Browse Source

Fix up config for icon

mscherer 3 years ago
parent
commit
37b6dfc00e

+ 1 - 0
config/Migrations/20200430170235_MigrationToolsTokens.php

@@ -1,4 +1,5 @@
 <?php
+
 use Migrations\AbstractMigration;
 
 class MigrationToolsTokens extends AbstractMigration {

+ 28 - 27
docs/Helper/Icon.md

@@ -33,19 +33,18 @@ E.g.
 For some Icon classes, there is additional configuration available:
 - `namespace`: Some fonts offer different traits (light, bold, round, ...)
 
-E.g.
+In this case make sure to use an array instead of just the class string:
 ```php
 'Icon' => [
-    'config' => [
+    'sets' => [
         'material' => [
+            'class' => \Tools\View\Icon\MaterialIcon::class,
             'namespace' => 'material-symbols-round',
         ],
         ...
     ],
 ],
 ```
-Make sure to use the same keys here as for the `sets` definition, otherwise the collector won't find your
-file configuration here.
 
 ## Usage
 
@@ -69,13 +68,13 @@ echo $this->Html->link(
 You can alias them via Configure for more usability:
 ```php
 // In app.php
-    'Icon' => [
-        'map' => [
-            'view' => 'bs:eye',
-            'translate' => 'bs:translate',
-            ...
-        ],
+'Icon' => [
+    'map' => [
+        'view' => 'bs:eye',
+        'translate' => 'bs:translate',
+        ...
     ],
+],
 
 // in the template
 echo $this->Icon->render('translate', [], ['title' => 'Translate this']);
@@ -88,27 +87,29 @@ You can get a nested list of all configured and available icons.
 For this make sure to set up the path config to the icon meta files as per each collector.
 E.g.:
 ```php
-    'Icon' => [
-        // For being able to parse the available icons
-        'config' => [
-            'fa' => [
-                'path' => '/path/to/font-awesome/less/variables.less',
-            ],
-            'bs' => [
-                'path' => '/path/to/bootstrap-icons/font/bootstrap-icons.json',
-            ],
-            'feather' => [
-                'path' => '/path/to/feather-icons/dist/icons.json',
-            ],
-            'material' => [
-                'path' => '/path/to/material-symbols/index.d.ts',
-            ],
+'Icon' => [
+    // For being able to parse the available icons
+    'sets' => [
+        'fa' => [
             ...
+            'path' => '/path/to/font-awesome/less/variables.less',
         ],
+        'bs' => [
+            ...
+            'path' => '/path/to/bootstrap-icons/font/bootstrap-icons.json',
+        ],
+        'feather' => [
+            ...
+            'path' => '/path/to/feather-icons/dist/icons.json',
+        ],
+        'material' => [
+            ...
+            'path' => '/path/to/material-symbols/index.d.ts',
+        ],
+        ...
     ],
+],
 ```
-Make sure to use the same keys here as for the `sets` definition, otherwise the collector won't find your
-file configuration here.
 
 You can then use this to iterate over all of them for display:
 ```php

+ 43 - 0
src/View/Icon/AbstractIcon.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace Tools\View\Icon;
+
+use Cake\View\StringTemplate;
+use RuntimeException;
+
+abstract class AbstractIcon implements IconInterface {
+
+	/**
+	 * @var \Cake\View\StringTemplate
+	 */
+	protected $template;
+
+	/**
+	 * @var array<string, mixed>
+	 */
+	protected $config;
+
+	/**
+	 * @param array<string, mixed> $config
+	 */
+	public function __construct(array $config = []) {
+		$this->template = new StringTemplate(['icon' => $config['template']]);
+		$this->config = $config;
+	}
+
+	/**
+	 * @return string
+	 */
+	protected function path(): string {
+		$path = $this->config['path'] ?? null;
+		if (!$path) {
+			throw new RuntimeException('You need to define a meta data file path for `' . static::class . '` in order to get icon names.');
+		}
+		if (!file_exists($path)) {
+			throw new RuntimeException('Cannot find meta data file path `' . $path . '` for `' . static::class . '`.');
+		}
+
+		return $path;
+	}
+
+}

+ 5 - 11
src/View/Icon/BootstrapIcon.php

@@ -2,15 +2,9 @@
 
 namespace Tools\View\Icon;
 
-use Cake\View\StringTemplate;
 use Tools\View\Icon\Collector\BootstrapIconCollector;
 
-class BootstrapIcon implements IconInterface {
-
-	/**
-	 * @var \Cake\View\StringTemplate
-	 */
-	protected $template;
+class BootstrapIcon extends AbstractIcon {
 
 	/**
 	 * @param array<string, mixed> $config
@@ -20,15 +14,15 @@ class BootstrapIcon implements IconInterface {
 			'template' => '<span class="{{class}}"{{attributes}}></span>',
 		];
 
-		$this->template = new StringTemplate(['icon' => $config['template']]);
+		parent::__construct($config);
 	}
 
 	/**
-	 * @param string $path
-	 *
 	 * @return array<string>
 	 */
-	public function names(string $path): array {
+	public function names(): array {
+		$path = $this->path();
+
 		return BootstrapIconCollector::collect($path);
 	}
 

+ 5 - 11
src/View/Icon/FeatherIcon.php

@@ -2,15 +2,9 @@
 
 namespace Tools\View\Icon;
 
-use Cake\View\StringTemplate;
 use Tools\View\Icon\Collector\FeatherIconCollector;
 
-class FeatherIcon implements IconInterface {
-
-	/**
-	 * @var \Cake\View\StringTemplate
-	 */
-	protected $template;
+class FeatherIcon extends AbstractIcon {
 
 	/**
 	 * @param array<string, mixed> $config
@@ -20,15 +14,15 @@ class FeatherIcon implements IconInterface {
 			'template' => '<span data-feather="{{name}}"{{attributes}}></span>',
 		];
 
-		$this->template = new StringTemplate(['icon' => $config['template']]);
+		parent::__construct($config);
 	}
 
 	/**
-	 * @param string $path
-	 *
 	 * @return array<string>
 	 */
-	public function names(string $path): array {
+	public function names(): array {
+		$path = $this->path();
+
 		return FeatherIconCollector::collect($path);
 	}
 

+ 5 - 11
src/View/Icon/FontAwesome4Icon.php

@@ -2,15 +2,9 @@
 
 namespace Tools\View\Icon;
 
-use Cake\View\StringTemplate;
 use Tools\View\Icon\Collector\FontAwesome4IconCollector;
 
-class FontAwesome4Icon implements IconInterface {
-
-	/**
-	 * @var \Cake\View\StringTemplate
-	 */
-	protected $template;
+class FontAwesome4Icon extends AbstractIcon {
 
 	/**
 	 * @param array<string, mixed> $config
@@ -20,15 +14,15 @@ class FontAwesome4Icon implements IconInterface {
 			'template' => '<span class="{{class}}"{{attributes}}></span>',
 		];
 
-		$this->template = new StringTemplate(['icon' => $config['template']]);
+		parent::__construct($config);
 	}
 
 	/**
-	 * @param string $path
-	 *
 	 * @return array<string>
 	 */
-	public function names(string $path): array {
+	public function names(): array {
+		$path = $this->path();
+
 		return FontAwesome4IconCollector::collect($path);
 	}
 

+ 7 - 18
src/View/Icon/FontAwesome5Icon.php

@@ -2,20 +2,9 @@
 
 namespace Tools\View\Icon;
 
-use Cake\View\StringTemplate;
 use Tools\View\Icon\Collector\FontAwesome5IconCollector;
 
-class FontAwesome5Icon implements IconInterface {
-
-	/**
-	 * @var \Cake\View\StringTemplate
-	 */
-	protected $template;
-
-	/**
-	 * @var string
-	 */
-	protected $namespace;
+class FontAwesome5Icon extends AbstractIcon {
 
 	/**
 	 * @param array<string, mixed> $config
@@ -23,18 +12,18 @@ class FontAwesome5Icon implements IconInterface {
 	public function __construct(array $config = []) {
 		$config += [
 			'template' => '<span class="{{class}}"{{attributes}}></span>',
+			'namespace' => 'fas',
 		];
 
-		$this->template = new StringTemplate(['icon' => $config['template']]);
-		$this->namespace = $config['namespace'] ?? 'fas';
+		parent::__construct($config);
 	}
 
 	/**
-	 * @param string $path
-	 *
 	 * @return array<string>
 	 */
-	public function names(string $path): array {
+	public function names(): array {
+		$path = $this->path();
+
 		return FontAwesome5IconCollector::collect($path);
 	}
 
@@ -50,7 +39,7 @@ class FontAwesome5Icon implements IconInterface {
 			];
 
 		$class = [
-			$this->namespace,
+			$this->config['namespace'],
 		];
 		if (!empty($options['extra'])) {
 			foreach ($options['extra'] as $i) {

+ 7 - 18
src/View/Icon/FontAwesome6Icon.php

@@ -2,20 +2,9 @@
 
 namespace Tools\View\Icon;
 
-use Cake\View\StringTemplate;
 use Tools\View\Icon\Collector\FontAwesome6IconCollector;
 
-class FontAwesome6Icon implements IconInterface {
-
-	/**
-	 * @var \Cake\View\StringTemplate
-	 */
-	protected $template;
-
-	/**
-	 * @var string
-	 */
-	protected $namespace;
+class FontAwesome6Icon extends AbstractIcon {
 
 	/**
 	 * @param array<string, mixed> $config
@@ -23,18 +12,18 @@ class FontAwesome6Icon implements IconInterface {
 	public function __construct(array $config = []) {
 		$config += [
 			'template' => '<span class="{{class}}"{{attributes}}></span>',
+			'namespace' => 'solid',
 		];
 
-		$this->template = new StringTemplate(['icon' => $config['template']]);
-		$this->namespace = $config['namespace'] ?? 'solid';
+		parent::__construct($config);
 	}
 
 	/**
-	 * @param string $path
-	 *
 	 * @return array<string>
 	 */
-	public function names(string $path): array {
+	public function names(): array {
+		$path = $this->path();
+
 		return FontAwesome6IconCollector::collect($path);
 	}
 
@@ -49,7 +38,7 @@ class FontAwesome6Icon implements IconInterface {
 		$formatOptions = $attributes + [
 		];
 
-		$namespace = 'fa-' . $this->namespace;
+		$namespace = 'fa-' . $this->config['namespace'];
 
 		$class = [
 			$namespace,

+ 1 - 9
src/View/Icon/IconCollection.php

@@ -66,15 +66,7 @@ class IconCollection {
 	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);
+			$iconNames = $set->names();
 			$names[$name] = $iconNames;
 		}
 

+ 1 - 3
src/View/Icon/IconInterface.php

@@ -5,11 +5,9 @@ namespace Tools\View\Icon;
 interface IconInterface {
 
 	/**
-	 * @param string $path
-	 *
 	 * @return array<string>
 	 */
-	public function names(string $path): array;
+	public function names(): array;
 
 	/**
 	 * Icon formatting using the specific engine.

+ 7 - 18
src/View/Icon/MaterialIcon.php

@@ -2,20 +2,9 @@
 
 namespace Tools\View\Icon;
 
-use Cake\View\StringTemplate;
 use Tools\View\Icon\Collector\MaterialIconCollector;
 
-class MaterialIcon implements IconInterface {
-
-	/**
-	 * @var \Cake\View\StringTemplate
-	 */
-	protected $template;
-
-	/**
-	 * @var string
-	 */
-	protected $namespace;
+class MaterialIcon extends AbstractIcon {
 
 	/**
 	 * @param array<string, mixed> $config
@@ -23,18 +12,18 @@ class MaterialIcon implements IconInterface {
 	public function __construct(array $config = []) {
 		$config += [
 			'template' => '<span class="{{class}}"{{attributes}}>{{name}}</span>',
+			'namespace' => 'material-icons',
 		];
 
-		$this->template = new StringTemplate(['icon' => $config['template']]);
-		$this->namespace = $config['namespace'] ?? 'material-icons';
+		parent::__construct($config);
 	}
 
 	/**
-	 * @param string $path
-	 *
 	 * @return array<string>
 	 */
-	public function names(string $path): array {
+	public function names(): array {
+		$path = $this->path();
+
 		return MaterialIconCollector::collect($path);
 	}
 
@@ -50,7 +39,7 @@ class MaterialIcon implements IconInterface {
 		];
 
 		$options['name'] = $icon;
-		$options['class'] = $this->namespace;
+		$options['class'] = $this->config['namespace'];
 		if (!empty($attributes['class'])) {
 			$options['class'] .= ' ' . $attributes['class'];
 		}

+ 2 - 5
tests/TestCase/View/Icon/IconCollectionTest.php

@@ -15,15 +15,12 @@ class IconCollectionTest extends TestCase {
 	public function testCollect(): void {
 		$config = [
 			'sets' => [
-				'feather' => FeatherIcon::class,
-				'material' => MaterialIcon::class,
-			],
-			// For being able to parse the available icons
-			'config' => [
 				'feather' => [
+					'class' => FeatherIcon::class,
 					'path' => TEST_FILES . 'font_icon/feather/icons.json',
 				],
 				'material' => [
+					'class' => MaterialIcon::class,
 					'path' => TEST_FILES . 'font_icon/material/index.d.ts',
 				],
 			],