View source
<?php
include_once drupal_get_path('module', 'exif') . '/ExifInterface.php';
function exif_menu() {
$items['admin/config/media/exif'] = array(
'title' => 'Image Metadata',
'page callback' => 'exif_admin_settings',
'access arguments' => array(
'administer image metadata',
),
'description' => t('Display available fields'),
'access callback' => 'user_access',
'file' => 'exif.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/media/exif/general'] = array(
'title' => 'Image Metadata',
'page callback' => 'exif_admin_settings',
'access arguments' => array(
'administer image metadata',
),
'description' => t('Display available fields'),
'access callback' => 'user_access',
'file' => 'exif.admin.inc',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/media/exif/settings'] = array(
'title' => 'Image Metadata fields settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'exif_admin_settings_form',
),
'access arguments' => array(
'administer image metadata',
),
'description' => t('Images Metadata Settings'),
'access callback' => 'user_access',
'file' => 'exif.admin.inc',
'type' => MENU_LOCAL_TASK,
);
return $items;
}
function exif_help($path, $arg) {
include_once drupal_get_path('module', 'exif') . '/exif.admin.inc';
switch ($path) {
case 'admin/help#exif':
return exif_admin_settings();
case 'admin/help/exif':
return exif_admin_settings();
}
}
function exif_permission() {
return array(
'administer image metadata' => array(
'title' => t('Administer image metadata'),
),
);
}
function _exif_node_insert_update($object_type, $object, $update = TRUE) {
$type = $object->type;
$fields = field_info_instances($object_type, $type);
if (_exif_check_for_exif_data($type)) {
$exif = _exif_get_class();
$ar_exif_fields = _exif_filter_fields_on_widgets($fields);
$ar_exif_fields = $exif
->getMetadataFields($ar_exif_fields);
if (!$update && property_exists($object, 'original')) {
$original = $object->original;
foreach ($ar_exif_fields as $drupal_field => $metadata_field_descriptor) {
$field_name = $drupal_field;
if (property_exists($object, $field_name) && property_exists($original, $field_name)) {
$object->{$field_name} = $original->{$field_name};
}
}
}
else {
$image_fields = _exif_get_image_fields($object_type, $object, $fields);
$metadata_images_fields = _exif_get_image_fields_metadata($object_type, $object, $ar_exif_fields, $image_fields);
foreach ($ar_exif_fields as $drupal_field => $metadata_field_descriptor) {
$field_name = $drupal_field;
$field_type = $fields[$field_name];
$tmp = NULL;
if (property_exists($object, $field_name)) {
$tmp = $object->{$field_name};
}
$language = $metadata_field_descriptor['language'];
if ($tmp == NULL) {
$tmp = array(
$language => array(),
);
}
$key = $metadata_field_descriptor['metadata_field']['tag'];
$section = $metadata_field_descriptor['metadata_field']['section'];
if (array_key_exists($metadata_field_descriptor['image_field'], $metadata_images_fields)) {
$values = array();
foreach ($metadata_images_fields[$metadata_field_descriptor['image_field']] as $metadata_image_fields) {
if (array_key_exists($section, $metadata_image_fields) && array_key_exists($key, $metadata_image_fields[$section])) {
$value = $metadata_image_fields[$section][$key];
if (is_string($value) && isset($metadata_field_descriptor['metadata_field_separator'])) {
$subValues = explode($metadata_field_descriptor['metadata_field_separator'], $value);
foreach ($subValues as $index => $subValue) {
$values[] = $subValue;
}
}
else {
$values[] = $value;
}
}
}
$j = 0;
foreach ($values as $innerkey => $value) {
if (is_array($value)) {
foreach ($value as $subkey => $subvalue) {
_exif_handle_field($j, $language, $field_type, $tmp, $section, $key, $subvalue);
$j++;
}
}
else {
_exif_handle_field($j, $language, $field_type, $tmp, $section, $key, $value);
$j++;
}
}
$object->{$field_name} = $tmp;
}
}
}
}
}
function _exif_get_image_fields_metadata($object_type, $node, &$ar_exif_fields, $image_fields) {
$result = array();
if (empty($ar_exif_fields)) {
return TRUE;
}
if (empty($image_fields)) {
return FALSE;
}
$exif = _exif_get_class();
foreach ($ar_exif_fields as $drupal_field => $metadata_settings) {
$field_image_name = $metadata_settings['image_field'];
if (empty($image_fields[$field_image_name])) {
$result[$field_image_name] = array();
}
else {
$images_descriptor = _exif_get_file_uri_and_language($node, $field_image_name, $object_type);
if ($images_descriptor == FALSE) {
$fullmetadata = array();
}
else {
foreach ($images_descriptor as $index => $image_descriptor) {
$fullmetadata[$index] = _exif_get_data_from_file_uri($exif, $image_descriptor['uri']);
}
}
$result[$field_image_name] = $fullmetadata;
$ar_exif_fields[$drupal_field]['language'] = $image_descriptor['language'];
}
}
return $result;
}
function _exif_get_file_uri_and_language($node, $field_image_name, $object_type) {
if ($object_type == 'node') {
$result = array();
if (!is_array($node->{$field_image_name})) {
return FALSE;
}
else {
$field_image = $node->{$field_image_name};
$language = _exif_get_image_language($node, $field_image);
if ($language == FALSE) {
return FALSE;
}
else {
$fids = _exif_get_image_fid($field_image, $language);
if ($fids == FALSE) {
return FALSE;
}
else {
foreach ($fids as $index => $fid) {
$file = file_load($fid);
$result[$index]['uri'] = $file->uri;
$result[$index]['language'] = $language;
}
}
}
}
}
else {
if ($object_type == 'file') {
$result[0]['uri'] = $node->uri;
$result[0]['language'] = 'und';
}
}
return $result;
}
function _exif_get_data_from_file_uri($exif, $file_uri) {
$metadata =& drupal_static(__FUNCTION__);
if (!isset($metadata) || !isset($metadata[$file_uri])) {
if (stream_is_local($file_uri)) {
$absolute_file_path = drupal_realpath($file_uri);
$metadata[$file_uri] = $exif
->readMetadataTags($absolute_file_path);
}
else {
$tmp_name = drupal_tempnam(file_directory_temp(), 'exif') . '.' . pathinfo($file_uri, PATHINFO_EXTENSION);
if (copy($file_uri, $tmp_name)) {
$metadata[$file_uri] = $exif
->readMetadataTags($tmp_name);
@drupal_unlink($tmp_name);
}
else {
$metadata[$file_uri] = array();
}
}
}
return $metadata[$file_uri];
}
function _exif_handle_field($index, $language, $field_type, &$field_data, $exif_section, $exif_name, $exif_value) {
$field = field_info_field($field_type['field_name']);
if ($field['module'] == 'text') {
_exif_handle_text_field($index, $language, $field, $field_type, $field_data, $exif_section, $exif_name, $exif_value);
}
else {
if ($field['module'] == 'taxonomy' || $field['module'] == 'i18n_taxonomy') {
_exif_handle_taxonomy_field($index, $language, $field, $field_type, $field_data, $exif_section, $exif_name, $exif_value);
}
else {
if ($field['module'] == 'date') {
_exif_handle_date_field($index, $language, $field, $field_type, $field_data, $exif_section, $exif_name, $exif_value);
}
}
}
}
function _exif_handle_field_value_consistency($exif_value, $field) {
if (!drupal_validate_utf8($exif_value)) {
$exif_value = check_plain(utf8_encode($exif_value));
}
if (!empty($field['settings']['max_length'])) {
$exif_value = truncate_utf8($exif_value, $field['settings']['max_length'], TRUE, TRUE);
}
return $exif_value;
}
function _exif_handle_text_field($index, $language, $field, $field_type, &$field_data, $exif_section, $exif_name, $exif_value) {
$field_data[$language][$index]['value'] = _exif_handle_field_value_consistency($exif_value, $field);
}
function _exif_handle_date_field($index, $language, $field, $field_type, &$field_data, $exif_section, $exif_name, $exif_value) {
$exif_value = _exif_handle_field_value_consistency($exif_value, $field);
if ($exif_name == 'filedatetime') {
$format = DateObject::ATOM;
}
else {
$format = variable_get('date_format_exif', 'Y-m-d\\TH:i:s');
}
$date_datetime = new DateObject($exif_value, NULL, $format);
$date_datetime
->setTimezone(timezone_open(date_get_timezone($field['settings']['tz_handling'])));
$offset = $date_datetime
->getOffset();
$date_field = $date_datetime
->format(date_type_format($field['type']));
$field_data[$language][$index] = array(
'value' => $date_field,
'value2' => $date_field,
'timezone' => $date_datetime
->getTimezone(),
'offset' => $offset,
'offset2' => $offset,
);
}
function _exif_handle_taxonomy_field($index, $language, $field, $field_type, &$field_data, $exif_section, $exif_name, $exif_value) {
$exif_value = _exif_handle_field_value_consistency($exif_value, $field);
$chosen_vocabulary = $field['settings']['allowed_values'][0]['vocabulary'];
if (isset($chosen_vocabulary)) {
$vocabularies = taxonomy_vocabulary_get_names();
if (is_array($vocabularies) && isset($vocabularies[$chosen_vocabulary])) {
$vocabulary = $vocabularies[$chosen_vocabulary];
$terms = taxonomy_get_term_by_name($exif_value, $chosen_vocabulary);
if (is_array($terms) && count($terms) > 0) {
$term = array_shift($terms);
$field_data[$language][$index]['tid'] = $term->tid;
}
else {
$terms = taxonomy_get_term_by_name($exif_name, $chosen_vocabulary);
if (is_array($terms) && count($terms) > 0) {
$parent_term = array_shift($terms);
}
else {
$terms = taxonomy_get_term_by_name($exif_section, $chosen_vocabulary);
if (is_array($terms) && count($terms) > 0) {
$section_term = array_shift($terms);
}
else {
$section_term = _exif_create_term($vocabulary->vid, $exif_section);
}
$parent_term = _exif_create_term($vocabulary->vid, $exif_name, $section_term->tid);
}
$term = _exif_create_term($vocabulary->vid, $exif_value, $parent_term->tid);
if (isset($term->tid)) {
$field_data[$language][$index]['tid'] = $term->tid;
}
}
}
}
}
function _exif_create_term($vid, $name, $parent_term = 0) {
$term = new stdClass();
$term->vid = $vid;
$term->name = $name;
$term->parent = array(
$parent_term,
);
taxonomy_term_save($term);
return $term;
}
function exif_field_attach_presave($obj_type, $object) {
if ($obj_type == 'node' || $obj_type == 'file') {
$shouldUpdateMetadata = variable_get('exif_update', TRUE);
_exif_node_insert_update($obj_type, $object, $shouldUpdateMetadata);
}
}
function exif_date_format_types() {
return array(
'exif' => 'Exif',
);
}
function exif_date_formats() {
return array(
array(
'type' => 'exif',
'format' => 'Y:m:d H:i:s',
),
);
}
function _exif_check_for_exif_data($node_type) {
$new_types = array();
foreach (variable_get('exif_nodetypes', array()) as $type) {
if ($type != "0") {
$new_types[] = $type;
}
}
foreach (variable_get('exif_mediatypes', array()) as $type) {
if ($type != "0") {
$new_types[] = $type;
}
}
if (in_array($node_type, $new_types)) {
return TRUE;
}
return FALSE;
}
function _exif_get_image_fields($object_type, $object, $fields) {
$result = array();
if ($object_type == 'node') {
foreach ($fields as $key => $value) {
if (is_array($value) && is_array($value['widget']) && ($value['widget']['type'] == 'image_image' || $value['widget']['type'] == 'media_generic' || $value['widget']['type'] == 'image_miw')) {
$result[$key] = $value;
}
}
}
if ($object_type == 'file') {
$result['file'] = $object;
}
return $result;
}
function _exif_get_image_language($node, $field) {
if (property_exists($node, 'language')) {
if (array_key_exists($node->language, $field)) {
return $node->language;
}
else {
if (array_key_exists('und', $field)) {
return 'und';
}
else {
return FALSE;
}
}
}
else {
return FALSE;
}
}
function _exif_get_image_fid($field, $language) {
$fids = array();
if (is_array($field[$language]) && !empty($field[$language])) {
foreach ($field[$language] as $index => $value) {
if (is_array($value)) {
$fids[] = $value['fid'];
}
}
}
else {
return FALSE;
}
return $fids;
}
function _exif_get_class() {
include_once drupal_get_path('module', 'exif') . '/ExifFactory.php';
$exif = \Drupal\exif\ExifFactory::getExifInterface();
return $exif;
}
function exif_field_widget_info() {
return array(
'exif_readonly' => array(
'label' => t('metadata from image'),
'description' => t('field content is calculated from image field in the same content type (read only)'),
'field types' => array(
'text',
'text_long',
'text_with_summary',
'taxonomy_term_reference',
'date',
'datetime',
'datestamp',
),
'settings' => array(
'image_field' => '',
'exif_field' => '',
'exif_field_separator' => '',
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
'default value' => FIELD_BEHAVIOR_DEFAULT,
),
),
);
}
function exif_field_widget_info_alter(&$info) {
$field_types = array(
'text',
'text_long',
'taxonomy_term_reference',
'date',
'datetime',
'datestamp',
);
$info['options_select']['field types'] = array_unique(array_merge($info['options_select']['field types'], $field_types));
$info['options_buttons']['field types'] = array_unique(array_merge($info['options_buttons']['field types'], $field_types));
}
function exif_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$defaults = field_info_widget_settings($widget['type']);
$settings = array_merge($defaults, $widget['settings']);
$form = array();
if ($widget['type'] == 'exif_readonly') {
$exif_fields = _exif_field_widget_retrieve_exif_fields();
$default_exif_value = _exif_get_field_widget_retrieve_exif_field_default_value($widget);
$default_exif_separator_value = _exif_get_field_widget_retrieve_exif_field_separator_default_value($widget);
if ($instance['entity_type'] == 'node') {
$image_fields = _exif_field_widget_retrieve_image_field_from_bundle($instance['entity_type'], $instance['bundle']);
$default_image_value = _exif_get_field_widget_retrieve_image_field_default_value($widget, $image_fields);
$form['image_field'] = array(
'#type' => 'radios',
'#title' => t('image field to use to retrieve data'),
'#description' => t('determine the image used to look for exif and iptc metadata'),
'#options' => $image_fields,
'#default_value' => $default_image_value,
'#element_validate' => array(
'_exif_field_widget_image_field_validate',
),
);
}
if ($instance['entity_type'] == 'file') {
$form['image_field'] = array(
'#type' => 'hidden',
'#default_value' => "file",
'#value' => "file",
);
}
$form['exif_field'] = array(
'#type' => 'select',
'#title' => t('exif field data'),
'#description' => t('These settings will automatically retrieve data from the image field referenced.'),
'#options' => array_merge(array(
'naming_convention' => 'name of the field is the exif field name',
), $exif_fields),
'#default_value' => $default_exif_value,
'#element_validate' => array(
'_exif_field_widget_exif_field_validate',
),
);
$form['exif_field_separator'] = array(
'#type' => 'textfield',
'#title' => t('exif field separator'),
'#description' => t('separator used to split values (if field definition support several values). let it empty if you do not want to split values.'),
'#default_value' => $default_exif_separator_value,
'#element_validate' => array(
'_exif_field_widget_exif_field_separator_validate',
),
);
}
return $form;
}
function _exif_get_field_widget_retrieve_image_field_default_value($widget, $image_fields) {
$result = $widget['settings']['image_field'];
if (empty($result)) {
$temp = array_keys($image_fields);
if (!empty($temp) && is_array($temp)) {
$result = $temp[0];
}
}
return $result;
}
function _exif_get_field_widget_retrieve_exif_field_default_value($widget) {
$result = $widget['settings']['exif_field'];
if (empty($result)) {
$result = 'naming_convention';
}
return $result;
}
function _exif_get_field_widget_retrieve_exif_field_separator_default_value($widget) {
$result = $widget['settings']['exif_field_separator'];
if (empty($result)) {
$result = '';
}
return $result;
}
function exif_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$form['#attached']['css'][] = drupal_get_path('module', 'exif') . '/exif.css';
$element_info = element_info($field['type']);
$element += array(
'#type' => '#hidden',
'#value' => '',
'#process' => array_merge(array(
'exif_field_readonly_widget_process',
)),
);
return $element;
}
function _exif_field_widget_retrieve_image_field_from_bundle($entity_type, $bundle_name) {
$fields_of_bundle = field_info_instances($entity_type, $bundle_name);
$result = array();
foreach ($fields_of_bundle as $key => $value) {
if (is_array($value) && is_array($value['widget']) && ($value['widget']['type'] == 'image_image' || $value['widget']['type'] == 'media_generic' || $value['widget']['type'] == 'image_miw')) {
$result[$key] = $value['label'] . " (" . $key . ")";
}
}
return $result;
}
function _exif_field_widget_retrieve_exif_fields() {
$exif = _exif_get_class();
return $exif
->getFieldKeys();
}
function _exif_field_widget_image_field_validate($element, &$form_state) {
$image_field_settings = $form_state['values']['instance']['widget']['settings']['image_field'];
if (empty($image_field_settings)) {
form_error($element, t('you must choose at least one image field to retrieve metadata.'));
}
}
function _exif_field_widget_exif_field_validate($element, &$form_state) {
$exif_field_settings = $form_state['values']['instance']['widget']['settings']['exif_field'];
if (empty($exif_field_settings)) {
form_error($element, t('you must choose at least one method to retrieve image metadata.'));
}
}
function _exif_field_widget_exif_field_separator_validate($element, &$form_state) {
$exif_field_settings = $form_state['values']['instance']['widget']['settings']['exif_field_separator'];
if (!empty($exif_field_settings) && strlen($exif_field_settings) > 1) {
form_error($element, t('the separator is only one character long.'));
}
}
function _exif_filter_fields_on_widgets($fields_of_bundle) {
$result = array();
foreach ($fields_of_bundle as $key => $value) {
if ($value['widget']['type'] == 'exif_readonly') {
$element = array();
if ($value['widget']['settings']['exif_field'] == 'naming_convention') {
$name = substr($key, 6);
}
else {
$name = $value['widget']['settings']['exif_field'];
}
$element['metadata_field'] = $name;
if (isset($value['widget']['settings']['exif_field_separator']) && !empty($value['widget']['settings']['exif_field_separator'])) {
$element['metadata_field_separator'] = $value['widget']['settings']['exif_field_separator'];
}
if (!isset($value['widget']['settings']['image_field']) && isset($value['widget']['settings']['media_generic'])) {
$element['image_field'] = $value['widget']['settings']['media_generic'];
}
else {
$element['image_field'] = $value['widget']['settings']['image_field'];
}
$result[$key] = $element;
}
}
return $result;
}
function exif_field_widget_error($element, $error, $form, &$form_state) {
form_error($element, $error['message']);
}
function exif_field_widget_validate($element, &$form_state) {
}
function exif_field_readonly_widget_process($element, &$form_state, $form) {
$instance = field_widget_instance($element, $form_state);
$settings = $instance['settings'];
$widget_settings = $instance['widget']['settings'];
$element['tid'] = array(
'#type' => 'hidden',
'#value' => '',
);
$element['value'] = array(
'#type' => 'hidden',
'#value' => '',
);
$element['timezone'] = array(
'#type' => 'hidden',
'#value' => '',
);
$element['value2'] = array(
'#type' => 'hidden',
'#value' => '',
);
return $element;
}