/OpenVBX/libraries/Plugin.php

https://github.com/MichaelMackus/OpenVBX · PHP · 308 lines · 231 code · 44 blank · 33 comment · 42 complexity · 5348d46b3bcbf8d8dd1a22f7b60b806c MD5 · raw file

  1. <?php
  2. /**
  3. * "The contents of this file are subject to the Mozilla Public License
  4. * Version 1.1 (the "License"); you may not use this file except in
  5. * compliance with the License. You may obtain a copy of the License at
  6. * http://www.mozilla.org/MPL/
  7. * Software distributed under the License is distributed on an "AS IS"
  8. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  9. * License for the specific language governing rights and limitations
  10. * under the License.
  11. * The Original Code is OpenVBX, released June 15, 2010.
  12. * The Initial Developer of the Original Code is Twilio Inc.
  13. * Portions created by Twilio Inc. are Copyright (C) 2010.
  14. * All Rights Reserved.
  15. * Contributor(s):
  16. **/
  17. class PluginException extends Exception {}
  18. class Plugin
  19. {
  20. // Parent directory where this plugin is installed
  21. protected $plugins_dir;
  22. // Name of directory where plugin is installed
  23. protected $dir_name;
  24. // Full directory path to plugin
  25. protected $plugin_path;
  26. // Plugin configuration for plugin.json
  27. protected $config;
  28. public function __construct($plugin_dir_name = null, $plugins_dir = null)
  29. {
  30. if(empty($plugin_dir_name))
  31. {
  32. throw new PluginException('Empty plugin directory name');
  33. }
  34. if(empty($plugins_dir))
  35. {
  36. $plugins_dir = PLUGIN_PATH;
  37. }
  38. $this->plugins_dir = $plugins_dir;
  39. $this->dir_name = $plugin_dir_name;
  40. $this->plugin_path = $this->plugins_dir . '/' . $this->dir_name;
  41. if(is_file($this->plugin_path . '/plugin.json'))
  42. {
  43. $config_contents = file_get_contents($this->plugin_path . '/plugin.json');
  44. if(!empty($config_contents))
  45. {
  46. $this->config = json_decode($config_contents);
  47. }
  48. /* Optional arguments should be checked and declared here */
  49. $this->config->disabled = isset($this->config->disabled)? $this->config->disabled : false;
  50. $this->config->name = isset($this->config->name)? $this->config->name : 'Unknown';
  51. $this->config->author = isset($this->config->author)? $this->config->author : 'Unknown';
  52. $this->config->description = isset($this->config->description)? $this->config->description : '';
  53. $this->config->url = isset($this->config->url)? $this->config->url : '';
  54. $this->config->version = isset($this->config->version)? $this->config->version : '';
  55. }
  56. /* Gracefully handle plugins without a configuration file */
  57. else
  58. {
  59. $this->config = new stdClass();
  60. $this->config->name = $this->dir_name;
  61. $this->config->author = 'Unknown';
  62. $this->config->description = '';
  63. $this->config->url = '';
  64. $this->config->disabled = false;
  65. $this->config->version = false;
  66. /* Warn developers */
  67. error_log('Plugin is missing plugin.json file: '. $this->dir_name);
  68. }
  69. }
  70. public function getPluginId()
  71. {
  72. return 'PL'.md5($this->config->name);
  73. }
  74. public function getPluginVersion()
  75. {
  76. return $this->config->version;
  77. }
  78. public function getInfo()
  79. {
  80. $public_info = array('name' => $this->config->name,
  81. 'dir_name' => $this->dir_name,
  82. 'plugin_path' => $this->plugin_path,
  83. 'plugin_id' => $this->getPluginId()
  84. );
  85. $config = get_object_vars($this->config);
  86. return array_merge($config, $public_info);
  87. }
  88. public function getScript($page)
  89. {
  90. if(empty($this->config))
  91. {
  92. throw new PluginException("Plugin has invalid configuration: $this->dir_name");
  93. }
  94. if($page == 'config')
  95. {
  96. $script = $this->plugin_path . '/config.php';
  97. if(!is_file($script))
  98. {
  99. throw new PluginException("Missing file in plugin: $this->dir_name :: config.php");
  100. }
  101. return $script;
  102. }
  103. if(!empty($this->config->links))
  104. {
  105. $found = false;
  106. foreach($this->config->links as $index => $link)
  107. {
  108. if($link->url == $page)
  109. {
  110. $found = true;
  111. break;
  112. }
  113. }
  114. if(isset($this->config->links[$index]) && $found)
  115. {
  116. $page = $this->config->links[$index];
  117. $script = $this->plugin_path . '/' . $page->script;
  118. if(!is_file($script))
  119. {
  120. throw new PluginException("Missing file in plugin: $this->dir_name :: $page->script");
  121. }
  122. return $script;
  123. }
  124. }
  125. }
  126. public function getHookScript($page)
  127. {
  128. if(empty($this->config))
  129. {
  130. throw new PluginException("Plugin has invalid configuration: $this->dir_name");
  131. }
  132. if($page == 'config')
  133. {
  134. return false;
  135. }
  136. if(!empty($this->config->links))
  137. {
  138. $found = false;
  139. foreach($this->config->links as $index => $link)
  140. {
  141. if($link->hook == true AND $link->url == $page)
  142. {
  143. $found = true;
  144. break;
  145. }
  146. }
  147. if(isset($this->config->links[$index]) && $found)
  148. {
  149. $page = $this->config->links[$index];
  150. $script = $this->plugin_path . '/' . $page->script;
  151. if(!is_file($script))
  152. {
  153. throw new PluginException("Missing file in plugin: $this->dir_name :: $page->script");
  154. }
  155. return $script;
  156. }
  157. }
  158. }
  159. public function getPluginPageName($page) {
  160. if(empty($this->config)) {
  161. throw new PluginException("Plugin has invalid configuration: $this->dir_name");
  162. }
  163. $name = '';
  164. if (empty($this->config->links) || $this->config->disabled) {
  165. return $name;
  166. }
  167. foreach ($this->config->links as $link) {
  168. if (!empty($link->url) && $link->url == $page && empty($link->hook)) {
  169. $name = $link->label;
  170. }
  171. }
  172. return $name;
  173. }
  174. public function getLinks()
  175. {
  176. $nav = array();
  177. if(empty($this->config))
  178. {
  179. throw new PluginException("Plugin has invalid configuration: $this->dir_name");
  180. }
  181. if(empty($this->config->links) || $this->config->disabled)
  182. return array();
  183. // HACK: Put this in a better spot, Menu class?
  184. $standard_menu_options = array('util', 'admin', 'setup', 'site_admin', 'log');
  185. foreach($this->config->links as $link)
  186. {
  187. // don't expose API/Ajax hooks to the menu
  188. if (!empty($link->hook)) {
  189. continue;
  190. }
  191. $script = isset($link->script)? $link->script : '';
  192. $url = isset($link->url)? $link->url : '';
  193. $label = isset($link->label)? $link->label : '';
  194. $menu = isset($link->menu)? $link->menu : '';
  195. if(empty($url))
  196. {
  197. /* throw exception? */
  198. }
  199. if(empty($menu))
  200. {
  201. /* throw exception? */
  202. }
  203. if(empty($label))
  204. {
  205. /* throw exception? */
  206. }
  207. if(empty($script))
  208. {
  209. /* throw exception? */
  210. }
  211. if(in_array($menu, $standard_menu_options))
  212. {
  213. $nav[$menu.'_links']["p/$url"] = $label;
  214. }
  215. else
  216. {
  217. $nav['plugin_menus'][strtolower($menu)]["p/$url"] = $label;
  218. }
  219. }
  220. return $nav;
  221. }
  222. public static function get($name)
  223. {
  224. try
  225. {
  226. return new self($name, PLUGIN_PATH);
  227. }
  228. catch(PluginException $e)
  229. {
  230. error_log($e->getMessage());
  231. $ci = &get_instance();
  232. $ci->session->set_flashdata('error', 'Failed to initialize plugin: '.$e->getMessage());
  233. }
  234. return null;
  235. }
  236. public static function all()
  237. {
  238. $plugins = array();
  239. $plugin_dir_names = scandir(PLUGIN_PATH);
  240. foreach($plugin_dir_names as $plugin_dir_name)
  241. {
  242. // Ignore hidden dirs
  243. if($plugin_dir_name[0] == '.')
  244. {
  245. continue;
  246. }
  247. try
  248. {
  249. $plugins[] = new self($plugin_dir_name, PLUGIN_PATH);
  250. }
  251. catch(PluginException $e)
  252. {
  253. error_log($e->getMessage());
  254. $ci = &get_instance();
  255. $ci->session->set_flashdata('error', 'Failed to initialize plugin: '.$e->getMessage());
  256. }
  257. }
  258. return $plugins;
  259. }
  260. }