Skip to content

Instantly share code, notes, and snippets.

@timkelty
Last active January 22, 2019 06:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timkelty/8de8531df688b6ac08d2da0713b6ff00 to your computer and use it in GitHub Desktop.
Save timkelty/8de8531df688b6ac08d2da0713b6ff00 to your computer and use it in GitHub Desktop.
Standardize Element API requests
<?php
namespace Craft;
class Custom_ElementApiHelper
{
public static function getParams($params)
{
$requestParams = array_filter([
'elementType' => craft()->request->getParam('elementType'),
'criteria' => Custom_ElementApiHelper::prepCriteria(craft()->request->getParam('criteria')),
'transformer' => Custom_ElementApiHelper::prepTransformer(craft()->request->getParam('transformer', 'element')),
'first' => (bool) craft()->request->getParam('first', false),
'paginate' => (bool) craft()->request->getParam('paginate', true),
'elementsPerPage' => craft()->request->getParam('elementsPerPage'),
'pageParam' => craft()->request->getParam('pageParam'),
], function ($i) {
return $i !== null;
});
$params = array_merge($params, $requestParams);
if (!isset($params['criteria']))
{
throw new Exception('Element API configs must specify a criteria.');
}
return $params;
}
public static function prepTransformer($transformer)
{
if (!$transformer) {
return;
}
$transformerClass = 'Custom_'.ucfirst($transformer).'Transformer';
return class_exists('Craft\\'.$transformerClass) ? Craft::createComponent('Craft\\'.$transformerClass) : null;
}
public static function prepCriteria($criteria)
{
if (!$criteria) {
return;
}
$criteria['relatedTo'] = self::prepRelatedCriteria(isset($criteria['relatedTo']) && $criteria['relatedTo'] ? $criteria['relatedTo'] : []);
return $criteria;
}
private static function prepRelatedCriteria($relatedTo)
{
$relatedTo = is_array($relatedTo) ? $relatedTo : [$relatedTo];
$operator = isset($relatedTo['operator']) && $relatedTo['operator'] ? $relatedTo['operator'] : 'and';
unset($relatedTo['operator']);
$relatedTo = array_filter(array_map(function ($field, $element) {
$criteria['element'] = array_filter(is_array($element) ? $element : [$element]);
if (is_string($field)) {
$criteria['field'] = $field;
}
return empty($criteria['element']) ? null : $criteria;
}, array_keys($relatedTo), $relatedTo));
if (count($relatedTo)) {
array_unshift($relatedTo, $operator);
}
return $relatedTo;
}
}
<?php
namespace Craft;
require realpath(implode('/', [
craft()->path->getPluginsPath(),
'/elementapi/vendor/autoload.php'
]));
use League\Fractal\TransformerAbstract;
class Custom_ElementTransformer extends TransformerAbstract
{
protected $fields = ['title', 'slug', 'id'];
public function transform(BaseElementModel $element)
{
$values = array();
foreach ($this->fields as $fieldName) {
$values[$fieldName] = $this->transformAttribute($element->$fieldName);
}
return $values;
}
protected function transformAttribute($value)
{
if ($value instanceof \DateTime) {
return $value->format(\DateTime::ISO8601);
} elseif ($value instanceOf ElementCriteriaModel) {
if ($value->elementType instanceof AssetElementType) {
return array_map(function($item) {
return [
'url' => $item->url,
'imgAltText' => $item->imgAltText,
];
}, $value->find());
}
return $value->ids();
} elseif ($value instanceOf RichTextData) {
return $value->getParsedContent();
}
return ModelHelper::packageAttributeValue($value);
}
}
<?php
namespace Craft;
Craft::import('plugins.custom.integrations.elementapi.*');
return [
'endpoints' => [
'api/elements.json' => function () {
return Custom_ElementApiHelper::getParams([
'transformer' => 'elements',
]);
},
'api/products.json' => function () {
return Custom_ElementApiHelper::getParams([
'transformer' => 'product',
'elementType' => ElementType::Entry,
]);
},
],
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment