1<?php 2/* 3 * e107 website system 4 * 5 * Copyright (C) 2008-2013 e107 Inc (e107.org) 6 * Released under the terms and conditions of the 7 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) 8 * 9 */ 10 11if (!defined('e107_INIT')) { exit; } 12 13/** 14 * 15 * @package e107 16 * @category e107_handlers 17 * @author e107inc 18 * 19 * Plugin administration handler 20 */ 21 22 23e107::coreLan('plugin', true); 24 25 26// new in v2.1.5 - optimized for speed. 27class e_plugin 28{ 29 30 31 protected $_data = array(); 32 protected $_ids = array(); 33 protected $_installed = array(); 34 protected $_addons = array(); 35 protected $_plugdir = null; // the currently loaded plugin 36 37 const CACHETIME = 120; // 2 hours 38 const CACHETAG = "Meta_plugin"; 39 40 41 protected $_addon_types = array( 42 'e_admin', 43 'e_bb', 44 'e_cron', 45 'e_notify', 46 'e_linkgen', 47 'e_list', 48 49 'e_meta', // @Deprecated 50 'e_emailprint', 51 'e_print', // new v2.2 52 'e_frontpage', 53 'e_latest', /* @deprecated - see e_dashboard */ 54 'e_status', /* @deprecated - see e_dashboard */ 55 'e_menu', 56 'e_search', 57 'e_shortcode', 58 'e_module', 59 'e_event', 60 'e_comment', 61 'e_sql', 62 'e_dashboard', // Admin Front-Page addon. 63 // 'e_userprofile', @deprecated @see e_user 64 'e_header', // loaded in header prior to javascript manager. 65 'e_footer', // Loaded in footer prior to javascript manager. 66 // 'e_userinfo', @deprecated @see e_user 67 'e_tagwords', 68 'e_url', // simple mod-rewrite. 69 'e_mailout', 70 'e_sitelink', // sitelinks generator. 71 'e_tohtml', /* @deprecated - use e_parse */ 72 'e_featurebox', 73 'e_parse', 74 'e_related', 75 'e_rss', 76 'e_upload', 77 'e_user', 78 'e_library', // For third-party libraries are defined by plugins/themes. 79 'e_gsitemap', 80 'e_output', //hook into all pages at the end (after closing </html>) 81 ); 82 83 protected $_core_plugins = array( 84 "_blank","admin_menu","banner","blogcalendar_menu", 85 "chatbox_menu", "clock_menu","comment_menu", 86 "contact", "download", "featurebox", "forum","gallery", 87 "gsitemap","import", "linkwords", "list_new", "log", "login_menu", 88 "metaweblog", "newforumposts_main", "news", "newsfeed", 89 "newsletter","online", "page", "pm","poll", 90 "rss_menu","search_menu","siteinfo", "social", "tagcloud", "tinymce4", 91 "trackback","tree_menu","user" 92 ); 93 94 95 96 private $_accepted_categories = array('settings'=>EPL_ADLAN_147, 'users'=>EPL_ADLAN_148, 'content'=>EPL_ADLAN_149,'tools'=> EPL_ADLAN_150, 'manage'=>EPL_ADLAN_151,'misc'=> EPL_ADLAN_152, 'menu'=>EPL_ADLAN_153, 'about'=> EPL_ADLAN_154); 97 98 function __construct() 99 { 100 101 $this->_init(); 102 103 if(empty($this->_ids) ) 104 { 105 // e107::getDebug()->log("Running e_plugin::_initIDs()"); 106 // e107::getDebug()->log(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)); 107 $this->_initIDs(); 108 } 109 110 } 111 112 /** 113 * Load specified plugin data. 114 * @param string $plugdir 115 * @return e_plugin 116 */ 117 public function load($plugdir) 118 { 119 $this->_plugdir = (string) $plugdir; 120 121 return $this; 122 } 123 124 public function getCategoryList() 125 { 126 return $this->_accepted_categories; 127 } 128 129 public function getDetected() 130 { 131 return array_keys($this->_data); 132 } 133 134 public function getCorePluginList() 135 { 136 return $this->_core_plugins; 137 } 138 139 public function clearCache() 140 { 141 $this->_installed = array(); 142 $this->_addons = array(); 143 e107::setRegistry('core/e107/addons/e_url'); 144 145 $this->_init(true); 146 $this->_initIDs(); 147 return $this; 148 } 149 150 public function getInstalledWysiwygEditors() 151 { 152 $result = array(); 153 154 foreach(array_keys($this->_installed) as $k) 155 { 156 $pl = new e_plugin(); 157 $pl->load($k); 158 $keys = $pl->getKeywords(); 159 // check the keywords 160 if (is_array($keys) && in_array('wysiwyg', $keys['word'])) 161 { 162 if (in_array('default', $keys['word'])) 163 { 164 // add "default" editor to the beginning of the array 165 $result = array_merge(array($k => $pl->getName()), $result); 166 } 167 else 168 { 169 // add all "wysiwyg" editors to the array 170 $result[$k] = $pl->getName(); 171 } 172 } 173 174 } 175 return $result; 176 } 177 178 public function getInstalled() 179 { 180 return $this->_installed; 181 } 182 183 public function getId() 184 { 185 if(empty($this->_plugdir)) 186 { 187 e107::getDebug()->log("\$this->_plugdir is empty ".__FILE__." ". __CLASS__ ."::".__METHOD__); 188 } 189 190 if(isset($this->_ids[$this->_plugdir])) 191 { 192 return $this->_ids[$this->_plugdir]; 193 } 194 195 return false; 196 } 197 198 199 public function getCompat() 200 { 201 202 if(isset($this->_data[$this->_plugdir]['@attributes']['compatibility'])) 203 { 204 return $this->_data[$this->_plugdir]['@attributes']['compatibility']; 205 } 206 207 return false; 208 } 209 210 public function getInstallRequired() 211 { 212 213 if(empty($this->_plugdir)) 214 { 215 e107::getDebug()->log("\$this->_plugdir is empty ".__FILE__." ". __CLASS__ ."::".__METHOD__); 216 } 217 218 if(isset($this->_data[$this->_plugdir]['@attributes']['installRequired'])) 219 { 220 return ($this->_data[$this->_plugdir]['@attributes']['installRequired'] === 'false') ? false : true; 221 } 222 223 return false; 224 } 225 226 227 228 public function getVersion() 229 { 230 if(empty($this->_plugdir)) 231 { 232 e107::getDebug()->log("\$this->_plugdir is empty ".__FILE__." ". __CLASS__ ."::".__METHOD__); 233 } 234 235 if(isset($this->_data[$this->_plugdir]['@attributes']['version'])) 236 { 237 return $this->_data[$this->_plugdir]['@attributes']['version']; 238 } 239 240 return false; 241 } 242 243 244 245 public function getDate() 246 { 247 if(isset($this->_data[$this->_plugdir]['@attributes']['date'])) 248 { 249 return $this->_data[$this->_plugdir]['@attributes']['date']; 250 } 251 252 return false; 253 } 254 255 256 public function getAuthor($type='name') 257 { 258 if(!isset($this->_data[$this->_plugdir]['author']['@attributes'][$type])) 259 { 260 return false; 261 } 262 263 return $this->_data[$this->_plugdir]['author']['@attributes'][$type]; 264 265 } 266 267 268 269 public function getCategory() 270 { 271 if(!isset($this->_data[$this->_plugdir]['category'])) 272 { 273 return false; 274 } 275 276 return (string) $this->_data[$this->_plugdir]['category']; 277 278 } 279 280 public function getKeywords() 281 { 282 if(!isset($this->_data[$this->_plugdir]['keywords'])) 283 { 284 return false; 285 } 286 287 return $this->_data[$this->_plugdir]['keywords']; 288 289 } 290 291 292 public function getDescription() 293 { 294 if(!isset($this->_data[$this->_plugdir]['description']['@value'])) 295 { 296 return false; 297 } 298 299 return $this->_data[$this->_plugdir]['description']['@value']; 300 301 } 302 303 304 public function getIcon($size = 16,$opt='') 305 { 306 307 308 309 $link = $this->_data[$this->_plugdir]['adminLinks']['link'][0]['@attributes']; 310 311 $k = array(16 => 'iconSmall', 24 => 'icon', 32 => 'icon', 128=>'icon128'); 312 $def = array(16 => E_16_PLUGIN, 24 => E_24_PLUGIN, 32 => E_32_PLUGIN); 313 314 $key = $k[$size]; 315 316 if(empty($link[$key])) 317 { 318 return $def[$size]; 319 } 320 321 $caption = $this->getName(); 322 323 if($opt === 'path') 324 { 325 return e107::getParser()->createConstants(e_PLUGIN_ABS.$this->_plugdir.'/'.$link[$key]); 326 } 327 328 return "<img src='".e_PLUGIN.$this->_plugdir.'/'.$link[$key] ."' alt=\"".$caption."\" class='icon S".$size."' />"; 329 } 330 331 332 333 public function getAdminCaption() 334 { 335 $att = $this->_data[$this->_plugdir]['adminLinks']['link'][0]['@attributes']; 336 337 if(empty($att['description'])) 338 { 339 return false; 340 } 341 342 return str_replace("'", '', e107::getParser()->toHTML($att['description'], FALSE, 'defs, emotes_off')); 343 344 } 345 346 347 348 public function getAdminUrl() 349 { 350 if(!empty($this->_data[$this->_plugdir]['administration']['configFile'])) 351 { 352 return e_PLUGIN_ABS.$this->_plugdir.'/'.$this->_data[$this->_plugdir]['administration']['configFile']; 353 } 354 355 return false; 356 357 } 358 359 360 /** 361 * Check if the current plugin is a legacy plugin which doesn't use plugin.xml 362 * @return mixed 363 */ 364 public function isLegacy() 365 { 366 if(empty($this->_plugdir)) 367 { 368 e107::getDebug()->log("\$this->_plugdir is empty ".__FILE__." ". __CLASS__ ."::".__METHOD__); 369 } 370 371 return $this->_data[$this->_plugdir]['legacy']; 372 } 373 374 375 /** 376 * Check if the current plugin has a global lan file 377 * @return mixed 378 */ 379 public function hasLanGlobal() 380 { 381 if(empty($this->_plugdir)) 382 { 383 e107::getDebug()->log("\$this->_plugdir is empty ".__FILE__." ". __CLASS__ ."::".__METHOD__); 384 return null; 385 } 386 387 return isset($this->_data[$this->_plugdir]['lan']) ? $this->_data[$this->_plugdir]['lan'] : false; 388 } 389 390 391 function setInstalled($plug,$version) 392 { 393 $this->_installed[$plug] = $version; 394 395 return $this; 396 } 397 398 399 400 401 402 /** 403 * Check if the currently loaded plugin is installed 404 * @return mixed 405 */ 406 public function isInstalled() 407 { 408 if(empty($this->_plugdir)) 409 { 410 e107::getDebug()->log("\$this->_plugdir is empty ".__FILE__." ". __CLASS__ ."::".__METHOD__); 411 } 412 413 return in_array($this->_plugdir, array_keys($this->_installed)); 414 } 415 416 417 /** 418 * Check if the currently loaded plugin's addon has errors. 419 * @param string e_xxxx addon 420 * @return mixed 421 */ 422 public function getAddonErrors($e_xxx) 423 { 424 425 if(substr($e_xxx, -3) === '.sc') 426 { 427 $filename = $e_xxx; 428 $sc = true; 429 } 430 else 431 { 432 $filename = $e_xxx.".php"; 433 $sc = false; 434 } 435 436 if (is_readable(e_PLUGIN.$this->_plugdir."/".$filename)) 437 { 438 $content = file_get_contents(e_PLUGIN.$this->_plugdir."/".$filename); 439 } 440 else 441 { 442 return 2; 443 } 444 445 if(substr($e_xxx, - 4, 4) == '_sql') 446 { 447 448 if(strpos($content,'INSERT INTO')!==false) 449 { 450 return array('type'=> 'error', 'msg'=>"INSERT sql commands are not permitted here. Use a ".$this->_plugdir."_setup.php file instead."); 451 } 452 else 453 { 454 return 0; 455 } 456 } 457 458 // Generic markup check 459 if ($sc === false && !$this->isValidAddonMarkup($content)) 460 { 461 return 1; 462 } 463 464 465 if($e_xxx == 'e_meta' && strpos($content,'<script')!==false) 466 { 467 return array('type'=> 'warning', 'msg'=>"Contains script tags. Use e_header.php with the e107::js() function instead."); 468 } 469 470 471 if($e_xxx == 'e_latest' && strpos($content,'<div')!==false) 472 { 473 return array('type'=> 'warning', 'msg'=>"Using deprecated method. See e_latest.php in the forum plugin for an example."); 474 } 475 476 if($e_xxx == 'e_status' && strpos($content,'<div')!==false) 477 { 478 return array('type'=> 'warning', 'msg'=>"Using deprecated method. See e_status.php in the forum plugin for an example."); 479 } 480 481 482 return 0; 483 484 485 } 486 487 public function isValidAddonMarkup($content='') 488 { 489 if ((substr($content, 0, 5) != '<'.'?php')) 490 { 491 return false; 492 } 493 494 if ((substr($content, -2, 2) != '?'.'>') && (strrpos(substr($content, -20, 20), '?'.'>') !== false)) 495 { 496 return false; 497 } 498 499 500 return true; 501 502 } 503 504 505 public function getUpgradableList() 506 { 507 $needed = array(); 508 509 foreach($this->_installed as $path=>$curVal) 510 { 511 512 $version = $this->load($path)->getVersion(); 513 514 if(version_compare($curVal,$version,"<")) // check pref version against file version. 515 { 516 e107::getDebug()->log($curVal." vs ".$version); 517 $needed[$path] = $version; 518 } 519 520 } 521 522 return !empty($needed) ? $needed : false; 523 } 524 525 526 private function _initIDs() 527 { 528 $sql = e107::getDb(); 529 $cfg = e107::getConfig(); 530 531 $pref = $cfg->get('plug_installed'); 532 $detected = $this->getDetected(); 533 534 $toRemove = array(); 535 536 $save = false; 537 if ($rows = $sql->retrieve("plugin", "*", "plugin_id != 0 ORDER by plugin_path ", true)) 538 { 539 540 foreach($rows as $row) 541 { 542 543 $path = $row['plugin_path']; 544 545 if(!empty($detected) && !in_array($path,$detected)) 546 { 547 $toRemove[] = (int) $row['plugin_id']; 548 continue; 549 } 550 551 552 $this->_ids[$path] = (int) $row['plugin_id']; 553 554 if(!empty($row['plugin_installflag']) ) 555 { 556 $this->_installed[$path] = $row['plugin_version']; 557 558 if(!isset($pref[$path])) 559 { 560 $cfg->setPref('plug_installed/'.$path, $row['plugin_version']); 561 e107::getAdminLog()->addDebug($path)->save("plug_installed pref updated"); 562 $save = true; 563 } 564 } 565 566 $this->_addons[$path] = !empty($row['plugin_addons']) ? explode(',',$row['plugin_addons']) : null;// $path; 567 } 568 569 if($save) 570 { 571 $cfg->save(false,true,false); 572 } 573 } 574 575 576 $runUpdate = false; 577 578 if(!empty($toRemove)) 579 { 580 $runUpdate = true; 581 $delList = implode(",", $toRemove); 582 583 if($sql->delete('plugin', "plugin_id IN (".$delList.")")) 584 { 585 e107::getAdminLog()->addDebug("Deleted missing plugins with id(s): ".$delList)->save("Plugin Table Updated"); 586 // e107::getDebug()->log("Deleted missing plugins with id(s): ".$delList); 587 } 588 } 589 590 591 if(e_PAGE == 'e107_update.php') 592 { 593 return null; 594 } 595 596 597 foreach($detected as $path) // add a missing plugin to the database table. 598 { 599 600 if(!isset($this->_ids[$path]) && !empty($this->_data[$path]['@attributes'])) 601 { 602 $this->load($path); 603 $row = $this->getFields(); 604 605//var_dump($row); 606 if(!$id = $sql->insert('plugin',$row)) 607 { 608 e107::getDebug()->log("Unable to insert plugin data into table".print_a($row,true)); 609 e107::getAdminLog()->addDebug("Unable to insert plugin data into table".print_a($row,true))->save("plug_installed pref updated"); 610 } 611 else 612 { 613 $this->_ids[$path] = (int) $id; 614 $this->_addons[$path] = !empty($row['plugin_addons']) ? explode(',',$row['plugin_addons']) : null; 615 $runUpdate = true; 616 617 e107::getDebug()->log("Inserting plugin data into table".print_a($row,true)); 618 e107::getAdminLog()->addArray($row)->save("Plugin Table Entry Added"); 619 620 if($row['plugin_installflag'] == 1) 621 { 622 e107::getConfig()->setPref('plug_installed/'.$path, $row['plugin_version'])->save(false,true,false); 623 } 624 625 } 626 627 } 628 629 } 630 631 if($runUpdate === true) // clearCache 632 { 633 $this->_init(true); 634 635 } 636 637 638 } 639 640 public function getFields($currentStatus = false) 641 { 642 /*if(!isset($this->_data[$this->_plugdir]['@attributes']['name'])) 643 { 644 return false; 645 }*/ 646 647 648 $ret = array( 649 'plugin_name' => $this->getName('db'), 650 'plugin_version' => $this->getVersion(), 651 'plugin_path' => $this->_plugdir, 652 'plugin_installflag' => ($this->getInstallRequired() === true) ? 0 : 1, 653 'plugin_addons' => $this->getAddons(), 654 'plugin_category' => $this->getCategory() 655 ); 656 657 if($currentStatus) 658 { 659 $ret['plugin_installflag'] = (int) $this->isInstalled(); 660 $ret['plugin_id'] = $this->getId(); 661 } 662 663 return $ret; 664 665 } 666 667 668 /** 669 *Returns a list of addons available for the currently loaded plugin. 670 * @return string (comma separated) 671 */ 672 public function getAddons() 673 { 674 675 $allFiles = isset($this->_data[$this->_plugdir]) ? $this->_data[$this->_plugdir]['files']: array(); 676 677 $addons = array(); 678 679 foreach($this->_addon_types as $ad) 680 { 681 $file = $ad.".php"; 682 683 if(in_array($file,$allFiles)) 684 { 685 $addons[] = $ad; 686 } 687 688 } 689 690 foreach($allFiles as $file) 691 { 692 693 if(substr($file, -8) === "_sql.php") 694 { 695 $addons[] = str_replace(".php", '', $file); 696 } 697 698 if(substr($file, -3) === ".bb") 699 { 700 $addons[] = $file; 701 } 702 703 704 if(substr($file, -3) === ".sc") 705 { 706 $addons[] = $file; 707 } 708 709 if(preg_match('/^bb_(.*)\.php$/',$file)) 710 { 711 $addons[] = $file; 712 } 713 714 } 715 716 if(!empty($this->_data[$this->_plugdir]['shortcodes'])) 717 { 718 foreach($this->_data[$this->_plugdir]['shortcodes'] as $val) 719 { 720 $addons[] = 'sc_'.$val; 721 } 722 723 } 724 725 726 727 return implode(',', $addons); 728 729 730 } 731 732 733 734 private function _init($force=false) 735 { 736 737 $cacheTag = self::CACHETAG; 738 739 if($force === false && $tmp = e107::getCache()->retrieve($cacheTag, self::CACHETIME, true, true)) 740 { 741 $this->_data = e107::unserialize($tmp); 742 return true; 743 } 744 745 $dirs = scandir(e_PLUGIN); 746 747 $arr = array(); 748 749 foreach($dirs as $plugName) 750 { 751 $ret = null; 752 753 if((htmlentities($plugName) != $plugName) || empty($plugName) || $plugName === '.' || $plugName === '..' || !is_dir(e_PLUGIN.$plugName)) 754 { 755 continue; 756 } 757 758 if (file_exists(e_PLUGIN.$plugName.'/plugin.xml')) 759 { 760 $ret = $this->parse_plugin_xml($plugName); 761 } 762 elseif (file_exists(e_PLUGIN.$plugName.'/plugin.php')) 763 { 764 $ret = $this->parse_plugin_php($plugName); 765 } 766 767 if(!empty($ret['@attributes']['name'])) // make sure it's a valid plugin. 768 { 769 $arr[$plugName] = $ret; 770 } 771 } 772 773 if(empty($arr)) 774 { 775 return false; 776 } 777 778 $cacheSet = e107::serialize($arr,'json'); 779 780 if(empty($cacheSet)) 781 { 782 $error = json_last_error_msg(); 783 e107::getMessage()->addDebug("Plugin Cache JSON encoding is failing! (".__METHOD__.") Line: ".__LINE__); 784 e107::getMessage()->addDebug("JSON Error: ".$error); 785 } 786 787 e107::getCache()->set($cacheTag,$cacheSet,true,true,true); 788 789 $this->_data = $arr; 790 791 return null; 792 } 793 794 795 public function getMeta() 796 { 797 798 if(isset($this->_data[$this->_plugdir])) 799 { 800 return $this->_data[$this->_plugdir]; 801 } 802 803 return false; 804 } 805 806 807 public function getName($mode=null) 808 { 809 if(!empty($this->_data[$this->_plugdir]['@attributes']['lan'])) 810 { 811 if($mode === 'db') 812 { 813 return $this->_data[$this->_plugdir]['@attributes']['lan']; 814 } 815 elseif(defined( $this->_data[$this->_plugdir]['@attributes']['lan'])) 816 { 817 return constant($this->_data[$this->_plugdir]['@attributes']['lan']); 818 } 819 } 820 821 if(isset($this->_data[$this->_plugdir]['@attributes']['name'])) 822 { 823 return ($mode === 'db') ? $this->_data[$this->_plugdir]['@attributes']['name'] : e107::getParser()->toHTML($this->_data[$this->_plugdir]['@attributes']['name'],FALSE,"defs, emotes_off"); 824 } 825 826 return false; 827 828 } 829 830 831 private function parse_plugin_xml($plugName) 832 { 833 // $tp = e107::getParser(); 834 // loadLanFiles($plugName, 'admin'); // Look for LAN files on default paths 835 $xml = e107::getXml(); 836 $mes = e107::getMessage(); 837 838 839 840 841 // $xml->setOptArrayTags('extendedField,userclass,menuLink,commentID'); // always arrays for these tags. 842 // $xml->setOptStringTags('install,uninstall,upgrade'); 843 // if(null === $where) $where = 'plugin.xml'; 844 845 $where = 'plugin.xml'; 846 $ret = $xml->loadXMLfile(e_PLUGIN.$plugName.'/'.$where, 'advanced'); 847 848 if ($ret === FALSE) 849 { 850 $mes->addError("Error reading {$plugName}/plugin.xml"); 851 return FALSE; 852 } 853 854 855 856 $ret['folder'] = $plugName; // remove the need for <folder> tag in plugin.xml. 857 $ret['category'] = (isset($ret['category'])) ? $this->checkCategory($ret['category']) : "misc"; 858 $ret['files'] = preg_grep('/^([^.])/', scandir(e_PLUGIN.$plugName,SCANDIR_SORT_ASCENDING)); 859 $ret['lan'] = $this->_detectLanGlobal($plugName); 860 861 862 $ret['@attributes']['version'] = $this->_fixVersion($ret['@attributes']['version']); 863 $ret['@attributes']['compatibility'] = $this->_fixCompat($ret['@attributes']['compatibility']); 864 865 if(varset($ret['description'])) 866 { 867 if (is_array($ret['description'])) 868 { 869 if (isset($ret['description']['@attributes']['lan']) && defined($ret['description']['@attributes']['lan'])) 870 { 871 // Pick up the language-specific description if it exists. 872 $ret['description']['@value'] = constant($ret['description']['@attributes']['lan']); 873 } 874 } 875 else 876 { 877 $diz = $ret['description']; 878 unset($ret['description']); 879 880 $ret['description']['@value'] = $diz; 881 } 882 } 883 884 885 // Very useful debug code.to compare plugin.php vs plugin.xml 886 /* 887 $testplug = 'forum'; 888 if($plugName == $testplug) 889 { 890 $plug_vars1 = $ret; 891 $this->parse_plugin_php($testplug); 892 $plug_vars2 = $ret; 893 ksort($plug_vars2); 894 ksort($plug_vars1); 895 echo "<table> 896 <tr><td><h1>PHP</h1></td><td><h1>XML</h1></td></tr> 897 <tr><td style='border-right:1px solid black'>"; 898 print_a($plug_vars2); 899 echo "</td><td>"; 900 print_a($plug_vars1); 901 echo "</table>"; 902 } 903 */ 904 905 906 // TODO search for $ret['adminLinks']['link'][0]['@attributes']['primary']==true. 907 $ret['administration']['icon'] = varset($ret['adminLinks']['link'][0]['@attributes']['icon']); 908 $ret['administration']['caption'] = varset($ret['adminLinks']['link'][0]['@attributes']['description']); 909 $ret['administration']['iconSmall'] = varset($ret['adminLinks']['link'][0]['@attributes']['iconSmall']); 910 $ret['administration']['configFile'] = varset($ret['adminLinks']['link'][0]['@attributes']['url']); 911 $ret['legacy'] = false; 912 913 if (is_dir(e_PLUGIN.$plugName."/shortcodes/single/")) 914 { 915 $ret['shortcodes'] = preg_grep('/^([^.])/', scandir(e_PLUGIN.$plugName,SCANDIR_SORT_ASCENDING)); 916 } 917 918 919 return $ret; 920 921 } 922 923 924 /** 925 * @param $plugName 926 * @return array 927 */ 928 private function parse_plugin_php($plugName) 929 { 930 $tp = e107::getParser(); 931 $sql = e107::getDb(); // in case it is used inside plugin.php 932 933 $PLUGINS_FOLDER = '{e_PLUGIN}'; // Could be used in plugin.php file. 934 935 $eplug_conffile = null; 936 $eplug_table_names = null; 937 $eplug_prefs = null; 938 $eplug_module = null; 939 $eplug_userclass = null; 940 $eplug_status = null; 941 $eplug_latest = null; 942 $eplug_icon = null; 943 $eplug_icon_small = null; 944 $eplug_compatible = null; 945 $eplug_version = null; 946 947 948 ob_start(); 949 include(e_PLUGIN.$plugName.'/plugin.php'); 950 ob_end_clean(); 951 $ret = array(); 952 953 unset($sql); 954 unset($PLUGINS_FOLDER); 955 956 $ret['@attributes']['name'] = varset($eplug_name); 957 $ret['@attributes']['lan'] = varset($eplug_name); 958 $ret['@attributes']['version'] = $this->_fixVersion($eplug_version, true); 959 $ret['@attributes']['date'] = varset($eplug_date); 960 $ret['@attributes']['compatibility'] = $this->_fixCompat($eplug_compatible); 961 $ret['@attributes']['installRequired'] = ($eplug_conffile || is_array($eplug_table_names) || is_array($eplug_prefs) || $eplug_module || $eplug_userclass || $eplug_status || $eplug_latest) ? 'true' : ''; 962 $ret['@attributes']['xhtmlcompliant'] = vartrue($eplug_compliant) ? 'true' : ''; 963 $ret['folder'] = $plugName; // (varset($eplug_folder)) ? $eplug_folder : $plugName; 964 965 $ret['author']['@attributes']['name'] = varset($eplug_author); 966 $ret['author']['@attributes']['url'] = varset($eplug_url); 967 $ret['author']['@attributes']['email'] = varset($eplug_email); 968 $ret['description']['@value'] = varset($eplug_description); 969 $ret['description']['@attributes']['lan'] = varset($eplug_description); 970 971 $ret['category'] = !empty($eplug_category) ? $this->checkCategory($eplug_category) : "misc"; 972 $ret['readme'] = !empty($eplug_readme); 973 974 $ret['menuName'] = varset($eplug_menu_name); 975 976 977 if (!empty($eplug_prefs) && is_array($eplug_prefs)) 978 { 979 $c = 0; 980 foreach($eplug_prefs as $name => $value) 981 { 982 $ret['mainPrefs']['pref'][$c]['@attributes']['name'] = $name; 983 $ret['mainPrefs']['pref'][$c]['@value'] = $value; 984 $c++; 985 } 986 } 987 988 989 990 // For BC. 991 $ret['administration']['icon'] = $this->_fixPath($eplug_icon,$plugName); 992 $ret['administration']['caption'] = varset($eplug_caption); 993 $ret['administration']['iconSmall'] = $this->_fixPath($eplug_icon_small,$plugName); 994 $ret['administration']['configFile'] = varset($eplug_conffile); 995 996 997 998 if(isset($eplug_conffile)) 999 { 1000 $ret['adminLinks']['link'][0]['@attributes']['url'] = varset($eplug_conffile); 1001 $ret['adminLinks']['link'][0]['@attributes']['description'] = LAN_CONFIGURE; 1002 $ret['adminLinks']['link'][0]['@attributes']['icon'] = $this->_fixPath($eplug_icon,$plugName); // str_replace($plugName."/","",$eplug_icon); 1003 $ret['adminLinks']['link'][0]['@attributes']['iconSmall'] = $this->_fixPath($eplug_icon_small,$plugName); 1004 $ret['adminLinks']['link'][0]['@attributes']['primary'] = 'true'; 1005 } 1006 if(!empty($eplug_link) && isset($eplug_link_name) && isset($eplug_link_url)) 1007 { 1008 $ret['siteLinks']['link'][0]['@attributes']['url'] = $tp->createConstants($eplug_link_url, 1); 1009 $ret['siteLinks']['link'][0]['@attributes']['perm'] = varset($eplug_link_perms); 1010 $ret['siteLinks']['link'][0]['@value'] = varset($eplug_link_name); 1011 } 1012 1013 if(!empty($eplug_userclass) && !empty($eplug_userclass_description)) 1014 { 1015 $ret['userClasses']['class'][0]['@attributes']['name'] = $eplug_userclass; 1016 $ret['userClasses']['class'][0]['@attributes']['description'] = $eplug_userclass_description; 1017 } 1018 1019 $ret['files'] = preg_grep('/^([^.])/', scandir(e_PLUGIN.$plugName,SCANDIR_SORT_ASCENDING)); 1020 $ret['lan'] = $this->_detectLanGlobal($plugName); 1021 $ret['legacy'] = true; 1022 1023 return $ret; 1024 1025 } 1026 1027 private function _detectLanGlobal($pluginDir) 1028 { 1029 $path_a = e_PLUGIN.$pluginDir."/languages/English_global.php"; // always check for English so we have a fall-back 1030 $path_b = e_PLUGIN.$pluginDir."/languages/English/English_global.php"; 1031 1032 if(file_exists($path_a) || file_exists($path_b)) 1033 { 1034 return $pluginDir; 1035 } 1036 1037 return false; 1038 } 1039 1040 1041 private function _fixVersion($ver, $legacy=false) 1042 { 1043 1044 if(empty($ver)) 1045 { 1046 return null; 1047 } 1048 1049 $ver = str_replace('e107','',$ver); 1050 1051 $regex = ($legacy === true) ? '/([^\d\.ab])/' : '/([^\d\.])/'; 1052 1053 return preg_replace($regex,'',$ver); // eg. 2.0.1b okay for BC plugin. 1054 1055 1056 } 1057 1058 private function _fixCompat($ver) 1059 { 1060 $ver = $this->_fixVersion($ver); 1061 $ver = str_replace('0.8','2.0',$ver); 1062 if($ver == 7 || intval($ver) < 1) 1063 { 1064 $ver = "1.0"; 1065 } 1066 1067 return $ver; 1068 } 1069 1070 1071 private function _fixPath($path, $plugName) 1072 { 1073 $pathFilter = array( 1074 e_PLUGIN.$plugName.'/', 1075 $plugName."/" 1076 1077 ); 1078 1079 return str_replace($pathFilter,'', $path); 1080 } 1081 1082 1083 private function checkCategory($cat) 1084 { 1085 $okayCats = array_keys($this->_accepted_categories); 1086 1087 if (!empty($cat) && in_array($cat, $okayCats)) 1088 { 1089 return $cat; 1090 } 1091 else 1092 { 1093 return 'misc'; 1094 } 1095 } 1096 1097 1098 1099 public function buildAddonPrefLists() 1100 { 1101 $core = e107::getConfig('core'); 1102 1103 $urlsBefore = $core->get('e_url_list', array()); // get URL settings to be restored after. 1104 1105 foreach ($this->_addon_types as $var) // clear all existing prefs. 1106 { 1107 $core->update($var.'_list', ""); 1108 } 1109 1110 // reset 1111 $core->set('bbcode_list', array()) 1112 ->set('shortcode_legacy_list', array()) 1113 ->set('shortcode_list', array()) 1114 ->set('lan_global_list', array()); 1115 1116 $paths = $this->getDetected(); 1117 1118 /** 1119 * Prevent this method from wiping out the variable that is tracking 1120 * the currently loaded plugin by moving the currently loaded plugin to 1121 * the end of the iterated array. 1122 * @see https://github.com/e107inc/e107/issues/3531 1123 * @see https://github.com/e107inc/e107-test/issues/9 1124 */ 1125 $paths = array_diff($paths, [$this->_plugdir]); 1126 $paths[] = $this->_plugdir; 1127 1128 foreach($paths as $path) 1129 { 1130 1131 $this->load($path); 1132 1133 $is_installed = $this->isInstalled(); 1134 $tmp = explode(",", $this->getAddons()); 1135 1136 1137 if ($is_installed) 1138 { 1139 if($hasLAN = $this->hasLanGlobal()) 1140 { 1141 $core->setPref('lan_global_list/'.$hasLAN, $hasLAN); 1142 } 1143 1144 foreach ($tmp as $val) 1145 { 1146 if (strpos($val, 'e_') === 0) 1147 { 1148 $core->setPref($val.'_list/'.$path, $path); 1149 } 1150 } 1151 } 1152 1153 // search for .bb and .sc files. 1154 $scl_array = array(); 1155 $sc_array = array(); 1156 $bb_array = array(); 1157 // $sql_array = array(); 1158 1159 foreach ($tmp as $adds) 1160 { 1161 // legacy shortcodes - plugin root *.sc files 1162 if (substr($adds, -3) === ".sc") 1163 { 1164 $sc_name = substr($adds, 0, -3); // remove the .sc 1165 if ($is_installed) 1166 { 1167 $scl_array[$sc_name] = "0"; // default userclass = e_UC_PUBLIC 1168 } 1169 else 1170 { 1171 $scl_array[$sc_name] = e_UC_NOBODY; // register shortcode, but disable it 1172 } 1173 } 1174 // new shortcodes location - shortcodes/single/*.php 1175 elseif (substr($adds, 0, 3) === "sc_") 1176 { 1177 $sc_name = substr(substr($adds, 3), 0, -4); // remove the sc_ and .php 1178 1179 if ($is_installed) 1180 { 1181 $sc_array[$sc_name] = "0"; // default userclass = e_UC_PUBLIC 1182 } 1183 else 1184 { 1185 $sc_array[$sc_name] = e_UC_NOBODY; // register shortcode, but disable it 1186 } 1187 } 1188 1189 if($is_installed) 1190 { 1191 // simple bbcode 1192 if(substr($adds,-3) == ".bb") 1193 { 1194 $bb_name = substr($adds, 0,-3); // remove the .bb 1195 $bb_array[$bb_name] = "0"; // default userclass. 1196 } 1197 // bbcode class 1198 elseif(substr($adds, 0, 3) == "bb_" && substr($adds, -4) == ".php") 1199 { 1200 $bb_name = substr($adds, 0,-4); // remove the .php 1201 $bb_name = substr($bb_name, 3); 1202 $bb_array[$bb_name] = "0"; // TODO - instance and getPermissions() method 1203 } 1204 } 1205 1206 if ($is_installed && (substr($adds, -4) == "_sql")) 1207 { 1208 $core->setPref('e_sql_list/'.$path, $adds); 1209 } 1210 } 1211 1212 // Build Bbcode list (will be empty if plugin not installed) 1213 if (count($bb_array) > 0) 1214 { 1215 ksort($bb_array); 1216 $core->setPref('bbcode_list/'.$path, $bb_array); 1217 } 1218 1219 // Build shortcode list - do if uninstalled as well 1220 if (count($scl_array) > 0) 1221 { 1222 ksort($scl_array); 1223 $core->setPref('shortcode_legacy_list/'.$path, $scl_array); 1224 } 1225 1226 if (count($sc_array) > 0) 1227 { 1228 ksort($sc_array); 1229 $core->setPref('shortcode_list/'.$path, $sc_array); 1230 } 1231 } 1232 1233 // Restore e_url settings 1234 $urlsAfter = $core->get('e_url_list', array()); 1235 foreach($urlsAfter as $k=>$v) 1236 { 1237 if(isset($urlsBefore[$k])) 1238 { 1239 $core->setPref('e_url_list/'.$k, $urlsBefore[$k]); 1240 } 1241 } 1242 1243 1244 $core->save(false, true, false); 1245 1246 } 1247 1248 1249 1250 1251 1252} 1253 1254 1255 1256/** 1257 * @deprecated in part. To eventually be replaced with e_plugin above. 1258 */ 1259class e107plugin 1260{ 1261 // Reserved Addon names. 1262 var $plugin_addons = array( 1263 'e_admin', 1264 'e_bb', 1265 'e_cron', 1266 'e_notify', 1267 'e_linkgen', 1268 'e_list', 1269 1270 'e_meta', // @Deprecated 1271 'e_emailprint', 1272 'e_print', // new v2.2 1273 'e_frontpage', 1274 'e_latest', /* @deprecated - see e_dashboard */ 1275 'e_status', /* @deprecated - see e_dashboard */ 1276 'e_menu', 1277 'e_search', 1278 'e_shortcode', 1279 'e_module', 1280 'e_event', 1281 'e_comment', 1282 'e_sql', 1283 'e_dashboard', // Admin Front-Page addon. 1284 // 'e_userprofile', @deprecated @see e_user 1285 'e_header', // loaded in header prior to javascript manager. 1286 'e_footer', // Loaded in footer prior to javascript manager. 1287 // 'e_userinfo', @deprecated @see e_user 1288 'e_tagwords', 1289 'e_url', // simple mod-rewrite. 1290 'e_mailout', 1291 'e_sitelink', // sitelinks generator. 1292 'e_tohtml', /* @deprecated - use e_parse */ 1293 'e_featurebox', 1294 'e_parse', 1295 'e_related', 1296 'e_rss', 1297 'e_upload', 1298 'e_user', 1299 'e_library', // For third-party libraries are defined by plugins/themes. 1300 'e_gsitemap', 1301 'e_output', //hook into all pages at the end (after closing </html>) 1302 ); 1303 1304 1305 /** Deprecated or non-v2.x standards */ 1306 private $plugin_addons_deprecated = array( 1307 'e_bb', // @deprecated 1308 'e_list', 1309 'e_meta', // @deprecated 1310 'e_latest', // @deprecated 1311 'e_status', // @deprecated 1312 'e_tagwords', 1313 'e_sql.php', 1314 'e_linkgen', 1315 'e_frontpage', 1316 'e_tohtml', // @deprecated rename to e_parser ? 1317 'e_sql', 1318 'e_emailprint', 1319 ); 1320 1321 1322 1323 private $plugin_addons_diz = array( 1324 'e_admin' => "Add form elements to existing core admin areas.", 1325 'e_cron' => "Include your plugin's cron in the 'Scheduled Tasks' admin area.", 1326 'e_notify' => "Include your plugin's notification to the Notify admin area.", 1327 'e_linkgen' => "Add link generation into the sitelinks area.", 1328 'e_frontpage' => "Add your plugin as a frontpage option.", 1329 'e_menu' => "Gives your plugin's menu(s) configuration options in the Menu Manager.", 1330 'e_featurebox' => "Allow your plugin to generate content for the featurebox plugin.", 1331 'e_search' => "Add your plugin to the search page.", 1332 'e_shortcode' => "Add a global shortcode which can be used site-wide. (use sparingly)", 1333 'e_module' => "Include a file within class2.php (every page of the site).", 1334 'e_event' => "Hook into core events and process them with custom functions.", 1335 'e_comment' => "Override the core commenting system.", 1336 'e_dashboard' => "Add something to the default admin dashboard panel.", // Admin Front-Page addon. 1337 'e_header' => "Have your plugin include code in the head of every page of the site. eg. css", // loaded in header prior to javascript manager. 1338 'e_footer' => "Have your plugin include code in the foot of every page of the site. eg. javascript", // Loaded in footer prior to javascript manager. 1339 'e_url' => "Give your plugin search-engine-friendly URLs", // simple mod-rewrite. 1340 'e_mailout' => "Allow the mailing engine to use data from your plugin's database tables.", 1341 'e_sitelink' => "Create dynamic navigation links for your plugin.", // sitelinks generator. 1342 'e_related' => "Allow your plugin to be included in the 'related' links.", 1343 'e_rss' => "Give your plugin an rss feed.", 1344 'e_upload' => "Use data from your plugin in the user upload form.", 1345 'e_user' => "Have your plugin include data on the user-profile page.", 1346 'e_library' => "Include a third-party library", 1347 'e_parse' => "Hook into e107's text/html parser", 1348 'e_output' => "Hook into all pages at the end (after closing </html>)" 1349 ); 1350 1351 1352 var $disAllowed = array( 1353 'theme', 1354 'core' 1355 ); 1356 1357 1358 protected $core_plugins = array( 1359 "_blank","admin_menu","banner","blogcalendar_menu", 1360 "chatbox_menu", "clock_menu","comment_menu", 1361 "contact", "download", "featurebox", "forum","gallery", 1362 "gsitemap","import", "linkwords", "list_new", "log", "login_menu", 1363 "metaweblog", "newforumposts_main", "news", "newsfeed", 1364 "newsletter","online", "page", "pm","poll", 1365 "rss_menu","search_menu","siteinfo", "social", "tagcloud", "tinymce4", 1366 "trackback","tree_menu","user" 1367 ); 1368 1369 1370 // List of all plugin variables which need to be checked - install required if one or more set and non-empty 1371 // Deprecated in 0.8 (used in plugin.php only). Probably delete in 0.9 1372 var $all_eplug_install_variables = array( 1373 'eplug_link_url', 1374 'eplug_link', 1375 'eplug_prefs', 1376 'eplug_array_pref', 1377 'eplug_table_names', 1378 // 'eplug_sc', // Not used in 0.8 (or later 0.7) 1379 'eplug_userclass', 1380 'eplug_module', 1381 // 'eplug_bb', // Not used in 0.8 (or later 0.7) 1382 'eplug_latest', 1383 'eplug_status', 1384 'eplug_comment_ids', 1385 'eplug_conffile', 1386 'eplug_menu_name' 1387 ); 1388 1389 // List of all plugin variables involved in an update (not used ATM, but worth 'documenting') 1390 // Deprecated in 0.8 (used in plugin.php only). Probably delete in 0.9 1391 var $all_eplug_update_variables = array( 1392 'upgrade_alter_tables', 1393 // 'upgrade_add_eplug_sc', // Not used in 0.8 (or later 0.7) 1394 // 'upgrade_remove_eplug_sc', // Not used in 0.8 (or later 0.7) 1395 // 'upgrade_add_eplug_bb', // Not used in 0.8 (or later 0.7) 1396 // 'upgrade_remove_eplug_bb', // Not used in 0.8 (or later 0.7) 1397 'upgrade_add_prefs', 1398 'upgrade_remove_prefs', 1399 'upgrade_add_array_pref', 1400 'upgrade_remove_array_pref' 1401 ); 1402 1403 // List of all 'editable' DB fields ('plugin_id' is an arbitrary reference which is never edited) 1404 var $all_editable_db_fields = array( 1405 'plugin_name', // Name of the plugin - language dependent 1406 'plugin_version', // Version - arbitrary text field 1407 'plugin_path', // Name of the directory off e_PLUGIN - unique 1408 'plugin_installflag', // '0' = not installed, '1' = installed 1409 'plugin_addons', // List of any extras associated with plugin - bbcodes, e_XXX files... 1410 'plugin_category' // Plugin Category: settings, users, content, management, tools, misc, about 1411 ); 1412 1413 var $accepted_categories = array('settings', 'users', 'content', 'tools', 'manage', 'misc', 'menu', 'about'); 1414 1415 var $plug_vars; 1416 var $current_plug; 1417 var $parsed_plugin = array(); 1418 var $plugFolder; 1419 var $plugConfigFile; 1420 var $unInstallOpts; 1421 var $module = array(); 1422 private $options = array(); 1423 private $log = array(); 1424 1425 1426 1427 1428 1429 1430 function __construct() 1431 { 1432 //$parsed_plugin = array(); 1433 } 1434 1435 /** 1436 * @deprecated to be removed. Use e_plugin instead. 1437 * Returns an array containing details of all plugins in the plugin table - should normally use e107plugin::update_plugins_table() first to 1438 * make sure the table is up to date. (Primarily called from plugin manager to get lists of installed and uninstalled plugins. 1439 * @return array|bool plugin details 1440 */ 1441 private function getall($flag) 1442 { 1443 $sql = e107::getDb(); 1444 1445 if($flag === 'all') 1446 { 1447 $qry = "SELECT * FROM #plugin ORDER BY plugin_path ASC"; 1448 } 1449 else 1450 { 1451 $qry = "SELECT * FROM #plugin WHERE plugin_installflag = ".(int) $flag." ORDER BY plugin_path ASC"; 1452 } 1453 1454 if ($sql->gen($qry)) 1455 { 1456 $ret = $sql->db_getList(); 1457 return $ret; 1458 } 1459 1460 return false; 1461 } 1462 1463 /** 1464 * Return a list of core plugins. 1465 */ 1466 public function getCorePlugins() 1467 { 1468 return $this->core_plugins; 1469 } 1470 1471 /** 1472 * Return a list of non-core plugins 1473 */ 1474 public function getOtherPlugins() 1475 { 1476 $allplugs = e107::getFile()->get_dirs(e_PLUGIN); 1477 1478 return array_diff($allplugs,$this->core_plugins); 1479 } 1480 1481 1482 /** 1483 * Returns an array containing details of all plugins in the plugin table - should normally use e107plugin::update_plugins_table() first to 1484 * make sure the table is up to date. (Primarily called from plugin manager to get lists of installed and uninstalled plugins. 1485 * @param string $path 1486 * @return int 1487 */ 1488 private function getId($path) 1489 { 1490 $sql = e107::getDb(); 1491 1492 if ($sql->select("plugin", "plugin_id", "plugin_path = '".(string) $path."' LIMIT 1")) 1493 { 1494 $row = $sql->fetch(); 1495 return intval($row['plugin_id']); 1496 } 1497 1498 return false; 1499 } 1500 1501 /** 1502 * Checks all installed plugins and returns an array of those needing an update. 1503 * @param string $mode 'boolean' for a quick true/false or null for full array returned. 1504 * @return mixed 1505 */ 1506 public function updateRequired($mode=null) 1507 { 1508 // $xml = e107::getXml(); 1509 $mes = e107::getMessage(); 1510 $needed = array(); 1511 $log = e107::getAdminLog(); 1512 1513 if(!$plugVersions = e107::getConfig('core')->get('plug_installed')) 1514 { 1515 return FALSE; 1516 } 1517 1518 $dbv = e107::getObject('db_verify', null, e_HANDLER."db_verify_class.php"); 1519 $plg = e107::getPlug(); 1520 1521 foreach($plugVersions as $path=>$version) 1522 { 1523 1524 $data = $plg->load($path)->getMeta(); 1525 1526 if($plg->isLegacy() === true) 1527 { 1528 continue; 1529 } 1530 1531 if(!in_array($path, $this->core_plugins)) // check non-core plugins for sql file changes. 1532 { 1533 $dbv->errors = array(); 1534 $dbv->compare($path); 1535 1536 if($dbv->errors()) 1537 { 1538 $mes->addDebug("Plugin Update(s) Required - db structure change [".$path."]"); 1539 $needed[$path] = $data; 1540 } 1541 } 1542 1543 $curVal = $version; 1544 $fileVal = $plg->getVersion(); 1545 1546 if($ret = $this->execute_function($path, 'upgrade', 'required', array($this, $curVal, $fileVal))) // Check {plugin}_setup.php and run a 'required' method, if true, then update is required. 1547 { 1548 $mes->addDebug("Plugin Update(s) Required in ".$path."_setup.php [".$path."]"); 1549 1550 if($mode === 'boolean') 1551 { 1552 return TRUE; 1553 } 1554 1555 $needed[$path] = $data; 1556 } 1557 1558 if(version_compare($curVal,$fileVal,"<")) // check pref version against file version. 1559 { 1560 $mes->addDebug("Plugin Update(s) Required - different version [".$path."]"); 1561 1562 if($mode === 'boolean') 1563 { 1564 return TRUE; 1565 } 1566 1567 // $mes->addDebug("Plugin: <strong>{$path}</strong> requires an update."); 1568 1569 // $log->flushMessages(); 1570 $needed[$path] = $data; 1571 } 1572 1573 } 1574 1575 // Display debug and log to file. 1576 foreach($needed as $path=>$tmp) 1577 { 1578 $log->addDebug("Plugin: <strong>{$path}</strong> requires an update."); 1579 } 1580 1581 1582 if($mode === 'boolean') 1583 { 1584 return count($needed) ? true : FALSE; 1585 } 1586 1587 1588 return count($needed) ? $needed : FALSE; 1589 } 1590 1591 1592 1593 /** 1594 * Check for new plugins, create entry in plugin table and remove deleted plugins 1595 * @deprecated by e_plugin::init() some parts might still need to be integrated into the new method. 1596 * @param string $mode = install|upgrade|refresh|uninstall - defines the intent of the call 1597 * 1598 * 'upgrade' and 'refresh' are very similar in intent, and often take the same actions: 1599 * 'upgrade' signals a possible change to the installed list of plugins 1600 * 'refresh' validates the stored data for existing plugins, recreating any that has gone missing 1601 */ 1602 function update_plugins_table($mode = 'upgrade') 1603 { 1604 1605 $sql = e107::getDb(); 1606 $sql2 = e107::getDb('sql2'); 1607 $tp = e107::getParser(); 1608 $fl = e107::getFile(); 1609 $mes = e107::getMessage(); 1610 1611 $mes->addDebug("Updating plugins Table"); 1612 1613 $log = e107::getAdminLog(); 1614 1615 global $mySQLprefix, $menu_pref; 1616 $pref = e107::getPref(); 1617 1618 1619 $sp = FALSE; 1620 1621 $pluginDBList = array(); 1622 if ($sql->select('plugin', "*")) // Read all the plugin DB info into an array to save lots of accesses 1623 1624 { 1625 while ($row = $sql->fetch()) 1626 { 1627 $pluginDBList[$row['plugin_path']] = $row; 1628 $pluginDBList[$row['plugin_path']]['status'] = 'read'; 1629 // echo "Found plugin: ".$row['plugin_path']." in DB<br />"; 1630 } 1631 } 1632 e107::getDebug()->logTime('Start Scanning Plugin Files'); 1633 $plugList = $fl->get_files(e_PLUGIN, "^plugin\.(php|xml)$", "standard", 1); 1634 1635 foreach ($plugList as $num => $val) // Remove Duplicates caused by having both plugin.php AND plugin.xml. 1636 { 1637 $key = basename($val['path']); 1638 $pluginList[$key] = $val; 1639 } 1640 1641 e107::getDebug()->logTime('After Scanning Plugin Files'); 1642 $p_installed = e107::getPref('plug_installed', array()); // load preference; 1643 $mes = e107::getMessage(); 1644 1645 foreach ($pluginList as $p) 1646 { 1647 $p['path'] = substr(str_replace(e_PLUGIN, "", $p['path']), 0, -1); 1648 $plugin_path = $p['path']; 1649 1650 if (strpos($plugin_path, 'e107_') !== FALSE) 1651 { 1652 $mes->addWarning("Folder error: <i>{$p['path']}</i>. 'e107_' is not permitted within plugin folder names."); 1653 continue; 1654 } 1655 1656 if(in_array($plugin_path, $this->disAllowed)) 1657 { 1658 $mes->addWarning("Folder error: <i>{$p['path']}</i> is not permitted as an acceptable folder name."); 1659 continue; 1660 } 1661 1662 1663 $plug['plug_action'] = 'scan'; // Make sure plugin.php knows what we're up to 1664 1665 if (!$this->parse_plugin($p['path'])) 1666 { 1667 //parsing of plugin.php/plugin.xml failed. 1668 $mes->addError("Parsing failed - file format error: {$p['path']}"); 1669 continue; // Carry on and do any others that are OK 1670 } 1671 1672 $plug_info = $this->plug_vars; 1673 $eplug_addons = $this->getAddons($plugin_path); 1674 1675 //Ensure the plugin path lives in the same folder as is configured in the plugin.php/plugin.xml - no longer relevant. 1676 if ($plugin_path == $plug_info['folder']) 1677 { 1678 if (array_key_exists($plugin_path, $pluginDBList)) 1679 { // Update the addons needed by the plugin 1680 $pluginDBList[$plugin_path]['status'] = 'exists'; 1681 1682 // Check for name (lan) changes 1683 if (vartrue($plug_info['@attributes']['lan']) && $pluginDBList[$plugin_path]['plugin_name'] != $plug_info['@attributes']['lan']) 1684 { 1685 // print_a($plug_info); 1686 $pluginDBList[$plugin_path]['status'] = 'update'; 1687 $pluginDBList[$plugin_path]['plugin_name'] = $plug_info['@attributes']['lan']; 1688 $this->plugFolder = $plugin_path; 1689 $this->XmlLanguageFiles('upgrade'); 1690 } 1691 1692 if ($mode == 'refresh') 1693 { 1694 if ($this->XmlLanguageFileCheck('_log', 'lan_log_list', 'refresh', $pluginDBList[$plugin_path]['plugin_installflag'], FALSE, $plugin_path)) $sp = TRUE; 1695 if ($this->XmlLanguageFileCheck('_global', 'lan_global_list', 'refresh', $pluginDBList[$plugin_path]['plugin_installflag'], TRUE, $plugin_path)) $sp = TRUE; 1696 } 1697 1698 // Check for missing plugin_category in plugin table. 1699 if ($pluginDBList[$plugin_path]['plugin_category'] == '' || $pluginDBList[$plugin_path]['plugin_category'] != $plug_info['category']) 1700 { 1701 // print_a($plug_info); 1702 $pluginDBList[$plugin_path]['status'] = 'update'; 1703 $pluginDBList[$plugin_path]['plugin_category'] = (vartrue($plug_info['category'])) ? $plug_info['category'] : "misc"; 1704 } 1705 1706 // If plugin not installed, and version number of files changed, update version as well 1707 if (($pluginDBList[$plugin_path]['plugin_installflag'] == 0) && ($pluginDBList[$plugin_path]['plugin_version'] != $plug_info['@attributes']['version'])) 1708 { // Update stored version 1709 $pluginDBList[$plugin_path]['plugin_version'] = $plug_info['@attributes']['version']; 1710 $pluginDBList[$plugin_path]['status'] = 'update'; 1711 } 1712 if ($pluginDBList[$plugin_path]['plugin_addons'] != $eplug_addons) 1713 { // Update stored addons list 1714 $pluginDBList[$plugin_path]['plugin_addons'] = $eplug_addons; 1715 $pluginDBList[$plugin_path]['status'] = 'update'; 1716 } 1717 1718 if ($pluginDBList[$plugin_path]['plugin_installflag'] == 0) // Plugin not installed - make sure $pref not set 1719 1720 { 1721 if (isset($p_installed[$plugin_path])) 1722 { 1723 unset($p_installed[$plugin_path]); 1724 $sp = TRUE; 1725 } 1726 } 1727 else 1728 { // Plugin installed - make sure $pref is set 1729 if (!isset($p_installed[$plugin_path]) || ($p_installed[$plugin_path] != $pluginDBList[$plugin_path]['plugin_version'])) 1730 { // Update prefs array of installed plugins 1731 $p_installed[$plugin_path] = $pluginDBList[$plugin_path]['plugin_version']; 1732 // echo "Add: ".$plugin_path."->".$ep_row['plugin_version']."<br />"; 1733 $sp = TRUE; 1734 } 1735 } 1736 } 1737 else // New plugin - not in table yet, so add it. If no install needed, mark it as 'installed' 1738 { 1739 if ($plug_info['@attributes']['name']) 1740 { 1741 $pName = vartrue($plug_info['@attributes']['lan']) ? $plug_info['@attributes']['lan'] : $plug_info['@attributes']['name'] ; 1742 1743 $_installed = ($plug_info['@attributes']['installRequired'] == 'true' || $plug_info['@attributes']['installRequired'] == 1 ? 0 : 1); 1744 1745 1746 $pInsert = array( 1747 'plugin_id' => 0, 1748 'plugin_name' => $tp->toDB($pName, true), 1749 'plugin_version' => $tp->toDB($plug_info['@attributes']['version'], true), 1750 'plugin_path' => $tp->toDB($plugin_path, true), 1751 'plugin_installflag' => $_installed, 1752 'plugin_addons' => $eplug_addons, 1753 'plugin_category' => $this->manage_category($plug_info['category']) 1754 ); 1755 1756 // if (e107::getDb()->db_Insert("plugin", "0, '".$tp->toDB($pName, true)."', '".$tp->toDB($plug_info['@attributes']['version'], true)."', '".$tp->toDB($plugin_path, true)."',{$_installed}, '{$eplug_addons}', '".$this->manage_category($plug_info['category'])."' ")) 1757 if (e107::getDb()->insert("plugin", $pInsert)) 1758 { 1759 $log->addDebug("Added <b>".$tp->toHTML($pName,false,"defs")."</b> to the plugin table."); 1760 } 1761 else 1762 { 1763 $log->addDebug("Failed to add ".$tp->toHTML($pName,false,"defs")." to the plugin table."); 1764 } 1765 1766 $log->flushMessages("Updated Plugins table"); 1767 } 1768 } 1769 } 1770 // else 1771 { // May be useful that we ignore what will usually be copies/backups of plugins - but don't normally say anything 1772 // echo "Plugin copied to wrong directory. Is in: {$plugin_path} Should be: {$plug_info['folder']}<br /><br />"; 1773 } 1774 1775 // print_a($plug_info); 1776 } 1777 1778 // Now scan the table, updating the DB where needed 1779 foreach ($pluginDBList as $plug_path => $plug_info) 1780 { 1781 if ($plug_info['status'] == 'read') 1782 { // In table, not on server - delete it 1783 $sql->delete('plugin', "`plugin_id`={$plug_info['plugin_id']}"); 1784 // echo "Deleted: ".$plug_path."<br />"; 1785 } 1786 if ($plug_info['status'] == 'update') 1787 { 1788 $temp = array(); 1789 foreach ($this->all_editable_db_fields as $p_f) 1790 { 1791 $temp[] = "`{$p_f}` = '{$plug_info[$p_f]}'"; 1792 } 1793 $sql->update('plugin', implode(", ", $temp)." WHERE `plugin_id`={$plug_info['plugin_id']}"); 1794 // echo "Updated: ".$plug_path."<br />"; 1795 } 1796 } 1797 if ($sp/* && vartrue($p_installed)*/) 1798 { 1799 e107::getConfig('core')->setPref('plug_installed', $p_installed); 1800 $this->rebuildUrlConfig(); 1801 e107::getConfig('core')->save(true,false,false); 1802 } 1803 1804 // Triggering system (post) event. 1805 e107::getEvent()->trigger('system_plugins_table_updated', array( 1806 'mode' => $mode, 1807 )); 1808 } 1809 1810 private function manage_category($cat) 1811 { 1812 $this->log("Running ".__FUNCTION__); 1813 if (vartrue($cat) && in_array($cat, $this->accepted_categories)) 1814 { 1815 return $cat; 1816 } 1817 else 1818 { 1819 return 'misc'; 1820 } 1821 } 1822 1823 private function manage_icons($plugin = '', $function = '') 1824 { 1825 $this->log("Running ".__FUNCTION__); 1826 if ($plugin == '') 1827 { 1828 return null; 1829 } 1830 1831 $mes = e107::getMessage(); 1832 $sql = e107::getDb(); 1833 $tp = e107::getParser(); 1834 $med = e107::getMedia(); 1835 1836 if ($function == 'install' || $function == 'upgrade') 1837 { 1838 $med->importIcons(e_PLUGIN.$plugin); 1839 return null; 1840 } 1841 1842 if ($function == 'uninstall') 1843 { 1844 if (vartrue($this->unInstallOpts['delete_ipool'], FALSE)) 1845 { 1846 $status = ($med->removePath(e_PLUGIN.$plugin, 'icon')) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 1847 $mes->add(IMALAN_164, $status); 1848 $this->log("Deleted Icons from Media-Manager "); // No LANS 1849 } 1850 return null; 1851 } 1852 1853 } 1854 1855 /** 1856 * Returns details of a plugin from the plugin table from it's ID 1857 * @deprecated 1858 * @param int|string $id 1859 * @return array plugin info 1860 */ 1861 static function getPluginRecord($id) 1862 { 1863 1864 $path = (!is_numeric($id)) ? $id : false; 1865 $id = (int)$id; 1866 1867 if(!empty($path)) 1868 { 1869 // $bla = e107::getPlug()->load($path); 1870 if($tmp = e107::getPlug()->load($path)->getFields(true)) 1871 { 1872 return $tmp; 1873 } 1874 } 1875 else // log all deprecated calls made using an integer so they can be removed in future. 1876 { 1877 $dbgArr = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,3); 1878 unset($dbgArr[0]); 1879 e107::getLog()->addDebug("Deprecated call to getPluginRecord() using integer.".print_a($dbgArr,true)); 1880 1881 } 1882 1883 $sql = e107::getDb(); 1884 $getinfo_results = array(); 1885 1886 1887 $qry = "plugin_id = " . $id; 1888 $qry .= ($path != false) ? " OR plugin_path = '" . $path . "' " : ""; 1889 1890 if ($sql->select('plugin', '*', $qry)) { 1891 $getinfo_results[$id] = $sql->fetch(); 1892 } 1893 1894 return $getinfo_results[$id]; 1895 } 1896 1897 private function setUe() 1898 { 1899 if (!isset($this->module['ue'])) 1900 { 1901 include_once(e_HANDLER.'user_extended_class.php'); 1902 $this->module['ue'] = new e107_user_extended; 1903 } 1904 } 1905 1906 /** 1907 * User field name, based on its type 1908 * @param string $folder plugin folder 1909 * @param int $type normalized field type 1910 * @param string $name field name 1911 * @return string field name 1912 */ 1913 private function ue_field_name($folder, $type, $name) 1914 { 1915 if($type == EUF_PREFIELD || $type == EUF_CATEGORY) 1916 { 1917 return $name; // no plugin_plugname_ prefix 1918 } 1919 return 'plugin_'.$folder.'_'.$name; 1920 } 1921 1922 /** 1923 * Normalize type 1924 * @param array $attrib parsed from XML user field definitions 1925 * @return integer type ID 1926 */ 1927 private function ue_field_type($attrib) 1928 { 1929 $field_type = $attrib['type']; 1930 $type = defined($field_type) ? constant($field_type) : $field_type; 1931 if(!is_numeric($type)) 1932 { 1933 // normalize further 1934 $this->setUe(); 1935 $type = $this->module['ue']->typeArray[$type]; 1936 } 1937 return $type; 1938 } 1939 1940 /** 1941 * Type number to type name 1942 * @param integer $typeId 1943 * @return string type name 1944 */ 1945 private function ue_field_type_name($typeId) 1946 { 1947 if(is_numeric($typeId)) 1948 { 1949 $this->setUe(); 1950 return array_search($typeId, $this->module['ue']->typeArray); 1951 } 1952 return $typeId; 1953 } 1954 1955 /** 1956 * Field attributes ($field_attrib array) as they have to be defined in plugin.xml: 1957 * name - REQUIRED string 1958 * text - (string|constant name) field label 1959 * type - REQUIRED (constant name) see EUF_* constants in e107_user_extended class 1960 * regex - regex validation string 1961 * required - 0-not requried, don't show on signup; 1 - required, show on signup; 2-not required, show on signup 1962 * allow_hide (0|1) - allow user to hide this field on profile page 1963 * read, write, applicable - classes, see e_UC_* defines 1964 * values - comma separated values (if required) 1965 * default - default value 1966 * order - (number) 1967 * parent - (string) category name for this field 1968 * system - (0|1) - field wont be shown if it's system, NOTE - default value if system is not set is 1! 1969 * 1970 * @param string $action - add|remove 1971 * @param string $field_name normalized field name (see self::ue_field_name()) 1972 * @param array $field_attrib 1973 * @param string $field_source used for system user fields 1974 * 1975 * @return boolean success 1976 */ 1977 private function manage_extended_field($action, $field_name, $field_attrib, $field_source = '') 1978 { 1979 $this->log("Running ".__FUNCTION__); 1980 $mes = e107::getMessage(); 1981 $this->setUe(); 1982 1983 $type = $this->ue_field_type($field_attrib); 1984 $type_name = $this->ue_field_type_name($type); 1985 1986 $mes->addDebug("Extended Field: ".$action.": ".$field_name." : ".$type_name); 1987 1988 // predefined 1989 if($type == EUF_PREFIELD) 1990 { 1991 1992 $preList = $this->module['ue']->parse_extended_xml(''); // passed value currently not used at all, could be file path in the near future 1993 if($preList && isset($preList[$field_name])) 1994 { 1995 $preField = $preList[$field_name]; 1996 if($preField) 1997 { 1998 $field_attrib = array_merge($preField, $field_attrib); // merge 1999 // predefined type - numeric value, constant or as defined in user_extended_class::typeArray 2000 $field_attrib['type'] = $type = $this->ue_field_type($preField); // override type 2001 } 2002 else 2003 { 2004 return false; 2005 } 2006 } 2007 2008 } 2009 // not allowed for categories 2010 elseif($type == EUF_CATEGORY) 2011 { 2012 $field_attrib['parent'] = 0; 2013 } 2014 2015 if ($action == 'add') 2016 { 2017 // system field 2018 if($field_attrib['system']) 2019 { 2020 return $this->module['ue']->user_extended_add_system($field_name, $type, varset($field_attrib['default'], ''), $field_source); 2021 } 2022 2023 // new - add non-system extended field 2024 2025 // classes 2026 $field_attrib['read'] = varset($field_attrib['read'], 'e_UC_MEMBER'); 2027 $field_attrib['write'] = varset($field_attrib['read'], 'e_UC_MEMBER'); 2028 $field_attrib['applicable'] = varset($field_attrib['applicable'], 'e_UC_MEMBER'); 2029 2030 // manage parent 2031 if(vartrue($field_attrib['parent'])) 2032 { 2033 foreach ($this->module['ue']->catDefinitions as $key => $value) 2034 { 2035 if($value['user_extended_struct_name'] == $field_attrib['parent']) 2036 { 2037 $field_attrib['parent'] = $key; 2038 break; 2039 } 2040 } 2041 if(!is_numeric($field_attrib['parent'])) $field_attrib['parent'] = 0; 2042 } 2043 else $field_attrib['parent'] = 0; 2044 2045 2046 // manage required (0, 1, 2) 2047 if(!isset($field_attrib['required'])) 2048 { 2049 $field_attrib['required'] = 0; 2050 } 2051 2052 // manage params 2053 $field_attrib['parms'] = ''; 2054 2055 // validation and parms 2056 $include = varset($field_attrib['include_text']); 2057 $regex = varset($field_attrib['regex']); 2058 $hide = vartrue($field_attrib['allow_hide']) ? 1 : 0; 2059 $failmsg = ''; 2060 if($regex || $hide) 2061 { 2062 // failmsg only when required 2063 if($field_attrib['required'] == 1 || $regex) 2064 $failmsg = vartrue($field_attrib['error']) ? $field_attrib['error'] : 'LAN_UE_FAIL_'.strtoupper($field_name); 2065 2066 $field_attrib['parms'] = $include."^,^".$regex."^,^".$failmsg.'^,^'.$hide; 2067 } 2068 2069 //var_dump($field_attrib, $field_name, $type); 2070 $mes->addDebug("Extended Field: ".print_a($field_attrib,true)); 2071 2072 $status = $this->module['ue']->user_extended_add( 2073 $field_name, 2074 varset($field_attrib['text'], "LAN_UE_".strtoupper($field_name)), 2075 $type, 2076 $field_attrib['parms'], 2077 varset($field_attrib['values'], ''), 2078 varset($field_attrib['default'], ''), 2079 $field_attrib['required'], 2080 defset($field_attrib['read'], e_UC_MEMBER), 2081 defset($field_attrib['write'], e_UC_MEMBER), 2082 defset($field_attrib['applicable'], e_UC_MEMBER), 2083 varset($field_attrib['order'], ''), 2084 $field_attrib['parent'] 2085 ); 2086 2087 // db fields handling 2088 if($status && $type == EUF_DB_FIELD) 2089 { 2090 // handle DB, use original non-modified name value 2091 $status = !$this->manage_extended_field_sql('add', $field_attrib['name']); // reverse logic - sql method do a error check 2092 } 2093 2094 // refresh categories - sadly the best way so far... need improvement (inside ue class) 2095 if($status && $type == EUF_CATEGORY) 2096 { 2097 $cats = $this->module['ue']->user_extended_get_categories(false); 2098 foreach ($cats as $cat) 2099 { 2100 $this->module['ue']->catDefinitions[$cat['user_extended_struct_id']] = $cat; 2101 } 2102 } 2103 2104 return $status; 2105 } 2106 2107 if ($action == 'remove') 2108 { 2109 //var_dump($field_attrib, $field_name, $type); 2110 $status = $this->module['ue']->user_extended_remove($field_name, $field_name); 2111 if($status && $type == EUF_DB_FIELD) 2112 { 2113 $status = $this->manage_extended_field_sql('remove', $field_attrib['name']); 2114 } 2115 2116 return $status; 2117 } 2118 2119 return false; 2120 } 2121 2122 private function manage_extended_field_sql($action, $field_name) 2123 { 2124 $this->log("Running ".__FUNCTION__); 2125 $f = e_CORE.'sql/extended_'.preg_replace('/[^\w]/', '', $field_name).'.php'; // quick security, always good idea 2126 2127 if(!is_readable($f)) return false; 2128 2129 // TODO - taken from user_extended Administration, need to be refined :/ 2130 // FIXME - use sql parse handler 2131 $error = FALSE; 2132 $count = 0; 2133 2134 $sql = e107::getDb(); 2135 2136 2137 if($action == 'add') 2138 { 2139 $sql_data = file_get_contents($f); 2140 2141 $search[0] = "CREATE TABLE "; $replace[0] = "CREATE TABLE ".MPREFIX; 2142 $search[1] = "INSERT INTO "; $replace[1] = "INSERT INTO ".MPREFIX; 2143 2144 preg_match_all("/create(.*?)myisam;/si", $sql_data, $creation); 2145 foreach($creation[0] as $tab) 2146 { 2147 $query = str_replace($search,$replace,$tab); 2148 if(!$sql->gen($query)) 2149 { 2150 $error = TRUE; 2151 } 2152 $count++; 2153 } 2154 2155 preg_match_all("/insert(.*?);/si", $sql_data, $inserts); 2156 foreach($inserts[0] as $ins) 2157 { 2158 $qry = str_replace($search,$replace,$ins); 2159 if(!$sql->gen($qry)) 2160 { 2161 $error = TRUE; 2162 } 2163 $count++; 2164 } 2165 2166 if(!$count) $error = TRUE; 2167 2168 return $error; 2169 } 2170 2171 //remove 2172 if($action == 'remove') 2173 { 2174 // executed only if the sql file exists! 2175 return $sql->gen("DROP TABLE ".MPREFIX."user_extended_".$field_name) ? true : false; 2176 } 2177 } 2178 2179 private function manage_userclass($action, $class_name, $class_description='') 2180 { 2181 $this->log("Running ".__FUNCTION__); 2182 $e107 = e107::getInstance(); 2183 $tp = e107::getParser(); 2184 $sql = e107::getDb(); 2185 $mes = e107::getMessage(); 2186 2187 $mes->addDebug("Userclass: ".$action.": ".$class_name." : ".$class_description); 2188 2189 if (!$e107->user_class->isAdmin()) 2190 { 2191 $e107->user_class = new user_class_admin; // We need the extra methods of the admin extension 2192 } 2193 2194 $class_name = strip_tags(strtoupper($class_name)); 2195 if ($action == 'add') 2196 { 2197 if ($e107->user_class->ucGetClassIDFromName($class_name) !== FALSE) 2198 { // Class already exists. 2199 return TRUE; // That's probably OK 2200 } 2201 $i = $e107->user_class->findNewClassID(); 2202 if ($i !== FALSE) 2203 { 2204 $tmp = array(); 2205 $tmp['userclass_id'] = $i; 2206 $tmp['userclass_name'] = $class_name; 2207 $tmp['userclass_description'] = $class_description; 2208 $tmp['userclass_editclass'] = e_UC_ADMIN; 2209 $tmp['userclass_visibility'] = e_UC_ADMIN; 2210 $tmp['userclass_type'] = UC_TYPE_STD; 2211 $tmp['userclass_parent'] = e_UC_NOBODY; 2212 $tmp['_FIELD_TYPES']['userclass_editclass'] = 'int'; 2213 $tmp['_FIELD_TYPES']['userclass_visibility'] = 'int'; 2214 $tmp['_FIELD_TYPES']['userclass_id'] = 'int'; 2215 $tmp['_FIELD_TYPES']['_DEFAULT'] = 'todb'; 2216 return $e107->user_class->add_new_class($tmp); 2217 } 2218 else 2219 { 2220 return NULL; 2221 } 2222 } 2223 if ($action == 'remove') 2224 { 2225 $classID = $e107->user_class->ucGetClassIDFromName($class_name); 2226 if (($classID !== FALSE) && ($e107->user_class->deleteClassAndUsers($classID) === TRUE)) 2227 { 2228 return TRUE; 2229 } 2230 else 2231 { 2232 return FALSE; 2233 } 2234 } 2235 2236 return null; 2237 } 2238 2239 private function manage_link($action, $link_url, $link_name, $link_class = 0, $options=array()) 2240 { 2241 2242 $sql = e107::getDb(); 2243 $tp = e107::getParser(); 2244 2245 if (!is_numeric($link_class)) 2246 { 2247 $link_class = strtolower($link_class); 2248 $plug_perm['everyone'] = e_UC_PUBLIC; 2249 $plug_perm['guest'] = e_UC_GUEST; 2250 $plug_perm['member'] = e_UC_MEMBER; 2251 $plug_perm['mainadmin'] = e_UC_MAINADMIN; 2252 $plug_perm['admin'] = e_UC_ADMIN; 2253 $plug_perm['nobody'] = e_UC_NOBODY; 2254 $link_class = ($plug_perm[$link_class]) ? intval($plug_perm[$link_class]) : e_UC_PUBLIC; 2255 } 2256 2257 2258 $link_url = $tp->toDB($link_url, true); 2259 $link_name = $tp->toDB($link_name, true); 2260 $path = str_replace("../", "", $link_url); // This should clean up 'non-standard' links 2261 $path = $tp->createConstants($path); // Add in standard {e_XXXX} directory constants if we can 2262 2263 if ($action == 'add') 2264 { 2265 $link_t = $sql->count('links'); 2266 if (!$sql->count('links', '(*)', "WHERE link_url = '{$path}' OR link_name = '{$link_name}'")) 2267 { 2268 $linkData = array( 2269 'link_name' => $link_name, 2270 'link_url' => $path, 2271 'link_description' => vartrue($options['link_desription'],''), 2272 'link_button' => vartrue($options['link_icon'],''), 2273 'link_category' => '1', 2274 'link_order' => $link_t + 1, 2275 'link_parent' => '0', 2276 'link_open' => '0', 2277 'link_class' => vartrue($link_class,'0'), 2278 'link_function' => vartrue($options['link_function']), 2279 'link_sefurl' => vartrue($options['link_sef']), 2280 'link_owner' => vartrue($options['link_owner']) 2281 ); 2282 return $sql->insert('links', $linkData); 2283 } 2284 else 2285 { 2286 return null; 2287 } 2288 } 2289 if ($action == 'remove') 2290 { 2291 //v2.x 2292 if(vartrue($options['link_owner']) && $sql->select('links', 'link_id', "link_owner = '".$options['link_owner']."'")) 2293 { 2294 return $sql->delete('links', "link_owner = '".$options['link_owner']."' "); 2295 } 2296 2297 // Look up by URL if we can - should be more reliable. Otherwise try looking up by name (as previously) 2298 if (($path && $sql->select('links', 'link_id,link_order', "link_url = '{$path}'")) || $sql->select('links', 'link_id,link_order', "link_name = '{$link_name}'")) 2299 { 2300 $row = $sql->fetch(); 2301 $sql->db_Update('links', "link_order = link_order - 1 WHERE link_order > {$row['link_order']}"); 2302 return $sql->delete('links', "link_id = {$row['link_id']}"); 2303 } 2304 } 2305 } 2306 2307 // DEPRECATED in 0.8 - 2308 // Update prefs array according to $action 2309 // $prefType specifies the storage type - may be 'pref', 'listPref' or 'arrayPref' 2310 /** 2311 * @deprecated See XmlPrefs(); Left for BC. 2312 * @param $action 2313 * @param $var 2314 * @param string $prefType 2315 * @param string $path 2316 * @param bool $unEscape 2317 * @return null|void 2318 */ 2319 function manage_prefs($action, $var, $prefType = 'pref', $path = '', $unEscape = FALSE) 2320 { 2321 $this->log("Running ".__FUNCTION__); 2322 global $pref; 2323 if (!is_array($var)) 2324 return null; 2325 if (($prefType == 'arrayPref') && ($path == '')) 2326 return null; 2327 foreach ($var as $k => $v) 2328 { 2329 if ($unEscape) 2330 { 2331 $v = str_replace(array('\{', '\}'), array('{', '}'), $v); 2332 } 2333 switch ($prefType) 2334 { 2335 case 'pref': 2336 switch ($action) 2337 { 2338 case 'add': 2339 $pref[$k] = $v; 2340 break; 2341 2342 case 'update' : 2343 case 'upgrade' : 2344 case 'refresh': 2345 // Only update if $pref doesn't exist 2346 if (!isset($pref[$k])) 2347 $pref[$k] = $v; 2348 break; 2349 2350 case 'remove': 2351 if (is_numeric($k)) 2352 { // Sometimes arrays specified with value being the name of the key to delete 2353 unset($pref[$var[$k]]); 2354 } 2355 else 2356 { // This is how the array should be specified - key is the name of the pref 2357 unset($pref[$k]); 2358 } 2359 break; 2360 } 2361 break; 2362 case 'listPref': 2363 $tmp = array(); 2364 if (isset($pref[$k])) 2365 $tmp = explode(',', $pref[$k]); 2366 switch ($action) 2367 { 2368 case 'add': 2369 case 'update' : 2370 case 'upgrade' : 2371 case 'refresh': 2372 if (!in_array($v, $tmp)) 2373 $tmp[] = $v; 2374 break; 2375 case 'remove': 2376 if (($tkey = array_search($v, $tmp)) !== FALSE) 2377 unset($tmp[$tkey]); 2378 break; 2379 } 2380 $pref[$k] = implode(',', $tmp); // Leaves an empty element if no values - probably acceptable or even preferable 2381 break; 2382 case 'arrayPref': 2383 switch ($action) 2384 { 2385 case 'add': 2386 $pref[$k][$path] = $v; 2387 break; 2388 case 'update' : 2389 case 'upgrade' : 2390 case 'refresh': 2391 if (!isset($pref[$k][$path])) 2392 $pref[$k][$path] = $v; 2393 break; 2394 case 'remove': 2395 if (isset($pref[$k][$path])) 2396 unset($pref[$k][$path]); // Leaves an empty element if no values - probably acceptable or even preferable 2397 break; 2398 } 2399 break; 2400 } 2401 } 2402 2403 e107::getConfig('core')->setPref($pref)->save(true,false,false); 2404 2405 return null; 2406 2407 } 2408 2409 function manage_comments($action, $comment_id) 2410 { 2411 $this->log("Running ".__FUNCTION__); 2412 $sql = e107::getDb(); 2413 $tp = e107::getParser(); 2414 2415 $tmp = array(); 2416 if ($action == 'remove') 2417 { 2418 foreach ($comment_id as $com) 2419 { 2420 $tmp[] = "comment_type='".$tp->toDB($com, true)."'"; 2421 } 2422 $qry = implode(" OR ", $tmp); 2423 // echo $qry."<br />"; 2424 return $sql->delete('comments', $qry); 2425 } 2426 } 2427 2428 // Handle table updates - passed an array of actions. 2429 // $var array: 2430 // For 'add' - its a query to create the table 2431 // For 'upgrade' - its a query to modify the table (not called from the plugin.xml handler) 2432 // For 'remove' - its a table name 2433 // 'upgrade' and 'remove' operate on all language variants of the same table 2434 function manage_tables($action, $var) 2435 { 2436 $this->log("Running ".__FUNCTION__); 2437 $sql = e107::getDb(); 2438 $mes = e107::getMessage(); 2439 2440 if (!is_array($var)) 2441 return FALSE; // Return if nothing to do 2442 $error = false; 2443 $error_data = array(); 2444 switch ($action) 2445 { 2446 case 'add': 2447 foreach ($var as $tab) 2448 { 2449 2450 $tab = str_replace("TYPE=MyISAM","ENGINE=MyISAM",$tab); 2451 $tab = str_replace("IF NOT EXISTS", "", $tab); 2452 2453 if(!preg_match("/MyISAM.*CHARSET ?= ?utf8/i",$tab)) 2454 { 2455 $tab = str_replace("MyISAM", "MyISAM DEFAULT CHARSET=utf8", $tab); 2456 } 2457 2458 2459 $mes->addDebug($tab); 2460 if (false === $sql->db_Query($tab)) 2461 { 2462 $error = true; 2463 $error_data[] = $tab; 2464 } 2465 } 2466 break; 2467 case 'upgrade': 2468 foreach ($var as $tab) 2469 { 2470 if (false === $sql->db_Query_all($tab)) 2471 { 2472 $error = true; 2473 $error_data[] = $tab; 2474 } 2475 } 2476 break; 2477 case 'remove': 2478 foreach ($var as $tab) 2479 { 2480 $qry = 'DROP TABLE '.MPREFIX.$tab; 2481 if (!$sql->db_Query_all($qry)) 2482 { 2483 $error = true; 2484 $error_data[] = $tab; 2485 } 2486 } 2487 break; 2488 } 2489 // doesn't exit the loop now, returns true on success 2490 // or error queries (string) 2491 return (!$error ? true : (!empty($$error_data) ? implode('<br />', $error_data) : false)); 2492 } 2493 2494 // DEPRECATED for 0.8 xml files - See XmlPrefs(); 2495 // Handle prefs from arrays (mostly 0.7 stuff, possibly apart from the special cases) 2496 function manage_plugin_prefs($action, $prefname, $plugin_folder, $varArray = '') 2497 { // These prefs are 'cumulative' - several plugins may contribute an array element 2498 // global $pref; 2499 /* 2500 if ($prefname == 'plug_sc' || $prefname == 'plug_bb') 2501 { // Special cases - shortcodes and bbcodes - each plugin may contribute several elements 2502 foreach($varArray as $code) 2503 { 2504 $prefvals[] = "$code:$plugin_folder"; 2505 } 2506 } 2507 else 2508 { 2509 */ 2510 $pref = e107::getPref(); 2511 2512 $prefvals[] = $varArray; 2513 // $prefvals[] = $plugin_folder; 2514 // } 2515 $curvals = explode(',', $pref[$prefname]); 2516 2517 if ($action == 'add') 2518 { 2519 $newvals = array_merge($curvals, $prefvals); 2520 } 2521 if ($action == 'remove') 2522 { 2523 foreach ($prefvals as $v) 2524 { 2525 if (($i = array_search($v, $curvals)) !== FALSE) 2526 { 2527 unset($curvals[$i]); 2528 } 2529 } 2530 $newvals = $curvals; 2531 } 2532 $newvals = array_unique($newvals); 2533 $pref[$prefname] = implode(',', $newvals); 2534 2535 if (substr($pref[$prefname], 0, 1) == ",") 2536 { 2537 $pref[$prefname] = substr($pref[$prefname], 1); 2538 } 2539 2540 e107::getConfig('core')->setPref($pref); 2541 e107::getConfig('core')->save(true,false,false); 2542 2543 } 2544 2545 function manage_search($action, $eplug_folder) 2546 { 2547 global $sysprefs; 2548 $sql = e107::getDb(); 2549 2550 $search_prefs = e107::getConfig('search')->getPref(); 2551 2552 // $search_prefs = $sysprefs -> getArray('search_prefs'); 2553 $default = file_exists(e_PLUGIN.$eplug_folder.'/e_search.php') ? TRUE : FALSE; 2554 $comments = file_exists(e_PLUGIN.$eplug_folder.'/search/search_comments.php') ? TRUE : FALSE; 2555 if ($action == 'add') 2556 { 2557 $install_default = $default ? TRUE : FALSE; 2558 $install_comments = $comments ? TRUE : FALSE; 2559 } 2560 else 2561 if ($action == 'remove') 2562 { 2563 $uninstall_default = isset($search_prefs['plug_handlers'][$eplug_folder]) ? TRUE : FALSE; 2564 $uninstall_comments = isset($search_prefs['comments_handlers'][$eplug_folder]) ? TRUE : FALSE; 2565 } 2566 else 2567 if ($action == 'upgrade') 2568 { 2569 if (isset($search_prefs['plug_handlers'][$eplug_folder])) 2570 { 2571 $uninstall_default = $default ? FALSE : TRUE; 2572 } 2573 else 2574 { 2575 $install_default = $default ? TRUE : FALSE; 2576 } 2577 if (isset($search_prefs['comments_handlers'][$eplug_folder])) 2578 { 2579 $uninstall_comments = $comments ? FALSE : TRUE; 2580 } 2581 else 2582 { 2583 $install_comments = $comments ? TRUE : FALSE; 2584 } 2585 } 2586 if (vartrue($install_default)) 2587 { 2588 $search_prefs['plug_handlers'][$eplug_folder] = array('class' => 0, 'pre_title' => 1, 'pre_title_alt' => '', 'chars' => 150, 'results' => 10); 2589 } 2590 else 2591 if (vartrue($uninstall_default)) 2592 { 2593 unset($search_prefs['plug_handlers'][$eplug_folder]); 2594 } 2595 if (vartrue($install_comments)) 2596 { 2597 $comments_type_id = ''; 2598 require_once(e_PLUGIN.$eplug_folder.'/search/search_comments.php'); 2599 $search_prefs['comments_handlers'][$eplug_folder] = array('id' => $comments_type_id, 'class' => 0, 'dir' => $eplug_folder); 2600 } 2601 else 2602 if (vartrue($uninstall_comments)) 2603 { 2604 unset($search_prefs['comments_handlers'][$eplug_folder]); 2605 } 2606 2607 // e107::getConfig('search')->setPref($search_prefs)->save(true,false,false); 2608 2609 } 2610 2611 function manage_notify($action, $eplug_folder) 2612 { 2613 $this->log("Running ".__FUNCTION__); 2614 $tp = e107::getParser(); 2615 // $notify_prefs = $sysprefs -> get('notify_prefs'); 2616 // $notify_prefs = $eArrayStorage -> ReadArray($notify_prefs); 2617 2618 $notify_prefs = e107::getConfig('notify'); 2619 $e_notify = file_exists(e_PLUGIN.$eplug_folder.'/e_notify.php') ? TRUE : FALSE; 2620 if ($action == 'add') 2621 { 2622 $install_notify = $e_notify ? TRUE : FALSE; 2623 } 2624 else 2625 if ($action == 'remove') 2626 { 2627 $uninstall_notify = $notify_prefs->isData('plugins/'.$eplug_folder); //isset($notify_prefs['plugins'][$eplug_folder]) ? TRUE : FALSE; 2628 } 2629 else 2630 if ($action == 'upgrade') 2631 { 2632 if ($notify_prefs->isData('plugins/'.$eplug_folder)) 2633 { 2634 $uninstall_notify = $e_notify ? FALSE : TRUE; 2635 } 2636 else 2637 { 2638 $install_notify = $e_notify ? TRUE : FALSE; 2639 } 2640 } 2641 2642 $config_events = array(); // Notice removal 2643 if (vartrue($install_notify)) 2644 { 2645 $notify_prefs->setPref('plugins/'.$eplug_folder, 1); //$notify_prefs['plugins'][$eplug_folder] = TRUE; 2646 2647 require_once(e_PLUGIN.$eplug_folder.'/e_notify.php'); 2648 foreach ($config_events as $event_id => $event_text) 2649 { 2650 $notify_prefs->setPref('event/'.$event_id.'/class', e_UC_NOBODY) 2651 ->setPref('event/'.$event_id.'/email', ''); 2652 //$notify_prefs['event'][$event_id] = array('class' => e_UC_NOBODY, 'email' => ''); 2653 } 2654 } 2655 else 2656 if (vartrue($uninstall_notify)) 2657 { 2658 $notify_prefs->removePref('plugins/'.$eplug_folder); 2659 //unset($notify_prefs['plugins'][$eplug_folder]); 2660 require_once(e_PLUGIN.$eplug_folder.'/e_notify.php'); 2661 foreach ($config_events as $event_id => $event_text) 2662 { 2663 $notify_prefs->removePref('event/'.$event_id); 2664 //unset($notify_prefs['event'][$event_id]); 2665 } 2666 } 2667 //$s_prefs = $tp -> toDB($notify_prefs); 2668 //$s_prefs = e107::getArrayStorage()->WriteArray($s_prefs); 2669 //e107::getDb() -> db_Update("core", "e107_value='".$s_prefs."' WHERE e107_name='notify_prefs'"); 2670 $notify_prefs->save(false,false,false); 2671 } 2672 2673 /** 2674 * Rebuild URL configuration values 2675 * Note - new core system pref values will be set, but not saved 2676 * e107::getConfig()->save() is required outside after execution of this method 2677 * @return void 2678 */ 2679 public function rebuildUrlConfig() 2680 { 2681 $this->log("Running ".__FUNCTION__); 2682 $modules = eRouter::adminReadModules(); // get all available locations, non installed plugins will be ignored 2683 $config = eRouter::adminBuildConfig(e107::getPref('url_config'), $modules); // merge with current config 2684 $locations = eRouter::adminBuildLocations($modules); // rebuild locations pref 2685 $aliases = eRouter::adminSyncAliases(e107::getPref('url_aliases'), $config); // rebuild aliases 2686 2687 // set new values, changes should be saved outside this methods 2688 /* e107::getConfig() 2689 ->set('url_aliases', $aliases) 2690 ->set('url_config', $config) 2691 ->set('url_modules', $modules) 2692 ->set('url_locations', $locations); 2693 */ 2694 eRouter::clearCache(); 2695 } 2696 2697 function displayArray(&$array, $msg = '') 2698 { 2699 $txt = ($msg ? $msg.'<br />' : ''); 2700 foreach ($array as $_k => $_v) 2701 { 2702 $txt .= "{$_k} -> {$_v}<br />"; 2703 } 2704 $txt .= '<br />'; 2705 return $txt; 2706 } 2707 2708 2709 private function log($message) 2710 { 2711 $this->log[] = $message; 2712 } 2713 2714 public function getLog() 2715 { 2716 $text = $this->log; 2717 2718 $this->log = array(); 2719 2720 return $text; 2721 2722 } 2723 2724 /** 2725 * Install routine for XML file 2726 * @param mixed $id (the number of the plugin in the DB) or the path to the plugin folder. eg. 'forum' 2727 * @param string $function install|upgrade|uninstall|refresh (adds things that are missing, but doesn't change any existing settings) 2728 * @param array $options [optional] an array of possible options - ATM used only for uninstall: 2729 * 'delete_userclasses' - to delete userclasses created 2730 * 'delete_tables' - to delete DB tables 2731 * 'delete_xfields' - to delete extended fields 2732 * 'delete_ipool' - to delete icon pool entry 2733 * + any defined in <pluginname>_setup.php in the uninstall_options() method. 2734 * @return bool 2735 */ 2736 function install_plugin_xml($id, $function = '', $options = null) 2737 { 2738 2739 $pref = e107::getPref(); 2740 $sql = e107::getDb(); 2741 $mes = e107::getMessage(); 2742 $event = e107::getEvent(); 2743 2744 $this->log("Running Plugin: ".$function); 2745 2746 $error = array(); // Array of error messages 2747 $canContinue = TRUE; // Clear flag if must abort part way through 2748 2749 if(is_array($id)) // plugin info array 2750 { 2751 $plug = $id; 2752 $id = (int) $plug['plugin_id']; 2753 } 2754 elseif(is_numeric($id)) // plugin database id 2755 { 2756 $id = (int) $id; 2757 $plug = e107plugin::getPluginRecord($id); // Get plugin info from DB 2758 } 2759 else // Plugin Path. 2760 { 2761 $id = $this->getId($id); 2762 $plug = e107plugin::getPluginRecord($id); // Get plugin info from DB 2763 } 2764 2765 $this->current_plug = $plug; 2766 2767 $txt = ''; 2768 $path = e_PLUGIN.$plug['plugin_path'].'/'; 2769 2770 $this->plugFolder = $plug['plugin_path']; 2771 2772 2773 2774 $this->unInstallOpts = $options; 2775 2776 $addons = explode(',', $plug['plugin_addons']); 2777 $sql_list = array(); 2778 foreach ($addons as $addon) 2779 { 2780 if (substr($addon, -4) == '_sql') 2781 { 2782 $sql_list[] = $addon.'.php'; 2783 } 2784 } 2785 2786 if (!file_exists($path.'plugin.xml') || $function == '') 2787 { 2788 $error[] = EPL_ADLAN_77; 2789 $this->log("Cannot find plugin.xml"); // Do NOT LAN. Debug Only. 2790 $canContinue = false; 2791 } 2792 2793 if ($canContinue && $this->parse_plugin_xml($plug['plugin_path'])) 2794 { 2795 $plug_vars = $this->plug_vars; 2796 $this->log("Vars: ".print_r($plug_vars,true)); 2797 } 2798 else 2799 { 2800 $error[] = EPL_ADLAN_76; 2801 $this->log("Error in plugin.xml"); 2802 $canContinue = FALSE; 2803 } 2804 2805 // Load install language file and set lan_global pref. 2806 $this->XmlLanguageFiles($function, varset($plug_vars['languageFiles']), 'pre'); // First of all, see if there's a language file specific to install 2807 2808 // Next most important, if installing or upgrading, check that any dependencies are met 2809 if($canContinue && ($function != 'uninstall') && isset($plug_vars['dependencies'])) 2810 { 2811 $canContinue = $this->XmlDependencies($plug_vars['dependencies']); 2812 } 2813 2814 if ($canContinue === false) 2815 { 2816 $this->log("Cannot Continue. Line:".__LINE__); // Do NOT LAN. Debug Only. 2817 return false; 2818 } 2819 2820 // All the dependencies are OK - can start the install now 2821 2822 // Run custom {plugin}_setup install/upgrade etc. for INSERT, ALTER etc. etc. etc. 2823 $ret = $this->execute_function($plug['plugin_path'], $function, 'pre'); 2824 if (!is_bool($ret)) 2825 { 2826 $txt .= $ret; 2827 } 2828 2829 // Handle tables 2830 $this->XmlTables($function, $plug, $options); 2831 2832 if (varset($plug_vars['adminLinks'])) 2833 { 2834 $this->XmlAdminLinks($function, $plug_vars['adminLinks']); 2835 } 2836 2837 if (!empty($plug_vars['siteLinks'])) 2838 { 2839 $this->XmlSiteLinks($function, $plug_vars); 2840 } 2841 2842 if (varset($plug_vars['mainPrefs'])) //Core pref items <mainPrefs> 2843 { 2844 $this->XmlPrefs('core', $function, $plug_vars['mainPrefs']); 2845 } 2846 2847 if (varset($plug_vars['pluginPrefs'])) //Plugin pref items <pluginPrefs> 2848 { 2849 $this->XmlPrefs($plug['plugin_path'], $function, $plug_vars['pluginPrefs']); 2850 } 2851 2852 if (varset($plug_vars['userClasses'])) 2853 { 2854 $this->XmlUserClasses($function, $plug_vars['userClasses']); 2855 } 2856 2857 if (varset($plug_vars['extendedFields'])) 2858 { 2859 $this->XmlExtendedFields($function, $plug_vars['extendedFields']); 2860 } 2861 2862 if (varset($plug_vars['languageFiles'])) 2863 { 2864 $this->XmlLanguageFiles($function, $plug_vars['languageFiles']); 2865 } 2866 2867 if (varset($plug_vars['bbcodes'])) 2868 { 2869 $this->XmlBBcodes($function, $plug_vars); 2870 } 2871 2872 if (varset($plug_vars['mediaCategories'])) 2873 { 2874 $this->XmlMediaCategories($function, $plug_vars); 2875 } 2876 2877 $this->XmlMenus($this->plugFolder, $function, $plug_vars['files']); 2878 2879 2880 $this->manage_icons($this->plugFolder, $function); 2881 2882 //FIXME 2883 //If any commentIDs are configured, we need to remove all comments on uninstall 2884 if ($function == 'uninstall' && isset($plug_vars['commentID'])) 2885 { 2886 $txt .= 'Removing all plugin comments: ('.implode(', ', $plug_vars['commentID']).')<br />'; 2887 $commentArray = array(); 2888 $this->manage_comments('remove', $commentArray); 2889 } 2890 2891 $this->manage_search($function, $plug_vars['folder']); 2892 $this->manage_notify($function, $plug_vars['folder']); 2893 2894 $eplug_addons = $this->getAddons($plug['plugin_path']); 2895 2896 $p_installed = e107::getPref('plug_installed', array()); // load preference; 2897 2898 if ($function == 'install' || $function == 'upgrade' || $function == 'refresh') 2899 { 2900 $sql->update('plugin', "plugin_installflag = 1, plugin_addons = '{$eplug_addons}', plugin_version = '{$plug_vars['@attributes']['version']}', plugin_category ='".$this->manage_category($plug_vars['category'])."' WHERE plugin_id = ".$id); 2901 $p_installed[$plug['plugin_path']] = $plug_vars['@attributes']['version']; 2902 2903 e107::getConfig('core')->setPref('plug_installed', $p_installed); 2904 //e107::getConfig('core')->save(); - save triggered below 2905 } 2906 2907 if ($function == 'uninstall') 2908 { 2909 $sql->update('plugin', "plugin_installflag = 0, plugin_addons = '{$eplug_addons}', plugin_version = '{$plug_vars['@attributes']['version']}', plugin_category ='".$this->manage_category($plug_vars['category'])."' WHERE plugin_id = ".$id); 2910 unset($p_installed[$plug['plugin_path']]); 2911 2912 e107::getConfig('core')->setPref('plug_installed', $p_installed); 2913 2914 2915 $this->removeCrons($plug_vars); 2916 2917 } 2918 2919 2920 2921 2922 $this->rebuildUrlConfig(); 2923 2924 $this->log("Updated 'plug_installed' core pref. "); 2925 2926 e107::getConfig('core')->save(true, false, false); 2927/* 2928 e107::getPlug()->clearCache()->buildAddonPrefLists(); 2929 2930 if($function === 'install') 2931 { 2932 e107::getPlug()->setInstalled($plug_vars['folder'],$plug_vars['@attributes']['version']); 2933 } 2934*/ 2935 2936 // e107::getPlug()->setInstalled($plug_vars['folder'],$plug_vars['@attributes']['version'])->buildAddonPrefLists(); 2937 2938 // e107::getPlug()->clearCache()->setInstalled($plug_vars['folder'],$plug_vars['@attributes']['version'])->buildAddonPrefLists(); 2939 2940 $this->save_addon_prefs('update'); // to be replaced with buildAddonPrefLists(); once working correctly. 2941 2942 /* if($function == 'install') 2943 { 2944 if(isset($plug_vars['management']['installDone'][0])) 2945 { 2946 $mes->add($plug_vars['management']['installDone'][0], E_MESSAGE_SUCCESS); 2947 } 2948 }*/ 2949 2950 // Run custom {plugin}_setup install/upgrade etc. for INSERT, ALTER etc. etc. etc. 2951 // Call any custom post functions defined in <plugin>_setup.php or the deprecated <management> section 2952 if (!$this->execute_function($plug['plugin_path'], $function, 'post')) 2953 { 2954 if ($function == 'install') 2955 { 2956 $text = EPL_ADLAN_238; 2957 2958 if ($this->plugConfigFile) 2959 { 2960 $text .= "<br /><a class='btn btn-primary' href='".$this->plugConfigFile."'>".LAN_CONFIGURE."</a>"; 2961 } 2962 2963 $mes->addSuccess($text); 2964 } 2965 2966 } 2967 2968 $event->trigger('admin_plugin_'.$function, $plug); 2969 2970 2971 return null; 2972 2973 } 2974 2975 2976 private function removeCrons($plug_vars) 2977 { 2978 $this->log("Running ".__METHOD__); 2979 2980 if(!file_exists(e_PLUGIN. $plug_vars['folder']."/e_cron.php")) 2981 { 2982 return false; 2983 } 2984 2985 if(e107::getDb()->delete('cron', 'cron_function LIKE "'. $plug_vars['folder'] . '::%"')) 2986 { 2987 $this->log($plug_vars['folder']." crons removed successfully."); // no LANs. 2988 e107::getMessage()->addDebug($plug_vars['folder']." crons removed successfully."); // No LAN necessary 2989 } 2990 2991 return false; 2992 2993 } 2994 2995 private function XmlMenus($plug, $function, $files) 2996 { 2997 $this->log("Running ".__FUNCTION__); 2998 2999 $menuFiles = array(); 3000 3001 3002 3003 foreach($files as $file) 3004 { 3005 if($file === 'e_menu.php') 3006 { 3007 continue; 3008 } 3009 3010 if(substr($file,-9) === '_menu.php') 3011 { 3012 $menuFiles[] = basename($file, '.php'); 3013 } 3014 3015 3016 } 3017 3018 $this->log("Scanning for _menu.php files - ". count($menuFiles)." found."); // Debug info, no LAN 3019 3020 3021 if(empty($menuFiles)) 3022 { 3023 return false; 3024 } 3025 3026 3027 switch($function) 3028 { 3029 case "install": 3030 case "refresh": 3031 3032 $this->log("Adding menus to menus table."); // NO LANS - debug info! 3033 3034 foreach($menuFiles as $menu) 3035 { 3036 if(!e107::getMenu()->add($plug, $menu)) 3037 { 3038 $this->log("Couldn't add ".$menu." to menus table."); // NO LAN 3039 } 3040 } 3041 3042 break; 3043 3044 case "uninstall": 3045 3046 $this->log("Removing menus from menus table."); // No Lan 3047 3048 if(!e107::getMenu()->remove($plug)) 3049 { 3050 $this->log("Couldn't remove menus for plugin: ".$plug); // NO LAN 3051 } 3052 3053 break; 3054 3055 } 3056 3057 return null; 3058 } 3059 3060 /** 3061 * Parse {plugin}_sql.php file and install/upgrade/uninstall tables. 3062 * @param $function string install|upgrade|uninstall 3063 * @param $plug - array of plugin data - mostly $plug['plugin_path'] 3064 * @param array $options 3065 */ 3066 function XmlTables($function, $plug, $options = array()) 3067 { 3068 $this->log("Running ".__METHOD__); 3069 3070 $sqlFile = e_PLUGIN.$plug['plugin_path'].'/'.str_replace("_menu","", $plug['plugin_path'])."_sql.php"; 3071 3072 if(!file_exists($sqlFile)) // No File, so return; 3073 { 3074 $this->log("No SQL File Found at: ".$sqlFile); 3075 return null; 3076 } 3077 3078 if(!is_readable($sqlFile)) // File Can't be read. 3079 { 3080 e107::getMessage()->addError("Can't read SQL definition: ".$sqlFile); 3081 $this->log("Can't read SQL definition: ".$sqlFile); 3082 return null; 3083 } 3084 3085 $dbv = e107::getSingleton('db_verify', e_HANDLER."db_verify_class.php"); 3086 // require_once(e_HANDLER."db_verify_class.php"); 3087 // $dbv = new db_verify; 3088 $sql = e107::getDb(); 3089 3090 // Add or Remove Table -------------- 3091 if($function == 'install' || $function == 'uninstall') 3092 { 3093 $contents = file_get_contents($sqlFile); 3094 3095 if(empty($contents)) 3096 { 3097 e107::getMessage()->addError("Can't read SQL definition: ".$sqlFile); 3098 $this->log("Can't read SQL definition: ".$sqlFile); 3099 return null; 3100 } 3101 3102 $tableData = $dbv->getSqlFileTables($contents); 3103 3104 $query = ''; 3105 foreach($tableData['tables'] as $k=>$v) 3106 { 3107 switch($function) 3108 { 3109 case "install": 3110 $query = "CREATE TABLE `".MPREFIX.$v."` (\n"; 3111 $query .= $tableData['data'][$k]; 3112 $query .= "\n) ENGINE=". vartrue($tableData['engine'][$k],"InnoDB")." DEFAULT CHARSET=utf8 "; 3113 3114 $txt = EPL_ADLAN_239." <b>{$v}</b> "; 3115 $status = $sql->db_Query($query) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3116 break; 3117 3118 case "uninstall": 3119 if (!empty($options['delete_tables'])) 3120 { 3121 $query = "DROP TABLE `".MPREFIX.$v."`; "; 3122 $txt = EPL_ADLAN_240." <b> {$v} </b><br />"; 3123 $status = $sql->db_Query_all($query) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3124 3125 } 3126 else 3127 { 3128 $status = E_MESSAGE_SUCCESS; 3129 $txt = "Table {$v} left in place."; 3130 } 3131 break; 3132 } 3133 3134 3135 3136 e107::getMessage()->add($txt, $status); 3137 e107::getMessage()->addDebug($query); 3138 } 3139 3140 } 3141 3142 // Upgrade Table -------------- 3143 if($function == 'upgrade') 3144 { 3145 $dbv->errors = array(); 3146 $dbv->compare($plug['plugin_path']); 3147 if($dbv->errors()) 3148 { 3149 $dbv->compileResults(); 3150 $dbv->runFix(); 3151 } 3152 3153 } 3154 3155 3156 3157 } 3158 3159 3160 /** 3161 * Check if plugin is being used by another plugin before uninstalling it. 3162 * 3163 * @param array $plugin 3164 * Plugin name. 3165 * 3166 * @return boolean 3167 * TRUE if plugin is used, otherwise FALSE. 3168 */ 3169 function isUsedByAnotherPlugin($plugin) 3170 { 3171 $this->log("Running ".__FUNCTION__); 3172 $db = e107::getDb(); 3173 $tp = e107::getParser(); 3174 $mes = e107::getMessage(); 3175 $xml = e107::getXml(); 3176 3177 $pluginIsUsed = false; 3178 $enPlugs = array(); 3179 $usedBy = array(); 3180 3181 // Get list of enabled plugins. 3182 $db->select("plugin", "*", "plugin_id !='' order by plugin_path ASC"); 3183 while($row = $db->fetch()) 3184 { 3185 if($row['plugin_installflag'] == 1) 3186 { 3187 $enPlugs[] = $row['plugin_path']; 3188 } 3189 } 3190 3191 foreach($enPlugs as $enPlug) 3192 { 3193 if(!file_exists(e_PLUGIN . $enPlug . '/plugin.xml')) 3194 { 3195 continue; 3196 } 3197 3198 $plugInfo = $xml->loadXMLfile(e_PLUGIN . $enPlug . '/plugin.xml', 'advanced'); 3199 3200 if($plugInfo === false) 3201 { 3202 continue; 3203 } 3204 3205 if (!isset($plugInfo['dependencies'])) 3206 { 3207 continue; 3208 } 3209 3210 // FIXME too many nested foreach, need refactoring. 3211 foreach($plugInfo['dependencies'] as $dt => $da) 3212 { 3213 foreach($da as $dv) 3214 { 3215 if(isset($dv['@attributes']) && isset($dv['@attributes']['name'])) 3216 { 3217 switch($dt) 3218 { 3219 case 'plugin': 3220 if ($dv['@attributes']['name'] == $plugin) 3221 { 3222 $usedBy[] = $enPlug; 3223 } 3224 break; 3225 } 3226 } 3227 } 3228 } 3229 } 3230 3231 if(count($usedBy)) 3232 { 3233 $pluginIsUsed = true; 3234 $text = '<b>' . LAN_UNINSTALL_FAIL . '</b><br />'; 3235 $text .= $tp->lanVars(LAN_PLUGIN_IS_USED, array('x' => $plugin), true) . ' '; 3236 $text .= implode(', ', $usedBy); 3237 $mes->addError($text); 3238 } 3239 3240 return $pluginIsUsed; 3241 } 3242 3243 /** 3244 * Process XML Tag <dependencies> (deprecated 'depend' which is a brand of adult diapers) 3245 * 3246 * @param array $tags 3247 * Tags (in <dependencies> tag) from XML file. 3248 * 3249 * @return boolean 3250 */ 3251 function XmlDependencies($tags) 3252 { 3253 $this->log("Running ".__METHOD__); 3254 $db = e107::getDb(); 3255 $mes = e107::getMessage(); 3256 3257 $canContinue = true; 3258 $enabledPlugins = array(); 3259 $error = array(); 3260 3261 // Get list of enabled plugins. 3262 $db->select("plugin", "*", "plugin_id !='' order by plugin_path ASC"); 3263 while($row = $db->fetch()) 3264 { 3265 if($row['plugin_installflag'] == 1) 3266 { 3267 $enabledPlugins[$row['plugin_path']] = $row['plugin_version']; 3268 } 3269 } 3270 3271 // FIXME too many nested foreach, need refactoring. 3272 foreach($tags as $dt => $da) 3273 { 3274 foreach($da as $dv) 3275 { 3276 if(isset($dv['@attributes']) && isset($dv['@attributes']['name'])) 3277 { 3278 switch($dt) 3279 { 3280 case 'plugin': 3281 if(!isset($enabledPlugins[$dv['@attributes']['name']])) 3282 { // Plugin not installed 3283 $canContinue = false; 3284 $error[] = EPL_ADLAN_70 . $dv['@attributes']['name']; 3285 } 3286 elseif(isset($dv['@attributes']['min_version']) && (version_compare($dv['@attributes']['min_version'], $enabledPlugins[$dv['@attributes']['name']], '<=') === false)) 3287 { 3288 $error[] = EPL_ADLAN_71 . $dv['@attributes']['name'] . EPL_ADLAN_72 . $dv['@attributes']['min_version']; 3289 $canContinue = false; 3290 } 3291 break; 3292 case 'extension': 3293 if(!extension_loaded($dv['@attributes']['name'])) 3294 { 3295 $canContinue = false; 3296 $error[] = EPL_ADLAN_73 . $dv['@attributes']['name']; 3297 } 3298 elseif(isset($dv['@attributes']['min_version']) && (version_compare($dv['@attributes']['min_version'], phpversion($dv['@attributes']['name']), '<=') === false)) 3299 { 3300 $error[] = EPL_ADLAN_71 . $dv['@attributes']['name'] . EPL_ADLAN_72 . $dv['@attributes']['min_version']; 3301 $canContinue = false; 3302 } 3303 break; 3304 case 'php': // all should be lowercase 3305 if(isset($dv['@attributes']['min_version']) && (version_compare($dv['@attributes']['min_version'], phpversion(), '<=') === false)) 3306 { 3307 $error[] = EPL_ADLAN_74 . $dv['@attributes']['min_version']; 3308 $canContinue = false; 3309 } 3310 break; 3311 case 'mysql': // all should be lowercase 3312 if(isset($dv['@attributes']['min_version']) && (version_compare($dv['@attributes']['min_version'], $db->mySqlServerInfo(), '<=') === false) 3313 ) 3314 { 3315 $error[] = EPL_ADLAN_75 . $dv['@attributes']['min_version']; 3316 $canContinue = false; 3317 } 3318 break; 3319 default: 3320 // TODO lan 3321 echo "Unknown dependency: {$dt}<br />"; 3322 } 3323 } 3324 } 3325 } 3326 3327 if(count($error)) 3328 { 3329 $text = '<b>' . LAN_INSTALL_FAIL . '</b><br />' . implode('<br />', $error); 3330 $mes->addError($text); 3331 } 3332 3333 return $canContinue; 3334 } 3335 3336 3337 3338 /** 3339 * Look for a language file in the two acceptable places. 3340 * If found, update the appropriate pref 3341 * 3342 * @param string $fileEnd - the suffix of the file name (e.g. '_global') 3343 * @param string $prefName - the name of the pref to be updated 3344 * @param string $when = install|upgrade|refresh|uninstall ('update' also supported as alias for 'upgrade') 3345 * @param string $isInstalled - flag indicates whether plugin installed 3346 * - if false, any preference is removed. 3347 * - if TRUE, any preference is added 3348 * - so set TRUE to add value to pref regardless 3349 * @param boolean $justPath 3350 * - if TRUE, plugin name is written to pref, as a generic string which requires a search to locate the file. 3351 * - if FALSE, a precise path within the plugin folder, which includes '--LAN--' strings to substitute for language, is written 3352 * @param string $plugin - name of plugin folder. If empty string, $this->plugFolder is used (may not always exist). 3353 * 3354 * @return boolean TRUE if pref changed 3355 */ 3356 public function XmlLanguageFileCheck($fileEnd, $prefName, $when, $isInstalled, $justPath = FALSE, $plugin = '') 3357 { 3358 $core = e107::getConfig('core'); 3359 $mes = e107::getMessage(); 3360 3361 if (trim($plugin) == '') $plugin = $this->plugFolder; 3362 if (!$plugin) return FALSE; // No plugin name - error 3363 3364 if (!$isInstalled) $when = 'uninstall'; 3365 3366 $updated = false; 3367 3368 $path_a = e_PLUGIN.$plugin.'/languages/English'.$fileEnd.'.php'; // always check for English so we have a fall-back 3369 $path_b = e_PLUGIN.$plugin.'/languages/English/English'.$fileEnd.'.php'; 3370 $pathEntry = ''; 3371 3372 if (file_exists($path_a)) 3373 { 3374 $pathEntry = $justPath ? $plugin : '--LAN--'.$fileEnd.'.php'; 3375 } 3376 elseif (file_exists($path_b)) 3377 { 3378 $pathEntry = $justPath ? $plugin : '--LAN--/--LAN--'.$fileEnd.'.php'; 3379 } 3380 3381 $currentPref = $core->getPref($prefName.'/'.$plugin); 3382 //echo 'Path: '.$plugin.' Pref: '.$prefName.' Current: '.$currentPref.' New: '.$pathEntry.'<br />'; 3383 switch ($when) 3384 { 3385 case 'install': 3386 case 'upgrade': 3387 case 'update' : 3388 case 'refresh': 3389 if ($currentPref != $pathEntry) 3390 { 3391 $mes->addDebug('Adding '.$plugin.' to '.$prefName); 3392 $core->setPref($prefName.'/'.$plugin, $pathEntry); 3393 $updated = true; 3394 } 3395 break; 3396 case 'uninstall': 3397 if ($currentPref) 3398 { 3399 $mes->addDebug('Removing '.$plugin.' from '.$prefName); 3400 $core->removePref($prefName.'/'.$plugin); 3401 $updated = true; 3402 } 3403 break; 3404 } 3405 return $updated; 3406 } 3407 3408 3409 3410 /** 3411 * Process XML Tag <LanguageFiles> // Tag is DEPRECATED - using _install _log and _global 3412 * @param string $function install|uninstall|upgrade|refresh- should $when have been used? 3413 * @param object $tag (not used?) 3414 * @param string $when = install|upgrade|refresh|uninstall 3415 * @return null 3416 */ 3417 function XmlLanguageFiles($function, $tag='', $when = '') 3418 { 3419 $this->log("Running ".__FUNCTION__); 3420 $core = e107::getConfig('core'); 3421 3422 $updated = false; 3423 3424 $path_a = e_PLUGIN.$this->plugFolder."/languages/English_install.php"; // always check for English so we have a fall-back 3425 $path_b = e_PLUGIN.$this->plugFolder."/languages/English/English_install.php"; 3426 3427 if(file_exists($path_a) || file_exists($path_b)) 3428 { 3429 e107::lan($this->plugFolder,'install',true); 3430 } 3431 3432 $path_a = e_PLUGIN.$this->plugFolder."/languages/English_global.php"; // always check for English so we have a fall-back 3433 $path_b = e_PLUGIN.$this->plugFolder."/languages/English/English_global.php"; 3434 3435 if(file_exists($path_a) || file_exists($path_b)) 3436 { 3437 switch ($function) 3438 { 3439 case 'install': 3440 case 'upgrade': 3441 case 'refresh': 3442 e107::getMessage()->addDebug("Adding ".$this->plugFolder." to lan_global_list"); 3443 e107::lan($this->plugFolder,'global',true); 3444 $core->setPref('lan_global_list/'.$this->plugFolder, $this->plugFolder); 3445 $updated = true; 3446 break; 3447 case 'uninstall': 3448 $core->removePref('lan_global_list/'.$this->plugFolder); 3449 $update = true; 3450 break; 3451 } 3452 } 3453 3454 3455 $path_a = e_PLUGIN.$this->plugFolder."/languages/English_log.php"; // always check for English so we have a fall-back 3456 $path_b = e_PLUGIN.$this->plugFolder."/languages/English/English_log.php"; 3457 3458 if(file_exists($path_a) || file_exists($path_b)) 3459 { 3460 switch ($function) 3461 { 3462 case 'install': 3463 case 'upgrade': 3464 case 'refresh': 3465 $core->setPref('lan_log_list/'.$this->plugFolder, $this->plugFolder); 3466 $updated = true; 3467 break; 3468 case 'uninstall': 3469 $core->removePref('lan_log_list/'.$this->plugFolder); 3470 $updated = true; 3471 break; 3472 } 3473 } 3474 3475 3476 if($updated === true) 3477 { 3478 $this->log("Prefs saved"); 3479 $core->save(true,false,false); //FIXME do this quietly without an s-message 3480 } 3481 3482 return null; 3483 } 3484 3485 /** 3486 * Process XML Tag <siteLinks> 3487 * @param string $function install|upgrade|refresh|uninstall 3488 * @param array $array 3489 * @return null 3490 */ 3491 function XmlSiteLinks($function, $plug_vars) 3492 { 3493 $this->log("Running ".__FUNCTION__); 3494 3495 $mes = e107::getMessage(); 3496 3497 if(vartrue($this->options['nolinks'])) 3498 { 3499 return null; 3500 } 3501 3502 if($function == 'refresh') 3503 { 3504 $mes->addDebug("Checking Plugin Site-links"); 3505 $mes->addDebug(print_a($plug_vars['siteLinks'],true)); 3506 } 3507 3508 3509 $array = $plug_vars['siteLinks']; 3510 3511 foreach ($array['link'] as $link) 3512 { 3513 $attrib = $link['@attributes']; 3514 $linkName = (defset($link['@value'])) ? constant($link['@value']) : vartrue($link['@value'],''); 3515 $remove = (varset($attrib['deprecate']) == 'true') ? TRUE : FALSE; 3516 $url = vartrue($attrib['url']); 3517 $perm = vartrue($attrib['perm'],'everyone'); 3518 $sef = vartrue($attrib['sef']); 3519 3520 $options = array( 3521 'link_function' => !empty($attrib['function']) ? $plug_vars['folder'].'::'.$attrib['function'] : null, 3522 'link_owner' => vartrue($plug_vars['folder']), 3523 'link_sef' => $sef, 3524 'link_icon' => vartrue($attrib['icon']), 3525 'link_description' => vartrue($attrib['description']) 3526 ); 3527 3528 switch ($function) 3529 { 3530 case 'upgrade': 3531 case 'install': 3532 case 'refresh': 3533 3534 if (!$remove) // Add any non-deprecated link 3535 { 3536 3537 if($function == 'refresh') 3538 { 3539 $perm = 'nobody'; 3540 3541 } 3542 3543 $result = $this->manage_link('add', $url, $linkName, $perm, $options); 3544 if($result !== NULL) 3545 { 3546 $status = ($result) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3547 $mes->add(EPL_ADLAN_233." {$linkName} URL: [{$url}] ".EPL_ADLAN_252." {$perm} ", $status); 3548 } 3549 } 3550 3551 if ($function == 'upgrade' && $remove) //remove inactive links on upgrade 3552 { 3553 $status = ($this->manage_link('remove', $url, $linkName,false, $options)) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3554 $mes->add(EPL_ADLAN_234." {$linkName} URL: [{$url}]", $status); 3555 } 3556 break; 3557 3558 3559 case 'uninstall': //remove all links 3560 3561 $status = ($this->manage_link('remove', $url, $linkName, $perm, $options)) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3562 $mes->add(EPL_ADLAN_234." {$linkName} URL: [{$url}]", $status); 3563 break; 3564 } 3565 } 3566 3567 return ($status === E_MESSAGE_SUCCESS) ? true : false; 3568 } 3569 3570 /** 3571 * Process XML Tag <adminLinks> 3572 * @return null 3573 */ 3574 function XmlAdminLinks($function, $tag) 3575 { 3576 $this->log("Running ".__FUNCTION__); 3577 foreach ($tag['link'] as $link) 3578 { 3579 $attrib = $link['@attributes']; 3580 $url = e_PLUGIN_ABS.$this->plugFolder."/".$attrib['url']; 3581 if (isset($attrib['primary']) && $attrib['primary'] == 'true') 3582 { 3583 $this->plugConfigFile = $url; 3584 } 3585 } 3586 3587 return null; 3588 } 3589 3590 3591 3592 3593 function getPerm($type, $default = 'member') 3594 { 3595 3596 if(empty($type)) 3597 { 3598 $type = $default; 3599 } 3600 3601 $plug_perm = array(); 3602 $plug_perm['everyone'] = e_UC_PUBLIC; 3603 $plug_perm['guest'] = e_UC_GUEST; 3604 $plug_perm['member'] = e_UC_MEMBER; 3605 $plug_perm['mainadmin'] = e_UC_MAINADMIN; 3606 $plug_perm['admin'] = e_UC_ADMIN; 3607 $plug_perm['nobody'] = e_UC_NOBODY; 3608 3609 if(isset($plug_perm[$type])) 3610 { 3611 return $plug_perm[$type]; 3612 } 3613 3614 return $plug_perm[$default]; 3615 } 3616 3617 3618 // Only 1 category per file-type allowed. ie. 1 for images, 1 for files. 3619 function XmlMediaCategories($function, $tag) 3620 { 3621 $this->log("Running ".__FUNCTION__); 3622 $mes = e107::getMessage(); 3623 // print_a($tag); 3624 3625 $folder = $tag['folder']; 3626 $prevType = ""; 3627 3628 3629 //print_a($tag); 3630 switch ($function) 3631 { 3632 case 'install': 3633 case 'refresh': 3634 $c = 1; 3635 $i = array('file'=>1, 'image'=>1, 'video'=>1); 3636 3637 foreach($tag['mediaCategories']['category'] as $v) 3638 { 3639 $type = $v['@attributes']['type']; 3640 3641 if(strpos($type, 'image') !== 0 && strpos($type, 'file') !== 0 && strpos($type, 'video') !== 0) 3642 { 3643 continue; 3644 } 3645 3646 if($c == 4) 3647 { 3648 $mes->addDebug(EPL_ADLAN_244); 3649 break; 3650 } 3651 3652 // $prevType = $type; 3653 3654 $data['owner'] = $folder; 3655 $data['image'] = vartrue($v['@attributes']['image']); 3656 $data['category'] = $folder."_".$type; 3657 3658 if($i[$type] > 1) 3659 { 3660 $data['category'] .= "_".$i[$type]; 3661 } 3662 3663 $data['title'] = $v['@value']; 3664 $data['sef'] = vartrue($v['@attributes']['sef']); 3665 // $data['type'] = $v['@attributes']['type']; //TODO 3666 $data['class'] = $this->getPerm(varset($v['@attributes']['perm']), 'member'); 3667 3668 $status = e107::getMedia()->createCategory($data) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3669 $message = e107::getParser()->lanVars(EPL_ADLAN_245,$data['category'],true); 3670 // $message = str_replace('[x]', $data['category'], EPL_ADLAN_245); 3671 $mes->add($message, $status); 3672 e107::getMedia()->import($data['category'],e_PLUGIN.$folder, false,'min-size=20000'); 3673 $c++; 3674 $i[$type]++; 3675 } 3676 3677 break; 3678 3679 case 'uninstall': // Probably best to leave well alone 3680 $status = e107::getMedia()->deleteAllCategories($folder)? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3681 // $message = str_replace('[x]', $folder, EPL_ADLAN_246); 3682 $message = e107::getParser()->lanVars(EPL_ADLAN_246,$folder,true); 3683 $mes->add($message, $status); 3684 break; 3685 3686 3687 } 3688 3689 return null; 3690 } 3691 3692 3693 3694 /** 3695 * Process XML Tag <bbcodes> 3696 * @return null 3697 */ 3698 function XmlBBcodes($function, $tag) 3699 { 3700 $this->log("Running ".__FUNCTION__); 3701 3702 switch ($function) 3703 { 3704 case 'install': // Probably best to leave well alone 3705 if(vartrue($tag['bbcodes']['@attributes']['imgResize'])) 3706 { 3707 e107::getConfig('core')->setPref('resize_dimensions/'.$this->plugFolder."-bbcode", array('w'=>300,'h'=>300)); 3708 $this->log('Adding imageResize for: '.$this->plugFolder); 3709 } 3710 break; 3711 3712 case 'uninstall': // Probably best to leave well alone 3713 if(vartrue($tag['bbcodes']['@attributes']['imgResize'])) 3714 { 3715 //e107::getConfig('core')->removePref('resize_dimensions/'.$this->plugFolder); 3716 //e107::getConfig('core')->removePref('e_imageresize/'.$this->plugFolder); 3717 e107::getConfig('core')->removePref('resize_dimensions/'.$this->plugFolder."-bbcode"); 3718 $this->log('Removing imageResize for: '.$this->plugFolder."-bbcode"); 3719 } 3720 3721 break; 3722 } 3723 3724 3725 return null; 3726 3727 } 3728 3729 /** 3730 * Process XML Tag <userClasses> 3731 * @param string $function install|upgrade|refresh|uninstall 3732 * @param array $array 3733 * @return null 3734 */ 3735 function XmlUserClasses($function, $array) 3736 { 3737 $mes = e107::getMessage(); 3738 $this->log("Running ".__FUNCTION__); 3739 3740 foreach ($array['class'] as $uclass) 3741 { 3742 $attrib = $uclass['@attributes']; 3743 $name = $attrib['name']; 3744 $description = $attrib['description']; 3745 $remove = (varset($attrib['deprecate']) == 'true') ? TRUE : FALSE; 3746 3747 switch ($function) 3748 { 3749 case 'install': 3750 case 'upgrade': 3751 case 'refresh': 3752 3753 if (!$remove) // Add all active userclasses (code checks for already installed) 3754 { 3755 $result = $this->manage_userclass('add', $name, $description); 3756 if($result !== NULL) 3757 { 3758 $status = ($result) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3759 $mes->add('Adding Userclass: '.$name, $status); 3760 } 3761 } 3762 3763 if ($function == 'upgrade' && $remove) //If upgrading, removing any inactive userclass 3764 3765 { 3766 $status = $this->manage_userclass('remove', $name, $description) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3767 $mes->add('Removing Userclass: '.$name, $status); 3768 } 3769 3770 break; 3771 3772 case 'uninstall': //If uninstalling, remove all userclasses (active or inactive) 3773 3774 if (vartrue($this->unInstallOpts['delete_userclasses'], FALSE)) 3775 { 3776 $status = $this->manage_userclass('remove', $name, $description) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3777 $mes->add('Removing Userclass: '.$name, $status); 3778 } 3779 else 3780 { 3781 $mes->add('Userclass: '.$name.' left in place', E_MESSAGE_DEBUG); 3782 } 3783 3784 break; 3785 } 3786 } 3787 3788 return null; 3789 } 3790 3791 3792 /** 3793 * Process XML Tag <extendedFields> 3794 * @param string $function install|upgrade|refresh|uninstall 3795 * @param array $array 3796 * @return null 3797 */ 3798 function XmlExtendedFields($function, $array) 3799 { 3800 $this->log("Running ".__FUNCTION__); 3801 $mes = e107::getMessage(); 3802 $this->setUe(); 3803 3804 $ret = array(); 3805 3806 foreach ($array['field'] as $efield) 3807 { 3808 $attrib = $efield['@attributes']; 3809 $attrib['default'] = varset($attrib['default']); 3810 3811 $type = $this->ue_field_type($attrib); 3812 $name = $this->ue_field_name($this->plugFolder, $type, $attrib['name']); 3813 3814 //$name = 'plugin_'.$this->plugFolder.'_'.$attrib['name']; 3815 $source = 'plugin_'.$this->plugFolder; 3816 $remove = (varset($attrib['deprecate']) == 'true') ? TRUE : FALSE; 3817 3818 if(!isset($attrib['system'])) 3819 { 3820 $attrib['system'] = true; // default true 3821 } 3822 else 3823 { 3824 $attrib['system'] = ($attrib['system'] === 'true') ? true : false; 3825 } 3826 3827 switch ($function) 3828 { 3829 case 'install': // Add all active extended fields 3830 case 'upgrade': 3831 3832 if (!$remove) 3833 { 3834 //$status = $this->manage_extended_field('add', $name, $type, $attrib['default'], $source) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3835 3836 $status = $this->manage_extended_field('add', $name, $attrib, $source) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3837 $mes->add(EPL_ADLAN_249 .$name.' ... ', $status); 3838 } 3839 3840 if ($function == 'upgrade' && $remove) //If upgrading, removing any inactive extended fields 3841 3842 { 3843 $status = $this->manage_extended_field('remove', $name, $attrib, $source) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3844 $mes->add(EPL_ADLAN_250 .$name.' ... ', $status); 3845 } 3846 break; 3847 3848 case 'uninstall': //If uninstalling, remove all extended fields (active or inactive) 3849 3850 if (vartrue($this->unInstallOpts['delete_xfields'], FALSE)) 3851 { 3852 $status = ($this->manage_extended_field('remove', $name, $attrib, $source)) ? E_MESSAGE_SUCCESS : E_MESSAGE_ERROR; 3853 $mes->add(EPL_ADLAN_250 .$name.' ... ', $status); 3854 } 3855 else 3856 { 3857 $mes->add(EPL_ADLAN_251 .$name, E_MESSAGE_SUCCESS); 3858 } 3859 break; 3860 3861 case 'test': // phpunit 3862 $ret[] = array('name' => $name, 'attrib' => $attrib, 'source' => $source); 3863 break; 3864 } 3865 } 3866 3867 if(!empty($ret)) 3868 { 3869 return $ret; 3870 } 3871 3872 return null; 3873 } 3874 3875 3876 /** 3877 * Process XML tags <mainPrefs> and <pluginPrefs> 3878 * @param string $mode 'core' or the folder name of the plugin. 3879 * @param string $function install|uninstall|upgrade|refresh 3880 * @param array $prefArray XML array of prefs. eg. mainPref() or pluginPref(); 3881 * @return null 3882 */ 3883 function XmlPrefs($mode = 'core', $function='', $prefArray=array()) 3884 { 3885 $this->log("Running ".__FUNCTION__); 3886 3887 $mes = e107::getMessage(); 3888 3889 if(empty($prefArray)) 3890 { 3891 return null; 3892 } 3893 3894 $config = ($mode === 'core') ? e107::getConfig('core') : e107::getPlugConfig($mode); 3895 3896 foreach ($prefArray['pref'] as $tag) 3897 { 3898 $key = varset($tag['@attributes']['name']); 3899 $value = varset($tag['@value']); 3900 3901 // $this->log(" Pref: ".$key." => ".$value); 3902 3903 if(substr($value,0,5) == "e_UC_") // Convert Userclass constants. 3904 { 3905 $value = constant($value); 3906 } 3907 elseif($tmp = e107::unserialize($value)) // check for array data and convert when required. . 3908 { 3909 $value = $tmp; 3910 } 3911 3912 $remove = (varset($tag['@attributes']['deprecate']) == 'true') ? TRUE : FALSE; 3913 3914 if (varset($tag['@attributes']['value'])) 3915 { 3916 $mes->addError("Deprecated plugin.xml spec. found. Use the following format: ".htmlentities("<pref name='name'>value</pref>")); 3917 } 3918 3919 switch ($function) 3920 { 3921 case 'install': 3922 case 'upgrade': 3923 $ret = $config->add($key, $value); 3924 if($ret->data_has_changed == TRUE) 3925 { 3926 $mes->addSuccess(EPL_ADLAN_241, $key); 3927 } 3928 break; 3929 3930 3931 case 'refresh': 3932 if ($remove) // remove active='false' prefs. 3933 3934 { 3935 $config->remove($key); 3936 $mes->addSuccess(EPL_ADLAN_242, $key); 3937 } 3938 else 3939 { 3940 $config->update($key, $value); 3941 $mes->addSuccess(EPL_ADLAN_243, $key); 3942 } 3943 3944 break; 3945 3946 case 'uninstall': 3947 $config->remove($key); 3948 $mes->addSuccess(EPL_ADLAN_242, $key); 3949 $this->log("Removing Pref: ".$key); 3950 break; 3951 } 3952 } 3953 3954 if ($mode != "core") // Do only one core pref save during install/uninstall etc. 3955 { 3956 $config->save(true, false, false); 3957 } 3958 3959 return null; 3960 } 3961 3962 /** 3963 * 3964 * @param object $path [unused] 3965 * @param object $what install|uninstall|upgrade 3966 * @param object $when pre|post 3967 * @param array $callbackData callback method arguments 3968 * @return boolean FALSE 3969 */ 3970 function execute_function($path = null, $what = '', $when = '', $callbackData = null) 3971 { 3972 $mes = e107::getMessage(); 3973 3974 if($path == null) 3975 { 3976 $path = $this->plugFolder; 3977 } 3978 3979 $class_name = $path."_setup"; // was using $this->pluginFolder; 3980 $method_name = $what."_".$when; 3981 3982 3983 // {PLUGIN}_setup.php should ALWAYS be the name of the file.. 3984 3985 3986 // if (varset($this->plug_vars['@attributes']['setupFile'])) 3987 // { 3988 // $setup_file = e_PLUGIN.$this->plugFolder.'/'.$this->plug_vars['@attributes']['setupFile']; 3989 // } 3990 // else 3991 // { 3992 $setup_file = e_PLUGIN.$path.'/'.$path.'_setup.php'; 3993 // } 3994 3995 3996 3997 if(!is_readable($setup_file) && substr($path,-5) == "_menu") 3998 { 3999 $setup_file = e_PLUGIN.$path.'/'.str_replace("_menu","",$path).'_setup.php'; 4000 } 4001 4002 if(deftrue('E107_DBG_INCLUDES')) 4003 { 4004 e107::getMessage()->addDebug("Checking for SetUp File: ".$setup_file); 4005 } 4006 4007 if (is_readable($setup_file)) 4008 { 4009 if(e_PAGE == 'e107_update.php' && E107_DBG_INCLUDES) 4010 { 4011 $mes->addDebug("Found setup file <b>".$path."_setup.php</b> "); 4012 } 4013 4014 include_once($setup_file); 4015 4016 4017 if (class_exists($class_name)) 4018 { 4019 $obj = new $class_name; 4020 $obj->version_from = $this; 4021 4022 if (method_exists($obj, $method_name)) 4023 { 4024 if(e_PAGE == 'e107_update.php' && E107_DBG_INCLUDES) 4025 { 4026 $mes->addDebug("Executing setup function <b>".$class_name." :: ".$method_name."()</b>"); 4027 } 4028 if(null !== $callbackData) return call_user_func_array(array($obj, $method_name), $callbackData); 4029 return call_user_func(array($obj, $method_name), $this); 4030 } 4031 else 4032 { 4033 if(e_PAGE == 'e107_update.php' && E107_DBG_INCLUDES) 4034 { 4035 $mes->addDebug("Setup function ".$class_name." :: ".$method_name."() NOT found."); 4036 } 4037 return FALSE; 4038 } 4039 } 4040 else 4041 { 4042 // $mes->add("Setup Class ".$class_name." NOT found.", E_MESSAGE_DEBUG); 4043 return FALSE; 4044 } 4045 } 4046 else 4047 { 4048 //$mes->add("Optional Setup File NOT Found ".$path."_setup.php ", E_MESSAGE_DEBUG); 4049 } 4050 4051 return FALSE; // IMPORTANT. 4052 } 4053 4054/* @deprecated 4055 // @deprecated - See XMLPrefs(); 4056 function parse_prefs($pref_array, $mode = 'simple') 4057 { 4058 $ret = array(); 4059 if (!isset($pref_array[0])) 4060 { 4061 $pref_array = array($pref_array); 4062 } 4063 if (is_array($pref_array)) 4064 { 4065 foreach ($pref_array as $k => $p) 4066 { 4067 $attrib = $p['@attributes']; 4068 if (isset($attrib['type']) && $attrib['type'] == 'array') 4069 { 4070 $name = $attrib['name']; 4071 $tmp = $this->parse_prefs($pref_array[$k]['key']); 4072 $ret['all'][$name] = $tmp['all']; 4073 $ret['active'][$name] = $tmp['active']; 4074 $ret['inactive'][$name] = $tmp['inactive']; 4075 } 4076 else 4077 { 4078 $ret['all'][$attrib['name']] = $attrib['value']; 4079 if (!isset($attrib['active']) || $attrib['active'] == 'true') 4080 { 4081 $ret['active'][$attrib['name']] = $attrib['value']; 4082 } 4083 else 4084 { 4085 $ret['inactive'][$attrib['name']] = $attrib['value']; 4086 } 4087 } 4088 } 4089 } 4090 return $ret; 4091 } 4092 4093*/ 4094 4095 function install_plugin_php($id) 4096 { 4097 $function = 'install'; 4098 $sql = e107::getDb(); 4099 $mes = e107::getMessage(); 4100 $mySQLprefix = MPREFIX; // Fix for some plugin.php files. 4101 4102 $this->log("Running Legacy Plugin: ".$function); 4103 4104 if(is_array($id)) 4105 { 4106 $plug = $id; 4107 $id = $plug['plugin_id']; 4108 } 4109 else 4110 { 4111 $plug = e107plugin::getPluginRecord($id); 4112 } 4113 4114 $_path = e_PLUGIN.$plug['plugin_path'].'/'; 4115 4116 $plug['plug_action'] = 'install'; 4117 4118 $this->parse_plugin_php($plug['plugin_path']); 4119 $plug_vars = $this->plug_vars; 4120 4121 $eplug_folder = ''; 4122 $text = ''; 4123 4124 include($_path.'plugin.php'); 4125 4126 $func = $eplug_folder.'_install'; 4127 if (function_exists($func)) 4128 { 4129 $text .= call_user_func($func); 4130 } 4131 4132 if(!empty($eplug_tables) && is_array($eplug_tables)) 4133 { 4134 $result = $this->manage_tables('add', $eplug_tables); 4135 if ($result === true) 4136 { 4137 $text .= EPL_ADLAN_19.'<br />'; 4138 $this->log("Tables added"); 4139 $mes->addSuccess(EPL_ADLAN_19); 4140 } 4141 else 4142 { 4143 $this->log("Unable to create tables for this plugin."); // NO LANS - debug info! 4144 $mes->addError(EPL_ADLAN_18); 4145 4146 } 4147 } 4148 4149 /* if (is_array($eplug_prefs)) 4150 { 4151 $this->manage_prefs('add', $eplug_prefs); 4152 $text .= EPL_ADLAN_8.'<br />'; 4153 }*/ 4154 4155 if (varset($plug_vars['mainPrefs'])) //Core pref items <mainPrefs> 4156 { 4157 $this->XmlPrefs('core', $function, $plug_vars['mainPrefs']); 4158 $this->log("Prefs added"); 4159 //$text .= EPL_ADLAN_8.'<br />'; 4160 } 4161 4162 if (!empty($eplug_array_pref) && is_array($eplug_array_pref)) 4163 { 4164 foreach ($eplug_array_pref as $key => $val) 4165 { 4166 $this->manage_plugin_prefs('add', $key, $eplug_folder, $val); 4167 } 4168 $this->log("Adding Prefs: ". print_r($eplug_array_pref, true)); 4169 } 4170 4171 if (varset($plug_vars['siteLinks'])) 4172 { 4173 $this->XmlSiteLinks($function, $plug_vars); 4174 } 4175 4176 if (varset($plug_vars['userClasses'])) 4177 { 4178 $this->XmlUserClasses($function, $plug_vars['userClasses']); 4179 } 4180 4181 $this->manage_search('add', $eplug_folder); 4182 4183 $this->manage_notify('add', $eplug_folder); 4184 4185 $this->XmlMenus($plug_vars['folder'], $function, $plug_vars['files']); 4186 4187 $eplug_addons = $this->getAddons($eplug_folder); 4188 4189 $sql->update('plugin', "plugin_installflag = 1, plugin_addons = '{$eplug_addons}' WHERE plugin_id = ".(int) $id); 4190 4191 $p_installed = e107::getPref('plug_installed', array()); // load preference; 4192 $p_installed[$plug['plugin_path']] = $plug['plugin_version']; 4193 4194 e107::getConfig('core')->setPref('plug_installed', $p_installed); 4195 4196 $this->rebuildUrlConfig(); 4197 4198 e107::getConfig('core')->save(); 4199 4200 $this->save_addon_prefs('update'); 4201 4202 $text .= (isset($eplug_done) ? "<br />{$eplug_done}" : "<br />".LAN_INSTALL_SUCCESSFUL); 4203 4204 if (!empty($eplug_conffile)) 4205 { 4206 $text .= "<br /><a class='btn btn-primary' href='".e_PLUGIN.$eplug_folder."/".$eplug_conffile."'>".LAN_CONFIGURE."</a>"; 4207 } 4208 4209 // Event triggering after plugin installation. 4210 $event = e107::getEvent(); 4211 $event->trigger('admin_plugin_install', $plug); 4212 4213 return $text; 4214 } 4215 4216 /** 4217 * BC Alias for install(); 4218 */ 4219 public function install_plugin($id) 4220 { 4221 global $sysprefs, $mySQLprefix; 4222 return $this->install($id); 4223 4224 } 4225 4226 /** 4227 * Refresh Plugin Info, Install flag, e_xxx, ignore existing tables. etc. 4228 * 4229 * @param int $dir - plugin folder. 4230 */ 4231 function refresh($dir) 4232 { 4233 if(empty($dir)) 4234 { 4235 return null; 4236 } 4237 4238 global $sysprefs, $mySQLprefix; 4239 4240 $ns = e107::getRender(); 4241 $sql = e107::getDb(); 4242 $tp = e107::getParser(); 4243 4244 $plug = e107plugin::getPluginRecord($dir); 4245 4246 $this->options = array('nolinks'=>true); 4247 4248 if(!is_array($plug)) 4249 { 4250 return "'{$dir}' is missing from the plugin db table"; 4251 } 4252 4253 $_path = e_PLUGIN.$plug['plugin_path'].'/'; 4254 4255 if (file_exists($_path.'plugin.xml')) 4256 { 4257 $this->install_plugin_xml($plug, 'refresh'); 4258 } 4259 else 4260 { 4261 e107::getMessage()->addDebug("Missing xml file at : ".$_path."plugin.xml"); 4262 $text = EPL_ADLAN_21; 4263 4264 } 4265 4266 e107::getMessage()->addDebug("Running Refresh of ".$_path); 4267 4268 $this->save_addon_prefs(); 4269 4270 e107::getPlug()->clearCache(); 4271 4272 return $text; 4273 } 4274 4275 4276 /** 4277 * Installs a plugin by ID or folder name 4278 * 4279 * @param int $id 4280 * @param array $options (currently only 'nolinks' - set to true to prevent sitelink creation during install) 4281 */ 4282 function install($id, $options = array()) 4283 { 4284 global $sysprefs, $mySQLprefix; 4285 $this->log("Running ".__METHOD__); 4286 4287 $ns = e107::getRender(); 4288 $sql = e107::getDb(); 4289 $tp = e107::getParser(); 4290 4291 $this->options = $options; 4292 4293 4294 $text = ''; 4295 4296 e107::getPlug()->clearCache(); 4297 4298 // install plugin ... 4299 $plug = e107plugin::getPluginRecord($id); 4300 4301 // XXX: The code below does not actually check if the plugin is in the database table. 4302 if(!is_array($plug)) 4303 { 4304 $message = $id." is missing from the plugin db table"; 4305 $this->log($message); 4306 return $message; 4307 } 4308 // XXX: The code above does not actually check if the plugin is in the database table. 4309 4310 $plug['plug_action'] = !empty($options['function']) ? $options['function'] : 'install'; 4311 4312 if (!vartrue($plug['plugin_installflag'])) 4313 { 4314 $_path = e_PLUGIN.$plug['plugin_path'].'/'; 4315 4316 $this->log("Installing: ".$plug['plugin_path']); 4317 4318 if (file_exists($_path.'plugin.xml')) 4319 { 4320 4321 $text = $this->install_plugin_xml($plug, 'install'); 4322 } 4323 elseif (file_exists($_path.'plugin.php')) 4324 { 4325 $text = $this->install_plugin_php($plug); 4326 } 4327 } 4328 else 4329 { 4330 $text = EPL_ADLAN_21; 4331 4332 } 4333 4334 $this->log("Installation completed"); // no LANs 4335 4336 e107::getPlug()->clearCache(); 4337 4338 return $text; 4339 } 4340 4341 4342 public function uninstall($id, $options = array()) 4343 { 4344 $pref = e107::getPref(); 4345 $admin_log = e107::getAdminLog(); 4346 $plugin = e107::getPlugin(); 4347 $tp = e107::getParser(); 4348 4349 $sql = e107::getDb(); 4350 $plug = e107plugin::getPluginRecord($id); 4351 4352 $this->log("Uninstalling :" . $plug['plugin_path'] . " with options: " . print_r($options, true)); 4353 4354 $this->log("e107plugin::getPluginRecord() returned: " . print_r($plug, true)); 4355 4356 // Check if plugin is being used by another plugin before uninstalling it. 4357 if (isset($plug['plugin_path'])) 4358 { 4359 if ($this->isUsedByAnotherPlugin($plug['plugin_path'])) 4360 { 4361 $this->action = 'installed'; // Render plugin list. 4362 return false; 4363 } 4364 } 4365 4366 $text = ''; 4367 //Uninstall Plugin 4368 $eplug_folder = $plug['plugin_path']; 4369 if ($plug['plugin_installflag'] == true) 4370 { 4371 $this->log("plugin_installflag = true, proceeding to uninstall"); 4372 4373 $_path = e_PLUGIN . $plug['plugin_path'] . '/'; 4374 4375 if (file_exists($_path . 'plugin.xml')) 4376 { 4377 unset($_POST['uninstall_confirm']); 4378 $this->install_plugin_xml($plug, 'uninstall', $options); //$_POST must be used. 4379 } 4380 else 4381 { // Deprecated - plugin uses plugin.php 4382 $eplug_table_names = null; 4383 $eplug_prefs = null; 4384 $eplug_comment_ids = null; 4385 $eplug_array_pref = null; 4386 $eplug_menu_name = null; 4387 $eplug_link = null; 4388 $eplug_link_url = null; 4389 $eplug_link_name = null; 4390 $eplug_userclass = null; 4391 $eplug_version = null; 4392 4393 include(e_PLUGIN . $plug['plugin_path'] . '/plugin.php'); 4394 4395 $func = $eplug_folder . '_uninstall'; 4396 if (function_exists($func)) 4397 { 4398 $text .= call_user_func($func); 4399 } 4400 4401 if (!empty($options['delete_tables'])) 4402 { 4403 4404 if (is_array($eplug_table_names)) 4405 { 4406 $result = $this->manage_tables('remove', $eplug_table_names); 4407 if ($result !== TRUE) 4408 { 4409 $text .= EPL_ADLAN_27 . ' <b>' . MPREFIX . $result . '</b> - ' . EPL_ADLAN_30 . '<br />'; 4410 $this->log("Unable to delete table."); // No LANS 4411 } 4412 else 4413 { 4414 $text .= EPL_ADLAN_28 . "<br />"; 4415 $this->log("Deleting tables."); // NO LANS 4416 } 4417 } 4418 } 4419 else 4420 { 4421 $text .= EPL_ADLAN_49 . "<br />"; 4422 $this->log("Tables left intact by request."); // No LANS 4423 } 4424 4425 if (is_array($eplug_prefs)) 4426 { 4427 $this->manage_prefs('remove', $eplug_prefs); 4428 $text .= EPL_ADLAN_29 . "<br />"; 4429 } 4430 4431 if (is_array($eplug_comment_ids)) 4432 { 4433 $text .= ($this->manage_comments('remove', $eplug_comment_ids)) ? EPL_ADLAN_50 . "<br />" : ""; 4434 } 4435 4436 if (is_array($eplug_array_pref)) 4437 { 4438 foreach ($eplug_array_pref as $key => $val) 4439 { 4440 $this->manage_plugin_prefs('remove', $key, $eplug_folder, $val); 4441 } 4442 } 4443 /* 4444 if ($eplug_menu_name) 4445 { 4446 $sql->delete('menus', "menu_name='{$eplug_menu_name}' "); 4447 }*/ 4448 $folderFiles = scandir(e_PLUGIN . $plug['plugin_path']); 4449 $this->XmlMenus($eplug_folder, 'uninstall', $folderFiles); 4450 4451 if ($eplug_link) 4452 { 4453 $this->manage_link('remove', $eplug_link_url, $eplug_link_name); 4454 } 4455 4456 if ($eplug_userclass) 4457 { 4458 $this->manage_userclass('remove', $eplug_userclass); 4459 } 4460 4461 $sql->update('plugin', "plugin_installflag=0, plugin_version='{$eplug_version}' WHERE plugin_path='{$eplug_folder}' "); 4462 $this->manage_search('remove', $eplug_folder); 4463 4464 $this->manage_notify('remove', $eplug_folder); 4465 4466 // it's done inside install_plugin_xml(), required only here 4467 if (isset($pref['plug_installed'][$plug['plugin_path']])) 4468 { 4469 unset($pref['plug_installed'][$plug['plugin_path']]); 4470 } 4471 e107::getConfig('core')->setPref($pref); 4472 $this->rebuildUrlConfig(); 4473 e107::getConfig('core')->save(false, true, false); 4474 } 4475 4476 $logInfo = deftrue($plug['plugin_name'], $plug['plugin_name']) . " v" . $plug['plugin_version'] . " ({e_PLUGIN}" . $plug['plugin_path'] . ")"; 4477 e107::getLog()->add('PLUGMAN_03', $logInfo, E_LOG_INFORMATIVE, ''); 4478 } 4479 else 4480 { 4481 $this->log("plugin_installflag = false, uninstall skipped."); 4482 } 4483 4484 if (!empty($options['delete_files']) && ($plug['plugin_installflag'] == true)) 4485 { 4486 if (!empty($eplug_folder)) 4487 { 4488 $result = e107::getFile()->rmtree(e_PLUGIN . $eplug_folder); 4489 e107::getDb()->delete('plugin', "plugin_path='" . $eplug_folder . "'"); 4490 $text .= ($result ? '<br />' . EPL_ADLAN_86 . e_PLUGIN . $eplug_folder : '<br />' . EPL_ADLAN_87 . '<br />' . EPL_ADLAN_31 . ' <b>' . e_PLUGIN . $eplug_folder . '</b> ' . EPL_ADLAN_32); 4491 } 4492 } 4493 else 4494 { 4495 $text .= '<br />' . EPL_ADLAN_31 . ' <b>' . e_PLUGIN . $eplug_folder . '</b> ' . EPL_ADLAN_32; 4496 } 4497 4498 e107::getPlug()->clearCache()->buildAddonPrefLists(); 4499 4500 // $this->save_addon_prefs('update'); 4501 4502 $this->log("Uninstall completed"); 4503 4504 4505 return $text; 4506 } 4507 4508 4509 4510 4511 4512 /** 4513 * scan the plugin table and create path-array-prefs for each addon. 4514 * @deprecated Replaced by eplug::refreshAddonPrefList() 4515 * @param string $mode = install|upgrade|refresh|uninstall - defines the intent of the call 4516 * 4517 * 'upgrade' and 'refresh' are very similar in intent, and often take the same actions: 4518 * 'upgrade' signals a possible change to the installed list of plugins - usually an upgrade 4519 * 'refresh' validates the stored data for existing plugins, recreating any that has gone missing 4520 */ 4521 function save_addon_prefs($mode = 'upgrade') 4522 { 4523 $this->log('Running save_addon_prefs('.$mode.')'); 4524 4525 // e107::getPlug()->buildAddonPrefLists(); // XXX TODO Breaks plugin installation in most cases. 4526 4527 // return; 4528 4529 $sql = e107::getDb(); 4530 $core = e107::getConfig('core'); 4531 4532 foreach ($this->plugin_addons as $var) // clear all existing prefs. 4533 4534 { 4535 $core->update($var.'_list', ""); 4536 } 4537 4538 // reset 4539 $core->set('bbcode_list', array()) 4540 ->set('shortcode_legacy_list', array()) 4541 ->set('shortcode_list', array()); 4542 4543 $query = "SELECT * FROM #plugin WHERE plugin_addons !='' ORDER BY plugin_path ASC"; 4544 4545 if ($sql->gen($query)) 4546 { 4547 while ($row = $sql->fetch()) 4548 { 4549 $is_installed = ($row['plugin_installflag'] == 1); 4550 $tmp = explode(",", $row['plugin_addons']); 4551 $path = $row['plugin_path']; 4552 4553 if ($is_installed) 4554 { 4555 foreach ($tmp as $val) 4556 { 4557 if (strpos($val, 'e_') === 0) 4558 { 4559 // $addpref[$val."_list"][$path] = $path; 4560 $core->setPref($val.'_list/'.$path, $path); 4561 } 4562 } 4563 } 4564 4565 // search for .bb and .sc files. 4566 $scl_array = array(); 4567 $sc_array = array(); 4568 $bb_array = array(); 4569 $sql_array = array(); 4570 4571 foreach ($tmp as $adds) 4572 { 4573 // legacy shortcodes - plugin root *.sc files 4574 if (substr($adds, -3) === ".sc") 4575 { 4576 $sc_name = substr($adds, 0, -3); // remove the .sc 4577 if ($is_installed) 4578 { 4579 $scl_array[$sc_name] = "0"; // default userclass = e_UC_PUBLIC 4580 } 4581 else 4582 { 4583 $scl_array[$sc_name] = e_UC_NOBODY; // register shortcode, but disable it 4584 } 4585 } 4586 // new shortcodes location - shortcodes/single/*.php 4587 elseif (substr($adds, 0, 3) === "sc_") 4588 { 4589 $sc_name = substr(substr($adds, 3), 0, -4); // remove the sc_ and .php 4590 4591 if ($is_installed) 4592 { 4593 $sc_array[$sc_name] = "0"; // default userclass = e_UC_PUBLIC 4594 } 4595 else 4596 { 4597 $sc_array[$sc_name] = e_UC_NOBODY; // register shortcode, but disable it 4598 } 4599 } 4600 4601 if($is_installed) 4602 { 4603 // simple bbcode 4604 if(substr($adds,-3) == ".bb") 4605 { 4606 $bb_name = substr($adds, 0,-3); // remove the .bb 4607 $bb_array[$bb_name] = "0"; // default userclass. 4608 } 4609 // bbcode class 4610 elseif(substr($adds, 0, 3) == "bb_" && substr($adds, -4) == ".php") 4611 { 4612 $bb_name = substr($adds, 0,-4); // remove the .php 4613 $bb_name = substr($bb_name, 3); 4614 $bb_array[$bb_name] = "0"; // TODO - instance and getPermissions() method 4615 } 4616 } 4617 4618 if ($is_installed && (substr($adds, -4) == "_sql")) 4619 { 4620 $core->setPref('e_sql_list/'.$path, $adds); 4621 } 4622 } 4623 4624 // Build Bbcode list (will be empty if plugin not installed) 4625 if (count($bb_array) > 0) 4626 { 4627 ksort($bb_array); 4628 $core->setPref('bbcode_list/'.$path, $bb_array); 4629 } 4630 4631 // Build shortcode list - do if uninstalled as well 4632 if (count($scl_array) > 0) 4633 { 4634 ksort($scl_array); 4635 $core->setPref('shortcode_legacy_list/'.$path, $scl_array); 4636 } 4637 4638 if (count($sc_array) > 0) 4639 { 4640 ksort($sc_array); 4641 $core->setPref('shortcode_list/'.$path, $sc_array); 4642 } 4643 } 4644 } 4645 4646 $core->save(FALSE, false, false); 4647 4648 if ($this->manage_icons()) 4649 { 4650 // echo 'IT WORKED'; 4651 } 4652 else 4653 { 4654 // echo "didn't work!"; 4655 } 4656 return null; 4657 } 4658 4659 public function getAddonsList() 4660 { 4661 $list = array_diff($this->plugin_addons,$this->plugin_addons_deprecated); 4662 sort($list); 4663 4664 return $list; 4665 } 4666 4667 public function getAddonsDiz($v) 4668 { 4669 if(!empty($this->plugin_addons_diz[$v])) 4670 { 4671 return $this->plugin_addons_diz[$v]; 4672 } 4673 4674 return null; 4675 4676 } 4677 4678 4679 // return a list of available plugin addons for the specified plugin. e_xxx etc. 4680 // $debug = TRUE - prints diagnostics 4681 // $debug = 'check' - checks each file found for php tags - prints 'pass' or 'fail' 4682 function getAddons($plugin_path, $debug = FALSE) 4683 { 4684 $fl = e107::getFile(); 4685 $mes = e107::getMessage(); 4686 4687 $p_addons = array(); 4688 4689 4690 foreach ($this->plugin_addons as $addon) //Find exact matches only. 4691 { 4692 // if(preg_match("#^(e_.*)\.php$#", $f['fname'], $matches)) 4693 4694 $addonPHP = $addon.".php"; 4695 4696 if (is_readable(e_PLUGIN.$plugin_path."/".$addonPHP)) 4697 { 4698 if ($debug === 'check') 4699 { 4700 $passfail = ''; 4701 $file_text = file_get_contents(e_PLUGIN.$plugin_path."/".$addonPHP); 4702 if ((substr($file_text, 0, 5) != '<'.'?php') || ((substr($file_text, -2, 2) != '?'.'>') && (strrpos($file_text, '?'.'>') !== FALSE))) 4703 { 4704 $passfail = '<b>fail</b>'; 4705 } 4706 else 4707 { 4708 $passfail = 'pass'; 4709 } 4710 echo $plugin_path."/".$addon.".php - ".$passfail."<br />"; 4711 } 4712 // $mes->add('Detected addon: <b>'.$addon.'</b>', E_MESSAGE_DEBUG); 4713 4714 $p_addons[] = $addon; 4715 } 4716 } 4717 4718 // Grab List of Shortcodes & BBcodes 4719 $shortcodeLegacyList = $fl->get_files(e_PLUGIN.$plugin_path, '\.sc$', "standard", 1); 4720 $shortcodeList = $fl->get_files(e_PLUGIN.$plugin_path.'/shortcodes/single', '\.php$', "standard", 1); 4721 4722 $bbcodeList = $fl->get_files(e_PLUGIN.$plugin_path, '\.bb$', "standard", 1); 4723 $bbcodeClassList= $fl->get_files(e_PLUGIN.$plugin_path, '^bb_(.*)\.php$', "standard", 1); 4724 $bbcodeList = array_merge($bbcodeList, $bbcodeClassList); 4725 4726 $sqlList = $fl->get_files(e_PLUGIN.$plugin_path, '_sql\.php$', "standard", 1); 4727 4728 // Search Shortcodes 4729 foreach ($shortcodeLegacyList as $sc) 4730 { 4731 if (is_readable(e_PLUGIN.$plugin_path."/".$sc['fname'])) 4732 { 4733 $p_addons[] = $sc['fname']; 4734 } 4735 } 4736 foreach ($shortcodeList as $sc) 4737 { 4738 if (is_readable(e_PLUGIN.$plugin_path."/shortcodes/single/".$sc['fname'])) 4739 { 4740 $p_addons[] = 'sc_'.$sc['fname']; 4741 } 4742 } 4743 4744 // Search Bbcodes. 4745 foreach ($bbcodeList as $bb) 4746 { 4747 if (is_readable(e_PLUGIN.$plugin_path."/".$bb['fname'])) 4748 { 4749 $p_addons[] = $bb['fname']; 4750 } 4751 } 4752 4753 // Search _sql files. 4754 foreach ($sqlList as $esql) 4755 { 4756 if (is_readable(e_PLUGIN.$plugin_path."/".$esql['fname'])) 4757 { 4758 $fname = str_replace(".php", "", $esql['fname']); 4759 if (!in_array($fname, $p_addons)) 4760 $p_addons[] = $fname; // Probably already found - avoid duplication 4761 } 4762 } 4763 4764 if ($debug == true) 4765 { 4766 echo $plugin_path." = ".implode(",", $p_addons)."<br />"; 4767 } 4768 4769 $this->log("Detected Addons: ".print_r($p_addons,true)); 4770 4771 return implode(",", $p_addons); 4772 } 4773 4774 4775 /** 4776 * Check Plugin Addon for errors. 4777 * @return array or numeric. 0 = OK, 1 = Fail, 2 = inaccessible 4778 */ 4779 function checkAddon($plugin_path, $e_xxx) 4780 { 4781 4782 if (is_readable(e_PLUGIN.$plugin_path."/".$e_xxx.".php")) 4783 { 4784 $content = file_get_contents(e_PLUGIN.$plugin_path."/".$e_xxx.".php"); 4785 } 4786 else 4787 { 4788 return 2; 4789 } 4790 4791 if(substr($e_xxx, - 4, 4) == '_sql') 4792 { 4793 4794 if(strpos($content,'INSERT INTO')!==false) 4795 { 4796 return array('type'=> 'error', 'msg'=>"INSERT sql commands are not permitted here. Use a ".$plugin_path."_setup.php file instead."); 4797 } 4798 else 4799 { 4800 return 0; 4801 } 4802 } 4803 4804 // Generic markup check 4805 if ((substr($content, 0, 5) != '<'.'?php') || ((substr($content, -2, 2) != '?'.'>') && (strrpos($content, '?'.'>') !== FALSE))) 4806 { 4807 return 1; 4808 } 4809 4810 4811 if($e_xxx == 'e_meta' && strpos($content,'<script')!==false) 4812 { 4813 return array('type'=> 'warning', 'msg'=>"Contains script tags. Use e_header.php with the e107::js() function instead."); 4814 } 4815 4816 4817 if($e_xxx == 'e_latest' && strpos($content,'<div')!==false) 4818 { 4819 return array('type'=> 'warning', 'msg'=>"Using deprecated method. See e_latest.php in the forum plugin for an example."); 4820 } 4821 4822 if($e_xxx == 'e_status' && strpos($content,'<div')!==false) 4823 { 4824 return array('type'=> 'warning', 'msg'=>"Using deprecated method. See e_status.php in the forum plugin for an example."); 4825 } 4826 4827 4828 return 0; 4829 } 4830 4831 // Entry point to read plugin configuration data 4832 function parse_plugin($plugName, $force = false) 4833 { 4834 $ret = ""; 4835 4836 if (isset($this->parsed_plugin[$plugName]) && $force != true) 4837 { 4838 $this->plug_vars = $this->parsed_plugin[$plugName]; 4839 return true; 4840 } 4841 unset($this->parsed_plugin[$plugName]); // In case forced parsing which fails 4842 if (file_exists(e_PLUGIN.$plugName.'/plugin.xml')) 4843 { 4844 $ret = $this->parse_plugin_xml($plugName); 4845 } 4846 elseif (file_exists(e_PLUGIN.$plugName.'/plugin.php')) 4847 { 4848 $ret = $this->parse_plugin_php($plugName); 4849 } 4850 if ($ret == true) 4851 { 4852 $this->parsed_plugin[$plugName] = $this->plug_vars; 4853 } 4854 4855 return $ret; 4856 } 4857 4858 // return the Icon of the 4859 function getIcon($plugName='',$size=32, $defaultOverride=false) 4860 { 4861 if(!$plugName) return false; 4862 4863 $tp = e107::getParser(); 4864 4865 if(!isset($this->parsed_plugin[$plugName])) 4866 { 4867 $this->parse_plugin($plugName,true); 4868 4869 } 4870 4871 $plug_vars = $this->parsed_plugin[$plugName]; 4872 4873 4874 //return print_r($plug_vars,TRUE); 4875 4876 4877 $sizeArray = array(32=>'icon', 16=>'iconSmall'); 4878 $default = ($size == 32) ? $tp->toGlyph('e-cat_plugins-32') : "<img class='icon S16' src='".E_16_CAT_PLUG."' alt='' />"; 4879 $sz = $sizeArray[$size]; 4880 4881 $icon_src = e_PLUGIN.$plugName."/".$plug_vars['administration'][$sz]; 4882 $plugin_icon = $plug_vars['administration'][$sz] ? "<img src='{$icon_src}' alt='' class='icon S".intval($size)."' />" : $default; 4883 4884 if($defaultOverride !== false && $default === $plugin_icon) 4885 { 4886 return $defaultOverride; 4887 } 4888 4889 4890 if(!$plugin_icon) 4891 { 4892 // 4893 } 4894 4895 return $plugin_icon; 4896 } 4897 4898 4899 4900 // Called to parse the (deprecated) plugin.php file 4901 function parse_plugin_php($plugName) 4902 { 4903 $tp = e107::getParser(); 4904 $sql = e107::getDb(); // in case it is used inside plugin.php 4905 4906 $PLUGINS_FOLDER = '{e_PLUGIN}'; // Could be used in plugin.php file. 4907 4908 $eplug_conffile = null; 4909 $eplug_table_names = null; 4910 $eplug_prefs = null; 4911 $eplug_module = null; 4912 $eplug_userclass = null; 4913 $eplug_status = null; 4914 $eplug_latest = null; 4915 $eplug_icon = null; 4916 $eplug_icon_small = null; 4917 4918 e107::getDebug()->log("Legacy Plugin Parse (php): ".$plugName); 4919 4920 ob_start(); 4921 if (include(e_PLUGIN.$plugName.'/plugin.php')) 4922 { 4923 //$mes->add("Loading ".e_PLUGIN.$plugName.'/plugin.php', E_MESSAGE_DEBUG); 4924 } 4925 ob_end_clean(); 4926 $ret = array(); 4927 4928 // $ret['installRequired'] = ($eplug_conffile || is_array($eplug_table_names) || is_array($eplug_prefs) || is_array($eplug_sc) || is_array($eplug_bb) || $eplug_module || $eplug_userclass || $eplug_status || $eplug_latest); 4929 4930 $ret['@attributes']['name'] = varset($eplug_name); 4931 $ret['@attributes']['lang'] = varset($eplug_name); 4932 $ret['@attributes']['version'] = varset($eplug_version); 4933 $ret['@attributes']['date'] = varset($eplug_date); 4934 $ret['@attributes']['compatibility'] = varset($eplug_compatible); 4935 $ret['@attributes']['installRequired'] = ($eplug_conffile || is_array($eplug_table_names) || is_array($eplug_prefs) || $eplug_module || $eplug_userclass || $eplug_status || $eplug_latest) ? 'true' : ''; 4936 $ret['@attributes']['xhtmlcompliant'] = vartrue($eplug_compliant) ? 'true' : ''; 4937 $ret['folder'] = (varset($eplug_folder)) ? $eplug_folder : $plugName; 4938 4939 $ret['author']['@attributes']['name'] = varset($eplug_author); 4940 $ret['author']['@attributes']['url'] = varset($eplug_url); 4941 $ret['author']['@attributes']['email'] = varset($eplug_email); 4942 $ret['description']['@value'] = varset($eplug_description); 4943 $ret['description']['@attributes']['lang'] = varset($eplug_description); 4944 4945 $ret['category'] = varset($eplug_category) ? $this->manage_category($eplug_category) : "misc"; 4946 $ret['readme'] = varset($eplug_readme); 4947 4948 $ret['menuName'] = varset($eplug_menu_name); 4949 4950 4951 if (!empty($eplug_prefs) && is_array($eplug_prefs)) 4952 { 4953 $c = 0; 4954 foreach($eplug_prefs as $name => $value) 4955 { 4956 $ret['mainPrefs']['pref'][$c]['@attributes']['name'] = $name; 4957 $ret['mainPrefs']['pref'][$c]['@value'] = $value; 4958 $c++; 4959 } 4960 } 4961 4962 // For BC. 4963 $ret['administration']['icon'] = str_replace($plugName."/","",$eplug_icon); 4964 $ret['administration']['caption'] = varset($eplug_caption); 4965 $ret['administration']['iconSmall'] = str_replace($plugName."/","",$eplug_icon_small); 4966 $ret['administration']['configFile'] = varset($eplug_conffile); 4967 4968 if(varset($eplug_conffile)) 4969 { 4970 $ret['adminLinks']['link'][0]['@attributes']['url'] = varset($eplug_conffile); 4971 $ret['adminLinks']['link'][0]['@attributes']['description'] = LAN_CONFIGURE; 4972 $ret['adminLinks']['link'][0]['@attributes']['icon'] = str_replace($plugName."/","",$eplug_icon); 4973 $ret['adminLinks']['link'][0]['@attributes']['iconSmall'] = str_replace($plugName."/","",$eplug_icon_small); 4974 $ret['adminLinks']['link'][0]['@attributes']['primary'] = 'true'; 4975 } 4976 if(vartrue($eplug_link) && varset($eplug_link_name) && varset($eplug_link_url)) 4977 { 4978 $ret['siteLinks']['link'][0]['@attributes']['url'] = $tp->createConstants($eplug_link_url, 1); 4979 $ret['siteLinks']['link'][0]['@attributes']['perm'] = varset($eplug_link_perms); 4980 $ret['siteLinks']['link'][0]['@value'] = varset($eplug_link_name); 4981 } 4982 4983 if(vartrue($eplug_userclass) && vartrue($eplug_userclass_description)) 4984 { 4985 $ret['userClasses']['class'][0]['@attributes']['name'] = $eplug_userclass; 4986 $ret['userClasses']['class'][0]['@attributes']['description'] = $eplug_userclass_description; 4987 } 4988 4989 $ret['files'] = preg_grep('/^([^.])/', scandir(e_PLUGIN.$plugName,SCANDIR_SORT_ASCENDING)); 4990 4991 4992 // Set this key so we know the vars came from a plugin.php file 4993 // $ret['plugin_php'] = true; // Should no longer be needed. 4994 $this->plug_vars = $ret; 4995 4996 4997 return true; 4998 } 4999 5000 // Called to parse the plugin.xml file if it exists 5001 5002 /** 5003 * @deprecated To eventually be replaced by e_plugin::parse_plugin_xml. 5004 * @param $plugName 5005 * @param null $where 5006 * @return bool 5007 */ 5008 function parse_plugin_xml($plugName, $where = null) 5009 { 5010 5011 $tp = e107::getParser(); 5012 // loadLanFiles($plugName, 'admin'); // Look for LAN files on default paths 5013 $xml = e107::getXml(); 5014 $mes = e107::getMessage(); 5015 5016 if(E107_DEBUG_LEVEL > 0) 5017 { 5018 $dbgArr = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,3); 5019 unset($dbgArr[0]); 5020 e107::getDebug()->log("Legacy Plugin Parse (xml): ".$plugName. print_a($dbgArr,true)); 5021 } 5022 5023 5024 5025 // $xml->setOptArrayTags('extendedField,userclass,menuLink,commentID'); // always arrays for these tags. 5026 // $xml->setOptStringTags('install,uninstall,upgrade'); 5027 if(null === $where) $where = 'plugin.xml'; 5028 5029 $this->plug_vars = $xml->loadXMLfile(e_PLUGIN.$plugName.'/'.$where, 'advanced'); 5030 5031 if ($this->plug_vars === FALSE) 5032 { 5033 $mes->addError("Error reading {$plugName}/plugin.xml"); 5034 return FALSE; 5035 } 5036 5037 $this->plug_vars['folder'] = $plugName; // remove the need for <folder> tag in plugin.xml. 5038 $this->plug_vars['category'] = (isset($this->plug_vars['category'])) ? $this->manage_category($this->plug_vars['category']) : "misc"; 5039 $this->plug_vars['files'] = preg_grep('/^([^.])/', scandir(e_PLUGIN.$plugName,SCANDIR_SORT_ASCENDING)); 5040 5041 5042 if(varset($this->plug_vars['description'])) 5043 { 5044 if (is_array($this->plug_vars['description'])) 5045 { 5046 if (isset($this->plug_vars['description']['@attributes']['lan']) && defined($this->plug_vars['description']['@attributes']['lan'])) 5047 { 5048 // Pick up the language-specific description if it exists. 5049 $this->plug_vars['description']['@value'] = constant($this->plug_vars['description']['@attributes']['lan']); 5050} 5051 } 5052 else 5053 { 5054 $diz = $this->plug_vars['description']; 5055 unset($this->plug_vars['description']); 5056 5057 $this->plug_vars['description']['@value'] = $diz; 5058 } 5059 } 5060 5061 5062 // Very useful debug code.to compare plugin.php vs plugin.xml 5063 /* 5064 $testplug = 'forum'; 5065 if($plugName == $testplug) 5066 { 5067 $plug_vars1 = $this->plug_vars; 5068 $this->parse_plugin_php($testplug); 5069 $plug_vars2 = $this->plug_vars; 5070 ksort($plug_vars2); 5071 ksort($plug_vars1); 5072 echo "<table> 5073 <tr><td><h1>PHP</h1></td><td><h1>XML</h1></td></tr> 5074 <tr><td style='border-right:1px solid black'>"; 5075 print_a($plug_vars2); 5076 echo "</td><td>"; 5077 print_a($plug_vars1); 5078 echo "</table>"; 5079 } 5080 */ 5081 5082 5083 // TODO search for $this->plug_vars['adminLinks']['link'][0]['@attributes']['primary']==true. 5084 $this->plug_vars['administration']['icon'] = varset($this->plug_vars['adminLinks']['link'][0]['@attributes']['icon']); 5085 $this->plug_vars['administration']['caption'] = varset($this->plug_vars['adminLinks']['link'][0]['@attributes']['description']); 5086 $this->plug_vars['administration']['iconSmall'] = varset($this->plug_vars['adminLinks']['link'][0]['@attributes']['iconSmall']); 5087 $this->plug_vars['administration']['configFile'] = varset($this->plug_vars['adminLinks']['link'][0]['@attributes']['url']); 5088 5089 return TRUE; 5090 } 5091 5092} 5093 5094 5095