/**
  * Log debug information
  *
  * @since 2.12
  *
  * @param	string	$message Error message.
  */
 private static function _mla_debug_add($message)
 {
     if (self::$mla_debug) {
         if (class_exists('MLACore')) {
             MLACore::mla_debug_add($message);
         } else {
             error_log($message, 0);
         }
     }
 }
 /**
  * Filters taxonomy updates by language for Bulk Edit during Add New Media
  * and the Media/Edit Media screen
  *
  * @since 2.11
  *
  * @param	integer	ID of the current post
  */
 public static function edit_attachment($post_id)
 {
     static $already_updating = 0;
     MLACore::mla_debug_add(__LINE__ . " MLA_WPML::edit_attachment( {$post_id} ) _REQUEST = " . var_export($_REQUEST, true), MLACore::MLA_DEBUG_CATEGORY_LANGUAGE);
     /*
      * mla_update_single_item may call this action again, and
      * nothing should happen while updating duplicate items
      */
     if ($already_updating == $post_id || self::$updating_duplicates) {
         return;
     } else {
         $already_updating = $post_id;
     }
     /*
      * Check for Bulk Edit during Add New Media
      */
     if (!empty($_REQUEST['mlaAddNewBulkEditFormString'])) {
         if (!empty(self::$bulk_edit_request['tax_input'])) {
             $tax_inputs = self::$bulk_edit_request['tax_input'];
             if ('checked' == MLACore::mla_get_option('term_assignment', false, false, MLA_WPML::$mla_language_option_definitions)) {
                 self::_build_tax_input($post_id, $tax_inputs, self::$bulk_edit_request['tax_action']);
                 $tax_inputs = self::_apply_tax_input($post_id);
             }
         } else {
             $tax_inputs = NULL;
         }
         $updates = MLA::mla_prepare_bulk_edits($post_id, self::$bulk_edit_request, self::$bulk_edit_map);
         unset($updates['tax_input']);
         unset($updates['tax_action']);
         MLAData::mla_update_single_item($post_id, $updates, $tax_inputs);
         return;
     }
     // Upload New Media Bulk Edit
     /*
      * For the Bulk Edit action on the Media/Assistant screen, only synchronization is needed
      */
     if (!(isset($_REQUEST['bulk_action']) && 'bulk_edit' == $_REQUEST['bulk_action'])) {
         /*
          * This is the Media/Edit Media screen.
          * The category taxonomy (edit screens) is a special case because 
          * post_categories_meta_box() changes the input name
          */
         if (isset($_REQUEST['tax_input'])) {
             $tax_inputs = $_REQUEST['tax_input'];
         } else {
             $tax_inputs = array();
         }
         if (isset($_REQUEST['post_category'])) {
             $tax_inputs['category'] = $_REQUEST['post_category'];
         }
         if (isset($_REQUEST['tax_action'])) {
             $tax_actions = $_REQUEST['tax_action'];
         } else {
             $tax_actions = NULL;
         }
         if (!empty($tax_inputs) && 'checked' == MLACore::mla_get_option('term_assignment', false, false, MLA_WPML::$mla_language_option_definitions)) {
             self::_build_tax_input($post_id, $tax_inputs, $tax_actions);
             $tax_inputs = self::_apply_tax_input($post_id);
         }
         if (!empty($tax_inputs)) {
             MLAData::mla_update_single_item($post_id, array(), $tax_inputs);
         }
     }
     // Media/Edit Media screen, NOT Bulk Edit
 }
 /**
  * Creates new items from the "Bulk Translate" list.
  *
  * @since 2.11
  *
  * @param	array	$item_content	NULL, to indicate no handler.
  * @param	string	$bulk_action	the requested action.
  * @param	integer	$post_id		the affected attachment.
  *
  * @return	object	updated $item_content. NULL if no handler, otherwise
  *					( 'message' => error or status message(s), 'body' => '' )
  */
 public static function mla_list_table_custom_bulk_action($item_content, $bulk_action, $post_id)
 {
     global $polylang;
     MLACore::mla_debug_add(__LINE__ . " MLA_Polylang::mla_list_table_bulk_action_item_request( {$bulk_action}, {$post_id} )", MLACore::MLA_DEBUG_CATEGORY_LANGUAGE);
     if ('pll-translate' == $bulk_action) {
         $translations = array();
         if (isset($_REQUEST['bulk_tr_languages'])) {
             $bulk_tr_languages = $_REQUEST['bulk_tr_languages'];
             // Expand All Languages selection
             if (isset($bulk_tr_languages['all'])) {
                 foreach ($polylang->model->get_languages_list() as $language) {
                     $bulk_tr_languages[$language->slug] = 'translate';
                 }
                 unset($bulk_tr_languages['all']);
             }
             // Process language selection(s)
             foreach ($bulk_tr_languages as $language => $action) {
                 $new_id = MLA_Polylang::_get_translation($post_id, $language);
                 $translations[] = $new_id;
             }
         }
         // Clear all the "Filter-by" parameters
         if (isset($_REQUEST['bulk_tr_options']['clear_filters'])) {
             MLA::mla_clear_filter_by();
         }
         if (empty($translations)) {
             $item_content = array('message' => "Item {$post_id}, no translations.");
         } else {
             $_REQUEST['heading_suffix'] = __('Bulk Translations', 'media-library-assistant');
             MLA_Polylang::$bulk_action_includes = array_merge(MLA_Polylang::$bulk_action_includes, $translations);
             $translations = implode(',', $translations);
             $item_content = array('message' => "Item {$post_id}, translation(s): {$translations}.");
         }
     }
     return $item_content;
 }
Esempio n. 4
0
 /**
  * Filters all clauses for shortcode queries, post caching plugins
  * 
  * This is for debug purposes only.
  * Defined as public because it's a filter.
  *
  * @since 1.80
  *
  * @param	array	query clauses before modification
  *
  * @return	array	query clauses after modification (none)
  */
 public static function mla_query_posts_clauses_request_filter($pieces)
 {
     /* translators: 1: DEBUG tag 2: SQL clauses */
     MLACore::mla_debug_add(sprintf(_x('%1$s: mla_query_posts_clauses_request_filter = "%2$s".', 'error_log', 'media-library-assistant'), __('DEBUG', 'media-library-assistant'), var_export($pieces, true)));
     return $pieces;
 }
 /**
  * Get ALL markup templates from $mla_custom_templates, including 'default'
  *
  * @since 2.30
  *
  * @param	string	Shortcode to which the template(s) apply; default 'gallery'
  *
  * @return	array|null	name => value for all markup templates or null if no templates
  */
 public static function mla_get_markup_templates($shortcode = '')
 {
     if (!is_array(MLATemplate_Support::$mla_custom_templates)) {
         MLACore::mla_debug_add('<strong>mla_debug mla_get_markup_templates()</strong> ' . __('no templates exist', 'media-library-assistant'));
         return NULL;
     }
     if (!empty($shortcode)) {
         if (array_key_exists($shortcode, MLATemplate_Support::$mla_custom_templates['markup'])) {
             return MLATemplate_Support::$mla_custom_templates['markup'][$shortcode];
         }
         return NULL;
     }
     $templates = array();
     foreach (MLATemplate_Support::$mla_custom_templates['markup'] as $shortcode => $value) {
         $templates = array_merge($templates, $value);
     }
     // foreach
     return $templates;
 }
 /**
  * Retrieve the terms in one or more taxonomies.
  *
  * Alternative to WordPress /wp-includes/taxonomy.php function get_terms() that provides
  * an accurate count of attachments associated with each term.
  *
  * taxonomy - string containing one or more (comma-delimited) taxonomy names
  * or an array of taxonomy names. Default 'post_tag'.
  *
  * post_mime_type - MIME type(s) of the items to include in the term-specific counts. Default 'all'.
  *
  * post_type - The post type(s) of the items to include in the term-specific counts.
  * The default is "attachment". 
  *
  * post_status - The post status value(s) of the items to include in the term-specific counts.
  * The default is "inherit".
  *
  * ids - A comma-separated list of attachment ID values for an item-specific cloud.
  *
  * include - An array, comma- or space-delimited string of term ids to include
  * in the return array.
  *
  * exclude - An array, comma- or space-delimited string of term ids to exclude
  * from the return array. If 'include' is non-empty, 'exclude' is ignored.
  *
  * parent - term_id of the terms' immediate parent; 0 for top-level terms.
  *
  * minimum - minimum number of attachments a term must have to be included. Default 0.
  *
  * no_count - 'true', 'false' (default) to suppress term-specific attachment-counting process.
  *
  * number - maximum number of term objects to return. Terms are ordered by count,
  * descending and then by term_id before this value is applied. Default 0.
  *
  * orderby - 'count', 'id', 'name' (default), 'none', 'random', 'slug'
  *
  * order - 'ASC' (default), 'DESC'
  *
  * no_orderby - 'true', 'false' (default) to suppress ALL sorting clauses else false.
  *
  * preserve_case - 'true', 'false' (default) to make orderby case-sensitive.
  *
  * pad_counts - 'true', 'false' (default) to to include the count of all children in their parents' count.
  *
  * limit - final number of term objects to return, for pagination. Default 0.
  *
  * offset - number of term objects to skip, for pagination. Default 0.
  *
  * @since 2.20
  *
  * @param	array	taxonomies to search and query parameters
  *
  * @return	array	array of term objects, empty if none found
  */
 public static function mla_get_terms($attr)
 {
     global $wpdb;
     /*
      * Make sure $attr is an array, even if it's empty
      */
     if (empty($attr)) {
         $attr = array();
     } elseif (is_string($attr)) {
         $attr = shortcode_parse_atts($attr);
     }
     /*
      * Merge input arguments with defaults
      */
     $attr = apply_filters('mla_get_terms_query_attributes', $attr);
     $arguments = shortcode_atts(self::$mla_get_terms_parameters, $attr);
     $arguments = apply_filters('mla_get_terms_query_arguments', $arguments);
     /*
      * Build an array of individual clauses that can be filtered
      */
     $clauses = array('fields' => '', 'join' => '', 'where' => '', 'order' => '', 'orderby' => '', 'limits' => '');
     /*
      * If we're not counting attachments per term, strip
      * post fields out of list and adjust the orderby  value
      */
     if ($no_count = 'true' == (string) $arguments['no_count']) {
         $field_array = explode(',', $arguments['fields']);
         foreach ($field_array as $index => $field) {
             if (false !== strpos($field, 'p.')) {
                 unset($field_array[$index]);
             }
         }
         $arguments['fields'] = implode(',', $field_array);
         $arguments['minimum'] = 0;
         $arguments['post_mime_type'] = 'all';
         if ('count' == strtolower($arguments['orderby'])) {
             $arguments['orderby'] = 'none';
         }
     }
     $clauses['fields'] = $arguments['fields'];
     $clause = array('INNER JOIN `' . $wpdb->term_taxonomy . '` AS tt ON t.term_id = tt.term_id');
     $clause_parameters = array();
     if (!$no_count) {
         $clause[] = 'LEFT JOIN `' . $wpdb->term_relationships . '` AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id';
         $clause[] = 'LEFT JOIN `' . $wpdb->posts . '` AS p ON tr.object_id = p.ID';
         /*
          * Add type and status constraints
          */
         if (is_array($arguments['post_type'])) {
             $post_types = $arguments['post_type'];
         } else {
             $post_types = array($arguments['post_type']);
         }
         $placeholders = array();
         foreach ($post_types as $post_type) {
             $placeholders[] = '%s';
             $clause_parameters[] = $post_type;
         }
         $clause[] = 'AND p.post_type IN (' . join(',', $placeholders) . ')';
         if (is_array($arguments['post_status'])) {
             $post_stati = $arguments['post_status'];
         } else {
             $post_stati = array($arguments['post_status']);
         }
         $placeholders = array();
         foreach ($post_stati as $post_status) {
             if ('private' != $post_status || is_user_logged_in()) {
                 $placeholders[] = '%s';
                 $clause_parameters[] = $post_status;
             }
         }
         $clause[] = 'AND p.post_status IN (' . join(',', $placeholders) . ')';
     }
     $clause = join(' ', $clause);
     $clauses['join'] = $wpdb->prepare($clause, $clause_parameters);
     /*
      * Start WHERE clause with a taxonomy constraint
      */
     if (is_array($arguments['taxonomy'])) {
         $taxonomies = $arguments['taxonomy'];
     } else {
         $taxonomies = array($arguments['taxonomy']);
     }
     foreach ($taxonomies as $taxonomy) {
         if (!taxonomy_exists($taxonomy)) {
             $error = new WP_Error('invalid_taxonomy', __('Invalid taxonomy', 'media-library-assistant'), $taxonomy);
             return $error;
         }
     }
     $clause_parameters = array();
     $placeholders = array();
     foreach ($taxonomies as $taxonomy) {
         $placeholders[] = '%s';
         $clause_parameters[] = $taxonomy;
     }
     $clause = array('tt.taxonomy IN (' . join(',', $placeholders) . ')');
     /*
      * The "ids" parameter can build an item-specific cloud.
      * Compile a list of all the terms assigned to the items.
      */
     if (!empty($arguments['ids']) && empty($arguments['include'])) {
         $ids = wp_parse_id_list($arguments['ids']);
         $placeholders = implode("','", $ids);
         $clause[] = "AND p.ID IN ( '{$placeholders}' )";
         $includes = array();
         foreach ($ids as $id) {
             foreach ($taxonomies as $taxonomy) {
                 $terms = get_the_terms($id, $taxonomy);
                 if (is_array($terms)) {
                     foreach ($terms as $term) {
                         $includes[$term->term_id] = $term->term_id;
                     }
                     // terms
                 }
             }
             // taxonomies
         }
         // ids
         /*
          * If there are no terms we want an empty cloud
          */
         if (empty($includes)) {
             $arguments['include'] = (string) 0x7fffffff;
         } else {
             ksort($includes);
             $arguments['include'] = implode(',', $includes);
         }
     }
     /*
      * Add include/exclude and parent constraints to WHERE cluse
      */
     if (!empty($arguments['include'])) {
         $placeholders = implode("','", wp_parse_id_list($arguments['include']));
         $clause[] = "AND t.term_id IN ( '{$placeholders}' )";
     } elseif (!empty($arguments['exclude'])) {
         $placeholders = implode("','", wp_parse_id_list($arguments['exclude']));
         $clause[] = "AND t.term_id NOT IN ( '{$placeholders}' )";
     }
     if ('' !== $arguments['parent']) {
         $parent = (int) $arguments['parent'];
         $clause[] = "AND tt.parent = '{$parent}'";
     }
     if ('all' !== strtolower($arguments['post_mime_type'])) {
         $where = str_replace('%', '%%', wp_post_mime_type_where($arguments['post_mime_type'], 'p'));
         if (0 == absint($arguments['minimum'])) {
             $clause[] = ' AND ( p.post_mime_type IS NULL OR ' . substr($where, 6);
         } else {
             $clause[] = $where;
         }
     }
     $clause = join(' ', $clause);
     $clauses['where'] = $wpdb->prepare($clause, $clause_parameters);
     /*
      * For the inner/initial query, always select the most popular terms
      */
     if ($arguments['no_orderby']) {
         $arguments['orderby'] = 'count';
         $arguments['order'] = 'DESC';
     }
     /*
      * Add sort order
      */
     $orderby = strtolower($arguments['orderby']);
     $order = strtoupper($arguments['order']);
     if ('DESC' != $order) {
         $order = 'ASC';
     }
     $clauses['order'] = $order;
     $clauses['orderby'] = "ORDER BY {$orderby}";
     /*
      * Count, Descending, is the default order so no further work
      * is needed unless a different order is specified
      */
     if ('count' != $orderby || 'DESC' != $order) {
         if ('true' == strtolower($arguments['preserve_case'])) {
             $binary_keys = array('name', 'slug');
         } else {
             $binary_keys = array();
         }
         $allowed_keys = array('empty_orderby_default' => 'name', 'count' => 'count', 'id' => 'term_id', 'name' => 'name', 'random' => 'RAND()', 'slug' => 'slug');
         $clause = 'ORDER BY ' . self::_validate_sql_orderby($arguments, '', $allowed_keys, $binary_keys);
         $clauses['orderby'] = substr($clause, 0, strrpos($clause, ' ' . $order));
     }
     // add ORDER BY
     /*
      * Add pagination
      */
     $clauses['limits'] = '';
     $offset = absint($arguments['offset']);
     $limit = absint($arguments['limit']);
     if (0 < $offset && 0 < $limit) {
         $clauses['limits'] = "LIMIT {$offset}, {$limit}";
     } elseif (0 < $limit) {
         $clauses['limits'] = "LIMIT {$limit}";
     } elseif (0 < $offset) {
         $clause_parameters = 0x7fffffff;
         $clauses['limits'] = "LIMIT {$offset}, {$clause_parameters}";
     }
     $clauses = apply_filters('mla_get_terms_clauses', $clauses);
     /*
      * Build the final query
      */
     $query = array('SELECT');
     $query[] = $clauses['fields'];
     $query[] = 'FROM `' . $wpdb->terms . '` AS t';
     $query[] = $clauses['join'];
     $query[] = 'WHERE (';
     $query[] = $clauses['where'];
     $query[] = ') GROUP BY tt.term_taxonomy_id';
     $clause_parameters = absint($arguments['minimum']);
     if (0 < $clause_parameters) {
         $query[] = "HAVING count >= {$clause_parameters}";
     }
     /*
      * If specifically told to omit the ORDER BY clause or the COUNT,
      * supply a sort order for the initial/inner query only
      */
     if (!($arguments['no_orderby'] || $no_count)) {
         $query[] = 'ORDER BY count DESC, t.term_id ASC';
     }
     /*
      * Limit the total number of terms returned
      */
     $terms_limit = absint($arguments['number']);
     if (0 < $terms_limit) {
         $query[] = "LIMIT {$terms_limit}";
     }
     /*
      * $final_clauses, if present, require an SQL subquery
      */
     $final_clauses = array();
     if ('count' != $orderby || 'DESC' != $order) {
         $final_clauses[] = $clauses['orderby'];
         $final_clauses[] = $clauses['order'];
     }
     if ('' !== $clauses['limits']) {
         $final_clauses[] = $clauses['limits'];
     }
     /*
      * If we're limiting the final results, we need to get an accurate total count first
      */
     if (!$no_count && (0 < $offset || 0 < $limit)) {
         $count_query = 'SELECT COUNT(*) as count FROM (' . join(' ', $query) . ' ) as subQuery';
         $count = $wpdb->get_results($count_query);
         $found_rows = $count[0]->count;
     }
     if (!empty($final_clauses)) {
         if (!$no_count) {
             array_unshift($query, 'SELECT * FROM (');
             $query[] = ') AS subQuery';
         }
         $query = array_merge($query, $final_clauses);
     }
     $query = join(' ', $query);
     $tags = $wpdb->get_results($query);
     if (!isset($found_rows)) {
         $found_rows = $wpdb->num_rows;
     }
     if (self::$mla_debug) {
         MLACore::mla_debug_add('<strong>' . __('mla_debug query arguments', 'media-library-assistant') . '</strong> = ' . var_export($arguments, true));
         MLACore::mla_debug_add('<strong>' . __('mla_debug last_query', 'media-library-assistant') . '</strong> = ' . var_export($wpdb->last_query, true));
         MLACore::mla_debug_add('<strong>' . __('mla_debug last_error', 'media-library-assistant') . '</strong> = ' . var_export($wpdb->last_error, true));
         MLACore::mla_debug_add('<strong>' . __('mla_debug num_rows', 'media-library-assistant') . '</strong> = ' . var_export($wpdb->num_rows, true));
         MLACore::mla_debug_add('<strong>' . __('mla_debug found_rows', 'media-library-assistant') . '</strong> = ' . var_export($found_rows, true));
     }
     if ('true' == strtolower(trim($arguments['pad_counts']))) {
         self::_pad_term_counts($tags, reset($taxonomies), $post_types, $post_stati);
     }
     $tags['found_rows'] = $found_rows;
     $tags = apply_filters('mla_get_terms_query_results', $tags);
     return $tags;
 }
 /**
  * Assemble the in-memory representation of the (read-only) Optional Upload MIME Types 
  *
  * @since 1.40
  *
  * @return	boolean	Success (true) or failure (false) of the operation
  */
 private static function _get_optional_upload_mime_templates()
 {
     if (NULL != self::$mla_optional_upload_mime_templates) {
         return true;
     }
     self::$mla_optional_upload_mime_templates = array();
     $template_array = MLACore::mla_load_template('mla-default-mime-types.tpl');
     if (isset($template_array['mla-optional-mime-types'])) {
         $mla_mime_types = preg_split('/[\\r\\n]+/', $template_array['mla-optional-mime-types']);
         $ID = 0;
         foreach ($mla_mime_types as $mla_type) {
             // Ignore blank lines
             if (empty($mla_type)) {
                 continue;
             }
             $array = explode(',', $mla_type);
             // Bypass damaged entries
             if (3 > count($array)) {
                 MLACore::mla_debug_add(__LINE__ . " _get_upload_mime_templates mla-default-mime-types.tpl section mla-optional-mime-types( {$ID} '{$mla_type}' ) \$array = " . var_export($array, true), MLACore::MLA_DEBUG_CATEGORY_ANY);
                 continue;
             }
             $slug = $array[0];
             if ($matched_type = self::mla_get_upload_mime($slug)) {
                 $core_type = $matched_type['core_type'];
                 $mla_type = $matched_type['mla_type'];
             } else {
                 $core_type = '';
                 $mla_type = '';
             }
             self::$mla_optional_upload_mime_templates[++$ID] = array('ID' => $ID, 'slug' => $slug, 'mime_type' => $array[1], 'core_type' => $core_type, 'mla_type' => $mla_type, 'description' => $array[2]);
         }
     }
     return true;
 }
 /**
  * Load option settings templates to $mla_option_templates
  *
  * @since 0.80
  *
  * @return	void
  */
 private static function _load_option_templates()
 {
     MLAOptions::$mla_option_templates = MLACore::mla_load_template('mla-option-templates.tpl');
     /* 	
      * Load the option settings templates
      */
     if (is_null(MLAOptions::$mla_option_templates)) {
         MLACore::mla_debug_add('<strong>mla_debug _load_option_templates()</strong> ' . __('error loading tpls/mla-option-templates.tpl', 'media-library-assistant'));
         return;
     } elseif (!MLAOptions::$mla_option_templates) {
         MLACore::mla_debug_add('<strong>mla_debug _load_option_templates()</strong> ' . __('tpls/mla-option-templates.tpl not found', 'media-library-assistant'));
         MLAOptions::$mla_option_templates = NULL;
         return;
     }
 }
Esempio n. 9
0
 /**
  * Get ALL markup templates from $mla_templates, including 'default'
  *
  * @since 0.80
  *
  * @return	array|null	name => value for all markup templates or null if no templates
  */
 public static function mla_get_markup_templates()
 {
     if (!is_array(MLAShortcode_Support::$mla_custom_templates)) {
         MLACore::mla_debug_add('<strong>mla_debug mla_get_markup_templates()</strong> ' . __('no templates exist', 'media-library-assistant'));
         return NULL;
     }
     $templates = array();
     foreach (MLAShortcode_Support::$mla_custom_templates as $key => $value) {
         // Note order: -row-open must precede -open!
         $tail = strrpos($key, '-row-open-markup');
         if (!(false === $tail)) {
             $name = substr($key, 0, $tail);
             $templates[$name]['row-open'] = $value;
             continue;
         }
         $tail = strrpos($key, '-open-markup');
         if (!(false === $tail)) {
             $name = substr($key, 0, $tail);
             $templates[$name]['open'] = $value;
             continue;
         }
         $tail = strrpos($key, '-item-markup');
         if (!(false === $tail)) {
             $name = substr($key, 0, $tail);
             $templates[$name]['item'] = $value;
             continue;
         }
         $tail = strrpos($key, '-row-close-markup');
         if (!(false === $tail)) {
             $name = substr($key, 0, $tail);
             $templates[$name]['row-close'] = $value;
             continue;
         }
         $tail = strrpos($key, '-close-markup');
         if (!(false === $tail)) {
             $name = substr($key, 0, $tail);
             $templates[$name]['close'] = $value;
         }
     }
     // foreach
     return $templates;
 }
Esempio n. 10
0
 /**
  * Ajax handler for bulk editing and mapping
  *
  * @since 2.00
  *
  * @return	void	echo json results or error message, then die()
  */
 private static function _bulk_edit_ajax_handler()
 {
     MLACore::mla_debug_add('_bulk_edit_ajax_handler $_REQUEST = ' . var_export($_REQUEST, true), MLACore::MLA_DEBUG_CATEGORY_AJAX);
     /*
      * The category taxonomy (edit screens) is a special case because 
      * post_categories_meta_box() changes the input name
      */
     if (!isset($_REQUEST['tax_input'])) {
         $_REQUEST['tax_input'] = array();
     }
     if (isset($_REQUEST['post_category'])) {
         $_REQUEST['tax_input']['category'] = $_REQUEST['post_category'];
         unset($_REQUEST['post_category']);
     }
     /*
      * Convert bulk_action to the old button name/value variables
      */
     switch ($_REQUEST['bulk_action']) {
         case 'bulk_custom_field_map':
             $_REQUEST['bulk_custom_field_map'] = __('Map Custom Field metadata', 'media-library-assistant');
             break;
         case 'bulk_map':
             $_REQUEST['bulk_map'] = __('Map IPTC/EXIF metadata', 'media-library-assistant');
             break;
         case 'bulk_edit':
             $_REQUEST['bulk_edit'] = __('Update', 'media-library-assistant');
     }
     $item_content = (object) self::mla_process_bulk_action('edit');
     wp_send_json_success($item_content);
 }
 /**
  * MLA_List_Table inline edit item values
  *
  * Builds the Language dropdown and edit translation links for the
  * Quick and Bulk Edit forms, adding them to the 'custom_fields'
  * and 'bulk_custom_fields' substitution parameters.
  *
  * @since 2.11
  *
  * @param	array	$item_values parameter_name => parameter_value pairs
  *
  * @return	array	updated substitution parameter name => value pairs
  */
 public static function mla_list_table_inline_values($item_values)
 {
     global $polylang;
     // Find the first "language" column slug
     $language_column = '';
     foreach ($polylang->filters_columns->model->get_languages_list() as $language) {
         if (empty($polylang->filters_columns->curlang) || $language->slug != $polylang->filters_columns->curlang->slug) {
             $language_column = 'language_' . $language->slug;
             break;
         }
     }
     // do_action is required because the Polylang function uses "current_filter()" to compose its output
     ob_start();
     do_action('quick_edit_custom_box', $language_column, 'attachment');
     $value = ob_get_clean();
     if (empty($value)) {
         MLACore::mla_debug_add(__LINE__ . ' MLA_Polylang::mla_list_table_inline_values language_column = ' . var_export($language_column, true), MLACore::MLA_DEBUG_CATEGORY_ANY);
         MLACore::mla_debug_add(__LINE__ . ' MLA_Polylang::mla_list_table_inline_values $polylang->filters_columns->curlang = ' . var_export($polylang->filters_columns->curlang, true), MLACore::MLA_DEBUG_CATEGORY_ANY);
         MLACore::mla_debug_add(__LINE__ . ' MLA_Polylang::mla_list_table_inline_values $polylang->filters_columns->model->get_languages_list() = ' . var_export($polylang->filters_columns->model->get_languages_list(), true), MLACore::MLA_DEBUG_CATEGORY_ANY);
     }
     // Strip off <fieldset> and <div> tags around the <input> and <label> tags
     preg_match('/\\<input|\\<label/', $value, $match_start, PREG_OFFSET_CAPTURE);
     preg_match('/\\<\\/label[^\\>]*\\>/', $value, $match_end, PREG_OFFSET_CAPTURE);
     $item_values['custom_fields'] .= substr($value, $match_start[0][1], $match_end[0][1] + strlen($match_end[0][0]) - $match_start[0][1]);
     // Add the Translate links to the Quick Edit values
     if (array_key_exists('Quick Edit', $item_values)) {
         $actions = "<input name=\"inline_translations\" type=\"hidden\" value=\"\">\n";
         $actions .= "<input name=\"pll_quick_language\" type=\"hidden\" value=\"\">\n";
         $actions .= "<input name=\"pll_quick_id\" type=\"hidden\" value=\"\">\n";
         $actions .= "<input name=\"lang\" type=\"hidden\" value=\"\">\n";
         $actions .= "<label class=\"alignleft\" style=\"clear: both;\">\n<span class=\"title\">Translate</span>\n";
         $actions .= "<table class=\"pll-media-action-table\">\n";
         foreach ($polylang->model->get_languages_list() as $language) {
             $actions .= '<tr class = "pll-media-action-row-' . $language->slug . "\">\n";
             $actions .= '<td class = "pll-media-language-column"><span class = "pll-translation-flag">' . $language->flag . '</span>' . esc_html($language->name) . "</td>\n";
             $actions .= '<td class = "pll-media-action-column pll-media-action-column-' . $language->slug . '">';
             $actions .= sprintf('<input type="hidden" name="media_tr_lang[%s]" value="" /><a href="#pll-quick-translate-edit" title="" class=""></a>', esc_attr($language->slug));
             $actions .= "</td>\n";
             $actions .= "</tr>\n";
         }
         $actions .= "</table>\n</label>\n";
         $actions .= "<div class=\"pll-quick-translate-save\"><span class=\"spinner\" style=\"float: left;\"></span></div>\n";
         $item_values['custom_fields'] .= $actions;
     }
     ob_start();
     do_action('bulk_edit_custom_box', $language_column, 'attachment');
     $value = ob_get_clean();
     // Strip off <fieldset> and <div> tags around the <input> and <label> tags
     preg_match('/\\<input|\\<label/', $value, $match_start, PREG_OFFSET_CAPTURE);
     preg_match('/\\<\\/label[^\\>]*\\>/', $value, $match_end, PREG_OFFSET_CAPTURE);
     $item_values['bulk_custom_fields'] .= substr($value, $match_start[0][1], $match_end[0][1] + strlen($match_end[0][0]) - $match_start[0][1]);
     return $item_values;
 }
 /**
  * Ajax handler for IPTC/EXIF tab inline mapping
  *
  * @since 2.00
  *
  * @return	void	echo json response object, then die()
  */
 public static function mla_inline_mapping_iptc_exif_action()
 {
     MLACore::mla_debug_add('MLASettings::mla_inline_mapping_iptc_exif_action $_REQUEST = ' . var_export($_REQUEST, true), MLACore::MLA_DEBUG_CATEGORY_AJAX);
     set_current_screen($_REQUEST['screen']);
     check_ajax_referer(MLACore::MLA_ADMIN_NONCE_ACTION, MLACore::MLA_ADMIN_NONCE_NAME);
     /*
      * Convert the ajax bulk_action back to the older Submit button equivalent
      */
     if (!empty($_REQUEST['bulk_action'])) {
         switch ($_REQUEST['bulk_action']) {
             case 'iptc-exif-options-process-standard':
                 $_REQUEST['iptc-exif-options-process-standard'] = __('Map All Attachments, Standard Fields Now', 'media-library-assistant');
                 break;
             case 'iptc-exif-options-process-taxonomy':
                 $_REQUEST['iptc-exif-options-process-taxonomy'] = __('Map All Attachments, Taxonomy Terms Now', 'media-library-assistant');
                 break;
             case 'iptc-exif-options-process-custom':
                 $_REQUEST['iptc-exif-options-process-custom'] = __('Map All Attachments, Custom Fields Now', 'media-library-assistant');
                 break;
             default:
                 $match_count = preg_match('/iptc_exif_mapping\\[custom\\]\\[(.*)\\]\\[(.*)\\]\\[(.*)\\]/', $_REQUEST['bulk_action'], $matches);
                 if ($match_count) {
                     $_REQUEST['iptc_exif_mapping']['custom'][$matches[1]][$matches[2]][$matches[3]] = __('Map All Attachments', 'media-library-assistant');
                 }
         }
     }
     /*
      * Check for action or submit buttons.
      */
     if (isset($_REQUEST['iptc_exif_mapping']) && is_array($_REQUEST['iptc_exif_mapping'])) {
         /*
          * Find the current chunk
          */
         $offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : 0;
         $length = isset($_REQUEST['length']) ? $_REQUEST['length'] : 0;
         /*
          * Check for page-level submit button to map attachments.
          */
         if (!empty($_REQUEST['iptc-exif-options-process-standard'])) {
             $page_content = self::_process_iptc_exif_standard($offset, $length);
         } elseif (!empty($_REQUEST['iptc-exif-options-process-taxonomy'])) {
             $page_content = self::_process_iptc_exif_taxonomy($offset, $length);
         } elseif (!empty($_REQUEST['iptc-exif-options-process-custom'])) {
             $page_content = self::_process_iptc_exif_custom(NULL, $offset, $length);
         } else {
             $page_content = array('message' => '', 'body' => '', 'processed' => 0, 'unchanged' => 0, 'success' => 0);
             /*
              * Check for single-rule action buttons
              */
             foreach ($_REQUEST['iptc_exif_mapping']['custom'] as $key => $value) {
                 $value = stripslashes_deep($value);
                 if (isset($value['action'])) {
                     $settings = array('custom' => array($key => $value));
                     foreach ($value['action'] as $action => $label) {
                         switch ($action) {
                             case 'map_now':
                                 $page_content = self::_process_iptc_exif_custom($settings, $offset, $length);
                                 break;
                             case 'add_rule_map':
                                 if ('none' == $value['name']) {
                                     $page_content['message'] = __('IPTC/EXIF no mapping changes detected.', 'media-library-assistant');
                                     break;
                                 }
                                 // fallthru
                             // fallthru
                             case 'add_field_map':
                                 if ('' == $value['name']) {
                                     $page_content['message'] = __('IPTC/EXIF no mapping changes detected.', 'media-library-assistant');
                                     break;
                                 }
                                 if (0 == $offset) {
                                     $page_content = self::_save_iptc_exif_custom_settings($settings);
                                     if (false !== strpos($page_content['message'], __('ERROR', 'media-library-assistant'))) {
                                         $page_content['processed'] = 0;
                                         $page_content['unchanged'] = 0;
                                         $page_content['success'] = 0;
                                         break;
                                     }
                                 }
                                 $current_values = MLACore::mla_get_option('iptc_exif_mapping');
                                 $settings = array('custom' => array($value['name'] => $current_values['custom'][$value['name']]));
                                 $map_content = self::_process_iptc_exif_custom($settings, $offset, $length);
                                 $page_content['message'] .= '<br>&nbsp;<br>' . $map_content['message'];
                                 $page_content['processed'] = $map_content['processed'];
                                 $page_content['unchanged'] = $map_content['unchanged'];
                                 $page_content['success'] = $map_content['success'];
                                 $page_content['refresh'] = true;
                                 break;
                             default:
                                 // ignore everything else
                         }
                         //switch action
                     }
                     // foreach action
                 }
                 /// isset action
             }
             // foreach rule
         }
     } else {
         $page_content = array('message' => '', 'body' => '', 'processed' => 0, 'unchanged' => 0, 'success' => 0);
     }
     $chunk_results = array('message' => $page_content['message'], 'processed' => $page_content['processed'], 'unchanged' => $page_content['unchanged'], 'success' => $page_content['success'], 'refresh' => isset($page_content['refresh']) && true == $page_content['refresh']);
     MLACore::mla_debug_add('MLASettings::mla_inline_mapping_iptc_exif_action $chunk_results = ' . var_export($chunk_results, true), MLACore::MLA_DEBUG_CATEGORY_AJAX);
     wp_send_json_success($chunk_results);
 }
Esempio n. 13
0
 /**
  * Fetch and filter IPTC and EXIF, XMP or PDF metadata for an image attachment
  * 
  * @since 0.90
  *
  * @param	int		post ID of attachment
  * @param	string	optional; if $post_id is zero, path to the image file.
  *
  * @return	array	Meta data variables, IPTC and EXIF or PDF
  */
 public static function mla_fetch_attachment_image_metadata($post_id, $path = '')
 {
     $results = array('post_id' => $post_id, 'mla_iptc_metadata' => array(), 'mla_exif_metadata' => array(), 'mla_xmp_metadata' => array(), 'mla_pdf_metadata' => array());
     if (0 != $post_id) {
         $path = get_attached_file($post_id);
     }
     if (!empty($path)) {
         if ('pdf' == strtolower(pathinfo($path, PATHINFO_EXTENSION))) {
             if (!class_exists('MLAPDF')) {
                 require_once MLA_PLUGIN_PATH . 'includes/class-mla-data-pdf.php';
             }
             $pdf_metadata = MLAPDF::mla_extract_pdf_metadata($path);
             $results['mla_xmp_metadata'] = $pdf_metadata['xmp'];
             $results['mla_pdf_metadata'] = $pdf_metadata['pdf'];
             return $results;
         }
         $size = getimagesize($path, $info);
         if (is_callable('iptcparse')) {
             if (!empty($info['APP13'])) {
                 //set_error_handler( 'MLAData::mla_IPTC_EXIF_error_handler' );
                 $iptc_values = iptcparse($info['APP13']);
                 //restore_error_handler();
                 if (!empty(MLAData::$mla_IPTC_EXIF_errors)) {
                     $results['mla_iptc_errors'] = MLAData::$mla_IPTC_EXIF_errors;
                     MLAData::$mla_IPTC_EXIF_errors = array();
                     MLACore::mla_debug_add(__LINE__ . __('ERROR', 'media-library-assistant') . ': ' . '$results[mla_iptc_errors] = ' . var_export($results['mla_exif_errors'], true), MLACore::MLA_DEBUG_CATEGORY_ANY);
                 }
                 if (!is_array($iptc_values)) {
                     $iptc_values = array();
                 }
                 foreach ($iptc_values as $key => $value) {
                     if (in_array($key, array('1#000', '1#020', '1#022', '1#120', '1#122', '2#000', '2#200', '2#201'))) {
                         $value = unpack('nbinary', $value[0]);
                         $results['mla_iptc_metadata'][$key] = (string) $value['binary'];
                     } elseif (1 == count($value)) {
                         $results['mla_iptc_metadata'][$key] = $value[0];
                     } else {
                         $results['mla_iptc_metadata'][$key] = $value;
                     }
                 }
                 // foreach $value
             }
             // ! empty
         }
         // iptcparse
         if (is_callable('exif_read_data') && in_array($size[2], array(IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM))) {
             //set_error_handler( 'MLAData::mla_IPTC_EXIF_error_handler' );
             $results['mla_exif_metadata'] = $exif_data = @exif_read_data($path);
             //restore_error_handler();
             if (!empty(MLAData::$mla_IPTC_EXIF_errors)) {
                 $results['mla_exif_errors'] = MLAData::$mla_IPTC_EXIF_errors;
                 MLAData::$mla_IPTC_EXIF_errors = array();
                 MLACore::mla_debug_add(__LINE__ . __('ERROR', 'media-library-assistant') . ': ' . '$results[mla_exif_errors] = ' . var_export($results['mla_exif_errors'], true), MLACore::MLA_DEBUG_CATEGORY_ANY);
             }
         }
         // exif_read_data
         $results['mla_xmp_metadata'] = self::mla_parse_xmp_metadata($path, 0);
         if (NULL == $results['mla_xmp_metadata']) {
             $results['mla_xmp_metadata'] = array();
         }
         // experimental damage repair for Robert O'Conner (Rufus McDufus)
         if (isset($exif_data['DateTimeOriginal']) && 8 > strlen($exif_data['DateTimeOriginal'])) {
             if (isset($results['mla_xmp_metadata']['CreateDate']) && is_numeric(strtotime($results['mla_xmp_metadata']['CreateDate']))) {
                 $exif_data['BadDateTimeOriginal'] = $exif_data['DateTimeOriginal'];
                 $results['mla_exif_metadata']['BadDateTimeOriginal'] = $exif_data['DateTimeOriginal'];
                 $exif_data['DateTimeOriginal'] = $results['mla_xmp_metadata']['CreateDate'];
                 $results['mla_exif_metadata']['DateTimeOriginal'] = $results['mla_xmp_metadata']['CreateDate'];
             }
         }
         // experimental damage repair for Elsie Gilmore (earthnutvt)
         if (isset($exif_data['Keywords']) && '????' == substr($exif_data['Keywords'], 0, 4)) {
             if (isset($results['mla_xmp_metadata']['Keywords'])) {
                 $exif_data['Keywords'] = $results['mla_xmp_metadata']['Keywords'];
                 $results['mla_exif_metadata']['Keywords'] = $results['mla_xmp_metadata']['Keywords'];
             } else {
                 unset($exif_data['Keywords']);
                 unset($results['mla_exif_metadata']['Keywords']);
             }
         }
     }
     /*
      * Expand EXIF Camera-related values:
      *
      * ExposureBiasValue
      * ExposureTime
      * Flash
      * FNumber 
      * FocalLength
      * ShutterSpeed from ExposureTime
      */
     $new_data = array();
     if (isset($exif_data['FNumber'])) {
         if (false !== ($value = self::_rational_to_string($exif_data['FNumber'], '%1$d', '%1$d/%2$d', '%1$.1f'))) {
             $new_data['FNumber'] = $value;
         }
     }
     // FNumber
     if (isset($exif_data['ExposureBiasValue'])) {
         $fragments = array_map('intval', explode('/', $exif_data['ExposureBiasValue']));
         if (!is_null($fragments[1])) {
             $numerator = $fragments[0];
             $denominator = $fragments[1];
             // Clean up some common format issues, e.g. 4/6, 2/4
             while (0 == ($numerator & 0x1) && 0 == ($denominator & 0x1)) {
                 $numerator = $numerator >> 1;
                 $denominator = $denominator >> 1;
             }
             // Remove excess precision
             if ($denominator > $numerator && 1000 < $numerator && 1000 < $denominator) {
                 $exif_data['ExposureBiasValue'] = sprintf('%1$+.3f', $numerator / $denominator);
             } else {
                 $fragments[0] = $numerator;
                 $fragments[1] = $denominator;
                 $exif_data['ExposureBiasValue'] = $numerator . '/' . $denominator;
             }
         }
         if (false !== ($value = self::_rational_to_string($exif_data['ExposureBiasValue'], '%1$+d', '%1$+d/%2$d', '%1$+.2f'))) {
             $new_data['ExposureBiasValue'] = $value;
         }
     }
     // ExposureBiasValue
     if (isset($exif_data['Flash'])) {
         $value = absint($exif_data['Flash']);
         if ($value & 0x1) {
             $new_data['Flash'] = __('Yes', 'media-library-assistant');
         } else {
             $new_data['Flash'] = __('No', 'media-library-assistant');
         }
     }
     // Flash
     if (isset($exif_data['FocalLength'])) {
         if (false !== ($value = self::_rational_to_string($exif_data['FocalLength'], '%1$d', '%1$d/%2$d', '%1$.2f'))) {
             $new_data['FocalLength'] = $value;
         }
     }
     // FocalLength
     if (isset($exif_data['ExposureTime'])) {
         if (false !== ($value = self::_rational_to_string($exif_data['ExposureTime'], '%1$d', '%1$d/%2$d', '%1$.2f'))) {
             $new_data['ExposureTime'] = $value;
         }
     }
     // ExposureTime
     /*
      * ShutterSpeed in "1/" format, from ExposureTime
      * Special logic for "fractional shutter speed" values 1.3, 1.5, 1.6, 2.5
      */
     if (isset($exif_data['ExposureTime'])) {
         $fragments = array_map('intval', explode('/', $exif_data['ExposureTime']));
         if (!is_null($fragments[1] && $fragments[0])) {
             if (1 == $fragments[1]) {
                 $new_data['ShutterSpeed'] = $new_data['ExposureTime'] = sprintf('%1$d', $fragments[0]);
             } elseif (0 != $fragments[1]) {
                 $value = $fragments[0] / $fragments[1];
                 if (0 < $value && 1 > $value) {
                     // Convert to "1/" value for shutter speed
                     if (1 == $fragments[0]) {
                         $new_data['ShutterSpeed'] = $new_data['ExposureTime'];
                     } else {
                         $test = (double) number_format(1.0 / $value, 1, '.', '');
                         if (in_array($test, array(1.3, 1.5, 1.6, 2.5))) {
                             $new_data['ShutterSpeed'] = '1/' . number_format(1.0 / $value, 1, '.', '');
                         } else {
                             $new_data['ShutterSpeed'] = '1/' . number_format(1.0 / $value, 0, '.', '');
                         }
                     }
                 } else {
                     $new_data['ShutterSpeed'] = $new_data['ExposureTime'] = sprintf('%1$.2f', $value);
                 }
             }
             // fractional value
         }
         // valid denominator and non-zero numerator
     }
     // ShutterSpeed
     if (isset($exif_data['UndefinedTag:0xA420'])) {
         $new_data['ImageUniqueID'] = $exif_data['UndefinedTag:0xA420'];
     }
     if (isset($exif_data['UndefinedTag:0xA430'])) {
         $new_data['CameraOwnerName'] = $exif_data['UndefinedTag:0xA430'];
     }
     if (isset($exif_data['UndefinedTag:0xA431'])) {
         $new_data['BodySerialNumber'] = $exif_data['UndefinedTag:0xA431'];
     }
     if (isset($exif_data['UndefinedTag:0xA432']) && is_array($exif_data['UndefinedTag:0xA432'])) {
         $array = $new_data['LensSpecification'] = $exif_data['UndefinedTag:0xA432'];
         if (isset($array[0])) {
             if (false !== ($value = self::_rational_to_string($array[0], '%1$d', '%1$d/%2$d', '%1$.2f'))) {
                 $new_data['LensMinFocalLength'] = $value;
             }
         }
         if (isset($array[1])) {
             if (false !== ($value = self::_rational_to_string($array[1], '%1$d', '%1$d/%2$d', '%1$.2f'))) {
                 $new_data['LensMaxFocalLength'] = $value;
             }
         }
         if (isset($array[2])) {
             if (false !== ($value = self::_rational_to_string($array[2], '%1$d', '%1$d/%2$d', '%1$.1f'))) {
                 $new_data['LensMinFocalLengthFN'] = $value;
             }
         }
         if (isset($array[3])) {
             if (false !== ($value = self::_rational_to_string($array[3], '%1$d', '%1$d/%2$d', '%1$.1f'))) {
                 $new_data['LensMaxFocalLengthFN'] = $value;
             }
         }
     }
     if (isset($exif_data['UndefinedTag:0xA433'])) {
         $new_data['LensMake'] = $exif_data['UndefinedTag:0xA433'];
     }
     if (isset($exif_data['UndefinedTag:0xA434'])) {
         $new_data['LensModel'] = $exif_data['UndefinedTag:0xA434'];
     }
     if (isset($exif_data['UndefinedTag:0xA435'])) {
         $new_data['LensSerialNumber'] = $exif_data['UndefinedTag:0xA435'];
     }
     if (!empty($new_data)) {
         $results['mla_exif_metadata']['CAMERA'] = $new_data;
     }
     /*
      * Expand EXIF GPS values
      */
     $new_data = array();
     if (isset($exif_data['GPSVersion'])) {
         $new_data['Version'] = sprintf('%1$d.%2$d.%3$d.%4$d', ord($exif_data['GPSVersion'][0]), ord($exif_data['GPSVersion'][1]), ord($exif_data['GPSVersion'][2]), ord($exif_data['GPSVersion'][3]));
     }
     if (isset($exif_data['GPSLatitudeRef'])) {
         $new_data['LatitudeRef'] = $exif_data['GPSLatitudeRef'];
         $new_data['LatitudeRefS'] = 'N' == $exif_data['GPSLatitudeRef'] ? '' : '-';
         $ref = $new_data['LatitudeRef'];
         $refs = $new_data['LatitudeRefS'];
     } else {
         $ref = '';
         $refs = '';
     }
     if (isset($exif_data['GPSLatitude'])) {
         $rational = $exif_data['GPSLatitude'];
         $new_data['LatitudeD'] = $degrees = self::_rational_to_decimal($rational[0]);
         $new_data['LatitudeM'] = $minutes = self::_rational_to_decimal($rational[1]);
         $new_data['LatitudeS'] = sprintf('%1$01.4f', $seconds = self::_rational_to_decimal($rational[2]));
         $decimal_minutes = $minutes + $seconds / 60;
         $decimal_degrees = $decimal_minutes / 60;
         $new_data['Latitude'] = sprintf('%1$dd %2$d\' %3$01.4f" %4$s', $degrees, $minutes, $seconds, $ref);
         $new_data['LatitudeDM'] = sprintf('%1$d %2$01.4f', $degrees, $decimal_minutes);
         $new_data['LatitudeDD'] = sprintf('%1$01f', $degrees + $decimal_degrees);
         $new_data['LatitudeMinDec'] = substr($new_data['LatitudeDM'], strpos($new_data['LatitudeDM'], ' ') + 1);
         $new_data['LatitudeDegDec'] = substr($new_data['LatitudeDD'], strpos($new_data['LatitudeDD'], '.'));
         $new_data['LatitudeSDM'] = $refs . $new_data['LatitudeDM'];
         $new_data['LatitudeSDD'] = $refs . $new_data['LatitudeDD'];
         $new_data['LatitudeDM'] = $new_data['LatitudeDM'] . $ref;
         $new_data['LatitudeDD'] = $new_data['LatitudeDD'] . $ref;
     }
     if (isset($exif_data['GPSLongitudeRef'])) {
         $new_data['LongitudeRef'] = $exif_data['GPSLongitudeRef'];
         $new_data['LongitudeRefS'] = 'E' == $exif_data['GPSLongitudeRef'] ? '' : '-';
         $ref = $new_data['LongitudeRef'];
         $refs = $new_data['LongitudeRefS'];
     } else {
         $ref = '';
         $refs = '';
     }
     if (isset($exif_data['GPSLongitude'])) {
         $rational = $exif_data['GPSLongitude'];
         $new_data['LongitudeD'] = $degrees = self::_rational_to_decimal($rational[0]);
         $new_data['LongitudeM'] = $minutes = self::_rational_to_decimal($rational[1]);
         $new_data['LongitudeS'] = sprintf('%1$01.4f', $seconds = self::_rational_to_decimal($rational[2]));
         $decimal_minutes = $minutes + $seconds / 60;
         $decimal_degrees = $decimal_minutes / 60;
         $new_data['Longitude'] = sprintf('%1$dd %2$d\' %3$01.4f" %4$s', $degrees, $minutes, $seconds, $ref);
         $new_data['LongitudeDM'] = sprintf('%1$d %2$01.4f', $degrees, $decimal_minutes);
         $new_data['LongitudeDD'] = sprintf('%1$01f', $degrees + $decimal_degrees);
         $new_data['LongitudeMinDec'] = substr($new_data['LongitudeDM'], strpos($new_data['LongitudeDM'], ' ') + 1);
         $new_data['LongitudeDegDec'] = substr($new_data['LongitudeDD'], strpos($new_data['LongitudeDD'], '.'));
         $new_data['LongitudeSDM'] = $refs . $new_data['LongitudeDM'];
         $new_data['LongitudeSDD'] = $refs . $new_data['LongitudeDD'];
         $new_data['LongitudeDM'] = $new_data['LongitudeDM'] . $ref;
         $new_data['LongitudeDD'] = $new_data['LongitudeDD'] . $ref;
     }
     if (isset($exif_data['GPSAltitudeRef'])) {
         $new_data['AltitudeRef'] = sprintf('%1$d', ord($exif_data['GPSAltitudeRef'][0]));
         $new_data['AltitudeRefS'] = '0' == $new_data['AltitudeRef'] ? '' : '-';
         $refs = $new_data['AltitudeRefS'];
     } else {
         $refs = '';
     }
     if (isset($exif_data['GPSAltitude'])) {
         $new_data['Altitude'] = sprintf('%1$s%2$01.4f', $refs, $meters = self::_rational_to_decimal($exif_data['GPSAltitude']));
         $new_data['AltitudeFeet'] = sprintf('%1$s%2$01.2f', $refs, $meters * 3.280839895013);
     }
     if (isset($exif_data['GPSTimeStamp'])) {
         $rational = $exif_data['GPSTimeStamp'];
         $new_data['TimeStampH'] = sprintf('%1$02d', $hours = self::_rational_to_decimal($rational[0]));
         $new_data['TimeStampM'] = sprintf('%1$02d', $minutes = self::_rational_to_decimal($rational[1]));
         $new_data['TimeStampS'] = sprintf('%1$02d', $seconds = self::_rational_to_decimal($rational[2]));
         $new_data['TimeStamp'] = sprintf('%1$02d:%2$02d:%3$02d', $hours, $minutes, $seconds);
     }
     if (isset($exif_data['GPSDateStamp'])) {
         $parts = explode(':', $exif_data['GPSDateStamp']);
         $new_data['DateStampY'] = $parts[0];
         $new_data['DateStampM'] = $parts[1];
         $new_data['DateStampD'] = $parts[2];
         $new_data['DateStamp'] = $exif_data['GPSDateStamp'];
     }
     if (isset($exif_data['GPSMapDatum'])) {
         $new_data['MapDatum'] = $exif_data['GPSMapDatum'];
     }
     if (!empty($new_data)) {
         $results['mla_exif_metadata']['GPS'] = $new_data;
     }
     //error_log( __LINE__ . " mla_fetch_attachment_image_metadata( {$post_id} ) results = " . var_export( $results, true ), 0 );
     return $results;
 }