/**
  * Evaluate IPTC/EXIF mapping updates for a post
  *
  * @since 1.00
  *
  * @param	object 	post object with current values
  * @param	string 	category to evaluate against, e.g., iptc_exif_standard_mapping or iptc_exif_mapping
  * @param	array 	(optional) iptc_exif_mapping values, default - current option value
  * @param	array 	(optional) _wp_attachment_metadata, for MLAOptions::mla_update_attachment_metadata_filter
  * @param	boolean	(optional) true if uploading a new item else false (default)
  *
  * @return	array	Updates suitable for MLAData::mla_update_single_item, if any
  */
 public static function mla_evaluate_iptc_exif_mapping($post, $category, $settings = NULL, $attachment_metadata = NULL, $is_upload = false)
 {
     $image_metadata = MLAData::mla_fetch_attachment_image_metadata($post->ID);
     /*
      * Make the PDF/XMP metadata available as EXIF values so simple rules like "EXIF:Keywords" will work
      */
     if (empty($image_metadata['mla_exif_metadata'])) {
         if (!empty($image_metadata['mla_xmp_metadata'])) {
             $image_metadata['mla_exif_metadata'] = $image_metadata['mla_xmp_metadata'];
         } elseif (!empty($image_metadata['mla_pdf_metadata'])) {
             $image_metadata['mla_exif_metadata'] = $image_metadata['mla_pdf_metadata'];
         }
     }
     $updates = array();
     $update_all = 'iptc_exif_mapping' == $category;
     $data_source_category = $update_all ? 'single_attachment_mapping' : 'custom_field_mapping';
     if (NULL == $settings) {
         $settings = MLACore::mla_get_option('iptc_exif_mapping');
     }
     $settings = apply_filters('mla_mapping_settings', $settings, $post->ID, $category, $attachment_metadata);
     if ($update_all || 'iptc_exif_standard_mapping' == $category) {
         foreach ($settings['standard'] as $setting_key => $setting_value) {
             $setting_value = apply_filters('mla_mapping_rule', $setting_value, $post->ID, 'iptc_exif_standard_mapping', $attachment_metadata);
             if (NULL === $setting_value) {
                 continue;
             }
             if ('none' == $setting_value['iptc_value']) {
                 $iptc_value = '';
             } else {
                 $iptc_value = MLAData::mla_iptc_metadata_value($setting_value['iptc_value'], $image_metadata);
             }
             $iptc_value = apply_filters('mla_mapping_iptc_value', $iptc_value, $setting_key, $post->ID, 'iptc_exif_standard_mapping', $attachment_metadata);
             if ('template:[+empty+]' == $setting_value['exif_value']) {
                 $exif_value = NULL;
             } elseif ('template:' == substr($setting_value['exif_value'], 0, 9)) {
                 $data_value = array('name' => $setting_key, 'data_source' => 'template', 'meta_name' => substr($setting_value['exif_value'], 9), 'keep_existing' => $setting_value['keep_existing'], 'format' => 'native', 'option' => 'text');
                 $exif_value = MLAOptions::mla_get_data_source($post->ID, $data_source_category, $data_value, $attachment_metadata);
                 if (' ' == $exif_value) {
                     $exif_value = '';
                 }
             } else {
                 $exif_value = MLAData::mla_exif_metadata_value($setting_value['exif_value'], $image_metadata);
             }
             $exif_value = apply_filters('mla_mapping_exif_value', $exif_value, $setting_key, $post->ID, 'iptc_exif_standard_mapping', $attachment_metadata);
             $keep_existing = (bool) $setting_value['keep_existing'];
             if ($setting_value['iptc_first']) {
                 if (!empty($iptc_value)) {
                     $new_text = $iptc_value;
                 } else {
                     $new_text = $exif_value;
                 }
             } else {
                 if (!empty($exif_value) || is_null($exif_value)) {
                     $new_text = $exif_value;
                 } else {
                     $new_text = $iptc_value;
                 }
             }
             $new_text = apply_filters('mla_mapping_new_text', $new_text, $setting_key, $post->ID, 'iptc_exif_standard_mapping', $attachment_metadata);
             if (is_array($new_text)) {
                 $new_text = implode(',', $new_text);
             }
             // Handle 'template:[+empty+]'
             if (is_null($new_text)) {
                 $updates[$setting_key] = '';
                 continue;
             }
             /*
              * See /wp-includes/formatting.php, function convert_chars()
              *
              * Metadata tags <<title>> and <<category>> are removed, <<br>> and <<hr>> are
              * converted into correct XHTML and Unicode characters are converted to the
              * valid range.
              */
             $new_text = trim(convert_chars($new_text));
             if (!empty($new_text)) {
                 switch ($setting_key) {
                     case 'post_title':
                         if ((empty($post->post_title) || !$keep_existing) && (trim($new_text) && !is_numeric(sanitize_title($new_text)))) {
                             $updates[$setting_key] = $new_text;
                         }
                         break;
                     case 'post_name':
                         $updates[$setting_key] = wp_unique_post_slug(sanitize_title($new_text), $post->ID, $post->post_status, $post->post_type, $post->post_parent);
                         break;
                     case 'image_alt':
                         $old_text = get_metadata('post', $post->ID, '_wp_attachment_image_alt', true);
                         if (empty($old_text) || !$keep_existing) {
                             $updates[$setting_key] = $new_text;
                         }
                         break;
                     case 'post_excerpt':
                         if (empty($post->post_excerpt) || !$keep_existing) {
                             $updates[$setting_key] = $new_text;
                         }
                         break;
                     case 'post_content':
                         if (empty($post->post_content) || !$keep_existing) {
                             $updates[$setting_key] = $new_text;
                         }
                         break;
                     default:
                         // ignore anything else
                 }
                 // $setting_key
             }
         }
         // foreach new setting
     }
     // update standard field mappings
     if ($update_all || 'iptc_exif_taxonomy_mapping' == $category) {
         $tax_inputs = array();
         $tax_actions = array();
         foreach ($settings['taxonomy'] as $setting_key => $setting_value) {
             if (!MLACore::mla_taxonomy_support($setting_key, 'support')) {
                 continue;
             }
             /*
              * Convert checkbox value(s)
              */
             $hierarchical = $setting_value['hierarchical'] = (bool) $setting_value['hierarchical'];
             $setting_value = apply_filters('mla_mapping_rule', $setting_value, $post->ID, 'iptc_exif_taxonomy_mapping', $attachment_metadata);
             if (NULL === $setting_value) {
                 continue;
             }
             if ('none' == $setting_value['iptc_value']) {
                 $iptc_value = '';
             } else {
                 $iptc_value = MLAData::mla_iptc_metadata_value($setting_value['iptc_value'], $image_metadata);
             }
             $iptc_value = apply_filters('mla_mapping_iptc_value', $iptc_value, $setting_key, $post->ID, 'iptc_exif_taxonomy_mapping', $attachment_metadata);
             if ('template:' == substr($setting_value['exif_value'], 0, 9)) {
                 $data_value = array('name' => $setting_key, 'data_source' => 'template', 'meta_name' => substr($setting_value['exif_value'], 9), 'keep_existing' => $setting_value['keep_existing'], 'format' => 'native', 'option' => 'array');
                 $exif_value = MLAOptions::mla_get_data_source($post->ID, $data_source_category, $data_value, $attachment_metadata);
                 if (' ' == $exif_value) {
                     $exif_value = '';
                 }
             } else {
                 $exif_value = MLAData::mla_exif_metadata_value($setting_value['exif_value'], $image_metadata);
             }
             $exif_value = apply_filters('mla_mapping_exif_value', $exif_value, $setting_key, $post->ID, 'iptc_exif_taxonomy_mapping', $attachment_metadata);
             $tax_action = $setting_value['keep_existing'] ? 'add' : 'replace';
             $tax_parent = isset($setting_value['parent']) && 0 != (int) $setting_value['parent'] ? (int) $setting_value['parent'] : 0;
             if ($setting_value['iptc_first']) {
                 if (!empty($iptc_value)) {
                     $new_text = $iptc_value;
                 } else {
                     $new_text = $exif_value;
                 }
             } else {
                 if (!empty($exif_value)) {
                     $new_text = $exif_value;
                 } else {
                     $new_text = $iptc_value;
                 }
             }
             /*
              * Parse out individual terms
              */
             if (!empty($setting_value['delimiters'])) {
                 $text = $setting_value['delimiters'];
                 $delimiters = array();
                 while (!empty($text)) {
                     $delimiters[] = $text[0];
                     $text = substr($text, 1);
                 }
             } else {
                 $delimiters = array(_x(',', 'tag_delimiter', 'media-library-assistant'));
             }
             if (is_scalar($new_text)) {
                 $new_text = array($new_text);
             }
             foreach ($delimiters as $delimiter) {
                 $new_terms = array();
                 foreach ($new_text as $text) {
                     $fragments = explode($delimiter, $text);
                     foreach ($fragments as $fragment) {
                         if (MLATest::$wp_3dot5) {
                             $fragment = trim(stripslashes_deep($fragment));
                         } else {
                             $fragment = trim(wp_unslash($fragment));
                         }
                         if (!empty($fragment)) {
                             $new_terms[] = $fragment;
                         }
                     }
                     // foreach fragment
                 }
                 // foreach $text
                 $new_text = array_unique($new_terms);
             }
             // foreach $delimiter
             $new_text = apply_filters('mla_mapping_new_text', $new_text, $setting_key, $post->ID, 'iptc_exif_taxonomy_mapping', $attachment_metadata);
             if (empty($new_text)) {
                 continue;
             }
             $current_terms = array();
             if (!$is_upload) {
                 $post_terms = get_object_term_cache($post->ID, $setting_key);
                 if (false === $post_terms) {
                     $post_terms = wp_get_object_terms($post->ID, $setting_key);
                     wp_cache_add($post->ID, $post_terms, $setting_key . '_relationships');
                 }
                 foreach ($post_terms as $new_term) {
                     if ($hierarchical) {
                         $current_terms[$new_term->term_id] = $new_term->term_id;
                     } else {
                         $current_terms[$new_term->name] = $new_term->name;
                     }
                 }
             }
             /*
              * Hierarchical taxonomies require term_id, flat require term names
              */
             if ($hierarchical) {
                 /*
                  * Convert text to term_id
                  */
                 $new_terms = array();
                 foreach ($new_text as $new_term) {
                     if (0 < ($new_term = MLAOptions::_get_term_id($new_term, $tax_parent, $setting_key, $post_terms))) {
                         $new_terms[] = $new_term;
                     }
                 }
                 // foreach new_term
             } else {
                 $new_terms = $new_text;
             }
             if ('replace' == $tax_action) {
                 /*
                  * If the new terms match the term cache, we can skip the update
                  */
                 foreach ($new_terms as $new_term) {
                     if (isset($current_terms[$new_term])) {
                         unset($current_terms[$new_term]);
                     } else {
                         $current_terms[$new_term] = $new_term;
                         break;
                         // not a match; stop checking
                     }
                 }
                 $do_update = !empty($current_terms);
             } else {
                 /*
                  * We are adding terms; remove existing terms
                  */
                 foreach ($new_terms as $index => $new_term) {
                     if (isset($current_terms[esc_attr($new_term)])) {
                         unset($new_terms[$index]);
                     }
                 }
                 $do_update = !empty($new_terms);
             }
             if ($do_update) {
                 $tax_inputs[$setting_key] = $new_terms;
                 $tax_actions[$setting_key] = $tax_action;
             }
         }
         // foreach new setting
         if (!empty($tax_inputs)) {
             $updates['taxonomy_updates'] = array('inputs' => $tax_inputs, 'actions' => $tax_actions);
         }
     }
     // update taxonomy term mappings
     if ($update_all || 'iptc_exif_custom_mapping' == $category) {
         $custom_updates = array();
         foreach ($settings['custom'] as $setting_key => $setting_value) {
             /*
              * Convert checkbox value(s)
              */
             $setting_value['no_null'] = isset($setting_value['no_null']);
             $setting_name = $setting_value['name'];
             $setting_value = apply_filters('mla_mapping_rule', $setting_value, $post->ID, 'iptc_exif_custom_mapping', $attachment_metadata);
             if (NULL === $setting_value) {
                 continue;
             }
             if ('none' == $setting_value['iptc_value']) {
                 $iptc_value = '';
             } else {
                 $data_value = array('name' => $setting_key, 'data_source' => 'template', 'meta_name' => '([+iptc:' . $setting_value['iptc_value'] . '+])', 'keep_existing' => $setting_value['keep_existing'], 'format' => $setting_value['format'], 'option' => $setting_value['option']);
                 $iptc_value = MLAOptions::mla_get_data_source($post->ID, $data_source_category, $data_value, $attachment_metadata);
                 if (' ' == $iptc_value) {
                     $iptc_value = '';
                 }
             }
             $iptc_value = apply_filters('mla_mapping_iptc_value', $iptc_value, $setting_key, $post->ID, 'iptc_exif_custom_mapping', $attachment_metadata);
             $exif_value = trim($setting_value['exif_value']);
             if (!empty($exif_value)) {
                 $data_value = array('name' => $setting_key, 'data_source' => 'template', 'keep_existing' => $setting_value['keep_existing'], 'format' => $setting_value['format'], 'option' => $setting_value['option']);
                 if ('template:' == substr($exif_value, 0, 9)) {
                     $data_value['meta_name'] = substr($exif_value, 9);
                 } else {
                     $data_value['meta_name'] = '([+exif:' . $exif_value . '+])';
                 }
                 $exif_value = MLAOptions::mla_get_data_source($post->ID, $data_source_category, $data_value, $attachment_metadata);
                 if (' ' == $exif_value) {
                     $exif_value = '';
                 }
             }
             $exif_value = apply_filters('mla_mapping_exif_value', $exif_value, $setting_key, $post->ID, 'iptc_exif_custom_mapping', $attachment_metadata);
             if ($setting_value['iptc_first']) {
                 if (!empty($iptc_value)) {
                     $new_text = $iptc_value;
                 } else {
                     $new_text = $exif_value;
                 }
             } else {
                 if (!empty($exif_value)) {
                     $new_text = $exif_value;
                 } else {
                     $new_text = $iptc_value;
                 }
             }
             $new_text = apply_filters('mla_mapping_new_text', $new_text, $setting_key, $post->ID, 'iptc_exif_custom_mapping', $attachment_metadata);
             if ($setting_value['keep_existing']) {
                 if ('meta:' == substr($setting_name, 0, 5)) {
                     $meta_key = substr($setting_name, 5);
                     if (NULL === $attachment_metadata) {
                         $attachment_metadata = maybe_unserialize(get_metadata('post', $post->ID, '_wp_attachment_metadata', true));
                     }
                     if (array($attachment_metadata)) {
                         $old_value = MLAData::mla_find_array_element($meta_key, $attachment_metadata, 'array');
                     } else {
                         $old_value = '';
                     }
                 } else {
                     if (is_string($old_value = get_metadata('post', $post->ID, $setting_name, true))) {
                         $old_value = trim($old_value);
                     }
                 }
                 if (!empty($new_text) && empty($old_value)) {
                     $custom_updates[$setting_name] = $new_text;
                 }
             } else {
                 // } keep_existing
                 if (empty($new_text) && $setting_value['no_null']) {
                     $new_text = NULL;
                 }
                 $custom_updates[$setting_name] = $new_text;
             }
         }
         // foreach new setting
         if (!empty($custom_updates)) {
             $updates['custom_updates'] = $custom_updates;
         }
     }
     // update custom field mappings
     $updates = apply_filters('mla_mapping_updates', $updates, $post->ID, $category, $settings, $attachment_metadata);
     return $updates;
 }
 /**
  * Evaluate IPTC/EXIF mapping updates for a post
  *
  * @since 1.00
  *
  * @param	object 	post object with current values
  * @param	string 	category to evaluate against, e.g., iptc_exif_standard_mapping or iptc_exif_mapping
  * @param	array 	(optional) iptc_exif_mapping values, default - current option value
  *
  * @return	array	Updates suitable for MLAData::mla_update_single_item, if any
  */
 public static function mla_evaluate_iptc_exif_mapping($post, $category, $settings = NULL)
 {
     $metadata = MLAData::mla_fetch_attachment_image_metadata($post->ID);
     $updates = array();
     $update_all = 'iptc_exif_mapping' == $category;
     if (NULL == $settings) {
         $settings = self::mla_get_option('iptc_exif_mapping');
     }
     if ($update_all || 'iptc_exif_standard_mapping' == $category) {
         foreach ($settings['standard'] as $new_key => $new_value) {
             if ('none' == $new_value['iptc_value']) {
                 $iptc_value = '';
             } else {
                 $iptc_value = MLAData::mla_iptc_metadata_value($new_value['iptc_value'], $metadata);
             }
             if ('template:' == substr($new_value['exif_value'], 0, 9)) {
                 $data_value = array('name' => $new_key, 'data_source' => 'template', 'meta_name' => substr($new_value['exif_value'], 9), 'keep_existing' => $new_value['keep_existing'], 'format' => 'native', 'option' => 'text');
                 $exif_value = self::_evaluate_data_source($post->ID, 'single_attachment_mapping', $data_value, $metadata);
             } else {
                 $exif_value = MLAData::mla_exif_metadata_value($new_value['exif_value'], $metadata);
             }
             $keep_existing = (bool) $new_value['keep_existing'];
             if ($new_value['iptc_first']) {
                 if (!empty($iptc_value)) {
                     $new_text = $iptc_value;
                 } else {
                     $new_text = $exif_value;
                 }
             } else {
                 if (!empty($exif_value)) {
                     $new_text = $exif_value;
                 } else {
                     $new_text = $iptc_value;
                 }
             }
             if (is_array($new_text)) {
                 $new_text = implode(',', $new_text);
             }
             $new_text = trim(convert_chars($new_text));
             if (!empty($new_text)) {
                 switch ($new_key) {
                     case 'post_title':
                         if ((empty($post->post_title) || !$keep_existing) && (trim($new_text) && !is_numeric(sanitize_title($new_text)))) {
                             $updates[$new_key] = $new_text;
                         }
                         break;
                     case 'post_name':
                         $updates[$new_key] = wp_unique_post_slug(sanitize_title($new_text), $post->ID, $post->post_status, $post->post_type, $post->post_parent);
                         break;
                     case 'image_alt':
                         $old_text = get_metadata('post', $post->ID, '_wp_attachment_image_alt', true);
                         if (empty($old_text) || !$keep_existing) {
                             $updates[$new_key] = $new_text;
                         }
                         break;
                     case 'post_excerpt':
                         if (empty($post->post_excerpt) || !$keep_existing) {
                             $updates[$new_key] = $new_text;
                         }
                         break;
                     case 'post_content':
                         if (empty($post->post_content) || !$keep_existing) {
                             $updates[$new_key] = $new_text;
                         }
                         break;
                     default:
                         // ignore anything else
                 }
             }
             // $new_key
         }
         // foreach new setting
     }
     // update standard field mappings
     if ($update_all || 'iptc_exif_taxonomy_mapping' == $category) {
         $tax_inputs = array();
         $tax_actions = array();
         foreach ($settings['taxonomy'] as $new_key => $new_value) {
             if ('none' == $new_value['iptc_value']) {
                 $iptc_value = '';
             } else {
                 $iptc_value = MLAData::mla_iptc_metadata_value($new_value['iptc_value'], $metadata);
             }
             if ('template:' == substr($new_value['exif_value'], 0, 9)) {
                 $data_value = array('name' => $new_key, 'data_source' => 'template', 'meta_name' => substr($new_value['exif_value'], 9), 'keep_existing' => $new_value['keep_existing'], 'format' => 'native', 'option' => 'array');
                 $exif_value = self::_evaluate_data_source($post->ID, 'single_attachment_mapping', $data_value, $metadata);
             } else {
                 $exif_value = MLAData::mla_exif_metadata_value($new_value['exif_value'], $metadata);
             }
             $tax_action = $new_value['keep_existing'] ? 'add' : 'replace';
             $tax_parent = isset($new_value['parent']) && 0 != (int) $new_value['parent'] ? (int) $new_value['parent'] : 0;
             if ($new_value['iptc_first']) {
                 if (!empty($iptc_value)) {
                     $new_text = $iptc_value;
                 } else {
                     $new_text = $exif_value;
                 }
             } else {
                 if (!empty($exif_value)) {
                     $new_text = $exif_value;
                 } else {
                     $new_text = $iptc_value;
                 }
             }
             if (!empty($new_text)) {
                 if ($new_value['hierarchical']) {
                     if (is_string($new_text)) {
                         $new_text = array($new_text);
                     }
                     $new_terms = array();
                     foreach ($new_text as $new_term) {
                         $term_object = term_exists($new_term, $new_key);
                         if ($term_object !== 0 && $term_object !== null) {
                             $new_terms[] = $term_object['term_id'];
                         } else {
                             $term_object = wp_insert_term($new_term, $new_key, array('parent' => $tax_parent));
                             if (isset($term_object['term_id'])) {
                                 $new_terms[] = $term_object['term_id'];
                             }
                         }
                     }
                     // foreach new_term
                     $tax_inputs[$new_key] = $new_terms;
                 } else {
                     $tax_inputs[$new_key] = $new_text;
                 }
                 $tax_actions[$new_key] = $tax_action;
             }
             // new_text
         }
         // foreach new setting
         if (!empty($tax_inputs)) {
             $updates['taxonomy_updates'] = array('inputs' => $tax_inputs, 'actions' => $tax_actions);
         }
     }
     // update taxonomy term mappings
     if ($update_all || 'iptc_exif_custom_mapping' == $category) {
         $custom_updates = array();
         foreach ($settings['custom'] as $new_key => $new_value) {
             if ('none' == $new_value['iptc_value']) {
                 $iptc_value = '';
             } else {
                 $iptc_value = MLAData::mla_iptc_metadata_value($new_value['iptc_value'], $metadata);
             }
             if ('template:' == substr($new_value['exif_value'], 0, 9)) {
                 $data_value = array('name' => $new_key, 'data_source' => 'template', 'meta_name' => substr($new_value['exif_value'], 9), 'keep_existing' => $new_value['keep_existing'], 'format' => 'native', 'option' => 'text');
                 $exif_value = self::_evaluate_data_source($post->ID, 'single_attachment_mapping', $data_value, $metadata);
             } else {
                 $exif_value = MLAData::mla_exif_metadata_value($new_value['exif_value'], $metadata);
             }
             if ($new_value['iptc_first']) {
                 if (!empty($iptc_value)) {
                     $new_text = $iptc_value;
                 } else {
                     $new_text = $exif_value;
                 }
             } else {
                 if (!empty($exif_value)) {
                     $new_text = $exif_value;
                 } else {
                     $new_text = $iptc_value;
                 }
             }
             if (is_array($new_text)) {
                 $new_text = implode(',', $new_text);
             }
             if ($new_value['keep_existing']) {
                 if ('meta:' == substr($new_key, 0, 5)) {
                     $meta_key = substr($new_key, 5);
                     $attachment_metadata = maybe_unserialize(get_metadata('post', $post->ID, '_wp_attachment_metadata', true));
                     if (array($attachment_metadata)) {
                         $old_value = MLAData::mla_find_array_element($meta_key, $attachment_metadata, 'array');
                     } else {
                         $old_value = '';
                     }
                 } else {
                     if (is_string($old_value = get_metadata('post', $post->ID, $new_key, true))) {
                         $old_value = trim($old_value);
                     }
                 }
                 if (!empty($new_text) && empty($old_value)) {
                     $custom_updates[$new_key] = $new_text;
                 }
             } else {
                 $custom_updates[$new_key] = $new_text;
             }
         }
         // foreach new setting
         if (!empty($custom_updates)) {
             $updates['custom_updates'] = $custom_updates;
         }
     }
     // update custom field mappings
     return $updates;
 }