Repository navigation
Expand file tree
/
Copy pathIcon_Command.php
More file actions
377 lines (348 loc) · 10.1 KB
/
Copy pathIcon_Command.php
File metadata and controls
377 lines (348 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
<?php
use WP_CLI\Formatter;
use WP_CLI\Utils;
/**
* Manages registered SVG icons.
*
* Icons are registered in code with `wp_register_icon()` by WordPress core,
* themes, and plugins, and always belong to an icon collection. Because they
* only exist for the duration of a request, they cannot be created or deleted
* from the command line.
*
* Icon names are namespaced with the slug of the collection they belong to,
* in the form `collection/icon-name`.
*
* ## EXAMPLES
*
* # List all registered icons
* $ wp icon list
* +-----------------+------------+------------+
* | name | label | collection |
* +-----------------+------------+------------+
* | core/arrow-down | Arrow Down | core |
* | core/plus | Plus | core |
* +-----------------+------------+------------+
*
* # Get details about a single icon
* $ wp icon get core/plus --fields=name,label,collection
* +------------+-----------+
* | Field | Value |
* +------------+-----------+
* | name | core/plus |
* | label | Plus |
* | collection | core |
* +------------+-----------+
*
* # Render an icon at a given size, ready to be embedded in a template
* $ wp icon render core/plus --size=48 --label="Add item" > plus.svg
*
* @package wp-cli
*/
class Icon_Command extends WP_CLI_Command {
/**
* Fields shown by default when listing icons.
*
* The SVG markup is left out on purpose, as it does not render well
* across many rows.
*/
private $fields = [
'name',
'label',
'collection',
];
/**
* Fields shown by default when getting a single icon.
*/
private $item_fields = [
'name',
'label',
'collection',
'content',
];
/**
* Lists registered icons.
*
* ## OPTIONS
*
* [--collection=<slug>]
* : Only list icons belonging to the given collection.
*
* [--search=<term>]
* : Only list icons whose name or label matches the given term.
*
* [--field=<field>]
* : Prints the value of a single field for each icon.
*
* [--fields=<fields>]
* : Limit the output to specific icon fields.
*
* [--format=<format>]
* : Render output in a particular format.
* ---
* default: table
* options:
* - table
* - csv
* - json
* - count
* - yaml
* - ids
* ---
*
* ## AVAILABLE FIELDS
*
* These fields will be displayed by default for each icon:
*
* * name
* * label
* * collection
*
* These fields are optionally available:
*
* * content
* * file_path
*
* ## EXAMPLES
*
* # List all icons of a specific collection
* $ wp icon list --collection=core
* +-----------------+------------+------------+
* | name | label | collection |
* +-----------------+------------+------------+
* | core/arrow-down | Arrow Down | core |
* | core/plus | Plus | core |
* +-----------------+------------+------------+
*
* # Search for icons by name or label
* $ wp icon list --search=arrow-down --field=name
* core/arrow-down-left
* core/arrow-down-right
* core/arrow-down
*
* # Count the icons of a collection
* $ wp icon list --collection=core --format=count
* 88
*
* @subcommand list
*
* @param string[] $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
*/
public function list_( $args, $assoc_args ) {
$collection = Utils\get_flag_value( $assoc_args, 'collection' );
$search = $this->to_string( Utils\get_flag_value( $assoc_args, 'search', '' ) );
if ( null !== $collection ) {
$collection = $this->to_string( $collection );
if ( ! WP_Icon_Collections_Registry::get_instance()->is_registered( $collection ) ) {
WP_CLI::error( "Icon collection {$collection} doesn't exist." );
}
}
$items = [];
foreach ( WP_Icons_Registry::get_instance()->get_registered_icons( $search ) as $icon ) {
if ( null !== $collection && ( $icon['collection'] ?? '' ) !== $collection ) {
continue;
}
$items[] = $this->format_icon( $icon );
}
$formatter = new Formatter( $assoc_args, $this->fields, 'icon' );
if ( 'ids' === $formatter->format ) {
$formatter->display_items( wp_list_pluck( $items, 'name' ) );
return;
}
$formatter->display_items( $items );
}
/**
* Gets details about a registered icon.
*
* ## OPTIONS
*
* <name>
* : Namespaced icon name, in the form "collection/icon-name".
*
* [--field=<field>]
* : Instead of returning the whole icon, returns the value of a single field.
*
* [--fields=<fields>]
* : Limit the output to specific fields.
*
* [--format=<format>]
* : Render output in a particular format.
* ---
* default: table
* options:
* - table
* - csv
* - json
* - yaml
* ---
*
* ## AVAILABLE FIELDS
*
* These fields will be displayed by default for the specified icon:
*
* * name
* * label
* * collection
* * content
*
* This field is optionally available:
*
* * file_path
*
* ## EXAMPLES
*
* # Get details of a specific icon
* $ wp icon get core/plus --fields=name,label,collection
* +------------+-----------+
* | Field | Value |
* +------------+-----------+
* | name | core/plus |
* | label | Plus |
* | collection | core |
* +------------+-----------+
*
* # Get the SVG markup of an icon, as it was registered
* $ wp icon get core/plus --field=content
* <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
* <path d="M11 12.5V17.5H12.5V12.5H17.5V11H12.5V6H11V11H6V12.5H11Z" />
* </svg>
*
* # Find out where an icon is loaded from
* $ wp icon get core/plus --field=file_path
* /var/www/html/wp-includes/images/icon-library/plus.svg
*
* @param string[] $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
*/
public function get( $args, $assoc_args ) {
$name = $args[0];
$icon = WP_Icons_Registry::get_instance()->get_registered_icon( $name );
if ( null === $icon ) {
WP_CLI::error( "Icon {$name} doesn't exist." );
}
$formatter = new Formatter( $assoc_args, $this->item_fields, 'icon' );
$formatter->display_item( $this->format_icon( $icon ) );
}
/**
* Checks if an icon is registered.
*
* ## OPTIONS
*
* <name>
* : Namespaced icon name, in the form "collection/icon-name".
*
* ## EXAMPLES
*
* # Bash script for checking if an icon is registered, with fallback.
*
* if wp icon is-registered core/plus 2>/dev/null; then
* # Icon is registered. Do something.
* else
* # Fallback if icon is not registered.
* fi
*
* @subcommand is-registered
*
* @param string[] $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
*/
public function is_registered( $args, $assoc_args ) {
$name = $args[0];
if ( ! WP_Icons_Registry::get_instance()->is_registered( $name ) ) {
WP_CLI::halt( 1 );
}
WP_CLI::halt( 0 );
}
/**
* Renders the SVG markup of a registered icon.
*
* Unlike `wp icon get <name> --field=content`, which prints the icon as it
* was registered, this applies the same sizing and accessibility attributes
* that WordPress applies when rendering the icon on the front end.
*
* ## OPTIONS
*
* <name>
* : Namespaced icon name, in the form "collection/icon-name".
*
* [--size=<size>]
* : Width and height of the icon in pixels. Pass "none" to leave the
* intrinsic dimensions of the SVG untouched.
* ---
* default: 24
* ---
*
* [--class=<class>]
* : Additional CSS class names, separated by spaces.
*
* [--label=<label>]
* : Accessible label for the icon. Without it, the icon is rendered as
* decorative and hidden from assistive technology.
*
* ## EXAMPLES
*
* # Render an icon at its default size of 24 pixels
* $ wp icon render core/plus
* <svg aria-hidden="true" focusable="false" height="24" width="24" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24">
* <path d="M11 12.5V17.5H12.5V12.5H17.5V11H12.5V6H11V11H6V12.5H11Z" />
* </svg>
*
* # Render a larger icon with a CSS class and an accessible label
* $ wp icon render core/plus --size=48 --class=my-icon --label="Add item" > plus.svg
*
* # Keep the intrinsic dimensions of the SVG
* $ wp icon render core/plus --size=none
*
* @param string[] $args Positional arguments.
* @param array<string, mixed> $assoc_args Associative arguments.
*/
public function render( $args, $assoc_args ) {
$name = $args[0];
if ( ! WP_Icons_Registry::get_instance()->is_registered( $name ) ) {
WP_CLI::error( "Icon {$name} doesn't exist." );
}
$raw_size = Utils\get_flag_value( $assoc_args, 'size', 24 );
$size = null;
if ( 'none' !== $raw_size ) {
if ( is_int( $raw_size ) ) {
$size = $raw_size;
} elseif ( is_string( $raw_size ) && ctype_digit( $raw_size ) ) {
$size = (int) $raw_size;
}
if ( null === $size || $size < 1 ) {
WP_CLI::error( 'The --size argument must be a positive integer or "none".' );
}
}
$markup = wp_get_icon(
$name,
[
'size' => $size,
'class' => $this->to_string( Utils\get_flag_value( $assoc_args, 'class', '' ) ),
'label' => $this->to_string( Utils\get_flag_value( $assoc_args, 'label', '' ) ),
]
);
if ( '' === $markup ) {
WP_CLI::error( "Icon {$name} doesn't contain valid SVG markup." );
}
WP_CLI::line( $markup );
}
/**
* @param array<string, mixed> $icon Registered icon properties.
* @return array<string, string>
*/
private function format_icon( array $icon ): array {
return [
'name' => $this->to_string( $icon['name'] ?? '' ),
'label' => $this->to_string( $icon['label'] ?? '' ),
'collection' => $this->to_string( $icon['collection'] ?? '' ),
'content' => $this->to_string( $icon['content'] ?? '' ),
'file_path' => $this->to_string( $icon['file_path'] ?? '' ),
];
}
/**
* @param mixed $value Value to convert.
*/
private function to_string( $value ): string {
return is_string( $value ) ? $value : '';
}
}