| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 | 
							- <?php
 
- declare(strict_types=1);
 
- namespace Grav\Plugin\FlexObjects;
 
- use Grav\Common\Config\Config;
 
- use Grav\Common\Filesystem\Folder;
 
- use Grav\Common\Grav;
 
- use Grav\Common\Page\Interfaces\PageInterface;
 
- use Grav\Common\Utils;
 
- use Grav\Framework\Flex\FlexDirectory;
 
- use Grav\Framework\Flex\FlexObject;
 
- use Grav\Framework\Flex\Interfaces\FlexCollectionInterface;
 
- use Grav\Framework\Flex\Interfaces\FlexCommonInterface;
 
- use Grav\Framework\Flex\Interfaces\FlexDirectoryInterface;
 
- use Grav\Framework\Flex\Interfaces\FlexInterface;
 
- use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
 
- use Grav\Plugin\FlexObjects\Admin\AdminController;
 
- use Grav\Plugin\FlexObjects\Table\DataTable;
 
- /**
 
-  * Class Flex
 
-  * @package Grav\Plugin\FlexObjects
 
-  */
 
- class Flex implements FlexInterface
 
- {
 
-     /** @var FlexInterface */
 
-     protected $flex;
 
-     /** @var array */
 
-     protected $adminRoutes;
 
-     /** @var array */
 
-     protected $adminMenu;
 
-     /** @var array */
 
-     protected $managed;
 
-     /**
 
-      * @param bool $newToOld
 
-      * @return array
 
-      * @internal
 
-      */
 
-     public static function getLegacyBlueprintMap(bool $newToOld = true): array
 
-     {
 
-         $map = [
 
-             'blueprints://flex-objects/pages.yaml' => 'blueprints://flex-objects/grav-pages.yaml',
 
-             'blueprints://flex-objects/user-accounts.yaml' => 'blueprints://flex-objects/grav-accounts.yaml',
 
-             'blueprints://flex-objects/user-groups.yaml' => 'blueprints://flex-objects/grav-user-groups.yaml'
 
-         ];
 
-         return $newToOld ? $map : array_flip($map);
 
-     }
 
-     /**
 
-      * Flex constructor.
 
-      * @param FlexInterface $flex
 
-      * @param array $types
 
-      */
 
-     public function __construct(FlexInterface $flex, array $types)
 
-     {
 
-         $this->flex = $flex;
 
-         $this->managed = [];
 
-         $legacy = static::getLegacyBlueprintMap(false);
 
-         foreach ($types as $blueprint) {
 
-             // Backwards compatibility to v1.0.0-rc.3
 
-             $blueprint = $legacy[$blueprint] ?? $blueprint;
 
-             $type = Utils::basename((string)$blueprint, '.yaml');
 
-             if ($type) {
 
-                 $this->managed[] = $type;
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * @param string $type
 
-      * @param string $blueprint
 
-      * @param array  $config
 
-      * @return $this
 
-      */
 
-     public function addDirectoryType(string $type, string $blueprint, array $config = [])
 
-     {
 
-         $this->flex->addDirectoryType($type, $blueprint, $config);
 
-         return $this;
 
-     }
 
-     /**
 
-      * @param FlexDirectory $directory
 
-      * @return $this
 
-      */
 
-     public function addDirectory(FlexDirectory $directory)
 
-     {
 
-         $this->flex->addDirectory($directory);
 
-         return $this;
 
-     }
 
-     /**
 
-      * @param string $type
 
-      * @return bool
 
-      */
 
-     public function hasDirectory(string $type): bool
 
-     {
 
-         return $this->flex->hasDirectory($type);
 
-     }
 
-     /**
 
-      * @param string[]|null $types
 
-      * @param bool $keepMissing
 
-      * @return array<FlexDirectoryInterface|null>
 
-      */
 
-     public function getDirectories(array $types = null, bool $keepMissing = false): array
 
-     {
 
-         return $this->flex->getDirectories($types, $keepMissing);
 
-     }
 
-     /**
 
-      * Get directories which are not hidden in the site.
 
-      *
 
-      * @return array
 
-      */
 
-     public function getDefaultDirectories(): array
 
-     {
 
-         $list = $this->getDirectories();
 
-         foreach ($list as $type => $directory) {
 
-             if ($directory->getConfig('site.hidden', false)) {
 
-                 unset($list[$type]);
 
-             }
 
-         }
 
-         return $list;
 
-     }
 
-     /**
 
-      * @param string $type
 
-      * @return FlexDirectory|null
 
-      */
 
-     public function getDirectory(string $type): ?FlexDirectory
 
-     {
 
-         return $this->flex->getDirectory($type);
 
-     }
 
-     /**
 
-      * @param string $type
 
-      * @param array|null $keys
 
-      * @param string|null $keyField
 
-      * @return FlexCollectionInterface|null
 
-      */
 
-     public function getCollection(string $type, array $keys = null, string $keyField = null): ?FlexCollectionInterface
 
-     {
 
-         return $this->flex->getCollection($type, $keys, $keyField);
 
-     }
 
-     /**
 
-      * @param array $keys
 
-      * @param array $options            In addition to the options in getObjects(), following options can be passed:
 
-      *                                  collection_class:   Class to be used to create the collection. Defaults to ObjectCollection.
 
-      * @return FlexCollectionInterface
 
-      * @throws \RuntimeException
 
-      */
 
-     public function getMixedCollection(array $keys, array $options = []): FlexCollectionInterface
 
-     {
 
-         return $this->flex->getMixedCollection($keys, $options);
 
-     }
 
-     /**
 
-      * @param array $keys
 
-      * @param array $options    Following optional options can be passed:
 
-      *                          types:          List of allowed types.
 
-      *                          type:           Allowed type if types isn't defined, otherwise acts as default_type.
 
-      *                          default_type:   Set default type for objects given without type (only used if key_field isn't set).
 
-      *                          keep_missing:   Set to true if you want to return missing objects as null.
 
-      *                          key_field:      Key field which is used to match the objects.
 
-      * @return array
 
-      */
 
-     public function getObjects(array $keys, array $options = []): array
 
-     {
 
-         return $this->flex->getObjects($keys, $options);
 
-     }
 
-     /**
 
-      * @param string $key
 
-      * @param string|null $type
 
-      * @param string|null $keyField
 
-      * @return FlexObjectInterface|null
 
-      */
 
-     public function getObject(string $key, string $type = null, string $keyField = null): ?FlexObjectInterface
 
-     {
 
-         return $this->flex->getObject($key, $type, $keyField);
 
-     }
 
-     /**
 
-      * @return int
 
-      */
 
-     public function count(): int
 
-     {
 
-         return $this->flex->count();
 
-     }
 
-     public function isManaged(string $type): bool
 
-     {
 
-         return \in_array($type, $this->managed, true);
 
-     }
 
-     /**
 
-      * @return array
 
-      */
 
-     public function getAll(): array
 
-     {
 
-         $directories = $this->getDirectories($this->managed);
 
-         $all = $this->getBlueprints();
 
-         /** @var FlexDirectory $directory */
 
-         foreach ($all as $type => $directory) {
 
-             if (!isset($directories[$type])) {
 
-                 $directories[$type] = $directory;
 
-             }
 
-         }
 
-         ksort($directories);
 
-         return $directories;
 
-     }
 
-     /**
 
-      * @return array
 
-      */
 
-     public function getBlueprints(): array
 
-     {
 
-         $params = [
 
-             'pattern' => '|\.yaml|',
 
-             'value' => 'Url',
 
-             'recursive' => false,
 
-             'folders' => false
 
-         ];
 
-         $directories = [];
 
-         $all = Folder::all('blueprints://flex-objects', $params);
 
-         foreach ($all as $url) {
 
-             $type = Utils::basename($url, '.yaml');
 
-             $directory = new FlexDirectory($type, $url);
 
-             if ($directory->getConfig('hidden') !== true) {
 
-                 $directories[$type] = $directory;
 
-             }
 
-         }
 
-         // Order blueprints by title.
 
-         usort($directories, static function (FlexDirectory $a, FlexDirectory $b) {
 
-             return $a->getTitle() <=> $b->getTitle();
 
-         });
 
-         return $directories;
 
-     }
 
-     /**
 
-      * @param string|FlexDirectory $type
 
-      * @param array $options
 
-      * @return DataTable
 
-      */
 
-     public function getDataTable($type, array $options = []): DataTable
 
-     {
 
-         $directory = $type instanceof FlexDirectory ? $type : $this->getDirectory($type);
 
-         if (!$directory) {
 
-             throw new \RuntimeException('Not Found', 404);
 
-         }
 
-         $collection = $options['collection'] ?? $directory->getCollection();
 
-         if (isset($options['filters']) && is_array($options['filters'])) {
 
-             $collection = $collection->filterBy($options['filters']);
 
-         }
 
-         $table = new DataTable($options);
 
-         $table->setCollection($collection);
 
-         return $table;
 
-     }
 
-     /**
 
-      * @param string|object|null $type
 
-      * @param array $params
 
-      * @param string $extension
 
-      * @return string
 
-      */
 
-     public function adminRoute($type = null, array $params = [], string $extension = ''): string
 
-     {
 
-         if (\is_object($type)) {
 
-             $object = $type;
 
-             if ($object instanceof FlexCommonInterface || $object instanceof FlexDirectory) {
 
-                 $type = $type->getFlexType();
 
-             } else {
 
-                 return '';
 
-             }
 
-         } else {
 
-             $object = null;
 
-         }
 
-         $routes = $this->getAdminRoutes();
 
-         $grav = Grav::instance();
 
-         /** @var Config $config */
 
-         $config = $grav['config'];
 
-         if (!Utils::isAdminPlugin()) {
 
-             $parts = [
 
-                 trim($grav['base_url'], '/'),
 
-                 trim($config->get('plugins.admin.route'), '/')
 
-             ];
 
-         }
 
-         if ($type && isset($routes[$type])) {
 
-             if (!$routes[$type]) {
 
-                 // Directory has empty route.
 
-                 return '';
 
-             }
 
-             // Directory has it's own menu item.
 
-             $parts[] = trim($routes[$type], '/');
 
-         } else {
 
-             if (empty($routes[''])) {
 
-                 // Default route has been disabled.
 
-                 return '';
 
-             }
 
-             // Use default route.
 
-             $parts[] = trim($routes[''], '/');
 
-             if ($type) {
 
-                 $parts[] = $type;
 
-             }
 
-         }
 
-         // Append object key if available.
 
-         if ($object instanceof FlexObject) {
 
-             if ($object->exists()) {
 
-                 $parts[] = trim($object->getKey(), '/');
 
-             } else {
 
-                 if ($object->hasKey()) {
 
-                     $parts[] = trim($object->getKey(), '/');
 
-                 }
 
-                 $params = ['' => 'add'] + $params;
 
-             }
 
-         }
 
-         $p = [];
 
-         $separator = $config->get('system.param_sep');
 
-         foreach ($params as $key => $val) {
 
-             $p[] = $key . $separator . $val;
 
-         }
 
-         $parts = array_filter($parts, static function ($val) { return $val !== ''; });
 
-         $route = '/' . implode('/', $parts);
 
-         $extension = $extension ? '.' . $extension : '';
 
-         return $route . $extension . ($p ? '/' . implode('/', $p) : '');
 
-     }
 
-     public function getAdminController(): ?AdminController
 
-     {
 
-         $grav = Grav::instance();
 
-         if (!isset($grav['admin'])) {
 
-             return null;
 
-         }
 
-         /** @var PageInterface $page */
 
-         $page = $grav['page'];
 
-         $header = $page->header();
 
-         $callable = $header->controller['controller']['instance'] ?? null;
 
-         if (null !== $callable && \is_callable($callable)) {
 
-             return $callable();
 
-         }
 
-         return null;
 
-     }
 
-     /**
 
-      * @return array
 
-      */
 
-     public function getAdminRoutes(): array
 
-     {
 
-         if (null === $this->adminRoutes) {
 
-             $routes = [];
 
-             /** @var FlexDirectory $directory */
 
-             foreach ($this->getDirectories() as $directory) {
 
-                 $config = $directory->getConfig('admin');
 
-                 if (!$directory->isEnabled() || !empty($config['disabled'])) {
 
-                     continue;
 
-                 }
 
-                 // Resolve route.
 
-                 $route = $config['router']['path']
 
-                     ?? $config['menu']['list']['route']
 
-                     ?? "/flex-objects/{$directory->getFlexType()}";
 
-                 $routes[$directory->getFlexType()] = $route;
 
-             }
 
-             $this->adminRoutes = $routes;
 
-         }
 
-         return $this->adminRoutes;
 
-     }
 
-     /**
 
-      * @return array
 
-      */
 
-     public function getAdminMenuItems(): array
 
-     {
 
-         if (null === $this->adminMenu) {
 
-             $routes = [];
 
-             $count = 0;
 
-             $directories = $this->getDirectories();
 
-             /** @var FlexDirectory $directory */
 
-             foreach ($directories as $directory) {
 
-                 $config = $directory->getConfig('admin');
 
-                 if (!$directory->isEnabled() || !empty($config['disabled'])) {
 
-                     continue;
 
-                 }
 
-                 $type = $directory->getFlexType();
 
-                 $items = $directory->getConfig('admin.menu') ?? [];
 
-                 if ($items) {
 
-                     foreach ($items as $view => $item) {
 
-                         $item += [
 
-                             'route' => '/' . $type,
 
-                             'title' => $directory->getTitle(),
 
-                             'icon' => 'fa fa-file',
 
-                             'directory' => $type
 
-                         ];
 
-                         $routes[$type] = $item;
 
-                     }
 
-                 } else {
 
-                     $count++;
 
-                 }
 
-             }
 
-             if ($count && !isset($routes[''])) {
 
-                 $routes[''] = ['route' => '/flex-objects'];
 
-             }
 
-             $this->adminMenu = $routes;
 
-         }
 
-         return $this->adminMenu;
 
-     }
 
- }
 
 
  |