<?php
$category = function(string $name, $parent = null) {
return new class($name, $parent) {
public $name;
public $parent;
public function __construct(string $name, $parent = null) {
$this->name = $name;
$this->parent = $parent;
}
public function breadcrumbs(array $trail = [], ?callable $decorator = null) {
$decorator = $decorator ?? function(string $item) {
return $item;
};
$trail[] = $decorator($this->name);
return $this->parent ? $this->parent->breadcrumbs($trail, $decorator) : $trail;
}
};
};
$categorize = function(...$categories) use($category) {
return array_reduce(array_reverse($categories), function($set, $item) use($category) {
if (!$set) {
return $category($item);
}
return $category($item, $set);
});
};
$product = function(string $name, string $sku, ...$categories) use($categorize) {
return new class($name, $sku, $categorize(...$categories)) {
public $name;
public $categories;
public $sku;
public function __construct(string $name, string $sku, $categories) {
$this->name = $name;
$this->sku = $sku;
$this->categories = $categories;
}
public function trail(string $separator = ' / ', ?callable $decorator = null): string {
return implode($separator, $this->categories->breadcrumbs([], $decorator));
}
public function linkSimilar(string $separator = ' / '): string {
return $this->trail($separator, function(string $name) {
return sprintf('<a href="/category/%s?similar-to=product/%s">%s</a>', $name, $this->sku, $name);
});
}
};
};
$book = $product('Harry Potter', 'U425261', 'books', 'hardback', 'young-adult');
$shoes = $product('Air Jordans', 'U425262', 'shoes', 'mens', 'sports', 'basketball');
$tapeMeasure = $product('Stanley 25', 'U425263', 'hardware', 'tools', 'measurement');
var_dump(
$book->trail(),
$shoes->trail(' | '),
$tapeMeasure->linkSimilar(PHP_EOL.' > ')
);
- Output for 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.33, 8.2.0 - 8.2.29, 8.3.0 - 8.3.25, 8.4.1 - 8.4.12
- string(30) "books / hardback / young-adult"
string(34) "shoes | mens | sports | basketball"
string(212) "<a href="/category/hardware?similar-to=product/U425263">hardware</a>
> <a href="/category/tools?similar-to=product/U425263">tools</a>
> <a href="/category/measurement?similar-to=product/U425263">measurement</a>"
preferences:
109.8 ms | 408 KiB | 5 Q