| | 365 | |
| | 366 | /** |
| | 367 | * Updates the IIS web.config file with the current rules if it is writable. |
| | 368 | * If the permalinks do not require rewrite rules then the rules are deleted from the web.config file. |
| | 369 | * |
| | 370 | * |
| | 371 | * @return bool True if web.config was updated successfully |
| | 372 | */ |
| | 373 | function iis7_save_url_rewrite_rules(){ |
| | 374 | global $wp_rewrite; |
| | 375 | |
| | 376 | $home_path = get_home_path(); |
| | 377 | $web_config_file = $home_path.'web.config'; |
| | 378 | |
| | 379 | // Using is__writable() instead of is_writable() because of a bug in Windows PHP |
| | 380 | if ((!file_exists($web_config_file) && is__writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks()) || is__writable($web_config_file)) { |
| | 381 | if ( iis7_supports_permalinks() ) { |
| | 382 | $rule = $wp_rewrite -> iis7_url_rewrite_rules(); |
| | 383 | if ( !empty($rule) ) // |
| | 384 | return iis7_add_rewrite_rule($web_config_file, $rule); |
| | 385 | else{ |
| | 386 | return iis7_delete_rewrite_rule($web_config_file); |
| | 387 | } |
| | 388 | } |
| | 389 | } |
| | 390 | return false; |
| | 391 | } |
| | 392 | // IIS 7 specific functions |
| | 393 | |
| | 394 | /** |
| | 395 | * Check if IIS 7 supports pretty permalinks |
| | 396 | * |
| | 397 | * |
| | 398 | * @return bool |
| | 399 | */ |
| | 400 | function iis7_supports_permalinks(){ |
| | 401 | // First we check if the DOMDocument class exists. If it does not exist, |
| | 402 | // which is the case for PHP 4.X, then we cannot easily update the xml configuration file, |
| | 403 | // hence we just bail out and tell user that pretty permalinks cannot be used. |
| | 404 | // This is not a big issue because PHP 4.X is going to be depricated and for IIS it |
| | 405 | // is recommended to use PHP 5.X NTS. |
| | 406 | $supports_permalinks = class_exists('DOMDocument') && iis7_url_rewrite_loaded(); |
| | 407 | return apply_filters('iis7_supports_permalinks', $supports_permalinks); |
| | 408 | } |
| | 409 | |
| | 410 | /** |
| | 411 | * Check if rewrite rule for WordPress already exists in the IIS 7 configuration file |
| | 412 | * |
| | 413 | * |
| | 414 | * @return bool |
| | 415 | * @param string $filename The file path to the configuration file |
| | 416 | */ |
| | 417 | function iis7_rewrite_rule_exists($filename) |
| | 418 | { |
| | 419 | if (!file_exists($filename)) return false; |
| | 420 | if (!class_exists('DOMDocument')) return false; |
| | 421 | |
| | 422 | $doc = new DOMDocument(); |
| | 423 | if ($doc -> load($filename) === false) return false; |
| | 424 | $xpath = new DOMXPath($doc); |
| | 425 | $rules = $xpath -> query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); |
| | 426 | if ($rules -> length == 0) |
| | 427 | return false; |
| | 428 | else |
| | 429 | return true; |
| | 430 | } |
| | 431 | |
| | 432 | /** |
| | 433 | * Delete WordPress rewrite rule from web.config file if it exists there |
| | 434 | * @return |
| | 435 | * @param string $filename Name of the configuration file |
| | 436 | */ |
| | 437 | function iis7_delete_rewrite_rule($filename) |
| | 438 | { |
| | 439 | // If configuration file does not exist then rules also do not exist so there is nothing to delete |
| | 440 | if (!file_exists($filename)) return true; |
| | 441 | |
| | 442 | if (!class_exists('DOMDocument')) return false; |
| | 443 | |
| | 444 | $doc = new DOMDocument(); |
| | 445 | $doc -> preserveWhiteSpace = false; |
| | 446 | |
| | 447 | if ($doc -> load($filename) === false) return false; |
| | 448 | $xpath = new DOMXPath($doc); |
| | 449 | $rules = $xpath -> query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); |
| | 450 | if ($rules -> length > 0) { |
| | 451 | $child = $rules -> item(0); |
| | 452 | $parent = $child -> parentNode; |
| | 453 | $parent -> removeChild($child); |
| | 454 | $doc -> formatOutput = true; |
| | 455 | saveDomDocument($doc, $filename); |
| | 456 | } |
| | 457 | return true; |
| | 458 | } |
| | 459 | |
| | 460 | /** |
| | 461 | * Add WordPress rewrite rule to the IIS 7 configuration file. |
| | 462 | * |
| | 463 | * |
| | 464 | * @return bool |
| | 465 | * @param string $filename The file path to the configuration file |
| | 466 | * @param string $rewrite_rule The XML fragment with URL Rewrite rule |
| | 467 | */ |
| | 468 | function iis7_add_rewrite_rule($filename, $rewrite_rule) |
| | 469 | { |
| | 470 | if (!class_exists('DOMDocument')) return false; |
| | 471 | |
| | 472 | // If configuration file does not exist then we create one. |
| | 473 | if (!file_exists($filename)) { |
| | 474 | $fp = fopen( $filename, 'w'); |
| | 475 | fwrite($fp, '<configuration/>'); |
| | 476 | fclose($fp); |
| | 477 | } |
| | 478 | |
| | 479 | $doc = new DOMDocument(); |
| | 480 | $doc -> preserveWhiteSpace = false; |
| | 481 | |
| | 482 | if ($doc -> load($filename) === false) return false; |
| | 483 | |
| | 484 | $xpath = new DOMXPath($doc); |
| | 485 | |
| | 486 | // First check if the rule already exists as in that case there is no need to re-add it |
| | 487 | $wordpress_rules = $xpath -> query('/configuration/system.webServer/rewrite/rules/rule[@name=\'wordpress\']'); |
| | 488 | if ($wordpress_rules -> length > 0) return true; |
| | 489 | |
| | 490 | // Check the XPath to the rewrite rule and create XML nodes if they do not exist |
| | 491 | $xmlnodes = $xpath -> query('/configuration/system.webServer/rewrite/rules'); |
| | 492 | if ($xmlnodes -> length > 0){ |
| | 493 | $rules_node = $xmlnodes -> item(0); |
| | 494 | } |
| | 495 | else{ |
| | 496 | $rules_node = $doc -> createElement('rules'); |
| | 497 | |
| | 498 | $xmlnodes = $xpath -> query('/configuration/system.webServer/rewrite'); |
| | 499 | if ($xmlnodes -> length > 0){ |
| | 500 | $rewrite_node = $xmlnodes -> item(0); |
| | 501 | $rewrite_node -> appendChild($rules_node); |
| | 502 | } |
| | 503 | else{ |
| | 504 | $rewrite_node = $doc -> createElement('rewrite'); |
| | 505 | $rewrite_node -> appendChild($rules_node); |
| | 506 | |
| | 507 | $xmlnodes = $xpath -> query('/configuration/system.webServer'); |
| | 508 | if ($xmlnodes -> length > 0){ |
| | 509 | $system_webServer_node = $xmlnodes -> item(0); |
| | 510 | $system_webServer_node -> appendChild($rewrite_node); |
| | 511 | } |
| | 512 | else{ |
| | 513 | $system_webServer_node = $doc -> createElement('system.webServer'); |
| | 514 | $system_webServer_node -> appendChild($rewrite_node); |
| | 515 | |
| | 516 | $xmlnodes = $xpath -> query('/configuration'); |
| | 517 | if ($xmlnodes -> length > 0){ |
| | 518 | $config_node = $xmlnodes -> item(0); |
| | 519 | $config_node -> appendChild($system_webServer_node); |
| | 520 | } |
| | 521 | else{ |
| | 522 | $config_node = $doc -> createElement('configuration'); |
| | 523 | $doc -> appendChild($config_node); |
| | 524 | $config_node -> appendChild($system_webServer_node); |
| | 525 | } |
| | 526 | } |
| | 527 | } |
| | 528 | } |
| | 529 | |
| | 530 | $rule_fragment = $doc -> createDocumentFragment(); |
| | 531 | $rule_fragment -> appendXML($rewrite_rule); |
| | 532 | $rules_node -> appendChild($rule_fragment); |
| | 533 | |
| | 534 | $doc -> formatOutput = true; |
| | 535 | saveDomDocument($doc, $filename); |
| | 536 | |
| | 537 | return true; |
| | 538 | } |
| | 539 | |
| | 540 | /** |
| | 541 | * Saves the XML document into a file |
| | 542 | * |
| | 543 | * @param DOMDocument $doc |
| | 544 | * @param string $filename |
| | 545 | */ |
| | 546 | function saveDomDocument($doc, $filename) |
| | 547 | { |
| | 548 | $config = $doc -> saveXML(); |
| | 549 | $config = preg_replace("/([^\r])\n/", "$1\r\n", $config); |
| | 550 | $fp = fopen($filename, 'w'); |
| | 551 | fwrite($fp, $config); |
| | 552 | fclose($fp); |
| | 553 | } |
| | 554 | |
| | 555 | /** |
| | 556 | * Workaround for Windows bug in is_writable() function |
| | 557 | * |
| | 558 | * @return |
| | 559 | * @param object $path |
| | 560 | */ |
| | 561 | function is__writable($path) { |
| | 562 | //will work in despite of Windows ACLs bug |
| | 563 | //NOTE: use a trailing slash for folders!!! |
| | 564 | //see http://bugs.php.net/bug.php?id=27609 |
| | 565 | //see http://bugs.php.net/bug.php?id=30931 |
| | 566 | |
| | 567 | if ($path{strlen($path)-1}=='/') // recursively return a temporary file path |
| | 568 | return is__writable($path.uniqid(mt_rand()).'.tmp'); |
| | 569 | else if (is_dir($path)) |
| | 570 | return is__writable($path.'/'.uniqid(mt_rand()).'.tmp'); |
| | 571 | // check tmp file for read/write capabilities |
| | 572 | $rm = file_exists($path); |
| | 573 | $f = @fopen($path, 'a'); |
| | 574 | if ($f===false) |
| | 575 | return false; |
| | 576 | fclose($f); |
| | 577 | if (!$rm) |
| | 578 | unlink($path); |
| | 579 | return true; |
| | 580 | } |
| | 581 | ?> |
| | 582 | No newline at end of file |