primo commit

This commit is contained in:
2024-12-17 17:34:10 +01:00
commit e650f8df99
16435 changed files with 2451012 additions and 0 deletions

View File

@ -0,0 +1,386 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory;
defined('_JEXEC') || die;
use Exception;
use FOF40\Container\Container;
use FOF40\Controller\Controller;
use FOF40\Dispatcher\Dispatcher;
use FOF40\Factory\Exception\ControllerNotFound;
use FOF40\Factory\Exception\DispatcherNotFound;
use FOF40\Factory\Exception\ModelNotFound;
use FOF40\Factory\Exception\ToolbarNotFound;
use FOF40\Factory\Exception\TransparentAuthenticationNotFound;
use FOF40\Factory\Exception\ViewNotFound;
use FOF40\Model\Model;
use FOF40\Toolbar\Toolbar;
use FOF40\TransparentAuthentication\TransparentAuthentication;
use FOF40\View\View;
use FOF40\View\ViewTemplateFinder;
use RuntimeException;
/**
* MVC object factory. This implements the basic functionality, i.e. creating MVC objects only if the classes exist in
* the same component section (front-end, back-end) you are currently running in. The Dispatcher and Toolbar will be
* created from default objects if specialised classes are not found in your application.
*/
class BasicFactory implements FactoryInterface
{
/** @var Container The container we belong to */
protected $container;
/**
* Section used to build the namespace prefix. We have to pass it since in CLI we need
* to force the section we're in (ie Site or Admin). {@see \FOF40\Container\Container::getNamespacePrefix() } for
* valid values
*
* @var string
*/
protected $section = 'auto';
/**
* Public constructor for the factory object
*
* @param Container $container The container we belong to
*/
public function __construct(Container $container)
{
$this->container = $container;
}
/**
* Create a new Controller object
*
* @param string $viewName The name of the view we're getting a Controller for.
* @param array $config Optional MVC configuration values for the Controller object.
*
* @return Controller
*/
public function controller(string $viewName, array $config = []): Controller
{
$controllerClass = $this->container->getNamespacePrefix($this->getSection()) . 'Controller\\' . ucfirst($viewName);
try
{
return $this->createController($controllerClass, $config);
}
catch (ControllerNotFound $e)
{
}
$controllerClass = $this->container->getNamespacePrefix($this->getSection()) . 'Controller\\' . ucfirst($this->container->inflector->singularize($viewName));
return $this->createController($controllerClass, $config);
}
/**
* Create a new Model object
*
* @param string $viewName The name of the view we're getting a Model for.
* @param array $config Optional MVC configuration values for the Model object.
*
* @return Model
*/
public function model(string $viewName, array $config = []): Model
{
$modelClass = $this->container->getNamespacePrefix($this->getSection()) . 'Model\\' . ucfirst($viewName);
try
{
return $this->createModel($modelClass, $config);
}
catch (ModelNotFound $e)
{
}
$modelClass = $this->container->getNamespacePrefix($this->getSection()) . 'Model\\' . ucfirst($this->container->inflector->singularize($viewName));
return $this->createModel($modelClass, $config);
}
/**
* Create a new View object
*
* @param string $viewName The name of the view we're getting a View object for.
* @param string $viewType The type of the View object. By default it's "html".
* @param array $config Optional MVC configuration values for the View object.
*
* @return View
*/
public function view(string $viewName, $viewType = 'html', array $config = []): View
{
$container = $this->container;
$prefix = $this->container->getNamespacePrefix($this->getSection());
$viewClass = $prefix . 'View\\' . ucfirst($viewName) . '\\' . ucfirst($viewType);
try
{
return $this->createView($viewClass, $config);
}
catch (ViewNotFound $e)
{
}
$viewClass = $prefix . 'View\\' . ucfirst($container->inflector->singularize($viewName)) . '\\' . ucfirst($viewType);
return $this->createView($viewClass, $config);
}
/**
* Creates a new Dispatcher
*
* @param array $config The configuration values for the Dispatcher object
*
* @return Dispatcher
*/
public function dispatcher(array $config = []): Dispatcher
{
$dispatcherClass = $this->container->getNamespacePrefix($this->getSection()) . 'Dispatcher\\Dispatcher';
try
{
return $this->createDispatcher($dispatcherClass, $config);
}
catch (DispatcherNotFound $e)
{
// Not found. Return the default Dispatcher
return new Dispatcher($this->container, $config);
}
}
/**
* Creates a new Toolbar
*
* @param array $config The configuration values for the Toolbar object
*
* @return Toolbar
*/
public function toolbar(array $config = []): Toolbar
{
$toolbarClass = $this->container->getNamespacePrefix($this->getSection()) . 'Toolbar\\Toolbar';
try
{
return $this->createToolbar($toolbarClass, $config);
}
catch (ToolbarNotFound $e)
{
// Not found. Return the default Toolbar
return new Toolbar($this->container, $config);
}
}
/**
* Creates a new TransparentAuthentication handler
*
* @param array $config The configuration values for the TransparentAuthentication object
*
* @return TransparentAuthentication
*/
public function transparentAuthentication(array $config = []): TransparentAuthentication
{
$authClass = $this->container->getNamespacePrefix($this->getSection()) . 'TransparentAuthentication\\TransparentAuthentication';
try
{
return $this->createTransparentAuthentication($authClass, $config);
}
catch (TransparentAuthenticationNotFound $e)
{
// Not found. Return the default TA
return new TransparentAuthentication($this->container, $config);
}
}
/**
* Creates a view template finder object for a specific View
*
* The default configuration is:
* Look for .php, .blade.php files; default layout "default"; no default sub-template;
* look only for the specified view; do NOT fall back to the default layout or sub-template;
* look for templates ONLY in site or admin, depending on where we're running from
*
* @param View $view The view this view template finder will be attached to
* @param array $config Configuration variables for the object
*
* @return ViewTemplateFinder
*
* @throws Exception
*/
public function viewFinder(View $view, array $config = []): ViewTemplateFinder
{
// Initialise the configuration with the default values
$defaultConfig = [
'extensions' => ['.php', '.blade.php'],
'defaultLayout' => 'default',
'defaultTpl' => '',
'strictView' => true,
'strictTpl' => true,
'strictLayout' => true,
'sidePrefix' => 'auto',
];
$config = array_merge($defaultConfig, $config);
// Apply fof.xml overrides
$appConfig = $this->container->appConfig;
$key = "views." . ucfirst($view->getName()) . ".config";
$fofXmlConfig = [
'extensions' => $appConfig->get("$key.templateExtensions", $config['extensions']),
'strictView' => $appConfig->get("$key.templateStrictView", $config['strictView']),
'strictTpl' => $appConfig->get("$key.templateStrictTpl", $config['strictTpl']),
'strictLayout' => $appConfig->get("$key.templateStrictLayout", $config['strictLayout']),
'sidePrefix' => $appConfig->get("$key.templateLocation", $config['sidePrefix']),
];
$config = array_merge($config, $fofXmlConfig);
// Create the new view template finder object
return new ViewTemplateFinder($view, $config);
}
/**
* @return string
*/
public function getSection(): string
{
return $this->section;
}
/**
* @param string $section
*/
public function setSection(string $section): void
{
$this->section = $section;
}
/**
* Creates a Controller object
*
* @param string $controllerClass The fully qualified class name for the Controller
* @param array $config Optional MVC configuration values for the Controller object.
*
* @return Controller
*
* @throws RuntimeException If the $controllerClass does not exist
*/
protected function createController(string $controllerClass, array $config = []): Controller
{
if (!class_exists($controllerClass))
{
throw new ControllerNotFound($controllerClass);
}
return new $controllerClass($this->container, $config);
}
/**
* Creates a Model object
*
* @param string $modelClass The fully qualified class name for the Model
* @param array $config Optional MVC configuration values for the Model object.
*
* @return Model
*
* @throws RuntimeException If the $modelClass does not exist
*/
protected function createModel(string $modelClass, array $config = []): Model
{
if (!class_exists($modelClass))
{
throw new ModelNotFound($modelClass);
}
return new $modelClass($this->container, $config);
}
/**
* Creates a View object
*
* @param string $viewClass The fully qualified class name for the View
* @param array $config Optional MVC configuration values for the View object.
*
* @return View
*
* @throws RuntimeException If the $viewClass does not exist
*/
protected function createView(string $viewClass, array $config = []): View
{
if (!class_exists($viewClass))
{
throw new ViewNotFound($viewClass);
}
return new $viewClass($this->container, $config);
}
/**
* Creates a Toolbar object
*
* @param string $toolbarClass The fully qualified class name for the Toolbar
* @param array $config The configuration values for the Toolbar object
*
* @return Toolbar
*
* @throws RuntimeException If the $toolbarClass does not exist
*/
protected function createToolbar(string $toolbarClass, array $config = []): Toolbar
{
if (!class_exists($toolbarClass))
{
throw new ToolbarNotFound($toolbarClass);
}
return new $toolbarClass($this->container, $config);
}
/**
* Creates a Dispatcher object
*
* @param string $dispatcherClass The fully qualified class name for the Dispatcher
* @param array $config The configuration values for the Dispatcher object
*
* @return Dispatcher
*
* @throws RuntimeException If the $dispatcherClass does not exist
*/
protected function createDispatcher(string $dispatcherClass, array $config = []): Dispatcher
{
if (!class_exists($dispatcherClass))
{
throw new DispatcherNotFound($dispatcherClass);
}
return new $dispatcherClass($this->container, $config);
}
/**
* Creates a TransparentAuthentication object
*
* @param string $authClass The fully qualified class name for the TransparentAuthentication
* @param array $config The configuration values for the TransparentAuthentication object
*
* @return TransparentAuthentication
*
* @throws RuntimeException If the $authClass does not exist
*/
protected function createTransparentAuthentication(string $authClass, array $config): TransparentAuthentication
{
if (!class_exists($authClass))
{
throw new TransparentAuthenticationNotFound($authClass);
}
return new $authClass($this->container, $config);
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Exception;
defined('_JEXEC') || die;
use Exception;
use Joomla\CMS\Language\Text;
use RuntimeException;
class ControllerNotFound extends RuntimeException
{
public function __construct(string $controller, int $code = 500, Exception $previous = null)
{
$message = Text::sprintf('LIB_FOF40_CONTROLLER_ERR_NOT_FOUND', $controller);
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Exception;
defined('_JEXEC') || die;
use Exception;
use Joomla\CMS\Language\Text;
use RuntimeException;
class DispatcherNotFound extends RuntimeException
{
public function __construct(string $dispatcherClass, int $code = 500, Exception $previous = null)
{
$message = Text::sprintf('LIB_FOF40_DISPATCHER_ERR_NOT_FOUND', $dispatcherClass);
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Exception;
defined('_JEXEC') || die;
use Exception;
use Joomla\CMS\Language\Text;
use RuntimeException;
class ModelNotFound extends RuntimeException
{
public function __construct(string $modelClass, int $code = 500, Exception $previous = null)
{
$message = Text::sprintf('LIB_FOF40_MODEL_ERR_NOT_FOUND', $modelClass);
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Exception;
defined('_JEXEC') || die;
use Exception;
use Joomla\CMS\Language\Text;
use RuntimeException;
class ToolbarNotFound extends RuntimeException
{
public function __construct(string $toolbarClass, int $code = 500, Exception $previous = null)
{
$message = Text::sprintf('LIB_FOF40_TOOLBAR_ERR_NOT_FOUND', $toolbarClass);
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Exception;
defined('_JEXEC') || die;
use Exception;
use Joomla\CMS\Language\Text;
use RuntimeException;
class TransparentAuthenticationNotFound extends RuntimeException
{
public function __construct(string $taClass, int $code = 500, Exception $previous = null)
{
$message = Text::sprintf('LIB_FOF40_TRANSPARENTAUTH_ERR_NOT_FOUND', $taClass);
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Exception;
defined('_JEXEC') || die;
use Exception;
use Joomla\CMS\Language\Text;
use RuntimeException;
class ViewNotFound extends RuntimeException
{
public function __construct(string $viewClass, int $code = 500, Exception $previous = null)
{
$message = Text::sprintf('LIB_FOF40_VIEW_ERR_NOT_FOUND', $viewClass);
parent::__construct($message, $code, $previous);
}
}

View File

@ -0,0 +1,110 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory;
defined('_JEXEC') || die;
use FOF40\Container\Container;
use FOF40\Controller\Controller;
use FOF40\Dispatcher\Dispatcher;
use FOF40\Model\Model;
use FOF40\Toolbar\Toolbar;
use FOF40\TransparentAuthentication\TransparentAuthentication;
use FOF40\View\View;
use FOF40\View\ViewTemplateFinder;
/**
* Interface for the MVC object factory
*/
interface FactoryInterface
{
/**
* Public constructor for the factory object
*
* @param Container $container The container we belong to
*/
public function __construct(Container $container);
/**
* Create a new Controller object
*
* @param string $viewName The name of the view we're getting a Controller for.
* @param array $config Optional MVC configuration values for the Controller object.
*
* @return Controller
*/
public function controller(string $viewName, array $config = []): Controller;
/**
* Create a new Model object
*
* @param string $viewName The name of the view we're getting a Model for.
* @param array $config Optional MVC configuration values for the Model object.
*
* @return Model
*/
public function model(string $viewName, array $config = []): Model;
/**
* Create a new View object
*
* @param string $viewName The name of the view we're getting a View object for.
* @param string $viewType The type of the View object. By default it's "html".
* @param array $config Optional MVC configuration values for the View object.
*
* @return View
*/
public function view(string $viewName, $viewType = 'html', array $config = []): View;
/**
* Creates a new Toolbar
*
* @param array $config The configuration values for the Toolbar object
*
* @return Toolbar
*/
public function toolbar(array $config = []): Toolbar;
/**
* Creates a new Dispatcher
*
* @param array $config The configuration values for the Dispatcher object
*
* @return Dispatcher
*/
public function dispatcher(array $config = []): Dispatcher;
/**
* Creates a new TransparentAuthentication handler
*
* @param array $config The configuration values for the TransparentAuthentication object
*
* @return TransparentAuthentication
*/
public function transparentAuthentication(array $config = []): TransparentAuthentication;
/**
* Creates a view template finder object for a specific View
*
* @param View $view The view this view template finder will be attached to
* @param array $config Configuration variables for the object
*
* @return ViewTemplateFinder
*/
public function viewFinder(View $view, array $config = []): ViewTemplateFinder;
/**
* @return string
*/
public function getSection(): string;
/**
* @param string $section
*/
public function setSection(string $section): void;
}

View File

@ -0,0 +1,55 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Magic;
defined('_JEXEC') || die;
use FOF40\Container\Container;
abstract class BaseFactory
{
/**
* @var Container|null The container where this factory belongs to
*/
protected $container;
/**
* Section used to build the namespace prefix. We have to pass it since in CLI we need
* to force the section we're in (ie Site or Admin). {@see \FOF40\Container\Container::getNamespacePrefix() } for
* valid values
*
* @var string
*/
protected $section = 'auto';
/**
* Public constructor
*
* @param Container $container The container we belong to
*/
public function __construct(Container $container)
{
$this->container = $container;
}
/**
* @return string
*/
public function getSection(): string
{
return $this->section;
}
/**
* @param string $section
*/
public function setSection(string $section): void
{
$this->section = $section;
}
}

View File

@ -0,0 +1,76 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Magic;
defined('_JEXEC') || die;
use FOF40\Controller\DataController;
use FOF40\Factory\Exception\ControllerNotFound;
/**
* Creates a DataController object instance based on the information provided by the fof.xml configuration file
*/
class ControllerFactory extends BaseFactory
{
/**
* Create a new object instance
*
* @param string $name The name of the class we're making
* @param array $config The config parameters which override the fof.xml information
*
* @return DataController A new DataController object
*/
public function make(string $name = null, array $config = []): DataController
{
if (empty($name))
{
throw new ControllerNotFound($name);
}
$appConfig = $this->container->appConfig;
$name = ucfirst($name);
$defaultConfig = [
'name' => $name,
'default_task' => $appConfig->get("views.$name.config.default_task", 'main'),
'autoRouting' => $appConfig->get("views.$name.config.autoRouting", 1),
'csrfProtection' => $appConfig->get("views.$name.config.csrfProtection", 2),
'viewName' => $appConfig->get("views.$name.config.viewName", null),
'modelName' => $appConfig->get("views.$name.config.modelName", null),
'taskPrivileges' => $appConfig->get("views.$name.acl"),
'cacheableTasks' => $appConfig->get("views.$name.config.cacheableTasks", [
'browse',
'read',
]),
'taskMap' => $appConfig->get("views.$name.taskmap"),
];
$config = array_merge($defaultConfig, $config);
$className = $this->container->getNamespacePrefix($this->getSection()) . 'Controller\\DefaultDataController';
if (!class_exists($className, true))
{
$className = 'FOF40\\Controller\\DataController';
}
$controller = new $className($this->container, $config);
$taskMap = $config['taskMap'];
if (is_array($taskMap) && !empty($taskMap))
{
foreach ($taskMap as $virtualTask => $method)
{
$controller->registerTask($virtualTask, $method);
}
}
return $controller;
}
}

View File

@ -0,0 +1,41 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Magic;
defined('_JEXEC') || die;
use FOF40\Dispatcher\Dispatcher;
/**
* Creates a Dispatcher object instance based on the information provided by the fof.xml configuration file
*/
class DispatcherFactory extends BaseFactory
{
/**
* Create a new object instance
*
* @param array $config The config parameters which override the fof.xml information
*
* @return Dispatcher A new Dispatcher object
*/
public function make(array $config = []): Dispatcher
{
$appConfig = $this->container->appConfig;
$defaultConfig = $appConfig->get('dispatcher.*');
$config = array_merge($defaultConfig, $config);
$className = $this->container->getNamespacePrefix($this->getSection()) . 'Dispatcher\\DefaultDispatcher';
if (!class_exists($className, true))
{
$className = '\\FOF40\\Dispatcher\\Dispatcher';
}
return new $className($this->container, $config);
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Magic;
defined('_JEXEC') || die;
use FOF40\Factory\Exception\ModelNotFound;
use FOF40\Model\DataModel;
use FOF40\Model\TreeModel;
/**
* Creates a DataModel/TreeModel object instance based on the information provided by the fof.xml configuration file
*/
class ModelFactory extends BaseFactory
{
/**
* Create a new object instance
*
* @param string $name The name of the class we're making
* @param array $config The config parameters which override the fof.xml information
*
* @return TreeModel|DataModel A new TreeModel or DataModel object
*/
public function make(string $name = null, array $config = []): DataModel
{
if (empty($name))
{
throw new ModelNotFound($name);
}
$appConfig = $this->container->appConfig;
$name = ucfirst($name);
$defaultConfig = [
'name' => $name,
'use_populate' => $appConfig->get("models.$name.config.use_populate"),
'ignore_request' => $appConfig->get("models.$name.config.ignore_request"),
'tableName' => $appConfig->get("models.$name.config.tbl"),
'idFieldName' => $appConfig->get("models.$name.config.tbl_key"),
'knownFields' => $appConfig->get("models.$name.config.knownFields", null),
'autoChecks' => $appConfig->get("models.$name.config.autoChecks"),
'contentType' => $appConfig->get("models.$name.config.contentType"),
'fieldsSkipChecks' => $appConfig->get("models.$name.config.fieldsSkipChecks", []),
'aliasFields' => $appConfig->get("models.$name.field", []),
'behaviours' => $appConfig->get("models.$name.behaviors", []),
'fillable_fields' => $appConfig->get("models.$name.config.fillable_fields", []),
'guarded_fields' => $appConfig->get("models.$name.config.guarded_fields", []),
'relations' => $appConfig->get("models.$name.relations", []),
];
$config = array_merge($defaultConfig, $config);
// Get the default class names
$dataModelClassName = $this->container->getNamespacePrefix($this->getSection()) . 'Model\\DefaultDataModel';
if (!class_exists($dataModelClassName, true))
{
$dataModelClassName = '\\FOF40\\Model\\DataModel';
}
$treeModelClassName = $this->container->getNamespacePrefix($this->getSection()) . 'Model\\DefaultTreeModel';
if (!class_exists($treeModelClassName, true))
{
$treeModelClassName = '\\FOF40\\Model\\TreeModel';
}
try
{
// First try creating a TreeModel
$model = new $treeModelClassName($this->container, $config);
}
catch (DataModel\Exception\TreeIncompatibleTable $e)
{
// If the table isn't a nested set, create a regular DataModel
$model = new $dataModelClassName($this->container, $config);
}
return $model;
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Magic;
defined('_JEXEC') || die;
use FOF40\TransparentAuthentication\TransparentAuthentication;
/**
* Creates a TransparentAuthentication object instance based on the information provided by the fof.xml configuration
* file
*/
class TransparentAuthenticationFactory extends BaseFactory
{
/**
* Create a new object instance
*
* @param array $config The config parameters which override the fof.xml information
*
* @return TransparentAuthentication A new TransparentAuthentication object
*/
public function make(array $config = []): TransparentAuthentication
{
$appConfig = $this->container->appConfig;
$defaultConfig = $appConfig->get('authentication.*');
$config = array_merge($defaultConfig, $config);
$className = $this->container->getNamespacePrefix($this->getSection()) . 'TransparentAuthentication\\DefaultTransparentAuthentication';
if (!class_exists($className, true))
{
$className = '\\FOF40\\TransparentAuthentication\\TransparentAuthentication';
}
return new $className($this->container, $config);
}
}

View File

@ -0,0 +1,68 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory\Magic;
defined('_JEXEC') || die;
use FOF40\Factory\Exception\ViewNotFound;
use FOF40\View\View;
/**
* Creates a DataModel/TreeModel object instance based on the information provided by the fof.xml configuration file
*/
class ViewFactory extends BaseFactory
{
/**
* Create a new object instance
*
* @param string $name The name of the class we're making
* @param string $viewType The view type, default html, possible values html, form, raw, json, csv
* @param array $config The config parameters which override the fof.xml information
*
* @return View A DataViewInterface view
*/
public function make(string $name = null, string $viewType = 'html', array $config = []): View
{
if (empty($name))
{
throw new ViewNotFound("[name : type] = [$name : $viewType]");
}
$appConfig = $this->container->appConfig;
$name = ucfirst($name);
$defaultConfig = [
'name' => $name,
'template_path' => $appConfig->get("views.$name.config.template_path"),
'layout' => $appConfig->get("views.$name.config.layout"),
// You can pass something like .php => Class1, .foo.bar => Class 2
'viewEngineMap' => $appConfig->get("views.$name.config.viewEngineMap"),
];
$config = array_merge($defaultConfig, $config);
$className = $this->container->getNamespacePrefix($this->getSection()) . 'View\\DataView\\Default' . ucfirst($viewType);
if (!class_exists($className, true))
{
$className = '\\FOF40\\View\\DataView\\' . ucfirst($viewType);
}
if (!class_exists($className, true))
{
$className = $this->container->getNamespacePrefix($this->getSection()) . 'View\\DataView\\DefaultHtml';
}
if (!class_exists($className))
{
$className = '\\FOF40\\View\\DataView\\Html';
}
return new $className($this->container, $config);
}
}

View File

@ -0,0 +1,168 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory;
defined('_JEXEC') || die;
use FOF40\Controller\Controller;
use FOF40\Dispatcher\Dispatcher;
use FOF40\Factory\Exception\ControllerNotFound;
use FOF40\Factory\Exception\DispatcherNotFound;
use FOF40\Factory\Exception\ModelNotFound;
use FOF40\Factory\Exception\TransparentAuthenticationNotFound;
use FOF40\Factory\Exception\ViewNotFound;
use FOF40\Factory\Magic\DispatcherFactory;
use FOF40\Factory\Magic\TransparentAuthenticationFactory;
use FOF40\Model\Model;
use FOF40\Toolbar\Toolbar;
use FOF40\TransparentAuthentication\TransparentAuthentication;
use FOF40\View\View;
/**
* Magic MVC object factory. This factory will "magically" create MVC objects even if the respective classes do not
* exist, based on information in your fof.xml file.
*
* Note: This factory class will ONLY look for MVC objects in the same component section (front-end, back-end) you are
* currently running in. If they are not found a new one will be created magically.
*/
class MagicFactory extends BasicFactory implements FactoryInterface
{
/**
* Create a new Controller object
*
* @param string $viewName The name of the view we're getting a Controller for.
* @param array $config Optional MVC configuration values for the Controller object.
*
* @return Controller
*/
public function controller(string $viewName, array $config = []): Controller
{
try
{
return parent::controller($viewName, $config);
}
catch (ControllerNotFound $e)
{
$magic = new Magic\ControllerFactory($this->container);
return $magic->make($viewName, $config);
}
}
/**
* Create a new Model object
*
* @param string $viewName The name of the view we're getting a Model for.
* @param array $config Optional MVC configuration values for the Model object.
*
* @return Model
*/
public function model(string $viewName, array $config = []): Model
{
try
{
return parent::model($viewName, $config);
}
catch (ModelNotFound $e)
{
$magic = new Magic\ModelFactory($this->container);
return $magic->make($viewName, $config);
}
}
/**
* Create a new View object
*
* @param string $viewName The name of the view we're getting a View object for.
* @param string $viewType The type of the View object. By default it's "html".
* @param array $config Optional MVC configuration values for the View object.
*
* @return View
*/
public function view(string $viewName, $viewType = 'html', array $config = []): View
{
try
{
return parent::view($viewName, $viewType, $config);
}
catch (ViewNotFound $e)
{
$magic = new Magic\ViewFactory($this->container);
return $magic->make($viewName, $viewType, $config);
}
}
/**
* Creates a new Toolbar
*
* @param array $config The configuration values for the Toolbar object
*
* @return Toolbar
*/
public function toolbar(array $config = []): Toolbar
{
$appConfig = $this->container->appConfig;
$defaultConfig = [
'useConfigurationFile' => true,
'renderFrontendButtons' => in_array($appConfig->get("views.*.config.renderFrontendButtons"), [
true, 'true', 'yes', 'on', 1,
]),
'renderFrontendSubmenu' => in_array($appConfig->get("views.*.config.renderFrontendSubmenu"), [
true, 'true', 'yes', 'on', 1,
]),
];
$config = array_merge($defaultConfig, $config);
return parent::toolbar($config);
}
public function dispatcher(array $config = []): Dispatcher
{
$dispatcherClass = $this->container->getNamespacePrefix() . 'Dispatcher\\Dispatcher';
try
{
return $this->createDispatcher($dispatcherClass, $config);
}
catch (DispatcherNotFound $e)
{
// Not found. Return the magically created Dispatcher
$magic = new DispatcherFactory($this->container);
return $magic->make($config);
}
}
/**
* Creates a new TransparentAuthentication handler
*
* @param array $config The configuration values for the TransparentAuthentication object
*
* @return TransparentAuthentication
*/
public function transparentAuthentication(array $config = []): TransparentAuthentication
{
$authClass = $this->container->getNamespacePrefix() . 'TransparentAuthentication\\TransparentAuthentication';
try
{
return $this->createTransparentAuthentication($authClass, $config);
}
catch (TransparentAuthenticationNotFound $e)
{
// Not found. Return the magically created TA
$magic = new TransparentAuthenticationFactory($this->container);
return $magic->make($config);
}
}
}

View File

@ -0,0 +1,208 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory;
defined('_JEXEC') || die;
use FOF40\Controller\Controller;
use FOF40\Dispatcher\Dispatcher;
use FOF40\Factory\Exception\ControllerNotFound;
use FOF40\Factory\Exception\DispatcherNotFound;
use FOF40\Factory\Exception\ModelNotFound;
use FOF40\Factory\Exception\TransparentAuthenticationNotFound;
use FOF40\Factory\Exception\ViewNotFound;
use FOF40\Factory\Magic\DispatcherFactory;
use FOF40\Factory\Magic\TransparentAuthenticationFactory;
use FOF40\Model\Model;
use FOF40\Toolbar\Toolbar;
use FOF40\TransparentAuthentication\TransparentAuthentication;
use FOF40\View\View;
/**
* Magic MVC object factory. This factory will "magically" create MVC objects even if the respective classes do not
* exist, based on information in your fof.xml file.
*
* Note: This factory class will look for MVC objects in BOTH component sections (front-end, back-end), not just the one
* you are currently running in. If no class is found a new object will be created magically. This is the same behaviour
* as FOF 2.x.
*/
class MagicSwitchFactory extends SwitchFactory implements FactoryInterface
{
/**
* Create a new Controller object
*
* @param string $viewName The name of the view we're getting a Controller for.
* @param array $config Optional MVC configuration values for the Controller object.
*
* @return Controller
*/
public function controller(string $viewName, array $config = []): Controller
{
try
{
return parent::controller($viewName, $config);
}
catch (ControllerNotFound $e)
{
$magic = new Magic\ControllerFactory($this->container);
// Let's pass the section override (if any)
$magic->setSection($this->getSection());
return $magic->make($viewName, $config);
}
}
/**
* Create a new Model object
*
* @param string $viewName The name of the view we're getting a Model for.
* @param array $config Optional MVC configuration values for the Model object.
*
* @return Model
*/
public function model(string $viewName, array $config = []): Model
{
try
{
return parent::model($viewName, $config);
}
catch (ModelNotFound $e)
{
$magic = new Magic\ModelFactory($this->container);
// Let's pass the section override (if any)
$magic->setSection($this->getSection());
return $magic->make($viewName, $config);
}
}
/**
* Create a new View object
*
* @param string $viewName The name of the view we're getting a View object for.
* @param string $viewType The type of the View object. By default it's "html".
* @param array $config Optional MVC configuration values for the View object.
*
* @return View
*/
public function view(string $viewName, $viewType = 'html', array $config = []): View
{
try
{
return parent::view($viewName, $viewType, $config);
}
catch (ViewNotFound $e)
{
$magic = new Magic\ViewFactory($this->container);
// Let's pass the section override (if any)
$magic->setSection($this->getSection());
return $magic->make($viewName, $viewType, $config);
}
}
/**
* Creates a new Toolbar
*
* @param array $config The configuration values for the Toolbar object
*
* @return Toolbar
*/
public function toolbar(array $config = []): Toolbar
{
$appConfig = $this->container->appConfig;
$defaultConfig = [
'useConfigurationFile' => true,
'renderFrontendButtons' => in_array($appConfig->get("views.*.config.renderFrontendButtons"), [
true, 'true', 'yes', 'on', 1,
]),
'renderFrontendSubmenu' => in_array($appConfig->get("views.*.config.renderFrontendSubmenu"), [
true, 'true', 'yes', 'on', 1,
]),
];
$config = array_merge($defaultConfig, $config);
return parent::toolbar($config);
}
/**
* Creates a new Dispatcher
*
* @param array $config The configuration values for the Dispatcher object
*
* @return Dispatcher
*/
public function dispatcher(array $config = []): Dispatcher
{
$dispatcherClass = $this->container->getNamespacePrefix($this->getSection()) . 'Dispatcher\\Dispatcher';
try
{
return $this->createDispatcher($dispatcherClass, $config);
}
catch (DispatcherNotFound $e)
{
// Not found. Let's go on.
}
$dispatcherClass = $this->container->getNamespacePrefix('inverse') . 'Dispatcher\\Dispatcher';
try
{
return $this->createDispatcher($dispatcherClass, $config);
}
catch (DispatcherNotFound $e)
{
// Not found. Return the magically created Dispatcher
$magic = new DispatcherFactory($this->container);
// Let's pass the section override (if any)
$magic->setSection($this->getSection());
return $magic->make($config);
}
}
/**
* Creates a new TransparentAuthentication
*
* @param array $config The configuration values for the TransparentAuthentication object
*
* @return TransparentAuthentication
*/
public function transparentAuthentication(array $config = []): TransparentAuthentication
{
$toolbarClass = $this->container->getNamespacePrefix($this->getSection()) . 'TransparentAuthentication\\TransparentAuthentication';
try
{
return $this->createTransparentAuthentication($toolbarClass, $config);
}
catch (TransparentAuthenticationNotFound $e)
{
// Not found. Let's go on.
}
$toolbarClass = $this->container->getNamespacePrefix('inverse') . 'TransparentAuthentication\\TransparentAuthentication';
try
{
return $this->createTransparentAuthentication($toolbarClass, $config);
}
catch (TransparentAuthenticationNotFound $e)
{
// Not found. Return the magically created TransparentAuthentication
$magic = new TransparentAuthenticationFactory($this->container);
// Let's pass the section override (if any)
$magic->setSection($this->getSection());
return $magic->make($config);
}
}
}

View File

@ -0,0 +1,266 @@
<?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Factory;
defined('_JEXEC') || die;
use Exception;
use FOF40\Controller\Controller;
use FOF40\Dispatcher\Dispatcher;
use FOF40\Factory\Exception\ControllerNotFound;
use FOF40\Factory\Exception\DispatcherNotFound;
use FOF40\Factory\Exception\ModelNotFound;
use FOF40\Factory\Exception\ToolbarNotFound;
use FOF40\Factory\Exception\TransparentAuthenticationNotFound;
use FOF40\Factory\Exception\ViewNotFound;
use FOF40\Model\Model;
use FOF40\Toolbar\Toolbar;
use FOF40\TransparentAuthentication\TransparentAuthentication;
use FOF40\View\View;
use FOF40\View\ViewTemplateFinder;
/**
* MVC object factory. This implements the advanced functionality, i.e. creating MVC objects only if the classes exist
* in any component section (front-end, back-end). For example, if you're in the front-end and a Model class doesn't
* exist there but does exist in the back-end then the back-end class will be returned.
*
* The Dispatcher and Toolbar will be created from default objects if specialised classes are not found in your application.
*/
class SwitchFactory extends BasicFactory implements FactoryInterface
{
/**
* Create a new Controller object
*
* @param string $viewName The name of the view we're getting a Controller for.
* @param array $config Optional MVC configuration values for the Controller object.
*
* @return Controller
*/
public function controller(string $viewName, array $config = []): Controller
{
try
{
return parent::controller($viewName, $config);
}
catch (ControllerNotFound $e)
{
}
$controllerClass = $this->container->getNamespacePrefix('inverse') . 'Controller\\' . ucfirst($viewName);
try
{
return $this->createController($controllerClass, $config);
}
catch (ControllerNotFound $e)
{
}
$controllerClass = $this->container->getNamespacePrefix('inverse') . 'Controller\\' . ucfirst($this->container->inflector->singularize($viewName));
return $this->createController($controllerClass, $config);
}
/**
* Create a new Model object
*
* @param string $viewName The name of the view we're getting a Model for.
* @param array $config Optional MVC configuration values for the Model object.
*
* @return Model
*/
public function model(string $viewName, array $config = []): Model
{
try
{
return parent::model($viewName, $config);
}
catch (ModelNotFound $e)
{
}
$modelClass = $this->container->getNamespacePrefix('inverse') . 'Model\\' . ucfirst($viewName);
try
{
return $this->createModel($modelClass, $config);
}
catch (ModelNotFound $e)
{
$modelClass = $this->container->getNamespacePrefix('inverse') . 'Model\\' . ucfirst($this->container->inflector->singularize($viewName));
return $this->createModel($modelClass, $config);
}
}
/**
* Create a new View object
*
* @param string $viewName The name of the view we're getting a View object for.
* @param string $viewType The type of the View object. By default it's "html".
* @param array $config Optional MVC configuration values for the View object.
*
* @return View
*/
public function view(string $viewName, $viewType = 'html', array $config = []): View
{
try
{
return parent::view($viewName, $viewType, $config);
}
catch (ViewNotFound $e)
{
}
$viewClass = $this->container->getNamespacePrefix('inverse') . 'View\\' . ucfirst($viewName) . '\\' . ucfirst($viewType);
try
{
return $this->createView($viewClass, $config);
}
catch (ViewNotFound $e)
{
$viewClass = $this->container->getNamespacePrefix('inverse') . 'View\\' . ucfirst($this->container->inflector->singularize($viewName)) . '\\' . ucfirst($viewType);
return $this->createView($viewClass, $config);
}
}
/**
* Creates a new Dispatcher
*
* @param array $config The configuration values for the Dispatcher object
*
* @return Dispatcher
*/
public function dispatcher(array $config = []): Dispatcher
{
$dispatcherClass = $this->container->getNamespacePrefix($this->getSection()) . 'Dispatcher\\Dispatcher';
try
{
return $this->createDispatcher($dispatcherClass, $config);
}
catch (DispatcherNotFound $e)
{
// Not found. Let's go on.
}
$dispatcherClass = $this->container->getNamespacePrefix('inverse') . 'Dispatcher\\Dispatcher';
try
{
return $this->createDispatcher($dispatcherClass, $config);
}
catch (DispatcherNotFound $e)
{
// Not found. Return the default Dispatcher
return new Dispatcher($this->container, $config);
}
}
/**
* Creates a new Toolbar
*
* @param array $config The configuration values for the Toolbar object
*
* @return Toolbar
*/
public function toolbar(array $config = []): Toolbar
{
$toolbarClass = $this->container->getNamespacePrefix($this->getSection()) . 'Toolbar\\Toolbar';
try
{
return $this->createToolbar($toolbarClass, $config);
}
catch (ToolbarNotFound $e)
{
// Not found. Let's go on.
}
$toolbarClass = $this->container->getNamespacePrefix('inverse') . 'Toolbar\\Toolbar';
try
{
return $this->createToolbar($toolbarClass, $config);
}
catch (ToolbarNotFound $e)
{
// Not found. Return the default Toolbar
return new Toolbar($this->container, $config);
}
}
/**
* Creates a new TransparentAuthentication
*
* @param array $config The configuration values for the TransparentAuthentication object
*
* @return TransparentAuthentication
*/
public function transparentAuthentication(array $config = []): TransparentAuthentication
{
$toolbarClass = $this->container->getNamespacePrefix($this->getSection()) . 'TransparentAuthentication\\TransparentAuthentication';
try
{
return $this->createTransparentAuthentication($toolbarClass, $config);
}
catch (TransparentAuthenticationNotFound $e)
{
// Not found. Let's go on.
}
$toolbarClass = $this->container->getNamespacePrefix('inverse') . 'TransparentAuthentication\\TransparentAuthentication';
try
{
return $this->createTransparentAuthentication($toolbarClass, $config);
}
catch (TransparentAuthenticationNotFound $e)
{
// Not found. Return the default TransparentAuthentication
return new TransparentAuthentication($this->container, $config);
}
}
/**
* Creates a view template finder object for a specific View.
*
* The default configuration is:
* Look for .php, .blade.php files; default layout "default"; no default sub-template;
* look for both pluralised and singular views; fall back to the default layout without sub-template;
* look for templates in both site and admin
*
* @param View $view The view this view template finder will be attached to
* @param array $config Configuration variables for the object
*
* @return mixed
*
* @throws Exception
*/
public function viewFinder(View $view, array $config = []): ViewTemplateFinder
{
// Initialise the configuration with the default values
$defaultConfig = [
'extensions' => ['.php', '.blade.php'],
'defaultLayout' => 'default',
'defaultTpl' => '',
'strictView' => false,
'strictTpl' => false,
'strictLayout' => false,
'sidePrefix' => 'any',
];
$config = array_merge($defaultConfig, $config);
return parent::viewFinder($view, $config);
}
}