Headline
CVE-2023-4716: class-mla-shortcode-support.php in media-library-assistant/trunk/includes – WordPress Plugin Repository
The Media Library Assistant plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the ‘mla_gallery’ shortcode in versions up to, and including, 3.10 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers with contributor-level and above permissions to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
1<?php2/**3 * Media Library Assistant Shortcode handler(s)4 *5 * @package Media Library Assistant6 * @since 2.207 */89// The MLA database access functions aren’t available to “front end” posts/pages10if ( !class_exists( ‘MLAQuery’ ) ) {11 require_once( MLA_PLUGIN_PATH . ‘includes/class-mla-data-query.php’ );12 MLAQuery::initialize();13}1415if ( !class_exists( ‘MLAData’ ) ) {16 require_once( MLA_PLUGIN_PATH . ‘includes/class-mla-data.php’ );17 MLAData::initialize();18}1920if ( !class_exists( ‘MLATemplate_Support’ ) ) {21 require_once( MLA_PLUGIN_PATH . ‘includes/class-mla-template-support.php’ );22}23//error_log( __LINE__ . ' DEBUG: MLAShortcode_Support $_REQUEST = ' . var_export( $_REQUEST, true ), 0 );2425/**26 * Class MLA (Media Library Assistant) Shortcode Support provides the functions that27 * implement the [mla_gallery] and [mla_tag_cloud] shortcodes. It also implements the28 * mla_get_shortcode_attachments() and mla_get_terms() database access functions.29 *30 * @package Media Library Assistant31 * @since 2.2032 */33class MLAShortcode_Support {34 /**35 * Verify the presence of Ghostscript for mla_viewer36 *37 * @since 2.2038 *39 * @param string Non-standard location to override default search, e.g.,40 * 'C:\Program Files (x86)\gs\gs9.15\bin\gswin32c.exe’41 * @param boolean Force ghostscript-only tests, used by 42 * MLASettings_Shortcodes::mla_compose_shortcodes_tab()43 *44 * @return boolean true if Ghostscript available else false45 */46 public static function mla_ghostscript_present( $explicit_path = '’, $ghostscript_only = false ) {47 static $ghostscript_present = NULL;4849 // If $ghostscript_only = false, let the mla_debug parameter control logging50 if ( $ghostscript_only ) {51 $mla_debug_category = MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL;52 } else {53 $mla_debug_category = NULL;54 }5556 MLACore::mla_debug_add( __LINE__ . " MLAShortcode_Support::mla_ghostscript_present( {$ghostscript_only} ) explicit_path = " . var_export( $explicit_path, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );57 MLACore::mla_debug_add( __LINE__ . " MLAShortcode_Support::mla_ghostscript_present( {$ghostscript_only} ) ghostscript_present = " . var_export( $ghostscript_present, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );5859 if ( ! $ghostscript_only ) {60 if ( isset( $ghostscript_present ) ) {61 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, ghostscript_present = ' . var_export( $ghostscript_present, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );62 return $ghostscript_present;63 }6465 if ( ‘checked’ != MLACore::mla_get_option( ‘enable_ghostscript_check’ ) ) {66 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, disabled’, $mla_debug_category );67 return $ghostscript_present = true;68 }6970 // Imagick must be installed as well71 if ( ! class_exists( ‘Imagick’ ) ) {72 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, Imagick missing’, $mla_debug_category );73 return $ghostscript_present = false;74 }75 } // not ghostscript_only7677 // Look for exec() - from http://stackoverflow.com/a/12980534/86661878 $blacklist = preg_split( '/,\s*/’, ini_get(‘disable_functions’) . ‘,’ . ini_get(‘suhosin.executor.func.blacklist’) );79 if ( in_array('exec’, $blacklist) ) {80 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, exec in blacklist’, $mla_debug_category );81 return $ghostscript_present = false;82 }8384 if ( ‘WIN’ === strtoupper( substr( PHP_OS, 0, 3) ) ) {85 if ( ! empty( $explicit_path ) ) {86 $return = exec( ‘dir /o:n/s/b "’ . $explicit_path . ‘"’ );87 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, WIN explicit path = ' . var_export( $return, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );88 if ( ! empty( $return ) ) {89 return $ghostscript_present = true;90 } else {91 return $ghostscript_present = false;92 }93 }9495 $return = getenv(‘GSC’);96 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, getenv(GSC) = ' . var_export( $return, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );97 if ( ! empty( $return ) ) {98 return $ghostscript_present = true;99 }100101 $return = exec(‘where gswin*c.exe’);102 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, exec(where gswin*c.exe) = ' . var_export( $return, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );103 if ( ! empty( $return ) ) {104 return $ghostscript_present = true;105 }106107 $return = exec(‘dir /o:n/s/b "C:\Program Files\gs\*gswin*c.exe"’);108 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, exec(dir /o:n/s/b “C:\Program Files\gs\*gswin*c.exe”) = ' . var_export( $return, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );109 if ( ! empty( $return ) ) {110 return $ghostscript_present = true;111 }112113 $return = exec(‘dir /o:n/s/b "C:\Program Files (x86)\gs\*gswin32c.exe"’);114 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, exec(dir /o:n/s/b “C:\Program Files (x86)\gs\*gswin32c.exe”) = ' . var_export( $return, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );115 if ( ! empty( $return ) ) {116 return $ghostscript_present = true;117 }118119 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, WIN detection failed’, $mla_debug_category );120 return $ghostscript_present = false;121 } // Windows platform122123 if ( ! empty( $explicit_path ) ) {124 exec( 'test -e ' . $explicit_path, $dummy, $ghostscript_path );125 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, explicit path = ' . var_export( $explicit_path, true ) . ', ghostscript_path = ' . var_export( $ghostscript_path, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );126 return ( $explicit_path === $ghostscript_path );127 }128129 $return = exec(‘which gs’);130 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, exec(which gs) = ' . var_export( $return, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );131 if ( ! empty( $return ) ) {132 return $ghostscript_present = true;133 }134135 $test_path = '/usr/bin/gs’;136 $output = array();137 $return_arg = -1;138 $return = exec( 'test -e ' . $test_path, $output, $return_arg );139 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, test_path = ' . var_export( $test_path, true ) . ', return_arg = ' . var_export( $return_arg, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );140 MLACore::mla_debug_add( __LINE__ . ' <strong>MLAShortcode_Support::mla_ghostscript_present</strong>, return = ' . var_export( $return, true ) . ', output = ' . var_export( $output, true ), MLACore::MLA_DEBUG_CATEGORY_THUMBNAIL );141 return $ghostscript_present = ( $test_path === $return_arg );142 }143144 /**145 * Removes MIME type restriction from Photonic Gallery query146 *147 * @since 2.76148 *149 * @param object $wp_query Current WP_Query object150 */151 public static function _photonic_pre_get_posts( $wp_query ) {152 // This has already been applied in MLA’s database query153 $wp_query->set( 'post_mime_type’, ‘’ );154 }155156 /**157 * Informs _get_attachment_image_src() of the ‘size=icon_feature’ setting158 *159 * @since 2.90160 *161 * @var string shortcode ‘size’ parameter value162 */163 private static $size_parameter = '’;164165 /**166 * Informs _get_attachment_image_src() of the ‘size=icon_feature’ setting167 *168 * @since 3.00169 *170 * @var boolean ‘mla_use_featured’ parameter value171 */172 private static $mla_use_featured = false;173174 /**175 * Filters the image src result, returning the “Featured Image” or an icon to represent a non-image attachment.176 *177 * @since 2.76178 *179 * @param array|false $image Either array with src, width & height, icon src, or false.180 * @param int $attachment_id Image attachment ID.181 * @param string|array $size Size of image. Image size or array of width and height values182 * (in that order). Default 'thumbnail’.183 * @param bool $icon Whether the image should be treated as an icon. Default false.184 */185 public static function _get_attachment_image_src( $image, $attachment_id, $size, $icon ) {186 static $nested_call = false;187188 if ( $nested_call ) {189 return $image;190 }191192 if ( ‘none’ === self::$size_parameter ) {193 return false;194 } elseif ( ( ‘icon_only’ === self::$size_parameter ) || ( ‘icon_feature’ === self::$size_parameter ) ) {195 // No native images allowed196 $image = false;197 }198199 // Look for the “Featured Image” as an alternate thumbnail for PDFs, etc.200 if ( self::$mla_use_featured && ( ‘checked’ == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_FEATURED_IMAGE ) ) ) {201 $nested_call = true;202 $feature = get_the_post_thumbnail( $attachment_id, $size, array( ‘class’ => ‘attachment-thumbnail’ ) );203 $nested_call = false;204205 if ( ! empty( $feature ) ) {206 $match_count = preg_match_all( '# width=\"([^\"]+)\" height=\"([^\"]+)\" src=\"([^\"]+)\" #’, $feature, $matches, PREG_OFFSET_CAPTURE );207 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {208 $image = array( $matches[3][0][0], $matches[1][0][0], $matches[2][0][0] );209 return $image;210 }211 }212 } // enable_featured_image213214 // If a native image exists, we’re done215 if ( false !== $image ) {216 return $image;217 }218219 // Look for the “Featured Image” as an alternate thumbnail for PDFs, etc.220 if ( ( ‘icon_only’ !== self::$size_parameter ) && ( ‘checked’ == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_FEATURED_IMAGE ) ) ) {221 $nested_call = true;222 $feature = get_the_post_thumbnail( $attachment_id, $size, array( ‘class’ => ‘attachment-thumbnail’ ) );223 $nested_call = false;224225 if ( ! empty( $feature ) ) {226 $match_count = preg_match_all( '# width=\"([^\"]+)\" height=\"([^\"]+)\" src=\"([^\"]+)\" #’, $feature, $matches, PREG_OFFSET_CAPTURE );227 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {228 $image = array( $matches[3][0][0], $matches[1][0][0], $matches[2][0][0] );229 return $image;230 }231 }232 } // enable_featured_image233234 // For any of the three “icon” variations, try to substitute an icon image235 if ( 0 === strpos( self::$size_parameter, ‘icon’ ) ) {236 if ( $src = wp_mime_type_icon( $attachment_id ) ) {237 /** This filter is documented in wp-includes/post.php */238 $icon_dir = apply_filters( 'icon_dir’, ABSPATH . WPINC . ‘/images/media’ );239240 $src_file = $icon_dir . ‘/’ . wp_basename( $src );241 @list( $width, $height ) = getimagesize( $src_file );242 }243244 if ( $src && $width && $height ) {245 $image = array( $src, $width, $height );246 }247 }248249 return $image;250 }251252 /**253 * Errors found in function mla_validate_attributes()254 *255 * @since 2.80256 *257 * @var array258 */259 private static $attributes_errors = array();260261 /**262 * Make sure $attr is an array, repair line-break damage, merge with $content263 *264 * @since 2.20265 *266 * @param mixed $attr Array or string containing shortcode attributes267 * @param string $content Optional content for enclosing shortcodes268 *269 * @return array clean attributes array270 */271 public static function mla_validate_attributes( $attr, $content = NULL ) {272//error_log( __LINE__ . " mla_validate_attributes() attr = " . var_export( $attr, true ), 0 );273//error_log( __LINE__ . " mla_validate_attributes() content = " . var_export( $content, true ), 0 );274275 if ( is_string( $attr ) ) {276 $attr = shortcode_parse_atts( $attr );277 }278279 if ( empty( $attr ) ) {280 $attr = array();281 }282//error_log( __LINE__ . " mla_validate_attributes() attr = " . var_export( $attr, true ), 0 );283284 // Numeric keys indicate parse errors285 $not_valid = false;286 foreach ( $attr as $key => $value ) {287 // Clean up damage caused by the Visual Editor 288 $attr[ $key ] = wp_specialchars_decode( $value );289290 if ( is_numeric( $key ) ) {291 $not_valid = true;292 break;293 }294 }295//error_log( __LINE__ . " mla_validate_attributes() attr = " . var_export( $attr, true ), 0 );296297 if ( $not_valid ) {298 /*299 * Found an error, e.g., line break(s) among the atttributes.300 * Try to reconstruct the input string without them.301 */302 $new_attr = '’;303 foreach ( $attr as $key => $value ) {304 $value = str_replace( array( '&’, '‘’, '’’, '“’, '”’, '′’, '″’, '&’, '<br />’, '<br>’, '<p>’, ‘</p>’, “\r", “\n", “\t” ),305 array( '&’, '\’’, '\’’, '"’, '"’, '\’’, '"’, '&’, ' ', ' ', ' ', ' ', ' ', ' ', ' ' ), $value );306//error_log( __LINE__ . " mla_validate_attributes() [{$key}] value = " . var_export( $value, true ), 0 );307 $break_tag = strpos( $value, ‘<br’ );308 if ( ( false !== $break_tag ) && ( ($break_tag + 3) == strlen( $value ) ) ) {309 $value = substr( $value, 0, ( strlen( $value ) - 3) );310 }311312 if ( is_numeric( $key ) ) {313 if ( ‘/>’ !== $value ) {314 $new_attr .= $value . ' ';315 }316 } else {317 $delimiter = ( false === strpos( $value, ‘"’ ) ) ? ‘"’ : “’";318 $new_attr .= $key . ‘=’ . $delimiter . $value . $delimiter . ' ';319 }320 }321//error_log( __LINE__ . " mla_validate_attributes() new_attr = " . var_export( $new_attr, true ), 0 );322323 $attr = shortcode_parse_atts( $new_attr );324//error_log( __LINE__ . " mla_validate_attributes() attr = " . var_export( $attr, true ), 0 );325326 // Remove empty values and still-invalid parameters327 $new_attr = array();328 foreach ( $attr as $key => $value ) {329 if ( is_numeric( $key ) || empty( $value ) ) {330 self::$attributes_errors[‘raw’][] = '[' . $key . '] => ' . $value;331 self::$attributes_errors[‘escaped’][] = '[' . $key . '] => ' . esc_html( $value );332 continue;333 }334335 $new_attr[ $key ] = $value;336 }337338 $attr = $new_attr;339 } // not_valid340//error_log( __LINE__ . " mla_validate_attributes() attr = " . var_export( $attr, true ), 0 );341342 // Look for parameters in an enclosing shortcode343 if ( ! ( empty( $content ) || isset( $attr[‘mla_alt_shortcode’] ) ) ) {344 $content = str_replace( array( '&’, '‘’, '’’, '“’, '”’, '′’, '″’, '&’, '<br />’, '<br>’, '<p>’, '</p>’, “\r", “\n", “\t” ),345 array( '&’, '\’’, '\’’, '"’, '"’, '\’’, '"’, '&’, ' ', ' ', ' ', ' ', ' ', ' ', ' ' ), $content );346 $content_attr = shortcode_parse_atts( $content );347//error_log( __LINE__ . " mla_validate_attributes() content_attr = " . var_export( $content_attr, true ), 0 );348 if ( is_array( $content_attr ) ) {349 // Remove empty values and still-invalid parameters350 $new_attr = array();351 foreach ( $content_attr as $key => $value ) {352 if ( is_numeric( $key ) || ( 0 === strlen( $value ) ) ) { // empty( $value ) ) {353 self::$attributes_errors[‘raw’][] = 'content [' . $key . '] => ' . $value;354 self::$attributes_errors[‘escaped’][] = 'content [' . $key . '] => ' . esc_html( $value );355 continue;356 }357358 $new_attr[ $key ] = $value;359 }360361 $attr = array_merge( $attr, $new_attr );362 }363 }364365 return $attr;366 }367368 /**369 * Turn debug collection and display on or off370 *371 * @since 2.20372 *373 * @var boolean374 */375 private static $mla_debug = false;376377 /**378 * Default values when global $post is not set379 *380 * @since 2.40381 *382 * @var array383 */384 private static $empty_post = array( 385 ‘ID’ => 0,386 ‘post_author’ => 0,387 ‘post_date’ => '0000-00-00 00:00:00’,388 ‘post_date_gmt’ => '0000-00-00 00:00:00’,389 ‘post_content’ => '’,390 ‘post_title’ => '’,391 ‘post_excerpt’ => '’,392 ‘post_status’ => 'publish’,393 ‘comment_status’ => 'open’,394 ‘ping_status’ => 'open’,395 ‘post_name’ => '’,396 ‘to_ping’ => 'None’,397 ‘pinged’ => 'None’,398 ‘post_modified’ => '0000-00-00 00:00:00’,399 ‘post_modified_gmt’ => '0000-00-00 00:00:00’,400 ‘post_content_filtered’ => 'None’,401 ‘post_parent’ => 0,402 ‘guid’ => '’,403 ‘menu_order’ => 0,404 ‘post_type’ => 'post’,405 ‘post_mime_type’ => '’,406 ‘comment_count’ => 0,407 );408409 /**410 * Default post object generator411 *412 * @since 3.10413 *414 * @return object Post objct with default or “quthor” information415 */416 private static function _get_default_post() {417 if ( is_author() ) {418 $author_post = (object) self::$empty_post;419420 $author_post->ID = get_the_author_meta( ‘ID’ );421 $author_post->post_author = get_the_author_meta( ‘ID’ );422 $author_post->post_title = get_the_author_meta( ‘display_name’ );423 $author_post->post_excerpt = get_the_author_meta( ‘nickname’ );424 $author_post->post_name = get_the_author_meta( ‘user_nicename’ );425 $author_post->post_content = get_the_author_meta( ‘description’ );426 $author_post->post_type = 'author’;427428 return $author_post;429 }430431 return (object) self::$empty_post;432 }433434 /**435 * The MLA Gallery shortcode.436 *437 * This is a superset of the WordPress Gallery shortcode for displaying images on a post,438 * page or custom post type. It is adapted from /wp-includes/media.php gallery_shortcode.439 * Enhancements include many additional selection parameters and full taxonomy support.440 *441 * @since 2.20442 *443 * @param array $attr Attributes of the shortcode444 * @param string $content Optional content for enclosing shortcodes445 *446 * @return string HTML content to display gallery.447 */448 public static function mla_gallery_shortcode( $attr, $content = NULL ) {449//error_log( __LINE__ . " mla_gallery_shortcode() _REQUEST = " . var_export( $_REQUEST, true ), 0 );450//error_log( __LINE__ . " mla_gallery_shortcode() attr = " . var_export( $attr, true ), 0 );451//error_log( __LINE__ . " mla_gallery_shortcode() content = " . var_export( $content, true ), 0 );452 global $post;453454 // Some do_shortcode callers may not have a specific post in mind455 if ( ! is_object( $post ) ) {456 $post = self::_get_default_post();457 }458459 // $instance supports multiple galleries in one page/post 460 static $instance = 0;461 $instance++;462463 // Some values are already known, and can be used in data selection parameters464 $upload_dir = wp_upload_dir();465 $page_values = array(466 ‘instance’ => $instance,467 ‘selector’ => “mla_gallery-{$instance}",468 ‘site_url’ => site_url(),469 ‘base_url’ => $upload_dir[‘baseurl’],470 ‘base_dir’ => $upload_dir[‘basedir’],471 ‘id’ => $post->ID,472 ‘page_ID’ => $post->ID,473 ‘page_author’ => $post->post_author,474 ‘page_date’ => $post->post_date,475 ‘page_content’ => $post->post_content,476 ‘page_title’ => $post->post_title,477 ‘page_excerpt’ => $post->post_excerpt,478 ‘page_status’ => $post->post_status,479 ‘page_name’ => $post->post_name,480 ‘page_modified’ => $post->post_modified,481 ‘page_parent’ => $post->post_parent,482 ‘page_guid’ => $post->guid,483 ‘page_type’ => $post->post_type,484 ‘page_mime_type’ => $post->post_mime_type,485 ‘page_url’ => get_page_link(),486 );487488 /*489 * Make sure $attr is an array, even if it’s empty,490 * and repair damage caused by link-breaks in the source text491 */492 $attr = self::mla_validate_attributes( $attr, $content );493494 // Filter the attributes before $mla_page_parameter and “request:” prefix processing.495 $attr = apply_filters( 'mla_gallery_raw_attributes’, $attr );496497 /*498 * The mla_paginate_current parameter can be changed to support499 * multiple galleries per page.500 */501 if ( ! isset( $attr[‘mla_page_parameter’] ) ) {502 $attr[‘mla_page_parameter’] = self::$mla_get_shortcode_attachments_parameters[‘mla_page_parameter’];503 }504505 // The mla_page_parameter can contain page_level parameters like {+page_ID+}506 $attr_value = str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $attr[‘mla_page_parameter’] ) );507 $mla_page_parameter = MLAData::mla_parse_template( $attr_value, $page_values );508509 /*510 * Special handling of the mla_paginate_current parameter to make511 * “MLA pagination” easier. Look for this parameter in $_REQUEST512 * if it’s not present in the shortcode itself.513 */514 if ( ! isset( $attr[ $mla_page_parameter ] ) ) {515 if ( isset( $_REQUEST[ $mla_page_parameter ] ) ) {516 $attr[ $mla_page_parameter ] = sanitize_text_field( wp_unslash( $_REQUEST[ $mla_page_parameter ] ) );517 }518 }519520 // These are the parameters for gallery display521 $mla_item_specific_arguments = array(522 ‘mla_link_attributes’ => '’,523 ‘mla_link_class’ => '’,524 ‘mla_link_href’ => '’,525 ‘mla_link_text’ => '’,526 ‘mla_nolink_text’ => '’,527 ‘mla_rollover_text’ => '’,528 ‘mla_image_class’ => '’,529 ‘mla_image_alt’ => '’,530 ‘mla_image_attributes’ => '’,531 ‘mla_caption’ => '’,532 ‘mla_alt_ids_value’ => NULL,533 );534535 // These arguments must not be passed on to alternate gallery shortcodes536 $mla_arguments = array_merge( array(537 ‘mla_minimum’ => '0’,538 ‘mla_output’ => 'gallery’,539 ‘mla_style’ => MLACore::mla_get_option(‘default_style’),540 ‘mla_markup’ => MLACore::mla_get_option(‘default_markup’),541 ‘mla_float’ => 'none’, // before v2.90: is_rtl() ? ‘right’ : 'left’,542 ‘mla_itemwidth’ => MLACore::mla_get_option(‘mla_gallery_itemwidth’),543 ‘mla_margin’ => MLACore::mla_get_option(‘mla_gallery_margin’),544 ‘mla_target’ => '’,545 ‘mla_debug’ => false,546 ‘mla_allow_rml’ => false,547 ‘mla_rml_folder’ => NULL,548 ‘mla_rml_include_children’ => false,549 ‘mla_allow_catf’ => true,550 ‘mla_catf_folder’ => NULL,551552 ‘mla_named_transfer’ => false,553 ‘mla_use_featured’ => false,554 ‘mla_viewer’ => false,555 ‘mla_single_thread’ => false,556 ‘mla_viewer_extensions’ => 'ai,eps,pdf,ps’,557 ‘mla_viewer_limit’ => '0’,558 ‘mla_viewer_width’ => '0’,559 ‘mla_viewer_height’ => '0’,560 ‘mla_viewer_best_fit’ => NULL,561 ‘mla_viewer_page’ => '1’,562 ‘mla_viewer_resolution’ => '0’,563 ‘mla_viewer_quality’ => '0’,564 ‘mla_viewer_type’ => '’,565566 ‘mla_alt_shortcode’ => NULL,567 ‘mla_alt_ids_name’ => 'ids’,568 ‘mla_alt_ids_template’ => NULL,569 ‘mla_alt_parameters’ => NULL,570 // paginatation arguments defined in $mla_get_shortcode_attachments_parameters571 // ‘mla_page_parameter’ => 'mla_paginate_current’, handled in code with $mla_page_parameter572 // ‘mla_paginate_current’ => NULL,573 // ‘mla_paginate_total’ => NULL,574 // ‘id’ => NULL,575576 'mla_end_size’=> 1,577 ‘mla_mid_size’ => 2,578 ‘mla_prev_text’ => '« ' . __( 'Previous’, ‘media-library-assistant’ ),579 ‘mla_next_text’ => __( 'Next’, ‘media-library-assistant’ ) . ' »’,580 ‘mla_paginate_type’ => 'plain’,581 ‘mla_paginate_rows’ => NULL ),582 $mla_item_specific_arguments583 );584585 $html5 = current_theme_supports( 'html5’, ‘gallery’ );586 $default_arguments = array_merge( array(587 ‘size’ => 'thumbnail’, // or 'medium’, 'large’, ‘full’ or registered size588 ‘itemtag’ => $html5 ? ‘figure’ : 'dl’,589 ‘icontag’ => $html5 ? ‘div’ : 'dt’,590 ‘captiontag’ => $html5 ? ‘figcaption’ : 'dd’,591 ‘columns’ => MLACore::mla_get_option(‘mla_gallery_columns’),592 ‘link’ => 'permalink’, // or 'post’, 'file’, a registered size, etc.593 // Photonic-specific594 ‘id’ => NULL,595 ‘style’ => NULL,596 ‘type’ => 'default’, // also used by WordPress.com Jetpack!597 ‘thumb_width’ => 75,598 ‘thumb_height’ => 75,599 ‘thumbnail_size’ => 'thumbnail’,600 ‘slide_size’ => 'large’,601 ‘slideshow_height’ => 500,602 ‘fx’ => 'fade’,603 ‘timeout’ => 4000,604 ‘speed’ => 1000,605 ‘pause’ => NULL),606 $mla_arguments607 );608609 // Convert to boolean610 $arguments[‘mla_named_transfer’] = ‘true’ === ( ( ! empty( $arguments[‘mla_named_transfer’] ) ) ? trim( strtolower( $arguments[‘mla_named_transfer’] ) ) : ‘false’ );611612 // Apply default arguments set in the markup template613 $template = $mla_arguments[‘mla_markup’];614 if ( isset( $attr[‘mla_markup’] ) && MLATemplate_Support::mla_fetch_custom_template( $attr[‘mla_markup’], 'gallery’, 'markup’, '[exists]' ) ) {615 $template = $attr[‘mla_markup’];616 }617618 $arguments = MLATemplate_Support::mla_fetch_custom_template( $template, 'gallery’, 'markup’, ‘arguments’ );619 if ( ! empty( $arguments ) ) {620 $attr = wp_parse_args( $attr, self::mla_validate_attributes( array(), $arguments ) );621 }622623 /*624 * Look for page-level, ‘request:’ and ‘query:’ substitution parameters,625 * which can be added to any input parameter626 */627 foreach ( $attr as $attr_key => $attr_value ) {628 /*629 * attachment-specific Gallery Display Content parameters must be evaluated630 * later, when all of the information is available.631 */632 if ( array_key_exists( $attr_key, $mla_item_specific_arguments ) ) {633 continue;634 }635636 // Don’t expand anything passed along to the alternate shortcode637 if ( ‘mla_alt_parameters’ === $attr_key ) {638 continue;639 }640641 $attr_value = str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $attr_value ) );642 $replacement_values = MLAData::mla_expand_field_level_parameters( $attr_value, $attr, $page_values );643 $attr[ $attr_key ] = MLAData::mla_parse_template( $attr_value, $replacement_values );644 }645646 // Merge gallery arguments with defaults, pass the query arguments on to mla_get_shortcode_attachments.647 $attr = apply_filters( 'mla_gallery_attributes’, $attr );648 $content = apply_filters( 'mla_gallery_initial_content’, $content, $attr );649 $arguments = shortcode_atts( $default_arguments, $attr );650 $arguments = apply_filters( 'mla_gallery_arguments’, $arguments );651652 // Decide which templates to use653 if ( ( ‘none’ !== $arguments[‘mla_style’] ) && ( ‘theme’ !== $arguments[‘mla_style’] ) ) {654 if ( !MLATemplate_Support::mla_fetch_custom_template( $arguments[‘mla_style’], 'gallery’, ‘style’, '[exists]' ) ) {655 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_gallery mla_style</strong> "’ . $arguments[‘mla_style’] . '” ' . __( 'not found’, ‘media-library-assistant’ ), MLACore::MLA_DEBUG_CATEGORY_ANY );656 $arguments[‘mla_style’] = $default_arguments[‘mla_style’];657 }658 }659660 if ( !MLATemplate_Support::mla_fetch_custom_template( $arguments[‘mla_markup’], 'gallery’, ‘markup’, '[exists]' ) ) {661 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_gallery mla_markup</strong> "’ . $arguments[‘mla_markup’] . '” ' . __( 'not found’, ‘media-library-assistant’ ), MLACore::MLA_DEBUG_CATEGORY_ANY );662 $arguments[‘mla_markup’] = $default_arguments[‘mla_markup’];663 }664665 // Look for alternate gallery shortcode special cases666 if ( is_string( $arguments[‘mla_alt_shortcode’] ) ) {667 // Special value to avoid Justified Image Grid conflict668 if ( ‘yes’ === $arguments[‘mla_alt_shortcode’] ) {669 $arguments[‘mla_alt_shortcode’] = 'mla_gallery’;670 } elseif ( in_array( $arguments[‘mla_alt_shortcode’], array( 'mla_gallery’, ‘no’ ) ) ) {671 // Handle “no effect” alternate gallery shortcode to support plugins such as Justified Image Grid672 $arguments[‘mla_alt_shortcode’] = NULL;673 $arguments[‘mla_alt_ids_name’] = ‘ids’;674 $arguments[‘mla_alt_ids_value’] = NULL;675 $arguments[‘mla_alt_ids_template’] = NULL;676 $arguments[‘mla_alt_parameters’] = NULL;677 }678 }679680 self::$mla_debug = ( ! empty( $arguments[‘mla_debug’] ) ) ? trim( strtolower( $arguments[‘mla_debug’] ) ) : false;681 if ( self::$mla_debug ) {682 if ( ‘true’ == self::$mla_debug ) {683 MLACore::mla_debug_mode( ‘buffer’ );684 } elseif ( ‘log’ == self::$mla_debug ) {685 MLACore::mla_debug_mode( ‘log’ );686 } else {687 self::$mla_debug = false;688 }689 }690691 if ( self::$mla_debug ) {692 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug REQUEST’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $_REQUEST, true ) );693694 if ( ! empty( self::$attributes_errors ) ) {695 if ( ‘log’ == self::$mla_debug ) {696 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug attributes_errors’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( self::$attributes_errors[‘raw’], true ) );697 } else {698 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug attributes_errors’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( self::$attributes_errors[‘escaped’], true ) );699 }700701 self::$attributes_errors = array();702 }703704 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug attributes’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $attr, true ) );705 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug arguments’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $arguments, true ) );706 }707708 // Determine output type709 $output_parameters = array_map( 'strtolower’, array_map( 'trim’, explode( ',’, $arguments[‘mla_output’] ) ) );710 if ( ! in_array( $output_parameters[0], array( 'gallery’, 'next_link’, 'current_link’, 'previous_link’, 'next_page’, 'previous_page’, ‘paginate_links’ ) ) ) {711 $output_parameters[0] = 'gallery’;712 }713714 $is_gallery = ‘gallery’ == $output_parameters[0];715 $is_pagination = in_array( $output_parameters[0], array( 'previous_page’, 'next_page’, ‘paginate_links’ ) ); 716717 if ( $is_pagination && ( NULL !== $arguments[‘mla_paginate_rows’] ) ) {718 $attachments[‘found_rows’] = absint( $arguments[‘mla_paginate_rows’] );719 } else {720 // Look for negative phrases in keyword search721 if ( ! empty( $attr[‘s’] ) ) {722 $term_delimiter = /* ! empty( $attr[‘mla_term_delimiter’] ) ? $attr[‘mla_term_delimiter’] : */ ',’;723 $negative_delimiter = ! empty( $attr[‘mla_negative_delimiter’] ) ? $attr[‘mla_negative_delimiter’] : '/’;724 $search_phrases = MLAQuery::mla_divide_search_string( $attr[‘s’], $term_delimiter, $negative_delimiter );725726 if ( ! empty( $search_phrases[‘negative’] ) ) {727 $negative_arguments = $attr;728 unset( $negative_arguments[ $mla_page_parameter ] );729 unset( $negative_arguments[‘nopaging’] );730 unset( $negative_arguments[‘offset’] );731 unset( $negative_arguments[‘paged’] );732 $negative_arguments[‘orderby’] = 'none’;733 $save_excludes = explode( ',’, ! empty( $negative_arguments[‘exclude’] ) ? $negative_arguments[‘exclude’] : ‘’ );734 $negative_arguments[‘exclude’] = '’;735736 $negative_arguments[‘s’] = $search_phrases[‘negative’];737 $negative_arguments[‘fields’] = 'ids’;738 $excluded_items = self::mla_get_shortcode_attachments( $post->ID, $negative_arguments, false );739740 $attr[‘s’] = $search_phrases[‘positive’];741 $attr[‘exclude’] = implode( ',’, array_merge( $save_excludes, $excluded_items ) );742 }743 }744745 // Look for negative phrases in taxonomy term keyword search746 if ( ! empty( $attr[‘mla_terms_phrases’] ) ) {747 $term_delimiter = ! empty( $attr[‘mla_term_delimiter’] ) ? $attr[‘mla_term_delimiter’] : ',’;748 $negative_delimiter = ! empty( $attr[‘mla_negative_delimiter’] ) ? $attr[‘mla_negative_delimiter’] : '/’;749 $search_phrases = MLAQuery::mla_divide_search_string( $attr[‘mla_terms_phrases’], $term_delimiter, $negative_delimiter );750751 if ( ! empty( $search_phrases[‘negative’] ) ) {752 $negative_arguments = $attr;753 unset( $negative_arguments[ $mla_page_parameter ] );754 unset( $negative_arguments[‘nopaging’] );755 unset( $negative_arguments[‘offset’] );756 unset( $negative_arguments[‘paged’] );757 $negative_arguments[‘orderby’] = 'none’;758 $save_excludes = explode( ',’, ! empty( $negative_arguments[‘exclude’] ) ? $negative_arguments[‘exclude’] : ‘’ );759 $negative_arguments[‘exclude’] = '’;760761 $negative_arguments[‘mla_terms_phrases’] = $search_phrases[‘negative’];762 $negative_arguments[‘fields’] = 'ids’;763 $excluded_items = self::mla_get_shortcode_attachments( $post->ID, $negative_arguments, false );764765 $attr[‘mla_terms_phrases’] = $search_phrases[‘positive’];766 $attr[‘exclude’] = implode( ‘,’, array_merge( $save_excludes, $excluded_items ) );767 }768 }769770 $attachments = self::mla_get_shortcode_attachments( $post->ID, $attr, true );771 }772773 if ( is_string( $attachments ) ) {774 return $attachments;775 }776777 $current_rows = count( $attachments );778779 if ( isset( $attachments[‘max_num_pages’] ) ) {780 $max_num_pages = $attachments[‘max_num_pages’];781 unset( $attachments[‘max_num_pages’] );782 $current_rows–;783 } else {784 $max_num_pages = 1;785 }786787 if ( isset( $attachments[‘found_rows’] ) ) {788 $found_rows = $attachments[‘found_rows’];789 unset( $attachments[‘found_rows’] );790 $current_rows–;791 } else {792 $found_rows = $current_rows;793 }794795 $mla_minimum = absint( $arguments[‘mla_minimum’] );796 if ( 0 < $mla_minimum ) {797 if ( $is_gallery && ( empty($attachments) || count($attachments) < $mla_minimum ) ) {798 $attachments = array();799 }800 801 if ( $is_pagination && empty( $found_rows ) || $found_rows < $mla_minimum ) {802 $found_rows = 0;803 }804 }805 806 if ( ( $is_gallery && empty($attachments) ) || ( $is_pagination && empty( $found_rows ) ) ) {807 if ( self::$mla_debug ) {808 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug empty gallery’, ‘media-library-assistant’ ) . '</strong>, query = ' . var_export( $attr, true ) );809 $output = MLACore::mla_debug_flush();810 } else {811 $output = '’;812 }813814 if ( ! empty( $arguments[‘mla_nolink_text’] ) ) {815 $attr_value = str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $arguments[‘mla_nolink_text’] ) );816 $replacement_values = MLAData::mla_expand_field_level_parameters( $attr_value, $attr, $page_values );817 $output .= MLAData::mla_parse_template( $attr_value, $replacement_values );818 }819820 return $output;821 } // empty $attachments822823 // Pass size argument to _get_attachment_image_src() and replace special values824 $size = strtolower( $arguments[‘size’] );825 self::$size_parameter = $size;826827 // Pass mla_use_featured argument to _get_attachment_image_src() and replace special values828 self::$mla_use_featured = !empty( $arguments[‘mla_use_featured’] ) ? ‘true’ === strtolower( $arguments[‘mla_use_featured’] ) : false;829830 if ( ( ‘icon_only’ === $size ) || ( ‘icon_feature’ === $size ) ) {831 $size = 'icon’;832 }833834 $size_class = $size;835836 // Look for Photonic-enhanced gallery; use the [gallery] shortcode if found837 global $photonic;838839 $is_photonic = false;840 if ( is_object( $photonic ) && ! empty( $arguments[‘style’] ) && empty( $arguments[‘mla_alt_shortcode’] ) ) {841 if ( ‘default’ != strtolower( $arguments[‘type’] ) ) {842 return ‘<p>’ . __( '<strong>Photonic-enhanced [mla_gallery]</strong> type must be <strong>default</strong>, query = ', ‘media-library-assistant’ ) . var_export( $attr, true ) . '</p>’;843 }844845 if ( isset( $arguments[‘pause’] ) && ( ‘false’ == $arguments[‘pause’] ) ) {846 $arguments[‘pause’] = NULL;847 }848849 $arguments[‘mla_alt_shortcode’] = 'gallery’;850 $is_photonic = true;851 }852853 // Look for user-specified alternate gallery shortcode854 $processing_alt_ids_value = false;855 if ( is_string( $arguments[‘mla_alt_shortcode’] ) ) {856 // Replace data-selection parameters with the “ids” list857 $blacklist = array_merge( self::$mla_get_shortcode_attachments_parameters, self::$mla_get_shortcode_dynamic_attachments_parameters );858859 // Other MLA shortcodes use some of the same parameters, e.g., mla_link_href, so let them thru860 if ( !in_array( $arguments[‘mla_alt_shortcode’], array( 'mla_tag_cloud’, ‘mla_term_list’ ) ) ) {861 $blacklist = array_merge( $mla_arguments, $blacklist );862 }863864 // Suppress mla_alt… shortcode arguments in second mla_gallery865 if ( ‘mla_gallery’ === $arguments[‘mla_alt_shortcode’] ) {866 $blacklist = array_merge( $blacklist, array( 867 ‘mla_alt_shortcode’ => NULL,868 ‘mla_alt_ids_name’ => 'ids’,869 ‘mla_alt_ids_value’ => NULL,870 ‘mla_alt_ids_template’ => NULL,871 ‘mla_alt_parameters’ => NULL,872 ) 873 );874 }875876 $blacklist = apply_filters( 'mla_gallery_alt_shortcode_blacklist’, $blacklist );877 $alt_attr = apply_filters( 'mla_gallery_alt_shortcode_attributes’, $attr );878//error_log( __LINE__ . " alt_attr = " . var_export( $alt_attr, true ), 0 );879880 // Allow for overide of blacklist values, e.g., post_mime_type881 $alt_parameters = array();882 if ( !empty( $alt_attr[‘mla_alt_parameters’] ) ) {883 $alt_parameters = self::mla_validate_attributes( $alt_attr[‘mla_alt_parameters’] );884//error_log( __LINE__ . " alt_parameters = " . var_export( $alt_parameters, true ), 0 );885 unset( $alt_attr[‘mla_alt_parameters’] );886 $alt_attr = array_merge( $alt_attr, $alt_parameters );887 }888//error_log( __LINE__ . " alt_attr = " . var_export( $alt_attr, true ), 0 );889890 $mla_alt_shortcode_args = array();891 foreach ( $alt_attr as $key => $value ) {892 if ( array_key_exists( $key, $blacklist ) && ( !array_key_exists( $key, $alt_parameters ) ) ) {893 continue;894 }895896 $slashed = addcslashes( $value, chr(0).chr(7).chr(8)."\f\n\r\t\v\"\\\$” );897 if ( ( false !== strpos( $value, ' ' ) ) || ( false !== strpos( $value, ‘\’’ ) ) || ( $slashed != $value ) ) {898 $value = ‘"’ . $slashed . '"’;899 }900901 $mla_alt_shortcode_args[] = $key . ‘=’ . $value;902 } // foreach $attr903//error_log( __LINE__ . " mla_alt_shortcode_args = " . var_export( $mla_alt_shortcode_args, true ), 0 );904905906 $mla_alt_shortcode_args = implode( ' ', $mla_alt_shortcode_args );907908 // Restore original delimiters909 $mla_alt_shortcode_args = str_replace( '[+’, '{+’, str_replace( '+]', '+}’, $mla_alt_shortcode_args ) );910//error_log( __LINE__ . " mla_alt_shortcode_args = " . var_export( $mla_alt_shortcode_args, true ), 0 );911912 /*913 * If an alternate value has been specified we must delay alt shortcode execution914 * and accumulate $mla_alt_shortcode_ids in the template Item section.915 */916 $mla_alt_ids_value = is_null( $arguments[‘mla_alt_ids_value’] ) ? NULL : str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $arguments[‘mla_alt_ids_value’] ) );917 $mla_alt_shortcode_ids = array();918 $mla_alt_ids_template = is_null( $arguments[‘mla_alt_ids_template’] ) ? NULL : str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $arguments[‘mla_alt_ids_template’] ) );919920 if ( is_null( $mla_alt_ids_value ) ) {921 $mla_alt_shortcode_ids = apply_filters_ref_array( 'mla_gallery_alt_shortcode_ids’, array( $mla_alt_shortcode_ids, $arguments[‘mla_alt_ids_name’], &$attachments ) );922 if ( is_array( $mla_alt_shortcode_ids ) ) {923 if ( 0 == count( $mla_alt_shortcode_ids ) ) {924 foreach ( $attachments as $value ) {925 $mla_alt_shortcode_ids[] = $value->ID;926 } // foreach $attachments927 }928929 // Apply the template when mla_alt_ids_template present930 if ( is_string( $mla_alt_ids_template ) ) {931 $page_values[‘alt_ids’] = implode( ',’, $mla_alt_shortcode_ids );932 $replacement_values = MLAData::mla_expand_field_level_parameters( $mla_alt_ids_template, $attr, $page_values );933 $mla_alt_shortcode_ids = $arguments[‘mla_alt_ids_name’] . ‘="’ . MLAData::mla_parse_template( $mla_alt_ids_template, $replacement_values ) . '"’;934 unset( $page_values[‘alt_ids’] );935 } else {936 $mla_alt_shortcode_ids = $arguments[‘mla_alt_ids_name’] . ‘="’ . implode( ',’, $mla_alt_shortcode_ids ) . '"’;937 }938 }939940 if ( self::$mla_debug ) {941 $output = MLACore::mla_debug_flush();942 } else {943 $output = '’;944 }945946 // Execute the alternate gallery shortcode with the new parameters947 $content = apply_filters( 'mla_gallery_final_content’, $content );948949 if ( $is_photonic ) {950 add_filter( 'pre_get_posts’, 'MLAShortcode_Support::_photonic_pre_get_posts’, 10, 4 );951 add_filter( 'wp_get_attachment_image_src’, 'MLAShortcode_Support::_get_attachment_image_src’, 10, 4 );952 }953954 if ( ! empty( $content ) ) {955 $output .= do_shortcode( sprintf( '[%1$s %2$s %3$s]%4$s[/%1$s]', $arguments[‘mla_alt_shortcode’], $mla_alt_shortcode_ids, $mla_alt_shortcode_args, $content ) );956 } else {957 $output .= do_shortcode( sprintf( '[%1$s %2$s %3$s]', $arguments[‘mla_alt_shortcode’], $mla_alt_shortcode_ids, $mla_alt_shortcode_args ) );958 }959960 if ( $is_photonic ) {961 remove_filter( 'wp_get_attachment_image_src’, ‘MLAShortcode_Support::_get_attachment_image_src’ );962 remove_filter( 'pre_get_posts’, ‘MLAShortcode_Support::_photonic_pre_get_posts’ );963 }964965 do_action( ‘mla_gallery_end_alt_shortcode’ );966 return $output;967 } /* is_null( $mla_alt_ids_value ) */ else {968 /*969 * If an alternate value has been specified we must delay alt shortcode execution970 * and accumulate $mla_alt_shortcode_ids in the template Item section.971 */972 $processing_alt_ids_value = true;973 }974 } // mla_alt_shortcode975976 if ( ‘icon’ == strtolower( $size ) ) {977 if ( ‘checked’ == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_MLA_ICONS ) ) {978 $size = array( 64, 64 );979 } else {980 $size = array( 60, 60 );981 }982 }983984 // Feeds such as RSS, Atom or RDF do not require styled and formatted output985 if ( is_feed() ) {986 $output = “\n";987 foreach ( $attachments as $att_id => $attachment )988 $output .= wp_get_attachment_link( $att_id, $size, true ) . “\n";989 return $output;990 }991992 // Check for Imagick thumbnail generation arguments993 $mla_viewer_required = false;994 if ( ‘checked’ == MLACore::mla_get_option( ‘enable_mla_viewer’ ) ) {995 if ( ! empty( $arguments[‘mla_viewer’] ) ) {996 // Split out the required suffix997 $mla_viewer_args = explode( ',’, strtolower( $arguments[‘mla_viewer’] ) ) ;998 $mla_viewer_required = ( 1 < count( $mla_viewer_args ) && ‘required’ == $mla_viewer_args[1] );9991000 if ( ‘single’ == $mla_viewer_args[0] ) {1001 $arguments[‘mla_single_thread’] = true; 1002 $arguments[‘mla_viewer’] = true;1003 } elseif ( ‘true’ == $mla_viewer_args[0] ) {1004 $arguments[‘mla_viewer’] = true;1005 } elseif ( ‘required’ == $mla_viewer_args[0] ) {1006 $mla_viewer_required = true;1007 $arguments[‘mla_viewer’] = true;1008 } else {1009 $arguments[‘mla_viewer’] = false;1010 }1011 }1012 } else {1013 $arguments[‘mla_viewer’] = false;1014 }10151016 if ( $arguments[‘mla_viewer’] ) {1017 // Test for Ghostscript here so debug messages can be recorded1018 $ghostscript_path = MLACore::mla_get_option( ‘ghostscript_path’ );1019 if ( self::mla_ghostscript_present( $ghostscript_path ) ) {1020 $arguments[‘mla_viewer_extensions’] = array_filter( array_map( 'trim’, explode( ',’, $arguments[‘mla_viewer_extensions’] ) ) );1021 } else {1022 $arguments[‘mla_viewer_extensions’] = array();1023 }10241025 // Convert limit (in MB) to float1026 $arguments[‘mla_viewer_limit’] = abs( 0.0 + $arguments[‘mla_viewer_limit’] );10271028 // Fill width and/or height from explicit intermediate size1029 if ( ( empty( $attr[‘mla_viewer_width’] ) && empty( $attr[‘mla_viewer_height’] ) ) && ! empty( $attr[‘size’] ) ) {1030 $registered_dimensions = self::_registered_dimensions();1031 if ( isset( $registered_dimensions[ $attr[‘size’] ] ) ) {1032 $arguments[‘mla_viewer_width’] = absint( $registered_dimensions[ $attr[‘size’] ][0] );1033 $arguments[‘mla_viewer_height’] = absint( $registered_dimensions[ $attr[‘size’] ][1] );10341035 if ( empty( $attr[‘mla_viewer_best_fit’] ) ) {1036 $arguments[‘mla_viewer_best_fit’] = 'true’;1037 }1038 }1039 }10401041 $arguments[‘mla_viewer_width’] = absint( $arguments[‘mla_viewer_width’] );1042 $arguments[‘mla_viewer_height’] = absint( $arguments[‘mla_viewer_height’] );1043 $arguments[‘mla_viewer_page’] = absint( $arguments[‘mla_viewer_page’] );10441045 if ( isset( $arguments[‘mla_viewer_best_fit’] ) ) {1046 $arguments[‘mla_viewer_best_fit’] = ‘true’ == strtolower( $arguments[‘mla_viewer_best_fit’] );1047 }10481049 $arguments[‘mla_viewer_resolution’] = absint( $arguments[‘mla_viewer_resolution’] );1050 $arguments[‘mla_viewer_quality’] = absint( $arguments[‘mla_viewer_quality’] );1051 }10521053 /*1054 * The default MLA style template includes “margin: 1.5%” to put a bit of1055 * minimum space between the columns. “mla_margin” can be used to change1056 * this. “mla_itemwidth” can be used with “columns=0” to achieve a “responsive"1057 * layout.1058 */1059 1060 $columns = absint( $arguments[‘columns’] );1061 $margin_string = strtolower( trim( $arguments[‘mla_margin’] ) );10621063 if ( is_numeric( $margin_string ) && ( 0 != $margin_string) ) {1064 $margin_string .= '%’; // Legacy values are always in percent1065 }10661067 if ( ‘%’ == substr( $margin_string, -1 ) ) {1068 $margin_percent = (float) substr( $margin_string, 0, strlen( $margin_string ) - 1 );1069 } else {1070 $margin_percent = 0;1071 }10721073 $width_string = strtolower( trim( $arguments[‘mla_itemwidth’] ) );1074 if ( ‘none’ != $width_string ) {1075 switch ( $width_string ) {1076 case 'exact’:1077 $margin_percent = 0;1078 // fallthru1079 case 'calculate’:1080 $width_string = $columns > 0 ? (floor(1000/$columns)/10) - ( 2.0 * $margin_percent ) : 100 - ( 2.0 * $margin_percent );1081 // fallthru1082 default:1083 if ( is_numeric( $width_string ) && ( 0 != $width_string) ) {1084 $width_string .= '%’; // Legacy values are always in percent1085 }1086 }1087 } // $use_width10881089 $float = strtolower( $arguments[‘mla_float’] );1090 if ( ! in_array( $float, array( 'left’, 'none’, ‘right’ ) ) ) {1091 $float = 'none’; // before v2.90: is_rtl() ? ‘right’ : 'left’;1092 }10931094 $style_values = array_merge( $page_values, array(1095 ‘mla_style’ => $arguments[‘mla_style’],1096 ‘mla_markup’ => $arguments[‘mla_markup’],1097 ‘itemtag’ => tag_escape( $arguments[‘itemtag’] ),1098 ‘icontag’ => tag_escape( $arguments[‘icontag’] ),1099 ‘captiontag’ => tag_escape( $arguments[‘captiontag’] ),1100 ‘columns’ => $columns,1101 ‘itemwidth’ => $width_string,1102 ‘margin’ => $margin_string,1103 ‘float’ => $float,1104 ‘size_class’ => sanitize_html_class( $size_class ),1105 ‘found_rows’ => $found_rows,1106 ‘current_rows’ => $current_rows,1107 ‘max_num_pages’ => $max_num_pages,1108 ) );11091110 $style_template = $gallery_style = '’;11111112 if ( ‘theme’ == strtolower( $style_values[‘mla_style’] ) ) {1113 $use_mla_gallery_style = apply_filters( 'use_default_gallery_style’, ! $html5 );1114 } else {1115 $use_mla_gallery_style = ( ‘none’ != strtolower( $style_values[‘mla_style’] ) );1116 }11171118 if ( apply_filters( 'use_mla_gallery_style’, $use_mla_gallery_style, $style_values[‘mla_style’] ) ) {1119 $style_template = MLATemplate_support::mla_fetch_custom_template( $style_values[‘mla_style’], 'gallery’, ‘style’ );1120 if ( empty( $style_template ) ) {1121 $style_values[‘mla_style’] = 'default’;1122 $style_template = MLATemplate_support::mla_fetch_custom_template( 'default’, 'gallery’, ‘style’ );1123 }11241125 if ( ! empty ( $style_template ) ) {1126 // Look for ‘query’ and ‘request’ substitution parameters1127 $style_values = MLAData::mla_expand_field_level_parameters( $style_template, $attr, $style_values );11281129 // Clean up the template to resolve width or margin == 'none’1130 if ( ‘none’ == $margin_string ) {1131 $style_values[‘margin’] = '0’;1132 $style_template = preg_replace( '/margin:[\s]*\[\+margin\+\][\%]*[\;]*/’, '’, $style_template );1133 }11341135 if ( ‘none’ == $width_string ) {1136 $style_values[‘itemwidth’] = 'auto’;1137 $style_template = preg_replace( '/width:[\s]*\[\+itemwidth\+\][\%]*[\;]*/’, '’, $style_template );1138 }11391140 $style_values = apply_filters( 'mla_gallery_style_values’, $style_values );1141 $style_template = apply_filters( 'mla_gallery_style_template’, $style_template );1142 $gallery_style = MLAData::mla_parse_template( $style_template, $style_values );1143 $gallery_style = apply_filters( 'mla_gallery_style_parse’, $gallery_style, $style_template, $style_values );11441145 // Clean up the styles to resolve extra “%” suffixes on width or margin (pre v1.42 values)1146 $preg_pattern = array( '/([margin|width]:[^\%]*)\%\%/’, '/([margin|width]:.*)auto\%/’, ‘/([margin|width]:.*)inherit\%/’ );1147 $preg_replacement = array( '${1}%’, '${1}auto’, '${1}inherit’, );1148 $gallery_style = preg_replace( $preg_pattern, $preg_replacement, $gallery_style );1149 } // !empty template1150 } // use_mla_gallery_style11511152 $markup_values = $style_values;11531154 $open_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'gallery’, 'markup’, ‘open’ );1155 if ( empty( $open_template ) ) {1156 $open_template = '’;1157 }11581159 // Emulate [gallery] handling of row open markup for the default template only1160 if ( $html5 && ( ‘default’ == $markup_values[‘mla_markup’] ) ) {1161 $row_open_template = '’;1162 } else{1163 $row_open_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'gallery’, 'markup’, ‘row-open’ );11641165 if ( empty( $row_open_template ) ) {1166 $row_open_template = '’;1167 }1168 }11691170 $item_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'gallery’, 'markup’, ‘item’ );1171 if ( empty( $item_template ) ) {1172 $item_template = '’;1173 }11741175 // Emulate [gallery] handling of row close markup for the default template only1176 if ( $html5 && ( ‘default’ == $markup_values[‘mla_markup’] ) ) {1177 $row_close_template = '’;1178 } else{1179 $row_close_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'gallery’, 'markup’, ‘row-close’ );11801181 if ( empty( $row_close_template ) ) {1182 $row_close_template = '’;1183 }1184 }11851186 $close_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'gallery’, 'markup’, ‘close’ );1187 if ( empty( $close_template ) ) {1188 $close_template = '’;1189 }11901191 // Look for gallery-level markup substitution parameters1192 $new_text = $open_template . $row_open_template . $row_close_template . $close_template;1193 $markup_values = MLAData::mla_expand_field_level_parameters( $new_text, $attr, $markup_values );11941195 if ( self::$mla_debug ) {1196 $output = MLACore::mla_debug_flush();1197 } else {1198 $output = '’;1199 }12001201 // These $markup_values are used for both pagination and gallery output1202 $markup_values = apply_filters( 'mla_gallery_open_values’, $markup_values );12031204 if ( $is_gallery ) {1205 $open_template = apply_filters( 'mla_gallery_open_template’, $open_template );1206 if ( empty( $open_template ) ) {1207 $gallery_open = '’;1208 } else {1209 $gallery_open = MLAData::mla_parse_template( $open_template, $markup_values );1210 }12111212 $gallery_open = apply_filters( 'mla_gallery_open_parse’, $gallery_open, $open_template, $markup_values );1213 if ( ! $processing_alt_ids_value ) {1214 $output .= apply_filters( 'mla_gallery_style’, $gallery_style . $gallery_open, $style_values, $markup_values, $style_template, $open_template );1215 }1216 } else {1217 // Handle 'previous_page’, 'next_page’, and 'paginate_links’1218 $pagination_result = self::_process_pagination_output_types( $output_parameters, $markup_values, $arguments, $attr, $found_rows, $output );1219 if ( false !== $pagination_result ) {1220 return $pagination_result;1221 }1222 }12231224 /*1225 * For “previous_link", “current_link” and “next_link",1226 * discard all of the $attachments except the appropriate choice1227 */1228 if ( ! $is_gallery ) {1229 $link_type = $output_parameters[0];12301231 if ( ! in_array( $link_type, array ( 'previous_link’, 'current_link’, ‘next_link’ ) ) ) {1232 return '’; // unknown output type1233 }12341235 $is_wrap = isset( $output_parameters[1] ) && ‘wrap’ == $output_parameters[1];1236 $current_id = empty( $arguments[‘id’] ) ? $markup_values[‘id’] : $arguments[‘id’];12371238 $pagination_index = 1;1239 foreach ( $attachments as $id => $attachment ) {1240 if ( $attachment->ID == $current_id ) {1241 break;1242 }12431244 $pagination_index++;1245 }12461247 $target = NULL;1248 if ( isset( $id ) ) {1249 switch ( $link_type ) {1250 case 'previous_link’:1251 $target_id = $id - 1;1252 break;1253 case 'next_link’:1254 $target_id = $id + 1;1255 break;1256 case 'current_link’:1257 default:1258 $target_id = $id;1259 } // link_type12601261 if ( isset( $attachments[ $target_id ] ) ) {1262 $target = $attachments[ $target_id ];1263 } elseif ( $is_wrap ) {1264 switch ( $link_type ) {1265 case 'previous_link’:1266 $target = array_pop( $attachments );1267 break;1268 case 'next_link’:1269 $target = array_shift( $attachments );1270 } // link_type1271 } // is_wrap1272 } // isset id12731274 if ( isset( $target ) ) {1275 $attachments = array( $target ); 1276 } elseif ( ! empty( $arguments[‘mla_nolink_text’] ) ) {1277 return self::_process_shortcode_parameter( $arguments[‘mla_nolink_text’], $markup_values ) . '</a>’;1278 } else {1279 return '’;1280 }1281 } else { // ! is_gallery1282 $link_type= '’;1283 }12841285 $column_index = 0;1286 foreach ( $attachments as $id => $attachment ) {1287 $item_values = apply_filters( 'mla_gallery_item_initial_values’, $markup_values, $attachment );12881289 // fill in item-specific elements1290 $item_values[‘index’] = (string) $is_gallery ? 1 + $column_index : $pagination_index;1291 $item_values[‘last_in_row’] = '’;12921293 $item_values[‘excerpt’] = wptexturize( $attachment->post_excerpt );1294 $item_values[‘attachment_ID’] = $attachment->ID;1295 $item_values[‘mime_type’] = $attachment->post_mime_type;1296 $item_values[‘menu_order’] = $attachment->menu_order;1297 $item_values[‘date’] = $attachment->post_date;1298 $item_values[‘modified’] = $attachment->post_modified;1299 $item_values[‘parent’] = $attachment->post_parent;1300 $item_values[‘parent_name’] = '’;1301 $item_values[‘parent_type’] = '’;1302 $item_values[‘parent_title’] = '(' . __( 'Unattached’, ‘media-library-assistant’ ) . ')';1303 $item_values[‘parent_date’] = '’;1304 $item_values[‘parent_permalink’] = '’;1305 $item_values[‘title’] = wptexturize( $attachment->post_title );1306 $item_values[‘slug’] = $attachment->post_name;1307 $item_values[‘width’] = '’;1308 $item_values[‘height’] = '’;1309 $item_values[‘orientation’] = '’;1310 $item_values[‘image_meta’] = '’;1311 $item_values[‘image_alt’] = '’;1312 $item_values[‘base_file’] = '’;1313 $item_values[‘path’] = '’;1314 $item_values[‘file’] = '’;1315 $item_values[‘description’] = wptexturize( $attachment->post_content );1316 $item_values[‘file_url’] = wp_get_attachment_url( $attachment->ID );1317 $item_values[‘author_id’] = $attachment->post_author;1318 $item_values[‘author’] = '’;1319 $item_values[‘caption’] = '’;1320 $item_values[‘captiontag_content’] = '’;13211322 $user = get_user_by( 'id’, $attachment->post_author );1323 if ( isset( $user->data->display_name ) ) {1324 $item_values[‘author’] = wptexturize( $user->data->display_name );1325 } else {1326 $item_values[‘author’] = __( 'unknown’, ‘media-library-assistant’ );1327 }13281329 $post_meta = MLAQuery::mla_fetch_attachment_metadata( $attachment->ID );1330 $base_file = isset( $post_meta[‘mla_wp_attached_file’] ) ? $post_meta[‘mla_wp_attached_file’] : '’;1331 $sizes = isset( $post_meta[‘mla_wp_attachment_metadata’][‘sizes’] ) ? $post_meta[‘mla_wp_attachment_metadata’][‘sizes’] : array();13321333 if ( ! empty( $post_meta[‘mla_wp_attachment_metadata’][‘width’] ) ) {1334 $item_values[‘width’] = $post_meta[‘mla_wp_attachment_metadata’][‘width’];1335 $width = absint( $item_values[‘width’] );1336 } else {1337 $width = 0;1338 }13391340 if ( ! empty( $post_meta[‘mla_wp_attachment_metadata’][‘height’] ) ) {1341 $item_values[‘height’] = $post_meta[‘mla_wp_attachment_metadata’][‘height’];1342 $height = absint( $item_values[‘height’] );1343 } else {1344 $height = 0;1345 }13461347 if ( $width && $height ) {1348 $item_values[‘orientation’] = ( $height > $width ) ? ‘portrait’ : 'landscape’;1349 }13501351 if ( ! empty( $post_meta[‘mla_wp_attachment_metadata’][‘image_meta’] ) ) {1352 $item_values[‘image_meta’] = var_export( $post_meta[‘mla_wp_attachment_metadata’][‘image_meta’], true );1353 }13541355 if ( ! empty( $post_meta[‘mla_wp_attachment_image_alt’] ) ) {1356 if ( is_array( $post_meta[‘mla_wp_attachment_image_alt’] ) ) {1357 $item_values[‘image_alt’] = wptexturize( $post_meta[‘mla_wp_attachment_image_alt’][0] );1358 } else {1359 $item_values[‘image_alt’] = wptexturize( $post_meta[‘mla_wp_attachment_image_alt’] );1360 }1361 }13621363 if ( ! empty( $base_file ) ) {1364 $last_slash = strrpos( $base_file, ‘/’ );1365 if ( false === $last_slash ) {1366 $file_name = $base_file;1367 $item_values[‘base_file’] = $base_file;1368 $item_values[‘file’] = $base_file;1369 } else {1370 $file_name = substr( $base_file, $last_slash + 1 );1371 $item_values[‘base_file’] = $base_file;;1372 $item_values[‘path’] = substr( $base_file, 0, $last_slash + 1 );1373 $item_values[‘file’] = $file_name;1374 }1375 } else {1376 $file_name = '’;1377 }13781379 if ( 0 < $attachment->post_parent ) {1380 $parent_info = MLAQuery::mla_fetch_attachment_parent_data( $attachment->post_parent );1381 if ( isset( $parent_info[‘parent_name’] ) ) {1382 $item_values[‘parent_name’] = $parent_info[‘parent_name’];1383 }13841385 if ( isset( $parent_info[‘parent_type’] ) ) {1386 $item_values[‘parent_type’] = wptexturize( $parent_info[‘parent_type’] );1387 }13881389 if ( isset( $parent_info[‘parent_title’] ) ) {1390 $item_values[‘parent_title’] = wptexturize( $parent_info[‘parent_title’] );1391 }13921393 if ( isset( $parent_info[‘parent_date’] ) ) {1394 $item_values[‘parent_date’] = wptexturize( $parent_info[‘parent_date’] );1395 }13961397 $permalink = get_permalink( $attachment->post_parent );1398 if ( false !== $permalink ) {1399 $item_values[‘parent_permalink’] = $permalink;1400 }1401 } // has parent14021403 // Add attachment-specific field-level substitution parameters1404 $new_text = isset( $item_template ) ? $item_template : '’;1405 foreach( $mla_item_specific_arguments as $index => $value ) {1406 $new_text .= str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $arguments[ $index ] ) );1407 }1408 $item_values = MLAData::mla_expand_field_level_parameters( $new_text, $attr, $item_values, $attachment->ID );14091410 if ( $item_values[‘captiontag’] ) {1411 $item_values[‘caption’] = wptexturize( $attachment->post_excerpt );1412 if ( ! empty( $arguments[‘mla_caption’] ) ) {1413 $item_values[‘caption’] = wptexturize( self::_process_shortcode_parameter( $arguments[‘mla_caption’], $item_values ) );1414 }1415 } else {1416 $item_values[‘caption’] = '’;1417 }14181419 if ( ! empty( $arguments[‘mla_link_text’] ) ) {1420 $link_text = self::_process_shortcode_parameter( $arguments[‘mla_link_text’], $item_values );1421 } else {1422 $link_text = false;1423 }14241425 /*1426 * As of WP 3.7, this function returns “<a href=’$url’>$link_text</a>", where1427 * $link_text can be an image thumbnail or a text link. The “title=” attribute1428 * was dropped. The function is defined in /wp-includes/post-template.php.1429 *1430 * As of WP 4.1, this function has an additional optional parameter, an “Array or1431 * string of attributes", used in the [gallery] shortcode to tie the link to a1432 * caption with 'aria-describedby’. The caption has a matching ‘id’ attribute1433 * “$selector-#id". See below for the MLA equivalent processing.1434 */1435 if ( ‘attachment’ == $attachment->post_type ) {1436 // Avoid native PDF thumbnails, if specified1437 if ( $mla_viewer_required && in_array( $attachment->post_mime_type, array( ‘application/pdf’ ) ) ) {1438 $item_values[‘pagelink’] = sprintf( '<a href=\’%1$s\’>%2$s</a>’, get_permalink( $attachment->ID ), $attachment->post_title );1439 $item_values[‘filelink’] = sprintf( '<a href=\’%1$s\’>%2$s</a>’, $attachment->guid, $attachment->post_title );1440 } else {1441 add_filter( 'wp_get_attachment_image_src’, 'MLAShortcode_Support::_get_attachment_image_src’, 10, 4 );14421443 // The fourth argument, “show icon” is always false because we handle it in _get_attachment_image_src()1444 $item_values[‘pagelink’] = wp_get_attachment_link($attachment->ID, $size, true, false, $link_text);1445 $item_values[‘filelink’] = wp_get_attachment_link($attachment->ID, $size, false, false, $link_text);14461447 remove_filter( 'wp_get_attachment_image_src’, ‘MLAShortcode_Support::_get_attachment_image_src’ );1448 }1449 } else {1450 $thumbnail_content = $attachment->post_title;14511452 if ( ( ‘none’ !== $arguments[‘size’] ) && ( ‘checked’ == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_FEATURED_IMAGE ) ) ) {1453 // Look for the “Featured Image” as an alternate thumbnail for PDFs, etc.1454 $thumb = get_the_post_thumbnail( $attachment->ID, $size, array( ‘class’ => ‘attachment-thumbnail’ ) );1455 $thumb = apply_filters( 'mla_gallery_featured_image’, $thumb, $attachment, $size, $item_values );14561457 if ( ! empty( $thumb ) ) {1458 $thumbnail_content = $thumb;1459 }1460 }14611462 $item_values[‘pagelink’] = sprintf( '<a href=\’%1$s\’>%2$s</a>’, $attachment->guid, $thumbnail_content );1463 $item_values[‘filelink’] = sprintf( '<a href=\’%1$s\’>%2$s</a>’, get_permalink( $attachment->ID ), $thumbnail_content );1464 }14651466 if ( in_array( $attachment->post_mime_type, array( ‘image/svg+xml’ ) ) ) {1467 $registered_dimensions = self::_registered_dimensions();1468 if ( isset( $registered_dimensions[ $size_class ] ) ) {1469 $dimensions = $registered_dimensions[ $size_class ];1470 } else {1471 $dimensions = $registered_dimensions[‘thumbnail’];1472 }14731474 $thumb = preg_replace( '/width=\”[^\”]*\"/’, sprintf( 'width="%1$d"’, $dimensions[1] ), $item_values[‘pagelink’] );1475 $item_values[‘pagelink’] = preg_replace( '/height=\”[^\”]*\"/’, sprintf( 'height="%1$d"’, $dimensions[0] ), $thumb );1476 $thumb = preg_replace( '/width=\”[^\”]*\"/’, sprintf( 'width="%1$d"’, $dimensions[1] ), $item_values[‘filelink’] );1477 $item_values[‘filelink’] = preg_replace( '/height=\”[^\”]*\"/’, sprintf( 'height="%1$d"’, $dimensions[0] ), $thumb );1478 } // SVG thumbnail14791480 /*1481 * Apply the Gallery Display Content parameters.1482 * Note that $link_attributes and $rollover_text1483 * are used in the Google Viewer code below1484 */1485 $link_attributes = ‘’;1486 if ( ! empty( $arguments[‘mla_rollover_text’] ) ) {1487 $rollover_text = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_rollover_text’], $item_values ) );14881489 /*1490 * The “title=” attribute was removed in WP 3.7+, but look for it anyway.1491 * If it’s not there, add the “title=” value to the link attributes.1492 */1493 if ( false === strpos( $item_values[‘pagelink’], ' title=’ ) ) {1494 $link_attributes .= ‘title="’ . $rollover_text . '” ‘;1495 }else {1496 // Replace single- and double-quote delimited values1497 $item_values[‘pagelink’] = preg_replace(‘# title=\’([^\’]*)\’#’, " title=’{$rollover_text}’", $item_values[‘pagelink’] );1498 $item_values[‘pagelink’] = preg_replace('# title=\”([^\”]*)\"#’, " title=\"{$rollover_text}\"", $item_values[‘pagelink’] );1499 $item_values[‘filelink’] = preg_replace(‘# title=\’([^\’]*)\’#’, " title=’{$rollover_text}’", $item_values[‘filelink’] );1500 $item_values[‘filelink’] = preg_replace('# title=\"([^\"]*)\"#’, " title=\"{$rollover_text}\"", $item_values[‘filelink’] );1501 }1502 } else {1503 $rollover_text = esc_attr( $item_values[‘title’] );1504 }15051506 if ( ! empty( $arguments[‘mla_target’] ) ) {1507 $link_attributes .= ‘target="’ . $arguments[‘mla_target’] . '" ';1508 }15091510 if ( ! empty( $arguments[‘mla_link_attributes’] ) ) {1511 $link_attributes .= self::_process_shortcode_parameter( $arguments[‘mla_link_attributes’], $item_values ) . ' ';1512 }15131514 if ( ! empty( $arguments[‘mla_link_class’] ) ) {1515 $link_attributes .= ‘class="’ . self::_process_shortcode_parameter( $arguments[‘mla_link_class’], $item_values ) . '" ';1516 }15171518 if ( ! empty( $link_attributes ) ) {1519 $item_values[‘pagelink’] = preg_replace( '#<a( .*)href=#’, ‘<a$1’ . $link_attributes . 'href=’, $item_values[‘pagelink’] );1520 $item_values[‘filelink’] = preg_replace( '#<a( .*)href=#’, ‘<a$1’ . $link_attributes . 'href=’, $item_values[‘filelink’] );1521// $item_values[‘pagelink’] = str_replace( '<a href=’, '<a ' . $link_attributes . 'href=’, $item_values[‘pagelink’] );1522// $item_values[‘filelink’] = str_replace( '<a href=’, '<a ' . $link_attributes . 'href=’, $item_values[‘filelink’] );1523 }15241525 /*1526 * Process the <img> tag, if present1527 * Note that $image_attributes, $image_class and $image_alt1528 * are used in the Google Viewer code below1529 */1530 if ( ! empty( $arguments[‘mla_image_attributes’] ) ) {1531 $image_attributes = self::_process_shortcode_parameter( $arguments[‘mla_image_attributes’], $item_values ) . ' ';1532 } else {1533 $image_attributes = '’;1534 }15351536 /*1537 * WordPress 4.1 ties the <img> tag to the caption with 'aria-describedby’1538 * has a matching ‘id’ attribute “$selector-#id".1539 */1540 if ( trim( $item_values[‘caption’] ) && ( false === strpos( $image_attributes, ‘aria-describedby=’ ) ) && ( ‘default’ == $item_values[‘mla_markup’] ) ) {1541 $image_attributes .= ‘aria-describedby="’ . $item_values[‘selector’] . '-' . $item_values[‘attachment_ID’] . '” ';1542 }15431544 if ( ! empty( $arguments[‘mla_image_class’] ) ) {1545 $image_class = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_image_class’], $item_values ) );1546 } else {1547 $image_class = '’;1548 }15491550 if ( ! empty( $arguments[‘mla_image_alt’] ) ) {1551 $image_alt = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_image_alt’], $item_values ) );1552 } else {1553 $image_alt = '’;1554 }15551556 /*1557 * Look for alt= and class= attributes in $image_attributes. If found,1558 * they override and completely replace the corresponding values.1559 */1560 $class_replace = false;1561 if ( ! empty( $image_attributes ) ) {1562 $match_count = preg_match( ‘#alt=(([\’\"])([^\’]+?)\2)#’, $image_attributes, $matches, PREG_OFFSET_CAPTURE );1563 if ( 1 === $match_count ) {1564 $image_alt = $matches[3][0];1565 $image_attributes = substr_replace( $image_attributes, '’, $matches[0][1], strlen( $matches[0][0] ) );1566 }15671568 $match_count = preg_match( ‘#class=(([\’\"])([^\’]+?)\2)#’, $image_attributes, $matches, PREG_OFFSET_CAPTURE );1569 if ( 1 === $match_count ) {1570 $class_replace = true;1571 $image_class = $matches[3][0];1572 $image_attributes = substr_replace( $image_attributes, '’, $matches[0][1], strlen( $matches[0][0] ) );1573 }15741575 $image_attributes = trim( $image_attributes );1576 if ( ! empty( $image_attributes ) ) {1577 $image_attributes .= ' ';1578 }1579 }15801581 if ( false !== strpos( $item_values[‘pagelink’], '<img ' ) ) {1582 if ( ! empty( $image_attributes ) ) {1583 $item_values[‘pagelink’] = str_replace( '<img ', '<img ' . $image_attributes, $item_values[‘pagelink’] );1584 $item_values[‘filelink’] = str_replace( '<img ', '<img ' . $image_attributes, $item_values[‘filelink’] );1585 }15861587 // Extract existing class values and add to them1588 if ( ! empty( $image_class ) ) {1589 $match_count = preg_match_all( '# class=\"([^\"]+)\" #’, $item_values[‘pagelink’], $matches, PREG_OFFSET_CAPTURE );1590 if ( ! ( $class_replace || ( $match_count == false ) || ( $match_count == 0 ) ) ) {1591 $class = $matches[1][0][0] . ' ' . $image_class;1592 } else {1593 $class = $image_class;1594 }15951596 $item_values[‘pagelink’] = preg_replace('# class=\"([^\"]*)\"#’, " class=\"{$class}\"", $item_values[‘pagelink’] );1597 $item_values[‘filelink’] = preg_replace('# class=\"([^\"]*)\"#’, " class=\"{$class}\"", $item_values[‘filelink’] );1598 }15991600 if ( ! empty( $image_alt ) ) {1601 $item_values[‘pagelink’] = preg_replace('# alt=\"([^\"]*)\"#’, " alt=\"{$image_alt}\"", $item_values[‘pagelink’] );1602 $item_values[‘filelink’] = preg_replace(‘# alt=\"([^\"]*)\"#’, " alt=\"{$image_alt}\"", $item_values[‘filelink’] );1603 }1604 } // process <img> tag16051606 // Create download and named transfer links with all Content Parameters1607 $match_count = preg_match( ‘#href=\’([^\’]+)\’#’, $item_values[‘filelink’], $matches, PREG_OFFSET_CAPTURE );1608 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {1609 /*/ Forced download link - NO LONGER ALLOWED, SEE BELOW1610 $args = array(1611 ‘mla_download_file’ => urlencode( $item_values[‘base_dir’] . ‘/’ . $item_values[‘base_file’] ),1612 ‘mla_download_type’ => $item_values[‘mime_type’]1613 );16141615 if ( ‘log’ == $arguments[‘mla_debug’] ) {1616 $args[‘mla_debug’] = 'log’;1617 }16181619 $item_values[‘downloadlink_url’] = add_query_arg( $args, MLA_PLUGIN_URL . ‘includes/mla-file-downloader.php’ );1620 $item_values[‘downloadlink’] = preg_replace( ‘"’ . $matches[0][0] . '"’, sprintf( 'href=\’%1$s\’’, $item_values[‘downloadlink_url’] ), $item_values[‘filelink’] ); // */16211622 // AJAX-based Named Transfer link1623 $args = array(1624 ‘action’ => 'mla_named_transfer’,1625 ‘mla_item’ => $attachment->post_name,1626 ‘mla_disposition’ => ( ‘download’ === $arguments[‘link’] ) ? ‘attachment’ : 'inline’,1627 );16281629 if ( ‘log’ == $arguments[‘mla_debug’] ) {1630 $args[‘mla_debug’] = 'log’;1631 }16321633 $item_values[‘transferlink_url’] = add_query_arg( $args, admin_url( ‘admin-ajax.php’ ) );1634 $item_values[‘transferlink’] = preg_replace( ‘"’ . $matches[0][0] . '"’, sprintf( 'href=\’%1$s\’’, $item_values[‘transferlink_url’] ), $item_values[‘filelink’] );16351636 // AJAX-based Named Transfer link for forced downloads1637 $args = array(1638 ‘action’ => 'mla_named_transfer’,1639 ‘mla_item’ => $attachment->post_name,1640 ‘mla_disposition’ => 'attachment’,1641 );16421643 if ( ‘log’ == $arguments[‘mla_debug’] ) {1644 $args[‘mla_debug’] = 'log’;1645 }16461647 $item_values[‘downloadlink_url’] = add_query_arg( $args, admin_url( ‘admin-ajax.php’ ) );1648 $item_values[‘downloadlink’] = preg_replace( ‘"’ . $matches[0][0] . '"’, sprintf( 'href=\’%1$s\’’, $item_values[‘transferlink_url’] ), $item_values[‘filelink’] );1649 } else {1650 $item_values[‘downloadlink_url’] = $item_values[‘filelink_url’];1651 $item_values[‘downloadlink’] = $item_values[‘filelink’];16521653 $item_values[‘transferlink_url’] = $item_values[‘filelink_url’];1654 $item_values[‘transferlink’] = $item_values[‘filelink’];1655 }16561657 switch ( $arguments[‘link’] ) {1658 case 'permalink’:1659 case 'post’:1660 $item_values[‘link’] = $item_values[‘pagelink’];1661 break;1662 case 'file’:1663 case 'full’:1664 $item_values[‘link’] = $item_values[‘filelink’];1665 break;1666 case 'download’:1667 $item_values[‘link’] = $item_values[‘downloadlink’];1668 break;1669 default:1670 $item_values[‘link’] = $item_values[‘filelink’];16711672 // Check for link to specific (registered) file size, image types only1673 if ( array_key_exists( $arguments[‘link’], $sizes ) ) {1674 if ( 0 === strpos( $attachment->post_mime_type, ‘image/’ ) ) {1675 $target_file = $sizes[ $arguments[‘link’] ][‘file’];1676 $item_values[‘link’] = str_replace( $file_name, $target_file, $item_values[‘filelink’] );1677 }1678 }1679 } // switch ‘link’16801681 // Replace link with AJAX-based item transfer using post slug1682 if ( $arguments[‘mla_named_transfer’] ) {1683 $item_values[‘link’] = $item_values[‘transferlink’];1684 }16851686 // Extract target and thumbnail fields1687 $match_count = preg_match_all( ‘#href=\’([^\’]+)\’#’, $item_values[‘pagelink’], $matches, PREG_OFFSET_CAPTURE );1688 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {1689 $item_values[‘pagelink_url’] = $matches[1][0][0];1690 } else {1691 $item_values[‘pagelink_url’] = ‘’;1692 }16931694 $match_count = preg_match_all( ‘#href=\’([^\’]+)\’#’, $item_values[‘filelink’], $matches, PREG_OFFSET_CAPTURE );1695 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {1696 $item_values[‘filelink_url’] = $matches[1][0][0];1697 } else {1698 $item_values[‘filelink_url’] = ‘’;1699 }17001701 /*1702 * Override the link value; leave filelink and pagelink unchanged1703 * Note that $link_href is used in the Google Viewer code below1704 */1705 if ( ! empty( $arguments[‘mla_link_href’] ) ) {1706 $link_href = self::_process_shortcode_parameter( $arguments[‘mla_link_href’], $item_values );17071708 // Replace single- and double-quote delimited values1709 $item_values[‘link’] = preg_replace(‘# href=\’([^\’]*)\’#’, " href=’{$link_href}’", $item_values[‘link’] );1710 $item_values[‘link’] = preg_replace('# href=\"([^\"]*)\"#’, " href=\"{$link_href}\"", $item_values[‘link’] );1711 } else {1712 $link_href = ‘’;1713 }17141715 $match_count = preg_match_all( ‘#href=\’([^\’]+)\’#’, $item_values[‘link’], $matches, PREG_OFFSET_CAPTURE );1716 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {1717 $item_values[‘link_url’] = $matches[1][0][0];1718 } else {1719 $item_values[‘link_url’] = '’;1720 }17211722 $match_count = preg_match_all( '#(\<a [^\>]+\>)(.*)\</a\>#’, $item_values[‘link’], $matches, PREG_OFFSET_CAPTURE );1723 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {1724 $link_tag = $matches[1][0][0];1725 $item_values[‘thumbnail_content’] = $matches[2][0][0];1726 } else {1727 $link_tag = '’;1728 $item_values[‘thumbnail_content’] = '’;1729 }17301731 $match_count = preg_match_all( '# width=\"([^\"]+)\" height=\"([^\"]+)\" src=\"([^\"]+)\" #’, $item_values[‘link’], $matches, PREG_OFFSET_CAPTURE );1732 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {1733 $item_values[‘thumbnail_width’] = $matches[1][0][0];1734 $item_values[‘thumbnail_height’] = $matches[2][0][0];1735 $item_values[‘thumbnail_url’] = $matches[3][0][0];1736 } else {1737 $item_values[‘thumbnail_width’] = '’;1738 $item_values[‘thumbnail_height’] = '’;1739 $item_values[‘thumbnail_url’] = '’;17401741 /* Replaced by logic in _get_attachment_image_src v2.901742 if ( ( ‘none’ !== $arguments[‘size’] ) && ( ‘checked’ == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_FEATURED_IMAGE ) ) ) {1743 // Look for the “Featured Image” as an alternate thumbnail for PDFs, etc.1744 $feature = get_the_post_thumbnail( $attachment->ID, $size, array( ‘class’ => ‘attachment-thumbnail’ ) );1745 $feature = apply_filters( 'mla_gallery_featured_image’, $feature, $attachment, $size, $item_values );17461747 if ( ! empty( $feature ) ) {1748 $match_count = preg_match_all( '# width=\"([^\"]+)\" height=\"([^\"]+)\" src=\"([^\"]+)\" #’, $feature, $matches, PREG_OFFSET_CAPTURE );1749 if ( ! ( ( $match_count == false ) || ( $match_count == 0 ) ) ) {1750 $item_values[‘link’] = $link_tag . $feature . '</a>’;1751 $item_values[‘thumbnail_content’] = $feature;1752 $item_values[‘thumbnail_width’] = $matches[1][0][0];1753 $item_values[‘thumbnail_height’] = $matches[2][0][0];1754 $item_values[‘thumbnail_url’] = $matches[3][0][0];1755 }1756 }1757 } // enable_featured_image */1758 }17591760 // Now that we have thumbnail_content we can check for ‘span’ and 'none’1761 if ( ‘none’ == $arguments[‘link’] ) {1762 $item_values[‘link’] = $item_values[‘thumbnail_content’];1763 } elseif ( ‘span’ == $arguments[‘link’] ) {1764 $item_values[‘link’] = sprintf( '<span %1$s>%2$s</span>’, $link_attributes, $item_values[‘thumbnail_content’] );1765 }17661767 /*1768 * Check for Imagick thumbnail generation, uses above-defined1769 * $link_attributes (includes target), $rollover_text, $link_href (link only),1770 * $image_attributes, $image_class, $image_alt1771 */1772 if ( $arguments[‘mla_viewer’] && empty( $item_values[‘thumbnail_url’] ) ) {1773 // Check for a match on file extension1774 $last_dot = strrpos( $item_values[‘file’], ‘.’ );1775 if ( !( false === $last_dot) ) {1776 $extension = substr( $item_values[‘file’], $last_dot + 1 );1777 if ( in_array( $extension, $arguments[‘mla_viewer_extensions’] ) ) {1778 // Default to an icon if thumbnail generation is not available1779 $icon_url = wp_mime_type_icon( $attachment->ID );1780 $upload_dir = wp_upload_dir();1781 $args = array(1782 ‘mla_stream_file’ => urlencode( ‘file://’ . $upload_dir[‘basedir’] . ‘/’ . $item_values[‘base_file’] ),1783 );17841785 if ( ‘log’ == $arguments[‘mla_debug’] ) {1786 $args[‘mla_debug’] = 'log’;1787 }17881789 if ( $arguments[‘mla_single_thread’] ) {1790 $args[‘mla_single_thread’] = 'true’;1791 }17921793 if ( $arguments[‘mla_viewer_width’] ) {1794 $args[‘mla_stream_width’] = $arguments[‘mla_viewer_width’];1795 }17961797 if ( $arguments[‘mla_viewer_height’] ) {1798 $args[‘mla_stream_height’] = $arguments[‘mla_viewer_height’];1799 }18001801 if ( isset( $arguments[‘mla_viewer_best_fit’] ) ) {1802 $args[‘mla_stream_fit’] = $arguments[‘mla_viewer_best_fit’] ? ‘1’ : '0’;1803 }18041805 /*1806 * Non-standard location, if not empty. Write the value to a file that can be1807 * found by the stand-alone (no WordPress) image stream processor.1808 */1809 $ghostscript_path = MLACore::mla_get_option( ‘ghostscript_path’ );1810 if ( ! empty( $ghostscript_path ) ) {1811 if ( false !== @file_put_contents( dirname( __FILE__ ) . ‘/’ . 'mla-ghostscript-path.txt’, $ghostscript_path ) ) {1812 $args[‘mla_ghostscript_path’] = ‘custom’;1813 }1814 }18151816 if ( self::mla_ghostscript_present( $ghostscript_path ) ) {1817 // Optional upper limit (in MB) on file size1818 if ( $limit = ( 1024 * 1024 ) * $arguments[‘mla_viewer_limit’] ) {1819 $file_size = 0 + @filesize( $item_values[‘base_dir’] . ‘/’ . $item_values[‘base_file’] );1820 if ( ( 0 < $file_size ) && ( $file_size > $limit ) ) {1821 $file_size = 0;1822 }1823 } else {1824 $file_size = 1;1825 }18261827 // Generate “real” thumbnail1828 if ( $file_size ) {1829 $frame = ( 0 < $arguments[‘mla_viewer_page’] ) ? $arguments[‘mla_viewer_page’] - 1 : 0;1830 if ( $frame ) {1831 $args[‘mla_stream_frame’] = $frame;1832 }18331834 if ( $arguments[‘mla_viewer_resolution’] ) {1835 $args[‘mla_stream_resolution’] = $arguments[‘mla_viewer_resolution’];1836 }18371838 if ( $arguments[‘mla_viewer_quality’] ) {1839 $args[‘mla_stream_quality’] = $arguments[‘mla_viewer_quality’];1840 }18411842 if ( ! empty( $arguments[‘mla_viewer_type’] ) ) {1843 $args[‘mla_stream_type’] = $arguments[‘mla_viewer_type’];1844 }18451846 // For efficiency, image streaming is done outside WordPress1847 $icon_url = add_query_arg( $args, MLA_PLUGIN_URL . ‘includes/mla-stream-image.php’ );1848 }1849 }18501851 // <img> tag (thumbnail_text)1852 if ( ! empty( $image_class ) ) {1853 $image_class = ' class="’ . $image_class . ‘"’;1854 }18551856 if ( ! empty( $image_alt ) ) {1857 $image_alt = ' alt="’ . $image_alt . ‘"’;1858 } elseif ( ! empty( $item_values[‘caption’] ) ) {1859 $image_alt = ' alt="’ . $item_values[‘caption’] . '"’;1860 }18611862 $item_values[‘thumbnail_content’] = sprintf( '<img %1$ssrc="%2$s"%3$s%4$s>’, $image_attributes, $icon_url, $image_class, $image_alt );18631864 // Filelink, pagelink and link. The “title=” attribute is in $link_attributes for WP 3.7+.1865 if ( false === strpos( $link_attributes, ‘title=’ ) ) {1866 $item_values[‘pagelink’] = sprintf( '<a %1$shref="%2$s" title="%3$s">%4$s</a>’, $link_attributes, $item_values[‘pagelink_url’], $rollover_text, $item_values[‘thumbnail_content’] );1867 $item_values[‘filelink’] = sprintf( '<a %1$shref="%2$s" title="%3$s">%4$s</a>’, $link_attributes, $item_values[‘filelink_url’], $rollover_text, $item_values[‘thumbnail_content’] );1868 $item_values[‘downloadlink’] = sprintf( '<a %1$shref="%2$s" title="%3$s">%4$s</a>’, $link_attributes, $item_values[‘downloadlink_url’], $rollover_text, $item_values[‘thumbnail_content’] );1869 } else {1870 $item_values[‘pagelink’] = sprintf( '<a %1$shref="%2$s">%3$s</a>’, $link_attributes, $item_values[‘pagelink_url’], $item_values[‘thumbnail_content’] );1871 $item_values[‘filelink’] = sprintf( '<a %1$shref="%2$s">%3$s</a>’, $link_attributes, $item_values[‘filelink_url’], $item_values[‘thumbnail_content’] );1872 $item_values[‘downloadlink’] = sprintf( '<a %1$shref="%2$s">%3$s</a>’, $link_attributes, $item_values[‘downloadlink_url’], $item_values[‘thumbnail_content’] );1873 }1874 if ( ! empty( $link_href ) ) {1875 $item_values[‘link’] = sprintf( '<a %1$shref="%2$s" title="%3$s">%4$s</a>’, $link_attributes, $link_href, $rollover_text, $item_values[‘thumbnail_content’] );1876 } elseif ( ‘permalink’ == $arguments[‘link’] || ‘post’ == $arguments[‘link’] ) {1877 $item_values[‘link’] = $item_values[‘pagelink’];1878 } elseif ( ‘file’ == $arguments[‘link’] || ‘full’ == $arguments[‘link’] ) {1879 $item_values[‘link’] = $item_values[‘filelink’];1880 } elseif ( ‘download’ == $arguments[‘link’] ) {1881 $item_values[‘link’] = $item_values[‘downloadlink’];1882 } elseif ( ‘span’ == $arguments[‘link’] ) {1883 $item_values[‘link’] = sprintf( '<a %1$s>%2$s</a>’, $link_attributes, $item_values[‘thumbnail_content’] );1884 } else {1885 $item_values[‘link’] = $item_values[‘thumbnail_content’];1886 }1887 } // viewer extension1888 } // has extension1889 } // mla_viewer18901891 if ( $is_gallery ) {1892 // Start of row markup1893 if ( $markup_values[‘columns’] > 0 && $column_index % $markup_values[‘columns’] == 0 ) {1894 $markup_values = apply_filters( 'mla_gallery_row_open_values’, $markup_values );1895 $row_open_template = apply_filters( 'mla_gallery_row_open_template’, $row_open_template );1896 $parse_value = MLAData::mla_parse_template( $row_open_template, $markup_values );1897 if ( ! $processing_alt_ids_value ) {1898 $output .= apply_filters( 'mla_gallery_row_open_parse’, $parse_value, $row_open_template, $markup_values );1899 }1900 }19011902 // item markup1903 $column_index++;1904 if ( $item_values[‘columns’] > 0 && $column_index % $item_values[‘columns’] == 0 ) {1905 $item_values[‘last_in_row’] = ‘last_in_row’;1906 } else {1907 $item_values[‘last_in_row’] = ‘’;1908 }19091910 // Conditional caption tag to replicate WP 4.1+, now used in the default markup template.1911 if ( $item_values[‘captiontag’] && trim( $item_values[‘caption’] ) ) {1912// $item_values[‘captiontag_content’] = ‘<’ . $item_values[‘captiontag’] . " class=’wp-caption-text gallery-caption’ id=’" . $item_values[‘selector’] . '-' . $item_values[‘attachment_ID’] . “’>\n\t\t” . $item_values[‘caption’] . “\n\t</” . $item_values[‘captiontag’] . ">\n";1913 $item_values[‘captiontag_content’] = ‘<’ . $item_values[‘captiontag’] . " class=’wp-caption-text gallery-caption’ id=’" . $item_values[‘selector’] . '-' . $item_values[‘attachment_ID’] . “’>\n\t” . $item_values[‘caption’] . “\n\t</” . $item_values[‘captiontag’] . “>";1914 } else {1915 $item_values[‘captiontag_content’] = '’;1916 }19171918 $item_values = apply_filters( 'mla_gallery_item_values’, $item_values );19191920 // Accumulate mla_alt_shortcode_ids when mla_alt_ids_value present1921 if ( $processing_alt_ids_value ) {1922 $item_values = MLAData::mla_expand_field_level_parameters( $mla_alt_ids_value, $attr, $item_values );1923 $mla_alt_shortcode_ids[] = MLAData::mla_parse_template( $mla_alt_ids_value, $item_values );1924 continue;1925 }19261927 $item_template = apply_filters( 'mla_gallery_item_template’, $item_template );1928 $parse_value = MLAData::mla_parse_template( $item_template, $item_values );1929 $output .= apply_filters( 'mla_gallery_item_parse’, $parse_value, $item_template, $item_values );19301931 // End of row markup1932 if ( $markup_values[‘columns’] > 0 && $column_index % $markup_values[‘columns’] == 0 ) {1933 $markup_values = apply_filters( 'mla_gallery_row_close_values’, $markup_values );1934 $row_close_template = apply_filters( 'mla_gallery_row_close_template’, $row_close_template );1935 $parse_value = MLAData::mla_parse_template( $row_close_template, $markup_values );1936 $output .= apply_filters( 'mla_gallery_row_close_parse’, $parse_value, $row_close_template, $markup_values );1937 }1938 } // is_gallery1939 elseif ( ! empty( $link_type ) ) {1940 return $item_values[‘link’];1941 }1942 } // foreach attachment19431944 // Execute the alternate gallery shortcode with the new parameters1945 if ( $processing_alt_ids_value ) {1946 // Apply the template when mla_alt_ids_template present1947 if ( is_string( $mla_alt_ids_template ) ) {1948 $markup_values[‘alt_ids’] = implode( ',’, $mla_alt_shortcode_ids );1949 $replacement_values = MLAData::mla_expand_field_level_parameters( $mla_alt_ids_template, $attr, $markup_values );1950 $mla_alt_shortcode_ids = $arguments[‘mla_alt_ids_name’] . ‘="’ . MLAData::mla_parse_template( $mla_alt_ids_template, $replacement_values ) . '"’;1951 unset( $markup_values[‘alt_ids’] );1952 } else {1953 $mla_alt_shortcode_ids = $arguments[‘mla_alt_ids_name’] . ‘="’ . implode( ',’, $mla_alt_shortcode_ids ) . '"’;1954 }19551956 $content = apply_filters( 'mla_gallery_final_content’, $content );1957 if ( ! empty( $content ) ) {1958 return $output . do_shortcode( sprintf( '[%1$s %2$s %3$s]%4$s[/%1$s]', $arguments[‘mla_alt_shortcode’], $mla_alt_shortcode_ids, $mla_alt_shortcode_args, $content ) );1959 } else {1960 return $output . do_shortcode( sprintf( '[%1$s %2$s %3$s]', $arguments[‘mla_alt_shortcode’], $mla_alt_shortcode_ids, $mla_alt_shortcode_args ) );1961 }1962 }19631964 if ( $is_gallery ) {1965 // Close out partial row1966 if ( ! ($markup_values[‘columns’] > 0 && $column_index % $markup_values[‘columns’] == 0 ) ) {1967 $markup_values = apply_filters( 'mla_gallery_row_close_values’, $markup_values );1968 $row_close_template = apply_filters( 'mla_gallery_row_close_template’, $row_close_template );1969 $parse_value = MLAData::mla_parse_template( $row_close_template, $markup_values );1970 $output .= apply_filters( 'mla_gallery_row_close_parse’, $parse_value, $row_close_template, $markup_values );1971 }19721973 $markup_values = apply_filters( 'mla_gallery_close_values’, $markup_values );1974 $close_template = apply_filters( 'mla_gallery_close_template’, $close_template );1975 $parse_value = MLAData::mla_parse_template( $close_template, $markup_values );1976 $output .= apply_filters( 'mla_gallery_close_parse’, $parse_value, $close_template, $markup_values );1977 } // is_gallery19781979 return $output;1980 }19811982 /**1983 * The MLA Tag Cloud support function.1984 *1985 * This is an alternative to the WordPress wp_tag_cloud function, with additional1986 * options to customize the hyperlink behind each term.1987 *1988 * @since 2.201989 *1990 * @param array $attr Attributes of the shortcode.1991 *1992 * @return void|string|string[] Void if ‘echo’ attribute is true, or on failure. Otherwise, tag cloud markup as a string or an array of links, depending on ‘mla_output’ attribute.1993 */1994 public static function mla_tag_cloud( $attr ) {1995 global $post;19961997 // Some do_shortcode callers may not have a specific post in mind1998 if ( ! is_object( $post ) ) {1999 $post = self::_get_default_post();2000 }20012002 // $instance supports multiple clouds in one page/post 2003 static $instance = 0;2004 $instance++;20052006 // Some values are already known, and can be used in data selection parameters2007 $upload_dir = wp_upload_dir();2008 $page_values = array(2009 ‘instance’ => $instance,2010 ‘selector’ => “mla_tag_cloud-{$instance}",2011 ‘site_url’ => site_url(),2012 ‘base_url’ => $upload_dir[‘baseurl’],2013 ‘base_dir’ => $upload_dir[‘basedir’],2014 ‘id’ => $post->ID,2015 ‘page_ID’ => $post->ID,2016 ‘page_author’ => $post->post_author,2017 ‘page_date’ => $post->post_date,2018 ‘page_content’ => $post->post_content,2019 ‘page_title’ => $post->post_title,2020 ‘page_excerpt’ => $post->post_excerpt,2021 ‘page_status’ => $post->post_status,2022 ‘page_name’ => $post->post_name,2023 ‘page_modified’ => $post->post_modified,2024 ‘page_guid’ => $post->guid,2025 ‘page_type’ => $post->post_type,2026 ‘page_url’ => get_page_link(),2027 );20282029 // These are the default parameters for tag cloud display2030 $mla_item_specific_arguments = array(2031 ‘mla_link_attributes’ => '’,2032 ‘mla_link_class’ => '’,2033 ‘mla_link_style’ => '’,2034 ‘mla_link_href’ => '’,2035 ‘mla_link_text’ => '’,2036 ‘mla_nolink_text’ => '’,2037 ‘mla_rollover_text’ => '’,2038 ‘mla_caption’ => '’,2039 ‘mla_item_value’ => '’,2040 );20412042 $defaults = array_merge(2043 self::$mla_get_terms_parameters,2044 array(2045 ‘smallest’ => 8,2046 ‘largest’ => 22,2047 ‘default_size’ => 12,2048 ‘unit’ => 'pt’,2049 ‘separator’ => “\n",2050 ‘single_text’ => '%s item’,2051 ‘multiple_text’ => '%s items’,20522053 ‘echo’ => false,2054 ‘link’ => 'view’,2055 ‘current_item’ => '’,2056 ‘current_item_class’ => 'mla_current_item’,20572058 ‘itemtag’ => 'ul’,2059 ‘termtag’ => 'li’,2060 ‘captiontag’ => '’,2061 ‘columns’ => MLACore::mla_get_option(‘mla_tag_cloud_columns’),20622063 ‘mla_output’ => 'flat’,2064 ‘mla_style’ => NULL,2065 ‘mla_markup’ => NULL,2066 ‘mla_float’ => is_rtl() ? ‘right’ : 'left’,2067 ‘mla_itemwidth’ => MLACore::mla_get_option(‘mla_tag_cloud_itemwidth’),2068 ‘mla_margin’ => MLACore::mla_get_option(‘mla_tag_cloud_margin’),2069 ‘mla_target’ => '’,2070 ‘mla_debug’ => false,20712072 ‘option_all_text’ => '’,2073 ‘option_all_value’ => NULL,2074 ‘option_no_terms_text’ => '’,2075 ‘option_no_terms_value’ => NULL,2076 ‘option_any_terms_text’ => '’,2077 ‘option_any_terms_value’ => NULL,20782079 // Pagination parameters2080 ‘term_id’ => NULL,2081 'mla_end_size’=> 1,2082 ‘mla_mid_size’ => 2,2083 ‘mla_prev_text’ => '« ' . __( 'Previous’, ‘media-library-assistant’ ),2084 ‘mla_next_text’ => __( 'Next’, ‘media-library-assistant’ ) . ' »’,2085 ‘mla_page_parameter’ => 'mla_cloud_current’,2086 ‘mla_cloud_current’ => 1,2087 ‘mla_paginate_total’ => NULL,2088 ‘mla_paginate_type’ => ‘plain’),20892090 $mla_item_specific_arguments2091 );20922093 // Filter the attributes before $mla_page_parameter and “request:” prefix processing.2094 $attr = apply_filters( 'mla_tag_cloud_raw_attributes’, $attr );20952096 /*2097 * The mla_paginate_current parameter can be changed to support2098 * multiple clouds per page.2099 */2100 if ( ! isset( $attr[‘mla_page_parameter’] ) ) {2101 $attr[‘mla_page_parameter’] = $defaults[‘mla_page_parameter’];2102 }21032104 // The mla_page_parameter can contain page_level parameters like {+page_ID+}2105 $attr_value = str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $attr[‘mla_page_parameter’] ) );2106 $mla_page_parameter = MLAData::mla_parse_template( $attr_value, $page_values );2107 2108 /*2109 * Special handling of mla_page_parameter to make “MLA pagination” easier.2110 * Look for this parameter in $_REQUEST if it’s not present in the shortcode itself.2111 */2112 if ( ! isset( $attr[ $mla_page_parameter ] ) ) {2113 if ( isset( $_REQUEST[ $mla_page_parameter ] ) ) {2114 $attr[ $mla_page_parameter ] = sanitize_text_field( wp_unslash( $_REQUEST[ $mla_page_parameter ] ) );2115 }2116 }2117 2118 // Special handling of current_item; look for this parameter in $_REQUEST if it’s not present in the shortcode itself.2119 if ( ! isset( $attr[‘current_item’] ) ) {2120 if ( isset( $_REQUEST[‘current_item’] ) ) {2121 $attr[‘current_item’] = sanitize_text_field( wp_unslash( $_REQUEST[‘current_item’] ) );2122 }2123 }2124 2125 // Determine markup template to get default arguments2126 $arguments = shortcode_atts( $defaults, $attr );2127 if ( $arguments[‘mla_markup’] ) {2128 $template = $arguments[‘mla_markup’];2129 if ( ! MLATemplate_Support::mla_fetch_custom_template( $template, 'tag-cloud’, 'markup’, '[exists]' ) ) {2130 $template = NULL;2131 }2132 } else {2133 $template = NULL;2134 }21352136 if ( empty( $template ) ) {2137 $output_parameters = array_map( 'strtolower’, array_map( 'trim’, explode( ',’, $arguments[‘mla_output’] ) ) );21382139 if ( !in_array( $output_parameters[0], array( 'flat’, 'list’, 'ulist’, 'olist’, 'dlist’, 'grid’, 'array’, 'next_link’, 'current_link’, 'previous_link’, 'next_page’, 'previous_page’, ‘paginate_links’ ) ) ) {2140 $output_parameters[0] = 'flat’;2141 }21422143 if ( ‘grid’ == $output_parameters[0] ) {2144 $template = MLACore::mla_get_option(‘default_tag_cloud_markup’);2145 } elseif ( in_array( $output_parameters[0], array( 'list’, 'ulist’, 'olist’, ‘dlist’ ) ) ) {2146 if ( ( ‘dlist’ == $output_parameters[0] ) || (‘list’ == $output_parameters[0] && ‘dd’ == $arguments[‘captiontag’] ) ) {2147 $template = 'tag-cloud-dl’;2148 } else {2149 $template = 'tag-cloud-ul’;2150 }2151 } else {2152 $template = NULL;2153 }2154 }21552156 // Apply default arguments set in the markup template2157 if ( ! empty( $template ) ) {2158 $arguments = MLATemplate_Support::mla_fetch_custom_template( $template, 'tag-cloud’, 'markup’, ‘arguments’ );2159 if ( ! empty( $arguments ) ) {2160 $attr = wp_parse_args( $attr, self::mla_validate_attributes( array(), $arguments ) );2161 }2162 }21632164 /*2165 * Look for page-level, ‘request:’ and ‘query:’ substitution parameters,2166 * which can be added to any input parameter2167 */2168 foreach ( $attr as $attr_key => $attr_value ) {2169 /*2170 * item-specific Display Content parameters must be evaluated2171 * later, when all of the information is available.2172 */2173 if ( array_key_exists( $attr_key, $mla_item_specific_arguments ) ) {2174 continue;2175 }21762177 $attr_value = str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $attr_value ) );2178 $replacement_values = MLAData::mla_expand_field_level_parameters( $attr_value, $attr, $page_values );2179 $attr[ $attr_key ] = MLAData::mla_parse_template( $attr_value, $replacement_values );2180 }21812182 $attr = apply_filters( 'mla_tag_cloud_attributes’, $attr );2183 $arguments = shortcode_atts( $defaults, $attr );21842185 /*2186 * $mla_page_parameter, if non-default, doesn’t make it through the shortcode_atts2187 * filter, so we handle it separately2188 */2189 if ( empty( $arguments[ $mla_page_parameter ] ) ) {2190 if ( !empty( $attr[ $mla_page_parameter ] ) ) {2191 $arguments[ $mla_page_parameter ] = $attr[ $mla_page_parameter ];2192 } else {2193 $arguments[ $mla_page_parameter ] = $defaults[‘mla_cloud_current’];21942195 }2196 }21972198 // Process the pagination parameter, if present2199 if ( isset( $arguments[ $mla_page_parameter ] ) ) {2200 $arguments[‘offset’] = absint( $arguments[‘limit’] ) * ( absint( $arguments[ $mla_page_parameter ] ) - 1);2201 }22022203 // Clean up the current_item to separate term_id from slug2204 if ( ! empty( $arguments[‘current_item’] ) && is_numeric( $arguments[‘current_item’] ) ) {2205 $arguments[‘current_item’] = (integer) $arguments[‘current_item’];2206 }22072208 $arguments = apply_filters( ‘mla_tag_cloud_arguments’, $arguments );22092210 self::$mla_debug = ( ! empty( $arguments[‘mla_debug’] ) ) ? trim( strtolower( $arguments[‘mla_debug’] ) ) : false;2211 if ( self::$mla_debug ) {2212 if ( ‘true’ == self::$mla_debug ) {2213 MLACore::mla_debug_mode( ‘buffer’ );2214 } elseif ( ‘log’ == self::$mla_debug ) {2215 MLACore::mla_debug_mode( ‘log’ );2216 } else {2217 self::$mla_debug = false;2218 }2219 }22202221 if ( self::$mla_debug ) {2222 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug REQUEST’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $_REQUEST, true ) );2223 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug attributes’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $attr, true ) );2224 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug arguments’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $arguments, true ) );2225 }22262227 // Determine templates and output type2228 if ( $arguments[‘mla_style’] && ( ‘none’ !== $arguments[‘mla_style’] ) ) {2229 if ( !MLATemplate_Support::mla_fetch_custom_template( $arguments[‘mla_style’], 'tag-cloud’, ‘style’, '[exists]' ) ) {2230 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_tag_cloud mla_style</strong> "’ . $arguments[‘mla_style’] . '” ' . __( 'not found’, ‘media-library-assistant’ ), MLACore::MLA_DEBUG_CATEGORY_ANY );2231 $arguments[‘mla_style’] = NULL;2232 }2233 }22342235 if ( $arguments[‘mla_markup’] ) {2236 if ( !MLATemplate_Support::mla_fetch_custom_template( $arguments[‘mla_markup’], 'tag-cloud’, ‘markup’, '[exists]' ) ) {2237 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_tag_cloud mla_markup</strong> "’ . $arguments[‘mla_markup’] . '” ' . __( 'not found’, ‘media-library-assistant’ ), MLACore::MLA_DEBUG_CATEGORY_ANY );2238 $arguments[‘mla_markup’] = NULL;2239 }2240 }22412242 $output_parameters = array_map( 'strtolower’, array_map( 'trim’, explode( ',’, $arguments[‘mla_output’] ) ) );22432244 if ( !in_array( $output_parameters[0], array( 'flat’, 'list’, 'ulist’, 'olist’, 'dlist’, 'grid’, 'array’, 'next_link’, 'current_link’, 'previous_link’, 'next_page’, 'previous_page’, ‘paginate_links’ ) ) ) {2245 $output_parameters[0] = 'flat’;2246 }22472248 if ( $is_grid = ‘grid’ == $output_parameters[0] ) {2249 $default_style = MLACore::mla_get_option(‘default_tag_cloud_style’);2250 $default_markup = MLACore::mla_get_option(‘default_tag_cloud_markup’);22512252 if ( NULL == $arguments[‘mla_style’] ) {2253 $arguments[‘mla_style’] = $default_style;2254 }22552256 if ( NULL == $arguments[‘mla_markup’] ) {2257 $arguments[‘mla_markup’] = $default_markup;2258 }22592260 if ( empty( $attr[‘itemtag’] ) ) {2261 $arguments[‘itemtag’] = 'dl’;2262 }22632264 if ( empty( $attr[‘termtag’] ) ) {2265 $arguments[‘termtag’] = 'dt’;2266 }22672268 if ( empty( $attr[‘captiontag’] ) ) {2269 $arguments[‘captiontag’] = 'dd’;2270 }2271 }22722273 if ( $is_list = in_array( $output_parameters[0], array( 'list’, 'ulist’, 'olist’, ‘dlist’ ) ) ) {2274 $default_style = 'none’;22752276 if ( ‘list’ == $output_parameters[0] && ‘dd’ == $arguments[‘captiontag’] ) {2277 $default_markup = 'tag-cloud-dl’;2278 $arguments[‘itemtag’] = 'dl’;2279 $arguments[‘termtag’] = 'dt’;2280 } else {2281 $default_markup = 'tag-cloud-ul’;2282 $arguments[‘termtag’] = 'li’;2283 $arguments[‘captiontag’] = '’;22842285 switch ( $output_parameters[0] ) {2286 case 'ulist’:2287 $arguments[‘itemtag’] = 'ul’;2288 break;2289 case 'olist’:2290 $arguments[‘itemtag’] = 'ol’;2291 break;2292 case 'dlist’:2293 $default_markup = 'tag-cloud-dl’;2294 $arguments[‘itemtag’] = 'dl’;2295 $arguments[‘termtag’] = 'dt’;2296 $arguments[‘captiontag’] = 'dd’;2297 break;2298 default:2299 $arguments[‘itemtag’] = 'ul’;2300 }2301 }23022303 if ( NULL == $arguments[‘mla_style’] ) {2304 $arguments[‘mla_style’] = $default_style;2305 }23062307 if ( NULL == $arguments[‘mla_markup’] ) {2308 $arguments[‘mla_markup’] = $default_markup;2309 }2310 }23112312 $is_pagination = in_array( $output_parameters[0], array( 'previous_link’, 'current_link’, 'next_link’, 'previous_page’, 'next_page’, ‘paginate_links’ ) ); 23132314 // Convert lists to arrays2315 if ( is_string( $arguments[‘taxonomy’] ) ) {2316 $arguments[‘taxonomy’] = explode( ',’, $arguments[‘taxonomy’] );2317 }23182319 if ( is_string( $arguments[‘post_type’] ) ) {2320 $arguments[‘post_type’] = explode( ',’, $arguments[‘post_type’] );2321 }23222323 if ( is_string( $arguments[‘post_status’] ) ) {2324 $arguments[‘post_status’] = explode( ',’, $arguments[‘post_status’] );2325 }23262327 $tags = self::mla_get_terms( $arguments );23282329 // Invalid taxonomy names return WP_Error2330 if ( is_wp_error( $tags ) ) {2331 $cloud = ‘<strong>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . $tags->get_error_message() . ‘</strong>, ' . $tags->get_error_data( $tags->get_error_code() );23322333 if ( ‘array’ == $arguments[‘mla_output’] ) {2334 return array( $cloud );2335 }23362337 if ( empty($arguments[‘echo’]) ) {2338 return $cloud;2339 }23402341 echo $cloud; // phpcs:ignore2342 return;2343 }23442345 if ( ! ( empty( $arguments[‘option_any_terms_text’] ) && empty( $arguments[‘option_no_terms_text’] ) && empty( $arguments[‘option_all_text’] ) ) ) {2346 $terms_assigned_counts = self::mla_get_all_none_term_counts( $arguments );2347 } else {2348 $terms_assigned_counts = array( ‘ignore.terms.assigned’ => 0, ‘no.terms.assigned’ => 0, ‘any.terms.assigned’ => 0 );2349 }23502351 // Fill in the item_specific link properties, calculate cloud parameters2352 if ( isset( $tags[‘found_rows’] ) ) {2353 $found_rows = $tags[‘found_rows’];2354 unset( $tags[‘found_rows’] );2355 } else {2356 $found_rows = count( $tags );2357 }23582359 if ( 0 === $found_rows ) {2360 if ( self::$mla_debug ) {2361 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug empty cloud’, ‘media-library-assistant’ ) . '</strong>, query = ' . var_export( $arguments, true ) );2362 $cloud = MLACore::mla_debug_flush();23632364 if ( ‘<p></p>’ == $cloud ) {2365 $cloud = '’;2366 }2367 } else {2368 $cloud = '’;2369 }23702371 $cloud .= $arguments[‘mla_nolink_text’];2372 if ( ‘array’ == $arguments[‘mla_output’] ) {2373 if ( empty( $cloud ) ) {2374 return array();2375 } else {2376 return array( $cloud );2377 }2378 }23792380 if ( empty($arguments[‘echo’]) ) {2381 return $cloud;2382 }23832384 echo $cloud; // phpcs:ignore2385 return;2386 } // Empty cloud23872388 if ( self::$mla_debug ) {2389 $cloud = MLACore::mla_debug_flush();2390 } else {2391 $cloud = '’;2392 }23932394 $min_count = 0x7FFFFFFF;2395 $max_count = 0;2396 $min_scaled_count = 0x7FFFFFFF;2397 $max_scaled_count = 0;2398 foreach ( $tags as $key => $tag ) {2399 $tag_count = isset ( $tag->count ) ? $tag->count : 0;2400 $tag->scaled_count = apply_filters( 'mla_tag_cloud_scale’, round(log10($tag_count + 1) * 100), $attr, $arguments, $tag );24012402 if ( $tag_count < $min_count ) {2403 $min_count = $tag_count;2404 }24052406 if ( $tag_count > $max_count ) {2407 $max_count = $tag_count;2408 }24092410 if ( $tag->scaled_count < $min_scaled_count ) {2411 $min_scaled_count = $tag->scaled_count;2412 }24132414 if ( $tag->scaled_count > $max_scaled_count ) {2415 $max_scaled_count = $tag->scaled_count;2416 }24172418 $link = get_edit_tag_link( $tag->term_id, $tag->taxonomy );2419 if ( ! is_wp_error( $link ) ) {2420 $tags[ $key ]->edit_link = $link;2421 $link = get_term_link( (int) $tag->term_id, $tag->taxonomy );2422 $tags[ $key ]->term_link = $link;2423 }24242425 if ( is_wp_error( $link ) ) {2426 $cloud = ‘<strong>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . $link->get_error_message() . '</strong>, ' . $link->get_error_data( $link->get_error_code() );24272428 if ( ‘array’ == $arguments[‘mla_output’] ) {2429 return array( $cloud );2430 }24312432 if ( empty($arguments[‘echo’]) ) {2433 return $cloud;2434 }24352436 echo $cloud; // phpcs:ignore2437 return;2438 }24392440 if ( ‘edit’ == $arguments[‘link’] ) {2441 $tags[ $key ]->link = $tags[ $key ]->edit_link;2442 } else {2443 $tags[ $key ]->link = $tags[ $key ]->term_link;2444 }2445 } // foreach tag24462447 // Add the optional 'all-terms’, ‘any-terms’ and/or ‘no-terms’ option(s), if requested2448 if ( ! empty( $arguments[‘option_any_terms_text’] ) ) {2449 $new_term_id = -2;2450 $new_term_slug = 'any.terms.assigned’;24512452 if ( ! empty( $arguments[‘option_any_terms_value’] ) ) {2453 $new_term_value = self::_process_shortcode_parameter( $arguments[‘option_any_terms_value’], $page_values );2454 if ( is_numeric( $new_term_value ) ) {2455 $new_term_id = (integer) $new_term_value;2456 $new_term_slug = sanitize_title( $arguments[‘option_any_terms_text’] );2457 } else {2458 $new_term_slug = sanitize_title( $new_term_value );2459 }2460 }24612462 $new_term = ( object ) array(2463 ‘term_id’ => $new_term_id,2464 ‘name’ => $arguments[‘option_any_terms_text’],2465 ‘slug’ => $new_term_slug,2466 ‘term_group’ => '0’,2467 ‘term_taxonomy_id’ => $new_term_id,2468 ‘taxonomy’ => $arguments[‘taxonomy’][0],2469 ‘description’ => '’,2470 ‘parent’ => '0’,2471 ‘count’ => $terms_assigned_counts[‘any.terms.assigned’],2472 ‘level’ => 0,2473 ‘edit_link’ => '’,2474 ‘term_link’ => '’,2475 ‘link’ => '’,2476 );2477 $new_term->scaled_count = apply_filters( ‘mla_tag_cloud_scale’, round( log10( 1 ) * 100 ), $attr, $arguments, $new_term );24782479 if ( self::$mla_debug ) {2480 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug adding ANY terms’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $new_term, true ) );2481 }2482 array_unshift( $tags, $new_term );2483 $found_rows += 1;2484 }24852486 if ( ! empty( $arguments[‘option_no_terms_text’] ) ) {2487 $new_term_id = -1;2488 $new_term_slug = 'no.terms.assigned’;24892490 if ( ! empty( $arguments[‘option_no_terms_value’] ) ) {2491 $new_term_value = self::_process_shortcode_parameter( $arguments[‘option_no_terms_value’], $page_values );2492 if ( is_numeric( $new_term_value ) ) {2493 $new_term_id = (integer) $new_term_value;2494 $new_term_slug = sanitize_title( $arguments[‘option_no_terms_text’] );2495 } else {2496 $new_term_slug = sanitize_title( $new_term_value );2497 }2498 }24992500 $new_term = ( object ) array(2501 ‘term_id’ => $new_term_id,2502 ‘name’ => $arguments[‘option_no_terms_text’],2503 ‘slug’ => $new_term_slug,2504 ‘term_group’ => '0’,2505 ‘term_taxonomy_id’ => $new_term_id,2506 ‘taxonomy’ => $arguments[‘taxonomy’][0],2507 ‘description’ => '’,2508 ‘parent’ => '0’,2509 ‘count’ => $terms_assigned_counts[‘no.terms.assigned’],2510 ‘level’ => 0,2511 ‘edit_link’ => '’,2512 ‘term_link’ => '’,2513 ‘link’ => '’,2514 );2515 $new_term->scaled_count = apply_filters( ‘mla_tag_cloud_scale’, round( log10( 1 ) * 100 ), $attr, $arguments, $new_term );25162517 if ( self::$mla_debug ) {2518 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug adding NO terms’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $new_term, true ) );2519 }2520 array_unshift( $tags, $new_term );2521 $found_rows += 1;2522 }25232524 if ( ! empty( $arguments[‘option_all_text’] ) ) {2525 $new_term_id = -3;2526 $new_term_slug = 'ignore.terms.assigned’;25272528 if ( ! empty( $arguments[‘option_all_value’] ) ) {2529 $new_term_value = self::_process_shortcode_parameter( $arguments[‘option_all_value’], $page_values );2530 if ( is_numeric( $new_term_value ) ) {2531 $new_term_id = (integer) $new_term_value;2532 $new_term_slug = sanitize_title( $arguments[‘option_all_text’] );2533 } else {2534 $new_term_slug = sanitize_title( $new_term_value );2535 }2536 }25372538 $new_term = ( object ) array(2539 ‘term_id’ => $new_term_id,2540 ‘name’ => $arguments[‘option_all_text’],2541 ‘slug’ => $new_term_slug,2542 ‘term_group’ => '0’,2543 ‘term_taxonomy_id’ => $new_term_id,2544 ‘taxonomy’ => $arguments[‘taxonomy’][0],2545 ‘description’ => '’,2546 ‘parent’ => '0’,2547 ‘count’ => $terms_assigned_counts[‘ignore.terms.assigned’],2548 ‘level’ => 0,2549 ‘edit_link’ => '’,2550 ‘term_link’ => '’,2551 ‘link’ => '’,2552 );2553 $new_term->scaled_count = apply_filters( ‘mla_tag_cloud_scale’, round( log10( 1 ) * 100 ), $attr, $arguments, $new_term );25542555 if ( self::$mla_debug ) {2556 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug adding IGNORE terms’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $new_term, true ) );2557 }2558 array_unshift( $tags, $new_term );2559 $found_rows += 1;2560 }25612562 /*2563 * The default MLA style template includes “margin: 1.5%” to put a bit of2564 * minimum space between the columns. “mla_margin” can be used to change2565 * this. “mla_itemwidth” can be used with “columns=0” to achieve a2566 * “responsive” layout.2567 */2568 2569 $columns = absint( $arguments[‘columns’] );2570 $margin_string = strtolower( trim( $arguments[‘mla_margin’] ) );25712572 if ( is_numeric( $margin_string ) && ( 0 != $margin_string) ) {2573 $margin_string .= '%’; // Legacy values are always in percent2574 }25752576 if ( ‘%’ == substr( $margin_string, -1 ) ) {2577 $margin_percent = (float) substr( $margin_string, 0, strlen( $margin_string ) - 1 );2578 } else {2579 $margin_percent = 0;2580 }25812582 $width_string = strtolower( trim( $arguments[‘mla_itemwidth’] ) );2583 if ( ‘none’ != $width_string ) {2584 switch ( $width_string ) {2585 case 'exact’:2586 $margin_percent = 0;2587 // fallthru2588 case 'calculate’:2589 $width_string = $columns > 0 ? (floor(1000/$columns)/10) - ( 2.0 * $margin_percent ) : 100 - ( 2.0 * $margin_percent );2590 // fallthru2591 default:2592 if ( is_numeric( $width_string ) && ( 0 != $width_string) ) {2593 $width_string .= '%’; // Legacy values are always in percent2594 }2595 }2596 } // $use_width25972598 $float = strtolower( $arguments[‘mla_float’] );2599 if ( ! in_array( $float, array( 'left’, 'none’, ‘right’ ) ) ) {2600 $float = is_rtl() ? ‘right’ : 'left’;2601 }26022603 // Calculate cloud parameters2604 $spread = $max_scaled_count - $min_scaled_count;2605 if ( $spread <= 0 ) {2606 $spread = 1;2607 }26082609 $font_spread = $arguments[‘largest’] - $arguments[‘smallest’];2610 if ( $font_spread < 0 ) {2611 $font_spread = 1;2612 }26132614 $font_step = $font_spread / $spread;26152616 $style_values = array_merge( $page_values, array(2617 ‘mla_output’ => $arguments[‘mla_output’],2618 ‘mla_style’ => $arguments[‘mla_style’],2619 ‘mla_markup’ => $arguments[‘mla_markup’],2620 ‘taxonomy’ => implode( '-', $arguments[‘taxonomy’] ),2621 ‘current_item’ => $arguments[‘current_item’],2622 ‘itemtag’ => tag_escape( $arguments[‘itemtag’] ),2623 ‘termtag’ => tag_escape( $arguments[‘termtag’] ),2624 ‘captiontag’ => tag_escape( $arguments[‘captiontag’] ),2625 ‘columns’ => $columns,2626 ‘itemwidth’ => $width_string,2627 ‘margin’ => $margin_string,2628 ‘float’ => $float,2629 ‘found_rows’ => $found_rows,2630 ‘min_count’ => $min_count,2631 ‘max_count’ => $max_count,2632 ‘min_scaled_count’ => $min_scaled_count,2633 ‘max_scaled_count’ => $max_scaled_count,2634 ‘spread’ => $spread,2635 ‘smallest’ => $arguments[‘smallest’],2636 ‘largest’ => $arguments[‘largest’],2637 ‘unit’ => $arguments[‘unit’],2638 ‘font_spread’ => $font_spread,2639 ‘font_step’ => $font_step,2640 ‘separator’ => $arguments[‘separator’],2641 ‘single_text’ => $arguments[‘single_text’],2642 ‘multiple_text’ => $arguments[‘multiple_text’],2643 ‘echo’ => $arguments[‘echo’],2644 ‘link’ => $arguments[‘link’]2645 ) );26462647 $style_template = $gallery_style = '’;2648 $use_mla_tag_cloud_style = ( $is_grid || $is_list ) && ( ‘none’ != strtolower( $style_values[‘mla_style’] ) );2649 if ( apply_filters( 'use_mla_tag_cloud_style’, $use_mla_tag_cloud_style, $style_values[‘mla_style’] ) ) {2650 $style_template = MLATemplate_support::mla_fetch_custom_template( $style_values[‘mla_style’], 'tag-cloud’, ‘style’ );2651 if ( empty( $style_template ) ) {2652 $style_values[‘mla_style’] = $default_style;2653 $style_template = MLATemplate_support::mla_fetch_custom_template( $default_style, 'tag-cloud’, ‘style’ );2654 }26552656 if ( ! empty ( $style_template ) ) {2657 // Look for ‘query’ and ‘request’ substitution parameters2658 $style_values = MLAData::mla_expand_field_level_parameters( $style_template, $attr, $style_values );26592660 // Clean up the template to resolve width or margin == 'none’2661 if ( ‘none’ == $margin_string ) {2662 $style_values[‘margin’] = '0’;2663 $style_template = preg_replace( '/margin:[\s]*\[\+margin\+\][\%]*[\;]*/’, '’, $style_template );2664 }26652666 if ( ‘none’ == $width_string ) {2667 $style_values[‘itemwidth’] = 'auto’;2668 $style_template = preg_replace( '/width:[\s]*\[\+itemwidth\+\][\%]*[\;]*/’, '’, $style_template );2669 }26702671 $style_values = apply_filters( 'mla_tag_cloud_style_values’, $style_values );2672 $style_template = apply_filters( 'mla_tag_cloud_style_template’, $style_template );2673 $gallery_style = MLAData::mla_parse_template( $style_template, $style_values );2674 $gallery_style = apply_filters( 'mla_tag_cloud_style_parse’, $gallery_style, $style_template, $style_values );2675 } // !empty template2676 } // use_mla_tag_cloud_style26772678 $markup_values = $style_values;26792680 if ( $is_grid || $is_list ) {2681 $open_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'tag-cloud’, 'markup’, ‘open’ );2682 if ( false === $open_template ) {2683 $markup_values[‘mla_markup’] = $default_markup;2684 $open_template = MLATemplate_support::mla_fetch_custom_template( $default_markup, 'tag-cloud’, 'markup’, ‘open’ );2685 }26862687 if ( empty( $open_template ) ) {2688 $open_template = '’;2689 }26902691 if ( $is_grid ) {2692 $row_open_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'tag-cloud’, 'markup’, ‘row-open’ );2693 if ( empty( $row_open_template ) ) {2694 $row_open_template = '’;2695 }2696 } else {2697 $row_open_template = '’;2698 }26992700 $item_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'tag-cloud’, 'markup’, ‘item’ );2701 if ( empty( $item_template ) ) {2702 $item_template = '’;2703 }27042705 if ( $is_grid ) {2706 $row_close_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'tag-cloud’, 'markup’, ‘row-close’ );2707 if ( empty( $row_close_template ) ) {2708 $row_close_template = '’;2709 }2710 } else {2711 $row_close_template = '’;2712 }27132714 $close_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'tag-cloud’, 'markup’, ‘close’ );2715 if ( empty( $close_template ) ) {2716 $close_template = '’;2717 }27182719 // Look for gallery-level markup substitution parameters2720 $new_text = $open_template . $row_open_template . $row_close_template . $close_template;2721 $markup_values = MLAData::mla_expand_field_level_parameters( $new_text, $attr, $markup_values );27222723 $markup_values = apply_filters( 'mla_tag_cloud_open_values’, $markup_values );2724 $open_template = apply_filters( 'mla_tag_cloud_open_template’, $open_template );2725 if ( empty( $open_template ) ) {2726 $gallery_open = '’;2727 } else {2728 $gallery_open = MLAData::mla_parse_template( $open_template, $markup_values );2729 }27302731 $gallery_open = apply_filters( 'mla_tag_cloud_open_parse’, $gallery_open, $open_template, $markup_values );2732 $cloud .= $gallery_style . $gallery_open;2733 } // is_grid || is_list2734 elseif ( $is_pagination ) {2735 // Handle 'previous_page’, 'next_page’, and 'paginate_links’2736 if ( isset( $attr[‘limit’] ) ) {2737 $attr[‘posts_per_page’] = $attr[‘limit’];2738 }27392740 $pagination_result = self::_process_pagination_output_types( $output_parameters, $markup_values, $arguments, $attr, $found_rows );2741 if ( false !== $pagination_result ) {2742 return $pagination_result;2743 }27442745 // For “previous_link", “current_link” and “next_link", discard all of the $tags except the appropriate choice2746 $link_type = $output_parameters[0];27472748 if ( ! in_array( $link_type, array ( 'previous_link’, 'current_link’, ‘next_link’ ) ) ) {2749 return '’; // unknown output type2750 }27512752 $is_wrap = isset( $output_parameters[1] ) && ‘wrap’ == $output_parameters[1];2753 if ( empty( $arguments[‘term_id’] ) ) {2754 $target_id = -2; // won’t match anything2755 } else {2756 $current_id = $arguments[‘term_id’];27572758 foreach ( $tags as $id => $tag ) {2759 if ( $tag->term_id == $current_id ) {2760 break;2761 }2762 }27632764 switch ( $link_type ) {2765 case 'previous_link’:2766 $target_id = $id - 1;2767 break;2768 case 'next_link’:2769 $target_id = $id + 1;2770 break;2771 case 'current_link’:2772 default:2773 $target_id = $id;2774 } // link_type2775 }27762777 $target = NULL;2778 if ( isset( $tags[ $target_id ] ) ) {2779 $target = $tags[ $target_id ];2780 } elseif ( $is_wrap ) {2781 switch ( $link_type ) {2782 case 'previous_link’:2783 $target = array_pop( $tags );2784 break;2785 case 'next_link’:2786 $target = array_shift( $tags );2787 } // link_type2788 } // is_wrap27892790 if ( isset( $target ) ) {2791 $tags = array( $target );2792 } elseif ( ! empty( $arguments[‘mla_nolink_text’] ) ) {2793 return self::_process_shortcode_parameter( $arguments[‘mla_nolink_text’], $markup_values ) . '</a>’;2794 } else {2795 return '’;2796 }2797 } // is_pagination27982799 // Accumulate links for flat and array output2800 $tag_links = array();28012802 // Find delimiter for currentlink, currentlink_url2803 if ( strpos( $markup_values[‘page_url’], ‘?’ ) ) {2804 $current_item_delimiter = '&’;2805 } else {2806 $current_item_delimiter = '?’;2807 }28082809 $column_index = 0;2810 foreach ( $tags as $key => $tag ) {2811 $item_values = $markup_values;28122813 // fill in item-specific elements2814 $item_values[‘index’] = (string) 1 + $column_index;2815 if ( $item_values[‘columns’] > 0 && ( 1 + $column_index ) % $item_values[‘columns’] == 0 ) {2816 $item_values[‘last_in_row’] = 'last_in_row’;2817 } else {2818 $item_values[‘last_in_row’] = '’;2819 }28202821 $item_values[‘key’] = $key;2822 $item_values[‘term_id’] = $tag->term_id;2823 $item_values[‘name’] = wptexturize( $tag->name );2824 $item_values[‘slug’] = $tag->slug;2825 $item_values[‘term_group’] = $tag->term_group;2826 $item_values[‘term_taxonomy_id’] = $tag->term_taxonomy_id;2827 $item_values[‘taxonomy’] = $tag->taxonomy;2828 $item_values[‘description’] = wptexturize( $tag->description );2829 $item_values[‘parent’] = $tag->parent;2830 $item_values[‘count’] = isset ( $tag->count ) ? (integer) $tag->count : 0; 2831 $item_values[‘term_count’] = isset ( $tag->term_count ) ? (integer) $tag->term_count : 0; 2832 $item_values[‘scaled_count’] = $tag->scaled_count;28332834 if ( in_array( $tag->slug, array( 'ignore.terms.assigned’, 'no.terms.assigned’, ‘any.terms.assigned’ ) ) ) {2835 $item_values[‘font_size’] = absint( $arguments[‘default_size’] );2836 } else {2837 $item_values[‘font_size’] = str_replace( ',’, '.’, ( $item_values[‘smallest’] + ( ( $item_values[‘scaled_count’] - $item_values[‘min_scaled_count’] ) * $item_values[‘font_step’] ) ) );2838 }28392840 $item_values[‘link_url’] = $tag->link;2841 $item_values[‘currentlink_url’] = sprintf( '%1$s%2$scurrent_item=%3$d’, $item_values[‘page_url’], $current_item_delimiter, $item_values[‘term_id’] );2842 $item_values[‘editlink_url’] = $tag->edit_link;2843 $item_values[‘termlink_url’] = $tag->term_link;2844 // Added in the code below:2845 $item_values[‘caption’] = '’;2846 $item_values[‘link_attributes’] = '’;2847 $item_values[‘current_item_class’] = '’;2848 $item_values[‘rollover_text’] = '’;2849 $item_values[‘link_style’] = '’;2850 $item_values[‘link_text’] = '’;2851 $item_values[‘currentlink’] = '’;2852 $item_values[‘editlink’] = '’;2853 $item_values[‘termlink’] = '’;2854 $item_values[‘thelink’] = '’;28552856 if ( ! empty( $arguments[‘current_item’] ) ) {2857 if ( is_integer( $arguments[‘current_item’] ) ) {2858 if ( intval( $tag->term_id ) === $arguments[‘current_item’] ) {2859 $item_values[‘current_item_class’] = $arguments[‘current_item_class’];2860 }2861 } else {2862 if ( sanitize_title_for_query( $tag->slug ) === sanitize_title_for_query( $arguments[‘current_item’] ) ) {2863 $item_values[‘current_item_class’] = $arguments[‘current_item_class’];2864 }2865 }2866 }28672868 // Add item_specific field-level substitution parameters2869 $new_text = isset( $item_template ) ? $item_template : '’;2870 foreach( $mla_item_specific_arguments as $index => $value ) {2871 $new_text .= str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $arguments[ $index ] ) );2872 }28732874 $item_values = MLAData::mla_expand_field_level_parameters( $new_text, $attr, $item_values );28752876 if ( $item_values[‘captiontag’] ) {2877 $item_values[‘caption’] = wptexturize( $tag->description );2878 if ( ! empty( $arguments[‘mla_caption’] ) ) {2879 $item_values[‘caption’] = wptexturize( self::_process_shortcode_parameter( $arguments[‘mla_caption’], $item_values ) );2880 }2881 } else {2882 $item_values[‘caption’] = '’;2883 }28842885 // Apply the Display Content parameters.2886 if ( ! empty( $arguments[‘mla_target’] ) ) {2887 $link_attributes = ‘target="’ . $arguments[‘mla_target’] . '” ';2888 } else {2889 $link_attributes = '’;2890 }28912892 if ( ! empty( $arguments[‘mla_link_attributes’] ) ) {2893 $link_attributes .= self::_process_shortcode_parameter( $arguments[‘mla_link_attributes’], $item_values ) . ' ';2894 }28952896 if ( ! empty( $item_values[‘current_item_class’] ) ) {2897 $class_attributes = $item_values[‘current_item_class’];2898 } else {2899 $class_attributes = ‘’;2900 }29012902 if ( ! empty( $arguments[‘mla_link_class’] ) ) {2903 $class_attributes .= ' ' . self::_process_shortcode_parameter( $arguments[‘mla_link_class’], $item_values );2904 }29052906 if ( ! empty( $class_attributes ) ) {2907 $link_attributes .= ' class="’ . trim( $class_attributes ) . '” ';2908 }29092910 $item_values[‘link_attributes’] = $link_attributes;29112912 // Ignore option- all,any_terms,no_terms2913 if ( -1 !== $item_values[‘count’] ) {2914 $item_values[‘rollover_text’] = sprintf( _n( $item_values[‘single_text’], $item_values[‘multiple_text’], $item_values[‘count’], ‘media-library-assistant’ ), number_format_i18n( $item_values[‘count’] ) );2915 }29162917 if ( ! empty( $arguments[‘mla_rollover_text’] ) ) {2918 $item_values[‘rollover_text’] = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_rollover_text’], $item_values ) );2919 }29202921 if ( ! empty( $arguments[‘mla_link_href’] ) ) {2922 $link_href = self::_process_shortcode_parameter( $arguments[‘mla_link_href’], $item_values );2923 $item_values[‘link_url’] = $link_href;2924 } else {2925 $link_href = '’;2926 }29272928 if ( ! empty( $arguments[‘mla_link_style’] ) ) {2929 $item_values[‘link_style’] = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_link_style’], $item_values ) );2930 } else {2931 $item_values[‘link_style’] = 'font-size: ' . $item_values[‘font_size’] . $item_values[‘unit’];2932 }29332934 if ( ! empty( $arguments[‘mla_link_text’] ) ) {2935 $item_values[‘link_text’] = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_link_text’], $item_values ) );2936 } else {2937 $item_values[‘link_text’] = $item_values[‘name’];2938 }29392940 if ( empty( $arguments[‘mla_item_value’] ) ) {2941 $item_values[‘thevalue’] = $item_values[‘term_id’];2942 } else {2943 $item_values[‘thevalue’] = self::_process_shortcode_parameter( $arguments[‘mla_item_value’], $item_values );2944 }29452946 // Currentlink, editlink, termlink and thelink2947 $item_values[‘currentlink’] = sprintf( '<a %1$shref="%2$s%3$scurrent_item=%4$d” title="%5$s" style="%6$s">%7$s</a>’, $link_attributes, $item_values[‘page_url’], $current_item_delimiter, $item_values[‘thevalue’], $item_values[‘rollover_text’], $item_values[‘link_style’], $item_values[‘link_text’] );2948 $item_values[‘editlink’] = sprintf( '<a %1$shref="%2$s" title="%3$s" style="%4$s">%5$s</a>’, $link_attributes, $item_values[‘editlink_url’], $item_values[‘rollover_text’], $item_values[‘link_style’], $item_values[‘link_text’] );2949 $item_values[‘termlink’] = sprintf( '<a %1$shref="%2$s" title="%3$s" style="%4$s">%5$s</a>’, $link_attributes, $item_values[‘termlink_url’], $item_values[‘rollover_text’], $item_values[‘link_style’], $item_values[‘link_text’] );29502951 if ( ! empty( $link_href ) ) {2952 $item_values[‘thelink’] = sprintf( '<a %1$shref="%2$s" title="%3$s" style="%4$s">%5$s</a>’, $link_attributes, $link_href, $item_values[‘rollover_text’], $item_values[‘link_style’], $item_values[‘link_text’] );2953 } elseif ( ‘current’ == $arguments[‘link’] ) {2954 $item_values[‘link_url’] = $item_values[‘currentlink_url’];2955 $item_values[‘thelink’] = $item_values[‘currentlink’];2956 } elseif ( ‘edit’ == $arguments[‘link’] ) {2957 $item_values[‘thelink’] = $item_values[‘editlink’];2958 } elseif ( ‘view’ == $arguments[‘link’] ) {2959 $item_values[‘thelink’] = $item_values[‘termlink’];2960 } elseif ( ‘span’ == $arguments[‘link’] ) {2961 $item_values[‘thelink’] = sprintf( '<span %1$sstyle="%2$s">%3$s</span>’, $link_attributes, $item_values[‘link_style’], $item_values[‘link_text’] );2962 } else {2963 $item_values[‘thelink’] = $item_values[‘link_text’];2964 }29652966 if ( $is_grid || $is_list ) {2967 // Start of row markup2968 if ( $is_grid && ( $markup_values[‘columns’] > 0 && $column_index % $markup_values[‘columns’] == 0 ) ) {2969 $markup_values = apply_filters( 'mla_tag_cloud_row_open_values’, $markup_values );2970 $row_open_template = apply_filters( 'mla_tag_cloud_row_open_template’, $row_open_template );2971 $parse_value = MLAData::mla_parse_template( $row_open_template, $markup_values );2972 $cloud .= apply_filters( 'mla_tag_cloud_row_open_parse’, $parse_value, $row_open_template, $markup_values );2973 }29742975 // item markup2976 $column_index++;2977 $item_values = apply_filters( 'mla_tag_cloud_item_values’, $item_values );2978 $item_template = apply_filters( 'mla_tag_cloud_item_template’, $item_template );2979 $parse_value = MLAData::mla_parse_template( $item_template, $item_values );2980 $cloud .= apply_filters( 'mla_tag_cloud_item_parse’, $parse_value, $item_template, $item_values );29812982 // End of row markup2983 if ( $is_grid && ( $markup_values[‘columns’] > 0 && $column_index % $markup_values[‘columns’] == 0 ) ) {2984 $markup_values = apply_filters( 'mla_tag_cloud_row_close_values’, $markup_values );2985 $row_close_template = apply_filters( 'mla_tag_cloud_row_close_template’, $row_close_template );2986 $parse_value = MLAData::mla_parse_template( $row_close_template, $markup_values );2987 $cloud .= apply_filters( 'mla_tag_cloud_row_close_parse’, $parse_value, $row_close_template, $markup_values );2988 }2989 } // is_grid || is_list2990 elseif ( $is_pagination ) {2991 return $item_values[‘thelink’];2992 } else {2993 $column_index++;2994 $item_values = apply_filters( 'mla_tag_cloud_item_values’, $item_values );2995 $tag_links[] = apply_filters( 'mla_tag_cloud_item_parse’, $item_values[‘thelink’], NULL, $item_values );2996 } 2997 } // foreach tag29982999 if ($is_grid || $is_list ) {3000 // Close out partial row3001 if ( $is_grid && ( ! ($markup_values[‘columns’] > 0 && $column_index % $markup_values[‘columns’] == 0 ) ) ) {3002 $markup_values = apply_filters( 'mla_tag_cloud_row_close_values’, $markup_values );3003 $row_close_template = apply_filters( 'mla_tag_cloud_row_close_template’, $row_close_template );3004 $parse_value = MLAData::mla_parse_template( $row_close_template, $markup_values );3005 $cloud .= apply_filters( 'mla_tag_cloud_row_close_parse’, $parse_value, $row_close_template, $markup_values );3006 }30073008 $markup_values = apply_filters( 'mla_tag_cloud_close_values’, $markup_values );3009 $close_template = apply_filters( 'mla_tag_cloud_close_template’, $close_template );3010 $parse_value = MLAData::mla_parse_template( $close_template, $markup_values );3011 $cloud .= apply_filters( 'mla_tag_cloud_close_parse’, $parse_value, $close_template, $markup_values );3012 } // is_grid || is_list3013 else {3014 switch ( $markup_values[‘mla_output’] ) {3015 case ‘array’ :3016 $cloud =& $tag_links;3017 break;3018 case ‘flat’ :3019 default :3020 $cloud .= join( $markup_values[‘separator’], $tag_links );3021 break;3022 } // switch format3023 }30243025 if ( ‘array’ == $arguments[‘mla_output’] || empty($arguments[‘echo’]) ) {3026 return $cloud;3027 }30283029 echo $cloud; // phpcs:ignore3030 }30313032 /**3033 * The MLA Tag Cloud shortcode.3034 *3035 * This is an interface to the mla_tag_cloud function.3036 *3037 * @since 2.203038 *3039 * @param array $attr Attributes of the shortcode.3040 * @param string $content Optional content for enclosing shortcodes3041 *3042 * @return string HTML content to display the tag cloud.3043 */3044 public static function mla_tag_cloud_shortcode( $attr, $content = NULL ) {3045 /*3046 * Make sure $attr is an array, even if it’s empty,3047 * and repair damage caused by line breaks in the source text3048 */3049 $attr = self::mla_validate_attributes( $attr, $content );30503051 // The ‘array’ format makes no sense in a shortcode3052 if ( isset( $attr[‘mla_output’] ) && ‘array’ == $attr[‘mla_output’] ) {3053 $attr[‘mla_output’] = 'flat’;3054 }3055 3056 // A shortcode must return its content to the caller, so “echo” makes no sense3057 $attr[‘echo’] = false;3058 3059 return self::mla_tag_cloud( $attr );3060 }30613062 /**3063 * Compose one level of an mla_term_list3064 *3065 * Adds shortcode output text and term-specific links to arrays passed by reference.3066 *3067 * @since 2.253068 *3069 * @param string $list Shortcode output text, by reference3070 * @param array $links Term-specific links for flat/array output, by reference3071 * @param array $terms Term objects, by reference3072 * @param array $markup_values Style and list-level substitution parameters, by reference3073 * @param array $arguments Shortcode parameters, including defaults, by reference3074 * @param array $attr Shortcode parameters, explicit, by reference3075 *3076 * @return boolean True if the list contains the “current_item"; appends to &$list, &$links3077 */3078 public static function _compose_term_list( &$list, &$links, &$terms, &$markup_values, &$arguments, &$attr ) {3079 $term = reset( $terms );3080 $markup_values[‘current_level’] = $current_level = $term->level;3081 if ( $current_level ) {3082 $markup_values[‘itemtag_class’] = 'term-list term-list-taxonomy-' . $term->taxonomy . ' children’; 3083 $markup_values[‘itemtag_id’] = $markup_values[‘selector’] . '-' . $term->parent;3084 } else {3085 $markup_values[‘itemtag_class’] = 'term-list term-list-taxonomy-' . $term->taxonomy; 3086 $markup_values[‘itemtag_id’] = $markup_values[‘selector’];3087 }30883089 $mla_item_parameter = $arguments[‘mla_item_parameter’];30903091 // Determine output type and templates3092 $output_parameters = array_map( 'strtolower’, array_map( 'trim’, explode( ',’, $arguments[‘mla_output’] ) ) );30933094 if ( !in_array( $output_parameters[0], array( 'flat’, 'list’, 'ulist’, 'olist’, 'dlist’, 'dropdown’, 'checklist’, ‘array’ ) ) ) {3095 $output_parameters[0] = 'ulist’;3096 }30973098 $is_list = in_array( $output_parameters[0], array( 'list’, 'ulist’, 'olist’, ‘dlist’ ) );3099 $is_dropdown = ‘dropdown’ == $output_parameters[0];3100 $is_checklist = ‘checklist’ == $output_parameters[0];3101 $is_hierarchical = !( ‘false’ === $arguments[‘hierarchical’] );3102 $combine_hierarchical = ‘combine’ === $arguments[‘hierarchical’];31033104 // Using the slug is a common practice and affects current_item3105 if ( $is_dropdown || $is_checklist ) {3106 $current_is_slug = in_array( $arguments[‘mla_option_value’], array( '{+slug+}’, '[+slug+]' ) );3107 } else {3108 $current_is_slug = in_array( $arguments[‘mla_item_value’], array( '{+slug+}’, '[+slug+]' ) );3109 }31103111 if ( $is_list || $is_dropdown || $is_checklist ) {3112 if ( $term->parent ) {3113 $open_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'term-list’, 'markup’, ‘child-open’ );3114 } else {3115 $open_template = false;3116 }31173118 if ( false === $open_template ) {3119 $open_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'term-list’, 'markup’, ‘open’ );3120 }31213122 // Fall back to default template if no Open section3123 if ( false === $open_template ) {3124 $markup_values[‘mla_markup’] = $arguments[‘default_mla_markup’];31253126 if ( $term->parent ) {3127 $open_template = MLATemplate_support::mla_fetch_custom_template( $arguments[‘mla_markup’], 'term-list’, 'markup’, ‘child-open’ );3128 } else {3129 $open_template = false;3130 }31313132 if ( false === $open_template ) {3133 $open_template = MLATemplate_support::mla_fetch_custom_template( $arguments[‘mla_markup’], 'term-list’, 'markup’, ‘open’ );3134 }3135 }31363137 if ( empty( $open_template ) ) {3138 $open_template = '’;3139 }31403141 if ( $term->parent ) {3142 $item_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'term-list’, 'markup’, ‘child-item’ );3143 } else {3144 $item_template = false;3145 }31463147 if ( false === $item_template ) {3148 $item_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'term-list’, 'markup’, ‘item’ );3149 }31503151 if ( empty( $item_template ) ) {3152 $item_template = '’;3153 }31543155 if ( $term->parent ) {3156 $close_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'term-list’, 'markup’, ‘child-close’ );3157 } else {3158 $close_template = false;3159 }31603161 if ( false === $close_template ) {3162 $close_template = MLATemplate_support::mla_fetch_custom_template( $markup_values[‘mla_markup’], 'term-list’, 'markup’, ‘close’ );3163 }31643165 if ( empty( $close_template ) ) {3166 $close_template = '’;3167 }31683169 if ( $is_list || ( ( 0 == $current_level ) && $is_dropdown ) || $is_checklist ) {3170 // Look for gallery-level markup substitution parameters3171 $new_text = $open_template . $close_template;3172 $markup_values = MLAData::mla_expand_field_level_parameters( $new_text, $attr, $markup_values );31733174 $markup_values = apply_filters( 'mla_term_list_open_values’, $markup_values );3175 $open_template = apply_filters( 'mla_term_list_open_template’, $open_template );3176 if ( empty( $open_template ) ) {3177 $gallery_open = '’;3178 } else {3179 $gallery_open = MLAData::mla_parse_template( $open_template, $markup_values );3180 }31813182 $list .= apply_filters( 'mla_term_list_open_parse’, $gallery_open, $open_template, $markup_values );3183 }3184 } // $is_list || $is_dropdown || $is_checklist31853186 // Find delimiter for currentlink, currentlink_url3187 if ( strpos( $markup_values[‘page_url’], ‘?’ ) ) {3188 $current_item_delimiter = '&’;3189 } else {3190 $current_item_delimiter = '?’;3191 }31923193 $has_active = false;3194 foreach ( $terms as $key => $term ) {3195 $item_values = $markup_values;3196 $is_active = false;31973198 // fill in item-specific elements3199 $item_values[‘key’] = $key;3200 $item_values[‘term_id’] = $term->term_id;3201 $item_values[‘name’] = wptexturize( $term->name );3202 $item_values[‘slug’] = $term->slug;3203 $item_values[‘term_group’] = $term->term_group;3204 $item_values[‘term_taxonomy_id’] = $term->term_taxonomy_id;3205 $item_values[‘taxonomy’] = $term->taxonomy;3206 $item_values[‘description’] = wptexturize( $term->description );3207 $item_values[‘parent’] = $term->parent;3208 $item_values[‘count’] = isset ( $term->count ) ? (integer) $term->count : 0; 3209 $item_values[‘term_count’] = isset ( $term->term_count ) ? (integer) $term->term_count : 0; 3210 $item_values[‘link_url’] = $term->link;3211 $item_values[‘currentlink_url’] = sprintf( '%1$s%2$scurrent_item=%3$d’, $item_values[‘page_url’], $current_item_delimiter, $item_values[‘term_id’] );3212 $item_values[‘editlink_url’] = $term->edit_link;3213 $item_values[‘termlink_url’] = $term->term_link;3214 $item_values[‘children’] = '’;3215 $item_values[‘termtag_attributes’] = '’;3216 $item_values[‘termtag_class’] = $term->parent ? ‘term-list-term children’ : 'term-list-term’;3217 $item_values[‘termtag_id’] = sprintf( '%1$s-%2$d’, $item_values[‘taxonomy’], $item_values[‘term_id’] );3218 // Added in the code below:3219 $item_values[‘caption’] = '’;3220 $item_values[‘link_attributes’] = '’;3221 $item_values[‘active_item_class’] = '’;3222 $item_values[‘current_item_class’] = '’;3223 $item_values[‘rollover_text’] = '’;3224 $item_values[‘link_style’] = '’;3225 $item_values[‘link_text’] = '’;3226 $item_values[‘currentlink’] = '’;3227 $item_values[‘editlink’] = '’;3228 $item_values[‘termlink’] = '’;3229 $item_values[‘thelink’] = '’;32303231 if ( ! empty( $arguments[ $mla_item_parameter ] ) ) {3232 foreach ( $arguments[ $mla_item_parameter ] as $current_item ) {3233 // Check for multi-taxonomy taxonomy.term compound values3234 $value = explode( '.’, $current_item );3235 if ( 2 === count( $value ) ) {3236 if ( $value[0] !== $term->taxonomy ) {3237 continue;3238 }32393240 $current_item = $value[1];3241 }32423243 // Must work for special values, e.g., any.terms.assigned or -23244 if ( $current_is_slug || !is_numeric( $current_item ) ) {3245 if ( sanitize_title_for_query( $term->slug ) === sanitize_title_for_query( $current_item ) ) {3246 $is_active = true;3247 $item_values[‘current_item_class’] = $arguments[‘current_item_class’];3248 break;3249 }3250 } else {3251 if ( (integer) $term->term_id === (integer) $current_item ) {3252 $is_active = true;3253 $item_values[‘current_item_class’] = $arguments[‘current_item_class’];3254 break;3255 }3256 }3257 }3258 }32593260 // Add item_specific field-level substitution parameters3261 $new_text = isset( $item_template ) ? $item_template : '’;3262 foreach( self::$term_list_item_specific_arguments as $index => $value ) {3263 $new_text .= str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $arguments[ $index ] ) );3264 }32653266 $item_values = MLAData::mla_expand_field_level_parameters( $new_text, $attr, $item_values );32673268 if ( $item_values[‘captiontag’] ) {3269 $item_values[‘caption’] = wptexturize( $term->description );3270 if ( ! empty( $arguments[‘mla_caption’] ) ) {3271 $item_values[‘caption’] = wptexturize( self::_process_shortcode_parameter( $arguments[‘mla_caption’], $item_values ) );3272 }3273 } else {3274 $item_values[‘caption’] = '’;3275 }32763277 // Apply the Display Content parameters.3278 if ( ! empty( $arguments[‘mla_target’] ) ) {3279 $link_attributes = ‘target="’ . $arguments[‘mla_target’] . '” ';3280 } else {3281 $link_attributes = '’;3282 }32833284 if ( ! empty( $arguments[‘mla_link_attributes’] ) ) {3285 $link_attributes .= self::_process_shortcode_parameter( $arguments[‘mla_link_attributes’], $item_values ) . ' ';3286 }32873288 if ( ! empty( $arguments[‘mla_link_class’] ) ) {3289 $link_attributes .= ‘class="’ . self::_process_shortcode_parameter( $arguments[‘mla_link_class’], $item_values ) . '" ';3290 }32913292 $item_values[‘link_attributes’] = $link_attributes;32933294 // Ignore option- all,any_terms,no_terms3295 if ( -1 !== $item_values[‘count’] ) {3296 $item_values[‘rollover_text’] = sprintf( _n( $item_values[‘single_text’], $item_values[‘multiple_text’], $item_values[‘count’], ‘media-library-assistant’ ), number_format_i18n( $item_values[‘count’] ) );32973298 }32993300 if ( ! empty( $arguments[‘mla_rollover_text’] ) ) {3301 $item_values[‘rollover_text’] = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_rollover_text’], $item_values ) );3302 }33033304 if ( ! empty( $arguments[‘mla_link_href’] ) ) {3305 $link_href = self::_process_shortcode_parameter( $arguments[‘mla_link_href’], $item_values );3306 $item_values[‘link_url’] = $link_href;3307 } else {3308 $link_href = '’;3309 }33103311 if ( ! empty( $arguments[‘mla_link_text’] ) ) {3312 $item_values[‘link_text’] = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_link_text’], $item_values ) );3313 } else {3314 $item_values[‘link_text’] = $item_values[‘name’];3315 }33163317 if ( ! empty( $arguments[‘show_count’] ) && ( ‘true’ == strtolower( $arguments[‘show_count’] ) ) ) {3318 // Ignore option- all,any_terms,no_terms3319 if ( -1 !== $item_values[‘count’] ) {3320 $item_values[‘link_text’] .= ' (' . $item_values[‘count’] . ')';3321 }3322 }33233324 if ( empty( $arguments[‘mla_item_value’] ) ) {3325 $item_values[‘thevalue’] = $item_values[‘term_id’];3326 } else {3327 $item_values[‘thevalue’] = self::_process_shortcode_parameter( $arguments[‘mla_item_value’], $item_values );3328 }33293330 // Currentlink, editlink, termlink and thelink TODO - link style3331 $item_values[‘currentlink’] = sprintf( '<a %1$shref="%2$s%3$s%4$s=%5$s" title="%6$s" style="%7$s">%8$s</a>’, $link_attributes, $item_values[‘page_url’], $current_item_delimiter, $mla_item_parameter, $item_values[‘thevalue’], $item_values[‘rollover_text’], '’, $item_values[‘link_text’] );3332 $item_values[‘editlink’] = sprintf( '<a %1$shref="%2$s" title="%3$s" style="%4$s">%5$s</a>’, $link_attributes, $item_values[‘editlink_url’], $item_values[‘rollover_text’], '’, $item_values[‘link_text’] );3333 $item_values[‘termlink’] = sprintf( '<a %1$shref="%2$s" title="%3$s" style="%4$s">%5$s</a>’, $link_attributes, $item_values[‘termlink_url’], $item_values[‘rollover_text’], '’, $item_values[‘link_text’] );33343335 if ( ! empty( $link_href ) ) {3336 $item_values[‘thelink’] = sprintf( '<a %1$shref="%2$s" title="%3$s" style="%4$s">%5$s</a>’, $link_attributes, $link_href, $item_values[‘rollover_text’], '’, $item_values[‘link_text’] );3337 } elseif ( ‘current’ == $arguments[‘link’] ) {3338 $item_values[‘link_url’] = $item_values[‘currentlink_url’];3339 $item_values[‘thelink’] = $item_values[‘currentlink’];3340 } elseif ( ‘edit’ == $arguments[‘link’] ) {3341 $item_values[‘thelink’] = $item_values[‘editlink’];3342 } elseif ( ‘view’ == $arguments[‘link’] ) {3343 $item_values[‘thelink’] = $item_values[‘termlink’];3344 } elseif ( ‘span’ == $arguments[‘link’] ) {3345 $item_values[‘thelink’] = sprintf( '<span %1$sstyle="%2$s">%3$s</span>’, $link_attributes, '’, $item_values[‘link_text’] );3346 } else {3347 $item_values[‘thelink’] = $item_values[‘link_text’];3348 }33493350 if ( $is_dropdown || $is_checklist ) {3351 // Indent the dropdown list3352 if ( $is_dropdown && $current_level && $is_hierarchical ) {3353 $pad = str_repeat(' ', $current_level * 3);3354 } else {3355 $pad = '’;3356 }33573358 if ( empty( $arguments[‘mla_option_text’] ) ) {3359 $item_values[‘thelabel’] = $pad . $item_values[‘link_text’];3360 } else {3361 $item_values[‘thelabel’] = $pad . self::_process_shortcode_parameter( $arguments[‘mla_option_text’], $item_values );3362 }33633364 if ( empty( $arguments[‘mla_option_value’] ) ) {3365 $item_values[‘thevalue’] = $item_values[‘term_id’];33663367 // Combined hierarchical multi-taxonomy controls generate compound taxonomy.term values 3368 if ( ( $is_dropdown || $is_checklist ) && 1 < count( $arguments[‘taxonomy’] ) ) {3369 if ( !( $is_hierarchical && !$combine_hierarchical ) ) {3370 $item_values[‘thevalue’] = $item_values[‘taxonomy’] . ‘.’ . $item_values[‘term_id’];3371 }3372 }3373 } else {3374 $item_values[‘thevalue’] = self::_process_shortcode_parameter( $arguments[‘mla_option_value’], $item_values );3375 }33763377 $item_values[‘popular’] = '’; // TODO Calculate 'term-list-popular’33783379 if ( $item_values[‘current_item_class’] == $arguments[‘current_item_class’] ) {3380 if ( $is_dropdown ) {3381 $item_values[‘selected’] = 'selected=selected’;3382 } else {3383 $item_values[‘selected’] = 'checked=checked’;3384 }3385 } else {3386 $item_values[‘selected’] = '’;3387 }3388 }33893390 $child_links = array();3391 $child_active = false;3392 if ( $is_hierarchical && ! empty( $term->children ) ) {3393 $child_active = self::_compose_term_list( $item_values[‘children’], $child_links, $term->children, $markup_values, $arguments, $attr );3394 $markup_values[‘current_level’] = $current_level; // Changed in _compose_term_list3395 }33963397 if ( $is_active || $child_active ) {3398 $has_active = true;3399 $item_values[‘active_item_class’] = $arguments[‘active_item_class’];3400 }34013402 if ( $is_list || $is_dropdown || $is_checklist ) {3403 // item markup3404 $item_values = apply_filters( 'mla_term_list_item_values’, $item_values );3405 $item_template = apply_filters( 'mla_term_list_item_template’, $item_template );3406 $parse_value = MLAData::mla_parse_template( $item_template, $item_values );3407 $list .= apply_filters( 'mla_term_list_item_parse’, $parse_value, $item_template, $item_values );3408 } else {3409 $item_values = apply_filters( 'mla_term_list_item_values’, $item_values );3410 $links[] = apply_filters( 'mla_term_list_item_parse’, $item_values[‘thelink’], NULL, $item_values );34113412 if ( $is_hierarchical && ! empty( $child_links ) ) {3413 $links = array_merge( $links, $child_links );3414 }3415 } 3416 } // foreach tag34173418 // If the current item isn’t in the term list, remove it to prevent “stale” [mla_gallery] content3419 if ( ( 0 == $current_level ) && ( false === $has_active ) ) {3420 $mla_control_name = $markup_values[‘thename’];34213422 // Does not handle default 'tax_input[[+taxonomy+]][]' values3423 if ( false === strpos( $mla_control_name, '[]' ) ) {3424 unset( $_REQUEST[ $mla_item_parameter ] );3425 unset( $_REQUEST[ $mla_control_name ] );3426 }3427 }34283429 if ( $is_list || $is_dropdown || $is_checklist ) {3430 if ( $is_list || ( ( 0 == $current_level ) && $is_dropdown ) || $is_checklist ) {3431 $markup_values = apply_filters( 'mla_term_list_close_values’, $markup_values );3432 $close_template = apply_filters( 'mla_term_list_close_template’, $close_template );3433 $parse_value = MLAData::mla_parse_template( $close_template, $markup_values );3434 $list .= apply_filters( 'mla_term_list_close_parse’, $parse_value, $close_template, $markup_values );3435 }3436 } else {3437 switch ( $markup_values[‘mla_output’] ) {3438 case ‘array’ :3439 $list =& $links;3440 break;3441 case ‘flat’ :3442 default :3443 $list .= join( $markup_values[‘separator’], $links );3444 break;3445 } // switch format3446 }34473448 return $has_active;3449 }34503451 /**3452 * These are the default parameters for term list display3453 *3454 * @since 2.303455 *3456 * @var array3457 */3458 private static $term_list_item_specific_arguments = array(3459 ‘mla_link_attributes’ => '’,3460 ‘mla_link_class’ => '’,3461 ‘mla_link_href’ => '’,3462 ‘mla_link_text’ => '’,3463 ‘mla_rollover_text’ => '’,3464 ‘mla_caption’ => '’,3465 ‘mla_item_value’ => '’,34663467 ‘mla_control_name’ => '’,3468 ‘mla_option_text’ => '’,3469 ‘mla_option_value’ => '’,3470 );34713472 /**3473 * The MLA Term List support function.3474 *3475 * This is an alternative to the WordPress wp_list_categories, wp_dropdown_categories3476 * and wp_terms_checklist functions, with additional options to customize the hyperlink3477 * behind each term.3478 *3479 * @since 2.253480 *3481 * @param array $attr Attributes of the shortcode.3482 *3483 * @return void|string|string[] Void if ‘echo’ attribute is true, or on failure. Otherwise, term list markup as a string or an array of links, depending on ‘mla_output’ attribute.3484 */3485 public static function mla_term_list( $attr ) {3486 global $post;34873488 // Some do_shortcode callers may not have a specific post in mind3489 if ( ! is_object( $post ) ) {3490 $post = self::_get_default_post();3491 }34923493 // $instance supports multiple lists in one page/post 3494 static $instance = 0;3495 $instance++;34963497 // Some values are already known, and can be used in data selection parameters3498 $upload_dir = wp_upload_dir();3499 $page_values = array(3500 ‘instance’ => $instance,3501 ‘selector’ => “mla_term_list-{$instance}",3502 ‘site_url’ => site_url(),3503 ‘base_url’ => $upload_dir[‘baseurl’],3504 ‘base_dir’ => $upload_dir[‘basedir’],3505 ‘id’ => $post->ID,3506 ‘page_ID’ => $post->ID,3507 ‘page_author’ => $post->post_author,3508 ‘page_date’ => $post->post_date,3509 ‘page_content’ => $post->post_content,3510 ‘page_title’ => $post->post_title,3511 ‘page_excerpt’ => $post->post_excerpt,3512 ‘page_status’ => $post->post_status,3513 ‘page_name’ => $post->post_name,3514 ‘page_modified’ => $post->post_modified,3515 ‘page_guid’ => $post->guid,3516 ‘page_type’ => $post->post_type,3517 ‘page_url’ => get_page_link(),3518 );35193520 $defaults = array_merge(3521 self::$mla_get_terms_parameters,3522 array(3523 ‘echo’ => false,3524 ‘mla_debug’ => false,3525 ‘mla_output’ => 'ulist’,3526 ‘hierarchical’ => 'true’,35273528 ‘separator’ => “\n",3529 ‘single_text’ => '%s item’,3530 ‘multiple_text’ => '%s items’,3531 ‘link’ => 'current’,3532 ‘current_item’ => '’,3533 ‘active_item_class’ => 'mla_active_item’,3534 ‘current_item_class’ => 'mla_current_item’,3535 ‘mla_item_parameter’ => 'current_item’,3536 ‘show_count’ => false,35373538 ‘mla_style’ => NULL,3539 ‘mla_markup’ => NULL,3540 ‘itemtag’ => 'ul’,3541 ‘termtag’ => 'li’,3542 ‘captiontag’ => '’,3543 ‘mla_multi_select’ => '’,35443545 ‘mla_nolink_text’ => '’,3546 ‘mla_target’ => '’,3547 ‘hide_if_empty’ => false,35483549 ‘option_all_text’ => '’,3550 ‘option_all_value’ => NULL,3551 ‘option_no_terms_text’ => '’,3552 ‘option_no_terms_value’ => NULL,3553 ‘option_any_terms_text’ => '’,3554 ‘option_any_terms_value’ => NULL,35553556 ‘option_none_text’ => '’,3557 ‘option_none_value’ => NULL,35583559 ‘depth’ => 0,3560 ‘child_of’ => 0,3561 ‘include_tree’ => NULL,3562 ‘exclude_tree’ => NULL,3563 ),3564 self::$term_list_item_specific_arguments3565 );35663567 // Filter the attributes before $mla_item_parameter and “request:” prefix processing.3568 $attr = apply_filters( 'mla_term_list_raw_attributes’, $attr );35693570 /*3571 * The current_item parameter can be changed to support3572 * multiple lists per page.3573 */3574 if ( ! isset( $attr[‘mla_item_parameter’] ) ) {3575 $attr[‘mla_item_parameter’] = $defaults[‘mla_item_parameter’];3576 }35773578 // The mla_item_parameter can contain page_level parameters like {+page_ID+}3579 $attr_value = str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $attr[‘mla_item_parameter’] ) );3580 $mla_item_parameter = MLAData::mla_parse_template( $attr_value, $page_values );3581 3582 /*3583 * Special handling of mla_item_parameter to make multiple lists per page easier.3584 * Look for this parameter in $_REQUEST if it’s not present in the shortcode itself.3585 */3586 if ( ! isset( $attr[ $mla_item_parameter ] ) ) {3587 if ( isset( $_REQUEST[ $mla_item_parameter ] ) ) {3588 $attr[ $mla_item_parameter ] = sanitize_text_field( wp_unslash( $_REQUEST[ $mla_item_parameter ] ) );3589 }3590 }3591 3592 // Determine markup template to get default arguments3593 $arguments = shortcode_atts( $defaults, $attr );35943595 /*3596 * $mla_item_parameter, if non-default, doesn’t make it through the shortcode_atts3597 * filter, so we handle it separately3598 */3599 if ( ! isset( $arguments[ $mla_item_parameter ] ) ) {3600 if ( isset( $attr[ $mla_item_parameter ] ) ) {3601 $arguments[ $mla_item_parameter ] = $attr[ $mla_item_parameter ];3602 } else {3603 $arguments[ $mla_item_parameter ] = $defaults[‘current_item’];3604 }3605 }36063607 if ( $arguments[‘mla_markup’] ) {3608 $template = $arguments[‘mla_markup’];3609 if ( ! MLATemplate_Support::mla_fetch_custom_template( $template, 'term-list’, 'markup’, '[exists]' ) ) {3610 $template = NULL;3611 }3612 } else {3613 $template = NULL;3614 }36153616 if ( empty( $template ) ) {3617 $output_parameters = array_map( 'strtolower’, array_map( 'trim’, explode( ',’, $arguments[‘mla_output’] ) ) );36183619 if ( !in_array( $output_parameters[0], array( 'flat’, 'list’, 'ulist’, 'olist’, 'dlist’, 'dropdown’, 'checklist’, ‘array’ ) ) ) {3620 $output_parameters[0] = 'ulist’;3621 }36223623 if ( in_array( $output_parameters[0], array( 'list’, 'ulist’, 'olist’, ‘dlist’ ) ) ) {3624 if ( ( ‘dlist’ == $output_parameters[0] ) || (‘list’ == $output_parameters[0] && ‘dd’ == $arguments[‘captiontag’] ) ) {3625 $template = 'term-list-dl’;3626 } else {3627 $template = 'term-list-ul’;3628 }3629 } elseif ( ‘dropdown’ == $output_parameters[0] ) {3630 $template = 'term-list-dropdown’;3631 } elseif ( ‘checklist’ == $output_parameters[0] ) {3632 $template = 'term-list-checklist’;3633 }3634 }36353636 // Apply default arguments set in the markup template3637 $arguments = MLATemplate_Support::mla_fetch_custom_template( $template, 'term-list’, 'markup’, ‘arguments’ );3638 if ( ! empty( $arguments ) ) {3639 $attr = wp_parse_args( $attr, self::mla_validate_attributes( array(), $arguments ) );3640 }36413642 // Adjust data selection arguments; remove pagination-specific arguments3643 unset( $attr[‘limit’] );3644 unset( $attr[‘offset’] );36453646 /*3647 * Look for page-level, ‘request:’ and ‘query:’ substitution parameters,3648 * which can be added to any input parameter3649 */3650 foreach ( $attr as $attr_key => $attr_value ) {3651 /*3652 * item-specific Display Content parameters must be evaluated3653 * later, when all of the information is available.3654 */3655 if ( array_key_exists( $attr_key, self::$term_list_item_specific_arguments ) ) {3656 continue;3657 }36583659 $attr_value = str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $attr_value ) );3660 $replacement_values = MLAData::mla_expand_field_level_parameters( $attr_value, $attr, $page_values );3661 $attr[ $attr_key ] = MLAData::mla_parse_template( $attr_value, $replacement_values );3662 }36633664 $attr = apply_filters( 'mla_term_list_attributes’, $attr );3665 $arguments = shortcode_atts( $defaults, $attr );36663667 /*3668 * $mla_item_parameter, if non-default, doesn’t make it through the shortcode_atts3669 * filter, so we handle it separately3670 */3671 if ( ! isset( $arguments[ $mla_item_parameter ] ) ) {3672 if ( isset( $attr[ $mla_item_parameter ] ) ) {3673 $arguments[ $mla_item_parameter ] = $attr[ $mla_item_parameter ];3674 } else {3675 $arguments[ $mla_item_parameter ] = $defaults[‘current_item’];36763677 }3678 }36793680 // Clean up the current_item(s) to separate term_id from slug3681 if ( ! empty( $arguments[ $mla_item_parameter ] ) ) {3682 if ( is_string( $arguments[ $mla_item_parameter ] ) ) {3683 $arguments[ $mla_item_parameter ] = explode( ',’, $arguments[ $mla_item_parameter ] );3684 }3685 foreach( $arguments[ $mla_item_parameter ] as $index => $value ) {3686 if ( ctype_digit( $value ) ) {3687 $arguments[ $mla_item_parameter ][ $index ] = absint( $value );3688 }3689 }3690 }36913692 $arguments = apply_filters( 'mla_term_list_arguments’, $arguments );36933694 // Clean up hierarchical parameter to simplify later processing3695 $arguments[‘hierarchical’] = strtolower( trim( $arguments[‘hierarchical’] ) ) ;3696 if ( !in_array( $arguments[‘hierarchical’], array( 'true’, ‘combine’ ) ) ) {3697 $arguments[‘hierarchical’] = ‘false’;3698 }36993700 self::$mla_debug = ( ! empty( $arguments[‘mla_debug’] ) ) ? trim( strtolower( $arguments[‘mla_debug’] ) ) : false;3701 if ( self::$mla_debug ) {3702 if ( ‘true’ == self::$mla_debug ) {3703 MLACore::mla_debug_mode( ‘buffer’ );3704 } elseif ( ‘log’ == self::$mla_debug ) {3705 MLACore::mla_debug_mode( ‘log’ );3706 } else {3707 self::$mla_debug = false;3708 }3709 }37103711 if ( self::$mla_debug ) {3712 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug REQUEST’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $_REQUEST, true ) );3713 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug attributes’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $attr, true ) );3714 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug arguments’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $arguments, true ) );3715 }37163717 // Determine templates and output type3718 if ( $arguments[‘mla_style’] && ( ‘none’ !== $arguments[‘mla_style’] ) ) {3719 if ( !MLATemplate_Support::mla_fetch_custom_template( $arguments[‘mla_style’], 'term-list’, ‘style’, '[exists]' ) ) {3720 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_term_list mla_style</strong> "’ . $arguments[‘mla_style’] . '” ' . __( 'not found’, ‘media-library-assistant’ ), MLACore::MLA_DEBUG_CATEGORY_ANY );3721 $arguments[‘mla_style’] = NULL;3722 }3723 }37243725 if ( $arguments[‘mla_markup’] ) {3726 if ( !MLATemplate_Support::mla_fetch_custom_template( $arguments[‘mla_markup’], 'term-list’, ‘markup’, '[exists]' ) ) {3727 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_term_list mla_markup</strong> "’ . $arguments[‘mla_markup’] . '” ' . __( 'not found’, ‘media-library-assistant’ ), MLACore::MLA_DEBUG_CATEGORY_ANY );3728 $arguments[‘mla_markup’] = NULL;3729 }3730 }37313732 $output_parameters = array_map( 'strtolower’, array_map( 'trim’, explode( ',’, $arguments[‘mla_output’] ) ) );37333734 if ( !in_array( $output_parameters[0], array( 'flat’, 'list’, 'ulist’, 'olist’, 'dlist’, 'dropdown’, 'checklist’, ‘array’ ) ) ) {3735 $output_parameters[0] = 'ulist’;3736 }37373738 $default_style = 'term-list’;3739 $default_markup = 'term-list-ul’;37403741 if ( $is_list = in_array( $output_parameters[0], array( 'list’, 'ulist’, 'olist’, ‘dlist’ ) ) ) {37423743 if ( ‘list’ == $output_parameters[0] && ‘dd’ == $arguments[‘captiontag’] ) {3744 $default_markup = 'term-list-dl’;3745 $arguments[‘itemtag’] = 'dl’;3746 $arguments[‘termtag’] = 'dt’;3747 } else {3748 $default_markup = 'term-list-ul’;3749 $arguments[‘termtag’] = 'li’;3750 $arguments[‘captiontag’] = '’;37513752 switch ( $output_parameters[0] ) {3753 case 'ulist’:3754 $arguments[‘itemtag’] = 'ul’;3755 break;3756 case 'olist’:3757 $arguments[‘itemtag’] = 'ol’;3758 break;3759 case 'dlist’:3760 $default_markup = 'term-list-dl’;3761 $arguments[‘itemtag’] = 'dl’;3762 $arguments[‘termtag’] = 'dt’;3763 $arguments[‘captiontag’] = 'dd’;3764 break;3765 default:3766 $arguments[‘itemtag’] = 'ul’;3767 }3768 }3769 }37703771 if ( $is_dropdown = ‘dropdown’ == $output_parameters[0] ) {3772 $default_markup = 'term-list-dropdown’;3773 $arguments[‘itemtag’] = empty( $attr[‘itemtag’] ) ? ‘select’ : $attr[‘itemtag’];3774 $arguments[‘termtag’] = 'option’;3775 }37763777 if ( $is_checklist = ‘checklist’ == $output_parameters[0] ) {3778 $default_markup = 'term-list-checklist’;3779 $arguments[‘termtag’] = 'li’;3780 }37813782 $arguments[‘default_mla_style’] = $default_style;3783 if ( NULL == $arguments[‘mla_style’] ) {3784 $arguments[‘mla_style’] = $default_style;3785 }37863787 $arguments[‘default_mla_markup’] = $default_markup;3788 if ( NULL == $arguments[‘mla_markup’] ) {3789 $arguments[‘mla_markup’] = $default_markup;3790 }37913792 $mla_multi_select = ! empty( $arguments[‘mla_multi_select’] ) && ( ‘true’ == strtolower( $arguments[‘mla_multi_select’] ) );37933794 $is_hierarchical = !( ‘false’ === $arguments[‘hierarchical’] );3795 $combine_hierarchical = ‘combine’ === $arguments[‘hierarchical’];37963797 // Convert lists to arrays3798 if ( is_string( $arguments[‘taxonomy’] ) ) {3799 $arguments[‘taxonomy’] = explode( ',’, $arguments[‘taxonomy’] );3800 }38013802 if ( is_string( $arguments[‘post_type’] ) ) {3803 $arguments[‘post_type’] = explode( ',’, $arguments[‘post_type’] );3804 }38053806 if ( is_string( $arguments[‘post_status’] ) ) {3807 $arguments[‘post_status’] = explode( ',’, $arguments[‘post_status’] );3808 }38093810 // Hierarchical exclude is done in _get_term_tree to exclude children3811 if ( $is_hierarchical && isset( $arguments[‘exclude’] ) ) {3812 $exclude_later = $arguments[‘exclude’];3813 unset( $arguments[‘exclude’] );3814 } else {3815 $exclude_later = NULL;3816 }38173818 $tags = self::mla_get_terms( $arguments );3819 if ( ! empty( $exclude_later ) ) {3820 $arguments[‘exclude’] = $exclude_later;3821 }38223823 // Invalid taxonomy names return WP_Error3824 if ( is_wp_error( $tags ) ) {3825 $list = ‘<strong>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . $tags->get_error_message() . '</strong>, ' . $tags->get_error_data( $tags->get_error_code() );38263827 if ( ‘array’ == $arguments[‘mla_output’] ) {3828 return array( $list );3829 }38303831 if ( empty($arguments[‘echo’]) ) {3832 return $list;3833 }38343835 echo $list; // phpcs:ignore3836 return;3837 }38383839 // Fill in the item_specific link properties, calculate list parameters3840 if ( isset( $tags[‘found_rows’] ) ) {3841 $found_rows = $tags[‘found_rows’];3842 unset( $tags[‘found_rows’] );3843 } else {3844 $found_rows = count( $tags );3845 }38463847 $show_empty = false;3848 if ( 0 == $found_rows ) {3849 if ( !empty( $arguments[‘mla_control_name’] ) ) {3850 // Remove the current item from the parameters to prevent “stale” [mla_gallery] content3851 $mla_control_name = self::_process_shortcode_parameter( $arguments[‘mla_control_name’], $page_values );3852 3853 // Does not handle default ‘tax_input[[+taxonomy+]][]' values3854 unset( $_REQUEST[ $mla_item_parameter ] );3855 unset( $_REQUEST[ $mla_control_name ] );3856 }3857 3858 if ( self::$mla_debug ) {3859 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug empty list’, ‘media-library-assistant’ ) . '</strong>, query = ' . var_export( $arguments, true ) );3860 $list = MLACore::mla_debug_flush();38613862 if ( ‘<p></p>’ == $list ) {3863 $list = '’;3864 }3865 } else {3866 $list = '’;3867 }38683869 if ( ‘array’ == $arguments[‘mla_output’] ) {3870 $list .= $arguments[‘mla_nolink_text’];38713872 if ( empty( $list ) ) {3873 return array();3874 } else {3875 return array( $list );3876 }3877 }38783879 $show_empty = empty( $arguments[‘hide_if_empty’] ) || ( ‘true’ !== strtolower( $arguments[‘hide_if_empty’] ) );3880 if ( ( $is_checklist || $is_dropdown ) && $show_empty ) {3881 if ( empty( $arguments[‘option_none_text’] ) ) {3882 $arguments[‘option_none_text’] = __( 'no-terms’, ‘media-library-assistant’ );3883 }38843885 if ( ! empty( $arguments[‘option_none_value’] ) ) {3886 $option_none_value = self::_process_shortcode_parameter( $arguments[‘option_none_value’], $page_values );3887 if ( is_numeric( $option_none_value ) ) {3888 $option_none_id = (int) $option_none_value;3889 $option_none_slug = sanitize_title( $arguments[‘option_none_text’] );3890 } else {3891 $option_none_id = -1;3892 $option_none_slug = sanitize_title( $option_none_value );3893 }3894 } else {3895 $option_none_id = -1;3896 $option_none_slug = sanitize_title( $arguments[‘option_none_text’] );3897 }38983899 $tags[0] = ( object ) array(3900 ‘term_id’ => $option_none_id,3901 ‘name’ => $arguments[‘option_none_text’],3902 ‘slug’ => $option_none_slug,3903 ‘term_group’ => '0’,3904 ‘term_taxonomy_id’ => $option_none_id,3905 ‘taxonomy’ => reset( $arguments[‘taxonomy’] ),3906 ‘description’ => '’,3907 ‘parent’ => '0’,3908 ‘count’ => 0,3909 ‘level’ => 0,3910 ‘edit_link’ => '’,3911 ‘term_link’ => '’,3912 ‘link’ => '’,3913 );39143915 $is_hierarchical = false;3916 $found_rows = 1;3917 } else {3918 $list .= $arguments[‘mla_nolink_text’];39193920 if ( empty($arguments[‘echo’]) ) {3921 return $list;3922 }39233924 echo $list; // phpcs:ignore3925 return;3926 }3927 }39283929 if ( self::$mla_debug ) {3930 $list = MLACore::mla_debug_flush();3931 } else {3932 $list = '’;3933 }39343935 if ( !$show_empty ) {3936 $add_all_option = ! empty( $arguments[‘option_all_text’] );3937 $add_any_terms_option = ! empty( $arguments[‘option_any_terms_text’] );3938 $add_no_terms_option = ! empty( $arguments[‘option_no_terms_text’] );3939 } else {3940 $add_all_option = false;3941 $add_any_terms_option = false;3942 $add_no_terms_option = false;3943 }39443945 if ( $add_all_option || $add_any_terms_option || $add_no_terms_option ) {3946 $terms_assigned_counts = self::mla_get_all_none_term_counts( $arguments );3947 } else {3948 $terms_assigned_counts = array( ‘ignore.terms.assigned’ => 0, ‘no.terms.assigned’ => 0, ‘any.terms.assigned’ => 0 );3949 }39503951 // Using the slug is a common practice and affects option_ all/any_terms/no_terms _value(s)3952 $option_all_id = -3;3953 $option_all_slug = 'ignore.terms.assigned’;3954 if ( $add_all_option ) {3955 if ( ! empty( $arguments[‘option_all_value’] ) ) {3956 $option_all_value = self::_process_shortcode_parameter( $arguments[‘option_all_value’], $page_values );3957 if ( is_numeric( $option_all_value ) ) {3958 $option_all_id = (integer) $option_all_value;3959 $option_all_slug = sanitize_title( $arguments[‘option_all_text’] );3960 } else {3961 $option_all_slug = sanitize_title( $option_all_value );3962 }3963 }3964 }39653966 $option_any_terms_id = -2;3967 $option_any_terms_slug = 'any.terms.assigned’;3968 if ( $add_any_terms_option ) {3969 if ( ! empty( $arguments[‘option_any_terms_value’] ) ) {3970 $option_any_terms_value = self::_process_shortcode_parameter( $arguments[‘option_any_terms_value’], $page_values );3971 if ( is_numeric( $option_any_terms_value ) ) {3972 $option_any_terms_id = (integer) $option_any_terms_value;3973 $option_any_terms_slug = sanitize_title( $arguments[‘option_any_terms_text’] );3974 } else {3975 $option_any_terms_slug = sanitize_title( $option_any_terms_value );3976 }3977 }3978 }39793980 $option_no_terms_id = -1;3981 $option_no_terms_slug = 'no.terms.assigned’;3982 if ( $add_no_terms_option ) {3983 if ( ! empty( $arguments[‘option_no_terms_value’] ) ) {3984 $option_no_terms_value = self::_process_shortcode_parameter( $arguments[‘option_no_terms_value’], $page_values );3985 if ( is_numeric( $option_no_terms_value ) ) {3986 $option_no_terms_id = (integer) $option_no_terms_value;3987 $option_no_terms_slug = sanitize_title( $arguments[‘option_no_terms_text’] );3988 } else {3989 $option_no_terms_slug = sanitize_title( $option_no_terms_value );3990 }3991 }3992 }39933994 if ( $is_hierarchical ) {3995 $tags = self::_get_term_tree( $tags, $arguments );39963997 if ( is_wp_error( $tags ) ) {3998 $list = ‘<strong>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . $tags->get_error_message() . '</strong>, ' . $tags->get_error_data( $tags->get_error_code() );39994000 if ( ‘array’ == $arguments[‘mla_output’] ) {4001 return array( $list );4002 }40034004 if ( empty($arguments[‘echo’]) ) {4005 return $list;4006 }40074008 echo $list; // phpcs:ignore4009 return;4010 }40114012 if ( isset( $tags[‘found_rows’] ) ) {4013 $found_rows = $tags[‘found_rows’];4014 unset( $tags[‘found_rows’] );4015 } else {4016 $found_rows = count( $tags );4017 }40184019 if ( ( 0 === $found_rows ) && !empty( $arguments[‘mla_control_name’] ) ) {4020 // Remove the current item from the parameters to prevent “stale” [mla_gallery] content4021 $mla_control_name = self::_process_shortcode_parameter( $arguments[‘mla_control_name’], $page_values );4022 4023 // Does not handle default 'tax_input[[+taxonomy+]][]' values4024 unset( $_REQUEST[ $mla_item_parameter ] );4025 unset( $_REQUEST[ $mla_control_name ] );4026 }4027 } else {4028 if ( !$show_empty ) {4029 foreach ( $tags as $key => $tag ) {4030 $tags[ $key ]->level = 0;4031 $link = get_edit_tag_link( $tag->term_id, $tag->taxonomy );4032 if ( ! is_wp_error( $link ) ) {4033 $tags[ $key ]->edit_link = $link;4034 $link = get_term_link( (int) $tag->term_id, $tag->taxonomy );4035 $tags[ $key ]->term_link = $link;4036 }40374038 if ( is_wp_error( $link ) ) {4039 $list = ‘<strong>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . $link->get_error_message() . '</strong>, ' . $link->get_error_data( $link->get_error_code() );40404041 if ( ‘array’ == $arguments[‘mla_output’] ) {4042 return array( $list );4043 }40444045 if ( empty($arguments[‘echo’]) ) {4046 return $list;4047 }40484049 echo $list; // phpcs:ignore4050 return;4051 }40524053 if ( ‘edit’ == $arguments[‘link’] ) {4054 $tags[ $key ]->link = $tags[ $key ]->edit_link;4055 } else {4056 $tags[ $key ]->link = $tags[ $key ]->term_link;4057 }4058 } // foreach tag4059 } // !show_empty4060 }// !is_hierarchical40614062 if ( $add_all_option ) {4063 $found_rows += 1;4064 }4065 if ( $add_any_terms_option ) {4066 $found_rows += 1;4067 }4068 if ( $add_no_terms_option ) {4069 $found_rows += 1;4070 }40714072 $style_values = array_merge( $page_values, array(4073 ‘mla_output’ => $arguments[‘mla_output’],4074 ‘mla_style’ => $arguments[‘mla_style’],4075 ‘mla_markup’ => $arguments[‘mla_markup’],4076 ‘taxonomy’ => implode( '-', $arguments[‘taxonomy’] ),4077 ‘current_item’ => $arguments[‘current_item’],4078 ‘itemtag’ => tag_escape( $arguments[‘itemtag’] ),4079 ‘termtag’ => tag_escape( $arguments[‘termtag’] ),4080 ‘captiontag’ => tag_escape( $arguments[‘captiontag’] ),4081 ‘multiple’ => $arguments[‘mla_multi_select’] ? ‘multiple’ : '’,4082 ‘itemtag_attributes’ => '’,4083 ‘itemtag_class’ => 'term-list term-list-taxonomy-' . implode( '-', $arguments[‘taxonomy’] ), 4084 ‘itemtag_id’ => $page_values[‘selector’],4085 ‘all_found_rows’ => $found_rows,4086 ‘found_rows’ => $found_rows,4087 ‘separator’ => $arguments[‘separator’],4088 ‘single_text’ => $arguments[‘single_text’],4089 ‘multiple_text’ => $arguments[‘multiple_text’],4090 ‘echo’ => $arguments[‘echo’],4091 ‘link’ => $arguments[‘link’]4092 ) );40934094 $style_template = $gallery_style = '’;4095 $use_mla_term_list_style = ‘none’ != strtolower( $style_values[‘mla_style’] );4096 if ( apply_filters( 'use_mla_term_list_style’, $use_mla_term_list_style, $style_values[‘mla_style’] ) ) {4097 $style_template = MLATemplate_support::mla_fetch_custom_template( $style_values[‘mla_style’], 'term-list’, ‘style’ );4098 if ( empty( $style_template ) ) {4099 $style_values[‘mla_style’] = $default_style;4100 $style_template = MLATemplate_support::mla_fetch_custom_template( $default_style, 'term-list’, ‘style’ );4101 }41024103 if ( ! empty ( $style_template ) ) {4104 // Look for ‘query’ and ‘request’ substitution parameters4105 $style_values = MLAData::mla_expand_field_level_parameters( $style_template, $attr, $style_values );41064107 $style_values = apply_filters( 'mla_term_list_style_values’, $style_values );4108 $style_template = apply_filters( 'mla_term_list_style_template’, $style_template );4109 $gallery_style = MLAData::mla_parse_template( $style_template, $style_values );4110 $gallery_style = apply_filters( 'mla_term_list_style_parse’, $gallery_style, $style_template, $style_values );4111 } // !empty template4112 } // use_mla_term_list_style41134114 $list .= $gallery_style;4115 $markup_values = $style_values;41164117 if ( empty( $arguments[‘mla_control_name’] ) ) {4118 $mla_control_name = 'tax_input[[+taxonomy+]][]';4119 } else {4120 $mla_control_name = $arguments[‘mla_control_name’];;4121 }41224123 // Accumulate links for flat and array output4124 $tag_links = array();41254126 if ( $is_hierarchical ) {4127 if ( $combine_hierarchical ) {4128 $combined_tags = array();4129 foreach( $tags as $taxonomy => $root_terms ) {4130 $combined_tags = array_merge( $combined_tags, $root_terms );4131 }4132 $tags = array( $markup_values[‘taxonomy’] => $combined_tags );4133 } // $combine_hierarchical41344135 foreach( $tags as $taxonomy => $root_terms ) {4136 $markup_values[‘taxonomy’] = $taxonomy;4137 $markup_values[‘thename’] = self::_process_shortcode_parameter( $mla_control_name, $markup_values );413841394140 // Add the optional 'all-terms’, ‘any-terms’ and/or ‘no-terms’ option(s), if requested4141 $add_to_found_rows = 0;4142 if ( $add_any_terms_option ) {4143 $new_term = ( object ) array(4144 ‘term_id’ => $option_any_terms_id,4145 ‘name’ => $arguments[‘option_any_terms_text’],4146 ‘slug’ => $option_any_terms_slug,4147 ‘term_group’ => '0’,4148 ‘term_taxonomy_id’ => $option_any_terms_id,4149 ‘taxonomy’ => $taxonomy,4150 ‘description’ => '’,4151 ‘parent’ => '0’,4152 ‘count’ => $terms_assigned_counts[‘any.terms.assigned’],4153 ‘level’ => 0,4154 ‘edit_link’ => '’,4155 ‘term_link’ => '’,4156 ‘link’ => '’,4157 );41584159 array_unshift( $root_terms, $new_term );4160 $add_to_found_rows += 1;4161 }41624163 if ( $add_no_terms_option ) {4164 $new_term = ( object ) array(4165 ‘term_id’ => $option_no_terms_id,4166 ‘name’ => $arguments[‘option_no_terms_text’],4167 ‘slug’ => $option_no_terms_slug,4168 ‘term_group’ => '0’,4169 ‘term_taxonomy_id’ => $option_no_terms_id,4170 ‘taxonomy’ => $taxonomy,4171 ‘description’ => '’,4172 ‘parent’ => '0’,4173 ‘count’ => $terms_assigned_counts[‘no.terms.assigned’],4174 ‘level’ => 0,4175 ‘edit_link’ => '’,4176 ‘term_link’ => '’,4177 ‘link’ => '’,4178 );41794180 array_unshift( $root_terms, $new_term );4181 $add_to_found_rows += 1;4182 }41834184 if ( $add_all_option ) {4185 $new_term = ( object ) array(4186 ‘term_id’ => $option_all_id,4187 ‘name’ => $arguments[‘option_all_text’],4188 ‘slug’ => $option_all_slug,4189 ‘term_group’ => '0’,4190 ‘term_taxonomy_id’ => $option_all_id,4191 ‘taxonomy’ => $taxonomy,4192 ‘description’ => '’,4193 ‘parent’ => '0’,4194 ‘count’ => $terms_assigned_counts[‘ignore.terms.assigned’],4195 ‘level’ => 0,4196 ‘edit_link’ => '’,4197 ‘term_link’ => '’,4198 ‘link’ => '’,4199 );42004201 array_unshift( $root_terms, $new_term );4202 $add_to_found_rows += 1;4203 }42044205 if ( isset( $root_terms[‘found_rows’] ) ) {4206 $markup_values[‘found_rows’] = $add_to_found_rows + $root_terms[‘found_rows’];4207 unset( $root_terms[‘found_rows’] );4208 } else {4209 $markup_values[‘found_rows’] = count( $root_terms );4210 }42114212 if ( count( $root_terms ) ) {4213 self::_compose_term_list( $list, $tag_links, $root_terms, $markup_values, $arguments, $attr );4214 }4215 }4216 } else {4217 $markup_values[‘thename’] = self::_process_shortcode_parameter( $mla_control_name, $markup_values );42184219 // Add the optional 'all-terms’, ‘any-terms’ and/or ‘no-terms’ option(s), if requested4220 if ( $add_any_terms_option ) {4221 $new_term = ( object ) array(4222 ‘term_id’ => $option_any_terms_id,4223 ‘name’ => $arguments[‘option_any_terms_text’],4224 ‘slug’ => $option_any_terms_slug,4225 ‘term_group’ => '0’,4226 ‘term_taxonomy_id’ => $option_any_terms_id,4227 ‘taxonomy’ => $taxonomy,4228 ‘description’ => '’,4229 ‘parent’ => '0’,4230 ‘count’ => -1,4231 ‘level’ => 0,4232 ‘edit_link’ => '’,4233 ‘term_link’ => '’,4234 ‘link’ => '’,4235 );42364237 array_unshift( $tags, $new_term );4238 }42394240 if ( $add_no_terms_option ) {4241 $new_term = ( object ) array(4242 ‘term_id’ => $option_no_terms_id,4243 ‘name’ => $arguments[‘option_no_terms_text’],4244 ‘slug’ => $option_no_terms_slug,4245 ‘term_group’ => '0’,4246 ‘term_taxonomy_id’ => $option_no_terms_id,4247 ‘taxonomy’ => $taxonomy,4248 ‘description’ => '’,4249 ‘parent’ => '0’,4250 ‘count’ => -1,4251 ‘level’ => 0,4252 ‘edit_link’ => '’,4253 ‘term_link’ => '’,4254 ‘link’ => '’,4255 );42564257 array_unshift( $tags, $new_term );4258 }42594260 if ( $add_all_option ) {4261 $new_term = ( object ) array(4262 ‘term_id’ => $option_all_id,4263 ‘name’ => $arguments[‘option_all_text’],4264 ‘slug’ => $option_all_slug,4265 ‘term_group’ => '0’,4266 ‘term_taxonomy_id’ => $option_all_id,4267 ‘taxonomy’ => $taxonomy,4268 ‘description’ => '’,4269 ‘parent’ => '0’,4270 ‘count’ => -1,4271 ‘level’ => 0,4272 ‘edit_link’ => '’,4273 ‘term_link’ => '’,4274 ‘link’ => '’,4275 );42764277 array_unshift( $tags, $new_term );4278 }42794280 if ( count( $tags ) ) {4281 self::_compose_term_list( $list, $tag_links, $tags, $markup_values, $arguments, $attr );4282 }4283 }42844285 if ( ‘array’ === $arguments[‘mla_output’] || empty($arguments[‘echo’]) ) {4286 return $list;4287 }42884289 echo $list; // phpcs:ignore4290 }42914292 /**4293 * The MLA Term List shortcode.4294 *4295 * This is an interface to the mla_term_list function.4296 *4297 * @since 2.254298 *4299 * @param array $attr Attributes of the shortcode.4300 * @param string $content Optional content for enclosing shortcodes4301 *4302 * @return string HTML content to display the term list.4303 */4304 public static function mla_term_list_shortcode( $attr, $content = NULL ) {4305//error_log( __LINE__ . " mla_term_list_shortcode() _REQUEST = " . var_export( $_REQUEST, true ), 0 );4306//error_log( __LINE__ . " mla_term_list_shortcode() attr = " . var_export( $attr, true ), 0 );4307//error_log( __LINE__ . " mla_term_list_shortcode() content = " . var_export( $content, true ), 0 );4308 /*4309 * Make sure $attr is an array, even if it’s empty,4310 * and repair damage caused by link-breaks in the source text4311 */4312 $attr = self::mla_validate_attributes( $attr, $content );43134314 // The ‘array’ format makes no sense in a shortcode4315 if ( isset( $attr[‘mla_output’] ) && ‘array’ == $attr[‘mla_output’] ) {4316 $attr[‘mla_output’] = 'flat’;4317 }4318 4319 // A shortcode must return its content to the caller, so “echo” makes no sense4320 $attr[‘echo’] = false;43214322 if ( ! empty( $attr[‘mla_output’] ) ) {4323 switch ( $attr[‘mla_output’] ) {4324 case 'wp_list_categories’:4325 return wp_list_categories( $attr );4326 case 'wp_dropdown_categories’:4327 return wp_dropdown_categories( $attr );4328 case 'wp_terms_checklist’:4329 require_once( ABSPATH . ‘wp-admin/includes/template.php’ );4330 return wp_terms_checklist( 0, $attr );4331 }4332 }43334334 return self::mla_term_list( $attr );4335 }43364337 /**4338 * Computes image dimensions for scalable graphics, e.g., SVG 4339 *4340 * @since 2.204341 *4342 * @return array 4343 */4344 private static function _registered_dimensions() {4345 global $_wp_additional_image_sizes;43464347 if ( ‘checked’ == MLACore::mla_get_option( MLACoreOptions::MLA_ENABLE_MLA_ICONS ) ) {4348 $sizes = array( ‘icon’ => array( 64, 64 ) );4349 } else {4350 $sizes = array( ‘icon’ => array( 60, 60 ) );4351 }43524353 foreach( get_intermediate_image_sizes() as $s ) {4354 $sizes[ $s ] = array( 0, 0 );43554356 if( in_array( $s, array( 'thumbnail’, 'medium’, ‘large’ ) ) ) {4357 $sizes[ $s ][0] = get_option( $s . ‘_size_w’ );4358 $sizes[ $s ][1] = get_option( $s . ‘_size_h’ );4359 } else {4360 if( isset( $_wp_additional_image_sizes ) && isset( $_wp_additional_image_sizes[ $s ] ) ) {4361 $sizes[ $s ] = array( $_wp_additional_image_sizes[ $s ][‘width’], $_wp_additional_image_sizes[ $s ][‘height’], );4362 }4363 }4364 }4365 4366 return $sizes;4367 }43684369 /**4370 * Handles brace/bracket escaping and parses template for a shortcode parameter4371 *4372 * @since 2.204373 *4374 * @param string raw shortcode parameter, e.g., “text {+field+} {brackets} \\{braces\\}"4375 * @param string template substitution values, e.g., (‘instance’ => '1’, … )4376 *4377 * @return string parameter with brackets, braces, substitution parameters and templates processed4378 */4379 private static function _process_shortcode_parameter( $text, $markup_values ) {4380 $new_text = str_replace( '{\+’, '\[\+’, str_replace( '+\}’, '+\\\\]', $text ) );4381 $new_text = str_replace( '{’, '[', str_replace( '}’, ']', $new_text ) );4382 $new_text = str_replace( '\[', '{’, str_replace( '\]', '}’, $new_text ) );4383 return MLAData::mla_parse_template( $new_text, $markup_values );4384 }43854386 /**4387 * Replaces or removes a query argument, preserving url encoding4388 *4389 * @since 2.844390 *4391 * @param string argument name4392 * @param mixed argument value (string) or false to remove argument4393 * @param string url4394 *4395 * @return string url with argument replaced4396 */4397 private static function _replace_query_parameter( $key, $value, $url ) {4398 $parts = wp_parse_url( $url );4399 if ( empty( $parts[‘path’] ) ) {4400 $parts[‘path’] = '’;4401 }44024403 // Fragments must come at the end of the URL and be preceded by a #4404 if ( !empty( $parts[‘fragment’] ) ) {4405 $parts[‘fragment’] = ‘#’ . $parts[‘fragment’];4406 } else {4407 $parts[‘fragment’] = '’;4408 }44094410 $clean_query = array();4411 if ( empty( $parts[‘query’] ) ) {4412 // No existing query arguments; create query if requested4413 if ( false !== $value ) {4414 $clean_query[ $key ] = $value;4415 }4416 } else {4417 parse_str( $parts[‘query’], $query );44184419 $add_it = true;4420 foreach ( $query as $query_key => $query_value ) {4421 // Query argument names cannot have URL special characters4422 if ( $query_key === urldecode( $query_key ) ) {4423 if ( $key === $query_key ) {4424 $add_it = false;4425 // Deleting argument?4426 if ( false === $value ) {4427 continue;4428 }44294430 $query_value = $value;4431 }44324433 $clean_query[ $query_key ] = $query_value;4434 }4435 }44364437 if ( $add_it && ( false !== $value ) ) {4438 $clean_query[ $key ] = $value;4439 }4440 }44414442 $clean_query = urlencode_deep( $clean_query );4443 $clean_query = build_query( $clean_query );44444445 // Query arguments must come before the fragment, if any4446 if ( !empty( $clean_query ) ) {4447 return $parts[‘scheme’] . ‘://’ . $parts[‘host’] . $parts[‘path’] . ‘?’ . $clean_query . $parts[‘fragment’];4448 } else {4449 return $parts[‘scheme’] . ‘://’ . $parts[‘host’] . $parts[‘path’] . $parts[‘fragment’];4450 }4451 }44524453 /**4454 * Handles pagnation output types 'previous_page’, 'next_page’, and 'paginate_links’4455 *4456 * @since 2.204457 *4458 * @param array value(s) for mla_output_type parameter4459 * @param array template substitution values, e.g., (‘instance’ => '1’, … )4460 * @param array merged default and passed shortcode parameter values4461 * @param integer number of attachments in the gallery, without pagination4462 * @param string output text so far, may include debug values4463 *4464 * @return string empty string, mla_nolink_text or string with HTML for pagination output types4465 */4466 private static function _paginate_links( $output_parameters, $markup_values, $arguments, $found_rows, $output = ‘’ ) {4467 if ( 2 > $markup_values[‘last_page’] ) {4468 if ( ! empty( $arguments[‘mla_nolink_text’] ) ) {4469 return self::_process_shortcode_parameter( $arguments[‘mla_nolink_text’], $markup_values );4470 } else {4471 return '’;4472 }4473 }44744475 $show_all = $prev_next = false;44764477 if ( isset ( $output_parameters[1] ) ) {4478 switch ( $output_parameters[1] ) {4479 case 'show_all’:4480 $show_all = true;4481 break;4482 case 'prev_next’:4483 $prev_next = true;4484 }4485 }44864487 $mla_page_parameter = $arguments[‘mla_page_parameter’];4488 $current_page = $markup_values[‘current_page’];4489 $last_page = $markup_values[‘last_page’];4490 $end_size = absint( $arguments[‘mla_end_size’] );4491 $mid_size = absint( $arguments[‘mla_mid_size’] );4492 $posts_per_page = $markup_values[‘posts_per_page’];44934494 $new_target = ( ! empty( $arguments[‘mla_target’] ) ) ? ‘target="’ . $arguments[‘mla_target’] . '” ' : '’;44954496 // these will add to the default classes4497 $new_class = ( ! empty( $arguments[‘mla_link_class’] ) ) ? ' ' . esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_link_class’], $markup_values ) ) : '’;44984499 $new_attributes = ( ! empty( $arguments[‘mla_link_attributes’] ) ) ? esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_link_attributes’], $markup_values ) ) . ' ' : '’;45004501 $new_base = ( ! empty( $arguments[‘mla_link_href’] ) ) ? self::_process_shortcode_parameter( $arguments[‘mla_link_href’], $markup_values ) : $markup_values[‘new_url’];45024503 // Build the array of page links4504 $page_links = array();4505 $dots = false;45064507 if ( $prev_next && $current_page && 1 < $current_page ) {4508 $markup_values[‘new_page’] = $current_page - 1;4509 $new_title = ( ! empty( $arguments[‘mla_rollover_text’] ) ) ? ‘title="’ . esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_rollover_text’], $markup_values ) ) . '" ' : '’;4510 $new_url = self::_replace_query_parameter( $mla_page_parameter, $current_page - 1, $new_base );4511 $prev_text = ( ! empty( $arguments[‘mla_prev_text’] ) ) ? esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_prev_text’], $markup_values ) ) : '« ' . __( 'Previous’, ‘media-library-assistant’ );4512 $page_links[] = sprintf( '<a %1$sclass="prev page-numbers%2$s" %3$s%4$shref="%5$s">%6$s</a>’,4513 /* %1$s */ $new_target,4514 /* %2$s */ $new_class,4515 /* %3$s */ $new_attributes,4516 /* %4$s */ $new_title,4517 /* %5$s */ $new_url,4518 /* %6$s */ $prev_text );4519 }45204521 for ( $new_page = 1; $new_page <= $last_page; $new_page++ ) {4522 $new_page_display = number_format_i18n( $new_page );4523 $markup_values[‘new_page’] = $new_page;4524 $new_title = ( ! empty( $arguments[‘mla_rollover_text’] ) ) ? ‘title="’ . esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_rollover_text’], $markup_values ) ) . '" ' : '’;45254526 if ( $new_page == $current_page ) {4527 // build current page span4528 $page_links[] = sprintf( '<span class="page-numbers current%1$s">%2$s</span>’,4529 /* %1$s */ $new_class,4530 /* %2$s */ $new_page_display );4531 $dots = true;4532 } else {4533 if ( $show_all || ( $new_page <= $end_size || ( $current_page && $new_page >= $current_page - $mid_size && $new_page <= $current_page + $mid_size ) || $new_page > $last_page - $end_size ) ) {4534 // build link4535 $new_url = self::_replace_query_parameter( $mla_page_parameter, $new_page, $new_base );4536 $page_links[] = sprintf( '<a %1$sclass="page-numbers%2$s" %3$s%4$shref="%5$s">%6$s</a>’,4537 /* %1$s */ $new_target,4538 /* %2$s */ $new_class,4539 /* %3$s */ $new_attributes,4540 /* %4$s */ $new_title,4541 /* %5$s */ $new_url,4542 /* %6$s */ $new_page_display );4543 $dots = true;4544 } elseif ( $dots && ! $show_all ) {4545 // build link4546 $page_links[] = sprintf( '<span class="page-numbers dots%1$s">…</span>’,4547 /* %1$s */ $new_class );4548 $dots = false;4549 }4550 } // ! current4551 } // for $new_page45524553 if ( $prev_next && $current_page && ( $current_page < $last_page || -1 == $last_page ) ) {4554 // build next link4555 $markup_values[‘new_page’] = $current_page + 1;4556 $new_title = ( ! empty( $arguments[‘mla_rollover_text’] ) ) ? ‘title="’ . esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_rollover_text’], $markup_values ) ) . '" ' : '’;4557 $new_url = self::_replace_query_parameter( $mla_page_parameter, $current_page + 1, $new_base );4558 $next_text = ( ! empty( $arguments[‘mla_next_text’] ) ) ? esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_next_text’], $markup_values ) ) : __( 'Next’, ‘media-library-assistant’ ) . ' »’;4559 $page_links[] = sprintf( '<a %1$sclass="next page-numbers%2$s" %3$s%4$shref="%5$s">%6$s</a>’,4560 /* %1$s */ $new_target,4561 /* %2$s */ $new_class,4562 /* %3$s */ $new_attributes,4563 /* %4$s */ $new_title,4564 /* %5$s */ $new_url,4565 /* %6$s */ $next_text );4566 }45674568 switch ( strtolower( trim( $arguments[‘mla_paginate_type’] ) ) ) {4569 case 'list’:4570 $results = “<ul class=’page-numbers’>\n\t<li>";4571 $results .= join(“</li>\n\t<li>", $page_links);4572 $results .= “</li>\n</ul>\n";4573 break;4574 case 'plain’:4575 default:4576 $results = join(“\n", $page_links);4577 } // mla_paginate_type45784579 return $output . $results;4580 }45814582 /**4583 * Handles pagnation output types 'previous_page’, 'next_page’, and 'paginate_links’4584 *4585 * @since 2.204586 *4587 * @param array value(s) for mla_output_type parameter4588 * @param array template substitution values, e.g., (‘instance’ => '1’, … )4589 * @param array merged default and passed shortcode parameter values4590 * @param array raw passed shortcode parameter values4591 * @param integer number of attachments in the gallery, without pagination4592 * @param string output text so far, may include debug values4593 *4594 * @return mixed false or string with HTML for pagination output types4595 */4596 private static function _process_pagination_output_types( $output_parameters, $markup_values, $arguments, $attr, $found_rows, $output = ‘’ ) {4597//error_log( __LINE__ . ' _process_pagination_output_types output_parameters = ' . var_export( $output_parameters, true ), 0 );4598//error_log( __LINE__ . ' _process_pagination_output_types markup_values = ' . var_export( $markup_values, true ), 0 );4599//error_log( __LINE__ . ' _process_pagination_output_types arguments = ' . var_export( $arguments, true ), 0 );4600//error_log( __LINE__ . ' _process_pagination_output_types attr = ' . var_export( $attr, true ), 0 );4601 if ( ! in_array( $output_parameters[0], array( 'previous_page’, 'next_page’, ‘paginate_links’ ) ) ) {4602 return false;4603 }46044605 // Add data selection parameters to gallery-specific and mla_gallery-specific parameters4606 $arguments = array_merge( $arguments, shortcode_atts( self::$mla_get_shortcode_attachments_parameters, $attr ) );4607 $posts_per_page = absint( $arguments[‘posts_per_page’] );4608 $mla_page_parameter = $arguments[‘mla_page_parameter’];46094610 /*4611 * $mla_page_parameter, if set, doesn’t make it through the shortcode_atts filter,4612 * so we handle it separately4613 */4614 if ( ! isset( $arguments[ $mla_page_parameter ] ) ) {4615 if ( isset( $attr[ $mla_page_parameter ] ) ) {4616 $arguments[ $mla_page_parameter ] = $attr[ $mla_page_parameter ];4617 } else {4618 $arguments[ $mla_page_parameter ] = '’;4619 }4620 }4621//error_log( __LINE__ . ' _process_pagination_output_types arguments = ' . var_export( $arguments, true ), 0 );46224623 if ( 0 == $posts_per_page ) {4624 $posts_per_page = absint( $arguments[‘numberposts’] );4625 }46264627 if ( 0 == $posts_per_page ) {4628 $posts_per_page = absint( get_option(‘posts_per_page’) );4629 }46304631 if ( 0 < $posts_per_page ) {4632 $max_page = (integer) floor( $found_rows / $posts_per_page );4633 if ( $max_page < ( $found_rows / $posts_per_page ) ) {4634 $max_page++;4635 }4636 } else {4637 $max_page = 1;4638 }46394640 if ( isset( $arguments[‘mla_paginate_total’] ) && $max_page > absint( $arguments[‘mla_paginate_total’] ) ) {4641 $max_page = absint( $arguments[‘mla_paginate_total’] );4642 }46434644 if ( isset( $arguments[ $mla_page_parameter ] ) ) {4645 $paged = absint( $arguments[ $mla_page_parameter ] );4646 } else {4647 $paged = absint( $arguments[‘paged’] );4648 }46494650 if ( 0 == $paged ) {4651 $paged = 1;4652 }46534654 if ( $max_page < $paged ) {4655 $paged = $max_page;4656 }46574658 switch ( $output_parameters[0] ) {4659 case 'previous_page’:4660 if ( 1 < $paged ) {4661 $new_page = $paged - 1;4662 } else {4663 $new_page = 0;46644665 if ( isset ( $output_parameters[1] ) ) {4666 switch ( $output_parameters[1] ) {4667 case 'wrap’:4668 $new_page = $max_page;4669 break;4670 case 'first’:4671 $new_page = 1;4672 }4673 }4674 }46754676 break;4677 case 'next_page’:4678 if ( $paged < $max_page ) {4679 $new_page = $paged + 1;4680 } else {4681 $new_page = 0;46824683 if ( isset ( $output_parameters[1] ) ) {4684 switch ( $output_parameters[1] ) {4685 case 'last’:4686 $new_page = $max_page;4687 break;4688 case 'wrap’:4689 $new_page = 1;4690 }4691 }4692 }46934694 break;4695 case 'paginate_links’:4696 $new_page = 0;4697 }46984699 $markup_values[‘current_page’] = $paged;4700 $markup_values[‘new_page’] = $new_page;4701 $markup_values[‘last_page’] = $max_page;4702 $markup_values[‘posts_per_page’] = $posts_per_page;4703 $markup_values[‘found_rows’] = $found_rows;47044705 if ( $paged ) {4706 $markup_values[‘current_offset’] = ( $paged - 1 ) * $posts_per_page;4707 } else {4708 $markup_values[‘current_offset’] = 0;4709 }47104711 if ( $new_page ) {4712 $markup_values[‘new_offset’] = ( $new_page - 1 ) * $posts_per_page;4713 } else {4714 $markup_values[‘new_offset’] = 0;4715 }47164717 $markup_values[‘current_page_text’] = $mla_page_parameter . '=”[+current_page+]“’;4718 $markup_values[‘new_page_text’] = $mla_page_parameter . '=”[+new_page+]“’;4719 $markup_values[‘last_page_text’] = 'mla_paginate_total=”[+last_page+]“’;4720 $markup_values[‘posts_per_page_text’] = 'posts_per_page=”[+posts_per_page+]“’;47214722 if ( ‘HTTPS’ == substr( $_SERVER[“SERVER_PROTOCOL”], 0, 5 ) ) { // phpcs:ignore4723 $markup_values[‘scheme’] = 'https://’;4724 } else {4725 $markup_values[‘scheme’] = 'http://’;4726 }47274728 $markup_values[‘http_host’] = $_SERVER[‘HTTP_HOST’]; // phpcs:ignore47294730 $parts = wp_parse_url( $_SERVER[‘REQUEST_URI’] ); // phpcs:ignore4731 $uri_path = empty( $parts[‘path’] ) ? ‘’ : $parts[‘path’];4732 $uri_query = empty( $parts[‘query’] ) ? ‘’ : $parts[‘query’];47334734 // Add or replace the current page parameter4735 if ( 0 < $new_page ) {4736 $uri_query = remove_query_arg( $mla_page_parameter, $uri_query );4737 $uri_query = add_query_arg( array( $mla_page_parameter => $new_page ), $uri_query ); 4738 }47394740 if ( ( 0 < strlen( $uri_query ) ) && ( ‘?’ !== $uri_query[0] ) ) {4741 $uri_query = ‘?’ . $uri_query;4742 }47434744 // Validate the query arguments to prevent cross-site scripting (reflection) attacks4745 $test_query = array();4746 parse_str( strval( $uri_query ), $test_query );47474748 $clean_query = array();4749 foreach ( $test_query as $test_key => $test_value ) {4750 // Query argument names cannot have URL special characters4751 if ( $test_key === urldecode( $test_key ) ) {4752 $clean_query[ $test_key ] = $test_value;4753 }4754 }47554756 $clean_query = urlencode_deep( $clean_query );4757 $clean_query = build_query( $clean_query );4758 $markup_values[‘query_string’] = $clean_query;47594760 if ( !empty( $clean_query ) ) {4761// $markup_values[‘request_uri’] = $uri_path . ‘?’ . $clean_query; 4762 $markup_values[‘request_uri’] = $uri_path . $clean_query; 4763 } else {4764 $markup_values[‘request_uri’] = $uri_path;4765 }47664767 $markup_values[‘new_url’] = set_url_scheme( $markup_values[‘scheme’] . $markup_values[‘http_host’] . $markup_values[‘request_uri’] );4768 $markup_values = apply_filters( 'mla_gallery_pagination_values’, $markup_values );47694770 /*4771 * Expand pagination-specific Gallery Display Content parameters,4772 * which can contain request: and query: arguments.4773 */4774 $pagination_arguments = array( 'mla_nolink_text’, 'mla_link_class’, 'mla_rollover_text’, 'mla_link_attributes’, 'mla_link_href’, 'mla_link_text’, 'mla_prev_text’, ‘mla_next_text’ );47754776 $new_text = '’;4777 foreach( $pagination_arguments as $value ) {4778 $new_text .= str_replace( '{+’, '[+’, str_replace( '+}’, '+]', $arguments[ $value ] ) );4779 }47804781 $markup_values = MLAData::mla_expand_field_level_parameters( $new_text, $attr, $markup_values );47824783 // Build the new link, applying Gallery Display Content parameters4784 if ( ‘paginate_links’ == $output_parameters[0] ) {4785 return self::_paginate_links( $output_parameters, $markup_values, $arguments, $found_rows, $output );4786 }47874788 if ( 0 == $new_page ) {4789 if ( ! empty( $arguments[‘mla_nolink_text’] ) ) {4790 return self::_process_shortcode_parameter( $arguments[‘mla_nolink_text’], $markup_values );4791 } else {4792 return '’;4793 }4794 }47954796 $new_link = '<a ';47974798 if ( ! empty( $arguments[‘mla_target’] ) ) {4799 $new_link .= ‘target="’ . $arguments[‘mla_target’] . '” ';4800 }48014802 if ( ! empty( $arguments[‘mla_link_class’] ) ) {4803 $new_link .= ‘class="’ . esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_link_class’], $markup_values ) ) . '” ';4804 }48054806 if ( ! empty( $arguments[‘mla_rollover_text’] ) ) {4807 $new_link .= ‘title="’ . esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_rollover_text’], $markup_values ) ) . '” ';4808 }48094810 if ( ! empty( $arguments[‘mla_link_attributes’] ) ) {4811 $new_link .= esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_link_attributes’], $markup_values ) ) . ' ';4812 }48134814 if ( ! empty( $arguments[‘mla_link_href’] ) ) {4815 $new_link .= ‘href="’ . self::_process_shortcode_parameter( $arguments[‘mla_link_href’], $markup_values ) . '” >’;4816 } else {4817 $new_link .= ‘href="’ . $markup_values[‘new_url’] . '" >’;4818 }48194820 if ( ! empty( $arguments[‘mla_link_text’] ) ) {4821 $new_link .= self::_process_shortcode_parameter( $arguments[‘mla_link_text’], $markup_values ) . '</a>’;4822 } else {4823 if ( ‘previous_page’ == $output_parameters[0] ) {4824 if ( isset( $arguments[‘mla_prev_text’] ) ) {4825 $new_text = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_prev_text’], $markup_values ) );4826 } else {4827 $new_text = '« ' . __( 'Previous’, ‘media-library-assistant’ );4828 }4829 } else {4830 if ( isset( $arguments[‘mla_next_text’] ) ) {4831 $new_text = esc_attr( self::_process_shortcode_parameter( $arguments[‘mla_next_text’], $markup_values ) );4832 } else {4833 $new_text = __( ‘Next’, ‘media-library-assistant’ ) . ' »’;4834 }4835 }48364837 $new_link .= $new_text . ‘</a>’;4838 }48394840 return $new_link;4841 }48424843 /**4844 * WP_Query filter “parameters"4845 *4846 * This array defines parameters for the query’s join, where and orderby filters.4847 * The parameters are set up in the mla_get_shortcode_attachments function, and4848 * any further logic required to translate those values is contained in the filter.4849 *4850 * Array index values are: orderby, post_parent4851 *4852 * @since 2.204853 *4854 * @var array4855 */4856 private static $query_parameters = array();48574858 /**4859 * Error details from _validate_array_specification()4860 *4861 * @since 2.944862 *4863 * @var string4864 */4865 private static $array_specification_error = '’;48664867 /**4868 * Checks for valid, perhaps nested PHP array specification4869 *4870 * @since 2.824871 *4872 * @param string $specification query specification; PHP nested arrays4873 * @param array $interor_arrays Optional. Values for nested arrays, by reference.4874 *4875 * @return boolean true if specification is a valid PHP array else false4876 */4877 private static function _validate_array_specification( $specification, &$interor_arrays = array() ) {4878//error_log( __LINE__ . " _validate_array_specification() specification = " . var_export( $specification, true ), 0 );4879//error_log( __LINE__ . " _validate_array_specification() interor_arrays = " . var_export( $interor_arrays, true ), 0 );4880 self::$array_specification_error = '’;48814882 // Check for outer array specification(s) and reject anything else.4883 if ( 1 !== preg_match( '/^array\s*\((.*)\)[\s\,]*$/’, $specification, $matches ) ) {4884//error_log( __LINE__ . " _validate_array_specification() specification = " . var_export( $specification, true ), 0 );4885 self::$array_specification_error = " FAILED outer array = " . var_export( $specification, true );4886 return false;4887 }48884889 $converted_array = array();4890 4891 $interior = trim( $matches[1], ', ' );4892 while ( strlen( $interior ) ) {4893//error_log( __LINE__ . " _validate_array_specification() converted_array = " . var_export( $converted_array, true ), 0 );4894//error_log( __LINE__ . " _validate_array_specification() interior = " . var_export( $interior, true ), 0 );4895 $interior_array = array();4896 4897 // Recursive matching required for nested and multiple arrays4898 while ( preg_match_all( '/(?x)array\s*\( ( (?>[^()]+) | (?R) )* \)/’, $interior, $matches ) ) {4899//error_log( __LINE__ . " _validate_array_specification() recursion matches = " . var_export( $matches, true ), 0 );4900 foreach ( $matches[0] as $search ) {4901 // Replace valid arrays with a harmless literal value4902 $interior_array = self::_validate_array_specification( $search, $interor_arrays );4903 if ( false === $interior_array ) {4904 self::$array_specification_error = " FAILED nested array = " . var_export( $search, true );4905//error_log( __LINE__ . " _validate_array_specification() search = " . var_export( $search, true ), 0 );4906 return false;4907 }49084909 $interor_arrays[] = $interior_array;4910 $interior = str_replace( $search, sprintf( 'ARRAY%1$03d’, ( count( $interor_arrays ) - 1 ) ), $interior );4911 }4912//error_log( __LINE__ . " _validate_array_specification() recursion interior = " . var_export( $interior, true ), 0 );4913//error_log( __LINE__ . " _validate_array_specification() recursion interor_arrays = " . var_export( $interor_arrays, true ), 0 );4914 }49154916 // Look for a nested array4917 if ( 1 === preg_match( ‘/^(array\s*\(.*\))(.*)$/’, $interior, $matches ) ) {4918//error_log( __LINE__ . " _validate_array_specification() nested matches = " . var_export( $matches, true ), 0 );4919 $interior_array = self::_validate_array_specification( $matches[1], $interor_arrays );4920 if ( false === $interior_array ) {4921 return false;4922 }49234924 $converted_array[] = $interior_array;4925 $interior = trim( $matches[2], ' ,’ );4926 continue;4927 }49284929 // PHP “undefined constant” pattern: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*4930 /* Look for ‘key’ => value4931 * 0 Entire interior4932 * 1 key and assignment literal, e.g., ‘\’key\’ => '4933 * 2 quoted string | integer | undefined constant4934 * 3 string key with enclosing quotes4935 * 4 string key without quotes4936 * 5 integer key4937 * 6 undefined constant key4938 * 7 quoted string | integer | ARRAY999 placeholder | 4- or 5-letter word 4939 * 8 string value with quotes4940 * 9 string value without quotes4941 * 10 integer value4942 * 11 ARRAY999 placeholder4943 * 12 tail portion following ARRAY999 placeholder4944 * 13 4 or 5 letter word, e.g. true or false4945 * 14 tail portion following string, integer or word/boolean value4946 */4947 if ( 1 === preg_match( '/^((([\’\”](.+?)[\’\"])|(\d+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))\s*\=\>\s*)(([\’\"](.*?)[\’\"])|(\d+)|(ARRAY…)(.*)|(\w{4,5}))(.*)$/’, $interior, $matches /*, PREG_OFFSET_CAPTURE */ ) ) {4948//error_log( __LINE__ . " _validate_array_specification() key => value matches = " . var_export( $matches, true ), 0 );49494950 // Validate boolean values4951 if ( ! empty( $matches[13] ) ) {4952//error_log( __LINE__ . " _validate_array_specification() boolean and array() matches = " . var_export( $matches[10], true ), 0 );4953//error_log( __LINE__ . " _validate_array_specification() boolean and array() interior_array = " . var_export( $interior_array, true ), 0 );4954 if ( false === in_array( strtolower( $matches[13] ), array( ‘false’, ‘true’ ) ) ) {4955//error_log( __LINE__ . " _validate_array_specification() FAILED boolean matches = " . var_export( $matches[7], true ), 0 );4956 self::$array_specification_error = " FAILED boolean matches = " . var_export( $matches[7], true );4957 return false;4958 }4959 }49604961 if ( ! empty( $matches[5] ) ) {4962 $key = (integer) $matches[5];4963 } else {4964 $key = trim( $matches[2], ‘"\’’ );4965 }49664967 if ( 8 === strlen( $matches[11] ) ) {4968 $simple_index = substr( $matches[11], 5, 3 );4969 if ( ‘XXX’ !== $simple_index ) {4970 $converted_array[ $key ] = $interor_arrays[ (integer) $simple_index ];4971 }49724973 $interior = trim( $matches[12], ' ,’ );4974 } else {4975 if ( ! empty( $matches[10] ) ) {4976 $converted_array[ $key ] = (integer) $matches[10];4977 } elseif ( ! empty( $matches[13] ) ) {4978 $converted_array[ $key ] = ( ‘true’ === strtolower( $matches[13] ) );4979 } else {4980 $converted_array[ $key ] = trim( $matches[7], ‘"\’’ );4981 }4982 4983 $interior = trim( $matches[14], ' ,’ );4984 }4985 4986 continue;4987 }49884989 /*4990 * Look for already-validated array match, simple quoted string, integer value or “undefined constant", e.g., in ‘terms’ =>4991 * 0 Entire interior4992 * 1 string | integer | constant4993 * 2 string with quotes4994 * 3 string trimmed of quotes4995 * 4 integer4996 * 5 undefined constant or ARRAY999 placeholder4997 * 6 tail portion of interior4998 */4999 if ( 1 === preg_match( '/^(([\’\”](.+?)[\’\"])|(-{0,1}\d+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))(.*)$/’, $interior, $matches ) ) {5000//error_log( __LINE__ . " _validate_array_specification() simple matches = " . var_export( $matches, true ), 0 );5001 if ( 0 === strpos( $interior, ‘ARRAY’ ) ) {5002 $simple_index = substr( $interior, 5, 3 );5003 if ( ‘XXX’ !== $simple_index ) {5004 $converted_array[] = $interor_arrays[ (integer) $simple_index ];5005 }5006 } else {5007 if ( !empty( $matches[4] ) ) {5008 $converted_array[] = (integer) $matches[4];5009 } else {5010 $converted_array[] = trim( $matches[1], ‘"\’’ );5011 }5012 }5013 5014 $interior = trim( $matches[6], ' ,’ );5015 continue;5016 }50175018//error_log( __LINE__ . " _validate_array_specification() FAILED interior = " . var_export( $interior, true ), 0 );5019 self::$array_specification_error = " FAILED interior = " . var_export( $interior, true );5020 return false;5021 }5022//error_log( __LINE__ . " _validate_array_specification() GOOD interior = " . var_export( $interior, true ), 0 );50235024//error_log( __LINE__ . " _validate_array_specification() GOOD converted_array = " . var_export( $converted_array, true ), 0 );5025 return $converted_array;5026 }50275028 /**5029 * Cleans up damage caused by the Visual Editor to the tax_query and meta_query specifications,5030 * then checks for valid PHP array specification to avoid remote code execution attacks.5031 *5032 * @since 2.205033 *5034 * @param string query specification; PHP nested arrays5035 *5036 * @return string query specification with HTML escape sequences and line breaks removed5037 */5038 private static function _sanitize_query_specification( $specification ) {5039//error_log( __LINE__ . " _sanitize_query_specification() specification = " . var_export( $specification, true ), 0 );5040 // Clean up the text5041 $candidate = wp_specialchars_decode( $specification );50425043 $candidate = str_replace( array( '&’, '‘’, '’’, '“’, '”’, '′’, '″’, '&’, '<br />’, '<br>’, '<p>’, '</p>’, "\r", "\n", “\t” ),5044 array( '&’, '\’’, '\’’, '"’, '"’, '\’’, '"’, '&’, ' ', ' ', ' ', ' ', ' ', ' ‘, ' ' ), $candidate );50455046 $candidate = trim( $candidate, ' ,"\`’ );5047//error_log( __LINE__ . " _sanitize_query_specification() candidate = " . var_export( $candidate, true ), 0 );50485049 // Check for nested array specification(s) and reject anything else.5050 $result = self::_validate_array_specification( $candidate );5051 if ( true === $result ) {5052 return $candidate;5053 }50545055//error_log( __LINE__ . " _sanitize_query_specification() FAILED array_specification_error = " . var_export( self::$array_specification_error, true ), 0 );5056 return 'false’;5057 }50585059 /**5060 * Translates query parameters to a valid SQL order by clause.5061 *5062 * Accepts one or more valid columns, with or without ASC/DESC.5063 * Enhanced version of /wp-includes/formatting.php function sanitize_sql_orderby().5064 *5065 * @since 2.205066 *5067 * @param array Validated query parameters; 'order’, 'orderby’, 'meta_key’, 'post__in’.5068 * @param string Optional. Database table prefix; can be empty. Default taken from $wpdb->posts.5069 * @param array Optional. Field names (keys) and database column equivalents (values). Defaults from [mla_gallery].5070 * @param array Optional. Field names (values) that require a BINARY prefix to preserve case order. Default array()5071 * @return string|bool Returns the orderby clause if present, false otherwise.5072 */5073 private static function _validate_sql_orderby( $query_parameters, $table_prefix = NULL, $allowed_keys = NULL, $binary_keys = array() ){5074 global $wpdb;50755076 $results = array ();5077 $order = isset( $query_parameters[‘order’] ) ? ' ' . trim( strtoupper( $query_parameters[‘order’] ) ) : '’;5078 $orderby = isset( $query_parameters[‘orderby’] ) ? $query_parameters[‘orderby’] : '’;5079 $meta_key = isset( $query_parameters[‘meta_key’] ) ? $query_parameters[‘meta_key’] : '’;50805081 if ( is_null( $table_prefix ) ) {5082 $table_prefix = $wpdb->posts . '.’;5083 }50845085 if ( is_null( $allowed_keys ) ) {5086 $allowed_keys = array(5087 ‘empty_orderby_default’ => 'post_date’,5088 ‘explicit_orderby_field’ => 'post__in’,5089 ‘explicit_orderby_column’ => 'ID’,5090 ‘id’ => 'ID’,5091 ‘author’ => 'post_author’,5092 ‘date’ => 'post_date’,5093 ‘description’ => 'post_content’,5094 ‘content’ => 'post_content’,5095 ‘title’ => 'post_title’,5096 ‘caption’ => 'post_excerpt’,5097 ‘excerpt’ => 'post_excerpt’,5098 ‘slug’ => 'post_name’,5099 ‘name’ => 'post_name’,5100 ‘modified’ => 'post_modified’,5101 ‘parent’ => 'post_parent’,5102 ‘menu_order’ => 'menu_order’,5103 ‘mime_type’ => 'post_mime_type’,5104 ‘comment_count’ => 'post_content’,5105 ‘rand’ => 'RAND()',5106 );5107 }51085109 if ( empty( $orderby ) ) {5110 if ( ! empty( $allowed_keys[‘empty_orderby_default’] ) ) {5111 return $table_prefix . $allowed_keys[‘empty_orderby_default’] . " {$order}";5112 } else {5113 return "{$table_prefix}post_date {$order}";5114 }5115 } elseif ( ‘none’ == $orderby ) {5116 return '’;5117 } elseif ( ! empty( $allowed_keys[‘explicit_orderby_field’] ) ) {5118 $explicit_field = $allowed_keys[‘explicit_orderby_field’];5119 if ( $orderby == $explicit_field ) {5120 if ( ! empty( $query_parameters[ $explicit_field ] ) ) {5121 $explicit_order = implode(',’, array_map( 'absint’, $query_parameters[ $explicit_field ] ) );51225123 if ( ! empty( $explicit_order ) ) {5124 $explicit_column = $allowed_keys[‘explicit_orderby_column’];5125 return "FIELD( {$table_prefix}{$explicit_column}, {$explicit_order} )";5126 } else {5127 return '’;5128 }5129 }5130 }5131 }51325133 if ( ! empty( $meta_key ) ) {5134 $allowed_keys[ $meta_key ] = "$wpdb->postmeta.meta_value";5135 $allowed_keys[‘meta_value’] = "$wpdb->postmeta.meta_value";5136 $allowed_keys[‘meta_value_num’] = "$wpdb->postmeta.meta_value+0";5137 }51385139 $obmatches = preg_split('/\s*,\s*/’, trim($query_parameters[‘orderby’]));5140 foreach ( $obmatches as $index => $value ) {5141 $count = preg_match('/([a-z0-9_]+)(\s+(ASC|DESC))?/i’, $value, $matches);5142 if ( $count && ( $value == $matches[0] ) ) {5143 $matches[1] = strtolower( $matches[1] );5144 if ( isset( $matches[2] ) ) {5145 $matches[2] = strtoupper( $matches[2] );5146 }51475148 if ( array_key_exists( $matches[1], $allowed_keys ) ) {5149 if ( ( ‘rand’ == $matches[1] ) || ( ‘random’ == $matches[1] ) ){5150 $results[] = 'RAND()';5151 } else {5152 switch ( $matches[1] ) {5153 case $meta_key:5154 case 'meta_value’:5155 $matches[1] = "$wpdb->postmeta.meta_value";5156 break;5157 case 'meta_value_num’:5158 $matches[1] = "$wpdb->postmeta.meta_value+0";5159 break;5160 default:5161 if ( in_array( $matches[1], $binary_keys ) ) {5162 $matches[1] = 'BINARY ' . $table_prefix . $allowed_keys[ $matches[1] ];5163 } else {5164 $matches[1] = $table_prefix . $allowed_keys[ $matches[1] ];5165 }5166 } // switch $matches[1]51675168 $results[] = isset( $matches[2] ) ? $matches[1] . $matches[2] : $matches[1] . $order;5169 } // not 'rand’5170 } // allowed key5171 } // valid column specification5172 } // foreach $obmatches51735174 $orderby = implode( ', ', $results );5175 if ( empty( $orderby ) ) {5176 return false;5177 }51785179 return $orderby;5180 }51815182 /**5183 * Data selection parameters for the WP_Query in [mla_gallery]5184 *5185 * @since 2.205186 *5187 * @var array5188 */5189 private static $mla_get_shortcode_attachments_parameters = array(5190 ‘order’ => 'ASC’, // or ‘DESC’ or 'RAND’5191 ‘orderby’ => 'menu_order,ID’,5192 ‘id’ => NULL,5193 ‘ids’ => array(),5194 ‘include’ => array(),5195 ‘exclude’ => array(),5196 // MLA extensions, from WP_Query5197 // Force ‘get_children’ style query5198 ‘post_parent’ => NULL, // post/page ID, 'none’, 'any’, ‘current’ or 'all’5199 // Author5200 ‘author’ => NULL,5201 ‘author_name’ => '’,5202 // Category5203 ‘cat’ => 0,5204 ‘category_name’ => '’,5205 ‘category__and’ => array(),5206 ‘category__in’ => array(),5207 ‘category__not_in’ => array(),5208 // Tag5209 ‘tag’ => '’,5210 ‘tag_id’ => 0,5211 ‘tag__and’ => array(),5212 ‘tag__in’ => array(),5213 ‘tag__not_in’ => array(),5214 ‘tag_slug__and’ => array(),5215 ‘tag_slug__in’ => array(),5216 // Taxonomy parameters are handled separately5217 // {tax_slug} => ‘term’ | array ( 'term’, 'term’, … )5218 // ‘tax_query’ => '’5219 // ‘tax_input’ => '’5220 // ‘tax_relation’ => 'OR’, ‘AND’ (default),5221 // ‘tax_operator’ => ‘OR’ (default), 'IN’, 'NOT IN’, 'AND’,5222 // ‘tax_include_children’ => true (default), false5223 // Post 5224 ‘post_type’ => 'attachment’,5225 ‘post_status’ => 'inherit’,5226 ‘post_mime_type’ => 'image’,5227 // Pagination - no default for most of these5228 ‘nopaging’ => true,5229 ‘numberposts’ => 0,5230 ‘posts_per_page’ => 0,5231 ‘posts_per_archive_page’ => 0,5232 ‘paged’ => NULL, // page number or 'current’5233 ‘offset’ => NULL,5234 ‘mla_page_parameter’ => 'mla_paginate_current’,5235 ‘mla_paginate_current’ => NULL,5236 ‘mla_paginate_total’ => NULL,5237 // Date and Time Queries5238 ‘year’ => '’,5239 ‘monthnum’ => '’,5240 ‘w’ => '’,5241 ‘day’ => '’,5242 ‘m’ => '’,5243 ‘date_query’ => '’,5244 // Custom Field5245 ‘meta_key’ => '’,5246 ‘meta_value’ => '’,5247 ‘meta_value_num’ => NULL,5248 ‘meta_compare’ => '’,5249 ‘meta_query’ => '’,5250 // Terms Search5251 ‘mla_terms_phrases’ => '’,5252 ‘mla_terms_taxonomies’ => '’,5253 ‘mla_phrase_delimiter’ => '’,5254 ‘mla_phrase_connector’ => '’,5255 ‘mla_term_delimiter’ => '’,5256 ‘mla_term_connector’ => '’,5257 // Search5258 ‘s’ => '’,5259 ‘mla_search_fields’ => '’,5260 ‘mla_search_connector’ => '’,5261 ‘whole_word’ => '’,5262 ‘sentence’ => '’,5263 ‘exact’ => '’,5264 // Returned fields, for support topic “Adding ‘fields’ to function mla_get_shortcode_attachments” by leoloso5265 ‘fields’ => '’,5266 // Caching parameters, for support topic “Lag in attachment categories” by Ruriko5267 ‘cache_results’ => NULL,5268 ‘update_post_meta_cache’ => NULL,5269 ‘update_post_term_cache’ => NULL,5270 // WordPress Real Media Library plugin support5271 ‘mla_allow_rml’ => false,5272 ‘mla_rml_folder’ => NULL,5273 ‘mla_rml_include_children’ => false,5274 // WordPress CatFolders plugin support5275 ‘mla_allow_catf’ => true,5276 ‘mla_catf_folder’ => NULL,5277 );52785279 /**5280 * Data selection parameters for the WP_Query in [mla_gallery]5281 *5282 * @since 2.405283 *5284 * @var array5285 */5286 private static $mla_get_shortcode_dynamic_attachments_parameters = array(5287 // Taxonomy parameters are handled separately5288 // {tax_slug} => ‘term’ | array ( 'term’, 'term’, … )5289 // ‘tax_query’ => '’5290 // ‘tax_relation’ => 'OR’, ‘AND’ (default),5291 // ‘tax_operator’ => ‘OR’ (default), 'IN’, 'NOT IN’, 'AND’,5292 // ‘tax_include_children’ => true (default), false5293 );52945295 /**5296 * For Paid Memberships Pro plugin, Hide the ‘attachment’ post type5297 * from searches and archives if membership is required to access.5298 *5299 * @since 2.845300 *5301 * @param array Post types to be screened for membership5302 */53035304 public static function mla_pmp_hide_attachments_filter( $post_types ) {5305 $post_types[] = 'attachment’;5306 return $post_types;5307 }53085309 /**5310 * Convert a taxonomy, date or meta query parameter to an array5311 *5312 * @since 2.995313 *5314 * @param string $query_type 'tax_query’, ‘date_query’ or 'meta_query’.5315 * @param mixed $query_string Array specification in text or array format, e.g., array of arrays.5316 * @param array $where_used_alternative Harmless substitute for invalid “where-used” queries.5317 *5318 * @return mixed An array on success, error message string on failure5319 */5320 private static function _convert_query_parameter( $query_type, $query_string, $where_used_alternative ) {5321//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) query_string = " . var_export( $query_string, true ), 0 );5322 if ( is_array( $query_string ) ) {5323 return $query_string;5324 }53255326 // Clean up damage caused by the Visual Editor 5327 $candidate = wp_specialchars_decode( $query_string );53285329 $candidate = str_replace( array( '&’, '‘’, '’’, '“’, '”’, '′’, '″’, '&’, '<br />’, '<br>’, '<p>’, '</p>’, "\r", "\n", “\t” ),5330 array( '&’, '\’’, '\’’, '"’, '"’, '\’’, '"’, '&’, ' ', ' ', ' ', ' ', ' ', ' ‘, ' ' ), $candidate );53315332 $candidate = trim( $candidate, ' ,"\`’ );5333//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) candidate = " . var_export( $candidate, true ), 0 );53345335 // Unexpanded substitution parameters are not allowed5336 if ( false !== strpos( $candidate, ‘{+’ ) ) {5337 $converted_result = false;5338 self::$array_specification_error = 'FAILED substitution parameter in ' . $candidate;5339 } else {5340 // Check for nested array specification(s) and reject anything else.5341 $converted_result = self::_validate_array_specification( $candidate );5342 }5343//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) converted_result = " . var_export( $converted_result, true ), 0 );53445345 if ( false === $converted_result ) {5346 // Replace invalid queries from “where-used” callers with a harmless equivalent5347 if ( !empty( $where_used_alternative ) ) {5348 return $where_used_alternative;5349 }53505351 return ‘<p>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . __( 'Invalid mla_gallery’, ‘media-library-assistant’ ) . " {$query_type} = " . self::$array_specification_error . '</p>’;5352 }5353 5354/* * /5355 try {5356//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) candidate = " . var_export( $candidate, true ), 0 );5357 $result = @eval( 'return ' . $candidate . ‘;’ );5358//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) result = " . var_export( $result, true ), 0 );5359 } catch ( Throwable $e ) { // PHP 7+5360 $result = NULL;5361 } catch ( Exception $e ) { // PHP 55362 $result = NULL;5363 } // */5364//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) result = " . var_export( $result, true ), 0 );53655366// if ( is_array( $result ) ) {5367 if ( is_array( $converted_result ) ) {5368/* * /5369 if ( $converted_result != $result ) {5370//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) loose failure converted_result = " . var_export( $converted_result, true ), 0 );5371//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) loose failure eval result = " . var_export( $result, true ), 0 );5372 }53735374 if ( $converted_result !== $result ) {5375//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) strict failure converted_result = " . var_export( $converted_result, true ), 0 );5376//error_log( __LINE__ . " _convert_query_parameter( {$query_type} ) strict failure eval result = " . var_export( $result, true ), 0 );5377 } // */53785379// return $result;5380 return $converted_result;5381 }5382 5383 return ‘<p>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . __( 'Invalid mla_gallery’, ‘media-library-assistant’ ) . " {$query_type} = " . var_export( $candidate, true ) . '</p>’;5384 }53855386 /**5387 * Parses shortcode parameters and returns the gallery objects5388 *5389 * @since 2.205390 *5391 * @param int ID of the post/page in which the shortcode appears; zero (0) if none5392 * @param array Attributes of the shortcode5393 * @param boolean Optional; true to calculate and return ['found_rows’, ‘max_num_pages’] as array elements5394 * @param boolean Optional; true activate debug logging, false to suppress it.5395 *5396 * @return array List of attachments returned from WP_Query5397 */5398 public static function mla_get_shortcode_attachments( $post_parent, $attr, $return_found_rows = NULL, $overide_debug = NULL ) {5399 global $wp_query;54005401 // Set the local debug mode5402 $old_debug_mode = self::$mla_debug;5403 if ( NULL !== $overide_debug ) {5404 self::$mla_debug = ( true === $overide_debug );5405 }54065407 // Parameters passed to the join, where and orderby filter functions5408 self::$query_parameters = array( MLAQuery::MLA_ALT_TEXT_SUBQUERY => false, MLAQuery::MLA_FILE_SUBQUERY => false, );54095410 // Parameters passed to the posts_search filter function in MLAData5411 MLAQuery::$search_parameters = array( ‘debug’ => ‘none’ );54125413 // Make sure $attr is an array, even if it’s empty5414 if ( empty( $attr ) ) {5415 $attr = array();5416 } elseif ( is_string( $attr ) ) {5417 $attr = shortcode_parse_atts( $attr );5418 }54195420 /*5421 * The “where used” queries have no $_REQUEST context available to them,5422 * so tax_, date_ and meta_query evaluation will fail if they contain "{+request:"5423 * parameters. Ignore these errors.5424 */5425 if ( isset( $attr[‘where_used_query’] ) && ( ‘this-is-a-where-used-query’ == $attr[‘where_used_query’] ) ) {5426 $where_used_query = true;5427 unset( $attr[‘where_used_query’] );54285429 // remove pagination parameters to get a complete result5430 $attr[‘nopaging’] = true;5431 unset( $attr[‘numberposts’] );5432 unset( $attr[‘posts_per_page’] );5433 unset( $attr[‘posts_per_archive_page’] );5434 unset( $attr[‘paged’] );5435 unset( $attr[‘offset’] );5436 unset( $attr[‘mla_paginate_current’] );5437 unset( $attr[‘mla_page_parameter’] );5438 unset( $attr[‘mla_paginate_total’] );54395440 // There’s no point in sorting the items5441 $attr[‘orderby’] = 'none’;5442 } else {5443 $where_used_query = false;5444 }54455446 /*5447 * Merge input arguments with defaults, then extract the query arguments.5448 *5449 * $return_found_rows is used to indicate that the call comes from gallery_shortcode(),5450 * which is the only call that supplies it.5451 */5452 if ( ! is_null( $return_found_rows ) ) {5453 $attr = apply_filters( 'mla_gallery_query_attributes’, $attr );5454 }54555456 $arguments = shortcode_atts( self::$mla_get_shortcode_attachments_parameters, $attr );5457 $mla_page_parameter = $arguments[‘mla_page_parameter’];5458 unset( $arguments[‘mla_page_parameter’] );54595460 // Convert to boolean, detect mla_rml_folder5461 $arguments[‘mla_allow_rml’] = ‘true’ === ( ( ! empty( $arguments[‘mla_allow_rml’] ) ) ? trim( strtolower( $arguments[‘mla_allow_rml’] ) ) : ‘false’ );5462 $arguments[‘mla_rml_include_children’] = ‘true’ === ( ( ! empty( $arguments[‘mla_rml_include_children’] ) ) ? trim( strtolower( $arguments[‘mla_rml_include_children’] ) ) : ‘false’ );5463 if ( ! empty( $arguments[‘mla_rml_folder’] ) ) {5464 $arguments[‘mla_rml_folder’] = absint( $arguments[‘mla_rml_folder’] );5465 $arguments[‘mla_allow_rml’] = 0 < $arguments[‘mla_rml_folder’];5466 }54675468 $arguments[‘mla_allow_catf’] = ‘true’ === ( ( ! empty( $arguments[‘mla_allow_catf’] ) ) ? trim( strtolower( $arguments[‘mla_allow_catf’] ) ) : ‘true’ );5469 if ( ! empty( $arguments[‘mla_catf_folder’] ) ) {5470 $arguments[‘mla_catf_folder’] = intval( $arguments[‘mla_catf_folder’] );5471 $arguments[‘mla_allow_catf’] = 0 < $arguments[‘mla_catf_folder’];5472 }54735474 /*5475 * $mla_page_parameter, if set, doesn’t make it through the shortcode_atts filter,5476 * so we handle it separately5477 */5478 if ( ! isset( $arguments[ $mla_page_parameter ] ) ) {5479 if ( isset( $attr[ $mla_page_parameter ] ) ) {5480 $arguments[ $mla_page_parameter ] = $attr[ $mla_page_parameter ];5481 } else {5482 $arguments[ $mla_page_parameter ] = NULL;5483 }5484 }54855486 if ( ! empty( $arguments[‘ids’] ) ) {5487 // ‘ids’ is explicitly ordered, unless you specify otherwise.5488 if ( empty( $attr[‘orderby’] ) ) {5489 $arguments[‘orderby’] = 'post__in’;5490 }54915492 $arguments[‘include’] = $arguments[‘ids’];5493 }5494 unset( $arguments[‘ids’] );54955496 if ( ! is_null( $return_found_rows ) ) {5497 $arguments = apply_filters( 'mla_gallery_query_arguments’, $arguments );5498 }54995500 // Extract taxonomy arguments5501 self::$mla_get_shortcode_dynamic_attachments_parameters = array();5502 $query_arguments = array();5503 $terms_assigned_query = false;5504 if ( ! empty( $attr ) ) {5505 $all_taxonomies = get_taxonomies( array ( ‘show_ui’ => true ), ‘names’ );5506 $simple_tax_queries = array();5507 foreach ( $attr as $key => $value ) {5508 if ( ‘tax_query’ === $key ) {5509 // An empty query should be ignored, as is an empty "simple tax query"5510 if ( empty( $value ) ) {5511 continue;5512 }55135514 if ( is_array( $value ) ) {5515 $query_arguments[ $key ] = $value;5516 self::$mla_get_shortcode_dynamic_attachments_parameters[ $key ] = $value;5517 } else {5518 $tax_query = self::_convert_query_parameter( 'tax_query’, $value, array( array( ‘taxonomy’ => 'none’, ‘field’ => ‘slug’, ‘terms’ => ‘none’ ) ) );55195520 if ( is_array( $tax_query ) ) {5521 // Check for ignore.terms.assigned/-3, no.terms.assigned/-1 or any.terms.assigned/-25522 foreach ( $tax_query as $tax_query_key => $tax_query_element ) {5523 if ( !is_array( $tax_query_element ) ) {5524 continue;5525 }55265527 if ( isset( $tax_query_element[‘taxonomy’] ) ) {5528 $tax_query_taxonomy = $tax_query_element[‘taxonomy’];5529 } else {5530 continue;5531 }55325533 if ( isset( $tax_query_element[‘terms’] ) ) {5534 $terms = $tax_query_element[‘terms’];55355536 if ( empty( $terms ) || ( $terms === '-3’ ) || ( is_array( $terms ) && in_array( '-3’, $terms ) ) ) {5537 $terms = 'ignore.terms.assigned’;5538 }55395540 if ( ( $terms === ‘ignore.terms.assigned’ ) || ( is_array( $terms ) && in_array( ‘ignore.terms.assigned’, $terms ) ) ) {5541 unset( $tax_query[ $tax_query_key ] );5542 continue;5543 }55445545 if ( ( $terms === '-1’ ) || ( is_array( $terms ) && in_array( '-1’, $terms ) ) ) {5546 $terms = 'no.terms.assigned’;5547 }55485549 if ( ( $terms === ‘no.terms.assigned’ ) || ( is_array( $terms ) && in_array( 'no.terms.assigned’, $terms ) ) ) {5550 $tax_query[ $tax_query_key ] = array(5551 ‘taxonomy’ => $tax_query_taxonomy,5552 ‘operator’ => ‘NOT EXISTS’,5553 );55545555 continue;5556 }55575558 if ( ( $terms === '-2’ ) || ( is_array( $terms ) && in_array( '-2’, $terms ) ) ) {5559 $terms = 'any.terms.assigned’;5560 }55615562 if ( ( $terms === ‘any.terms.assigned’ ) || ( is_array( $terms ) && in_array( 'any.terms.assigned’, $terms ) ) ) {5563 $tax_query[ $tax_query_key ] = array(5564 ‘taxonomy’ => $tax_query_taxonomy,5565 ‘operator’ => 'EXISTS’,5566 );55675568 continue;5569 }5570 } // isset( terms )5571 } // is_array( $tax_query )55725573 $query_arguments[ $key ] = $tax_query;5574 self::$mla_get_shortcode_dynamic_attachments_parameters[ $key ] = $value;5575 break; // Done - the tax_query overrides all other taxonomy parameters5576 } else {5577 self::$mla_debug = $old_debug_mode;5578 return ‘<p>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . __( 'Invalid mla_gallery’, ‘media-library-assistant’ ) . ' tax_query = ' . var_export( $value, true ) . '</p>’;5579 } // generated value is not an array5580 } // $tax_query is a string, not array5581 } // attr is 'tax_query’5582 elseif ( ‘tax_input’ == $key ) {5583 if ( is_array( $value ) ) {5584 $tax_queries = $value;5585 } else {5586 $tax_queries = array();5587 $compound_values = array_filter( array_map( 'trim’, explode( ',’, $value ) ) );5588 foreach ( $compound_values as $compound_value ) {5589 $value = explode( '.’, $compound_value );5590 if ( 2 === count( $value ) ) {5591 if ( array_key_exists( $value[0], $all_taxonomies ) ) {5592 $tax_queries[ $value[0] ][] = $value[1];5593 } // valid taxonomy5594 } // valid coumpound value5595 } // foreach compound_value5596 } // string value55975598 foreach( $tax_queries as $key => $value ) {5599 if ( is_string( $value ) ) {5600 $value = explode( ',’, $value );5601 }56025603 $simple_tax_queries[ $key ] = implode(',’, array_filter( array_map( 'trim’, $value ) ) );5604 if ( in_array( $simple_tax_queries[ $key ], array( 'ignore.terms.assigned’, '-3’, 'no.terms.assigned’, '-1’, ‘any.terms.assigned’, '-2’ ) ) ) {5605 $terms_assigned_query = true;5606 }5607 }5608 } // tax_input5609 elseif ( array_key_exists( $key, $all_taxonomies ) ) {5610 if ( is_string( $value ) ) {5611 $value = explode( ',’, $value );5612 }56135614 $simple_tax_queries[ $key ] = implode(',’, array_filter( array_map( 'trim’, $value ) ) );5615 if ( in_array( $simple_tax_queries[ $key ], array( 'ignore.terms.assigned’, '-3’, 'no.terms.assigned’, '-1’, ‘any.terms.assigned’, '-2’ ) ) ) {5616 $terms_assigned_query = true;5617 }5618 } // array_key_exists5619 } //foreach $attr56205621 /*5622 * One of five outcomes:5623 * 1) An explicit tax_query was found; use it and ignore all other taxonomy parameters5624 * 2) No tax query is present; no further processing required5625 * 3) Two or more simple tax queries are present; compose a tax_query5626 * 4) One simple tax query and (tax_operator or tax_include_children) are present; compose a tax_query5627 * 5) One simple tax query is present; use it as-is or convert ‘category’ to 'category_name’5628 */5629 if ( isset( $query_arguments[‘tax_query’] ) || empty( $simple_tax_queries ) ) {5630 // No further action required5631 } elseif ( ( 1 < count( $simple_tax_queries ) ) || isset( $attr[‘tax_operator’] ) || isset( $attr[‘tax_include_children’] ) || $terms_assigned_query ) {5632 // Build a tax_query5633 if ( 1 < count( $simple_tax_queries ) ) {5634 $tax_relation = 'AND’;5635 if ( isset( $attr[‘tax_relation’] ) ) {5636 if ( ‘OR’ == strtoupper( $attr[‘tax_relation’] ) ) {5637 $tax_relation = 'OR’;5638 }5639 }5640 $tax_query = array (‘relation’ => $tax_relation );5641 } else {5642 $tax_query = array ();5643 }56445645 // Validate other tax_query parameters or set defaults5646 $tax_operator = ‘IN’;5647 if ( isset( $attr[‘tax_operator’] ) ) {5648 $attr_value = strtoupper( $attr[‘tax_operator’] );5649 if ( in_array( $attr_value, array( ‘IN’, ‘NOT IN’, ‘AND’ ) ) ) {5650 $tax_operator = $attr_value;5651 }5652 }56535654 $tax_include_children = true;5655 if ( isset( $attr[‘tax_include_children’] ) ) {5656 if ( ‘false’ == strtolower( $attr[‘tax_include_children’] ) ) {5657 $tax_include_children = false;5658 }5659 }56605661 foreach( $simple_tax_queries as $key => $value ) {5662 // simple queries with these values are ignored5663 if ( empty( $value ) || ( ‘ignore.terms.assigned’ === $value ) || ( '-3’ === $value ) ) {5664 continue;5665 }56665667 if ( ( ‘no.terms.assigned’ === $value ) || ( '-1’ === $value ) ) {5668 $tax_query[] = array(5669 ‘taxonomy’ => $key,5670 ‘operator’ => ‘NOT EXISTS’ 5671 );56725673 continue;5674 }56755676 if ( ( ‘any.terms.assigned’ === $value ) || ( '-2’ === $value ) ) {5677 $tax_query[] = array(5678 ‘taxonomy’ => $key,5679 ‘operator’ => ‘EXISTS’ 5680 );56815682 continue;5683 }56845685 $tax_query[] = array( ‘taxonomy’ => $key, ‘field’ => 'slug’, ‘terms’ => explode( ',’, $value ), ‘operator’ => $tax_operator, ‘include_children’ => $tax_include_children );5686 } // foreach simple_tax_queries56875688 $query_arguments[‘tax_query’] = $tax_query;5689 self::$mla_get_shortcode_dynamic_attachments_parameters[‘tax_query’] = $tax_query;5690 } else {5691 // exactly one simple query is present5692 if ( isset( $simple_tax_queries[‘category’] ) ) {5693 $arguments[‘category_name’] = $simple_tax_queries[‘category’];5694 } else {5695 $query_arguments = $simple_tax_queries;5696 }56975698 self::$mla_get_shortcode_dynamic_attachments_parameters = $simple_tax_queries;5699 }5700 } // ! empty57015702 // Finish building the dynamic parameters5703 if ( isset( $attr[‘tax_relation’] ) ) {5704 self::$mla_get_shortcode_dynamic_attachments_parameters[‘tax_relation’] = $attr[‘tax_relation’];5705 }57065707 if ( isset( $attr[‘tax_operator’] ) ) {5708 self::$mla_get_shortcode_dynamic_attachments_parameters[‘tax_operator’] = $attr[‘tax_operator’];5709 }57105711 if ( isset( $attr[‘tax_include_children’] ) ) {5712 self::$mla_get_shortcode_dynamic_attachments_parameters[‘tax_include_children’] = $attr[‘tax_include_children’];5713 }57145715 // Convert lists to arrays, if they have more than one element5716 if ( isset( $arguments[‘post_type’] ) && is_string( $arguments[‘post_type’] ) ) {5717 $value = explode( ',’, $arguments[‘post_type’] );5718 if ( 1 < count( $value ) ) {5719 $arguments[‘post_type’] = $value;5720 }5721 }57225723 if ( isset( $arguments[‘post_status’] ) && is_string( $arguments[‘post_status’] ) ) {5724 $value = explode( ',’, $arguments[‘post_status’] );5725 if ( 1 < count( $value ) ) {5726 $arguments[‘post_status’] = $value;5727 }5728 }57295730 // $query_arguments has been initialized in the taxonomy code above.5731 $is_tax_query = ! ($use_children = empty( $query_arguments ));5732 foreach ($arguments as $key => $value ) {5733 /*5734 * There are several “fallthru” cases in this switch statement that decide 5735 * whether or not to limit the query to children of a specific post.5736 */5737 $children_ok = true;5738 switch ( $key ) {5739 case 'post_parent’:5740 switch ( strtolower( $value ) ) {5741 case 'all’:5742 $value = NULL;5743 $use_children = false;5744 break;5745 case 'any’:5746 self::$query_parameters[‘post_parent’] = 'any’;5747 $value = NULL;5748 $use_children = false;5749 break;5750 case 'current’:5751 $value = $post_parent;5752 $use_children = true;5753 break;5754 case 'none’:5755 self::$query_parameters[‘post_parent’] = 'none’;5756 $value = NULL;5757 $use_children = false;5758 break;5759 default:5760 if ( false !== strpos( $value, ‘,’ ) ) {5761 self::$query_parameters[‘post_parent’] = array_filter( array_map( 'absint’, explode( ',’, $value ) ) );5762 $value = NULL;5763 $use_children = false;5764 }5765 }5766 // fallthru5767 case 'id’:5768 if ( is_numeric( $value ) ) {5769 $query_arguments[ $key ] = (int) $value;5770 if ( ! $children_ok ) {5771 $use_children = false;5772 }5773 }5774 unset( $arguments[ $key ] );5775 break;5776 case 'numberposts’:5777 case 'posts_per_page’:5778 case 'posts_per_archive_page’:5779 if ( is_numeric( $value ) ) {5780 $value = (int) $value;5781 if ( ! empty( $value ) ) {5782 $query_arguments[ $key ] = $value;5783 }5784 }5785 unset( $arguments[ $key ] );5786 break;5787 case 'meta_value_num’:5788 $children_ok = false;5789 // fallthru5790 case 'offset’:5791 if ( is_numeric( $value ) ) {5792 $query_arguments[ $key ] = (int) $value;5793 if ( ! $children_ok ) {5794 $use_children = false;5795 }5796 }5797 unset( $arguments[ $key ] );5798 break;5799 case 'paged’:5800 // Avoid PHP deprecation warning about null strtolower argument5801 if ( NULL !== $value ) {5802 if ( ‘current’ == strtolower( $value ) ) {5803 /*5804 * Note: The query variable ‘page’ holds the pagenumber for a single paginated5805 * Post or Page that includes the <!–nextpage–> Quicktag in the post content. 5806 */5807 if ( get_query_var(‘page’) ) {5808 $query_arguments[ $key ] = get_query_var(‘page’);5809 } else {5810 $query_arguments[ $key ] = (get_query_var(‘paged’)) ? get_query_var(‘paged’) : 1;5811 }5812 } elseif ( is_numeric( $value ) ) {5813 $query_arguments[ $key ] = (int) $value;5814 } elseif ( ‘’ === $value ) {5815 $query_arguments[ $key ] = 1;5816 }5817 }58185819 unset( $arguments[ $key ] );5820 break;5821 case $mla_page_parameter :5822 case 'mla_paginate_total’:5823 if ( is_numeric( $value ) ) {5824 $query_arguments[ $key ] = (int) $value;5825 } elseif ( ‘’ === $value ) {5826 $query_arguments[ $key ] = 1;5827 }58285829 unset( $arguments[ $key ] );5830 break;5831 case 'author’:5832 case 'cat’:5833 case 'tag_id’:5834 if ( ! empty( $value ) ) {5835 if ( is_array( $value ) ) {5836 $query_arguments[ $key ] = array_filter( $value );5837 } else {5838 $query_arguments[ $key ] = array_filter( array_map( 'intval’, explode( ",", $value ) ) );5839 }58405841 if ( 1 == count( $query_arguments[ $key ] ) ) {5842 $query_arguments[ $key ] = $query_arguments[ $key ][0];5843 } else {5844 $query_arguments[ $key ] = implode(',’, $query_arguments[ $key ] );5845 }58465847 $use_children = false;5848 }5849 unset( $arguments[ $key ] );5850 break;5851 case 'category__and’:5852 case 'category__in’:5853 case 'category__not_in’:5854 case 'tag__and’:5855 case 'tag__in’:5856 case 'tag__not_in’:5857 case 'include’:5858 $children_ok = false;5859 // fallthru5860 case 'exclude’:5861 if ( ! empty( $value ) ) {5862 if ( is_array( $value ) ) {5863 $value = array_filter( $value );5864 } else {5865 $value = array_filter( array_map( 'intval’, explode( ",", $value ) ) );5866 }58675868 if ( ! empty( $value ) ) {5869 $query_arguments[ $key ] = $value;58705871 if ( ! $children_ok ) {5872 $use_children = false;5873 }5874 }5875 }5876 unset( $arguments[ $key ] );5877 break;5878 case 'tag_slug__and’:5879 case 'tag_slug__in’:5880 if ( ! empty( $value ) ) {5881 if ( is_array( $value ) ) {5882 $query_arguments[ $key ] = $value;5883 } else {5884 $query_arguments[ $key ] = array_filter( array_map( 'trim’, explode( ",", $value ) ) );5885 }58865887 $use_children = false;5888 }5889 unset( $arguments[ $key ] );5890 break;5891 case 'nopaging’: // boolean value, default false5892 if ( ! empty( $value ) && ( ‘false’ != strtolower( $value ) ) ) {5893 $query_arguments[ $key ] = true;5894 }58955896 unset( $arguments[ $key ] );5897 break;5898 // boolean values, default true5899 case 'cache_results’:5900 case 'update_post_meta_cache’:5901 case 'update_post_term_cache’:5902 if ( ! empty( $value ) && ( ‘true’ != strtolower( $value ) ) ) {5903 $query_arguments[ $key ] = false;5904 }59055906 unset( $arguments[ $key ] );5907 break;5908 case 'whole_word’:5909 case 'sentence’:5910 case 'exact’:5911 if ( ! empty( $value ) && ( ‘true’ == strtolower( $value ) ) ) {5912 MLAQuery::$search_parameters[ $key ] = true;5913 } else {5914 MLAQuery::$search_parameters[ $key ] = false;5915 }59165917 unset( $arguments[ $key ] );5918 break;5919 case 'mla_search_connector’:5920 case 'mla_phrase_connector’:5921 case 'mla_term_connector’:5922 if ( ! empty( $value ) && ( ‘OR’ == strtoupper( $value ) ) ) {5923 MLAQuery::$search_parameters[ $key ] = 'OR’;5924 } else {5925 MLAQuery::$search_parameters[ $key ] = 'AND’;5926 }59275928 unset( $arguments[ $key ] );5929 break;5930 case 'mla_phrase_delimiter’:5931 case 'mla_term_delimiter’:5932 if ( ! empty( $value ) ) {5933 MLAQuery::$search_parameters[ $key ] = substr( $value, 0, 1 );5934 }59355936 unset( $arguments[ $key ] );5937 break;5938 case 'mla_terms_phrases’:5939 $children_ok = false;5940 $value = stripslashes( trim( $value ) );5941 // fallthru5942 case 'mla_terms_taxonomies’:5943 case 'mla_search_fields’:5944 if ( ! empty( $value ) ) {5945 MLAQuery::$search_parameters[ $key ] = $value;59465947 if ( ! $children_ok ) {5948 $use_children = false;5949 }5950 }59515952 unset( $arguments[ $key ] );5953 break;5954 case 's’:5955 MLAQuery::$search_parameters[‘s’] = stripslashes( trim( $value ) );5956 // fallthru5957 case 'author_name’:5958 case 'category_name’:5959 case 'tag’:5960 case 'meta_key’:5961 case 'meta_value’:5962 case 'meta_compare’:5963 $children_ok = false;5964 // fallthru5965 case 'post_type’:5966 case 'post_status’:5967 case 'post_mime_type’:5968 case 'orderby’:5969 if ( ! empty( $value ) ) {5970 $query_arguments[ $key ] = $value;59715972 if ( ! $children_ok ) {5973 $use_children = false;5974 }5975 }59765977 unset( $arguments[ $key ] );5978 break;5979 case 'order’:5980 if ( ! empty( $value ) ) {5981 $value = strtoupper( $value );5982 if ( in_array( $value, array( 'ASC’, ‘DESC’ ) ) ) {5983 $query_arguments[ $key ] = $value;5984 }5985 }59865987 unset( $arguments[ $key ] );5988 break;5989 case 'year’: // 4 digit year, e.g., 20215990 if ( 4 === strlen( $value ) && is_numeric( $value ) ) {5991 $query_arguments[ $key ] = (int) $value;5992 $use_children = false;5993 }59945995 unset( $arguments[ $key ] );5996 break;5997 case 'monthnum’: // Month number (from 1 to 12)5998 $value = absint( $value );5999 if ( ( 0 < $value ) && ( 13 > $value ) ) {6000 $query_arguments[ $key ] = $value;6001 $use_children = false;6002 }60036004 unset( $arguments[ $key ] );6005 break;6006 case 'w’: // Week of the year (from 0 to 53). Uses MySQL WEEK command. The mode is dependent on the “start_of_week” option.6007 $value = absint( $value );6008 if ( ( 0 < $value ) && ( 54 > $value ) ) {6009 $query_arguments[ $key ] = $value;6010 $use_children = false;6011 }60126013 unset( $arguments[ $key ] );6014 break;6015 case 'day’: // Day of the month (from 1 to 31)6016 $value = absint( $value );6017 if ( ( 0 < $value ) && ( 32 > $value ) ) {6018 $query_arguments[ $key ] = $value;6019 $use_children = false;6020 }60216022 unset( $arguments[ $key ] );6023 break;6024 case 'm’: //YearMonth, e.g., 2021016025 if ( 6 === strlen( $value ) && is_numeric( $value ) ) {6026 $query_arguments[ $key ] = (int) $value;6027 $use_children = false;6028 }60296030 unset( $arguments[ $key ] );6031 break;6032 case 'date_query’:6033 if ( ! empty( $value ) ) {6034 if ( is_array( $value ) ) {6035 $query_arguments[ $key ] = $value;6036 } else {6037 $date_query = self::_convert_query_parameter( 'date_query’, $value, ( $where_used_query ? array( array( ‘key’ => 'unlikely’, ‘value’ => ‘none or otherwise unlikely’ ) ) : ‘’ ) );6038 6039 if ( is_array( $date_query ) ) {6040 $query_arguments[ $key ] = $date_query;6041 } else {6042 self::$mla_debug = $old_debug_mode;6043 return $date_query;6044 }6045 } // not array60466047 $use_children = false;6048 }60496050 unset( $arguments[ $key ] );6051 break;6052 case 'meta_query’:6053 if ( ! empty( $value ) ) {6054 if ( is_array( $value ) ) {6055 $query_arguments[ $key ] = $value;6056 } else {6057 $meta_query = self::_convert_query_parameter( 'meta_query’, $value, ( $where_used_query ? array( array( ‘key’ => 'unlikely’, ‘value’ => ‘none or otherwise unlikely’ ) ) : ‘’ ) );60586059 if ( is_array( $meta_query ) ) {6060 $query_arguments[ $key ] = $meta_query;6061 } else {6062 self::$mla_debug = $old_debug_mode;6063 return $meta_query; // ‘<p>’ . __( 'ERROR’, ‘media-library-assistant’ ) . ': ' . __( 'Invalid mla_gallery’, ‘media-library-assistant’ ) . ' meta_query = ' . var_export( $value, true ) . '</p>’;6064 }6065 } // not array60666067 $use_children = false;6068 }60696070 unset( $arguments[ $key ] );6071 break;6072 case 'fields’:6073 if ( ! empty( $value ) ) {6074 $value = strtolower( $value );6075 if ( in_array( $value, array( 'ids’, ‘id=>parent’ ) ) ) {6076 $query_arguments[ $key ] = $value;6077 }6078 }60796080 unset( $arguments[ $key ] );6081 break;6082 default:6083 // ignore anything else6084 } // switch $key6085 } // foreach $arguments 60866087 // Decide whether to use a “get_children” style query6088 self::$query_parameters[‘disable_tax_join’] = $is_tax_query && ! $use_children;6089 if ( $use_children && ! isset( $query_arguments[‘post_parent’] ) ) {6090 if ( ! isset( $query_arguments[‘id’] ) ) {6091 $query_arguments[‘post_parent’] = $post_parent;6092 } else {6093 $query_arguments[‘post_parent’] = $query_arguments[‘id’];6094 }60956096 unset( $query_arguments[‘id’] );6097 }60986099 if ( isset( $query_arguments[‘numberposts’] ) && ! isset( $query_arguments[‘posts_per_page’] )) {6100 $query_arguments[‘posts_per_page’] = $query_arguments[‘numberposts’];6101 }6102 unset( $query_arguments[‘numberposts’] );61036104 /*6105 * Apply the archive/search tests here because WP_Query doesn’t apply them to galleries within6106 * search results or archive pages.6107 */6108 if ( self::$mla_debug ) {6109 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_debug is_archive()</strong> = ' . var_export( is_archive(), true ) );6110 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_debug is_search()</strong> = ' . var_export( is_search(), true ) );6111 }61126113 if ( isset( $query_arguments[‘posts_per_archive_page’] ) && ( is_archive() || is_search() ) ) {6114 $query_arguments[‘posts_per_page’] = $query_arguments[‘posts_per_archive_page’];6115 }6116 unset( $query_arguments[‘posts_per_archive_page’] );61176118 // MLA pagination will override WordPress pagination6119 if ( isset( $query_arguments[ $mla_page_parameter ] ) ) {6120 unset( $query_arguments[‘nopaging’] );6121 unset( $query_arguments[‘offset’] );6122 unset( $query_arguments[‘paged’] );61236124 if ( isset( $query_arguments[‘mla_paginate_total’] ) && ( $query_arguments[ $mla_page_parameter ] > $query_arguments[‘mla_paginate_total’] ) ) {6125 $query_arguments[‘offset’] = 0x7FFFFFFF; // suppress further output6126 } else {6127 $query_arguments[‘paged’] = $query_arguments[ $mla_page_parameter ];6128 }6129 } else {6130 if ( isset( $query_arguments[‘posts_per_page’] ) || isset( $query_arguments[‘posts_per_archive_page’] ) ||6131 isset( $query_arguments[‘paged’] ) || isset( $query_arguments[‘offset’] ) ) {6132 unset( $query_arguments[‘nopaging’] );6133 }6134 }6135 unset( $query_arguments[ $mla_page_parameter ] );6136 unset( $query_arguments[‘mla_paginate_total’] );61376138 if ( isset( $query_arguments[‘post_mime_type’] ) && (‘all’ == strtolower( $query_arguments[‘post_mime_type’] ) ) ) {6139 unset( $query_arguments[‘post_mime_type’] );6140 }61416142 if ( ! empty($query_arguments[‘include’]) ) {6143 $incposts = wp_parse_id_list( $query_arguments[‘include’] );61446145 if ( ! ( isset( $query_arguments[‘posts_per_page’] ) && ( 0 < $query_arguments[‘posts_per_page’] ) ) ) {6146 $query_arguments[‘posts_per_page’] = count($incposts); // only the number of posts included6147 }61486149 $query_arguments[‘post__in’] = $incposts;6150 unset( $query_arguments[‘include’] );6151 } elseif ( ! empty($query_arguments[‘exclude’]) ) {6152 $query_arguments[‘post__not_in’] = wp_parse_id_list( $query_arguments[‘exclude’] );6153 unset( $query_arguments[‘exclude’] );6154 }61556156 $query_arguments[‘ignore_sticky_posts’] = true;6157 $query_arguments[‘no_found_rows’] = is_null( $return_found_rows ) ? true : ! $return_found_rows;61586159 // We will always handle “orderby” in our filter6160 self::$query_parameters[‘orderby’] = self::_validate_sql_orderby( $query_arguments );6161 if ( false === self::$query_parameters[‘orderby’] ) {6162 unset( self::$query_parameters[‘orderby’] );6163 }61646165 // RML Pro overrides orderby if it’s not present in the query arguments6166 if ( false === defined(‘RML_FILE’) ) {6167 unset( $query_arguments[‘orderby’] );6168 unset( $query_arguments[‘order’] );6169 }6170 6171 if ( self::$mla_debug ) {6172 add_filter( 'posts_clauses’, 'MLAShortcode_Support::mla_shortcode_query_posts_clauses_filter’, 0x7FFFFFFF, 1 );6173 add_filter( 'posts_clauses_request’, 'MLAShortcode_Support::mla_shortcode_query_posts_clauses_request_filter’, 0x7FFFFFFF, 1 );6174 }61756176 add_filter( 'posts_join’, 'MLAShortcode_Support::mla_shortcode_query_posts_join_filter’, 0x7FFFFFFF, 1 );6177 add_filter( 'posts_where’, 'MLAShortcode_Support::mla_shortcode_query_posts_where_filter’, 0x7FFFFFFF, 1 );6178 add_filter( 'posts_orderby’, 'MLAShortcode_Support::mla_shortcode_query_posts_orderby_filter’, 0x7FFFFFFF, 1 );61796180 /*6181 * Handle the keyword and terms search in the posts_search filter.6182 * One or both of ‘mla_terms_phrases’ and ‘s’ must be present to6183 * trigger the search.6184 */6185 if ( empty( MLAQuery::$search_parameters[‘mla_terms_phrases’] ) && empty( MLAQuery::$search_parameters[‘s’] ) ) {6186 MLAQuery::$search_parameters = array( ‘debug’ => ‘none’ );6187 } else {6188 /*6189 * Convert Terms Search parameters to the filter’s requirements.6190 * mla_terms_taxonomies is shared with keyword search.6191 */6192 if ( empty( MLAQuery::$search_parameters[‘mla_terms_taxonomies’] ) ) {6193 MLAQuery::$search_parameters[‘mla_terms_search’][‘taxonomies’] = MLACore::mla_supported_taxonomies( ‘term-search’ );6194 } else {6195 MLAQuery::$search_parameters[‘mla_terms_search’][‘taxonomies’] = array_filter( array_map( 'trim’, explode( ',’, MLAQuery::$search_parameters[‘mla_terms_taxonomies’] ) ) );6196 }61976198 if ( ! empty( MLAQuery::$search_parameters[‘mla_terms_phrases’] ) ) {6199 MLAQuery::$search_parameters[‘mla_terms_search’][‘phrases’] = MLAQuery::$search_parameters[‘mla_terms_phrases’];62006201 if ( empty( MLAQuery::$search_parameters[‘mla_phrase_delimiter’] ) ) {6202 MLAQuery::$search_parameters[‘mla_terms_search’][‘phrase_delimiter’] = ' ';6203 } else {6204 MLAQuery::$search_parameters[‘mla_terms_search’][‘phrase_delimiter’] = MLAQuery::$search_parameters[‘mla_phrase_delimiter’];6205 }62066207 if ( empty( MLAQuery::$search_parameters[‘mla_phrase_connector’] ) ) {6208 MLAQuery::$search_parameters[‘mla_terms_search’][‘radio_phrases’] = 'AND’;6209 } else {6210 MLAQuery::$search_parameters[‘mla_terms_search’][‘radio_phrases’] = MLAQuery::$search_parameters[‘mla_phrase_connector’];6211 }62126213 if ( empty( MLAQuery::$search_parameters[‘mla_term_delimiter’] ) ) {6214 MLAQuery::$search_parameters[‘mla_terms_search’][‘term_delimiter’] = ',’;6215 } else {6216 MLAQuery::$search_parameters[‘mla_terms_search’][‘term_delimiter’] = MLAQuery::$search_parameters[‘mla_term_delimiter’];6217 }62186219 if ( empty( MLAQuery::$search_parameters[‘mla_term_connector’] ) ) {6220 MLAQuery::$search_parameters[‘mla_terms_search’][‘radio_terms’] = 'OR’;6221 } else {6222 MLAQuery::$search_parameters[‘mla_terms_search’][‘radio_terms’] = MLAQuery::$search_parameters[‘mla_term_connector’];6223 }62246225 MLAQuery::$search_parameters[‘mla_terms_search’][‘whole_word’] = ! empty( MLAQuery::$search_parameters[‘whole_word’] );6226 MLAQuery::$search_parameters[‘mla_terms_search’][‘exact’] = ! empty( MLAQuery::$search_parameters[‘exact’] );6227 MLAQuery::$search_parameters[‘mla_terms_search’][‘sentence’] = ! empty( MLAQuery::$search_parameters[‘sentence’] );6228 }62296230 // Remove terms-search-specific parameters6231 unset( MLAQuery::$search_parameters[‘mla_terms_phrases’] );6232 unset( MLAQuery::$search_parameters[‘mla_terms_taxonomies’] );6233 unset( MLAQuery::$search_parameters[‘mla_phrase_connector’] );6234 unset( MLAQuery::$search_parameters[‘mla_term_connector’] );6235 unset( MLAQuery::$search_parameters[‘whole_word’] );62366237 if ( empty( MLAQuery::$search_parameters[‘mla_search_fields’] ) ) {6238 MLAQuery::$search_parameters[‘mla_search_fields’] = array( 'title’, ‘content’ );6239 } else {6240 MLAQuery::$search_parameters[‘mla_search_fields’] = array_filter( array_map( 'trim’, explode( ',’, MLAQuery::$search_parameters[‘mla_search_fields’] ) ) );6241 MLAQuery::$search_parameters[‘mla_search_fields’] = array_intersect( array( 'title’, 'name’, 'excerpt’, 'content’, 'alt-text’, 'file’, ‘terms’ ), MLAQuery::$search_parameters[‘mla_search_fields’] );62426243 if ( in_array( 'alt-text’, MLAQuery::$search_parameters[‘mla_search_fields’] ) ) {6244 self::$query_parameters[MLAQuery::MLA_ALT_TEXT_SUBQUERY] = true;6245 }62466247 if ( in_array( 'file’, MLAQuery::$search_parameters[‘mla_search_fields’] ) ) {6248 self::$query_parameters[MLAQuery::MLA_FILE_SUBQUERY] = true;6249 }62506251 // Look for keyword search including ‘terms’ 6252 foreach ( MLAQuery::$search_parameters[‘mla_search_fields’] as $index => $field ) {6253 if ( ‘terms’ == $field ) {6254 if ( isset( MLAQuery::$search_parameters[‘mla_terms_search’][‘phrases’] ) ) {6255 // The Terms Search overrides any terms-based keyword search for now; too complicated.6256 unset ( MLAQuery::$search_parameters[‘mla_search_fields’][ $index ] );6257 } else {6258 MLAQuery::$search_parameters[‘mla_search_taxonomies’] = MLAQuery::$search_parameters[‘mla_terms_search’][‘taxonomies’];6259 unset( MLAQuery::$search_parameters[‘mla_terms_search’][‘taxonomies’] );6260 }6261 } // terms in search fields6262 }6263 } // mla_search_fields present62646265 if ( empty( MLAQuery::$search_parameters[‘mla_search_connector’] ) ) {6266 MLAQuery::$search_parameters[‘mla_search_connector’] = 'AND’;6267 }62686269 if ( empty( MLAQuery::$search_parameters[‘whole_word’] ) ) {6270 MLAQuery::$search_parameters[‘whole_word’] = false;6271 }62726273 if ( empty( MLAQuery::$search_parameters[‘sentence’] ) ) {6274 MLAQuery::$search_parameters[‘sentence’] = false;6275 }62766277 if ( empty( MLAQuery::$search_parameters[‘exact’] ) ) {6278 MLAQuery::$search_parameters[‘exact’] = false;6279 }62806281 MLAQuery::$search_parameters[‘debug’] = self::$mla_debug ? ‘shortcode’ : 'none’;62826283 add_filter( 'posts_search’, 'MLAQuery::mla_query_posts_search_filter’, 10, 2 );6284 add_filter( 'posts_groupby’, ‘MLAQuery::mla_query_posts_groupby_filter’ );6285 }62866287 if ( self::$mla_debug ) {6288 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_debug $wp_filter[posts_where]</strong> = ' . MLACore::mla_decode_wp_filter(‘posts_where’) );6289 MLACore::mla_debug_add( __LINE__ . ' <strong>mla_debug $wp_filter[posts_orderby]</strong> = ' . MLACore::mla_decode_wp_filter(‘posts_orderby’) );6290 }62916292 /*6293 * Disable Relevanssi - A Better Search, v3.2 by Mikko Saari 6294 * relevanssi_prevent_default_request( $request, $query )6295 * apply_filters('relevanssi_admin_search_ok’, $admin_search_ok, $query );6296 * apply_filters('relevanssi_prevent_default_request’, $prevent, $query );6297 */6298 if ( function_exists( ‘relevanssi_prevent_default_request’ ) ) {6299 add_filter( 'relevanssi_admin_search_ok’, ‘MLAQuery::mla_query_relevanssi_admin_search_ok_filter’ );6300 add_filter( 'relevanssi_prevent_default_request’, ‘MLAQuery::mla_query_relevanssi_prevent_default_request_filter’ );6301 }63026303 if ( class_exists( ‘MLA_Polylang’ ) ) {6304 $query_arguments = apply_filters( 'mla_get_shortcode_attachments_final_terms’, $query_arguments, $return_found_rows );6305 }63066307 // Paid Memberships Pro support6308 if( defined(‘PMPRO_VERSION’) ) {6309 add_filter( 'pmpro_search_filter_post_types’, ‘MLAShortcode_Support::mla_pmp_hide_attachments_filter’ );6310 }63116312 if ( isset( $query_arguments[‘post_type’] ) && is_string( $query_arguments[‘post_type’] ) && ( ‘attachment’ === $query_arguments[‘post_type’] ) ) {6313 if ( self::$query_parameters[‘disable_tax_join’] ) {6314 // Suppress WordPress WP_Query LEFT JOIN on post_parent, etc.6315 $query_arguments[‘post_type’] = 'mladisabletaxjoin’;6316 } 63176318 if ( defined(‘RML_FILE’) ) {6319 if ( $arguments[‘mla_allow_rml’] ) {6320 add_filter( 'posts_clauses’, 'MLAShortcode_Support::mla_shortcode_query_posts_clauses_rml_filter’, 9, 2 );63216322 if ( ! empty( $arguments[‘mla_rml_folder’] ) ) {6323 unset( $query_arguments[‘post_parent’] );6324 $query_arguments[‘rml_folder’] = $arguments[‘mla_rml_folder’];63256326 if ( $arguments[‘mla_rml_include_children’] ) {6327 $query_arguments[‘rml_include_children’] = $arguments[‘mla_rml_include_children’];6328 }6329 }6330 } else {6331 // Suppress RML additions to MLA queries6332 $query_arguments[‘post_type’] = 'mladisablerml’;6333 }6334 }63356336 if ( defined(‘CATF_VERSION’)){ 6337 if ( $arguments[‘mla_allow_catf’] ) {6338 if ( ! empty( $arguments[‘mla_catf_folder’] ) ) {6339 unset( $query_arguments[‘post_parent’] );6340 $query_arguments[‘catf’] = $arguments[‘mla_catf_folder’];6341 }6342 }6343 }63446345 } // post_type is attachment63466347 MLAShortcodes::$mla_gallery_wp_query_object = new WP_Query;6348 $attachments = MLAShortcodes::$mla_gallery_wp_query_object->query( $query_arguments );63496350 // Paid Memberships Pro support6351 if( defined(‘PMPRO_VERSION’) ) {6352 remove_filter( 'pmpro_search_filter_post_types’, ‘MLAShortcode_Support::mla_pmp_hide_attachments_filter’ );6353 }63546355 /*6356 * $return_found_rows is used to indicate that the call comes from gallery_shortcode(),6357 * which is the only call that supplies it.6358 */6359 if ( is_null( $return_found_rows ) ) {6360 $return_found_rows = false;6361 } else {6362 do_action( 'mla_gallery_wp_query_object’, $query_arguments );63636364 if ( $return_found_rows ) {6365 $attachments[‘found_rows’] = absint( MLAShortcodes::$mla_gallery_wp_query_object->found_posts );6366 $attachments[‘max_num_pages’] = absint( MLAShortcodes::$mla_gallery_wp_query_object->max_num_pages );6367 }63686369 $filtered_attachments = apply_filters_ref_array( 'mla_gallery_the_attachments’, array( NULL, &$attachments ) ) ;6370 if ( !is_null( $filtered_attachments ) ) {6371 $attachments = $filtered_attachments;6372 }6373 }63746375 if ( ! empty( MLAQuery::$search_parameters ) ) {6376 remove_filter( 'posts_groupby’, ‘MLAQuery::mla_query_posts_groupby_filter’ );6377 remove_filter( 'posts_search’, ‘MLAQuery::mla_query_posts_search_filter’ );6378 }63796380 if ( function_exists( ‘relevanssi_prevent_default_request’ ) ) {6381 remove_filter( 'relevanssi_admin_search_ok’, ‘MLAQuery::mla_query_relevanssi_admin_search_ok_filter’ );6382 remove_filter( 'relevanssi_prevent_default_request’, ‘MLAQuery::mla_query_relevanssi_prevent_default_request_filter’ );6383 }63846385 remove_filter( 'posts_join’, 'MLAShortcode_Support::mla_shortcode_query_posts_join_filter’, 0x7FFFFFFF );6386 remove_filter( 'posts_where’, 'MLAShortcode_Support::mla_shortcode_query_posts_where_filter’, 0x7FFFFFFF );6387 remove_filter( 'posts_orderby’, 'MLAShortcode_Support::mla_shortcode_query_posts_orderby_filter’, 0x7FFFFFFF );63886389 if ( self::$mla_debug ) {6390 remove_filter( 'posts_clauses’, 'MLAShortcode_Support::mla_shortcode_query_posts_clauses_filter’, 0x7FFFFFFF );6391 remove_filter( 'posts_clauses_request’, ‘MLAShortcode_Support::mla_shortcode_query_posts_clauses_request_filter’, 0x7FFFFFFF );63926393 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug query’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $query_arguments, true ) );6394 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug request’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( MLAShortcodes::$mla_gallery_wp_query_object->request, true ) );6395 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug query_vars’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( MLAShortcodes::$mla_gallery_wp_query_object->query_vars, true ) );6396 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug post_count’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( MLAShortcodes::$mla_gallery_wp_query_object->post_count, true ) );6397 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug found_posts’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( MLAShortcodes::$mla_gallery_wp_query_object->found_posts, true ) );6398 }63996400 MLAQuery::$search_parameters = array( ‘debug’ => ‘none’ );6401 MLAShortcodes::$mla_gallery_wp_query_object = NULL;64026403 self::$mla_debug = $old_debug_mode;6404 return $attachments;6405 }64066407 /**6408 * Filters the JOIN clause for shortcode queries6409 * 6410 * Defined as public because it’s a filter.6411 *6412 * @since 2.206413 *6414 * @param string query clause before modification6415 *6416 * @return string query clause after item modification6417 */6418 public static function mla_shortcode_query_posts_join_filter( $join_clause ) {6419 global $wpdb;64206421 if ( self::$mla_debug ) {6422 $old_clause = $join_clause;6423 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug JOIN filter’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $join_clause, true ) );6424 }64256426 /*6427 * Set for taxonomy queries unless post_parent=current. If true, we must disable6428 * the LEFT JOIN clause that get_posts() adds to taxonomy queries.6429 * We leave the clause in because the WHERE clauses refer to "p2.".6430 * Replaced in MLA v2.94 by "post_type = 'mladisabletaxjoin’"6431 * /6432 if ( self::$query_parameters[‘disable_tax_join’] ) {6433 $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 );6434 } // */64356436 // These joins support the ‘terms’ search_field6437 if ( isset( MLAQuery::$search_parameters[‘tax_terms_count’] ) ) {6438 $tax_index = 0;6439 $tax_clause = '’;64406441 while ( $tax_index < MLAQuery::$search_parameters[‘tax_terms_count’] ) {6442 $prefix = ‘mlatt’ . $tax_index++;6443 $tax_clause .= sprintf( ' INNER JOIN %1$s AS %2$s ON (%3$s.ID = %2$s.object_id)', $wpdb->term_relationships, $prefix, $wpdb->posts );6444 }64456446 $join_clause .= $tax_clause;6447 }64486449 /*6450 * ALT Text and File Name searches use a subquery to build an intermediate table and6451 * modify the JOIN to include posts with no value for the metadata field.6452 */6453 if ( self::$query_parameters[MLAQuery::MLA_ALT_TEXT_SUBQUERY] ) {6454 $sub_query = sprintf( 'SELECT post_id, meta_value FROM %1$s WHERE %1$s.meta_key = \’%2$s\’’, $wpdb->postmeta, ‘_wp_attachment_image_alt’ );6455 $join_clause .= sprintf( ' LEFT JOIN ( %1$s ) %2$s ON (%3$s.ID = %2$s.post_id)', $sub_query, MLAQuery::MLA_ALT_TEXT_SUBQUERY, $wpdb->posts );6456 }64576458 if ( self::$query_parameters[MLAQuery::MLA_FILE_SUBQUERY] ) {6459 $sub_query = sprintf( 'SELECT post_id, meta_value FROM %1$s WHERE %1$s.meta_key = \’%2$s\’’, $wpdb->postmeta, ‘_wp_attached_file’ );6460 $join_clause .= sprintf( ' LEFT JOIN ( %1$s ) %2$s ON (%3$s.ID = %2$s.post_id)‘, $sub_query, MLAQuery::MLA_FILE_SUBQUERY, $wpdb->posts );6461 }64626463 if ( self::$mla_debug && ( $old_clause != $join_clause ) ) {6464 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug modified JOIN filter’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $join_clause, true ) );6465 }64666467 return $join_clause;6468 }64696470 /**6471 * Filters the WHERE clause for shortcode queries6472 * 6473 * Captures debug information. Adds whitespace to the post_type = ‘attachment’6474 * phrase to circumvent subsequent Role Scoper modification of the clause.6475 * Handles post_parent “any” and “none” cases.6476 * Defined as public because it’s a filter.6477 *6478 * @since 2.206479 *6480 * @param string query clause before modification6481 *6482 * @return string query clause after modification6483 */6484 public static function mla_shortcode_query_posts_where_filter( $where_clause ) {6485 global $table_prefix;64866487 if ( self::$mla_debug ) {6488 $old_clause = $where_clause;6489 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug WHERE filter’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $where_clause, true ) );6490 }64916492 // Reverse post_type modification used to avoid redundant LEFT JOIN insertion or RML folder insertion6493 if ( strpos( $where_clause, “post_type = 'mladisabletaxjoin’” ) ) {6494 $where_clause = str_replace( "post_type = 'mladisabletaxjoin’", "post_type = 'attachment’", $where_clause );6495 } elseif ( strpos( $where_clause, “post_type = 'mladisablerml’” ) ) {6496 $where_clause = str_replace( "post_type = 'mladisablerml’", "post_type = 'attachment’", $where_clause );6497 }64986499 // Add whitespace to prevent Role Scoper plugin clause modification6500 if ( strpos( $where_clause, “post_type = 'attachment’” ) ) {6501 $where_clause = str_replace( "post_type = 'attachment’", "post_type = 'attachment’", $where_clause );6502 }65036504 if ( isset( self::$query_parameters[‘post_parent’] ) ) {6505 if ( is_array( self::$query_parameters[‘post_parent’] ) ) {6506 $parent_list = implode( ',’, self::$query_parameters[‘post_parent’] );6507 $where_clause .= " AND {$table_prefix}posts.post_parent IN ({$parent_list})";6508 } else {6509 switch ( self::$query_parameters[‘post_parent’] ) {6510 case 'any’:6511 $where_clause .= " AND {$table_prefix}posts.post_parent > 0";6512 break;6513 case ‘none’:6514 $where_clause .= " AND {$table_prefix}posts.post_parent < 1";6515 break;6516 }6517 }6518 }65196520 // Support Plugin Name: Featured Image from URL, “Media Library” option setting6521 if ( function_exists(‘fifu_is_off’) && fifu_is_off(‘fifu_media_library’)) {6522 $where_clause .= " AND {$table_prefix}posts.post_author <> 77777";6523 }65246525 if ( self::$mla_debug && ( $old_clause != $where_clause ) ) {6526 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug modified WHERE filter’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $where_clause, true ) );6527 }65286529 return $where_clause;6530 }65316532 /**6533 * Filters the ORDERBY clause for shortcode queries6534 * 6535 * This is an enhanced version of the code found in wp-includes/query.php, function get_posts.6536 * Defined as public because it’s a filter.6537 *6538 * @since 2.206539 *6540 * @param string query clause before modification6541 *6542 * @return string query clause after modification6543 */6544 public static function mla_shortcode_query_posts_orderby_filter( $orderby_clause ) {6545 global $wpdb;65466547 if ( self::$mla_debug ) {6548 $replacement = isset( self::$query_parameters[‘orderby’] ) ? var_export( self::$query_parameters[‘orderby’], true ) : ‘none’;6549 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug ORDER BY filter, incoming’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $orderby_clause, true ) . ‘<br>’ . __( 'Replacement ORDER BY clause’, ‘media-library-assistant’ ) . ' = ' . $replacement );6550 }65516552 if ( isset( self::$query_parameters[‘orderby’] ) ) {6553 return self::$query_parameters[‘orderby’];6554 }65556556 return $orderby_clause;6557 }65586559 /**6560 * Reverse mladisabletaxjoin/mladisablerml overide for RML queries6561 * 6562 * @since 2.956563 *6564 * @param array query clauses before modification6565 * @param WP_Query query object6566 */6567 public static function mla_shortcode_query_posts_clauses_rml_filter( $pieces, $query ) {6568 remove_filter( 'posts_clauses’, 'MLAShortcode_Support::mla_shortcode_query_posts_clauses_rml_filter’, 9 );65696570 if ( $query->get( ‘post_type’ ) === ‘mladisabletaxjoin’ ) {6571 $query->set( ‘post_type’, ‘attachment’ );6572 }65736574 return $pieces;6575 }65766577 /**6578 * Filters all clauses for shortcode queries, pre caching plugins6579 * 6580 * This is for debug purposes only.6581 * Defined as public because it’s a filter.6582 *6583 * @since 2.206584 *6585 * @param array query clauses before modification6586 *6587 * @return array query clauses after modification (none)6588 */6589 public static function mla_shortcode_query_posts_clauses_filter( $pieces ) {6590 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug posts_clauses filter’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $pieces, true ) );65916592 return $pieces;6593 }65946595 /**6596 * Filters all clauses for shortcode queries, post caching plugins6597 * 6598 * This is for debug purposes only.6599 * Defined as public because it’s a filter.6600 *6601 * @since 2.206602 *6603 * @param array query clauses before modification6604 *6605 * @return array query clauses after modification (none)6606 */6607 public static function mla_shortcode_query_posts_clauses_request_filter( $pieces ) {6608 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug posts_clauses_request filter’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $pieces, true ) );66096610 return $pieces;6611 }66126613 /**6614 * Data selection parameters for mla_get_all_none_term_counts()6615 *6616 * @since 2.966617 *6618 * @var array6619 */6620 private static $mla_get_all_none_term_counts = array(6621 ‘taxonomy’ => 'post_tag’,6622 ‘post_mime_type’ => 'all’,6623 ‘post_type’ => 'attachment’,6624 ‘post_status’ => 'inherit’,6625 );66266627 /**6628 * Retrieve the "ignore.", "no.", and “any.” “terms.assigned” counts in one taxonomy6629 *6630 * taxonomy - string containing one or more (comma-delimited) taxonomy names6631 * or an array of taxonomy names. Default 'post_tag’. Only the first value is used.6632 *6633 * post_mime_type - MIME type(s) of the items to include in the term-specific counts. Default 'all’.6634 *6635 * post_type - The post type(s) of the items to include in the term-specific counts.6636 * The default is "attachment". 6637 *6638 * post_status - The post status value(s) of the items to include in the term-specific counts.6639 * The default is "inherit".6640 *6641 * @since 2.966642 *6643 * @param array taxonomy to search and query parameters6644 *6645 * @return array ( ‘ignore.terms.assigned’ => count, ‘no.terms.assigned’ => count, ‘any.terms.assigned’ => count )6646 */6647 public static function mla_get_all_none_term_counts( $attr ) {6648 global $wpdb;66496650 // Make sure $attr is an array, even if it’s empty6651 if ( empty( $attr ) ) {6652 $attr = array();6653 } elseif ( is_string( $attr ) ) {6654 $attr = shortcode_parse_atts( $attr );6655 }66566657 // Merge input arguments with defaults6658 $attr = apply_filters( 'mla_get_terms_query_attributes’, $attr );6659 $arguments = shortcode_atts( self::$mla_get_all_none_term_counts, $attr );6660 $arguments = apply_filters( ‘mla_get_terms_query_arguments’, $arguments );66616662 if ( self::$mla_debug ) {6663 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug attributes’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $attr, true ) );6664 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug arguments’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $arguments, true ) );6665 }66666667 // Isolate the first taxonomy value6668 if ( is_array( $arguments[‘taxonomy’] ) ) {6669 $taxonomy = reset( $arguments[‘taxonomy’] );6670 } else {6671 $taxonomy = reset( explode( ',’, $arguments[‘taxonomy’] ) );6672 }66736674 $clause = array( ‘SELECT’ );6675 $clause[] = 'COUNT( p.ID) as `ignore.terms.assigned`, COUNT( sq.object_id ) as `any.terms.assigned`’;6676 $clause[] = 'FROM mladev_posts AS p’;6677 $clause[] = 'LEFT JOIN ( ';6678 $clause[] = 'SELECT DISTINCT tr.object_id FROM mladev_term_relationships as tr’;6679 $clause[] = 'INNER JOIN mladev_term_taxonomy as tt’;6680 $clause[] = 'ON tt.term_taxonomy_id = tr.term_taxonomy_id’;6681 $clause[] = ‘AND tt.taxonomy = \’’ . $taxonomy . '\’’;6682 $clause[] = ') AS sq’;6683 $clause[] = 'ON p.ID = sq.object_id’;6684 $clause[] = 'WHERE 1=1’;66856686 // Add type and status constraints6687 if ( is_array( $arguments[‘post_type’] ) ) {6688 $post_types = $arguments[‘post_type’];6689 } else {6690 $post_types = array( $arguments[‘post_type’] );6691 }66926693 $placeholders = array();6694 $clause_parameters = array();6695 foreach ( $post_types as $post_type ) {6696 $placeholders[] = '%s’;6697 $clause_parameters[] = $post_type;6698 }66996700 $clause[] = $wpdb->prepare( 'AND p.post_type IN ( ' . join( ',’, $placeholders ) . ' )', $clause_parameters );67016702 if ( is_array( $arguments[‘post_status’] ) ) {6703 $post_stati = $arguments[‘post_status’];6704 } else {6705 $post_stati = array( $arguments[‘post_status’] );6706 }67076708 $placeholders = array();6709 $clause_parameters = array();6710 foreach ( $post_stati as $post_status ) {6711 if ( ( ‘private’ != $post_status ) || is_user_logged_in() ) {6712 $placeholders[] = '%s’;6713 $clause_parameters[] = $post_status;6714 }6715 }67166717 $clause[] = $wpdb->prepare( 'AND p.post_status IN ( ' . join( ',’, $placeholders ) . ' )', $clause_parameters );67186719 // Add optional post_mime_type constraint6720 if ( ‘all’ === strtolower( $arguments[‘post_mime_type’] ) ) {6721 $post_mimes = '’;6722 } else {6723 $post_mimes = wp_post_mime_type_where( $arguments[‘post_mime_type’], ‘p’ );6724 $clause[] = str_replace( '%’, '%%’, $post_mimes );6725 }67266727 $query = join(' ', $clause);6728 $results = $wpdb->get_results( $query );67296730 if ( is_wp_error( $results ) ) {6731 $results = array(6732 ‘ignore.terms.assigned’ => 0,6733 ‘no.terms.assigned’ => 0,6734 ‘any.terms.assigned’ => 0,6735 ‘wp_error_code’ => $results->get_error_code(),6736 ‘wp_error_message’ => $results->get_error_message(),6737 ‘wp_error_data’ => $results->get_error_data( $results->get_error_code() ),6738 );6739 } elseif ( isset( $results[0] ) ) {6740 $results = array_map( ‘absint’, (array) $results[0] );6741 $results[‘no.terms.assigned’] = $results[‘ignore.terms.assigned’] - $results[‘any.terms.assigned’];6742 } else {6743 $results = array( ‘ignore.terms.assigned’ => 0, ‘no.terms.assigned’ => 0, ‘any.terms.assigned’ => 0 );6744 $results[‘wpdb_last_error’] = $wpdb->last_error;6745 }67466747 if ( self::$mla_debug ) {6748 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug query’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $query, true ) );6749 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug results’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $results, true ) );6750 }67516752 return $results;6753 } // mla_get_all_none_term_counts67546755 /**6756 * Data selection parameters for [mla_tag_cloud], [mla_term_list]6757 *6758 * @since 2.206759 *6760 * @var array6761 */6762 private static $mla_get_terms_parameters = array(6763 ‘taxonomy’ => 'post_tag’,6764 ‘post_mime_type’ => 'all’,6765 ‘post_type’ => 'attachment’,6766 ‘post_status’ => 'inherit’,6767 ‘ids’ => array(),6768 ‘fields’ => 't.term_id, t.name, t.slug, t.term_group, tt.term_taxonomy_id, tt.taxonomy, tt.description, tt.parent, COUNT(p.ID) AS `count`’,6769 ‘include’ => '’,6770 ‘exclude’ => '’,6771 ‘parent’ => '’,6772 ‘minimum’ => 0,6773 ‘no_count’ => false,6774 ‘number’ => 0,6775 ‘orderby’ => 'name’,6776 ‘order’ => 'ASC’,6777 ‘no_orderby’ => false,6778 ‘preserve_case’ => false,6779 ‘pad_counts’ => false,6780 ‘limit’ => 0,6781 ‘offset’ => 06782 );67836784 /**6785 * Retrieve the terms in one or more taxonomies.6786 *6787 * Alternative to WordPress /wp-includes/taxonomy.php function get_terms() that provides6788 * an accurate count of attachments associated with each term.6789 *6790 * taxonomy - string containing one or more (comma-delimited) taxonomy names6791 * or an array of taxonomy names. Default 'post_tag’.6792 *6793 * post_mime_type - MIME type(s) of the items to include in the term-specific counts. Default ‘all’.6794 *6795 * post_type - The post type(s) of the items to include in the term-specific counts.6796 * The default is "attachment". 6797 *6798 * post_status - The post status value(s) of the items to include in the term-specific counts.6799 * The default is "inherit".6800 *6801 * ids - A comma-separated list of attachment ID values for an item-specific cloud.6802 *6803 * include - An array, comma- or space-delimited string of term ids to include6804 * in the return array.6805 *6806 * exclude - An array, comma- or space-delimited string of term ids to exclude6807 * from the return array. If ‘include’ is non-empty, ‘exclude’ is ignored.6808 *6809 * parent - term_id of the terms’ immediate parent; 0 for top-level terms.6810 *6811 * minimum - minimum number of attachments a term must have to be included. Default 0.6812 *6813 * no_count - 'true’, ‘false’ (default) to suppress term-specific attachment-counting process.6814 *6815 * number - maximum number of term objects to return. Terms are ordered by count,6816 * descending and then by term_id before this value is applied. Default 0.6817 *6818 * orderby - 'count’, 'id’, ‘name’ (default), 'none’, 'random’, 'slug’6819 *6820 * order - ‘ASC’ (default), 'DESC’6821 *6822 * no_orderby - 'true’, ‘false’ (default) to suppress ALL sorting clauses else false.6823 *6824 * preserve_case - 'true’, ‘false’ (default) to make orderby case-sensitive.6825 *6826 * pad_counts - ‘true’, ‘false’ (default) to to include the count of all children in their parents’ count.6827 *6828 * limit - final number of term objects to return, for pagination. Default 0.6829 *6830 * offset - number of term objects to skip, for pagination. Default 0.6831 *6832 * fields - string with fields for the SQL SELECT clause, e.g.,6833 * 't.term_id, t.name, t.slug, COUNT(p.ID) AS `count`’6834 *6835 * @since 2.206836 *6837 * @param array taxonomies to search and query parameters6838 *6839 * @return array array of term objects, empty if none found6840 */6841 public static function mla_get_terms( $attr ) {6842 global $wpdb;68436844 // Make sure $attr is an array, even if it’s empty6845 if ( empty( $attr ) ) {6846 $attr = array();6847 } elseif ( is_string( $attr ) ) {6848 $attr = shortcode_parse_atts( $attr );6849 }68506851 // Merge input arguments with defaults6852 $attr = apply_filters( 'mla_get_terms_query_attributes’, $attr );6853 $arguments = shortcode_atts( self::$mla_get_terms_parameters, $attr );6854 $arguments = apply_filters( 'mla_get_terms_query_arguments’, $arguments );68556856 // Build an array of individual clauses that can be filtered6857 $clauses = array( ‘fields’ => '’, ‘join’ => '’, ‘where’ => '’, ‘orderby’ => '’, ‘limits’ => '’, );68586859 /*6860 * If we’re not counting attachments per term, strip6861 * post fields out of list and adjust the orderby value6862 */6863 $no_count = true;6864 $count_string = trim( strtolower( (string) $arguments[‘no_count’] ) );6865 $field_array = explode( ',’, $arguments[‘fields’] );68666867 switch ( $count_string ) {6868 case 'true’:6869 foreach ( $field_array as $index => $field ) {6870 if ( false !== strpos( $field, ‘p.’ ) ) {6871 unset( $field_array[ $index ] );6872 }6873 }68746875 $arguments[‘minimum’] = 0;6876 $arguments[‘post_mime_type’] = 'all’;68776878 if ( ‘count’ == strtolower( $arguments[‘orderby’] ) ) {6879 $arguments[‘orderby’] = 'none’;6880 }68816882 break;6883 case 'internal’:6884 foreach ( $field_array as $index => $field ) {6885 if ( false !== strpos( $field, ‘p.’ ) ) {6886 unset( $field_array[ $index ] );6887 }6888 }68896890 $field_array[] = ' tt.count’;6891 $arguments[‘post_mime_type’] = 'all’;6892 break;6893 default:6894 $no_count = false;6895 }68966897 // Support Simple Taxonomy Ordering plugin6898 if ( ‘tax_position’ === strtolower( $arguments[‘orderby’] ) ) {6899 if ( class_exists( 'Yikes_Custom_Taxonomy_Order’, false ) ) {6900 $field_array[] = ' term_meta.meta_value AS tax_position’;6901 } else {6902 $arguments[‘orderby’] = 'name’;6903 }6904 }69056906 // Support Simple Custom Post Order plugin6907 if ( ‘term_order’ === strtolower( $arguments[‘orderby’] ) ) {6908 if ( class_exists( 'SCPO_Engine’, false ) ) {6909 $field_array[] = ' t.term_order’;6910 } else {6911 $arguments[‘orderby’] = 'name’;6912 }6913 }69146915 $clauses[‘fields’] = implode( ',’, $field_array );6916 $clause = array ( ‘INNER JOIN `’ . $wpdb->term_taxonomy . ‘` AS tt ON t.term_id = tt.term_id’ );6917 $clause_parameters = array();69186919 if ( $no_count ) {6920 // If no_count=internal we just omit the explicit count and use the WP-maintained count6921 $no_count = ‘true’ === $count_string;69226923 if ( ‘internal’ === $count_string ) {6924 // The ids parameter requires item-specific ID values6925 if ( ! empty( $arguments[‘ids’] ) && empty( $arguments[‘include’] ) ) {6926 $clause[] = ‘LEFT JOIN `’ . $wpdb->term_relationships . '` AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id’;6927 }6928 }6929 } else {6930 $clause[] = ‘LEFT JOIN `’ . $wpdb->term_relationships . '` AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id’;6931 $clause[] = ‘LEFT JOIN `’ . $wpdb->posts . '` AS p ON ( tr.object_id = p.ID’;69326933 // Add type and status constraints6934 if ( is_array( $arguments[‘post_type’] ) ) {6935 $post_types = $arguments[‘post_type’];6936 } else {6937 $post_types = array( $arguments[‘post_type’] );6938 }69396940 $placeholders = array();6941 foreach ( $post_types as $post_type ) {6942 $placeholders[] = '%s’;6943 $clause_parameters[] = $post_type;6944 }69456946 $clause[] = 'AND p.post_type IN (' . join( ',’, $placeholders ) . ')';69476948 if ( is_array( $arguments[‘post_status’] ) ) {6949 $post_stati = $arguments[‘post_status’];6950 } else {6951 $post_stati = array( $arguments[‘post_status’] );6952 }69536954 $placeholders = array();6955 foreach ( $post_stati as $post_status ) {6956 if ( ( ‘private’ != $post_status ) || is_user_logged_in() ) {6957 $placeholders[] = '%s’;6958 $clause_parameters[] = $post_status;6959 }6960 }69616962 $clause[] = 'AND p.post_status IN (' . join( ',’, $placeholders ) . ') )';6963 }69646965 $clause = join(' ', $clause);6966 if ( ! empty( $clause_parameters ) ) {6967 $clauses[‘join’] = $wpdb->prepare( $clause, $clause_parameters );6968 } else {6969 $clauses[‘join’] = $clause;6970 }69716972 // Start WHERE clause with a taxonomy constraint6973 if ( is_array( $arguments[‘taxonomy’] ) ) {6974 $taxonomies = $arguments[‘taxonomy’];6975 } else {6976 $taxonomies = array( $arguments[‘taxonomy’] );6977 }69786979 foreach ( $taxonomies as $taxonomy ) {6980 if ( ! taxonomy_exists( $taxonomy ) ) {6981 $error = new WP_Error( 'invalid_taxonomy’, __( 'Invalid taxonomy’, ‘media-library-assistant’ ), $taxonomy );6982 return $error;6983 }6984 }69856986 $clause_parameters = array();6987 $placeholders = array();6988 foreach ($taxonomies as $taxonomy) {6989 $placeholders[] = '%s’;6990 $clause_parameters[] = $taxonomy;6991 }69926993 $clause = array( 'tt.taxonomy IN (' . join( ',’, $placeholders ) . ')' );69946995 /*6996 * The “ids” parameter can build an item-specific cloud.6997 * Compile a list of all the terms assigned to the items.6998 */6999 if ( ! empty( $arguments[‘ids’] ) ) {7000 $ids = wp_parse_id_list( $arguments[‘ids’] );7001 $placeholders = implode( "’,’", $ids );7002 $clause[] = "AND tr.object_id IN ( ‘{$placeholders}’ )";70037004 $includes = array();7005 foreach ( $ids as $id ) {7006 foreach ($taxonomies as $taxonomy) {7007 $terms = get_the_terms( $id, $taxonomy );7008 if ( is_array( $terms ) ) {7009 foreach( $terms as $term ) {7010 $includes[ $term->term_id ] = $term->term_id;7011 } // terms7012 }7013 } // taxonomies7014 } // ids70157016 // Apply a non-empty argument before we replace it.7017 if ( ! empty( $arguments[‘include’] ) ) {7018 $includes = array_intersect( $includes, wp_parse_id_list( $arguments[‘include’] ) );7019 }70207021 // If there are no terms we want an empty cloud7022 if ( empty( $includes ) ) {7023 $arguments[‘include’] = (string) 0x7FFFFFFF;7024 } else {7025 ksort( $includes );7026 $arguments[‘include’] = implode( ',’, $includes );7027 }7028 }70297030 // Add include/exclude and parent constraints to WHERE cluse7031 if ( ! empty( $arguments[‘include’] ) ) {7032 $placeholders = implode( "’,’", wp_parse_id_list( $arguments[‘include’] ) );7033 $clause[] = "AND t.term_id IN ( ‘{$placeholders}’ )";7034 } elseif ( ! empty( $arguments[‘exclude’] ) ) {7035 $placeholders = implode( "’,’", wp_parse_id_list( $arguments[‘exclude’] ) );7036 $clause[] = "AND t.term_id NOT IN ( ‘{$placeholders}’ )";7037 }70387039 if ( ‘’ !== $arguments[‘parent’] ) {7040 $parent = (int) $arguments[‘parent’];7041 $clause[] = "AND tt.parent = '{$parent}’";7042 }70437044 if ( ‘all’ === strtolower( $arguments[‘post_mime_type’] ) ) {7045 $post_mimes = '’;7046 } else {7047 $post_mimes = wp_post_mime_type_where( $arguments[‘post_mime_type’], ‘p’ );7048 $where = str_replace( '%’, '%%’, $post_mimes );70497050 if ( 0 == absint( $arguments[‘minimum’] ) ) {7051 $clause[] = ' AND ( p.post_mime_type IS NULL OR ' . substr( $where, 6 );7052 } else {7053 $clause[] = $where;7054 }7055 }70567057 $clause = join(' ', $clause);7058 if ( ! empty( $clause_parameters ) ) {7059 $clauses[‘where’] = $wpdb->prepare( $clause, $clause_parameters );7060 } else {7061 $clauses[‘where’] = $clause;7062 }70637064 // For the inner/initial query, always select the most popular terms7065 if ( $no_orderby = ‘true’ == (string) $arguments[‘no_orderby’] ) {7066 $arguments[‘orderby’] = 'count’;7067 $arguments[‘order’] = 'DESC’;7068 }70697070 // Add sort order7071 if ( ‘none’ !== strtolower( $arguments[‘orderby’] ) ) {7072 if ( ( ‘tax_position’ === strtolower( $arguments[‘orderby’] ) ) && class_exists( 'Yikes_Custom_Taxonomy_Order’, false ) ) {7073 // Support Simple Taxonomy Ordering plugin7074 $yikes_custom_taxonomy_order = Yikes_Custom_Taxonomy_Order::get_instance();7075 $clauses = $yikes_custom_taxonomy_order->set_tax_order( $clauses, $taxonomies, array() );7076 // Adjust the orderby clause to account for the subquery and the alias in the fields[] clause7077 $clauses[‘orderby’] = 'ORDER BY CAST( tax_position AS UNSIGNED )';7078 } elseif ( ( ‘term_order’ === strtolower( $arguments[‘orderby’] ) ) && class_exists( 'SCPO_Engine’, false ) ) {7079 // Support Simple Custom Post Order plugin7080 $clauses[‘orderby’] = 'ORDER BY term_order’;7081 } else {7082 if ( ‘true’ == strtolower( $arguments[‘preserve_case’] ) ) {7083 $binary_keys = array( 'name’, 'slug’, );7084 } else {7085 $binary_keys = array();7086 }70877088 $allowed_keys = array(7089 ‘empty_orderby_default’ => 'name’,7090 ‘count’ => 'count’,7091 ‘id’ => 'term_id’,7092 ‘name’ => 'name’,7093 ‘random’ => 'RAND()',7094 ‘slug’ => 'slug’,7095 );70967097 $clauses[‘orderby’] = 'ORDER BY ' . self::_validate_sql_orderby( $arguments, '’, $allowed_keys, $binary_keys );7098 } // not tax_position or term_order7099 } else {7100 $clauses[‘orderby’] = '’;7101 }71027103 // Add pagination7104 $clauses[‘limits’] = '’;7105 $offset = absint( $arguments[‘offset’] );7106 $limit = absint( $arguments[‘limit’] );7107 if ( 0 < $offset && 0 < $limit ) {7108 $clauses[‘limits’] = "LIMIT {$offset}, {$limit}";7109 } elseif ( 0 < $limit ) {7110 $clauses[‘limits’] = "LIMIT {$limit}";7111 } elseif ( 0 < $offset ) {7112 $clause_parameters = 0x7FFFFFFF;7113 $clauses[‘limits’] = "LIMIT {$offset}, {$clause_parameters}";7114 }71157116 $clauses = apply_filters( 'mla_get_terms_clauses’, $clauses );71177118 // Build the final query7119 $query = array( ‘SELECT’ );7120 $query[] = $clauses[‘fields’];7121 $query[] = ‘FROM `’ . $wpdb->terms . '` AS t’;7122 $query[] = $clauses[‘join’];7123 $query[] = 'WHERE (';7124 $query[] = $clauses[‘where’];7125 $query[] = ') GROUP BY tt.term_taxonomy_id’;71267127 $clause_parameters = absint( $arguments[‘minimum’] );7128 if ( 0 < $clause_parameters ) {7129 $query[] = "HAVING count >= {$clause_parameters}";7130 }71317132 /*7133 * Unless specifically told to omit the ORDER BY clause or the COUNT,7134 * supply a sort order for the initial/inner query only7135 */7136 if ( ! ( $no_orderby || $no_count ) ) {7137 $query[] = 'ORDER BY count DESC, t.term_id ASC’;7138 }71397140 // Limit the total number of terms returned7141 $terms_limit = absint( $arguments[‘number’] );7142 if ( 0 < $terms_limit ) {7143 $query[] = "LIMIT {$terms_limit}";7144 }71457146 // $final_clauses, if present, require an SQL subquery7147 $final_clauses = array();71487149 if ( ! empty( $clauses[‘orderby’] ) && ‘ORDER BY count DESC’ != $clauses[‘orderby’] ) {7150 $final_clauses[] = $clauses[‘orderby’];7151 }71527153 if ( ‘’ !== $clauses[‘limits’] ) {7154 $final_clauses[] = $clauses[‘limits’];7155 }71567157 // If we’re paginating the final results, we need to get an accurate total count first7158 if ( ! $no_count && ( 0 < $offset || 0 < $limit ) ) {7159 $count_query = 'SELECT COUNT(*) as count FROM (' . join(' ', $query) . ' ) as subQuery’;7160 $count = $wpdb->get_results( $count_query );7161 $found_rows = $count[0]->count;7162 }71637164 if ( ! empty( $final_clauses ) ) {7165 if ( ! $no_count ) {7166 array_unshift($query, 'SELECT * FROM (');7167 $query[] = ') AS subQuery’;7168 }71697170 $query = array_merge( $query, $final_clauses );7171 }71727173 $query = join(' ‘, $query);7174 $tags = $wpdb->get_results( $query );7175 if ( ! isset( $found_rows ) ) {7176 $found_rows = $wpdb->num_rows;7177 }71787179 if ( self::$mla_debug ) {7180 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug query arguments’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $arguments, true ) );7181 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug last_query’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $wpdb->last_query, true ) );7182 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug last_error’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $wpdb->last_error, true ) );7183 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug num_rows’, ‘media-library-assistant’ ) . ‘</strong> = ' . var_export( $wpdb->num_rows, true ) );7184 MLACore::mla_debug_add( __LINE__ . ' <strong>’ . __( 'mla_debug found_rows’, ‘media-library-assistant’ ) . '</strong> = ' . var_export( $found_rows, true ) );7185 }71867187 if ( ‘true’ == strtolower( trim( $arguments[‘pad_counts’] ) ) ) {7188 self::_pad_term_counts( $tags, reset( $taxonomies ), $post_types, $post_stati, $post_mimes );7189 }71907191 $tags[‘found_rows’] = $found_rows;7192 $tags = apply_filters( 'mla_get_terms_query_results’, $tags );7193 return $tags;7194 } // mla_get_terms71957196 /**7197 * Walk a list of terms and find hierarchy, preserving source order.7198 *7199 * @since 2.257200 *7201 * @param array $terms Term objects, by reference7202 * @param array $arguments Shortcode arguments, including defaults7203 *7204 * @return array ( [taxonomy] => array( [root terms] => array( [fields], array( ‘children’ => [child terms] )7205 */7206 private static function _get_term_tree( &$terms, $arguments = array() ) {7207 $term = current( $terms );72087209 if ( empty( $term ) or ! isset( $term->parent ) ) {7210 return array();7211 }72127213 // Set found_rows aside to be restored later7214 if ( isset( $terms[‘found_rows’] ) ) {7215 $found_rows = $terms[‘found_rows’];7216 unset( $terms[‘found_rows’] );7217 } else {7218 $found_rows = NULL;7219 }72207221 $child_of = ! empty( $arguments[‘child_of’] ) ? absint( $arguments[‘child_of’] ) : NULL;7222 $include_tree = ! empty( $arguments[‘include_tree’] ) ? wp_parse_id_list( $arguments[‘include_tree’] ) : NULL;7223 $exclude_tree = empty( $include_tree ) && ! empty( $arguments[‘exclude_tree’] ) ? wp_parse_id_list( $arguments[‘exclude_tree’] ) : NULL;72247225 $depth = ! empty( $arguments[‘depth’] ) ? absint( $arguments[‘depth’] ) : 0;7226 $term_tree = array();7227 $root_ids = array();7228 $parents = array();7229 $child_ids = array();7230 foreach( $terms as $index => $term ) {7231 // Preserve order for sorting later7232 $term->original_index = $index;72337234 // TODO Make this conditional on $arguments[‘link’]7235 $link = get_edit_tag_link( $term->term_id, $term->taxonomy );7236 if ( ! is_wp_error( $link ) ) {7237 $term->edit_link = $link;7238 $link = get_term_link( (int) $term->term_id, $term->taxonomy );7239 $term->term_link = $link;7240 }72417242 if ( is_wp_error( $link ) ) {7243 return $link;7244 }72457246 if ( ‘edit’ == $arguments[‘link’] ) {7247 $term->link = $term->edit_link;7248 } else {7249 $term->link = $term->term_link;7250 }72517252 $term->children = array();7253 $parent = absint( $term->parent );7254 if ( 0 == $parent ) {7255 $term_tree[ $term->taxonomy ][] = $term;7256 $root_ids[ $term->taxonomy ][ $term->term_id ] = count( $term_tree[ $term->taxonomy ] ) - 1;7257 } else {7258 $parents[ $term->taxonomy ][ $term->parent ][] = $term;7259 $child_ids[ $term->taxonomy ][ $term->term_id ] = absint( $term->parent );7260 }7261 }72627263 // Collapse multi-level children7264 foreach ( $parents as $taxonomy => $tax_parents ) {7265 if ( ! isset( $term_tree[ $taxonomy ] ) ) {7266 $term_tree[ $taxonomy ] = array();7267 $root_ids[ $taxonomy ] = array();7268 }72697270 while ( ! empty( $tax_parents ) ) {7271 foreach( $tax_parents as $parent_id => $children ) {7272 foreach( $children as $index => $child ) {7273 if ( ! array_key_exists( $child->term_id, $tax_parents ) ) {72747275 if ( array_key_exists( $child->parent, $root_ids[ $taxonomy ] ) ) {7276 // Found a root node - attach the leaf7277 $term_tree[ $taxonomy ][ $root_ids[ $taxonomy ][ $child->parent ] ]->children[] = $child;7278 } elseif ( isset( $child_ids[ $taxonomy ][ $child->parent ] ) ) {7279 // Found a non-root parent node - attach the leaf7280 $the_parent = $child_ids[ $taxonomy ][ $child->parent ];7281 foreach( $tax_parents[ $the_parent ] as $candidate_index => $candidate ) {7282 if ( $candidate->term_id == $child->parent ) {7283 $parents[ $taxonomy ][ $the_parent ][ $candidate_index ]->children[] = $child;7284 break;7285 }7286 } // foreach candidate7287 } else {7288 // No parent exists; make this a root node7289 $term_tree[ $taxonomy ][] = $child;7290 $root_ids[ $taxonomy ][ $child->term_id ] = count( $term_tree[ $taxonomy ] ) - 1;7291 } // Move the leaf node72927293 unset( $tax_parents[ $parent_id ][ $index ] );7294 if ( empty( $tax_parents[ $parent_id ] ) ) {7295 unset( $tax_parents[ $parent_id ] );7296 }7297 } // leaf node; no children7298 } // foreach child7299 } // foreach parent_id7300 } // has parents7301 } // foreach taxonomy73027303 // Calculate and potentially trim parent/child tree7304 $all_terms_count = 0;7305 foreach ( array_keys( $term_tree ) as $taxonomy ) {7306 if ( $include_tree ) {7307 $result = self::_find_include_tree( $term_tree[ $taxonomy ], $include_tree );7308 if ( false !== $result ) {7309 $term_tree[ $taxonomy ] = $result;7310 } else {7311 $term_tree[ $taxonomy ] = array();7312 continue;7313 }7314 } // $include_tree73157316 if ( $exclude_tree ) {7317 self::_remove_exclude_tree( $term_tree[ $taxonomy ], $exclude_tree );7318 }73197320 if ( $child_of ) {7321 $result = self::_find_child_of( $term_tree[ $taxonomy ], $child_of );73227323 if ( false !== $result ) {7324 $term_tree[ $taxonomy ] = $result->children;7325 } else {7326 $term_tree[ $taxonomy ] = array();7327 continue;7328 }7329 } // $child_of73307331 $term_count = 0;7332 $root_limit = count( $term_tree[ $taxonomy ] );73337334 if ( $root_limit ) {7335 for ( $root_index = 0; $root_index < $root_limit; $root_index++ ) {7336 if ( isset( $term_tree[ $taxonomy ][ $root_index ] ) ) {7337 $term_count++;7338 $term_tree[ $taxonomy ][ $root_index ]->level = 0;7339 if ( ! empty( $term_tree[ $taxonomy ][ $root_index ]->children ) ) {7340 $term_count += self::_count_term_children( $term_tree[ $taxonomy ][ $root_index ], $depth );7341 }7342 } else {7343 $root_limit++;7344 }7345 }7346 }73477348 // Restore original sort order7349 $term_tree[ $taxonomy ] = self::_sort_by_original_index( $term_tree[ $taxonomy ] );73507351 $term_tree[ $taxonomy ][‘found_rows’] = $term_count;7352 $all_terms_count += $term_count;7353 } // foreach taxonomy73547355 $term_tree[‘found_rows’] = $all_terms_count;7356 return $term_tree;7357 } // _get_term_tree73587359 /**7360 * Sort an array of terms (and their children) by original source order7361 *7362 * @since 2.847363 *7364 * @param array $unsorted_tree unsorted term array, by reference7365 *7366 * @return array term array sorted by original source order7367 */7368 private static function _sort_by_original_index( &$unsorted_tree ) {7369 $sorted_tree = array();73707371 foreach ( $unsorted_tree as $unsorted_term ) {7372 if ( ! empty( $unsorted_term->children ) ) {7373 $unsorted_term->children = self::_sort_by_original_index( $unsorted_term->children );7374 }73757376 $sorted_tree[ $unsorted_term->original_index ] = $unsorted_term;7377 }73787379 ksort( $sorted_tree ); 7380 return $sorted_tree;7381 } // _sort_by_original_index73827383 /**7384 * Find a term that matches $child_of7385 *7386 * @since 2.257387 *7388 * @param array $parents Potential parent Term objects, by reference7389 * @param integer $parent_id Term_id of the desired parent7390 *7391 * @return mixed Term object of the desired parent else false7392 */7393 private static function _find_child_of( &$parents, $parent_id ) {7394 foreach( $parents as $parent ) {7395 if ( $parent_id == $parent->term_id ) {7396 return $parent;7397 }73987399 $result = self::_find_child_of( $parent->children, $parent_id );7400 if ( false !== $result ) {7401 return $result;7402 }7403 }74047405 return false;7406 } // _find_child_of74077408 /**7409 * Find the term(s) that match $include_tree7410 *7411 * @since 2.257412 *7413 * @param array $terms Potential term objects, by reference7414 * @param array $include_tree term_id(s) of the desired terms7415 *7416 * @return mixed Term object(s) of the desired terms else false7417 */7418 private static function _find_include_tree( &$terms, $include_tree ) {7419 $new_tree = array();74207421 foreach( $terms as $term ) {7422 if ( in_array( $term->term_id, $include_tree ) ) {7423 $new_tree[] = $term;7424 } elseif ( ! empty( $term->children ) ) {7425 $result = self::_find_include_tree( $term->children, $include_tree );7426 if ( false !== $result ) {7427 $new_tree = array_merge( $new_tree, $result );7428 }7429 }7430 }74317432 if ( empty( $new_tree ) ) { 7433 return false;7434 }74357436 return $new_tree;7437 } // _find_include_tree74387439 /**7440 * Remove the term(s) that match $exclude_tree7441 *7442 * @since 2.257443 *7444 * @param array $terms Potential term objects, by reference7445 * @param array $exclude_tree term_id(s) of the desired terms7446 *7447 * @return void Term object(s) are removed from the &parents array7448 */7449 private static function _remove_exclude_tree( &$terms, $exclude_tree ) {7450 foreach( $terms as $index => $term ) {7451 if ( in_array( $term->term_id, $exclude_tree ) ) {7452 unset( $terms[ $index ] );7453 } elseif ( ! empty( $term->children ) ) {7454 self::_remove_exclude_tree( $term->children, $exclude_tree );7455 }7456 }7457 } // _remove_exclude_tree74587459 /**7460 * Add level to term children and count them, all levels.7461 *7462 * Recalculates term counts by including items from child terms. Assumes all7463 * relevant children are already in the $terms argument.7464 *7465 * @since 2.257466 *7467 * @param object $parent Parent Term objects, by reference7468 * @param integer $depth Maximum depth of parent/child relationship7469 *7470 * @return integer Total number of children, all levels7471 */7472 private static function _count_term_children( &$parent, $depth = 0 ) {7473 $term_count = 0;7474 $child_level = $parent->level + 1;74757476 // level is zero-based, depth is one-based7477 if ( $depth && $child_level >= $depth ) {7478 $parent->children = array();7479 return 0;7480 }74817482 $child_limit = count( $parent->children );7483 for ( $child_index = 0; $child_index < $child_limit; $child_index++ ) {7484 if ( isset( $parent->children[ $child_index ] ) ) {7485 $term_count++;7486 $parent->children[ $child_index ]->level = $child_level;7487 if ( ! empty( $parent->children[ $child_index ]->children ) ) {7488 $term_count += self::_count_term_children( $parent->children[ $child_index ], $depth );7489 }7490 } else {7491 $child_limit++;7492 }7493 }74947495 return $term_count;7496 } // _count_term_children74977498 /**7499 * Add count of children to parent count.7500 *7501 * Recalculates term counts by including items from child terms. Assumes all7502 * relevant children are already in the $terms argument.7503 *7504 * @since 2.207505 *7506 * @param array Array of Term objects, by reference7507 * @param string Term Context7508 * @param array Qualifying post type value(s)7509 * @param array Qualifying post status value(s)7510 * @param string Qualifying post MIME type clause7511 * @return null Will break from function if conditions are not met.7512 */7513 private static function _pad_term_counts( &$terms, $taxonomy, $post_types = NULL, $post_stati = NULL, $post_mimes = ‘’ ) {7514 global $wpdb;75157516 // This function only works for hierarchical taxonomies like post categories.7517 if ( !is_taxonomy_hierarchical( $taxonomy ) ) {7518 return;7519 }75207521 $terms_by_id = array(); // key term_id, value = reference to term object7522 $term_ids = array(); // key term_taxonomy_id, value = term_id7523 $term_items = array(); // key term_id, value = array( object_id => reference_count )75247525 foreach ( $terms as $key => $term ) {7526 if ( is_integer( $key ) ) {7527 $terms_by_id[ $term->term_id ] = & $terms[ $key ];7528 $term_ids[ $term->term_taxonomy_id ] = $term->term_id;7529 }7530 }75317532 if ( is_array( $post_stati ) ) {7533 $post_stati = esc_sql( $post_stati );7534 } else {7535 $post_stati = array( ‘inherit’ );7536 }75377538 if ( is_array( $post_types ) ) {7539 $post_types = esc_sql( $post_types );7540 } else {7541 $tax_obj = get_taxonomy( $taxonomy );7542 $post_types = esc_sql( $tax_obj->object_type );7543 }75447545 // Get the object and term ids and stick them in a lookup table7546 $results = $wpdb->get_results( “SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts AS p ON object_id = ID WHERE term_taxonomy_id IN (" . implode( ',’, array_keys($term_ids) ) . ") AND p.post_type IN ('” . implode( “’, ‘", $post_types ) . "’) AND p.post_status in ( '” . implode( "’, ‘", $post_stati ) . "’ )" . $post_mimes );7547 foreach ( $results as $row ) {7548 $id = $term_ids[ $row->term_taxonomy_id ];7549 $term_items[ $id ][ $row->object_id ] = isset( $term_items[ $id ][ $row->object_id ] ) ? ++$term_items[ $id ][ $row->object_id ] : 1;7550 }75517552 // Touch every ancestor’s lookup row for each post in each term7553 foreach ( $term_ids as $term_id ) {7554 $child = $term_id;7555 while ( ! empty( $terms_by_id[ $child] ) && $parent = $terms_by_id[ $child ]->parent ) {7556 if ( ! empty( $term_items[ $term_id ] ) ) {7557 foreach ( $term_items[ $term_id ] as $item_id => $touches ) {7558 $term_items[ $parent ][ $item_id ] = isset( $term_items[ $parent ][ $item_id ] ) ? ++$term_items[ $parent ][ $item_id ]: 1;7559 }7560 }75617562 $child = $parent;7563 }7564 }75657566 // Transfer the touched cells, updating $terms by reference7567 foreach ( (array) $term_items as $id => $items ) {7568 if ( isset( $terms_by_id[ $id ] ) ) {7569 $terms_by_id[ $id ]->term_count = (integer) $terms_by_id[ $id ]->count;7570 $terms_by_id[ $id ]->count = count( $items );7571 }7572 }7573 }7574} // Class MLAShortcode_Support7575?>