GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — feature/attachment-taxonomies ( 355e81...ebe0e0 )
by Brad
02:59
created

override_attachment_taxonomy_fields()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 4
nop 2
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
1
<?php
2
if ( ! class_exists( 'FooGallery_Attachment_Taxonomies' ) ) {
3
4
    define( 'FOOGALLERY_ATTACHMENT_TAXONOMY_TAG', 'foogallery_attachment_tag' );
5
    define( 'FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION', 'foogallery_attachment_collection' );
6
7
    class FooGallery_Attachment_Taxonomies {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
8
9
    	private $cached_terms = array();
10
11
        /**
12
         * Class Constructor
13
         */
14
        function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
15
            add_action( 'init', array( $this, 'add_taxonomies' ) );
16
17
            if ( is_admin() ) {
18
                add_action( 'admin_menu', array( $this, 'add_menu_items' ), 1 );
19
                add_filter( 'parent_file', array( $this, 'set_current_menu' ) );
20
                add_filter( 'manage_media_columns', array( $this, 'change_attachment_column_names' ) );
21
                add_filter( 'manage_edit-foogallery_attachment_tag_columns', array( $this, 'clean_column_names' ), 999 );
22
                add_filter( 'manage_edit-foogallery_attachment_collection_columns', array( $this, 'clean_column_names' ), 999 );
23
24
				//make the attachment taxonomies awesome
25
				add_action( 'admin_head', array( $this, 'include_inline_taxonomy_data_script' ) );
26
				add_filter( 'attachment_fields_to_edit', array( $this, 'override_attachment_taxonomy_fields' ), 10, 2 );
27
                add_filter( 'attachment_fields_to_save', array( $this, 'save_fields' ), 10, 2 );
28
				add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_js' ), 99 );
29
30
				//ajax actions from the media modal
31
                add_action( 'wp_ajax_foogallery-taxonomies-add-term', array( $this, 'ajax_add_term' ) );
32
                add_action( 'wp_ajax_foogallery-taxonomies-save-terms', array( $this, 'ajax_save_terms' ) );
33
34
                //add_filter( 'foogallery_attachment_add_fields', array( $this, 'remove_taxonomy_fields') );
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
35
                //add_action( 'restrict_manage_posts', array( $this, 'add_collection_filter' ) );
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
36
37
                //add_filter( 'foogallery_attachment_custom_fields_with_post', array( $this, 'add_taxonomy_fields' ), 10, 2 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
38
                //add_filter( 'foogallery_attachment_field_taxonomy_tag', array( $this, 'customize_media_tag_field'), 10, 2 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
39
                //add_filter( 'foogallery_attachment_save_field_taxonomy_tag', array( $this, 'save_media_tag_field' ), 10, 4 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
40
            }
41
        }
42
43
        /**
44
         * Save terms for an attachment
45
         *
46
         * @since 1.4.19
47
         */
48
        public function ajax_save_terms()
0 ignored issues
show
Coding Style introduced by
ajax_save_terms uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
49
        {
50
            $nonce = $_POST['nonce'];
51
            if (wp_verify_nonce($nonce, 'foogallery-attachment-taxonomy')) {
52
53
                $attachment_id = $_POST['attachment_id'];
54
                $terms = $_POST['terms'];
55
                $taxonomy = $_POST['taxonomy'];
56
57
                $result = wp_set_object_terms($attachment_id, array_map('trim', preg_split('/,+/', $terms)), $taxonomy, false);
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
58
            }
59
            die();
60
        }
61
62
        /**
63
         * Add new term via an ajax call from admin
64
         *
65
         * @since 1.4.19
66
         * @access public
67
         */
68
        public function ajax_add_term() {
0 ignored issues
show
Coding Style introduced by
ajax_add_term uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
69
            $nonce = $_POST['nonce'];
70
            if (wp_verify_nonce($nonce, 'foogallery-attachment-taxonomy')) {
71
72
                $new_term = wp_insert_term($_POST['term_label'], $_POST['taxonomy']);
73
74
                if (is_wp_error($new_term)) {
75
                    die();
76
                }
77
78
                $new_term_obj = null;
79
80
                if (isset($new_term['term_id'])) {
81
                    $new_term_obj = get_term($new_term['term_id']);
82
                }
83
84
                if (!is_wp_error($new_term_obj)) {
85
                    wp_send_json(array(
86
                        'new_term' => $new_term_obj,
87
                        'all_terms' => $this->build_terms_recursive($_POST['taxonomy'], array('hide_empty' => false))
88
                    ));
89
                }
90
            }
91
92
            die();
93
        }
94
95
        public function save_fields( $post, $attachment ) {
0 ignored issues
show
Unused Code introduced by
The parameter $attachment is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
save_fields uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
96
            $something = $_POST;
0 ignored issues
show
Unused Code introduced by
$something is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
97
98
            return $post;
99
        }
100
101
		/**
102
		 * Enqueue admin script and styles
103
		 *
104
		 * @since 1.0.0
105
		 * @access public
106
		 * @static
107
		 */
108
		public function enqueue_js() {
109
			global $pagenow, $mode;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
110
111
			$should_add = wp_script_is('media-views') || ($pagenow === 'upload.php' && $mode === 'grid');
112
113
			if( !$should_add ) {
114
				return;
115
			}
116
117
//			// Enqueue filters script
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
118
//			if(Property::$has_filter) {
119
//				wp_enqueue_script(
120
//					'f4-media-taxonomies-filter',
121
//					F4_MT_URL . 'Core/Assets/js/filter.js',
122
//					array(),
123
//					false,
124
//					true
125
//				);
126
//			}
127
128
			//enqueue selectize assets
129
			wp_enqueue_script( 'foogallery-selectize-core', FOOGALLERY_URL . 'lib/selectize/selectize.min.js', array('jquery'), FOOGALLERY_VERSION );
130
			wp_enqueue_script( 'foogallery-selectize', FOOGALLERY_URL . 'lib/selectize/foogallery.selectize.js', array('foogallery-selectize-core'), FOOGALLERY_VERSION );
131
			wp_enqueue_style(  'foogallery-selectize', FOOGALLERY_URL . 'lib/selectize/selectize.css', array(), FOOGALLERY_VERSION );
132
133
134
			//enqueue media attachment autosave script
135
            wp_enqueue_script( 'foogallery-attachment-autosave', FOOGALLERY_URL . 'js/admin-foogallery-attachment-autosave.js', ['media-views']);
136
137
138
139
//wp_enqueue_script(
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
140
//				'f4-media-taxonomies-assignment',
141
//				F4_MT_URL . 'Core/Assets/js/assignment.js',
142
//				array(),
143
//				false,
144
//				true
145
//			);
146
		}
147
148
		/**
149
		 * Add fields to attachment
150
		 *
151
		 * @since 1.0.0
152
		 * @access public
153
		 * @static
154
		 * @param array $fields An array with all fields to edit
155
		 * @param object $post An object for the current post
156
		 * @return array $fields An array with all fields to edit
157
		 */
158
		public function override_attachment_taxonomy_fields($fields, $post) {
159
			if ( array_key_exists( FOOGALLERY_ATTACHMENT_TAXONOMY_TAG, $fields ) ) {
160
161
				$value = trim( $fields[FOOGALLERY_ATTACHMENT_TAXONOMY_TAG]['value'] );
162
163
				$fields[FOOGALLERY_ATTACHMENT_TAXONOMY_TAG] = array(
164
					'show_in_edit' => false,
165
					'input' => 'html',
166
					'html' => $this->build_taxonomy_html( FOOGALLERY_ATTACHMENT_TAXONOMY_TAG, $post, $value ),
167
					'label' => __( 'Media Tags', 'foogallery' )
168
				);
169
			}
170
171
			if ( array_key_exists( FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION, $fields ) ) {
172
173
				$value = trim( $fields[FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION]['value'] );
174
175
				$fields[FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION] = array(
176
					'show_in_edit' => false,
177
					'input' => 'html',
178
					'html' => $this->build_taxonomy_html( FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION, $post, $value ),
179
					'label' => __( 'Media Collections', 'foogallery' )
180
				);
181
			}
182
183
			return $fields;
184
		}
185
186
		/**
187
		 * Add custom js into admin head so that we can build up decent taxonomy selectize controls
188
		 *
189
		 * @since 1.0.0
190
		 * @access public
191
		 * @static
192
		 */
193
		public function include_inline_taxonomy_data_script() {
194
			global $pagenow, $mode;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
195
196
			$should_add = wp_script_is('media-views') || ($pagenow === 'upload.php' && $mode === 'grid');
197
198
			if( !$should_add ) {
199
				return;
200
			}
201
202
			$taxonomy_data[FOOGALLERY_ATTACHMENT_TAXONOMY_TAG] = array(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$taxonomy_data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $taxonomy_data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
203
				'slug' => FOOGALLERY_ATTACHMENT_TAXONOMY_TAG,
204
				'terms' => $this->build_terms_recursive(FOOGALLERY_ATTACHMENT_TAXONOMY_TAG, array('hide_empty' => false)),
205
				'query_var' => true,
206
				'labels' => array(
207
					'placeholder' => __( 'Select tags, or add a new tag...', 'foogallery' ),
208
					'add' => __( 'Add new tag', 'foogallery' )
209
				),
210
			);
211
212
			$taxonomy_data[FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION] = array(
213
				'slug' => FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION,
214
				'terms' => $this->build_terms_recursive(FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION, array('hide_empty' => false)),
215
				'query_var' => true,
216
				'labels' => array(
217
					'placeholder' => __( 'Select collections, or add a new collection...', 'foogallery' ),
218
					'add' => __( 'Add new collection', 'foogallery' )
219
				),
220
			);
221
222
			$taxonomy_data['nonce'] = wp_create_nonce( 'foogallery-attachment-taxonomy' );
223
224
			echo '<script type="text/javascript">
225
			window.FOOGALLERY_TAXONOMY_DATA = ' . json_encode($taxonomy_data) . ';
226
		</script>';
227
		}
228
229
        function change_attachment_column_names( $columns ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
230
231
             if ( array_key_exists( 'taxonomy-foogallery_attachment_collection', $columns ) ) {
232
                 $columns['taxonomy-foogallery_attachment_collection'] = __('Collections', 'foogallery');
233
             }
234
235
             return $columns;
236
        }
237
238
        /**
239
         * Clean up the taxonomy columns for WP Seo plugin
240
         *
241
         * @param $columns
242
         * @return mixed
243
         */
244
        function clean_column_names( $columns ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
245
246
             //cleanup wpseo columns!
247
             if ( array_key_exists( 'wpseo_score', $columns ) ) {
248
                 unset( $columns['wpseo_score'] );
249
             }
250
            if ( array_key_exists( 'wpseo_score_readability', $columns ) ) {
251
                unset( $columns['wpseo_score_readability'] );
252
            }
253
             return $columns;
254
        }
255
256
        /**
257
         * Add the menu items under the FooGallery main menu
258
         */
259
        function add_menu_items() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
260
            foogallery_add_submenu_page(
261
                __( 'Media Tags', 'foogallery' ),
262
                'manage_options',
263
                'edit-tags.php?taxonomy=' . FOOGALLERY_ATTACHMENT_TAXONOMY_TAG . '&post_type=' . FOOGALLERY_CPT_GALLERY,
264
                null
265
            );
266
267
            foogallery_add_submenu_page(
268
                __( 'Media Collections', 'foogallery' ),
269
                'manage_options',
270
                'edit-tags.php?taxonomy=' . FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION . '&post_type=' . FOOGALLERY_CPT_GALLERY,
271
                null
272
            );
273
        }
274
275
        /**
276
         * Make sure the taxonomy menu items are highlighted
277
         * @param $parent_file
278
         * @return mixed
279
         */
280
        function set_current_menu( $parent_file ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
281
            global $submenu_file, $current_screen;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
282
283
            if ( $current_screen->post_type == FOOGALLERY_CPT_GALLERY ) {
284
285
                if ( 'edit-foogallery_attachment_tag' === $current_screen->id ) {
286
                    $submenu_file = 'edit-tags.php?taxonomy=' . FOOGALLERY_ATTACHMENT_TAXONOMY_TAG . '&post_type=' . FOOGALLERY_CPT_GALLERY;
287
                }
288
289
                if ( 'edit-foogallery_attachment_collection' === $current_screen->id ) {
290
                    $submenu_file = 'edit-tags.php?taxonomy=' . FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION . '&post_type=' . FOOGALLERY_CPT_GALLERY;
291
                }
292
            }
293
294
            return $parent_file;
295
        }
296
297
        /**
298
         * Register the taxonomies for attachments
299
         */
300
        function add_taxonomies() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
301
302
            $tag_args = array(
303
                'labels'            => array(
304
                    'name'              => __( 'Media Tags', 'foogallery' ),
305
                    'singular_name'     => __( 'Tag', 'foogallery' ),
306
                    'search_items'      => __( 'Search Tags', 'foogallery' ),
307
                    'all_items'         => __( 'All Tags', 'foogallery' ),
308
                    'parent_item'       => __( 'Parent Tag', 'foogallery' ),
309
                    'parent_item_colon' => __( 'Parent Tag:', 'foogallery' ),
310
                    'edit_item'         => __( 'Edit Tag', 'foogallery' ),
311
                    'update_item'       => __( 'Update Tag', 'foogallery' ),
312
                    'add_new_item'      => __( 'Add New Tag', 'foogallery' ),
313
                    'new_item_name'     => __( 'New Tag Name', 'foogallery' ),
314
                    'menu_name'         => __( 'Media Tags', 'foogallery' )
315
                ),
316
                'hierarchical'      => false,
317
                'query_var'         => true,
318
                'rewrite'           => false,
319
                'show_admin_column' => false,
320
                'show_in_menu'      => false,
321
                'update_count_callback' => '_update_generic_term_count'
322
            );
323
324
            register_taxonomy( FOOGALLERY_ATTACHMENT_TAXONOMY_TAG, 'attachment', $tag_args );
325
326
            $collection_args = array(
327
                'labels'            => array(
328
                    'name'              => __( 'Media Collections', 'foogallery' ),
329
                    'singular_name'     => __( 'Collection', 'foogallery' ),
330
                    'search_items'      => __( 'Search Collections', 'foogallery' ),
331
                    'all_items'         => __( 'All Collections', 'foogallery' ),
332
                    'parent_item'       => __( 'Parent Collection', 'foogallery' ),
333
                    'parent_item_colon' => __( 'Parent Collection:', 'foogallery' ),
334
                    'edit_item'         => __( 'Edit Collection', 'foogallery' ),
335
                    'update_item'       => __( 'Update Collection', 'foogallery' ),
336
                    'add_new_item'      => __( 'Add New Collection', 'foogallery' ),
337
                    'new_item_name'     => __( 'New Collection Name', 'foogallery' ),
338
                    'menu_name'         => __( 'Media Collections', 'foogallery' )
339
                ),
340
                'hierarchical'      => true,
341
                'query_var'         => true,
342
                'rewrite'           => false,
343
                'show_admin_column' => true,
344
                'show_in_menu'      => false,
345
                'update_count_callback' => '_update_generic_term_count'
346
            );
347
348
            register_taxonomy( FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION, 'attachment', $collection_args );
349
        }
350
351
        /**
352
         * Add the taxonomy fields to the attachment
353
         *
354
         * @param $fields array All fields that will be added to the media modal
355
		 * @param $post
356
         *
357
         * @return mixed
358
         */
359
        function add_taxonomy_fields( $fields, $post ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
360
361
			$fields[FOOGALLERY_ATTACHMENT_TAXONOMY_TAG] = array(
362
				'show_in_edit' => false,
363
				'input' => 'html',
364
				'html' => $this->build_taxonomy_html( FOOGALLERY_ATTACHMENT_TAXONOMY_TAG, $post ),
0 ignored issues
show
Bug introduced by
The call to build_taxonomy_html() misses a required argument $value.

This check looks for function calls that miss required arguments.

Loading history...
365
				'label' => __( 'Tags', 'foogallery' )
366
			);
367
368
			$fields[FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION] = array(
369
				'show_in_edit' => false,
370
				'input' => 'html',
371
				'html' => $this->build_taxonomy_html( FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION, $post ),
0 ignored issues
show
Bug introduced by
The call to build_taxonomy_html() misses a required argument $value.

This check looks for function calls that miss required arguments.

Loading history...
372
				'label' => __( 'Collections', 'foogallery' )
373
			);
374
375
            return $fields;
376
        }
377
378
		/**
379
		 * Build up a taxonomy field HTML
380
		 *
381
		 * @param $taxonomy
382
		 * @param $post
383
		 *
384
		 * @return array
385
		 */
386
        function build_taxonomy_html( $taxonomy, $post, $value ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
387
			$html = '<input type="text" data-attachment_id="' . $post->ID . '" class="foogallery-attachment-ignore-change" id="attachments-' . $post->ID .'-' . $taxonomy . '" name="attachments-' . $post->ID .'-' . $taxonomy . '" value="' . $value . '" />';
388
			$html .= '<script type="script/javascript">
389
				FOOGALLERY_SELECTIZE(\'#attachments-' . $post->ID .'-' . $taxonomy . '\', \'' . $taxonomy .'\');
390
				</script>';
391
			return $html;
392
		}
393
394
		/**
395
		 * Get terms sorted by hierarchy in a recursive way
396
		 *
397
		 * @param  string $taxonomy The taxonomy name
398
		 * @param  array $args The arguments which should be passed to the get_terms function
399
		 * @param  int $parent The terms parent id (for recursive usage)
400
		 * @param  int $level The current level (for recursive usage)
401
		 * @param  array $parents An array with all the parent terms (for recursive usage)
402
		 *
403
		 * @return array $terms_all An array with all the terms for this taxonomy
404
		 */
405
		function build_terms_recursive($taxonomy, $args = array(), $parent = 0, $level = 1, $parents = array()) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
406
			//check if the taxonomy terms have already been built up
407
			if ( 0 === $parent && array_key_exists( $taxonomy, $this->cached_terms ) ) {
408
				return $this->cached_terms[$taxonomy];
409
			}
410
411
			$terms_all = array();
412
413
			$args['parent'] = $args['child_of'] = $parent;
414
415
			$terms = get_terms($taxonomy, $args);
416
417
			foreach($terms as $term) {
418
				$term->level = $level;
419
				$term->parents = $parents;
420
				$term_parents = $parents;
421
				$term_parents[] = $term->name;
422
				$terms_all[] = $term;
423
				$terms_sub = $this->build_terms_recursive($taxonomy, $args, $term->term_id, $level + 1, $term_parents);
424
425
				if(!empty($terms_sub)) {
426
					$terms_all = array_merge($terms_all, $terms_sub);
427
				}
428
			}
429
430
			//cache what we have built up
431
			if ( 0 === $parent && !array_key_exists( $taxonomy, $this->cached_terms ) ) {
432
				$this->cached_terms[$taxonomy] = $terms_all;
433
			}
434
435
			return $terms_all;
436
		}
437
438
        /**
439
         * Remove the automatically added attachments fields
440
         * @param $fields
441
         *
442
         * @return mixed
443
         */
444
        function remove_taxonomy_fields( $fields ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
445
            if ( array_key_exists( FOOGALLERY_ATTACHMENT_TAXONOMY_TAG, $fields ) ) {
446
                unset( $fields[FOOGALLERY_ATTACHMENT_TAXONOMY_TAG] );
447
            }
448
449
            if ( array_key_exists( FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION, $fields ) ) {
450
                unset( $fields[FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION] );
451
            }
452
453
            return $fields;
454
        }
455
456
        /**
457
         * Customize the media tag field to make sure we output a checkboxlist
458
         * @param $field_values
459
         *
460
         * @return mixed
461
         */
462
        function customize_media_tag_field( $field_values, $post_id ) {
463
464
            $media_tags = array();
465
466
            //get the terms linked to the attachment
467
            $terms = get_the_terms( $post_id, FOOGALLERY_ATTACHMENT_TAXONOMY_TAG );
468
            if ( $terms && ! is_wp_error( $terms ) ) {
469
                foreach ( $terms as $term ) {
470
                    $media_tags[ $term->term_id ] = $term->name;
471
                }
472
            }
473
474
            //set to html
475
            $field_values['input'] = 'html';
476
477
            $html = '';
478
            $i = 0;
479
480
            if ( ! empty( $field_values['options'] ) ) {
481
482
                foreach ( $field_values['options'] as $k => $v ) {
483
                    if ( array_key_exists( $k, $media_tags ) ) {
484
                        $checked = ' checked="checked"';
485
                    } else {
486
                        $checked = '';
487
                    }
488
489
                    $html .= '<input' . $checked . ' value="' . $k . '" type="checkbox" name="attachments[' . $post_id . '][' . FOOGALLERY_ATTACHMENT_TAXONOMY_TAG . '][' . $k . ']" id="' . sanitize_key( FOOGALLERY_ATTACHMENT_TAXONOMY_TAG . '_' . $post_id . '_' . $i ) . '" /> <label for="' . sanitize_key( FOOGALLERY_ATTACHMENT_TAXONOMY_TAG . '_' . $post_id . '_' . $i ) . '">' . $v . '</label> ';
490
                    $i++;
491
                }
492
            }
493
494
            if ( 0 === $i ) {
495
                $html .= __( 'No Tags Available!', 'foogallery' );
496
            }
497
498
            $html .= '<style>.compat-field-foogallery_media_tags .field input {margin-right: 0px;} .compat-field-foogallery_media_tags .field label {vertical-align: bottom; margin-right: 10px;}</style>';
499
500
            $html .= '<br /><a target="_blank" href="' . admin_url( 'edit-tags.php?taxonomy=' . FOOGALLERY_ATTACHMENT_TAXONOMY_TAG . '&post_type=attachment' ) . '">' . __( 'Manage Tags', 'foogallery' ) . '</a>';
501
502
            $field_values['value'] = '';
503
            $field_values['html'] = $html;
504
505
            return $field_values;
506
        }
507
508
        /**
509
         * Save the tags for the attachment
510
         *
511
         * @param $field
512
         * @param $values
513
         * @param $post
514
         * @param $attachment
515
         */
516
        function save_media_tag_field($field, $values, $post, $attachment) {
0 ignored issues
show
Unused Code introduced by
The parameter $values is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
517
            $post_id = $post['ID'];
518
519
            //first clear any tags for the post
520
            wp_delete_object_term_relationships( $post_id, FOOGALLERY_ATTACHMENT_TAXONOMY_TAG );
521
522
            $tag_ids = $attachment[ $field ];
523
524
            if ( !empty( $tag_ids ) ) {
525
                //clean tag ids
526
                $tag_ids = array_keys( $tag_ids );
527
                $tag_ids = array_map( 'intval', $tag_ids );
528
                $tag_ids = array_unique( $tag_ids );
529
530
                $term_taxonomy_ids = wp_set_object_terms( $post_id, $tag_ids, FOOGALLERY_ATTACHMENT_TAXONOMY_TAG );
531
532
                if ( is_wp_error( $term_taxonomy_ids ) ) {
533
                    // There was an error somewhere and the terms couldn't be set.
534
                    $post['errors'][ $field ]['errors'][] = __( 'Error saving the tags for the attachment!', 'foogallery' );
535
                }
536
            }
537
        }
538
539
540
        /***
541
         *
542
         * Add a tag filter to the attachments listing page
543
         */
544
        function add_collection_filter() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
545
            global $pagenow;
546
            if ( 'upload.php' == $pagenow ) {
547
548
                $dropdown_options = array(
549
                    'taxonomy'        => FOOGALLERY_ATTACHMENT_TAXONOMY_COLLECTION,
550
                    'show_option_all' => __( 'All Collections' ),
551
                    'hide_empty'      => false,
552
                    'hierarchical'    => true,
553
                    'orderby'         => 'name',
554
                    'show_count'      => true,
555
                    'walker'          => new foogallery_walker_category_dropdown(),
556
                    'value'           => 'slug'
557
                );
558
559
                wp_dropdown_categories( $dropdown_options );
560
            }
561
        }
562
    }
563
}
564