Same filename and directory in other branches
  1. 8.x-1.x exif.module 1 comment
  2. 8.x-2.x exif.module 1 comment

Primary hook implementations for the EXIF module.

File

./exif.module

View source
<?php


/**
 * @file
 * Primary hook implementations for the EXIF module.
 */
use Drupal\exif\ExifFactory;
include_once drupal_get_path('module', 'exif') . '/ExifInterface.php';

/**
 * Implements hook_menu().
 */
function exif_menu() {
    $items['admin/config/media/exif'] = array(
        'title' => 'Image Metadata',
        'page callback' => 'exif_admin_settings',
        'access arguments' => array(
            'administer image metadata',
        ),
        'description' => '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' => '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' => 'Images Metadata Settings',
        'access callback' => 'user_access',
        'file' => 'exif.admin.inc',
        'type' => MENU_LOCAL_TASK,
    );
    return $items;
}

/**
 * Implements hook_help().
 */
function exif_help($path, $arg) {
    include_once drupal_get_path('module', 'exif') . '/exif.admin.inc';
    switch ($path) {
        case 'admin/help#exif':
        case 'admin/help/exif':
            return exif_admin_settings();
    }
}

/**
 * Implements hook_permission().
 */
function exif_permission() {
    return array(
        'administer image metadata' => array(
            'title' => t('Administer image metadata (EXIF)'),
            'restrict access' => TRUE,
        ),
    );
}

/**
 * Main entrypoint of the module.
 *
 * @param string $object_type
 * @param object $object
 */
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) {
                        // Case for keywords.
                        if (is_array($value)) {
                            foreach ($value as $subkey => $subvalue) {
                                _exif_handle_field($j, $language, $field_type, $tmp, $section, $key, $subvalue);
                                $j++;
                            }
                            // Others.
                        }
                        else {
                            _exif_handle_field($j, $language, $field_type, $tmp, $section, $key, $value);
                            $j++;
                        }
                    }
                    $object->{$field_name} = $tmp;
                }
            }
        }
    }
}

/**
 *
 *
 * @param string $object_type
 * @param object $node
 * @param array $exif_fields
 * @param array $image_fields
 */
function _exif_get_image_fields_metadata($object_type, $node, array &$exif_fields, array $image_fields) {
    $result = array();
    if (empty($exif_fields)) {
        return TRUE;
    }
    if (empty($image_fields)) {
        return FALSE;
    }
    $exif = _exif_get_class();
    foreach ($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);
            $fullmetadata = array();
            if (!empty($images_descriptor)) {
                foreach ($images_descriptor as $index => $image_descriptor) {
                    $fullmetadata[$index] = _exif_get_data_from_file_uri($exif, $image_descriptor['uri']);
                }
            }
            $result[$field_image_name] = $fullmetadata;
            // @todo This was failing because the image_descriptor variable didn't
            // exist. Track down where this came from and work out why it's was
            // written this way; it might have just been an oversight.
            if (isset($image_descriptor['language'])) {
                $exif_fields[$drupal_field]['language'] = $image_descriptor['language'];
            }
            else {
                $exif_fields[$drupal_field]['language'] = LANGUAGE_NONE;
            }
        }
    }
    return $result;
}

/**
 *
 *
 * @param object $node
 * @param string $field_image_name
 * @param string $object_type
 */
function _exif_get_file_uri_and_language($node, $field_image_name, $object_type) {
    $result = array();
    if ($object_type == 'node') {
        // Escape early if the field doesn't exist or the field does not contain an
        // array.
        if (!isset($node->{$field_image_name}) || !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;
                    }
                }
            }
        }
    }
    elseif ($object_type == 'file') {
        $result[0]['uri'] = $node->uri;
        $result[0]['language'] = 'und';
    }
    return $result;
}

/**
 * Get EXIF data from file or stream wrapper.
 *
 * Caches the meta data in a static variable so we don't have to process the
 * file several times.
 *
 * @param object $exif
 *   EXIF class object.
 * @param string $file_uri
 *   File or stream wrapper to get EXIF data from.
 *
 * @return array
 *   EXIF meta data.
 */
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)) {
            // If $file_uri is a local stream pass the real path to
            // Exif::readMetadataTags().
            $absolute_file_path = drupal_realpath($file_uri);
            $metadata[$file_uri] = $exif->readMetadataTags($absolute_file_path);
        }
        else {
            // If $file_uri is not a local stream copy the file to local temp file and
            // pass that file to Exif::readMetadataTags.
            $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 {
                // If we failed to create the temporary file make sure we at least
                // return an empty array.
                $metadata[$file_uri] = array();
            }
        }
    }
    return $metadata[$file_uri];
}

/**
 * Handle field by delegating to specific type handler.
 *
 * @param int $index
 * @param string $field_type
 * @param array $field_data
 * @param string $exif_section
 * @param string $exif_name
 * @param string $exif_value
 */
function _exif_handle_field($index, $language, $field_type, array &$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);
    }
    elseif ($field['module'] == 'taxonomy' || $field['module'] == 'i18n_taxonomy') {
        _exif_handle_taxonomy_field($index, $language, $field, $field_type, $field_data, $exif_section, $exif_name, $exif_value);
    }
    elseif ($field['module'] == 'date') {
        _exif_handle_date_field($index, $language, $field, $field_type, $field_data, $exif_section, $exif_name, $exif_value);
    }
}

/**
 *
 *
 * @param string $exif_value
 * @param array $field
 */
function _exif_handle_field_value_consistency($exif_value, array $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;
}

/**
 * Handle text field.
 *
 * @param int $index
 * @param string $language
 * @param array $field
 * @param string $field_type
 * @param array $field_data
 * @param string $exif_section
 * @param string $exif_name
 * @param string $exif_value
 */
function _exif_handle_text_field($index, $language, array $field, $field_type, array &$field_data, $exif_section, $exif_name, $exif_value) {
    $field_data[$language][$index]['value'] = _exif_handle_field_value_consistency($exif_value, $field);
}

/**
 * Handle date field.
 *
 * @param int $index
 * @param string $language
 * @param array $field
 * @param string $field_type
 * @param array $field_data
 * @param string $exif_section
 * @param string $exif_name
 * @param string $exif_value
 */
function _exif_handle_date_field($index, $language, array $field, $field_type, array &$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 {
        // EXIF internal format do not handle timezone :(
        // Using website timezone instead.
        $format = variable_get('date_format_exif', 'Y-m-d\\TH:i:s');
    }
    $date_datetime = new DateObject($exif_value, NULL, $format);
    // Change to requeted timezone.
    $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,
    );
}

/**
 * Handle taxonomy field.
 *
 * @param int $index
 * @param string $language
 * @param array $field
 * @param string $field_type
 * @param array $field_data
 * @param string $exif_section
 * @param string $exif_name
 * @param string $exif_value
 */
function _exif_handle_taxonomy_field($index, $language, array $field, $field_type, array &$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 {
                // @todo make auto-creation optional even if vocabulary exist.
                // if not exist, create it
                // store full metadata in vocabulary
                $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;
                }
            }
        }
    }
}

/**
 * Create a term in the specified vocabulary.
 *
 * @param int $vid
 *   The ID of the vocabulary to add the term to.
 * @param string $name
 *   The name of the taxonomy term.
 * @param int $parent_term
 *   The parent term ID; defaults to 0.
 *
 * @return object
 *   The newly created term object.
 */
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;
}

/**
 * Implements hook_field_attach_presave().
 */
function exif_field_attach_presave($obj_type, $object) {
    // Calculate the value for each metadata field so they can be stored
    // correctly.
    if ($obj_type == 'node' || $obj_type == 'file') {
        $shouldUpdateMetadata = variable_get('exif_update', TRUE);
        _exif_node_insert_update($obj_type, $object, $shouldUpdateMetadata);
    }
}

/**
 * Date API hook.
 *
 * Make exif a date format in Date API. This makes it possible to alter the
 * format exif dates is parsed as.
 */
function exif_date_format_types() {
    return array(
        'exif' => 'EXIF',
    );
}

/**
 * Date API hook.
 *
 * Make the EXIF date format default for the 'exif' date type.
 *
 * @return array
 */
function exif_date_formats() {
    return array(
        array(
            'type' => 'exif',
            'format' => 'Y:m:d H:i:s',
        ),
    );
}

/**
 * Let's check if this node type contains an image field.
 *
 * @param string $node_type
 *   The content type to process.
 *
 * @return bool
 */
function _exif_check_for_exif_data($node_type) {
    $new_types = array();
    // Fill up array with checked nodetypes.
    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;
}

/**
 *
 *
 * @param string $object_type
 * @param object $object
 * @param array $fields
 *
 * @return array
 */
function _exif_get_image_fields($object_type, $object, array $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;
}

/**
 *
 * @param object $node
 * @param string $field
 *
 * @return string|bool
 */
function _exif_get_image_language($node, $field) {
    if (property_exists($node, 'language')) {
        if (array_key_exists($node->language, $field)) {
            return $node->language;
        }
        elseif (array_key_exists(LANGUAGE_NONE, $field)) {
            return LANGUAGE_NONE;
        }
        else {
            return FALSE;
        }
    }
    else {
        return FALSE;
    }
}

/**
 *
 *
 * @param array $field
 * @param string $language
 *
 * @return bool|array
 */
function _exif_get_image_fid(array $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;
}

/**
 * Helper function to get the exif class.
 *
 * @return \Exif
 */
function _exif_get_class() {
    include_once drupal_get_path('module', 'exif') . '/ExifFactory.php';
    $exif = ExifFactory::getExifInterface();
    return $exif;
}
//
// NEW VERSION FOR CONFIGURING FIELD. USING NEW FIELD WIDGET API.
//

/**
 * Implements hook_field_widget_info().
 */
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,
            ),
        ),
    );
}

/**
 * Implements hook_field_widget_info_alter().
 */
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));
}

/**
 * Implements hook_widget_settings().
 */
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;
}

/**
 * Calculate default value for settings form of widget.
 *
 * @param array $widget
 * @param array $image_fields
 *
 * @return string
 */
function _exif_get_field_widget_retrieve_image_field_default_value(array $widget, array $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;
}

/**
 * Calculate default value for settings form of widget.
 *
 * @param array $widget
 *
 * @return string
 */
function _exif_get_field_widget_retrieve_exif_field_default_value(array $widget) {
    $result = $widget['settings']['exif_field'];
    if (empty($result)) {
        $result = 'naming_convention';
    }
    return $result;
}

/**
 * Calculate default value for settings form of widget.
 *
 * @param array $widget
 *
 * @return string
 */
function _exif_get_field_widget_retrieve_exif_field_separator_default_value(array $widget) {
    $result = $widget['settings']['exif_field_separator'];
    if (empty($result)) {
        $result = '';
    }
    return $result;
}

/**
 * Implements hook_field_widget_form().
 */
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;
}

/**
 * Retrieve all image_field fields of the same content type (bundle)
 *
 * @param string $entity_type
 * @param string $bundle_name
 *
 * @return array
 */
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;
}

/**
 * Retrieve all field keys possible.
 *
 * @return array
 */
function _exif_field_widget_retrieve_exif_fields() {
    $exif = _exif_get_class();
    return $exif->getFieldKeys();
}

/**
 * Implementation of #element_validate FAPI Hook.
 */
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.'));
    }
}

/**
 * Implementation of #element_validate FAPI Hook.
 */
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.'));
    }
}

/**
 * Form API validation callback.
 */
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.'));
    }
}

/**
 *
 * @param array $fields_of_bundle
 *
 * @return array
 */
function _exif_filter_fields_on_widgets(array $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;
}

/**
 * FormAPI error handler.
 *
 * @todo Is this still needed?
 */
function exif_field_widget_error($element, $error, $form, &$form_state) {
    form_error($element, $error['message']);
}

/**
 * FormAPI validation callback.
 *
 * @todo Is this still needed?
 */
function exif_field_widget_validate($element, &$form_state) {
    // DO NOT CHANGE VALIDATION.
}

/**
 * Callback function call when a element of type exif_readonly is used.
 *
 * Handler added to element_info in exif_field_widget_form.
 * Handle image metadata widget fields.
 *
 * @param array $element
 *   The form element being processed.
 * @param array $form_state
 *   The form API state.
 * @param array $form
 *   The form being processed.
 *
 * @return array
 *
 * @see exif_field_widget_form()
 */
function exif_field_readonly_widget_process(array $element, array &$form_state, array $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;
}

/**
 * Determine whether a given string starts with a another string.
 *
 * @param string $haystack
 *   The source string to search.
 * @param string $needle
 *   The string to search for.
 *
 * @return bool
 *   Whether the haystack starts with the requested needle.
 */
function strstartswith($haystack, $needle) {
    return substr($haystack, 0, strlen($needle)) === $needle;
}

Functions

Title Deprecated Summary
exif_date_formats Date API hook.
exif_date_format_types Date API hook.
exif_field_attach_presave Implements hook_field_attach_presave().
exif_field_readonly_widget_process Callback function call when a element of type exif_readonly is used.
exif_field_widget_error FormAPI error handler.
exif_field_widget_form Implements hook_field_widget_form().
exif_field_widget_info Implements hook_field_widget_info().
exif_field_widget_info_alter Implements hook_field_widget_info_alter().
exif_field_widget_settings_form Implements hook_widget_settings().
exif_field_widget_validate FormAPI validation callback.
exif_help Implements hook_help().
exif_menu Implements hook_menu().
exif_permission Implements hook_permission().
strstartswith Determine whether a given string starts with a another string.
_exif_check_for_exif_data Let's check if this node type contains an image field.
_exif_create_term Create a term in the specified vocabulary.
_exif_field_widget_exif_field_separator_validate Form API validation callback.
_exif_field_widget_exif_field_validate Implementation of #element_validate FAPI Hook.
_exif_field_widget_image_field_validate Implementation of #element_validate FAPI Hook.
_exif_field_widget_retrieve_exif_fields Retrieve all field keys possible.
_exif_field_widget_retrieve_image_field_from_bundle Retrieve all image_field fields of the same content type (bundle)
_exif_filter_fields_on_widgets
_exif_get_class Helper function to get the exif class.
_exif_get_data_from_file_uri Get EXIF data from file or stream wrapper.
_exif_get_field_widget_retrieve_exif_field_default_value Calculate default value for settings form of widget.
_exif_get_field_widget_retrieve_exif_field_separator_default_value Calculate default value for settings form of widget.
_exif_get_field_widget_retrieve_image_field_default_value Calculate default value for settings form of widget.
_exif_get_file_uri_and_language
_exif_get_image_fid
_exif_get_image_fields
_exif_get_image_fields_metadata
_exif_get_image_language
_exif_handle_date_field Handle date field.
_exif_handle_field Handle field by delegating to specific type handler.
_exif_handle_field_value_consistency
_exif_handle_taxonomy_field Handle taxonomy field.
_exif_handle_text_field Handle text field.
_exif_node_insert_update Main entrypoint of the module.