Skip to content

Commit

Permalink
Properly determine custom attribute types
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinai committed Nov 25, 2020
1 parent cfa5b1a commit 3f43888
Show file tree
Hide file tree
Showing 26 changed files with 675 additions and 75 deletions.
4 changes: 3 additions & 1 deletion Api/DataTypeGuesserInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@

interface DataTypeGuesserInterface
{
public function typeOf($value): ?string;
public function valueToTypeCode($value): ?string;

public function typeToTypeCode(string $type): ?string;
}
13 changes: 9 additions & 4 deletions Model/DataType/ArrayDataType.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,26 @@ public function __construct(
$this->dataTypeGuesser = $dataTypeGuesser;
}

public function typeOf($value): ?string
public function valueToTypeCode($value): ?string
{
return is_array($value) ? self::TYPE_ARRAY : null;
}

public function typeToTypeCode(string $type): ?string
{
return $type === self::TYPE_ARRAY ? $type : null;
}

public function toString($value): ?string
{
return $this->typeOf($value)
return $this->valueToTypeCode($value)
? (empty($value) ? '[ ]' : sprintf('[...(%d)...]', count($value)))
: null;
}

public function toStringRecursive($value, $maxRecursionDepth = 1): ?string
{
return $this->typeOf($value) && $this->mayRecurse($maxRecursionDepth)
return $this->valueToTypeCode($value) && $this->mayRecurse($maxRecursionDepth)
? $this->implode($value, $maxRecursionDepth)
: $this->toString($value);
}
Expand All @@ -63,7 +68,7 @@ private function recur(array $value, int $maxRecursionDepth): array
$itemsToShow = $overLimit ? slice($value, 0, self::LIMIT) : $value;

$strings = map(function ($value) use ($maxRecursionDepth): string {
$converter = $this->toStringConverterLocator->forType($this->dataTypeGuesser->typeOf($value));
$converter = $this->toStringConverterLocator->forTypeCode($this->dataTypeGuesser->valueToTypeCode($value));
return $converter->toStringRecursive($value, $maxRecursionDepth - 1);
}, $itemsToShow);

Expand Down
57 changes: 57 additions & 0 deletions Model/DataType/CategoryLinkDataType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php declare(strict_types=1);

namespace Hyva\Admin\Model\DataType;

use Hyva\Admin\Api\DataTypeGuesserInterface;
use Hyva\Admin\Api\DataTypeValueToStringConverterInterface;
use Magento\Catalog\Api\Data\CategoryLinkInterface;

class CategoryLinkDataType implements DataTypeGuesserInterface, DataTypeValueToStringConverterInterface
{
const TYPE_MAGENTO_CATEGORY_LINK = 'magento_category_link';

public function valueToTypeCode($value): ?string
{
return $this->isCategoryLinkInstance($value)
? self::TYPE_MAGENTO_CATEGORY_LINK
: null;
}

public function typeToTypeCode(string $type): ?string
{
return $this->isCategoryLinkClassName($type)
? self::TYPE_MAGENTO_CATEGORY_LINK
: null;
}

private function isCategoryLinkInstance($value): bool
{
return is_object($value) && $value instanceof CategoryLinkInterface;
}

private function isCategoryLinkClassName($value): bool
{
return is_string($value) && is_subclass_of($value, CategoryLinkInterface::class);
}

/**
* @param CategoryLinkInterface|mixed $value
* @return string|null
*/
public function toString($value): ?string
{
return $this->valueToTypeCode($value)
? $this->formatCategoryLink($value)
: null;
}

public function toStringRecursive($value, $maxRecursionDepth = self::UNLIMITED_RECURSION): ?string
{
return $this->toString($value);
}

private function formatCategoryLink(CategoryLinkInterface $categoryLink): string
{
return sprintf('cat_%d', $categoryLink->getCategoryId());
}
}
20 changes: 14 additions & 6 deletions Model/DataType/CompositeDataTypeGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,26 @@ class CompositeDataTypeGuesser implements TypeGuesser
{
private array $dataTypeGuessers;

private DataTypeGuesserFactory $dataTypeGuesserFactory;
private DataTypeGuesserPool $dataTypeGuesserPool;

public function __construct(array $dataTypeGuessers, DataTypeGuesserFactory $dataTypeGuesserFactory)
public function __construct(array $dataTypeGuessers, DataTypeGuesserPool $dataTypeGuesserPool)
{
$this->dataTypeGuessers = $dataTypeGuessers;
$this->dataTypeGuesserFactory = $dataTypeGuesserFactory;
$this->dataTypeGuessers = $dataTypeGuessers;
$this->dataTypeGuesserPool = $dataTypeGuesserPool;
}

public function typeOf($value): ?string
public function valueToTypeCode($value): ?string
{
return reduce($this->dataTypeGuessers, function (?string $type, string $class) use ($value): ?string {
return $type ?? $this->dataTypeGuesserFactory->get($class)->typeOf($value);
return $type ?? $this->dataTypeGuesserPool->get($class)->valueToTypeCode($value);
}, null);
}

public function typeToTypeCode(string $type): ?string
{
return reduce($this->dataTypeGuessers, function (?string $typeCode, string $class) use ($type): ?string {
return $typeCode ?? $this->dataTypeGuesserPool->get($class)->typeToTypeCode($type);
}, null);

}
}
66 changes: 66 additions & 0 deletions Model/DataType/CustomerAddressDataType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php declare(strict_types=1);

namespace Hyva\Admin\Model\DataType;

use Hyva\Admin\Api\DataTypeGuesserInterface;
use Hyva\Admin\Api\DataTypeValueToStringConverterInterface;
use Magento\Customer\Api\Data\AddressInterface;

use function array_filter as filter;

class CustomerAddressDataType implements DataTypeGuesserInterface, DataTypeValueToStringConverterInterface
{
const TYPE_MAGENTO_CUSTOMER_ADDRESS = 'magento_customer_address';

public function valueToTypeCode($value): ?string
{
return $this->isAddressInstance($value)
? self::TYPE_MAGENTO_CUSTOMER_ADDRESS
: null;
}

public function typeToTypeCode(string $type): ?string
{
return $this->isAddressClassName($type)
? self::TYPE_MAGENTO_CUSTOMER_ADDRESS
: null;
}

private function isAddressInstance($value): bool
{
return is_object($value) && $value instanceof AddressInterface;
}

private function isAddressClassName($value): bool
{
return is_string($value) && is_subclass_of($value, AddressInterface::class);
}

/**
* @param AddressInterface|null $value
* @return string|null
*/
public function toString($value): ?string
{
return $this->valueToTypeCode($value)
? $this->renderAddress($value)
: null;
}

public function toStringRecursive($value, $maxRecursionDepth = self::UNLIMITED_RECURSION): ?string
{
return $this->toString($value);
}

private function renderAddress(?AddressInterface $value): string
{
$parts = [
$value->getFirstname() . ' ' . $value->getLastname(),
implode(', ', filter($value->getStreet() ?? [])),
$value->getCity(),
$value->getPostcode(),
$value->getCountryId(),
];
return implode(', ', filter($parts));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Hyva\Admin\Api\DataTypeGuesserInterface;
use Magento\Framework\ObjectManagerInterface;

class DataTypeGuesserFactory
class DataTypeGuesserPool
{
private ObjectManagerInterface $objectManager;

Expand Down
6 changes: 3 additions & 3 deletions Model/DataType/DataTypeToStringConverterLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ public function __construct(
$this->dataTypeValueToStringConverterFactory = $dataTypeValueToStringConverterFactory;
}

public function forType(string $type): ?DataTypeValueToStringConverterInterface
public function forTypeCode(string $typeCode): ?DataTypeValueToStringConverterInterface
{
return isset($this->valueToStringConverters[$type])
? $this->dataTypeValueToStringConverterFactory->get($this->valueToStringConverters[$type])
return isset($this->valueToStringConverters[$typeCode])
? $this->dataTypeValueToStringConverterFactory->get($this->valueToStringConverters[$typeCode])
: null;
}
}
43 changes: 43 additions & 0 deletions Model/DataType/DateTimeDataTypeConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php declare(strict_types=1);

namespace Hyva\Admin\Model\DataType;

use Hyva\Admin\Api\DataTypeGuesserInterface;
use Hyva\Admin\Api\DataTypeValueToStringConverterInterface;
use Magento\Framework\Stdlib\DateTime\DateTimeFormatterInterface;

class DateTimeDataTypeConverter implements DataTypeGuesserInterface, DataTypeValueToStringConverterInterface
{
const TYPE_DATETIME = 'datetime';

private DateTimeFormatterInterface $dateTimeFormatter;

public function __construct(DateTimeFormatterInterface $dateTimeFormatter)
{
$this->dateTimeFormatter = $dateTimeFormatter;
}

public function valueToTypeCode($value): ?string
{
return is_string($value) && preg_match('/^\d{4}-\d\d-\d\d[ T]\d\d:\d\d:\d\d$/', $value)
? self::TYPE_DATETIME
: null;
}

public function typeToTypeCode(string $type): ?string
{
return $type === self::TYPE_DATETIME ? self::TYPE_DATETIME : null;
}

public function toString($value): ?string
{
return $this->valueToTypeCode($value)
? $this->dateTimeFormatter->formatObject(new \DateTimeImmutable($value))
: null;
}

public function toStringRecursive($value, $maxRecursionDepth = self::UNLIMITED_RECURSION): ?string
{
return $this->toString($value);
}
}
51 changes: 51 additions & 0 deletions Model/DataType/GalleryDataType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types=1);

namespace Hyva\Admin\Model\DataType;

use Hyva\Admin\Api\DataTypeGuesserInterface;
use Hyva\Admin\Api\DataTypeValueToStringConverterInterface;
use Magento\Catalog\Model\Product\Image\UrlBuilder as ImageUrlBuilder;

use function array_map as map;

class GalleryDataType implements DataTypeGuesserInterface, DataTypeValueToStringConverterInterface
{
const TYPE_MAGENTO_PRODUCT_GALLERY = 'magento_product_gallery';

private ImageUrlBuilder $imageUrlBuilder;

public function __construct(ImageUrlBuilder $imageUrlBuilder)
{
$this->imageUrlBuilder = $imageUrlBuilder;
}

public function valueToTypeCode($value): ?string
{
return null;
}

public function typeToTypeCode(string $type): ?string
{
return $type === 'gallery'
? self::TYPE_MAGENTO_PRODUCT_GALLERY
: null;
}

public function toString($value): ?string
{
return implode('', map([$this, 'buildImageTag'], $value['images'] ?? []));
}

public function toStringRecursive($value, $maxRecursionDepth = self::UNLIMITED_RECURSION): ?string
{
return $this->toString($value);
}

private function buildImageTag(array $galleryImage): string
{
$file = $galleryImage['file'] ?? '';
return $file
? sprintf('<img src="%s" alt="Product Gallery Value"/>', $this->imageUrlBuilder->getUrl($file, 'thumbnail'))
: '';
}
}
26 changes: 22 additions & 4 deletions Model/DataType/ProductDataType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,38 @@ class ProductDataType implements DataTypeGuesserInterface, DataTypeValueToString
{
const MAGENTO_PRODUCT = 'magento_product';

public function typeOf($value): ?string
public function valueToTypeCode($value): ?string
{
return is_object($value) && $value instanceof ProductInterface
return $this->isProductInstance($value)
? self::MAGENTO_PRODUCT
: null;
}

public function typeToTypeCode(string $type): ?string
{
return $this->isProductClassName($type)
? self::MAGENTO_PRODUCT
: null;

}

private function isProductInstance($value): bool
{
return is_object($value) && $value instanceof ProductInterface;
}

private function isProductClassName($value): bool
{
return is_string($value) && is_subclass_of($value, ProductInterface::class);
}

/**
* @param ProductInterface|mixed $value
* @return string|null
*/
public function toString($value): ?string
{
return $this->typeOf($value)
return $this->valueToTypeCode($value)
? $this->getDisplayName($value)
: null;
}
Expand All @@ -35,7 +53,7 @@ private function getDisplayName(ProductInterface $product): string

public function toStringRecursive($value, $maxRecursionDepth = self::UNLIMITED_RECURSION): ?string
{
return $this->typeOf($value)
return $this->valueToTypeCode($value)
? sprintf('%s [SKU %s]', $this->getDisplayName($value), $value->getSku() ?? '?')
: null;
}
Expand Down
Loading

0 comments on commit 3f43888

Please sign in to comment.