WordPress.org

Make WordPress Core

Ticket #8974: 8974.diff

File 8974.diff, 14.8 KB (added by Denis-de-Bernardy, 5 years ago)

per ryan's comment

  • 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         * @access public 
     1706         * 
     1707         * @return string 
     1708         */ 
     1709        function iis7_url_rewrite_rules(){ 
     1710                 
     1711                if ( ! $this->using_permalinks()) { 
     1712                        return ''; 
     1713                } 
     1714                $rules =  "<rule name=\"wordpress\" patternSyntax=\"Wildcard\">\n"; 
     1715                $rules .= "     <match url=\"*\" />\n"; 
     1716                $rules .= "     <conditions>\n"; 
     1717                $rules .= "             <add input=\"{REQUEST_FILENAME}\" matchType=\"IsFile\" negate=\"true\" />\n"; 
     1718                $rules .= "             <add input=\"{REQUEST_FILENAME}\" matchType=\"IsDirectory\" negate=\"true\" />\n"; 
     1719                $rules .= "     </conditions>\n"; 
     1720                $rules .= "     <action type=\"Rewrite\" url=\"index.php\" />\n"; 
     1721                $rules .= "</rule>"; 
     1722                                 
     1723                $rules = apply_filters('iis7_url_rewrite_rules', $rules); 
     1724                 
     1725                return $rules; 
     1726        } 
    16981727 
    16991728        /** 
    17001729         * Add a straight rewrite rule. 
     
    17901819                $this->wp_rewrite_rules(); 
    17911820                if ( function_exists('save_mod_rewrite_rules') ) 
    17921821                        save_mod_rewrite_rules(); 
     1822                if ( function_exists('iis7_save_url_rewrite_rules')) 
     1823                        iis7_save_url_rewrite_rules(); 
    17931824        } 
    17941825 
    17951826        /** 
  • 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 *  
     143 * @return bool True if web.config was updated successfully 
     144 */ 
     145function iis7_save_url_rewrite_rules(){ 
     146        global $wp_rewrite; 
     147         
     148        $home_path = get_home_path(); 
     149        $web_config_file = $home_path.'web.config'; 
     150 
     151        // Using win_is_writable() instead of is_writable() because of a bug in Windows PHP      
     152        if ((!file_exists($web_config_file) && win_is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks()) || win_is_writable($web_config_file)) { 
     153                if ( iis7_supports_permalinks() ) { 
     154                        $rule = $wp_rewrite -> iis7_url_rewrite_rules(); 
     155                        if ( !empty($rule) ) //  
     156                                return iis7_add_rewrite_rule($web_config_file, $rule); 
     157                        else{ 
     158                                return iis7_delete_rewrite_rule($web_config_file); 
     159                        } 
     160                } 
     161        } 
     162        return false; 
     163} 
     164 
     165/** 
    139166 * {@internal Missing Short Description}} 
    140167 * 
    141168 * @since unknown 
     
    370397                exit; 
    371398        } 
    372399} 
    373 ?> 
    374  No newline at end of file 
     400 
     401// IIS 7 specific functions 
     402/** 
     403 * Check if IIS 7 supports pretty permalinks 
     404 *  
     405 *  
     406 * @return bool 
     407 */ 
     408function iis7_supports_permalinks(){ 
     409        global $is_iis7; 
     410 
     411        $supports_permalinks = false;    
     412        if ($is_iis7){ 
     413                // First we check if the DOMDocument class exists. If it does not exist, 
     414                // which is the case for PHP 4.X, then we cannot easily update the xml configuration file, 
     415                // hence we just bail out and tell user that pretty permalinks cannot be used. 
     416                // This is not a big issue because PHP 4.X is going to be depricated and for IIS it 
     417                // is recommended to use PHP 5.X NTS. 
     418                // Next we check if the URL Rewrite Module 1.1 is loaded and enabled for the web site. When 
     419                // URL Rewrite 1.1 is loaded it always sets a server variable called 'IIS_UrlRewriteModule'. 
     420                // Lastly we make sure that PHP is running via FastCGI. This is important because if it runs  
     421                // via ISAPI then pretty permalinks will not work. 
     422                $supports_permalinks = class_exists('DOMDocument') && isset($_SERVER['IIS_UrlRewriteModule']) && (php_sapi_name() == 'cgi-fcgi'); 
     423        } 
     424                 
     425        return apply_filters('iis7_supports_permalinks', $supports_permalinks); 
     426} 
     427 
     428/** 
     429 * Check if rewrite rule for WordPress already exists in the IIS 7 configuration file 
     430 *  
     431 *  
     432 * @return bool 
     433 * @param string $filename The file path to the configuration file 
     434 */ 
     435function iis7_rewrite_rule_exists($filename) 
     436{        
     437        if (!file_exists($filename)) return false;       
     438        if (!class_exists('DOMDocument')) return false; 
     439         
     440        $doc = new DOMDocument(); 
     441        if ($doc -> load($filename) === false) return false; 
     442        $xpath = new DOMXPath($doc); 
     443        $rules = $xpath -> query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); 
     444        if ($rules -> length == 0)  
     445                return false; 
     446        else 
     447                return true;     
     448} 
     449 
     450/** 
     451 * Delete WordPress rewrite rule from web.config file if it exists there 
     452 * @return  
     453 * @param string $filename Name of the configuration file 
     454 */ 
     455function iis7_delete_rewrite_rule($filename) 
     456{        
     457        // If configuration file does not exist then rules also do not exist so there is nothing to delete 
     458        if (!file_exists($filename)) return true; 
     459         
     460        if (!class_exists('DOMDocument')) return false; 
     461         
     462        $doc = new DOMDocument(); 
     463        $doc -> preserveWhiteSpace = false; 
     464 
     465        if ($doc -> load($filename) === false) return false; 
     466        $xpath = new DOMXPath($doc); 
     467        $rules = $xpath -> query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); 
     468        if ($rules -> length > 0) { 
     469                $child = $rules -> item(0); 
     470                $parent = $child -> parentNode; 
     471                $parent -> removeChild($child); 
     472                $doc -> formatOutput = true; 
     473                saveDomDocument($doc, $filename); 
     474        } 
     475        return true; 
     476} 
     477 
     478/** 
     479 * Add WordPress rewrite rule to the IIS 7 configuration file. 
     480 *  
     481 *  
     482 * @return bool 
     483 * @param string $filename The file path to the configuration file 
     484 * @param string $rewrite_rule The XML fragment with URL Rewrite rule 
     485 */ 
     486function iis7_add_rewrite_rule($filename, $rewrite_rule) 
     487{        
     488        if (!class_exists('DOMDocument')) return false; 
     489         
     490        // If configuration file does not exist then we create one. 
     491        if (!file_exists($filename)) { 
     492                $fp = fopen( $filename, 'w'); 
     493                fwrite($fp, '<configuration/>'); 
     494                fclose($fp); 
     495        } 
     496         
     497        $doc = new DOMDocument(); 
     498        $doc -> preserveWhiteSpace = false; 
     499 
     500        if ($doc -> load($filename) === false) return false; 
     501         
     502        $xpath = new DOMXPath($doc); 
     503 
     504        // First check if the rule already exists as in that case there is no need to re-add it 
     505        $wordpress_rules = $xpath -> query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); 
     506        if ($wordpress_rules -> length > 0) return true; 
     507 
     508        // Check the XPath to the rewrite rule and create XML nodes if they do not exist 
     509        $xmlnodes = $xpath -> query('/configuration/system.webServer/rewrite/rules'); 
     510        if ($xmlnodes -> length > 0){ 
     511                $rules_node = $xmlnodes -> item(0); 
     512        } 
     513        else{ 
     514                $rules_node = $doc -> createElement('rules'); 
     515                 
     516                $xmlnodes = $xpath -> query('/configuration/system.webServer/rewrite'); 
     517                if ($xmlnodes -> length > 0){ 
     518                        $rewrite_node = $xmlnodes -> item(0); 
     519                        $rewrite_node -> appendChild($rules_node); 
     520                } 
     521                else{ 
     522                        $rewrite_node = $doc -> createElement('rewrite'); 
     523                        $rewrite_node -> appendChild($rules_node); 
     524 
     525                        $xmlnodes = $xpath -> query('/configuration/system.webServer'); 
     526                        if ($xmlnodes -> length > 0){ 
     527                                $system_webServer_node = $xmlnodes -> item(0); 
     528                                $system_webServer_node -> appendChild($rewrite_node); 
     529                        } 
     530                        else{ 
     531                                $system_webServer_node = $doc -> createElement('system.webServer'); 
     532                                $system_webServer_node -> appendChild($rewrite_node); 
     533                 
     534                                $xmlnodes = $xpath -> query('/configuration'); 
     535                                if ($xmlnodes -> length > 0){ 
     536                                        $config_node = $xmlnodes -> item(0); 
     537                                        $config_node -> appendChild($system_webServer_node); 
     538                                } 
     539                                else{ 
     540                                        $config_node = $doc -> createElement('configuration'); 
     541                                        $doc -> appendChild($config_node); 
     542                                        $config_node -> appendChild($system_webServer_node); 
     543                                }  
     544                        }                
     545                } 
     546        } 
     547         
     548        $rule_fragment = $doc -> createDocumentFragment(); 
     549        $rule_fragment -> appendXML($rewrite_rule); 
     550        $rules_node -> appendChild($rule_fragment); 
     551 
     552        $doc -> formatOutput = true;     
     553        saveDomDocument($doc, $filename); 
     554 
     555        return true;     
     556} 
     557 
     558/** 
     559 * Saves the XML document into a file 
     560 *  
     561 * @param DOMDocument $doc 
     562 * @param string $filename 
     563 */ 
     564function saveDomDocument($doc, $filename) 
     565{ 
     566        $config = $doc -> saveXML();     
     567        $config = preg_replace("/([^\r])\n/", "$1\r\n", $config); 
     568        $fp = fopen($filename, 'w'); 
     569        fwrite($fp, $config); 
     570        fclose($fp); 
     571} 
     572 
     573/** 
     574 * Workaround for Windows bug in is_writable() function 
     575 *  
     576 * @return  
     577 * @param object $path 
     578 */ 
     579function win_is_writable($path) { 
     580//will work in despite of Windows ACLs bug 
     581//NOTE: use a trailing slash for folders!!! 
     582//see http://bugs.php.net/bug.php?id=27609 
     583//see http://bugs.php.net/bug.php?id=30931 
     584 
     585    if ($path{strlen($path)-1}=='/') // recursively return a temporary file path 
     586        return win_is_writable($path.uniqid(mt_rand()).'.tmp'); 
     587    else if (is_dir($path)) 
     588        return win_is_writable($path.'/'.uniqid(mt_rand()).'.tmp'); 
     589    // check tmp file for read/write capabilities 
     590    $rm = file_exists($path); 
     591    $f = @fopen($path, 'a'); 
     592    if ($f===false) 
     593        return false; 
     594    fclose($f); 
     595    if (!$rm) 
     596        unlink($path); 
     597    return true; 
     598} 
     599?> 
  • 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} 
     110else{ 
     111        if ( (!file_exists($home_path.'.htaccess') && is_writable($home_path)) || is_writable($home_path.'.htaccess') ) 
     112                $writable = true; 
     113        else 
     114                $writable = false; 
     115} 
    107116 
    108117if ($wp_rewrite->using_index_permalinks()) 
    109118        $usingpi = true; 
     
    115124 
    116125<?php if (isset($_POST['submit'])) : ?> 
    117126<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.'); 
     127if ($iis7_permalinks){ 
     128        if ($permalink_structure && !$usingpi && !$writable) 
     129                _e('You should update your web.config now'); 
     130        else if ($permalink_structure && !$usingpi && $writable) 
     131                _e('Permalink structure updated. Remove write access on web.config file now!'); 
     132        else 
     133                _e('Permalink structure updated'); 
     134} 
     135else{ 
     136        if ( $permalink_structure && !$usingpi && !$writable ) 
     137                _e('You should update your .htaccess now.'); 
     138        else 
     139                _e('Permalink structure updated.'); 
     140} 
    122141?></p></div> 
    123142<?php endif; ?> 
    124143 
     
    134153<?php 
    135154$prefix = ''; 
    136155 
    137 if ( ! got_mod_rewrite() ) 
     156if ( !got_mod_rewrite() && !$iis7_permalinks ) 
    138157        $prefix = '/index.php'; 
    139158 
    140159$structures = array( 
     
    179198</table> 
    180199 
    181200<h3><?php _e('Optional'); ?></h3> 
    182 <?php if ($is_apache) : ?> 
     201<?php if ($is_apache || $iis7_permalinks) : ?> 
    183202        <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> 
    184203<?php else : ?> 
    185204        <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> 
     
    203222        <input type="submit" name="submit" class="button-primary" value="<?php _ea('Save Changes') ?>" /> 
    204223</p> 
    205224  </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> 
     225<?php if ($iis7_permalinks) : 
     226        if ( isset($_POST['submit']) && $permalink_structure && !$usingpi && !$writable ) : ?> 
     227<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> 
    208228<form action="options-permalink.php" method="post"> 
    209229<?php wp_nonce_field('update-permalink') ?> 
     230        <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> 
     231</form> 
     232<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>   
     233        <?php endif; ?> 
     234<?php else :  
     235        if ( $permalink_structure && !$usingpi && !writable ) :?>        
     236<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> 
     237<form action="options-permalink.php" method="post"> 
     238<?php wp_nonce_field('update-permalink') ?> 
    210239        <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> 
    211240</form> 
     241        <?php endif; ?> 
    212242<?php endif; ?> 
    213243 
    214244</div> 
    215245 
    216 <?php require('./admin-footer.php'); ?> 
     246<?php require('./admin-footer.php'); ?> 
     247 No newline at end of file