| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805 | 
							- <?php
 
- namespace Grav\Plugin;
 
- use Composer\Autoload\ClassLoader;
 
- use Grav\Common\Debugger;
 
- use Grav\Common\Grav;
 
- use Grav\Common\Page\Interfaces\PageInterface;
 
- use Grav\Common\Page\Pages;
 
- use Grav\Common\Page\Types;
 
- use Grav\Common\Plugin;
 
- use Grav\Common\User\Interfaces\UserInterface;
 
- use Grav\Common\Utils;
 
- use Grav\Events\FlexRegisterEvent;
 
- use Grav\Events\PermissionsRegisterEvent;
 
- use Grav\Events\PluginsLoadedEvent;
 
- use Grav\Framework\Acl\PermissionsReader;
 
- use Grav\Framework\Flex\FlexDirectory;
 
- use Grav\Framework\Flex\FlexForm;
 
- use Grav\Framework\Flex\Interfaces\FlexAuthorizeInterface;
 
- use Grav\Framework\Flex\Interfaces\FlexInterface;
 
- use Grav\Framework\Form\Interfaces\FormInterface;
 
- use Grav\Framework\Route\Route;
 
- use Grav\Plugin\Admin\Admin;
 
- use Grav\Plugin\FlexObjects\Controllers\ObjectController;
 
- use Grav\Plugin\FlexObjects\FlexFormFactory;
 
- use Grav\Plugin\Form\Forms;
 
- use Grav\Plugin\FlexObjects\Admin\AdminController;
 
- use Grav\Plugin\FlexObjects\Flex;
 
- use Psr\Http\Message\ServerRequestInterface;
 
- use RocketTheme\Toolbox\Event\Event;
 
- use function is_array;
 
- use function is_callable;
 
- /**
 
-  * Class FlexObjectsPlugin
 
-  * @package Grav\Plugin
 
-  */
 
- class FlexObjectsPlugin extends Plugin
 
- {
 
-     /** @var string */
 
-     protected const MIN_GRAV_VERSION = '1.7.0';
 
-     /** @var int[] */
 
-     public $features = [
 
-         'blueprints' => 1000,
 
-     ];
 
-     /** @var AdminController */
 
-     protected $controller;
 
-     /**
 
-      * @return bool
 
-      */
 
-     public static function checkRequirements(): bool
 
-     {
 
-         return version_compare(GRAV_VERSION, static::MIN_GRAV_VERSION, '>=');
 
-     }
 
-     /**
 
-      * @return array
 
-      *
 
-      * The getSubscribedEvents() gives the core a list of events
 
-      *     that the plugin wants to listen to. The key of each
 
-      *     array section is the event that the plugin listens to
 
-      *     and the value (in the form of an array) contains the
 
-      *     callable (or function) as well as the priority. The
 
-      *     higher the number the higher the priority.
 
-      */
 
-     public static function getSubscribedEvents(): array
 
-     {
 
-         if (!static::checkRequirements()) {
 
-             return [];
 
-         }
 
-         return [
 
-             PluginsLoadedEvent::class => [
 
-                 ['initializeFlex', 10]
 
-             ],
 
-             PermissionsRegisterEvent::class => [
 
-                 ['onRegisterPermissions', 100]
 
-             ],
 
-             FlexRegisterEvent::class => [
 
-                 ['onRegisterFlex', 100]
 
-             ],
 
-             'onCliInitialize' => [
 
-                 ['autoload', 100000],
 
-                 ['initializeFlex', 10]
 
-             ],
 
-             'onPluginsInitialized' => [
 
-                 ['onPluginsInitialized', 0],
 
-             ],
 
-             'onFormRegisterTypes' => [
 
-                 ['onFormRegisterTypes', 0]
 
-             ]
 
-         ];
 
-     }
 
-     /**
 
-      * Get list of form field types specified in this plugin. Only special types needs to be listed.
 
-      *
 
-      * @return array
 
-      */
 
-     public function getFormFieldTypes()
 
-     {
 
-         return [
 
-             'list' => [
 
-                 'array' => true
 
-             ],
 
-             'pagemedia' => [
 
-                 'array' => true,
 
-                 'media_field' => true,
 
-                 'validate' => [
 
-                     'type' => 'ignore'
 
-                 ]
 
-             ],
 
-             'filepicker' => [
 
-                 'media_picker_field' => true
 
-             ],
 
-         ];
 
-     }
 
-     /**
 
-      * @return ClassLoader
 
-      */
 
-     public function autoload(): ClassLoader
 
-     {
 
-         return require __DIR__ . '/vendor/autoload.php';
 
-     }
 
-     /**
 
-      * [PluginsLoadedEvent:10]: Initialize Flex
 
-      *
 
-      * @return void
 
-      */
 
-     public function initializeFlex(): void
 
-     {
 
-         $config = $this->config->get('plugins.flex-objects.directories') ?? [];
 
-         // Add to DI container
 
-         $this->grav['flex_objects'] = static function (Grav $grav) use ($config) {
 
-             /** @var FlexInterface $flex */
 
-             $flex = $grav['flex'];
 
-             $flexObjects = new Flex($flex, $config);
 
-             // This event is for backwards compatibility only, do not use it!
 
-             $grav->fireEvent('onFlexInit', new Event(['flex' => $flexObjects]));
 
-             return $flexObjects;
 
-         };
 
-     }
 
-     /**
 
-      * Initialize the plugin
 
-      *
 
-      * @return void
 
-      */
 
-     public function onPluginsInitialized(): void
 
-     {
 
-         if ($this->isAdmin()) {
 
-             /** @var UserInterface|null $user */
 
-             $user = $this->grav['user'] ?? null;
 
-             if (null === $user || !$user->authorize('login', 'admin')) {
 
-                 return;
 
-             }
 
-             $this->enable([
 
-                 'onAdminTwigTemplatePaths' => [
 
-                     ['onAdminTwigTemplatePaths', 10]
 
-                 ],
 
-                 'onAdminMenu' => [
 
-                     ['onAdminMenu', 0]
 
-                 ],
 
-                 'onAdminPage' => [
 
-                     ['onAdminPage', 0]
 
-                 ],
 
-                 'onAdminCompilePresetSCSS' => [
 
-                     ['onAdminCompilePresetSCSS', 0]
 
-                 ],
 
-                 'onDataTypeExcludeFromDataManagerPluginHook' => [
 
-                     ['onDataTypeExcludeFromDataManagerPluginHook', 0]
 
-                 ],
 
-                 'onAdminControllerInit' => [
 
-                     ['onAdminControllerInit', 0]
 
-                 ],
 
-                 'onThemeInitialized' => [
 
-                     ['onThemeInitialized', 0]
 
-                 ],
 
-                 'onPageInitialized' => [
 
-                     ['onAdminPageInitialized', 0]
 
-                 ],
 
-                 'onTwigSiteVariables' => [
 
-                     ['onTwigAdminVariables', 0]
 
-                 ],
 
-                 'onGetPageTemplates' =>
 
-                     ['onGetPageTemplates', 0]
 
-             ]);
 
-         } else {
 
-             $this->enable([
 
-                 'onTwigTemplatePaths' => [
 
-                     ['onTwigTemplatePaths', 0]
 
-                 ],
 
-                 'onPagesInitialized' => [
 
-                     ['onPagesInitialized', -10000]
 
-                 ],
 
-                 'onPageInitialized' => [
 
-                     ['authorizePage', 10000]
 
-                 ],
 
-                 'onBeforeFlexFormInitialize' => [
 
-                     ['onBeforeFlexFormInitialize', -10]
 
-                 ],
 
-                 'onPageTask' => [
 
-                     ['onPageTask', -10]
 
-                 ],
 
-             ]);
 
-         }
 
-     }
 
-     /**
 
-      * @param FlexRegisterEvent $event
 
-      * @return void
 
-      */
 
-     public function onRegisterFlex(FlexRegisterEvent $event): void
 
-     {
 
-         /** @var \Grav\Framework\Flex\Flex $flex */
 
-         $flex = $event->flex;
 
-         $types = (array)$this->config->get('plugins.flex-objects.directories', []);
 
-         $this->registerDirectories($flex, $types);
 
-     }
 
-     /**
 
-      * @return void
 
-      */
 
-     public function onThemeInitialized(): void
 
-     {
 
-         // Register directories defined in the theme.
 
-         /** @var \Grav\Framework\Flex\Flex $flex */
 
-         $flex = $this->grav['flex'];
 
-         $types = (array)$this->config->get('plugins.flex-objects.directories', []);
 
-         $this->registerDirectories($flex, $types, true);
 
-         $this->controller = new AdminController();
 
-         /** @var Debugger $debugger */
 
-         $debugger = Grav::instance()['debugger'];
 
-         $names = implode(', ', array_keys($flex->getDirectories()));
 
-         $debugger->addMessage(sprintf('Registered flex types: %s', $names), 'debug');
 
-     }
 
-     /**
 
-      * @param Event $event
 
-      */
 
-     public function onBeforeFlexFormInitialize(Event $event): void
 
-     {
 
-         /** @var array $form */
 
-         $form = $event['form'];
 
-         $edit = $form['actions']['edit'] ?? false;
 
-         if (!isset($form['flex']['key']) && $edit === true) {
 
-             /** @var Route $route */
 
-             $route = $this->grav['route'];
 
-             $id = rawurldecode($route->getGravParam('id'));
 
-             if (null !== $id) {
 
-                 $form['flex']['key'] = $id;
 
-                 $event['form'] = $form;
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * [onPagesInitialized:-10000] Default router for flex pages.
 
-      *
 
-      * @param Event $event
 
-      */
 
-     public function onPagesInitialized(Event $event): void
 
-     {
 
-         /** @var Route|null $route */
 
-         $route = $event['route'] ?? null;
 
-         if (null === $route) {
 
-             // Stop if in CLI.
 
-             return;
 
-         }
 
-         /** @var PageInterface|null $page */
 
-         $page = $this->grav['page'] ?? null;
 
-         $base = '';
 
-         $path = [];
 
-         if (!$page->routable() || $page->template() === 'notfound') {
 
-             /** @var Pages $pages */
 
-             $pages = $this->grav['pages'];
 
-             // Find first existing and routable parent page.
 
-             $parts = explode('/', $route->getRoute());
 
-             array_shift($parts);
 
-             $page = null;
 
-             while (!$page && $parts) {
 
-                 $path[] = array_pop($parts);
 
-                 $base = '/' . implode('/', $parts);
 
-                 $page = $pages->find($base);
 
-                 if ($page && !$page->routable()) {
 
-                     $page = null;
 
-                 }
 
-             }
 
-         }
 
-         // If page is found, check if it contains flex directory router.
 
-         if ($page) {
 
-             $flex = $this->grav['flex'];
 
-             $options = $page->header()->flex ?? null;
 
-             $router = $options['router'] ?? null;
 
-             $type = $options['directory'] ?? null;
 
-             $directory = $type ? $flex->getDirectory($type) : null;
 
-             if (\is_string($router)) {
 
-                 $path = implode('/', array_reverse($path));
 
-                 $response = null;
 
-                 $flexEvent = new Event([
 
-                     'flex' => $flex,
 
-                     'directory' => $directory,
 
-                     'parent' => $page,
 
-                     'page' => $page,
 
-                     'base' => $base,
 
-                     'path' => $path,
 
-                     'route' => $route,
 
-                     'options' => $options,
 
-                     'request' => $event['request'],
 
-                     'response' => &$response,
 
-                 ]);
 
-                 $flexEvent = $this->grav->fireEvent("flex.router.{$router}", $flexEvent);
 
-                 if ($response) {
 
-                     $this->grav->close($response);
 
-                 }
 
-                 /** @var PageInterface|null $routedPage */
 
-                 $routedPage = $flexEvent['page'];
 
-                 if ($routedPage) {
 
-                     /** @var Debugger $debugger */
 
-                     $debugger = Grav::instance()['debugger'];
 
-                     $debugger->addMessage(sprintf('Flex uses page %s', $routedPage->route()));
 
-                     unset($this->grav['page']);
 
-                     $this->grav['page'] = $routedPage;
 
-                     $event->stopPropagation();
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * [onPageInitialized:10000] Authorize Flex Objects Page
 
-      *
 
-      * @param Event $event
 
-      */
 
-     public function authorizePage(Event $event): void
 
-     {
 
-         /** @var PageInterface|null $page */
 
-         $page = $event['page'];
 
-         if (!$page instanceof PageInterface) {
 
-             return;
 
-         }
 
-         $header = $page->header();
 
-         $forms = $page->getForms();
 
-         // Update dynamic flex forms from the page.
 
-         $form = null;
 
-         foreach ($forms as $name => $test) {
 
-             $type = $form['type'] ?? null;
 
-             if ($type === 'flex') {
 
-                 $form = $test;
 
-                 // Update the form and add it back to the page.
 
-                 $this->grav->fireEvent('onBeforeFlexFormInitialize', new Event(['page' => $page, 'name' => $name, 'form' => &$form]));
 
-                 $page->addForms([$form], true);
 
-             }
 
-         }
 
-         // Make sure the page contains flex.
 
-         $config = $header->flex ?? null;
 
-         if (!is_array($config) && !$form) {
 
-             return;
 
-         }
 
-         /** @var Route $route */
 
-         $route = $this->grav['route'];
 
-         $type = $form['flex']['type'] ?? $config['directory'] ?? $route->getGravParam('directory') ?? null;
 
-         $key = $form['flex']['key'] ?? $config['id'] ?? $route->getGravParam('id') ?? '';
 
-         if (\is_string($type)) {
 
-             /** @var Flex $flex */
 
-             $flex = $this->grav['flex_objects'];
 
-             $directory = $flex->getDirectory($type);
 
-         } else {
 
-             $directory = null;
 
-         }
 
-         if (!$directory) {
 
-             return;
 
-         }
 
-         $create = (bool)($form['actions']['create'] ?? false);
 
-         $edit = (bool)($form['actions']['edit'] ?? false);
 
-         $scope = $config['access']['scope'] ?? null;
 
-         $object = $key !== '' ? $directory->getObject($key) : null;
 
-         $hasAccess = null;
 
-         $action = $config['access']['action'] ?? null;
 
-         if (null === $action) {
 
-             if (!$form) {
 
-                 $action = $key !== '' ? 'read' : 'list';
 
-                 if (null === $scope) {
 
-                     $hasAccess = true;
 
-                 }
 
-             } elseif ($object) {
 
-                 if ($edit) {
 
-                     $scope = $scope ?? 'admin';
 
-                     $action = 'update';
 
-                 } else {
 
-                     $hasAccess = false;
 
-                 }
 
-             } elseif ($create) {
 
-                 $object = $directory->createObject([], $key);
 
-                 $scope = $scope ?? 'admin';
 
-                 $action = 'create';
 
-             } else {
 
-                 $hasAccess = false;
 
-             }
 
-         }
 
-         if ($action && $hasAccess === null) {
 
-             if ($object instanceof FlexAuthorizeInterface) {
 
-                 $hasAccess = $object->isAuthorized($action, $scope);
 
-             } else {
 
-                 $hasAccess = $directory->isAuthorized($action, $scope);
 
-             }
 
-         }
 
-         if (!$hasAccess) {
 
-             // Hide the page (404).
 
-             $page->routable(false);
 
-             $page->visible(false);
 
-             // If page is not a module, replace the current page with unauthorized page.
 
-             if (!$page->isModule()) {
 
-                 $login = $this->grav['login'] ?? null;
 
-                 $unauthorized = $login ? $login->addPage('unauthorized') : null;
 
-                 if ($unauthorized) {
 
-                     unset($this->grav['page']);
 
-                     $this->grav['page'] = $unauthorized;
 
-                 }
 
-             }
 
-         } elseif ($config['access']['override'] ?? false) {
 
-             // Override page access settings (allow).
 
-             $page->modifyHeader('access', []);
 
-         }
 
-     }
 
-     /**
 
-      * @param Event $event
 
-      */
 
-     public function onPageTask(Event $event): void
 
-     {
 
-         /** @var FormInterface|null $form */
 
-         $form = $event['form'] ?? null;
 
-         if (!$form instanceof FlexForm) {
 
-             return;
 
-         }
 
-         $object = $form->getObject();
 
-         /** @var ServerRequestInterface $request */
 
-         $request = $event['request'];
 
-         $request = $request
 
-             ->withAttribute('type', $object->getFlexType())
 
-             ->withAttribute('key', $object->getKey())
 
-             ->withAttribute('object', $object)
 
-             ->withAttribute('form', $form);
 
-         $controller = new ObjectController();
 
-         $response = $controller->handle($request);
 
-         if ($response->getStatusCode() !== 418) {
 
-             $this->grav->close($response);
 
-         }
 
-     }
 
-     /**
 
-      * @param \Grav\Framework\Flex\Flex $flex
 
-      * @param array $types
 
-      * @param bool $report
 
-      */
 
-     protected function registerDirectories(\Grav\Framework\Flex\Flex $flex, array $types, bool $report = false): void
 
-     {
 
-         $map = Flex::getLegacyBlueprintMap(false);
 
-         foreach ($types as $blueprint) {
 
-             // Backwards compatibility to v1.0.0-rc.3
 
-             $blueprint = $map[$blueprint] ?? $blueprint;
 
-             $type = Utils::basename((string)$blueprint, '.yaml');
 
-             if (!$type) {
 
-                 continue;
 
-             }
 
-             if (!file_exists($blueprint)) {
 
-                 if ($report) {
 
-                     /** @var Debugger $debugger */
 
-                     $debugger = Grav::instance()['debugger'];
 
-                     $debugger->addMessage(sprintf('Flex: blueprint for flex type %s is missing', $type), 'error');
 
-                 }
 
-                 continue;
 
-             }
 
-             $directory = $flex->getDirectory($type);
 
-             if (!$directory || !$directory->isEnabled()) {
 
-                 $flex->addDirectoryType($type, $blueprint);
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * Initial stab at registering permissions (WIP)
 
-      *
 
-      * @param PermissionsRegisterEvent $event
 
-      * @return void
 
-      */
 
-     public function onRegisterPermissions(PermissionsRegisterEvent $event): void
 
-     {
 
-         /** @var Flex $flex */
 
-         $flex = $this->grav['flex_objects'];
 
-         $directories = $flex->getDirectories();
 
-         $permissions = $event->permissions;
 
-         $actions = [];
 
-         foreach ($directories as $directory) {
 
-             $data = $directory->getConfig('admin.permissions', []);
 
-             $actions[] = PermissionsReader::fromArray($data, $permissions->getTypes());
 
-         }
 
-         $actions[] = PermissionsReader::fromYaml("plugin://{$this->name}/permissions.yaml");
 
-         $permissions->addActions(array_replace(...$actions));
 
-     }
 
-     /**
 
-      * @param Event $event
 
-      * @return void
 
-      */
 
-     public function onFormRegisterTypes(Event $event): void
 
-     {
 
-         /** @var Forms $forms */
 
-         $forms = $event['forms'];
 
-         $forms->registerType('flex', new FlexFormFactory());
 
-     }
 
-     /**
 
-      * @param Event $event
 
-      * @return void
 
-      */
 
-     public function onAdminPage(Event $event): void
 
-     {
 
-         if ($this->controller->isActive()) {
 
-             $event->stopPropagation();
 
-             /** @var PageInterface $page */
 
-             $page = $event['page'];
 
-             $page->init(new \SplFileInfo(__DIR__ . '/admin/pages/flex-objects.md'));
 
-             $page->slug($this->controller->getLocation());
 
-             $header = $page->header();
 
-             $header->access = ['admin.login'];
 
-             $header->controller = $this->controller->getInfo();
 
-         }
 
-     }
 
-     /**
 
-      * [onPageInitialized:0]: Run controller
 
-      *
 
-      * @return void
 
-      */
 
-     public function onAdminPageInitialized(): void
 
-     {
 
-         if ($this->controller->isActive()) {
 
-             $this->controller->execute();
 
-             $this->controller->redirect();
 
-         }
 
-     }
 
-     /**
 
-      * @param Event $event
 
-      * @return void
 
-      */
 
-     public function onAdminControllerInit(Event $event): void
 
-     {
 
-         $eventController = $event['controller'];
 
-         // Blacklist all admin routes, including aliases and redirects.
 
-         $eventController->blacklist_views[] = 'flex-objects';
 
-         foreach ($this->controller->getAdminRoutes() as $route => $info) {
 
-             $eventController->blacklist_views[] = trim($route, '/');
 
-         }
 
-     }
 
-     /**
 
-      * Add Flex-Object's preset.scss to the Admin Preset SCSS compile process
 
-      *
 
-      * @param Event $event
 
-      * @return void
 
-      */
 
-     public function onAdminCompilePresetSCSS(Event $event): void
 
-     {
 
-         $event['scss']->add($this->grav['locator']->findResource('plugins://flex-objects/scss/_preset.scss'));
 
-     }
 
-     /**
 
-      * @param Event $event
 
-      * @return void
 
-      */
 
-     public function onGetPageTemplates(Event $event): void
 
-     {
 
-         /** @var Types $types */
 
-         $types = $event->types;
 
-         $types->register('flex-objects', 'plugins://flex-objects/blueprints/pages/flex-objects.yaml');
 
-     }
 
-     /**
 
-      * Form select options listing all enabled directories.
 
-      *
 
-      * @return array
 
-      */
 
-     public static function directoryOptions(): array
 
-     {
 
-         /** @var Flex $flex */
 
-         $flex = Grav::instance()['flex_objects'];
 
-         $directories = $flex->getDirectories();
 
-         $list = [];
 
-         /**
 
-          * @var string $type
 
-          * @var FlexDirectory $directory
 
-          */
 
-         foreach ($directories as $type => $directory) {
 
-             if (!$directory->getConfig('site.hidden')) {
 
-                 $list[$type] = $directory->getTitle();
 
-             }
 
-         }
 
-         return $list;
 
-     }
 
-     /**
 
-      * @return array
 
-      */
 
-     public function getAdminMenu(): array
 
-     {
 
-         /** @var Flex $flex */
 
-         $flex = $this->grav['flex_objects'];
 
-         $list = [];
 
-         foreach ($flex->getAdminMenuItems() as $name => $item) {
 
-             $route = trim($item['route'] ?? $name, '/');
 
-             $list[$route] = $item;
 
-         }
 
-         return $list;
 
-     }
 
-     /**
 
-      * Add Flex Directory to admin menu
 
-      *
 
-      * @return void
 
-      */
 
-     public function onAdminMenu(): void
 
-     {
 
-         /** @var Flex $flex */
 
-         $flex = $this->grav['flex_objects'];
 
-         /** @var Admin $admin */
 
-         $admin = $this->grav['admin'];
 
-         foreach ($this->getAdminMenu() as $route => $item) {
 
-             $directory = null;
 
-             if (isset($item['directory'])) {
 
-                 $directory = $flex->getDirectory($item['directory']);
 
-                 if (!$directory || !$directory->isEnabled()) {
 
-                     continue;
 
-                 }
 
-             }
 
-             $title = $item['title'] ?? 'PLUGIN_FLEX_OBJECTS.TITLE';
 
-             $index = $item['index'] ?? 0;
 
-             if (($this->grav['twig']->plugins_hooked_nav[$title]['index'] ?? 1000) <= $index) {
 
-                 continue;
 
-             }
 
-             $location = $item['location'] ?? $route;
 
-             $hidden = $item['hidden'] ?? false;
 
-             $icon = $item['icon'] ?? 'fa-list';
 
-             $authorize = $item['authorize'] ?? ($directory ? null : ['admin.flex-objects', 'admin.super']);
 
-             if ($hidden || (null === $authorize && $directory->isAuthorized('list', 'admin', $admin->user))) {
 
-                 continue;
 
-             }
 
-             $cache = $directory ? $directory->getCache('index') : null;
 
-             $count = $cache ? $cache->get('admin-count-' . md5($admin->user->username)) : false;
 
-             if (null === $count) {
 
-                 try {
 
-                     $collection = $directory->getCollection();
 
-                     if (is_callable([$collection, 'isAuthorized'])) {
 
-                         $count = $collection->isAuthorized('list', 'admin', $admin->user)->count();
 
-                     } else {
 
-                         $count = $collection->count();
 
-                     }
 
-                     $cache->set('admin-count-' . md5($admin->user->username), $count);
 
-                 } catch (\InvalidArgumentException $e) {
 
-                     continue;
 
-                 }
 
-             }
 
-             $badge = $directory ? ['badge' => ['count' => $count]] : [];
 
-             $priority = $item['priority'] ?? 0;
 
-             $this->grav['twig']->plugins_hooked_nav[$title] = [
 
-                 'location' => $location,
 
-                 'route' => $route,
 
-                 'index' => $index,
 
-                 'icon' => $icon,
 
-                 'authorize' => $authorize,
 
-                 'priority' => $priority
 
-             ] + $badge;
 
-         }
 
-     }
 
-     /**
 
-      * Exclude Flex Directory data from the Data Manager plugin
 
-      *
 
-      * @return void
 
-      */
 
-     public function onDataTypeExcludeFromDataManagerPluginHook(): void
 
-     {
 
-         $this->grav['admin']->dataTypesExcludedFromDataManagerPlugin[] = 'flex-objects';
 
-     }
 
-     /**
 
-      * Add current directory to twig lookup paths.
 
-      *
 
-      * @return void
 
-      */
 
-     public function onTwigTemplatePaths(): void
 
-     {
 
-         $extra_site_twig_path = $this->config->get('plugins.flex-objects.extra_site_twig_path');
 
-         $extra_path = $extra_site_twig_path ? $this->grav['locator']->findResource($extra_site_twig_path) : null;
 
-         if ($extra_path) {
 
-             $this->grav['twig']->twig_paths[] = $extra_path;
 
-         }
 
-         $this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
 
-     }
 
-     /**
 
-      * Add plugin templates path
 
-      *
 
-      * @param Event $event
 
-      * @return void
 
-      */
 
-     public function onAdminTwigTemplatePaths(Event $event): void
 
-     {
 
-         $extra_admin_twig_path = $this->config->get('plugins.flex-objects.extra_admin_twig_path');
 
-         $extra_path = $extra_admin_twig_path ? $this->grav['locator']->findResource($extra_admin_twig_path) : null;
 
-         $paths = $event['paths'];
 
-         if ($extra_path) {
 
-             $paths[] = $extra_path;
 
-         }
 
-         $paths[] = __DIR__ . '/admin/templates';
 
-         $event['paths'] = $paths;
 
-     }
 
-     /**
 
-      * Set needed variables to display directory.
 
-      *
 
-      * @return void
 
-      */
 
-     public function onTwigAdminVariables(): void
 
-     {
 
-         if ($this->controller->isActive()) {
 
-             // Twig shortcuts
 
-             $this->grav['twig']->twig_vars['controller'] = $this->controller;
 
-             $this->grav['twig']->twig_vars['action'] = $this->controller->getAction();
 
-             $this->grav['twig']->twig_vars['task'] = $this->controller->getTask();
 
-             $this->grav['twig']->twig_vars['target'] = $this->controller->getTarget();
 
-             $this->grav['twig']->twig_vars['key'] = $this->controller->getId();
 
-             $this->grav['twig']->twig_vars['flex'] = $this->grav['flex_objects'];
 
-             $this->grav['twig']->twig_vars['directory'] = $this->controller->getDirectory();
 
-             $this->grav['twig']->twig_vars['collection'] = $this->controller->getCollection();
 
-             $this->grav['twig']->twig_vars['object'] = $this->controller->getObject();
 
-             // CSS / JS Assets
 
-             $this->grav['assets']->addCss('plugin://flex-objects/css/admin.css');
 
-             $this->grav['assets']->addCss('plugin://admin/themes/grav/css/codemirror/codemirror.css');
 
-         }
 
-     }
 
- }
 
 
  |