Last active
November 23, 2020 19:55
-
-
Save timkelty/fe00ff49785802f3722bf3aaee5dd670 to your computer and use it in GitHub Desktop.
Scout Transformers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace modules\appmodule\transformers; | |
use craft\base\ElementInterface; | |
use League\Fractal\TransformerAbstract; | |
use modules\appmodule\AppModule; | |
use Tightenco\Collect\Support\Collection; | |
class ElementTransformer extends TransformerAbstract | |
{ | |
const DEFAULT_ATTRIBUTES = [ | |
'id', | |
'title', | |
'slug', | |
'uri', | |
'dateCreated', | |
'dateUpdated', | |
]; | |
public $transformer; | |
public function __construct() | |
{ | |
$this->transformer = AppModule::getInstance()->transformer; | |
} | |
public function transform(ElementInterface $element): array | |
{ | |
$values = Collection::make($element)->only(self::DEFAULT_ATTRIBUTES); | |
return $this->transformer->transformValues($values)->all(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace modules\appmodule\transformers; | |
use craft\base\ElementInterface; | |
use Tightenco\Collect\Support\Collection; | |
class ProductTransformer extends ElementTransformer | |
{ | |
public function transform(ElementInterface $entry): array | |
{ | |
$collection = Collection::make($entry) | |
->only([ | |
'someField', | |
'someOtherField', | |
]) | |
->merge(parent::transform($entry)) | |
->put('myMenu', $this->transformer->structureToMenuHierarchy($entry->myCategoriesField)); | |
return $this->transformer->transformValues($collection)->all(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace modules\appmodule\services; | |
use craft\base\Element; | |
use craft\elements\Asset; | |
use craft\elements\db\ElementQuery; | |
use craft\elements\User; | |
use craft\fields\data\MultiOptionsFieldData; | |
use craft\fields\data\OptionData; | |
use craft\models\EntryType; | |
use craft\models\Section; | |
use modules\appmodule\transformers\ElementTransformer; | |
use Tightenco\Collect\Support\Collection; | |
use yii\base\Component; | |
use yii\db\QueryInterface; | |
class Transformer extends Component | |
{ | |
public function transformSingleOptionFieldData(OptionData $data): Collection | |
{ | |
return Collection::make($data)->only('label', 'value'); | |
} | |
public function transformMultiOptionsFieldData(MultiOptionsFieldData $data): Collection | |
{ | |
return Collection::make($data->getOptions()) | |
->filter(function ($item) { | |
return $item->selected; | |
}) | |
->map(function ($item) { | |
return $this->transformSingleOptionFieldData($item); | |
}) | |
->values(); | |
} | |
public function structureToMenuHierarchy(ElementQuery $elementQuery): Collection | |
{ | |
$elements = Collection::make($elementQuery->orderBy(['level' => SORT_ASC])->all()) | |
->map(function ($element) { | |
$rootElement = $element->getAncestors()->one() ?? $element; | |
return Collection::make($element) | |
->only(['level', 'title', 'id']) | |
->put('rootId', $rootElement->id); | |
}); | |
return $elements | |
->groupBy('level') | |
->keys() | |
->flatMap(function ($level) use ($elements) { | |
$crumbs = $elements | |
->where('level', '<=', $level) | |
->groupBy('rootId') | |
->values() | |
->map(function ($item) { | |
return $item->pluck('title')->join(' > '); | |
}); | |
$key = implode('', ['lvl', $level -1]); | |
return [ | |
$key => $crumbs, | |
]; | |
}); | |
} | |
public function transformValue($value) | |
{ | |
if ($value instanceof \DateTime) { | |
return $value->getTimestamp(); | |
} elseif ($value instanceof RedactorFieldData) { | |
return (string) $value; | |
} elseif ($value instanceof MultiOptionsFieldData) { | |
return $this->transformMultiOptionsFieldData($value); | |
} elseif ($value instanceof SingleOptionFieldData) { | |
return $this->transformSingleOptionFieldData($value); | |
} elseif ($value instanceof User) { | |
return Collection::make($value) | |
->only([ | |
'id', | |
'username', | |
]); | |
} elseif ($value instanceof Asset) { | |
return Collection::make($value) | |
->only([ | |
'id', | |
'url', | |
]); | |
} elseif ($value instanceof Element) { | |
return (new ElementTransformer)->transform($value); | |
} elseif ($value instanceof Section || $value instanceof EntryType) { | |
return Collection::make($value) | |
->only([ | |
'name', | |
'handle', | |
]); | |
} elseif ($value instanceof QueryInterface) { | |
return $this->queryToCollection($value); | |
} | |
return $value; | |
} | |
public function queryToCollection(?QueryInterface $query): Collection | |
{ | |
return Collection::make($query ? $query->all() : null); | |
} | |
public function transformValues($values): Collection | |
{ | |
return Collection::make($this->transformValue($values))->map(function ($value) { | |
return (is_iterable($value)) ? | |
$this->transformValues($value) : | |
$this->transformValue($value); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment