Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
use craft\events\DefineConsoleActionsEvent;
use craft\events\DefineFieldLayoutFieldsEvent;
use craft\events\RegisterComponentTypesEvent;
use craft\events\RegisterGqlQueriesEvent;
use craft\events\RegisterGqlSchemaComponentsEvent;
use craft\events\RegisterGqlTypesEvent;
use craft\events\RegisterUrlRulesEvent;
use craft\feedme\events\RegisterFeedMeFieldsEvent;
use craft\fields\Link;
Expand All @@ -30,6 +33,7 @@
use craft\services\Elements;
use craft\services\Fields;
use craft\services\Gc;
use craft\services\Gql;
use craft\services\Utilities;
use craft\shopify\db\Table;
use craft\shopify\elements\Product;
Expand All @@ -39,6 +43,8 @@
use craft\shopify\fieldlayoutelements\OptionsField;
use craft\shopify\fieldlayoutelements\VariantsField;
use craft\shopify\fields\Products as ProductsField;
use craft\shopify\gql\interfaces\elements\Product as GqlProductInterface;
use craft\shopify\gql\queries\Product as GqlProductQueries;
use craft\shopify\handlers\Webhook;
use craft\shopify\linktypes\Product as ProductLinkType;
use craft\shopify\models\Settings;
Expand Down Expand Up @@ -137,6 +143,9 @@ public function init()
$this->_registerResaveCommands();
$this->_registerGarbageCollection();
$this->_registerFeedMeEvents();
$this->_registerGqlInterfaces();
$this->_registerGqlQueries();
$this->_registerGqlComponents();

if (!$request->getIsConsoleRequest()) {
if ($request->getIsCpRequest()) {
Expand Down Expand Up @@ -251,6 +260,49 @@ private function _registerElementTypes(): void
});
}


/**
* Register the Gql interfaces
* @since 7.1.0
*/
private function _registerGqlInterfaces(): void
{
Event::on(Gql::class, Gql::EVENT_REGISTER_GQL_TYPES, static function(RegisterGqlTypesEvent $event) {
$event->types[] = GqlProductInterface::class;
});
}

/**
* Register the Gql queries
* @since 7.1.0
*/
private function _registerGqlQueries(): void
{
Event::on(Gql::class, Gql::EVENT_REGISTER_GQL_QUERIES, static function(RegisterGqlQueriesEvent $event) {
$event->queries = array_merge(
$event->queries,
GqlProductQueries::getQueries(),
);
});
}

/**
* Register the Gql permissions
* @since 7.1.0
*/
private function _registerGqlComponents(): void
{
Event::on(Gql::class, Gql::EVENT_REGISTER_GQL_SCHEMA_COMPONENTS, static function(RegisterGqlSchemaComponentsEvent $event) {
$typeName = (new Product())->getGqlTypeName();
$event->queries = array_merge($event->queries, [
Craft::t('shopify', 'Shopify Products') => [
$typeName . ':read' => ['label' => Craft::t('shopify', 'View products')],
],
]);
});
}


/**
* Register Shopify’s fields
*
Expand Down
19 changes: 19 additions & 0 deletions src/elements/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,25 @@ public function init(): void
parent::init();
}

/**
* @inheritdoc
* @since 7.1.0
*/
public static function gqlScopesByContext(mixed $context): array
{
/** @var FieldLayout $context */
return ['ShopifyProduct'];
}

/**
* @return string
* @since 7.1.0
*/
public function getGqlTypeName(): string
{
return 'ShopifyProduct';
}

/**
* @inheritdoc
*/
Expand Down
1 change: 0 additions & 1 deletion src/elements/db/ProductQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class ProductQuery extends ElementQuery
*/
public mixed $handle = null;


/**
* @var mixed|null
*/
Expand Down
80 changes: 80 additions & 0 deletions src/gql/arguments/elements/Product.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\shopify\gql\arguments\elements;

use Craft;
use craft\gql\base\ElementArguments;
use craft\gql\types\QueryArgument;
use craft\shopify\elements\Product as ProductElement;
use craft\shopify\Plugin;
use GraphQL\Type\Definition\Type;

/**
* Class Product
*
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 7.1.0
*/
class Product extends ElementArguments
{
/**
* @inheritdoc
*/
public static function getArguments(): array
{
return array_merge(parent::getArguments(), self::getContentArguments(), [
'shopifyId' => [
'name' => 'shopifyId',
'type' => Type::listOf(QueryArgument::getType()),
'description' => 'Narrows the query results based on the Shopify ID on the product.',
],
'shopifyGid' => [
'name' => 'shopifyGid',
'type' => Type::listOf(QueryArgument::getType()),
'description' => 'Narrows the query results based on the Shopify GID on the product.',
],
'shopifyStatus' => [
'name' => 'shopifyStatus',
'type' => Type::listOf(QueryArgument::getType()),
'description' => 'Narrows the query results based on the Shopify status of the product.',
],
'handle' => [
'name' => 'handle',
'type' => Type::listOf(QueryArgument::getType()),
'description' => 'Narrows the query results based on the handle on the product.',
],
'productType' => [
'name' => 'productType',
'type' => Type::listOf(QueryArgument::getType()),
'description' => 'Narrows the query results based on the product type on the product.',
],
'tags' => [
'name' => 'tags',
'type' => Type::listOf(QueryArgument::getType()),
'description' => 'Narrows the query results based on the tags on the product.',
],
'vendor' => [
'name' => 'vendor',
'type' => Type::listOf(QueryArgument::getType()),
'description' => 'Narrows the query results based on the vendor on the product.',
],
]);
}

/**
* @inheritdoc
*/
public static function getContentArguments(): array
{
$productFieldsArguments = Craft::$app->getGql()->getContentArguments([
Plugin::getInstance()->getSettings()->getProductFieldLayout(),
], ProductElement::class);

return array_merge(parent::getContentArguments(), $productFieldsArguments);
}
}
155 changes: 155 additions & 0 deletions src/gql/interfaces/elements/Product.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\shopify\gql\interfaces\elements;

use Craft;
use craft\gql\GqlEntityRegistry;
use craft\gql\interfaces\Element;
use craft\gql\types\DateTime;
use craft\shopify\elements\Product as ProductElement;
use craft\shopify\gql\types\generators\ProductType;
use craft\shopify\gql\types\JsonType;
use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\Type;

/**
* Class Product
*
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 7.1.0
*/
class Product extends Element
{
/**
* @inheritdoc
*/
public static function getTypeGenerator(): string
{
return ProductType::class;
}

/**
* @inheritdoc
*/
public static function getType($fields = null): Type
{
if ($type = GqlEntityRegistry::getEntity(self::getName())) {
return $type;
}

$type = GqlEntityRegistry::createEntity(self::getName(), new InterfaceType([
'name' => static::getName(),
'fields' => self::class . '::getFieldDefinitions',
'description' => 'This is the interface implemented by all products.',
'resolveType' => function(ProductElement $value) {
return $value->getGqlTypeName();
},
]));

ProductType::generateTypes();

return $type;
}

/**
* @inheritdoc
*/
public static function getName(): string
{
return 'ShopifyProductInterface';
}

/**
* @inheritdoc
*/
public static function getFieldDefinitions(): array
{
return Craft::$app->getGql()->prepareFieldDefinitions(array_merge(parent::getFieldDefinitions(), [
'createdAt' => [
'name' => 'createdAt',
'type' => DateTime::getType(),
'description' => 'The date the product was created in Shopify.',
],
'publishedAt' => [
'name' => 'publishedAt',
'type' => DateTime::getType(),
'description' => 'The date the product was published in Shopify.',
],
'updatedAt' => [
'name' => 'updatedAt',
'type' => DateTime::getType(),
'description' => 'The date the product was updated in Shopify.',
],
'handle' => [
'name' => 'handle',
'type' => Type::string(),
'description' => 'The product’s handle.',
],
'descriptionHtml' => [
'name' => 'descriptionHtml',
'type' => Type::string(),
'description' => 'The product’s description HTML in Shopify.',
],
'productType' => [
'name' => 'productType',
'type' => Type::string(),
'description' => 'The product’s type in Shopify.',
],
'publishedOnCurrentPublication' => [
'name' => 'publishedOnCurrentPublication',
'type' => Type::boolean(),
'description' => 'If the product is published on the current publication in Shopify.',
],
'shopifyId' => [
'name' => 'shopifyId',
'type' => Type::string(),
'description' => 'The product’s Shopify ID.',
],
'shopifyGid' => [
'name' => 'shopifyGid',
'type' => Type::string(),
'description' => 'The product’s Shopify GID.',
],
'shopifyStatus' => [
'name' => 'shopifyStatus',
'type' => Type::string(),
'description' => 'The product’s status in Shopify.',
],
'vendor' => [
'name' => 'vendor',
'type' => Type::string(),
'description' => 'The product’s vendor in Shopify.',
],
'images' => [
'name' => 'images',
'type' => JsonType::getType(),
'description' => 'The product’s images in Shopify.',
],
'tags' => [
'name' => 'tags',
'type' => JsonType::getType(),
'description' => 'The product’s tags in Shopify.',
],
'metafields' => [
'name' => 'metafields',
'type' => JsonType::getType(),
'description' => 'The product’s metafields in Shopify.',
],
'variants' => [
'name' => 'variants',
'type' => JsonType::getType(),
'description' => 'The product’s variants in Shopify.',
],
'data' => [
'name' => 'data',
'type' => JsonType::getType(),
'description' => 'The product’s synced data from Shopify.',
],
]), self::getName());
}
}
Loading
Loading