%PDF- %PDF-
Direktori : /home/lightco1/upgrade.lightco.com.au/libraries/fof30/Factory/ |
Current File : /home/lightco1/upgrade.lightco.com.au/libraries/fof30/Factory/BasicFactory.php |
<?php /** * @package FOF * @copyright 2010-2017 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU GPL version 2 or later */ namespace FOF30\Factory; use FOF30\Container\Container; use FOF30\Controller\Controller; use FOF30\Dispatcher\Dispatcher; use FOF30\Factory\Exception\ControllerNotFound; use FOF30\Factory\Exception\DispatcherNotFound; use FOF30\Factory\Exception\FormLoadData; use FOF30\Factory\Exception\FormLoadFile; use FOF30\Factory\Exception\ModelNotFound; use FOF30\Factory\Exception\ToolbarNotFound; use FOF30\Factory\Exception\FormNotFound; use FOF30\Factory\Exception\TransparentAuthenticationNotFound; use FOF30\Factory\Exception\ViewNotFound; use FOF30\Factory\Scaffolding\Layout\Builder as LayoutBuilder; use FOF30\Factory\Scaffolding\Controller\Builder as ControllerBuilder; use FOF30\Factory\Scaffolding\Model\Builder as ModelBuilder; use FOF30\Factory\Scaffolding\View\Builder as ViewBuilder; use FOF30\Form\Form; use FOF30\Model\Model; use FOF30\Toolbar\Toolbar; use FOF30\TransparentAuthentication\TransparentAuthentication; use FOF30\View\View; use FOF30\View\ViewTemplateFinder; defined('_JEXEC') or die; /** * 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 = null; /** @var bool Should I look for form files on the other side of the component? */ protected $formLookupInOtherSide = false; /** @var bool Should I enable view scaffolding, i.e. automatic browse, read and add/edit XML form generation when there's no other view template? */ protected $scaffolding = false; /** @var bool When enabled, FOF will commit the scaffolding results to disk. */ protected $saveScaffolding = false; /** @var bool When enabled, FOF will commit controller scaffolding results to disk. */ protected $saveControllerScaffolding = false; /** @var bool When enabled, FOF will commit model scaffolding results to disk. */ protected $saveModelScaffolding = false; /** @var bool When enabled, FOF will commit view scaffolding results to disk. */ protected $saveViewScaffolding = false; /** * Section used to build the namespace prefix. We have to pass it since in CLI scaffolding we need * to force the section we're in (ie Site or Admin). {@see \FOF30\Container\Container::getNamespacePrefix() } for valid values * * @var string */ protected $section = 'auto'; /** * Public constructor for the factory object * * @param \FOF30\Container\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($viewName, array $config = array()) { $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)); try { $controller = $this->createController($controllerClass, $config); } catch(ControllerNotFound $e) { // Do I have to create and save the class file? If not, let's rethrow the exception if(!$this->saveControllerScaffolding) { throw $e; } $scaffolding = new ControllerBuilder($this->container); // Was the scaffolding successful? If so let's call ourself again, otherwise throw a not found exception if($scaffolding->make($controllerClass, $viewName)) { $controller = $this->controller($viewName, $config); } else { throw $e; } } return $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($viewName, array $config = array()) { $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)); try { $model = $this->createModel($modelClass, $config); } catch(ModelNotFound $e) { // Do I have to create and save the class file? If not, let's rethrow the exception if(!$this->saveModelScaffolding) { throw $e; } // By default model classes are plural $modelClass = $this->container->getNamespacePrefix($this->getSection()) . 'Model\\' . ucfirst($viewName); $scaffolding = new ModelBuilder($this->container); // Was the scaffolding successful? If so let's call ourself again, otherwise throw a not found exception if($scaffolding->make($modelClass, $viewName)) { $model = $this->model($viewName, $config); } else { throw $e; } } return $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($viewName, $viewType = 'html', array $config = array()) { $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); try { $view = $this->createView($viewClass, $config); } catch(ViewNotFound $e) { // Do I have to create and save the class file? If not, let's rethrow the exception. Note: I can only create HTML views if(!$this->saveViewScaffolding) { throw $e; } // By default view classes are plural $viewClass = $prefix . 'View\\' . ucfirst($container->inflector->pluralize($viewName)) . '\\' . ucfirst($viewType); $scaffolding = new ViewBuilder($this->container); // Was the scaffolding successful? If so let's call ourself again, otherwise throw a not found exception if($scaffolding->make($viewClass, $viewName, $viewType)) { $view = $this->view($viewName, $viewType, $config); } else { throw $e; } } return $view; } /** * Creates a new Dispatcher * * @param array $config The configuration values for the Dispatcher object * * @return Dispatcher */ public function dispatcher(array $config = array()) { $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 = array()) { $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 = array()) { $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 new Form object * * @param string $name The name of the form. * @param string $source The form source filename without path and .xml extension e.g. "form.default" OR raw XML data * @param string $viewName The name of the view you're getting the form for. * @param array $options Options to the Form object * @param bool $replace Should form fields be replaced if a field already exists with the same group/name? * @param bool $xpath An optional xpath to search for the fields. * * @return Form|null The loaded form or null if the form filename doesn't exist * * @throws \RuntimeException If the form exists but cannot be loaded * * @deprecated 3.1 Support for XML forms will be removed in FOF 4 */ public function form($name, $source, $viewName, array $options = array(), $replace = true, $xpath = false) { $formClass = $this->container->getNamespacePrefix($this->getSection()) . 'Form\\Form'; try { $form = $this->createForm($formClass, $name, $options); } catch (FormNotFound $e) { // Not found. Return the default Toolbar $form = new Form($this->container, $name, $options); } // If $source looks like raw XML data, parse it directly if (strpos($source, '<form') !== false) { if ($form->load($source, $replace, $xpath) === false) { throw new FormLoadData; } return $form; } $formFileName = $this->getFormFilename($source, $viewName); if (empty($formFileName)) { if ($this->scaffolding) { $scaffolding = new LayoutBuilder($this->container); $xml = $scaffolding->make($source, $viewName); if (!is_null($xml)) { return $this->form($name, $xml, $viewName, $options, $replace, $xpath); } } return null; } if ($form->loadFile($formFileName, $replace, $xpath) === false) { throw new FormLoadFile($source); } return $form; } /** * 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 subtemplate; * look only for the specified view; do NOT fall back to the default layout or subtemplate; * 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 = array()) { // Initialise the configuration with the default values $defaultConfig = array( 'extensions' => array('.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 = array( '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); } /** * Is scaffolding enabled? * * @return boolean */ public function isScaffolding() { return $this->scaffolding; } /** * Set the scaffolding status * * @param boolean $scaffolding */ public function setScaffolding($scaffolding) { $this->scaffolding = (bool) $scaffolding; } /** * Is saving the scaffolding result to disk enabled? * * @return boolean */ public function isSaveScaffolding() { return $this->saveScaffolding; } /** * Set the status of saving the scaffolding result to disk. * * @param boolean $saveScaffolding */ public function setSaveScaffolding($saveScaffolding) { $this->saveScaffolding = (bool) $saveScaffolding; } /** * Should we save controller to disk? * * @param boolean $state */ public function setSaveControllerScaffolding($state) { $this->saveControllerScaffolding = (bool) $state; } /** * Should we save controller scaffolding to disk? * * @return boolean $state */ public function isSaveControllerScaffolding() { return $this->saveControllerScaffolding; } /** * Should we save model to disk? * * @param boolean $state */ public function setSaveModelScaffolding($state) { $this->saveModelScaffolding = (bool) $state; } /** * Should we save model scaffolding to disk? * * @return boolean $state */ public function isSaveModelScaffolding() { return $this->saveModelScaffolding; } /** * Should we save view to disk? * * @param boolean $state */ public function setSaveViewScaffolding($state) { $this->saveViewScaffolding = (bool) $state; } /** * Should we save view scaffolding to disk? * * @return boolean $state */ public function isSaveViewScaffolding() { return $this->saveViewScaffolding; } /** * 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($controllerClass, array $config = array()) { 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($modelClass, array $config = array()) { 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($viewClass, array $config = array()) { 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($toolbarClass, array $config = array()) { if (!class_exists($toolbarClass)) { throw new ToolbarNotFound($toolbarClass); } return new $toolbarClass($this->container, $config); } /** * Creates a Form object * * @param string $formClass The fully qualified class name for the Form * @param string $name The name of the form * @param array $options The options values for the Form object * * @return Toolbar * * @throws FormNotFound If the $formClass does not exist */ protected function createForm($formClass, $name, array $options = array()) { if (!class_exists($formClass)) { throw new FormNotFound($formClass); } return new $formClass($this->container, $name, $options); } /** * 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($dispatcherClass, array $config = array()) { 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($authClass, $config) { if (!class_exists($authClass)) { throw new TransparentAuthenticationNotFound($authClass); } return new $authClass($this->container, $config); } /** * Tries to find the absolute file path for an abstract form filename. For example, it may convert form.default to * /home/myuser/mysite/components/com_foobar/View/tmpl/form.default.xml. * * @param string $source The abstract form filename * @param string $viewName The name of the view we're getting the path for * * @return string|bool The fill path to the form XML file or boolean false if it's not found */ protected function getFormFilename($source, $viewName = null) { if (empty($source)) { return false; } $componentName = $this->container->componentName; if (empty($viewName)) { $viewName = $this->container->dispatcher->getController()->getView()->getName(); } $viewNameAlt = $this->container->inflector->singularize($viewName); if ($viewNameAlt == $viewName) { $viewNameAlt = $this->container->inflector->pluralize($viewName); } $componentPaths = $this->container->platform->getComponentBaseDirs($componentName); $file_root = $componentPaths['main']; $alt_file_root = $componentPaths['alt']; $template_root = $this->container->platform->getTemplateOverridePath($componentName); // Basic paths we need to always search $paths = array( // Template override $template_root . '/' . $viewName, $template_root . '/' . $viewNameAlt, // Forms inside the specialized folder for easier template overrides $file_root . '/ViewTemplates/' . $viewName, $file_root . '/ViewTemplates/' . $viewNameAlt, // This side of the component $file_root . '/View/' . $viewName . '/tmpl', $file_root . '/View/' . $viewNameAlt . '/tmpl', ); // The other side of the component if ($this->formLookupInOtherSide) { // Forms inside the specialized folder for easier template overrides $paths[] = $alt_file_root . '/ViewTemplates/' . $viewName; $paths[] = $alt_file_root . '/ViewTemplates/' . $viewNameAlt; $paths[] = $alt_file_root . '/View/' . $viewName . '/tmpl'; $paths[] = $alt_file_root . '/View/' . $viewNameAlt . '/tmpl'; } // Legacy paths, this side of the component $paths[] = $file_root . '/views/' . $viewName . '/tmpl'; $paths[] = $file_root . '/views/' . $viewNameAlt . '/tmpl'; $paths[] = $file_root . '/Model/forms'; $paths[] = $file_root . '/models/forms'; // Legacy paths, the other side of the component if ($this->formLookupInOtherSide) { $paths[] = $file_root . '/views/' . $viewName . '/tmpl'; $paths[] = $file_root . '/views/' . $viewNameAlt . '/tmpl'; $paths[] = $file_root . '/Model/forms'; $paths[] = $file_root . '/models/forms'; } $paths = array_unique($paths); // Set up the suffixes to look into $suffixes = array(); $temp_suffixes = $this->container->platform->getTemplateSuffixes(); if (!empty($temp_suffixes)) { foreach ($temp_suffixes as $suffix) { $suffixes[] = $suffix . '.xml'; } } $suffixes[] = '.xml'; // Look for all suffixes in all paths $result = false; $filesystem = $this->container->filesystem; foreach ($paths as $path) { foreach ($suffixes as $suffix) { $filename = $path . '/' . $source . $suffix; if ($filesystem->fileExists($filename)) { $result = $filename; break; } } if ($result) { break; } } return $result; } /** * @return string */ public function getSection() { return $this->section; } /** * @param string $section */ public function setSection($section) { $this->section = $section; } }