plugins.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <?php
  2. /**
  3. * Defines a library class for managing SLOODLE Plugins.
  4. * It is constructed and used through a SloodleSession object.
  5. *
  6. * @package sloodle
  7. * @copyright Copyright (c) 2009 Sloodle (various contributors)
  8. * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
  9. *
  10. * @contributor Peter R. Bloomfield
  11. */
  12. // This library expects that the Sloodle config file has already been included
  13. // (along with the Moodle libraries)
  14. /** Include the general Sloodle functionality. */
  15. require_once(SLOODLE_DIRROOT.'/lib/general.php');
  16. /**
  17. * A class to load SLOODLE plugins, and provide a means to access them.
  18. * @package sloodle
  19. */
  20. class SloodlePluginManager
  21. {
  22. // DATA //
  23. /**
  24. * Internal only - reference to the containing {@link SloodleSession} object.
  25. * Note: always check that it is not null before use!
  26. * @var object
  27. * @access protected
  28. */
  29. var $_session = null;
  30. /**
  31. * 2d array of plugin class names.
  32. * The top level key gives the lower-case plugin category name, and the second level key gives the lower-case plugin ID. The value gives the name of the associated class.
  33. * This list exists to ensure compatibility with the different ways class name casing is handled on different platform configurations.
  34. * @var array
  35. * @access protected
  36. */
  37. var $plugin_class_names = array();
  38. /**
  39. * Plugin instance cache.
  40. * Stores the plugins which have already been created, to prevent new ones being instantiated unnecessarily.
  41. * Has the same 2d structure as $plugin_class_names, except the values are objects not class names.
  42. * i.e.: $plugin_cache['presenter-slide']['image'] = pluginobject;
  43. * @var array
  44. * @access protected
  45. */
  46. var $plugin_cache = array();
  47. // FUNCTIONS //
  48. /**
  49. * Class constructor.
  50. * @param object &$_session Reference to the containing {@link SloodleSession} object, if available.
  51. * @access public
  52. */
  53. function SloodlePluginManager(&$_session)
  54. {
  55. if (!is_null($_session)) $this->_session = &$_session;
  56. }
  57. /**
  58. * Loads all available plugins from the specified folder.
  59. * @param string $folder Name of the folder to load plugins from. This is a sub-folder of the 'sloodle/plugin' folder. It will only load files which are directly contained inside it.
  60. * @return bool True if successful, or false if it fails. (It will only report failure if the folder does not exist, or there is an error accessing it.)
  61. */
  62. function load_plugins($folder)
  63. {
  64. if (empty($folder)) return false;
  65. // Get a list of all the files in the specified folder
  66. $pluginFolder = SLOODLE_DIRROOT.'/plugin/'.$folder;
  67. $files = sloodle_get_files($pluginFolder, true);
  68. if (!$files) return false;
  69. if (count($files) == 0) return true;
  70. // Start by including the relevant base class files, if they are available
  71. @include_once(SLOODLE_DIRROOT.'/plugin/_base.php');
  72. @include_once($pluginFolder.'/_base.php');
  73. // Go through each filename
  74. foreach ($files as $file) {
  75. // Include the specified file
  76. // Skip things that are usually backups etc.
  77. // Skip .files
  78. if (preg_match('/^\./', $file)) {
  79. continue;
  80. }
  81. // Skip non-php files
  82. if (!preg_match('/\.php$/', $file)) {
  83. continue;
  84. }
  85. include_once($pluginFolder.'/'.$file);
  86. }
  87. // Build a complete list of plugin class names
  88. $this->plugin_class_names = array();
  89. $allclasses = get_declared_classes();
  90. foreach ($allclasses as $c) {
  91. // Attempt to get the plugin ID.
  92. // If this operation fails, then the class is not a SLOODLE plugin.
  93. $pluginid = @call_user_func(array($c,'sloodle_get_plugin_id'));
  94. if (empty($pluginid)) continue;
  95. // Attempt to get the plugin category
  96. $plugincat = @call_user_func(array($c,'get_category'));
  97. if (empty($plugincat)) $plugincat = '';
  98. // Store the class name
  99. $this->plugin_class_names[strtolower($plugincat)][strtolower($pluginid)] = $c;
  100. }
  101. return true;
  102. }
  103. /**
  104. * Dummy function included for error checking.
  105. */
  106. function get_plugin_names($type = '')
  107. {
  108. exit("***** Call to \"get_plugin_names\". This function is no longer valid. Please edit the code. *****");
  109. }
  110. /**
  111. * Gets an array of the names of all SLOODLE plugins, optionally filtered to a specific category.
  112. * Plugin categories are reported by the plugin classes themselves.
  113. * NOTE: this will search all plugins loaded by all plugin managers in the current PHP execution.
  114. * (There is no way to tell which manager loaded which plugins.)
  115. * @param string $category If it is a string, it specifies the name of a category of plugins to get. If null (default) then it is ignored.
  116. * @return array Numeric array of plugin IDs. Will return an empty array if no matching plugins have been loaded.
  117. */
  118. function get_plugin_ids($category = null)
  119. {
  120. // Create an array to store our list of plugin IDs
  121. $plugins = array();
  122. // Has a particular category been provided?
  123. if (is_string($category))
  124. {
  125. // Down-case the category name for compatibility
  126. $category = strtolower($category);
  127. if (!is_array($this->plugin_class_names[$category])) return $plugins;
  128. // Fetch each plugin ID in this category
  129. foreach ($this->plugin_class_names[$category] as $pluginid => $pluginclass) {
  130. // Add the ID to our array
  131. $plugins[] = $pluginid;
  132. }
  133. } else {
  134. // Go through each category of plugins
  135. foreach ($this->plugin_class_names as $cat)
  136. {
  137. // Go through each plugin in this category
  138. foreach ($cat as $pluginid => $pluginclass) {
  139. // Add the ID to our array
  140. $plugins[] = $pluginid;
  141. }
  142. }
  143. }
  144. return $plugins;
  145. }
  146. /**
  147. * Gets an array of the names of all SLOODLE plugin categories.
  148. * Plugin categories are reported by the plugin classes themselves.
  149. * NOTE: this will search all plugins loaded by all plugin managers in the current PHP execution.
  150. * (There is no way to tell which manager loaded which plugins.)
  151. * @return array Numeric array of plugin IDs. Will return an empty array if no matching plugins have been loaded.
  152. */
  153. function get_plugin_categories()
  154. {
  155. // Create an array to store our list of plugin IDs
  156. $plugincats = array();
  157. if (!is_array($this->plugin_class_names)) return $plugincats;
  158. // Go through each category of plugins and add it to our list
  159. foreach ($this->plugin_class_names as $catname => $plugins)
  160. {
  161. $plugincats[] = $catname;
  162. }
  163. return $plugincats;
  164. }
  165. /**
  166. * Gets an instance of the specified plugin.
  167. * This only works if the plugin has already been loaded.
  168. * @param string $plugincat Name of the plugin category we are loading from.
  169. * @param string $pluginid ID of the plugin type to get.
  170. * @param bool $forcenew If false (default) then a cached instance of the plugin will be returned. Set this to true to force the manager to create a new plugin instance.
  171. * @return object|bool A suitable plugin object instance if successful, or false on failure.
  172. */
  173. function get_plugin($plugincat, $pluginid, $forcenew = false)
  174. {
  175. // Down-case the incoming category and ID for compatibility
  176. $plugincat = strtolower($plugincat);
  177. $pluginid = strtolower($pluginid);
  178. // Attempt to retrieve the name of the plugin class, and make sure it exists
  179. if (empty($this->plugin_class_names[$plugincat][$pluginid])) return false;
  180. $classname = $this->plugin_class_names[$plugincat][$pluginid];
  181. if (!class_exists($classname)) return false;
  182. // Return a cached instance if possible, or create a new one if necessary
  183. if ($forcenew == false && !empty($this->plugin_cache[$plugincat][$pluginid]) && is_a($this->plugin_cache[$plugincat][$pluginid], $classname)) return $this->plugin_cache[$plugincat][$pluginid];
  184. $plugin = new $classname();
  185. if (empty($this->plugin_cache[$plugincat][$pluginid])) $this->plugin_cache[$plugincat][$pluginid] = $plugin;
  186. return $plugin;
  187. }
  188. }
  189. ?>