pluginhost.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. class PluginHost {
  3. private $link;
  4. private $hooks = array();
  5. private $plugins = array();
  6. private $handlers = array();
  7. private $commands = array();
  8. private $storage = array();
  9. private $owner_uid;
  10. const HOOK_ARTICLE_BUTTON = 1;
  11. const HOOK_ARTICLE_FILTER = 2;
  12. const HOOK_PREFS_TAB = 3;
  13. const HOOK_PREFS_TAB_SECTION = 4;
  14. const HOOK_PREFS_TABS = 5;
  15. const HOOK_FEED_PARSED = 6;
  16. const HOOK_UPDATE_TASK = 7;
  17. const HOOK_AUTH_USER = 8;
  18. const HOOK_HOTKEY_MAP = 9;
  19. const KIND_ALL = 1;
  20. const KIND_SYSTEM = 2;
  21. const KIND_USER = 3;
  22. function __construct($link) {
  23. $this->link = $link;
  24. $this->storage = $_SESSION["plugin_storage"];
  25. if (!$this->storage) $this->storage = array();
  26. }
  27. private function register_plugin($name, $plugin) {
  28. //array_push($this->plugins, $plugin);
  29. $this->plugins[$name] = $plugin;
  30. }
  31. function get_link() {
  32. return $this->link;
  33. }
  34. function get_plugins() {
  35. return $this->plugins;
  36. }
  37. function get_plugin($name) {
  38. return $this->plugins[$name];
  39. }
  40. function run_hooks($type, $method, $args) {
  41. foreach ($this->get_hooks($type) as $hook) {
  42. $hook->$method($args);
  43. }
  44. }
  45. function add_hook($type, $sender) {
  46. if (!is_array($this->hooks[$type])) {
  47. $this->hooks[$type] = array();
  48. }
  49. array_push($this->hooks[$type], $sender);
  50. }
  51. function del_hook($type, $sender) {
  52. if (is_array($this->hooks[$type])) {
  53. $key = array_Search($this->hooks[$type], $sender);
  54. if ($key !== FALSE) {
  55. unset($this->hooks[$type][$key]);
  56. }
  57. }
  58. }
  59. function get_hooks($type) {
  60. if (isset($this->hooks[$type])) {
  61. return $this->hooks[$type];
  62. } else {
  63. return array();
  64. }
  65. }
  66. function load_all($kind, $owner_uid = false) {
  67. $plugins = array_map("basename", glob("plugins/*"));
  68. $this->load(join(",", $plugins), $kind, $owner_uid);
  69. }
  70. function load($classlist, $kind, $owner_uid = false) {
  71. $plugins = explode(",", $classlist);
  72. $this->owner_uid = (int) $owner_uid;
  73. foreach ($plugins as $class) {
  74. $class = trim($class);
  75. $class_file = strtolower(basename($class));
  76. $file = dirname(__FILE__)."/../plugins/$class_file/init.php";
  77. if (!isset($this->plugins[$class])) {
  78. if (file_exists($file)) require_once $file;
  79. if (class_exists($class) && is_subclass_of($class, "Plugin")) {
  80. $plugin = new $class($this);
  81. switch ($kind) {
  82. case $this::KIND_SYSTEM:
  83. if ($this->is_system($plugin)) {
  84. $plugin->init($this);
  85. $this->register_plugin($class, $plugin);
  86. }
  87. break;
  88. case $this::KIND_USER:
  89. if (!$this->is_system($plugin)) {
  90. $plugin->init($this);
  91. $this->register_plugin($class, $plugin);
  92. }
  93. break;
  94. case $this::KIND_ALL:
  95. $plugin->init($this);
  96. $this->register_plugin($class, $plugin);
  97. break;
  98. }
  99. }
  100. }
  101. }
  102. }
  103. function is_system($plugin) {
  104. $about = $plugin->about();
  105. return @$about[3];
  106. }
  107. // only system plugins are allowed to modify routing
  108. function add_handler($handler, $method, $sender) {
  109. $handler = str_replace("-", "_", strtolower($handler));
  110. $method = strtolower($method);
  111. if ($this->is_system($sender)) {
  112. if (!is_array($this->handlers[$handler])) {
  113. $this->handlers[$handler] = array();
  114. }
  115. $this->handlers[$handler][$method] = $sender;
  116. }
  117. }
  118. function del_handler($handler, $method) {
  119. $handler = str_replace("-", "_", strtolower($handler));
  120. $method = strtolower($method);
  121. if ($this->is_system($sender)) {
  122. unset($this->handlers[$handler][$method]);
  123. }
  124. }
  125. function lookup_handler($handler, $method) {
  126. $handler = str_replace("-", "_", strtolower($handler));
  127. $method = strtolower($method);
  128. if (is_array($this->handlers[$handler])) {
  129. if (isset($this->handlers[$handler]["*"])) {
  130. return $this->handlers[$handler]["*"];
  131. } else {
  132. return $this->handlers[$handler][$method];
  133. }
  134. }
  135. return false;
  136. }
  137. function add_command($command, $description, $sender) {
  138. $command = "-" . str_replace("-", "_", strtolower($command));
  139. $this->commands[$command] = array("description" => $description,
  140. "class" => $sender);
  141. }
  142. function del_command($command) {
  143. $command = "-" . strtolower($command);
  144. unset($this->commands[$command]);
  145. }
  146. function lookup_command($command) {
  147. $command = "-" . strtolower($command);
  148. if (is_array($this->commands[$command])) {
  149. return $this->commands[$command]["class"];
  150. } else {
  151. return false;
  152. }
  153. return false;
  154. }
  155. function get_commands() {
  156. return $this->commands;
  157. }
  158. function run_commands($args) {
  159. foreach ($this->get_commands() as $command => $data) {
  160. if (in_array($command, $args)) {
  161. $command = str_replace("-", "", $command);
  162. $data["class"]->$command($args);
  163. }
  164. }
  165. }
  166. function load_data($force = false) {
  167. if ($this->owner_uid && (!$_SESSION["plugin_storage"] || $force)) {
  168. $plugin = db_escape_string($plugin);
  169. $result = db_query($this->link, "SELECT name, content FROM ttrss_plugin_storage
  170. WHERE owner_uid = '".$this->owner_uid."'");
  171. while ($line = db_fetch_assoc($result)) {
  172. $this->storage[$line["name"]] = unserialize($line["content"]);
  173. }
  174. $_SESSION["plugin_storage"] = $this->storage;
  175. }
  176. }
  177. private function save_data($plugin) {
  178. if ($this->owner_uid) {
  179. $plugin = db_escape_string($plugin);
  180. db_query($this->link, "BEGIN");
  181. $result = db_query($this->link,"SELECT id FROM ttrss_plugin_storage WHERE
  182. owner_uid= '".$this->owner_uid."' AND name = '$plugin'");
  183. if (!isset($this->storage[$plugin]))
  184. $this->storage[$plugin] = array();
  185. $content = db_escape_string(serialize($this->storage[$plugin]));
  186. if (db_num_rows($result) != 0) {
  187. db_query($this->link, "UPDATE ttrss_plugin_storage SET content = '$content'
  188. WHERE owner_uid= '".$this->owner_uid."' AND name = '$plugin'");
  189. } else {
  190. db_query($this->link, "INSERT INTO ttrss_plugin_storage
  191. (name,owner_uid,content) VALUES
  192. ('$plugin','".$this->owner_uid."','$content')");
  193. }
  194. db_query($this->link, "COMMIT");
  195. }
  196. }
  197. function set($sender, $name, $value, $sync = true) {
  198. $idx = get_class($sender);
  199. if (!isset($this->storage[$idx]))
  200. $this->storage[$idx] = array();
  201. $this->storage[$idx][$name] = $value;
  202. $_SESSION["plugin_storage"] = $this->storage;
  203. if ($sync) $this->save_data(get_class($sender));
  204. }
  205. function get($sender, $name, $default_value = false) {
  206. $idx = get_class($sender);
  207. if (isset($this->storage[$idx][$name])) {
  208. return $this->storage[$idx][$name];
  209. } else {
  210. return $default_value;
  211. }
  212. }
  213. function get_all($sender) {
  214. $idx = get_class($sender);
  215. return $this->storage[$idx];
  216. }
  217. function clear_data($sender) {
  218. if ($this->owner_uid) {
  219. $idx = get_class($sender);
  220. unset($this->storage[$idx]);
  221. db_query($this->link, "DELETE FROM ttrss_plugin_storage WHERE name = '$idx'
  222. AND owner_uid = " . $this->owner_uid);
  223. $_SESSION["plugin_storage"] = $this->storage;
  224. }
  225. }
  226. }
  227. ?>