Skip to content
Snippets Groups Projects
plugins.class.php 8.55 KiB
<?php

/**
 * WIP
 * base class for all plugin types to read available plugins
 * and its metadata
 * 
 * @example
 *        $CI_plugins=new ciplugins();
 *        print_r($CI_plugins->getPluginTypes());
 * 
 *        // $CI_plugins->setType('build');
 *        // print_r($CI_plugins->getPlugins());
 *        print_r($CI_plugins->getPlugins('build'));
 * 
 *        $CI_plugins->setPlugin('tgz', 'build'); // plugin name + type
 *
 * 
 * @author axel
 * 
 * 2024-08-26  v1.1  Axel Hahn  php8 only; added variable types
 */
class ciplugins
{

    /**
     * start path of all plugin types (as subdirs)
     * @var string
     */
    protected string $_sPlugindir = '';

    /**
     * path of the currently set plugin
     * @var string
     */
    protected string $_sSelfdir = '';

    /**
     * url of set plugin
     * @var string
     */
    protected string $_sSelfurl = '';

    /**
     * current plugin type - can be set via setType or setPlugin
     * @var string
     */
    protected string $_sType = '';

    /**
     * current plugin name - can be set via setPlugin
     * @var string
     */
    protected string $_sPluginname = '';

    /**
     * plugin language
     * @var string
     */
    protected string $_sLang = "en-en";

    /**
     * plugin language texts (lang*.json)
     * @var array
     */
    protected array $_aLang = [];

    /**
     * plugin configuration data (config.json)
     * @var array
     */
    protected array $_aConfig = [];

    /**
     * global plugins config
     * see config/config_custom.php - key plugins
     * @var array
     */
    protected array $_aGlobals = [];

    // ---------------------------------------------------------------
    // CONSTRUCTOR
    // ---------------------------------------------------------------

    /**
     * Constructor
     * initialize plugins
     *
     * @param  array  $aGlobals  global settings for plugins
     * @return boolean
     */
    public function __construct(array $aGlobals = [])
    {
        $this->_sPlugindir = dirname(__DIR__) . '/plugins';
        $this->setGlobalCustoms($aGlobals);
    }

    /**
     * Global configs
     * see config/config_custom.php - key plugins
     * 
     * @param  array  $aGlobals  global settings for plugins
     * @return boolean
     */
    public function setGlobalCustoms(array $aGlobals): bool
    {
        $this->_aGlobals = $aGlobals;
        return true;
    }
    // ---------------------------------------------------------------
    // FOR LISTING :: GETTER
    // ---------------------------------------------------------------

    /**
     * Get an array of available plugin types read from filesystem
     * @return array
     */
    public function getPluginTypes(): array
    {
        $aReturn = [];
        foreach (glob($this->_sPlugindir . '/*', GLOB_ONLYDIR) as $sMydir) {
            $aReturn[] = basename($sMydir);
        }
        return $aReturn;
    }

    /**
     * Get an array of available plugins read from filesystem
     * 
     * @param  string  $sType  set a new type of plugin; default: use current type
     * @return array
     */
    public function getPlugins(string $sType = ''): array
    {
        $aReturn = [];
        if ($sType) {
            if (!$this->setType($sType)) {
                return $aReturn;
            }
        }
        foreach (glob($this->_sPlugindir . '/' . $this->_sType . '/*', GLOB_ONLYDIR) as $sMydir) {
            $aReturn[] = basename($sMydir);
        }
        return $aReturn;
    }

    /**
     * Get an array of enabled plugins
     * config/config_custom.php - key "plugins" -> [type] -> [plugin] -> enabled
     * and it must be physically available
     * 
     * @param  string  $sType  set a new type of plugin; default: use current type
     * @return array
     */
    public function getEnabledPlugins(string $sType = ''): array
    {
        $aReturn = [];
        if ($sType) {
            if (!$this->setType($sType)) {
                return $aReturn;
            }
        }
        if (
            isset($this->_aGlobals[$this->_sType])
            && is_array($this->_aGlobals[$this->_sType])
        ) {
            foreach ($this->_aGlobals[$this->_sType] as $sPluginName => $aData) {
                if (
                    isset($aData['enabled'])
                    && $aData['enabled']
                    && is_dir($this->_sPlugindir . '/' . $this->_sType . '/' . $sPluginName)
                ) {
                    $aReturn[] = $sPluginName;
                }
            }
        }
        return $aReturn;
    }

    // ---------------------------------------------------------------
    // 
    // BELOW ARE METHODS FOR A SPECIFICLY SET PLUGIN AND TYPE
    // 
    // ---------------------------------------------------------------

    // ---------------------------------------------------------------
    // SETTER
    // ---------------------------------------------------------------

    /**
     * Set a type for plugins ... what is a name of a subdir in the plugins directory
     * @param  string  $sType  Name of a plugin type, e.g. build|rollout
     * @return bool
     */
    public function setType(string $sType): bool
    {
        $this->_sType = '';
        if (!$sType || !is_dir($this->_sPlugindir . '/' . $sType)) {
            return false;
        }
        $this->_sType = $sType;
        return true;
    }

    /**
     * Reset vars before setting a new plugin;
     * called in testPlugin()
     * @return boolean
     */
    protected function _resetPluginData(): bool
    {
        $this->_sPluginname = false;
        $this->_sSelfdir = false;
        $this->_sSelfurl = false;
        $this->_aLang = [];
        $this->_aConfig = [];
        return true;
    }

    /**
     * Test if a plugin of given type exists
     * 
     * It returns the path of php class for true 
     * or boolean false if it does not exist
     * 
     * This can be used standalone to embed html code 
     * without loading any php code of the plugin class.
     * 
     * @param  string  $sPluginName  name of the plugin
     * @param  string  $sType        optional: set a type
     * @return bool|string
     */
    public function testPlugin(string $sPluginName, string $sType = ''): bool|string
    {
        $this->_resetPluginData();
        if ($sType) {
            if (!$this->setType($sType)) {
                return false;
            }
        }
        $this->_sSelfdir = $this->_sPlugindir . '/' . $this->_sType . '/' . $sPluginName;
        $sFile = $this->_sSelfdir . '/plugin.php';
        if (!file_exists($sFile)) {
            // die(' MISS '.$sFile);
            $this->_sSelfdir = false;
            return false;
        }
        $this->_sPluginname = $sPluginName;
        $this->_sSelfurl = '/deployment/plugins/' . $this->_sType . '/' . $sPluginName;
        return $sFile;
    }

    /**
     * Set a plugin with autoload of its php class
     * It returns a boolean
     * 
     * @param  string  $sPluginName  name of the plugin
     * @param  string  $sType        optional: set a type
     * @return bool
     */
    public function setPlugin(string $sPluginName, string $sType = ''): bool
    {
        $sFile = $this->testPlugin($sPluginName, $sType);
        if (!$sFile) {
            return false;
        }
        include_once $sFile;
        return true;
    }
    // ---------------------------------------------------------------
    // getter for plugin
    // ---------------------------------------------------------------
    /**
     * Get config entry of a plugin
     * @param  string  $sKey  name of config value
     * @return mixed
     */
    public function getConfigitem(string $sKey): mixed
    {
        return $this->_aConfig[$sKey] ?? false;
    }
    /**
     * get plugin config from its config.json
     * works with
     *   - shellcmd plugins
     * @return array
     */
    public function getPluginConfig(): array
    {
        if (count($this->_aConfig)) {
            return $this->_aConfig;
        }
        $this->_aConfig = (file_exists($this->_sSelfdir . '/config.json'))
            ? json_decode(file_get_contents($this->_sSelfdir . '/config.json'), 1)
            : ["error" => "config.json not found in " . $this->_sSelfdir]
        ;
        return $this->_aConfig;
    }
    // ---------------------------------------------------------------
    // access plugin php class
    // ---------------------------------------------------------------

    /**
     * Get the classname of a plugin (it is generated by type and plugin name)
     * @return string
     */
    public function getPluginClassname(): string
    {
        return $this->_sType . '_' . $this->_sPluginname;
    }

}