<?php
namespace Jaxon\Utils\View;
use Jaxon\Utils\Config\Config;
use stdClass;
use Exception;
use Closure;
class Manager
{
/**
* The default namespace
*
* @var string
*/
protected $sDefaultNamespace = '';
/**
* The view namespaces
*
* @var array
*/
protected $aNamespaces = [];
/**
* Get the default namespace
*
* @return string
*/
public function getDefaultNamespace()
{
return $this->sDefaultNamespace;
}
/**
* Get the view namespaces
*
* @return array
*/
public function getNamespaces()
{
return $this->aNamespaces;
}
/**
* Find a view namespace by its name.
*
* @param string $sNamespace The namespace name
*
* @return array|null
*/
public function getNamespace($sNamespace)
{
return \array_key_exists($sNamespace, $this->aNamespaces) ?
$this->aNamespaces[$sNamespace] : null;
}
/**
* Add a view namespace, and set the corresponding renderer.
*
* @param string $sNamespace The corresponding renderer name
* @param array $aNamespace The namespace options
*
* @return void
*/
private function _addNamespace($sNamespace, array $aNamespace)
{
$this->aNamespaces[$sNamespace] = $aNamespace;
}
/**
* Add a view namespace, and set the corresponding renderer.
*
* @param string $sNamespace The namespace name
* @param string $sDirectory The namespace directory
* @param string $sExtension The extension to append to template names
* @param string $sRenderer The corresponding renderer name
*
* @return void
*/
public function addNamespace($sNamespace, $sDirectory, $sExtension, $sRenderer)
{
$aNamespace = [
'directory' => $sDirectory,
'extension' => $sExtension,
'renderer' => $sRenderer,
];
$this->_addNamespace($sNamespace, $aNamespace);
}
/**
* Set the view namespaces.
*
* @param Config $xLibConfig The config options provided in the library
* @param Config $xAppConfig The config options provided in the app section of the global config file.
*
* @return void
*/
public function addNamespaces($xLibConfig, $xAppConfig = null)
{
$this->sDefaultNamespace = $xLibConfig->getOption('options.views.default', '');
$sPackage = $xLibConfig->getOption('package', '');
if(\is_array($aNamespaces = $xLibConfig->getOptionNames('views')))
{
foreach($aNamespaces as $sNamespace => $sOption)
{
// If no default namespace is defined, use the first one as default.
if($this->sDefaultNamespace == '')
{
$this->sDefaultNamespace = (string)$sNamespace;
}
// Save the namespace
$aNamespace = $xLibConfig->getOption($sOption);
$aNamespace['package'] = $sPackage;
if(!\array_key_exists('renderer', $aNamespace))
{
$aNamespace['renderer'] = 'jaxon'; // 'jaxon' is the default renderer.
}
// If the lib config has defined a template option, then its value must be
// read from the app config.
if($xAppConfig !== null && \array_key_exists('template', $aNamespace))
{
$sTemplateOption = $xLibConfig->getOption($sOption . '.template.option');
$sTemplateDefault = $xLibConfig->getOption($sOption . '.template.default');
$sTemplate = $xAppConfig->getOption($sTemplateOption, $sTemplateDefault);
$aNamespace['directory'] = \rtrim($aNamespace['directory'], '/') . '/' . $sTemplate;
}
$this->_addNamespace($sNamespace, $aNamespace);
}
}
}
/**
* Get the view renderer
*
* @param string $sId The unique identifier of the view renderer
*
* @return \Jaxon\Contracts\View
*/
public function getRenderer($sId)
{
// Return the view renderer with the given id
return jaxon()->di()->get('jaxon.app.view.' . $sId);
}
/**
* Add a view renderer with an id
*
* @param string $sId The unique identifier of the view renderer
* @param Closure $xClosure A closure to create the view instance
*
* @return void
*/
public function addRenderer($sId, Closure $xClosure)
{
// Return the initialized view renderer
jaxon()->di()->set('jaxon.app.view.' . $sId, function($di) use ($sId, $xClosure) {
// Get the defined renderer
$xRenderer = call_user_func($xClosure, $di);
// Init the renderer with the template namespaces
$aNamespaces = \array_filter($this->aNamespaces, function($aNamespace) use($sId) {
return $aNamespace['renderer'] === $sId;
});
foreach($aNamespaces as $sNamespace => $aNamespace)
{
$xRenderer->addNamespace($sNamespace, $aNamespace['directory'], $aNamespace['extension']);
}
return $xRenderer;
});
}
/**
* Get the view renderer for a given namespace
*
* @param string $sNamespace The namespace name
*
* @return \Jaxon\Contracts\View|null
*/
public function getNamespaceRenderer($sNamespace)
{
$aNamespace = $this->getNamespace($sNamespace);
if(!$aNamespace)
{
return null;
}
// Return the view renderer with the configured id
return $this->getRenderer($aNamespace['renderer']);
}
}
|