mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
f3a76ccf2d
* NEW: getByLink plugin allows arrays of links * Allow configurable resolver * Remove unused exception tag * Refactor to preserve API backward compat * Unit test * Add plugin to readOne * Fix test * add new test
105 lines
3.0 KiB
PHP
105 lines
3.0 KiB
PHP
<?php
|
|
|
|
|
|
namespace SilverStripe\CMS\GraphQL;
|
|
|
|
use GraphQL\Type\Definition\ResolveInfo;
|
|
use SilverStripe\CMS\Model\SiteTree;
|
|
use SilverStripe\Core\Config\Configurable;
|
|
use SilverStripe\Core\Injector\Injectable;
|
|
use SilverStripe\GraphQL\Schema\DataObject\Plugin\QueryFilter\QueryFilter;
|
|
use SilverStripe\GraphQL\Schema\Exception\SchemaBuilderException;
|
|
use SilverStripe\GraphQL\Schema\Field\ModelQuery;
|
|
use SilverStripe\GraphQL\Schema\Interfaces\ModelQueryPlugin;
|
|
use SilverStripe\GraphQL\Schema\Schema;
|
|
use SilverStripe\ORM\ArrayList;
|
|
use SilverStripe\ORM\DataList;
|
|
|
|
if (!interface_exists(ModelQueryPlugin::class)) {
|
|
return;
|
|
}
|
|
|
|
class LinkablePlugin implements ModelQueryPlugin
|
|
{
|
|
use Configurable;
|
|
use Injectable;
|
|
|
|
const IDENTIFIER = 'getByLink';
|
|
|
|
/**
|
|
* @var string
|
|
* @config
|
|
*/
|
|
private static $single_field_name = 'link';
|
|
|
|
/**
|
|
* @var string
|
|
* @config
|
|
*/
|
|
private static $list_field_name = 'links';
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private static $resolver = [__CLASS__, 'applyLinkFilter'];
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getIdentifier(): string
|
|
{
|
|
return self::IDENTIFIER;
|
|
}
|
|
|
|
/**
|
|
* @param ModelQuery $query
|
|
* @param Schema $schema
|
|
* @param array $config
|
|
*/
|
|
public function apply(ModelQuery $query, Schema $schema, array $config = []): void
|
|
{
|
|
$class = $query->getModel()->getSourceClass();
|
|
// Only site trees have the get_by_link capability
|
|
if ($class !== SiteTree::class && !is_subclass_of($class, SiteTree::class)) {
|
|
return;
|
|
}
|
|
$singleFieldName = $this->config()->get('single_field_name');
|
|
$listFieldName = $this->config()->get('list_field_name');
|
|
$fieldName = $query->isList() ? $listFieldName : $singleFieldName;
|
|
$type = $query->isList() ? '[String]' : 'String';
|
|
$query->addArg($fieldName, $type);
|
|
$query->addResolverAfterware(
|
|
$config['resolver'] ?? static::config()->get('resolver')
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $context
|
|
* @return callable
|
|
*/
|
|
public static function applyLinkFilter($obj, array $args, array $context, ResolveInfo $info)
|
|
{
|
|
$singleFieldName = static::config()->get('single_field_name');
|
|
$listFieldName = static::config()->get('list_field_name');
|
|
$filterLink = $args['filter'][$singleFieldName] ?? ($args['filter'][$listFieldName] ?? null);
|
|
$argLink = $args[$singleFieldName] ?? ($args[$listFieldName] ?? null);
|
|
$linkData = $filterLink ?: $argLink;
|
|
if (!$linkData) {
|
|
return $obj;
|
|
}
|
|
// Normalise to an array for both cases. The readOne operation will get
|
|
// ->first() run on it by the firstResult plugin.
|
|
$links = is_array($linkData) ? $linkData : [$linkData];
|
|
|
|
$result = ArrayList::create();
|
|
|
|
foreach ($links as $link) {
|
|
$page = SiteTree::get_by_link($link);
|
|
if ($page) {
|
|
$result->push($page);
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
}
|