// 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);
}
}
if ($data !== null) {
$this->content($data);
}
$filename = $this->filename;
if (is_link($filename)) {
$realname = realpath($filename);
if ($realname === false) {
throw new RuntimeException('Failed to save file ' . $filename);
}
$filename = $realname;
}
$dir = dirname($filename);
if (!$dir || !$this->mkdir($dir)) {
throw new RuntimeException('Creating directory failed for ' . $filename);
}
try {
if ($this->handle) {
$tmp = true;
// As we are using non-truncating locking, make sure that the file is empty before writing.
if (@ftruncate($this->handle, 0) === false || @fwrite($this->handle, $this->raw()) === false) {
// Writing file failed, throw an error.
$tmp = false;
}
} else {
// Create file with a temporary name and rename it to make the save action atomic.
$tmp = $this->tempname($filename);
if (file_put_contents($tmp, $this->raw()) === false) {
$tmp = false;
} elseif (@rename($tmp, $filename) === false) {
@unlink($tmp);
$tmp = false;
}
}
* @return array
*/
public function content($var = null)
{
/** @var array $content */
$content = parent::content($var);
return $content;
}
/**
* Saves PHP file and invalidates opcache.
*
* @param mixed $data Optional data to be saved, usually array.
* @return void
* @throws RuntimeException
*/
public function save($data = null)
{
parent::save($data);
// Invalidate configuration file from the opcache.
if (null !== $this->filename && function_exists('opcache_invalidate')) {
@opcache_invalidate($this->filename, true);
}
}
/**
* Check contents and make sure it is in correct format.
*
* @param mixed $var
* @return array
* @throws RuntimeException
*/
protected function check($var)
{
if (!(is_array($var) || is_object($var))) {
throw new RuntimeException('Provided data is not an array');
}
) {
// 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();
$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);
}
*
* @param string $theme
*/
public function __construct($theme)
{
$gantry = Gantry::instance();
/** @var UniformResourceLocator $locator */
$locator = $gantry['locator'];
$filename = $locator->findResource("gantry-themes://{$theme}/custom/gantry/theme.yaml") ?: $locator->findResource("gantry-themes://{$theme}/gantry/theme.yaml");
if (!$filename) {
throw new \RuntimeException(sprintf('Theme %s not found', $theme), 404);
}
/** @var string $cache */
$cache = $locator->findResource("gantry-cache://{$theme}/compiled/yaml", true, true);
$file = CompiledYamlFile::instance($filename);
$this->items = (array)$file->setCachePath($cache)->content();
$file->free();
$this->offsetSet('name', $theme);
$parent = (string) $this->get('configuration.theme.parent', $theme);
$parent = $parent !== $theme ? $parent : null;
$this->offsetSet('parent', $parent);
}
/**
* @return string
*/
public function addStreams()
{
$gantry = Gantry::instance();
// Initialize theme stream.
$streamName = $this->addStream($this->offsetGet('name'), $this->getPaths());
*/
protected static function loadThemes()
{
$gantry = Gantry::instance();
/** @var Platform $platform */
$platform = $gantry['platform'];
/** @var UniformResourceLocator $locator */
$locator = $gantry['locator'];
/** @var ThemeDetails[] $list */
$list = [];
$files = Folder::all('gantry-themes://', ['recursive' => false, 'files' => false]);
natsort($files);
foreach ($files as $theme) {
if ($locator('gantry-themes://' . $theme . '/gantry/theme.yaml')) {
$details = new ThemeDetails($theme);
$details->addStreams();
$details['name'] = $theme;
$details['title'] = $details['details.name'];
$details['preview_url'] = null;
$details['admin_url'] = $platform->getThemeAdminUrl($theme);
$details['params'] = [];
$list[$details->name] = $details;
}
}
// Add Thumbnails links after adding all the paths to the locator.
foreach ($list as $details) {
$details['thumbnail'] = $details->getUrl('details.images.thumbnail');
}
static::$items = $list;
}
$db = Factory::getDbo();
$query = $db
->getQuery(true)
->select('s.id, e.extension_id, s.template AS name, s.title, s.params')
->from('#__template_styles AS s')
->where('s.client_id = 0')
->where('e.enabled = 1')
->where('e.state = 0')
->leftJoin('#__extensions AS e ON e.element=s.template AND e.type='
. $db->quote('template') . ' AND e.client_id=s.client_id')
->order('s.id');
$db->setQuery($query);
$styles = (array) $db->loadObjectList();
if (!\is_array(static::$items)) {
static::loadThemes();
}
/** @var ThemeDetails[] $list */
$list = [];
foreach ($styles as $style)
{
$details = isset(static::$items[$style->name]) ? static::$items[$style->name] : null;
if (!$details) {
continue;
}
$params = new Registry($style->params);
$details = clone $details;
$details['id'] = $style->id;
$details['extension_id'] = $style->extension_id;
$details['style'] = $style->title;
$details['preview_url'] = $platform->getThemePreviewUrl($style->id);
$details['params'] = $params->toArray();
/**
* @param string $name
* @return mixed
*/
public static function getTheme($name)
{
$styles = static::getStyles($name);
return reset($styles);
}
/**
* @param string $template
* @return array
*/
public static function getStyles($template = null, $force = false)
{
if ($force || !\is_array(static::$styles)) {
static::loadStyles();
}
if ($template) {
return isset(static::$styles[$template]) ? static::$styles[$template] : [];
}
$list = [];
foreach (static::$styles as $styles) {
$list += $styles;
}
ksort($list);
return $list;
}
/**
*
*/
protected static function loadThemes()
/** @var UniformResourceLocator $locator */
$locator = $this->container['locator'];
return ($outline && is_dir($locator("{$this->path}/{$outline}"))) ? $outline : $preset;
}
/**
* @param string $path
* @return $this
*/
public function load($path = 'gantry-config://')
{
$this->path = $path;
$gantry = $this->container;
$theme = isset($gantry['theme.name']) ? $gantry['theme.name'] : null;
$styles = ThemeList::getStyles($theme);
$installer = new ThemeInstaller($this->container['theme.name']);
$title = $installer->getStyleName('%s - ');
$outlines = [];
foreach ($styles as $style) {
$preset = isset($style->params['preset']) ? $style->params['preset'] : null;
$outline = isset($style->params['configuration']) ? $style->params['configuration'] : $preset;
if ($outline && $outline != $style->id) {
// New style generated by Joomla.
StyleHelper::copy($style, $outline, $style->id);
}
$outlines[$style->id] = preg_replace('|^' . preg_quote($title, '|') . '|', '', $style->style);
}
asort($outlines);
$this->items = $this->addDefaults($outlines);
// Make sure that nobody modifies the original collection by making it a factory.
$instance['outlines'] = $instance->factory(static function ($c) {
static $collection;
if (!$collection) {
$collection = (new Outlines($c))->load();
}
return $collection->copy();
});
// @deprecated 5.3
$instance['configurations'] = $instance->factory(static function ($c) {
if (\GANTRY_DEBUGGER) {
Debugger::addMessage('Depredated call: gantry.configurations');
}
static $collection;
if (!$collection) {
$collection = (new Outlines($c))->load();
}
return $collection->copy();
});
$instance['positions'] = $instance->factory(static function ($c) {
static $collection;
if (!$collection) {
$collection = (new Positions($c))->load();
}
return $collection->copy();
});
$instance['global'] = static function (Gantry $c) {
$data = $c->loadGlobal() + [
'debug' => false,
'production' => true,
'use_media_folder' => false,
'asset_timestamps' => true,
* @throws UnknownIdentifierException If the identifier is not defined
*/
#[\ReturnTypeWillChange]
public function offsetGet($id)
{
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
*/
#[\ReturnTypeWillChange]
public function offsetExists($id)
<?php
/**
* @package Gantry 5 Theme
* @author RocketTheme http://www.rockettheme.com
* @copyright Copyright (C) 2007 - 2016 RocketTheme, LLC
* @license GNU/GPLv2 and later
*
* http://www.gnu.org/licenses/gpl-2.0.html
*/
defined('_JEXEC') or die;
// Bootstrap Gantry framework or fail gracefully (inside included file).
$gantry = include __DIR__ . '/includes/gantry.php';
/** @var \Gantry\Framework\Theme $theme */
$theme = $gantry['theme'];
/** @var \Gantry\Framework\Outlines $configurations */
$configurations = $gantry['configurations'];
// All the custom twig variables can be defined in here:
$context = array();
// Render the page.
echo $theme->render('index.html.twig', $context);
* @param string $directory The name of the template
* @param string $filename The actual filename
*
* @return string The contents of the template
*
* @since 1.7.0
*/
protected function _loadTemplate($directory, $filename)
{
$contents = '';
// Check to see if we have a valid template file
if (file_exists($directory . '/' . $filename))
{
// Store the file path
$this->_file = $directory . '/' . $filename;
// Get the file content
ob_start();
require $directory . '/' . $filename;
$contents = ob_get_contents();
ob_end_clean();
}
// Try to find a favicon by checking the template and root folder
$icon = '/favicon.ico';
foreach (array($directory, JPATH_BASE) as $dir)
{
if (file_exists($dir . $icon))
{
$path = str_replace(JPATH_BASE, '', $dir);
$path = str_replace('\\', '/', $path);
$this->addFavicon(Uri::base(true) . $path . $icon);
break;
}
}
return $contents;
}
if (!file_exists($directory . '/' . $template . '/' . $file))
{
$file = 'index.php';
}
// Load the language file for the template
$lang = \JFactory::getLanguage();
// 1.5 or core then 1.6
$lang->load('tpl_' . $template, JPATH_BASE, null, false, true)
|| $lang->load('tpl_' . $template, $directory . '/' . $template, null, false, true);
// Assign the variables
$this->template = $template;
$this->baseurl = Uri::base(true);
$this->params = isset($params['params']) ? $params['params'] : new Registry;
// Load
$this->_template = $this->_loadTemplate($directory . '/' . $template, $file);
return $this;
}
/**
* Parse a document template
*
* @return HtmlDocument instance of $this to allow chaining
*
* @since 1.7.0
*/
protected function _parseTemplate()
{
$matches = array();
if (preg_match_all('#<jdoc:include\ type="([^"]+)"(.*)\/>#iU', $this->_template, $matches))
{
$template_tags_first = array();
$template_tags_last = array();
$options['title'] = (isset($args[3])) ? $args[3] : null;
}
parent::$_buffer[$options['type']][$options['name']][$options['title']] = $content;
return $this;
}
/**
* Parses the template and populates the buffer
*
* @param array $params Parameters for fetching the template
*
* @return HtmlDocument instance of $this to allow chaining
*
* @since 1.7.0
*/
public function parse($params = array())
{
return $this->_fetchTemplate($params)->_parseTemplate();
}
/**
* Outputs the template to the browser.
*
* @param boolean $caching If true, cache the output
* @param array $params Associative array of attributes
*
* @return string The rendered data
*
* @since 1.7.0
*/
public function render($caching = false, $params = array())
{
$this->_caching = $caching;
if (empty($this->_template))
{
$this->parse($params);
}
*/
protected function render()
{
// Setup the document options.
$this->docOptions['template'] = $this->get('theme');
$this->docOptions['file'] = $this->get('themeFile', 'index.php');
$this->docOptions['params'] = $this->get('themeParams');
if ($this->get('themes.base'))
{
$this->docOptions['directory'] = $this->get('themes.base');
}
// Fall back to constants.
else
{
$this->docOptions['directory'] = defined('JPATH_THEMES') ? JPATH_THEMES : (defined('JPATH_BASE') ? JPATH_BASE : __DIR__) . '/themes';
}
// Parse the document.
$this->document->parse($this->docOptions);
// Trigger the onBeforeRender event.
\JPluginHelper::importPlugin('system');
$this->triggerEvent('onBeforeRender');
$caching = false;
if ($this->isClient('site') && $this->get('caching') && $this->get('caching', 2) == 2 && !\JFactory::getUser()->get('id'))
{
$caching = true;
}
// Render the document.
$data = $this->document->render($caching, $this->docOptions);
// Set the application output data.
$this->setBody($data);
// Trigger the onAfterRender event.
$this->triggerEvent('onAfterRender');
$this->setUserState('users.login.form.data', array('return' => \JUri::getInstance()->toString()));
$this->set('themeFile', 'offline.php');
$this->setHeader('Status', '503 Service Temporarily Unavailable', 'true');
}
if (!is_dir(JPATH_THEMES . '/' . $template->template) && !$this->get('offline'))
{
$this->set('themeFile', 'component.php');
}
// Ensure themeFile is set by now
if ($this->get('themeFile') == '')
{
$this->set('themeFile', $file . '.php');
}
break;
}
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);
// 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 ($this->get('block_floc', 1))
{
$headers = $this->getHeaders();
$notPresent = true;
foreach ($headers as $header)
{
if (strtolower($header['name']) === 'permissions-policy')
{
// Append interest-cohort if the Permissions-Policy is not set
if (strpos($header['value'], 'interest-cohort') === false)
{
$this->setHeader('Permissions-Policy', $header['value'] . ', interest-cohort=()', true);
}
$notPresent = false;
{
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();