Files
FreshRSS/lib/Minz/Extension.php
Alexis Degrugillier 54f04e1233 Fix configuration local cache (#3431)
Before, setting values did not refresh the configuration cache. Thus
generating some weird behavior when configuring extensions.
Now, the cache is updated with the most recent values when the
configuration is modified.
2021-02-08 22:47:09 +01:00

292 lines
7.1 KiB
PHP

<?php
/**
* The extension base class.
*/
abstract class Minz_Extension {
private $name;
private $entrypoint;
private $path;
private $author;
private $description;
private $version;
private $type;
private $config_key = 'extensions';
private $user_configuration;
public static $authorized_types = array(
'system',
'user',
);
private $is_enabled;
/**
* The constructor to assign specific information to the extension.
*
* Available fields are:
* - name: the name of the extension (required).
* - entrypoint: the extension class name (required).
* - path: the pathname to the extension files (required).
* - author: the name and / or email address of the extension author.
* - description: a short description to describe the extension role.
* - version: a version for the current extension.
* - type: "system" or "user" (default).
*
* @param $meta_info contains information about the extension.
*/
final public function __construct($meta_info) {
$this->name = $meta_info['name'];
$this->entrypoint = $meta_info['entrypoint'];
$this->path = $meta_info['path'];
$this->author = isset($meta_info['author']) ? $meta_info['author'] : '';
$this->description = isset($meta_info['description']) ? $meta_info['description'] : '';
$this->version = isset($meta_info['version']) ? $meta_info['version'] : '0.1';
$this->setType(isset($meta_info['type']) ? $meta_info['type'] : 'user');
$this->is_enabled = false;
}
/**
* Used when installing an extension (e.g. update the database scheme).
*
* @return true if the extension has been installed or a string explaining
* the problem.
*/
public function install() {
return true;
}
/**
* Used when uninstalling an extension (e.g. revert the database scheme to
* cancel changes from install).
*
* @return true if the extension has been uninstalled or a string explaining
* the problem.
*/
public function uninstall() {
return true;
}
/**
* Call at the initialization of the extension (i.e. when the extension is
* enabled by the extension manager).
*/
abstract public function init();
/**
* Set the current extension to enable.
*/
public function enable() {
$this->is_enabled = true;
}
/**
* Return if the extension is currently enabled.
*
* @return true if extension is enabled, false else.
*/
public function isEnabled() {
return $this->is_enabled;
}
/**
* Return the content of the configure view for the current extension.
*
* @return the html content from ext_dir/configure.phtml, false if it does
* not exist.
*/
public function getConfigureView() {
$filename = $this->path . '/configure.phtml';
if (!file_exists($filename)) {
return false;
}
ob_start();
include($filename);
return ob_get_clean();
}
/**
* Handle the configure action.
*/
public function handleConfigureAction() {}
/**
* Getters and setters.
*/
public function getName() {
return $this->name;
}
public function getEntrypoint() {
return $this->entrypoint;
}
public function getPath() {
return $this->path;
}
public function getAuthor() {
return $this->author;
}
public function getDescription() {
return $this->description;
}
public function getVersion() {
return $this->version;
}
public function getType() {
return $this->type;
}
private function setType($type) {
if (!in_array($type, self::$authorized_types)) {
throw new Minz_ExtensionException('invalid `type` info', $this->name);
}
$this->type = $type;
}
/**
* Return the url for a given file.
*
* @param $filename name of the file to serve.
* @param $type the type (js or css) of the file to serve.
* @return the url corresponding to the file.
*/
public function getFileUrl($filename, $type) {
$dir = substr(strrchr($this->path, '/'), 1);
$file_name_url = urlencode($dir . '/static/' . $filename);
$absolute_path = $this->path . '/static/' . $filename;
$mtime = @filemtime($absolute_path);
$url = '/ext.php?f=' . $file_name_url .
'&amp;t=' . $type .
'&amp;' . $mtime;
return Minz_Url::display($url, 'php');
}
/**
* Register a controller in the Dispatcher.
*
* @param @base_name the base name of the controller. Final name will be:
* FreshExtension_<base_name>_Controller.
*/
public function registerController($base_name) {
Minz_Dispatcher::registerController($base_name, $this->path);
}
/**
* Register the views in order to be accessible by the application.
*/
public function registerViews() {
Minz_View::addBasePathname($this->path);
}
/**
* Register i18n files from ext_dir/i18n/
*/
public function registerTranslates() {
$i18n_dir = $this->path . '/i18n';
Minz_Translate::registerPath($i18n_dir);
}
/**
* Register a new hook.
*
* @param $hook_name the hook name (must exist).
* @param $hook_function the function name to call (must be callable).
*/
public function registerHook($hook_name, $hook_function) {
Minz_ExtensionManager::addHook($hook_name, $hook_function, $this);
}
/**
* @return bool
*/
private function isUserConfigurationEnabled() {
if (!class_exists('FreshRSS_Context', false)) {
return false;
}
if (null === FreshRSS_Context::$user_conf) {
return false;
}
return true;
}
/**
* @return bool
*/
private function isExtensionConfigured() {
if (!FreshRSS_Context::$user_conf->hasParam($this->config_key)) {
return false;
}
$extensions = FreshRSS_Context::$user_conf->{$this->config_key};
return array_key_exists($this->getName(), $extensions);
}
/**
* @return array
*/
public function getUserConfiguration() {
if (!$this->isUserConfigurationEnabled()) {
return [];
}
if (!$this->isExtensionConfigured()) {
return [];
}
return FreshRSS_Context::$user_conf->{$this->config_key}[$this->getName()];
}
/**
* @param mixed $default
* @return mixed
*/
public function getUserConfigurationValue(string $key, $default = null) {
if (!is_array($this->user_configuration)) {
$this->user_configuration = $this->getUserConfiguration();
}
if (array_key_exists($key, $this->user_configuration)) {
return $this->user_configuration[$key];
}
return $default;
}
public function setUserConfiguration(array $configuration) {
if (!$this->isUserConfigurationEnabled()) {
return;
}
if (FreshRSS_Context::$user_conf->hasParam($this->config_key)) {
$extensions = FreshRSS_Context::$user_conf->{$this->config_key};
} else {
$extensions = [];
}
$extensions[$this->getName()] = $configuration;
FreshRSS_Context::$user_conf->{$this->config_key} = $extensions;
FreshRSS_Context::$user_conf->save();
$this->user_configuration = $configuration;
}
public function removeUserConfiguration(){
if (!$this->isUserConfigurationEnabled()) {
return;
}
if (!$this->isExtensionConfigured()) {
return;
}
$extensions = FreshRSS_Context::$user_conf->{$this->config_key};
unset($extensions[$this->getName()]);
if (empty($extensions)) {
$extensions = null;
}
FreshRSS_Context::$user_conf->{$this->config_key} = $extensions;
FreshRSS_Context::$user_conf->save();
$this->user_configuration = null;
}
}