diff -ru exif/exif.module exif-date-api/exif.module --- exif/exif.module 2009-12-01 16:00:49.000000000 +0100 +++ exif-date-api/exif.module 2010-01-20 03:19:07.908584778 +0100 @@ -90,53 +90,130 @@ break; } case 'insert': - if (_exif_check_for_exif_data($node->type)) { - $info = content_types($node->type); - $fields = $info['fields']; - $exif = _exif_get_class(); - - //get all the fields that will be filled with exif data - $ar_exif_fields = $exif->getExifFields($fields); - - //get the path to the image - $image_path = _exif_get_image_path($fields, $node); - - $fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $image_path)); - $file = file_create_path($image_path); - - $data1 = _exif_reformat($exif->readExifTags($file, $ar_exif_fields)); - $data2 = $exif->readIPTCTags($file, $ar_exif_fields); - $data = array_merge($data1, $data2); - - // prepare data to be stored in CCK - $i = 0; - foreach ($data as $key => $value) { - $field_name = 'field_'. $key; - $tmp = $node->$field_name; - - $date_array = array('datetimeoriginal', 'datetime', 'datetimedigitized'); - //incase we get a datefield, we need to reformat it to the ISO 8601 standard: - //which will look something like 2004-02-12T15:19:21 - if (in_array($key, $date_array)) { - $date_time = explode(" ", $value); - $date_time[0] = str_replace(":", "-", $date_time[0]); - if (variable_get('exif_granularity', 0) == 1) { - $date_time[1] = "00:00:00"; - } - $value = implode("T", $date_time); - //dsm($value,$key); - } - $tmp[0]['value'] = $value; + if (! _exif_check_for_exif_data($node->type)) { + return; + } + $info = content_types($node->type); + $fields = $info['fields']; + $exif = _exif_get_class(); + + //get all the fields that will be filled with exif data + $ar_exif_fields = $exif->getExifFields($fields); + + //get the path to the image + $image_path = _exif_get_image_path($fields, $node); + + $fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $image_path)); + $file = file_create_path($image_path); + + $data1 = _exif_reformat($exif->readExifTags($file, $ar_exif_fields)); + $data2 = $exif->readIPTCTags($file, $ar_exif_fields); + $data = array_merge($data1, $data2); + + // Loop through every exif enabled field and set its value to the + // corresponding exif value. If no exif value was found, set the field + // value to NULL, to avoid strange behaviour in other field modules + // (date). + foreach ($ar_exif_fields as $ar_exif_field) { + $exif_name = $ar_exif_field['section'] .'_'. $ar_exif_field['tag']; + $exif_value = isset($data[$exif_name]) ? $data[$exif_name] : NULL; + $field_name = 'field_'. $exif_name; + if (! $exif_value) { + $node->{$field_name}[0]['value'] = NULL; + continue; + } + $field = $fields[$field_name]; - $node->$field_name = $tmp; - $i++; + // Setup the field value array for delta = 0. + switch ($exif_name) { + case 'exif_datetimeoriginal': + case 'exif_datetimedigitized': + case 'ifd0_datetime': + $first_delta = _exif_date_handler($field, $exif_value); + break; + default: + $first_delta = array('value' => $data[$exif_name]); + break; } + $node->{$field_name}[0] = $first_delta; } break; } } /** + * 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. + */ +function exif_date_formats() { + return array( + array( + 'type' => 'exif', + 'format' => 'Y:m:d H:i:s', + ), + ); +} + +/** + * Helper function to handle all date values from exif header. This is + * designed for the date_api and date modules, but is compatible if these + * aren't enabled. + * + * @param array $field + * The field definition for the matcing exif date + * @param string $exif_date + * The date extracted from exif header. + * @return array + * The field value array for delta = 0 + */ +function _exif_date_handler($field, $exif_date) { + if (! module_exists('date_api')) { + // Don't bother doing anything if the webmaster doesn't ... + return array('value' => $exif_date); + } + + require_once drupal_get_path('module', 'date_api') .'/date_api_elements.inc'; + $date_datetime = date_convert_from_custom($exif_date, variable_get('date_format_exif', 'Y:m:d H:i:s')); + if (! in_array($field['type'], array('date', 'datetime', 'datestamp'))) { + // Field is not a date field type, so we return a ISO-8601 representation + return array('value' => date_convert($date_datetime, DATE_DATETIME, DATE_ISO)); + } + + // Exif doesn't handles timezones, so we assume the exif date is in the + // timezone configured for this date field. This means the exif date needs + // to be converted to UTC before it's stored. + $timezone = date_get_timezone($field['tz_handling']); + $date = date_make_date($date_datetime, $timezone, DATE_DATETIME, $field['granularity']); + + // Store date offset before converting to UTC as this is lost when setting + // timezone to 'UTC'. + $offset = date_offset_get($date); + date_timezone_set($date, timezone_open('UTC')); + + // Finally, convert the date object in UTC to a date according to the field + // type: DATE_ISO, DATE_DATETIME or DATE_UNIX. + $date_field = date_convert($date, DATE_OBJECT, $field['type']); + return array( + 'value' => $date_field, + 'value2' => $date_field, + 'timezone' => $timezone, + 'offset' => $offset, + 'offset2' => $offset, + ); +} + +/** * Let's check if this node type contains an image field. * * @param $fields fields from this content type @@ -258,16 +335,6 @@ elseif ($key == 'gps_longitude') { $value = _exif_DMS2D($value, $data['gps_gpslongituderef']); } - elseif (in_array($key, $date_array)) { - // In case we get a datefield, we need to reformat it to the ISO 8601 standard: - // which will look something like 2004-02-12T15:19:21 - $date_time = explode(" ", $value); - $date_time[0] = str_replace(":", "-", $date_time[0]); - if (variable_get('exif_granularity', 0) == 1) { - $date_time[1] = "00:00:00"; - } - $value = implode("T", $date_time); - } } return $data; }