__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2021 RocketTheme, LLC
 * @license   Dual License: MIT or GNU/GPLv2 and later
 *
 * http://opensource.org/licenses/MIT
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * Gantry Framework code that extends GPL code is considered GNU/GPLv2 and later
 */

namespace Gantry\Component\Theme;

use Gantry\Component\Config\Config;
use Gantry\Component\Content\Block\ContentBlock;
use Gantry\Component\Content\Block\ContentBlockInterface;
use Gantry\Component\Content\Block\HtmlBlock;
use Gantry\Component\File\CompiledYamlFile;
use Gantry\Component\Filesystem\Folder;
use Gantry\Component\Gantry\GantryTrait;
use Gantry\Component\Layout\Layout;
use Gantry\Component\Stylesheet\CssCompilerInterface;
use Gantry\Component\Stylesheet\ScssCompiler;
use Gantry\Debugger;
use Gantry\Framework\Document;
use Gantry\Framework\Menu;
use Gantry\Framework\Services\ConfigServiceProvider;
use RocketTheme\Toolbox\File\PhpFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

/**
 * Class ThemeTrait
 * @package Gantry\Component
 *
 * @property string $path
 * @property string $layout
 */
trait ThemeTrait
{
    use GantryTrait;

    /** @var Layout */
    protected $layoutObject;
    /** @var bool */
    protected $atoms = false;
    /** @var array */
    protected $segments;
    /** @var string|null */
    protected $preset;
    /** @var array */
    protected $cssCache = [];
    /** @var CssCompilerInterface */
    protected $compiler;
    /** @var array */
    protected $equalized = [3 => 33.3, 6 => 16.7, 7 => 14.3, 8 => 12.5, 9 => 11.1, 11 => 9.1, 12 => 8.3];
    /** @var ThemeDetails */
    protected $details;

    /**
     * Register Theme stream.
     *
     * @param string|string[] $savePath
     */
    public function registerStream($savePath = null)
    {
        $streamName = $this->details()->addStreams();

        /** @var UniformResourceLocator $locator */
        $locator = self::gantry()['locator'];
        $locator->addPath('gantry-theme', '', array_merge((array) $savePath, [[$streamName, '']]));
    }

    /**
     * Update all CSS files in the theme.
     *
     * @param array $outlines
     * @return array List of CSS warnings.
     */
    public function updateCss(array $outlines = null)
    {
        $gantry = static::gantry();
        $compiler = $this->compiler();

        if (null === $outlines) {
            /** @var UniformResourceLocator $locator */
            $locator = $gantry['locator'];
            $path = $locator->findResource($compiler->getTarget(), true, true);

            // Make sure that all the CSS files get deleted.
            if (is_dir($path)) {
                Folder::delete($path, false);
            }

            $outlines = $gantry['outlines'];
        }

        // Make sure that PHP has the latest data of the files.
        clearstatcache();

        $warnings = [];
        foreach ($outlines as $outline => $title) {
            $config = ConfigServiceProvider::load($gantry, $outline);

            $compiler->reset()->setConfiguration($outline)->setVariables($config->flatten('styles', '-'));

            $warnings[$outline] = $compiler->compileAll()->getWarnings();
        }

        $check = [];
        foreach ($warnings as $outline => $files) {
            foreach ($files as $file => $list) {
                if ($file === '__TITLE__') {
                    unset($warnings[$outline][$file]);
                    $warnings['__TITLE__'] = $list;
                    continue;
                }
                $filter = isset($check[$file]) ? $check[$file] : [];
                $filtered = array_diff($list, $filter);
                $check[$file] = array_unique(array_merge($filter, $list));
                if ($filtered) {
                    $warnings[$outline][$file] = $filtered;
                } else {
                    unset($warnings[$outline][$file]);
                }
            }
            if (empty($warnings[$outline])) {
                unset($warnings[$outline]);
            }
        }

        return $warnings;
    }

    /**
     * Set layout to be used.
     *
     * @param string $name
     * @param bool $force
     * @return $this
     */
    public function setLayout($name = null, $force = false)
    {
        $gantry = static::gantry();

        // Force new layout to be set.
        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'];
            $preset = $config->get('styles.preset', '-undefined-');
        }

        if ($preset && !isset($presets[$preset])) {
            $preset = null;
        }

        return $preset;
    }

    /**
     * Set preset to be used.
     *
     * @param string $name
     * @return $this
     */
    public function setPreset($name = null)
    {
        // Set preset if given.
        if ($name) {
            $this->preset = $name;
        }

        return $this;
    }

    /**
     * Return CSS compiler used in the theme.
     *
     * @return CssCompilerInterface
     * @throws \RuntimeException
     */
    public function compiler()
    {
        if (!$this->compiler) {
            $compilerClass = (string) $this->details()->get('configuration.css.compiler', ScssCompiler::class);

            if (!class_exists($compilerClass)) {
                throw new \RuntimeException('CSS compiler used by the theme not found');
            }

            $details = $this->details();

            /** @var CssCompilerInterface $compiler */
            $this->compiler = new $compilerClass();
            $this->compiler
                ->setTarget($details->get('configuration.css.target'))
                ->setPaths($details->get('configuration.css.paths'))
                ->setFiles($details->get('configuration.css.files'))
                ->setFonts($details->get('configuration.fonts'));
        }

        $preset = $this->preset(true);
        if ($preset) {
            $this->compiler->setConfiguration($preset);
        } else {
            $gantry = static::gantry();
            $this->compiler->setConfiguration(isset($gantry['configuration']) ? $gantry['configuration'] : 'default');
        }

        return $this->compiler->reset();
    }

    /**
     * Returns URL to CSS file.
     *
     * If file does not exist, it will be created by using CSS compiler.
     *
     * @param string $name
     * @return string
     */
    public function css($name)
    {
        if (!isset($this->cssCache[$name])) {
            $compiler = $this->compiler();

            if ($compiler->needsCompile($name, [$this, 'getCssVariables'])) {
                if (\GANTRY_DEBUGGER) {
                    Debugger::startTimer("css-{$name}", "Compiling CSS: {$name}");
                    Debugger::addMessage("Compiling CSS: {$name}");
                }

                $compiler->compileFile($name);

                if (\GANTRY_DEBUGGER) {
                    Debugger::stopTimer("css-{$name}");
                }
            }

            $this->cssCache[$name] = $compiler->getCssUrl($name);
        }

        return $this->cssCache[$name];
    }

    /**
     * @return array
     */
    public function getCssVariables()
    {
        if ($this->preset) {
            $variables = $this->presets()->flatten($this->preset . '.styles', '-');
        } else {
            $gantry = self::gantry();
            /** @var Config $config */
            $config = $gantry['config'];
            $variables = $config->flatten('styles', '-');
        }

        return $variables;
    }

    /**
     * Returns style presets for the theme.
     *
     * @return Config
     */
    public function presets()
    {
        static $presets;

        if (!$presets) {
            $gantry = static::gantry();

            /** @var UniformResourceLocator $locator */
            $locator = $gantry['locator'];

            $filename = $locator->findResource('gantry-theme://gantry/presets.yaml');
            $file = CompiledYamlFile::instance($filename);
            $presets = new Config((array)$file->content());
            $file->free();
        }

        return $presets;
    }

    /**
     * Return name of the used layout preset.
     *
     * @return string
     * @throws \RuntimeException
     */
    public function type()
    {
        if (!$this->layoutObject) {
            throw new \RuntimeException('Function called too early');
        }
        $name = isset($this->layoutObject->preset['name']) ? $this->layoutObject->preset['name'] : 'unknown';

        return $name;
    }

    /**
     * Load current layout and its configuration.
     *
     * @param string $name
     * @return Layout
     * @throws \LogicException
     */
    public function loadLayout($name = null)
    {
        if (!$name) {
            try {
                $name = static::gantry()['configuration'];
            } catch (\Exception $e) {
                throw new \LogicException('Gantry: Outline has not been defined yet', 500);
            }
        }

        if (!isset($this->layoutObject) || $this->layoutObject->name !== $name) {
            $layout = Layout::instance($name);

            if (!$layout->exists()) {
                $layout = Layout::instance('default');
            }

            // TODO: Optimize
            $this->layoutObject = $layout->init();
        }

        return $this->layoutObject;
    }

    /**
     * Check whether layout has content bock.
     *
     * @return bool
     */
    public function hasContent()
    {
        $layout = $this->loadLayout();
        $content = $layout->referencesByType('system', 'content');

        return !empty($content);
    }

    /**
     * Load atoms and assets from the page settings.
     *
     * @since 5.4.9
     */
    public function loadAtoms()
    {
        if (!$this->atoms) {
            $this->atoms = true;

            if (\GANTRY_DEBUGGER) {
                Debugger::startTimer('atoms', 'Preparing atoms');
            }

            $gantry = static::gantry();

            /** @var Config $config */
            $config = $gantry['config'];

            /** @var Document $document */
            $document = $gantry['document'];

            $atoms = (array) $config->get('page.head.atoms');

            foreach ($atoms as $data) {
                $atom = [
                    'type' => 'atom',
                    'subtype' => $data['type'],
                ] + $data;

                try {
                    $block = $this->getContent($atom);
                    $document->addBlock($block);

                } catch (\Exception $e) {
                    if ($gantry->debug()) {
                        throw new \RuntimeException("Rendering Atom '{$atom['subtype']}' failed on error: {$e->getMessage()}", 500, $e);
                    }
                }
            }

            $assets = (array) $config->get('page.assets');

            if ($assets) {
                $atom = [
                    'id' => 'page-assets',
                    'title' => 'Page Assets',
                    'type' => 'atom',
                    'subtype' => 'assets',
                    'attributes' => $assets + ['enabled' => 1]
                ];

                try {
                    $block = $this->getContent($atom);
                    $document->addBlock($block);

                } catch (\Exception $e) {
                    if ($gantry->debug()) {
                        throw new \RuntimeException("Rendering CSS/JS Assets failed on error: {$e->getMessage()}", 500, $e);
                    }
                }
            }

            if (\GANTRY_DEBUGGER) {
                Debugger::stopTimer('atoms');
            }
        }
    }

    /**
     * Returns all non-empty segments from the layout.
     *
     * @return array
     */
    public function segments()
    {
        if (!isset($this->segments)) {
            $this->segments = $this->loadLayout()->toArray();

            if (\GANTRY_DEBUGGER) {
                Debugger::startTimer('segments', 'Preparing layout');
            }

            $this->prepareLayout($this->segments);

            if (\GANTRY_DEBUGGER) {
                Debugger::stopTimer('segments');
            }
        }

        return $this->segments;
    }

    /**
     * Prepare layout for rendering. Initializes all CSS/JS in particles.
     */
    public function prepare()
    {
        $this->segments();
    }

    /**
     * Returns details of the theme.
     *
     * @return ThemeDetails
     */
    public function details()
    {
        if (!$this->details) {
            $this->details = new ThemeDetails($this->name);
        }
        return $this->details;
    }

    /**
     * Returns configuration of the theme.
     *
     * @return array
     */
    public function configuration()
    {
        return (array) $this->details()['configuration'];
    }

    /**
     * Function to convert block sizes into CSS classes.
     *
     * @param $text
     * @return string
     */
    public function toGrid($text)
    {
        if (!$text) {
            return '';
        }

        $number = round($text, 1);
        $number = max(5, $number);
        $number = (string) ($number === 100.0 ? 100 : min(95, $number));

        static $sizes = [
            '33.3' => 'size-33-3',
            '16.7' => 'size-16-7',
            '14.3' => 'size-14-3',
            '12.5' => 'size-12-5',
            '11.1' => 'size-11-1',
            '9.1'  => 'size-9-1',
            '8.3'  => 'size-8-3'
        ];

        return isset($sizes[$number]) ? ' ' . $sizes[$number] : 'size-' . (int) $number;
    }

    /**
     * Magic setter method
     *
     * @param mixed $offset Asset name value
     * @param mixed $value  Asset value
     */
    public function __set($offset, $value)
    {
        if ($offset === 'title') {
            $offset = 'name';
        }

        $this->details()->offsetSet('details.' . $offset, $value);
    }

    /**
     * Magic getter method
     *
     * @param  mixed $offset Asset name value
     * @return mixed         Asset value
     */
    public function __get($offset)
    {
        if ($offset === 'title') {
            $offset = 'name';
        }

        $value = $this->details()->offsetGet('details.' . $offset);

        if ($offset === 'version' && is_int($value)) {
            $value .= '.0';
        }

        return $value;
    }

    /**
     * Magic method to determine if the attribute is set
     *
     * @param  mixed   $offset Asset name value
     * @return boolean         True if the value is set
     */
    public function __isset($offset)
    {
        if ($offset === 'title') {
            $offset = 'name';
        }

        return $this->details()->offsetExists('details.' . $offset);
    }

    /**
     * Magic method to unset the attribute
     *
     * @param mixed $offset The name value to unset
     */
    public function __unset($offset)
    {
        if ($offset === 'title') {
            $offset = 'name';
        }

        $this->details()->offsetUnset('details.' . $offset);
    }

    /**
     * Prepare layout by loading all the positions and particles.
     *
     * Action is needed before displaying the layout as it recalculates block widths based on the visible content.
     *
     * @param array $items
     * @param bool  $temporary
     * @param bool  $sticky
     * @internal
     */
    protected function prepareLayout(array &$items, $temporary = false, $sticky = false)
    {
        foreach ($items as $i => &$item) {
            // Non-numeric items are meta-data which should be ignored.
            if (((string)(int) $i !== (string) $i) || !is_object($item)) {
                continue;
            }

            if (!empty($item->children)) {
                $fixed = true;
                foreach ($item->children as $child) {
                    $fixed &= !empty($child->attributes->fixed);
                }

                $this->prepareLayout($item->children, $fixed, $temporary);
            }

            // TODO: remove hard coded types.
            switch ($item->type) {
                case 'system':
                    break;

                case 'atom':
                case 'particle':
                case 'position':
                case 'spacer':
                    if (\GANTRY_DEBUGGER) {
                        Debugger::startTimer($item->id, "Rendering {$item->id}");
                    }

                    $item->content = $this->renderContent($item, ['prepare_layout' => true]);
                    // Note that content can also be null (postpone rendering).
                    if ($item->content === '') {
                        unset($items[$i]);
                    }

                    if (\GANTRY_DEBUGGER) {
                        Debugger::stopTimer($item->id);
                    }

                    break;

                default:
                    if ($sticky) {
                        $item->attributes->sticky = 1;
                        break;
                    }

                    if (empty($item->children)) {
                        unset($items[$i]);
                        break;
                    }

                    $dynamicSize = 0;
                    $fixedSize = 0;
                    $childrenCount = count($item->children);
                    foreach ($item->children as $child) {
                        if (!isset($child->attributes->size)) {
                            $child->attributes->size = 100 / count($item->children);
                        }
                        if (empty($child->attributes->fixed)) {
                            $dynamicSize += $child->attributes->size;
                        } else {
                            $fixedSize += $child->attributes->size;
                        }
                    }

                    $roundSize = round($dynamicSize, 1);
                    $equalized = isset($this->equalized[$childrenCount]) ? $this->equalized[$childrenCount] : 0;

                    // force-casting string for testing comparison due to weird PHP behavior that returns wrong result
                    if ($roundSize !== 100.0 && (string) $roundSize !== (string) ($equalized * $childrenCount)) {
                        $fraction = 0;
                        $multiplier = (100 - $fixedSize) / ($dynamicSize ?: 1);
                        foreach ($item->children as $child) {
                            if (!empty($child->attributes->fixed)) {
                                continue;
                            }

                            // Calculate size for the next item by taking account the rounding error from the last item.
                            // This will allow us to approximate cumulating error and fix it when rounding error grows
                            // over the rounding treshold.
                            $size = ($child->attributes->size * $multiplier) + $fraction;
                            $newSize = round($size);
                            $fraction = $size - $newSize;
                            $child->attributes->size = $newSize;
                        }
                    }
            }
        }
    }

    /**
     * Renders individual content block, like particle or position.
     *
     * Function is used to pre-render content.
     *
     * @param object|array $item
     * @param array $options
     * @return string|null
     */
    public function renderContent($item, $options = [])
    {
        $gantry = static::gantry();

        $content = $this->getContent($item, $options);

        /** @var Document $document */
        $document = $gantry['document'];
        $document->addBlock($content);

        $html = $content->toString();

        return false === strpos($html, '@@DEFERRED@@') ? $html : null;
    }

    /**
     * Renders individual content block, like particle or position.
     *
     * Function is used to pre-render content.
     *
     * @param object|array $item
     * @param array $options
     * @return ContentBlock|ContentBlockInterface
     * @since 5.4.3
     */
    public function getContent($item, $options = [])
    {
        if (is_array($item)) {
            $item = (object) $item;
        }

        $gantry = static::gantry();

        /** @var Config $global */
        $global = $gantry['global'];

        /** @var Config $config */
        $config = $gantry['config'];

        $production = (bool) $global->get('production');
        $subtype = $item->subtype;
        $enabled = $config->get("particles.{$subtype}.enabled", 1);

        if (!$enabled) {
            return new HtmlBlock;
        }

        $attributes = isset($item->attributes) ? $item->attributes : [];
        $particle = $config->getJoined("particles.{$subtype}", $attributes);

        $cached = false;
        $cacheKey = [];

        // Enable particle caching only in production mode.
        if ($production && isset($particle['caching'])) {
            $caching = $particle['caching'] + ['type' => 'dynamic'];

            switch ($caching['type']) {
                case 'static':
                    $cached = true;
                    break;
                case 'config_matches':
                    if (isset($particle['caching']['values'])) {
                        $values = (array) $particle['caching']['values'];
                        $compare = array_intersect_key($particle, $values);
                        $cached = ($values === $compare);
                    }
                    break;
                case 'menu':
                    /** @var Menu $menu */
                    $menu = $gantry['menu'];
                    $cacheId = $menu->getCacheId();

                    // FIXME: menu caching needs to handle dynamic modules inside menu: turning it off for now.
                    if (false && $cacheId !== null) {
                        $cached = true;
                        $cacheKey['menu_cache_key'] = $cacheId;
                    }
                    break;
            }
        }

        if ($cached) {
            $cacheKey['language'] = $gantry['page']->language;
            $cacheKey['attributes'] = $particle;
            $cacheKey += (array) $item;

            /** @var UniformResourceLocator $locator */
            $locator = $gantry['locator'];
            $key = md5(json_encode($cacheKey));

            $filename = $locator->findResource("gantry-cache://theme/html/{$key}.php", true, true);
            $file = PhpFile::instance($filename);
            if ($file->exists()) {
                try {
                    return ContentBlock::fromArray((array) $file->content());
                } catch (\Exception $e) {
                    // Invalid cache, continue to rendering.
                    if (\GANTRY_DEBUGGER) {
                        Debugger::addMessage(sprintf('Failed to load %s %s cache', $item->type, $item->id), 'debug');
                    }
                }
            }
        }

        // Create new document context for assets.
        $context = $this->getContext(['segment' => $item, 'enabled' => 1, 'particle' => $particle] + $options);

        /** @var Document $document */
        $document = $gantry['document'];
        $document::push();
        $html = trim($this->render("@nucleus/content/{$item->type}.html.twig", $context));
        $content = $document::pop()->setContent($html);

        if (isset($file)) {
            // Save HTML and assets into the cache.
            if (\GANTRY_DEBUGGER) {
                Debugger::addMessage(sprintf('Caching %s %s', $item->type, $item->id), 'debug');
            }

            $file->save($content->toArray());
        }

        return $content;
    }
}

Filemanager

Name Type Size Permission Actions
AbstractTheme.php File 7.52 KB 0664
ThemeDetails.php File 6.12 KB 0664
ThemeInstaller.php File 10.07 KB 0664
ThemeInterface.php File 3.77 KB 0664
ThemeTrait.php File 24.32 KB 0664
Filemanager