PHP Classes

File: src/Plugin/Manager/PluginManager.php

Recommend this page to a friend!
  Packages of Thierry Feuzeu   Jaxon   src/Plugin/Manager/PluginManager.php   Download  
File: src/Plugin/Manager/PluginManager.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Jaxon
Call PHP classes from JavaScript using AJAX
Author: By
Last change:
Date: 4 months ago
Size: 7,952 bytes
 

Contents

Class file image Download
<?php

/**
 * PluginManager.php - Jaxon plugin registry
 *
 * Register Jaxon plugins and callables.
 *
 * @package jaxon-core
 * @author Jared White
 * @author J. Max Wilson
 * @author Joseph Woolley
 * @author Steffen Konerow
 * @author Thierry Feuzeu <thierry.feuzeu@gmail.com>
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson
 * @copyright 2016 Thierry Feuzeu <thierry.feuzeu@gmail.com>
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
 * @link https://github.com/jaxon-php/jaxon-core
 */

namespace Jaxon\Plugin\Manager;

use
Jaxon\Jaxon;
use
Jaxon\App\I18n\Translator;
use
Jaxon\Di\Container;
use
Jaxon\Exception\SetupException;
use
Jaxon\Plugin\CallableRegistryInterface;
use
Jaxon\Plugin\Code\CodeGenerator;
use
Jaxon\Plugin\CodeGeneratorInterface;
use
Jaxon\Plugin\PluginInterface;
use
Jaxon\Plugin\Request\CallableClass\CallableClassPlugin;
use
Jaxon\Plugin\Request\CallableClass\CallableDirPlugin;
use
Jaxon\Plugin\Request\CallableFunction\CallableFunctionPlugin;
use
Jaxon\Plugin\RequestHandlerInterface;
use
Jaxon\Plugin\Response\Databag\DatabagPlugin;
use
Jaxon\Plugin\Response\Dialog\DialogPlugin;
use
Jaxon\Plugin\Response\Script\ScriptPlugin;
use
Jaxon\Plugin\Response\Pagination\PaginatorPlugin;
use
Jaxon\Plugin\Response\Psr\PsrPlugin;
use
Jaxon\Plugin\ResponsePluginInterface;
use
Jaxon\Request\Handler\ParameterReader;

use function
class_implements;
use function
in_array;

class
PluginManager
{
   
/**
     * Request plugins, indexed by name
     *
     * @var array<string>
     */
   
private $aRegistryPlugins = [];

   
/**
     * Request handlers, indexed by name
     *
     * @var array<string>
     */
   
private $aRequestHandlers = [];

   
/**
     * Response plugins, indexed by name
     *
     * @var array<string>
     */
   
private $aResponsePlugins = [];

   
/**
     * The constructor
     *
     * @param Container $di
     * @param CodeGenerator $xCodeGenerator
     * @param Translator $xTranslator
     */
   
public function __construct(private Container $di,
        private
CodeGenerator $xCodeGenerator, private Translator $xTranslator)
    {}

   
/**
     * Get the request plugins
     *
     * @return array<class-string>
     */
   
public function getRequestHandlers(): array
    {
        return
$this->aRequestHandlers;
    }

   
/**
     * Register a plugin
     *
     * @param class-string $sClassName The plugin class
     * @param string $sPluginName The plugin name
     * @param array $aInterfaces The plugin interfaces
     *
     * @return int
     * @throws SetupException
     */
   
private function _registerPlugin(string $sClassName, string $sPluginName, array $aInterfaces): int
   
{
       
// Any plugin must implement the PluginInterface interface.
       
if(!in_array(PluginInterface::class, $aInterfaces))
        {
           
$sMessage = $this->xTranslator->trans('errors.register.invalid', [
               
'name' => $sClassName,
            ]);
            throw new
SetupException($sMessage);
        }

       
// Response plugin.
       
if(in_array(ResponsePluginInterface::class, $aInterfaces))
        {
           
$this->aResponsePlugins[$sPluginName] = $sClassName;
            return
1;
        }

       
// Request plugin.
       
$nCount = 0;
        if(
in_array(CallableRegistryInterface::class, $aInterfaces))
        {
           
$this->aRegistryPlugins[$sPluginName] = $sClassName;
           
$nCount++;
        }
        if(
in_array(RequestHandlerInterface::class, $aInterfaces))
        {
           
$this->aRequestHandlers[$sPluginName] = $sClassName;
           
$nCount++;
        }
        return
$nCount;
    }

   
/**
     * Register a plugin
     *
     * Below is a table for priorities and their description:
     * - 0 to 999: Plugins that are part of or extensions to the jaxon core
     * - 1000 to 8999: User created plugins, typically, these plugins don't care about order
     * - 9000 to 9999: Plugins that generally need to be last or near the end of the plugin list
     *
     * @param class-string $sClassName The plugin class
     * @param string $sPluginName The plugin name
     * @param integer $nPriority The plugin priority, used to order the plugins
     *
     * @return void
     * @throws SetupException
     */
   
public function registerPlugin(string $sClassName, string $sPluginName, int $nPriority = 1000): void
   
{
       
$aInterfaces = class_implements($sClassName);
       
$nCount = $this->_registerPlugin($sClassName, $sPluginName, $aInterfaces);

       
// Any plugin can implement the CodeGeneratorInterface interface.
       
if(in_array(CodeGeneratorInterface::class, $aInterfaces))
        {
           
$this->xCodeGenerator->addCodeGenerator($sClassName, $nPriority);
           
$nCount++;
        }
       
// The class is not a valid plugin.
       
if($nCount === 0)
        {
           
$sMessage = $this->xTranslator->trans('errors.register.invalid', [
               
'name' => $sClassName,
            ]);
            throw new
SetupException($sMessage);
        }

       
// Register the plugin in the DI container, if necessary
       
if(!$this->di->has($sClassName))
        {
           
$this->di->auto($sClassName);
        }
    }

   
/**
     * Find the specified response plugin by name or class name
     *
     * @template R of ResponsePluginInterface
     * @param string|class-string<R> $sName The name of the plugin
     *
     * @return ($sName is class-string ? R : ResponsePluginInterface)|null
     */
   
public function getResponsePlugin(string $sName): ?ResponsePluginInterface
   
{
        return
$this->di->h($sName) ? $this->di->g($sName) :
            (!isset(
$this->aResponsePlugins[$sName]) ? null :
           
$this->di->g($this->aResponsePlugins[$sName]));
    }

   
/**
     * Register a callable function or class
     *
     * Call the request plugin with the $sType defined as name.
     *
     * @param string $sType The type of request handler being registered
     * @param string $sCallable The callable entity being registered
     * @param array|string $xOptions The associated options
     *
     * @return void
     * @throws SetupException
     */
   
public function registerCallable(string $sType, string $sCallable, $xOptions = []): void
   
{
        if(isset(
$this->aRegistryPlugins[$sType]) &&
            (
$xPlugin = $this->di->g($this->aRegistryPlugins[$sType])))
        {
           
$xPlugin->register($sType, $sCallable, $xPlugin->checkOptions($sCallable, $xOptions));
            return;
        }
        throw new
SetupException($this->xTranslator->trans('errors.register.plugin',
            [
'name' => $sType, 'callable' => $sCallable]));
    }

   
/**
     * Register the Jaxon request plugins
     *
     * @return void
     * @throws SetupException
     */
   
public function registerPlugins(): void
   
{
       
// Request plugins
       
$this->registerPlugin(CallableClassPlugin::class, Jaxon::CALLABLE_CLASS, 101);
       
$this->registerPlugin(CallableFunctionPlugin::class, Jaxon::CALLABLE_FUNCTION, 102);
       
$this->registerPlugin(CallableDirPlugin::class, Jaxon::CALLABLE_DIR, 103);

       
// Response plugins
       
$this->registerPlugin(ScriptPlugin::class, ScriptPlugin::NAME, 700);
       
$this->registerPlugin(DatabagPlugin::class, DatabagPlugin::NAME, 700);
       
$this->registerPlugin(DialogPlugin::class, DialogPlugin::NAME, 750);
       
$this->registerPlugin(PaginatorPlugin::class, PaginatorPlugin::NAME, 800);
       
$this->registerPlugin(PsrPlugin::class, PsrPlugin::NAME, 850);
    }

   
/**
     * Get the parameter reader
     *
     * @return ParameterReader
     */
   
public function getParameterReader(): ParameterReader
   
{
        return
$this->di->g(ParameterReader::class);
    }
}