/**
  * Find Featured Image and inserted image/link references to an attachment
  * 
  * Called from MLAQuery::mla_fetch_attachment_references, which handles conditional
  * loading of this file.
  *
  * @since 0.1
  *
  * @param	int	post ID of attachment
  * @param	int	post ID of attachment's parent, if any
  * @param	boolean	True to compute references, false to return empty values
  *
  * @return	array	Reference information; see $references array comments
  */
 public static function mla_fetch_attachment_references_handler($ID, $parent, $add_references = true)
 {
     global $wpdb;
     static $save_id = -1, $references, $inserted_in_option = NULL;
     if ($save_id == $ID) {
         return $references;
     } elseif ($ID == -1) {
         $save_id = -1;
         return NULL;
     }
     /*
      * inserted_option	'enabled', 'base' or 'disabled'
      * tested_reference	true if any of the four where-used types was processed
      * found_reference	true if any where-used array is not empty()
      * found_parent		true if $parent matches a where-used post ID
      * is_unattached	true if $parent is zero (0)
      * base_file		relative path and name of the uploaded file, e.g., 2012/04/image.jpg
      * path				path to the file, relative to the "uploads/" directory, e.g., 2012/04/
      * file				The name portion of the base file, e.g., image.jpg
      * files			base file and any other image size files. Array key is path and file name.
      *					Non-image file value is a string containing file name without path
      *					Image file value is an array with file name, width and height
      * features			Array of objects with the post_type and post_title of each post
      *					that has the attachment as a "Featured Image"
      * inserts			Array of specific files (i.e., sizes) found in one or more posts/pages
      *					as an image (<img>) or link (<a href>). The array key is the path and file name.
      *					The array value is an array with the ID, post_type and post_title of each reference
      * mla_galleries	Array of objects with the post_type and post_title of each post
      *					that was returned by an [mla_gallery] shortcode
      * galleries		Array of objects with the post_type and post_title of each post
      *					that was returned by a [gallery] shortcode
      * parent_type		'post' or 'page' or the custom post type of the attachment's parent
      * parent_status	'publish', 'private', 'future', 'pending', 'draft'
      * parent_title		post_title of the attachment's parent
      * parent_errors	UNATTACHED, ORPHAN, BAD/INVALID PARENT
      */
     $references = array('inserted_option' => '', 'tested_reference' => false, 'found_reference' => false, 'found_parent' => false, 'is_unattached' => (int) $parent === 0, 'base_file' => '', 'path' => '', 'file' => '', 'files' => array(), 'features' => array(), 'inserts' => array(), 'mla_galleries' => array(), 'galleries' => array(), 'parent_type' => '', 'parent_status' => '', 'parent_title' => '', 'parent_errors' => '');
     if (!$add_references) {
         return $references;
     }
     /*
      * Fill in Parent data
      */
     $parent_data = MLAQuery::mla_fetch_attachment_parent_data($parent);
     if (isset($parent_data['parent_type'])) {
         $references['parent_type'] = $parent_data['parent_type'];
     }
     if (isset($parent_data['parent_status'])) {
         $references['parent_status'] = $parent_data['parent_status'];
     }
     if (isset($parent_data['parent_title'])) {
         $references['parent_title'] = $parent_data['parent_title'];
     }
     $references['base_file'] = get_post_meta($ID, '_wp_attached_file', true);
     $pathinfo = pathinfo($references['base_file']);
     $references['file'] = $pathinfo['basename'];
     if (!isset($pathinfo['dirname']) || '.' == $pathinfo['dirname']) {
         $references['path'] = '/';
     } else {
         $references['path'] = $pathinfo['dirname'] . '/';
     }
     $attachment_metadata = get_post_meta($ID, '_wp_attachment_metadata', true);
     $sizes = isset($attachment_metadata['sizes']) ? $attachment_metadata['sizes'] : NULL;
     if (is_array($sizes)) {
         // Using the name as the array key ensures each name is added only once
         foreach ($sizes as $size => $size_info) {
             $size_info['size'] = $size;
             $references['files'][$references['path'] . $size_info['file']] = $size_info;
         }
     }
     $base_type = wp_check_filetype($references['file']);
     $base_reference = array('file' => $references['file'], 'width' => isset($attachment_metadata['width']) ? $attachment_metadata['width'] : 0, 'height' => isset($attachment_metadata['height']) ? $attachment_metadata['height'] : 0, 'mime_type' => isset($base_type['type']) ? $base_type['type'] : 'unknown', 'size' => 'full');
     $references['files'][$references['base_file']] = $base_reference;
     /*
      * Process the where-used settings option
      */
     if ('checked' == MLACore::mla_get_option(MLACore::MLA_EXCLUDE_REVISIONS)) {
         $exclude_revisions = "(post_type <> 'revision') AND ";
     } else {
         $exclude_revisions = '';
     }
     /*
      * Accumulate reference test types, e.g., 0 = no tests, 4 = all tests
      */
     $reference_tests = 0;
     /*
      * Look for the "Featured Image(s)", if enabled
      */
     if (MLACore::$process_featured_in) {
         $reference_tests++;
         $features = $wpdb->get_results("\r\n\t\t\t\t\tSELECT post_id\r\n\t\t\t\t\tFROM {$wpdb->postmeta}\r\n\t\t\t\t\tWHERE meta_key = '_thumbnail_id' AND meta_value = {$ID}\r\n\t\t\t\t\t");
         if (!empty($features)) {
             foreach ($features as $feature) {
                 $feature_results = $wpdb->get_results("\r\n\t\t\t\t\t\t\tSELECT ID, post_type, post_status, post_title\r\n\t\t\t\t\t\t\tFROM {$wpdb->posts}\r\n\t\t\t\t\t\t\tWHERE {$exclude_revisions}(ID = {$feature->post_id})\r\n\t\t\t\t\t\t\t");
                 if (!empty($feature_results)) {
                     $references['found_reference'] = true;
                     $references['features'][$feature->post_id] = $feature_results[0];
                     if ($feature->post_id == $parent) {
                         $references['found_parent'] = true;
                     }
                 }
                 // ! empty
             }
             // foreach $feature
         }
     }
     // $process_featured_in
     /*
      * Look for item(s) inserted in post_content
      */
     $references['inserted_option'] = $inserted_in_option;
     if (MLACore::$process_inserted_in) {
         $reference_tests++;
         if (NULL == $inserted_in_option) {
             $inserted_in_option = MLACore::mla_get_option(MLACore::MLA_INSERTED_IN_TUNING);
             $references['inserted_option'] = $inserted_in_option;
         }
         if ('base' == $inserted_in_option) {
             $query_parameters = array();
             $query = array();
             $query[] = "SELECT ID, post_type, post_status, post_title, CONVERT(`post_content` USING utf8 ) AS POST_CONTENT FROM {$wpdb->posts} WHERE {$exclude_revisions} ( %s=%s";
             $query_parameters[] = '1';
             // for empty file name array
             $query_parameters[] = '0';
             // for empty file name array
             foreach ($references['files'] as $file => $file_data) {
                 if (empty($file)) {
                     continue;
                 }
                 $query[] = 'OR ( POST_CONTENT LIKE %s)';
                 if (MLAQuery::$wp_4dot0_plus) {
                     $query_parameters[] = '%' . $wpdb->esc_like($file) . '%';
                 } else {
                     $query_parameters[] = '%' . like_escape($file) . '%';
                 }
             }
             $query[] = ')';
             $query = join(' ', $query);
             $inserts = $wpdb->get_results($wpdb->prepare($query, $query_parameters));
             if (!empty($inserts)) {
                 $references['found_reference'] = true;
                 $references['inserts'][$pathinfo['filename']] = $inserts;
                 foreach ($inserts as $index => $insert) {
                     unset($references['inserts'][$pathinfo['filename']][$index]->POST_CONTENT);
                     if ($insert->ID == $parent) {
                         $references['found_parent'] = true;
                     }
                 }
                 // foreach $insert
             }
             // ! empty
         } else {
             // process base names
             foreach ($references['files'] as $file => $file_data) {
                 if (empty($file)) {
                     continue;
                 }
                 if (MLAQuery::$wp_4dot0_plus) {
                     $like = $wpdb->esc_like($file);
                 } else {
                     $like = like_escape($file);
                 }
                 $inserts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_type, post_status, post_title FROM {$wpdb->posts}\r\n\t\t\t\t\t\t\tWHERE {$exclude_revisions}(CONVERT(`post_content` USING utf8 ) LIKE %s)", "%{$like}%"));
                 if (!empty($inserts)) {
                     $references['found_reference'] = true;
                     $references['inserts'][$file_data['file']] = $inserts;
                     foreach ($inserts as $insert) {
                         if ($insert->ID == $parent) {
                             $references['found_parent'] = true;
                         }
                     }
                     // foreach $insert
                 }
                 // ! empty
             }
             // foreach $file
         }
         // process intermediate sizes
     }
     // $process_inserted_in
     /*
      * Look for [mla_gallery] references
      */
     if (MLACore::$process_mla_gallery_in) {
         $reference_tests++;
         if (self::_build_mla_galleries(MLACore::MLA_MLA_GALLERY_IN_TUNING, self::$mla_galleries, '[mla_gallery', $exclude_revisions)) {
             $galleries = self::_search_mla_galleries(self::$mla_galleries, $ID);
             if (!empty($galleries)) {
                 $references['found_reference'] = true;
                 $references['mla_galleries'] = $galleries;
                 foreach ($galleries as $post_id => $gallery) {
                     if ($post_id == $parent) {
                         $references['found_parent'] = true;
                     }
                 }
                 // foreach $gallery
             } else {
                 // ! empty
                 $references['mla_galleries'] = array();
             }
         }
     }
     // $process_mla_gallery_in
     /*
      * Look for [gallery] references
      */
     if (MLACore::$process_gallery_in) {
         $reference_tests++;
         if (self::_build_mla_galleries(MLACore::MLA_GALLERY_IN_TUNING, self::$galleries, '[gallery', $exclude_revisions)) {
             $galleries = self::_search_mla_galleries(self::$galleries, $ID);
             if (!empty($galleries)) {
                 $references['found_reference'] = true;
                 $references['galleries'] = $galleries;
                 foreach ($galleries as $post_id => $gallery) {
                     if ($post_id == $parent) {
                         $references['found_parent'] = true;
                     }
                 }
                 // foreach $gallery
             } else {
                 // ! empty
                 $references['galleries'] = array();
             }
         }
     }
     // $process_gallery_in
     /*
      * Evaluate and summarize reference tests
      */
     $errors = '';
     if (0 == $reference_tests) {
         $references['tested_reference'] = false;
         $errors .= '(' . __('NO REFERENCE TESTS', 'media-library-assistant') . ')';
     } else {
         $references['tested_reference'] = true;
         $suffix = 4 == $reference_tests ? '' : '?';
         if (!$references['found_reference']) {
             $errors .= '(' . sprintf(__('ORPHAN', 'media-library-assistant') . '%1$s) ', $suffix);
         }
         if (!$references['found_parent'] && !empty($references['parent_title'])) {
             $errors .= '(' . sprintf(__('UNUSED', 'media-library-assistant') . '%1$s) ', $suffix);
         }
     }
     if ($references['is_unattached']) {
         $errors .= '(' . __('UNATTACHED', 'media-library-assistant') . ')';
     } elseif (empty($references['parent_title'])) {
         $errors .= '(' . __('INVALID PARENT', 'media-library-assistant') . ')';
     }
     $references['parent_errors'] = trim($errors);
     $save_id = $ID;
     $references = apply_filters('mla_fetch_attachment_references', $references, $ID, $parent);
     return $references;
 }
 /**
  * The MLA Gallery shortcode.
  *
  * This is a superset of the WordPress Gallery shortcode for displaying images on a post,
  * page or custom post type. It is adapted from /wp-includes/media.php gallery_shortcode.
  * Enhancements include many additional selection parameters and full taxonomy support.
  *
  * @since 2.20
  *
  * @param array Attributes of the shortcode
  * @param string Optional content for enclosing shortcodes; used with mla_alt_shortcode
  *
  * @return string HTML content to display gallery.
  */
 public static function mla_gallery_shortcode($attr, $content = NULL)
 {
     global $post;
     /*
      * Some do_shortcode callers may not have a specific post in mind
      */
     if (!is_object($post)) {
         $post = (object) array('ID' => 0);
     }
     /*
      * Make sure $attr is an array, even if it's empty,
      * and repair damage caused by link-breaks in the source text
      */
     $attr = self::_validate_attributes($attr);
     /*
      * Filter the attributes before $mla_page_parameter and "request:" prefix processing.
      */
     $attr = apply_filters('mla_gallery_raw_attributes', $attr);
     /*
      * The mla_paginate_current parameter can be changed to support multiple galleries per page.
      */
     if (!isset($attr['mla_page_parameter'])) {
         $attr['mla_page_parameter'] = self::$mla_get_shortcode_attachments_parameters['mla_page_parameter'];
     }
     $mla_page_parameter = $attr['mla_page_parameter'];
     /*
      * Special handling of the mla_paginate_current parameter to make
      * "MLA pagination" easier. Look for this parameter in $_REQUEST
      * if it's not present in the shortcode itself.
      */
     if (!isset($attr[$mla_page_parameter])) {
         if (isset($_REQUEST[$mla_page_parameter])) {
             $attr[$mla_page_parameter] = $_REQUEST[$mla_page_parameter];
         }
     }
     /*
      * These are the parameters for gallery display
      */
     $mla_item_specific_arguments = array('mla_link_attributes' => '', 'mla_link_class' => '', 'mla_link_href' => '', 'mla_link_text' => '', 'mla_nolink_text' => '', 'mla_rollover_text' => '', 'mla_image_class' => '', 'mla_image_alt' => '', 'mla_image_attributes' => '', 'mla_caption' => '');
     $mla_arguments = array_merge(array('mla_output' => 'gallery', 'mla_style' => MLACore::mla_get_option('default_style'), 'mla_markup' => MLACore::mla_get_option('default_markup'), 'mla_float' => is_rtl() ? 'right' : 'left', 'mla_itemwidth' => MLACore::mla_get_option('mla_gallery_itemwidth'), 'mla_margin' => MLACore::mla_get_option('mla_gallery_margin'), 'mla_target' => '', 'mla_debug' => false, 'mla_viewer' => false, 'mla_single_thread' => false, 'mla_viewer_extensions' => 'ai,eps,pdf,ps', 'mla_viewer_limit' => '0', 'mla_viewer_width' => '0', 'mla_viewer_height' => '0', 'mla_viewer_best_fit' => NULL, 'mla_viewer_page' => '1', 'mla_viewer_resolution' => '0', 'mla_viewer_quality' => '0', 'mla_viewer_type' => '', 'mla_alt_shortcode' => NULL, 'mla_alt_ids_name' => 'ids', 'mla_end_size' => 1, 'mla_mid_size' => 2, 'mla_prev_text' => '&laquo; ' . __('Previous', 'media-library-assistant'), 'mla_next_text' => __('Next', 'media-library-assistant') . ' &raquo;', 'mla_paginate_type' => 'plain', 'mla_paginate_rows' => NULL), $mla_item_specific_arguments);
     $html5 = current_theme_supports('html5', 'gallery');
     $default_arguments = array_merge(array('size' => 'thumbnail', 'itemtag' => $html5 ? 'figure' : 'dl', 'icontag' => $html5 ? 'div' : 'dt', 'captiontag' => $html5 ? 'figcaption' : 'dd', 'columns' => MLACore::mla_get_option('mla_gallery_columns'), 'link' => 'permalink', 'id' => NULL, 'style' => NULL, 'type' => 'default', 'thumb_width' => 75, 'thumb_height' => 75, 'thumbnail_size' => 'thumbnail', 'slide_size' => 'large', 'slideshow_height' => 500, 'fx' => 'fade', 'timeout' => 4000, 'speed' => 1000, 'pause' => NULL), $mla_arguments);
     // $instance supports multiple galleries in one page/post
     static $instance = 0;
     $instance++;
     /*
      * Some values are already known, and can be used in data selection parameters
      */
     $upload_dir = wp_upload_dir();
     $page_values = array('instance' => $instance, 'selector' => "mla_gallery-{$instance}", 'site_url' => site_url(), 'base_url' => $upload_dir['baseurl'], 'base_dir' => $upload_dir['basedir'], 'id' => $post->ID, 'page_ID' => $post->ID, 'page_author' => $post->post_author, 'page_date' => $post->post_date, 'page_content' => $post->post_content, 'page_title' => $post->post_title, 'page_excerpt' => $post->post_excerpt, 'page_status' => $post->post_status, 'page_name' => $post->post_name, 'page_modified' => $post->post_modified, 'page_guid' => $post->guid, 'page_type' => $post->post_type, 'page_url' => get_page_link());
     /*
      * Look for page-level and 'request:' substitution parameters,
      * which can be added to any input parameter
      */
     foreach ($attr as $attr_key => $attr_value) {
         /*
          * attachment-specific Gallery Display Content parameters must be evaluated
          * later, when all of the information is available.
          */
         if (array_key_exists($attr_key, $mla_item_specific_arguments)) {
             continue;
         }
         $attr_value = str_replace('{+', '[+', str_replace('+}', '+]', $attr_value));
         $replacement_values = MLAData::mla_expand_field_level_parameters($attr_value, NULL, $page_values);
         $attr[$attr_key] = MLAData::mla_parse_template($attr_value, $replacement_values);
     }
     /*
      * Merge gallery arguments with defaults, pass the query arguments on to mla_get_shortcode_attachments.
      */
     $attr = apply_filters('mla_gallery_attributes', $attr);
     $content = apply_filters('mla_gallery_initial_content', $content, $attr);
     $arguments = shortcode_atts($default_arguments, $attr);
     $arguments = apply_filters('mla_gallery_arguments', $arguments);
     self::$mla_debug = !empty($arguments['mla_debug']) ? trim(strtolower($arguments['mla_debug'])) : false;
     if (self::$mla_debug) {
         if ('true' == self::$mla_debug) {
             MLACore::mla_debug_mode('buffer');
         } elseif ('log' == self::$mla_debug) {
             MLACore::mla_debug_mode('log');
         } else {
             self::$mla_debug = false;
         }
     }
     /*
      * Determine output type
      */
     $output_parameters = array_map('strtolower', array_map('trim', explode(',', $arguments['mla_output'])));
     $is_gallery = 'gallery' == $output_parameters[0];
     $is_pagination = in_array($output_parameters[0], array('previous_page', 'next_page', 'paginate_links'));
     if ($is_pagination && NULL !== $arguments['mla_paginate_rows']) {
         $attachments['found_rows'] = absint($arguments['mla_paginate_rows']);
     } else {
         $attachments = self::mla_get_shortcode_attachments($post->ID, $attr, $is_pagination);
     }
     if (is_string($attachments)) {
         return $attachments;
     }
     if (empty($attachments)) {
         if (self::$mla_debug) {
             MLACore::mla_debug_add('<strong>' . __('mla_debug empty gallery', 'media-library-assistant') . '</strong>, query = ' . var_export($attr, true));
             $output = MLACore::mla_debug_flush();
         } else {
             $output = '';
         }
         $output .= $arguments['mla_nolink_text'];
         return $output;
     }
     // empty $attachments
     /*
      * Look for user-specified alternate gallery shortcode
      */
     if (is_string($arguments['mla_alt_shortcode'])) {
         /*
          * Replace data-selection parameters with the "ids" list
          */
         if ('mla_tag_cloud' == $arguments['mla_alt_shortcode']) {
             $blacklist = self::$mla_get_shortcode_attachments_parameters;
         } else {
             $blacklist = array_merge($mla_arguments, self::$mla_get_shortcode_attachments_parameters);
         }
         $new_args = '';
         foreach ($attr as $key => $value) {
             if (array_key_exists($key, $blacklist)) {
                 continue;
             }
             $slashed = addcslashes($value, chr(0) . chr(7) . chr(8) . "\f\n\r\t\v\"\\\$");
             if (false !== strpos($value, ' ') || false !== strpos($value, '\'') || $slashed != $value) {
                 $value = '"' . $slashed . '"';
             }
             $new_args .= empty($new_args) ? $key . '=' . $value : ' ' . $key . '=' . $value;
         }
         // foreach $attr
         $new_ids = '';
         foreach ($attachments as $value) {
             $new_ids .= empty($new_ids) ? (string) $value->ID : ',' . $value->ID;
         }
         // foreach $attachments
         $new_ids = $arguments['mla_alt_ids_name'] . '="' . $new_ids . '"';
         if (self::$mla_debug) {
             $output = MLACore::mla_debug_flush();
         } else {
             $output = '';
         }
         /*
          * Execute the alternate gallery shortcode with the new parameters
          */
         $content = apply_filters('mla_gallery_final_content', $content);
         if (!empty($content)) {
             return $output . do_shortcode(sprintf('[%1$s %2$s %3$s]%4$s[/%5$s]', $arguments['mla_alt_shortcode'], $new_ids, $new_args, $content, $arguments['mla_alt_shortcode']));
         } else {
             return $output . do_shortcode(sprintf('[%1$s %2$s %3$s]', $arguments['mla_alt_shortcode'], $new_ids, $new_args));
         }
     }
     // mla_alt_shortcode
     /*
      * Look for Photonic-enhanced gallery
      */
     global $photonic;
     if (is_object($photonic) && !empty($arguments['style'])) {
         if ('default' != strtolower($arguments['type'])) {
             return '<p>' . __('<strong>Photonic-enhanced [mla_gallery]</strong> type must be <strong>default</strong>, query = ', 'media-library-assistant') . var_export($attr, true) . '</p>';
         }
         $images = array();
         foreach ($attachments as $key => $val) {
             $images[$val->ID] = $attachments[$key];
         }
         if (isset($arguments['pause']) && 'false' == $arguments['pause']) {
             $arguments['pause'] = NULL;
         }
         $output = $photonic->build_gallery($images, $arguments['style'], $arguments);
         return $output;
     }
     $size = $size_class = $arguments['size'];
     if ('icon' == strtolower($size)) {
         if ('checked' == MLACore::mla_get_option(MLACore::MLA_ENABLE_MLA_ICONS)) {
             $size = array(64, 64);
         } else {
             $size = array(60, 60);
         }
         $show_icon = true;
     } else {
         $show_icon = false;
     }
     /*
      * Feeds such as RSS, Atom or RDF do not require styled and formatted output
      */
     if (is_feed()) {
         $output = "\n";
         foreach ($attachments as $att_id => $attachment) {
             $output .= wp_get_attachment_link($att_id, $size, true) . "\n";
         }
         return $output;
     }
     /*
      * Check for Imagick thumbnail generation arguments
      */
     if ('checked' == MLACore::mla_get_option('enable_mla_viewer')) {
         if (!empty($arguments['mla_viewer']) && 'single' == strtolower($arguments['mla_viewer'])) {
             $arguments['mla_single_thread'] = true;
             $arguments['mla_viewer'] = 'true';
         }
         $arguments['mla_viewer'] = !empty($arguments['mla_viewer']) && 'true' == strtolower($arguments['mla_viewer']);
     } else {
         $arguments['mla_viewer'] = false;
     }
     if ($arguments['mla_viewer']) {
         /*
          * Test for Ghostscript here so debug messages can be recorded
          */
         $ghostscript_path = MLACore::mla_get_option('ghostscript_path');
         if (self::mla_ghostscript_present($ghostscript_path)) {
             $arguments['mla_viewer_extensions'] = array_filter(array_map('trim', explode(',', $arguments['mla_viewer_extensions'])));
         } else {
             $arguments['mla_viewer_extensions'] = array();
         }
         // convert limit (in MB) to float
         $arguments['mla_viewer_limit'] = abs(0.0 + $arguments['mla_viewer_limit']);
         $arguments['mla_viewer_width'] = absint($arguments['mla_viewer_width']);
         $arguments['mla_viewer_height'] = absint($arguments['mla_viewer_height']);
         $arguments['mla_viewer_page'] = absint($arguments['mla_viewer_page']);
         if (isset($arguments['mla_viewer_best_fit'])) {
             $arguments['mla_viewer_best_fit'] = 'true' == strtolower($arguments['mla_viewer_best_fit']);
         }
         $arguments['mla_viewer_resolution'] = absint($arguments['mla_viewer_resolution']);
         $arguments['mla_viewer_quality'] = absint($arguments['mla_viewer_quality']);
     }
     /*
      * The default MLA style template includes "margin: 1.5%" to put a bit of
      * minimum space between the columns. "mla_margin" can be used to change
      * this. "mla_itemwidth" can be used with "columns=0" to achieve a "responsive"
      * layout.
      */
     $columns = absint($arguments['columns']);
     $margin_string = strtolower(trim($arguments['mla_margin']));
     if (is_numeric($margin_string) && 0 != $margin_string) {
         $margin_string .= '%';
         // Legacy values are always in percent
     }
     if ('%' == substr($margin_string, -1)) {
         $margin_percent = (double) substr($margin_string, 0, strlen($margin_string) - 1);
     } else {
         $margin_percent = 0;
     }
     $width_string = strtolower(trim($arguments['mla_itemwidth']));
     if ('none' != $width_string) {
         switch ($width_string) {
             case 'exact':
                 $margin_percent = 0;
                 // fallthru
             // fallthru
             case 'calculate':
                 $width_string = $columns > 0 ? floor(1000 / $columns) / 10 - 2.0 * $margin_percent : 100 - 2.0 * $margin_percent;
                 // fallthru
             // fallthru
             default:
                 if (is_numeric($width_string) && 0 != $width_string) {
                     $width_string .= '%';
                     // Legacy values are always in percent
                 }
         }
     }
     // $use_width
     $float = strtolower($arguments['mla_float']);
     if (!in_array($float, array('left', 'none', 'right'))) {
         $float = is_rtl() ? 'right' : 'left';
     }
     $style_values = array_merge($page_values, array('mla_style' => $arguments['mla_style'], 'mla_markup' => $arguments['mla_markup'], 'itemtag' => tag_escape($arguments['itemtag']), 'icontag' => tag_escape($arguments['icontag']), 'captiontag' => tag_escape($arguments['captiontag']), 'columns' => $columns, 'itemwidth' => $width_string, 'margin' => $margin_string, 'float' => $float, 'size_class' => sanitize_html_class($size_class)));
     $style_template = $gallery_style = '';
     if ('theme' == strtolower($style_values['mla_style'])) {
         $use_mla_gallery_style = apply_filters('use_default_gallery_style', !$html5);
     } else {
         $use_mla_gallery_style = 'none' != strtolower($style_values['mla_style']);
     }
     if (apply_filters('use_mla_gallery_style', $use_mla_gallery_style, $style_values['mla_style'])) {
         $style_template = MLAShortcode_support::mla_fetch_gallery_template($style_values['mla_style'], 'style');
         if (empty($style_template)) {
             $style_values['mla_style'] = $default_arguments['mla_style'];
             $style_template = MLAShortcode_support::mla_fetch_gallery_template($style_values['mla_style'], 'style');
             if (empty($style_template)) {
                 $style_values['mla_style'] = 'default';
                 $style_template = MLAShortcode_support::mla_fetch_gallery_template('default', 'style');
             }
         }
         if (!empty($style_template)) {
             /*
              * Look for 'query' and 'request' substitution parameters
              */
             $style_values = MLAData::mla_expand_field_level_parameters($style_template, $attr, $style_values);
             /*
              * Clean up the template to resolve width or margin == 'none'
              */
             if ('none' == $margin_string) {
                 $style_values['margin'] = '0';
                 $style_template = preg_replace('/margin:[\\s]*\\[\\+margin\\+\\][\\%]*[\\;]*/', '', $style_template);
             }
             if ('none' == $width_string) {
                 $style_values['itemwidth'] = 'auto';
                 $style_template = preg_replace('/width:[\\s]*\\[\\+itemwidth\\+\\][\\%]*[\\;]*/', '', $style_template);
             }
             $style_values = apply_filters('mla_gallery_style_values', $style_values);
             $style_template = apply_filters('mla_gallery_style_template', $style_template);
             $gallery_style = MLAData::mla_parse_template($style_template, $style_values);
             $gallery_style = apply_filters('mla_gallery_style_parse', $gallery_style, $style_template, $style_values);
             /*
              * Clean up the styles to resolve extra "%" suffixes on width or margin (pre v1.42 values)
              */
             $preg_pattern = array('/([margin|width]:[^\\%]*)\\%\\%/', '/([margin|width]:.*)auto\\%/', '/([margin|width]:.*)inherit\\%/');
             $preg_replacement = array('${1}%', '${1}auto', '${1}inherit');
             $gallery_style = preg_replace($preg_pattern, $preg_replacement, $gallery_style);
         }
         // !empty template
     }
     // use_mla_gallery_style
     $markup_values = $style_values;
     $open_template = MLAShortcode_support::mla_fetch_gallery_template($markup_values['mla_markup'] . '-open', 'markup');
     if (false === $open_template) {
         $markup_values['mla_markup'] = $default_arguments['mla_markup'];
         $open_template = MLAShortcode_support::mla_fetch_gallery_template($markup_values['mla_markup'] . '-open', 'markup');
         if (false === $open_template) {
             $markup_values['mla_markup'] = 'default';
             $open_template = MLAShortcode_support::mla_fetch_gallery_template($markup_values['mla_markup'] . '-open', 'markup');
         }
     }
     if (empty($open_template)) {
         $open_template = '';
     }
     /*
      * Emulate [gallery] handling of row open markup for the default template only
      */
     if ($html5 && 'default' == $markup_values['mla_markup']) {
         $row_open_template = '';
     } else {
         $row_open_template = MLAShortcode_support::mla_fetch_gallery_template($markup_values['mla_markup'] . '-row-open', 'markup');
         if (empty($row_open_template)) {
             $row_open_template = '';
         }
     }
     $item_template = MLAShortcode_support::mla_fetch_gallery_template($markup_values['mla_markup'] . '-item', 'markup');
     if (empty($item_template)) {
         $item_template = '';
     }
     /*
      * Emulate [gallery] handling of row close markup for the default template only
      */
     if ($html5 && 'default' == $markup_values['mla_markup']) {
         $row_close_template = '';
     } else {
         $row_close_template = MLAShortcode_support::mla_fetch_gallery_template($markup_values['mla_markup'] . '-row-close', 'markup');
         if (empty($row_close_template)) {
             $row_close_template = '';
         }
     }
     $close_template = MLAShortcode_support::mla_fetch_gallery_template($markup_values['mla_markup'] . '-close', 'markup');
     if (empty($close_template)) {
         $close_template = '';
     }
     /*
      * Look for gallery-level markup substitution parameters
      */
     $new_text = $open_template . $row_open_template . $row_close_template . $close_template;
     $markup_values = MLAData::mla_expand_field_level_parameters($new_text, $attr, $markup_values);
     if (self::$mla_debug) {
         $output = MLACore::mla_debug_flush();
     } else {
         $output = '';
     }
     if ($is_gallery) {
         $markup_values = apply_filters('mla_gallery_open_values', $markup_values);
         $open_template = apply_filters('mla_gallery_open_template', $open_template);
         if (empty($open_template)) {
             $gallery_open = '';
         } else {
             $gallery_open = MLAData::mla_parse_template($open_template, $markup_values);
         }
         $gallery_open = apply_filters('mla_gallery_open_parse', $gallery_open, $open_template, $markup_values);
         $output .= apply_filters('mla_gallery_style', $gallery_style . $gallery_open, $style_values, $markup_values, $style_template, $open_template);
     } else {
         if (!isset($attachments['found_rows'])) {
             $attachments['found_rows'] = 0;
         }
         /*
          * Handle 'previous_page', 'next_page', and 'paginate_links'
          */
         $pagination_result = self::_process_pagination_output_types($output_parameters, $markup_values, $arguments, $attr, $attachments['found_rows'], $output);
         if (false !== $pagination_result) {
             return $pagination_result;
         }
         unset($attachments['found_rows']);
     }
     /*
      * For "previous_link", "current_link" and "next_link",
      * discard all of the $attachments except the appropriate choice
      */
     if (!$is_gallery) {
         $link_type = $output_parameters[0];
         if (!in_array($link_type, array('previous_link', 'current_link', 'next_link'))) {
             return '';
             // unknown output type
         }
         $is_wrap = isset($output_parameters[1]) && 'wrap' == $output_parameters[1];
         $current_id = empty($arguments['id']) ? $markup_values['id'] : $arguments['id'];
         foreach ($attachments as $id => $attachment) {
             if ($attachment->ID == $current_id) {
                 break;
             }
         }
         switch ($link_type) {
             case 'previous_link':
                 $target_id = $id - 1;
                 break;
             case 'next_link':
                 $target_id = $id + 1;
                 break;
             case 'current_link':
             default:
                 $target_id = $id;
         }
         // link_type
         $target = NULL;
         if (isset($attachments[$target_id])) {
             $target = $attachments[$target_id];
         } elseif ($is_wrap) {
             switch ($link_type) {
                 case 'previous_link':
                     $target = array_pop($attachments);
                     break;
                 case 'next_link':
                     $target = array_shift($attachments);
             }
             // link_type
         }
         // is_wrap
         if (isset($target)) {
             $attachments = array($target);
         } elseif (!empty($arguments['mla_nolink_text'])) {
             return self::_process_shortcode_parameter($arguments['mla_nolink_text'], $markup_values) . '</a>';
         } else {
             return '';
         }
     } else {
         // ! is_gallery
         $link_type = '';
     }
     $column_index = 0;
     foreach ($attachments as $id => $attachment) {
         $item_values = $markup_values;
         /*
          * fill in item-specific elements
          */
         $item_values['index'] = (string) 1 + $column_index;
         $item_values['excerpt'] = wptexturize($attachment->post_excerpt);
         $item_values['attachment_ID'] = $attachment->ID;
         $item_values['mime_type'] = $attachment->post_mime_type;
         $item_values['menu_order'] = $attachment->menu_order;
         $item_values['date'] = $attachment->post_date;
         $item_values['modified'] = $attachment->post_modified;
         $item_values['parent'] = $attachment->post_parent;
         $item_values['parent_name'] = '';
         $item_values['parent_type'] = '';
         $item_values['parent_title'] = '(' . __('Unattached', 'media-library-assistant') . ')';
         $item_values['parent_date'] = '';
         $item_values['parent_permalink'] = '';
         $item_values['title'] = wptexturize($attachment->post_title);
         $item_values['slug'] = wptexturize($attachment->post_name);
         $item_values['width'] = '';
         $item_values['height'] = '';
         $item_values['orientation'] = '';
         $item_values['image_meta'] = '';
         $item_values['image_alt'] = '';
         $item_values['base_file'] = '';
         $item_values['path'] = '';
         $item_values['file'] = '';
         $item_values['description'] = wptexturize($attachment->post_content);
         $item_values['file_url'] = wptexturize($attachment->guid);
         $item_values['author_id'] = $attachment->post_author;
         $item_values['caption'] = '';
         $item_values['captiontag_content'] = '';
         $user = get_user_by('id', $attachment->post_author);
         if (isset($user->data->display_name)) {
             $item_values['author'] = wptexturize($user->data->display_name);
         } else {
             $item_values['author'] = __('unknown', 'media-library-assistant');
         }
         $post_meta = MLAQuery::mla_fetch_attachment_metadata($attachment->ID);
         $base_file = $post_meta['mla_wp_attached_file'];
         $sizes = isset($post_meta['mla_wp_attachment_metadata']['sizes']) ? $post_meta['mla_wp_attachment_metadata']['sizes'] : array();
         if (!empty($post_meta['mla_wp_attachment_metadata']['width'])) {
             $item_values['width'] = $post_meta['mla_wp_attachment_metadata']['width'];
             $width = absint($item_values['width']);
         } else {
             $width = 0;
         }
         if (!empty($post_meta['mla_wp_attachment_metadata']['height'])) {
             $item_values['height'] = $post_meta['mla_wp_attachment_metadata']['height'];
             $height = absint($item_values['height']);
         } else {
             $height = 0;
         }
         if ($width && $height) {
             $item_values['orientation'] = $height > $width ? 'portrait' : 'landscape';
         }
         if (!empty($post_meta['mla_wp_attachment_metadata']['image_meta'])) {
             $item_values['image_meta'] = wptexturize(var_export($post_meta['mla_wp_attachment_metadata']['image_meta'], true));
         }
         if (!empty($post_meta['mla_wp_attachment_image_alt'])) {
             if (is_array($post_meta['mla_wp_attachment_image_alt'])) {
                 $item_values['image_alt'] = wptexturize($post_meta['mla_wp_attachment_image_alt'][0]);
             } else {
                 $item_values['image_alt'] = wptexturize($post_meta['mla_wp_attachment_image_alt']);
             }
         }
         if (!empty($base_file)) {
             $last_slash = strrpos($base_file, '/');
             if (false === $last_slash) {
                 $file_name = $base_file;
                 $item_values['base_file'] = wptexturize($base_file);
                 $item_values['file'] = wptexturize($base_file);
             } else {
                 $file_name = substr($base_file, $last_slash + 1);
                 $item_values['base_file'] = wptexturize($base_file);
                 $item_values['path'] = wptexturize(substr($base_file, 0, $last_slash + 1));
                 $item_values['file'] = wptexturize($file_name);
             }
         } else {
             $file_name = '';
         }
         if (0 < $attachment->post_parent) {
             $parent_info = MLAQuery::mla_fetch_attachment_parent_data($attachment->post_parent);
             if (isset($parent_info['parent_name'])) {
                 $item_values['parent_name'] = $parent_info['parent_name'];
             }
             if (isset($parent_info['parent_type'])) {
                 $item_values['parent_type'] = wptexturize($parent_info['parent_type']);
             }
             if (isset($parent_info['parent_title'])) {
                 $item_values['parent_title'] = wptexturize($parent_info['parent_title']);
             }
             if (isset($parent_info['parent_date'])) {
                 $item_values['parent_date'] = wptexturize($parent_info['parent_date']);
             }
             $permalink = get_permalink($attachment->post_parent);
             if (false !== $permalink) {
                 $item_values['parent_permalink'] = $permalink;
             }
         }
         // has parent
         /*
          * Add attachment-specific field-level substitution parameters
          */
         $new_text = isset($item_template) ? $item_template : '';
         foreach ($mla_item_specific_arguments as $index => $value) {
             $new_text .= str_replace('{+', '[+', str_replace('+}', '+]', $arguments[$index]));
         }
         $item_values = MLAData::mla_expand_field_level_parameters($new_text, $attr, $item_values, $attachment->ID);
         if ($item_values['captiontag']) {
             $item_values['caption'] = wptexturize($attachment->post_excerpt);
             if (!empty($arguments['mla_caption'])) {
                 $item_values['caption'] = wptexturize(self::_process_shortcode_parameter($arguments['mla_caption'], $item_values));
             }
         } else {
             $item_values['caption'] = '';
         }
         if (!empty($arguments['mla_link_text'])) {
             $link_text = self::_process_shortcode_parameter($arguments['mla_link_text'], $item_values);
         } else {
             $link_text = false;
         }
         /*
          * As of WP 3.7, this function returns "<a href='$url'>$link_text</a>", where
          * $link_text can be an image thumbnail or a text link. The "title=" attribute
          * was dropped. The function is defined in /wp-includes/post-template.php.
          *
          * As of WP 4.1, this function has an additional optional parameter, an "Array or
          * string of attributes", used in the [gallery] shortcode to tie the link to a
          * caption with 'aria-describedby'. The caption has a matching 'id' attribute
          * "$selector-#id". See below for the MLA equivalent processing.
          */
         $item_values['pagelink'] = wp_get_attachment_link($attachment->ID, $size, true, $show_icon, $link_text);
         $item_values['filelink'] = wp_get_attachment_link($attachment->ID, $size, false, $show_icon, $link_text);
         if (in_array($attachment->post_mime_type, array('image/svg+xml'))) {
             $registered_dimensions = self::_registered_dimensions();
             if (isset($registered_dimensions[$size_class])) {
                 $dimensions = $registered_dimensions[$size_class];
             } else {
                 $dimensions = $registered_dimensions['thumbnail'];
             }
             $thumb = preg_replace('/width=\\"[^\\"]*\\"/', sprintf('width="%1$d"', $dimensions[1]), $item_values['pagelink']);
             $item_values['pagelink'] = preg_replace('/height=\\"[^\\"]*\\"/', sprintf('height="%1$d"', $dimensions[0]), $thumb);
             $thumb = preg_replace('/width=\\"[^\\"]*\\"/', sprintf('width="%1$d"', $dimensions[1]), $item_values['filelink']);
             $item_values['filelink'] = preg_replace('/height=\\"[^\\"]*\\"/', sprintf('height="%1$d"', $dimensions[0]), $thumb);
         }
         // SVG thumbnail
         /*
          * Apply the Gallery Display Content parameters.
          * Note that $link_attributes and $rollover_text
          * are used in the Google Viewer code below
          */
         $link_attributes = '';
         if (!empty($arguments['mla_rollover_text'])) {
             $rollover_text = esc_attr(self::_process_shortcode_parameter($arguments['mla_rollover_text'], $item_values));
             /*
              * The "title=" attribute was removed in WP 3.7+, but look for it anyway.
              * If it's not there, add the "title=" value to the link attributes.
              */
             if (false === strpos($item_values['pagelink'], ' title=')) {
                 $link_attributes .= 'title="' . $rollover_text . '" ';
             } else {
                 /*
                  * Replace single- and double-quote delimited values
                  */
                 $item_values['pagelink'] = preg_replace('# title=\'([^\']*)\'#', " title='{$rollover_text}'", $item_values['pagelink']);
                 $item_values['pagelink'] = preg_replace('# title=\\"([^\\"]*)\\"#', " title=\"{$rollover_text}\"", $item_values['pagelink']);
                 $item_values['filelink'] = preg_replace('# title=\'([^\']*)\'#', " title='{$rollover_text}'", $item_values['filelink']);
                 $item_values['filelink'] = preg_replace('# title=\\"([^\\"]*)\\"#', " title=\"{$rollover_text}\"", $item_values['filelink']);
             }
         } else {
             $rollover_text = esc_attr($item_values['title']);
         }
         if (!empty($arguments['mla_target'])) {
             $link_attributes .= 'target="' . $arguments['mla_target'] . '" ';
         }
         if (!empty($arguments['mla_link_attributes'])) {
             $link_attributes .= self::_process_shortcode_parameter($arguments['mla_link_attributes'], $item_values) . ' ';
         }
         if (!empty($arguments['mla_link_class'])) {
             $link_attributes .= 'class="' . self::_process_shortcode_parameter($arguments['mla_link_class'], $item_values) . '" ';
         }
         if (!empty($link_attributes)) {
             $item_values['pagelink'] = str_replace('<a href=', '<a ' . $link_attributes . 'href=', $item_values['pagelink']);
             $item_values['filelink'] = str_replace('<a href=', '<a ' . $link_attributes . 'href=', $item_values['filelink']);
         }
         /*
          * Process the <img> tag, if present
          * Note that $image_attributes, $image_class and $image_alt
          * are used in the Google Viewer code below
          */
         if (!empty($arguments['mla_image_attributes'])) {
             $image_attributes = self::_process_shortcode_parameter($arguments['mla_image_attributes'], $item_values) . ' ';
         } else {
             $image_attributes = '';
         }
         /*
          * WordPress 4.1 ties the <img> tag to the caption with 'aria-describedby'
          * has a matching 'id' attribute "$selector-#id".
          */
         if (trim($item_values['caption']) && false === strpos($image_attributes, 'aria-describedby=') && 'default' == $item_values['mla_markup']) {
             $image_attributes .= 'aria-describedby="' . $item_values['selector'] . '-' . $item_values['attachment_ID'] . '" ';
         }
         if (!empty($arguments['mla_image_class'])) {
             $image_class = esc_attr(self::_process_shortcode_parameter($arguments['mla_image_class'], $item_values));
         } else {
             $image_class = '';
         }
         if (!empty($arguments['mla_image_alt'])) {
             $image_alt = esc_attr(self::_process_shortcode_parameter($arguments['mla_image_alt'], $item_values));
         } else {
             $image_alt = '';
         }
         /*
          * Look for alt= and class= attributes in $image_attributes. If found,
          * they override and completely replace the corresponding values.
          */
         $class_replace = false;
         if (!empty($image_attributes)) {
             $match_count = preg_match('#alt=(([\'\\"])([^\']+?)\\2)#', $image_attributes, $matches, PREG_OFFSET_CAPTURE);
             if (1 === $match_count) {
                 $image_alt = $matches[3][0];
                 $image_attributes = substr_replace($image_attributes, '', $matches[0][1], strlen($matches[0][0]));
             }
             $match_count = preg_match('#class=(([\'\\"])([^\']+?)\\2)#', $image_attributes, $matches, PREG_OFFSET_CAPTURE);
             if (1 === $match_count) {
                 $class_replace = true;
                 $image_class = $matches[3][0];
                 $image_attributes = substr_replace($image_attributes, '', $matches[0][1], strlen($matches[0][0]));
             }
             $image_attributes = trim($image_attributes);
             if (!empty($image_attributes)) {
                 $image_attributes .= ' ';
             }
         }
         if (false !== strpos($item_values['pagelink'], '<img ')) {
             if (!empty($image_attributes)) {
                 $item_values['pagelink'] = str_replace('<img ', '<img ' . $image_attributes, $item_values['pagelink']);
                 $item_values['filelink'] = str_replace('<img ', '<img ' . $image_attributes, $item_values['filelink']);
             }
             /*
              * Extract existing class values and add to them
              */
             if (!empty($image_class)) {
                 $match_count = preg_match_all('# class=\\"([^\\"]+)\\" #', $item_values['pagelink'], $matches, PREG_OFFSET_CAPTURE);
                 if (!($class_replace || $match_count == false || $match_count == 0)) {
                     $class = $matches[1][0][0] . ' ' . $image_class;
                 } else {
                     $class = $image_class;
                 }
                 $item_values['pagelink'] = preg_replace('# class=\\"([^\\"]*)\\"#', " class=\"{$class}\"", $item_values['pagelink']);
                 $item_values['filelink'] = preg_replace('# class=\\"([^\\"]*)\\"#', " class=\"{$class}\"", $item_values['filelink']);
             }
             if (!empty($image_alt)) {
                 $item_values['pagelink'] = preg_replace('# alt=\\"([^\\"]*)\\"#', " alt=\"{$image_alt}\"", $item_values['pagelink']);
                 $item_values['filelink'] = preg_replace('# alt=\\"([^\\"]*)\\"#', " alt=\"{$image_alt}\"", $item_values['filelink']);
             }
         }
         // process <img> tag
         switch ($arguments['link']) {
             case 'permalink':
             case 'post':
                 $item_values['link'] = $item_values['pagelink'];
                 break;
             case 'file':
             case 'full':
                 $item_values['link'] = $item_values['filelink'];
                 break;
             default:
                 $item_values['link'] = $item_values['filelink'];
                 /*
                  * Check for link to specific (registered) file size
                  */
                 if (array_key_exists($arguments['link'], $sizes)) {
                     $target_file = $sizes[$arguments['link']]['file'];
                     $item_values['link'] = str_replace($file_name, $target_file, $item_values['filelink']);
                 }
         }
         // switch 'link'
         /*
          * Extract target and thumbnail fields
          */
         $match_count = preg_match_all('#href=\'([^\']+)\'#', $item_values['pagelink'], $matches, PREG_OFFSET_CAPTURE);
         if (!($match_count == false || $match_count == 0)) {
             $item_values['pagelink_url'] = $matches[1][0][0];
         } else {
             $item_values['pagelink_url'] = '';
         }
         $match_count = preg_match_all('#href=\'([^\']+)\'#', $item_values['filelink'], $matches, PREG_OFFSET_CAPTURE);
         if (!($match_count == false || $match_count == 0)) {
             $item_values['filelink_url'] = $matches[1][0][0];
         } else {
             $item_values['filelink_url'] = '';
         }
         $match_count = preg_match_all('#href=\'([^\']+)\'#', $item_values['link'], $matches, PREG_OFFSET_CAPTURE);
         if (!($match_count == false || $match_count == 0)) {
             $item_values['link_url'] = $matches[1][0][0];
         } else {
             $item_values['link_url'] = '';
         }
         /*
          * Override the link value; leave filelink and pagelink unchanged
          * Note that $link_href is used in the Google Viewer code below
          */
         if (!empty($arguments['mla_link_href'])) {
             $link_href = self::_process_shortcode_parameter($arguments['mla_link_href'], $item_values);
             /*
              * Replace single- and double-quote delimited values
              */
             $item_values['link'] = preg_replace('# href=\'([^\']*)\'#', " href='{$link_href}'", $item_values['link']);
             $item_values['link'] = preg_replace('# href=\\"([^\\"]*)\\"#', " href=\"{$link_href}\"", $item_values['link']);
         } else {
             $link_href = '';
         }
         $match_count = preg_match_all('#(\\<a [^\\>]+\\>)(.*)\\</a\\>#', $item_values['link'], $matches, PREG_OFFSET_CAPTURE);
         if (!($match_count == false || $match_count == 0)) {
             $link_tag = $matches[1][0][0];
             $item_values['thumbnail_content'] = $matches[2][0][0];
         } else {
             $item_values['thumbnail_content'] = '';
         }
         $match_count = preg_match_all('# width=\\"([^\\"]+)\\" height=\\"([^\\"]+)\\" src=\\"([^\\"]+)\\" #', $item_values['link'], $matches, PREG_OFFSET_CAPTURE);
         if (!($match_count == false || $match_count == 0)) {
             $item_values['thumbnail_width'] = $matches[1][0][0];
             $item_values['thumbnail_height'] = $matches[2][0][0];
             $item_values['thumbnail_url'] = $matches[3][0][0];
         } else {
             $item_values['thumbnail_width'] = '';
             $item_values['thumbnail_height'] = '';
             $item_values['thumbnail_url'] = '';
             if ('none' !== $arguments['size'] && 'checked' == MLACore::mla_get_option('enable_featured_image')) {
                 /*
                  * Look for the "Featured Image" as an alternate thumbnail for PDFs, etc.
                  */
                 $feature = get_the_post_thumbnail($attachment->ID, $size, array('class' => 'attachment-thumbnail'));
                 if (!empty($feature)) {
                     $match_count = preg_match_all('# width=\\"([^\\"]+)\\" height=\\"([^\\"]+)\\" src=\\"([^\\"]+)\\" #', $feature, $matches, PREG_OFFSET_CAPTURE);
                     if (!($match_count == false || $match_count == 0)) {
                         $item_values['link'] = $link_tag . $feature . '</a>';
                         $item_values['thumbnail_content'] = $feature;
                         $item_values['thumbnail_width'] = $matches[1][0][0];
                         $item_values['thumbnail_height'] = $matches[2][0][0];
                         $item_values['thumbnail_url'] = $matches[3][0][0];
                     }
                 }
             }
             // enable_featured_image
         }
         /*
          * Now that we have thumbnail_content we can check for 'span' and 'none'
          */
         if ('none' == $arguments['link']) {
             $item_values['link'] = $item_values['thumbnail_content'];
         } elseif ('span' == $arguments['link']) {
             $item_values['link'] = sprintf('<span %1$s>%2$s</span>', $link_attributes, $item_values['thumbnail_content']);
         }
         /*
          * Check for Imagick thumbnail generation, uses above-defined
          * $link_attributes (includes target), $rollover_text, $link_href (link only),
          * $image_attributes, $image_class, $image_alt
          */
         if ($arguments['mla_viewer'] && empty($item_values['thumbnail_url'])) {
             /*
              * Check for a match on file extension
              */
             $last_dot = strrpos($item_values['file'], '.');
             if (!(false === $last_dot)) {
                 $extension = substr($item_values['file'], $last_dot + 1);
                 if (in_array($extension, $arguments['mla_viewer_extensions'])) {
                     /*
                      * Default to an icon if thumbnail generation is not available
                      */
                     $icon_url = wp_mime_type_icon($attachment->ID);
                     $upload_dir = wp_upload_dir();
                     $args = array('page' => MLACore::ADMIN_PAGE_SLUG, 'mla_stream_file' => urlencode($upload_dir['basedir'] . '/' . $item_values['base_file']));
                     if ('log' == $arguments['mla_debug']) {
                         $args['mla_debug'] = 'log';
                     }
                     if ($arguments['mla_single_thread']) {
                         $args['mla_single_thread'] = 'true';
                     }
                     if ($arguments['mla_viewer_width']) {
                         $args['mla_stream_width'] = $arguments['mla_viewer_width'];
                     }
                     if ($arguments['mla_viewer_height']) {
                         $args['mla_stream_height'] = $arguments['mla_viewer_height'];
                     }
                     if (isset($arguments['mla_viewer_best_fit'])) {
                         $args['mla_stream_fit'] = $arguments['mla_viewer_best_fit'] ? '1' : '0';
                     }
                     /*
                      * Non-standard location, if not empty. Write the value to a file that can be
                      * found by the stand-alone (no WordPress) image stream processor.
                      */
                     $ghostscript_path = MLACore::mla_get_option('ghostscript_path');
                     if (!empty($ghostscript_path)) {
                         if (false !== @file_put_contents(dirname(__FILE__) . '/' . 'mla-ghostscript-path.txt', $ghostscript_path)) {
                             $args['mla_ghostscript_path'] = 'custom';
                         }
                     }
                     if (self::mla_ghostscript_present($ghostscript_path)) {
                         /*
                          * Optional upper limit (in MB) on file size
                          */
                         if ($limit = 1024 * 1024 * $arguments['mla_viewer_limit']) {
                             $file_size = 0 + @filesize($item_values['base_dir'] . '/' . $item_values['base_file']);
                             if (0 < $file_size && $file_size > $limit) {
                                 $file_size = 0;
                             }
                         } else {
                             $file_size = 1;
                         }
                         /*
                          * Generate "real" thumbnail
                          */
                         if ($file_size) {
                             $frame = 0 < $arguments['mla_viewer_page'] ? $arguments['mla_viewer_page'] - 1 : 0;
                             if ($frame) {
                                 $args['mla_stream_frame'] = $frame;
                             }
                             if ($arguments['mla_viewer_resolution']) {
                                 $args['mla_stream_resolution'] = $arguments['mla_viewer_resolution'];
                             }
                             if ($arguments['mla_viewer_quality']) {
                                 $args['mla_stream_quality'] = $arguments['mla_viewer_quality'];
                             }
                             if (!empty($arguments['mla_viewer_type'])) {
                                 $args['mla_stream_type'] = $arguments['mla_viewer_type'];
                             }
                             /*
                              * For efficiency, image streaming is done outside WordPress
                              */
                             $icon_url = add_query_arg($args, wp_nonce_url(MLA_PLUGIN_URL . 'includes/mla-stream-image.php', MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME));
                         }
                     }
                     /*
                      * <img> tag (thumbnail_text)
                      */
                     if (!empty($image_class)) {
                         $image_class = ' class="' . $image_class . '"';
                     }
                     if (!empty($image_alt)) {
                         $image_alt = ' alt="' . $image_alt . '"';
                     } elseif (!empty($item_values['caption'])) {
                         $image_alt = ' alt="' . $item_values['caption'] . '"';
                     }
                     $item_values['thumbnail_content'] = sprintf('<img %1$ssrc="%2$s"%3$s%4$s>', $image_attributes, $icon_url, $image_class, $image_alt);
                     /*
                      * Filelink, pagelink and link.
                      * The "title=" attribute is in $link_attributes for WP 3.7+.
                      */
                     if (false === strpos($link_attributes, 'title=')) {
                         $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']);
                         $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']);
                     } else {
                         $item_values['pagelink'] = sprintf('<a %1$shref="%2$s">%3$s</a>', $link_attributes, $item_values['pagelink_url'], $item_values['thumbnail_content']);
                         $item_values['filelink'] = sprintf('<a %1$shref="%2$s">%3$s</a>', $link_attributes, $item_values['filelink_url'], $item_values['thumbnail_content']);
                     }
                     if (!empty($link_href)) {
                         $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']);
                     } elseif ('permalink' == $arguments['link']) {
                         $item_values['link'] = $item_values['pagelink'];
                     } elseif ('file' == $arguments['link']) {
                         $item_values['link'] = $item_values['filelink'];
                     } elseif ('span' == $arguments['link']) {
                         $item_values['link'] = sprintf('<a %1$s>%2$s</a>', $link_attributes, $item_values['thumbnail_content']);
                     } else {
                         $item_values['link'] = $item_values['thumbnail_content'];
                     }
                 }
                 // viewer extension
             }
             // has extension
         }
         // mla_viewer
         if ($is_gallery) {
             /*
              * Start of row markup
              */
             if ($markup_values['columns'] > 0 && $column_index % $markup_values['columns'] == 0) {
                 $markup_values = apply_filters('mla_gallery_row_open_values', $markup_values);
                 $row_open_template = apply_filters('mla_gallery_row_open_template', $row_open_template);
                 $parse_value = MLAData::mla_parse_template($row_open_template, $markup_values);
                 $output .= apply_filters('mla_gallery_row_open_parse', $parse_value, $row_open_template, $markup_values);
             }
             /*
              * item markup
              */
             $column_index++;
             if ($item_values['columns'] > 0 && $column_index % $item_values['columns'] == 0) {
                 $item_values['last_in_row'] = 'last_in_row';
             } else {
                 $item_values['last_in_row'] = '';
             }
             /*
              * Conditional caption tag to replicate WP 4.1+,
              * now used in the default markup template.
              */
             if ($item_values['captiontag'] && trim($item_values['caption'])) {
                 $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";
             } else {
                 $item_values['captiontag_content'] = '';
             }
             $item_values = apply_filters('mla_gallery_item_values', $item_values);
             $item_template = apply_filters('mla_gallery_item_template', $item_template);
             $parse_value = MLAData::mla_parse_template($item_template, $item_values);
             $output .= apply_filters('mla_gallery_item_parse', $parse_value, $item_template, $item_values);
             /*
              * End of row markup
              */
             if ($markup_values['columns'] > 0 && $column_index % $markup_values['columns'] == 0) {
                 $markup_values = apply_filters('mla_gallery_row_close_values', $markup_values);
                 $row_close_template = apply_filters('mla_gallery_row_close_template', $row_close_template);
                 $parse_value = MLAData::mla_parse_template($row_close_template, $markup_values);
                 $output .= apply_filters('mla_gallery_row_close_parse', $parse_value, $row_close_template, $markup_values);
             }
         } elseif (!empty($link_type)) {
             return $item_values['link'];
         }
     }
     // foreach attachment
     if ($is_gallery) {
         /*
          * Close out partial row
          */
         if (!($markup_values['columns'] > 0 && $column_index % $markup_values['columns'] == 0)) {
             $markup_values = apply_filters('mla_gallery_row_close_values', $markup_values);
             $row_close_template = apply_filters('mla_gallery_row_close_template', $row_close_template);
             $parse_value = MLAData::mla_parse_template($row_close_template, $markup_values);
             $output .= apply_filters('mla_gallery_row_close_parse', $parse_value, $row_close_template, $markup_values);
         }
         $markup_values = apply_filters('mla_gallery_close_values', $markup_values);
         $close_template = apply_filters('mla_gallery_close_template', $close_template);
         $parse_value = MLAData::mla_parse_template($close_template, $markup_values);
         $output .= apply_filters('mla_gallery_close_parse', $parse_value, $close_template, $markup_values);
     }
     // is_gallery
     return $output;
 }
 /**
  * Evaluate custom field mapping data source
  *
  * @since 2.20
  *
  * @param	integer	post->ID of attachment
  * @param	string 	category/scope to evaluate against: custom_field_mapping or single_attachment_mapping
  * @param	array	data source specification ( name, *data_source, *keep_existing, *format, mla_column, quick_edit, bulk_edit, *meta_name, *option, no_null )
  * @param	array 	(optional) _wp_attachment_metadata, default NULL (use current postmeta database value)
  *
  * @return	string|array	data source value
  */
 private static function _evaluate_data_source($post_id, $category, $data_value, $attachment_metadata = NULL)
 {
     global $wpdb;
     static $upload_dir, $intermediate_sizes = NULL, $wp_attached_files = NULL, $wp_attachment_metadata = NULL;
     static $current_id = 0, $file_info = NULL, $parent_info = NULL, $references = NULL, $alt_text = NULL;
     if ('none' == $data_value['data_source']) {
         return '';
     }
     $data_source = $data_value['data_source'];
     /*
      * Do this once per page load; cache attachment metadata if mapping all attachments
      */
     if (NULL == $intermediate_sizes) {
         $upload_dir = wp_upload_dir();
         $upload_dir = $upload_dir['basedir'] . '/';
         $intermediate_sizes = get_intermediate_image_sizes();
         if ('custom_field_mapping' == $category) {
             if (!($table = _get_meta_table('post'))) {
                 $wp_attached_files = array();
                 $wp_attachment_metadata = array();
             } else {
                 $wp_attachment_metadata = $wpdb->get_results("SELECT post_id, meta_value FROM {$table} WHERE meta_key = '_wp_attachment_metadata'", OBJECT_K);
                 $wp_attached_files = $wpdb->get_results("SELECT post_id, meta_value FROM {$table} WHERE meta_key = '_wp_attached_file'", OBJECT_K);
             }
         }
         // custom_field_mapping, i.e., mapping all attachments
     }
     // first call after page load
     /*
      * Do this once per post. Simulate SQL results for $wp_attached_files and $wp_attachment_metadata.
      */
     if ($current_id != $post_id) {
         $current_id = $post_id;
         $parent_info = NULL;
         $references = NULL;
         $alt_text = NULL;
         if ('single_attachment_mapping' == $category) {
             $metadata = get_metadata('post', $post_id, '_wp_attached_file');
             if (isset($metadata[0])) {
                 $wp_attached_files = array($post_id => (object) array('post_id' => $post_id, 'meta_value' => $metadata[0]));
             } else {
                 $wp_attached_files = array();
             }
             if (NULL == $attachment_metadata) {
                 $metadata = get_metadata('post', $post_id, '_wp_attachment_metadata');
                 if (isset($metadata[0])) {
                     $attachment_metadata = $metadata[0];
                 }
             }
             if (empty($attachment_metadata)) {
                 $attachment_metadata = array();
             }
             $wp_attachment_metadata = array($post_id => (object) array('post_id' => $post_id, 'meta_value' => serialize($attachment_metadata)));
         }
         $file_info = MLAData_Source::_evaluate_file_information($upload_dir, $wp_attached_files, $wp_attachment_metadata, $post_id);
     }
     $size_info = array('file' => '', 'width' => '', 'height' => '');
     $match_count = preg_match('/(.+)\\[(.+)\\]/', $data_source, $matches);
     if (1 == $match_count) {
         $data_source = $matches[1] . '[size]';
         if (isset($file_info['sizes'][$matches[2]])) {
             $size_info = $file_info['sizes'][$matches[2]];
         }
     }
     $result = '';
     switch ($data_source) {
         case 'meta':
             $attachment_metadata = isset($wp_attachment_metadata[$post_id]->meta_value) ? maybe_unserialize($wp_attachment_metadata[$post_id]->meta_value) : array();
             $result = MLAData::mla_find_array_element($data_value['meta_name'], $attachment_metadata, $data_value['option'], $data_value['keep_existing']);
             break;
         case 'template':
             if (in_array($data_value['option'], array('single', 'export', 'array', 'multi'))) {
                 $default_option = 'array';
             } else {
                 $default_option = 'text';
             }
             /*
              * Go through the template and expand the non-prefixed elements
              * as Data Sources
              */
             $item_values = array();
             $placeholders = MLAData::mla_get_template_placeholders($data_value['meta_name'], $default_option);
             foreach ($placeholders as $key => $placeholder) {
                 if (empty($placeholder['prefix'])) {
                     $field_value = $data_value;
                     $field_value['data_source'] = $placeholder['value'];
                     $field_value['meta_name'] = '';
                     $field_value['option'] = $placeholder['option'];
                     $field_value['format'] = $placeholder['format'];
                     if (isset($placeholder['args'])) {
                         $field_value['args'] = $placeholder['args'];
                     }
                     $field_value = MLAData_Source::_evaluate_data_source($post_id, $category, $field_value, $attachment_metadata);
                     $item_values[$key] = MLAData::mla_apply_field_level_format($field_value, $placeholder);
                 }
                 // Data Source
             }
             // foreach placeholder
             /*
              * Now expand the template using the above Data Source values
              */
             $template = '[+template:' . $data_value['meta_name'] . '+]';
             $item_values = MLAData::mla_expand_field_level_parameters($template, NULL, $item_values, $post_id, $data_value['keep_existing'], $default_option);
             if ('array' == $default_option) {
                 $result = MLAData::mla_parse_array_template($template, $item_values);
                 $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             } else {
                 $result = MLAData::mla_parse_template($template, $item_values);
             }
             break;
         case 'parent':
             $data_source = 'post_parent';
             /* fallthru */
         /* fallthru */
         case 'ID':
         case 'post_id':
         case 'post_author':
         case 'post_parent':
         case 'menu_order':
         case 'comment_count':
             $result = absint(MLAData_Source::_evaluate_post_information($post_id, $category, $data_source));
             break;
         case 'alt_text':
             if (NULL == $alt_text) {
                 $metadata = get_metadata('post', $post_id, '_wp_attachment_image_alt');
                 if (is_array($metadata)) {
                     if (count($metadata) == 1) {
                         $alt_text = maybe_unserialize($metadata[0]);
                     } else {
                         $alt_text = array();
                         foreach ($metadata as $single_key => $single_value) {
                             $alt_text[$single_key] = maybe_unserialize($single_value);
                         }
                     }
                 }
             }
             if (!empty($alt_text)) {
                 $result = MLAData_Source::_evaluate_array_result($alt_text, $data_value['option'], $data_value['keep_existing']);
             }
             break;
         case 'mime_type':
             $data_source = 'post_mime_type';
             /* fallthru */
         /* fallthru */
         case 'post_date':
         case 'post_date_gmt':
         case 'post_content':
         case 'post_title':
         case 'post_excerpt':
         case 'post_status':
         case 'comment_status':
         case 'ping_status':
         case 'post_name':
         case 'post_modified':
         case 'post_modified_gmt':
         case 'post_content_filtered':
         case 'guid':
         case 'post_mime_type':
             $result = MLAData_Source::_evaluate_post_information($post_id, $category, $data_source);
             break;
         case 'absolute_path':
         case 'absolute_file_name':
         case 'base_file':
         case 'path':
         case 'file_name':
         case 'name_only':
         case 'extension':
         case 'width':
         case 'height':
         case 'orientation':
         case 'hwstring_small':
         case 'aperture':
         case 'credit':
         case 'camera':
         case 'caption':
         case 'created_timestamp':
         case 'copyright':
         case 'focal_length':
         case 'iso':
         case 'shutter_speed':
         case 'title':
             if (isset($file_info[$data_source])) {
                 $result = $file_info[$data_source];
             }
             break;
         case 'file_size':
             $filesize = @filesize($file_info['absolute_file_name_raw']);
             if (!(false === $filesize)) {
                 $result = $filesize;
             }
             break;
         case 'upload_date':
             $result = MLAData_Source::_evaluate_post_information($post_id, $category, 'post_date');
             break;
         case 'dimensions':
             $result = $file_info['width'] . 'x' . $file_info['height'];
             if ('x' == $result) {
                 $result = '';
             }
             break;
         case 'pixels':
             $result = absint((int) $file_info['width'] * (int) $file_info['height']);
             if (0 == $result) {
                 $result = '';
             } else {
                 $result = (string) $result;
             }
             break;
         case 'size_keys':
             $result = array();
             foreach ($file_info['sizes'] as $key => $value) {
                 $result[] = $key;
             }
             $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             break;
         case 'size_names':
             $result = array();
             foreach ($file_info['sizes'] as $key => $value) {
                 $result[] = $value['file'];
             }
             $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             break;
         case 'size_bytes':
             $result = array();
             foreach ($file_info['sizes'] as $key => $value) {
                 $filesize = @filesize($file_info['absolute_path_raw'] . $value['file']);
                 if (false === $filesize) {
                     $result[] = '?';
                 } else {
                     switch ($data_value['format']) {
                         case 'commas':
                             if (is_numeric($filesize)) {
                                 $filesize = number_format((double) $filesize);
                             }
                             break;
                         default:
                             // no change
                     }
                     // format
                     $result[] = $filesize;
                 }
             }
             $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             break;
         case 'size_pixels':
             $result = array();
             foreach ($file_info['sizes'] as $key => $value) {
                 $pixels = absint((int) $value['width'] * (int) $value['height']);
                 switch ($data_value['format']) {
                     case 'commas':
                         if (is_numeric($pixels)) {
                             $pixels = number_format((double) $pixels);
                         }
                         break;
                     default:
                         // no change
                 }
                 // format
                 $result[] = $pixels;
             }
             $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             break;
         case 'size_dimensions':
             $result = array();
             foreach ($file_info['sizes'] as $key => $value) {
                 $result[] = $value['width'] . 'x' . $value['height'];
             }
             $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             break;
         case 'size_name[size]':
             $result = $size_info['file'];
             break;
         case 'size_bytes[size]':
             $result = @filesize($file_info['absolute_path_raw'] . $size_info['file']);
             if (false === $result) {
                 $result = '?';
             }
             break;
         case 'size_pixels[size]':
             $result = absint((int) $size_info['width'] * (int) $size_info['height']);
             break;
         case 'size_dimensions[size]':
             $result = $size_info['width'] . 'x' . $size_info['height'];
             if ('x' == $result) {
                 $result = '';
             }
             break;
         case 'parent_date':
         case 'parent_type':
         case 'parent_title':
             if (is_null($parent_info)) {
                 $parent_info = MLAQuery::mla_fetch_attachment_parent_data(MLAData_Source::_evaluate_post_information($post_id, $category, 'post_parent'));
             }
             if (isset($parent_info[$data_source])) {
                 $result = $parent_info[$data_source];
             }
             break;
         case 'parent_issues':
             if (is_null($references)) {
                 $references = MLAQuery::mla_fetch_attachment_references($post_id, MLAData_Source::_evaluate_post_information($post_id, $category, 'post_parent'));
             }
             if (!empty($references['parent_errors'])) {
                 $result = $references['parent_errors'];
                 /*
                  * Remove (ORPHAN...
                  */
                 $orphan_certain = '(' . __('ORPHAN', 'media-library-assistant') . ')';
                 $orphan_possible = '(' . __('ORPHAN', 'media-library-assistant') . '?)';
                 if (false !== strpos($result, $orphan_certain)) {
                     $result = trim(substr($result, strlen($orphan_certain)));
                 } elseif (false !== strpos($result, $orphan_possible)) {
                     $result = trim(substr($result, strlen($orphan_possible)));
                 }
             }
             break;
         case 'reference_issues':
             if (is_null($references)) {
                 $references = MLAQuery::mla_fetch_attachment_references($post_id, MLAData_Source::_evaluate_post_information($post_id, $category, 'post_parent'));
             }
             if (!empty($references['parent_errors'])) {
                 $result = $references['parent_errors'];
             }
             break;
         case 'featured_in':
         case 'featured_in_title':
             if (is_null($references)) {
                 $references = MLAQuery::mla_fetch_attachment_references($post_id, MLAData_Source::_evaluate_post_information($post_id, $category, 'post_parent'));
             }
             if (!empty($references['features'])) {
                 $result = array();
                 foreach ($references['features'] as $ID => $value) {
                     if ('featured_in' == $data_source) {
                         $result[] = sprintf('%1$s (%2$s %3$d)', $value->post_title, $value->post_type, $ID);
                     } else {
                         $result[] = $value->post_title;
                     }
                 }
                 $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             } else {
                 $result = '';
             }
             break;
         case 'inserted_in':
         case 'inserted_in_title':
             if (is_null($references)) {
                 $references = MLAQuery::mla_fetch_attachment_references($post_id, MLAData_Source::_evaluate_post_information($post_id, $category, 'post_parent'));
             }
             if (!empty($references['inserts'])) {
                 $result = array();
                 foreach ($references['inserts'] as $base_file => $inserts) {
                     foreach ($inserts as $value) {
                         if ('inserted_in' == $data_source) {
                             $result[] = sprintf('%1$s (%2$s %3$d)', $value->post_title, $value->post_type, $value->ID);
                         } else {
                             $result[] = $value->post_title;
                         }
                     }
                 }
                 ksort($result);
                 $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             } else {
                 $result = '';
             }
             break;
         case 'gallery_in':
         case 'gallery_in_title':
             if (is_null($references)) {
                 $references = MLAQuery::mla_fetch_attachment_references($post_id, MLAData_Source::_evaluate_post_information($post_id, $category, 'post_parent'));
             }
             if (!empty($references['galleries'])) {
                 $result = array();
                 foreach ($references['galleries'] as $ID => $value) {
                     if ('gallery_in' == $data_source) {
                         $result[] = sprintf('%1$s (%2$s %3$d)', $value['post_title'], $value['post_type'], $ID);
                     } else {
                         $result[] = $value['post_title'];
                     }
                 }
                 $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             } else {
                 $result = '';
             }
             break;
         case 'mla_gallery_in':
         case 'mla_gallery_in_title':
             if (is_null($references)) {
                 $references = MLAQuery::mla_fetch_attachment_references($post_id, MLAData_Source::_evaluate_post_information($post_id, $category, 'post_parent'));
             }
             if (!empty($references['mla_galleries'])) {
                 $result = array();
                 foreach ($references['mla_galleries'] as $ID => $value) {
                     if ('mla_gallery_in' == $data_source) {
                         $result[] = sprintf('%1$s (%2$s %3$d)', $value['post_title'], $value['post_type'], $ID);
                     } else {
                         $result[] = $value['post_title'];
                     }
                 }
                 $result = MLAData_Source::_evaluate_array_result($result, $data_value['option'], $data_value['keep_existing']);
             } else {
                 $result = '';
             }
             break;
         default:
             $custom_value = apply_filters('mla_evaluate_custom_data_source', NULL, $post_id, $category, $data_value, $attachment_metadata);
             if (!is_null($custom_value)) {
                 return $custom_value;
             }
             return '';
     }
     // switch $data_source
     switch ($data_value['format']) {
         case 'raw':
             return $result;
         case 'commas':
             if (is_numeric($result)) {
                 $result = str_pad(number_format((double) $result), 15, ' ', STR_PAD_LEFT);
             }
             break;
         case 'native':
         default:
             /*
              * Make some numeric values sortable as strings, make all value non-empty
              */
             if (in_array($data_source, array('file_size', 'pixels', 'width', 'height'))) {
                 $result = str_pad($result, 15, ' ', STR_PAD_LEFT);
             } elseif (empty($result)) {
                 $result = ' ';
             }
     }
     // format
     return $result;
 }
Beispiel #4
0
 /**
  * Update a single item; change the "post" data, taxonomy terms 
  * and meta data for a single attachment
  * 
  * @since 0.1
  * 
  * @param	int		The ID of the attachment to be updated
  * @param	array	Field name => value pairs
  * @param	array	Optional taxonomy term values, default null
  * @param	array	Optional taxonomy actions (add, remove, replace), default null
  *
  * @return	array	success/failure message and NULL content
  */
 public static function mla_update_single_item($post_id, $new_data, $tax_input = NULL, $tax_actions = NULL)
 {
     $post_data = self::mla_get_attachment_by_id($post_id, false);
     if (!isset($post_data)) {
         return array('message' => __('ERROR', 'media-library-assistant') . ': ' . __('Could not retrieve Attachment.', 'media-library-assistant'), 'body' => '');
     }
     $updates = apply_filters('mla_update_single_item', compact(array('new_data', 'tax_input', 'tax_actions')), $post_id, $post_data);
     $new_data = isset($updates['new_data']) ? $updates['new_data'] : array();
     $tax_input = isset($updates['tax_input']) ? $updates['tax_input'] : NULL;
     $tax_actions = isset($updates['tax_actions']) ? $updates['tax_actions'] : NULL;
     $message = '';
     $updates = array('ID' => $post_id);
     $new_data = stripslashes_deep($new_data);
     $new_meta = NULL;
     foreach ($new_data as $key => $value) {
         switch ($key) {
             case 'post_title':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Title', 'media-library-assistant'), esc_attr($post_data[$key]), esc_attr($value));
                 $updates[$key] = $value;
                 break;
             case 'post_name':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 $value = sanitize_title($value);
                 /*
                  * Make sure new slug is unique
                  */
                 $args = array('name' => $value, 'post_type' => 'attachment', 'post_status' => 'inherit', 'showposts' => 1);
                 $my_posts = get_posts($args);
                 if ($my_posts) {
                     /* translators: 1: ERROR tag 2: old_value */
                     $message .= sprintf(__('%1$s: Could not change Name/Slug "%2$s"; name already exists', 'media-library-assistant') . '<br>', __('ERROR', 'media-library-assistant'), $value);
                 } else {
                     /* translators: 1: element name 2: old_value 3: new_value */
                     $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Name/Slug', 'media-library-assistant'), esc_attr($post_data[$key]), esc_attr($value));
                     $updates[$key] = $value;
                 }
                 break;
                 /*
                  * bulk_image_alt requires a separate key because some attachment types
                  * should not get a value, e.g., text or PDF documents
                  */
             /*
              * bulk_image_alt requires a separate key because some attachment types
              * should not get a value, e.g., text or PDF documents
              */
             case 'bulk_image_alt':
                 if ('image/' !== substr($post_data['post_mime_type'], 0, 6)) {
                     break;
                 }
                 // fallthru
             // fallthru
             case 'image_alt':
                 $key = 'mla_wp_attachment_image_alt';
                 if (!isset($post_data[$key])) {
                     $post_data[$key] = NULL;
                 }
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 if (empty($value)) {
                     if (delete_post_meta($post_id, '_wp_attachment_image_alt')) {
                         /* translators: 1: old_value */
                         $message .= sprintf(__('Deleting ALT Text, was "%1$s"', 'media-library-assistant') . '<br>', esc_attr($post_data[$key]));
                     } else {
                         /* translators: 1: ERROR tag 2: old_value */
                         $message .= sprintf(__('%1$s: Could not delete ALT Text, remains "%2$s"', 'media-library-assistant') . '<br>', __('ERROR', 'media-library-assistant'), esc_attr($post_data[$key]));
                     }
                 } else {
                     /*
                      * ALT Text isn't supposed to have multiple values, but it happens.
                      * Delete multiple values and start over.
                      */
                     if (is_array($post_data[$key])) {
                         delete_post_meta($post_id, '_wp_attachment_image_alt');
                     }
                     if (update_post_meta($post_id, '_wp_attachment_image_alt', $value)) {
                         /* translators: 1: element name 2: old_value 3: new_value */
                         $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('ALT Text', 'media-library-assistant'), esc_attr($post_data[$key]), esc_attr($value));
                     } else {
                         /* translators: 1: ERROR tag 2: old_value 3: new_value */
                         $message .= sprintf(__('%1$s: Could not change ALT Text from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('ERROR', 'media-library-assistant'), esc_attr($post_data[$key]), esc_attr($value));
                     }
                 }
                 break;
             case 'post_excerpt':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Caption', 'media-library-assistant'), esc_attr($post_data[$key]), esc_attr($value));
                 $updates[$key] = $value;
                 break;
             case 'post_content':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Description', 'media-library-assistant'), esc_textarea($post_data[$key]), esc_textarea($value));
                 $updates[$key] = $value;
                 break;
             case 'post_parent':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 $value = absint($value);
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Parent', 'media-library-assistant'), $post_data[$key], $value);
                 $updates[$key] = $value;
                 break;
             case 'menu_order':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 $value = absint($value);
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Menu Order', 'media-library-assistant'), $post_data[$key], $value);
                 $updates[$key] = $value;
                 break;
             case 'post_author':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 $value = absint($value);
                 $from_user = get_userdata($post_data[$key]);
                 $to_user = get_userdata($value);
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Author', 'media-library-assistant'), $from_user->display_name, $to_user->display_name);
                 $updates[$key] = $value;
                 break;
             case 'comment_status':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Comments', 'media-library-assistant'), esc_attr($post_data[$key]), esc_attr($value));
                 $updates[$key] = $value;
                 break;
             case 'ping_status':
                 if ($value == $post_data[$key]) {
                     break;
                 }
                 /* translators: 1: element name 2: old_value 3: new_value */
                 $message .= sprintf(__('Changing %1$s from "%2$s" to "%3$s"', 'media-library-assistant') . '<br>', __('Pings', 'media-library-assistant'), esc_attr($post_data[$key]), esc_attr($value));
                 $updates[$key] = $value;
                 break;
             case 'taxonomy_updates':
                 $tax_input = $value['inputs'];
                 $tax_actions = $value['actions'];
                 break;
             case 'custom_updates':
                 $new_meta = $value;
                 break;
             default:
                 // Ignore anything else
         }
         // switch $key
     }
     // foreach $new_data
     if (!empty($tax_input)) {
         foreach ($tax_input as $taxonomy => $tags) {
             if (!empty($tax_actions)) {
                 $tax_action = $tax_actions[$taxonomy];
             } else {
                 $tax_action = 'replace';
             }
             $taxonomy_obj = get_taxonomy($taxonomy);
             if (current_user_can($taxonomy_obj->cap->assign_terms)) {
                 if (is_array($tags)) {
                     // array of int = hierarchical, comma-delimited string = non-hierarchical.
                     $tags = array_filter($tags);
                 }
                 switch ($tax_action) {
                     case 'add':
                         if (!empty($tags)) {
                             $action_name = __('Adding', 'media-library-assistant');
                             $result = wp_set_post_terms($post_id, $tags, $taxonomy, true);
                         }
                         break;
                     case 'remove':
                         $action_name = __('Removing', 'media-library-assistant');
                         $tags = self::_remove_terms($post_id, $tags, $taxonomy_obj);
                         $result = wp_set_post_terms($post_id, $tags, $taxonomy);
                         if (empty($tags)) {
                             $result = true;
                         }
                         break;
                     case 'replace':
                         $action_name = __('Replacing', 'media-library-assistant');
                         $result = wp_set_post_terms($post_id, $tags, $taxonomy);
                         if (empty($tags)) {
                             $result = true;
                         }
                         break;
                     default:
                         $action_name = __('Ignoring', 'media-library-assistant');
                         $result = NULL;
                         // ignore anything else
                 }
                 /*
                  * Definitive results check would use:
                  * do_action( 'set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids );
                  * in /wp_includes/taxonomy.php function wp_set_object_terms()
                  */
                 if (!empty($result)) {
                     delete_transient(MLA_OPTION_PREFIX . 't_term_counts_' . $taxonomy);
                     /* translators: 1: action_name, 2: taxonomy */
                     $message .= sprintf(__('%1$s "%2$s" terms', 'media-library-assistant') . '<br>', $action_name, $taxonomy);
                 }
             } else {
                 // current_user_can
                 /* translators: 1: taxonomy */
                 $message .= sprintf(__('You cannot assign "%1$s" terms', 'media-library-assistant') . '<br>', $taxonomy);
             }
         }
         // foreach $tax_input
     }
     // ! empty $tax_input
     if (is_array($new_meta)) {
         $message .= self::mla_update_item_postmeta($post_id, $new_meta);
     }
     if (empty($message)) {
         return array('message' => sprintf(__('Item %1$d, no changes detected.', 'media-library-assistant'), $post_id), 'body' => '');
     } else {
         // invalidate the cached item
         self::mla_get_attachment_by_id(-1);
         MLAQuery::mla_fetch_attachment_parent_data(-1);
         MLAQuery::mla_fetch_attachment_metadata(-1);
         MLAQuery::mla_fetch_attachment_references(-1, 0);
         // See if anything else has changed
         if (1 < count($updates)) {
             $result = wp_update_post($updates);
         } else {
             $result = $post_id;
         }
         do_action('mla_updated_single_item', $post_id, $result);
         if ($result) {
             /* translators: 1: post ID */
             $final_message = sprintf(__('Item %1$d updated.', 'media-library-assistant'), $post_id);
             /*
              * Uncomment this for debugging.
              */
             // $final_message .= '<br>' . $message;
             //error_log( 'DEBUG: mla_update_single_item message = ' . var_export( $message, true ), 0 );
             return array('message' => $final_message, 'body' => '');
         } else {
             return array('message' => sprintf(__('%1$s: Item %2$d update failed.', 'media-library-assistant'), __('ERROR', 'media-library-assistant'), $post_id), 'body' => '');
         }
     }
 }