Version Description
- New: The "MLA Custom Field Search Example" plugin has been substantially upgraded. The new version has many more parameters and a new plugin settings page. A Documentation tab on the settings page contains all the information you need to understand and use the new version.
- New: A new example plugin, "MLA Postie Post After Example", adds support for running MLA mapping rules after the "Postie" plugin chron job creates posts and attachments from an email.
- New: The Library Views/Post MIME Type "Table View" custom field queries have been enhanced to allow searching multiple field names or "all fields" for one or more values.
- Fix: The "Smart Media Categories" example plugin has been enhanced to handle additional WordPress alternatives for term assignments and a new option is provided to exclude the Default Post Category from sync processing.
- Fix: Wildcard values for Library Views/Post MIME Type "Table View" custom field queries have been restored.
- Fix: PDF thumbnail streaming for
mla_viewer
processing has been restored. - Fix: For the
[mla_gallery]
shortcode, error reporting for the tax_query, date_query and meta_query parameters has been improved. - Fix: For the
[mla_gallery]
shortcode, proper handling of thesize=
"icon", "icon_only" and "icon_feature" options has been restored. - Fix: For the
[mla_gallery]
shortcode, performance is improved by avoiding a redundant LEFT JOIN database query clause (added by WP_Query). - Fix: For the
[mla_gallery]
shortcode, performance is improved by avoiding LEFT JOIN and WHERE database query clauses added by Real Media Library. - Fix: Unnecessary "term meta cache" queries have been removed from the Media/Assistant submenu table generation.
- Fix: Handling of disimissible admin messages has been restored.
Download this release
Release Info
Developer | dglingren |
Plugin | Media Library Assistant |
Version | 2.94 |
Comparing to | |
See all releases |
Code changes from version 2.93 to 2.94
- examples/plugins/mla-custom-field-search-example.php +0 -326
- examples/plugins/mla-custom-field-search-example/admin-settings-page.tpl +384 -0
- examples/plugins/mla-custom-field-search-example/class-mla-example-plugin-settings.php +491 -0
- examples/plugins/mla-custom-field-search-example/mla-custom-field-search-example.php +460 -0
- examples/plugins/mla-parent-custom-field-mapping/admin-settings-page.tpl +12 -11
- examples/plugins/mla-parent-search-example.php +4 -4
- examples/plugins/mla-postie-post-after-example.php +120 -0
- examples/plugins/smart-media-categories/admin/includes/class-smc-automatic-support.php +124 -35
- examples/plugins/smart-media-categories/admin/includes/class-smc-settings-support.php +14 -0
- examples/plugins/smart-media-categories/admin/includes/class-smc-sync-support.php +74 -11
- examples/plugins/smart-media-categories/public/class-smart-media-categories.php +1 -1
- examples/plugins/smart-media-categories/smart-media-categories.php +5 -7
- includes/class-mla-core.php +46 -20
- includes/class-mla-data-query.php +11 -4
- includes/class-mla-image-processor.php +11 -29
- includes/class-mla-list-table.php +2 -2
- includes/class-mla-main.php +23 -6
- includes/class-mla-settings.php +2 -1
- includes/class-mla-shortcode-support.php +97 -31
- includes/mla-stream-image.php +1 -1
- index.php +2 -2
- readme.txt +17 -3
- tpls/documentation-settings-tab.tpl +34 -6
examples/plugins/mla-custom-field-search-example.php
DELETED
@@ -1,326 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Extends the Media/Assistant "Search Media" box to custom field values
|
4 |
-
*
|
5 |
-
* In this example, a "custom:" prefix is detected in the Media/Assistant "search media" text
|
6 |
-
* box and the search is modified to query a custom field for a specific value, e.g.,
|
7 |
-
* "custom:photo reference=123456". You can also search for partial values:
|
8 |
-
*
|
9 |
-
* - To return all items that have a non-NULL value in the field, simply enter the prefix
|
10 |
-
* "custom:" followed by the custom field name, for example, custom:File Size. You can also
|
11 |
-
* enter the custom field name and then "=*", e.g., custom:File Size=*.
|
12 |
-
* - To return all items that have a NULL value in the field, enter the custom field name and
|
13 |
-
* then "=", e.g., custom:File Size=.
|
14 |
-
* - To return all items that match one or more values, enter the prefix "custom:" followed by
|
15 |
-
* the custom field name and then "=" followed by a list of values. For example, custom:Color=red
|
16 |
-
* or custom:Color=red,green,blue. Wildcard specifications are also supported; for example, "*post"
|
17 |
-
* to match anything ending in "post" or "th*da*" to match values like "the date" and "this day".
|
18 |
-
*
|
19 |
-
* This example plugin uses four of the many filters available in the Media/Assistant Submenu
|
20 |
-
* and illustrates some of the techniques you can use to customize the submenu table display.
|
21 |
-
*
|
22 |
-
* Created for support topic "Searching on custom fields"
|
23 |
-
* opened on 5/11/2015 by "BFI-WP".
|
24 |
-
* https://wordpress.org/support/topic/searching-on-custom-fields/
|
25 |
-
*
|
26 |
-
* @package MLA Custom Field Search Example
|
27 |
-
* @version 1.05
|
28 |
-
*/
|
29 |
-
|
30 |
-
/*
|
31 |
-
Plugin Name: MLA Custom Field Search Example
|
32 |
-
Plugin URI: http://davidlingren.com/
|
33 |
-
Description: Extends the Media/Assistant "Search Media" box to custom field values
|
34 |
-
Author: David Lingren
|
35 |
-
Version: 1.05
|
36 |
-
Author URI: http://davidlingren.com/
|
37 |
-
|
38 |
-
Copyright 2014 - 2015 David Lingren
|
39 |
-
|
40 |
-
This program is free software; you can redistribute it and/or modify
|
41 |
-
it under the terms of the GNU General Public License as published by
|
42 |
-
the Free Software Foundation; either version 2 of the License, or
|
43 |
-
(at your option) any later version.
|
44 |
-
|
45 |
-
This program is distributed in the hope that it will be useful,
|
46 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
47 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
48 |
-
GNU General Public License for more details.
|
49 |
-
|
50 |
-
You can get a copy of the GNU General Public License by writing to the
|
51 |
-
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
52 |
-
*/
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Class MLA Custom Field Search Example extends the Media/Assistant "Search Media" box
|
56 |
-
* to custom field values
|
57 |
-
*
|
58 |
-
* @package MLA Custom Field Search Example
|
59 |
-
* @since 1.00
|
60 |
-
*/
|
61 |
-
class MLACustomFieldSearchExample {
|
62 |
-
/**
|
63 |
-
* Initialization function, similar to __construct()
|
64 |
-
*
|
65 |
-
* @since 1.00
|
66 |
-
*
|
67 |
-
* @return void
|
68 |
-
*/
|
69 |
-
public static function initialize() {
|
70 |
-
// The filters are only useful for the admin section; exit in the front-end posts/pages
|
71 |
-
if ( ! is_admin() )
|
72 |
-
return;
|
73 |
-
|
74 |
-
// Defined in /media-library-assistant/includes/class-mla-main.php
|
75 |
-
add_filter( 'mla_list_table_new_instance', 'MLACustomFieldSearchExample::mla_list_table_new_instance', 10, 1 );
|
76 |
-
|
77 |
-
// Defined in /media-library-assistant/includes/class-mla-data.php
|
78 |
-
add_filter( 'mla_list_table_query_final_terms', 'MLACustomFieldSearchExample::mla_list_table_query_final_terms', 10, 1 );
|
79 |
-
|
80 |
-
// Defined in /media-library-assistant/includes/class-mla-media-modal.php
|
81 |
-
add_filter( 'mla_media_modal_query_initial_terms', 'MLACustomFieldSearchExample::mla_media_modal_query_initial_terms', 10, 2 );
|
82 |
-
|
83 |
-
// Defined in /media-library-assistant/includes/class-mla-data.php
|
84 |
-
add_filter( 'mla_media_modal_query_final_terms', 'MLACustomFieldSearchExample::mla_media_modal_query_final_terms', 10, 1 );
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Extend the MLA_List_Table class
|
89 |
-
*
|
90 |
-
* This filter gives you an opportunity to extend the MLA_List_Table class.
|
91 |
-
* You can also use this filter to inspect or modify any of the $_REQUEST arguments.
|
92 |
-
*
|
93 |
-
* @since 1.00
|
94 |
-
*
|
95 |
-
* @param object $mla_list_table NULL, to indicate no extension/use the base class.
|
96 |
-
*
|
97 |
-
* @return object updated mla_list_table object.
|
98 |
-
*/
|
99 |
-
public static function mla_list_table_new_instance( $mla_list_table ) {
|
100 |
-
/*
|
101 |
-
* Look for the special "custom:" prefix in the Search Media text box,
|
102 |
-
* after checking for the "debug" prefixes.
|
103 |
-
*/
|
104 |
-
if ( isset( $_REQUEST['s'] ) ) {
|
105 |
-
switch ( substr( $_REQUEST['s'], 0, 3 ) ) {
|
106 |
-
case '>|<':
|
107 |
-
self::$custom_field_parameters['debug'] = 'console';
|
108 |
-
$start = 3;
|
109 |
-
break;
|
110 |
-
case '<|>':
|
111 |
-
self::$custom_field_parameters['debug'] = 'log';
|
112 |
-
$start = 3;
|
113 |
-
break;
|
114 |
-
default:
|
115 |
-
$start = 0;
|
116 |
-
}
|
117 |
-
|
118 |
-
if ( 'custom:' == substr( $_REQUEST['s'], $start, 7 ) ) {
|
119 |
-
self::$custom_field_parameters['s'] = substr( $_REQUEST['s'], $start + 7 );
|
120 |
-
unset( $_REQUEST['s'] );
|
121 |
-
self::$custom_field_parameters['mla_search_connector'] = $_REQUEST['mla_search_connector'];
|
122 |
-
unset( $_REQUEST['mla_search_connector'] );
|
123 |
-
self::$custom_field_parameters['mla_search_fields'] = $_REQUEST['mla_search_fields'];
|
124 |
-
unset( $_REQUEST['mla_search_fields'] );
|
125 |
-
} else {
|
126 |
-
self::$custom_field_parameters = array();
|
127 |
-
}
|
128 |
-
} // isset s=custom:
|
129 |
-
|
130 |
-
return $mla_list_table;
|
131 |
-
} // mla_list_table_new_instance
|
132 |
-
|
133 |
-
/**
|
134 |
-
* Custom Field Search "parameters"
|
135 |
-
*
|
136 |
-
* @since 1.01
|
137 |
-
*
|
138 |
-
* @var array
|
139 |
-
*/
|
140 |
-
public static $custom_field_parameters = array();
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Filter the WP_Query request parameters for the prepare_items query
|
144 |
-
*
|
145 |
-
* Gives you an opportunity to change the terms of the prepare_items query
|
146 |
-
* after they are processed by the "Prepare List Table Query" handler.
|
147 |
-
*
|
148 |
-
* @since 1.01
|
149 |
-
*
|
150 |
-
* @param array WP_Query request prepared by "Prepare List Table Query"
|
151 |
-
*
|
152 |
-
* @return array updated WP_Query request
|
153 |
-
*/
|
154 |
-
public static function mla_list_table_query_final_terms( $request ) {
|
155 |
-
/*
|
156 |
-
* If $request['offset'] and $request['posts_per_page'] are set, this is the "prepare_items" request.
|
157 |
-
* If they are NOT set, this is a "view count" request, i.e., to get the count for a custom view.
|
158 |
-
*
|
159 |
-
* MLAData::$query_parameters and MLAData::$search_parameters contain
|
160 |
-
* additional parameters used in some List Table queries.
|
161 |
-
*/
|
162 |
-
if ( ! ( isset( $request['offset'] ) && isset( $request['posts_per_page'] ) ) ) {
|
163 |
-
return $request;
|
164 |
-
}
|
165 |
-
|
166 |
-
if ( empty( self::$custom_field_parameters ) ) {
|
167 |
-
return $request;
|
168 |
-
}
|
169 |
-
|
170 |
-
if ( isset( self::$custom_field_parameters['debug'] ) ) {
|
171 |
-
MLAData::$query_parameters['debug'] = self::$custom_field_parameters['debug'];
|
172 |
-
MLAData::$search_parameters['debug'] = self::$custom_field_parameters['debug'];
|
173 |
-
MLACore::mla_debug_mode( self::$custom_field_parameters['debug'] );
|
174 |
-
}
|
175 |
-
|
176 |
-
// Apply default field name?
|
177 |
-
if ( '=' == substr( self::$custom_field_parameters['s'], 0, 1 ) ) {
|
178 |
-
$tokens = array( 'Orientation', substr( self::$custom_field_parameters['s'], 1 ) );
|
179 |
-
} else {
|
180 |
-
$tokens = explode( '=', self::$custom_field_parameters['s'] ) ;
|
181 |
-
}
|
182 |
-
|
183 |
-
// See if the custom field name is present, followed by "=" and a value
|
184 |
-
if ( 1 < count( $tokens ) ) {
|
185 |
-
$field = array_shift( $tokens );
|
186 |
-
$value = implode( '=', $tokens );
|
187 |
-
} else {
|
188 |
-
// Supply a default custom field name
|
189 |
-
$field = 'Orientation';
|
190 |
-
$value = $tokens[0];
|
191 |
-
}
|
192 |
-
|
193 |
-
/*
|
194 |
-
* Parse the query, remove MLA-specific elements, fix numeric and "commas" format fields
|
195 |
-
*/
|
196 |
-
$tokens = MLAMime::mla_prepare_view_query( 'custom_field_search', 'custom:' . $field . '=' . $value );
|
197 |
-
$tokens = $tokens['meta_query'];
|
198 |
-
|
199 |
-
/*
|
200 |
-
* Matching a meta_value to NULL requires a LEFT JOIN to a view and a special WHERE clause;
|
201 |
-
* MLA filters will handle this case.
|
202 |
-
*/
|
203 |
-
if ( isset( $tokens['key'] ) ) {
|
204 |
-
MLAData::$query_parameters['use_postmeta_view'] = true;
|
205 |
-
MLAData::$query_parameters['postmeta_key'] = $tokens['key'];
|
206 |
-
MLAData::$query_parameters['postmeta_value'] = NULL;
|
207 |
-
return $request;
|
208 |
-
}
|
209 |
-
|
210 |
-
/*
|
211 |
-
* Process "normal" meta_query
|
212 |
-
*/
|
213 |
-
$query = array( 'relation' => $tokens['relation'] );
|
214 |
-
$padded_values = array();
|
215 |
-
$patterns = array();
|
216 |
-
foreach ( $tokens as $key => $value ) {
|
217 |
-
if ( ! is_numeric( $key ) ) {
|
218 |
-
continue;
|
219 |
-
}
|
220 |
-
|
221 |
-
if ( in_array( $value['key'], array( 'File Size', 'pixels', 'width', 'height' ) ) ) {
|
222 |
-
if ( '=' == $value['compare'] ) {
|
223 |
-
$value['value'] = str_pad( $value['value'], 15, ' ', STR_PAD_LEFT );
|
224 |
-
$padded_values[ trim( $value['value'] ) ] = $value['value'];
|
225 |
-
} else {
|
226 |
-
$value['value'] = '%' . $value['value'];
|
227 |
-
}
|
228 |
-
}
|
229 |
-
|
230 |
-
if ( 'LIKE' == $value['compare'] ) {
|
231 |
-
$patterns[] = $value['value'];
|
232 |
-
}
|
233 |
-
|
234 |
-
$query[] = $value;
|
235 |
-
}
|
236 |
-
|
237 |
-
if ( ! empty( $padded_values ) ) {
|
238 |
-
MLAData::$query_parameters['mla-metavalue'] = $padded_values;
|
239 |
-
}
|
240 |
-
|
241 |
-
if ( ! empty( $patterns ) ) {
|
242 |
-
MLAData::$query_parameters['patterns'] = $patterns;
|
243 |
-
}
|
244 |
-
|
245 |
-
/*
|
246 |
-
* Combine with an existing "custom view" meta_query, if present
|
247 |
-
*/
|
248 |
-
if ( isset( $request['meta_query'] ) ) {
|
249 |
-
$request['meta_query'] = array( 'relation' => 'AND', $request['meta_query'], $query );
|
250 |
-
} else {
|
251 |
-
$request['meta_query'] = $query;
|
252 |
-
}
|
253 |
-
|
254 |
-
return $request;
|
255 |
-
} // mla_list_table_query_final_terms
|
256 |
-
|
257 |
-
/**
|
258 |
-
* MLA Edit Media "Query Attachments" initial terms Filter
|
259 |
-
*
|
260 |
-
* Gives you an opportunity to change the terms of the
|
261 |
-
* Media Manager Modal Window "Query Attachments" query
|
262 |
-
* before they are pre-processed by the MLA handler.
|
263 |
-
*
|
264 |
-
* @since 1.03
|
265 |
-
*
|
266 |
-
* @param array WP_Query terms supported for "Query Attachments"
|
267 |
-
* @param array All terms passed in the request
|
268 |
-
*/
|
269 |
-
public static function mla_media_modal_query_initial_terms( $query, $raw_query ) {
|
270 |
-
/*
|
271 |
-
* Look for the special "custom:" prefix in the Search Media text box,
|
272 |
-
* after checking for the "debug" prefixes.
|
273 |
-
*/
|
274 |
-
if ( isset( $query['mla_search_value'] ) ) {
|
275 |
-
switch ( substr( $query['mla_search_value'], 0, 3 ) ) {
|
276 |
-
case '>|<':
|
277 |
-
self::$custom_field_parameters['debug'] = 'console';
|
278 |
-
$start = 3;
|
279 |
-
break;
|
280 |
-
case '<|>':
|
281 |
-
self::$custom_field_parameters['debug'] = 'log';
|
282 |
-
$start = 3;
|
283 |
-
break;
|
284 |
-
default:
|
285 |
-
$start = 0;
|
286 |
-
}
|
287 |
-
|
288 |
-
if ( 'custom:' == substr( $query['mla_search_value'], $start, 7 ) ) {
|
289 |
-
self::$custom_field_parameters['s'] = substr( $query['mla_search_value'], $start + 7 );
|
290 |
-
unset( $query['mla_search_value'] );
|
291 |
-
self::$custom_field_parameters['mla_search_connector'] = $query['mla_search_connector'];
|
292 |
-
unset( $query['mla_search_connector'] );
|
293 |
-
self::$custom_field_parameters['mla_search_fields'] = $query['mla_search_fields'];
|
294 |
-
unset( $query['mla_search_fields'] );
|
295 |
-
} else {
|
296 |
-
self::$custom_field_parameters = array();
|
297 |
-
}
|
298 |
-
} // isset mla_search_value=custom:
|
299 |
-
|
300 |
-
return $query;
|
301 |
-
}
|
302 |
-
|
303 |
-
/**
|
304 |
-
* MLA Edit Media "Query Attachments" final terms Filter
|
305 |
-
*
|
306 |
-
* Gives you an opportunity to change the terms of the
|
307 |
-
* Media Manager Modal Window "Query Attachments" query
|
308 |
-
* after they are processed by the "Prepare List Table Query" handler.
|
309 |
-
*
|
310 |
-
* @since 1.03
|
311 |
-
*
|
312 |
-
* @param array WP_Query request prepared by "Prepare List Table Query"
|
313 |
-
*/
|
314 |
-
public static function mla_media_modal_query_final_terms( $request ) {
|
315 |
-
/*
|
316 |
-
* The logic used in the Media/Assistant Search Media box will work here as well
|
317 |
-
*/
|
318 |
-
return MLACustomFieldSearchExample::mla_list_table_query_final_terms( $request );
|
319 |
-
}
|
320 |
-
} // Class MLACustomFieldSearchExample
|
321 |
-
|
322 |
-
/*
|
323 |
-
* Install the filters at an early opportunity
|
324 |
-
*/
|
325 |
-
add_action('init', 'MLACustomFieldSearchExample::initialize');
|
326 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
examples/plugins/mla-custom-field-search-example/admin-settings-page.tpl
ADDED
@@ -0,0 +1,384 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!-- template="page" -->
|
2 |
+
<a name="backtotop"></a>
|
3 |
+
|
4 |
+
<div class="wrap">
|
5 |
+
<h1 class="wp-heading-inline">[+plugin_title+] [+version+] Settings</h1>
|
6 |
+
[+messages+]
|
7 |
+
[+tablist+]
|
8 |
+
[+tab_content+]
|
9 |
+
</div><!-- wrap -->
|
10 |
+
|
11 |
+
<!-- template="tablist" -->
|
12 |
+
<h2 class="nav-tab-wrapper">
|
13 |
+
[+tablist+]
|
14 |
+
</h2>
|
15 |
+
<!-- template="tablist-item" -->
|
16 |
+
<a data-tab-id="[+data-tab-id+]" class="nav-tab [+nav-tab-active+]" href="?page=[+settings-page+]&mla_tab=[+data-tab-id+]">[+title+]</a>
|
17 |
+
|
18 |
+
<!-- template="messages" -->
|
19 |
+
<div class="[+mla_messages_class+]">
|
20 |
+
<p>
|
21 |
+
[+messages+]
|
22 |
+
</p>
|
23 |
+
</div>
|
24 |
+
|
25 |
+
<!-- template="page-level-options" -->
|
26 |
+
<tr valign="top">
|
27 |
+
<td class="textright">
|
28 |
+
<input name="[+slug_prefix+]_options[media_assistant_support]" id="[+slug_prefix+]_options_media_assistant_support" type="checkbox" [+media_assistant_support_checked+] value="1" />
|
29 |
+
</td>
|
30 |
+
<td>
|
31 |
+
<strong>Enable Media/Assistant searches</strong>
|
32 |
+
<div class="mla-settings-help"> Check this option to activate support for the Search Media box on the Media/Assistant admin submenu.</div>
|
33 |
+
</td>
|
34 |
+
</tr>
|
35 |
+
<tr valign="top">
|
36 |
+
<td class="textright">
|
37 |
+
<input name="[+slug_prefix+]_options[mmmw_support]" id="[+slug_prefix+]_options_mmmw_support" type="checkbox" [+mmmw_support_checked+] value="1" />
|
38 |
+
</td>
|
39 |
+
<td>
|
40 |
+
<strong>Enable Media Manager searches</strong>
|
41 |
+
<div class="mla-settings-help"> Check this option to activate support for the Media Manager Modal (popup) Window.</div>
|
42 |
+
</td>
|
43 |
+
</tr>
|
44 |
+
<tr valign="top">
|
45 |
+
<td class="textright">
|
46 |
+
<strong>Prefix</strong>
|
47 |
+
</td>
|
48 |
+
<td>
|
49 |
+
<input name="[+slug_prefix+]_options[prefix]" id="[+slug_prefix+]_options_prefix" type="text" size="20" maxlength="20"value="[+prefix+]" />
|
50 |
+
<div class="mla-settings-help"> Enter the prefix value that signifies a custom field search. Be sure to include something like a colon at the end.</div>
|
51 |
+
</td>
|
52 |
+
</tr>
|
53 |
+
<tr valign="top">
|
54 |
+
<td class="textright">
|
55 |
+
<strong>Default Field(s)</strong>
|
56 |
+
</td>
|
57 |
+
<td>
|
58 |
+
<input name="[+slug_prefix+]_options[default_fields]" id="[+slug_prefix+]_options_default_fields" type="text" size="40" maxlength="40"value="[+default_fields+]" />
|
59 |
+
<div class="mla-settings-help"> Enter the (comma-separated) custom field name(s) to be searched by default.</div>
|
60 |
+
</td>
|
61 |
+
</tr>
|
62 |
+
<tr valign="top">
|
63 |
+
<td class="textright">
|
64 |
+
<strong>All Fields Name</strong>
|
65 |
+
</td>
|
66 |
+
<td>
|
67 |
+
<input name="[+slug_prefix+]_options[all_fields]" id="[+slug_prefix+]_options_all_fields" type="text" size="20" maxlength="20"value="[+all_fields+]" />
|
68 |
+
<div class="mla-settings-help"> Enter the name that signifies a search of all custom fields.</div>
|
69 |
+
</td>
|
70 |
+
</tr>
|
71 |
+
<tr valign="top">
|
72 |
+
<td class="textright">
|
73 |
+
<input name="[+slug_prefix+]_options[all_fields_support]" id="[+slug_prefix+]_options_all_fields_support" type="checkbox" [+all_fields_support_checked+] value="1" />
|
74 |
+
</td>
|
75 |
+
<td>
|
76 |
+
<strong>Enable All Fields name substitution</strong>
|
77 |
+
<div class="mla-settings-help"> Check this option to use the above name for an "All Fields" search.</div>
|
78 |
+
</td>
|
79 |
+
</tr>
|
80 |
+
|
81 |
+
|
82 |
+
<!-- template="general-tab" -->
|
83 |
+
<style type='text/css'>
|
84 |
+
.mla-settings-help {
|
85 |
+
font-size: 8pt;
|
86 |
+
padding-bottom: 5px
|
87 |
+
}
|
88 |
+
|
89 |
+
.mla-page-level-options-form {
|
90 |
+
margin-left: 0px;
|
91 |
+
margin-top: 10px;
|
92 |
+
padding-bottom: 10px;
|
93 |
+
border-bottom:thin solid #888888;
|
94 |
+
}
|
95 |
+
|
96 |
+
span.submit.mla-settings-submit,
|
97 |
+
p.submit.mla-settings-submit {
|
98 |
+
padding-bottom: 0px
|
99 |
+
}
|
100 |
+
</style>
|
101 |
+
<h2>Plugin Options</h2>
|
102 |
+
<p>In this tab you can add or remove custom field search support for the Media/Assistant admin submenu and/or the Media Manager Modal (popup) Window (MMMW). The MMMW is used by the Media/Library grid view, the classic "Add Media..." function and the Gutenberg Image and Gallery blocks. You can leave these options checked unless you find a specific problem they cause (unlikely).</p>
|
103 |
+
<p>You can also specify one or more custom fields to search by default, i.e., without entering the field name(s) each time you perform a search. Finally, you can replace the default values used for the prefix that signals a custom field search and the special "field name" that specifies a search of all existing custom fields.</p>
|
104 |
+
<p>You can find more information about using all of the features of this plugin in the Documentation tab on this page.</p>
|
105 |
+
<div class="mla-page-level-options-form">
|
106 |
+
<form action="[+form_url+]" method="post" class="mla-display-settings-page" id="[+slug_prefix+]_options_general_tab">
|
107 |
+
<table class="optiontable">
|
108 |
+
<tbody>
|
109 |
+
[+options_list+]
|
110 |
+
</tbody>
|
111 |
+
</table>
|
112 |
+
<span class="submit mla-settings-submit">
|
113 |
+
<input name="[+slug_prefix+]_options_save" class="button-primary" id="[+slug_prefix+]_options_save" type="submit" value="Save Changes" />
|
114 |
+
<input name="[+slug_prefix+]_options_reset" class="button-primary alignright" id="[+slug_prefix+]_options_reset" type="submit" value="Delete Settings, Restore Defaults" />
|
115 |
+
</span>
|
116 |
+
[+_wpnonce+]
|
117 |
+
</form>
|
118 |
+
</div>
|
119 |
+
|
120 |
+
<!-- template="documentation-tab" -->
|
121 |
+
<style type='text/css'>
|
122 |
+
.mla-doc-toc-list {
|
123 |
+
list-style-position:inside;
|
124 |
+
list-style:disc;
|
125 |
+
line-height: 15px;
|
126 |
+
padding-left: 20px
|
127 |
+
}
|
128 |
+
|
129 |
+
.mla-doc-hook-label {
|
130 |
+
text-align: right;
|
131 |
+
padding: 0 1em 2em 0;
|
132 |
+
vertical-align: top;
|
133 |
+
font-weight:bold
|
134 |
+
}
|
135 |
+
|
136 |
+
.mla-doc-hook-definition {
|
137 |
+
vertical-align: top;
|
138 |
+
}
|
139 |
+
|
140 |
+
.mla-doc-table-label {
|
141 |
+
text-align: right;
|
142 |
+
padding-right: 10px;
|
143 |
+
vertical-align: top;
|
144 |
+
font-weight:bold
|
145 |
+
}
|
146 |
+
|
147 |
+
.mla-doc-table-sublabel {
|
148 |
+
padding-right: 10px;
|
149 |
+
vertical-align: top
|
150 |
+
}
|
151 |
+
|
152 |
+
.mla-doc-table-reverse {
|
153 |
+
text-align: right;
|
154 |
+
padding-right: 10px;
|
155 |
+
vertical-align:top
|
156 |
+
}
|
157 |
+
|
158 |
+
.mla-doc-table-definition {
|
159 |
+
vertical-align: top;
|
160 |
+
}
|
161 |
+
|
162 |
+
.mla-doc-bold-link {
|
163 |
+
font-size:14px;
|
164 |
+
font-weight:bold
|
165 |
+
}
|
166 |
+
</style>
|
167 |
+
<h2>Plugin Documentation</h2>
|
168 |
+
<p>In this tab, jump to:</p>
|
169 |
+
<div class="mla-display-settings-page" id="[+slug_prefix+]_options_documentation_tab" style="width:700px">
|
170 |
+
<ul class="mla-doc-toc-list">
|
171 |
+
<li><a href="#introduction"><strong>Introduction</strong></a></li>
|
172 |
+
<li><a href="#processing"><strong>How the Plugin Works</strong></a></li>
|
173 |
+
<li><a href="#composing_queries"><strong>Composing a Custom Field Query</strong></a></li>
|
174 |
+
<li><a href="#multiple_values"><strong>Searching for Multiple Values</strong></a></li>
|
175 |
+
<li><a href="#wildcards"><strong>Searching Partial Values; Wildcards</strong></a></li>
|
176 |
+
<li><a href="#multiple_fields"><strong>Searching in Multiple Fields or All Fields</strong></a></li>
|
177 |
+
<li><a href="#non_null_searches"><strong>Searching for the Presence of Any Value</strong></a></li>
|
178 |
+
<li><a href="#null_searches"><strong>Searching for the Absence of Any Value</strong></a></li>
|
179 |
+
<li><a href="#debugging"><strong>Debugging and Troubleshooting</strong></a></li>
|
180 |
+
</ul>
|
181 |
+
<p>
|
182 |
+
|
183 |
+
<a name="introduction"></a>
|
184 |
+
</p>
|
185 |
+
<p>
|
186 |
+
<a href="#backtotop">Go to Top</a>
|
187 |
+
</p>
|
188 |
+
<h3>Introduction</h3>
|
189 |
+
<p>
|
190 |
+
The MLA "Search Media" text box lets you search for keywords on the Media/Assistant admin submenu and in the Media Manager Modal (popup) Window. This example plugin lets you search custom field content from those same text boxes. The example plugin was originally developed in response to this MLA support topic:
|
191 |
+
</p>
|
192 |
+
<ul class="mla-doc-toc-list">
|
193 |
+
<li><a href="https://wordpress.org/support/topic/searching-on-custom-fields/" title="View the topic" target="_blank">Searching on custom fields</a></li>
|
194 |
+
</ul>
|
195 |
+
<p>
|
196 |
+
The current version, with enhanced search features and these Settings tabs was inspried by this MLA support topic:
|
197 |
+
</p>
|
198 |
+
<ul class="mla-doc-toc-list">
|
199 |
+
<li><a href="https://wordpress.org/support/topic/search-media-by-custom-field/" title="View the topic" target="_blank">Search Media by Custom Field</a></li>
|
200 |
+
</ul>
|
201 |
+
<p>
|
202 |
+
To use the plugin you must configure the options on the General tab, including the field name(s) to be searched by default. Once the settings are in place you simply use the custom field prefix to specify that the search be handled by this example plugin.
|
203 |
+
</p>
|
204 |
+
<p>
|
205 |
+
More details on composing and running searches are in the sections of this Documentation page.
|
206 |
+
<a name="processing"></a>
|
207 |
+
</p>
|
208 |
+
<p>
|
209 |
+
<a href="#backtotop">Go to Top</a>
|
210 |
+
</p>
|
211 |
+
<h3>How the Plugin Works</h3>
|
212 |
+
<p>
|
213 |
+
The example plugin makes no changes or additions to the MLA core code; it hooks some of the actions and filters MLA provides. The plugin works by detecting the presence of the <code>custom:</code> prefix (or the prefix set on the General tab) in the Search Media text. When the prefix is present, the plugin replaces the standard keyword(s) search with a custom field query. The example plugin uses MLA's existing "Table View" feature as described in the "Library Views/Post MIME Type Processing" section of the Settings/Media Library Assistant Documentation tab to compose and execute the custom field query.</p>
|
214 |
+
<p>
|
215 |
+
The outline that follows is somewhat technical, but should give you an idea of the sequence of events and actions that allow the plugin to do its work. When the post/page is loaded this plugin is initialized, setting up to five MLA "hooks" that may be called to start the plugin’s processing. If the General tab "Enable Media/Assistant searches" box is checked three hooks are set:
|
216 |
+
</p>
|
217 |
+
<ul class="mla-doc-toc-list">
|
218 |
+
<li><strong>mla_list_table_new_instance</strong> - called at the start of composing the Media/Assistant submenu page. If the custom search prefix is found in the Search Media text, the search specification is saved for processing in the next step.</li>
|
219 |
+
<li><strong>mla_list_table_query_final_terms</strong> - called just before the database is queried to find items for the submenu table display. If the search specification is present it is translated to a custom field query and added to the query arguments.</li>
|
220 |
+
<li><strong>mla_list_table_submenu_arguments</strong> - called when the submenu table navigation elements are composed. If the search specification is present it is added to the pagination links in the table header and footer areas.</li>
|
221 |
+
</ul>
|
222 |
+
<p>
|
223 |
+
The General tab "Enable Media Manager searches" box adds the plugin's features to the Media/Library Grid view and the Media Manager Modal (popup) Window (MMMW). If the box is checked two hooks are set:
|
224 |
+
</p>
|
225 |
+
<ul class="mla-doc-toc-list">
|
226 |
+
<li><strong>mla_media_modal_query_initial_terms</strong> - called at the start of the AJAX request that will fill the MMMW's item grid. If the custom search prefix is found in the "query_attachments" Search Media text, the search specification is saved for processing in the next step.</li>
|
227 |
+
<li><strong>mla_media_modal_query_final_terms</strong> - called just before the database is queried to find items for the MMMW item grid. If the search specification is present it is translated to a custom field query and added to the query arguments.</li>
|
228 |
+
</ul>
|
229 |
+
<p>
|
230 |
+
Once the custom field query is added to the database query arguments the example plugin's job is done and processing proceeds normally.
|
231 |
+
<a name="composing_queries"></a>
|
232 |
+
</p>
|
233 |
+
<p>
|
234 |
+
<a href="#backtotop">Go to Top</a>
|
235 |
+
</p>
|
236 |
+
<h3>Composing a Custom Field Query</h3>
|
237 |
+
<p>
|
238 |
+
A custom field query has four parts:
|
239 |
+
</p>
|
240 |
+
<ol>
|
241 |
+
<li>A prefix, "custom:" by default, or whatever you set on the General tab.</li>
|
242 |
+
<li>A comma-separated list of one or more custom field names.</li>
|
243 |
+
<li>An equals sign ("="), to divide the field names from the values</li>
|
244 |
+
<li>A comma-separated list of one or more values</li>
|
245 |
+
</ol>
|
246 |
+
<p>
|
247 |
+
So, for example, if you have a custom field named "Kingdom" with values of "Animal", "Mineral" and "Vegetable" you can compose a search like:
|
248 |
+
</p>
|
249 |
+
<ul class="mla-doc-toc-list">
|
250 |
+
<li><code>custom:Kingdom=Animal</code></li>
|
251 |
+
</ul>
|
252 |
+
<p>
|
253 |
+
It is important to note that custom field values are somewhat different from the keywords and phrases used in the standard Search Media searches. There is no "and/or" option or matching on one of the words you enter. If you enter "this example", the search will not match "this" or "example".
|
254 |
+
|
255 |
+
<a name="multiple_values"></a>
|
256 |
+
</p>
|
257 |
+
<p>
|
258 |
+
<a href="#backtotop">Go to Top</a>
|
259 |
+
</p>
|
260 |
+
<h3>Searching for Multiple Values</h3>
|
261 |
+
<p>
|
262 |
+
If you want to search for more than one value, simply separate each value you want by a comma, such as:
|
263 |
+
</p>
|
264 |
+
<ul class="mla-doc-toc-list">
|
265 |
+
<li><code>custom:Kingdom=Animal,Mineral</code></li>
|
266 |
+
</ul>
|
267 |
+
<p>
|
268 |
+
|
269 |
+
<a name="wildcards"></a>
|
270 |
+
</p>
|
271 |
+
<p>
|
272 |
+
<a href="#backtotop">Go to Top</a>
|
273 |
+
</p>
|
274 |
+
<h3>Searching Partial Values; Wildcards</h3>
|
275 |
+
<p>Wildcard specifications are also supported; for example:
|
276 |
+
<ul class="mla-doc-toc-list">
|
277 |
+
<li><code>custom:Kingdom=*al</code> to match anything ending in "al", e.g., "Animal" and "Mineral"</li>
|
278 |
+
<li><code>custom:Kingdom=*get*</code> to match "Vegetable".</li>
|
279 |
+
<li><code>custom:Headline=*this*,*example*</code> will match values containing "this" or "example".</li>
|
280 |
+
<li>As explained below, a value of <code>custom:Kingdom=*</code> will match any non-NULL value for a custom field.</li>
|
281 |
+
</ul>
|
282 |
+
</p>
|
283 |
+
<p>
|
284 |
+
|
285 |
+
<a name="multiple_fields"></a>
|
286 |
+
</p>
|
287 |
+
<p>
|
288 |
+
<a href="#backtotop">Go to Top</a>
|
289 |
+
</p>
|
290 |
+
<h3>Searching in Multiple Fields or All Fields</h3>
|
291 |
+
If you want to search for the same value(s) in more than one custom field, simply separate each field name you want to search in by a comma, such as:
|
292 |
+
</p>
|
293 |
+
<ul class="mla-doc-toc-list">
|
294 |
+
<li><code>custom:Artist,Patron=smith</code></li>
|
295 |
+
<li><code>custom:Artist,Patron=smith,jones</code></li>
|
296 |
+
</ul>
|
297 |
+
<p>
|
298 |
+
|
299 |
+
<a name="non_null_searches"></a>
|
300 |
+
</p>
|
301 |
+
<p>
|
302 |
+
<a href="#backtotop">Go to Top</a>
|
303 |
+
</p>
|
304 |
+
<h3>Searching for the Presence of Any Value</h3>
|
305 |
+
<p>
|
306 |
+
To return all items that have a non-NULL value in the field, enter the custom field name and then "=*". You can also enter the prefix "custom:" followed by just the custom field name(s). For example, <code>custom:My Featured Items</code>. For example:
|
307 |
+
</p>
|
308 |
+
<ul class="mla-doc-toc-list">
|
309 |
+
<li><code>custom:Kingdom=*</code></li>
|
310 |
+
<li><code>custom:Artist,Patron</code></li>
|
311 |
+
</ul>
|
312 |
+
<p>
|
313 |
+
|
314 |
+
<a name="null_searches"></a>
|
315 |
+
</p>
|
316 |
+
<p>
|
317 |
+
<a href="#backtotop">Go to Top</a>
|
318 |
+
</p>
|
319 |
+
<h3>Searching for the Absence of Any Value</h3>
|
320 |
+
<p>
|
321 |
+
To return all items that have a NULL value in the field, enter the prefix "custom:" followed by the custom field name(s) and then "=". You can also enter a single custom field name (exactly one name) and then ",null".</p>
|
322 |
+
<ul class="mla-doc-toc-list">
|
323 |
+
<li><code>custom:Artist,Patron=</code></li>
|
324 |
+
<li><code>custom:Kingdom,null</code></li>
|
325 |
+
</ul>
|
326 |
+
<p>
|
327 |
+
<a name="debugging"></a>
|
328 |
+
</p>
|
329 |
+
<p>
|
330 |
+
<a href="#backtotop">Go to Top</a>
|
331 |
+
</p>
|
332 |
+
<h3>Debugging and Troubleshooting</h3>
|
333 |
+
<p>
|
334 |
+
If you are not getting the results you expect from a custom field search carefully inspecting the results of parsing the specification and generating the query can be a valuable exercise. These queries follow different rules than the standard keyword search rules, and you may have to adjust the query a few times to get the expected results.
|
335 |
+
</p>
|
336 |
+
<p>
|
337 |
+
For a quick look at the plugin's operation on a given search you can add a debugging prefix to the search text. There are two debugging prefixes:
|
338 |
+
</p>
|
339 |
+
<ul class="mla-doc-toc-list">
|
340 |
+
<li><strong><code>'}|{'</code></strong> - Write debug information to the console, e.g., <code>}|{custom:Kingdom=*</code>. This option writes log entries as PHP Warnings, which might be displayed in the browser window or written to the error log depending on how your site is configured. It's quick and easy but the results are ugly. Also, it will not work for the Media/Library Grid view or the MMMW; information will go to the log for these cases.</li>
|
341 |
+
<li><strong><code>'}|{'</code></strong> - Write debug information to the error log, e.g., <code>}|{custom:Artist,Patron</code>. This option avoids cluttering the display with ugly messages but requires you to find a view the error log file to see the results. The MLA Debug tab may be an easy way to find and view the log.</li>
|
342 |
+
</ul>
|
343 |
+
<p>
|
344 |
+
</p>
|
345 |
+
<p>
|
346 |
+
If a problem persists you can activate additional MLA debug logging, run a test and inspect the log file for more information about what's going on. To activate MLA’s debug logging:
|
347 |
+
</p>
|
348 |
+
<ol>
|
349 |
+
<li>Navigate to the Settings/Media Library Assistant Debug tab.</li>
|
350 |
+
<li>Scroll down to the “MLA Reporting” text box and enter “0x3”. This will turn on MLA debug logging for the example plugin and AJAX operations (such as "query_attachments").</li>
|
351 |
+
<li>Click the Save Changes button to record your new setting.</li>
|
352 |
+
<li>Optionally, scroll to the bottom of the screen and click “Reset” to clear the error log. You may not want to do this depending on how you manage your error log.</li>
|
353 |
+
</ol>
|
354 |
+
<p>
|
355 |
+
Once that’s done you can run a test. The debug log can be very detailed, so restricting the test as best you can will be very helpful. One way to do that:
|
356 |
+
</p>
|
357 |
+
<ol>
|
358 |
+
<li>Go to the Media/Assistant admin submenu table.</li>
|
359 |
+
<li>Enter your custom field search specification in the Search Media text box. You do not need to add either of the above debugging prefixes for this test.</li>
|
360 |
+
<li>Click the Search Media text box to filter the display.</li>
|
361 |
+
</ol>
|
362 |
+
<p>
|
363 |
+
When you’ve finished testing, go back to the Debug screen and:
|
364 |
+
</p>
|
365 |
+
<ol>
|
366 |
+
<li>Enter “0” in the MLA Reporting text box to turn debug logging off.</li>
|
367 |
+
<li>Click the Save Changes button to record your new setting.</li>
|
368 |
+
<li>Scroll to the bottom and click “Download” to get the log content in a text file.</li>
|
369 |
+
<li>Optionally, scroll to the bottom of the screen and click “Reset” to clear the error log.</li>
|
370 |
+
</ol>
|
371 |
+
<p>
|
372 |
+
There may be a lot of messages written to the log, so limit the amount of activity during the logging period. You should see messages in the log like these:
|
373 |
+
</p>
|
374 |
+
<blockquote>
|
375 |
+
[28-Dec-2020 05:38:55 UTC] 610 MLACore::mla_plugins_loaded_action() MLA 2.94 mla_debug_level 0x3<br />
|
376 |
+
[28-Dec-2020 05:38:55 UTC] 37 MLA_Ajax::initialize( true ) $_REQUEST = array (
|
377 |
+
'action' => 'query-attachments',
|
378 |
+
'post_id' => '7283',
|
379 |
+
'query' => <br />
|
380 |
+
</blockquote>
|
381 |
+
<p>
|
382 |
+
Of course, the details will be different. If you discover a defect in the plugin (or in MLA) you can <a href="http://wordpress.org/support/plugin/media-library-assistant" target="_blank">open a support topic</a> or <a href="http://davidlingren.com/#two" target="_blank">contact me at my web site</a> so it can be investigated further. I may ask for a copy of the log file from your tests.
|
383 |
+
</p>
|
384 |
+
</div>
|
examples/plugins/mla-custom-field-search-example/class-mla-example-plugin-settings.php
ADDED
@@ -0,0 +1,491 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Provides option management and Settings/ General and Documentation submenu pages
|
4 |
+
*
|
5 |
+
* This file might be shared among multiple example plugins, so load it with:
|
6 |
+
*
|
7 |
+
* if ( ! class_exists( 'MLAExamplePluginSettings' ) ) {
|
8 |
+
* require_once( pathinfo( __FILE__, PATHINFO_DIRNAME ) . '/class-mla-example-plugin-settings.php' );
|
9 |
+
* }
|
10 |
+
*
|
11 |
+
* @package Media Library Assistant
|
12 |
+
* @since 1.00
|
13 |
+
*/
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Class MLA Example Settings Menu adds Settings/ General and Documentation submenu pages to an example plugin
|
17 |
+
*
|
18 |
+
* @package MLA Example Settings Menu
|
19 |
+
* @since 1.00
|
20 |
+
*/
|
21 |
+
class MLAExamplePluginSettings {
|
22 |
+
/**
|
23 |
+
* Default values for the __construct function
|
24 |
+
*
|
25 |
+
* @since 1.00
|
26 |
+
*
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
private static $default_arguments = array(
|
30 |
+
'slug_prefix' => 'example-plugin',
|
31 |
+
'plugin_title' => 'The Example Plugin',
|
32 |
+
'menu_title' => 'Example Plugin',
|
33 |
+
'plugin_file_name_only' => 'the-example-plugin',
|
34 |
+
'plugin_version' => '1.00',
|
35 |
+
'template_file' => 'absolute path to the template file', // e.g., dirname( __FILE__ ) . '/admin-settings-page.tpl'
|
36 |
+
'options' => array( 'slug' => array( 'type' => 'text|checkbox', 'default' => 'text|boolean' ) ),
|
37 |
+
'general_tab_values' => array(), // additional page_values for 'page-level-options' template
|
38 |
+
'documentation_tab_values' => array(), // page_values for 'documentation-tab' template
|
39 |
+
);
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Current values for this object instance
|
43 |
+
*
|
44 |
+
* @since 1.00
|
45 |
+
*
|
46 |
+
* @var array
|
47 |
+
*/
|
48 |
+
private $current_arguments = array();
|
49 |
+
|
50 |
+
/**
|
51 |
+
* This function sets option definitions and installs filters.
|
52 |
+
*
|
53 |
+
* @since 1.00
|
54 |
+
*
|
55 |
+
* @param array $attr Option definitions and settings
|
56 |
+
*/
|
57 |
+
public function __construct( $attr ) {
|
58 |
+
// Make sure $attr is an array, even if it's empty
|
59 |
+
if ( empty( $attr ) ) {
|
60 |
+
$attr = array();
|
61 |
+
} elseif ( is_string( $attr ) ) {
|
62 |
+
$attr = shortcode_parse_atts( $attr );
|
63 |
+
}
|
64 |
+
|
65 |
+
// Accept only the attributes we need and supply defaults
|
66 |
+
$this->current_arguments = shortcode_atts( self::$default_arguments, $attr );
|
67 |
+
|
68 |
+
// Compile the default settings
|
69 |
+
foreach ( $this->current_arguments['options'] as $slug => $option ) {
|
70 |
+
$this->default_settings[ $slug ] = $option['default'];
|
71 |
+
}
|
72 |
+
|
73 |
+
if ( is_admin() ) {
|
74 |
+
// Add submenu page in the "Settings" section
|
75 |
+
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Add submenu page in the "Settings" section
|
81 |
+
*
|
82 |
+
* @since 1.00
|
83 |
+
*/
|
84 |
+
public function admin_menu() {
|
85 |
+
/*
|
86 |
+
* We need a tab-specific page ID to manage the screen options on the General tab.
|
87 |
+
* Use the URL suffix, if present. If the URL doesn't have a tab suffix, use '-general'.
|
88 |
+
* This hack is required to pass the WordPress "referer" validation.
|
89 |
+
*/
|
90 |
+
if ( isset( $_REQUEST['page'] ) && is_string( $_REQUEST['page'] ) && ( $this->current_arguments['slug_prefix'] . '-settings-' == substr( $_REQUEST['page'], 0, strlen( $this->current_arguments['slug_prefix'] . '-settings-' ) ) ) ) {
|
91 |
+
$tab = substr( $_REQUEST['page'], strlen( $this->current_arguments['slug_prefix'] . '-settings-' ) );
|
92 |
+
} else {
|
93 |
+
$tab = 'general';
|
94 |
+
}
|
95 |
+
|
96 |
+
$tab = $this->_get_options_tablist( $tab ) ? '-' . $tab : '-general';
|
97 |
+
add_submenu_page( 'options-general.php', $this->current_arguments['plugin_title'], $this->current_arguments['menu_title'], 'manage_options', $this->current_arguments['slug_prefix'] . '-settings' . $tab, array( $this, 'add_submenu_page' ) );
|
98 |
+
add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2 );
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Add the "Settings" and "Guide" links to the Plugins section entry
|
103 |
+
*
|
104 |
+
* @since 1.00
|
105 |
+
*
|
106 |
+
* @param array array of links for the Plugin, e.g., "Activate"
|
107 |
+
* @param string Directory and name of the plugin Index file
|
108 |
+
*
|
109 |
+
* @return array Updated array of links for the Plugin
|
110 |
+
*/
|
111 |
+
public function plugin_action_links( $links, $file ) {
|
112 |
+
if ( $file == $this->current_arguments['plugin_file_name_only'] . '/' . $this->current_arguments['plugin_file_name_only'] . '.php' ) {
|
113 |
+
$settings_link = sprintf( '<a href="%s">%s</a>', admin_url( 'options-general.php?page=' . $this->current_arguments['slug_prefix'] . '-settings-documentation&mla_tab=documentation' ), 'Guide' );
|
114 |
+
array_unshift( $links, $settings_link );
|
115 |
+
$settings_link = sprintf( '<a href="%s">%s</a>', admin_url( 'options-general.php?page=' . $this->current_arguments['slug_prefix'] . '-settings-general' ), 'Settings' );
|
116 |
+
array_unshift( $links, $settings_link );
|
117 |
+
}
|
118 |
+
|
119 |
+
return $links;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Render (echo) the example plugin's submenu in the Settings section
|
124 |
+
*
|
125 |
+
* @since 1.00
|
126 |
+
*
|
127 |
+
* @return void Echoes HTML markup for the submenu page
|
128 |
+
*/
|
129 |
+
public function add_submenu_page() {
|
130 |
+
if ( !current_user_can( 'manage_options' ) ) {
|
131 |
+
echo '<h2>' . $this->current_arguments['plugin_title'] . " - Error</h2>\n";
|
132 |
+
wp_die( 'You do not have permission to manage plugin settings.' );
|
133 |
+
}
|
134 |
+
|
135 |
+
// Load template array and initialize page-level values.
|
136 |
+
$this->page_template_array = MLACore::mla_load_template( $this->current_arguments['template_file'], 'path' );
|
137 |
+
$current_tab_slug = isset( $_REQUEST['mla_tab'] ) ? $_REQUEST['mla_tab']: 'general';
|
138 |
+
$current_tab = $this->_get_options_tablist( $current_tab_slug );
|
139 |
+
$page_values = array(
|
140 |
+
'plugin_title' => $this->current_arguments['plugin_title'],
|
141 |
+
'version' => 'v' . $this->current_arguments['plugin_version'],
|
142 |
+
'messages' => '',
|
143 |
+
'tablist' => $this->_compose_settings_tabs( $current_tab_slug ),
|
144 |
+
'tab_content' => '',
|
145 |
+
);
|
146 |
+
|
147 |
+
// Compose tab content
|
148 |
+
if ( $current_tab ) {
|
149 |
+
if ( isset( $current_tab['render'] ) ) {
|
150 |
+
$handler = $current_tab['render'];
|
151 |
+
$page_content = call_user_func( array( $this, $handler ) );
|
152 |
+
} else {
|
153 |
+
$page_content = array( 'message' => "ERROR: Cannot render content tab {$current_tab_slug}", 'body' => '' );
|
154 |
+
}
|
155 |
+
} else {
|
156 |
+
$page_content = array( 'message' => "ERROR: Unknown content tab {$current_tab_slug}", 'body' => '' );
|
157 |
+
}
|
158 |
+
|
159 |
+
if ( ! empty( $page_content['message'] ) ) {
|
160 |
+
if ( false !== strpos( $page_content['message'], 'ERROR' ) ) {
|
161 |
+
$messages_class = 'updated error';
|
162 |
+
} else {
|
163 |
+
$messages_class = 'updated notice is-dismissible';
|
164 |
+
}
|
165 |
+
|
166 |
+
$page_values['messages'] = MLAData::mla_parse_template( $this->page_template_array['messages'], array(
|
167 |
+
'mla_messages_class' => $messages_class ,
|
168 |
+
'messages' => $page_content['message'],
|
169 |
+
) );
|
170 |
+
}
|
171 |
+
|
172 |
+
$page_values['tab_content'] = $page_content['body'];
|
173 |
+
|
174 |
+
echo MLAData::mla_parse_template( $this->page_template_array['page'], $page_values );
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Template file for the Settings page(s) and parts
|
179 |
+
*
|
180 |
+
* This array contains all of the template parts for the Settings page(s). The array is built once
|
181 |
+
* each page load and cached for subsequent use.
|
182 |
+
*
|
183 |
+
* @since 1.00
|
184 |
+
*
|
185 |
+
* @var array
|
186 |
+
*/
|
187 |
+
private $page_template_array = NULL;
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Definitions for Settings page tab ids, titles and handlers
|
191 |
+
* Each tab is defined by an array with the following elements:
|
192 |
+
*
|
193 |
+
* array key => HTML id/name attribute and option database key (OMIT MLA_OPTION_PREFIX)
|
194 |
+
*
|
195 |
+
* title => tab label / heading text
|
196 |
+
* render => rendering function for tab messages and content. Usage:
|
197 |
+
* $tab_content = ['render']();
|
198 |
+
*
|
199 |
+
* @since 1.00
|
200 |
+
*
|
201 |
+
* @var array
|
202 |
+
*/
|
203 |
+
private $mla_tablist = array(
|
204 |
+
'general' => array( 'title' => 'General', 'render' => '_compose_general_tab' ),
|
205 |
+
'documentation' => array( 'title' => 'Documentation', 'render' => '_compose_documentation_tab' ),
|
206 |
+
);
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Retrieve the list of options tabs or a specific tab value
|
210 |
+
*
|
211 |
+
* @since 1.00
|
212 |
+
*
|
213 |
+
* @param string Tab slug, to retrieve a single entry
|
214 |
+
*
|
215 |
+
* @return array|false The entire tablist ( $tab = NULL ), a single tab entry or false if not found/not allowed
|
216 |
+
*/
|
217 |
+
private function _get_options_tablist( $tab = NULL ) {
|
218 |
+
if ( is_string( $tab ) ) {
|
219 |
+
if ( isset( $this->mla_tablist[ $tab ] ) ) {
|
220 |
+
$results = $this->mla_tablist[ $tab ];
|
221 |
+
} else {
|
222 |
+
$results = false;
|
223 |
+
}
|
224 |
+
} else {
|
225 |
+
$results = $this->mla_tablist;
|
226 |
+
}
|
227 |
+
|
228 |
+
return $results;
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Compose the navigation tabs for the Settings subpage
|
233 |
+
*
|
234 |
+
* @since 1.00
|
235 |
+
* @uses $page_template_array contains tablist and tablist-item templates
|
236 |
+
*
|
237 |
+
* @param string Optional data-tab-id value for the active tab, default 'general'
|
238 |
+
*
|
239 |
+
* @return string HTML markup for the Settings subpage navigation tabs
|
240 |
+
*/
|
241 |
+
private function _compose_settings_tabs( $active_tab = 'general' ) {
|
242 |
+
$tablist_item = $this->page_template_array['tablist-item'];
|
243 |
+
$tabs = '';
|
244 |
+
foreach ( $this->_get_options_tablist() as $key => $item ) {
|
245 |
+
$item_values = array(
|
246 |
+
'data-tab-id' => $key,
|
247 |
+
'nav-tab-active' => ( $active_tab == $key ) ? 'nav-tab-active' : '',
|
248 |
+
'settings-page' => $this->current_arguments['slug_prefix'] . '-settings-' . $key,
|
249 |
+
'title' => $item['title']
|
250 |
+
);
|
251 |
+
|
252 |
+
$tabs .= MLAData::mla_parse_template( $tablist_item, $item_values );
|
253 |
+
} // foreach $item
|
254 |
+
|
255 |
+
$tablist_values = array( 'tablist' => $tabs );
|
256 |
+
return MLAData::mla_parse_template( $this->page_template_array['tablist'], $tablist_values );
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Compose the General tab content for the Settings subpage
|
261 |
+
*
|
262 |
+
* @since 1.00
|
263 |
+
* @uses $page_template_array contains tab content template(s)
|
264 |
+
*
|
265 |
+
* @return array 'message' => status/error messages, 'body' => tab content
|
266 |
+
*/
|
267 |
+
private function _compose_general_tab() {
|
268 |
+
$page_content = array( 'message' => '', 'body' => '' );
|
269 |
+
|
270 |
+
// Check for page-level Save Changes, Restore Defaults
|
271 |
+
if ( !empty( $_REQUEST[ $this->current_arguments['slug_prefix'] . '_options_save'] ) ) {
|
272 |
+
check_admin_referer( MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME );
|
273 |
+
$page_content = $this->_save_setting_changes();
|
274 |
+
} elseif ( !empty( $_REQUEST[ $this->current_arguments['slug_prefix'] . '_options_reset'] ) ) {
|
275 |
+
check_admin_referer( MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME );
|
276 |
+
$page_content = $this->_restore_setting_defaults();
|
277 |
+
}
|
278 |
+
|
279 |
+
if ( !empty( $page_content['body'] ) ) {
|
280 |
+
return $page_content;
|
281 |
+
}
|
282 |
+
|
283 |
+
// Display the General tab
|
284 |
+
$_SERVER['REQUEST_URI'] = remove_query_arg( array(
|
285 |
+
$this->current_arguments['slug_prefix'] . '_options',
|
286 |
+
'_wpnonce',
|
287 |
+
'_wp_http_referer',
|
288 |
+
$this->current_arguments['slug_prefix'] . '_options_save',
|
289 |
+
$this->current_arguments['slug_prefix'] . '_options_reset',
|
290 |
+
), $_SERVER['REQUEST_URI'] );
|
291 |
+
|
292 |
+
// Compose page-level options
|
293 |
+
$page_values = $this->current_arguments['general_tab_values'];
|
294 |
+
|
295 |
+
foreach ( $this->current_arguments['options'] as $slug => $option ) {
|
296 |
+
if ( 'checkbox' === $option['type'] ) {
|
297 |
+
$page_values[ $slug . '_checked' ] = $this->get_plugin_option( $slug ) ? 'checked="checked" ' : '';
|
298 |
+
} else {
|
299 |
+
$page_values[ $slug ] = $this->get_plugin_option( $slug );
|
300 |
+
}
|
301 |
+
}
|
302 |
+
//error_log( __LINE__ . ' MLAExamplePluginSettings::_compose_general_tab page_values = ' . var_export( $page_values, true ), 0 );
|
303 |
+
|
304 |
+
$options_list = MLAData::mla_parse_template( $this->page_template_array['page-level-options'], $page_values );
|
305 |
+
|
306 |
+
$form_arguments = '?page=' . $this->current_arguments['slug_prefix'] . '-settings-general&mla_tab=general';
|
307 |
+
|
308 |
+
$page_values = array(
|
309 |
+
'form_url' => admin_url( 'options-general.php' ) . $form_arguments,
|
310 |
+
'_wpnonce' => wp_nonce_field( MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME, true, false ),
|
311 |
+
'options_list' => $options_list,
|
312 |
+
'slug_prefix' => $this->current_arguments['slug_prefix'],
|
313 |
+
);
|
314 |
+
|
315 |
+
$page_content['body'] .= MLAData::mla_parse_template( $this->page_template_array['general-tab'], $page_values );
|
316 |
+
|
317 |
+
return $page_content;
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Compose the Documentation tab content for the Settings subpage
|
322 |
+
*
|
323 |
+
* @since 1.00
|
324 |
+
* @uses $page_template_array contains tab content template(s)
|
325 |
+
*
|
326 |
+
* @return array 'message' => status/error messages, 'body' => tab content
|
327 |
+
*/
|
328 |
+
private function _compose_documentation_tab() {
|
329 |
+
$page_content = array( 'message' => '', 'body' => '' );
|
330 |
+
$page_values = array(
|
331 |
+
);
|
332 |
+
|
333 |
+
$page_content['body'] = MLAData::mla_parse_template( $this->page_template_array['documentation-tab'], $this->current_arguments['documentation_tab_values'] );
|
334 |
+
return $page_content;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Save settings as a WordPress wp_options entry
|
339 |
+
*
|
340 |
+
* @since 1.00
|
341 |
+
*
|
342 |
+
* @return array 'message' => status/error messages, 'body' => tab content
|
343 |
+
*/
|
344 |
+
private function _save_setting_changes() {
|
345 |
+
$page_content = array( 'message' => 'Settings unchanged.', 'body' => '' );
|
346 |
+
|
347 |
+
$changed = false;
|
348 |
+
foreach ( $this->current_arguments['options'] as $slug => $option ) {
|
349 |
+
if ( 'checkbox' === $option['type'] ) {
|
350 |
+
$changed |= $this->_update_plugin_option( $slug, isset( $_REQUEST[ $this->current_arguments['slug_prefix'] . '_options' ][ $slug ] ) );
|
351 |
+
} else {
|
352 |
+
if ( isset( $_REQUEST[ $this->current_arguments['slug_prefix'] . '_options' ][ $slug ] ) ) {
|
353 |
+
$changed |= $this->_update_plugin_option( $slug, $_REQUEST[ $this->current_arguments['slug_prefix'] . '_options' ][ $slug ] );
|
354 |
+
} else {
|
355 |
+
$changed |= $this->_update_plugin_option( $slug, $option['default'] );
|
356 |
+
}
|
357 |
+
}
|
358 |
+
} // foreach option
|
359 |
+
|
360 |
+
if ( $changed ) {
|
361 |
+
// No reason to save defaults in the database
|
362 |
+
if ( $this->current_settings === $this->default_settings ) {
|
363 |
+
delete_option( $this->current_arguments['slug_prefix'] . '-settings' );
|
364 |
+
} else {
|
365 |
+
$changed = update_option( $this->current_arguments['slug_prefix'] . '-settings', $this->current_settings, false );
|
366 |
+
}
|
367 |
+
|
368 |
+
if ( $changed ) {
|
369 |
+
$page_content['message'] = "Settings have been updated.";
|
370 |
+
} else {
|
371 |
+
$page_content['message'] = "Settings updated failed.";
|
372 |
+
}
|
373 |
+
}
|
374 |
+
|
375 |
+
return $page_content;
|
376 |
+
} // _save_setting_changes
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Delete the plugin's WordPress wp_options entry, restoring the default settings
|
380 |
+
*
|
381 |
+
* @since 1.00
|
382 |
+
*
|
383 |
+
* @return array 'message' => status/error messages, 'body' => tab content
|
384 |
+
*/
|
385 |
+
private function _restore_setting_defaults() {
|
386 |
+
$page_content = array( 'message' => 'Settings unchanged.', 'body' => '' );
|
387 |
+
$this->current_settings = $this->default_settings;
|
388 |
+
$changed = delete_option( $this->current_arguments['slug_prefix'] . '-settings' );
|
389 |
+
|
390 |
+
if ( $changed ) {
|
391 |
+
$page_content['message'] = "Settings have been updated.";
|
392 |
+
}
|
393 |
+
|
394 |
+
return $page_content;
|
395 |
+
} // _restore_setting_defaults
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Assemble the in-memory representation of the plugin settings
|
399 |
+
*
|
400 |
+
* @since 1.00
|
401 |
+
*
|
402 |
+
* @param boolean $force_refresh Optional. Force a reload of rules. Default false.
|
403 |
+
*
|
404 |
+
* @return boolean Success (true) or failure (false) of the operation
|
405 |
+
*/
|
406 |
+
private function _get_plugin_settings( $force_refresh = false ) {
|
407 |
+
if ( false == $force_refresh && NULL != $this->current_settings ) {
|
408 |
+
return true;
|
409 |
+
}
|
410 |
+
|
411 |
+
// Update the plugin options from the wp_options table or set defaults
|
412 |
+
$this->current_settings = get_option( $this->current_arguments['slug_prefix'] . '-settings' );
|
413 |
+
if ( !is_array( $this->current_settings ) ) {
|
414 |
+
$this->current_settings = $this->default_settings;
|
415 |
+
}
|
416 |
+
|
417 |
+
// Initialize any new setting(s) from the default settings
|
418 |
+
foreach ( $this->current_arguments['options'] as $slug => $option ) {
|
419 |
+
if ( !isset( $this->current_settings[ $slug ] ) ) {
|
420 |
+
$this->current_settings[ $slug ] = $option['default'];
|
421 |
+
}
|
422 |
+
}
|
423 |
+
|
424 |
+
return true;
|
425 |
+
}
|
426 |
+
|
427 |
+
/**
|
428 |
+
* In-memory representation of the option settings
|
429 |
+
*
|
430 |
+
* @since 1.00
|
431 |
+
*
|
432 |
+
* @var array
|
433 |
+
*/
|
434 |
+
private $current_settings = NULL;
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Default processing options
|
438 |
+
*
|
439 |
+
* @since 1.00
|
440 |
+
*
|
441 |
+
* @var array
|
442 |
+
*/
|
443 |
+
private $default_settings = array();
|
444 |
+
|
445 |
+
/**
|
446 |
+
* Get a plugin option setting
|
447 |
+
*
|
448 |
+
* @since 1.00
|
449 |
+
*
|
450 |
+
* @param string $name Option name
|
451 |
+
*
|
452 |
+
* @return mixed Option value, if it exists else NULL
|
453 |
+
*/
|
454 |
+
public function get_plugin_option( $name ) {
|
455 |
+
if ( !$this->_get_plugin_settings() ) {
|
456 |
+
return NULL;
|
457 |
+
}
|
458 |
+
|
459 |
+
if ( !isset( $this->current_settings[ $name ] ) ) {
|
460 |
+
return NULL;
|
461 |
+
}
|
462 |
+
|
463 |
+
return $this->current_settings[ $name ];
|
464 |
+
}
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Update a plugin option setting
|
468 |
+
*
|
469 |
+
* @since 1.00
|
470 |
+
*
|
471 |
+
* @param string $name Option name
|
472 |
+
* @param mixed $new_value Option value
|
473 |
+
*
|
474 |
+
* @return mixed True if option value changed, false if value unchanged, NULL if failure
|
475 |
+
*/
|
476 |
+
private function _update_plugin_option( $name, $new_value ) {
|
477 |
+
if ( !$this->_get_plugin_settings() ) {
|
478 |
+
return NULL;
|
479 |
+
}
|
480 |
+
|
481 |
+
$old_value = isset( $this->current_settings[ $name ] ) ? $this->current_settings[ $name ] : NULL;
|
482 |
+
|
483 |
+
if ( $new_value === $old_value ) {
|
484 |
+
return false;
|
485 |
+
}
|
486 |
+
|
487 |
+
$this->current_settings[ $name ] = $new_value;
|
488 |
+
return true;
|
489 |
+
}
|
490 |
+
} // Class MLAExamplePluginSettings
|
491 |
+
?>
|
examples/plugins/mla-custom-field-search-example/mla-custom-field-search-example.php
ADDED
@@ -0,0 +1,460 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Extends the Media/Assistant "Search Media" box to custom field values
|
4 |
+
*
|
5 |
+
* In this example, a "custom:" prefix is detected in the Media/Assistant "search media" text
|
6 |
+
* box and the search is modified to query a custom field for a specific value, e.g.,
|
7 |
+
* "custom:photo reference=123456". You can also search for partial values:
|
8 |
+
*
|
9 |
+
* - To return all items that have a non-NULL value in the field, simply enter the prefix
|
10 |
+
* "custom:" followed by the custom field name, for example, custom:File Size. You can also
|
11 |
+
* enter the custom field name and then "=*", e.g., custom:File Size=*.
|
12 |
+
* - To return all items that have a NULL value in the field, enter the custom field name and
|
13 |
+
* then "=", e.g., custom:File Size=.
|
14 |
+
* - To return all items that match one or more values, enter the prefix "custom:" followed by
|
15 |
+
* the custom field name and then "=" followed by a list of values. For example, custom:Color=red
|
16 |
+
* or custom:Color=red,green,blue. Wildcard specifications are also supported; for example, "*post"
|
17 |
+
* to match anything ending in "post" or "th*da*" to match values like "the date" and "this day".
|
18 |
+
*
|
19 |
+
* This example plugin uses four of the many filters available in the Media/Assistant Submenu
|
20 |
+
* and illustrates some of the techniques you can use to customize the submenu table display.
|
21 |
+
*
|
22 |
+
* Created for support topic "Searching on custom fields"
|
23 |
+
* opened on 5/11/2015 by "BFI-WP".
|
24 |
+
* https://wordpress.org/support/topic/searching-on-custom-fields/
|
25 |
+
*
|
26 |
+
* Enhanced for support topic "Search Media by Custom Field"
|
27 |
+
* opened on 12/2/2020 by "icedarkness".
|
28 |
+
* https://wordpress.org/support/topic/search-media-by-custom-field/
|
29 |
+
*
|
30 |
+
* @package MLA Custom Field Search Example
|
31 |
+
* @version 1.06
|
32 |
+
*/
|
33 |
+
|
34 |
+
/*
|
35 |
+
Plugin Name: MLA Custom Field Search Example
|
36 |
+
Plugin URI: http://davidlingren.com/
|
37 |
+
Description: Extends the Media/Assistant "Search Media" box to custom field values
|
38 |
+
Author: David Lingren
|
39 |
+
Version: 1.06
|
40 |
+
Author URI: http://davidlingren.com/
|
41 |
+
|
42 |
+
Copyright 2014 - 2020 David Lingren
|
43 |
+
|
44 |
+
This program is free software; you can redistribute it and/or modify
|
45 |
+
it under the terms of the GNU General Public License as published by
|
46 |
+
the Free Software Foundation; either version 2 of the License, or
|
47 |
+
(at your option) any later version.
|
48 |
+
|
49 |
+
This program is distributed in the hope that it will be useful,
|
50 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
51 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
52 |
+
GNU General Public License for more details.
|
53 |
+
|
54 |
+
You can get a copy of the GNU General Public License by writing to the
|
55 |
+
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
56 |
+
*/
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Class MLA Custom Field Search Example extends the Media/Assistant "Search Media" box
|
60 |
+
* to custom field values
|
61 |
+
*
|
62 |
+
* @package MLA Custom Field Search Example
|
63 |
+
* @since 1.00
|
64 |
+
*/
|
65 |
+
class MLACustomFieldSearchExample {
|
66 |
+
/**
|
67 |
+
* Plugin version number for debug logging
|
68 |
+
*
|
69 |
+
* @since 1.01
|
70 |
+
*
|
71 |
+
* @var integer
|
72 |
+
*/
|
73 |
+
const PLUGIN_VERSION = '1.06';
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Constant to log this plugin's debug activity
|
77 |
+
*
|
78 |
+
* @since 1.06
|
79 |
+
*
|
80 |
+
* @var integer
|
81 |
+
*/
|
82 |
+
const MLA_DEBUG_CATEGORY = 0x00008000;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Slug prefix for registering and enqueueing submenu pages, style sheets, scripts and settings
|
86 |
+
*
|
87 |
+
* @since 1.06
|
88 |
+
*
|
89 |
+
* @var string
|
90 |
+
*/
|
91 |
+
const SLUG_PREFIX = 'mlacustomfieldsearch';
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Configuration values for the Settings Management object
|
95 |
+
*
|
96 |
+
* @since 1.06
|
97 |
+
*
|
98 |
+
* @var array
|
99 |
+
*/
|
100 |
+
private static $settings_arguments = array(
|
101 |
+
'slug_prefix' => self::SLUG_PREFIX,
|
102 |
+
'plugin_title' => 'MLA Custom Field Search Example',
|
103 |
+
'menu_title' => 'MLA Custom Search',
|
104 |
+
'plugin_file_name_only' => 'mla-custom-field-search-example',
|
105 |
+
'plugin_version' => self::PLUGIN_VERSION,
|
106 |
+
'template_file' => '/admin-settings-page.tpl', // Add the path at runtime, in initialize()
|
107 |
+
'options' => array( // 'slug' => array( 'type' => 'text|checkbox', 'default' => 'text|boolean' )
|
108 |
+
'media_assistant_support' =>array( 'type' => 'checkbox', 'default' => true ),
|
109 |
+
'mmmw_support' =>array( 'type' => 'checkbox', 'default' => true ),
|
110 |
+
'prefix' =>array( 'type' => 'text', 'default' => 'custom:' ),
|
111 |
+
'default_fields' =>array( 'type' => 'text', 'default' => '' ),
|
112 |
+
'all_fields' =>array( 'type' => 'text', 'default' => '*' ),
|
113 |
+
'all_fields_support' =>array( 'type' => 'checkbox', 'default' => true ),
|
114 |
+
),
|
115 |
+
'general_tab_values' => array(), // additional page_values for 'page-level-options' template
|
116 |
+
'documentation_tab_values' => array(
|
117 |
+
'plugin_title' => 'MLA Custom Field Search Example',
|
118 |
+
), // page_values for 'documentation-tab' template
|
119 |
+
);
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Settings Management object
|
123 |
+
*
|
124 |
+
* @since 1.06
|
125 |
+
*
|
126 |
+
* @var array
|
127 |
+
*/
|
128 |
+
private static $plugin_settings = NULL;
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Initialization function, similar to __construct()
|
132 |
+
*
|
133 |
+
* @since 1.06
|
134 |
+
*
|
135 |
+
* @return void
|
136 |
+
*/
|
137 |
+
public static function initialize() {
|
138 |
+
// This plugin requires MLA
|
139 |
+
if ( ! class_exists( 'MLACore', false ) ) {
|
140 |
+
return;
|
141 |
+
}
|
142 |
+
|
143 |
+
// The filters are only useful for the admin section; exit in the front-end posts/pages
|
144 |
+
if ( ! is_admin() ) {
|
145 |
+
return;
|
146 |
+
}
|
147 |
+
|
148 |
+
// The plugin settings class is shared with other MLA example plugins
|
149 |
+
if ( ! class_exists( 'MLAExamplePluginSettings' ) ) {
|
150 |
+
require_once( pathinfo( __FILE__, PATHINFO_DIRNAME ) . '/class-mla-example-plugin-settings.php' );
|
151 |
+
}
|
152 |
+
|
153 |
+
// Add the run-time values to the arguments
|
154 |
+
self::$settings_arguments['template_file'] = dirname( __FILE__ ) . self::$settings_arguments['template_file'];
|
155 |
+
|
156 |
+
// Create our own settings object
|
157 |
+
self::$plugin_settings = new MLAExamplePluginSettings( self::$settings_arguments );
|
158 |
+
|
159 |
+
if ( self::$plugin_settings->get_plugin_option( 'media_assistant_support' ) ) {
|
160 |
+
// Defined in /media-library-assistant/includes/class-mla-main.php
|
161 |
+
add_filter( 'mla_list_table_new_instance', 'MLACustomFieldSearchExample::mla_list_table_new_instance', 10, 1 );
|
162 |
+
|
163 |
+
// Defined in /media-library-assistant/includes/class-mla-data.php
|
164 |
+
add_filter( 'mla_list_table_query_final_terms', 'MLACustomFieldSearchExample::mla_list_table_query_final_terms', 10, 1 );
|
165 |
+
|
166 |
+
// Defined in /media-library-assistant/includes/class-mla-list-table.php
|
167 |
+
add_filter( 'mla_list_table_submenu_arguments', 'MLACustomFieldSearchExample::mla_list_table_submenu_arguments', 10, 2 );
|
168 |
+
}
|
169 |
+
|
170 |
+
if ( self::$plugin_settings->get_plugin_option( 'mmmw_support' ) ) {
|
171 |
+
// Defined in /media-library-assistant/includes/class-mla-media-modal.php
|
172 |
+
add_filter( 'mla_media_modal_query_initial_terms', 'MLACustomFieldSearchExample::mla_media_modal_query_initial_terms', 10, 2 );
|
173 |
+
|
174 |
+
// Defined in /media-library-assistant/includes/class-mla-data.php
|
175 |
+
add_filter( 'mla_media_modal_query_final_terms', 'MLACustomFieldSearchExample::mla_media_modal_query_final_terms', 10, 1 );
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Filter the URL parameters that will be retained when the submenu page refreshes
|
181 |
+
*
|
182 |
+
* @since 1.06
|
183 |
+
*
|
184 |
+
* @param array $submenu_arguments non-empty view, search, filter and sort arguments.
|
185 |
+
* @param boolean $include_filters Include the "click filter" values in the results.
|
186 |
+
*/
|
187 |
+
public static function mla_list_table_submenu_arguments( $submenu_arguments, $include_filters ) {
|
188 |
+
if ( $include_filters ) {
|
189 |
+
if ( !empty( self::$custom_field_parameters['s'] ) ) {
|
190 |
+
$prefix = self::$plugin_settings->get_plugin_option( 'prefix' );
|
191 |
+
$submenu_arguments['s'] = $prefix . self::$custom_field_parameters['s'];
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
return $submenu_arguments;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Extend the MLA_List_Table class
|
200 |
+
*
|
201 |
+
* This filter gives you an opportunity to extend the MLA_List_Table class.
|
202 |
+
* You can also use this filter to inspect or modify any of the $_REQUEST arguments.
|
203 |
+
*
|
204 |
+
* @since 1.00
|
205 |
+
*
|
206 |
+
* @param object $mla_list_table NULL, to indicate no extension/use the base class.
|
207 |
+
*
|
208 |
+
* @return object updated mla_list_table object.
|
209 |
+
*/
|
210 |
+
public static function mla_list_table_new_instance( $mla_list_table ) {
|
211 |
+
/*
|
212 |
+
* Look for the custom field search prefix in the Search Media text box,
|
213 |
+
* after checking for the "debug" prefixes.
|
214 |
+
*/
|
215 |
+
if ( isset( $_REQUEST['s'] ) ) {
|
216 |
+
switch ( substr( $_REQUEST['s'], 0, 3 ) ) {
|
217 |
+
case '}|{':
|
218 |
+
self::$custom_field_parameters['debug'] = 'console';
|
219 |
+
$start = 3;
|
220 |
+
break;
|
221 |
+
case '{|}':
|
222 |
+
self::$custom_field_parameters['debug'] = 'log';
|
223 |
+
$start = 3;
|
224 |
+
break;
|
225 |
+
default:
|
226 |
+
$start = 0;
|
227 |
+
}
|
228 |
+
|
229 |
+
$prefix = self::$plugin_settings->get_plugin_option( 'prefix' );
|
230 |
+
if ( $prefix === substr( $_REQUEST['s'], $start, strlen( $prefix ) ) ) {
|
231 |
+
self::$custom_field_parameters['s'] = substr( $_REQUEST['s'], $start + strlen( $prefix ) );
|
232 |
+
unset( $_REQUEST['s'] );
|
233 |
+
//self::$custom_field_parameters['mla_search_connector'] = $_REQUEST['mla_search_connector'];
|
234 |
+
unset( $_REQUEST['mla_search_connector'] );
|
235 |
+
//self::$custom_field_parameters['mla_search_fields'] = $_REQUEST['mla_search_fields'];
|
236 |
+
unset( $_REQUEST['mla_search_fields'] );
|
237 |
+
} else {
|
238 |
+
self::$custom_field_parameters = array();
|
239 |
+
}
|
240 |
+
} // isset $_REQUEST['s']
|
241 |
+
|
242 |
+
return $mla_list_table;
|
243 |
+
} // mla_list_table_new_instance
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Custom Field Search "parameters"
|
247 |
+
*
|
248 |
+
* @since 1.01
|
249 |
+
*
|
250 |
+
* @var array
|
251 |
+
*/
|
252 |
+
public static $custom_field_parameters = array();
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Filter the WP_Query request parameters for the prepare_items query
|
256 |
+
*
|
257 |
+
* Gives you an opportunity to change the terms of the prepare_items query
|
258 |
+
* after they are processed by the "Prepare List Table Query" handler.
|
259 |
+
*
|
260 |
+
* @since 1.01
|
261 |
+
*
|
262 |
+
* @param array WP_Query request prepared by "Prepare List Table Query"
|
263 |
+
*
|
264 |
+
* @return array updated WP_Query request
|
265 |
+
*/
|
266 |
+
public static function mla_list_table_query_final_terms( $request ) {
|
267 |
+
/*
|
268 |
+
* If $request['offset'] and $request['posts_per_page'] are set, this is the "prepare_items" request.
|
269 |
+
* If they are NOT set, this is a "view count" request, i.e., to get the count for a custom view.
|
270 |
+
*
|
271 |
+
* MLAQuery::$query_parameters and MLAQuery::$search_parameters contain
|
272 |
+
* additional parameters used in some List Table queries.
|
273 |
+
*/
|
274 |
+
if ( ! ( isset( $request['offset'] ) && isset( $request['posts_per_page'] ) ) ) {
|
275 |
+
return $request;
|
276 |
+
}
|
277 |
+
|
278 |
+
if ( empty( self::$custom_field_parameters ) ) {
|
279 |
+
return $request;
|
280 |
+
}
|
281 |
+
|
282 |
+
if ( isset( self::$custom_field_parameters['debug'] ) ) {
|
283 |
+
MLAQuery::$query_parameters['debug'] = self::$custom_field_parameters['debug'];
|
284 |
+
MLAQuery::$search_parameters['debug'] = self::$custom_field_parameters['debug'];
|
285 |
+
MLACore::mla_debug_mode( self::$custom_field_parameters['debug'] );
|
286 |
+
}
|
287 |
+
|
288 |
+
$specification = self::$custom_field_parameters['s'];
|
289 |
+
|
290 |
+
// Check for and reformat special "<field>,null" case
|
291 |
+
if ( ( strlen( $specification ) >= strlen(',null') ) && ( false !== strpos( $specification, ',null', -strlen(',null') ) ) ) {
|
292 |
+
$field = substr( $specification, 0, strlen( $specification ) - strlen(',null') );
|
293 |
+
$specification = $field . '=';
|
294 |
+
}
|
295 |
+
|
296 |
+
// Check for and reformat "field names only" case
|
297 |
+
if ( false === strpos( $specification, '=' ) ) {
|
298 |
+
$specification .= '=*';
|
299 |
+
}
|
300 |
+
|
301 |
+
// Apply default field name?
|
302 |
+
$default_fields = self::$plugin_settings->get_plugin_option( 'default_fields' );
|
303 |
+
if ( empty( $default_fields ) ) {
|
304 |
+
$default_fields = 'ERROR - No Default Field(s) Specified';
|
305 |
+
}
|
306 |
+
|
307 |
+
if ( '=' == substr( $specification, 0, 1 ) ) {
|
308 |
+
$tokens = array( $default_fields, substr( $specification, 1 ) );
|
309 |
+
} else {
|
310 |
+
$tokens = explode( '=', $specification ) ;
|
311 |
+
}
|
312 |
+
|
313 |
+
// See if the custom field name is present, followed by "=" and a value
|
314 |
+
if ( 1 < count( $tokens ) ) {
|
315 |
+
$field = array_shift( $tokens );
|
316 |
+
$value = implode( '=', $tokens );
|
317 |
+
} else {
|
318 |
+
// Supply a default custom field name
|
319 |
+
$field = $default_fields;
|
320 |
+
$value = $tokens[0];
|
321 |
+
}
|
322 |
+
|
323 |
+
// Look for substitute All Fields value
|
324 |
+
if ( self::$plugin_settings->get_plugin_option( 'all_fields_support' ) ) {
|
325 |
+
if ( $field === self::$plugin_settings->get_plugin_option( 'all_fields' ) ) {
|
326 |
+
$field = '*';
|
327 |
+
}
|
328 |
+
}
|
329 |
+
|
330 |
+
// Parse the query, remove MLA-specific elements, fix numeric and "commas" format fields
|
331 |
+
MLACore::mla_debug_add( __LINE__ . " MLACustomFieldSearchExample::mla_list_table_query_final_terms query = custom:{$field}={$value}" );
|
332 |
+
$tokens = MLACore::mla_prepare_view_query( 'custom_field_search', 'custom:' . $field . '=' . $value );
|
333 |
+
MLACore::mla_debug_add( __LINE__ . ' MLACustomFieldSearchExample::mla_list_table_query_final_terms tokens = ' . var_export( $tokens, true ) );
|
334 |
+
$tokens = $tokens['meta_query'];
|
335 |
+
MLACore::mla_debug_add( __LINE__ . ' MLACustomFieldSearchExample::mla_list_table_query_final_terms meta_query = ' . var_export( $tokens, true ) );
|
336 |
+
|
337 |
+
/*
|
338 |
+
* Matching a meta_value to NULL requires a LEFT JOIN to a view and a special WHERE clause;
|
339 |
+
* MLA filters will handle this case.
|
340 |
+
*/
|
341 |
+
if ( isset( $tokens['key'] ) ) {
|
342 |
+
MLAQuery::$query_parameters['use_postmeta_view'] = true;
|
343 |
+
MLAQuery::$query_parameters['postmeta_key'] = $tokens['key'];
|
344 |
+
MLAQuery::$query_parameters['postmeta_value'] = NULL;
|
345 |
+
return $request;
|
346 |
+
}
|
347 |
+
|
348 |
+
// Process "normal" meta_query
|
349 |
+
$query = array( 'relation' => $tokens['relation'] );
|
350 |
+
$padded_values = array();
|
351 |
+
$patterns = array();
|
352 |
+
foreach ( $tokens as $key => $value ) {
|
353 |
+
// The key/value/compare elements are nested within the query array
|
354 |
+
if ( ! is_numeric( $key ) ) {
|
355 |
+
continue;
|
356 |
+
}
|
357 |
+
|
358 |
+
if ( !empty( $value['key'] ) && in_array( $value['key'], array( 'File Size', 'pixels', 'width', 'height' ) ) ) {
|
359 |
+
if ( '=' == $value['compare'] ) {
|
360 |
+
$value['value'] = str_pad( $value['value'], 15, ' ', STR_PAD_LEFT );
|
361 |
+
$padded_values[ trim( $value['value'] ) ] = $value['value'];
|
362 |
+
} else {
|
363 |
+
$value['value'] = '%' . $value['value'];
|
364 |
+
}
|
365 |
+
}
|
366 |
+
|
367 |
+
if ( 'LIKE' == $value['compare'] ) {
|
368 |
+
$patterns[] = $value['value'];
|
369 |
+
}
|
370 |
+
|
371 |
+
$query[] = $value;
|
372 |
+
}
|
373 |
+
|
374 |
+
if ( ! empty( $padded_values ) ) {
|
375 |
+
MLAQuery::$query_parameters['mla-metavalue'] = $padded_values;
|
376 |
+
}
|
377 |
+
|
378 |
+
if ( ! empty( $patterns ) ) {
|
379 |
+
MLAQuery::$query_parameters['patterns'] = $patterns;
|
380 |
+
}
|
381 |
+
|
382 |
+
// Combine with an existing "custom view" meta_query, if present
|
383 |
+
if ( isset( $request['meta_query'] ) ) {
|
384 |
+
$request['meta_query'] = array( 'relation' => 'AND', $request['meta_query'], $query );
|
385 |
+
} else {
|
386 |
+
$request['meta_query'] = $query;
|
387 |
+
}
|
388 |
+
|
389 |
+
MLACore::mla_debug_add( __LINE__ . ' mla_list_table_query_final_terms request = ' . var_export( $request, true ) );
|
390 |
+
return $request;
|
391 |
+
} // mla_list_table_query_final_terms
|
392 |
+
|
393 |
+
/**
|
394 |
+
* MLA Edit Media "Query Attachments" initial terms Filter
|
395 |
+
*
|
396 |
+
* Gives you an opportunity to change the terms of the
|
397 |
+
* Media Manager Modal Window "Query Attachments" query
|
398 |
+
* before they are pre-processed by the MLA handler.
|
399 |
+
*
|
400 |
+
* @since 1.03
|
401 |
+
*
|
402 |
+
* @param array WP_Query terms supported for "Query Attachments"
|
403 |
+
* @param array All terms passed in the request
|
404 |
+
*/
|
405 |
+
public static function mla_media_modal_query_initial_terms( $query, $raw_query ) {
|
406 |
+
/*
|
407 |
+
* Look for the custom field search prefix in the Search Media text box,
|
408 |
+
* after checking for the "debug" prefixes.
|
409 |
+
*/
|
410 |
+
if ( isset( $query['mla_search_value'] ) ) {
|
411 |
+
switch ( substr( $query['mla_search_value'], 0, 3 ) ) {
|
412 |
+
case '}|{':
|
413 |
+
self::$custom_field_parameters['debug'] = 'log'; // = 'console'; won't work for AJAX queries
|
414 |
+
$start = 3;
|
415 |
+
break;
|
416 |
+
case '{|}':
|
417 |
+
self::$custom_field_parameters['debug'] = 'log';
|
418 |
+
$start = 3;
|
419 |
+
break;
|
420 |
+
default:
|
421 |
+
$start = 0;
|
422 |
+
}
|
423 |
+
|
424 |
+
$prefix = self::$plugin_settings->get_plugin_option( 'prefix' );
|
425 |
+
if ( $prefix === substr( $query['mla_search_value'], $start, strlen( $prefix ) ) ) {
|
426 |
+
self::$custom_field_parameters['s'] = substr( $query['mla_search_value'], $start + strlen( $prefix ) );
|
427 |
+
unset( $query['mla_search_value'] );
|
428 |
+
//self::$custom_field_parameters['mla_search_connector'] = $query['mla_search_connector'];
|
429 |
+
unset( $query['mla_search_connector'] );
|
430 |
+
//self::$custom_field_parameters['mla_search_fields'] = $query['mla_search_fields'];
|
431 |
+
unset( $query['mla_search_fields'] );
|
432 |
+
} else {
|
433 |
+
self::$custom_field_parameters = array();
|
434 |
+
}
|
435 |
+
} // isset mla_search_value=custom:
|
436 |
+
|
437 |
+
return $query;
|
438 |
+
}
|
439 |
+
|
440 |
+
/**
|
441 |
+
* MLA Edit Media "Query Attachments" final terms Filter
|
442 |
+
*
|
443 |
+
* Gives you an opportunity to change the terms of the
|
444 |
+
* Media Manager Modal Window "Query Attachments" query
|
445 |
+
* after they are processed by the "Prepare List Table Query" handler.
|
446 |
+
*
|
447 |
+
* @since 1.03
|
448 |
+
*
|
449 |
+
* @param array WP_Query request prepared by "Prepare List Table Query"
|
450 |
+
*/
|
451 |
+
public static function mla_media_modal_query_final_terms( $request ) {
|
452 |
+
// The logic used in the Media/Assistant Search Media box will work here as well
|
453 |
+
return MLACustomFieldSearchExample::mla_list_table_query_final_terms( $request );
|
454 |
+
}
|
455 |
+
|
456 |
+
} // Class MLACustomFieldSearchExample
|
457 |
+
|
458 |
+
// Install the filters at an early opportunity
|
459 |
+
add_action('init', 'MLACustomFieldSearchExample::initialize');
|
460 |
+
?>
|
examples/plugins/mla-parent-custom-field-mapping/admin-settings-page.tpl
CHANGED
@@ -340,35 +340,36 @@ You can leave the default (checked) setting in place unless you are having a spe
|
|
340 |
</p>
|
341 |
<h3>Debugging and Troubleshooting</h3>
|
342 |
<p>
|
343 |
-
When you are creating a new rule testing it out on one or a few posts/pages and carefully inspecting the results can be a valuable exercise.
|
344 |
</p>
|
345 |
<p>
|
346 |
-
If a problem persists you can activate the debug logging, run a test and
|
347 |
</p>
|
348 |
<ol>
|
349 |
<li>Navigate to the Settings/Media Library Assistant Debug tab.</li>
|
350 |
-
<li>Scroll down to the
|
351 |
<li>Click the Save Changes button to record your new setting.</li>
|
352 |
-
<li>Optionally, scroll to the bottom of the screen and click
|
353 |
</ol>
|
354 |
<p>
|
355 |
-
Once that
|
356 |
</p>
|
357 |
<ol>
|
358 |
<li>Manually delete the Repeater Field content for one of your posts.</li>
|
359 |
<li>Go to the Media/Assistant admin submenu table and find one of the attachments for that post.</li>
|
360 |
-
<li>Click on the
|
361 |
<li>Click the box next to the ID/Parent column title to select all the attachments.</li>
|
362 |
-
<li>Select
|
363 |
-
<li>Click the
|
364 |
</ol>
|
365 |
<p>
|
366 |
-
When you
|
367 |
</p>
|
368 |
<ol>
|
369 |
-
<li>Enter
|
370 |
<li>Click the Save Changes button to record your new setting.</li>
|
371 |
-
<li>Scroll to the bottom and click
|
|
|
372 |
</ol>
|
373 |
<p>
|
374 |
There should be a lot of messages written to the log, so limit the amount of activity during the logging period. You should see messages in the log like these:
|
340 |
</p>
|
341 |
<h3>Debugging and Troubleshooting</h3>
|
342 |
<p>
|
343 |
+
When you are creating a new rule testing it out on one or a few posts/pages and carefully inspecting the results can be a valuable exercise. You may have to delete the field values, modify the rule and reapply it a few times to get the expected results.
|
344 |
</p>
|
345 |
<p>
|
346 |
+
If a problem persists you can activate the debug logging, run a test and inspect the log file for more information about what's going on. To activate MLA’s debug logging:
|
347 |
</p>
|
348 |
<ol>
|
349 |
<li>Navigate to the Settings/Media Library Assistant Debug tab.</li>
|
350 |
+
<li>Scroll down to the “MLA Reporting” text box and enter “0x8013”. This will turn on MLA debug logging for the example plugin, AJAX operations (such as WP/LR Sync) and the IPTC/EXIF metadata mapping rules.</li>
|
351 |
<li>Click the Save Changes button to record your new setting.</li>
|
352 |
+
<li>Optionally, scroll to the bottom of the screen and click “Reset” to clear the error log. You may not want to do this depending on how you manage your error log.</li>
|
353 |
</ol>
|
354 |
<p>
|
355 |
+
Once that’s done you can run a test. The debug log will be very detailed, so restricting the test as best you can will be very helpful. You can often update just one post and then collect the test results. One way to do that:
|
356 |
</p>
|
357 |
<ol>
|
358 |
<li>Manually delete the Repeater Field content for one of your posts.</li>
|
359 |
<li>Go to the Media/Assistant admin submenu table and find one of the attachments for that post.</li>
|
360 |
+
<li>Click on the “(Parent:xxxx)” link in the ID/Parent column to filter the display showing all the attachments for that one post.</li>
|
361 |
<li>Click the box next to the ID/Parent column title to select all the attachments.</li>
|
362 |
+
<li>Select “Edit” from the Bulk Actions dropdown and click “Apply”.</li>
|
363 |
+
<li>Click the “Map IPTC/EXIF metadata” button in the bottom-right corner of the Bulk Edit area.</li>
|
364 |
</ol>
|
365 |
<p>
|
366 |
+
When you’ve finished testing, go back to the Debug screen and:
|
367 |
</p>
|
368 |
<ol>
|
369 |
+
<li>Enter “0” in the MLA Reporting text box to turn debug logging off.</li>
|
370 |
<li>Click the Save Changes button to record your new setting.</li>
|
371 |
+
<li>Scroll to the bottom and click “Download” to get the log content in a text file.</li>
|
372 |
+
<li>Optionally, scroll to the bottom of the screen and click “Reset” to clear the error log.</li>
|
373 |
</ol>
|
374 |
<p>
|
375 |
There should be a lot of messages written to the log, so limit the amount of activity during the logging period. You should see messages in the log like these:
|
examples/plugins/mla-parent-search-example.php
CHANGED
@@ -94,11 +94,11 @@ class MLAParentSearchExample {
|
|
94 |
*/
|
95 |
if ( isset( $_REQUEST['s'] ) ) {
|
96 |
switch ( substr( $_REQUEST['s'], 0, 3 ) ) {
|
97 |
-
case '
|
98 |
self::$parent_search_parameters['debug'] = 'console';
|
99 |
$start = 3;
|
100 |
break;
|
101 |
-
case '
|
102 |
self::$parent_search_parameters['debug'] = 'log';
|
103 |
$start = 3;
|
104 |
break;
|
@@ -216,11 +216,11 @@ class MLAParentSearchExample {
|
|
216 |
*/
|
217 |
if ( isset( $query['mla_search_value'] ) ) {
|
218 |
switch ( substr( $query['mla_search_value'], 0, 3 ) ) {
|
219 |
-
case '
|
220 |
self::$parent_search_parameters['debug'] = 'console';
|
221 |
$start = 3;
|
222 |
break;
|
223 |
-
case '
|
224 |
self::$parent_search_parameters['debug'] = 'log';
|
225 |
$start = 3;
|
226 |
break;
|
94 |
*/
|
95 |
if ( isset( $_REQUEST['s'] ) ) {
|
96 |
switch ( substr( $_REQUEST['s'], 0, 3 ) ) {
|
97 |
+
case '}|{':
|
98 |
self::$parent_search_parameters['debug'] = 'console';
|
99 |
$start = 3;
|
100 |
break;
|
101 |
+
case '{|}':
|
102 |
self::$parent_search_parameters['debug'] = 'log';
|
103 |
$start = 3;
|
104 |
break;
|
216 |
*/
|
217 |
if ( isset( $query['mla_search_value'] ) ) {
|
218 |
switch ( substr( $query['mla_search_value'], 0, 3 ) ) {
|
219 |
+
case '}|{':
|
220 |
self::$parent_search_parameters['debug'] = 'console';
|
221 |
$start = 3;
|
222 |
break;
|
223 |
+
case '{|}':
|
224 |
self::$parent_search_parameters['debug'] = 'log';
|
225 |
$start = 3;
|
226 |
break;
|
examples/plugins/mla-postie-post-after-example.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Applies MLA mapping rules to child attachments after Postie creates a parent post from an email
|
4 |
+
*
|
5 |
+
* Created for support topic "Plugin ‘MLA Postie Post After Example’"
|
6 |
+
* opened on 12/7/2020 by "ernstwg":
|
7 |
+
* https://wordpress.org/support/topic/plugin-mla-simple-mapping-hooks-example/
|
8 |
+
*
|
9 |
+
* @package MLA Postie Post After Example
|
10 |
+
* @version 1.00
|
11 |
+
*/
|
12 |
+
|
13 |
+
/*
|
14 |
+
Plugin Name: MLA Postie Post After Example
|
15 |
+
Plugin URI: http://davidlingren.com/
|
16 |
+
Description: Applies MLA mapping rules to child attachments after Postie creates a parent post from an email
|
17 |
+
Author: David Lingren
|
18 |
+
Version: 1.00
|
19 |
+
Author URI: http://davidlingren.com/
|
20 |
+
|
21 |
+
Copyright 2020 David Lingren
|
22 |
+
|
23 |
+
This program is free software; you can redistribute it and/or modify
|
24 |
+
it under the terms of the GNU General Public License as published by
|
25 |
+
the Free Software Foundation; either version 2 of the License, or
|
26 |
+
(at your option) any later version.
|
27 |
+
|
28 |
+
This program is distributed in the hope that it will be useful,
|
29 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
30 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
31 |
+
GNU General Public License for more details.
|
32 |
+
|
33 |
+
You can get a copy of the GNU General Public License by writing to the
|
34 |
+
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
35 |
+
*/
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Class MLA Postie Post After Example hooks the Postie 'postie_post_after' action
|
39 |
+
*
|
40 |
+
* @package MLA Postie Post After Example
|
41 |
+
* @since 1.00
|
42 |
+
*/
|
43 |
+
class MLAPostiePostAfterExample {
|
44 |
+
/**
|
45 |
+
* Initialization function, similar to __construct()
|
46 |
+
*
|
47 |
+
* Installs filters and actions that handle the MLA hooks for uploading and mapping.
|
48 |
+
*
|
49 |
+
* @since 1.00
|
50 |
+
*
|
51 |
+
* @return void
|
52 |
+
*/
|
53 |
+
public static function initialize() {
|
54 |
+
// This plugin requires both MLA and Postie
|
55 |
+
if ( class_exists( 'MLACore', false ) && class_exists( 'Postie', false ) ) {
|
56 |
+
add_action( 'postie_post_after', 'MLAPostiePostAfterExample::postie_post_after', 10, 1 );
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* PostieMessage::save_post() action
|
62 |
+
*
|
63 |
+
* Signals end of Postie post insertion.
|
64 |
+
*
|
65 |
+
* @since 1.00
|
66 |
+
*
|
67 |
+
* @param array $details An array of slashed, sanitized, and processed attachment post data.
|
68 |
+
*/
|
69 |
+
public static function postie_post_after( $details ) {
|
70 |
+
global $wpdb;
|
71 |
+
|
72 |
+
// Build an array of SQL clauses to find Parent/Child relationships
|
73 |
+
$query = array();
|
74 |
+
$query_parameters = array();
|
75 |
+
|
76 |
+
$query[] = "SELECT p.ID FROM {$wpdb->posts} AS p";
|
77 |
+
|
78 |
+
// INNER JOIN removes posts with no attachments
|
79 |
+
$query[] = "INNER JOIN {$wpdb->posts} as p2";
|
80 |
+
$query[] = "ON (p.post_parent = p2.ID)";
|
81 |
+
|
82 |
+
$query[] = "WHERE p2.post_type = '" . $details['post_type'] . "'";
|
83 |
+
$query[] = "AND p2.post_status = '" . $details['post_status'] . "'";
|
84 |
+
|
85 |
+
$placeholders = array( '%d' );;
|
86 |
+
$query_parameters[] = $details['ID'];
|
87 |
+
$query[] = 'AND ( p.post_parent IN (' . join( ',', $placeholders ) . ') )';
|
88 |
+
|
89 |
+
$query[] = "AND p.post_type = 'attachment'";
|
90 |
+
$query[] = "AND p.post_status = 'inherit'";
|
91 |
+
|
92 |
+
$query = join(' ', $query);
|
93 |
+
$results = $wpdb->get_results( $wpdb->prepare( $query, $query_parameters ) );
|
94 |
+
|
95 |
+
foreach ( $results as $result ) {
|
96 |
+
$item_id = (integer) $result->ID;
|
97 |
+
|
98 |
+
do_action( 'mla_begin_mapping', 'single_custom', $item_id );
|
99 |
+
$updates = MLAOptions::mla_evaluate_custom_field_mapping( $item_id, 'single_attachment_mapping' );
|
100 |
+
do_action( 'mla_end_mapping' );
|
101 |
+
|
102 |
+
if ( !empty( $updates ) ) {
|
103 |
+
$item_content = MLAData::mla_update_single_item( $item_id, $updates );
|
104 |
+
}
|
105 |
+
|
106 |
+
$item = get_post( $item_id );
|
107 |
+
do_action( 'mla_begin_mapping', 'single_iptc_exif', $item_id );
|
108 |
+
$updates = MLAOptions::mla_evaluate_iptc_exif_mapping( $item, 'iptc_exif_mapping' );
|
109 |
+
do_action( 'mla_end_mapping' );
|
110 |
+
|
111 |
+
if ( !empty( $updates ) ) {
|
112 |
+
$item_content = MLAData::mla_update_single_item( $item_id, $updates );
|
113 |
+
}
|
114 |
+
} // foreach child
|
115 |
+
} // postie_post_after
|
116 |
+
} //MLAPostiePostAfterExample
|
117 |
+
|
118 |
+
// Install the filters at an early opportunity
|
119 |
+
add_action('init', 'MLAPostiePostAfterExample::initialize');
|
120 |
+
?>
|
examples/plugins/smart-media-categories/admin/includes/class-smc-automatic-support.php
CHANGED
@@ -38,11 +38,23 @@ class SMC_Automatic_Support {
|
|
38 |
* @return void
|
39 |
*/
|
40 |
public static function initialize() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
//error_log( __LINE__ . ' SMC_Automatic_Support::initialize() $_REQUEST = ' . var_export( $_REQUEST, true), 0 );
|
42 |
|
43 |
add_filter( 'wp_handle_upload_prefilter', 'SMC_Automatic_Support::filter_wp_handle_upload_prefilter', 0x7FFFFFFE, 1 );
|
44 |
add_filter( 'wp_handle_upload', 'SMC_Automatic_Support::filter_wp_handle_upload_filter', 0x7FFFFFFE, 2 );
|
45 |
|
|
|
|
|
|
|
46 |
add_action( 'pre_post_update', 'SMC_Automatic_Support::action_pre_post_update', 0x7FFFFFFE, 2 );
|
47 |
add_action( 'edit_attachment', 'SMC_Automatic_Support::action_edit_attachment', 0x7FFFFFFE, 1 );
|
48 |
add_action( 'add_attachment', 'SMC_Automatic_Support::action_add_attachment', 0x7FFFFFFE, 1 );
|
@@ -102,6 +114,54 @@ class SMC_Automatic_Support {
|
|
102 |
return $upload;
|
103 |
} // filter_wp_handle_upload_filter
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
/**
|
106 |
* Fires immediately before an existing post/attachment is updated in the database
|
107 |
*
|
@@ -122,6 +182,11 @@ class SMC_Automatic_Support {
|
|
122 |
SMC_Automatic_support::rule_update_post_terms( $post_id, NULL, NULL, NULL, 'before' );
|
123 |
}
|
124 |
|
|
|
|
|
|
|
|
|
|
|
125 |
if ( (boolean) SMC_Settings_Support::get_option( 'attach_orphan' ) ) {
|
126 |
SMC_Automatic_support::rule_attach_orphan( $data['post_parent'], $post_id, true );
|
127 |
}
|
@@ -170,7 +235,7 @@ class SMC_Automatic_Support {
|
|
170 |
//error_log( __LINE__ . ' SMC_Automatic_Support::action_add_attachment $post_id = ' . var_export( $post_id, true), 0 );
|
171 |
//error_log( __LINE__ . ' SMC_Automatic_Support::action_add_attachment $post = ' . var_export( get_post( $post_id ), true), 0 );
|
172 |
|
173 |
-
// Flush the cache of parent/child term assignments
|
174 |
SMC_Sync_Support::get_posts_per_view( NULL, true );
|
175 |
|
176 |
if ( (boolean) SMC_Settings_Support::get_option( 'upload_item' ) ) {
|
@@ -391,12 +456,9 @@ class SMC_Automatic_Support {
|
|
391 |
* @param array $old_tt_ids Old array of term taxonomy IDs.
|
392 |
*/
|
393 |
public static function action_set_object_terms( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) {
|
394 |
-
//error_log( __LINE__ .
|
395 |
-
//error_log( __LINE__ .
|
396 |
-
//error_log( __LINE__ .
|
397 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::action_set_object_terms $taxonomy = ' . var_export( $taxonomy, true), 0 );
|
398 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::action_set_object_terms $append = ' . var_export( $append, true), 0 );
|
399 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::action_set_object_terms $old_tt_ids = ' . var_export( $old_tt_ids, true), 0 );
|
400 |
|
401 |
if ( (boolean) SMC_Settings_Support::get_option( 'update_post_terms' ) ) {
|
402 |
SMC_Automatic_support::rule_update_post_terms( $object_id, $taxonomy, $tt_ids, $old_tt_ids, 'during' );
|
@@ -674,9 +736,9 @@ class SMC_Automatic_Support {
|
|
674 |
*
|
675 |
* @since 1.0.6
|
676 |
*
|
677 |
-
* @param integer Post ID.
|
|
|
678 |
* @param array An array of new term taxonomy IDs.
|
679 |
-
* @param string Taxonomy slug.
|
680 |
* @param array Old array of term taxonomy IDs.
|
681 |
* @param string Update phase; 'before', 'during', 'after'.
|
682 |
*
|
@@ -686,35 +748,34 @@ class SMC_Automatic_Support {
|
|
686 |
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms( {$post_id}, {$taxonomy}, {$phase} ) \$tt_ids = " . var_export( $tt_ids, true), 0 );
|
687 |
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms( {$post_id}, {$taxonomy}, {$phase} ) \$old_tt_ids = " . var_export( $old_tt_ids, true), 0 );
|
688 |
static $update_post = NULL, $update_type = NULL, $active_taxonomies = NULL, $terms_changed = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
689 |
|
690 |
switch ( $phase ) {
|
691 |
case 'before':
|
692 |
$terms_changed = false;
|
693 |
-
|
694 |
-
// Make sure the object is a supported Post Type
|
695 |
-
$post = get_post( $post_id );
|
696 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms $post = ' . var_export( $post, true), 0 );
|
697 |
-
if ( !SMC_Settings_Support::is_smc_post_type( $post->post_type ) ) {
|
698 |
-
$update_post = NULL;
|
699 |
-
$update_type = NULL;
|
700 |
-
return;
|
701 |
-
}
|
702 |
-
|
703 |
$update_post = $post_id;
|
704 |
-
$update_type = $post->post_type;
|
705 |
-
if ( is_null( $active_taxonomies ) ) {
|
706 |
-
$active_taxonomies = SMC_Sync_Support::get_active_taxonomies( $update_type );
|
707 |
-
}
|
708 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms $active_taxonomies = ' . var_export( $active_taxonomies, true), 0 );
|
709 |
break;
|
710 |
case 'during':
|
711 |
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms during $update_post = ' . var_export( $update_post, true), 0 );
|
712 |
-
|
713 |
-
if ( is_null( $update_post ) || ( $update_post != $post_id ) ) {
|
714 |
-
return;
|
715 |
-
}
|
716 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms during $taxonomy = ' . var_export( $taxonomy, true), 0 );
|
717 |
-
|
718 |
// Make sure it's an active taxonomy
|
719 |
if ( ! array_key_exists( $taxonomy, $active_taxonomies ) ) {
|
720 |
return;
|
@@ -723,22 +784,50 @@ class SMC_Automatic_Support {
|
|
723 |
// tt_ids are strings on input, old_tt_ids are integers
|
724 |
$tt_ids = array_map( 'absint', $tt_ids );
|
725 |
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms mapped $tt_ids = ' . var_export( $tt_ids, true), 0 );
|
726 |
-
|
727 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
728 |
}
|
729 |
|
|
|
730 |
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms ({$taxonomy}) \$terms_changed = " . var_export( $terms_changed, true), 0 );
|
731 |
break;
|
732 |
case 'after':
|
733 |
// Make sure terms have changed and it's the right Post
|
734 |
-
if ( $terms_changed && $update_post
|
|
|
735 |
$all_assignments = SMC_Sync_Support::get_posts_per_view( array( 'post_type' => $update_type, 'smc_status' => 'unsync', 'post_parents' => array( $post_id ), 'fields' => 'all' ) );
|
736 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms $all_assignments = ' . var_export( $all_assignments, true ), 0 );
|
737 |
$results = SMC_Sync_Support::sync_all( $all_assignments );
|
738 |
-
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms $results = ' . var_export( $results, true ), 0 );
|
739 |
}
|
740 |
|
741 |
$update_post = NULL;
|
|
|
|
|
742 |
$terms_changed = false;
|
743 |
break;
|
744 |
} // phase
|
38 |
* @return void
|
39 |
*/
|
40 |
public static function initialize() {
|
41 |
+
// Look for Postie chron job
|
42 |
+
if ( isset( $_REQUEST['doing_wp_cron'] ) && class_exists( 'Postie', false ) ) {
|
43 |
+
if ( false === (boolean) SMC_Settings_Support::get_option( 'postie_sync' ) ) {
|
44 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::initialize() no Postie Support', 0 );
|
45 |
+
return;
|
46 |
+
}
|
47 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::initialize() Postie Support in Cron Job', 0 );
|
48 |
+
}
|
49 |
+
|
50 |
//error_log( __LINE__ . ' SMC_Automatic_Support::initialize() $_REQUEST = ' . var_export( $_REQUEST, true), 0 );
|
51 |
|
52 |
add_filter( 'wp_handle_upload_prefilter', 'SMC_Automatic_Support::filter_wp_handle_upload_prefilter', 0x7FFFFFFE, 1 );
|
53 |
add_filter( 'wp_handle_upload', 'SMC_Automatic_Support::filter_wp_handle_upload_filter', 0x7FFFFFFE, 2 );
|
54 |
|
55 |
+
add_filter( 'wp_insert_post_data', 'SMC_Automatic_Support::filter_wp_insert_post_data', 0x7FFFFFFE, 3 );
|
56 |
+
add_action( 'wp_insert_post', 'SMC_Automatic_Support::action_wp_insert_post', 0x7FFFFFFE, 3 );
|
57 |
+
|
58 |
add_action( 'pre_post_update', 'SMC_Automatic_Support::action_pre_post_update', 0x7FFFFFFE, 2 );
|
59 |
add_action( 'edit_attachment', 'SMC_Automatic_Support::action_edit_attachment', 0x7FFFFFFE, 1 );
|
60 |
add_action( 'add_attachment', 'SMC_Automatic_Support::action_add_attachment', 0x7FFFFFFE, 1 );
|
114 |
return $upload;
|
115 |
} // filter_wp_handle_upload_filter
|
116 |
|
117 |
+
/**
|
118 |
+
* Filters slashed post data just before it is inserted into the database.
|
119 |
+
*
|
120 |
+
* Called from /wp-includes/post.php, function wp_insert_post
|
121 |
+
*
|
122 |
+
* @since 1.1.6
|
123 |
+
*
|
124 |
+
* @param array $data An array of slashed, sanitized, and processed post data.
|
125 |
+
* @param array $postarr An array of sanitized (and slashed) but otherwise unmodified post data.
|
126 |
+
* @param array $unsanitized_postarr An array of slashed yet *unsanitized* and unprocessed post data as
|
127 |
+
* originally passed to wp_insert_post().
|
128 |
+
*/
|
129 |
+
public static function filter_wp_insert_post_data( $data, $postarr, $unsanitized_postarr ) {
|
130 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::filter_wp_insert_post_data $data = ' . var_export( $data, true), 0 );
|
131 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::filter_wp_insert_post_data $postarr = ' . var_export( $postarr, true), 0 );
|
132 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::filter_wp_insert_post_data $unsanitized_postarr = ' . var_export( $unsanitized_postarr, true), 0 );
|
133 |
+
|
134 |
+
// Handle the case of setting terms during original post insert
|
135 |
+
if ( empty( $postarr['ID'] ) ) {
|
136 |
+
if ( (boolean) SMC_Settings_Support::get_option( 'update_post_terms' ) ) {
|
137 |
+
$post_type = isset( $postarr['post_type'] ) ? $postarr['post_type'] : 'post';
|
138 |
+
SMC_Automatic_support::rule_update_post_terms( 0, $post_type, NULL, NULL, 'before' );
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
return $data;
|
143 |
+
} // filter_wp_insert_post_data
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Fires once a post has been saved.
|
147 |
+
*
|
148 |
+
* Called from /wp-includes/post.php, function wp_insert_post
|
149 |
+
*
|
150 |
+
* @since 1.1.6
|
151 |
+
*
|
152 |
+
* @param int $post_ID Post ID.
|
153 |
+
* @param WP_Post $post Post object.
|
154 |
+
* @param bool $update Whether this is an existing post being updated.
|
155 |
+
*/
|
156 |
+
public static function action_wp_insert_post( $post_ID, $post, $update ) {
|
157 |
+
//error_log( __LINE__ . " SMC_Automatic_Support::filter_wp_insert_post( {$post_ID}, {$update} ) \$post = " . var_export( $post, true), 0 );
|
158 |
+
|
159 |
+
// Handle the case of setting terms during original post insert
|
160 |
+
if ( (boolean) SMC_Settings_Support::get_option( 'update_post_terms' ) ) {
|
161 |
+
SMC_Automatic_support::rule_update_post_terms( $post_ID, NULL, NULL, NULL, 'after' );
|
162 |
+
}
|
163 |
+
} // action_wp_insert_post
|
164 |
+
|
165 |
/**
|
166 |
* Fires immediately before an existing post/attachment is updated in the database
|
167 |
*
|
182 |
SMC_Automatic_support::rule_update_post_terms( $post_id, NULL, NULL, NULL, 'before' );
|
183 |
}
|
184 |
|
185 |
+
// This action can be called for any post_type, e.g., post or page in addition to attachment
|
186 |
+
if ( 'attachment' !== $data['post_type'] ) {
|
187 |
+
return;
|
188 |
+
}
|
189 |
+
|
190 |
if ( (boolean) SMC_Settings_Support::get_option( 'attach_orphan' ) ) {
|
191 |
SMC_Automatic_support::rule_attach_orphan( $data['post_parent'], $post_id, true );
|
192 |
}
|
235 |
//error_log( __LINE__ . ' SMC_Automatic_Support::action_add_attachment $post_id = ' . var_export( $post_id, true), 0 );
|
236 |
//error_log( __LINE__ . ' SMC_Automatic_Support::action_add_attachment $post = ' . var_export( get_post( $post_id ), true), 0 );
|
237 |
|
238 |
+
// Flush the cache of parent/child term assignments to force resynch
|
239 |
SMC_Sync_Support::get_posts_per_view( NULL, true );
|
240 |
|
241 |
if ( (boolean) SMC_Settings_Support::get_option( 'upload_item' ) ) {
|
456 |
* @param array $old_tt_ids Old array of term taxonomy IDs.
|
457 |
*/
|
458 |
public static function action_set_object_terms( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) {
|
459 |
+
//error_log( __LINE__ . " SMC_Automatic_Support::action_set_object_terms( {$object_id}, {$taxonomy}, {$append} ) \$terms = " . var_export( $terms, true), 0 );
|
460 |
+
//error_log( __LINE__ . " SMC_Automatic_Support::action_set_object_terms( {$object_id}, {$taxonomy}, {$append} ) \$tt_ids = " . var_export( $tt_ids, true), 0 );
|
461 |
+
//error_log( __LINE__ . " SMC_Automatic_Support::action_set_object_terms( {$object_id}, {$taxonomy}, {$append} ) \$old_tt_ids = " . var_export( $old_tt_ids, true), 0 );
|
|
|
|
|
|
|
462 |
|
463 |
if ( (boolean) SMC_Settings_Support::get_option( 'update_post_terms' ) ) {
|
464 |
SMC_Automatic_support::rule_update_post_terms( $object_id, $taxonomy, $tt_ids, $old_tt_ids, 'during' );
|
736 |
*
|
737 |
* @since 1.0.6
|
738 |
*
|
739 |
+
* @param integer Post ID or zero (0) in 'before' phase when inserting a new post.
|
740 |
+
* @param string Taxonomy slug or post_type in 'before' phase when inserting a new post.
|
741 |
* @param array An array of new term taxonomy IDs.
|
|
|
742 |
* @param array Old array of term taxonomy IDs.
|
743 |
* @param string Update phase; 'before', 'during', 'after'.
|
744 |
*
|
748 |
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms( {$post_id}, {$taxonomy}, {$phase} ) \$tt_ids = " . var_export( $tt_ids, true), 0 );
|
749 |
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms( {$post_id}, {$taxonomy}, {$phase} ) \$old_tt_ids = " . var_export( $old_tt_ids, true), 0 );
|
750 |
static $update_post = NULL, $update_type = NULL, $active_taxonomies = NULL, $terms_changed = false;
|
751 |
+
|
752 |
+
// Make sure the object is a supported Post Type
|
753 |
+
if ( 0 === $post_id ) {
|
754 |
+
// Inserting a new post
|
755 |
+
$update_type = $taxonomy;
|
756 |
+
} else {
|
757 |
+
$post = get_post( $post_id );
|
758 |
+
$update_type = $post->post_type;
|
759 |
+
}
|
760 |
+
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms( {$post_id}, {$update_type} )", 0 );
|
761 |
+
|
762 |
+
if ( is_null( $active_taxonomies ) ) {
|
763 |
+
$active_taxonomies = SMC_Sync_Support::get_active_taxonomies( $update_type );
|
764 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms $active_taxonomies = ' . var_export( $active_taxonomies, true), 0 );
|
765 |
+
}
|
766 |
+
|
767 |
+
if ( !SMC_Settings_Support::is_smc_post_type( $update_type ) ) {
|
768 |
+
return;
|
769 |
+
}
|
770 |
|
771 |
switch ( $phase ) {
|
772 |
case 'before':
|
773 |
$terms_changed = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
774 |
$update_post = $post_id;
|
|
|
|
|
|
|
|
|
|
|
775 |
break;
|
776 |
case 'during':
|
777 |
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms during $update_post = ' . var_export( $update_post, true), 0 );
|
778 |
+
|
|
|
|
|
|
|
|
|
|
|
779 |
// Make sure it's an active taxonomy
|
780 |
if ( ! array_key_exists( $taxonomy, $active_taxonomies ) ) {
|
781 |
return;
|
784 |
// tt_ids are strings on input, old_tt_ids are integers
|
785 |
$tt_ids = array_map( 'absint', $tt_ids );
|
786 |
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms mapped $tt_ids = ' . var_export( $tt_ids, true), 0 );
|
787 |
+
$current_terms_changed = ( $tt_ids != $old_tt_ids );
|
788 |
+
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms ({$taxonomy}) \$current_terms_changed = " . var_export( $current_terms_changed, true), 0 );
|
789 |
+
|
790 |
+
// Check for stand-alone terms update, i.e., not part of an insert/update post event
|
791 |
+
if ( is_null( $update_post ) ) {
|
792 |
+
// If terms have changed go ahead and sync
|
793 |
+
if ( $current_terms_changed ) {
|
794 |
+
SMC_Sync_Support::get_posts_per_view( NULL, true );
|
795 |
+
$all_assignments = SMC_Sync_Support::get_posts_per_view( array( 'post_type' => $update_type, 'smc_status' => 'unsync', 'post_parents' => array( $post_id ), 'fields' => 'all' ) );
|
796 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms standalone $all_assignments = ' . var_export( $all_assignments, true ), 0 );
|
797 |
+
$results = SMC_Sync_Support::sync_all( $all_assignments );
|
798 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms standalone $results = ' . var_export( $results, true ), 0 );
|
799 |
+
}
|
800 |
+
|
801 |
+
return;
|
802 |
+
} // is_null
|
803 |
+
|
804 |
+
// Inserting a new post?
|
805 |
+
if ( 0 === $update_post ) {
|
806 |
+
$update_post = $post_id;
|
807 |
+
}
|
808 |
+
|
809 |
+
// Make sure it's the right Post
|
810 |
+
if ( $update_post !== $post_id ) {
|
811 |
+
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms( {$post_id}, {$update_post} ) wrong post", 0 );
|
812 |
+
return;
|
813 |
}
|
814 |
|
815 |
+
$terms_changed |= $current_terms_changed;
|
816 |
//error_log( __LINE__ . " SMC_Automatic_Support::rule_update_post_terms ({$taxonomy}) \$terms_changed = " . var_export( $terms_changed, true), 0 );
|
817 |
break;
|
818 |
case 'after':
|
819 |
// Make sure terms have changed and it's the right Post
|
820 |
+
if ( $terms_changed && $update_post === $post_id ) {
|
821 |
+
SMC_Sync_Support::get_posts_per_view( NULL, true );
|
822 |
$all_assignments = SMC_Sync_Support::get_posts_per_view( array( 'post_type' => $update_type, 'smc_status' => 'unsync', 'post_parents' => array( $post_id ), 'fields' => 'all' ) );
|
823 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms after $all_assignments = ' . var_export( $all_assignments, true ), 0 );
|
824 |
$results = SMC_Sync_Support::sync_all( $all_assignments );
|
825 |
+
//error_log( __LINE__ . ' SMC_Automatic_Support::rule_update_post_terms after $results = ' . var_export( $results, true ), 0 );
|
826 |
}
|
827 |
|
828 |
$update_post = NULL;
|
829 |
+
$update_type = NULL;
|
830 |
+
$active_taxonomies = NULL;
|
831 |
$terms_changed = false;
|
832 |
break;
|
833 |
} // phase
|
examples/plugins/smart-media-categories/admin/includes/class-smc-settings-support.php
CHANGED
@@ -127,6 +127,20 @@ class SMC_Settings_Support {
|
|
127 |
'title' => __( 'Reattach Item', 'smart-media-categories' ),
|
128 |
'description' => __( "When an items new parent is a <strong>Sync Post Type</strong>, it will inherit the parent's terms.", 'smart-media-categories' ),
|
129 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
),
|
131 |
'smc_manual_options' => array(
|
132 |
),
|
127 |
'title' => __( 'Reattach Item', 'smart-media-categories' ),
|
128 |
'description' => __( "When an items new parent is a <strong>Sync Post Type</strong>, it will inherit the parent's terms.", 'smart-media-categories' ),
|
129 |
),
|
130 |
+
'exclude_default' => array(
|
131 |
+
'type' => 'checkbox',
|
132 |
+
'default' => '0',
|
133 |
+
'id' => 'smc_automatic_exclude_default',
|
134 |
+
'title' => __( 'Exclude Post Default', 'smart-media-categories' ),
|
135 |
+
'description' => __( "Exclude the Settings/Wriing 'Default Post Category' term from Attachments.", 'smart-media-categories' ),
|
136 |
+
),
|
137 |
+
'postie_sync' => array(
|
138 |
+
'type' => 'checkbox',
|
139 |
+
'default' => '1',
|
140 |
+
'id' => 'smc_automatic_postie_sync',
|
141 |
+
'title' => __( 'Sync Postie Emails', 'smart-media-categories' ),
|
142 |
+
'description' => __( "Apply syncronization options to posts created by Postie email processing.", 'smart-media-categories' ),
|
143 |
+
),
|
144 |
),
|
145 |
'smc_manual_options' => array(
|
146 |
),
|
examples/plugins/smart-media-categories/admin/includes/class-smc-sync-support.php
CHANGED
@@ -284,10 +284,36 @@ class SMC_Sync_Support {
|
|
284 |
return array( 'sync' => 0, 'unsync' => 0 );
|
285 |
}
|
286 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
// Compute sync status
|
288 |
foreach ( $assignments as $parent_id => $assignment ) {
|
289 |
-
//error_log( __LINE__ ." SMC_Sync_Support::get_posts_per_view (parent {$parent_id}) assignment = " . var_export( $assignment, true ), 0 );
|
290 |
$parent_terms = $assignment['ttids'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
unset( $assignment['ttids'] );
|
292 |
unset( $assignment['terms'] );
|
293 |
$assignments[ $parent_id ]['smc_sync'] = true;
|
@@ -295,8 +321,8 @@ class SMC_Sync_Support {
|
|
295 |
$smc_sync = $parent_terms == $child_terms;
|
296 |
$assignments[ $parent_id ][ $child_id ]['smc_sync'] = $smc_sync;
|
297 |
$assignments[ $parent_id ]['smc_sync'] &= $smc_sync;
|
298 |
-
}
|
299 |
-
}
|
300 |
//error_log( __LINE__ . ' SMC_Sync_Support::get_posts_per_view final $assignments = ' . var_export( $assignments, true ), 0 );
|
301 |
|
302 |
switch ( $smc_status ) {
|
@@ -350,7 +376,8 @@ class SMC_Sync_Support {
|
|
350 |
* @param integer ID of the parent post
|
351 |
* @param array IDs of children
|
352 |
*
|
353 |
-
* @return array ( [object_id] => array( [taxonomy] =>
|
|
|
354 |
*/
|
355 |
public static function get_terms( $parent_id, $children ) {
|
356 |
global $wpdb;
|
@@ -389,6 +416,21 @@ class SMC_Sync_Support {
|
|
389 |
//error_log( __LINE__ . ' SMC_Sync_Support::get_terms $taxonomies = ' . var_export( $taxonomies, true ), 0 );
|
390 |
//error_log( __LINE__ . ' SMC_Sync_Support::get_terms $results = ' . var_export( $results, true ), 0 );
|
391 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
// Add synchronization state information
|
393 |
foreach ( $taxonomies as $taxonomy ) {
|
394 |
if ( isset( $results[ $parent_id ][ $taxonomy ] ) ) {
|
@@ -397,13 +439,12 @@ class SMC_Sync_Support {
|
|
397 |
$parent_terms = $results[ $parent_id ][ $taxonomy ] = array();
|
398 |
}
|
399 |
//error_log( __LINE__ ." SMC_Sync_Support::get_terms ({$taxonomy}) \$parent_terms = " . var_export( $parent_terms, true ), 0 );
|
400 |
-
|
401 |
foreach( $children as $child ) {
|
402 |
if ( ! isset( $results[ $child ][ $taxonomy ] ) ) {
|
403 |
$results[ $child ][ $taxonomy ] = array();
|
404 |
}
|
405 |
|
406 |
-
$results[ $child ][ $taxonomy ]['smc_sync'] = ( $parent_terms
|
407 |
|
408 |
// All taxonomies must be synched for the overall child to be synched
|
409 |
if ( isset( $results[ $child ]['smc_sync'] ) ) {
|
@@ -440,15 +481,36 @@ class SMC_Sync_Support {
|
|
440 |
$tax_action[ $tax_name ] = 'sync';
|
441 |
$initial_tax_input[ $tax_name ] = array();
|
442 |
}
|
443 |
-
//error_log( __LINE__ . ' SMC_Sync_Support::sync_all $active_taxonomies = ' . var_export( $active_taxonomies, true ), 0 );
|
444 |
//error_log( __LINE__ . ' SMC_Sync_Support::sync_all $tax_action = ' . var_export( $tax_action, true ), 0 );
|
445 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
446 |
foreach( $assignments as $parent_id => $assignment ) {
|
447 |
$taxonomy_terms = $assignment[ 'terms' ];
|
448 |
unset( $assignment['terms'] );
|
449 |
unset( $assignment['ttids'] );
|
450 |
unset( $assignment['smc_sync'] );
|
451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
$tax_input = $initial_tax_input;
|
453 |
foreach( $taxonomy_terms as $taxonomy => $terms ) {
|
454 |
foreach( $terms as $ttid => $term ) {
|
@@ -560,13 +622,12 @@ class SMC_Sync_Support {
|
|
560 |
continue;
|
561 |
}
|
562 |
|
563 |
-
$taxonomy_obj = get_taxonomy( $taxonomy );
|
564 |
-
//error_log( __LINE__ ." SMC_Sync_Support::sync_terms \$taxonomy_obj = " . var_export( $taxonomy_obj, true ), 0 );
|
565 |
-
|
566 |
// Check if logged-in user can assign terms
|
567 |
$current_user = wp_get_current_user();
|
568 |
if ( $current_user->ID ) {
|
|
|
569 |
if ( ! current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
|
|
|
570 |
continue;
|
571 |
}
|
572 |
}
|
@@ -595,7 +656,9 @@ class SMC_Sync_Support {
|
|
595 |
sort( $terms_before );
|
596 |
}
|
597 |
|
598 |
-
|
|
|
|
|
599 |
sort( $terms_after );
|
600 |
if ( $terms_after != $terms_before ) {
|
601 |
$parent_changed = true;
|
284 |
return array( 'sync' => 0, 'unsync' => 0 );
|
285 |
}
|
286 |
|
287 |
+
// Check for Default Post Category exclusion
|
288 |
+
$default_tt_id = 0;
|
289 |
+
if ( (boolean) SMC_Settings_Support::get_option( 'exclude_default' ) ) {
|
290 |
+
// Get the actual TTID, just to be safe
|
291 |
+
$default_term = get_term( (integer) get_option( 'default_category' ), 'category' );
|
292 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_posts_per_view ID term = " . var_export( $default_term, true ), 0 );
|
293 |
+
if ( $default_term instanceof WP_Term ) {
|
294 |
+
$default_tt_id = $default_term->term_taxonomy_id;
|
295 |
+
}
|
296 |
+
} // exclude default
|
297 |
+
|
298 |
// Compute sync status
|
299 |
foreach ( $assignments as $parent_id => $assignment ) {
|
300 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_posts_per_view {$default_tt_id} (parent {$parent_id}) assignment = " . var_export( $assignment, true ), 0 );
|
301 |
$parent_terms = $assignment['ttids'];
|
302 |
+
|
303 |
+
// Check for Default Post Category exclusion
|
304 |
+
if ( $default_tt_id ) {
|
305 |
+
$parent = get_post( $parent_id );
|
306 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_posts_per_view {$default_tt_id} parent = " . var_export( $parent, true ), 0 );
|
307 |
+
if ( 'post' === $parent->post_type && 'auto-draft' !== $parent->post_status ) {
|
308 |
+
foreach ( $parent_terms as $index => $ttid ) {
|
309 |
+
if ( $default_tt_id === $ttid ) {
|
310 |
+
unset( $parent_terms[ $index ] );
|
311 |
+
}
|
312 |
+
} // foreach term
|
313 |
+
} // type === post
|
314 |
+
} // exclude category
|
315 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_posts_per_view revised \$parent_terms = " . var_export( $parent_terms, true ), 0 );
|
316 |
+
|
317 |
unset( $assignment['ttids'] );
|
318 |
unset( $assignment['terms'] );
|
319 |
$assignments[ $parent_id ]['smc_sync'] = true;
|
321 |
$smc_sync = $parent_terms == $child_terms;
|
322 |
$assignments[ $parent_id ][ $child_id ]['smc_sync'] = $smc_sync;
|
323 |
$assignments[ $parent_id ]['smc_sync'] &= $smc_sync;
|
324 |
+
} // foreach child
|
325 |
+
} // foreach parent assignment
|
326 |
//error_log( __LINE__ . ' SMC_Sync_Support::get_posts_per_view final $assignments = ' . var_export( $assignments, true ), 0 );
|
327 |
|
328 |
switch ( $smc_status ) {
|
376 |
* @param integer ID of the parent post
|
377 |
* @param array IDs of children
|
378 |
*
|
379 |
+
* @return array ( [object_id] => array( [taxonomy] =>
|
380 |
+
* array( [term_taxonomy_id] => array( 'id' => term_id, 'slug' => term_slug )... 'smc_sync' => true/false )... 'smc_sync' => true/false )
|
381 |
*/
|
382 |
public static function get_terms( $parent_id, $children ) {
|
383 |
global $wpdb;
|
416 |
//error_log( __LINE__ . ' SMC_Sync_Support::get_terms $taxonomies = ' . var_export( $taxonomies, true ), 0 );
|
417 |
//error_log( __LINE__ . ' SMC_Sync_Support::get_terms $results = ' . var_export( $results, true ), 0 );
|
418 |
|
419 |
+
// Check for Default Post Category exclusion
|
420 |
+
if ( ( ( boolean) SMC_Settings_Support::get_option( 'exclude_default' ) ) && ( 'category' === $term->taxonomy ) ) {
|
421 |
+
if ( 'post' === $parent->post_type && 'auto-draft' !== $parent->post_status ) {
|
422 |
+
$default_term_id = (integer) get_option( 'default_category' );
|
423 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_terms ({$term->taxonomy}) \$default_term_id = " . var_export( $default_term_id, true ), 0 );
|
424 |
+
foreach ( $results[ $parent_id ]['category'] as $index => $term ) {
|
425 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_terms ( category, {$index} ) \$term = " . var_export( $term, true ), 0 );
|
426 |
+
if ( $default_term_id === $index ) {
|
427 |
+
unset( $results[ $parent_id ]['category'][ $index ] );
|
428 |
+
}
|
429 |
+
}
|
430 |
+
} // type === post
|
431 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_terms ( category ) revised \$results = " . var_export( $results, true ), 0 );
|
432 |
+
} // exclude category
|
433 |
+
|
434 |
// Add synchronization state information
|
435 |
foreach ( $taxonomies as $taxonomy ) {
|
436 |
if ( isset( $results[ $parent_id ][ $taxonomy ] ) ) {
|
439 |
$parent_terms = $results[ $parent_id ][ $taxonomy ] = array();
|
440 |
}
|
441 |
//error_log( __LINE__ ." SMC_Sync_Support::get_terms ({$taxonomy}) \$parent_terms = " . var_export( $parent_terms, true ), 0 );
|
|
|
442 |
foreach( $children as $child ) {
|
443 |
if ( ! isset( $results[ $child ][ $taxonomy ] ) ) {
|
444 |
$results[ $child ][ $taxonomy ] = array();
|
445 |
}
|
446 |
|
447 |
+
$results[ $child ][ $taxonomy ]['smc_sync'] = ( $parent_terms === $results[ $child ][ $taxonomy ] );
|
448 |
|
449 |
// All taxonomies must be synched for the overall child to be synched
|
450 |
if ( isset( $results[ $child ]['smc_sync'] ) ) {
|
481 |
$tax_action[ $tax_name ] = 'sync';
|
482 |
$initial_tax_input[ $tax_name ] = array();
|
483 |
}
|
484 |
+
//error_log( __LINE__ . ' SMC_Sync_Support::sync_all $active_taxonomies = ' . var_export( array_keys( $active_taxonomies ), true ), 0 );
|
485 |
//error_log( __LINE__ . ' SMC_Sync_Support::sync_all $tax_action = ' . var_export( $tax_action, true ), 0 );
|
486 |
|
487 |
+
// Check for Default Post Category exclusion
|
488 |
+
$default_term_id = 0;
|
489 |
+
if ( (boolean) SMC_Settings_Support::get_option( 'exclude_default' ) ) {
|
490 |
+
$default_term_id = (integer) get_option( 'default_category' );
|
491 |
+
//error_log( __LINE__ ." SMC_Sync_Support::sync_all \$default_term_id = " . var_export( $default_term_id, true ), 0 );
|
492 |
+
} // exclude category
|
493 |
+
|
494 |
foreach( $assignments as $parent_id => $assignment ) {
|
495 |
$taxonomy_terms = $assignment[ 'terms' ];
|
496 |
unset( $assignment['terms'] );
|
497 |
unset( $assignment['ttids'] );
|
498 |
unset( $assignment['smc_sync'] );
|
499 |
|
500 |
+
// Check for Default Post Category exclusion
|
501 |
+
if ( $default_term_id ) {
|
502 |
+
$parent = get_post( $parent_id );
|
503 |
+
if ( 'post' === $parent->post_type && 'auto-draft' !== $parent->post_status && isset( $taxonomy_terms['category'] ) ) {
|
504 |
+
foreach ( $taxonomy_terms['category'] as $index => $term ) {
|
505 |
+
//error_log( __LINE__ ." SMC_Sync_Support::sync_all ( category, {$index} ) \$term = " . var_export( $term, true ), 0 );
|
506 |
+
if ( $default_term_id === $term['term_id'] ) {
|
507 |
+
unset( $taxonomy_terms['category'][ $index ] );
|
508 |
+
}
|
509 |
+
} // type === post
|
510 |
+
} // exclude category
|
511 |
+
//error_log( __LINE__ ." SMC_Sync_Support::get_terms ( category ) revised \$taxonomy_terms = " . var_export( $taxonomy_terms, true ), 0 );
|
512 |
+
} // foreach assignment
|
513 |
+
|
514 |
$tax_input = $initial_tax_input;
|
515 |
foreach( $taxonomy_terms as $taxonomy => $terms ) {
|
516 |
foreach( $terms as $ttid => $term ) {
|
622 |
continue;
|
623 |
}
|
624 |
|
|
|
|
|
|
|
625 |
// Check if logged-in user can assign terms
|
626 |
$current_user = wp_get_current_user();
|
627 |
if ( $current_user->ID ) {
|
628 |
+
$taxonomy_obj = get_taxonomy( $taxonomy );
|
629 |
if ( ! current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
|
630 |
+
//error_log( __LINE__ ." SMC_Sync_Support::sync_terms User( {$current_user->ID} can't assign {$taxonomy} terms", 0 );
|
631 |
continue;
|
632 |
}
|
633 |
}
|
656 |
sort( $terms_before );
|
657 |
}
|
658 |
|
659 |
+
// 1.1.6 - updating the parent's terms conflicts with the requirements
|
660 |
+
// $terms_after = wp_set_post_terms( $parent_id, $terms, $taxonomy );
|
661 |
+
$terms_after = $terms_before;
|
662 |
sort( $terms_after );
|
663 |
if ( $terms_after != $terms_before ) {
|
664 |
$parent_changed = true;
|
examples/plugins/smart-media-categories/public/class-smart-media-categories.php
CHANGED
@@ -25,7 +25,7 @@ class Smart_Media_Categories {
|
|
25 |
*
|
26 |
* @var string
|
27 |
*/
|
28 |
-
const VERSION = '1.1.
|
29 |
|
30 |
/**
|
31 |
* Unique identifier for your plugin.
|
25 |
*
|
26 |
* @var string
|
27 |
*/
|
28 |
+
const VERSION = '1.1.6';
|
29 |
|
30 |
/**
|
31 |
* Unique identifier for your plugin.
|
examples/plugins/smart-media-categories/smart-media-categories.php
CHANGED
@@ -14,7 +14,7 @@
|
|
14 |
* Plugin Name: Smart Media Categories
|
15 |
* Plugin URI: http://davidlingren.com/
|
16 |
* Description: Assigns taxonomy terms to Media Library items based on the terms of their parent post/page.
|
17 |
-
* Version: 1.1.
|
18 |
* Author: David Lingren
|
19 |
* Author URI: http://davidlingren.com/
|
20 |
* Text Domain: smart-media-categories
|
@@ -49,9 +49,7 @@ if ( ! defined( 'WPINC' ) ) {
|
|
49 |
* Public-Facing Functionality
|
50 |
*----------------------------------------------------------------------------*/
|
51 |
|
52 |
-
|
53 |
-
* Plugin class for the public-facing side of the WordPress site.
|
54 |
-
*/
|
55 |
require_once( plugin_dir_path( __FILE__ ) . 'public/class-smart-media-categories.php' );
|
56 |
|
57 |
/*
|
@@ -61,9 +59,7 @@ require_once( plugin_dir_path( __FILE__ ) . 'public/class-smart-media-categories
|
|
61 |
register_activation_hook( __FILE__, array( 'Smart_Media_Categories', 'activate' ) );
|
62 |
register_deactivation_hook( __FILE__, array( 'Smart_Media_Categories', 'deactivate' ) );
|
63 |
|
64 |
-
|
65 |
-
* Create an instance of the public-facing class.
|
66 |
-
*/
|
67 |
add_action( 'plugins_loaded', array( 'Smart_Media_Categories', 'get_instance' ) );
|
68 |
|
69 |
/*----------------------------------------------------------------------------*
|
@@ -82,9 +78,11 @@ add_action( 'plugins_loaded', array( 'Smart_Media_Categories', 'get_instance' )
|
|
82 |
*
|
83 |
* The code below is intended to to give the lightest footprint possible.
|
84 |
*/
|
|
|
85 |
if ( is_admin() /* && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) */ ) {
|
86 |
require_once( plugin_dir_path( __FILE__ ) . 'admin/class-smart-media-categories-admin.php' );
|
87 |
add_action( 'plugins_loaded', array( 'Smart_Media_Categories_Admin', 'get_instance' ) );
|
|
|
88 |
}
|
89 |
|
90 |
// Look for Postie chron job
|
14 |
* Plugin Name: Smart Media Categories
|
15 |
* Plugin URI: http://davidlingren.com/
|
16 |
* Description: Assigns taxonomy terms to Media Library items based on the terms of their parent post/page.
|
17 |
+
* Version: 1.1.6
|
18 |
* Author: David Lingren
|
19 |
* Author URI: http://davidlingren.com/
|
20 |
* Text Domain: smart-media-categories
|
49 |
* Public-Facing Functionality
|
50 |
*----------------------------------------------------------------------------*/
|
51 |
|
52 |
+
// Plugin class for the public-facing side of the WordPress site.
|
|
|
|
|
53 |
require_once( plugin_dir_path( __FILE__ ) . 'public/class-smart-media-categories.php' );
|
54 |
|
55 |
/*
|
59 |
register_activation_hook( __FILE__, array( 'Smart_Media_Categories', 'activate' ) );
|
60 |
register_deactivation_hook( __FILE__, array( 'Smart_Media_Categories', 'deactivate' ) );
|
61 |
|
62 |
+
// Create an instance of the public-facing class.
|
|
|
|
|
63 |
add_action( 'plugins_loaded', array( 'Smart_Media_Categories', 'get_instance' ) );
|
64 |
|
65 |
/*----------------------------------------------------------------------------*
|
78 |
*
|
79 |
* The code below is intended to to give the lightest footprint possible.
|
80 |
*/
|
81 |
+
|
82 |
if ( is_admin() /* && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) */ ) {
|
83 |
require_once( plugin_dir_path( __FILE__ ) . 'admin/class-smart-media-categories-admin.php' );
|
84 |
add_action( 'plugins_loaded', array( 'Smart_Media_Categories_Admin', 'get_instance' ) );
|
85 |
+
//error_log( __LINE__ . ' smart-media-categories.php is_admin() Support _REQUEST = ' . var_export( $_REQUEST, true ), 0 );
|
86 |
}
|
87 |
|
88 |
// Look for Postie chron job
|
includes/class-mla-core.php
CHANGED
@@ -21,7 +21,7 @@ class MLACore {
|
|
21 |
*
|
22 |
* @var string
|
23 |
*/
|
24 |
-
const CURRENT_MLA_VERSION = '2.
|
25 |
|
26 |
/**
|
27 |
* Slug for registering and enqueueing plugin style sheets (moved from class-mla-main.php)
|
@@ -472,16 +472,16 @@ class MLACore {
|
|
472 |
// Template file and database access functions.
|
473 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
|
474 |
MLAQuery::initialize();
|
475 |
-
|
476 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data.php' );
|
477 |
MLAData::initialize();
|
478 |
-
|
479 |
// Shortcode shim functions
|
480 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
|
481 |
MLAShortcodes::initialize();
|
482 |
-
|
483 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
|
484 |
-
|
485 |
// Plugin settings management
|
486 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-options.php' );
|
487 |
MLAOptions::initialize();
|
@@ -693,7 +693,7 @@ class MLACore {
|
|
693 |
if ( '_wpnonce' !== $name ) {
|
694 |
$actionurl = str_replace( '_wpnonce', $name, $actionurl );
|
695 |
}
|
696 |
-
|
697 |
return $actionurl;
|
698 |
}
|
699 |
|
@@ -1245,7 +1245,7 @@ class MLACore {
|
|
1245 |
'update_post_meta_cache' => 'false',
|
1246 |
'update_post_term_cache' => 'false',
|
1247 |
);
|
1248 |
-
|
1249 |
$specification = self::mla_parse_view_specification( $specification );
|
1250 |
if ( 'mime' == $specification['prefix'] ) {
|
1251 |
$query['post_mime_type'] = $specification['value'];
|
@@ -1255,13 +1255,14 @@ class MLACore {
|
|
1255 |
case 'match':
|
1256 |
$patterns = array_map( 'trim', explode( ',', $specification['value'] ) );
|
1257 |
foreach ( (array) $patterns as $pattern ) {
|
|
|
1258 |
$pattern = preg_replace( '/\*+/', '%', $pattern );
|
1259 |
if ( false !== strpos( $pattern, '%' ) ) {
|
1260 |
// Preserve the pattern - it will be used in the "where" filter
|
1261 |
$meta_query['patterns'][] = $pattern;
|
1262 |
-
$meta_query[] =
|
1263 |
} else {
|
1264 |
-
$meta_query[] =
|
1265 |
}
|
1266 |
} // foreach pattern
|
1267 |
|
@@ -1271,16 +1272,24 @@ class MLACore {
|
|
1271 |
|
1272 |
break;
|
1273 |
case 'null':
|
1274 |
-
|
|
|
|
|
|
|
1275 |
$meta_query['value'] = 'NULL';
|
1276 |
break;
|
1277 |
default: // '', 'any'
|
1278 |
-
|
|
|
|
|
|
|
|
|
1279 |
}
|
1280 |
|
1281 |
$query['meta_query'] = $meta_query;
|
1282 |
} // custom field specification
|
1283 |
|
|
|
1284 |
return $query;
|
1285 |
}
|
1286 |
|
@@ -1297,16 +1306,34 @@ class MLACore {
|
|
1297 |
if ( is_array( $specification ) ) {
|
1298 |
$specification = @implode( ',', $specification );
|
1299 |
}
|
|
|
1300 |
|
1301 |
$result = array( 'prefix' => '', 'name' => '', 'value' => '', 'option' => '' );
|
1302 |
$match_count = preg_match( '/^(.+):(.+)/', $specification, $matches );
|
1303 |
if ( 1 == $match_count ) {
|
1304 |
$result['prefix'] = trim( strtolower( $matches[1] ) );
|
1305 |
$tail = $matches[2];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1306 |
|
1307 |
$match_count = preg_match( '/([^,=]+)((,|=)(.*))$/', $tail, $matches );
|
1308 |
if ( 1 == $match_count ) {
|
1309 |
-
|
|
|
|
|
|
|
|
|
1310 |
|
1311 |
if ( ',' == $matches[3] ) {
|
1312 |
$result['option'] = trim( strtolower( $matches[4] ));
|
@@ -1329,9 +1356,7 @@ class MLACore {
|
|
1329 |
$result['value'] = $specification;
|
1330 |
}
|
1331 |
|
1332 |
-
|
1333 |
-
* Validate the results
|
1334 |
-
*/
|
1335 |
if ( 'mime' == $result['prefix'] ) {
|
1336 |
$mime_types = array_map( 'trim', explode( ',', $result['value'] ) );
|
1337 |
foreach ( (array) $mime_types as $raw_mime_type ) {
|
@@ -1345,13 +1370,14 @@ class MLACore {
|
|
1345 |
} elseif ( 'custom' == $result['prefix'] ) {
|
1346 |
if ( ! in_array( $result['option'], array( '', 'any', 'match', 'null' ) ) ) {
|
1347 |
/* translators: 1: ERROR tag 2: option, e.g., any, match, null */
|
1348 |
-
$result['error'] = '<br>' . sprintf( __( '%1$s: Bad specification option "%2$s"', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $
|
1349 |
}
|
1350 |
} else {
|
1351 |
/* translators: 1: ERROR tag 2: prefix, e.g., custom */
|
1352 |
-
$result['error'] = '<br>' . sprintf( __( '%1$s: Bad specification prefix "%2$s"', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $
|
1353 |
}
|
1354 |
|
|
|
1355 |
return $result;
|
1356 |
}
|
1357 |
|
@@ -1539,7 +1565,7 @@ class MLACore {
|
|
1539 |
} else {
|
1540 |
$callback_array = $wp_filter[ $filter ];
|
1541 |
}
|
1542 |
-
|
1543 |
foreach ( $callback_array as $priority => $callbacks ) {
|
1544 |
$hook_list .= "Priority: {$priority}\n";
|
1545 |
foreach ( $callbacks as $tag => $reference ) {
|
@@ -1552,7 +1578,7 @@ class MLACore {
|
|
1552 |
} else {
|
1553 |
$hook_list .= $reference['function'][0] . '::';
|
1554 |
}
|
1555 |
-
|
1556 |
$hook_list .= $reference['function'][1] . "()\n";
|
1557 |
} else {
|
1558 |
$hook_list .= 'unknown reference type: ' . gettype( $reference['function'] ) . "\n";
|
@@ -1560,7 +1586,7 @@ class MLACore {
|
|
1560 |
} // foreach tag
|
1561 |
} // foreach proprity
|
1562 |
} // filters exist
|
1563 |
-
|
1564 |
return $hook_list;
|
1565 |
}
|
1566 |
|
21 |
*
|
22 |
* @var string
|
23 |
*/
|
24 |
+
const CURRENT_MLA_VERSION = '2.94';
|
25 |
|
26 |
/**
|
27 |
* Slug for registering and enqueueing plugin style sheets (moved from class-mla-main.php)
|
472 |
// Template file and database access functions.
|
473 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
|
474 |
MLAQuery::initialize();
|
475 |
+
|
476 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data.php' );
|
477 |
MLAData::initialize();
|
478 |
+
|
479 |
// Shortcode shim functions
|
480 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcodes.php' );
|
481 |
MLAShortcodes::initialize();
|
482 |
+
|
483 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-shortcode-support.php' );
|
484 |
+
|
485 |
// Plugin settings management
|
486 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-options.php' );
|
487 |
MLAOptions::initialize();
|
693 |
if ( '_wpnonce' !== $name ) {
|
694 |
$actionurl = str_replace( '_wpnonce', $name, $actionurl );
|
695 |
}
|
696 |
+
|
697 |
return $actionurl;
|
698 |
}
|
699 |
|
1245 |
'update_post_meta_cache' => 'false',
|
1246 |
'update_post_term_cache' => 'false',
|
1247 |
);
|
1248 |
+
|
1249 |
$specification = self::mla_parse_view_specification( $specification );
|
1250 |
if ( 'mime' == $specification['prefix'] ) {
|
1251 |
$query['post_mime_type'] = $specification['value'];
|
1255 |
case 'match':
|
1256 |
$patterns = array_map( 'trim', explode( ',', $specification['value'] ) );
|
1257 |
foreach ( (array) $patterns as $pattern ) {
|
1258 |
+
$meta_key = ( !empty( $specification['name'] ) ) ? array( 'key' => $specification['name'] ) : array();
|
1259 |
$pattern = preg_replace( '/\*+/', '%', $pattern );
|
1260 |
if ( false !== strpos( $pattern, '%' ) ) {
|
1261 |
// Preserve the pattern - it will be used in the "where" filter
|
1262 |
$meta_query['patterns'][] = $pattern;
|
1263 |
+
$meta_query[] = array_merge( $meta_key, array( 'value' => $pattern, 'compare' => 'LIKE' ) );
|
1264 |
} else {
|
1265 |
+
$meta_query[] = array_merge( $meta_key, array( 'value' => $pattern, 'compare' => '=' ) );
|
1266 |
}
|
1267 |
} // foreach pattern
|
1268 |
|
1272 |
|
1273 |
break;
|
1274 |
case 'null':
|
1275 |
+
if ( !empty( $specification['name'] ) ) {
|
1276 |
+
$meta_query['key'] = $specification['name'];
|
1277 |
+
}
|
1278 |
+
|
1279 |
$meta_query['value'] = 'NULL';
|
1280 |
break;
|
1281 |
default: // '', 'any'
|
1282 |
+
if ( !empty( $specification['name'] ) ) {
|
1283 |
+
$meta_query[] = array( 'key' => $specification['name'], 'value' => NULL, 'compare' => '!=' );
|
1284 |
+
} else {
|
1285 |
+
$meta_query[] = array( 'value' => NULL, 'compare' => '!=' );
|
1286 |
+
}
|
1287 |
}
|
1288 |
|
1289 |
$query['meta_query'] = $meta_query;
|
1290 |
} // custom field specification
|
1291 |
|
1292 |
+
//error_log( __LINE__ . ' MLACore::mla_prepare_view_query query = ' . var_export( $query, true ), 0 );
|
1293 |
return $query;
|
1294 |
}
|
1295 |
|
1306 |
if ( is_array( $specification ) ) {
|
1307 |
$specification = @implode( ',', $specification );
|
1308 |
}
|
1309 |
+
//error_log( __LINE__ . ' MLACore::mla_parse_view_specification specification = ' . var_export( $specification, true ), 0 );
|
1310 |
|
1311 |
$result = array( 'prefix' => '', 'name' => '', 'value' => '', 'option' => '' );
|
1312 |
$match_count = preg_match( '/^(.+):(.+)/', $specification, $matches );
|
1313 |
if ( 1 == $match_count ) {
|
1314 |
$result['prefix'] = trim( strtolower( $matches[1] ) );
|
1315 |
$tail = $matches[2];
|
1316 |
+
//error_log( __LINE__ . ' MLACore::mla_parse_view_specification tail = ' . var_export( $tail, true ), 0 );
|
1317 |
+
|
1318 |
+
// Look for field name(s)
|
1319 |
+
$flag = '<found multiple names in the tail>';
|
1320 |
+
$match_count = preg_match( '/([^=]+)((=)(.*))$/', $tail, $matches );
|
1321 |
+
if ( 1 == $match_count ) {
|
1322 |
+
//error_log( __LINE__ . ' MLACore::mla_parse_view_specification matches = ' . var_export( $matches, true ), 0 );
|
1323 |
+
$result['name'] = explode( ',', $matches[1] );
|
1324 |
+
// Flag multiple field names for preservation
|
1325 |
+
if ( 1 < count( $result['name'] ) ) {
|
1326 |
+
$tail = $flag . $matches[2];
|
1327 |
+
}
|
1328 |
+
}
|
1329 |
|
1330 |
$match_count = preg_match( '/([^,=]+)((,|=)(.*))$/', $tail, $matches );
|
1331 |
if ( 1 == $match_count ) {
|
1332 |
+
//error_log( __LINE__ . ' MLACore::mla_parse_view_specification matches = ' . var_export( $matches, true ), 0 );
|
1333 |
+
// Preserve multiple field names, handle "any field"; name = *
|
1334 |
+
if ( $flag !== $matches[1] ) {
|
1335 |
+
$result['name'] = ( '*' === $matches[1] ) ? '' : $matches[1];
|
1336 |
+
}
|
1337 |
|
1338 |
if ( ',' == $matches[3] ) {
|
1339 |
$result['option'] = trim( strtolower( $matches[4] ));
|
1356 |
$result['value'] = $specification;
|
1357 |
}
|
1358 |
|
1359 |
+
// Validate the results
|
|
|
|
|
1360 |
if ( 'mime' == $result['prefix'] ) {
|
1361 |
$mime_types = array_map( 'trim', explode( ',', $result['value'] ) );
|
1362 |
foreach ( (array) $mime_types as $raw_mime_type ) {
|
1370 |
} elseif ( 'custom' == $result['prefix'] ) {
|
1371 |
if ( ! in_array( $result['option'], array( '', 'any', 'match', 'null' ) ) ) {
|
1372 |
/* translators: 1: ERROR tag 2: option, e.g., any, match, null */
|
1373 |
+
$result['error'] = '<br>' . sprintf( __( '%1$s: Bad specification option "%2$s"', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $result['option'] );
|
1374 |
}
|
1375 |
} else {
|
1376 |
/* translators: 1: ERROR tag 2: prefix, e.g., custom */
|
1377 |
+
$result['error'] = '<br>' . sprintf( __( '%1$s: Bad specification prefix "%2$s"', 'media-library-assistant' ), __( 'ERROR', 'media-library-assistant' ), $result['prefix'] );
|
1378 |
}
|
1379 |
|
1380 |
+
//error_log( __LINE__ . ' MLACore::mla_parse_view_specification result = ' . var_export( $result, true ), 0 );
|
1381 |
return $result;
|
1382 |
}
|
1383 |
|
1565 |
} else {
|
1566 |
$callback_array = $wp_filter[ $filter ];
|
1567 |
}
|
1568 |
+
|
1569 |
foreach ( $callback_array as $priority => $callbacks ) {
|
1570 |
$hook_list .= "Priority: {$priority}\n";
|
1571 |
foreach ( $callbacks as $tag => $reference ) {
|
1578 |
} else {
|
1579 |
$hook_list .= $reference['function'][0] . '::';
|
1580 |
}
|
1581 |
+
|
1582 |
$hook_list .= $reference['function'][1] . "()\n";
|
1583 |
} else {
|
1584 |
$hook_list .= 'unknown reference type: ' . gettype( $reference['function'] ) . "\n";
|
1586 |
} // foreach tag
|
1587 |
} // foreach proprity
|
1588 |
} // filters exist
|
1589 |
+
|
1590 |
return $hook_list;
|
1591 |
}
|
1592 |
|
includes/class-mla-data-query.php
CHANGED
@@ -995,10 +995,10 @@ class MLAQuery {
|
|
995 |
*/
|
996 |
case 's':
|
997 |
switch ( substr( $value, 0, 3 ) ) {
|
998 |
-
case '
|
999 |
$clean_request['debug'] = 'console';
|
1000 |
break;
|
1001 |
-
case '
|
1002 |
$clean_request['debug'] = 'log';
|
1003 |
break;
|
1004 |
}
|
@@ -1920,9 +1920,16 @@ class MLAQuery {
|
|
1920 |
|
1921 |
// WordPress modifies the LIKE clause - which we must reverse
|
1922 |
if ( isset( self::$query_parameters['patterns'] ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1923 |
foreach ( self::$query_parameters['patterns'] as $pattern ) {
|
1924 |
-
$pattern = str_replace( '_', '\\\\_', $pattern );
|
1925 |
-
$match_clause =
|
1926 |
$where_clause = str_replace( "LIKE '{$match_clause}'", "LIKE '{$pattern}'", $where_clause );
|
1927 |
}
|
1928 |
}
|
995 |
*/
|
996 |
case 's':
|
997 |
switch ( substr( $value, 0, 3 ) ) {
|
998 |
+
case '}|{':
|
999 |
$clean_request['debug'] = 'console';
|
1000 |
break;
|
1001 |
+
case '{|}':
|
1002 |
$clean_request['debug'] = 'log';
|
1003 |
break;
|
1004 |
}
|
1920 |
|
1921 |
// WordPress modifies the LIKE clause - which we must reverse
|
1922 |
if ( isset( self::$query_parameters['patterns'] ) ) {
|
1923 |
+
// WP after 4.8.3 replaces "%" with a long, complex placeholder
|
1924 |
+
if ( method_exists( $wpdb, 'placeholder_escape' ) ) {
|
1925 |
+
$placeholder = $wpdb->placeholder_escape();
|
1926 |
+
} else {
|
1927 |
+
$placeholder = '%';
|
1928 |
+
}
|
1929 |
+
|
1930 |
foreach ( self::$query_parameters['patterns'] as $pattern ) {
|
1931 |
+
$pattern = str_replace( array( '_', '%' ), array( '\\\\_', $placeholder ), $pattern );
|
1932 |
+
$match_clause = $placeholder . str_replace( $placeholder, '\\\\' . $placeholder, $pattern ) . $placeholder;
|
1933 |
$where_clause = str_replace( "LIKE '{$match_clause}'", "LIKE '{$pattern}'", $where_clause );
|
1934 |
}
|
1935 |
}
|
includes/class-mla-image-processor.php
CHANGED
@@ -36,9 +36,7 @@ class MLAImageProcessor {
|
|
36 |
private static function _get_temp_file( $extension = '.tmp' ) {
|
37 |
static $temp = NULL;
|
38 |
|
39 |
-
|
40 |
-
* Find a temp directory
|
41 |
-
*/
|
42 |
if ( NULL == $temp ) {
|
43 |
if ( function_exists('sys_get_temp_dir') ) {
|
44 |
$temp = sys_get_temp_dir();
|
@@ -59,9 +57,7 @@ class MLAImageProcessor {
|
|
59 |
}
|
60 |
}
|
61 |
|
62 |
-
|
63 |
-
* Create a unique file
|
64 |
-
*/
|
65 |
$path = $temp . uniqid( mt_rand() ) . $extension;
|
66 |
$f = @fopen( $path, 'a' );
|
67 |
if ( $f === false ) {
|
@@ -97,18 +93,14 @@ class MLAImageProcessor {
|
|
97 |
* @return boolean true if conversion succeeds else false
|
98 |
*/
|
99 |
private static function _ghostscript_convert( $file, $frame, $resolution, $output_type, $explicit_path = '' ) {
|
100 |
-
|
101 |
-
* Look for exec() - from http://stackoverflow.com/a/12980534/866618
|
102 |
-
*/
|
103 |
$blacklist = preg_split( '/,\s*/', ini_get('disable_functions') . ',' . ini_get('suhosin.executor.func.blacklist') );
|
104 |
if ( in_array('exec', $blacklist) ) {
|
105 |
self::_mla_debug_add( 'MLAImageProcessor::_ghostscript_convert blacklist failure' );
|
106 |
return false;
|
107 |
}
|
108 |
|
109 |
-
|
110 |
-
* Look for the Ghostscript executable
|
111 |
-
*/
|
112 |
$ghostscript_path = NULL;
|
113 |
do {
|
114 |
|
@@ -178,9 +170,7 @@ class MLAImageProcessor {
|
|
178 |
$extension = '.png';
|
179 |
}
|
180 |
|
181 |
-
|
182 |
-
* Generate a unique temporary file
|
183 |
-
*/
|
184 |
$output_file = self::_get_temp_file( $extension );
|
185 |
|
186 |
$cmd = escapeshellarg( $ghostscript_path ) . ' -sDEVICE=%1$s -r%2$dx%2$d -dFirstPage=%3$d -dLastPage=%3$d -dFitPage -o %4$s %5$s 2>&1';
|
@@ -475,7 +465,7 @@ class MLAImageProcessor {
|
|
475 |
ini_set( 'zlib.output_compression', 'Off' );
|
476 |
}
|
477 |
|
478 |
-
$file =
|
479 |
if ( ! is_file( $file ) ) {
|
480 |
self::_mla_die( 'File not found', __LINE__, 404 );
|
481 |
}
|
@@ -491,7 +481,7 @@ class MLAImageProcessor {
|
|
491 |
* If mla_ghostscript_path is present, a non-standard GS location can be found in a file written by
|
492 |
* the [mla_gallery] shortcode processor.
|
493 |
*/
|
494 |
-
$ghostscript_path =
|
495 |
if ( ! empty( $ghostscript_path ) ) {
|
496 |
$ghostscript_path = @file_get_contents( dirname( __FILE__ ) . '/' . 'mla-ghostscript-path.txt' );
|
497 |
}
|
@@ -507,9 +497,7 @@ class MLAImageProcessor {
|
|
507 |
self::_mla_debug_add( 'MLAImageProcessor::mla_process_stream_image begin file = ' . var_export( $file, true ) );
|
508 |
}
|
509 |
|
510 |
-
|
511 |
-
* Convert the file to an image format and load it
|
512 |
-
*/
|
513 |
try {
|
514 |
self::$image = new Imagick();
|
515 |
|
@@ -549,9 +537,7 @@ class MLAImageProcessor {
|
|
549 |
self::_mla_die( 'Image load exception: ' . $e->getMessage(), __LINE__, 404 );
|
550 |
}
|
551 |
|
552 |
-
|
553 |
-
* Prepare the output image; resize and flatten, if necessary
|
554 |
-
*/
|
555 |
try {
|
556 |
if ( isset( $_REQUEST['mla_stream_fit'] ) ) {
|
557 |
$best_fit = ( '1' == $_REQUEST['mla_stream_fit'] );
|
@@ -565,9 +551,7 @@ class MLAImageProcessor {
|
|
565 |
self::_mla_die( '_prepare_image exception: ' . $e->getMessage(), __LINE__, 500 );
|
566 |
}
|
567 |
|
568 |
-
|
569 |
-
* Stream the image back to the requestor
|
570 |
-
*/
|
571 |
try {
|
572 |
header( "Content-Type: $type" );
|
573 |
echo self::$image->getImageBlob(); // phpcs:ignore
|
@@ -649,9 +633,7 @@ class MLAMutex {
|
|
649 |
* @return void
|
650 |
*/
|
651 |
function __construct( $use_lock = false ) {
|
652 |
-
|
653 |
-
* If sem_ functions are not available require file locking
|
654 |
-
*/
|
655 |
if ( ! is_callable( 'sem_get' ) ) {
|
656 |
$use_lock = true;
|
657 |
}
|
36 |
private static function _get_temp_file( $extension = '.tmp' ) {
|
37 |
static $temp = NULL;
|
38 |
|
39 |
+
// Find a temp directory
|
|
|
|
|
40 |
if ( NULL == $temp ) {
|
41 |
if ( function_exists('sys_get_temp_dir') ) {
|
42 |
$temp = sys_get_temp_dir();
|
57 |
}
|
58 |
}
|
59 |
|
60 |
+
// Create a unique file
|
|
|
|
|
61 |
$path = $temp . uniqid( mt_rand() ) . $extension;
|
62 |
$f = @fopen( $path, 'a' );
|
63 |
if ( $f === false ) {
|
93 |
* @return boolean true if conversion succeeds else false
|
94 |
*/
|
95 |
private static function _ghostscript_convert( $file, $frame, $resolution, $output_type, $explicit_path = '' ) {
|
96 |
+
// Look for exec() - from http://stackoverflow.com/a/12980534/866618
|
|
|
|
|
97 |
$blacklist = preg_split( '/,\s*/', ini_get('disable_functions') . ',' . ini_get('suhosin.executor.func.blacklist') );
|
98 |
if ( in_array('exec', $blacklist) ) {
|
99 |
self::_mla_debug_add( 'MLAImageProcessor::_ghostscript_convert blacklist failure' );
|
100 |
return false;
|
101 |
}
|
102 |
|
103 |
+
// Look for the Ghostscript executable
|
|
|
|
|
104 |
$ghostscript_path = NULL;
|
105 |
do {
|
106 |
|
170 |
$extension = '.png';
|
171 |
}
|
172 |
|
173 |
+
// Generate a unique temporary file
|
|
|
|
|
174 |
$output_file = self::_get_temp_file( $extension );
|
175 |
|
176 |
$cmd = escapeshellarg( $ghostscript_path ) . ' -sDEVICE=%1$s -r%2$dx%2$d -dFirstPage=%3$d -dLastPage=%3$d -dFitPage -o %4$s %5$s 2>&1';
|
465 |
ini_set( 'zlib.output_compression', 'Off' );
|
466 |
}
|
467 |
|
468 |
+
$file = isset( $_REQUEST['mla_stream_file'] ) ? $_REQUEST['mla_stream_file'] : ''; // phpcs:ignore
|
469 |
if ( ! is_file( $file ) ) {
|
470 |
self::_mla_die( 'File not found', __LINE__, 404 );
|
471 |
}
|
481 |
* If mla_ghostscript_path is present, a non-standard GS location can be found in a file written by
|
482 |
* the [mla_gallery] shortcode processor.
|
483 |
*/
|
484 |
+
$ghostscript_path = isset( $_REQUEST['mla_ghostscript_path'] ) ? $_REQUEST['mla_ghostscript_path'] : ''; // phpcs:ignore
|
485 |
if ( ! empty( $ghostscript_path ) ) {
|
486 |
$ghostscript_path = @file_get_contents( dirname( __FILE__ ) . '/' . 'mla-ghostscript-path.txt' );
|
487 |
}
|
497 |
self::_mla_debug_add( 'MLAImageProcessor::mla_process_stream_image begin file = ' . var_export( $file, true ) );
|
498 |
}
|
499 |
|
500 |
+
// Convert the file to an image format and load it
|
|
|
|
|
501 |
try {
|
502 |
self::$image = new Imagick();
|
503 |
|
537 |
self::_mla_die( 'Image load exception: ' . $e->getMessage(), __LINE__, 404 );
|
538 |
}
|
539 |
|
540 |
+
// Prepare the output image; resize and flatten, if necessary
|
|
|
|
|
541 |
try {
|
542 |
if ( isset( $_REQUEST['mla_stream_fit'] ) ) {
|
543 |
$best_fit = ( '1' == $_REQUEST['mla_stream_fit'] );
|
551 |
self::_mla_die( '_prepare_image exception: ' . $e->getMessage(), __LINE__, 500 );
|
552 |
}
|
553 |
|
554 |
+
// Stream the image back to the requestor
|
|
|
|
|
555 |
try {
|
556 |
header( "Content-Type: $type" );
|
557 |
echo self::$image->getImageBlob(); // phpcs:ignore
|
633 |
* @return void
|
634 |
*/
|
635 |
function __construct( $use_lock = false ) {
|
636 |
+
// If sem_ functions are not available require file locking
|
|
|
|
|
637 |
if ( ! is_callable( 'sem_get' ) ) {
|
638 |
$use_lock = true;
|
639 |
}
|
includes/class-mla-list-table.php
CHANGED
@@ -268,7 +268,8 @@ class MLA_List_Table extends WP_List_Table {
|
|
268 |
'hierarchical' => true,
|
269 |
'pad_counts' => false,
|
270 |
'taxonomy' => $tax_filter,
|
271 |
-
'hide_if_empty' => false
|
|
|
272 |
), $dropdown_options );
|
273 |
|
274 |
ob_start();
|
@@ -590,7 +591,6 @@ class MLA_List_Table extends WP_List_Table {
|
|
590 |
* Use "@" because embedded arrays throw PHP Warnings from implode.
|
591 |
*/
|
592 |
if ( is_array( $value ) ) {
|
593 |
-
// $list[] = var_export( $value, true ); // Verbose output!
|
594 |
$list[] = 'array( ' . @implode( ', ', $value ) . ' )';
|
595 |
} elseif ( $is_meta ) {
|
596 |
$list[] = $value;
|
268 |
'hierarchical' => true,
|
269 |
'pad_counts' => false,
|
270 |
'taxonomy' => $tax_filter,
|
271 |
+
'hide_if_empty' => false,
|
272 |
+
'update_term_meta_cache' => false,
|
273 |
), $dropdown_options );
|
274 |
|
275 |
ob_start();
|
591 |
* Use "@" because embedded arrays throw PHP Warnings from implode.
|
592 |
*/
|
593 |
if ( is_array( $value ) ) {
|
|
|
594 |
$list[] = 'array( ' . @implode( ', ', $value ) . ' )';
|
595 |
} elseif ( $is_meta ) {
|
596 |
$list[] = $value;
|
includes/class-mla-main.php
CHANGED
@@ -1714,9 +1714,9 @@ class MLA {
|
|
1714 |
if ( !empty( $page_content['body'] ) ) {
|
1715 |
if ( !empty( $page_content['message'] ) ) {
|
1716 |
if ( false !== strpos( $page_content['message'], __( 'ERROR', 'media-library-assistant' ) ) ) {
|
1717 |
-
$messages_class = '
|
1718 |
} else {
|
1719 |
-
$messages_class = '
|
1720 |
}
|
1721 |
|
1722 |
echo " <div class=\"" . esc_html( $messages_class ) . "\"><p>\n";
|
@@ -1733,7 +1733,7 @@ class MLA {
|
|
1733 |
echo ' - ' . esc_html__( 'term search results for', 'media-library-assistant' ) . ' "' . esc_html( trim( sanitize_text_field( wp_unslash( $_REQUEST['mla_terms_search']['phrases'] ), 'post' ) ) ). "\"" . wp_kses( $heading_tail, 'post' );
|
1734 |
} elseif ( !empty( $_REQUEST['s'] ) ) {
|
1735 |
if ( empty( $_REQUEST['mla_search_fields'] ) ) {
|
1736 |
-
echo ' - ' . esc_html__( 'post/parent results for', 'media-library-assistant' ) . ' "' . esc_html( trim( wp_kses( wp_unslash( $_REQUEST['s'] , 'post' ) ) )
|
1737 |
} else {
|
1738 |
echo ' - ' . esc_html__( 'search results for', 'media-library-assistant' ) . ' "' . esc_html( trim( wp_kses( wp_unslash( $_REQUEST['s'] ), 'post' ) ) ) . "\"" . wp_kses( $heading_tail, 'post' );
|
1739 |
}
|
@@ -1743,9 +1743,9 @@ class MLA {
|
|
1743 |
|
1744 |
if ( !empty( $page_content['message'] ) ) {
|
1745 |
if ( false !== strpos( $page_content['message'], __( 'ERROR', 'media-library-assistant' ) ) ) {
|
1746 |
-
$messages_class = '
|
1747 |
} else {
|
1748 |
-
$messages_class = '
|
1749 |
}
|
1750 |
|
1751 |
echo " <div class=\"" . esc_html( $messages_class ) . "\"><p>\n";
|
@@ -2155,6 +2155,19 @@ class MLA {
|
|
2155 |
return $time_edit_form;
|
2156 |
}
|
2157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2158 |
/**
|
2159 |
* Build the hidden row templates for inline editing (quick and bulk edit)
|
2160 |
*
|
@@ -2217,7 +2230,9 @@ class MLA {
|
|
2217 |
foreach ( $hierarchical_taxonomies as $tax_name => $tax_object ) {
|
2218 |
if ( current_user_can( $tax_object->cap->assign_terms ) ) {
|
2219 |
ob_start();
|
|
|
2220 |
wp_terms_checklist( NULL, array( 'taxonomy' => $tax_name, 'popular_cats' => array(), ) );
|
|
|
2221 |
$tax_checklist = ob_get_contents();
|
2222 |
ob_end_clean();
|
2223 |
|
@@ -2226,7 +2241,7 @@ class MLA {
|
|
2226 |
'tax_attr' => esc_attr( $tax_name ),
|
2227 |
'Add New Term' => __( '+ Add New Term', 'media-library-assistant' ),
|
2228 |
'Add Reader' => __( 'Add New', 'media-library-assistant' ) . ' ' . esc_html( $tax_object->labels->singular_name ),
|
2229 |
-
'tax_parents' => wp_dropdown_categories( array( 'taxonomy' => $tax_name, 'hide_empty' => 0, 'name' => "new{$tax_name}_parent", 'orderby' => 'name', 'hierarchical' => 1, 'show_option_none' => '— ' . $tax_object->labels->parent_item . ' —', 'echo' => 0 ) ),
|
2230 |
'Add Button' => esc_html( $tax_object->labels->add_new_item ),
|
2231 |
'ajax_nonce_field' => wp_nonce_field( 'add-'.$tax_name, '_ajax_nonce-add-'.$tax_name, false ),
|
2232 |
);
|
@@ -2281,7 +2296,9 @@ class MLA {
|
|
2281 |
if ( current_user_can( $tax_object->cap->assign_terms ) ) {
|
2282 |
if ( MLACore::mla_taxonomy_support( $tax_name, 'flat-checklist' ) ) {
|
2283 |
ob_start();
|
|
|
2284 |
wp_terms_checklist( NULL, array( 'taxonomy' => $tax_name, 'popular_cats' => array(), ) );
|
|
|
2285 |
$tax_checklist = ob_get_contents();
|
2286 |
ob_end_clean();
|
2287 |
|
1714 |
if ( !empty( $page_content['body'] ) ) {
|
1715 |
if ( !empty( $page_content['message'] ) ) {
|
1716 |
if ( false !== strpos( $page_content['message'], __( 'ERROR', 'media-library-assistant' ) ) ) {
|
1717 |
+
$messages_class = 'updated error';
|
1718 |
} else {
|
1719 |
+
$messages_class = 'updated notice is-dismissible';
|
1720 |
}
|
1721 |
|
1722 |
echo " <div class=\"" . esc_html( $messages_class ) . "\"><p>\n";
|
1733 |
echo ' - ' . esc_html__( 'term search results for', 'media-library-assistant' ) . ' "' . esc_html( trim( sanitize_text_field( wp_unslash( $_REQUEST['mla_terms_search']['phrases'] ), 'post' ) ) ). "\"" . wp_kses( $heading_tail, 'post' );
|
1734 |
} elseif ( !empty( $_REQUEST['s'] ) ) {
|
1735 |
if ( empty( $_REQUEST['mla_search_fields'] ) ) {
|
1736 |
+
echo ' - ' . esc_html__( 'post/parent results for', 'media-library-assistant' ) . ' "' . esc_html( trim( wp_kses( wp_unslash( $_REQUEST['s'] ) , 'post' ) ) ) . "\"" . wp_kses( $heading_tail, 'post' );
|
1737 |
} else {
|
1738 |
echo ' - ' . esc_html__( 'search results for', 'media-library-assistant' ) . ' "' . esc_html( trim( wp_kses( wp_unslash( $_REQUEST['s'] ), 'post' ) ) ) . "\"" . wp_kses( $heading_tail, 'post' );
|
1739 |
}
|
1743 |
|
1744 |
if ( !empty( $page_content['message'] ) ) {
|
1745 |
if ( false !== strpos( $page_content['message'], __( 'ERROR', 'media-library-assistant' ) ) ) {
|
1746 |
+
$messages_class = 'updated error';
|
1747 |
} else {
|
1748 |
+
$messages_class = 'updated notice is-dismissible';
|
1749 |
}
|
1750 |
|
1751 |
echo " <div class=\"" . esc_html( $messages_class ) . "\"><p>\n";
|
2155 |
return $time_edit_form;
|
2156 |
}
|
2157 |
|
2158 |
+
/**
|
2159 |
+
* Suppress term_meta cache update for taxonomy checklists
|
2160 |
+
*
|
2161 |
+
* @since 2.94
|
2162 |
+
*
|
2163 |
+
* @param array $args An array of get_terms() arguments.
|
2164 |
+
* @param string[] $taxonomies An array of taxonomy names.
|
2165 |
+
*/
|
2166 |
+
public static function mla_get_terms_args_filter( $args, $taxonomies ) {
|
2167 |
+
$args['update_term_meta_cache'] = false;
|
2168 |
+
return $args;
|
2169 |
+
}
|
2170 |
+
|
2171 |
/**
|
2172 |
* Build the hidden row templates for inline editing (quick and bulk edit)
|
2173 |
*
|
2230 |
foreach ( $hierarchical_taxonomies as $tax_name => $tax_object ) {
|
2231 |
if ( current_user_can( $tax_object->cap->assign_terms ) ) {
|
2232 |
ob_start();
|
2233 |
+
add_filter( 'get_terms_args', 'MLA::mla_get_terms_args_filter', 10, 2 );
|
2234 |
wp_terms_checklist( NULL, array( 'taxonomy' => $tax_name, 'popular_cats' => array(), ) );
|
2235 |
+
remove_filter( 'get_terms_args', 'MLA::mla_get_terms_args_filter', 10, 2 );
|
2236 |
$tax_checklist = ob_get_contents();
|
2237 |
ob_end_clean();
|
2238 |
|
2241 |
'tax_attr' => esc_attr( $tax_name ),
|
2242 |
'Add New Term' => __( '+ Add New Term', 'media-library-assistant' ),
|
2243 |
'Add Reader' => __( 'Add New', 'media-library-assistant' ) . ' ' . esc_html( $tax_object->labels->singular_name ),
|
2244 |
+
'tax_parents' => wp_dropdown_categories( array( 'taxonomy' => $tax_name, 'hide_empty' => 0, 'name' => "new{$tax_name}_parent", 'orderby' => 'name', 'hierarchical' => 1, 'show_option_none' => '— ' . $tax_object->labels->parent_item . ' —', 'echo' => 0, 'update_term_meta_cache' => false ) ),
|
2245 |
'Add Button' => esc_html( $tax_object->labels->add_new_item ),
|
2246 |
'ajax_nonce_field' => wp_nonce_field( 'add-'.$tax_name, '_ajax_nonce-add-'.$tax_name, false ),
|
2247 |
);
|
2296 |
if ( current_user_can( $tax_object->cap->assign_terms ) ) {
|
2297 |
if ( MLACore::mla_taxonomy_support( $tax_name, 'flat-checklist' ) ) {
|
2298 |
ob_start();
|
2299 |
+
add_filter( 'get_terms_args', 'MLA::mla_get_terms_args_filter', 10, 2 );
|
2300 |
wp_terms_checklist( NULL, array( 'taxonomy' => $tax_name, 'popular_cats' => array(), ) );
|
2301 |
+
remove_filter( 'get_terms_args', 'MLA::mla_get_terms_args_filter', 10, 2 );
|
2302 |
$tax_checklist = ob_get_contents();
|
2303 |
ob_end_clean();
|
2304 |
|
includes/class-mla-settings.php
CHANGED
@@ -1486,7 +1486,8 @@ class MLASettings {
|
|
1486 |
$dismiss_button = '';
|
1487 |
} else {
|
1488 |
$messages_class = 'updated notice is-dismissible';
|
1489 |
-
$dismiss_button = " <button class=\"notice-dismiss\" type=\"button\"><span class=\"screen-reader-text\">[+dismiss_text+].</span></button>\n";
|
|
|
1490 |
}
|
1491 |
|
1492 |
$page_values['messages'] = MLAData::mla_parse_template( self::$page_template_array['messages'], array(
|
1486 |
$dismiss_button = '';
|
1487 |
} else {
|
1488 |
$messages_class = 'updated notice is-dismissible';
|
1489 |
+
// $dismiss_button = " <button class=\"notice-dismiss\" type=\"button\"><span class=\"screen-reader-text\">[+dismiss_text+].</span></button>\n";
|
1490 |
+
$dismiss_button = ''; // /wp-admin/js/common.js function makeNoticesDismissible() since WP 4.4.0
|
1491 |
}
|
1492 |
|
1493 |
$page_values['messages'] = MLAData::mla_parse_template( self::$page_template_array['messages'], array(
|
includes/class-mla-shortcode-support.php
CHANGED
@@ -6,9 +6,7 @@
|
|
6 |
* @since 2.20
|
7 |
*/
|
8 |
|
9 |
-
|
10 |
-
* The MLA database access functions aren't available to "front end" posts/pages
|
11 |
-
*/
|
12 |
if ( !class_exists( 'MLAQuery' ) ) {
|
13 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
|
14 |
MLAQuery::initialize();
|
@@ -178,7 +176,19 @@ class MLAShortcode_Support {
|
|
178 |
public static function _get_attachment_image_src( $image, $attachment_id, $size, $icon ) {
|
179 |
static $nested_call = false;
|
180 |
|
181 |
-
if ( $nested_call
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
return $image;
|
183 |
}
|
184 |
|
@@ -197,16 +207,19 @@ class MLAShortcode_Support {
|
|
197 |
}
|
198 |
} // enable_featured_image
|
199 |
|
200 |
-
|
201 |
-
|
202 |
-
$
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
|
|
|
|
|
|
210 |
}
|
211 |
|
212 |
return $image;
|
@@ -480,6 +493,7 @@ class MLAShortcode_Support {
|
|
480 |
'mla_margin' => MLACore::mla_get_option('mla_gallery_margin'),
|
481 |
'mla_target' => '',
|
482 |
'mla_debug' => false,
|
|
|
483 |
|
484 |
'mla_named_transfer' => false,
|
485 |
'mla_viewer' => false,
|
@@ -853,16 +867,12 @@ class MLAShortcode_Support {
|
|
853 |
}
|
854 |
} // mla_alt_shortcode
|
855 |
|
856 |
-
if ( 'icon' == strtolower( $size) ) {
|
857 |
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_MLA_ICONS ) ) {
|
858 |
$size = array( 64, 64 );
|
859 |
} else {
|
860 |
$size = array( 60, 60 );
|
861 |
}
|
862 |
-
|
863 |
-
$show_icon = true;
|
864 |
-
} else {
|
865 |
-
$show_icon = false;
|
866 |
}
|
867 |
|
868 |
// Feeds such as RSS, Atom or RDF do not require styled and formatted output
|
@@ -1324,8 +1334,9 @@ class MLAShortcode_Support {
|
|
1324 |
} else {
|
1325 |
add_filter( 'wp_get_attachment_image_src', 'MLAShortcode_Support::_get_attachment_image_src', 10, 4 );
|
1326 |
|
1327 |
-
|
1328 |
-
$item_values['
|
|
|
1329 |
|
1330 |
remove_filter( 'wp_get_attachment_image_src', 'MLAShortcode_Support::_get_attachment_image_src' );
|
1331 |
}
|
@@ -4369,6 +4380,15 @@ class MLAShortcode_Support {
|
|
4369 |
*/
|
4370 |
private static $query_parameters = array();
|
4371 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4372 |
/**
|
4373 |
* Checks for valid, perhaps nested PHP array specification
|
4374 |
*
|
@@ -4380,9 +4400,12 @@ class MLAShortcode_Support {
|
|
4380 |
*/
|
4381 |
private static function _validate_array_specification( $specification ) {
|
4382 |
//error_log( __LINE__ . " _validate_array_specification() specification = " . var_export( $specification, true ), 0 );
|
|
|
4383 |
|
4384 |
// Check for outer array specification(s) and reject anything else.
|
4385 |
if ( 1 !== preg_match( '/^array\s*\((.*)\)[\s\,]*$/', $specification, $matches ) ) {
|
|
|
|
|
4386 |
return false;
|
4387 |
}
|
4388 |
|
@@ -4395,6 +4418,8 @@ class MLAShortcode_Support {
|
|
4395 |
foreach ( $matches[0] as $search ) {
|
4396 |
// Replace valid arrays with a harmless literal value
|
4397 |
if ( false === self::_validate_array_specification( $search ) ) {
|
|
|
|
|
4398 |
return false;
|
4399 |
}
|
4400 |
|
@@ -4431,6 +4456,7 @@ class MLAShortcode_Support {
|
|
4431 |
//error_log( __LINE__ . " _validate_array_specification() boolean and array() matches = " . var_export( $matches[10], true ), 0 );
|
4432 |
if ( false === in_array( strtolower( $matches[11] ), array( 'false', 'true', 'array' ) ) ) {
|
4433 |
//error_log( __LINE__ . " _validate_array_specification() FAILED boolean matches = " . var_export( $matches[7], true ), 0 );
|
|
|
4434 |
return false;
|
4435 |
}
|
4436 |
}
|
@@ -4443,11 +4469,12 @@ class MLAShortcode_Support {
|
|
4443 |
if ( 1 === preg_match( '/^(([\'\"](.+?)[\'\"])|(\d+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))(.*)$/', $interior, $matches ) ) {
|
4444 |
//error_log( __LINE__ . " _validate_array_specification() simple matches = " . var_export( $matches, true ), 0 );
|
4445 |
|
4446 |
-
$interior = trim( $matches[
|
4447 |
continue;
|
4448 |
}
|
4449 |
|
4450 |
//error_log( __LINE__ . " _validate_array_specification() FAILED interior = " . var_export( $interior, true ), 0 );
|
|
|
4451 |
return false;
|
4452 |
}
|
4453 |
|
@@ -4477,11 +4504,12 @@ class MLAShortcode_Support {
|
|
4477 |
//error_log( __LINE__ . " _sanitize_query_specification() candidate = " . var_export( $candidate, true ), 0 );
|
4478 |
|
4479 |
// Check for nested array specification(s) and reject anything else.
|
4480 |
-
|
|
|
4481 |
return $candidate;
|
4482 |
}
|
4483 |
|
4484 |
-
//error_log( __LINE__ . " _sanitize_query_specification() FAILED", 0 );
|
4485 |
return 'false';
|
4486 |
}
|
4487 |
|
@@ -4691,6 +4719,7 @@ class MLAShortcode_Support {
|
|
4691 |
'cache_results' => NULL,
|
4692 |
'update_post_meta_cache' => NULL,
|
4693 |
'update_post_term_cache' => NULL,
|
|
|
4694 |
);
|
4695 |
|
4696 |
/**
|
@@ -4791,6 +4820,9 @@ class MLAShortcode_Support {
|
|
4791 |
$mla_page_parameter = $arguments['mla_page_parameter'];
|
4792 |
unset( $arguments['mla_page_parameter'] );
|
4793 |
|
|
|
|
|
|
|
4794 |
/*
|
4795 |
* $mla_page_parameter, if set, doesn't make it through the shortcode_atts filter,
|
4796 |
* so we handle it separately
|
@@ -4840,6 +4872,11 @@ class MLAShortcode_Support {
|
|
4840 |
// Replace invalid queries from "where-used" callers with a harmless equivalent
|
4841 |
if ( $where_used_query && ( ( 'false' === $value ) || ( false !== strpos( $value, '{+' ) ) ) ) {
|
4842 |
$value = "array( array( 'taxonomy' => 'none', 'field' => 'slug', 'terms' => 'none' ) )";
|
|
|
|
|
|
|
|
|
|
|
4843 |
}
|
4844 |
|
4845 |
try {
|
@@ -5274,6 +5311,11 @@ class MLAShortcode_Support {
|
|
5274 |
// Replace invalid queries from "where-used" callers with a harmless equivalent
|
5275 |
if ( $where_used_query && ( ( 'false' === $value ) || ( false !== strpos( $value, '{+' ) ) ) ) {
|
5276 |
$value = "array( array( 'key' => 'unlikely', 'value' => 'none or otherwise unlikely' ) )";
|
|
|
|
|
|
|
|
|
|
|
5277 |
}
|
5278 |
|
5279 |
try {
|
@@ -5305,6 +5347,11 @@ class MLAShortcode_Support {
|
|
5305 |
// Replace invalid queries from "where-used" callers with a harmless equivalent
|
5306 |
if ( $where_used_query && ( ( 'false' === $value ) || ( false !== strpos( $value, '{+' ) ) ) ) {
|
5307 |
$value = "array( array( 'key' => 'unlikely', 'value' => 'none or otherwise unlikely' ) )";
|
|
|
|
|
|
|
|
|
|
|
5308 |
}
|
5309 |
|
5310 |
try {
|
@@ -5563,6 +5610,16 @@ class MLAShortcode_Support {
|
|
5563 |
add_filter( 'pmpro_search_filter_post_types', 'MLAShortcode_Support::mla_pmp_hide_attachments_filter' );
|
5564 |
}
|
5565 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5566 |
MLAShortcodes::$mla_gallery_wp_query_object = new WP_Query;
|
5567 |
$attachments = MLAShortcodes::$mla_gallery_wp_query_object->query( $query_arguments );
|
5568 |
|
@@ -5643,10 +5700,11 @@ class MLAShortcode_Support {
|
|
5643 |
* Set for taxonomy queries unless post_parent=current. If true, we must disable
|
5644 |
* the LEFT JOIN clause that get_posts() adds to taxonomy queries.
|
5645 |
* We leave the clause in because the WHERE clauses refer to "p2.".
|
5646 |
-
|
|
|
5647 |
if ( self::$query_parameters['disable_tax_join'] ) {
|
5648 |
$join_clause = str_replace( " LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID) ", " LEFT JOIN {$wpdb->posts} AS p2 ON (p2.ID = p2.ID) ", $join_clause );
|
5649 |
-
}
|
5650 |
|
5651 |
// These joins support the 'terms' search_field
|
5652 |
if ( isset( MLAQuery::$search_parameters['tax_terms_count'] ) ) {
|
@@ -5704,6 +5762,14 @@ class MLAShortcode_Support {
|
|
5704 |
MLACore::mla_debug_add( '<strong>' . __( 'mla_debug WHERE filter', 'media-library-assistant' ) . '</strong> = ' . var_export( $where_clause, true ) );
|
5705 |
}
|
5706 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5707 |
if ( strpos( $where_clause, "post_type = 'attachment'" ) ) {
|
5708 |
$where_clause = str_replace( "post_type = 'attachment'", "post_type = 'attachment'", $where_clause );
|
5709 |
}
|
@@ -5944,7 +6010,7 @@ class MLAShortcode_Support {
|
|
5944 |
|
5945 |
// Support Simple Taxonomy Ordering plugin
|
5946 |
if ( 'tax_position' === strtolower( $arguments['orderby'] ) ) {
|
5947 |
-
if ( class_exists( 'Yikes_Custom_Taxonomy_Order' ) ) {
|
5948 |
$field_array[] = ' term_meta.meta_value AS tax_position';
|
5949 |
} else {
|
5950 |
$arguments['orderby'] = 'name';
|
@@ -5953,7 +6019,7 @@ class MLAShortcode_Support {
|
|
5953 |
|
5954 |
// Support Simple Custom Post Order plugin
|
5955 |
if ( 'term_order' === strtolower( $arguments['orderby'] ) ) {
|
5956 |
-
if ( class_exists( 'SCPO_Engine' ) ) {
|
5957 |
$field_array[] = ' t.term_order';
|
5958 |
} else {
|
5959 |
$arguments['orderby'] = 'name';
|
@@ -6109,13 +6175,13 @@ class MLAShortcode_Support {
|
|
6109 |
|
6110 |
// Add sort order
|
6111 |
if ( 'none' !== strtolower( $arguments['orderby'] ) ) {
|
6112 |
-
if ( ( 'tax_position' === strtolower( $arguments['orderby'] ) ) && class_exists( 'Yikes_Custom_Taxonomy_Order' ) ) {
|
6113 |
// Support Simple Taxonomy Ordering plugin
|
6114 |
$yikes_custom_taxonomy_order = Yikes_Custom_Taxonomy_Order::get_instance();
|
6115 |
$clauses = $yikes_custom_taxonomy_order->set_tax_order( $clauses, $taxonomies, array() );
|
6116 |
// Adjust the orderby clause to account for the subquery and the alias in the fields[] clause
|
6117 |
$clauses['orderby'] = 'ORDER BY CAST( tax_position AS UNSIGNED )';
|
6118 |
-
} elseif ( ( 'term_order' === strtolower( $arguments['orderby'] ) ) && class_exists( 'SCPO_Engine' ) ) {
|
6119 |
// Support Simple Custom Post Order plugin
|
6120 |
$clauses['orderby'] = 'ORDER BY term_order';
|
6121 |
} else {
|
@@ -6366,7 +6432,7 @@ class MLAShortcode_Support {
|
|
6366 |
|
6367 |
if ( $exclude_tree ) {
|
6368 |
self::_remove_exclude_tree( $term_tree[ $taxonomy ], $exclude_tree );
|
6369 |
-
}
|
6370 |
|
6371 |
$term_count = 0;
|
6372 |
$root_limit = count( $term_tree[ $taxonomy ] );
|
6 |
* @since 2.20
|
7 |
*/
|
8 |
|
9 |
+
// The MLA database access functions aren't available to "front end" posts/pages
|
|
|
|
|
10 |
if ( !class_exists( 'MLAQuery' ) ) {
|
11 |
require_once( MLA_PLUGIN_PATH . 'includes/class-mla-data-query.php' );
|
12 |
MLAQuery::initialize();
|
176 |
public static function _get_attachment_image_src( $image, $attachment_id, $size, $icon ) {
|
177 |
static $nested_call = false;
|
178 |
|
179 |
+
if ( $nested_call ) {
|
180 |
+
return $image;
|
181 |
+
}
|
182 |
+
|
183 |
+
if ( 'none' === self::$size_parameter ) {
|
184 |
+
return false;
|
185 |
+
} elseif ( ( 'icon_only' === self::$size_parameter ) || ( 'icon_feature' === self::$size_parameter ) ) {
|
186 |
+
// No native images allowed
|
187 |
+
$image = false;
|
188 |
+
}
|
189 |
+
|
190 |
+
// If a native image exists, we're done
|
191 |
+
if ( false !== $image ) {
|
192 |
return $image;
|
193 |
}
|
194 |
|
207 |
}
|
208 |
} // enable_featured_image
|
209 |
|
210 |
+
// For any of the three "icon" variations, try to substitute an icon image
|
211 |
+
if ( 0 === strpos( self::$size_parameter, 'icon' ) ) {
|
212 |
+
if ( $src = wp_mime_type_icon( $attachment_id ) ) {
|
213 |
+
/** This filter is documented in wp-includes/post.php */
|
214 |
+
$icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' );
|
215 |
+
|
216 |
+
$src_file = $icon_dir . '/' . wp_basename( $src );
|
217 |
+
@list( $width, $height ) = getimagesize( $src_file );
|
218 |
+
}
|
219 |
+
|
220 |
+
if ( $src && $width && $height ) {
|
221 |
+
$image = array( $src, $width, $height );
|
222 |
+
}
|
223 |
}
|
224 |
|
225 |
return $image;
|
493 |
'mla_margin' => MLACore::mla_get_option('mla_gallery_margin'),
|
494 |
'mla_target' => '',
|
495 |
'mla_debug' => false,
|
496 |
+
'mla_allow_rml' => false,
|
497 |
|
498 |
'mla_named_transfer' => false,
|
499 |
'mla_viewer' => false,
|
867 |
}
|
868 |
} // mla_alt_shortcode
|
869 |
|
870 |
+
if ( 'icon' == strtolower( $size ) ) {
|
871 |
if ( 'checked' == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_MLA_ICONS ) ) {
|
872 |
$size = array( 64, 64 );
|
873 |
} else {
|
874 |
$size = array( 60, 60 );
|
875 |
}
|
|
|
|
|
|
|
|
|
876 |
}
|
877 |
|
878 |
// Feeds such as RSS, Atom or RDF do not require styled and formatted output
|
1334 |
} else {
|
1335 |
add_filter( 'wp_get_attachment_image_src', 'MLAShortcode_Support::_get_attachment_image_src', 10, 4 );
|
1336 |
|
1337 |
+
// The fourth argument, "show icon" is always false because we handle it in _get_attachment_image_src()
|
1338 |
+
$item_values['pagelink'] = wp_get_attachment_link($attachment->ID, $size, true, false, $link_text);
|
1339 |
+
$item_values['filelink'] = wp_get_attachment_link($attachment->ID, $size, false, false, $link_text);
|
1340 |
|
1341 |
remove_filter( 'wp_get_attachment_image_src', 'MLAShortcode_Support::_get_attachment_image_src' );
|
1342 |
}
|
4380 |
*/
|
4381 |
private static $query_parameters = array();
|
4382 |
|
4383 |
+
/**
|
4384 |
+
* Error details from _validate_array_specification()
|
4385 |
+
*
|
4386 |
+
* @since 2.94
|
4387 |
+
*
|
4388 |
+
* @var string
|
4389 |
+
*/
|
4390 |
+
private static $array_specification_error = '';
|
4391 |
+
|
4392 |
/**
|
4393 |
* Checks for valid, perhaps nested PHP array specification
|
4394 |
*
|
4400 |
*/
|
4401 |
private static function _validate_array_specification( $specification ) {
|
4402 |
//error_log( __LINE__ . " _validate_array_specification() specification = " . var_export( $specification, true ), 0 );
|
4403 |
+
self::$array_specification_error = '';
|
4404 |
|
4405 |
// Check for outer array specification(s) and reject anything else.
|
4406 |
if ( 1 !== preg_match( '/^array\s*\((.*)\)[\s\,]*$/', $specification, $matches ) ) {
|
4407 |
+
//error_log( __LINE__ . " _validate_array_specification() specification = " . var_export( $specification, true ), 0 );
|
4408 |
+
self::$array_specification_error = " FAILED outer array = " . var_export( $specification, true );
|
4409 |
return false;
|
4410 |
}
|
4411 |
|
4418 |
foreach ( $matches[0] as $search ) {
|
4419 |
// Replace valid arrays with a harmless literal value
|
4420 |
if ( false === self::_validate_array_specification( $search ) ) {
|
4421 |
+
self::$array_specification_error = " FAILED nested array = " . var_export( $search, true );
|
4422 |
+
//error_log( __LINE__ . " _validate_array_specification() search = " . var_export( $search, true ), 0 );
|
4423 |
return false;
|
4424 |
}
|
4425 |
|
4456 |
//error_log( __LINE__ . " _validate_array_specification() boolean and array() matches = " . var_export( $matches[10], true ), 0 );
|
4457 |
if ( false === in_array( strtolower( $matches[11] ), array( 'false', 'true', 'array' ) ) ) {
|
4458 |
//error_log( __LINE__ . " _validate_array_specification() FAILED boolean matches = " . var_export( $matches[7], true ), 0 );
|
4459 |
+
self::$array_specification_error = " FAILED boolean matches = " . var_export( $matches[7], true );
|
4460 |
return false;
|
4461 |
}
|
4462 |
}
|
4469 |
if ( 1 === preg_match( '/^(([\'\"](.+?)[\'\"])|(\d+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))(.*)$/', $interior, $matches ) ) {
|
4470 |
//error_log( __LINE__ . " _validate_array_specification() simple matches = " . var_export( $matches, true ), 0 );
|
4471 |
|
4472 |
+
$interior = trim( $matches[6], ' ,' );
|
4473 |
continue;
|
4474 |
}
|
4475 |
|
4476 |
//error_log( __LINE__ . " _validate_array_specification() FAILED interior = " . var_export( $interior, true ), 0 );
|
4477 |
+
self::$array_specification_error = " FAILED interior = " . var_export( $interior, true );
|
4478 |
return false;
|
4479 |
}
|
4480 |
|
4504 |
//error_log( __LINE__ . " _sanitize_query_specification() candidate = " . var_export( $candidate, true ), 0 );
|
4505 |
|
4506 |
// Check for nested array specification(s) and reject anything else.
|
4507 |
+
$result = self::_validate_array_specification( $candidate );
|
4508 |
+
if ( true === $result ) {
|
4509 |
return $candidate;
|
4510 |
}
|
4511 |
|
4512 |
+
//error_log( __LINE__ . " _sanitize_query_specification() FAILED array_specification_error = " . var_export( self::$array_specification_error, true ), 0 );
|
4513 |
return 'false';
|
4514 |
}
|
4515 |
|
4719 |
'cache_results' => NULL,
|
4720 |
'update_post_meta_cache' => NULL,
|
4721 |
'update_post_term_cache' => NULL,
|
4722 |
+
'mla_allow_rml' => false, // RML Support, for Phil Boyd
|
4723 |
);
|
4724 |
|
4725 |
/**
|
4820 |
$mla_page_parameter = $arguments['mla_page_parameter'];
|
4821 |
unset( $arguments['mla_page_parameter'] );
|
4822 |
|
4823 |
+
// Convert to boolean
|
4824 |
+
$arguments['mla_allow_rml'] = 'true' === ( ( ! empty( $arguments['mla_allow_rml'] ) ) ? trim( strtolower( $arguments['mla_allow_rml'] ) ) : 'false' );
|
4825 |
+
|
4826 |
/*
|
4827 |
* $mla_page_parameter, if set, doesn't make it through the shortcode_atts filter,
|
4828 |
* so we handle it separately
|
4872 |
// Replace invalid queries from "where-used" callers with a harmless equivalent
|
4873 |
if ( $where_used_query && ( ( 'false' === $value ) || ( false !== strpos( $value, '{+' ) ) ) ) {
|
4874 |
$value = "array( array( 'taxonomy' => 'none', 'field' => 'slug', 'terms' => 'none' ) )";
|
4875 |
+
} else {
|
4876 |
+
// If sanitization fails, return an error message
|
4877 |
+
if ( 'false' === $value ) {
|
4878 |
+
return '<p>' . __( 'ERROR', 'media-library-assistant' ) . ': ' . __( 'Invalid mla_gallery', 'media-library-assistant' ) . ' tax_query = ' . self::$array_specification_error . '</p>';
|
4879 |
+
}
|
4880 |
}
|
4881 |
|
4882 |
try {
|
5311 |
// Replace invalid queries from "where-used" callers with a harmless equivalent
|
5312 |
if ( $where_used_query && ( ( 'false' === $value ) || ( false !== strpos( $value, '{+' ) ) ) ) {
|
5313 |
$value = "array( array( 'key' => 'unlikely', 'value' => 'none or otherwise unlikely' ) )";
|
5314 |
+
} else {
|
5315 |
+
// If sanitization fails, return an error message
|
5316 |
+
if ( 'false' === $value ) {
|
5317 |
+
return '<p>' . __( 'ERROR', 'media-library-assistant' ) . ': ' . __( 'Invalid mla_gallery', 'media-library-assistant' ) . ' date_query = ' . self::$array_specification_error . '</p>';
|
5318 |
+
}
|
5319 |
}
|
5320 |
|
5321 |
try {
|
5347 |
// Replace invalid queries from "where-used" callers with a harmless equivalent
|
5348 |
if ( $where_used_query && ( ( 'false' === $value ) || ( false !== strpos( $value, '{+' ) ) ) ) {
|
5349 |
$value = "array( array( 'key' => 'unlikely', 'value' => 'none or otherwise unlikely' ) )";
|
5350 |
+
} else {
|
5351 |
+
// If sanitization fails, return an error message
|
5352 |
+
if ( 'false' === $value ) {
|
5353 |
+
return '<p>' . __( 'ERROR', 'media-library-assistant' ) . ': ' . __( 'Invalid mla_gallery', 'media-library-assistant' ) . ' meta_query = ' . self::$array_specification_error . '</p>';
|
5354 |
+
}
|
5355 |
}
|
5356 |
|
5357 |
try {
|
5610 |
add_filter( 'pmpro_search_filter_post_types', 'MLAShortcode_Support::mla_pmp_hide_attachments_filter' );
|
5611 |
}
|
5612 |
|
5613 |
+
if ( isset( $query_arguments['post_type'] ) && is_string( $query_arguments['post_type'] ) && ( 'attachment' === $query_arguments['post_type'] ) ) {
|
5614 |
+
if ( self::$query_parameters['disable_tax_join'] ) {
|
5615 |
+
// Suppress WordPress WP_Query LEFT JOIN on post_parent, etc.
|
5616 |
+
$query_arguments['post_type'] = 'mladisabletaxjoin';
|
5617 |
+
} elseif ( defined('RML_FILE') && ( false === $arguments['mla_allow_rml'] ) ) {
|
5618 |
+
// Suppress RML additions to MLA queries
|
5619 |
+
$query_arguments['post_type'] = 'mladisablerml';
|
5620 |
+
}
|
5621 |
+
} // post_type is attachment
|
5622 |
+
|
5623 |
MLAShortcodes::$mla_gallery_wp_query_object = new WP_Query;
|
5624 |
$attachments = MLAShortcodes::$mla_gallery_wp_query_object->query( $query_arguments );
|
5625 |
|
5700 |
* Set for taxonomy queries unless post_parent=current. If true, we must disable
|
5701 |
* the LEFT JOIN clause that get_posts() adds to taxonomy queries.
|
5702 |
* We leave the clause in because the WHERE clauses refer to "p2.".
|
5703 |
+
* Replaced in MLA v2.94 by "post_type = 'mladisabletaxjoin'"
|
5704 |
+
* /
|
5705 |
if ( self::$query_parameters['disable_tax_join'] ) {
|
5706 |
$join_clause = str_replace( " LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID) ", " LEFT JOIN {$wpdb->posts} AS p2 ON (p2.ID = p2.ID) ", $join_clause );
|
5707 |
+
} // */
|
5708 |
|
5709 |
// These joins support the 'terms' search_field
|
5710 |
if ( isset( MLAQuery::$search_parameters['tax_terms_count'] ) ) {
|
5762 |
MLACore::mla_debug_add( '<strong>' . __( 'mla_debug WHERE filter', 'media-library-assistant' ) . '</strong> = ' . var_export( $where_clause, true ) );
|
5763 |
}
|
5764 |
|
5765 |
+
// Reverse post_type modification used to avoid redundant LEFT JOIN insertion or RML folder insertion
|
5766 |
+
if ( strpos( $where_clause, "post_type = 'mladisabletaxjoin'" ) ) {
|
5767 |
+
$where_clause = str_replace( "post_type = 'mladisabletaxjoin'", "post_type = 'attachment'", $where_clause );
|
5768 |
+
} elseif ( strpos( $where_clause, "post_type = 'mladisablerml'" ) ) {
|
5769 |
+
$where_clause = str_replace( "post_type = 'mladisablerml'", "post_type = 'attachment'", $where_clause );
|
5770 |
+
}
|
5771 |
+
|
5772 |
+
// Add whitespace to prevent Role Scoper plugin clause modification
|
5773 |
if ( strpos( $where_clause, "post_type = 'attachment'" ) ) {
|
5774 |
$where_clause = str_replace( "post_type = 'attachment'", "post_type = 'attachment'", $where_clause );
|
5775 |
}
|
6010 |
|
6011 |
// Support Simple Taxonomy Ordering plugin
|
6012 |
if ( 'tax_position' === strtolower( $arguments['orderby'] ) ) {
|
6013 |
+
if ( class_exists( 'Yikes_Custom_Taxonomy_Order', false ) ) {
|
6014 |
$field_array[] = ' term_meta.meta_value AS tax_position';
|
6015 |
} else {
|
6016 |
$arguments['orderby'] = 'name';
|
6019 |
|
6020 |
// Support Simple Custom Post Order plugin
|
6021 |
if ( 'term_order' === strtolower( $arguments['orderby'] ) ) {
|
6022 |
+
if ( class_exists( 'SCPO_Engine', false ) ) {
|
6023 |
$field_array[] = ' t.term_order';
|
6024 |
} else {
|
6025 |
$arguments['orderby'] = 'name';
|
6175 |
|
6176 |
// Add sort order
|
6177 |
if ( 'none' !== strtolower( $arguments['orderby'] ) ) {
|
6178 |
+
if ( ( 'tax_position' === strtolower( $arguments['orderby'] ) ) && class_exists( 'Yikes_Custom_Taxonomy_Order', false ) ) {
|
6179 |
// Support Simple Taxonomy Ordering plugin
|
6180 |
$yikes_custom_taxonomy_order = Yikes_Custom_Taxonomy_Order::get_instance();
|
6181 |
$clauses = $yikes_custom_taxonomy_order->set_tax_order( $clauses, $taxonomies, array() );
|
6182 |
// Adjust the orderby clause to account for the subquery and the alias in the fields[] clause
|
6183 |
$clauses['orderby'] = 'ORDER BY CAST( tax_position AS UNSIGNED )';
|
6184 |
+
} elseif ( ( 'term_order' === strtolower( $arguments['orderby'] ) ) && class_exists( 'SCPO_Engine', false ) ) {
|
6185 |
// Support Simple Custom Post Order plugin
|
6186 |
$clauses['orderby'] = 'ORDER BY term_order';
|
6187 |
} else {
|
6432 |
|
6433 |
if ( $exclude_tree ) {
|
6434 |
self::_remove_exclude_tree( $term_tree[ $taxonomy ], $exclude_tree );
|
6435 |
+
}
|
6436 |
|
6437 |
$term_count = 0;
|
6438 |
$root_limit = count( $term_tree[ $taxonomy ] );
|
includes/mla-stream-image.php
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
/*
|
10 |
* Process mla_viewer image stream requests
|
11 |
*/
|
12 |
-
//@ini_set('error_log','C:\Program Files
|
13 |
|
14 |
require_once( pathinfo( __FILE__, PATHINFO_DIRNAME ) . '/class-mla-image-processor.php' );
|
15 |
|
9 |
/*
|
10 |
* Process mla_viewer image stream requests
|
11 |
*/
|
12 |
+
//@ini_set('error_log','C:\Program Files\Apache Software Foundation\Apache24\logs\php-errors.log');
|
13 |
|
14 |
require_once( pathinfo( __FILE__, PATHINFO_DIRNAME ) . '/class-mla-image-processor.php' );
|
15 |
|
index.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
* will the rest of the plugin be loaded and run.
|
7 |
*
|
8 |
* @package Media Library Assistant
|
9 |
-
* @version 2.
|
10 |
*/
|
11 |
|
12 |
/*
|
@@ -16,7 +16,7 @@ Description: Enhances the Media Library; powerful [mla_gallery] [mla_tag_cloud]
|
|
16 |
Author: David Lingren
|
17 |
Text Domain: media-library-assistant
|
18 |
Domain Path: /languages
|
19 |
-
Version: 2.
|
20 |
Author URI: http://davidlingren.com/
|
21 |
|
22 |
Copyright 2011-2020 David Lingren
|
6 |
* will the rest of the plugin be loaded and run.
|
7 |
*
|
8 |
* @package Media Library Assistant
|
9 |
+
* @version 2.94
|
10 |
*/
|
11 |
|
12 |
/*
|
16 |
Author: David Lingren
|
17 |
Text Domain: media-library-assistant
|
18 |
Domain Path: /languages
|
19 |
+
Version: 2.94
|
20 |
Author URI: http://davidlingren.com/
|
21 |
|
22 |
Copyright 2011-2020 David Lingren
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: media, media library, gallery, images, categories, tags, attachments, IPTC
|
|
5 |
Requires at least: 3.5.0
|
6 |
Tested up to: 5.6
|
7 |
Requires PHP: 5.3
|
8 |
-
Stable tag: 2.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -181,6 +181,20 @@ All of the MLA source code has been annotated with "DocBlocks", a special type o
|
|
181 |
|
182 |
== Changelog ==
|
183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
= 2.93 =
|
185 |
* New: The "MLA Simple Mapping Hooks Example" plugin has been updated so it will run when attachments are uploaded or updated by the WP/LR Sync plugin.
|
186 |
* New: For the "Smart Media Categories" example plugin, support has been added for the "Postie" plugin chron job that creates posts and attachments from an email.
|
@@ -321,8 +335,8 @@ All of the MLA source code has been annotated with "DocBlocks", a special type o
|
|
321 |
|
322 |
== Upgrade Notice ==
|
323 |
|
324 |
-
= 2.
|
325 |
-
|
326 |
|
327 |
== Other Notes ==
|
328 |
|
5 |
Requires at least: 3.5.0
|
6 |
Tested up to: 5.6
|
7 |
Requires PHP: 5.3
|
8 |
+
Stable tag: 2.94
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
181 |
|
182 |
== Changelog ==
|
183 |
|
184 |
+
= 2.94 =
|
185 |
+
* New: <strong>The "MLA Custom Field Search Example" plugin has been substantially upgraded.</strong> The new version has many more parameters and a new plugin settings page. A Documentation tab on the settings page contains all the information you need to understand and use the new version.
|
186 |
+
* New: <strong>A new example plugin, "MLA Postie Post After Example"</strong>, adds support for running MLA mapping rules after the "Postie" plugin chron job creates posts and attachments from an email.
|
187 |
+
* New: The Library Views/Post MIME Type "Table View" custom field queries have been enhanced to allow searching multiple field names or "all fields" for one or more values.
|
188 |
+
* Fix: The "Smart Media Categories" example plugin has been enhanced to handle additional WordPress alternatives for term assignments and a new option is provided to exclude the Default Post Category from sync processing.
|
189 |
+
* Fix: Wildcard values for Library Views/Post MIME Type "Table View" custom field queries have been restored.
|
190 |
+
* Fix: PDF thumbnail streaming for <code>mla_viewer</code> processing has been restored.
|
191 |
+
* Fix: For the `[mla_gallery]` shortcode, error reporting for the tax_query, date_query and meta_query parameters has been improved.
|
192 |
+
* Fix: For the `[mla_gallery]` shortcode, proper handling of the <code>size=</code> "icon", "icon_only" and "icon_feature" options has been restored.
|
193 |
+
* Fix: For the `[mla_gallery]` shortcode, performance is improved by avoiding a redundant LEFT JOIN database query clause (added by WP_Query).
|
194 |
+
* Fix: For the `[mla_gallery]` shortcode, performance is improved by avoiding LEFT JOIN and WHERE database query clauses added by Real Media Library.
|
195 |
+
* Fix: Unnecessary "term meta cache" queries have been removed from the Media/Assistant submenu table generation.
|
196 |
+
* Fix: Handling of disimissible admin messages has been restored.
|
197 |
+
|
198 |
= 2.93 =
|
199 |
* New: The "MLA Simple Mapping Hooks Example" plugin has been updated so it will run when attachments are uploaded or updated by the WP/LR Sync plugin.
|
200 |
* New: For the "Smart Media Categories" example plugin, support has been added for the "Postie" plugin chron job that creates posts and attachments from an email.
|
335 |
|
336 |
== Upgrade Notice ==
|
337 |
|
338 |
+
= 2.94 =
|
339 |
+
For [mla_gallery], icon handling, mla_viewer, and performance fixes. New and enhanced example plugins. Three enhancements in all, nine fixes.
|
340 |
|
341 |
== Other Notes ==
|
342 |
|
tpls/documentation-settings-tab.tpl
CHANGED
@@ -628,7 +628,7 @@ The Size parameter specifies the image size to use for the thumbnail display; "t
|
|
628 |
</tr>
|
629 |
<tr>
|
630 |
<td class="mla-doc-table-label">icon</td>
|
631 |
-
<td>Display an appropriate 60x60 (or 64x64) pixel thumbnail for image items and an appropriate icon for non-image items such as PDF or text files.</td>
|
632 |
</tr>
|
633 |
<tr>
|
634 |
<td class="mla-doc-table-label">icon_feature</td>
|
@@ -6116,12 +6116,23 @@ Within WordPress, the Post MIME Types list is returned from <code>/wp-includes/p
|
|
6116 |
The Table View list adds several enhancements to the Post MIME Type list. In the Specification field you can select several MIME types with a comma-separated list, e.g., "audio,video". Wildcard specifications are also supported. For example, "*/mpeg" to select audio and video mpeg formats or "application/*ms*" to select all Microsoft application formats (Word, Excel, etc.). In the Menu Order field you can enter numeric values to re-arrange the order in which the list entries are displayed in, for example, the Media/Assistant screen.
|
6117 |
</p>
|
6118 |
<p>
|
6119 |
-
The Table View list also supports custom field queries.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6120 |
</p>
|
6121 |
<ul class="mla_settings">
|
6122 |
-
<li>To return all items that have a non-NULL value in the field,
|
6123 |
-
<li>To return all items that have a NULL value in the field, enter the prefix "custom:" followed by the custom field name and then ",
|
6124 |
-
<li>To return all items that match one or more values, enter the prefix "custom:" followed by the custom field name and then "=" followed by a list of values. For example, <code>custom:Color=red</code> or <code>custom:Color=red,green,blue</code>. Wildcard specifications are also supported; for example, "*post" to match anything ending in "post" or "th*da*" to match values like "the date" and "this day".</li>
|
6125 |
</ul>
|
6126 |
<p>
|
6127 |
If you have enabled the <em><strong>Media Manager Enhanced MIME Type filter</strong></em>, the Table View list will also be available in the Media Manager/Add Media "media items" drop down list.
|
@@ -6715,7 +6726,7 @@ The Format element has a "commas" value that can improve the results of sorting
|
|
6715 |
If you code the "template:" prefix at the beginning of the EXIF/Template value you have all the power of Content Templates at your disposal. Do <strong>not</strong> add the "[+" and "+]" delimiters; the prefix is all you need.
|
6716 |
</p>
|
6717 |
<p>
|
6718 |
-
A template can be used to access any XMP metadata your items contain
|
6719 |
<br />
|
6720 |
<code>template:([+xmp:Title+])</code><br />
|
6721 |
<code>template:([+xmp:Regions.RegionList.*.*.Name,array+])</code><br />
|
@@ -6770,6 +6781,23 @@ The first example above sets the date to a fixed value. The second example uses
|
|
6770 |
</p>
|
6771 |
<h4>IPTC/EXIF Mapping for PDF Documents</h4>
|
6772 |
<p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6773 |
You can use Content Templates in the EXIF/Template Value text box to extract metadata from your PDF documents and add it to the Standard Fields and Taxonomy Terms of your Media Library items. The templates can be coded to select the appropriate source whether the item is a PDF document or an image. Here are three rules for metadata contained in PDF documents:
|
6774 |
</p>
|
6775 |
<table>
|
628 |
</tr>
|
629 |
<tr>
|
630 |
<td class="mla-doc-table-label">icon</td>
|
631 |
+
<td>Display an appropriate 60x60 (or 64x64) pixel thumbnail for image items and an appropriate icon for non-image items such as PDF or text files. If, however, a non-image item has a "Featured Image" it will replace the icon.</td>
|
632 |
</tr>
|
633 |
<tr>
|
634 |
<td class="mla-doc-table-label">icon_feature</td>
|
6116 |
The Table View list adds several enhancements to the Post MIME Type list. In the Specification field you can select several MIME types with a comma-separated list, e.g., "audio,video". Wildcard specifications are also supported. For example, "*/mpeg" to select audio and video mpeg formats or "application/*ms*" to select all Microsoft application formats (Word, Excel, etc.). In the Menu Order field you can enter numeric values to re-arrange the order in which the list entries are displayed in, for example, the Media/Assistant screen.
|
6117 |
</p>
|
6118 |
<p>
|
6119 |
+
The Table View list also supports custom field queries. A custom field query has four parts:
|
6120 |
+
</p>
|
6121 |
+
<ol>
|
6122 |
+
<li>A prefix, "custom:"</li>
|
6123 |
+
<li>A comma-separated list of one or more custom field names</li>
|
6124 |
+
<li>An equals sign ("="), to divide the field names from the values</li>
|
6125 |
+
<li>A comma-separated list of one or more values</li>
|
6126 |
+
</ol>
|
6127 |
+
<p>
|
6128 |
+
To return all items that match one or more values, enter the prefix "custom:" followed by the custom field name(s) and then "=" followed by a list of values. For example, <code>custom:Color=red</code> or <code>custom:Color=red,green,blue</code>. To search multiple fields, enter something like <code>custom:Artist,Patron=smith,jones</code>. To search <strong>all</strong> custom fields, enter an asterisk ("*"), e.g., <code>custom:*=smith,jones</code>. Wildcard specifications are also supported; for example, "*post" to match anything ending in "post" or "th*da*" to match values like "the date" and "this day". As explained below, a value of "*" will match any non-NULL value for a custom field.
|
6129 |
+
</p>
|
6130 |
+
<p>
|
6131 |
+
There are two special forms of the custom field specification used to test for the presence (non-NULL) or absence (NULL) of <strong>any</strong> values:
|
6132 |
</p>
|
6133 |
<ul class="mla_settings">
|
6134 |
+
<li>To return all items that have a non-NULL value in the field, enter the custom field name and then "=*", e.g., <code>custom:My Featured Items=*</code>. You can also enter the prefix "custom:" followed by just the custom field name(s). For example, <code>custom:My Featured Items</code>.</li>
|
6135 |
+
<li>To return all items that have a NULL value in the field, enter the prefix "custom:" followed by the custom field name(s) and then "=", e.g., <code>custom:My Featured Items,My Inserted Items=</code>. You can also enter a single custom field name and then ",null". For example, <code>custom:My Featured Items,null</code>.</li>
|
|
|
6136 |
</ul>
|
6137 |
<p>
|
6138 |
If you have enabled the <em><strong>Media Manager Enhanced MIME Type filter</strong></em>, the Table View list will also be available in the Media Manager/Add Media "media items" drop down list.
|
6726 |
If you code the "template:" prefix at the beginning of the EXIF/Template value you have all the power of Content Templates at your disposal. Do <strong>not</strong> add the "[+" and "+]" delimiters; the prefix is all you need.
|
6727 |
</p>
|
6728 |
<p>
|
6729 |
+
A template can be used to access any IPTC, EXIF or XMP metadata your items contain, as well as any of the <a href="#field_level_data_sources">field-level data sources</a>. For example:<br />
|
6730 |
<br />
|
6731 |
<code>template:([+xmp:Title+])</code><br />
|
6732 |
<code>template:([+xmp:Regions.RegionList.*.*.Name,array+])</code><br />
|
6781 |
</p>
|
6782 |
<h4>IPTC/EXIF Mapping for PDF Documents</h4>
|
6783 |
<p>
|
6784 |
+
PDF documents contain a Document Information Dictionary (D.I.D.) and many also contain XMP metadata. For the <code>pdf:</code> prefix, you can code any of the nine D.I.D. entries:
|
6785 |
+
</p>
|
6786 |
+
<ul class="mla_settings">
|
6787 |
+
<li><strong>Title</strong> - The document's title</li>
|
6788 |
+
<li><strong>Author</strong> - The name of the person who created the document</li>
|
6789 |
+
<li><strong>Subject</strong> - The subject of the document</li>
|
6790 |
+
<li><strong>Keywords</strong> - Keywords associated with the document</li>
|
6791 |
+
<li><strong>Creator</strong> - the name of the conforming product that created the original document</li>
|
6792 |
+
<li><strong>Producer</strong> - the name of the conforming product that converted it to PDF</li>
|
6793 |
+
<li><strong>CreationDate</strong> - The date and time the document was created</li>
|
6794 |
+
<li><strong>ModDate</strong> - The date and time the document was most recently modified</li>
|
6795 |
+
<li><strong>Trapped</strong> - indicates whether the document has been modified to include trapping information</li>
|
6796 |
+
</ul>
|
6797 |
+
<p>
|
6798 |
+
MLA contains logic that attempts to fill in the entries from the dictionary or from any XMP metadata the document contains. This gives you a simple way to access the information regardless of where in the metadata it appears.
|
6799 |
+
</p>
|
6800 |
+
<p>
|
6801 |
You can use Content Templates in the EXIF/Template Value text box to extract metadata from your PDF documents and add it to the Standard Fields and Taxonomy Terms of your Media Library items. The templates can be coded to select the appropriate source whether the item is a PDF document or an image. Here are three rules for metadata contained in PDF documents:
|
6802 |
</p>
|
6803 |
<table>
|