PluginProbe
Categories Images / trunk
Categories Images vtrunk
trunk 1.0 1.1 1.2 2.0 2.1 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.5 2.5.1 2.5.2 2.5.3 2.5.4 3.0.0 3.0.1 3.1.0 All 30 releases
categories-images / categories-images.php

categories-images.php in Categories Images trunk, at categories-images.php

688 lines 26.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package CategoriesImages
4 */
5
6 /**
7 * Plugin Name: Categories Images
8 * Plugin URI: https://zahlan.net/blog/categories-images/
9 * Description: Categories Images Plugin allow you to add an image to category or any custom term.
10 * Author: Muhammad El Zahlan
11 * Version: 3.3.3
12 * Author URI: https://zahlan.net/
13 * Domain Path: /languages
14 * Text Domain: categories-images
15 * License: GPLv2 or later
16 */
17
18 if (!defined('ABSPATH'))
19 die;
20
21 if (!defined('Z_PLUGIN_URL'))
22 define('Z_PLUGIN_URL', untrailingslashit(plugins_url('', __FILE__)));
23
24 if (!defined('ZCI_VERSION'))
25 define('ZCI_VERSION', '3.3.3');
26
27 class ZCategoriesImages
28 {
29 public $plugin_name;
30 private $zci_placeholder;
31 private static $instance = null;
32
33 /**
34 * Singleton instance
35 */
36 public static function get_instance() {
37 if ( null == self::$instance ) {
38 self::$instance = new self;
39 }
40 return self::$instance;
41 }
42
43 private function __construct() {
44 $this->plugin_name = plugin_basename(__FILE__);
45
46 // The placeholder image url
47 $this->zci_placeholder = plugins_url('/assets/images/placeholder.png', __FILE__);
48 add_action('init', [$this, 'zInit']);
49 add_action('admin_init', [$this, 'zAdminInit']);
50
51 // save our taxonomy image while edit or create term
52 add_action('edit_term', [$this, 'zSaveTaxonomyImage']);
53 add_action('create_term', [$this, 'zSaveTaxonomyImage']);
54
55 // Plugin menu in admin panel
56 add_action('admin_menu', [$this, 'zSettingsMenu']);
57
58 // Settings page link in plugins list
59 add_filter("plugin_action_links_{$this->plugin_name}", [$this, 'zSettingsLink']);
60
61 // Elementor Dynamic Tag Registration
62 add_action('elementor/dynamic_tags/register', [$this, 'zRegisterElementorTags']);
63
64 // Register REST API Field
65 add_action('rest_api_init', [$this, 'zInitRestApi']);
66
67 // Enqueue frontend styles
68 add_action('wp_enqueue_scripts', [$this, 'zPublicEnqueue']);
69 }
70
71 /**
72 * Abstraction for retrieving term metadata
73 */
74 public function zci_get_term_meta( $term_id, $key ) {
75 if ( function_exists( 'get_term_meta' ) ) {
76 return get_term_meta( $term_id, $key, true );
77 } else {
78 return get_option( $key . $term_id );
79 }
80 }
81
82 /**
83 * Abstraction for updating term metadata
84 */
85 public function zci_update_term_meta( $term_id, $key, $value ) {
86 if ( function_exists( 'update_term_meta' ) ) {
87 return update_term_meta( $term_id, $key, $value );
88 } else {
89 return update_option( $key . $term_id, $value );
90 }
91 }
92
93 /**
94 * Abstraction for deleting term metadata
95 */
96 public function zci_delete_term_meta( $term_id, $key ) {
97 if ( function_exists( 'delete_term_meta' ) ) {
98 return delete_term_meta( $term_id, $key );
99 } else {
100 return delete_option( $key . $term_id );
101 }
102 }
103
104 function zAdminInit() {
105 // Migration Routine: Move data from options to term_meta if supported and not yet done
106 if ( function_exists( 'get_term_meta' ) && ! get_option( 'zci_migrated_to_termmeta' ) ) {
107 $taxonomies = get_taxonomies();
108 foreach ( $taxonomies as $taxonomy ) {
109 $terms = get_terms( $taxonomy, ['hide_empty' => false] );
110 if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) {
111 foreach ( $terms as $term ) {
112 // Check for old option data
113 $app_option_url = get_option( 'z_taxonomy_image' . $term->term_id );
114 $app_option_id = get_option( 'z_taxonomy_image_id' . $term->term_id );
115
116 if ( $app_option_url !== false ) {
117 update_term_meta( $term->term_id, 'z_taxonomy_image', $app_option_url );
118 delete_option( 'z_taxonomy_image' . $term->term_id );
119 }
120 if ( $app_option_id !== false ) {
121 update_term_meta( $term->term_id, 'z_taxonomy_image_id', $app_option_id );
122 delete_option( 'z_taxonomy_image_id' . $term->term_id );
123 }
124 }
125 }
126 }
127 update_option( 'zci_migrated_to_termmeta', 1 );
128 }
129
130 $z_taxonomies = get_taxonomies();
131 if (is_array($z_taxonomies)) {
132 $zci_options = (array) get_option('zci_options', []);
133
134 if (empty($zci_options['excluded_taxonomies']) || !is_array($zci_options['excluded_taxonomies']))
135 $zci_options['excluded_taxonomies'] = [];
136
137 foreach ($z_taxonomies as $z_taxonomy) {
138 if (in_array($z_taxonomy, $zci_options['excluded_taxonomies']))
139 continue;
140 add_action($z_taxonomy.'_add_form_fields', [$this, 'zAddTexonomyField']);
141 add_action($z_taxonomy.'_edit_form_fields', [$this, 'zEditTexonomyField']);
142 add_filter('manage_edit-'.$z_taxonomy.'_columns', [$this, 'zTaxonomyColumns']);
143 add_filter('manage_'.$z_taxonomy.'_custom_column', [$this, 'zTaxonomyColumn'], 10, 3 );
144
145 // If tax is deleted
146 // Note: term_meta deletes automatically when term is deleted in WP 4.4+, but we need to handle fallback.
147 add_action("delete_{$z_taxonomy}", [$this, 'zDeleteTaxonomyData']);
148 }
149 }
150
151 // Register styles and scripts
152 if ( strpos( $_SERVER['SCRIPT_NAME'], 'edit-tags.php' ) > 0 || strpos( $_SERVER['SCRIPT_NAME'], 'term.php' ) > 0 ) {
153 add_action('admin_enqueue_scripts', [$this, 'zAdminEnqueue']);
154 add_action('quick_edit_custom_box', [$this, 'zQuickEditCustomBox'], 10, 3);
155 }
156
157 // Register settings
158 register_setting('zci_options', 'zci_options');
159 add_settings_section('zci_settings', __('Categories Images settings', 'categories-images'), [$this, 'zSectionText'], 'zci-options');
160 add_settings_field('z_excluded_taxonomies', __('Excluded Taxonomies', 'categories-images'), [$this, 'zExcludedTaxonomies'], 'zci-options', 'zci_settings');
161 }
162
163 function zInit() {
164 // Register Shortcodes
165 add_shortcode('z_taxonomy_image', [$this, 'z_taxonomy_image_shortcode']);
166 add_shortcode('z_taxonomy_list', [$this, 'z_taxonomy_list_shortcode']);
167 }
168
169 function zDeleteTaxonomyData($tt_id) {
170 // delete_term_meta handles itself, but for backward compatibility with options:
171 if ( ! function_exists( 'delete_term_meta' ) ) {
172 delete_option('z_taxonomy_image'.(int)$tt_id);
173 delete_option('z_taxonomy_image_id'.(int)$tt_id);
174 }
175 }
176
177 function zAdminEnqueue() {
178 wp_enqueue_style('categories-images-admin-styles', plugins_url('/assets/css/zci-admin.css', __FILE__), [], ZCI_VERSION);
179 wp_enqueue_script('categories-images-scripts', plugins_url('/assets/js/zci-scripts.js', __FILE__), [], ZCI_VERSION, true);
180
181 $zci_js_config = [
182 'wordpress_ver' => get_bloginfo("version"),
183 'placeholder' => $this->zci_placeholder
184 ];
185 wp_localize_script('categories-images-scripts', 'zci_config', $zci_js_config);
186 }
187
188 function zPublicEnqueue() {
189 wp_enqueue_style('categories-images-styles', plugins_url('/assets/css/zci-styles.css', __FILE__), [], ZCI_VERSION);
190 }
191
192 // add image field in add form
193 function zAddTexonomyField() {
194 wp_enqueue_media();
195
196 $nonce = wp_create_nonce( 'zci_save_image' );
197
198 echo '<div class="form-field">
199 <input type="hidden" name="zci_nonce" value="' . esc_attr($nonce) . '" />
200 <input type="hidden" name="zci_taxonomy_image_id" id="zci_taxonomy_image_id" value="" />
201 <label for="zci_taxonomy_image">' . esc_html__('Image', 'categories-images') . '</label>
202 <input type="text" name="zci_taxonomy_image" id="zci_taxonomy_image" value="" />
203 <br/>
204 <button class="z_upload_image_button button">' . esc_html__('Upload/Add image', 'categories-images') . '</button>
205 </div>';
206 }
207
208 // add image field in edit form
209 function zEditTexonomyField($taxonomy) {
210 wp_enqueue_media();
211
212 if ($this->zTaxonomyImageUrl( $taxonomy->term_id, NULL, TRUE ) == $this->zci_placeholder) {
213 $image_url = "";
214 $image_id = "";
215 } else {
216 $image_url = $this->zTaxonomyImageUrl( $taxonomy->term_id, NULL, TRUE );
217 $image_id = $this->zTaxonomyImageID( $taxonomy->term_id );
218 }
219
220 $nonce = wp_create_nonce( 'zci_save_image' );
221
222 echo '<tr class="form-field">
223 <th scope="row" valign="top"><label for="zci_taxonomy_image">' . esc_html__('Image', 'categories-images') . '</label></th>
224 <td>
225 <input type="hidden" name="zci_nonce" value="' . esc_attr($nonce) . '" />
226 <input type="hidden" name="zci_taxonomy_image_id" id="zci_taxonomy_image_id" value="'.esc_attr($image_id).'" /><img class="zci-taxonomy-image" src="' . esc_url( $this->zTaxonomyImageUrl( $taxonomy->term_id, 'medium', TRUE ) ) . '"/><br/><input type="text" name="zci_taxonomy_image" id="zci_taxonomy_image" value="'.esc_url($image_url).'" /><br />
227 <button class="z_upload_image_button button">' . esc_html__('Upload/Add image', 'categories-images') . '</button>
228 <button class="z_remove_image_button button">' . esc_html__('Remove image', 'categories-images') . '</button>
229 </td>
230 </tr>';
231 }
232
233 function zTaxonomyColumns( $columns ) {
234 $new_columns = [];
235
236 // Keep checkbox column if it exists
237 if ( isset( $columns['cb'] ) ) {
238 $new_columns['cb'] = $columns['cb'];
239 unset( $columns['cb'] );
240 }
241
242 // Add image column
243 $new_columns['thumb'] = esc_html__( 'Image', 'categories-images' );
244
245 // Merge back the rest of the columns
246 return array_merge( $new_columns, $columns );
247 }
248
249 function zTaxonomyColumn( $columns, $column, $id ) {
250 if ( $column == 'thumb' ) {
251 // Get full URL and ID for Quick Edit
252 $full_url = $this->zTaxonomyImageUrl($id, 'full', FALSE);
253 $image_id = $this->zTaxonomyImageID($id);
254
255 $columns = '<span><img src="' . esc_url($this->zTaxonomyImageUrl($id, 'thumbnail', TRUE)) . '" alt="' . esc_attr(__('Thumbnail', 'categories-images')) . '" class="wp-post-image" />';
256 $columns .= '<span class="zci-data" style="display:none;" data-url="' . esc_url($full_url) . '" data-id="' . esc_attr($image_id) . '"></span>';
257 $columns .= '</span>';
258 }
259
260 return $columns;
261 }
262
263 function zQuickEditCustomBox($column_name, $screen, $name) {
264 if ($column_name == 'thumb') {
265 $nonce = wp_create_nonce( 'zci_save_image' );
266 echo '<fieldset>
267 <div class="thumb inline-edit-col">
268 <label>
269 <span class="title"><img src="" alt="Thumbnail"/></span>
270 <span class="input-text-wrap"><input type="text" name="zci_taxonomy_image" value="" class="tax_list" /></span>
271 <span class="input-text-wrap">
272 <input type="hidden" name="zci_nonce" value="' . esc_attr($nonce) . '" />
273 <button class="z_upload_image_button button">' . esc_html__('Upload/Add image', 'categories-images') . '</button>
274 <button class="z_remove_image_button button">' . esc_html__('Remove image', 'categories-images') . '</button>
275 </span>
276 <span class="input-text-wrap">
277 <input type="hidden" name="zci_taxonomy_image_id" value="" />
278 </span>
279 </label>
280 </div>
281 </fieldset>';
282 }
283 }
284
285 function zSaveTaxonomyImage($term_id) {
286 // Security check
287 if ( ! isset( $_POST['zci_nonce'] ) || ! wp_verify_nonce( $_POST['zci_nonce'], 'zci_save_image' ) ) {
288 return;
289 }
290
291 if(isset($_POST['zci_taxonomy_image'])) {
292 $this->zci_update_term_meta($term_id, 'z_taxonomy_image', esc_url_raw($_POST['zci_taxonomy_image']));
293 }
294 if(isset($_POST['zci_taxonomy_image_id'])) {
295 $this->zci_update_term_meta($term_id, 'z_taxonomy_image_id', absint($_POST['zci_taxonomy_image_id']));
296 }
297 }
298
299 // get attachment ID by image url
300 function zGetAttachmentIdByUrl($image_src) {
301 $id = attachment_url_to_postid($image_src);
302 return (!empty($id)) ? $id : NULL;
303 }
304
305 // get attachment ID by term id
306 function zTaxonomyImageID($term_id = NULL) {
307 if (!$term_id) {
308 if (is_category())
309 $term_id = get_query_var('cat');
310 elseif (is_tag())
311 $term_id = get_query_var('tag_id');
312 elseif (is_tax()) {
313 $current_term = get_term_by('slug', get_query_var('term'), get_query_var('taxonomy'));
314 $term_id = $current_term->term_id;
315 }
316 }
317
318 return $this->zci_get_term_meta($term_id, 'z_taxonomy_image_id');
319 }
320
321 // get taxonomy image url for the given term_id (Place holder image by default)
322 function zTaxonomyImageUrl($term_id = NULL, $size = 'full', $return_placeholder = FALSE) {
323 if (!$term_id) {
324 if (is_category())
325 $term_id = get_query_var('cat');
326 elseif (is_tag())
327 $term_id = get_query_var('tag_id');
328 elseif (is_tax()) {
329 $current_term = get_term_by('slug', get_query_var('term'), get_query_var('taxonomy'));
330 $term_id = $current_term->term_id;
331 }
332 }
333
334 $attachment_id = $this->zTaxonomyImageID($term_id);
335 $taxonomy_image_url = '';
336
337 if (!empty($attachment_id)) {
338 $taxonomy_image_src = wp_get_attachment_image_src($attachment_id, $size);
339 if ($taxonomy_image_src) {
340 $taxonomy_image_url = $taxonomy_image_src[0];
341 }
342 }
343
344 if (empty($taxonomy_image_url)) {
345 $taxonomy_image_url = $this->zci_get_term_meta($term_id, 'z_taxonomy_image');
346 if (!empty($taxonomy_image_url) && empty($attachment_id)) {
347 $attachment_id = $this->zGetAttachmentIdByUrl($taxonomy_image_url);
348 if (!empty($attachment_id)) {
349 $taxonomy_image_src = wp_get_attachment_image_src($attachment_id, $size);
350 if ($taxonomy_image_src) {
351 $taxonomy_image_url = $taxonomy_image_src[0];
352 }
353 }
354 }
355 }
356
357 if ($return_placeholder)
358 return ($taxonomy_image_url != '') ? $taxonomy_image_url : $this->zci_placeholder;
359 else
360 return $taxonomy_image_url;
361 }
362
363 // display taxonomy image for the given term_id
364 function zTaxonomyImage($term_id = NULL, $size = 'full', $attr = NULL, $echo = TRUE) {
365 if (!$term_id) {
366 if (is_category())
367 $term_id = get_query_var('cat');
368 elseif (is_tag())
369 $term_id = get_query_var('tag_id');
370 elseif (is_tax()) {
371 $current_term = get_term_by('slug', get_query_var('term'), get_query_var('taxonomy'));
372 $term_id = $current_term->term_id;
373 }
374 }
375
376 $attachment_id = $this->zTaxonomyImageID($term_id);
377 $taxonomy_image_url = '';
378 $taxonomy_image = '';
379
380 if (empty($attachment_id)) {
381 $taxonomy_image_url = $this->zci_get_term_meta($term_id, 'z_taxonomy_image');
382 if (!empty($taxonomy_image_url)) {
383 $attachment_id = $this->zGetAttachmentIdByUrl($taxonomy_image_url);
384 }
385 } else {
386 $taxonomy_image_url = $this->zci_get_term_meta($term_id, 'z_taxonomy_image');
387 }
388
389 if (!empty($attachment_id)) {
390 $taxonomy_image = wp_get_attachment_image($attachment_id, $size, FALSE, $attr);
391 }
392
393 // Fallback to raw URL if wp_get_attachment_image failed or no ID found
394 if (empty($taxonomy_image) && !empty($taxonomy_image_url)) {
395 $image_attr = '';
396 if(is_array($attr)) {
397 if(!empty($attr['class']))
398 $image_attr .= ' class="'.esc_attr($attr['class']).'" ';
399 if(!empty($attr['alt']))
400 $image_attr .= ' alt="'.esc_attr($attr['alt']).'" ';
401 if(!empty($attr['width']))
402 $image_attr .= ' width="'.esc_attr($attr['width']).'" ';
403 if(!empty($attr['height']))
404 $image_attr .= ' height="'.esc_attr($attr['height']).'" ';
405 if(!empty($attr['title']))
406 $image_attr .= ' title="'.esc_attr($attr['title']).'" ';
407 }
408 $taxonomy_image = '<img src="'.esc_url($taxonomy_image_url).'" '.$image_attr.'/>';
409 }
410
411 if ($echo)
412 echo wp_kses_post($taxonomy_image);
413 else
414 return $taxonomy_image;
415 }
416
417 function zSettingsMenu() {
418 add_options_page(__('Categories Images settings', 'categories-images'), __('Categories Images', 'categories-images'), 'manage_options', 'zci_settings', [$this, 'zSettingsPage']);
419 }
420
421 // Plugin option page
422 function zSettingsPage() {
423 if (!current_user_can('manage_options'))
424 wp_die(esc_html__( 'You do not have sufficient permissions to access this page.', 'categories-images'));
425
426 // Enqueue admin styles for settings page if not already there
427 wp_enqueue_style('categories-images-admin-styles', plugins_url('/assets/css/zci-admin.css', __FILE__), [], ZCI_VERSION);
428
429 require_once plugin_dir_path(__FILE__).'templates/admin.php';
430 }
431
432 function zSettingsLink($links) {
433 $settings_link = '<a href="options-general.php?page=zci_settings">Settings</a>';
434 array_push($links, $settings_link);
435 return $links;
436 }
437
438 // Settings section description
439 function zSectionText() {
440 echo '<p>'.esc_html__('Please select the taxonomies you want to exclude it from Categories Images plugin', 'categories-images').'</p>';
441 }
442
443 // Excluded taxonomies checkboxs
444 function zExcludedTaxonomies() {
445 $options = (array) get_option('zci_options', []);
446 $disabled_taxonomies = ['nav_menu', 'link_category', 'post_format'];
447 foreach (get_taxonomies() as $tax) : if (in_array($tax, $disabled_taxonomies)) continue; ?>
448 <input type="checkbox" name="zci_options[excluded_taxonomies][<?php echo esc_attr($tax) ?>]" value="<?php echo esc_attr($tax) ?>" <?php checked(isset($options['excluded_taxonomies'][$tax]) && is_array($options['excluded_taxonomies']) && $options['excluded_taxonomies'][$tax] == $tax); ?> /> <?php echo esc_html($tax) ;?><br />
449 <?php endforeach;
450 }
451
452 function activate() {
453 // Things will happen if the plugin activated.
454 flush_rewrite_rules();
455 }
456
457 function deactivate() {
458 // Things will happen if the plugin deactivated.
459 flush_rewrite_rules();
460 }
461
462 function zRegisterElementorTags( $dynamic_tags ) {
463 // Include the tag class file
464 if ( ! class_exists( 'ZCI_Elementor_Taxonomy_Image_Tag' ) ) {
465 require_once plugin_dir_path( __FILE__ ) . 'includes/elementor-integration.php';
466 }
467
468 // Register the tag
469 $dynamic_tags->register( new ZCI_Elementor_Taxonomy_Image_Tag() );
470 }
471
472 // Register field 'z_taxonomy_image_url' to the WP REST API
473 function zInitRestApi() {
474 $taxonomies = get_taxonomies();
475 $zci_options = (array) get_option('zci_options', []);
476 if (!isset($zci_options['excluded_taxonomies']) || !is_array($zci_options['excluded_taxonomies']))
477 $zci_options['excluded_taxonomies'] = [];
478
479 foreach ($taxonomies as $taxonomy) {
480 if (in_array($taxonomy, $zci_options['excluded_taxonomies']))
481 continue;
482
483 register_rest_field($taxonomy, 'z_taxonomy_image_url', [
484 'get_callback' => [$this, 'zGetTermImage'],
485 'update_callback' => null,
486 'schema' => null,
487 ]);
488 }
489 }
490
491 function zGetTermImage($object, $field_name, $request) {
492 $term_id = $object['id'];
493 $image_url = $this->zTaxonomyImageUrl($term_id, 'full', true);
494
495 return $image_url;
496 }
497
498 /**
499 * Shortcode [z_taxonomy_image]
500 */
501 function z_taxonomy_image_shortcode($atts) {
502 $raw_atts = $atts;
503 $atts = shortcode_atts([
504 'term_id' => '',
505 'taxonomy' => 'category',
506 'size' => 'full',
507 'class' => '',
508 'default' => null,
509 'link' => 'no', // yes, no, custom_url
510 'format' => 'img' // img, url
511 ], $atts);
512
513 // Handle positional 'default' attribute
514 if (is_array($raw_atts) && in_array('default', $raw_atts, true)) {
515 $atts['default'] = "";
516 }
517
518 $term_id = $atts['term_id'];
519
520 // If no term_id, try to detect
521 if (empty($term_id)) {
522 $term_id = get_queried_object_id();
523 }
524
525 // Output logic
526 if ($atts['format'] === 'url') {
527 $url = $this->zTaxonomyImageUrl($term_id, $atts['size'], true);
528 if ($url == $this->zci_placeholder) {
529 if ($atts['default'] === "") {
530 return $this->zci_placeholder;
531 } elseif (!empty($atts['default'])) {
532 return $atts['default'];
533 } elseif (is_null($atts['default'])) {
534 return ''; // No placeholder by default
535 }
536 }
537 return $url;
538 }
539
540 $image = $this->zTaxonomyImage($term_id, $atts['size'], ['class' => $atts['class']], false);
541
542 // Handle empty/placeholder
543 if (empty($image) || strpos($image, 'placeholder.png') !== false) {
544 if ($atts['default'] === "") {
545 $image = '<img src="' . esc_url($this->zci_placeholder) . '" class="' . esc_attr($atts['class']) . '" />';
546 } elseif (!empty($atts['default'])) {
547 $image = '<img src="' . esc_url($atts['default']) . '" class="' . esc_attr($atts['class']) . '" />';
548 } else {
549 $image = '';
550 }
551 }
552
553 // Link wrapping
554 if ($atts['link'] === 'yes') {
555 $term_link = get_term_link((int)$term_id, $atts['taxonomy']);
556 if (!is_wp_error($term_link)) {
557 $image = '<a href="' . esc_url($term_link) . '">' . $image . '</a>';
558 }
559 } elseif ($atts['link'] !== 'no') {
560 // custom URL
561 $image = '<a href="' . esc_url($atts['link']) . '">' . $image . '</a>';
562 }
563
564 return $image;
565 }
566
567 /**
568 * Shortcode [z_taxonomy_list]
569 */
570 function z_taxonomy_list_shortcode($atts) {
571 $atts = shortcode_atts([
572 'taxonomy' => 'category',
573 'post_id' => '',
574 'include' => '',
575 'exclude' => '',
576 'parent' => '',
577 'orderby' => 'name',
578 'order' => 'ASC',
579 'hide_empty' => 'yes',
580 'size' => 'full',
581 'style' => 'list', // list, grid, inline
582 'columns' => '3',
583 'show_name' => 'no',
584 'show_count' => 'no',
585 'format' => 'img'
586 ], $atts);
587
588 // Get Terms
589 $args = [
590 'taxonomy' => $atts['taxonomy'],
591 'orderby' => $atts['orderby'],
592 'order' => $atts['order'],
593 'hide_empty' => ($atts['hide_empty'] === 'yes'),
594 ];
595
596 if (!empty($atts['include'])) {
597 $args['include'] = explode(',', $atts['include']);
598 }
599 if (!empty($atts['exclude'])) {
600 $args['exclude'] = explode(',', $atts['exclude']);
601 }
602 if ($atts['parent'] !== '') {
603 $args['parent'] = (int)$atts['parent'];
604 }
605
606 $terms = [];
607 if (!empty($atts['post_id'])) {
608 $pid = ($atts['post_id'] === 'current') ? get_the_ID() : (int)$atts['post_id'];
609 $terms = get_the_terms($pid, $atts['taxonomy']);
610 } else {
611 $terms = get_terms($args);
612 }
613
614 if (empty($terms) || is_wp_error($terms)) {
615 return '';
616 }
617
618 if ($atts['format'] === 'array') {
619 return '<pre>' . print_r($terms, true) . '</pre>';
620 }
621
622 // CSS Classes
623 $classes = 'zci-taxonomy-list zci-' . $atts['style'];
624
625 // Grid Styles
626 $style_attr = '';
627 if ($atts['style'] === 'grid') {
628 $style_attr = 'style="--zci-columns: ' . intval($atts['columns']) . ';"';
629 }
630
631 $output = '<ul class="' . esc_attr($classes) . '" ' . $style_attr . '>';
632
633 foreach ($terms as $term) {
634 $image = $this->zTaxonomyImage($term->term_id, $atts['size'], ['class' => 'zci-img'], false);
635
636 // Skip if no image and no name to show
637 if (empty($image) && $atts['show_name'] !== 'yes') {
638 continue;
639 }
640
641 $link = get_term_link($term);
642
643 $output .= '<li class="zci-item">';
644 $output .= '<a href="' . esc_url($link) . '" class="zci-link">';
645 $output .= '<span class="zci-image">' . $image . '</span>';
646
647 if ($atts['show_name'] === 'yes') {
648 $output .= '<span class="zci-term-name">' . esc_html($term->name);
649 if ($atts['show_count'] === 'yes') {
650 $output .= ' <span class="zci-term-count">(' . $term->count . ')</span>';
651 }
652 $output .= '</span>';
653 }
654 $output .= '</a>';
655 $output .= '</li>';
656 }
657
658 $output .= '</ul>';
659
660 return $output;
661 }
662 }
663
664 if (class_exists('ZCategoriesImages')) {
665 // Instantiate the class via Singleton
666 $z_categories_images = ZCategoriesImages::get_instance();
667
668 // After activating the plugin
669 register_activation_hook(__FILE__, [$z_categories_images, 'activate']);
670
671 // After deactivating the plugin
672 register_deactivation_hook(__FILE__, [$z_categories_images, 'deactivate']);
673
674 function z_taxonomy_image_url($term_id = NULL, $size = 'full', $return_placeholder = FALSE) {
675 $zci = ZCategoriesImages::get_instance();
676 return $zci->zTaxonomyImageUrl($term_id, $size, $return_placeholder);
677 }
678
679 function z_taxonomy_image_id($term_id = NULL) {
680 $zci = ZCategoriesImages::get_instance();
681 return $zci->zTaxonomyImageID($term_id);
682 }
683
684 function z_taxonomy_image($term_id = NULL, $size = 'full', $attr = NULL, $echo = TRUE) {
685 $zci = ZCategoriesImages::get_instance();
686 return $zci->zTaxonomyImage($term_id, $size, $attr, $echo);
687 }
688 }