/** * 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; }
/** * Process bulk edit area fields, which may contain a Content Template * * @since 1.80 * * @param integer Current post ID * @param string Field value as entered * * @return string Empty, or new value for the field */ private static function _process_bulk_value($post_id, $bulk_value) { $new_value = trim($bulk_value); if ('template:[+empty+]' == $new_value) { return NULL; } elseif ('template:' == substr($new_value, 0, 9)) { $data_value = array('data_source' => 'template', 'meta_name' => substr($new_value, 9), 'keep_existing' => false, 'format' => 'raw', 'option' => 'text'); $new_value = MLAOptions::mla_get_data_source($post_id, 'single_attachment_mapping', $data_value); if (' ' == $new_value) { $new_value = ''; } } elseif (!empty($new_value)) { // preserve leading/trailing whitespace on non-empty entered values return $bulk_value; } return $new_value; }
/** * Analyze a template, expanding Field-level Markup Substitution Parameters * * Field-level parameters must have one of the following prefix values: * template, request, query, custom, terms, meta, iptc, exif, xmp, pdf. * All but request and query require an attachment ID. * * @since 1.50 * * @param string A formatting string containing [+placeholders+] * @param array Optional: an array of values from the query, if any, e.g. shortcode parameters * @param array Optional: an array of values to add to the returned array * @param integer Optional: attachment ID for attachment-specific placeholders * @param boolean Optional: for option 'multi', retain existing values * @param string Optional: default option value * * @return array ( parameter => value ) for all field-level parameters and anything in $markup_values */ public static function mla_expand_field_level_parameters($tpl, $query = NULL, $markup_values = array(), $post_id = 0, $keep_existing = false, $default_option = 'text') { static $cached_post_id = 0, $item_metadata = NULL, $attachment_metadata = NULL, $id3_metadata = NULL; if ($cached_post_id != $post_id) { $item_metadata = NULL; $attachment_metadata = NULL; $id3_metadata = NULL; $cached_post_id = $post_id; } $placeholders = self::mla_get_template_placeholders($tpl, $default_option); $template_count = 0; foreach ($placeholders as $key => $value) { if (isset($markup_values[$key])) { continue; } switch ($value['prefix']) { case 'template': $markup_values = self::mla_expand_field_level_parameters($value['value'], $query, $markup_values, $post_id, $keep_existing, $default_option); $template_count++; break; case 'meta': if (is_null($item_metadata)) { if (0 < $post_id) { $item_metadata = get_metadata('post', $post_id, '_wp_attachment_metadata', true); } else { break; } } $markup_values[$key] = self::mla_find_array_element($value['value'], $item_metadata, $value['option']); break; case 'query': if (isset($query) && isset($query[$value['value']])) { $markup_values[$key] = $query[$value['value']]; } else { $markup_values[$key] = ''; } break; case 'request': if (isset($_REQUEST[$value['value']])) { $record = $_REQUEST[$value['value']]; } else { $record = ''; } if (is_scalar($record)) { $text = sanitize_text_field((string) $record); } elseif (is_array($record)) { if ('export' == $value['option']) { $text = sanitize_text_field(var_export($record, true)); } else { $text = ''; foreach ($record as $term) { $term_name = sanitize_text_field($term); $text .= strlen($text) ? ',' . $term_name : $term_name; } } } // is_array $markup_values[$key] = $text; break; case 'terms': if (0 < $post_id) { $terms = get_object_term_cache($post_id, $value['value']); if (false === $terms) { $terms = wp_get_object_terms($post_id, $value['value']); wp_cache_add($post_id, $terms, $value['value'] . '_relationships'); } } else { break; } $text = ''; if (is_wp_error($terms)) { $text = implode(',', $terms->get_error_messages()); } elseif (!empty($terms)) { if ('single' == $value['option'] || 1 == count($terms)) { reset($terms); $term = current($terms); $text = sanitize_term_field('name', $term->name, $term->term_id, $value['value'], 'display'); } elseif ('export' == $value['option']) { $text = sanitize_text_field(var_export($terms, true)); } else { foreach ($terms as $term) { $term_name = sanitize_term_field('name', $term->name, $term->term_id, $value['value'], 'display'); $text .= strlen($text) ? ', ' . $term_name : $term_name; } } } $markup_values[$key] = $text; break; case 'custom': if (0 < $post_id) { $record = get_metadata('post', $post_id, $value['value'], 'single' == $value['option']); if (empty($record) && 'ALL_CUSTOM' == $value['value']) { $meta_values = self::mla_fetch_attachment_metadata($post_id); $clean_data = array(); foreach ($meta_values as $meta_key => $meta_value) { if (0 !== strpos($meta_key, 'mla_item_')) { continue; } $meta_key = substr($meta_key, 9); if (is_array($meta_value)) { $clean_data[$meta_key] = '(ARRAY)'; } elseif (is_string($meta_value)) { $clean_data[$meta_key] = self::_bin_to_utf8(substr($meta_value, 0, 256)); } else { $clean_data[$meta_key] = $meta_value; } } // foreach value /* * Convert the array to text, strip the outer "array( ... ,)" literal, * the interior linefeed/space/space separators and backslashes. */ $record = var_export($clean_data, true); $record = substr($record, 7, strlen($record) - 10); $record = str_replace(chr(0xa) . ' ', ' ', $record); $record = str_replace('\\', '', $record); } // ALL_CUSTOM } else { break; } $text = ''; if (is_wp_error($record)) { $text = implode(',', $record->get_error_messages()); } elseif (!empty($record)) { if (is_scalar($record)) { $text = 'raw' == $value['format'] ? (string) $record : sanitize_text_field((string) $record); } elseif (is_array($record)) { if ('export' == $value['option']) { $text = 'raw' == $value['format'] ? var_export($record, true) : sanitize_text_field(var_export($record, true)); } else { $text = ''; foreach ($record as $term) { $term_name = 'raw' == $value['format'] ? $term : sanitize_text_field($term); $text .= strlen($text) ? ', ' . $term_name : $term_name; } } } // is_array } // ! empty $markup_values[$key] = $text; break; case 'iptc': if (is_null($attachment_metadata)) { if (0 < $post_id) { $attachment_metadata = self::mla_fetch_attachment_image_metadata($post_id); } else { break; } } $markup_values[$key] = self::mla_iptc_metadata_value($value['value'], $attachment_metadata, $value['option'], $keep_existing); break; case 'exif': if (is_null($attachment_metadata)) { if (0 < $post_id) { $attachment_metadata = self::mla_fetch_attachment_image_metadata($post_id); } else { break; } } $record = self::mla_exif_metadata_value($value['value'], $attachment_metadata, $value['option'], $keep_existing); if (is_array($record)) { $markup_values[$key] = self::_process_field_level_array($record, $value['option'], $keep_existing); } else { $markup_values[$key] = $record; } break; case 'xmp': if (is_null($attachment_metadata)) { if (0 < $post_id) { $attachment_metadata = self::mla_fetch_attachment_image_metadata($post_id); } else { break; } } $markup_values[$key] = self::mla_xmp_metadata_value($value['value'], $attachment_metadata['mla_xmp_metadata'], $value['option'], $keep_existing); break; case 'id3': if (is_null($id3_metadata)) { if (0 < $post_id) { $id3_metadata = self::mla_fetch_attachment_id3_metadata($post_id); } else { break; } } $markup_values[$key] = self::mla_id3_metadata_value($value['value'], $id3_metadata, $value['option'], $keep_existing); break; case 'pdf': if (is_null($attachment_metadata)) { if (0 < $post_id) { $attachment_metadata = self::mla_fetch_attachment_image_metadata($post_id); } else { break; } } $record = self::mla_pdf_metadata_value($value['value'], $attachment_metadata); if (is_array($record)) { $markup_values[$key] = self::_process_field_level_array($record, $value['option'], $keep_existing); } else { $markup_values[$key] = $record; } break; case '': $candidate = str_replace('{', '[', str_replace('}', ']', $value['value'])); $key = str_replace('{', '[', str_replace('}', ']', $key)); if (MLAOptions::mla_is_data_source($candidate)) { $data_value = array('data_source' => $candidate, 'keep_existing' => false, 'format' => 'raw', 'option' => $value['option']); // single, export, text for array values, e.g., alt_text $markup_values[$key] = MLAOptions::mla_get_data_source($post_id, 'single_attachment_mapping', $data_value); } elseif (isset($markup_values[$value['value']])) { /* * A standard element can have a format modifier, e.g., commas, attr */ $markup_values[$key] = $markup_values[$value['value']]; } break; default: // ignore anything else } // switch if (isset($markup_values[$key])) { $markup_values[$key] = self::mla_apply_field_level_format($markup_values[$key], $value); } // isset( $markup_values[ $key ] ) } // foreach placeholder if ($template_count) { $markup_values['[+template_count+]'] = $template_count; } return $markup_values; }