| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- <?php
- namespace Tools\View\Icon;
- use Cake\Core\InstanceConfigTrait;
- use Cake\Utility\Inflector;
- use RuntimeException;
- class IconCollection {
- use InstanceConfigTrait;
- /**
- * @var array<string, mixed>
- */
- protected $_defaultConfig = [];
- /**
- * @var string
- */
- protected $defaultSet;
- /**
- * @var array<string, \Tools\View\Icon\IconInterface>
- */
- protected $iconSets = [];
- /**
- * @param array<string, mixed> $config
- */
- public function __construct(array $config = []) {
- /** @var array<class-string<\Tools\View\Icon\IconInterface>|array<string, mixed>> $sets */
- $sets = $config['sets'] ?? [];
- unset($config['sets']);
- foreach ($sets as $set => $setConfig) {
- if (is_string($setConfig)) {
- $setConfig = [
- 'class' => $setConfig,
- ];
- } else {
- if (empty($setConfig['class'])) {
- throw new RuntimeException('You must define a `class` for each icon set.');
- }
- }
- /** @var class-string<\Tools\View\Icon\IconInterface> $className */
- $className = $setConfig['class'];
- $setConfig += $config;
- $this->iconSets[$set] = new $className($setConfig);
- }
- $key = array_key_first($sets);
- if (!$key) {
- throw new RuntimeException('No set defined for icon collection, at least one is required.');
- }
- $this->defaultSet = $key;
- $this->setConfig($config);
- }
- /**
- * @return array<string, array<string>>
- */
- public function names(): array {
- $names = [];
- foreach ($this->iconSets as $name => $set) {
- $path = $this->_config['config'][$name]['path'] ?? null;
- if ($path === null) {
- continue;
- }
- if (!file_exists($path)) {
- throw new RuntimeException('Cannot find file path `' . $path . '` for icon set `' . $name . '`');
- }
- $iconNames = $set->names($path);
- $names[$name] = $iconNames;
- }
- ksort($names);
- return $names;
- }
- /**
- * Icons using the default namespace or an already prefixed one.
- *
- * @param string $icon Icon name, prefixed for non default namespace
- * @param array<string, mixed> $options :
- * - translate, title, ...
- * @param array<string, mixed> $attributes :
- * - class, ...
- * @return string
- */
- public function render(string $icon, array $options = [], array $attributes = []): string {
- if (isset($this->_config['map'][$icon])) {
- $icon = $this->_config['map'][$icon];
- }
- $separator = $this->_config['separator'];
- $separatorPos = strpos($icon, $separator);
- if ($separatorPos !== false) {
- [$set, $icon] = explode($separator, $icon, 2);
- } else {
- $set = $this->defaultSet;
- }
- if (!isset($this->iconSets[$set])) {
- throw new RuntimeException('No such icon namespace: `' . $set . '`.');
- }
- $options += $this->_config;
- if (!isset($options['title']) || $options['title'] !== false) {
- $titleField = !isset($options['title']) || $options['title'] === true ? 'title' : $options['title'];
- if (!isset($attributes[$titleField])) {
- $attributes[$titleField] = ucwords(Inflector::humanize(Inflector::underscore($icon)));
- }
- }
- if (!isset($options['translate']) || $options['translate'] !== false) {
- $attributes['title'] = __($attributes['title']);
- }
- return $this->iconSets[$set]->render($icon, $options, $attributes);
- }
- }
|