| [ Index ] |
|
Code source de Serendipity 1.2 |
1 <?php # $Id: serendipity_event_spartacus.php 1816 2007-08-06 10:18:39Z garvinhicking $ 2 3 /************ 4 TODO: 5 6 - Perform Serendipity version checks to only install plugins available for version 7 - Allow fetching files from mirrors / different locations - don't use ViewCVS hack (revision 1.999 dumbness) 8 9 ***********/ 10 11 12 if (IN_serendipity !== true) { 13 die ("Don't hack!"); 14 } 15 16 // Probe for a language include with constants. Still include defines later on, if some constants were missing 17 $probelang = dirname(__FILE__) . '/' . $serendipity['charset'] . 'lang_' . $serendipity['lang'] . '.inc.php'; 18 if (file_exists($probelang)) { 19 include $probelang; 20 } 21 22 include dirname(__FILE__) . '/lang_en.inc.php'; 23 24 class serendipity_event_spartacus extends serendipity_event 25 { 26 var $title = PLUGIN_EVENT_SPARTACUS_NAME; 27 var $purgeCache = false; 28 29 function microtime_float() { 30 list($usec, $sec) = explode(" ", microtime()); 31 return ((float)$usec + (float)$sec); 32 } 33 34 function introspect(&$propbag) 35 { 36 global $serendipity; 37 38 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_NAME); 39 $propbag->add('description', PLUGIN_EVENT_SPARTACUS_DESC); 40 $propbag->add('stackable', false); 41 $propbag->add('author', 'Garvin Hicking'); 42 $propbag->add('version', '2.14'); 43 $propbag->add('requirements', array( 44 'serendipity' => '0.9', 45 'smarty' => '2.6.7', 46 'php' => '4.1.0' 47 )); 48 $propbag->add('event_hooks', array( 49 'backend_plugins_fetchlist' => true, 50 'backend_plugins_fetchplugin' => true, 51 52 'backend_templates_fetchlist' => true, 53 'backend_templates_fetchtemplate' => true, 54 55 'backend_pluginlisting_header' => true, 56 'backend_pluginlisting_header_upgrade' => true 57 )); 58 $propbag->add('groups', array('BACKEND_FEATURES')); 59 $propbag->add('configuration', array('enable_plugins', 'enable_themes', 'mirror_xml', 'mirror_files', 'chown', 'chmod_files', 'chmod_dir')); 60 } 61 62 function generate_content(&$title) { 63 $title = $this->title; 64 } 65 66 function cleanup() { 67 global $serendipity; 68 69 // Purge DB cache 70 serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}pluginlist"); 71 serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}plugincategories"); 72 73 // Purge cached XML files. 74 $files = serendipity_traversePath($serendipity['serendipityPath'] . PATH_SMARTY_COMPILE, '', false, '/package_.+\.xml$/'); 75 76 if (!is_array($files)) { 77 return false; 78 } 79 80 foreach ($files as $file) { 81 $this->outputMSG('notice', sprintf(DELETING_FILE . '<br />', $file['name'])); 82 @unlink($serendipity['serendipityPath'] . PATH_SMARTY_COMPILE . '/' . $file['name']); 83 } 84 } 85 86 function &getMirrors($type = 'xml', $loc = false) { 87 static $mirror = array( 88 'xml' => array( 89 'Netmirror.org', 90 's9y.org' 91 ), 92 93 'files' => array( 94 'Netmirror.org', 95 'SourceForge.net', 96 's9y.org', 97 'BerliOS.de' 98 ) 99 ); 100 101 static $http = array( 102 'xml' => array( 103 'http://netmirror.org/mirror/serendipity/', 104 'http://s9y.org/mirror/' 105 ), 106 107 'files' => array( 108 'http://netmirror.org/mirror/serendipity/', 109 'http://php-blog.cvs.sourceforge.net/*checkout*/php-blog/', 110 'http://s9y.org/mirror/', 111 'http://svn.berlios.de/viewcvs/serendipity/' 112 ), 113 114 'files_health' => array( 115 'http://netmirror.org/' => 'http://netmirror.org/mirror/serendipity/last.txt', 116 'http://php-blog.cvs.sourceforge.net/' => 'http://php-blog.cvs.sourceforge.net/*checkout*/php-blog/serendipity/docs/LICENSE', 117 'http://s9y.org/' => 'http://s9y.org/', 118 'http://svn.berlios.de/' => 'http://svn.berlios.de/viewcvs/serendipity/' 119 ) 120 ); 121 122 if ($loc) { 123 return $http[$type]; 124 } else { 125 return $mirror[$type]; 126 } 127 } 128 129 function introspect_config_item($name, &$propbag) { 130 global $serendipity; 131 132 switch($name) { 133 case 'enable_plugins': 134 $propbag->add('type', 'boolean'); 135 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_ENABLE_PLUGINS); 136 $propbag->add('description', ''); 137 $propbag->add('default', 'true'); 138 break; 139 140 case 'enable_themes': 141 $propbag->add('type', 'boolean'); 142 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_ENABLE_THEMES); 143 $propbag->add('description', ''); 144 $propbag->add('default', 'true'); 145 break; 146 147 case 'chmod_files': 148 $propbag->add('type', 'string'); 149 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_CHMOD); 150 $propbag->add('description', PLUGIN_EVENT_SPARTACUS_CHMOD_DESC); 151 $propbag->add('default', ''); 152 break; 153 154 case 'chmod_dir': 155 $propbag->add('type', 'string'); 156 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_CHMOD_DIR); 157 $propbag->add('description', PLUGIN_EVENT_SPARTACUS_CHMOD_DIR_DESC); 158 $propbag->add('default', ''); 159 break; 160 161 case 'chown': 162 $propbag->add('type', 'string'); 163 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_CHOWN); 164 $propbag->add('description', PLUGIN_EVENT_SPARTACUS_CHOWN_DESC); 165 $propbag->add('default', ''); 166 break; 167 168 case 'mirror_xml': 169 $propbag->add('type', 'select'); 170 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_MIRROR_XML); 171 $propbag->add('description', PLUGIN_EVENT_SPARTACUS_MIRROR_DESC); 172 $propbag->add('select_values', $this->getMirrors('xml')); 173 $propbag->add('default', 0); 174 break; 175 176 case 'mirror_files': 177 $propbag->add('type', 'select'); 178 $propbag->add('name', PLUGIN_EVENT_SPARTACUS_MIRROR_FILES); 179 $propbag->add('description', PLUGIN_EVENT_SPARTACUS_MIRROR_DESC); 180 $propbag->add('select_values', $this->getMirrors('files')); 181 $propbag->add('default', 0); 182 break; 183 184 default: 185 return false; 186 } 187 return true; 188 } 189 190 function GetChildren(&$vals, &$i) { 191 $children = array(); 192 $cnt = sizeof($vals); 193 while (++$i < $cnt) { 194 // compare type 195 switch ($vals[$i]['type']) { 196 case 'cdata': 197 $children[] = $vals[$i]['value']; 198 break; 199 200 case 'complete': 201 $children[] = array( 202 'tag' => $vals[$i]['tag'], 203 'attributes' => $vals[$i]['attributes'], 204 'value' => $vals[$i]['value'] 205 ); 206 break; 207 208 case 'open': 209 $children[] = array( 210 'tag' => $vals[$i]['tag'], 211 'attributes' => $vals[$i]['attributes'], 212 'value' => $vals[$i]['value'], 213 'children' => $this->GetChildren($vals, $i) 214 ); 215 break; 216 217 case 'close': 218 return $children; 219 } 220 } 221 } 222 223 // Create recursive directories; begins at serendipity plugin root folder level 224 function rmkdir($dir, $sub = 'plugins') { 225 global $serendipity; 226 227 $spaths = explode('/', $serendipity['serendipityPath'] . $sub . '/'); 228 $paths = explode('/', $dir); 229 230 $stack = ''; 231 foreach($paths AS $pathid => $path) { 232 $stack .= $path . '/'; 233 234 if ($spaths[$pathid] == $path) { 235 continue; 236 } 237 238 if (!is_dir($stack) && !mkdir($stack)) { 239 return false; 240 } else { 241 $this->fileperm($stack, true); 242 } 243 } 244 245 return true; 246 } 247 248 // Apply file permission settings. 249 function fileperm($stack, $is_dir) { 250 $chmod_dir = intval($this->get_config('chmod_dir'), 8); 251 $chmod_files = intval($this->get_config('chmod_files'), 8); 252 $chown = $this->get_config('chown'); 253 254 if ($is_dir && !empty($chmod_dir) && function_exists('chmod')) { 255 @chmod($stack, $chmod_dir); // Always ensure directory traversal. 256 } 257 258 if (!$is_dir && !empty($chmod_files) && function_exists('chmod')) { 259 @chmod($stack, $chmod_files); // Always ensure directory traversal. 260 } 261 262 if (!empty($chown) && function_exists('chown')) { 263 $own = explode('.', $chown); 264 if (isset($own[1])) { 265 @chgrp($stack, $own[1]); 266 } 267 @chown($stack, $own[0]); 268 } 269 270 271 return true; 272 } 273 274 function outputMSG($status, $msg) { 275 switch($status) { 276 case 'notice': 277 echo '<div class="serendipityAdminMsgNotice"><img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="' . serendipity_getTemplateFile('admin/img/admin_msg_note.png') . '" alt="" />' . $msg . '</div>' . "\n"; 278 break; 279 280 case 'error': 281 echo '<div class="serendipityAdminMsgError"><img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="' . serendipity_getTemplateFile('admin/img/admin_msg_error.png') . '" alt="" />' . $msg . '</div>' . "\n"; 282 break; 283 284 default: 285 case 'success': 286 echo '<div class="serendipityAdminMsgSuccess"><img style="height: 22px; width: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="' . serendipity_getTemplateFile('admin/img/admin_msg_success.png') . '" alt="" />' . $msg . '</div>' . "\n"; 287 break; 288 } 289 } 290 291 function &fetchfile($url, $target, $cacheTimeout = 0, $decode_utf8 = false, $sub = 'plugins') { 292 static $error = false; 293 294 // Fix double URL strings. 295 $url = str_replace('http:/', 'http://', str_replace('//', '/', $url)); 296 297 // --JAM: Get the URL's IP in the most error-free way possible 298 $url_parts = @parse_url($url); 299 $url_hostname = 'localhost'; 300 if (is_array($url_parts)) { 301 $url_hostname = $url_parts['host']; 302 } 303 $url_ip = gethostbyname($url_hostname); 304 305 $this->outputMSG('notice', sprintf(PLUGIN_EVENT_SPARTACUS_FETCHING, '<a href="' . $url . '">' . basename($url) . '</a>')); 306 307 if (file_exists($target) && filesize($target) > 0 && filemtime($target) >= (time()-$cacheTimeout)) { 308 $data = file_get_contents($target); 309 $this->outputMSG('success', sprintf(PLUGIN_EVENT_SPARTACUS_FETCHED_BYTES_CACHE, strlen($data), $target)); 310 } else { 311 require_once S9Y_PEAR_PATH . 'HTTP/Request.php'; 312 $options = array(); 313 serendipity_plugin_api::hook_event('backend_http_request', $options, 'spartacus'); 314 serendipity_request_start(); 315 316 $req = &new HTTP_Request($url, $options); 317 318 if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') { 319 $resolved_url = $url . ' (IP ' . $url_ip . ')'; 320 $this->outputMSG('error', sprintf(PLUGIN_EVENT_SPARTACUS_FETCHERROR, $resolved_url)); 321 //--JAM: START FIREWALL DETECTION 322 if ($req->getResponseCode()) { 323 $this->outputMSG('error', sprintf(PLUGIN_EVENT_SPARTACUS_REPOSITORY_ERROR, $req->getResponseCode())); 324 } 325 $check_health = true; 326 if (function_exists('curl_init')) { 327 $this->outputMSG('notice', PLUGIN_EVENT_SPARTACUS_TRYCURL); 328 $curl_handle=curl_init(); 329 curl_setopt($curl_handle, CURLOPT_URL, $url); 330 curl_setopt($curl_handle, CURLOPT_HEADER, 0); 331 $data = curl_exec($curl_handle); 332 curl_close($curl_handle); 333 if ($curl_result) { 334 $check_health = false; 335 } else { 336 $this->outputMSG('error', PLUGIN_EVENT_SPARTACUS_CURLFAIL . "\n"); 337 } 338 } 339 } 340 if ($check_health) { 341 /*--JAM: Useful for later, when we have a health monitor for SPARTACUS 342 $propbag = new serendipity_property_bag; 343 $this->introspect($propbag); 344 $health_url = 'http://spartacus.s9y.org/spartacus_health.php?version=' . $propbag->get('version'); 345 */ 346 // Garvin: Temporary health. Better than nothing, eh? 347 $health_url = $url; 348 $matches = array(); 349 preg_match('#http://[^/]*/#', $url, $matches); 350 if ($matches[0]) { 351 $health_url = $matches[0]; 352 } 353 354 $mirrors = $this->getMirrors('files_health', true); 355 $health_url = $mirrors[$health_url]; 356 $this->outputMSG('notice', sprintf(PLUGIN_EVENT_SPARTACUS_HEALTHCHECK, $health_url)); 357 358 $health_options = $options; 359 serendipity_plugin_api::hook_event('backend_http_request', $health_options, 'spartacus_health'); 360 $health_req = &new HTTP_Request($health_url, $health_options); 361 $health_result = $health_req->sendRequest(); 362 if (PEAR::isError($health_result)) { 363 $fp = @fsockopen('www.google.com', 80, $errno, $errstr); 364 if (!$fp) { 365 $this->outputMSG('error', sprintf(PLUGIN_EVENT_SPARTACUS_HEALTHBLOCKED, $errno, $errstr)); 366 } else { 367 $this->outputMSG('error', PLUGIN_EVENT_SPARTACUS_HEALTHDOWN); 368 $this->outputMSG('notice', sprintf(PLUGIN_EVENT_SPARTACUS_HEALTHLINK, $health_url)); 369 fclose($fp); 370 } 371 } else if ($health_req->getResponseCode() != '200') { 372 $this->outputMSG('error', sprintf(PLUGIN_EVENT_SPARTACUS_HEALTHERROR, $health_req->getResponseCode())); 373 $this->outputMSG('notice', sprintf(PLUGIN_EVENT_SPARTACUS_HEALTHLINK, $health_url)); 374 } else { 375 $this->outputMSG('error', PLUGIN_EVENT_SPARTACUS_HEALTFIREWALLED); 376 //--JAM: Parse response and display it. 377 } 378 //--JAM: END FIREWALL DETECTION 379 if (file_exists($target) && filesize($target) > 0) { 380 $data = file_get_contents($target); 381 $this->outputMSG('success', sprintf(PLUGIN_EVENT_SPARTACUS_FETCHED_BYTES_CACHE, strlen($data), $target)); 382 echo "<br />\n"; 383 } 384 } else { 385 // Fetch file 386 if (!$data) { 387 $data = $req->getResponseBody(); 388 } 389 $this->outputMSG('success', sprintf(PLUGIN_EVENT_SPARTACUS_FETCHED_BYTES_URL, strlen($data), $target)); 390 391 $tdir = dirname($target); 392 if (!is_dir($tdir) && !$this->rmkdir($tdir, $sub)) { 393 $this->outputMSG('error', sprintf(FILE_WRITE_ERROR, $tdir)); 394 return $error; 395 } 396 397 $fp = @fopen($target, 'w'); 398 399 if (!$fp) { 400 $this->outputMSG('error', sprintf(FILE_WRITE_ERROR, $target)); 401 return $error; 402 } 403 404 if ($decode_utf8) { 405 $data = str_replace('<?xml version="1.0" encoding="UTF-8" ?>', '<?xml version="1.0" encoding="' . LANG_CHARSET . '" ?>', $data); 406 $this->decode($data, true); 407 } 408 409 fwrite($fp, $data); 410 fclose($fp); 411 412 $this->fileperm($target, false); 413 414 $this->outputMSG('success', PLUGIN_EVENT_SPARTACUS_FETCHED_DONE); 415 $this->purgeCache = true; 416 } 417 serendipity_request_end(); 418 } 419 420 return $data; 421 } 422 423 function decode(&$data, $force = false) { 424 // xml_parser_* functions to recoding from ISO-8859-1/UTF-8 425 if ($force === false && (LANG_CHARSET == 'ISO-8859-1' || LANG_CHARSET == 'UTF-8')) { 426 return true; 427 } 428 429 switch (strtolower(LANG_CHARSET)) { 430 case 'utf-8': 431 // The XML file is UTF-8 format. No changes needed. 432 break; 433 434 case 'iso-8859-1': 435 $data = utf8_decode($data); 436 break; 437 438 default: 439 if (function_exists('iconv')) { 440 $data = iconv('UTF-8', LANG_CHARSET, $data); 441 } elseif (function_exists('recode')) { 442 $data = recode('utf-8..' . LANG_CHARSET, $data); 443 } 444 break; 445 } 446 } 447 448 function &fetchOnline($type, $no_cache = false) { 449 global $serendipity; 450 451 switch($type) { 452 // Sanitize to not fetch other URLs 453 default: 454 case 'event': 455 $url_type = 'event'; 456 $i18n = true; 457 break; 458 459 case 'sidebar': 460 $url_type = 'sidebar'; 461 $i18n = true; 462 break; 463 464 case 'template': 465 $url_type = 'template'; 466 $i18n = false; 467 break; 468 } 469 470 if (!$i18n) { 471 $lang = ''; 472 } elseif (isset($serendipity['languages'][$serendipity['lang']])) { 473 $lang = '_' . $serendipity['lang']; 474 } else { 475 $lang = '_en'; 476 } 477 478 $mirrors = $this->getMirrors('xml', true); 479 $mirror = $mirrors[$this->get_config('mirror_xml', 0)]; 480 481 $url = $mirror . '/package_' . $url_type . $lang . '.xml'; 482 $cacheTimeout = 60*60*12; // XML file is cached for half a day 483 $target = $serendipity['serendipityPath'] . PATH_SMARTY_COMPILE . '/package_' . $url_type . $lang . '.xml'; 484 485 $xml = $this->fetchfile($url, $target, $cacheTimeout, true); 486 echo '<br /><br />'; 487 488 $new_crc = md5($xml); 489 $last_crc = $this->get_config('last_crc_' . $url_type); 490 491 if (!$no_cache && !$this->purgeCache && $last_crc == $new_crc) { 492 $out = 'cached'; 493 return $out; 494 } 495 496 // XML functions 497 $xml_string = '<?xml version="1.0" encoding="UTF-8" ?>'; 498 if (preg_match('@(<\?xml.+\?>)@imsU', $xml, $xml_head)) { 499 $xml_string = $xml_head[1]; 500 } 501 502 $encoding = 'UTF-8'; 503 if (preg_match('@encoding="([^"]+)"@', $xml_string, $xml_encoding)) { 504 $encoding = $xml_encoding[1]; 505 } 506 507 preg_match_all('@(<package version="[^"]+">.*</package>)@imsU', $xml, $xml_matches); 508 if (!is_array($xml_matches)) { 509 $out = 'cached'; 510 return $out; 511 } 512 513 $i = 0; 514 $tree = array(); 515 $tree[$i] = array( 516 'tag' => 'packages', 517 'attributes' => '', 518 'value' => '', 519 'children' => array() 520 ); 521 522 foreach($xml_matches[0] as $xml_index => $xml_package) { 523 $i = 0; 524 525 switch(strtolower($encoding)) { 526 case 'iso-8859-1': 527 case 'utf-8': 528 $p = xml_parser_create($encoding); 529 break; 530 531 default: 532 $p = xml_parser_create(''); 533 } 534 535 xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0); 536 @xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, LANG_CHARSET); 537 $xml_package = $xml_string . "\n" . $xml_package; 538 xml_parse_into_struct($p, $xml_package, $vals); 539 xml_parser_free($p); 540 $tree[0]['children'][] = array( 541 'tag' => $vals[$i]['tag'], 542 'attributes' => $vals[$i]['attributes'], 543 'value' => $vals[$i]['value'], 544 'children' => $this->GetChildren($vals, $i) 545 ); 546 unset($vals); 547 } 548 549 $this->set_config('last_crc_' . $url_type, $new_crc); 550 551 return $tree; 552 } 553 554 function &getCachedPlugins(&$plugins, $type) { 555 global $serendipity; 556 static $pluginlist = null; 557 558 if ($pluginlist === null) { 559 $pluginlist = array(); 560 $data = serendipity_db_query("SELECT p.*, 561 pc.category 562 FROM {$serendipity['dbPrefix']}pluginlist AS p 563 LEFT OUTER JOIN {$serendipity['dbPrefix']}plugincategories AS pc 564 ON pc.class_name = p.class_name 565 WHERE p.pluginlocation = 'Spartacus' AND 566 p.plugintype = '" . serendipity_db_escape_string($type) . "'"); 567 568 if (is_array($data)) { 569 foreach($data AS $p) { 570 $p['stackable'] = serendipity_db_bool($p['stackable']); 571 $p['requirements'] = unserialize($p['requirements']); 572 $this->checkPlugin($p, $plugins, $p['plugintype']); 573 574 if (!isset($pluginlist[$p['plugin_file']])) { 575 $pluginlist[$p['plugin_file']] = $p; 576 } 577 578 $pluginlist[$p['plugin_file']]['groups'][] = $p['category']; 579 } 580 } 581 } 582 583 return $pluginlist; 584 } 585 586 function checkPlugin(&$data, &$plugins, $type) { 587 $installable = true; 588 $upgradeLink = ''; 589 if (in_array($data['class_name'], $plugins)) { 590 $infoplugin =& serendipity_plugin_api::load_plugin($data['class_name']); 591 if (is_object($infoplugin)) { 592 $bag = new serendipity_property_bag; 593 $infoplugin->introspect($bag); 594 if ($bag->get('version') == $data['version']) { 595 $installable = false; 596 } elseif (version_compare($bag->get('version'), $data['version'], '<')) { 597 $data['upgradable'] = true; 598 $data['upgrade_version'] = $data['version']; 599 $data['version'] = $bag->get('version'); 600 $upgradeLink = '&serendipity[spartacus_upgrade]=true'; 601 } 602 } 603 } 604 605 $data['installable'] = $installable; 606 $data['pluginPath'] = 'online_repository'; 607 $data['pluginlocation'] = 'Spartacus'; 608 $data['plugintype'] = $type; 609 $data['customURI'] = '&serendipity[spartacus_fetch]=' . $type . $upgradeLink; 610 611 return true; 612 } 613 614 function &buildList(&$tree, $type) { 615 $plugins = serendipity_plugin_api::get_installed_plugins(); 616 617 if ($tree === 'cached') { 618 return $this->getCachedPlugins($plugins, $type); 619 } 620 621 $pluginstack = array(); 622 $i = 0; 623 624 $this->checkArray($tree); 625 626 foreach($tree[0]['children'] AS $idx => $subtree) { 627 if ($subtree['tag'] == 'package') { 628 $i++; 629 630 foreach($subtree['children'] AS $child => $childtree) { 631 switch($childtree['tag']) { 632 case 'name': 633 $pluginstack[$i]['plugin_class'] = 634 $pluginstack[$i]['plugin_file'] = 635 $pluginstack[$i]['class_name'] = 636 $pluginstack[$i]['true_name'] = $childtree['value']; 637 break; 638 639 case 'summary': 640 $pluginstack[$i]['name'] = $childtree['value']; 641 break; 642 643 case 'groups': 644 $pluginstack[$i]['groups'] = explode(',', $childtree['value']); 645 break; 646 647 case 'description': 648 $pluginstack[$i]['description'] = $childtree['value']; 649 break; 650 651 case 'release': 652 $pluginstack[$i]['version'] = $childtree['children'][0]['value']; 653 654 $pluginstack[$i]['requirements'] = array( 655 'serendipity' => '', 656 'php' => '', 657 'smarty' => '' 658 ); 659 660 foreach((array)$childtree['children'] AS $relInfo) { 661 if ($relInfo['tag'] == 'requirements:s9yVersion') { 662 $pluginstack[$i]['requirements']['serendipity'] = $relInfo['value']; 663 } 664 } 665 break; 666 667 case 'maintainers': 668 $pluginstack[$i]['author'] = $childtree['children'][0]['children'][0]['value']; // I dig my PHP arrays ;-) 669 break; 670 } 671 } 672 673 $this->checkPlugin($pluginstack[$i], $plugins, $type); 674 675 serendipity_plugin_api::setPluginInfo($pluginstack[$i], $pluginstack[$i]['plugin_file'], $i, $i, 'Spartacus'); 676 // Remove the temporary $i reference, as the array should be associative 677 $plugname = $pluginstack[$i]['true_name']; 678 $pluginstack[$plugname] = $pluginstack[$i]; 679 unset($pluginstack[$i]); 680 } 681 } 682 683 return $pluginstack; 684 } 685 686 function checkArray(&$tree) { 687 if (!is_array($tree) || !is_array($tree[0]['children'])) { 688 echo "DEBUG: The XML file could not be successfully parsed. Download or caching error. Please try again later or switch your XML/File mirror location. You can also try to go to the plugin configuration of the Spartacus Plugin and simply click on 'Save' - this will purge all cached XML files and try to download it again.<div style='display: none'>" . print_r($tree, true) . "</div><br />\n"; 689 } 690 } 691 692 function &buildTemplateList(&$tree) { 693 $pluginstack = array(); 694 $i = 0; 695 696 $mirrors = $this->getMirrors('files', true); 697 $mirror = $mirrors[$this->get_config('mirror_files', 0)]; 698 699 $this->checkArray($tree); 700 701 foreach($tree[0]['children'] AS $idx => $subtree) { 702 if ($subtree['tag'] == 'package') { 703 $i++; 704 705 foreach($subtree['children'] AS $child => $childtree) { 706 switch($childtree['tag']) { 707 case 'name': 708 $pluginstack[$i]['name'] = $childtree['value']; 709 break; 710 711 case 'summary': 712 $pluginstack[$i]['summary'] = $childtree['value']; 713 break; 714 715 case 'template': 716 $pluginstack[$i]['template'] = $childtree['value']; 717 break; 718 719 case 'description': 720 $pluginstack[$i]['description'] = $childtree['value']; 721 break; 722 723 case 'release': 724 $pluginstack[$i]['version'] = $childtree['children'][0]['value']; 725 726 $pluginstack[$i]['requirements'] = array( 727 'serendipity' => '', 728 'php' => '', 729 'smarty' => '' 730 ); 731 732 foreach((array)$childtree['children'] AS $relInfo) { 733 if ($relInfo['tag'] == 'requirements:s9yVersion') { 734 $pluginstack[$i]['requirements']['serendipity'] = $relInfo['value']; 735 } 736 737 if ($relInfo['tag'] == 'date') { 738 $pluginstack[$i]['date'] = $relInfo['value']; 739 } 740 741 } 742 743 $pluginstack[$i]['require serendipity'] = $pluginstack[$i]['requirements']['serendipity']; 744 break; 745 746 case 'maintainers': 747 $pluginstack[$i]['author'] = $childtree['children'][0]['children'][0]['value']; // I dig my PHP arrays ;-) 748 break; 749 } 750 } 751 752 $plugname = $pluginstack[$i]['template']; 753 $pluginstack[$i]['previewURL'] = $mirror . '/additional_themes/' . $plugname . '/preview.png?rev=1.9999'; 754 $pluginstack[$i]['preview_fullsizeURL'] = $mirror . '/additional_themes/' . $plugname . '/preview_fullsize.jpg?rev=1.9999'; 755 $pluginstack[$i]['customURI'] = '&serendipity[spartacus_fetch]=' . $plugname; 756 $pluginstack[$i]['customIcon'] = '_spartacus'; 757 758 // Remove the temporary $i reference, as the array should be associative 759 $pluginstack[$plugname] = $pluginstack[$i]; 760 unset($pluginstack[$i]); 761 } 762 } 763 764 return $pluginstack; 765 } 766 767 function download(&$tree, $plugin_to_install, $sub = 'plugins') { 768 global $serendipity; 769 770 switch($sub) { 771 case 'plugins': 772 default: 773 $sfloc = 'additional_plugins'; 774 break; 775 776 case 'templates': 777 $sfloc = 'additional_themes'; 778 break; 779 } 780 781 $pdir = $serendipity['serendipityPath'] . '/' . $sub . '/'; 782 if (!is_writable($pdir)) { 783 $this->outputMSG('error', sprintf(DIRECTORY_WRITE_ERROR, $pdir)); 784 return false; 785 } 786 787 $files = array(); 788 $found = false; 789 790 $this->checkArray($tree); 791 792 foreach($tree[0]['children'] AS $idx => $subtree) { 793 if ($subtree['tag'] != 'package') { 794 continue; 795 } 796 797 foreach($subtree['children'] AS $child => $childtree) { 798 if ($sub == 'templates' && $childtree['tag'] == 'template' && $childtree['value'] == $plugin_to_install) { 799 $found = true; 800 } elseif ($sub == 'plugins' && $childtree['tag'] == 'name' && $childtree['value'] == $plugin_to_install) { 801 $found = true; 802 } 803 804 if (!$found || $childtree['tag'] != 'release') { 805 continue; 806 } 807 808 foreach($childtree['children'] AS $child2 => $childtree2) { 809 if ($childtree2['tag'] != 'serendipityFilelist') { 810 continue; 811 } 812 813 foreach($childtree2['children'] AS $idx => $_files) { 814 if ($_files['tag'] == 'file' && !empty($_files['value'])) { 815 $files[] = $_files['value']; 816 } 817 } 818 } 819 820 $found = false; 821 } 822 } 823 824 if (count($files) == 0) { 825 echo "DEBUG: ERROR: XML tree did not contain requested plugin:<br />\n"; 826 print_r($tree); 827 } 828 829 $mirrors = $this->getMirrors('files', true); 830 $mirror = $mirrors[$this->get_config('mirror_files', 0)]; 831 832 foreach($files AS $file) { 833 $url = $mirror . '/' . $sfloc . '/' . $file . '?rev=1.9999'; 834 $target = $pdir . $file; 835 @mkdir($pdir . $plugin_to_install); 836 $this->fileperm($pdir . $plugin_to_install, true); 837 $this->fetchfile($url, $target); 838 if (!isset($baseDir)) { 839 $baseDirs = explode('/', $file); 840 $baseDir = $baseDirs[0]; 841 } 842 } 843 844 if (isset($baseDir)) { 845 return $baseDir; 846 } 847 } 848 849 function event_hook($event, &$bag, &$eventData) { 850 global $serendipity; 851 852 $hooks = &$bag->get('event_hooks'); 853 854 if (isset($hooks[$event])) { 855 switch($event) { 856 case 'backend_pluginlisting_header': 857 if (serendipity_db_bool($this->get_config('enable_plugins'))) { 858 echo '<br /><div id="upgrade_notice" class="serendipityAdminMsgSuccess">'; 859 echo '<a href="?serendipity[adminModule]=plugins&serendipity[adminAction]=addnew&serendipity[only_group]=UPGRADE" class="serendipityIconLink upgrade_sidebar"><img src="' . serendipity_getTemplateFile('admin/img/upgrade_now.png') . '" style="border: 0px none ; vertical-align: middle; display: inline;" alt="" />' . PLUGIN_EVENT_SPARTACUS_CHECK_SIDEBAR . '</a> '; 860 echo '<a href="?serendipity[adminModule]=plugins&serendipity[adminAction]=addnew&serendipity[only_group]=UPGRADE&serendipity[type]=event" class="serendipityIconLink upgrade_event"><img src="' . serendipity_getTemplateFile('admin/img/upgrade_now.png') . '" style="border: 0px none ; vertical-align: middle; display: inline;" alt="" />' . PLUGIN_EVENT_SPARTACUS_CHECK_EVENT . '</a> '; 861 echo '</div>'; 862 } 863 864 return true; 865 break; 866 867 case 'backend_pluginlisting_header_upgrade': 868 echo '<em>' . PLUGIN_EVENT_SPARTACUS_CHECK_HINT . '</em><br />'; 869 870 return true; 871 break; 872 873 case 'backend_templates_fetchlist': 874 if (serendipity_db_bool($this->get_config('enable_themes'))) { 875 $eventData = $this->buildTemplateList($this->fetchOnline('template', true), 'template'); 876 } 877 878 return true; 879 break; 880 881 case 'backend_templates_fetchtemplate': 882 if (serendipity_db_bool($this->get_config('enable_themes'))) { 883 if (!empty($eventData['GET']['spartacus_fetch'])) { 884 $this->download( 885 $this->fetchOnline('template', true), 886 $eventData['GET']['theme'], 887 'templates' 888 ); 889 } 890 } 891 892 return false; 893 break; 894 895 case 'backend_plugins_fetchlist': 896 if (serendipity_db_bool($this->get_config('enable_plugins'))) { 897 $type = (isset($serendipity['GET']['type']) ? $serendipity['GET']['type'] : 'sidebar'); 898 899 $eventData = array( 900 'pluginstack' => $this->buildList($this->fetchOnline($type), $type), 901 'errorstack' => array(), 902 'upgradeURI' => '&serendipity[spartacus_upgrade]=true', 903 'baseURI' => '&serendipity[spartacus_fetch]=' . $type 904 ); 905 } 906 907 return true; 908 break; 909 910 case 'backend_plugins_fetchplugin': 911 if (serendipity_db_bool($this->get_config('enable_plugins'))) { 912 if (!empty($eventData['GET']['spartacus_fetch'])) { 913 $baseDir = $this->download($this->fetchOnline($eventData['GET']['spartacus_fetch'], true), $eventData['GET']['install_plugin']); 914 915 if ($baseDir === false) { 916 $eventData['install'] = false; 917 } elseif (!empty($baseDir)) { 918 $eventData['GET']['pluginPath'] = $baseDir; 919 } else { 920 $eventData['GET']['pluginPath'] = $eventData['GET']['install_plugin']; 921 } 922 923 if ($eventData['GET']['spartacus_upgrade']) { 924 $eventData['install'] = false; 925 } 926 } 927 } 928 929 return false; 930 break; 931 932 default: 933 return false; 934 break; 935 } 936 } else { 937 return false; 938 } 939 } 940 } 941 942 /* vim: set sts=4 ts=4 expandtab : */
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sat Nov 24 09:00:37 2007 | par Balluche grâce à PHPXref 0.7 |
|