3 # FILE: PluginManager.php 5 # Part of the ScoutLib application support library 6 # Copyright 2009-2013 Edward Almasy and Internet Scout Research Group 7 # http://scout.wisc.edu 16 # ---- PUBLIC INTERFACE -------------------------------------------------- 25 public function __construct($AppFramework, $PluginDirectories)
27 # save framework and directory list for later use 28 $this->AF = $AppFramework;
30 $this->DirsToSearch = $PluginDirectories;
32 # get our own database handle 35 # hook into events to load plugin PHP and HTML files 36 $this->AF->HookEvent(
"EVENT_PHP_FILE_LOAD", array($this,
"FindPluginPhpFile"),
37 ApplicationFramework::ORDER_LAST);
38 $this->AF->HookEvent(
"EVENT_HTML_FILE_LOAD", array($this,
"FindPluginHtmlFile"),
39 ApplicationFramework::ORDER_LAST);
41 # tell PluginCaller helper object how to get to us 42 PluginCaller::$Manager = $this;
53 # look for plugin files 54 $PluginFiles = $this->FindPlugins($this->DirsToSearch);
56 # for each plugin found 57 foreach ($PluginFiles as $PluginName => $PluginFileName)
59 # attempt to load plugin 60 $Result = $this->LoadPlugin($PluginName, $PluginFileName);
62 # if errors were encountered during loading 63 if (is_array($Result))
66 $ErrMsgs[$PluginName][] = $Result;
70 # add plugin to list of loaded plugins 71 $this->Plugins[$PluginName] = $Result;
75 # check dependencies and drop any plugins with failed dependencies 76 $DepErrMsgs = $this->CheckDependencies($this->Plugins);
77 $DisabledPlugins = array();
78 foreach ($DepErrMsgs as $PluginName => $Msgs)
80 $DisabledPlugins[] = $PluginName;
81 foreach ($Msgs as $Msg)
83 $ErrMsgs[$PluginName][] = $Msg;
87 # sort plugins according to any loading order requests 88 $this->Plugins = $this->SortPluginsByInitializationPrecedence(
92 foreach ($this->Plugins as $PluginName => $Plugin)
94 # if plugin is loaded and enabled 95 if (!in_array($PluginName, $DisabledPlugins)
96 && $Plugin->IsEnabled())
98 # attempt to make plugin ready 99 $Result = $this->ReadyPlugin($Plugin);
101 # if making plugin ready failed 102 if ($Result !== NULL)
104 # save error messages 105 foreach ($Result as $Msg)
107 $ErrMsgs[$PluginName][] = $Msg;
112 # mark plugin as ready 113 $Plugin->IsReady(TRUE);
118 # check plugin dependencies again in case an install or upgrade failed 119 $DepErrMsgs = $this->CheckDependencies($this->Plugins, TRUE);
120 foreach ($DepErrMsgs as $PluginName => $Msgs)
122 $this->Plugins[$PluginName]->IsReady(FALSE);
123 foreach ($Msgs as $Msg)
125 $ErrMsgs[$PluginName][] = $Msg;
129 # save plugin files names and any error messages for later use 130 $this->PluginFiles = $PluginFiles;
131 $this->ErrMsgs = $ErrMsgs;
133 # report to caller whether any problems were encountered 134 return count($ErrMsgs) ? FALSE : TRUE;
144 return $this->ErrMsgs;
155 public function GetPlugin($PluginName, $EvenIfNotReady = FALSE)
157 if (!$EvenIfNotReady && array_key_exists($PluginName, $this->Plugins)
158 && !$this->Plugins[$PluginName]->IsReady())
160 $Trace = debug_backtrace();
161 $Caller = basename($Trace[0][
"file"]).
":".$Trace[0][
"line"];
162 throw new Exception(
"Attempt to access uninitialized plugin " 163 .$PluginName.
" from ".$Caller);
165 return isset($this->Plugins[$PluginName])
166 ? $this->Plugins[$PluginName] : NULL;
175 return $this->Plugins;
187 return $this->
GetPlugin($this->PageFilePlugin);
197 # for each loaded plugin 199 foreach ($this->Plugins as $PluginName => $Plugin)
201 # retrieve plugin attributes 202 $Info[$PluginName] = $Plugin->GetAttributes();
204 # add in other values to attributes 205 $Info[$PluginName][
"Enabled"] = $Plugin->IsEnabled();
206 $Info[$PluginName][
"Installed"] = $Plugin->IsInstalled();
207 $Info[$PluginName][
"ClassFile"] = $this->PluginFiles[$PluginName];
210 # sort plugins by name 211 uasort($Info,
function ($A, $B) {
212 $AName = strtoupper($A[
"Name"]);
213 $BName = strtoupper($B[
"Name"]);
214 return ($AName == $BName) ? 0
215 : ($AName < $BName) ? -1 : 1;
218 # return plugin info to caller 229 $Dependents = array();
231 foreach ($AllAttribs as $Name => $Attribs)
233 if (array_key_exists($PluginName, $Attribs[
"Requires"]))
235 $Dependents[] = $Name;
237 $Dependents = array_merge($Dependents, $SubDependents);
249 $ActivePluginNames = array();
250 foreach ($this->Plugins as $PluginName => $Plugin)
252 if ($Plugin->IsReady())
254 $ActivePluginNames[] = $PluginName;
257 return $ActivePluginNames;
268 return !isset($this->Plugins[$PluginName]) ? FALSE
269 : $this->Plugins[$PluginName]->IsEnabled($NewValue);
282 # if plugin is installed 283 if ($this->Plugins[$PluginName]->IsInstalled())
285 # call uninstall method for plugin 286 $Result = $this->Plugins[$PluginName]->Uninstall();
288 # if plugin uninstall method succeeded 289 if ($Result === NULL)
291 # remove plugin info from database 292 $this->DB->Query(
"DELETE FROM PluginInfo" 293 .
" WHERE BaseName = '".addslashes($PluginName).
"'");
295 # drop our data for the plugin 296 unset($this->Plugins[$PluginName]);
297 unset($this->PluginFiles[$PluginName]);
301 # report results (if any) to caller 306 # ---- PRIVATE INTERFACE ------------------------------------------------- 310 private $DirsToSearch;
311 private $ErrMsgs = array();
312 private $PageFilePlugin = NULL;
313 private $Plugins = array();
314 private $PluginFiles = array();
315 private $PluginHasDir = array();
324 private function FindPlugins($DirsToSearch)
327 $PluginFiles = array();
328 foreach ($DirsToSearch as $Dir)
330 # if directory exists 333 # for each file in directory 334 $FileNames = scandir($Dir);
335 foreach ($FileNames as $FileName)
337 # if file looks like base plugin file 338 if (preg_match(
"/^[a-zA-Z_][a-zA-Z0-9_]*\.php$/", $FileName))
341 $PluginName = preg_replace(
"/\.php$/",
"", $FileName);
342 $PluginFiles[$PluginName] = $Dir.
"/".$FileName;
344 # else if file looks like plugin directory 345 elseif (is_dir($Dir.
"/".$FileName)
346 && preg_match(
"/^[a-zA-Z_][a-zA-Z0-9_]*/", $FileName))
348 # if there is a base plugin file in the directory 349 $PluginName = $FileName;
350 $PluginFile = $Dir.
"/".$PluginName.
"/".$PluginName.
".php";
351 if (file_exists($PluginFile))
354 $PluginFiles[$PluginName] = $PluginFile;
359 $this->ErrMsgs[$PluginName][] =
360 "Expected plugin file <i>".$PluginName.
".php</i> not" 361 .
" found in plugin subdirectory <i>" 362 .$Dir.
"/".$PluginName.
"</i>";
369 # return info about found plugins to caller 380 private function LoadPlugin($PluginName, $PluginFileName)
382 # bring in plugin class file 383 include_once($PluginFileName);
385 # if plugin class was not defined by file 386 if (!class_exists($PluginName))
388 $ErrMsgs[] =
"Expected class <i>".$PluginName
389 .
"</i> not found in plugin file <i>" 390 .$PluginFileName.
"</i>";
394 # if plugin class is not a valid descendant of base plugin class 395 if (!is_subclass_of($PluginName,
"Plugin"))
397 $ErrMsgs[] =
"Plugin <b>".$PluginName.
"</b>" 398 .
" could not be loaded because <i>".$PluginName.
"</i> class" 399 .
" was not a subclass of base <i>Plugin</i> class";
403 # instantiate and register the plugin 404 $Plugin =
new $PluginName($PluginName);
406 # check required plugin attributes 407 $RequiredAttribs = array(
"Name",
"Version");
408 $Attribs = $Plugin->GetAttributes();
409 foreach ($RequiredAttribs as $AttribName)
411 if (!strlen($Attribs[$AttribName]))
413 $ErrMsgs[] =
"Plugin <b>".$PluginName.
"</b>" 414 .
" could not be loaded because it" 415 .
" did not have a <i>" 416 .$AttribName.
"</i> attribute set.";
420 # if all required attributes were found 421 if (!isset($ErrMsgs))
423 # if plugin has its own subdirectory 424 $this->PluginHasDir[$PluginName] = preg_match(
425 "%/".$PluginName.
"/".$PluginName.
".php\$%",
426 $PluginFileName) ? TRUE : FALSE;
427 if ($this->PluginHasDir[$PluginName])
429 # if plugin has its own object directory 430 $Dir = dirname($PluginFileName);
431 if (is_dir($Dir.
"/objects"))
433 # add object directory to class autoloading list 434 ApplicationFramework::AddObjectDirectory($Dir.
"/objects");
438 # add plugin directory to class autoloading list 439 ApplicationFramework::AddObjectDirectory($Dir);
442 # if plugin has its own interface directory 443 $InterfaceDir = $Dir.
"/interface";
444 if (is_dir($InterfaceDir))
446 # scan contents of interface directory for 447 # entries other than the default default 448 $InterfaceSubdirsFound = FALSE;
449 foreach (scandir($InterfaceDir) as $Entry)
451 if (($Entry !=
"default") && ($Entry[0] !=
"."))
453 $InterfaceSubdirsFound = TRUE;
458 # if entries found other than the default default 459 if ($InterfaceSubdirsFound)
461 # add directory to those scanned for interfaces 462 $this->AF->AddInterfaceDirectories(
463 array($InterfaceDir.
"/%ACTIVEUI%/",
464 $InterfaceDir.
"/%DEFAULTUI%/"));
467 # add plugin interface object directories if present 468 $ActiveUI = $this->AF->ActiveUserInterface();
469 $DefaultUI = $this->AF->DefaultUserInterface();
470 if (is_dir($InterfaceDir.
"/".$ActiveUI.
"/objects"))
472 ApplicationFramework::AddObjectDirectory(
473 $InterfaceDir.
"/%ACTIVEUI%/objects");
475 if (is_dir($InterfaceDir.
"/".$DefaultUI.
"/objects"))
477 ApplicationFramework::AddObjectDirectory(
478 $InterfaceDir.
"/%DEFAULTUI%/objects");
481 # add plugin interface include directories if present 482 if (is_dir($InterfaceDir.
"/".$DefaultUI.
"/include"))
484 $this->AF->AddIncludeDirectories(
485 $InterfaceDir.
"/%DEFAULTUI%/include");
487 if (is_dir($InterfaceDir.
"/".$ActiveUI.
"/include"))
489 $this->AF->AddIncludeDirectories(
490 $InterfaceDir.
"/%ACTIVEUI%/include");
498 # return loaded plugin or error messages, as appropriate 499 return isset($ErrMsgs) ? $ErrMsgs : $Plugin;
507 private function ReadyPlugin(&$Plugin)
509 # install or upgrade plugin if needed 510 $PluginInstalled = $this->InstallPlugin($Plugin);
512 # if install/upgrade failed 513 if (is_string($PluginInstalled))
515 # report errors to caller 516 return array($PluginInstalled);
519 # set up plugin configuration options 520 $ErrMsgs = $Plugin->SetUpConfigOptions();
522 # if plugin configuration setup failed 523 if ($ErrMsgs !== NULL)
525 # report errors to caller 526 return is_array($ErrMsgs) ? $ErrMsgs : array($ErrMsgs);
529 # set default configuration values if necessary 530 if ($PluginInstalled)
532 $this->SetPluginDefaultConfigValues($Plugin);
535 # initialize the plugin 536 $ErrMsgs = $Plugin->Initialize();
538 # if initialization failed 539 if ($ErrMsgs !== NULL)
541 # report errors to caller 542 return is_array($ErrMsgs) ? $ErrMsgs : array($ErrMsgs);
545 # register any events declared by plugin 546 $Events = $Plugin->DeclareEvents();
547 if (count($Events)) { $this->AF->RegisterEvent($Events); }
549 # if plugin has events that need to be hooked 550 $EventsToHook = $Plugin->HookEvents();
551 if (count($EventsToHook))
555 foreach ($EventsToHook as $EventName => $PluginMethods)
557 # for each method to hook for the event 558 if (!is_array($PluginMethods))
559 { $PluginMethods = array($PluginMethods); }
560 foreach ($PluginMethods as $PluginMethod)
562 # if the event only allows static callbacks 563 if ($this->AF->IsStaticOnlyEvent($EventName))
565 # hook event with shell for static callback 566 $Caller =
new PluginCaller(
567 $Plugin->GetBaseName(), $PluginMethod);
568 $Result = $this->AF->HookEvent(
570 array($Caller,
"CallPluginMethod"));
575 $Result = $this->AF->HookEvent(
576 $EventName, array($Plugin, $PluginMethod));
580 if ($Result === FALSE)
582 $ErrMsgs[] =
"Unable to hook requested event <i>" 583 .$EventName.
"</i> for plugin <b>" 584 .$Plugin->GetBaseName().
"</b>";
589 # if event hook setup failed 592 # report errors to caller 597 # report success to caller 608 private function InstallPlugin(&$Plugin)
610 # if plugin has not been installed 611 $InstallOrUpgradePerformed = FALSE;
612 $PluginName = $Plugin->GetBaseName();
613 $Attribs = $Plugin->GetAttributes();
614 if (!$Plugin->IsInstalled())
616 # set default values if present 617 $this->SetPluginDefaultConfigValues($Plugin, TRUE);
620 $ErrMsg = $Plugin->Install();
621 $InstallOrUpgradePerformed = TRUE;
623 # if install succeeded 626 # mark plugin as installed 627 $Plugin->IsInstalled(TRUE);
631 # return error message about installation failure 632 return "Installation of plugin <b>" 633 .$PluginName.
"</b> failed: <i>".$ErrMsg.
"</i>";
638 # if plugin version is newer than version in database 639 if (version_compare($Attribs[
"Version"],
640 $Plugin->InstalledVersion()) == 1)
642 # set default values for any new configuration settings 643 $this->SetPluginDefaultConfigValues($Plugin);
646 $ErrMsg = $Plugin->Upgrade($Plugin->InstalledVersion());
647 $InstallOrUpgradePerformed = TRUE;
649 # if upgrade succeeded 650 if ($ErrMsg === NULL)
652 # update plugin version in database 653 $Plugin->InstalledVersion($Attribs[
"Version"]);
657 # report error message about upgrade failure 658 return "Upgrade of plugin <b>" 659 .$PluginName.
"</b> from version <i>" 660 .addslashes($Plugin->InstalledVersion())
661 .
"</i> to version <i>" 662 .addslashes($Attribs[
"Version"]).
"</i> failed: <i>" 666 # else if plugin version is older than version in database 667 elseif (version_compare($Attribs[
"Version"],
668 $Plugin->InstalledVersion()) == -1)
670 # return error message about version conflict 672 .$PluginName.
"</b> is older (<i>" 673 .addslashes($Attribs[
"Version"])
674 .
"</i>) than previously-installed version (<i>" 675 .addslashes($Plugin->InstalledVersion())
680 # report result to caller 681 return $InstallOrUpgradePerformed;
691 private function SetPluginDefaultConfigValues($Plugin, $Overwrite = FALSE)
693 # if plugin has configuration info 694 $Attribs = $Plugin->GetAttributes();
695 if (isset($Attribs[
"CfgSetup"]))
697 foreach ($Attribs[
"CfgSetup"] as $CfgValName => $CfgSetup)
699 if (isset($CfgSetup[
"Default"]) && ($Overwrite
700 || ($Plugin->ConfigSetting($CfgValName) === NULL)))
702 $Plugin->ConfigSetting($CfgValName, $CfgSetup[
"Default"]);
715 private function CheckDependencies($Plugins, $CheckReady = FALSE)
717 # look until all enabled plugins check out okay 721 # start out assuming all plugins are okay 725 foreach ($Plugins as $PluginName => $Plugin)
727 # if plugin is enabled and not checking for ready 729 if ($Plugin->IsEnabled() && (!$CheckReady || $Plugin->IsReady()))
731 # load plugin attributes 732 if (!isset($Attribs[$PluginName]))
734 $Attribs[$PluginName] = $Plugin->GetAttributes();
737 # for each dependency for this plugin 738 foreach ($Attribs[$PluginName][
"Requires"]
739 as $ReqName => $ReqVersion)
741 # handle PHP version requirements 742 if ($ReqName ==
"PHP")
744 if (version_compare($ReqVersion, phpversion(),
">"))
746 $ErrMsgs[$PluginName][] =
"PHP version " 747 .
"<i>".$ReqVersion.
"</i>" 748 .
" required by <b>".$PluginName.
"</b>" 749 .
" was not available. (Current PHP version" 750 .
" is <i>".phpversion().
"</i>.)";
753 # handle PHP extension requirements 754 elseif (preg_match(
"/^PHPX_/", $ReqName))
756 list($Dummy, $ExtensionName) = explode(
"_", $ReqName, 2);
757 if (!extension_loaded($ExtensionName))
759 $ErrMsgs[$PluginName][] =
"PHP extension " 760 .
"<i>".$ExtensionName.
"</i>" 761 .
" required by <b>".$PluginName.
"</b>" 762 .
" was not available.";
765 # handle dependencies on other plugins 768 # load plugin attributes if not already loaded 769 if (isset($Plugins[$ReqName])
770 && !isset($Attribs[$ReqName]))
773 $Plugins[$ReqName]->GetAttributes();
776 # if target plugin is not present or is too old 778 # or (if appropriate) is not ready 779 if (!isset($Plugins[$ReqName])
780 || version_compare($ReqVersion,
781 $Attribs[$ReqName][
"Version"],
">")
782 || !$Plugins[$ReqName]->IsEnabled()
784 && !$Plugins[$ReqName]->IsReady()))
787 $ErrMsgs[$PluginName][] =
"Plugin <i>" 788 .$ReqName.
" ".$ReqVersion.
"</i>" 789 .
" required by <b>".$PluginName.
"</b>" 790 .
" was not available.";
794 # if problem was found with plugin 795 if (isset($ErrMsgs[$PluginName]))
797 # remove plugin from our list 798 unset($Plugins[$PluginName]);
800 # set flag to indicate a plugin had to be dropped 806 }
while ($AllOkay == FALSE);
808 # return messages about any dropped plugins back to caller 820 private function SortPluginsByInitializationPrecedence($Plugins)
822 # load plugin attributes 823 foreach ($Plugins as $PluginName => $Plugin)
825 $PluginAttribs[$PluginName] = $Plugin->GetAttributes();
828 # determine initialization order 829 $PluginsAfterUs = array();
830 foreach ($PluginAttribs as $PluginName => $Attribs)
832 foreach ($Attribs[
"InitializeBefore"] as $OtherPluginName)
834 $PluginsAfterUs[$PluginName][] = $OtherPluginName;
836 foreach ($Attribs[
"InitializeAfter"] as $OtherPluginName)
838 $PluginsAfterUs[$OtherPluginName][] = $PluginName;
842 # infer other initialization order cues from lists of required plugins 843 foreach ($PluginAttribs as $PluginName => $Attribs)
845 # for each required plugin 846 foreach ($Attribs[
"Requires"]
847 as $RequiredPluginName => $RequiredPluginVersion)
849 # if there is not a requirement in the opposite direction 850 if (!array_key_exists($PluginName,
851 $PluginAttribs[$RequiredPluginName][
"Requires"]))
853 # if the required plugin is not scheduled to be after us 854 if (!array_key_exists($PluginName, $PluginsAfterUs)
855 || !in_array($RequiredPluginName,
856 $PluginsAfterUs[$PluginName]))
858 # if we are not already scheduled to be after the required plugin 859 if (!array_key_exists($PluginName, $PluginsAfterUs)
860 || !in_array($RequiredPluginName,
861 $PluginsAfterUs[$PluginName]))
863 # schedule us to be after the required plugin 864 $PluginsAfterUs[$RequiredPluginName][] =
872 # keep track of those plugins we have yet to do and those that are done 873 $UnsortedPlugins = array_keys($Plugins);
874 $PluginsProcessed = array();
876 # limit the number of iterations of the plugin ordering loop 877 # to 10 times the number of plugins we have 878 $MaxIterations = 10 * count($UnsortedPlugins);
881 # iterate through all the plugins that need processing 882 while (($NextPlugin = array_shift($UnsortedPlugins)) !== NULL)
884 # check to be sure that we're not looping forever 886 if ($IterationCount > $MaxIterations)
889 "Max iteration count exceeded trying to determine plugin" 890 .
" loading order. Is there a dependency loop?");
893 # if no plugins require this one, it can go last 894 if (!isset($PluginsAfterUs[$NextPlugin]))
896 $PluginsProcessed[$NextPlugin] = $MaxIterations;
900 # for plugins that are required by others 901 $Index = $MaxIterations;
902 foreach ($PluginsAfterUs[$NextPlugin] as $GoBefore)
904 if (!isset($PluginsProcessed[$GoBefore]))
906 # if there is something that requires us which hasn't 907 # yet been assigned an order, then we can't determine 908 # our own place on this iteration 909 array_push($UnsortedPlugins, $NextPlugin);
914 # otherwise, make sure that we're loaded 915 # before the earliest of the things that require us 916 $Index = min($Index, $PluginsProcessed[$GoBefore] - 1);
919 $PluginsProcessed[$NextPlugin] = $Index;
923 # arrange plugins according to our ordering 924 asort($PluginsProcessed, SORT_NUMERIC);
925 $SortedPlugins = array();
926 foreach ($PluginsProcessed as $PluginName => $SortOrder)
928 $SortedPlugins[$PluginName] = $Plugins[$PluginName];
931 # return sorted list to caller 932 return $SortedPlugins;
943 public function FindPluginPhpFile($PageName)
945 # build list of possible locations for file 947 "local/plugins/%PLUGIN%/pages/%PAGE%.php",
948 "plugins/%PLUGIN%/pages/%PAGE%.php",
949 "local/plugins/%PLUGIN%/%PAGE%.php",
950 "plugins/%PLUGIN%/%PAGE%.php",
953 # look for file and return (possibly) updated page to caller 954 return $this->FindPluginPageFile($PageName, $Locations);
966 public function FindPluginHtmlFile($PageName)
968 # build list of possible locations for file 970 "local/plugins/%PLUGIN%/interface/%ACTIVEUI%/%PAGE%.html",
971 "plugins/%PLUGIN%/interface/%ACTIVEUI%/%PAGE%.html",
972 "local/plugins/%PLUGIN%/interface/%DEFAULTUI%/%PAGE%.html",
973 "plugins/%PLUGIN%/interface/%DEFAULTUI%/%PAGE%.html",
974 "local/plugins/%PLUGIN%/%PAGE%.html",
975 "plugins/%PLUGIN%/%PAGE%.html",
979 $Params = $this->FindPluginPageFile($PageName, $Locations);
981 # if plugin HTML file was found 982 if ($Params[
"PageName"] != $PageName)
984 # add subdirectories for plugin to search paths 985 $Dir = preg_replace(
"%^local/%",
"", dirname($Params[
"PageName"]));
986 $this->AF->AddImageDirectories(array(
987 "local/".$Dir.
"/images",
990 $this->AF->AddIncludeDirectories(array(
991 "local/".$Dir.
"/include",
994 $this->AF->AddFunctionDirectories(array(
995 "local/".$Dir.
"/include",
1000 # return possibly revised HTML file name to caller 1015 private function FindPluginPageFile($PageName, $Locations)
1017 # set up return value assuming we will not find plugin page file 1018 $ReturnValue[
"PageName"] = $PageName;
1020 # look for plugin name and plugin page name in base page name 1021 preg_match(
"/P_([A-Za-z].[A-Za-z0-9]*)_([A-Za-z0-9_-]+)/", $PageName, $Matches);
1023 # if plugin name and plugin page name were found and plugin name is valid 1024 if (count($Matches) == 3)
1026 # if plugin is valid and enabled and has its own subdirectory 1027 $PluginName = $Matches[1];
1028 if (isset($this->Plugins[$PluginName])
1029 && $this->PluginHasDir[$PluginName]
1030 && $this->Plugins[$PluginName]->IsEnabled())
1032 # for each possible location 1033 $PageName = $Matches[2];
1034 $ActiveUI = $this->AF->ActiveUserInterface();
1035 $DefaultUI = $this->AF->DefaultUserInterface();
1036 foreach ($Locations as $Loc)
1038 # make any needed substitutions into path 1039 $FileName = str_replace(
1040 array(
"%DEFAULTUI%",
"%ACTIVEUI%",
"%PLUGIN%",
"%PAGE%"),
1041 array($DefaultUI, $ActiveUI, $PluginName, $PageName),
1044 # if file exists in this location 1045 if (file_exists($FileName))
1047 # set return value to contain full plugin page file name 1048 $ReturnValue[
"PageName"] = $FileName;
1050 # save plugin name as home of current page 1051 $this->PageFilePlugin = $PluginName;
1053 # set G_Plugin to plugin associated with current page 1063 # return array containing page name or page file name to caller 1064 return $ReturnValue;
1088 public function __construct($PluginName, $MethodName)
1090 $this->PluginName = $PluginName;
1091 $this->MethodName = $MethodName;
1099 public function CallPluginMethod()
1101 $Args = func_get_args();
1102 $Plugin = self::$Manager->GetPlugin($this->PluginName);
1103 return call_user_func_array(array($Plugin, $this->MethodName), $Args);
1110 public function GetCallbackAsText()
1112 return $this->PluginName.
"::".$this->MethodName;
1120 public function __sleep()
1122 return array(
"PluginName",
"MethodName");
1126 static public $Manager;
1128 private $PluginName;
1129 private $MethodName;
GetErrorMessages()
Retrieve any error messages generated during plugin loading.
Manager to load and invoke plugins.
GetPlugin($PluginName, $EvenIfNotReady=FALSE)
Retrieve specified plugin.
SQL database abstraction object with smart query caching.
UninstallPlugin($PluginName)
Uninstall plugin and (optionally) delete any associated data.
GetDependents($PluginName)
Returns a list of plugins dependent on the specified plugin.
GetActivePluginList()
Get list of active (i.e.
GetPluginAttributes()
Retrieve info about currently loaded plugins.
PluginEnabled($PluginName, $NewValue=NULL)
Get/set whether specified plugin is enabled.
__construct($AppFramework, $PluginDirectories)
PluginManager class constructor.
GetPluginForCurrentPage()
Retrieve plugin for current page (if any).
GetPlugins()
Retrieve all loaded plugins.
static SetApplicationFramework($AF)
Set the application framework to be referenced within plugins.
LoadPlugins()
Load and initialize plugins.