From f1c1e124790f235f6b47e5a234e9895574dad023 Mon Sep 17 00:00:00 2001 From: Thom Vrijmoed Date: Fri, 1 Nov 2019 14:23:27 +0100 Subject: [PATCH] added caftql support --- src/Navie.php | 38 +++++++----- .../arguments/ListItemQueryArguments.php | 44 ++++++++++++++ src/craftql/factories/ListFactory.php | 19 ++++++ src/craftql/repositories/ListRepository.php | 38 ++++++++++++ src/craftql/types/ItemInterface.php | 59 +++++++++++++++++++ src/craftql/types/ListItemType.php | 24 ++++++++ src/craftql/types/ListType.php | 37 ++++++++++++ src/listeners/GetNavieFieldSchema.php | 52 ++++++++++++++++ src/records/ListRecord.php | 6 +- 9 files changed, 298 insertions(+), 19 deletions(-) create mode 100644 src/craftql/arguments/ListItemQueryArguments.php create mode 100644 src/craftql/factories/ListFactory.php create mode 100644 src/craftql/repositories/ListRepository.php create mode 100644 src/craftql/types/ItemInterface.php create mode 100644 src/craftql/types/ListItemType.php create mode 100644 src/craftql/types/ListType.php create mode 100644 src/listeners/GetNavieFieldSchema.php diff --git a/src/Navie.php b/src/Navie.php index d6aca72..58ec240 100644 --- a/src/Navie.php +++ b/src/Navie.php @@ -10,27 +10,33 @@ namespace dutchheight\navie; -use dutchheight\navie\base\PluginTrait; -use dutchheight\navie\variables\NavieVariable; -use dutchheight\navie\models\Settings; -use dutchheight\navie\elements\ListItem as ListItemElement; -use dutchheight\navie\graphql\queries\ListItem as ListItemQuery; -use dutchheight\navie\graphql\interfaces\ListItem as ListItemInterface; - use Craft; use craft\base\Plugin; -use craft\helpers\UrlHelper; -use craft\services\UserPermissions; -use craft\services\Gql; -use craft\web\UrlManager; -use craft\web\twig\variables\CraftVariable; -use craft\events\RegisterUrlRulesEvent; -use craft\events\RegisterUserPermissionsEvent; use craft\events\RegisterGqlQueriesEvent; use craft\events\RegisterGqlTypesEvent; +use craft\events\RegisterUrlRulesEvent; +use craft\events\RegisterUserPermissionsEvent; use craft\events\SiteEvent; +use craft\helpers\UrlHelper; use craft\queue\jobs\ResaveElements; +use craft\services\Gql; use craft\services\Sites; +use craft\services\UserPermissions; +use craft\web\twig\variables\CraftVariable; +use craft\web\UrlManager; + +use dutchheight\navie\base\PluginTrait; +use dutchheight\navie\elements\ListItem as ListItemElement; +use dutchheight\navie\graphql\interfaces\ListItem as ListItemInterface; +use dutchheight\navie\graphql\queries\ListItem as ListItemQuery; +use dutchheight\navie\listeners\GetNavieFieldSchema; +use dutchheight\navie\models\Settings; +use dutchheight\navie\variables\NavieVariable; + +use markhuot\CraftQL\Builders\Schema; +use markhuot\CraftQL\CraftQL; +use markhuot\CraftQL\Events\AlterQuerySchema; + use yii\base\Event; /** @@ -142,6 +148,10 @@ private function _registerEventListeners() $this->_registerGraphql(); } + if (class_exists(CraftQL::class)) { + Event::on(Schema::class, AlterQuerySchema::EVENT, [GetNavieFieldSchema::class, 'handle']); + } + // Install only for non-console Control Panel requests if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) { $this->_registerCpEventListeners(); diff --git a/src/craftql/arguments/ListItemQueryArguments.php b/src/craftql/arguments/ListItemQueryArguments.php new file mode 100644 index 0000000..433f39a --- /dev/null +++ b/src/craftql/arguments/ListItemQueryArguments.php @@ -0,0 +1,44 @@ +load(); + + $this->owner->addIntArgument('ancestorOf'); + $this->owner->addIntArgument('ancestorDist'); + $this->owner->addIntArgument('level'); + $this->owner->addIntArgument('descendantOf'); + $this->owner->addIntArgument('descendantDist'); + $this->owner->addBooleanArgument('fixedOrder'); + $this->owner->addArgument('list')->type((new ListFactory($repository, $this->owner->request))->enum())->lists(); + $this->owner->addIntArgument('listId'); + $this->owner->addIntArgument('id')->lists(); + $this->owner->addStringArgument('indexBy'); + $this->owner->addIntArgument('limit'); + $this->owner->addStringArgument('site'); + $this->owner->addIntArgument('siteId'); + $this->owner->addIntArgument('nextSiblingOf'); + $this->owner->addIntArgument('offset'); + $this->owner->addStringArgument('order'); + $this->owner->addStringArgument('orderBy'); + $this->owner->addIntArgument('positionedAfter'); + $this->owner->addIntArgument('positionedBefore'); + $this->owner->addIntArgument('prevSiblingOf'); + $this->owner->addIntArgument('siblingOf'); + $this->owner->addStringArgument('title'); + $this->owner->addStringArgument('url'); + + $fieldService = \Yii::$container->get('craftQLFieldService'); + $arguments = $fieldService->getQueryArguments($this->owner->getRequest()); + $this->owner->addArguments($arguments, false); + } +} \ No newline at end of file diff --git a/src/craftql/factories/ListFactory.php b/src/craftql/factories/ListFactory.php new file mode 100644 index 0000000..f09c016 --- /dev/null +++ b/src/craftql/factories/ListFactory.php @@ -0,0 +1,19 @@ +getLists()->getAllLists() as $list) { + if (!isset($this->lists[$list->id])) { + $this->lists[$list->id] = $list; + + if (!empty($list->uid)) { + $this->lists[$list->uid] = $list; + } + } + } + } + + public function get($id) + { + if (!isset($this->lists[$id])) { + return false; + } + + return $this->lists[$id]; + } + + public function all() + { + return $this->lists; + } +} \ No newline at end of file diff --git a/src/craftql/types/ItemInterface.php b/src/craftql/types/ItemInterface.php new file mode 100644 index 0000000..5c07698 --- /dev/null +++ b/src/craftql/types/ItemInterface.php @@ -0,0 +1,59 @@ +addIntField('id')->nonNull(); + $this->addIntField('listId'); + $this->addIntField('elementId'); + $this->addIntField('level'); + + $this->addStringField('title')->nonNull(); + $this->addStringField('type'); + $this->addStringField('url'); + $this->addStringField('target'); + + $this->addField('children') + ->type(ItemInterface::class) + ->lists() + ->use(new ListItemQueryArguments) + ->resolve(function ($root, $args, $context, $info) { + return ItemInterface::criteriaResolver($root, $args, $context, $info, $root->getChildren()); + }); + + $this->addField('parent')->type(ItemInterface::class); + $this->addField('next')->type(ItemInterface::class); + $this->addField('nextSibling')->type(ItemInterface::class); + $this->addField('prev')->type(ItemInterface::class); + $this->addField('prevSibling')->type(ItemInterface::class); + } + + function getResolveType() + { + return function ($item) { + return ucfirst($item->list->handle) . 'List'; + }; + } + + static function criteriaResolver($root, $args, $context, $info, $criteria = null, $asArray = true) { + $criteria = $criteria ?: ListItem::find(); + + if (isset($args['list'])) { + $args['listId'] = $args['list'][0]; + unset($args['list']); + } + + foreach ($args as $key => $value) { + $criteria = $criteria->{$key}($value); + } + + return $asArray ? $criteria->all() : $criteria; + } +} \ No newline at end of file diff --git a/src/craftql/types/ListItemType.php b/src/craftql/types/ListItemType.php new file mode 100644 index 0000000..9732322 --- /dev/null +++ b/src/craftql/types/ListItemType.php @@ -0,0 +1,24 @@ +addFieldsByLayoutId($this->context->fieldLayoutId); + } + + function getName(): string + { + return ucfirst($this->context->handle) . 'List'; + } + +} diff --git a/src/craftql/types/ListType.php b/src/craftql/types/ListType.php new file mode 100644 index 0000000..f3e4140 --- /dev/null +++ b/src/craftql/types/ListType.php @@ -0,0 +1,37 @@ +addIntField('id'); + $this->addIntField('structureId'); + $this->addIntField('fieldLayoutId'); + $this->addIntField('maxLevels'); + + $this->addStringField('name'); + $this->addStringField('handle'); + $this->addStringField('uid'); + + $this->addBooleanField('propagate'); + + $this->addDateField('dateCreated'); + $this->addDateField('dateUpdated'); + } + + static function criteriaResolver($root, $args, $context, $info, $criteria = null, $asArray = true) + { + $criteria = $criteria ?: ListRecord::find(); + + foreach ($args as $key => $value) { + $criteria = $criteria->where([$key => $value]); + } + + return $asArray ? $criteria->all() : $criteria; + } +} diff --git a/src/listeners/GetNavieFieldSchema.php b/src/listeners/GetNavieFieldSchema.php new file mode 100644 index 0000000..42700cc --- /dev/null +++ b/src/listeners/GetNavieFieldSchema.php @@ -0,0 +1,52 @@ +load(); + + $factory = new ListFactory($repository, $event->query->getRequest()); + + foreach ($factory->all() as $list) { + $event->query->addConcreteType($list->getRawGraphQLObject()); + } + + $navieType = $event->query->createObjectType('Navie'); + + $navieType + ->addField('items') + ->lists() + ->type(ItemInterface::class) + ->use(new ListItemQueryArguments) + ->resolve(function ($root, $args, $context, $info) { + return ItemInterface::criteriaResolver($root, $args, $context, $info); + }); + + $navieType + ->addField('lists') + ->lists() + ->type(ListType::class) + ->resolve(function ($root, $args, $context, $info) { + return ListType::criteriaResolver($root, $args, $context, $info); + }); + + $event->query + ->addField('navie') + ->type($navieType) + ->resolve(function ($root) { + return []; + }); + } +} \ No newline at end of file diff --git a/src/records/ListRecord.php b/src/records/ListRecord.php index 17d909a..3af94dd 100644 --- a/src/records/ListRecord.php +++ b/src/records/ListRecord.php @@ -10,12 +10,9 @@ namespace dutchheight\navie\records; -use dutchheight\navie\Navie; - -use Craft; use craft\db\ActiveRecord; -use craft\records\Structure; use craft\records\FieldLayout; +use craft\records\Structure; use yii\db\ActiveQueryInterface; @@ -38,7 +35,6 @@ class ListRecord extends ActiveRecord /** * @inheritdoc - * @return string */ public static function tableName(): string {