Extension.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <?php
  2. /**
  3. * The extension base class.
  4. */
  5. abstract class Minz_Extension {
  6. private $name;
  7. private $entrypoint;
  8. private $path;
  9. private $author;
  10. private $description;
  11. private $version;
  12. private $type;
  13. private $config_key = 'extensions';
  14. public static $authorized_types = array(
  15. 'system',
  16. 'user',
  17. );
  18. private $is_enabled;
  19. /**
  20. * The constructor to assign specific information to the extension.
  21. *
  22. * Available fields are:
  23. * - name: the name of the extension (required).
  24. * - entrypoint: the extension class name (required).
  25. * - path: the pathname to the extension files (required).
  26. * - author: the name and / or email address of the extension author.
  27. * - description: a short description to describe the extension role.
  28. * - version: a version for the current extension.
  29. * - type: "system" or "user" (default).
  30. *
  31. * @param $meta_info contains information about the extension.
  32. */
  33. final public function __construct($meta_info) {
  34. $this->name = $meta_info['name'];
  35. $this->entrypoint = $meta_info['entrypoint'];
  36. $this->path = $meta_info['path'];
  37. $this->author = isset($meta_info['author']) ? $meta_info['author'] : '';
  38. $this->description = isset($meta_info['description']) ? $meta_info['description'] : '';
  39. $this->version = isset($meta_info['version']) ? $meta_info['version'] : '0.1';
  40. $this->setType(isset($meta_info['type']) ? $meta_info['type'] : 'user');
  41. $this->is_enabled = false;
  42. }
  43. /**
  44. * Used when installing an extension (e.g. update the database scheme).
  45. *
  46. * @return true if the extension has been installed or a string explaining
  47. * the problem.
  48. */
  49. public function install() {
  50. return true;
  51. }
  52. /**
  53. * Used when uninstalling an extension (e.g. revert the database scheme to
  54. * cancel changes from install).
  55. *
  56. * @return true if the extension has been uninstalled or a string explaining
  57. * the problem.
  58. */
  59. public function uninstall() {
  60. return true;
  61. }
  62. /**
  63. * Call at the initialization of the extension (i.e. when the extension is
  64. * enabled by the extension manager).
  65. */
  66. abstract public function init();
  67. /**
  68. * Set the current extension to enable.
  69. */
  70. public function enable() {
  71. $this->is_enabled = true;
  72. }
  73. /**
  74. * Return if the extension is currently enabled.
  75. *
  76. * @return true if extension is enabled, false else.
  77. */
  78. public function isEnabled() {
  79. return $this->is_enabled;
  80. }
  81. /**
  82. * Return the content of the configure view for the current extension.
  83. *
  84. * @return the html content from ext_dir/configure.phtml, false if it does
  85. * not exist.
  86. */
  87. public function getConfigureView() {
  88. $filename = $this->path . '/configure.phtml';
  89. if (!file_exists($filename)) {
  90. return false;
  91. }
  92. ob_start();
  93. include($filename);
  94. return ob_get_clean();
  95. }
  96. /**
  97. * Handle the configure action.
  98. */
  99. public function handleConfigureAction() {}
  100. /**
  101. * Getters and setters.
  102. */
  103. public function getName() {
  104. return $this->name;
  105. }
  106. public function getEntrypoint() {
  107. return $this->entrypoint;
  108. }
  109. public function getPath() {
  110. return $this->path;
  111. }
  112. public function getAuthor() {
  113. return $this->author;
  114. }
  115. public function getDescription() {
  116. return $this->description;
  117. }
  118. public function getVersion() {
  119. return $this->version;
  120. }
  121. public function getType() {
  122. return $this->type;
  123. }
  124. private function setType($type) {
  125. if (!in_array($type, self::$authorized_types)) {
  126. throw new Minz_ExtensionException('invalid `type` info', $this->name);
  127. }
  128. $this->type = $type;
  129. }
  130. /**
  131. * Return the url for a given file.
  132. *
  133. * @param $filename name of the file to serve.
  134. * @param $type the type (js or css) of the file to serve.
  135. * @return the url corresponding to the file.
  136. */
  137. public function getFileUrl($filename, $type) {
  138. $dir = substr(strrchr($this->path, '/'), 1);
  139. $file_name_url = urlencode($dir . '/static/' . $filename);
  140. $absolute_path = $this->path . '/static/' . $filename;
  141. $mtime = @filemtime($absolute_path);
  142. $url = '/ext.php?f=' . $file_name_url .
  143. '&amp;t=' . $type .
  144. '&amp;' . $mtime;
  145. return Minz_Url::display($url, 'php');
  146. }
  147. /**
  148. * Register a controller in the Dispatcher.
  149. *
  150. * @param @base_name the base name of the controller. Final name will be:
  151. * FreshExtension_<base_name>_Controller.
  152. */
  153. public function registerController($base_name) {
  154. Minz_Dispatcher::registerController($base_name, $this->path);
  155. }
  156. /**
  157. * Register the views in order to be accessible by the application.
  158. */
  159. public function registerViews() {
  160. Minz_View::addBasePathname($this->path);
  161. }
  162. /**
  163. * Register i18n files from ext_dir/i18n/
  164. */
  165. public function registerTranslates() {
  166. $i18n_dir = $this->path . '/i18n';
  167. Minz_Translate::registerPath($i18n_dir);
  168. }
  169. /**
  170. * Register a new hook.
  171. *
  172. * @param $hook_name the hook name (must exist).
  173. * @param $hook_function the function name to call (must be callable).
  174. */
  175. public function registerHook($hook_name, $hook_function) {
  176. Minz_ExtensionManager::addHook($hook_name, $hook_function, $this);
  177. }
  178. /**
  179. * @return bool
  180. */
  181. private function isUserConfigurationEnabled() {
  182. if (!class_exists('FreshRSS_Context', false)) {
  183. return false;
  184. }
  185. if (null === FreshRSS_Context::$user_conf) {
  186. return false;
  187. }
  188. return true;
  189. }
  190. /**
  191. * @return bool
  192. */
  193. private function isExtensionConfigured() {
  194. if (!FreshRSS_Context::$user_conf->hasParam($this->config_key)) {
  195. return false;
  196. }
  197. $extensions = FreshRSS_Context::$user_conf->{$this->config_key};
  198. return array_key_exists($this->getName(), $extensions);
  199. }
  200. /**
  201. * @return array
  202. */
  203. public function getUserConfiguration() {
  204. if (!$this->isUserConfigurationEnabled()) {
  205. return [];
  206. }
  207. if (!$this->isExtensionConfigured()) {
  208. return [];
  209. }
  210. return FreshRSS_Context::$user_conf->{$this->config_key}[$this->getName()];
  211. }
  212. public function setUserConfiguration(array $configuration) {
  213. if (!$this->isUserConfigurationEnabled()) {
  214. return;
  215. }
  216. if (FreshRSS_Context::$user_conf->hasParam($this->config_key)) {
  217. $extensions = FreshRSS_Context::$user_conf->{$this->config_key};
  218. } else {
  219. $extensions = [];
  220. }
  221. $extensions[$this->getName()] = $configuration;
  222. FreshRSS_Context::$user_conf->{$this->config_key} = $extensions;
  223. FreshRSS_Context::$user_conf->save();
  224. }
  225. public function removeUserConfiguration(){
  226. if (!$this->isUserConfigurationEnabled()) {
  227. return;
  228. }
  229. if (!$this->isExtensionConfigured()) {
  230. return;
  231. }
  232. $extensions = FreshRSS_Context::$user_conf->{$this->config_key};
  233. unset($extensions[$this->getName()]);
  234. if (empty($extensions)) {
  235. $extensions = null;
  236. }
  237. FreshRSS_Context::$user_conf->{$this->config_key} = $extensions;
  238. FreshRSS_Context::$user_conf->save();
  239. }
  240. }