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