// Load and extend blueprints.
$data = $this->doLoad($files, $extends);
$this->items = (array)array_shift($data);
foreach ($data as $content) {
$this->extend($content, true);
}
}
}
// Import blueprints.
$this->deepInit($this->items);
} catch (Exception $e) {
$filename = $this->filename;
if (is_array($filename)) {
$filename = implode(' | ', $filename);
}
throw new RuntimeException(sprintf('Cannot load blueprint %s: %s', $filename, $e->getMessage()), 500, $e);
}
return $this;
}
/**
* Initialize blueprints with its dynamic fields.
*
* @return $this
*/
public function init()
{
foreach ($this->dynamic as $key => $data) {
// Locate field.
$path = explode('/', $key);
$current = &$this->items;
foreach ($path as $field) {
if (\is_object($current)) {
// Handle objects.
// If compiled file wasn't already locked by another process, save it.
if ($file->locked() !== false) {
$file->save($cache);
$file->unlock();
// Compile cached file into bytecode cache
if (function_exists('opcache_invalidate')) {
// Silence error in case if `opcache.restrict_api` directive is set.
@opcache_invalidate($file->filename(), true);
}
}
}
$file->free();
$this->content = $cache['data'];
}
} catch (\Exception $e) {
throw new \RuntimeException(sprintf('Failed to read %s: %s', Gantry::basename($this->filename), $e->getMessage()), 500, $e);
}
return parent::content($var);
}
}
/**
* Converts a YAML string to a PHP value.
*
* @param string $value A YAML string
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
* @param bool $objectForMap True if maps should return a stdClass instead of array()
* @param array $references Mapping of variable names to values
*
* @return mixed A PHP value
*
* @throws ParseException
*/
public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
{
self::$exceptionOnInvalidType = $exceptionOnInvalidType;
self::$objectSupport = $objectSupport;
self::$objectForMap = $objectForMap;
$value = trim($value);
if ('' === $value) {
return '';
}
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}
$i = 0;
switch ($value[0]) {
case '[':
$result = self::parseSequence($value, $i, $references);
++$i;
break;
case '{':
$result = self::parseMapping($value, $i, $references);
++$i;
break;
/**
* Converts a YAML string to a PHP value.
*
* @param string $value A YAML string
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
* @param bool $objectSupport True if object support is enabled, false otherwise
* @param bool $objectForMap True if maps should return a stdClass instead of array()
* @param array $references Mapping of variable names to values
*
* @return mixed A PHP value
*
* @throws ParseException
*/
public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
{
self::$exceptionOnInvalidType = $exceptionOnInvalidType;
self::$objectSupport = $objectSupport;
self::$objectForMap = $objectForMap;
$value = trim($value);
if ('' === $value) {
return '';
}
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}
$i = 0;
switch ($value[0]) {
case '[':
$result = self::parseSequence($value, $i, $references);
++$i;
break;
case '{':
$result = self::parseMapping($value, $i, $references);
++$i;
break;
$data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} else {
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
}
}
if ($isRef) {
$this->refs[$isRef] = end($data);
}
} elseif (
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
&& (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))
) {
if ($context && 'sequence' == $context) {
throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine);
}
$context = 'mapping';
// force correct settings
Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
try {
$key = Inline::parseScalar($values['key']);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);
throw $e;
}
// Convert float keys to strings, to avoid being converted to integers by PHP
if (is_float($key)) {
$key = (string) $key;
}
if ('<<' === $key && (!isset($values['value']) || !self::preg_match('#^&(?P<ref>[^ ]+)#u', $values['value'], $refMatches))) {
$mergeNode = true;
$allowOverwrite = true;
if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
$refName = substr($values['value'], 1);
if (!array_key_exists($refName, $this->refs)) {
*/
public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
{
if (false === preg_match('//u', $value)) {
throw new ParseException('The YAML value does not appear to be valid UTF-8.');
}
$this->refs = array();
$mbEncoding = null;
$e = null;
$data = null;
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
}
try {
$data = $this->doParse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} catch (\Exception $e) {
} catch (\Throwable $e) {
}
if (null !== $mbEncoding) {
mb_internal_encoding($mbEncoding);
}
$this->lines = array();
$this->currentLine = '';
$this->refs = array();
$this->skippedLineNumbers = array();
$this->locallySkippedLineNumbers = array();
if (null !== $e) {
throw $e;
}
return $data;
}
*/
public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
{
// if input is a file, process it
$file = '';
if (false === strpos($input, "\n") && is_file($input)) {
@trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED);
if (false === is_readable($input)) {
throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
}
$file = $input;
$input = file_get_contents($file);
}
$yaml = new Parser();
try {
return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} catch (ParseException $e) {
if ($file) {
$e->setParsedFile($file);
}
throw $e;
}
}
}
// Try native PECL YAML PHP extension first if available.
if (function_exists('yaml_parse') && $this->setting('native', true)) {
// Safely decode YAML.
$saved = @ini_get('yaml.decode_php');
@ini_set('yaml.decode_php', '0');
$data = @yaml_parse($var);
if ($saved !== false) {
@ini_set('yaml.decode_php', $saved);
}
if ($data !== false) {
return (array)$data;
}
}
try {
return (array)YamlParser::parse($var);
} catch (ParseException $e) {
if ($this->setting('compat', true)) {
return (array)FallbackYamlParser::parse($var);
}
throw $e;
}
}
}
$class = get_class($this);
$cache = $file->exists() ? $file->content() : null;
// Load real file if cache isn't up to date (or is invalid).
if (!isset($cache['@class'])
|| $cache['@class'] !== $class
|| $cache['modified'] !== $modified
|| $cache['filename'] !== $this->filename
) {
// Attempt to lock the file for writing.
try {
$file->lock(false);
} catch (\Exception $e) {
// Another process has locked the file; we will check this in a bit.
}
// Decode RAW file into compiled array.
$data = $this->decode($this->raw());
$cache = [
'@class' => $class,
'filename' => $this->filename,
'modified' => $modified,
'data' => $data
];
// If compiled file wasn't already locked by another process, save it.
if ($file->locked() !== false) {
$file->save($cache);
$file->unlock();
// Compile cached file into bytecode cache
if (function_exists('opcache_invalidate')) {
// Silence error in case if `opcache.restrict_api` directive is set.
@opcache_invalidate($file->filename(), true);
}
}
}
$file->free();
*/
public function schema()
{
if (!isset($this->schema)) {
$this->schema = new BlueprintSchema;
$this->schema->embed('', $this->items);
$this->schema->init();
}
return $this->schema;
}
/**
* @param string $filename
* @return array
*/
protected function loadFile($filename)
{
$file = CompiledYamlFile::instance($filename);
$content = (array)$file->content();
$file->free();
return $content;
}
/**
* @param string|array $path
* @param string $context
* @return array
*/
protected function getFiles($path, $context = null)
{
if (is_string($path) && !strpos($path, '://')) {
// Resolve filename.
if (isset($this->overrides[$path])) {
$path = $this->overrides[$path];
} else {
if ($context === null) {
$context = $this->context;
}
$this->deepInit($imported, $path);
$name = implode('/', $path);
$this->embed($name, $imported, '/', false);
}
}
/**
* Internal function that handles loading extended blueprints.
*
* @param string[] $files
* @param string|array|null $extends
* @return array
*/
protected function doLoad(array $files, $extends = null)
{
$filename = array_shift($files);
if (!is_string($filename)) {
throw new InvalidArgumentException(__METHOD__ . '(): Parameter #1 does not contain array of filenames');
}
$content = $this->loadFile($filename);
$key = '';
if (isset($content['extends@'])) {
$key = 'extends@';
} elseif (isset($content['@extends'])) {
$key = '@extends';
} elseif (isset($content['@extends@'])) {
$key = '@extends@';
}
$override = (bool)$extends;
$extends = (array)($key && !$extends ? $content[$key] : $extends);
unset($content['extends@'], $content['@extends'], $content['@extends@']);
$data = $extends ? $this->doExtend($filename, $files, $extends, $override) : [];
$data[] = $content;
return $data;
}
return $this;
}
/**
* Load blueprint.
*
* @param string|array|null $extends
* @return $this
*/
public function load($extends = null)
{
try {
// Only load and extend blueprint if it has not yet been loaded.
if (!$this->items) {
// Get list of files.
$files = $this->filename ? $this->getFiles($this->filename) : [];
if ($files) {
// Load and extend blueprints.
$data = $this->doLoad($files, $extends);
$this->items = (array)array_shift($data);
foreach ($data as $content) {
$this->extend($content, true);
}
}
}
// Import blueprints.
$this->deepInit($this->items);
} catch (Exception $e) {
$filename = $this->filename;
if (is_array($filename)) {
$filename = implode(' | ', $filename);
}
throw new RuntimeException(sprintf('Cannot load blueprint %s: %s', $filename, $e->getMessage()), 500, $e);
}
/**
* Finalize configuration object.
*/
protected function finalizeObject()
{
}
/**
* Load single configuration file and append it to the correct position.
*
* @param string $name Name of the position.
* @param string|array $filename File to be loaded.
*/
protected function loadFile($name, $filename)
{
// Load blueprint file.
$blueprint = new BlueprintForm($filename);
$this->object->embed($name, $blueprint->load()->toArray(), '/', true);
}
/**
* Load and join all configuration files.
*
* @return bool
* @internal
*/
protected function loadFiles()
{
$this->createObject();
// Convert file list into parent list.
$list = [];
foreach ($this->files as $files) {
foreach ($files as $name => $item) {
$list[$name][] = $this->path . $item['file'];
}
}
* Load and join all configuration files.
*
* @return bool
* @internal
*/
protected function loadFiles()
{
$this->createObject();
// Convert file list into parent list.
$list = [];
foreach ($this->files as $files) {
foreach ($files as $name => $item) {
$list[$name][] = $this->path . $item['file'];
}
}
// Load files.
foreach ($list as $name => $files) {
$this->loadFile($name, $files);
}
$this->finalizeObject();
return true;
}
/**
* @return array
*/
protected function getState()
{
return $this->object->getState();
}
}
/**
* Function gets called when cached configuration is saved.
*/
public function modified()
{
}
/**
* Load the configuration.
*
* @return mixed
*/
public function load()
{
if ($this->object) {
return $this->object;
}
$filename = $this->createFilename();
if (!$this->loadCompiledFile($filename) && $this->loadFiles()) {
$this->saveCompiledFile($filename);
}
return $this->object;
}
/**
* Returns checksum from the configuration files.
*
* You can set $this->checksum = false to disable this check.
*
* @return bool|string
*/
public function checksum()
{
if (!isset($this->checksum)) {
$this->checksum = md5(json_encode($this->files) . $this->version);
}
return $this->checksum;
*/
public static function blueprints(Container $container)
{
/** @var UniformResourceLocator $locator */
$locator = $container['locator'];
$cache = $locator->findResource('gantry-cache://theme/compiled/blueprints', true, true);
if (is_bool($cache)) {
throw new \RuntimeException('Who just removed Gantry 5 cache folder? Try reloading the page if it fixes the issue');
}
$files = [];
$paths = $locator->findResources('gantry-particles://');
$files += (new ConfigFileFinder)->setBase('particles')->locateFiles($paths);
$paths = $locator->findResources('gantry-blueprints://');
$files += (new ConfigFileFinder)->locateFiles($paths);
$config = new CompiledBlueprints($cache, $files, GANTRY5_ROOT);
return $config->load();
}
/**
* @param Container $container
* @param string $name
* @param bool $combine
* @param bool $withDefaults
* @return mixed
*/
public static function load(Container $container, $name = 'default', $combine = true, $withDefaults = true)
{
/** @var UniformResourceLocator $locator */
$locator = $container['locator'];
$combine = $combine && $name !== 'default';
// Merge current configuration with the default.
$uris = $combine ? ["gantry-config://{$name}", 'gantry-config://default'] : ["gantry-config://{$name}"];
$paths = [[]];
use Pimple\ServiceProviderInterface;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
/**
* Class ConfigServiceProvider
* @package Gantry\Framework\Services
*/
class ConfigServiceProvider implements ServiceProviderInterface
{
/**
* @param Container $gantry
*/
public function register(Container $gantry)
{
$gantry['blueprints'] = static function(Gantry $gantry) {
if (\GANTRY_DEBUGGER) {
Debugger::startTimer('blueprints', 'Loading blueprints');
}
$blueprints = static::blueprints($gantry);
if (\GANTRY_DEBUGGER) {
Debugger::stopTimer('blueprints');
}
return $blueprints;
};
$gantry['config'] = static function(Gantry $gantry) {
// Make sure configuration has been set.
if (!isset($gantry['configuration'])) {
throw new \LogicException('Gantry: Please set current configuration before using $gantry["config"]', 500);
}
if (\GANTRY_DEBUGGER) {
Debugger::startTimer('config', 'Loading configuration');
}
// Get the current configuration and lock the value from modification.
$outline = $gantry->lock('configuration');
{
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}
if (
isset($this->raw[$id])
|| !\is_object($this->values[$id])
|| isset($this->protected[$this->values[$id]])
|| !\method_exists($this->values[$id], '__invoke')
) {
return $this->values[$id];
}
if (isset($this->factories[$this->values[$id]])) {
return $this->values[$id]($this);
}
$raw = $this->values[$id];
$val = $this->values[$id] = $raw($this);
$this->raw[$id] = $raw;
$this->frozen[$id] = true;
return $val;
}
/**
* Checks if a parameter or an object is set.
*
* @param string $id The unique identifier for the parameter or object
*
* @return bool
*/
public function offsetExists($id)
{
return isset($this->keys[$id]);
}
/**
// Merge current configuration with the default.
$uris = $combine ? ["gantry-config://{$name}", 'gantry-config://default'] : ["gantry-config://{$name}"];
$paths = [[]];
foreach ($uris as $uri) {
$paths[] = $locator->findResources($uri);
}
$paths = array_merge(...$paths);
// Locate all configuration files to be compiled.
$files = (new ConfigFileFinder)->locateFiles($paths);
$cache = $locator->findResource('gantry-cache://theme/compiled/config', true, true);
if (is_bool($cache)) {
throw new \RuntimeException('Who just removed Gantry 5 cache folder? Try reloading the page if it fixes the issue');
}
$compiled = new CompiledConfig($cache, $files, GANTRY5_ROOT);
$compiled->setBlueprints(static function() use ($container) {
return $container['blueprints'];
});
$config = $compiled->load($withDefaults);
// Set atom inheritance.
$atoms = $config->get('page.head.atoms');
if (is_array($atoms)) {
$config->set('page.head.atoms', (new Atoms($atoms))->init()->toArray());
}
// Set FA default in Joomla
if (class_exists(Version::class)) {
$config->def('page.fontawesome.version', Version::MAJOR_VERSION < 4 ? 'fa4' : 'fa5css');
}
return $config;
}
}
* @param bool $withDefaults
* @return mixed
*/
public function load($withDefaults = false)
{
$this->withDefaults = $withDefaults;
return parent::load();
}
/**
* Create configuration object.
*
* @param array $data
*/
protected function createObject(array $data = [])
{
if ($this->withDefaults && empty($data) && is_callable($this->callable)) {
$blueprints = $this->callable;
$data = $blueprints()->getDefaults();
}
$this->object = new Config($data, $this->callable);
}
/**
* Finalize configuration object.
*/
protected function finalizeObject()
{
}
/**
* Load single configuration file and append it to the correct position.
*
* @param string $name Name of the position.
* @param string $filename File to be loaded.
*/
protected function loadFile($name, $filename)
{
*/
abstract protected function finalizeObject();
/**
* Load single configuration file and append it to the correct position.
*
* @param string $name Name of the position.
* @param string $filename File to be loaded.
*/
abstract protected function loadFile($name, $filename);
/**
* Load and join all configuration files.
*
* @return bool
* @internal
*/
protected function loadFiles()
{
$this->createObject();
$list = array_reverse($this->files);
foreach ($list as $files) {
foreach ($files as $name => $item) {
$this->loadFile($name, $this->path . $item['file']);
}
}
$this->finalizeObject();
return true;
}
/**
* Load compiled file.
*
* @param string $filename
* @return bool
* @internal
*/
/**
* Function gets called when cached configuration is saved.
*/
public function modified()
{
}
/**
* Load the configuration.
*
* @return mixed
*/
public function load()
{
if ($this->object) {
return $this->object;
}
$filename = $this->createFilename();
if (!$this->loadCompiledFile($filename) && $this->loadFiles()) {
$this->saveCompiledFile($filename);
}
return $this->object;
}
/**
* Returns checksum from the configuration files.
*
* You can set $this->checksum = false to disable this check.
*
* @return bool|string
*/
public function checksum()
{
if (!isset($this->checksum)) {
$this->checksum = md5(json_encode($this->files) . $this->version);
}
return $this->checksum;
*
* @param callable $blueprints
* @return $this
*/
public function setBlueprints(callable $blueprints)
{
$this->callable = $blueprints;
return $this;
}
/**
* @param bool $withDefaults
* @return mixed
*/
public function load($withDefaults = false)
{
$this->withDefaults = $withDefaults;
return parent::load();
}
/**
* Create configuration object.
*
* @param array $data
*/
protected function createObject(array $data = [])
{
if ($this->withDefaults && empty($data) && is_callable($this->callable)) {
$blueprints = $this->callable;
$data = $blueprints()->getDefaults();
}
$this->object = new Config($data, $this->callable);
}
/**
* Finalize configuration object.
*/
$paths = [[]];
foreach ($uris as $uri) {
$paths[] = $locator->findResources($uri);
}
$paths = array_merge(...$paths);
// Locate all configuration files to be compiled.
$files = (new ConfigFileFinder)->locateFiles($paths);
$cache = $locator->findResource('gantry-cache://theme/compiled/config', true, true);
if (is_bool($cache)) {
throw new \RuntimeException('Who just removed Gantry 5 cache folder? Try reloading the page if it fixes the issue');
}
$compiled = new CompiledConfig($cache, $files, GANTRY5_ROOT);
$compiled->setBlueprints(static function() use ($container) {
return $container['blueprints'];
});
$config = $compiled->load($withDefaults);
// Set atom inheritance.
$atoms = $config->get('page.head.atoms');
if (is_array($atoms)) {
$config->set('page.head.atoms', (new Atoms($atoms))->init()->toArray());
}
// Set FA default in Joomla
if (class_exists(Version::class)) {
$config->def('page.fontawesome.version', Version::MAJOR_VERSION < 4 ? 'fa4' : 'fa5css');
}
return $config;
}
}
if ($force) {
unset($gantry['configuration']);
}
// Set default name only if configuration has not been set before.
if ($name === null && !isset($gantry['configuration'])) {
$name = 'default';
}
$outline = isset($gantry['configuration']) ? $gantry['configuration'] : null;
// Set configuration if given.
if ($name && $name !== $outline) {
if (\GANTRY_DEBUGGER) {
Debugger::addMessage("Using Gantry outline {$name}");
}
$gantry['configuration'] = $name;
unset($gantry['config']);
$gantry['config'] = ConfigServiceProvider::load($gantry, $name);
}
return $this;
}
/**
* Get current preset.
*
* @param bool $forced If true, return only forced preset or null.
* @return string|null $preset
*/
public function preset($forced = false)
{
$presets = $this->presets()->toArray();
$preset = $this->preset;
if (!$preset && !$forced) {
/** @var Config $config */
$config = static::gantry()['config'];
}
if (\GANTRY_DEBUGGER) {
Debugger::addMessage("Using Gantry 5 template {$templateName}");
}
/** @var Theme $theme */
$theme = $gantry['theme'];
$assignments = new Assignments();
if (\GANTRY_DEBUGGER) {
Debugger::addMessage('Selecting outline (rules, matches, scores):', 'debug');
Debugger::addMessage($assignments->getPage(), 'debug');
Debugger::addMessage($assignments->loadAssignments(), 'debug');
Debugger::addMessage($assignments->matches(), 'debug');
Debugger::addMessage($assignments->scores(), 'debug');
}
$theme->setLayout($assignments->select());
if ($this->params->get('asset_timestamps', 1)) {
$age = (int)($this->params->get('asset_timestamps_period', 7) * 86400);
Document::$timestamp_age = $age > 0 ? $age : PHP_INT_MAX;
} else {
Document::$timestamp_age = 0;
}
}
/**
* Re-route Gantry templates to Gantry Administration component.
*/
private function onAfterRouteAdmin()
{
$input = $this->app->input;
$option = $input->getCmd('option');
$task = $input->getCmd('task');
if (in_array($option, array('com_templates', 'com_advancedtemplates'), true)) {
/**
* Return global configuration for Gantry5.
*
* @param array $global
*/
public function onGantryGlobalConfig(&$global)
{
$global = $this->params->toArray();
}
public function onAfterRoute()
{
if (version_compare(JVERSION, '4.0', '<')) {
// In Joomla 3.9 we need to make sure that user identity has been loaded.
$this->app->loadIdentity();
}
if ($this->app->isClient('site')) {
$this->onAfterRouteSite();
} elseif ($this->app->isClient('administrator')) {
$this->onAfterRouteAdmin();
}
}
/**
* Document gets set during dispatch, we need language and direction.
*/
public function onAfterDispatch()
{
if (class_exists('Gantry\Framework\Gantry')) {
$this->onAfterDispatchSiteAdmin();
}
}
public function onAfterRender()
{
if ($this->app->isClient('site') && class_exists('Gantry\Framework\Gantry')) {
$this->onAfterRenderSite();
* @param array &$args Arguments
*
* @return mixed Routine return value
*
* @since 1.5
*/
public function update(&$args)
{
// First let's get the event from the argument array. Next we will unset the
// event argument as it has no bearing on the method to handle the event.
$event = $args['event'];
unset($args['event']);
/*
* If the method to handle an event exists, call it and return its return
* value. If it does not exist, return null.
*/
if (method_exists($this, $event))
{
return call_user_func_array(array($this, $event), array_values($args));
}
}
}
if (!isset($this->_methods[$event]) || empty($this->_methods[$event]))
{
// No Plugins Associated To Event!
return $result;
}
// Loop through all plugins having a method matching our event
foreach ($this->_methods[$event] as $key)
{
// Check if the plugin is present.
if (!isset($this->_observers[$key]))
{
continue;
}
// Fire the event for an object based observer.
if (is_object($this->_observers[$key]))
{
$args['event'] = $event;
$value = $this->_observers[$key]->update($args);
}
// Fire the event for a function based observer.
elseif (is_array($this->_observers[$key]))
{
$value = call_user_func_array($this->_observers[$key]['handler'], array_values($args));
}
if (isset($value))
{
$result[] = $value;
}
}
return $result;
}
/**
* Attach an observer object
*
* @param object $observer An observer object to attach
}
return $this;
}
/**
* Calls all handlers associated with an event group.
*
* @param string $event The event name.
* @param array $args An array of arguments (optional).
*
* @return array An array of results from each function call, or null if no dispatcher is defined.
*
* @since 3.0.0
*/
public function triggerEvent($event, array $args = null)
{
if ($this->dispatcher instanceof \JEventDispatcher)
{
return $this->dispatcher->trigger($event, $args);
}
return;
}
/**
* Allows the application to load a custom or default dispatcher.
*
* The logic and options for creating this object are adequately generic for default cases
* but for many applications it will make sense to override this method and create event
* dispatchers, if required, based on more specific needs.
*
* @param \JEventDispatcher $dispatcher An optional dispatcher object. If omitted, the factory dispatcher is created.
*
* @return BaseApplication This method is chainable.
*
* @since 3.0.0
*/
public function loadDispatcher(\JEventDispatcher $dispatcher = null)
{
$this->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true);
$this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true);
$this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);
$this->setHeader('Pragma', 'no-cache');
$this->sendHeaders();
$this->redirect((string) $oldUri, 301);
}
}
}
foreach ($result as $key => $value)
{
$this->input->def($key, $value);
}
// Trigger the onAfterRoute event.
\JPluginHelper::importPlugin('system');
$this->triggerEvent('onAfterRoute');
}
/**
* Sets the value of a user state variable.
*
* @param string $key The path of the state.
* @param mixed $value The value of the variable.
*
* @return mixed The previous state, if one existed.
*
* @since 3.2
*/
public function setUserState($key, $value)
{
$session = \JFactory::getSession();
$registry = $session->get('registry');
if ($registry !== null)
{
return $registry->set($key, $value);
parent::render();
}
/**
* Route the application.
*
* Routing is the process of examining the request environment to determine which
* component should receive the request. The component optional parameters
* are then set in the request object to be processed when the application is being
* dispatched.
*
* @return void
*
* @since 3.2
*/
protected function route()
{
// Execute the parent method
parent::route();
$Itemid = $this->input->getInt('Itemid', null);
$this->authorise($Itemid);
}
/**
* Set the current state of the detect browser option.
*
* @param boolean $state The new state of the detect browser option
*
* @return boolean The previous state
*
* @since 3.2
*/
public function setDetectBrowser($state = false)
{
$old = $this->_detect_browser;
$this->_detect_browser = $state;
return $old;
$this->triggerEvent('onAfterDispatch');
}
/**
* Method to run the Web application routines.
*
* @return void
*
* @since 3.2
*/
protected function doExecute()
{
// Initialise the application
$this->initialiseApp();
// Mark afterInitialise in the profiler.
JDEBUG ? $this->profiler->mark('afterInitialise') : null;
// Route the application
$this->route();
// Mark afterRoute in the profiler.
JDEBUG ? $this->profiler->mark('afterRoute') : null;
/*
* Check if the user is required to reset their password
*
* Before $this->route(); "option" and "view" can't be safely read using:
* $this->input->getCmd('option'); or $this->input->getCmd('view');
* ex: due of the sef urls
*/
$this->checkUserRequireReset('com_users', 'profile', 'edit', 'com_users/profile.save,com_users/profile.apply,com_users/user.logout');
// Dispatch the application
$this->dispatch();
// Mark afterDispatch in the profiler.
JDEBUG ? $this->profiler->mark('afterDispatch') : null;
}
array('option', 'view', 'format', 'lang', 'Itemid', 'template', 'templateStyle', 'task'),
function($systemVariable) use ($input) {
return $input->exists($systemVariable) && is_array($input->getRaw($systemVariable));
}
);
// Unset invalid system variables
foreach ($invalidInputVariables as $systemVariable)
{
$input->set($systemVariable, null);
}
// Abort when there are invalid variables
if ($invalidInputVariables)
{
throw new \RuntimeException('Invalid input, aborting application.');
}
// Perform application routines.
$this->doExecute();
// If we have an application document object, render it.
if ($this->document instanceof \JDocument)
{
// Render the application output.
$this->render();
}
// If gzip compression is enabled in configuration and the server is compliant, compress the output.
if ($this->get('gzip') && !ini_get('zlib.output_compression') && ini_get('output_handler') !== 'ob_gzhandler')
{
$this->compress();
// Trigger the onAfterCompress event.
$this->triggerEvent('onAfterCompress');
}
// Send the application response.
$this->respond();
{
include_once __DIR__ . '/defines.php';
}
if (!defined('_JDEFINES'))
{
define('JPATH_BASE', __DIR__);
require_once JPATH_BASE . '/includes/defines.php';
}
require_once JPATH_BASE . '/includes/framework.php';
// Set profiler start time and memory usage and mark afterLoad in the profiler.
JDEBUG ? JProfiler::getInstance('Application')->setStart($startTime, $startMem)->mark('afterLoad') : null;
// Instantiate the application.
$app = JFactory::getApplication('site');
// Execute the application.
$app->execute();