Wordpress 2.8
[autoinstalls/wordpress.git] / wp-admin / includes / misc.php
1 <?php
2 /**
3  * Misc WordPress Administration API.
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /**
10  * {@internal Missing Short Description}}
11  *
12  * @since unknown
13  *
14  * @return unknown
15  */
16 function got_mod_rewrite() {
17         $got_rewrite = apache_mod_loaded('mod_rewrite', true);
18         return apply_filters('got_rewrite', $got_rewrite);
19 }
20
21 /**
22  * {@internal Missing Short Description}}
23  *
24  * @since unknown
25  *
26  * @param unknown_type $filename
27  * @param unknown_type $marker
28  * @return array An array of strings from a file (.htaccess ) from between BEGIN and END markers.
29  */
30 function extract_from_markers( $filename, $marker ) {
31         $result = array ();
32
33         if (!file_exists( $filename ) ) {
34                 return $result;
35         }
36
37         if ( $markerdata = explode( "\n", implode( '', file( $filename ) ) ));
38         {
39                 $state = false;
40                 foreach ( $markerdata as $markerline ) {
41                         if (strpos($markerline, '# END ' . $marker) !== false)
42                                 $state = false;
43                         if ( $state )
44                                 $result[] = $markerline;
45                         if (strpos($markerline, '# BEGIN ' . $marker) !== false)
46                                 $state = true;
47                 }
48         }
49
50         return $result;
51 }
52
53 /**
54  * {@internal Missing Short Description}}
55  *
56  * Inserts an array of strings into a file (.htaccess ), placing it between
57  * BEGIN and END markers. Replaces existing marked info. Retains surrounding
58  * data. Creates file if none exists.
59  *
60  * @since unknown
61  *
62  * @param unknown_type $filename
63  * @param unknown_type $marker
64  * @param unknown_type $insertion
65  * @return bool True on write success, false on failure.
66  */
67 function insert_with_markers( $filename, $marker, $insertion ) {
68         if (!file_exists( $filename ) || is_writeable( $filename ) ) {
69                 if (!file_exists( $filename ) ) {
70                         $markerdata = '';
71                 } else {
72                         $markerdata = explode( "\n", implode( '', file( $filename ) ) );
73                 }
74
75                 $f = fopen( $filename, 'w' );
76                 $foundit = false;
77                 if ( $markerdata ) {
78                         $state = true;
79                         foreach ( $markerdata as $n => $markerline ) {
80                                 if (strpos($markerline, '# BEGIN ' . $marker) !== false)
81                                         $state = false;
82                                 if ( $state ) {
83                                         if ( $n + 1 < count( $markerdata ) )
84                                                 fwrite( $f, "{$markerline}\n" );
85                                         else
86                                                 fwrite( $f, "{$markerline}" );
87                                 }
88                                 if (strpos($markerline, '# END ' . $marker) !== false) {
89                                         fwrite( $f, "# BEGIN {$marker}\n" );
90                                         if ( is_array( $insertion ))
91                                                 foreach ( $insertion as $insertline )
92                                                         fwrite( $f, "{$insertline}\n" );
93                                         fwrite( $f, "# END {$marker}\n" );
94                                         $state = true;
95                                         $foundit = true;
96                                 }
97                         }
98                 }
99                 if (!$foundit) {
100                         fwrite( $f, "\n# BEGIN {$marker}\n" );
101                         foreach ( $insertion as $insertline )
102                                 fwrite( $f, "{$insertline}\n" );
103                         fwrite( $f, "# END {$marker}\n" );
104                 }
105                 fclose( $f );
106                 return true;
107         } else {
108                 return false;
109         }
110 }
111
112 /**
113  * Updates the htaccess file with the current rules if it is writable.
114  *
115  * Always writes to the file if it exists and is writable to ensure that we
116  * blank out old rules.
117  *
118  * @since unknown
119  */
120 function save_mod_rewrite_rules() {
121         global $wp_rewrite;
122
123         $home_path = get_home_path();
124         $htaccess_file = $home_path.'.htaccess';
125
126         // If the file doesn't already exists check for write access to the directory and whether of not we have some rules.
127         // else check for write access to the file.
128         if ((!file_exists($htaccess_file) && is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks()) || is_writable($htaccess_file)) {
129                 if ( got_mod_rewrite() ) {
130                         $rules = explode( "\n", $wp_rewrite->mod_rewrite_rules() );
131                         return insert_with_markers( $htaccess_file, 'WordPress', $rules );
132                 }
133         }
134
135         return false;
136 }
137
138 /**
139  * Updates the IIS web.config file with the current rules if it is writable.
140  * If the permalinks do not require rewrite rules then the rules are deleted from the web.config file.
141  *
142  * @since 2.8.0
143  *
144  * @return bool True if web.config was updated successfully
145  */
146 function iis7_save_url_rewrite_rules(){
147         global $wp_rewrite;
148
149         $home_path = get_home_path();
150         $web_config_file = $home_path . 'web.config';
151
152         // Using win_is_writable() instead of is_writable() because of a bug in Windows PHP
153         if ( ( ! file_exists($web_config_file) && win_is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks() ) || win_is_writable($web_config_file) ) {
154                 if ( iis7_supports_permalinks() ) {
155                         $rule = $wp_rewrite->iis7_url_rewrite_rules();
156                         if ( ! empty($rule) ) {
157                                 return iis7_add_rewrite_rule($web_config_file, $rule);
158                         } else {
159                                 return iis7_delete_rewrite_rule($web_config_file);
160                         }
161                 }
162         }
163         return false;
164 }
165
166 /**
167  * {@internal Missing Short Description}}
168  *
169  * @since unknown
170  *
171  * @param unknown_type $file
172  */
173 function update_recently_edited( $file ) {
174         $oldfiles = (array ) get_option( 'recently_edited' );
175         if ( $oldfiles ) {
176                 $oldfiles = array_reverse( $oldfiles );
177                 $oldfiles[] = $file;
178                 $oldfiles = array_reverse( $oldfiles );
179                 $oldfiles = array_unique( $oldfiles );
180                 if ( 5 < count( $oldfiles ))
181                         array_pop( $oldfiles );
182         } else {
183                 $oldfiles[] = $file;
184         }
185         update_option( 'recently_edited', $oldfiles );
186 }
187
188 /**
189  * If siteurl or home changed, flush rewrite rules.
190  *
191  * @since unknown
192  *
193  * @param unknown_type $old_value
194  * @param unknown_type $value
195  */
196 function update_home_siteurl( $old_value, $value ) {
197         global $wp_rewrite;
198
199         if ( defined( "WP_INSTALLING" ) )
200                 return;
201
202         // If home changed, write rewrite rules to new location.
203         $wp_rewrite->flush_rules();
204 }
205
206 add_action( 'update_option_home', 'update_home_siteurl', 10, 2 );
207 add_action( 'update_option_siteurl', 'update_home_siteurl', 10, 2 );
208
209 /**
210  * {@internal Missing Short Description}}
211  *
212  * @since unknown
213  *
214  * @param unknown_type $url
215  * @return unknown
216  */
217 function url_shorten( $url ) {
218         $short_url = str_replace( 'http://', '', stripslashes( $url ));
219         $short_url = str_replace( 'www.', '', $short_url );
220         if ('/' == substr( $short_url, -1 ))
221                 $short_url = substr( $short_url, 0, -1 );
222         if ( strlen( $short_url ) > 35 )
223                 $short_url = substr( $short_url, 0, 32 ).'...';
224         return $short_url;
225 }
226
227 /**
228  * {@internal Missing Short Description}}
229  *
230  * @since unknown
231  *
232  * @param unknown_type $vars
233  */
234 function wp_reset_vars( $vars ) {
235         for ( $i=0; $i<count( $vars ); $i += 1 ) {
236                 $var = $vars[$i];
237                 global $$var;
238
239                 if (!isset( $$var ) ) {
240                         if ( empty( $_POST["$var"] ) ) {
241                                 if ( empty( $_GET["$var"] ) )
242                                         $$var = '';
243                                 else
244                                         $$var = $_GET["$var"];
245                         } else {
246                                 $$var = $_POST["$var"];
247                         }
248                 }
249         }
250 }
251
252 /**
253  * {@internal Missing Short Description}}
254  *
255  * @since unknown
256  *
257  * @param unknown_type $message
258  */
259 function show_message($message) {
260         if( is_wp_error($message) ){
261                 if( $message->get_error_data() )
262                         $message = $message->get_error_message() . ': ' . $message->get_error_data();
263                 else
264                         $message = $message->get_error_message();
265         }
266         echo "<p>$message</p>\n";
267 }
268
269 function wp_doc_link_parse( $content ) {
270         if ( !is_string( $content ) || empty( $content ) )
271                 return array();
272
273         $tokens = token_get_all( $content );
274         $functions = array();
275         $ignore_functions = array();
276         for ( $t = 0, $count = count( $tokens ); $t < $count; $t++ ) {
277                 if ( !is_array( $tokens[$t] ) ) continue;
278                 if ( T_STRING == $tokens[$t][0] && ( '(' == $tokens[ $t + 1 ] || '(' == $tokens[ $t + 2 ] ) ) {
279                         // If it's a function or class defined locally, there's not going to be any docs available
280                         if ( ( isset( $tokens[ $t - 2 ][1] ) && in_array( $tokens[ $t - 2 ][1], array( 'function', 'class' ) ) ) || ( isset( $tokens[ $t - 2 ][0] ) && T_OBJECT_OPERATOR == $tokens[ $t - 1 ][0] ) ) {
281                                 $ignore_functions[] = $tokens[$t][1];
282                         }
283                         // Add this to our stack of unique references
284                         $functions[] = $tokens[$t][1];
285                 }
286         }
287
288         $functions = array_unique( $functions );
289         sort( $functions );
290         $ignore_functions = apply_filters( 'documentation_ignore_functions', $ignore_functions );
291         $ignore_functions = array_unique( $ignore_functions );
292
293         $out = array();
294         foreach ( $functions as $function ) {
295                 if ( in_array( $function, $ignore_functions ) )
296                         continue;
297                 $out[] = $function;
298         }
299
300         return $out;
301 }
302
303 /**
304  * Determines the language to use for CodePress syntax highlighting,
305  * based only on a filename.
306  *
307  * @since 2.8
308  *
309  * @param string $filename The name of the file to be highlighting
310 **/
311 function codepress_get_lang( $filename ) {
312         $codepress_supported_langs = apply_filters( 'codepress_supported_langs',
313                                                                         array( '.css' => 'css',
314                                                                                         '.js' => 'javascript',
315                                                                                         '.php' => 'php',
316                                                                                         '.html' => 'html',
317                                                                                         '.htm' => 'html',
318                                                                                         '.txt' => 'text'
319                                                                                         ) );
320         $extension = substr( $filename, strrpos( $filename, '.' ) );
321         if ( $extension && array_key_exists( $extension, $codepress_supported_langs ) )
322                 return $codepress_supported_langs[$extension];
323
324         return 'generic';
325 }
326
327 /**
328  * Adds Javascript required to make CodePress work on the theme/plugin editors.
329  *
330  * This code is attached to the action admin_print_footer_scripts.
331  *
332  * @since 2.8
333 **/
334 function codepress_footer_js() {
335         // Script-loader breaks CP's automatic path-detection, thus CodePress.path
336         // CP edits in an iframe, so we need to grab content back into normal form
337         ?><script type="text/javascript">
338 /* <![CDATA[ */
339 var codepress_path = '<?php echo includes_url('js/codepress/'); ?>';
340 jQuery('#template').submit(function(){
341         if (jQuery('#newcontent_cp').length)
342                 jQuery('#newcontent_cp').val(newcontent.getCode()).removeAttr('disabled');
343 });
344 jQuery('#codepress-on').hide();
345 jQuery('#codepress-off').show();
346 /* ]]> */
347 </script>
348 <?php
349 }
350
351 /**
352  * Determine whether to use CodePress or not.
353  *
354  * @since 2.8
355 **/
356 function use_codepress() {
357
358         if ( isset($_GET['codepress']) ) {
359                 $on = 'on' == $_GET['codepress'] ? 'on' : 'off';
360                 set_user_setting( 'codepress', $on );
361         } else {
362                 $on = get_user_setting('codepress', 'on');
363         }
364
365         if ( 'on' == $on ) {
366                 add_action( 'admin_print_footer_scripts', 'codepress_footer_js' );
367                 return true;
368         }
369
370         return false;
371 }
372
373 /**
374  * Saves option for number of rows when listing posts, pages, comments, etc.
375  *
376  * @since 2.8
377 **/
378 function set_screen_options() {
379
380         if ( isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options']) ) {
381                 check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' );
382
383                 if ( !$user = wp_get_current_user() )
384                         return;
385                 $option = $_POST['wp_screen_options']['option'];
386                 $value = $_POST['wp_screen_options']['value'];
387
388                 if ( !preg_match( '/^[a-z_-]+$/', $option ) )
389                         return;
390
391                 $option = str_replace('-', '_', $option);
392
393                 switch ( $option ) {
394                         case 'edit_per_page':
395                         case 'edit_pages_per_page':
396                         case 'edit_comments_per_page':
397                         case 'upload_per_page':
398                         case 'categories_per_page':
399                         case 'edit_tags_per_page':
400                         case 'plugins_per_page':
401                                 $value = (int) $value;
402                                 if ( $value < 1 || $value > 999 )
403                                         return;
404                                 break;
405                         default:
406                                 $value = apply_filters('set-screen-option', false, $option, $value);
407                                 if ( false === $value )
408                                         return;
409                                 break;
410                 }
411
412                 update_usermeta($user->ID, $option, $value);
413                 wp_redirect( remove_query_arg( array('pagenum', 'apage', 'paged'), wp_get_referer() ) );
414                 exit;
415         }
416 }
417
418 function wp_menu_unfold() {
419         if ( isset($_GET['unfoldmenu']) ) {
420                 delete_user_setting('mfold');
421                 wp_redirect( remove_query_arg( 'unfoldmenu', stripslashes($_SERVER['REQUEST_URI']) ) );
422                 exit;
423         }
424 }
425
426 /**
427  * Check if IIS 7 supports pretty permalinks
428  *
429  * @since 2.8.0
430  *
431  * @return bool
432  */
433 function iis7_supports_permalinks() {
434         global $is_iis7;
435
436         $supports_permalinks = false;
437         if ( $is_iis7 ) {
438                 /* First we check if the DOMDocument class exists. If it does not exist,
439                  * which is the case for PHP 4.X, then we cannot easily update the xml configuration file,
440                  * hence we just bail out and tell user that pretty permalinks cannot be used.
441                  * This is not a big issue because PHP 4.X is going to be depricated and for IIS it
442                  * is recommended to use PHP 5.X NTS.
443                  * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When
444                  * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'.
445                  * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs
446                  * via ISAPI then pretty permalinks will not work.
447                  */
448                 $supports_permalinks = class_exists('DOMDocument') && isset($_SERVER['IIS_UrlRewriteModule']) && ( php_sapi_name() == 'cgi-fcgi' );
449         }
450
451         return apply_filters('iis7_supports_permalinks', $supports_permalinks);
452 }
453
454 /**
455  * Check if rewrite rule for WordPress already exists in the IIS 7 configuration file
456  *
457  * @since 2.8.0
458  *
459  * @return bool
460  * @param string $filename The file path to the configuration file
461  */
462 function iis7_rewrite_rule_exists($filename) {
463         if ( ! file_exists($filename) )
464                 return false;
465         if ( ! class_exists('DOMDocument') )
466                 return false;
467
468         $doc = new DOMDocument();
469         if ( $doc->load($filename) === false )
470                 return false;
471         $xpath = new DOMXPath($doc);
472         $rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']');
473         if ( $rules->length == 0 )
474                 return false;
475         else
476                 return true;
477 }
478
479 /**
480  * Delete WordPress rewrite rule from web.config file if it exists there
481  *
482  * @since 2.8.0
483  *
484  * @param string $filename Name of the configuration file
485  * @return bool
486  */
487 function iis7_delete_rewrite_rule($filename) {
488         // If configuration file does not exist then rules also do not exist so there is nothing to delete
489         if ( ! file_exists($filename) )
490                 return true;
491
492         if ( ! class_exists('DOMDocument') )
493                 return false;
494
495         $doc = new DOMDocument();
496         $doc->preserveWhiteSpace = false;
497
498         if ( $doc -> load($filename) === false )
499                 return false;
500         $xpath = new DOMXPath($doc);
501         $rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']');
502         if ( $rules->length > 0 ) {
503                 $child = $rules->item(0);
504                 $parent = $child->parentNode;
505                 $parent->removeChild($child);
506                 $doc->formatOutput = true;
507                 saveDomDocument($doc, $filename);
508         }
509         return true;
510 }
511
512 /**
513  * Add WordPress rewrite rule to the IIS 7 configuration file.
514  *
515  * @since 2.8.0
516  *
517  * @param string $filename The file path to the configuration file
518  * @param string $rewrite_rule The XML fragment with URL Rewrite rule
519  * @return bool
520  */
521 function iis7_add_rewrite_rule($filename, $rewrite_rule) {
522         if ( ! class_exists('DOMDocument') )
523                 return false;
524
525         // If configuration file does not exist then we create one.
526         if ( ! file_exists($filename) ) {
527                 $fp = fopen( $filename, 'w');
528                 fwrite($fp, '<configuration/>');
529                 fclose($fp);
530         }
531
532         $doc = new DOMDocument();
533         $doc->preserveWhiteSpace = false;
534
535         if ( $doc->load($filename) === false )
536                 return false;
537
538         $xpath = new DOMXPath($doc);
539
540         // First check if the rule already exists as in that case there is no need to re-add it
541         $wordpress_rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']');
542         if ( $wordpress_rules->length > 0 )
543                 return true;
544
545         // Check the XPath to the rewrite rule and create XML nodes if they do not exist
546         $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite/rules');
547         if ( $xmlnodes->length > 0 ) {
548                 $rules_node = $xmlnodes->item(0);
549         } else {
550                 $rules_node = $doc->createElement('rules');
551
552                 $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite');
553                 if ( $xmlnodes->length > 0 ) {
554                         $rewrite_node = $xmlnodes->item(0);
555                         $rewrite_node->appendChild($rules_node);
556                 } else {
557                         $rewrite_node = $doc->createElement('rewrite');
558                         $rewrite_node->appendChild($rules_node);
559
560                         $xmlnodes = $xpath->query('/configuration/system.webServer');
561                         if ( $xmlnodes->length > 0 ) {
562                                 $system_webServer_node = $xmlnodes->item(0);
563                                 $system_webServer_node->appendChild($rewrite_node);
564                         } else {
565                                 $system_webServer_node = $doc->createElement('system.webServer');
566                                 $system_webServer_node->appendChild($rewrite_node);
567
568                                 $xmlnodes = $xpath->query('/configuration');
569                                 if ( $xmlnodes->length > 0 ) {
570                                         $config_node = $xmlnodes->item(0);
571                                         $config_node->appendChild($system_webServer_node);
572                                 } else {
573                                         $config_node = $doc->createElement('configuration');
574                                         $doc->appendChild($config_node);
575                                         $config_node->appendChild($system_webServer_node);
576                                 }
577                         }
578                 }
579         }
580
581         $rule_fragment = $doc->createDocumentFragment();
582         $rule_fragment->appendXML($rewrite_rule);
583         $rules_node->appendChild($rule_fragment);
584
585         $doc->formatOutput = true;
586         saveDomDocument($doc, $filename);
587
588         return true;
589 }
590
591 /**
592  * Saves the XML document into a file
593  *
594  * @since 2.8.0
595  *
596  * @param DOMDocument $doc
597  * @param string $filename
598  */
599 function saveDomDocument($doc, $filename) {
600         $config = $doc->saveXML();
601         $config = preg_replace("/([^\r])\n/", "$1\r\n", $config);
602         $fp = fopen($filename, 'w');
603         fwrite($fp, $config);
604         fclose($fp);
605 }
606
607 /**
608  * Workaround for Windows bug in is_writable() function
609  *
610  * @since 2.8.0
611  *
612  * @param object $path
613  * @return bool
614  */
615 function win_is_writable($path) {
616         /* will work in despite of Windows ACLs bug
617          * NOTE: use a trailing slash for folders!!!
618          * see http://bugs.php.net/bug.php?id=27609
619          * see http://bugs.php.net/bug.php?id=30931
620          */
621
622     if ( $path{strlen($path)-1} == '/' ) // recursively return a temporary file path
623         return win_is_writable($path . uniqid(mt_rand()) . '.tmp');
624     else if ( is_dir($path) )
625         return win_is_writable($path . '/' . uniqid(mt_rand()) . '.tmp');
626     // check tmp file for read/write capabilities
627     $rm = file_exists($path);
628     $f = @fopen($path, 'a');
629     if ($f===false)
630         return false;
631     fclose($f);
632     if ( ! $rm )
633         unlink($path);
634     return true;
635 }
636 ?>