Spade

Mini Shell

Directory:~$ /home/lmsyaran/public_html/joomla4/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/public_html/joomla4/Admin.zip

PK��[���Controller/Html/About.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Admin\ThemeList;
use Gantry\Component\Admin\HtmlController;

class About extends HtmlController
{
    public function index()
    {
        // TODO: Find better way:
        $this->params['info'] = (new
ThemeList)->getTheme($this->container['theme.name']);

        return
$this->render('@gantry-admin/pages/about/about.html.twig',
$this->params);
    }
}
PK��[$�_EYYController/Html/Cache.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Response\JsonResponse;
use Gantry\Component\Filesystem\Folder;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Cache extends HtmlController
{
    public function index()
    {
        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];

        Folder::delete($locator('gantry-cache://theme'), false);
        Folder::delete($locator('gantry-cache://admin'), false);

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

        return new JsonResponse(['html' => 'Cache was
successfully cleared', 'title' => 'Cache
Cleared']);
    }
}
PK��[��x�		.Controller/Html/Configurations/Assignments.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html\Configurations;

use Gantry\Component\Admin\HtmlController;
use Gantry\Framework\Assignments as AssignmentsObject;
use RocketTheme\Toolbox\Event\Event;

class Assignments extends HtmlController
{
    public function index()
    {
        $outline = $this->params['outline'];

        if ($this->hasAssignments($outline)) {
            $assignments = new AssignmentsObject($outline);

            $this->params['assignments'] =
$assignments->get();
            $this->params['options'] =
$assignments->assignmentOptions();
            $this->params['assignment'] =
$assignments->getAssignment();
        }

        return
$this->render('@gantry-admin/pages/configurations/assignments/assignments.html.twig',
$this->params);
    }

    public function store()
    {
        // Authorization.
        if (!$this->authorize('outline.assign')) {
            $this->forbidden();
        }

        $outline = $this->params['outline'];
        if (!$this->hasAssignments($outline)) {
            $this->undefined();
        }

        if (!$this->request->post->get('_end')) {
            throw new \OverflowException("Incomplete data received.
Please increase the value of 'max_input_vars' variable (in
php.ini or .htaccess)", 400);
        }

        // Save assignments.
        $assignments = new AssignmentsObject($outline);
       
$assignments->save($this->request->post->getArray('assignments'));

        // Fire save event.
        $event = new Event;
        $event->gantry = $this->container;
        $event->theme = $this->container['theme'];
        $event->controller = $this;
        $event->assignments = $assignments;
       
$this->container->fireEvent('admin.assignments.save',
$event);

        return '';
    }

    protected function hasAssignments($outline)
    {
        // Default outline and system outlines cannot have assignments.
        return $outline !== 'default' && $outline[0] !==
'_';
    }
}
PK��[�}mFmF)Controller/Html/Configurations/Layout.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html\Configurations;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Config\BlueprintSchema;
use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Config\Config;
use Gantry\Component\File\CompiledYamlFile;
use Gantry\Component\Layout\Layout as LayoutObject;
use Gantry\Component\Response\JsonResponse;
use Gantry\Framework\Outlines;
use RocketTheme\Toolbox\Event\Event;

class Layout extends HtmlController
{
    protected $httpVerbs = [
        'GET'    => [
            '/'         => 'index',
            '/create'   => 'create',
            '/create/*' => 'create',
            '/*'        => 'undefined',
            '/switch'   => 'listSwitches',
            '/switch/*' => 'switchLayout',
            '/preset'   => 'undefined',
            '/preset/*' => 'preset'
        ],
        'POST'   => [
            '/'                     => 'save',
            '/*'                    => 'undefined',
            '/*/*'                  => 'particle',
            '/switch'               => 'undefined',
            '/switch/*'             =>
'switchLayout',
            '/preset'               => 'undefined',
            '/preset/*'             => 'preset',
            '/particles'            => 'undefined',
            '/particles/*'          => 'undefined',
            '/particles/*/validate' => 'validate'
        ],
        'PUT'    => [
            '/*' => 'replace'
        ],
        'PATCH'  => [
            '/*' => 'update'
        ],
        'DELETE' => [
            '/*' => 'destroy'
        ]
    ];

    public function create($id = null)
    {
        if (!$id) {
            // TODO: we might want to display list of options here
            throw new \RuntimeException('Not Implemented', 404);
        }

        $layout = $this->getLayout("presets/{$id}");
        if (!$layout) {
            throw new \RuntimeException('Preset not found', 404);
        }
        $this->params['page_id'] = $id;
        $this->params['layout'] =
$layout->prepareWidths()->toArray();

        return
$this->render('@gantry-admin/pages/configurations/layouts/create.html.twig',
$this->params);
    }

    public function index()
    {
        $outline = $this->params['outline'];
        $layout = $this->getLayout($outline);
        if (!$layout) {
            throw new \RuntimeException('Layout not found', 404);
        }

        $groups = [
            'Positions' => ['position' => [],
'spacer' => [], 'system' => []],
            'Particles' => ['particle' => []]
        ];

        $particles = [
            'position'    => [],
            'spacer'      => [],
            'system' => [],
            'particle' => []
        ];

        $particles = array_replace($particles, $this->getParticles());
        foreach ($particles as &$group) {
            asort($group);
        }
        unset($group);

        foreach ($groups as $section => $children) {
            foreach ($children as $key => $child) {
                $groups[$section][$key] = $particles[$key];
            }
        }

        $this->params['page_id'] = $outline;
        $this->params['layout'] =
$layout->prepareWidths()->toArray();
        $this->params['preset'] = $layout->preset;
        $this->params['preset_title'] =
ucwords(trim(str_replace('_', ' ',
$layout->preset['name'])));
        $this->params['id'] =
ucwords(str_replace('_', ' ', ltrim($outline,
'_')));
        $this->params['particles'] = $groups;
        $this->params['switcher_url'] =
str_replace('.', '/',
"configurations.{$outline}.layout.switch");

        return
$this->render('@gantry-admin/pages/configurations/layouts/edit.html.twig',
$this->params);
    }

    public function save()
    {
        $layout = $this->request->post->get('layout');
        $layout = json_decode($layout);

        if (!isset($layout)) {
            throw new \RuntimeException('Error while saving layout:
Structure missing', 400);
        }

        $outline = $this->params['outline'];
        $preset =
$this->request->post->getJsonArray('preset');

        // Create layout from the data.
        $layout = new LayoutObject($outline, $layout, $preset);
        $layout->init(false, false);

        /** @var Outlines $outlines */
        $outlines = $this->container['outlines'];

        // Update layouts from all inheriting outlines.
        $elements = $layout->sections() + $layout->particles(false);
        foreach ($outlines->getInheritingOutlines($outline) as
$inheritedId => $inheritedName) {
           
LayoutObject::instance($inheritedId)->updateInheritance($outline,
$outline, $elements)->save()->saveIndex();
        }

        // Save layout and its index.
        $layout->save()->saveIndex();

        // Fire save event.
        $event = new Event;
        $event->gantry = $this->container;
        $event->theme = $this->container['theme'];
        $event->controller = $this;
        $event->layout = $layout;
        $this->container->fireEvent('admin.layout.save',
$event);
    }

    public function particle($type, $id)
    {
        if ($type === 'atom') { return ''; }

        $outline = $this->params['outline'];
        $layout = $this->getLayout($outline);
        if (!$layout) {
            throw new \RuntimeException('Layout not found', 404);
        }

        $item = $layout->find($id);
        $item->type    = $this->request->post['type'] ?:
$type;
        $item->subtype = $this->request->post['subtype']
?: $type;
        $item->title   = $this->request->post['title']
?: ucfirst($type);
        $parent   = $this->request->post['parent'] ?:
$layout->getParentId($id);
        if (!isset($item->attributes)) {
            $item->attributes = new \stdClass;
        }
        if (!isset($item->inherit)) {
            $item->inherit = new \stdClass;
        }

        $block =
$this->request->post->getArray('block');
        if (!empty($block)) {
            $item->block = (object) $block;
        }

        $attributes =
$this->request->post->getArray('options');
        $inherit =
$this->request->post->getArray('inherit');

        $particle = !$layout->isLayoutType($type);
        if (!$particle) {
            $name = $type;
            $section = ($type === 'section');
            $hasBlock = $section && !empty($block);
            $prefix = "particles.{$type}";
            $defaults = [];
            $attributes += (array) $item->attributes;
            $blueprints =
BlueprintForm::instance("layout/{$type}.yaml",
'gantry-admin://blueprints');

        } else {
            $name = $item->subtype;
            $hasBlock = true;
            $prefix = "particles.{$name}";
            $defaults = (array)
$this->container['config']->get($prefix);

            $blueprints =
$this->container['particles']->getBlueprintForm($name);
            $blueprints->set('form/fields/_inherit',
['type' => 'gantry.inherit']);
        }

        if ($hasBlock) {
            $blockBlueprints =
BlueprintForm::instance('layout/block.yaml',
'gantry-admin://blueprints');
        } else {
            $blockBlueprints = null;
        }

        $file =
"gantry-admin://blueprints/layout/inheritance/{$type}.yaml";
        if (file_exists($file)) {
            $inheritType = $particle ? 'particle' :
'section';

            /** @var Outlines $outlines */
            $outlines = $this->container['outlines'];

            if ($outline !== 'default') {
                if ($particle) {
                    $list =
$outlines->getOutlinesWithParticle($item->subtype, false);
                } else {
                    $list =
$outlines->getOutlinesWithSection($item->id, false);
                }
                unset($list[$outline]);
            } else {
                $list = [];
            }

            if (!empty($inherit['outline']) || (!($inheriting =
$outlines->getInheritingOutlines($outline, [$id, $parent])) &&
$list)) {
                $inheritable = true;
                $inheritance = BlueprintForm::instance($file,
'gantry-admin://blueprints');

               
$inheritance->set('form/fields/outline/filter',
array_keys($list));
                if (!$hasBlock) {
                   
$inheritance->undef('form/fields/include/options/block');
                }

                if ($particle) {
                   
$inheritance->set('form/fields/particle/particle', $name);
                }

            } elseif (!empty($inheriting)) {
                // Already inherited by other outlines.
                $inheritance =
BlueprintForm::instance('layout/inheritance/messages/inherited.yaml',
'gantry-admin://blueprints');
                $inheritance->set(
                    'form/fields/_note/content',
                   
sprintf($inheritance->get('form/fields/_note/content'),
$inheritType, ' <ul><li>' . implode('</li>
<li>', $inheriting) . '</li></ul>')
                );

            } elseif ($outline === 'default') {
                // Base outline.
                $inheritance =
BlueprintForm::instance('layout/inheritance/messages/default.yaml',
'gantry-admin://blueprints');

            } else {
                // Nothing to inherit from.
                $inheritance =
BlueprintForm::instance('layout/inheritance/messages/empty.yaml',
'gantry-admin://blueprints');
            }
        }

        $item->attributes = (object) $attributes;
        $item->inherit = (object) $inherit;

        $this->params['id'] = $name;
        $this->params += [
            'extra'         => $blockBlueprints,
            'inherit'       =>
!empty($inherit['outline']) ? $inherit['outline'] :
null,
            'inheritance'   => isset($inheritance) ?
$inheritance : null,
            'inheritable'   => !empty($inheritable),
            'item'          => $item,
            'data'          => ['particles' =>
[$name => $item->attributes]],
            'defaults'      => ['particles' =>
[$name => $defaults]],
            'prefix'        => "particles.{$name}.",
            'particle'      => $blueprints,
            'parent'        => 'settings',
            'route'         =>
"configurations.{$outline}.settings",
            'action'        => str_replace('.',
'/', 'configurations.' . $outline .
'.layout.' . $prefix . '.validate'),
            'skip'          => ['enabled'],
            'editable'      => $particle,
            'overrideable'  => $particle,
        ];

        if ($particle) {
            $result =
$this->render('@gantry-admin/pages/configurations/layouts/particle.html.twig',
$this->params);
        } else {
            $typeLayout = $type === 'container' ?
'container' : 'section';
            $result =
$this->render('@gantry-admin/pages/configurations/layouts/' .
$typeLayout . '.html.twig', $this->params);
        }

        return $result;
    }

    public function listSwitches()
    {
        $this->params['presets'] = LayoutObject::presets();
        $result =
$this->render('@gantry-admin/layouts/switcher.html.twig',
$this->params);

        return new JsonResponse(['html' => $result]);
    }

    public function switchLayout($id)
    {
        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        $outline = $this->params['outline'];
        $layout = $this->getLayout($id);
        if (!$layout->toArray()) {
            // Layout hasn't been defined, return default layout
instead.
            $layout = $this->getLayout('default');
        }

        $input =
$this->request->post->getJson('layout');
        $deleted = isset($input) ?
$layout->clearSections()->copySections($input): [];
        if ($outline === 'default') {
            $layout->inheritNothing();
        } elseif (!$input &&
$this->request->post['inherit'] === '1') {
            $layout->inheritAll();
        }

        $message = $deleted
            ?
$this->render('@gantry-admin/ajax/particles-loss.html.twig',
['particles' => $deleted])
            : null;

        return new JsonResponse([
            'title' => ucwords(trim(str_replace('_',
' ', $layout->preset['name']))),
            'preset' => json_encode($layout->preset),
            'data' =>
$layout->prepareWidths()->toJson(),
            'deleted' => $deleted,
            'message' => $message
        ]);
    }

    public function preset($id)
    {
        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        $preset = LayoutObject::preset($id);
        if (!$preset) {
            throw new \RuntimeException('Preset not found', 404);
        }

        $layout = new LayoutObject($id, $preset);

        $input =
$this->request->post->getJson('layout');
        $deleted = isset($input) ?
$layout->clearSections()->copySections($input): [];
        $message = $deleted
            ?
$this->render('@gantry-admin/ajax/particles-loss.html.twig',
['particles' => $deleted])
            : null;

        return new JsonResponse([
            'title' => ucwords(trim(str_replace('_',
' ', $id))),
            'preset' => json_encode($layout->preset),
            'data' =>
$layout->prepareWidths()->toJson(),
            'deleted' => $deleted,
            'message' => $message
        ]);
    }

    public function validate($particle)
    {
        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        // Load particle blueprints and default settings.
        $validator = new BlueprintSchema;

        $name = $particle;
        if (in_array($particle, ['wrapper', 'section',
'container', 'grid', 'offcanvas'], true)) {
            $type = $particle;
            $particle = null;
            $file =
CompiledYamlFile::instance("gantry-admin://blueprints/layout/{$type}.yaml");
            $validator->embed('options',
(array)$file->content());
            $file->free();
        } else {
            $type = in_array($particle, ['spacer',
'system', 'position'], true) ? $particle : 
'particle';
            $validator->embed('options',
$this->container['particles']->get($particle));
        }

        // Create configuration from the defaults.
        $data = new Config(
            [
                'type'    => $type,
            ],
            function () use ($validator) {
                return $validator;
            }
        );

        // Join POST data.
        $data->join('options',
$this->request->post->getArray("particles." . $name));
        if ($particle) {
            $data->set('options.enabled', (int)
$data->get('options.enabled', 1));
        }

        if ($particle) {
            if ($type !== $particle) {
                $data->set('subtype', $particle);
            }

            $data->join('title',
$this->request->post['title'] ?: ucfirst($particle));
        }

        $block =
$this->request->post->getArray('block');
        if ($block) {
            // TODO: remove empty items in some other way:
            foreach ($block as $key => $param) {
                if ($param === '') {
                    unset($block[$key]);
                    continue;
                }
                if ($key === 'size') {
                    $param = round($param, 4);
                    if ($param < 5) {
                        $param = 5;
                    } elseif ($param > 100) {
                        $param = 100;
                    }
                    $block[$key] = $param;
                }
            }

            $data->join('block', $block);
        }

        $inherit =
$this->request->post->getArray('inherit');
        $clone = !empty($inherit['mode']) &&
$inherit['mode'] === 'clone';
        $inherit['include'] =
!empty($inherit['include']) ? explode(',',
$inherit['include']) : [];
        if (!$clone && !empty($inherit['outline'])
&& count($inherit['include'])) {
            // Clean up inherit and add it to the data.
            if (!$block) {
                $inherit['include'] =
array_values(array_diff($inherit['include'],
['block']));
            }

            unset($inherit['mode']);
            $data->join('inherit', $inherit);
        }

        // Optionally send children of the object.
        if (in_array('children', $inherit['include'],
true)) {
            $layout = LayoutObject::instance($inherit['outline']
?: $this->params['outline']);
            if ($clone) {
                $item = $layout->find($inherit['section']);
            } else {
                $item =
$layout->inheritAll()->find($inherit['section']);
            }
            $data->join('children', !empty($item->children)
? $item->children : []);
        }

        // TODO: validate

        return new JsonResponse(['data' =>
$data->toArray()]);
    }

    /**
     * @param string $name
     * @return LayoutObject
     */
    protected function getLayout($name)
    {
        return LayoutObject::instance($name);
    }

    protected function getParticles($onlyEnabled = false)
    {
        /** @var Config $config */
        $config = $this->container['config'];

        $particles = $this->container['particles']->all();

        $list = [];
        foreach ($particles as $name => $particle) {
            $type = isset($particle['type']) ?
$particle['type'] : 'particle';
            $particleName = isset($particle['name']) ?
$particle['name'] : $name;
            $particleIcon = isset($particle['icon']) ?
$particle['icon'] : null;

            if (!$onlyEnabled ||
$config->get("particles.{$name}.enabled", true)) {
                $list[$type][$name] = ['name' =>
$particleName, 'icon' => $particleIcon];
            }
        }

        return $list;
    }
}
PK��['��L-L-'Controller/Html/Configurations/Page.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html\Configurations;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Config\BlueprintSchema;
use Gantry\Component\Config\Config;
use Gantry\Component\Layout\Layout;
use Gantry\Component\Response\JsonResponse;
use Gantry\Framework\Atoms;
use Gantry\Framework\Services\ConfigServiceProvider;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\File\YamlFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Page extends HtmlController
{
    protected $httpVerbs = [
        'GET'    => [
            '/' => 'index'
        ],
        'POST'   => [
            '/'                 => 'save',
            '/*'                => 'save',
            '/*/**'             => 'formfield',
            '/atoms'            => 'undefined',
            '/atoms/*'          => 'atom',
            '/atoms/*/validate' => 'atomValidate'
        ],
        'PUT'    => [
            '/' => 'save'
        ],
        'PATCH'  => [
            '/' => 'save'
        ],
        'DELETE' => [
            '/' => 'forbidden'
        ]
    ];

    public function index()
    {
        $outline = $this->params['outline'];

        if ($outline == 'default') {
            $this->params['overrideable'] = false;
            $data = $this->container['config'];
        } else {
            $this->params['overrideable'] = true;
            $this->params['defaults'] = $defaults =
$this->container['defaults'];
            $data = ConfigServiceProvider::load($this->container,
$outline, false, false);
        }

        $deprecated = $this->getDeprecatedAtoms();
        if ($deprecated) {
            $data->set('page.head.atoms', $deprecated);
        }

        if (isset($defaults)) {
            $currentAtoms = $data->get('page.head.atoms');
            if (!$currentAtoms) {
                // Make atoms to appear to be inherited in they are loaded
from defaults.
                $defaultAtoms = (array)
$defaults->get('page.head.atoms');
                $atoms = (new
Atoms($defaultAtoms))->inheritAll('default')->toArray();
                $defaults->set('page.head.atoms', $atoms);
            }
        }

        $this->params += [
            'data' => $data,
            'page' =>
$this->container['page']->group(),
            'route'  => "configurations.{$outline}",
            'page_id' => $outline,
            'atoms' => $this->getAtoms(),
            'atoms_deprecated' => $deprecated
        ];

        return
$this->render('@gantry-admin/pages/configurations/page/page.html.twig',
$this->params);
    }

    public function save($id = null)
    {
        $data = $id ? [$id => $this->request->post->getArray()]
: $this->request->post->getArray('page');

        foreach ($data as $name => $values) {
            $this->saveItem($name, $values);
        }

        // Fire save event.
        $event             = new Event;
        $event->gantry     = $this->container;
        $event->theme      = $this->container['theme'];
        $event->controller = $this;
        $event->data       = $data;
        $this->container->fireEvent('admin.page.save',
$event);

        return $id ? $this->display($id) : $this->index();
    }

    public function formfield($id)
    {
        $path = func_get_args();

        $end = end($path);
        if ($end === '') {
            array_pop($path);
        }
        if (end($path) == 'validate') {
            return call_user_func_array([$this, 'validate'],
$path);
        }

        // Load blueprints.
        $blueprints =
$this->container['page']->getBlueprintForm($id);

        list($fields, $path, $value) =
$blueprints->resolve(array_slice($path, 1), '/');

        if (!$fields) {
            throw new \RuntimeException('Page Not Found', 404);
        }

        $data =
$this->request->post->getJsonArray('data');

        $offset = "page.{$id}." . implode('.', $path);
        if ($value !== null) {
            $parent = $fields;
            $fields = ['fields' =>
$fields['fields']];
            $offset .= '.' . $value;
            $data = $data ?:
$this->container['config']->get($offset);
            $data = ['data' => $data];
            $scope = 'data.';
        } else {
            $data = $data ?:
$this->container['config']->get($offset);
            $scope = 'data';
        }

        $fields['is_current'] = true;

        array_pop($path);

        $outline = $this->params['outline'];
        $configuration = "configurations/{$outline}";
        $this->params = [
                'configuration' => $configuration,
                'blueprints' => $fields,
                'data' => $data,
                'prefix' => '',
                'scope' => $scope,
                'parent' => $path
                    ? "$configuration/settings/particles/{$id}/"
. implode('/', $path)
                    : "$configuration/settings/particles/{$id}",
                'route' =>
"configurations.{$outline}.{$offset}",
            ] + $this->params;

        if (isset($parent['key'])) {
            $this->params['key'] = $parent['key'];
        }
        if (isset($parent['value'])) {
            $this->params['title'] =
$parent['value'];
        }

        return
$this->render('@gantry-admin/pages/configurations/settings/field.html.twig',
$this->params);
    }

    public function validate($particle)
    {
        $path = implode('.', array_slice(func_get_args(), 1,
-1));

        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        // Load particle blueprints.
        $validator =
$this->container['particles']->get($particle);

        // Create configuration from the defaults.
        $data = new Config(
            [],
            function () use ($validator) {
                return $validator;
            }
        );

        $data->join($path,
$this->request->post->getArray('data'));

        // TODO: validate

        return new JsonResponse(['data' =>
$data->get($path)]);
    }

    public function atom($name)
    {
        $outline = $this->params['outline'];
        $atoms = Atoms::instance($outline);

        $data = $this->request->post['data'];
        if ($data) {
            $data = json_decode($data, true);
        } else {
            $data = $this->request->post->getArray();
        }

        // Create atom and get its blueprint.
        $item = $atoms->createAtom($name, $data);
        $blueprint = $item->blueprint();

        // Load inheritance blueprint.
        $inheritance = $atoms->getInheritanceBlueprint($name,
$item->id);
        $inheritable = $inheritance &&
$inheritance->get('form/fields/outline/filter', []);

        $this->params += [
            'inherit'       =>
!empty($inherit['outline']) ? $inherit['outline'] :
null,
            'inheritance'   => $inheritance,
            'inheritable'   => $inheritable,
            'item'          => $item,
            'data'          => ['particles' =>
[$name => $item->attributes]],
            'blueprints'    => $blueprint,
            'parent'        => 'settings',
            'prefix'        => "particles.{$name}.",
            'route'         =>
"configurations.default.settings",
            'action'        =>
"configurations/{$outline}/page/atoms/{$name}/validate",
            'skip'          => ['enabled']
        ];

        return new JsonResponse(['html' =>
$this->render('@gantry-admin/modals/atom.html.twig',
$this->params)]);
    }

    /**
     * Validate data for the atom.
     *
     * @param string $name
     * @return JsonResponse
     */
    public function atomValidate($name)
    {
        // Load particle blueprints and default settings.
        $validator = new BlueprintSchema;
        $validator->embed('options',
$this->container['particles']->get($name));

        $blueprints =
$this->container['particles']->getBlueprintForm($name);

        // Create configuration from the defaults.
        $data = new Config([],
            function () use ($validator) {
                return $validator;
            }
        );

        $data->set('id',
$this->request->post['id']);
        $data->set('type', $name);
        $data->set('title',
$this->request->post['title'] ?:
$blueprints->get('name'));
        $data->set('attributes',
$this->request->post->getArray("particles.{$name}"));
        $data->def('attributes.enabled', 1);

        $block =
$this->request->post->getArray('block');
        foreach ($block as $key => $param) {
            if ($param === '') {
                unset($block[$key]);
            }
        }

        $inherit =
$this->request->post->getArray('inherit');
        $clone = !empty($inherit['mode']) &&
$inherit['mode'] === 'clone';
        $inherit['include'] =
!empty($inherit['include']) ? explode(',',
$inherit['include']) : [];
        if (!$clone && !empty($inherit['outline'])
&& count($inherit['include'])) {
            unset($inherit['mode']);
            $data->join('inherit', $inherit);
        }

        // TODO: validate

        // Fill parameters to be passed to the template file.
        $this->params['item'] = (object) $data->toArray();

        return new JsonResponse(['item' =>
$data->toArray()]);
    }

    protected function saveItem($id, $data)
    {
        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];

        // Save layout into custom directory for the current theme.
        $outline = $this->params['outline'];

        // Move atoms out of layout.
        if ($id === 'head') {
            $layout = Layout::instance($outline);
            if (is_array($layout->atoms())) {
                $layout->save(false);
            }
            if (isset($data['atoms'])) {
                $atoms = new Atoms($data['atoms']);
                $data['atoms'] =
$atoms->update()->toArray();
            }
        }

        $save_dir      =
$locator->findResource("gantry-config://{$outline}/page",
true, true);
        $filename      = "{$save_dir}/{$id}.yaml";

        $file = YamlFile::instance($filename);
        if (!is_array($data)) {
            if ($file->exists()) {
                $file->delete();
            }
        } else {
            $blueprints =
$this->container['page']->getBlueprintForm($id);
            $config     = new Config($data, function () use ($blueprints) {
return $blueprints; });

            $file->save($config->toArray());
        }
        $file->free();
    }

    protected function getDeprecatedAtoms()
    {
        $id     = $this->params['outline'];
        $layout = Layout::instance($id);

        return $layout->atoms();
    }

    protected function getAtoms($onlyEnabled = false)
    {
        $config = $this->container['config'];

        $atoms = $this->container['particles']->all();

        $list = [];
        foreach ($atoms as $name => $atom) {
            $type     = isset($atom['type']) ?
$atom['type'] : 'atom';
            $atomName = isset($atom['name']) ?
$atom['name'] : $name;

            if (!$onlyEnabled ||
$config->get("particles.{$name}.enabled", true)) {
                $list[$type][$name] = $atomName;
            }
        }

        return $list['atom'];
    }
}
PK��[�Qޙ""+Controller/Html/Configurations/Settings.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html\Configurations;

use Gantry\Admin\Particles;
use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Config\Config;
use Gantry\Component\Response\JsonResponse;
use Gantry\Framework\Services\ConfigServiceProvider;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\File\YamlFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Settings extends HtmlController
{
    protected $httpVerbs = [
        'GET' => [
            '/'                 => 'index',
            '/particles'        => 'undefined',
            '/particles/*'      => 'display',
            '/particles/*/**'   => 'formfield',
        ],
        'POST' => [
            '/'                 => 'save',
            '/particles'        => 'forbidden',
            '/particles/*'      => 'save',
            '/particles/*/**'   => 'formfield'
        ],
        'PUT' => [
            '/'            => 'save',
            '/particles'   => 'forbidden',
            '/particles/*' => 'save'
        ],
        'PATCH' => [
            '/'            => 'save',
            '/particles'   => 'forbidden',
            '/particles/*' => 'save'
        ],
        'DELETE' => [
            '/'            => 'forbidden',
            '/particles'   => 'forbidden',
            '/particles/*' => 'reset'
        ]
    ];

    public function index()
    {
        $outline = $this->params['outline'];

        if ($outline === 'default') {
            $this->params['overrideable'] = false;
            $data = $this->container['config'];
        } else {
            $this->params['overrideable'] = true;
            $this->params['defaults'] =
$this->container['defaults'];
            $data = ConfigServiceProvider::load($this->container,
$outline, false, false);
        }

        /** @var Particles $particles */
        $particles = $this->container['particles'];
        $this->params += [
            'data' => $data,
            'particles' =>
$particles->group(['atom']),
            'route'  =>
"configurations.{$outline}.settings",
            'page_id' => $outline
        ];

        return
$this->render('@gantry-admin/pages/configurations/settings/settings.html.twig',
$this->params);
    }

    public function display($id)
    {
        $outline = $this->params['outline'];

        /** @var Particles $particles */
        $particles = $this->container['particles'];

        $blueprints = $particles->getBlueprintForm($id);
        $prefix = 'particles.' . $id;

        if($outline === 'default') {
            $this->params['overrideable'] = false;
            $data = $this->container['config'];
        } else {
            $this->params['overrideable'] = true;
            $this->params['defaults'] =
$this->container['defaults']->get($prefix);
            $data = ConfigServiceProvider::load($this->container,
$outline, false, false);
        }

        $this->params += [
            'scope' => 'particle.',
            'particle' => $blueprints,
            'data' =>  ['particle' =>
$data->get($prefix)],
            'id' => $id,
            'parent' =>
"configurations/{$outline}/settings",
            'route'  =>
"configurations.{$outline}.settings.{$prefix}",
            'skip' => ['enabled']
            ];

        return
$this->render('@gantry-admin/pages/configurations/settings/item.html.twig',
$this->params);
    }

    public function formfield($id)
    {
        $path = func_get_args();

        $end = end($path);
        if ($end === '') {
            array_pop($path);
        }
        if (end($path) === 'validate') {
            return call_user_func_array([$this, 'validate'],
$path);
        }

        /** @var Particles $particles */
        $particles = $this->container['particles'];

        // Load blueprints.
        $blueprints = $particles->getBlueprintForm($id);

        list($fields, $path, $value) =
$blueprints->resolve(array_slice($path, 1), '/');
        if (!$fields) {
            throw new \RuntimeException('Page Not Found', 404);
        }

        $data =
$this->request->post->getJsonArray('data');

        /** @var Config $config */
        $config = $this->container['config'];

        $offset = "particles.{$id}." . implode('.',
$path);
        if ($value !== null) {
            $parent = $fields;
            $fields = ['fields' =>
$fields['fields']];
            $offset .= '.' . $value;
            $data = $data ?: $config->get($offset);
            $data = ['data' => $data];
            $scope = 'data.';
        } else {
            $data = $data ?: $config->get($offset);
            $scope = 'data';
        }

        $fields['is_current'] = true;

        array_pop($path);

        $outline = $this->params['outline'];
        $configuration = "configurations/{$outline}";
        $this->params = [
                'configuration' => $configuration,
                'blueprints' => $fields,
                'data' => $data,
                'scope' => $scope,
                'parent' => $path
                    ?
"{$configuration}/settings/particles/{$id}/" .
implode('/', $path)
                    :
"{$configuration}/settings/particles/{$id}",
                'route' =>
"configurations.{$outline}.settings.{$offset}",
            ] + $this->params;

        if (isset($parent['key'])) {
            $this->params['key'] = $parent['key'];
        }
        if (isset($parent['value'])) {
            $this->params['title'] =
$parent['value'];
        }

        return
$this->render('@gantry-admin/pages/configurations/settings/field.html.twig',
$this->params);
    }

    public function validate($particle)
    {
        $path = implode('.', array_slice(func_get_args(), 1,
-1));

        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        /** @var Particles $particles */
        $particles = $this->container['particles'];

        // Load particle blueprints.
        $validator = $particles->get($particle);

        // Create configuration from the defaults.
        $data = new Config(
            [],
            function () use ($validator) {
                return $validator;
            }
        );

        $data->join($path,
$this->request->post->getArray('data'));

        // TODO: validate

        return new JsonResponse(['data' =>
$data->get($path)]);
    }

    public function save($id = null)
    {
        if (!$this->request->post->get('_end')) {
            throw new \OverflowException("Incomplete data received.
Please increase the value of 'max_input_vars' variable (in
php.ini or .htaccess)", 400);
        }

        $data = $id ? [$id =>
$this->request->post->getArray('particle')] :
$this->request->post->getArray('particles');

        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];

        // Save layout into custom directory for the current theme.
        $outline = $this->params['outline'];
        $save_dir =
$locator->findResource("gantry-config://{$outline}/particles",
true, true);

        foreach ($data as $name => $values) {
            $this->saveItem($name, $values, $save_dir);
        }
        @rmdir($save_dir);

        // Fire save event.
        $event = new Event;
        $event->gantry = $this->container;
        $event->theme = $this->container['theme'];
        $event->controller = $this;
        $event->data = $data;
        $this->container->fireEvent('admin.settings.save',
$event);

        return $id ? $this->display($id) : $this->index();
    }

    protected function saveItem($id, $data, $save_dir)
    {
        $filename = "{$save_dir}/{$id}.yaml";

        $file = YamlFile::instance($filename);
        if (!is_array($data)) {
            if ($file->exists()) {
                $file->delete();
            }
        } else {
            /** @var Particles $particles */
            $particles = $this->container['particles'];

            $blueprints = $particles->getBlueprintForm($id);
            $config = new Config($data, function() use ($blueprints) {
return $blueprints; });

            $file->save($config->toArray());
        }
        $file->free();
    }

    public function reset($id)
    {
        $this->params += [
            'data' => [],
        ];

        return $this->display($id);
    }
}
PK��[�[T� 
)Controller/Html/Configurations/Styles.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html\Configurations;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Config\Config;
use Gantry\Component\Response\JsonResponse;
use Gantry\Framework\Services\ConfigServiceProvider;
use Gantry\Framework\Theme;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\File\YamlFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Styles extends HtmlController
{

    protected $httpVerbs = [
        'GET' => [
            '/'              => 'index',
            '/blocks'        => 'undefined',
            '/blocks/*'      => 'display',
            '/blocks/*/**'   => 'formfield'
        ],
        'POST' => [
            '/'          => 'save',
            '/blocks'    => 'forbidden',
            '/blocks/*'  => 'save',
            '/compile'   => 'compile'
        ],
        'PUT' => [
            '/'         => 'save',
            '/blocks'   => 'forbidden',
            '/blocks/*' => 'save'
        ],
        'PATCH' => [
            '/'         => 'save',
            '/blocks'   => 'forbidden',
            '/blocks/*' => 'save'
        ],
        'DELETE' => [
            '/'         => 'forbidden',
            '/blocks'   => 'forbidden',
            '/blocks/*' => 'reset'
        ]
    ];

    public function index()
    {
        $outline = $this->params['outline'];

        if($outline == 'default') {
            $this->params['overrideable'] = false;
            $this->params['data'] =
$this->container['config'];
        } else {
            $this->params['overrideable'] = true;
            $this->params['defaults'] =
$this->container['defaults'];
            $this->params['data'] =
ConfigServiceProvider::load($this->container, $outline, false, false);
        }

        $this->params['blocks'] =
$this->container['styles']->group();
        $this->params['route']  =
"configurations.{$outline}.styles";

        return
$this->render('@gantry-admin/pages/configurations/styles/styles.html.twig',
$this->params);
    }

    public function display($id)
    {
        $outline = $this->params['outline'];
        $blueprints =
$this->container['styles']->getBlueprintForm($id);
        $prefix = 'styles.' . $id;

        if($outline == 'default') {
            $this->params['overrideable'] = false;
            $this->params['data'] =
$this->container['config']->get($prefix);
        } else {
            $this->params['overrideable'] = true;
            $this->params['defaults'] =
$this->container['defaults']->get($prefix);
            $this->params['data'] =
ConfigServiceProvider::load($this->container, $outline, false,
false)->get($prefix);
        }

        $this->params += [
            'block' => $blueprints,
            'id' => $id,
            'parent' =>
"configurations/{$outline}/styles",
            'route'  =>
"configurations.{$outline}.styles.{$prefix}",
            'skip' => ['enabled']
        ];

        return
$this->render('@gantry-admin/pages/configurations/styles/item.html.twig',
$this->params);
    }

    public function formfield($id)
    {
        $path = func_get_args();

        $outline = $this->params['outline'];

        // Load blueprints.
        $blueprints =
$this->container['styles']->getBlueprintForm($id);

        list($fields, $path, $value) =
$blueprints->resolve(array_slice($path, 1), '/');

        if (!$fields) {
            throw new \RuntimeException('Page Not Found', 404);
        }

        $fields['is_current'] = true;

        // Get the prefix.
        $prefix = "styles.{$id}." . implode('.',
$path);
        if ($value !== null) {
            $parent = $fields;
            $fields = ['fields' =>
$fields['fields']];
            $prefix .= '.' . $value;
        }
        array_pop($path);

        if($outline == 'default') {
            $this->params['overrideable'] = false;
            $this->params['data'] =
$this->container['config']->get($prefix);
        } else {
            $this->params['overrideable'] = true;
            $this->params['defaults'] =
$this->container['defaults']->get($prefix);
            $this->params['data'] =
ConfigServiceProvider::load($this->container, $outline, false,
false)->get($prefix);
        }

        $this->params = [
                'blueprints' => $fields,
                'parent' => $path
                    ?
"configurations/{$outline}/styles/blocks/{$id}/" .
implode('/', $path)
                    :
"configurations/{$outline}/styles/blocks/{$id}",
                'route' => 'styles.' . $prefix
            ] + $this->params;

        if (isset($parent['key'])) {
            $this->params['key'] = $parent['key'];
        }

        return
$this->render('@gantry-admin/pages/configurations/styles/field.html.twig',
$this->params);
    }

    public function reset($id)
    {
        $this->params += [
            'data' => [],
        ];

        return $this->display($id);
    }


    public function compile()
    {
        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        $warnings = $this->compileSettings();

        if ($warnings) {
            $this->params += ['warnings' => $warnings];
            return new JsonResponse(
                [
                    'html'    =>
$this->render('@gantry-admin/layouts/css-warnings.html.twig',
$this->params),
                    'warning' => true,
                    'title'   => 'CSS Compiled With
Warnings',
                ]
            );
        } else {
            return new JsonResponse(['html' => 'The CSS
was successfully compiled', 'title' => 'CSS
Compiled']);
        }
    }

    public function save($id = null)
    {
        /** @var Config $config */
        $config = $this->container['config'];

        if ($id) {
            $data = (array) $config->get('styles');
            $data[$id] = $this->request->post->getArray();
        } else {
            $data =
$this->request->post->getArray('styles');
        }

        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];

        // Save layout into custom directory for the current theme.
        $outline = $this->params['outline'];
        $save_dir =
$locator->findResource("gantry-config://{$outline}", true,
true);
        $filename = "{$save_dir}/styles.yaml";

        $file = YamlFile::instance($filename);
        $file->save($data);
        $file->free();

        // Fire save event.
        $event = new Event;
        $event->gantry = $this->container;
        $event->theme = $this->container['theme'];
        $event->controller = $this;
        $event->data = $data;
        $this->container->fireEvent('admin.styles.save',
$event);

        // Compile CSS.
        $warnings = $this->compileSettings();

        if (empty($this->params['ajax'])) {
            // FIXME: HTML request: Output compiler warnings!!
            return $id ? $this->display($id) : $this->index();
        }

        if ($warnings) {
            $this->params += ['warnings' => $warnings];
            return new JsonResponse(
                [
                    'html'    =>
$this->render('@gantry-admin/layouts/css-warnings.html.twig',
$this->params),
                    'warning' => true,
                    'title'   => 'CSS Compiled With
Warnings',
                ]
            );
        } else {
            return new JsonResponse(['html' => 'The CSS
was successfully compiled', 'title' => 'CSS
Compiled']);
        }
    }

    /**
     * @returns array
     */
    protected function compileSettings()
    {
        /** @var Theme $theme */
        $theme = $this->container['theme'];
        $outline = $this->params['outline'];

        return $theme->updateCss($outline !== 'default' ?
[$outline => ucfirst($outline)] : null);
    }
}
PK��[���7VV"Controller/Html/Configurations.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Response\HtmlResponse;
use Gantry\Component\Response\JsonResponse;
use Gantry\Component\Response\RedirectResponse;
use Gantry\Component\Response\Response;
use Gantry\Component\Layout\Layout as LayoutObject;
use Gantry\Framework\Outlines as OutlinesObject;

class Configurations extends HtmlController
{
    protected $httpVerbs = [
        'GET' => [
            '/'                 => 'index',
            '/*'                => 'forward',
            '/*/delete'         =>
'confirmDeletion',
            '/*/**'             => 'forward',
        ],
        'POST' => [
            '/'                 => 'undefined',
            '/*'                => 'undefined',
            '/create'           => 'createForm',
            '/create/new'       => 'create',
            '/*/rename'         => 'rename',
            '/*/duplicate'      => 'duplicateForm',
            '/*/duplicate/new'  => 'duplicate',
            '/*/delete'         => 'undefined',
            '/*/delete/confirm' => 'delete',
            '/*/**'             => 'forward',
        ],
        'PUT'    => [
            '/'   => 'undefined',
            '/**' => 'forward'
        ],
        'PATCH'  => [
            '/'   => 'undefined',
            '/**' => 'forward'
        ]
    ];

    public function index()
    {
        return
$this->render('@gantry-admin/pages/configurations/configurations.html.twig',
$this->params);
    }

    public function createForm()
    {
        if (!$this->authorize('outline.create')) {
            $this->forbidden();
        }

        $params = [
            'presets' => LayoutObject::presets(),
            'outlines' =>
$this->container['outlines']
        ];

        $response = ['html' =>
$this->render('@gantry-admin/ajax/outline-new.html.twig',
$params)];

        return new JsonResponse($response);
    }

    public function create()
    {
        // Check if we want to duplicate outline instead.
        if ($this->request->post['from'] ===
'outline') {
            return
$this->duplicate($this->request->post['outline']);
        }

        if (!$this->authorize('outline.create')) {
            $this->forbidden();
        }

        /** @var OutlinesObject $outlines */
        $outlines = $this->container['outlines'];
        $title = $this->request->post['title'];
        $preset = $this->request->post['preset'];

        $id = $outlines->create(null, $title, $preset);

        $html =
$this->render('@gantry-admin/layouts/outline.html.twig',
['name' => $id, 'title' => $outlines[$id]]);

        return new JsonResponse(['html' => 'Outline
created.', 'id' => "outline-{$id}",
'outline' => $html]);
    }

    public function rename($outline)
    {
        if (!$this->authorize('outline.rename')) {
            $this->forbidden();
        }

        /** @var OutlinesObject $outlines */
        $outlines = $this->container['outlines'];
        $title = $this->request->post['title'];

        $id = $outlines->rename($outline, $title);

        $html =
$this->render('@gantry-admin/layouts/outline.html.twig',
['name' => $id, 'title' => $outlines[$id]]);

        return new JsonResponse(['html' => 'Outline
renamed.', 'id' => "outline-{$outline}",
'outline' => $html]);
    }

    public function duplicateForm($outline)
    {
        if (!$this->authorize('outline.create')) {
            $this->forbidden();
        }

        $params = [
            'outlines' =>
$this->container['outlines'],
            'outline' => $outline,
            'duplicate' => true
        ];

        $response = ['html' =>
$this->render('@gantry-admin/ajax/outline-new.html.twig',
$params)];

        return new JsonResponse($response);
    }

    public function duplicate($outline)
    {
        if (!$this->authorize('outline.create')) {
            $this->forbidden();
        }

        /** @var OutlinesObject $outlines */
        $outlines = $this->container['outlines'];
        $title = $this->request->post['title'];
        $inherit =
in_array($this->request->post['inherit'], ['1',
'true']);

        $id = $outlines->duplicate($outline, $title, $inherit);

        $html =
$this->render('@gantry-admin/layouts/outline.html.twig',
['name' => $id, 'title' => $outlines[$id]]);

        return new JsonResponse(['html' => 'Outline
duplicated.', 'id' => $id, 'outline' =>
$html]);
    }

    public function delete($outline)
    {
        if (!$this->authorize('outline.delete')) {
            $this->forbidden();
        }

        /** @var OutlinesObject $outlines */
        $outlines = $this->container['outlines'];
        $list = $outlines->user();

        if (!isset($list[$outline])) {
            $this->forbidden();
        }

        $outlines->delete($outline);

        return new JsonResponse(['html' => 'Outline
deleted.', 'outline' => $outline]);
    }

    /**
     * @return JsonResponse
     */
    public function confirmDeletion($id)
    {
        /** @var OutlinesObject $outlines */
        $outlines = $this->container['outlines'];

        $params = [
            'id' => $id,
            'page_type' => 'OUTLINE',
            'outline' => $outlines->title($id),
            'inherited' =>
$outlines->getInheritingOutlines($id)
        ];

        $html =
$this->render('@gantry-admin/pages/configurations/confirm-deletion.html.twig',
$params);

        return new JsonResponse(['html' => $html]);
    }

    /**
     * @return HtmlResponse|RedirectResponse|JsonResponse
     */
    public function forward()
    {
        $path = func_get_args();

        $outline = array_shift($path);
        $page = array_shift($path);

        $method = $this->params['method'];

        if ((!isset($outline) || !isset($page)) &&
$this->params['format'] !== 'json') {
            // Redirect path to the styles page of the selected outline.
            return new
RedirectResponse($this->container->route('configurations',
is_string($outline) ? $outline : 'default', 'styles'));
        }

        $outlines = $this->container['outlines'];

        if (!isset($outlines[$outline])) {
            throw new \RuntimeException('Outline not found.',
404);
        }

        $this->container['outline'] = $outline;
        $this->container['configuration'] = $outline;

        $resource = $this->params['location'] . '/'.
$page;

        $this->params['outline'] = $outline;
        $this->params['configuration'] = $outline;
        $this->params['location'] = $resource;
        $this->params['configuration_page'] = $page;
        $this->params['navbar'] =
!empty($this->request->get['navbar']);

        return $this->executeForward($resource, $method, $path,
$this->params);
    }

    protected function executeForward($resource, $method = 'GET',
$path, $params = [])
    {
        $class = '\\Gantry\\Admin\\Controller\\Html\\' .
strtr(ucwords(strtr($resource, '/', ' ')), '
', '\\');
        if (!class_exists($class)) {
            throw new \RuntimeException('Page not found', 404);
        }

        /** @var HtmlController $controller */
        $controller = new $class($this->container);

        // Execute action.
        $response = $controller->execute($method, $path, $params);

        if (!$response instanceof Response) {
            $response = new HtmlResponse($response);
        }

        return $response;
    }
}
PK��[��_iEEController/Html/Export.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Component\Admin\HtmlController;
use Gantry\Framework\Exporter;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use Symfony\Component\Yaml\Yaml;

class Export extends HtmlController
{
    public function index()
    {
        if (!class_exists('Gantry\Framework\Exporter')) {
            $this->forbidden();
        }

        if (!class_exists('ZipArchive')) {
            throw new \RuntimeException('Please enable PHP ZIP
extension to use this feature.');
        }

        $exporter = new Exporter;
        $exported = $exporter->all();

        $zipname =
$exported['export']['theme']['name'] .
'-export.zip';
        $tmpname = tempnam(sys_get_temp_dir(), 'zip');

        $zip = new \ZipArchive();
        $zip->open($tmpname, \ZipArchive::CREATE);

        $zip->addFromString("export.yaml",
Yaml::dump($exported['export'], 10, 2));
        unset($exported['export']);

        foreach ($exported['positions'] as $key => $position)
{
            foreach ($position['items'] as $module => $data) {
               
$zip->addFromString("positions/{$key}/{$module}.yaml",
Yaml::dump($data, 10, 2));
            }

            $position['ordering'] =
array_keys($position['items']);
            unset($position['items']);

            $zip->addFromString("positions/{$key}.yaml",
Yaml::dump($position, 10, 2));
        }

        foreach ($exported['outlines'] as $outline =>
&$data) {
            if (!empty($data['config'])) {
                foreach ($data['config'] as $name => $config)
{
                    if (in_array($name, ['particles',
'page'])) {
                        foreach ($config as $sub => $subconfig) {
                           
$zip->addFromString("outlines/{$outline}/{$name}/{$sub}.yaml",
Yaml::dump($subconfig, 10, 2));
                        }
                    } else {
                       
$zip->addFromString("outlines/{$outline}/{$name}.yaml",
Yaml::dump($config, 10, 2));
                    }
                }
            }
            unset($data['config']);
        }
        $zip->addFromString("outlines/outlines.yaml",
Yaml::dump($exported['outlines'], 10, 2));

        foreach ($exported['menus'] as $menu => $data) {
            $zip->addFromString("menus/{$menu}.yaml",
Yaml::dump($data, 10, 2));
        }

        foreach ($exported['content'] as $id => $data) {
            $zip->addFromString("content/{$id}.yaml",
Yaml::dump($data, 10, 2));
        }

        if (!empty($exported['categories'])) {
            $zip->addFromString("content/categories.yaml",
Yaml::dump($exported['categories'], 10, 2));
        }

        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];

        foreach ($exported['files'] as $stream => $files) {
            foreach ($files as $path => $uri) {
                $filename = $locator->findResource($uri);
                
                if (file_exists($filename)) {
                    $zip->addFile($filename,
"files/{$stream}/{$path}");
                }
            }
            
        }

        $zip->close();

        header('Content-Type: application/zip');
        header('Content-Disposition: attachment; filename=' .
$zipname);
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($tmpname));

        @ob_end_clean();
        flush();

        readfile($tmpname);
        unlink($tmpname);

        exit;
    }
}
PK��[�?�C}
}
Controller/Html/Import.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Filesystem\Folder;
use Gantry\Framework\Importer;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use Symfony\Component\Yaml\Yaml;

class Import extends HtmlController
{
    protected $httpVerbs = [
        'GET' => [
            '/'                 => 'index',
        ],
        'POST' => [
            '/'                 => 'import',
        ]
    ];

    public function index()
    {
        return
$this->render('@gantry-admin/pages/import/import.html.twig',
$this->params);
    }

    public function import()
    {
        if (!isset($_FILES['file']['error']) ||
is_array($_FILES['file']['error'])) {
            throw new \RuntimeException('No file sent', 400);
        }

        // Check $_FILES['file']['error'] value.
        switch ($_FILES['file']['error']) {
            case UPLOAD_ERR_OK:
                break;
            case UPLOAD_ERR_NO_FILE:
                throw new \RuntimeException('No file sent', 400);
            case UPLOAD_ERR_INI_SIZE:
            case UPLOAD_ERR_FORM_SIZE:
                throw new \RuntimeException('Exceeded filesize
limit.', 400);
            default:
                throw new \RuntimeException('Unkown errors',
400);
        }

        $filename = $_FILES['file']['tmp_name'];
        
        if (!is_uploaded_file($filename)) {
            throw new \RuntimeException('No file sent', 400);
        }

        $zip = new \ZipArchive;
        if ($zip->open($filename) !== true || !($export =
Yaml::parse($zip->getFromName('export.yaml'))) ||
!isset($export['gantry'])) {
            throw new \RuntimeException('Uploaded file is not Gantry 5
export file', 400);
        }

        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];

        $folder =
$locator->findResource('gantry-cache://import', true, true);
        if (is_dir($folder)) Folder::delete($folder);
        $zip->extractTo($folder);
        $zip->close();

        $importer = new Importer($folder);
        $importer->all();

        if (is_dir($folder)) Folder::delete($folder);

        $this->params['success'] = true;

        return
$this->render('@gantry-admin/pages/import/import.html.twig',
$this->params);
    }
}
PK��[�^�wwController/Html/Install.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Component\Admin\HtmlController;
use Gantry\Framework\ThemeInstaller;

class Install extends HtmlController
{
    public function index()
    {
        if (!$this->authorize('updates.manage') ||
!class_exists('\Gantry\Framework\ThemeInstaller')) {
            $this->forbidden();
        }

        $installer = new ThemeInstaller();
        $installer->initialized = true;
       
$installer->loadExtension($this->container['theme.name']);
        $installer->installDefaults();
        $installer->installSampleData();
        $installer->finalize();

        $this->params['actions'] = $installer->actions;
        
        return
$this->render('@gantry-admin/pages/install/install.html.twig',
$this->params);
    }
}
PK��[
����F�FController/Html/Menu.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Config\BlueprintSchema;
use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Config\Config;
use Gantry\Component\Menu\Item;
use Gantry\Component\Request\Input;
use Gantry\Component\Response\HtmlResponse;
use Gantry\Component\Response\JsonResponse;
use Gantry\Component\Response\Response;
use Gantry\Framework\Menu as MenuObject;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\File\YamlFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Menu extends HtmlController
{
    protected $httpVerbs = [
        'GET'    => [
            '/'                  => 'item',
            '/*'                 => 'item',
            '/*/**'              => 'item',
            '/particle'          => 'particle',
            '/particle/*'        =>
'validateParticle',
            '/select'            => 'undefined',
            '/select/particle'   =>
'selectParticle',
            '/select/module'     => 'selectModule',
            '/select/widget'     => 'selectWidget',
            '/edit'              => 'undefined',
            '/edit/*'            => 'edit',
            '/edit/*/**'         => 'editItem',
        ],
        'POST'   => [
            '/'                  => 'save',
            '/*'                 => 'save',
            '/*/**'              => 'item',
            '/particle'          => 'particle',
            '/particle/*'        =>
'validateParticle',
            '/select'            => 'undefined',
            '/select/particle'   =>
'selectParticle',
            '/select/module'     => 'selectModule',
            '/select/widget'     => 'selectWidget',
            '/widget'            => 'widget',
            '/edit'              => 'undefined',
            '/edit/*'            => 'edit',
            '/edit/*/**'         => 'editItem',
            '/edit/*/validate'   => 'validate',
        ],
        'PUT'    => [
            '/*' => 'replace'
        ],
        'PATCH'  => [
            '/*' => 'update'
        ],
        'DELETE' => [
            '/*' => 'destroy'
        ]
    ];

    public function execute($method, array $path, array $params)
    {
        if (!$this->authorize('menu.manage')) {
            $this->forbidden();
        }

        return parent::execute($method, $path, $params);
    }

    public function item($id = null)
    {
        // Load the menu.
        try {
            $resource = $this->loadResource($id,
$this->build($this->request->post));
        } catch (\Exception $e) {
            return
$this->render('@gantry-admin/pages/menu/menu.html.twig',
$this->params);
        }

        // All extra arguments become the path.
        $path = array_slice(func_get_args(), 1);

        // Get menu item and make sure it exists.
        $item = $resource[implode('/', $path)];
        if (!$item) {
            throw new \RuntimeException('Menu item not found',
404);
        }

        // Fill parameters to be passed to the template file.
        $this->params['id'] = $resource->name();
        $this->params['menus'] = $resource->getMenus();
        $this->params['default_menu'] =
$resource->hasDefaultMenu() ? $resource->getDefaultMenuName() :
false;
        $this->params['menu'] = $resource;
        $this->params['path'] = implode('/', $path);

        // Detect special case to fetch only single column group.
        $group = $this->request->get['group'];

        if (empty($this->params['ajax']) ||
empty($this->request->get['inline'])) {
            // Handle special case to fetch only one column group.
            if (count($path) > 0) {
                $this->params['columns'] =
$resource[$path[0]];
            }
            if (count($path) > 1) {
                $this->params['column'] = isset($group) ?
(int) $group : $resource[implode('/', array_slice($path, 0,
2))]->group;
                $this->params['override'] = $item;
            }

            return
$this->render('@gantry-admin/pages/menu/menu.html.twig',
$this->params);

        } else {
            // Get layout name.
            $layout = $this->layoutName(count($path) + (int)
isset($group));

            $this->params['item'] = $item;
            $this->params['group'] = isset($group) ? (int)
$group : $resource[implode('/', array_slice($path, 0,
2))]->group;

            return $this->render('@gantry-admin/menu/' .
$layout . '.html.twig', $this->params) ?:
'&nbsp;';
        }
    }

    public function edit($id)
    {
        $resource = $this->loadResource($id);
        $input = $this->build($this->request->post);
        if ($input) {
            $resource->config()->merge(['settings' =>
$input['settings']]);
        }

        // Fill parameters to be passed to the template file.
        $this->params['id'] = $resource->name();
        $this->params['blueprints'] =
$this->loadBlueprints();
        $this->params['data'] = ['settings' =>
$resource->settings()];

        return
$this->render('@gantry-admin/pages/menu/edit.html.twig',
$this->params);
    }

    public function save($id = null)
    {
        $resource = $this->loadResource($id);

        $data = $this->build($this->request->post);

        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];
        $filename =
$locator->findResource("gantry-config://menu/{$resource->name()}.yaml",
true, true);

        // Fire save event.
        $event = new Event;
        $event->gantry = $this->container;
        $event->theme = $this->container['theme'];
        $event->controller = $this;
        $event->resource = $id;
        $event->menu = $data;
        $this->container->fireEvent('admin.menus.save',
$event);

        $file = YamlFile::instance($filename);
        $file->settings(['inline' => 99]);
        $file->save($data->toArray());
        $file->free();
    }

    public function editItem($id)
    {
        // All extra arguments become the path.
        $path = array_slice(func_get_args(), 1);
        $keyword = end($path);

        // Special case: validate instead of fetching menu item.
        if ($this->method == 'POST' && $keyword ==
'validate') {
            $params = array_slice(func_get_args(), 0, -1);
            return call_user_func_array([$this, 'validateitem'],
$params);
        }

        $path = html_entity_decode(implode('/', $path),
ENT_COMPAT | ENT_HTML5, 'UTF-8');

        // Load the menu.
        $resource = $this->loadResource($id);

        // Get menu item and make sure it exists.
        /** @var Item $item */
        $item = $resource[$path];
        if (!$item) {
            throw new \RuntimeException('Menu item not found',
404);
        }
        $data =
$this->request->post->getJsonArray('item');
        if ($data) {
            $item->update($data);
        }

        // Load blueprints for the menu item.
        $blueprints = $this->loadBlueprints('menuitem');

        $this->params = [
                'id'         => $resource->name(),
                'path'       => $path,
                'blueprints' => ['fields' =>
$blueprints['form/fields/items/fields']],
                'data'       => $item->toArray() +
['path' => $path],
            ] + $this->params;

        return
$this->render('@gantry-admin/pages/menu/menuitem.html.twig',
$this->params);
    }

    public function particle()
    {
        $data = $this->request->post['item'];
        if ($data) {
            $data = json_decode($data, true);
        } else {
            $data = $this->request->post->getArray();
        }

        $name = isset($data['particle']) ?
$data['particle'] : null;

        $block = BlueprintForm::instance('menu/block.yaml',
'gantry-admin://blueprints');
        $blueprints =
$this->container['particles']->getBlueprintForm($name);

        // Load particle blueprints and default settings.
        $validator = $this->loadBlueprints('menu');
        $callable = function () use ($validator) {
            return $validator;
        };

        // Create configuration from the defaults.
        $item = new Config($data, $callable);
        $item->def('type', 'particle');
        $item->def('title',
$blueprints->get('name'));
        $item->def('options.type',
$blueprints->get('type', 'particle'));
        $item->def('options.particle', []);
        $item->def('options.block', []);

        $this->params += [
            'item'          => $item,
            'block'         => $block,
            'data'          => ['particles' =>
[$name => $item->options['particle']]],
            'particle'      => $blueprints,
            'parent'        => 'settings',
            'prefix'        => "particles.{$name}.",
            'route'         =>
"configurations.default.settings",
            'action'        =>
"menu/particle/{$name}"
        ];

        return
$this->render('@gantry-admin/pages/menu/particle.html.twig',
$this->params);
    }


    public function validateParticle($name)
    {
        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        // Load particle blueprints and default settings.
        $validator = new BlueprintSchema;
        $validator->embed('options',
$this->container['particles']->get($name));

        $blueprints =
$this->container['particles']->getBlueprintForm($name);

        // Create configuration from the defaults.
        $data = new Config([],
            function () use ($validator) {
                return $validator;
            }
        );

        $data->set('type', 'particle');
        $data->set('particle', $name);
        $data->set('title',
$this->request->post['title'] ?:
$blueprints->post['name']);
        $data->set('options.particle',
$this->request->post->getArray("particles.{$name}"));
        $data->def('options.particle.enabled', 1);
        $data->set('enabled',
$data->get('options.particle.enabled'));

        $block =
$this->request->post->getArray('block');
        foreach ($block as $key => $param) {
            if ($param === '') {
                unset($block[$key]);
            }
        }

        $data->join('options.block', $block);

        // TODO: validate

        // Fill parameters to be passed to the template file.
        $this->params['item'] = (object) $data->toArray();

        $html =
$this->render('@gantry-admin/menu/item.html.twig',
$this->params);

        return new JsonResponse(['item' =>
$data->toArray(), 'html' => $html]);
    }

    public function selectModule()
    {
        return
$this->render('@gantry-admin/modals/module-picker.html.twig',
$this->params);
    }

    public function selectWidget()
    {
        $this->params['next'] = 'menu/widget';

        return
$this->render('@gantry-admin/modals/widget-picker.html.twig',
$this->params);
    }

    public function widget()
    {
        $data = $this->request->post->getJson('item');
        $path = [$data->widget];
        $this->params['scope'] = 'menu';

        return $this->executeForward('widget',
'POST', $path, $this->params);
    }

    public function selectParticle()
    {
        $groups = [
            'Particles' => ['particle' => []],
        ];

        $particles = [
            'position'    => [],
            'spacer'      => [],
            'system'      => [],
            'particle'    => [],
        ];

        $particles = array_replace($particles, $this->getParticles());
        unset($particles['atom'],
$particles['position']);

        foreach ($particles as &$group) {
            asort($group);
        }

        foreach ($groups as $section => $children) {
            foreach ($children as $key => $child) {
                $groups[$section][$key] = $particles[$key];
            }
        }

        $this->params += [
            'particles' => $groups,
            'route' => 'menu/particle',
        ];

        return
$this->render('@gantry-admin/modals/particle-picker.html.twig',
$this->params);
    }

    public function validate($id)
    {
        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        // Load particle blueprints and default settings.
        $validator = $this->loadBlueprints('menu');
        $callable = function () use ($validator) {
            return $validator;
        };

        // Create configuration from the defaults.
        $data = new Config($this->request->post->getArray(),
$callable);

        // TODO: validate

        return new JsonResponse(['settings' => (array)
$data->get('settings')]);
    }

    public function validateitem($id)
    {
        // All extra arguments become the path.
        $path = array_slice(func_get_args(), 1);

        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        // Load the menu.
        $resource = $this->loadResource($id);

        // Load particle blueprints and default settings.
        $validator = $this->loadBlueprints('menuitem');
        $callable = function () use ($validator) {
            return $validator;
        };

        // Create configuration from the defaults.
        $data = new Config($this->request->post->getArray(),
$callable);

        // TODO: validate

        $item = $resource[implode('/', $path)];
        $item->update($data->toArray());

        // Fill parameters to be passed to the template file.
        $this->params['id'] = $resource->name();
        $this->params['item'] = $item;
        $this->params['group'] = isset($group) ? $group :
$resource[implode('/', array_slice($path, 0, 2))]->group;

        if (!$item->title) {
            throw new \RuntimeException('Title from the Menu Item
should not be empty', 400);
        }

        $html =
$this->render('@gantry-admin/menu/item.html.twig',
$this->params);

        return new JsonResponse(['path' =>
implode('/', $path), 'item' => $data->toArray(),
'html' => $html]);
    }

    protected function layoutName($level)
    {
        switch ($level) {
            case 0:
                return 'base';
            case 1:
                return 'columns';
            default:
                return 'list';
        }
    }

    /**
     * Load resource.
     *
     * @param string $id
     * @param Config $config
     *
     * @return \Gantry\Component\Menu\AbstractMenu
     * @throws \RuntimeException
     */
    protected function loadResource($id, Config $config = null)
    {
        /** @var MenuObject $menus */
        $menus = $this->container['menu'];

        return $menus->instance(['menu' => $id,
'admin' => true], $config);
    }

    /**
     * Load blueprints.
     *
     * @param string $name
     *
     * @return BlueprintForm
     */
    protected function loadBlueprints($name = 'menu')
    {
        return BlueprintForm::instance("menu/{$name}.yaml",
'gantry-admin://blueprints');
    }


    public function build(Input $input)
    {
        try {
            $items = $input->get('items');
            if ($items && $items[0] !== '{' &&
$items[0] !== '[') {
                $items = urldecode((string)base64_decode($items));
            }
            $items = json_decode($items, true);

            $settings = $input->getJsonArray('settings');
            $order = $input->getJsonArray('ordering');
        } catch (\Exception $e) {
            throw new \RuntimeException('Invalid menu structure',
400);
        }

        if (!$items && !$settings && !$order) {
            return null;
        }


        krsort($order);
        $ordering = ['' => []];
        foreach ($order as $path => $columns) {
            foreach ($columns as $column => $colitems) {
                $list = [];
                foreach ($colitems as $item) {
                    $name = trim(substr($item, strlen($path)),
'/');
                    if (isset($ordering[$item])) {
                        $list[$name] = $ordering[$item];
                        unset($ordering[$item]);
                    } else {
                        $list[$name] = '';
                    }
                }
                if (count($columns) > 1) {
                    $ordering[$path][$column] = $list;
                } else {
                    $ordering[$path] = $list;
                }
            }
        }

        $data = new Config([]);
        $data->set('settings', $settings);
        $data->set('ordering', $ordering['']);
        $data->set('items', $items);

        return $data;
    }

    protected function getParticles()
    {
        $particles = $this->container['particles']->all();

        $list = [];
        foreach ($particles as $name => $particle) {
            $type = isset($particle['type']) ?
$particle['type'] : 'particle';
            $particleName = isset($particle['name']) ?
$particle['name'] : $name;
            $particleIcon = isset($particle['icon']) ?
$particle['icon'] : null;
            $list[$type][$name] = ['name' => $particleName,
'icon' => $particleIcon];
        }

        return $list;
    }

    protected function executeForward($resource, $method = 'GET',
$path, $params = [])
    {
        $class = '\\Gantry\\Admin\\Controller\\Json\\' .
strtr(ucwords(strtr($resource, '/', ' ')), '
', '\\');
        if (!class_exists($class)) {
            throw new \RuntimeException('Page not found', 404);
        }

        /** @var HtmlController $controller */
        $controller = new $class($this->container);

        // Execute action.
        $response = $controller->execute($method, $path, $params);

        if (!$response instanceof Response) {
            $response = new HtmlResponse($response);
        }

        return $response;
    }
}
PK��[�,�ȵ*�*Controller/Html/Positions.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Component\Admin\HtmlController;
use Gantry\Component\Config\BlueprintSchema;
use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Config\Config;
use Gantry\Component\Position\Module;
use Gantry\Component\Position\Position;
use Gantry\Component\Response\JsonResponse;
use Gantry\Framework\Assignments;
use Gantry\Framework\Positions as PositionsObject;

class Positions extends HtmlController
{
    protected $httpVerbs = [
        'GET' => [
            '/'                   => 'index',
            '/*'                  => 'undefined',
            '/*/add'              =>
'selectParticle',
        ],
        'POST' => [
            '/'                   => 'save',
            '/create'             => 'create',
            '/*'                  => 'undefined',
            '/*/rename'           => 'rename',
            '/*/duplicate'        => 'duplicate',
            '/*/delete'           => 'delete',
            '/*/edit'             => 'undefined',
            '/*/edit/particle'    => 'particle',
            '/*/edit/particle/*'  =>
'validateParticle',
            '/edit'               => 'undefined',
            '/edit/particle'      => 'particle',
        ]
    ];

    public function index()
    {
        $this->params['positions'] =
$this->container['positions'];

        return
$this->render('@gantry-admin/pages/positions/positions.html.twig',
$this->params);
    }

    public function create()
    {
        // Create only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        /** @var PositionsObject $position */
        $positions = $this->container['positions'];

        $title = (string)
$this->request->post->get('title',
'Untitled');
        $key = (string) $this->request->post['key'];

        $id = $positions->create($title, $key);

        $html =
$this->render('@gantry-admin/layouts/position.html.twig',
['position' => ['name' => $id, 'title'
=> $title]]);

        return new JsonResponse(['html' =>
sprintf("Position '%s' created.", $id), 'id'
=> "position-{$id}", 'key' => $id,
'position' => $html]);
    }

    public function rename($old)
    {
        // Rename only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        $title = (string) $this->request->post['title'];
        $key = (string) $this->request->post['key'];
        $data = (string) $this->request->post['data'];

        /** @var PositionsObject $positions */
        $positions = $this->container['positions'];
        $position = $positions[$old];
        $exists = isset($position);

        if (!$exists) {
            if (!$data) {
                throw new \RuntimeException(sprintf("Position
'%s' not found", $old), 404);
            }

            $position = new Position($key ?: $old);
        }

        if (strlen($title)) {
            $position->title = (string) $title;
        }
        if ($exists && strlen($key)) {
            $position = $position->rename($key);
        } else {
            $position->save();
        }

        if ($data) {
            $data = ['title' => $position->title] +
json_decode($data, true);

            $position = new Position($position->name, $data);
        }

        $html =
$this->render('@gantry-admin/layouts/position.html.twig',
['position' => $position]);

        return new JsonResponse(['html' =>
sprintf("Position saved"), 'id' =>
"position-{$position->name}", 'key' =>
$position->name, 'position' => $html]);
    }

    public function duplicate($position)
    {
        // Duplicate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        /** @var PositionsObject $positions */
        $positions = $this->container['positions'];

        $id = $positions->duplicate($position);

        return new JsonResponse(['html' =>
sprintf("Position duplicated as '%s'.", $id)]);
    }

    public function delete($position)
    {
        // Delete only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        /** @var PositionsObject $positions */
        $positions = $this->container['positions'];

        $positions->delete($position);

        return new JsonResponse(['html' =>
sprintf("Position '%s' deleted.", $position),
'position' => $position]);
    }

    public function save()
    {
        // Save only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        $data =
$this->request->post->getJsonArray('positions');

        /** @var PositionsObject $position */
        $positions = $this->container['positions'];
        $positions->import($data);

        return new JsonResponse(['html' =>
sprintf("Positions saved.")]);
    }

    public function particle($position = null)
    {
        if (!$position) {
            $position = $this->request->post['position'];
        }
        $data = $this->request->post['item'];
        if ($data) {
            $data = json_decode($data, true);
        } else {
            $data = $this->request->post->getArray();
        }
        $name = isset($data['options']['type']) ?
$data['options']['type'] :
(isset($data['particle']) ? $data['particle'] : null);

        $blueprints =
$this->container['particles']->getBlueprintForm($name);

        $chromeBlueprints =
BlueprintForm::instance('position/chrome.yaml',
'gantry-admin://blueprints');

        $data['title'] = isset($data['title']) ?
$data['title'] : $blueprints['name'];
        $data['chrome'] = isset($data['chrome']) ?
$data['chrome'] : [];
        $data['options'] = isset($data['options']) ?
$data['options'] : [];
        $data['options']['type'] = $name;
        $attributes =
isset($data['options']['attributes']) ?
$data['options']['attributes'] : [];
        $assignments = new Assignments();

        $this->params += [
            'item'          => $data,
            'data'          => [
                'particles' => [$name => $attributes],
                'chrome'    => $data['chrome'],
                'assignments' =>
isset($data['assignments']) ? $data['assignments'] :
'all'
            ],
            'particle'      => $blueprints,
            'chrome'        => $chromeBlueprints,
            'assignments'   => $assignments->get(),
            'parent'        => 'settings',
            'prefix'        => "particles.{$name}.",
            'route'         =>
"configurations.default.settings",
            'action'        =>
"positions/{$position}/edit/particle/{$name}"
        ];

        return
$this->render('@gantry-admin/pages/positions/particle.html.twig',
$this->params);
    }


    public function validateParticle($position, $name)
    {
        // Validate only exists for JSON.
        if (empty($this->params['ajax'])) {
            $this->undefined();
        }

        if (!$this->request->post->get('_end')) {
            throw new \OverflowException("Incomplete data received.
Please increase the value of 'max_input_vars' variable (in
php.ini or .htaccess)", 400);
        }

        // Load particle blueprints and default settings.
        $validator = new BlueprintSchema;
        $validator->embed('options',
$this->container['particles']->get($name));

        $blueprints =
$this->container['particles']->getBlueprintForm($name);

        // Create configuration from the defaults.
        $data = new Config([],
            function () use ($validator) {
                return $validator;
            }
        );

        $data->set('position', $position);
        $data->set('id', $id =
$this->request->post['id']);
        $data->set('type', 'particle');
        $data->set('title',
$this->request->post['title'] ?:
$blueprints->post['name']);
        $data->set('chrome',
$this->request->post->getArray('chrome'));
        $data->set('options.type', $name);
        $data->set('options.attributes',
$this->request->post->getArray("particles.{$name}"));
        $data->def('options.attributes.enabled', 1);

        $assignments = (new
Assignments())->filter($this->request->post->getArray('assignments'),
true);

        if (!$assignments) {
            // Use special syntax for no assignments.
            $assignments = 'none';
        } elseif ($assignments === ['page' => [true]]) {
            // Use special syntax for assigned to all pages. This is a
special case and hardcoded for now.
            $assignments = 'all';
        }

        $data->set('assignments', $assignments);

        // TODO: validate

        // Fill parameters to be passed to the template file.
        $this->params['position'] = $position;
        $this->params['item'] = (object) $data->toArray();
        $this->params['module'] = new Module($id, $position,
$data->toArray());

        $html =
$this->render('@gantry-admin/pages/positions/item.html.twig',
$this->params);

        return new JsonResponse(['item' =>
$data->toArray(), 'html' => $html, 'position'
=> $position]);
    }

    public function selectParticle($position)
    {
        $groups = [
            'Particles' => ['particle' => []],
        ];

        $particles = [
            'position'    => [],
            'spacer'      => [],
            'system'      => [],
            'particle'    => [],
        ];

        $particles = array_replace($particles, $this->getParticles());
        unset($particles['atom'],
$particles['position']);

        foreach ($particles as &$group) {
            asort($group);
        }

        foreach ($groups as $section => $children) {
            foreach ($children as $key => $child) {
                $groups[$section][$key] = $particles[$key];
            }
        }

        $this->params += [
            'particles' => $groups,
            'route' =>
"positions/{$position}/edit/particle",
        ];

        return
$this->render('@gantry-admin/modals/particle-picker.html.twig',
$this->params);
    }

    protected function getParticles()
    {
        $particles = $this->container['particles']->all();

        $list = [];
        foreach ($particles as $name => $particle) {
            $type = isset($particle['type']) ?
$particle['type'] : 'particle';
            $particleName = isset($particle['name']) ?
$particle['name'] : $name;
            $particleIcon = isset($particle['icon']) ?
$particle['icon'] : null;
            $list[$type][$name] = ['name' => $particleName,
'icon' => $particleIcon];
        }

        return $list;
    }
}
PK��[�����Controller/Html/Themes.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Html;

use Gantry\Admin\ThemeList;
use Gantry\Component\Admin\HtmlController;

class Themes extends HtmlController
{
    public function index()
    {
        $this->params['themes'] = (new
ThemeList)->getThemes();

        return
$this->render('@gantry-admin/pages/themes/themes.html.twig',
$this->params);
    }
}
PK��[��z66Controller/Json/Atoms.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Response\JsonResponse;

/**
 * Class Atoms
 * @package Gantry\Admin\Controller\Json
 */
class Atoms extends JsonController
{
    protected $httpVerbs = [
        'GET' => [
            '/' => 'index',
            '/*' => 'index',
            '/instance' => 'atom'
        ],
        'POST' => [
            '/' => 'index',
            '/*' => 'index',
            '/instance' => 'atom'
        ]
    ];
    
    public function index()
    {
        $path = implode('/', func_get_args());

        $post = $this->request->request;

        $outline = $post['outline'];
        $type = $post['subtype'];
        $inherit = $post['inherit'];
        $id = $post['id'];

        if (!$outline) {
            throw new \RuntimeException('Outline not given',
400);
        }

        $this->container['outline'] = $outline;
        $this->container['configuration'] = $outline;

        $atoms = new \Gantry\Framework\Atoms((array)
$this->container['config']->get('page.head.atoms'));
        if ($inherit) {
            $atoms->inheritAll($outline);
        }

        $item = (object) $atoms->id($id);

        if ($path === 'list') {
            $list = $atoms->type($type);
            if (empty($item->id)) {
                $item = (object)reset($list);
            }
        }
        $selected = !empty($item->id) ? $item->id : null;

        $type = isset($item->type) ? $item->type : $type;
        $item->attributes = isset($item->attributes) ? (array)
$item->attributes : [];

        $blueprints =
$this->container['particles']->getBlueprintForm($type);
        $blueprints->set('form/fields/_inherit',
['type' => 'gantry.inherit']);

        $params = [
            'gantry'        => $this->container,
            'parent'        => 'settings',
            'route'         =>
"configurations.{$outline}.settings",
            'inherit'       => $inherit ? $outline : null,
            'title'         => isset($item->title) ?
$item->title : '',
            'blueprints'    =>
$blueprints->get('form'),
            'item'          => $item,
            'data'          => ['particles' =>
[$type => $item->attributes]],
            'prefix'        => "particles.{$type}.",
            'editable'      => true,
            'overrideable'  => false,
            'skip'          => ['enabled']
        ];

        $html['g-settings-atom'] =
$this->render('@gantry-admin/pages/configurations/layouts/particle-card.html.twig',
 $params);
        if (isset($list)) {
            $html['g-inherit-atom'] =
$this->renderAtomsInput($inherit ? $outline : null, $type, $selected,
$list);
        }

        return new JsonResponse(['json' => $item,
'html' => $html]);
    }

    public function atom()
    {
        $post = $this->request->request;

        $outline = $post['outline'];
        $id = $post['id'];

        if (!$outline) {
            throw new \RuntimeException('Outline not given',
400);
        }

        $this->container['outline'] = $outline;
        $this->container['configuration'] = $outline;

        $atoms = new \Gantry\Framework\Atoms((array)
$this->container['config']->get('page.head.atoms'));
        $item = (object) $atoms->id($id);
        if (empty($item->id)) {
            throw new \RuntimeException('Atom was not found from the
outline', 404);
        }

        $name = $item->type;

        $prefix = "particles.{$name}";

        $blueprints =
$this->container['particles']->getBlueprintForm($name);
        $blueprints->set('form/fields/_inherit',
['type' => 'gantry.inherit']);

        $item->attributes = isset($item->attributes) ? (array)
$item->attributes : [];

        $this->params['id'] = $name;
        $this->params += [
            'item'          => $item,
            'data'          => ['particles' =>
[$name => $item->attributes]],
            'prefix'        => "particles.{$name}.",
            'particle'      => $blueprints,
            'parent'        => 'settings',
            'route'         =>
"configurations.{$outline}.settings",
            'action'        => str_replace('.',
'/', 'configurations.' . $outline .
'.layout.' . $prefix . '.validate'),
            'skip'          => ['enabled'],
            'editable'      => false,
            'overrideable'  => false,
        ];

        $html =
$this->render('@gantry-admin/modals/atom-preview.html.twig',
$this->params);

        return new JsonResponse(['html' => $html]);
    }

    /**
     * Render input field for particle picker.
     *
     * @param string $outline
     * @param string $type
     * @param string $selected
     * @param array $instances
     * @return string
     */
    protected function renderAtomsInput($outline, $type, $selected, array
$instances)
    {
        $params = [
            'layout' => 'input',
            'scope' => 'inherit.',
            'field' => [
                'name' => 'atom',
                'type' => 'gantry.atoms',
                'id' => 'g-inherit-atom',
                'outline' => $outline,
                'atoms' => $instances,
                'atom' => $type
            ],
            'value' => $selected
        ];

        return
$this->render('@gantry-admin/forms/fields/gantry/atoms.html.twig',
$params);
    }
}
PK��[7��]��Controller/Json/Changelog.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Remote\Response as RemoteResponse;
use Gantry\Component\Response\JsonResponse;

class Changelog extends JsonController
{
    protected $url =
'https://raw.githubusercontent.com/gantry/gantry5';
    protected $fullurl =
'https://github.com/gantry/gantry5/blob/develop';
    protected $issues =
'https://github.com/gantry/gantry5/issues';
    protected $contrib = 'https://github.com';
    protected $file = 'CHANGELOG.md';

    protected $platforms = ['common' => 'share-alt',
'joomla' => '', 'wordpress' =>
'', 'grav' => ''];

    protected $httpVerbs = [
        'POST' => [
            '/' => 'index'
        ]
    ];

    public function index()
    {
        $version = $this->request->post['version'];
        $lookup = $version;
        
        if ($version == '@version@') {
            $version = 'develop';
            $lookup  = '';
        }

        if (substr($version, 0, 4) == 'dev-') {
            $version = preg_replace('/^dev-/i', '',
$version);
            $lookup  = '';
        }

        $url       = $this->url . '/' . $version .
'/' . $this->file;
        $changelog = RemoteResponse::get($url);

        if ($changelog) {
            $found = preg_match("/(#\\s" . $lookup .
".+?\\n.*?)(?=\\n{1,}#|$)/uis", $changelog, $changelog);

            if ($found) {
                $changelog =
\Parsedown::instance()->parse($changelog[0]);

                // auto-link issues
                $changelog = preg_replace("/#(\\d{1,})/uis",
'<a target="_blank" rel="noopener"
href="' . $this->issues .
'/$1">#$1</a>', $changelog);

                // auto-link contributors
                $changelog = preg_replace("/@([\\w]+)[^\\w]/uis",
'<a target="_blank" rel="noopener"
href="' . $this->contrib . '/$1">@$1</a>
', $changelog);

                // add icons for platforms
                foreach($this->platforms as $platform => $icon) {
                    $changelog = preg_replace('/(<a
href="\#' . $platform . '">)/uis',
'$1<i class="fa fa-' . ($icon ?: $platform) .
'" aria-hidden="true"></i> ',
$changelog);
                }
            } else {
                $changelog = 'No changelog for version
<strong>' . $version . '</strong> was found.';
            }
        }

        $response = [
            'html' =>
$this->render('@gantry-admin/ajax/changelog.html.twig', [
                'changelog' => $changelog,
                'version'   => $version,
                'url'       => $url,
                'fullurl'   => $this->fullurl .
'/' . $this->file
            ])
        ];

        return new JsonResponse($response);
    }
}
PK��[�)����#Controller/Json/Confirmdeletion.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Response\JsonResponse;

class Confirmdeletion extends JsonController
{
    protected $httpVerbs = [
        'GET' => [
            '/' => 'index'
        ]
    ];

    public function index()
    {
        $pageType =
$this->request->get->get('page_type',
'OUTLINE');
        $response = ['html' =>
$this->render('@gantry-admin/ajax/confirm-deletion.html.twig',
['page_type' => $pageType])];

        return new JsonResponse($response);
    }
}
PK��[�����Controller/Json/Devprod.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Response\JsonResponse;
use RocketTheme\Toolbox\Event\Event;

class Devprod extends JsonController
{
    public function store()
    {
        $production =
intval((bool)$this->request->post['mode']);

        // Fire save event.
        $event = new Event;
        $event->gantry = $this->container;
        $event->controller = $this;
        $event->data = ['production' => $production];

        $this->container->fireEvent('admin.global.save',
$event);

        $response = [
            'mode' => $production,
            'title' => $production ? 'Production' :
'Development',
            'html' => $production ? 'Production mode
enabled' : 'Development mode enabled',
        ];
        return new JsonResponse($response);
    }
}
PK��[
PQ�>�>Controller/Json/Filepicker.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Filesystem\Folder;
use Gantry\Component\Response\JsonResponse;
use RocketTheme\Toolbox\File\File;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceIterator;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;


class Filepicker extends JsonController
{
    protected $base = false;
    protected $value = false;
    protected $filter = false;
    protected $httpVerbs = [
        'GET'    => [
            '/'            => 'index',
            '/*'           => 'index',
            '/display'     => 'undefined',
            '/display/**'  => 'displayFile',
            '/download'    => 'undefined',
            '/download/**' => 'downloadFile',
        ],
        'POST'   => [
            '/'            => 'index',
            '/*'           => 'index',
            '/subfolder'   => 'subfolder',
            '/subfolder/*' => 'subfolder',
            '/upload'      => 'undefined',
            '/upload/**'   => 'upload'
        ],
        'DELETE' => [
            '/'   => 'undefined',
            '/**' => 'delete'
        ]
    ];

    public function index()
    {
        /** @var UniformResourceLocator $locator */
        $locator   = $this->container['locator'];
        $bookmarks = [];
        $drives    = ['/'];
        $subfolder = false;

        $this->base = $locator->base;

        if ($this->method == 'POST') {
            $root         = $this->request->post['root'];
            $drives       = isset($root) ? ($root !== 'false' ?
(array) $root : ['/']) : ['/'];
            $subfolder    =
$this->request->post['subfolder'] ? true : false;
            $filter       = $this->request->post['filter'];
            $this->filter = isset($filter) ? ($filter !==
'false' ? $filter : false) : false;
            $this->value  =
$this->request->post['value'] ?: '';
        }

        foreach ($drives as $drive) {
            // cleanup of the path so it's chrooted.
            $drive  = str_replace('..', '', $drive);

            $isStream = $locator->isStream($drive);
            $path     = rtrim($this->base, '/') .
'/' . ltrim($drive, '/');

            // It's a stream but the scheme doesn't exist. we
skip it.
            if (!$isStream && (strpos($drive, '://') ||
!file_exists($path))) {
                continue;
            }

            if ($isStream && !$locator->findResources($drive)) {
                continue;
            }

            $key = $isStream ? $drive : preg_replace('#/{2,}+#',
'/', $drive);

            if (!array_key_exists($key, $bookmarks)) {
                $bookmarks[$key] = $isStream
                    ? [$locator->getIterator($drive)]
                    : [rtrim(Folder::getRelativePath($path), '/')
. '/'];
            }
        }

        if (!count($bookmarks)) {
            throw new \RuntimeException(sprintf('%s "%s" not
found', count($drives) > 1 ? 'directories' :
'directory', implode('", "', $drives)), 404);
        }

        $folders = [];
        $active  = [];

        $index = 0;
        $activeFallback = '';

        // iterating the folder and collecting subfolders and files
        foreach ($bookmarks as $key => $bookmark) {
            $folders[$key] = [];

            if (!$index) {
                $activeFallback = $key;
            }

            foreach ($bookmark as $folder) {
                $isStream = $this->isStream($folder);

                if ($isStream) {
                    unset($bookmarks[$key]);
                    $iterator = new \IteratorIterator($folder);
                    $folder   = $key;
                } else {
                    $iterator = new \DirectoryIterator($this->base .
'/' . ltrim($folder, '/'));
                }

                $folders[$key][$folder] = new \ArrayObject();
                if (!$index && !$this->value) {
                    $active[] = $folder;
                }

                /** @var \SplFileInfo $info */
                foreach ($iterator as $info) {
                    // no dot files nor files beginning with dot
                    if ($info->isDot() ||
substr($info->getFilename(), 0, 1) == '.') {
                        continue;
                    }

                    $file = new \stdClass();
                    $this->attachData($file, $info, $folder);

                    if ($file->dir) {
                        if ($file->pathname == dirname($this->value))
{
                            $active[] = $file->pathname;
                        }

                        $folders[$key][$folder]->append($file);
                    } else {
                        /*if ($filter && !preg_match("/"
. $filter . "/i", $file->filename)) {
                            continue;
                        }
                        if ((!$index && !$this->value) ||
(in_array(dirname($file->pathname), $active))) {
                            $files->append($file);
                        }*/
                    }
                }

                if ($isStream) {
                    $bookmarks[$key][] = $key;
                }

                $index++;
            }
        }

        if (!count($active)) {
            $active[] = $activeFallback;
        }

        $lastItem = end($active);
        $files    = $this->listFiles($lastItem);
        $response = [];

        reset($active);
        if (!$subfolder) {
            $response['html'] = $this->render(
                '@gantry-admin/ajax/filepicker.html.twig', [
                    'active'    => $active,
                    'base'      => $this->base,
                    'bookmarks' => $bookmarks,
                    'folders'   => $folders,
                    'files'     => $files,
                    'filter'    => $this->filter,
                    'value'     => $this->value
                ]
            );
        } else {
            $response['subfolder'] =
!$folders[$key][$folder]->count()
                ? false
                : $this->render(
                   
'@gantry-admin/ajax/filepicker/subfolders.html.twig',
                    ['folder' => $folders[$key][$folder]]
                );
            $response['files']     = $this->render(
                '@gantry-admin/ajax/filepicker/files.html.twig',
                ['files' => $files, 'value' =>
$this->value]
            );
        }

        return new JsonResponse($response);
    }

    protected function attachData(&$node, $iteration, $folder)
    {
        foreach (
            ['getFilename', 'getExtension',
'getPerms', 'getMTime', 'getBasename',
'getPathname', 'getSize', 'getType',
'isReadable', 'isWritable',
             'isDir', 'isFile'] as $method
        ) {
            $keyMethod          =
strtolower(preg_replace("/^(is|get)/", '', $method));
            $node->{$keyMethod} = $iteration->{$method}();

            if ($method == 'getPathname') {
                $node->{$keyMethod} = $this->isStream($folder) ?
$iteration->getUrl() : Folder::getRelativePath($node->{$keyMethod});
            } else {
                if ($method == 'getExtension') {
                    $node->isImage =
in_array(strtolower($node->{$keyMethod}), ['jpg',
'jpeg', 'png', 'gif', 'ico',
'svg', 'bmp', 'webp']);
                }
            }
        }

    }

    protected function listFiles($folder)
    {
        $isStream = $this->isStream($folder);
        $locator  = $this->container['locator'];
        $iterator = $isStream ? new
\IteratorIterator($locator->getIterator($folder)) : new
\DirectoryIterator($this->base . '/' . ltrim($folder,
'/'));
        $files    = new \ArrayObject();

        /** @var \SplFileInfo $info */
        foreach ($iterator as $info) {
            // no dot files nor files beginning with dot
            if ($info->isDot() || substr($info->getFilename(), 0, 1)
== '.') {
                continue;
            }

            $file = new \stdClass();
            $this->attachData($file, $info, $folder);

            if (!$file->dir) {
                if ($this->filter && !preg_match("/" .
$this->filter . "/i", $file->filename)) {
                    continue;
                }

                $file->isInCustom = false;

                if ($isStream) {
                    $stream         = explode('://', $folder);
                    $stream         = array_shift($stream) .
'://';
                    $customLocation = $locator->findResource($stream,
true, true);
                    if (substr($info->getPathname(), 0,
strlen($customLocation)) === $customLocation) {
                        $file->isInCustom = true;
                    }
                }


                $files->append($file);
            }
        }

        $files->asort();
        return $files;

    }

    public function subfolder()
    {
        $response         = [];
        $response['html'] = 'subfolder';

        return new JsonResponse($response);

    }

    public function displayFile()
    {
        $path = implode('/', func_get_args());

        $this->doDownload($path, false);

    }

    protected function doDownload($path, $download)
    {
        if (!$path) {
            throw new \RuntimeException('No file specified',
400);
        }

        // TODO: handle streams
        $targetPath = GANTRY5_ROOT . '/' . $path;

        if (!file_exists($targetPath)) {
            throw new \RuntimeException(sprintf('File not found:
%s', $path), 404);
        }

        $hash = md5_file($path);

        // Handle 304 Not Modified
        if
(isset($this->request->server['HTTP_IF_NONE_MATCH'])) {
            $etag =
stripslashes($this->request->server['HTTP_IF_NONE_MATCH']);

            if ($etag == $hash) {
                header('Last-Modified: ' . gmdate('D, d M Y
H:i:s', filemtime($path)) . ' GMT', true, 304);

                // Give fast response.
                flush();
                exit();
            }
        }

        // Set file headers.
        header('ETag: ' . $hash);
        header('Pragma: public');
        header('Last-Modified: ' . gmdate('D, d M Y
H:i:s', filemtime($path)) . ' GMT');

        // Get the image file information.
        $info    = getimagesize($path);
        $isImage = (bool)$info;

        if (!$download && $isImage) {
            $fileType = $info['mime'];

            // Force re-validate.
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0,
pre-check=0');
            header('Content-type: ' . $fileType);
            header('Content-Disposition: inline; filename="'
. basename($path) . '"');
        } else {
            // Force file download.
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0,
pre-check=0');
            header('Content-Description: File Transfer');
            header('Content-Type: application/force-download');
            header('Content-Type: application/octet-stream');
            header('Content-Type: application/download');
            header('Content-Disposition: attachment;
filename="' . basename($path) . '"');
        }

        header('Content-Transfer-Encoding: binary');
        header('Content-Length: ' . filesize($path));
        flush();

        // Output the file contents.
        @readfile($path);
        flush();

        exit();

    }

    public function downloadFile()
    {
        $path = implode('/', func_get_args());

        $this->doDownload($path, true);

    }

    public function upload()
    {
        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];
        $path    = implode('/', func_get_args());

        if (base64_decode($path, true) !== false) {
            $path = urldecode(base64_decode($path));
        }

        $stream = explode('://', $path);
        $scheme = $stream[0];

        $isStream = $locator->schemeExists($scheme);
        if ($isStream) {
            $targetPath = dirname($locator->findResource($path, true,
true));
        } else {
            $targetPath = dirname(GANTRY5_ROOT . '/' . $path);
        }

        if (!isset($_FILES['file']['error']) ||
is_array($_FILES['file']['error'])) {
            throw new \RuntimeException('No file sent', 400);
        }

        // Check $_FILES['file']['error'] value.
        switch ($_FILES['file']['error']) {
            case UPLOAD_ERR_OK:
                break;
            case UPLOAD_ERR_NO_FILE:
                throw new \RuntimeException('No file sent', 400);
            case UPLOAD_ERR_INI_SIZE:
            case UPLOAD_ERR_FORM_SIZE:
                throw new \RuntimeException('Exceeded filesize
limit.', 400);
            default:
                throw new \RuntimeException('Unkown errors',
400);
        }

        $maxSize =
$this->returnBytes(min(ini_get('post_max_size'),
ini_get('upload_max_filesize')));
        if ($_FILES['file']['size'] > $maxSize) {
            throw new \RuntimeException('Exceeded filesize limit. File
is ' . $_FILES['file']['size'] . ', maximum
allowed is ' . $maxSize, 400);
        }

        // Check extension
        $fileParts = pathinfo($_FILES['file']['name']);
        $fileExt   = strtolower($fileParts['extension']);

        // TODO: check if download is of supported type.

        // Upload it
        $destination = sprintf('%s/%s', $targetPath,
$_FILES['file']['name']);
        $destination = preg_replace('#//#', '/',
$destination);

        Folder::create($targetPath);

        if
(!move_uploaded_file($_FILES['file']['tmp_name'],
$destination)) {
            throw new \RuntimeException('Failed to move uploaded
file.', 500);
        }

        $finfo = new \stdClass();
        $this->attachData($finfo, new \SplFileInfo($destination),
$targetPath);
        return new JsonResponse(['success' => 'File
uploaded successfully', 'finfo' => $finfo,
'url' => $path]);

    }

    protected function returnBytes($size_str)
    {
        switch (strtolower(substr($size_str, -1))) {
            case 'm':
            case 'mb':
                return (int)$size_str * 1048576;
            case 'k':
            case 'kb':
                return (int)$size_str * 1024;
            case 'g':
            case 'gb':
                return (int)$size_str * 1073741824;
            default:
                return $size_str;
        }

    }

    public function delete()
    {
        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];
        $path    = implode('/', func_get_args());

        if (base64_decode($path, true) !== false) {
            $path = urldecode(base64_decode($path));
        }

        $stream = explode('://', $path);
        $scheme = $stream[0];

        if (!$path) {
            throw new \RuntimeException('No file specified for
delete', 400);
        }

        $isStream = $locator->schemeExists($scheme);
        if ($isStream) {
            $targetPath = $locator->findResource($path, true, true);
        } else {
            $targetPath = GANTRY5_ROOT . '/' . $path;
        }

        $file = File::instance($targetPath);

        if (!$file->exists()) {
            throw new \RuntimeException(sprintf('File not found:
%s', $targetPath), 404);
        }

        try {
            $file->delete();
        } catch (\Exception $e) {
            throw new \RuntimeException(sprintf('File could not be
deleted: %s', $targetPath), 500);
        }
        $file->free();

        return new JsonResponse(['success', 'File deleted:
' . $targetPath]);
    }

    private function isStream($folder)
    {
        return $folder instanceof UniformResourceIterator ||
strpos($folder, '://');
    }
}
PK��[��l�
�
Controller/Json/Fontpicker.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Response\JsonResponse;
use RocketTheme\Toolbox\File\JsonFile;

class Fontpicker extends JsonController
{
    protected $google_fonts =
'gantry-admin://js/google-fonts.json';

    protected $httpVerbs = [
        'GET' => [
            '/' => 'index'
        ]
    ];

    public function index()
    {
        $this->params['fonts'] = $this->loadGoogleFonts();
        $this->params['variantsMap'] =
$this->variantsMap();
        $response = [
            'html' =>
$this->render('@gantry-admin/ajax/fontpicker.html.twig',
$this->params)
        ];
        return new JsonResponse($response);
    }

    public function loadGoogleFonts()
    {
        $data = new \stdClass();
        $file = JsonFile::instance($this->google_fonts);
        $fonts = $file->content()['items'];
        $file->free();

        $data->categories = [];
        $data->subsets = [];

        // create list of unique categories and subsets
        array_walk($fonts, function (&$item) use ($data) {
            if (!in_array($item->category, $data->categories)) {
                $data->categories[] = $item->category;
            }
            $data->subsets = array_unique(array_merge($data->subsets,
$item->subsets));
        });

        asort($data->categories);
        asort($data->subsets);

        $data->families = $fonts;
        $data->local_families = $this->loadLocalFonts();

        if (count($data->local_families)) {
            array_unshift($data->categories, 'local-fonts');
        }

        $data->count = count($data->families);

        return $data;
    }

    public function loadLocalFonts()
    {
        $local_fonts =
$this->container['theme']->details()->get('configuration.fonts',
[]);
        $map = [];

        foreach ($local_fonts as $name => $variants) {
            if (is_array($variants)) {
                $list = array_keys($variants);
            } else {
                $list = ['regular'];
            }

            $map[] = ['family' => $name, 'variants'
=> $list, 'category' => 'local-fonts'];
        }

        return $map;
    }

    protected function variantsMap()
    {
        return [
            '100'       => 'Thin 100',
            '100italic' => 'Thin 100 Italic',
            '200'       => 'Extra-Light 200',
            '200italic' => 'Extra-Light 200 Italic',
            '300'       => 'Light 300',
            '300italic' => 'Light 300 Italic',
            '400'       => 'Normal 400',
            'regular'   => 'Normal 400',
            '400italic' => 'Normal 400 Italic',
            'italic'    => 'Normal 400 Italic',
            '500'       => 'Medium 500',
            '500italic' => 'Medium 500 Italic',
            '600'       => 'Semi-Bold 600',
            '600italic' => 'Semi-Bold 600 Italic',
            '700'       => 'Bold 700',
            '700italic' => 'Bold 700 Italic',
            '800'       => 'Extra-Bold 800',
            '800italic' => 'Extra-Bold 800 Italic',
            '900'       => 'Ultra-Bold 900',
            '900italic' => 'Ultra-Bold 900 Italic'
        ];
    }
}
PK��[�u#S�F�FController/Json/Icons.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Response\JsonResponse;

class Icons extends JsonController
{
    public function index()
    {
        $response = [];

        // Font Awesome Icons list [v4.7.0 - 730 icons]
        // NOTE: To get an updated list of icons:
        //       1. Go to: http://fontawesome.io/icons/
        //       2. Open Console in Deveveloper Tools
        //       3. Type this JS snippet: var list = [];
document.querySelectorAll('.fontawesome-icon-list
i').forEach(function(icon, index){ var name =
icon.className.replace(/^fa\s/, ''); list.push(name); }); var
output = '$list = ["' + list.join('",
"') + '"];'; console.log(output); copy(output);
console.info('The output has been copied to the clipboard, you can now
CMD + V / CTRL + V to update the icons variable');
        //       4. Press Enter and replace the line below
        $list = ["fa-address-book",
"fa-address-book-o", "fa-address-card",
"fa-address-card-o", "fa-bandcamp",
"fa-bath", "fa-bathtub",
"fa-drivers-license", "fa-drivers-license-o",
"fa-eercast", "fa-envelope-open",
"fa-envelope-open-o", "fa-etsy",
"fa-free-code-camp", "fa-grav",
"fa-handshake-o", "fa-id-badge",
"fa-id-card", "fa-id-card-o", "fa-imdb",
"fa-linode", "fa-meetup", "fa-microchip",
"fa-podcast", "fa-quora", "fa-ravelry",
"fa-s15", "fa-shower", "fa-snowflake-o",
"fa-superpowers", "fa-telegram",
"fa-thermometer", "fa-thermometer-0",
"fa-thermometer-1", "fa-thermometer-2",
"fa-thermometer-3", "fa-thermometer-4",
"fa-thermometer-empty", "fa-thermometer-full",
"fa-thermometer-half", "fa-thermometer-quarter",
"fa-thermometer-three-quarters", "fa-times-rectangle",
"fa-times-rectangle-o", "fa-user-circle",
"fa-user-circle-o", "fa-user-o", "fa-vcard",
"fa-vcard-o", "fa-window-close",
"fa-window-close-o", "fa-window-maximize",
"fa-window-minimize", "fa-window-restore",
"fa-wpexplorer", "fa-address-book",
"fa-address-book-o", "fa-address-card",
"fa-address-card-o", "fa-adjust",
"fa-american-sign-language-interpreting", "fa-anchor",
"fa-archive", "fa-area-chart", "fa-arrows",
"fa-arrows-h", "fa-arrows-v",
"fa-asl-interpreting",
"fa-assistive-listening-systems", "fa-asterisk",
"fa-at", "fa-audio-description",
"fa-automobile", "fa-balance-scale",
"fa-ban", "fa-bank", "fa-bar-chart",
"fa-bar-chart-o", "fa-barcode", "fa-bars",
"fa-bath", "fa-bathtub", "fa-battery",
"fa-battery-0", "fa-battery-1",
"fa-battery-2", "fa-battery-3",
"fa-battery-4", "fa-battery-empty",
"fa-battery-full", "fa-battery-half",
"fa-battery-quarter", "fa-battery-three-quarters",
"fa-bed", "fa-beer", "fa-bell",
"fa-bell-o", "fa-bell-slash",
"fa-bell-slash-o", "fa-bicycle",
"fa-binoculars", "fa-birthday-cake",
"fa-blind", "fa-bluetooth", "fa-bluetooth-b",
"fa-bolt", "fa-bomb", "fa-book",
"fa-bookmark", "fa-bookmark-o", "fa-braille",
"fa-briefcase", "fa-bug", "fa-building",
"fa-building-o", "fa-bullhorn",
"fa-bullseye", "fa-bus", "fa-cab",
"fa-calculator", "fa-calendar",
"fa-calendar-check-o", "fa-calendar-minus-o",
"fa-calendar-o", "fa-calendar-plus-o",
"fa-calendar-times-o", "fa-camera",
"fa-camera-retro", "fa-car",
"fa-caret-square-o-down", "fa-caret-square-o-left",
"fa-caret-square-o-right", "fa-caret-square-o-up",
"fa-cart-arrow-down", "fa-cart-plus",
"fa-cc", "fa-certificate", "fa-check",
"fa-check-circle", "fa-check-circle-o",
"fa-check-square", "fa-check-square-o",
"fa-child", "fa-circle", "fa-circle-o",
"fa-circle-o-notch", "fa-circle-thin",
"fa-clock-o", "fa-clone", "fa-close",
"fa-cloud", "fa-cloud-download",
"fa-cloud-upload", "fa-code", "fa-code-fork",
"fa-coffee", "fa-cog", "fa-cogs",
"fa-comment", "fa-comment-o",
"fa-commenting", "fa-commenting-o",
"fa-comments", "fa-comments-o", "fa-compass",
"fa-copyright", "fa-creative-commons",
"fa-credit-card", "fa-credit-card-alt",
"fa-crop", "fa-crosshairs", "fa-cube",
"fa-cubes", "fa-cutlery", "fa-dashboard",
"fa-database", "fa-deaf", "fa-deafness",
"fa-desktop", "fa-diamond",
"fa-dot-circle-o", "fa-download",
"fa-drivers-license", "fa-drivers-license-o",
"fa-edit", "fa-ellipsis-h", "fa-ellipsis-v",
"fa-envelope", "fa-envelope-o",
"fa-envelope-open", "fa-envelope-open-o",
"fa-envelope-square", "fa-eraser",
"fa-exchange", "fa-exclamation",
"fa-exclamation-circle", "fa-exclamation-triangle",
"fa-external-link", "fa-external-link-square",
"fa-eye", "fa-eye-slash", "fa-eyedropper",
"fa-fax", "fa-feed", "fa-female",
"fa-fighter-jet", "fa-file-archive-o",
"fa-file-audio-o", "fa-file-code-o",
"fa-file-excel-o", "fa-file-image-o",
"fa-file-movie-o", "fa-file-pdf-o",
"fa-file-photo-o", "fa-file-picture-o",
"fa-file-powerpoint-o", "fa-file-sound-o",
"fa-file-video-o", "fa-file-word-o",
"fa-file-zip-o", "fa-film", "fa-filter",
"fa-fire", "fa-fire-extinguisher", "fa-flag",
"fa-flag-checkered", "fa-flag-o", "fa-flash",
"fa-flask", "fa-folder", "fa-folder-o",
"fa-folder-open", "fa-folder-open-o",
"fa-frown-o", "fa-futbol-o", "fa-gamepad",
"fa-gavel", "fa-gear", "fa-gears",
"fa-gift", "fa-glass", "fa-globe",
"fa-graduation-cap", "fa-group",
"fa-hand-grab-o", "fa-hand-lizard-o",
"fa-hand-paper-o", "fa-hand-peace-o",
"fa-hand-pointer-o", "fa-hand-rock-o",
"fa-hand-scissors-o", "fa-hand-spock-o",
"fa-hand-stop-o", "fa-handshake-o",
"fa-hard-of-hearing", "fa-hashtag",
"fa-hdd-o", "fa-headphones", "fa-heart",
"fa-heart-o", "fa-heartbeat", "fa-history",
"fa-home", "fa-hotel", "fa-hourglass",
"fa-hourglass-1", "fa-hourglass-2",
"fa-hourglass-3", "fa-hourglass-end",
"fa-hourglass-half", "fa-hourglass-o",
"fa-hourglass-start", "fa-i-cursor",
"fa-id-badge", "fa-id-card", "fa-id-card-o",
"fa-image", "fa-inbox", "fa-industry",
"fa-info", "fa-info-circle",
"fa-institution", "fa-key", "fa-keyboard-o",
"fa-language", "fa-laptop", "fa-leaf",
"fa-legal", "fa-lemon-o", "fa-level-down",
"fa-level-up", "fa-life-bouy",
"fa-life-buoy", "fa-life-ring",
"fa-life-saver", "fa-lightbulb-o",
"fa-line-chart", "fa-location-arrow",
"fa-lock", "fa-low-vision", "fa-magic",
"fa-magnet", "fa-mail-forward",
"fa-mail-reply", "fa-mail-reply-all",
"fa-male", "fa-map", "fa-map-marker",
"fa-map-o", "fa-map-pin", "fa-map-signs",
"fa-meh-o", "fa-microchip", "fa-microphone",
"fa-microphone-slash", "fa-minus",
"fa-minus-circle", "fa-minus-square",
"fa-minus-square-o", "fa-mobile",
"fa-mobile-phone", "fa-money", "fa-moon-o",
"fa-mortar-board", "fa-motorcycle",
"fa-mouse-pointer", "fa-music", "fa-navicon",
"fa-newspaper-o", "fa-object-group",
"fa-object-ungroup", "fa-paint-brush",
"fa-paper-plane", "fa-paper-plane-o",
"fa-paw", "fa-pencil", "fa-pencil-square",
"fa-pencil-square-o", "fa-percent",
"fa-phone", "fa-phone-square", "fa-photo",
"fa-picture-o", "fa-pie-chart", "fa-plane",
"fa-plug", "fa-plus", "fa-plus-circle",
"fa-plus-square", "fa-plus-square-o",
"fa-podcast", "fa-power-off", "fa-print",
"fa-puzzle-piece", "fa-qrcode",
"fa-question", "fa-question-circle",
"fa-question-circle-o", "fa-quote-left",
"fa-quote-right", "fa-random", "fa-recycle",
"fa-refresh", "fa-registered", "fa-remove",
"fa-reorder", "fa-reply", "fa-reply-all",
"fa-retweet", "fa-road", "fa-rocket",
"fa-rss", "fa-rss-square", "fa-s15",
"fa-search", "fa-search-minus",
"fa-search-plus", "fa-send", "fa-send-o",
"fa-server", "fa-share", "fa-share-alt",
"fa-share-alt-square", "fa-share-square",
"fa-share-square-o", "fa-shield", "fa-ship",
"fa-shopping-bag", "fa-shopping-basket",
"fa-shopping-cart", "fa-shower",
"fa-sign-in", "fa-sign-language",
"fa-sign-out", "fa-signal", "fa-signing",
"fa-sitemap", "fa-sliders", "fa-smile-o",
"fa-snowflake-o", "fa-soccer-ball-o",
"fa-sort", "fa-sort-alpha-asc",
"fa-sort-alpha-desc", "fa-sort-amount-asc",
"fa-sort-amount-desc", "fa-sort-asc",
"fa-sort-desc", "fa-sort-down",
"fa-sort-numeric-asc", "fa-sort-numeric-desc",
"fa-sort-up", "fa-space-shuttle",
"fa-spinner", "fa-spoon", "fa-square",
"fa-square-o", "fa-star", "fa-star-half",
"fa-star-half-empty", "fa-star-half-full",
"fa-star-half-o", "fa-star-o",
"fa-sticky-note", "fa-sticky-note-o",
"fa-street-view", "fa-suitcase", "fa-sun-o",
"fa-support", "fa-tablet", "fa-tachometer",
"fa-tag", "fa-tags", "fa-tasks",
"fa-taxi", "fa-television", "fa-terminal",
"fa-thermometer", "fa-thermometer-0",
"fa-thermometer-1", "fa-thermometer-2",
"fa-thermometer-3", "fa-thermometer-4",
"fa-thermometer-empty", "fa-thermometer-full",
"fa-thermometer-half", "fa-thermometer-quarter",
"fa-thermometer-three-quarters", "fa-thumb-tack",
"fa-thumbs-down", "fa-thumbs-o-down",
"fa-thumbs-o-up", "fa-thumbs-up",
"fa-ticket", "fa-times", "fa-times-circle",
"fa-times-circle-o", "fa-times-rectangle",
"fa-times-rectangle-o", "fa-tint",
"fa-toggle-down", "fa-toggle-left",
"fa-toggle-off", "fa-toggle-on",
"fa-toggle-right", "fa-toggle-up",
"fa-trademark", "fa-trash", "fa-trash-o",
"fa-tree", "fa-trophy", "fa-truck",
"fa-tty", "fa-tv", "fa-umbrella",
"fa-universal-access", "fa-university",
"fa-unlock", "fa-unlock-alt", "fa-unsorted",
"fa-upload", "fa-user", "fa-user-circle",
"fa-user-circle-o", "fa-user-o",
"fa-user-plus", "fa-user-secret",
"fa-user-times", "fa-users", "fa-vcard",
"fa-vcard-o", "fa-video-camera",
"fa-volume-control-phone", "fa-volume-down",
"fa-volume-off", "fa-volume-up",
"fa-warning", "fa-wheelchair",
"fa-wheelchair-alt", "fa-wifi",
"fa-window-close", "fa-window-close-o",
"fa-window-maximize", "fa-window-minimize",
"fa-window-restore", "fa-wrench",
"fa-american-sign-language-interpreting",
"fa-asl-interpreting",
"fa-assistive-listening-systems",
"fa-audio-description", "fa-blind",
"fa-braille", "fa-cc", "fa-deaf",
"fa-deafness", "fa-hard-of-hearing",
"fa-low-vision", "fa-question-circle-o",
"fa-sign-language", "fa-signing", "fa-tty",
"fa-universal-access", "fa-volume-control-phone",
"fa-wheelchair", "fa-wheelchair-alt",
"fa-hand-grab-o", "fa-hand-lizard-o",
"fa-hand-o-down", "fa-hand-o-left",
"fa-hand-o-right", "fa-hand-o-up",
"fa-hand-paper-o", "fa-hand-peace-o",
"fa-hand-pointer-o", "fa-hand-rock-o",
"fa-hand-scissors-o", "fa-hand-spock-o",
"fa-hand-stop-o", "fa-thumbs-down",
"fa-thumbs-o-down", "fa-thumbs-o-up",
"fa-thumbs-up", "fa-ambulance",
"fa-automobile", "fa-bicycle", "fa-bus",
"fa-cab", "fa-car", "fa-fighter-jet",
"fa-motorcycle", "fa-plane", "fa-rocket",
"fa-ship", "fa-space-shuttle", "fa-subway",
"fa-taxi", "fa-train", "fa-truck",
"fa-wheelchair", "fa-wheelchair-alt",
"fa-genderless", "fa-intersex", "fa-mars",
"fa-mars-double", "fa-mars-stroke",
"fa-mars-stroke-h", "fa-mars-stroke-v",
"fa-mercury", "fa-neuter", "fa-transgender",
"fa-transgender-alt", "fa-venus",
"fa-venus-double", "fa-venus-mars",
"fa-file", "fa-file-archive-o",
"fa-file-audio-o", "fa-file-code-o",
"fa-file-excel-o", "fa-file-image-o",
"fa-file-movie-o", "fa-file-o",
"fa-file-pdf-o", "fa-file-photo-o",
"fa-file-picture-o", "fa-file-powerpoint-o",
"fa-file-sound-o", "fa-file-text",
"fa-file-text-o", "fa-file-video-o",
"fa-file-word-o", "fa-file-zip-o",
"fa-circle-o-notch", "fa-cog", "fa-gear",
"fa-refresh", "fa-spinner",
"fa-check-square", "fa-check-square-o",
"fa-circle", "fa-circle-o",
"fa-dot-circle-o", "fa-minus-square",
"fa-minus-square-o", "fa-plus-square",
"fa-plus-square-o", "fa-square",
"fa-square-o", "fa-cc-amex",
"fa-cc-diners-club", "fa-cc-discover",
"fa-cc-jcb", "fa-cc-mastercard",
"fa-cc-paypal", "fa-cc-stripe", "fa-cc-visa",
"fa-credit-card", "fa-credit-card-alt",
"fa-google-wallet", "fa-paypal",
"fa-area-chart", "fa-bar-chart",
"fa-bar-chart-o", "fa-line-chart",
"fa-pie-chart", "fa-bitcoin", "fa-btc",
"fa-cny", "fa-dollar", "fa-eur",
"fa-euro", "fa-gbp", "fa-gg",
"fa-gg-circle", "fa-ils", "fa-inr",
"fa-jpy", "fa-krw", "fa-money",
"fa-rmb", "fa-rouble", "fa-rub",
"fa-ruble", "fa-rupee", "fa-shekel",
"fa-sheqel", "fa-try", "fa-turkish-lira",
"fa-usd", "fa-won", "fa-yen",
"fa-align-center", "fa-align-justify",
"fa-align-left", "fa-align-right", "fa-bold",
"fa-chain", "fa-chain-broken",
"fa-clipboard", "fa-columns", "fa-copy",
"fa-cut", "fa-dedent", "fa-eraser",
"fa-file", "fa-file-o", "fa-file-text",
"fa-file-text-o", "fa-files-o",
"fa-floppy-o", "fa-font", "fa-header",
"fa-indent", "fa-italic", "fa-link",
"fa-list", "fa-list-alt", "fa-list-ol",
"fa-list-ul", "fa-outdent", "fa-paperclip",
"fa-paragraph", "fa-paste", "fa-repeat",
"fa-rotate-left", "fa-rotate-right",
"fa-save", "fa-scissors", "fa-strikethrough",
"fa-subscript", "fa-superscript", "fa-table",
"fa-text-height", "fa-text-width", "fa-th",
"fa-th-large", "fa-th-list", "fa-underline",
"fa-undo", "fa-unlink",
"fa-angle-double-down", "fa-angle-double-left",
"fa-angle-double-right", "fa-angle-double-up",
"fa-angle-down", "fa-angle-left",
"fa-angle-right", "fa-angle-up",
"fa-arrow-circle-down", "fa-arrow-circle-left",
"fa-arrow-circle-o-down", "fa-arrow-circle-o-left",
"fa-arrow-circle-o-right", "fa-arrow-circle-o-up",
"fa-arrow-circle-right", "fa-arrow-circle-up",
"fa-arrow-down", "fa-arrow-left",
"fa-arrow-right", "fa-arrow-up", "fa-arrows",
"fa-arrows-alt", "fa-arrows-h",
"fa-arrows-v", "fa-caret-down",
"fa-caret-left", "fa-caret-right",
"fa-caret-square-o-down", "fa-caret-square-o-left",
"fa-caret-square-o-right", "fa-caret-square-o-up",
"fa-caret-up", "fa-chevron-circle-down",
"fa-chevron-circle-left", "fa-chevron-circle-right",
"fa-chevron-circle-up", "fa-chevron-down",
"fa-chevron-left", "fa-chevron-right",
"fa-chevron-up", "fa-exchange",
"fa-hand-o-down", "fa-hand-o-left",
"fa-hand-o-right", "fa-hand-o-up",
"fa-long-arrow-down", "fa-long-arrow-left",
"fa-long-arrow-right", "fa-long-arrow-up",
"fa-toggle-down", "fa-toggle-left",
"fa-toggle-right", "fa-toggle-up",
"fa-arrows-alt", "fa-backward",
"fa-compress", "fa-eject", "fa-expand",
"fa-fast-backward", "fa-fast-forward",
"fa-forward", "fa-pause", "fa-pause-circle",
"fa-pause-circle-o", "fa-play",
"fa-play-circle", "fa-play-circle-o",
"fa-random", "fa-step-backward",
"fa-step-forward", "fa-stop",
"fa-stop-circle", "fa-stop-circle-o",
"fa-youtube-play", "fa-500px", "fa-adn",
"fa-amazon", "fa-android", "fa-angellist",
"fa-apple", "fa-bandcamp", "fa-behance",
"fa-behance-square", "fa-bitbucket",
"fa-bitbucket-square", "fa-bitcoin",
"fa-black-tie", "fa-bluetooth",
"fa-bluetooth-b", "fa-btc", "fa-buysellads",
"fa-cc-amex", "fa-cc-diners-club",
"fa-cc-discover", "fa-cc-jcb",
"fa-cc-mastercard", "fa-cc-paypal",
"fa-cc-stripe", "fa-cc-visa", "fa-chrome",
"fa-codepen", "fa-codiepie",
"fa-connectdevelop", "fa-contao", "fa-css3",
"fa-dashcube", "fa-delicious",
"fa-deviantart", "fa-digg", "fa-dribbble",
"fa-dropbox", "fa-drupal", "fa-edge",
"fa-eercast", "fa-empire", "fa-envira",
"fa-etsy", "fa-expeditedssl", "fa-fa",
"fa-facebook", "fa-facebook-f",
"fa-facebook-official", "fa-facebook-square",
"fa-firefox", "fa-first-order", "fa-flickr",
"fa-font-awesome", "fa-fonticons",
"fa-fort-awesome", "fa-forumbee",
"fa-foursquare", "fa-free-code-camp",
"fa-ge", "fa-get-pocket", "fa-gg",
"fa-gg-circle", "fa-git", "fa-git-square",
"fa-github", "fa-github-alt",
"fa-github-square", "fa-gitlab", "fa-gittip",
"fa-glide", "fa-glide-g", "fa-google",
"fa-google-plus", "fa-google-plus-circle",
"fa-google-plus-official", "fa-google-plus-square",
"fa-google-wallet", "fa-gratipay", "fa-grav",
"fa-hacker-news", "fa-houzz", "fa-html5",
"fa-imdb", "fa-instagram",
"fa-internet-explorer", "fa-ioxhost",
"fa-joomla", "fa-jsfiddle", "fa-lastfm",
"fa-lastfm-square", "fa-leanpub",
"fa-linkedin", "fa-linkedin-square",
"fa-linode", "fa-linux", "fa-maxcdn",
"fa-meanpath", "fa-medium", "fa-meetup",
"fa-mixcloud", "fa-modx", "fa-odnoklassniki",
"fa-odnoklassniki-square", "fa-opencart",
"fa-openid", "fa-opera", "fa-optin-monster",
"fa-pagelines", "fa-paypal", "fa-pied-piper",
"fa-pied-piper-alt", "fa-pied-piper-pp",
"fa-pinterest", "fa-pinterest-p",
"fa-pinterest-square", "fa-product-hunt",
"fa-qq", "fa-quora", "fa-ra",
"fa-ravelry", "fa-rebel", "fa-reddit",
"fa-reddit-alien", "fa-reddit-square",
"fa-renren", "fa-resistance", "fa-safari",
"fa-scribd", "fa-sellsy", "fa-share-alt",
"fa-share-alt-square", "fa-shirtsinbulk",
"fa-simplybuilt", "fa-skyatlas", "fa-skype",
"fa-slack", "fa-slideshare", "fa-snapchat",
"fa-snapchat-ghost", "fa-snapchat-square",
"fa-soundcloud", "fa-spotify",
"fa-stack-exchange", "fa-stack-overflow",
"fa-steam", "fa-steam-square",
"fa-stumbleupon", "fa-stumbleupon-circle",
"fa-superpowers", "fa-telegram",
"fa-tencent-weibo", "fa-themeisle",
"fa-trello", "fa-tripadvisor", "fa-tumblr",
"fa-tumblr-square", "fa-twitch",
"fa-twitter", "fa-twitter-square", "fa-usb",
"fa-viacoin", "fa-viadeo",
"fa-viadeo-square", "fa-vimeo",
"fa-vimeo-square", "fa-vine", "fa-vk",
"fa-wechat", "fa-weibo", "fa-weixin",
"fa-whatsapp", "fa-wikipedia-w",
"fa-windows", "fa-wordpress",
"fa-wpbeginner", "fa-wpexplorer",
"fa-wpforms", "fa-xing", "fa-xing-square",
"fa-y-combinator", "fa-y-combinator-square",
"fa-yahoo", "fa-yc", "fa-yc-square",
"fa-yelp", "fa-yoast", "fa-youtube",
"fa-youtube-play", "fa-youtube-square",
"fa-ambulance", "fa-h-square", "fa-heart",
"fa-heart-o", "fa-heartbeat",
"fa-hospital-o", "fa-medkit",
"fa-plus-square", "fa-stethoscope",
"fa-user-md", "fa-wheelchair",
"fa-wheelchair-alt"];
        $options = [
            'fw' => 'Fixed Width',
            'spin' => 'Spinning',
            'larger' => ['' => '- Size -
', 'lg' => 'Large', '2x' =>
'2x', '3x' => '3x', '4x' =>
'4x', '5x' => '5x'],
            'rotation' => ['' => '- Rotation
-', 'flip-horizontal' => 'Horizontal Flip',
'flip-vertical' => 'Vertical Flip',
'rotate-90' => 'Rotate 90°', 'rotate-180'
=> 'Rotate 180°', 'rotate-270' => 'Rotate
270°']
        ];

        $list = array_unique($list);
        sort($list);

        $response['html'] =
$this->render('@gantry-admin/ajax/icons.html.twig',
['icons' => $list, 'options' => $options,
'total' => count($list)]);

        return new JsonResponse($response);
    }
}
PK��[�DEL L
Controller/Json/Layouts.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Layout\Layout;
use Gantry\Component\Response\JsonResponse;

/**
 * Class Layouts
 * @package Gantry\Admin\Controller\Json
 */
class Layouts extends JsonController
{
    protected $httpVerbs = [
        'GET' => [
            '/' => 'index',
            '/*' => 'index',
            '/particle' => 'particle'
        ],
        'POST' => [
            '/' => 'index',
            '/*' => 'index',
            '/particle' => 'particle'
        ]
    ];
    
    public function index()
    {
        $path = implode('/', func_get_args());

        $post = $this->request->request;

        $outline = $post['outline'];
        $type = $post['type'];
        $subtype = $post['subtype'];
        $inherit = $post['inherit'];
        $clone = $post['mode'] === 'clone';
        $id = $post['id'];

        $this->container['outline'] = $outline;
        $this->container['configuration'] = $outline;

        $layout = Layout::instance($outline);
        if ($inherit) {
            $layout->inheritAll();
        }

        if ($path == 'list' &&
!$layout->isLayoutType($type)) {
            $instance = $this->getParticleInstances($outline, $subtype,
null);
            $id = $instance['selected'];
        }

        $item = $layout->find($id);
        $type = isset($item->type) ? $item->type : $type;
        $subtype = isset($item->subtype) ? $item->subtype : $subtype;
        $item->attributes = isset($item->attributes) ? (array)
$item->attributes : [];
        $block = $layout->block($id);
        $block = isset($block->attributes) ? (array)
$block->attributes : [];

        $params = [
            'gantry'        => $this->container,
            'parent'        => 'settings',
            'route'         =>
"configurations.{$outline}.settings",
            'inherit'       => $inherit ? $outline : null,
        ];

        if ($layout->isLayoutType($type)) {
            $name = $type;
            $particle = false;
            $defaults = [];
            $blueprints =
BlueprintForm::instance("layout/{$name}.yaml",
'gantry-admin://blueprints');
        } else {
            $name = $subtype;
            $particle = true;
            $defaults =
$this->container['config']->get("particles.{$name}");
            $item->attributes = $item->attributes + $defaults;
            $blueprints =
$this->container['particles']->getBlueprintForm($name);
            $blueprints->set('form/fields/_inherit',
['type' => 'gantry.inherit']);
        }

        $paramsParticle = [
            'title'         => isset($item->title) ?
$item->title : '',
            'blueprints'    =>
$blueprints->get('form'),
            'item'          => $item,
            'data'          => ['particles' =>
[$name => $item->attributes]],
            'defaults'      => ['particles' =>
[$name => $defaults]],
            'prefix'        => "particles.{$name}.",
            'editable'      => $particle,
            'overrideable'  => $particle,
            'skip'          => ['enabled']
        ] + $params;

        $html['g-settings-particle'] =
$this->render('@gantry-admin/pages/configurations/layouts/particle-card.html.twig',
 $paramsParticle);
        $html['g-settings-block-attributes'] =
$this->renderBlockFields($block, $params);
        if ($path == 'list') {
            $html['g-inherit-particle'] =
$this->renderParticlesInput($inherit || $clone ? $outline : null,
$subtype, $post['selected']);
        }

        return new JsonResponse(['json' => $item,
'html' => $html]);
    }

    public function particle()
    {
        $post = $this->request->request;

        $outline = $post['outline'];
        $id = $post['id'];

        $this->container['outline'] = $outline;
        $this->container['configuration'] = $outline;

        $layout = Layout::instance($outline);

        $particle = clone $layout->find($id);
        if (!isset($particle->type)) {
            throw new \RuntimeException('Particle was not found from
the outline', 404);
        }

        $particle->block = $layout->block($id);

        $name = $particle->subtype;
        $prefix = "particles.{$name}";
        $defaults = (array)
$this->container['config']->get($prefix);
        $attributes = (array) $particle->attributes + $defaults;

        $particleBlueprints =
$this->container['particles']->getBlueprintForm($name);
        $particleBlueprints->set('form/fields/_inherit',
['type' => 'gantry.inherit']);

        $blockBlueprints =
BlueprintForm::instance('layout/block.yaml',
'gantry-admin://blueprints');

        // TODO: Use blueprints to merge configuration.
        $particle->attributes = (object) $attributes;

        $this->params['id'] = $name;
        $this->params += [
            'extra'         => $blockBlueprints,
            'item'          => $particle,
            'data'          => ['particles' =>
[$name => $attributes]],
            'defaults'      => ['particles' =>
[$name => $defaults]],
            'prefix'        => "particles.{$name}.",
            'particle'      => $particleBlueprints,
            'parent'        => 'settings',
            'route'         =>
"configurations.{$outline}.settings",
            'action'        => str_replace('.',
'/', 'configurations.' . $outline .
'.layout.' . $prefix . '.validate'),
            'skip'          => ['enabled'],
            'editable'      => false,
            'overrideable'  => true,
        ];

        $html =
$this->render('@gantry-admin/pages/configurations/layouts/particle-preview.html.twig',
$this->params);

        return new JsonResponse(['html' => $html]);
    }

    /**
     * Render block settings.
     *
     * @param array $block
     * @param array $params
     * @return string
     */
     protected function renderBlockFields(array $block, array $params)
     {
         $blockBlueprints =
BlueprintForm::instance('layout/block.yaml',
'gantry-admin://blueprints');

         $paramsBlock = [
                 'title' =>
$this->container['translator']->translate('GANTRY5_PLATFORM_BLOCK'),
                 'blueprints' => ['fields' =>
$blockBlueprints->get('form/fields/block_container/fields')],
                 'data' => ['block' => $block],
                 'prefix' => 'block.',
             ] + $params;

         return
$this->render('@gantry-admin/forms/fields.html.twig', 
$paramsBlock);
     }

    /**
     * Gets the list of available particle instances for an outline
     *
     * @param string $outline
     * @param string $particle
     * @param string $selected
     * @return string
     */

    protected function getParticleInstances($outline, $particle, $selected)
    {
        $list = $outline ?
$this->container['outlines']->getParticleInstances($outline,
$particle, false) : [];
        $selected = isset($list[$selected]) ? $selected : key($list);

        return ['list' => $list, 'selected' =>
$selected];
    }

    /**
     * Render input field for particle picker.
     *
     * @param string $outline
     * @param string $particle
     * @param string $selected
     * @return string
     */
    protected function renderParticlesInput($outline, $particle, $selected)
    {
        $instances = $this->getParticleInstances($outline, $particle,
$selected);

        $params = [
            'layout' => 'input',
            'scope' => 'inherit.',
            'field' => [
                'name' => 'particle',
                'type' => 'gantry.particles',
                'id' => 'g-inherit-particle',
                'outline' => $outline,
                'particles' => $instances['list'],
                'particle' => $particle
            ],
            'value' => $instances['selected']
        ];

        return
$this->render('@gantry-admin/forms/fields/gantry/particles.html.twig',
$params);
    }
}
PK��[�e��))Controller/Json/Particle.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Config\BlueprintSchema;
use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Config\Config;
use Gantry\Component\Response\JsonResponse;

class Particle extends JsonController
{
    protected $httpVerbs = [
        'GET'    => [
            '/'                  =>
'selectParticle',
            '/module'            => 'selectModule'
        ],
        'POST'   => [
            '/'                  => 'undefined',
            '/*'                 => 'particle',
            '/*/validate'        => 'validate',
        ],
        'PUT'    => [
            '/*' => 'replace'
        ],
        'PATCH'  => [
            '/*' => 'update'
        ],
        'DELETE' => [
            '/*' => 'destroy'
        ]
    ];

    /**
     * Return a modal for selecting a particle.
     *
     * @return string
     */
    public function selectParticle()
    {
        $groups = [
            'Particles' => ['particle' => []],
        ];

        $particles = [
            'position'    => [],
            'spacer'      => [],
            'system'      => [],
            'particle'    => [],
        ];

        $particles = array_replace($particles, $this->getParticles());
        unset($particles['atom'],
$particles['position']);

        foreach ($particles as &$group) {
            asort($group);
        }

        foreach ($groups as $section => $children) {
            foreach ($children as $key => $child) {
                $groups[$section][$key] = $particles[$key];
            }
        }

        $this->params['particles'] = $groups;
        return new JsonResponse(['html' =>
$this->render('@gantry-admin/modals/particle-picker.html.twig',
$this->params)]);
    }

    /**
     * Return a modal content for selecting module.
     *
     * @return mixed
     */
    public function selectModule()
    {
        return new JsonResponse(['html' =>
$this->render('@gantry-admin/modals/module-picker.html.twig',
$this->params)]);
    }

    /**
     * Return form for the particle (filled with data coming from POST).
     *
     * @param string $name
     * @return mixed
     */
    public function particle($name)
    {
        $data = $this->request->post['item'];
        if ($data) {
            $data = json_decode($data, true);
        } else {
            $data = $this->request->post->getArray();
        }

        // TODO: add support for other block types as well, like menu.
        // $block = BlueprintForm::instance('layout/block.yaml',
'gantry-admin://blueprints');
        $blueprints =
$this->container['particles']->getBlueprintForm($name);

        // Load particle blueprints and default settings.
        $validator = $this->loadBlueprints('menu');
        $callable = function () use ($validator) {
            return $validator;
        };

        // Create configuration from the defaults.
        $item = new Config($data, $callable);
        $item->def('type', 'particle');
        $item->def('title',
$blueprints->get('name'));
        $item->def('options.type',
$blueprints->get('type', 'particle'));
        $item->def('options.particle', []);
        $item->def('options.block', []);

        $this->params += [
            'item'          => $item,
            // 'block'         => $block,
            'data'          => ['particles' =>
[$name => $item->options['particle']]],
            'particle'      => $blueprints,
            'parent'        => 'settings',
            'prefix'        => "particles.{$name}.",
            'route'         =>
"configurations.default.settings",
            'action'        =>
"particle/{$name}/validate"
        ];

        return new JsonResponse(['html' =>
$this->render('@gantry-admin/modals/particle.html.twig',
$this->params)]);
    }

    /**
     * Validate data for the particle.
     *
     * @param string $name
     * @return JsonResponse
     */
    public function validate($name)
    {
        // Load particle blueprints and default settings.
        $validator = new BlueprintSchema;
        $validator->embed('options',
$this->container['particles']->get($name));

        $blueprints =
$this->container['particles']->getBlueprintForm($name);

        // Create configuration from the defaults.
        $data = new Config([],
            function () use ($validator) {
                return $validator;
            }
        );

        $data->set('type', 'particle');
        $data->set('particle', $name);
        $data->set('title',
$this->request->post['title'] ?:
$blueprints->get('name'));
        $data->set('options.particle',
$this->request->post->getArray("particles.{$name}"));
        $data->def('options.particle.enabled', 1);

        $block =
$this->request->post->getArray('block');
        foreach ($block as $key => $param) {
            if ($param === '') {
                unset($block[$key]);
            }
        }

        if ($block) {
            $data->join('options.block', $block);
        }

        // TODO: validate

        // Fill parameters to be passed to the template file.
        $this->params['item'] = (object) $data->toArray();

        return new JsonResponse(['item' =>
$data->toArray()]);
    }

    protected function getParticles()
    {
        $particles = $this->container['particles']->all();

        $list = [];
        foreach ($particles as $name => $particle) {
            $type = isset($particle['type']) ?
$particle['type'] : 'particle';
            $particleName = isset($particle['name']) ?
$particle['name'] : $name;
            $particleIcon = isset($particle['icon']) ?
$particle['icon'] : null;
            $list[$type][$name] = ['name' => $particleName,
'icon' => $particleIcon];
        }

        return $list;
    }

    /**
     * Load blueprints.
     *
     * @param string $name
     *
     * @return BlueprintForm
     */
    protected function loadBlueprints($name = 'menu')
    {
        return BlueprintForm::instance("menu/{$name}.yaml",
'gantry-admin://blueprints');
    }
}
PK��[�P_�%%Controller/Json/Unsaved.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin\Controller\Json;

use Gantry\Component\Admin\JsonController;
use Gantry\Component\Response\JsonResponse;

class Unsaved extends JsonController
{
    protected $httpVerbs = [
        'GET' => [
            '/' => 'index'
        ]
    ];

    public function index()
    {
        $response = ['html' =>
$this->render('@gantry-admin/ajax/unsaved.html.twig')];
        return new JsonResponse($response);
    }
}
PK��[譤��EventListener.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 RocketTheme, LLC
 * @license   GNU/GPLv2 and later
 *
 * http://www.gnu.org/licenses/gpl-2.0.html
 */

namespace Gantry\Admin;

use Gantry\Component\Layout\Layout;
use Gantry\Joomla\CacheHelper;
use Gantry\Joomla\Manifest;
use Gantry\Joomla\StyleHelper;
use Joomla\Registry\Registry;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\Event\EventSubscriberInterface;
use RocketTheme\Toolbox\File\IniFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class EventListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            'admin.init.theme'  =>
['onAdminThemeInit', 0],
            'admin.global.save' => ['onGlobalSave',
0],
            'admin.styles.save' => ['onStylesSave',
0],
            'admin.settings.save' =>
['onSettingsSave', 0],
            'admin.layout.save' => ['onLayoutSave',
0],
            'admin.assignments.save' =>
['onAssignmentsSave', 0],
            'admin.menus.save' => ['onMenusSave', 0]
        ];
    }

    public function onAdminThemeInit(Event $event)
    {
        \JPluginHelper::importPlugin('gantry5');

        // Trigger the onGantryThemeInit event.
        $dispatcher = \JEventDispatcher::getInstance();
        $dispatcher->trigger('onGantry5AdminInit',
['theme' => $event->theme]);
    }

    public function onGlobalSave(Event $event)
    {
        \JPluginHelper::importPlugin('gantry5');

        // Trigger the onGantryThemeUpdateCss event.
        $dispatcher = \JEventDispatcher::getInstance();
        $dispatcher->trigger('onGantry5SaveConfig',
[$event->data]);
    }

    public function onStylesSave(Event $event)
    {
        \JPluginHelper::importPlugin('gantry5');

        // Trigger the onGantryThemeUpdateCss event.
        $dispatcher = \JEventDispatcher::getInstance();
        $dispatcher->trigger('onGantry5UpdateCss',
['theme' => $event->theme]);
    }

    public function onSettingsSave(Event $event)
    {
    }

    public function onLayoutSave(Event $event)
    {
        /** @var Layout $layout */
        $layout = $event->layout;

        if ($layout->name[0] !== '_' &&
$layout->name !== 'default') {
            $preset = isset($layout->preset['name']) ?
$layout->preset['name'] : 'default';

            // Update Joomla template style.
            StyleHelper::update($layout->name, $preset);
        }

        $theme = $event->gantry['theme.name'];

        $positions =
$event->gantry['outlines']->positions();
        $positions['debug'] = 'Debug';

        $manifest = new Manifest($theme);
        $manifest->setPositions(array_keys($positions));
        $manifest->save();

        $translations = [];
        foreach ($positions as $key => $translation) {
            // Encode translation key in Joomla way.
            $key = preg_replace('/[^A-Z0-9_\-]/', '_',
strtoupper("TPL_{$theme}_POSITION_{$key}"));
            $translations[$key] = $translation;
        }

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

        $filename =
"gantry-theme://language/en-GB/en-GB.tpl_{$theme}_positions.ini";

        $ini = IniFile::instance($locator->findResource($filename, true,
true));
        $ini->save($translations);
        $ini->free();
    }

    public function onAssignmentsSave(Event $event)
    {
    }


    public function onMenusSave(Event $event)
    {
        $defaults = [
            'id' => 0,
            'layout' => 'list',
            'target' => '_self',
            'dropdown' => '',
            'icon' => '',
            'image' => '',
            'subtitle' => '',
            'icon_only' => false,
            'visible' => true,
            'group' => 0,
            'columns' => [],
            'link_title' => '',
            'hash' => '',
            'class' => ''
        ];

        $gantry = $event->gantry;
        $menu = $event->menu;

        // Save global menu settings into Joomla.
        /** @var \JTableMenuType $table */
        $menuType = \JTable::getInstance('MenuType');
        if (!$menuType->load(['menutype' =>
$event->resource])) {
            throw new \RuntimeException("Saving menu failed: Menu type
{$event->resource} not found.", 400);
        }
        $options = [
            'title' => $menu['settings.title'],
            'description' =>
$menu['settings.description']
        ];
        if ($gantry->authorize('menu.edit') &&
!$menuType->save($options)) {
            throw new \RuntimeException('Saving menu failed: '.
$menuType->getError(), 400);
        }

        unset($menu['settings']);

        /** @var \JTableMenu $table */
        $table = \JTable::getInstance('menu');

        foreach ($menu['items'] as $key => $item) {
            $id = !empty($item['id']) ? (int)
$item['id'] : 0;
            if ($id && $table->load($item['id'])) {
                $params = new Registry($table->params);

                // Menu item exists in Joomla, let's update it
instead.
                unset($item['type'], $item['link']);

                $item['id'] = (int) $id;

                $title = $menu["items.{$key}.title"];
                $browserNav = intval($menu["items.{$key}.target"]
=== '_blank');

                $options = [
                    // Disabled as the option has different meaning in
Joomla than in Gantry, see issue #1656.
                    // 'menu-anchor_css' =>
$menu["items.{$key}.class"],
                    'menu_image' =>
$menu["items.{$key}.image"],
                    'menu_text' =>
intval(!$menu["items.{$key}.icon_only"]),
                    'menu_show' =>
intval($menu["items.{$key}.enabled"]),
                ];

                $modified = false;

                if ($table->title != $title) {
                    $table->title = $title;
                    $modified = true;
                }

                if ($table->browserNav != $browserNav) {
                    $table->browserNav = $browserNav;
                    $modified = true;
                }

                foreach ($options as $var => $value) {
                    if ($params->get($var) !== $value) {
                        $params->set($var, $value);
                        $modified = true;
                    }
                }

                if ($modified &&
$gantry->authorize('menu.edit')) {
                    $table->params = (string) $params;
                    if (!$table->check() || !$table->store()) {
                        throw new \RuntimeException("Failed to save
/{$key}: {$table->getError()}", 400);
                    }
                }

                // Avoid saving values which are also stored in Joomla.
                unset($item['title'],
$item['anchor_class'], $item['image'],
$item['icon_only'], $item['target']);
                if (version_compare(JVERSION, '3.5.1',
'>=')) {
                    unset($item['enabled']);
                }

            }

            // Do not save default values.
            foreach ($defaults as $var => $value) {
                if (isset($item[$var]) && $item[$var] == $value) {
                    unset($item[$var]);
                }
            }

            // Do not save derived values.
            unset($item['path'], $item['alias'],
$item['parent_id'], $item['level'],
$item['group']);

            // Particles have no link.
            if (isset($item['type']) &&
$item['type'] === 'particle') {
                unset($item['link']);
            }

            // Because of ordering we need to save all menu items,
including those from Joomla which have no data except id.
            $event->menu["items.{$key}"] = $item;
        }

        // Clean the cache.
        CacheHelper::cleanMenu();
    }
}
PK��[uTQ'Page.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin;

use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Config\ConfigFileFinder;
use Gantry\Component\File\CompiledYamlFile;
use Gantry\Framework\Theme as SiteTheme;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Page
{
    protected $container;
    protected $files;
    protected $blocks;

    public function __construct($container)
    {
        $this->container = $container;
    }

    public function all()
    {
        if (!$this->blocks)
        {
            $files = $this->locateBlocks();

            $this->blocks = [];
            foreach ($files as $key => $fileArray) {
                $filename = key($fileArray);
                $file = CompiledYamlFile::instance(GANTRY5_ROOT .
'/' . $filename);
                $this->blocks[$key] = $file->content();
                $file->free();
            }
        }

        return $this->blocks;
    }

    public function group()
    {
        $blocks = $this->all();

        $list = [];
        foreach ($blocks as $name => $setting) {
            $type = isset($setting['type']) ?
$setting['type'] : '';
            $list[$type][$name] = $setting;
        }

        return $this->sort($list);
    }

    public function get($id)
    {
        if ($this->blocks[$id]) {
            return $this->blocks[$id];
        }

        $files = $this->locateBlocks();

        if (empty($files[$id])) {
            throw new \RuntimeException(sprintf("Settings for
'%s' not found.", $id), 404);
        }

        $filename = key($files[$id]);
        $file = CompiledYamlFile::instance(GANTRY5_ROOT . '/' .
$filename);
        $setting = $file->content();
        $file->free();

        return $setting;
    }

    /**
     * @param string $id
     * @return BlueprintForm
     */
    public function getBlueprintForm($id)
    {
        return BlueprintForm::instance($id,
'gantry-blueprints://page');
    }

    protected function sort(array $blocks)
    {
        $list = [];

        /** @var SiteTheme $theme */
        $theme = $this->container['theme'];
        $ordering = (array) $theme->details()['admin.page'];
        if (!count($ordering)) {
            $ordering = ['global' => ['head',
'assets', 'body', 'generics']];
        }

        ksort($blocks);

        foreach ($ordering as $name => $order) {
            if (isset($blocks[$name])) {
                $list[$name] = $this->sortItems($blocks[$name], (array)
$order);
            }
        }
        $list += $blocks;

        return $list;
    }

    protected function sortItems(array $items, array $ordering)
    {
        $list = [];

        ksort($items);

        foreach ($ordering as $name) {
            if (isset($items[$name])) {
                $list[$name] = $items[$name];
            }
        }
        $list += $items;

        return $list;
    }

    protected function locateBlocks()
    {
        if (!$this->files) {
            /** @var UniformResourceLocator $locator */
            $locator = $this->container['locator'];
            $paths =
$locator->findResources('gantry-blueprints://page');

            $this->files = (new ConfigFileFinder)->listFiles($paths);
        }

        return $this->files;
    }
}
PK��[�Ht���
Particles.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin;

use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Config\ConfigFileFinder;
use Gantry\Component\File\CompiledYamlFile;
use Gantry\Framework\Theme as SiteTheme;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Particles
{
    protected $container;
    protected $files;
    protected $particles;

    public function __construct($container)
    {
        $this->container = $container;
    }

    public function overrides($outline, $particle = null)
    {
        if ($outline === 'default') {
            return true;
        }

        /** @var UniformResourceLocator $locator */
        $locator = $this->container['locator'];

        if ($particle) {
            // PHP 5.4
            $resource =
$locator->findResources("gantry-theme://config/{$outline}/particles/{$particle}.yaml");
            return !empty($resource);
        }

        // PHP 5.4
        $resource =
$locator->findResources("gantry-theme://config/{$outline}/particles");
        return !empty($resource);
    }

    public function all()
    {
        if (null === $this->particles) {
            $platform = $this->container['platform'];
            $files = $this->locateParticles();

            $this->particles = [];
            foreach ($files as $key => $fileArray) {
                $filename = key($fileArray);
                $file = CompiledYamlFile::instance(GANTRY5_ROOT .
'/' . $filename);
                $particle = $file->content();
                $file->free();

                if (!isset($particle['dependencies']) ||
$platform->checkDependencies($particle['dependencies'])) {
                    $this->particles[$key] = $particle;
                }
            }
        }

        return $this->particles;
    }

    public function group($exclude = [])
    {
        $particles = $this->all();

        $list = [];
        foreach ($particles as $name => $particle) {
            $type = isset($particle['type']) ?
$particle['type'] : 'particle';
            if (in_array($type, $exclude)) {
                continue;
            }
            if (in_array($type, ['spacer', 'system']))
{
                $type = 'position';
            }
            $list[$type][$name] = $particle;
        }

        return $this->sort($list);
    }

    public function get($id)
    {
        if (isset($this->particles[$id])) {
            return $this->particles[$id];
        }

        $files = $this->locateParticles();

        if (empty($files[$id])) {
            throw new \RuntimeException(sprintf("Settings for
'%s' not found.", $id), 404);
        }

        $filename = key($files[$id]);
        $file = CompiledYamlFile::instance(GANTRY5_ROOT . '/' .
$filename);
        $particle = $file->content();
        $particle['subtype'] = $id; // TODO: can this be done
better or is it fine like that?
        $file->free();

        return $particle;
    }

    /**
     * @param string $id
     * @return BlueprintForm
     */
    public function getBlueprintForm($id)
    {
        return BlueprintForm::instance($id,
'gantry-blueprints://particles');
    }

    protected function sort(array $blocks)
    {
        $list = [];

        /** @var SiteTheme $theme */
        $theme = $this->container['theme'];
        $ordering = (array)
$theme->details()['admin.settings'] ?: [
                'particle' => [],
                'position' => ['position',
'spacer', 'messages', 'content'],
                'atom' => []
            ];

        ksort($blocks);

        foreach ($ordering as $name => $order) {
            if (isset($blocks[$name])) {
                $list[$name] = $this->sortItems($blocks[$name], (array)
$order);
            }
        }
        $list += $blocks;

        return $list;
    }


    protected function sortItems(array $items, array $ordering)
    {
        $list = [];

        ksort($items);

        foreach ($ordering as $name) {
            if (isset($items[$name])) {
                $list[$name] = $items[$name];
            }
        }
        $list += $items;

        return $list;
    }

    protected function locateParticles()
    {
        if (!$this->files) {
            /** @var UniformResourceLocator $locator */
            $locator = $this->container['locator'];
            $paths =
$locator->findResources('gantry-blueprints://particles');

            $this->files = (new ConfigFileFinder)->listFiles($paths);
        }

        return $this->files;
    }
}
PK��[�w�22
Router.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 RocketTheme, LLC
 * @license   GNU/GPLv2 and later
 *
 * http://www.gnu.org/licenses/gpl-2.0.html
 */

namespace Gantry\Admin;

use Gantry\Component\File\CompiledYamlFile;
use Gantry\Component\Request\Request;
use Gantry\Component\Response\JsonResponse;
use Gantry\Component\Response\Response;
use Gantry\Component\Router\Router as BaseRouter;
use Gantry\Joomla\StyleHelper;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

/**
 * Gantry administration router for Joomla.
 */
class Router extends BaseRouter
{
    public function boot()
    {
        \JHtml::_('behavior.keepalive');

        $app = \JFactory::getApplication();
        $input = $app->input;

        // TODO: Remove style variable.
        $style = $input->getInt('style');
        $theme = $input->getCmd('theme');
        $path = array_filter(explode('/',
$input->getString('view', '')), function($var) {
return $var !== ''; });

        $this->setTheme($theme, $style);

        /** @var Request $request */
        $request = $this->container['request'];

        $this->method = $request->getMethod();
        $this->path = $path ?:
(isset($this->container['theme.name']) ?
['configurations', true] : ['themes']);
        $this->resource = array_shift($this->path);
        $this->format = $input->getCmd('format',
'html');
        $ajax = ($this->format == 'json');

        $this->params = [
            'user' => \JFactory::getUser(),
            'ajax' => $ajax,
            'location' => $this->resource,
            'method' => $this->method,
            'format' => $this->format,
            'params' =>
$request->post->getJsonArray('params')
        ];

        return $this;
    }

    public function setTheme($theme, $style)
    {
        if ($style) {
            \JTable::addIncludePath(JPATH_ADMINISTRATOR .
'/components/com_templates/tables');
            $table = \JTable::getInstance('Style',
'TemplatesTable');
            $table->load(['id' => $style,
'client_id' => 0]);

            $theme = $table->template;
        }
        if (!$theme) {
            $theme = StyleHelper::getDefaultStyle()->template;
        }

        $path = JPATH_SITE . '/templates/' . $theme;

        if (!is_file("{$path}/gantry/theme.yaml")) {
            $theme = null;
            $this->container['streams']->register();

            /** @var UniformResourceLocator $locator */
            $locator = $this->container['locator'];

            CompiledYamlFile::$defaultCachePath =
$locator->findResource('gantry-cache://theme/compiled/yaml',
true, true);
            CompiledYamlFile::$defaultCaching =
$this->container['global']->get('compile_yaml',
1);
        }

        $this->container['base_url'] = \JUri::base(true) .
'/index.php?option=com_gantry5';

        $this->container['ajax_suffix'] =
'&format=json';

        $token = \JSession::getFormToken();

        $this->container['routes'] = [
            '1' =>
"&view=%s&theme={$theme}&{$token}=1",

            'themes' => '&view=themes',
            'picker/layouts' =>
"&view=layouts&theme={$theme}&{$token}=1",
        ];

        if (!$theme) {
            return $this;
        }

        $this->container['theme.path'] = $path;
        $this->container['theme.name'] = $theme;

        // Load language file for the template.
        $languageFile = 'tpl_' . $theme;
        $lang = \JFactory::getLanguage();
        $lang->load($languageFile, JPATH_SITE)
            || $lang->load($languageFile, $path)
            || $lang->load($languageFile, $path, 'en-GB');

        return $this;
    }

    protected function checkSecurityToken()
    {
        return \JSession::checkToken('get');
    }

    /**
     * Send response to the client.
     *
     * @param Response $response
     * @return string
     */
    protected function send(Response $response)
    {
        $app = \JFactory::getApplication();
        $document = \JFactory::getDocument();
        $document->setCharset($response->charset);
        $document->setMimeEncoding($response->mimeType);

        // Output HTTP header.
        $app->setHeader('Status', $response->getStatus());
        $app->setHeader('Content-Type', $response->mimeType
. '; charset=' . $response->charset);
        foreach ($response->getHeaders() as $key => $values) {
            $replace = true;
            foreach ($values as $value) {
                $app->setHeader($key, $value, $replace);
                $replace = false;
            }
        }

        if ($response instanceof JsonResponse) {
            $app->setHeader('Expires', 'Wed, 17 Aug 2005
00:00:00 GMT', true);
            $app->setHeader('Last-Modified', gmdate('D, d
M Y H:i:s') . ' GMT', true);
            $app->setHeader('Cache-Control', 'no-store,
no-cache, must-revalidate, post-check=0, pre-check=0', false);
            $app->setHeader('Pragma', 'no-cache');
            $app->sendHeaders();
        }

        // Output Gantry response.
        echo $response;

        if ($response instanceof JsonResponse) {
            $app->close();
        }
    }
}
PK��[\��Ɵ
�
Styles.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin;

use Gantry\Component\Config\BlueprintForm;
use Gantry\Component\Config\ConfigFileFinder;
use Gantry\Component\File\CompiledYamlFile;
use Gantry\Framework\Theme as SiteTheme;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Styles
{
    protected $container;
    protected $files;
    protected $blocks;

    public function __construct($container)
    {
        $this->container = $container;
    }

    public function all()
    {
        if (!$this->blocks)
        {
            $files = $this->locateBlocks();

            $this->blocks = [];
            foreach ($files as $key => $fileArray) {
                $filename = key($fileArray);
                $file = CompiledYamlFile::instance(GANTRY5_ROOT .
'/' . $filename);
                $this->blocks[$key] = $file->content();
                $file->free();
            }
        }

        return $this->blocks;
    }

    public function group()
    {
        $blocks = $this->all();

        $list = [];
        foreach ($blocks as $name => $style) {
            $type = isset($style['type']) ?
$style['type'] : 'block';
            $list[$type][$name] = $style;
        }

        return $this->sort($list);
    }

    public function get($id)
    {
        if ($this->blocks[$id]) {
            return $this->blocks[$id];
        }

        $files = $this->locateBlocks();

        if (empty($files[$id])) {
            throw new \RuntimeException(sprintf("Settings for
'%s' not found.", $id), 404);
        }

        $filename = key($files[$id]);
        $file = CompiledYamlFile::instance(GANTRY5_ROOT . '/' .
$filename);
        $particle = $file->content();
        $file->free();

        return $particle;
    }

    /**
     * @param string $id
     * @return BlueprintForm
     */
    public function getBlueprintForm($id)
    {
        return BlueprintForm::instance($id,
'gantry-blueprints://styles');
    }

    protected function sort(array $blocks)
    {
        $list = [];

        /** @var SiteTheme $theme */
        $theme = $this->container['theme'];
        $ordering = (array) $theme->details()['admin.styles'];

        ksort($blocks);

        foreach ($ordering as $name => $order) {
            if (isset($blocks[$name])) {
                $list[$name] = $this->sortItems($blocks[$name], (array)
$order);
            }
        }
        $list += $blocks;

        return $list;
    }

    protected function sortItems(array $items, array $ordering)
    {
        $list = [];

        ksort($items);

        foreach ($ordering as $name) {
            if (isset($items[$name])) {
                $list[$name] = $items[$name];
            }
        }
        $list += $items;

        return $list;
    }

    protected function locateBlocks()
    {
        if (!$this->files) {
            /** @var UniformResourceLocator $locator */
            $locator = $this->container['locator'];
            $paths =
$locator->findResources('gantry-blueprints://styles');

            $this->files = (new ConfigFileFinder)->listFiles($paths);
        }

        return $this->files;
    }
}
PK��[�Y�zpp	Theme.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 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\Admin;

use Gantry\Component\Config\CompiledConfig;
use Gantry\Component\Config\ConfigFileFinder;
use Gantry\Component\Filesystem\Folder;
use Gantry\Component\Theme\AbstractTheme;
use Gantry\Framework\Platform;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;

class Theme extends AbstractTheme
{
    /**
     * @see AbstractTheme::init()
     */
    protected function init()
    {
        $gantry = static::gantry();

        // Add particles, styles and defaults into DI.

        $gantry['particles'] = function ($c) {
            return new Particles($c);
        };

        $gantry['styles'] = function ($c) {
            return new Styles($c);
        };

        $gantry['page'] = function ($c) {
            return new Page($c);
        };

        $gantry['defaults'] = function($c) {
            /** @var UniformResourceLocator $locator */
            $locator = $c['locator'];

            $cache =
$locator->findResource('gantry-cache://theme/compiled/config',
true, true);
            $paths =
$locator->findResources('gantry-config://default');

            $files = (new ConfigFileFinder)->locateFiles($paths);

            $config = new CompiledConfig($cache, $files, GANTRY5_ROOT);
            $config->setBlueprints(function() use ($c) {
                return $c['blueprints'];
            });

            return $config->load(true);
        };

        // Initialize admin streams.

        /** @var Platform $patform */
        $patform = $gantry['platform'];

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

        $nucleus =
$patform->getEnginePaths('nucleus')[''];
        if (strpos($this->path, '://')) {
            $relpath = $this->path;
        } else {
            $relpath = Folder::getRelativePath($this->path);
        }
        $patform->set(
            'streams.gantry-admin.prefixes', [
                ''        =>
['gantry-theme://admin', $relpath, $relpath .
'/common', 'gantry-engine://admin'],
                'assets/' => array_merge([$relpath, $relpath .
'/common'], $nucleus, ['gantry-assets://'])
            ]
        );

        // Add admin paths.
        foreach
($patform->get('streams.gantry-admin.prefixes') as $prefix
=> $paths) {
            $locator->addPath('gantry-admin', $prefix,
$paths);
        }

        // Fire admin init event.
        $event = new Event;
        $event->gantry = $gantry;
        $event->theme = $this;
        $gantry->fireEvent('admin.init.theme', $event);
    }

    /**
     * @see AbstractTheme::getCachePath()
     *
     * @param string $path
     * @return string
     */
    protected function getCachePath($path = '')
    {
        $gantry = static::gantry();

        /** @var Platform $patform */
        $patform = $gantry['platform'];

        // Initialize theme cache stream.
        return $patform->getCachePath() . '/admin' . ($path ?
'/' . $path : '');
    }

    /**
     * @see AbstractTheme::setTwigLoaderPaths()
     *
     * @param \Twig_LoaderInterface $loader
     */
    protected function setTwigLoaderPaths(\Twig_LoaderInterface $loader)
    {
        if (!($loader instanceof \Twig_Loader_Filesystem)) {
            return;
        }

        $gantry = static::gantry();

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

       
$loader->setPaths($locator->findResources('gantry-admin://templates'));
       
$loader->setPaths($locator->findResources('gantry-admin://templates'),
'gantry-admin');
    }
}
PK��[܁l
ThemeList.phpnu�[���<?php
/**
 * @package   Gantry5
 * @author    RocketTheme http://www.rockettheme.com
 * @copyright Copyright (C) 2007 - 2017 RocketTheme, LLC
 * @license   GNU/GPLv2 and later
 *
 * http://www.gnu.org/licenses/gpl-2.0.html
 */

namespace Gantry\Admin;

use Gantry\Component\Filesystem\Folder;
use Gantry\Component\Theme\ThemeDetails;
use Gantry\Framework\Gantry;
use Joomla\Registry\Registry;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;


class ThemeList
{
    /**
     * @var ThemeDetails[]
     */
    protected static $items;

    /**
     * @var array
     */
    protected static $styles;

    /**
     * @return array
     */
    public static function getThemes()
    {
        if (!is_array(static::$items)) {
            static::loadThemes();
        }

        $list = [];
        foreach (static::$items as $item) {
            $details = static::getTheme($item['name']);
            if ($details) {
                $list[$item['name']] = $details;
            }
        }

        return $list;
    }

    /**
     * @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()
    {
        $gantry = Gantry::instance();

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

        /** @var array|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'] =
$gantry['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;
    }

    protected static function loadStyles()
    {
        $gantry = Gantry::instance();
        $db = \JFactory::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 array|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'] =
$gantry['platform']->getThemePreviewUrl($style->id);
            $details['params'] = $params->toArray();

            $list[$style->name][$style->id] = $details;
        }

        static::$styles = $list;
    }
}
PK��[���Controller/Html/About.phpnu�[���PK��[$�_EYYTController/Html/Cache.phpnu�[���PK��[��x�		.�Controller/Html/Configurations/Assignments.phpnu�[���PK��[�}mFmF)qController/Html/Configurations/Layout.phpnu�[���PK��['��L-L-'7XController/Html/Configurations/Page.phpnu�[���PK��[�Qޙ""+څController/Html/Configurations/Settings.phpnu�[���PK��[�[T�

)N�Controller/Html/Configurations/Styles.phpnu�[���PK��[���7VV"��Controller/Html/Configurations.phpnu�[���PK��[��_iEE^�Controller/Html/Export.phpnu�[���PK��[�?�C}
}
�Controller/Html/Import.phpnu�[���PK��[�^�ww�Controller/Html/Install.phpnu�[���PK��[
����F�FvController/Html/Menu.phpnu�[���PK��[�,�ȵ*�*�MController/Html/Positions.phpnu�[���PK��[������xController/Html/Themes.phpnu�[���PK��[��z66�{Controller/Json/Atoms.phpnu�[���PK��[7��]��5�Controller/Json/Changelog.phpnu�[���PK��[�)����#h�Controller/Json/Confirmdeletion.phpnu�[���PK��[�����T�Controller/Json/Devprod.phpnu�[���PK��[
PQ�>�>\�Controller/Json/Filepicker.phpnu�[���PK��[��l�
�
V�Controller/Json/Fontpicker.phpnu�[���PK��[�u#S�F�Fp�Controller/Json/Icons.phpnu�[���PK��[�DEL
L
9;Controller/Json/Layouts.phpnu�[���PK��[�e��))�[Controller/Json/Particle.phpnu�[���PK��[�P_�%%EuController/Json/Unsaved.phpnu�[���PK��[譤���xEventListener.phpnu�[���PK��[uTQ'��Page.phpnu�[���PK��[�Ht���
�Particles.phpnu�[���PK��[�w�22
�Router.phpnu�[���PK��[\��Ɵ
�
}�Styles.phpnu�[���PK��[�Y�zpp	V�Theme.phpnu�[���PK��[܁l
��ThemeList.phpnu�[���PK�
��