WordPress.org

Make WordPress Core

Ticket #8974: 8974.3.diff

File 8974.3.diff, 15.0 KB (added by sivel, 5 years ago)
  • wp-includes/vars.php

     
    7373 */ 
    7474$is_IIS = (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false) ? true : false; 
    7575 
     76/** 
     77 * Whether the server software is IIS 7.X 
     78 * @global bool $is_IIS7 
     79 */ 
     80$is_iis7 = ($is_IIS && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/7.') !== false) ? true : false; 
     81 
     82 
    7683?> 
     84 No newline at end of file 
  • wp-includes/rewrite.php

     
    16951695 
    16961696                return $rules; 
    16971697        } 
     1698         
     1699        /** 
     1700         * Retrieve IIS7 URL Rewrite formatted rewrite rules to write to web.config file. 
     1701         * 
     1702         * Does not actually write to the web.config file, but creates the rules for 
     1703         * the process that will. 
     1704         * 
     1705         * @since 2.8.0  
     1706         * @access public 
     1707         * 
     1708         * @return string 
     1709         */ 
     1710        function iis7_url_rewrite_rules(){ 
     1711                 
     1712                if ( ! $this->using_permalinks()) { 
     1713                        return ''; 
     1714                } 
     1715                $rules  = "<rule name=\"wordpress\" patternSyntax=\"Wildcard\">\n"; 
     1716                $rules .= "     <match url=\"*\" />\n"; 
     1717                $rules .= "     <conditions>\n"; 
     1718                $rules .= "             <add input=\"{REQUEST_FILENAME}\" matchType=\"IsFile\" negate=\"true\" />\n"; 
     1719                $rules .= "             <add input=\"{REQUEST_FILENAME}\" matchType=\"IsDirectory\" negate=\"true\" />\n"; 
     1720                $rules .= "     </conditions>\n"; 
     1721                $rules .= "     <action type=\"Rewrite\" url=\"index.php\" />\n"; 
     1722                $rules .= "</rule>"; 
     1723                                 
     1724                $rules = apply_filters('iis7_url_rewrite_rules', $rules); 
     1725                 
     1726                return $rules; 
     1727        } 
    16981728 
    16991729        /** 
    17001730         * Add a straight rewrite rule. 
     
    17901820                $this->wp_rewrite_rules(); 
    17911821                if ( function_exists('save_mod_rewrite_rules') ) 
    17921822                        save_mod_rewrite_rules(); 
     1823                if ( function_exists('iis7_save_url_rewrite_rules') ) 
     1824                        iis7_save_url_rewrite_rules(); 
    17931825        } 
    17941826 
    17951827        /** 
  • wp-admin/includes/misc.php

     
    136136} 
    137137 
    138138/** 
     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 */ 
     146function 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/** 
    139167 * {@internal Missing Short Description}} 
    140168 * 
    141169 * @since unknown 
     
    370398                exit; 
    371399        } 
    372400} 
    373 ?> 
    374  No newline at end of file 
     401 
     402/** 
     403 * Check if IIS 7 supports pretty permalinks 
     404 *  
     405 * @since 2.8.0 
     406 *  
     407 * @return bool 
     408 */ 
     409function iis7_supports_permalinks() { 
     410        global $is_iis7; 
     411 
     412        $supports_permalinks = false;    
     413        if ( $is_iis7 ) { 
     414                /* First we check if the DOMDocument class exists. If it does not exist, 
     415                 * which is the case for PHP 4.X, then we cannot easily update the xml configuration file, 
     416                 * hence we just bail out and tell user that pretty permalinks cannot be used. 
     417                 * This is not a big issue because PHP 4.X is going to be depricated and for IIS it 
     418                 * is recommended to use PHP 5.X NTS. 
     419                 * Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When 
     420                 * URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'. 
     421                 * Lastly we make sure that PHP is running via FastCGI. This is important because if it runs  
     422                 * via ISAPI then pretty permalinks will not work. 
     423                 */ 
     424                $supports_permalinks = class_exists('DOMDocument') && isset($_SERVER['IIS_UrlRewriteModule']) && ( php_sapi_name() == 'cgi-fcgi' ); 
     425        } 
     426                 
     427        return apply_filters('iis7_supports_permalinks', $supports_permalinks); 
     428} 
     429 
     430/** 
     431 * Check if rewrite rule for WordPress already exists in the IIS 7 configuration file 
     432 *  
     433 * @since 2.8.0 
     434 *  
     435 * @return bool 
     436 * @param string $filename The file path to the configuration file 
     437 */ 
     438function iis7_rewrite_rule_exists($filename) {   
     439        if ( ! file_exists($filename) ) 
     440                return false;    
     441        if ( ! class_exists('DOMDocument') ) 
     442                return false; 
     443         
     444        $doc = new DOMDocument(); 
     445        if ( $doc->load($filename) === false ) 
     446                return false; 
     447        $xpath = new DOMXPath($doc); 
     448        $rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); 
     449        if ( $rules->length == 0 ) 
     450                return false; 
     451        else 
     452                return true;     
     453} 
     454 
     455/** 
     456 * Delete WordPress rewrite rule from web.config file if it exists there 
     457 * 
     458 * @since 2.8.0  
     459 * 
     460 * @param string $filename Name of the configuration file 
     461 * @return bool 
     462 */ 
     463function iis7_delete_rewrite_rule($filename) {   
     464        // If configuration file does not exist then rules also do not exist so there is nothing to delete 
     465        if ( ! file_exists($filename) ) 
     466                return true; 
     467         
     468        if ( ! class_exists('DOMDocument') ) 
     469                return false; 
     470         
     471        $doc = new DOMDocument(); 
     472        $doc->preserveWhiteSpace = false; 
     473 
     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                $child = $rules->item(0); 
     480                $parent = $child->parentNode; 
     481                $parent->removeChild($child); 
     482                $doc->formatOutput = true; 
     483                saveDomDocument($doc, $filename); 
     484        } 
     485        return true; 
     486} 
     487 
     488/** 
     489 * Add WordPress rewrite rule to the IIS 7 configuration file. 
     490 *  
     491 * @since 2.8.0 
     492 *  
     493 * @param string $filename The file path to the configuration file 
     494 * @param string $rewrite_rule The XML fragment with URL Rewrite rule 
     495 * @return bool 
     496 */ 
     497function iis7_add_rewrite_rule($filename, $rewrite_rule) {       
     498        if ( ! class_exists('DOMDocument') ) 
     499                return false; 
     500         
     501        // If configuration file does not exist then we create one. 
     502        if ( ! file_exists($filename) ) { 
     503                $fp = fopen( $filename, 'w'); 
     504                fwrite($fp, '<configuration/>'); 
     505                fclose($fp); 
     506        } 
     507         
     508        $doc = new DOMDocument(); 
     509        $doc->preserveWhiteSpace = false; 
     510 
     511        if ( $doc->load($filename) === false ) 
     512                return false; 
     513         
     514        $xpath = new DOMXPath($doc); 
     515 
     516        // First check if the rule already exists as in that case there is no need to re-add it 
     517        $wordpress_rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); 
     518        if ( $wordpress_rules->length > 0 ) 
     519                return true; 
     520 
     521        // Check the XPath to the rewrite rule and create XML nodes if they do not exist 
     522        $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite/rules'); 
     523        if ( $xmlnodes->length > 0 ) { 
     524                $rules_node = $xmlnodes->item(0); 
     525        } else { 
     526                $rules_node = $doc->createElement('rules'); 
     527                 
     528                $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite'); 
     529                if ( $xmlnodes->length > 0 ) { 
     530                        $rewrite_node = $xmlnodes->item(0); 
     531                        $rewrite_node->appendChild($rules_node); 
     532                } else { 
     533                        $rewrite_node = $doc->createElement('rewrite'); 
     534                        $rewrite_node->appendChild($rules_node); 
     535 
     536                        $xmlnodes = $xpath->query('/configuration/system.webServer'); 
     537                        if ( $xmlnodes->length > 0 ) { 
     538                                $system_webServer_node = $xmlnodes->item(0); 
     539                                $system_webServer_node->appendChild($rewrite_node); 
     540                        } else { 
     541                                $system_webServer_node = $doc->createElement('system.webServer'); 
     542                                $system_webServer_node->appendChild($rewrite_node); 
     543                 
     544                                $xmlnodes = $xpath->query('/configuration'); 
     545                                if ( $xmlnodes->length > 0 ) { 
     546                                        $config_node = $xmlnodes->item(0); 
     547                                        $config_node->appendChild($system_webServer_node); 
     548                                } else { 
     549                                        $config_node = $doc->createElement('configuration'); 
     550                                        $doc->appendChild($config_node); 
     551                                        $config_node->appendChild($system_webServer_node); 
     552                                } 
     553                        } 
     554                } 
     555        } 
     556         
     557        $rule_fragment = $doc->createDocumentFragment(); 
     558        $rule_fragment->appendXML($rewrite_rule); 
     559        $rules_node->appendChild($rule_fragment); 
     560 
     561        $doc->formatOutput = true;       
     562        saveDomDocument($doc, $filename); 
     563 
     564        return true;     
     565} 
     566 
     567/** 
     568 * Saves the XML document into a file 
     569 *  
     570 * @since 2.8.0 
     571 * 
     572 * @param DOMDocument $doc 
     573 * @param string $filename 
     574 */ 
     575function saveDomDocument($doc, $filename) { 
     576        $config = $doc->saveXML(); 
     577        $config = preg_replace("/([^\r])\n/", "$1\r\n", $config); 
     578        $fp = fopen($filename, 'w'); 
     579        fwrite($fp, $config); 
     580        fclose($fp); 
     581} 
     582 
     583/** 
     584 * Workaround for Windows bug in is_writable() function 
     585 * 
     586 * @since 2.8.0 
     587 * 
     588 * @param object $path 
     589 * @return bool 
     590 */ 
     591function win_is_writable($path) { 
     592        /* will work in despite of Windows ACLs bug 
     593         * NOTE: use a trailing slash for folders!!! 
     594         * see http://bugs.php.net/bug.php?id=27609 
     595         * see http://bugs.php.net/bug.php?id=30931 
     596         */ 
     597 
     598    if ( $path{strlen($path)-1} == '/' ) // recursively return a temporary file path 
     599        return win_is_writable($path . uniqid(mt_rand()) . '.tmp'); 
     600    else if ( is_dir($path) ) 
     601        return win_is_writable($path . '/' . uniqid(mt_rand()) . '.tmp'); 
     602    // check tmp file for read/write capabilities 
     603    $rm = file_exists($path); 
     604    $f = @fopen($path, 'a'); 
     605    if ($f===false) 
     606        return false; 
     607    fclose($f); 
     608    if ( ! $rm ) 
     609        unlink($path); 
     610    return true; 
     611} 
     612?> 
  • wp-admin/options-permalink.php

     
    7070include('admin-header.php'); 
    7171 
    7272$home_path = get_home_path(); 
     73$iis7_permalinks = iis7_supports_permalinks(); 
    7374 
    7475if ( isset($_POST['permalink_structure']) || isset($_POST['category_base']) ) { 
    7576        check_admin_referer('update-permalink'); 
     
    100101$category_base = get_option('category_base'); 
    101102$tag_base = get_option( 'tag_base' ); 
    102103 
    103 if ( (!file_exists($home_path.'.htaccess') && is_writable($home_path)) || is_writable($home_path.'.htaccess') ) 
    104         $writable = true; 
    105 else 
    106         $writable = false; 
     104if ( $iis7_permalinks ) { 
     105        if ( ( ! file_exists($home_path . 'web.config') && win_is_writable($home_path) ) || win_is_writable($home_path . 'web.config') ) 
     106                $writable = true; 
     107        else 
     108                $writable = false; 
     109} else { 
     110        if ( ( ! file_exists($home_path . '.htaccess') && is_writable($home_path) ) || is_writable($home_path . '.htaccess') ) 
     111                $writable = true; 
     112        else 
     113                $writable = false; 
     114} 
    107115 
    108 if ($wp_rewrite->using_index_permalinks()) 
     116if ( $wp_rewrite->using_index_permalinks() ) 
    109117        $usingpi = true; 
    110118else 
    111119        $usingpi = false; 
     
    115123 
    116124<?php if (isset($_POST['submit'])) : ?> 
    117125<div id="message" class="updated fade"><p><?php 
    118 if ( $permalink_structure && !$usingpi && !$writable ) 
    119         _e('You should update your .htaccess now.'); 
    120 else 
    121         _e('Permalink structure updated.'); 
    122 ?></p></div> 
     126if ( $iis7_permalinks ) { 
     127        if ( $permalink_structure && ! $usingpi && ! $writable ) 
     128                _e('You should update your web.config now'); 
     129        else if ( $permalink_structure && ! $usingpi && $writable) 
     130                _e('Permalink structure updated. Remove write access on web.config file now!'); 
     131        else 
     132                _e('Permalink structure updated'); 
     133} else { 
     134        if ( $permalink_structure && ! $usingpi && ! $writable ) 
     135                _e('You should update your .htaccess now.'); 
     136        else 
     137                _e('Permalink structure updated.'); 
     138} 
     139?> 
     140</p></div> 
    123141<?php endif; ?> 
    124142 
    125143<div class="wrap"> 
     
    134152<?php 
    135153$prefix = ''; 
    136154 
    137 if ( ! got_mod_rewrite() ) 
     155if ( ! got_mod_rewrite() && ! $iis7_permalinks ) 
    138156        $prefix = '/index.php'; 
    139157 
    140158$structures = array( 
     
    179197</table> 
    180198 
    181199<h3><?php _e('Optional'); ?></h3> 
    182 <?php if ($is_apache) : ?> 
     200<?php if ( $is_apache || $iis7_permalinks ) : ?> 
    183201        <p><?php _e('If you like, you may enter custom structures for your category and tag <abbr title="Universal Resource Locator">URL</abbr>s here. For example, using <kbd>topics</kbd> as your category base would make your category links like <code>http://example.org/topics/uncategorized/</code>. If you leave these blank the defaults will be used.') ?></p> 
    184202<?php else : ?> 
    185203        <p><?php _e('If you like, you may enter custom structures for your category and tag <abbr title="Universal Resource Locator">URL</abbr>s here. For example, using <code>topics</code> as your category base would make your category links like <code>http://example.org/index.php/topics/uncategorized/</code>. If you leave these blank the defaults will be used.') ?></p> 
     
    203221        <input type="submit" name="submit" class="button-primary" value="<?php esc_attr_e('Save Changes') ?>" /> 
    204222</p> 
    205223  </form> 
    206 <?php if ( $permalink_structure && !$usingpi && !$writable ) : ?> 
    207   <p><?php _e('If your <code>.htaccess</code> file were <a href="http://codex.wordpress.org/Changing_File_Permissions">writable</a>, we could do this automatically, but it isn&#8217;t so these are the mod_rewrite rules you should have in your <code>.htaccess</code> file. Click in the field and press <kbd>CTRL + a</kbd> to select all.') ?></p> 
     224<?php if ($iis7_permalinks) : 
     225        if ( isset($_POST['submit']) && $permalink_structure && ! $usingpi && ! $writable ) : ?> 
     226<p><?php _e('If your <code>web.config</code> file were <a href="http://codex.wordpress.org/Changing_File_Permissions">writable</a>, we could do this automatically, but it isn&#8217;t so this is the url rewrite rule you should have in your <code>web.config</code> file. Click in the field and press <kbd>CTRL + a</kbd> to select all. Then insert this rule inside of the <code>/&lt;configuration&gt;/&lt;system.webServer&gt;/&lt;rewrite&gt;/&lt;rules&gt;</code> element in <code>web.config</code> file.') ?></p> 
    208227<form action="options-permalink.php" method="post"> 
    209228<?php wp_nonce_field('update-permalink') ?> 
     229        <p><textarea rows="10" class="large-text readonly" name="rules" id="rules" readonly="readonly"><?php echo wp_specialchars($wp_rewrite->iis7_url_rewrite_rules()); ?></textarea></p> 
     230</form> 
     231<p><?php _e('If you temporarily make your <code>web.config</code> file writable for us to generate rewrite rules automatically, do not forget to revert the permissions after rule has been saved.')  ?></p>   
     232        <?php endif; ?> 
     233<?php else :  
     234        if ( $permalink_structure && ! $usingpi && ! $writable ) : ?> 
     235<p><?php _e('If your <code>.htaccess</code> file were <a href="http://codex.wordpress.org/Changing_File_Permissions">writable</a>, we could do this automatically, but it isn&#8217;t so these are the mod_rewrite rules you should have in your <code>.htaccess</code> file. Click in the field and press <kbd>CTRL + a</kbd> to select all.') ?></p> 
     236<form action="options-permalink.php" method="post"> 
     237<?php wp_nonce_field('update-permalink') ?> 
    210238        <p><textarea rows="6" class="large-text readonly" name="rules" id="rules" readonly="readonly"><?php echo wp_specialchars($wp_rewrite->mod_rewrite_rules()); ?></textarea></p> 
    211239</form> 
     240        <?php endif; ?> 
    212241<?php endif; ?> 
    213242 
    214243</div>