aboutsummaryrefslogtreecommitdiff
path: root/exif.module
diff options
context:
space:
mode:
authorSilvio <silvio@devlet.com.br>2010-10-08 15:34:02 -0300
committerSilvio <silvio@devlet.com.br>2010-10-08 15:34:02 -0300
commitebbcd617393c83364699592dfeca8c6e7c3a578a (patch)
treecb940bddbed4b1ad1cfcfb1a1e0496dfc5a5ad03 /exif.module
parent6715a36dad52d37b54c63c9ccc0f9532d61e1b43 (diff)
downloadexif-ebbcd617393c83364699592dfeca8c6e7c3a578a.tar.gz
exif-ebbcd617393c83364699592dfeca8c6e7c3a578a.tar.bz2
CVS update
Diffstat (limited to 'exif.module')
-rwxr-xr-xexif.module569
1 files changed, 277 insertions, 292 deletions
diff --git a/exif.module b/exif.module
index 3853eb4..ecbbd6e 100755
--- a/exif.module
+++ b/exif.module
@@ -1,362 +1,347 @@
<?php
-// $Id: exif.module,v 1.9 2008/04/05 23:22:05 davidlesieur Exp $
+// $Id: exif.module,v 1.9.2.18 2010/07/23 17:47:46 rapsli Exp $:
/**
- * Implementation of hook_menu().
+ * @file implementing the drupal api
+ */
+/**
+ * @author: Raphael Schär - www.rapsli.ch
*/
-function exif_menu($may_cache) {
- $items = array();
-
- if ($may_cache) {
- $items[] = array(
- 'path' => 'admin/settings/exif',
- 'title' => t('Exif'),
- 'callback' => 'drupal_get_form',
- 'callback arguments' => array('exif_admin_settings_form'),
- 'access' => user_access('administer site configuration'),
- 'description' => t('Configure what Exif tags to display.'),
- );
- }
+function exif_menu() {
+ $items['admin/settings/exif'] = array(
+ 'title' => 'Exif',
+ 'page callback' => 'exif_admin_settings',
+ 'access arguments' => array('administer site configuration'),
+ 'description' => t('Display available fields'),
+ 'access callback' => 'user_access',
+ 'file' => 'exif.admin.inc',
+ 'type' => MENU_NORMAL_ITEM,
+ );
+ $items['admin/settings/exif/general'] = array(
+ 'title' => 'Exif',
+ 'page callback' => 'exif_admin_settings',
+ 'access arguments' => array('administer site configuration'),
+ 'description' => t('Display available fields'),
+ 'access callback' => 'user_access',
+ 'file' => 'exif.admin.inc',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ $items['admin/settings/exif/config'] = array(
+ 'title' => 'Config',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('exif_admin_settings_form'),
+ 'access arguments' => array('administer site configuration'),
+ 'description' => t('Some Settings'),
+ 'access callback' => 'user_access',
+ 'file' => 'exif.admin.inc',
+ 'type' => MENU_LOCAL_TASK,
+ );
return $items;
}
/**
- * Implementation of hook_nodeapi().
+ * implementation of hook_nodeapi
*/
-function exif_nodeapi(&$node, $op, $teaser) {
- if ($teaser || $node->type != 'image') {
+function exif_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
+
+ if ($teaser) {
return;
}
switch ($op) {
- case 'insert':
+
case 'update':
- $fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $node->images[IMAGE_ORIGINAL]));
- $file = file_create_path($node->images[IMAGE_ORIGINAL]);
- $data = _exif_read_exif($file);
- db_query('DELETE FROM {exif} WHERE fid = %d', $fid);
-
- // Cache data in db.
- foreach ($data as $ifd => $tags) {
- foreach ($tags as $tag => $value) {
- db_query("INSERT INTO {exif} (fid, ifd, tag, value) VALUES (%d, %d, %d, '%s')",
- $fid, $ifd, $tag, $value);
- }
+ //we are only going to update if we have said so
+ if (!variable_get('exif_update', TRUE)) {
+ break;
}
- break;
+ case 'insert':
+ 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);
- case 'load':
- $fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $node->images[IMAGE_ORIGINAL]));
- return array('exif_data' => _exif_get_exif($fid));
- case 'view':
- $node->content['exif'] = array(
- '#value' => theme('exif_table', $node),
- '#weight' => 10,
- );
+ $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);
+
+ if (class_exists('SXMPFiles')) {
+ $data3 = $exif->readXMPTags($file, $ar_exif_fields);
+ $data = array_merge($data1, $data2, $data3);
+ }
+ else {
+ $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) {
+ if (variable_get('exif_empty_values', TRUE)) {
+ $node->{$field_name}[0]['value'] = NULL;
+ }
+ continue;
+ }
+ $field = $fields[$field_name];
+
+ // 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;
}
}
/**
- * Administration page callback.
+ * 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_admin_settings_form() {
- _exif_bootstrap();
- $tags = exif_load_settings();
- foreach ($tags as $tag) {
- $form['tags']["{$tag->ifd}_{$tag->tag}"]['type'] = array(
- '#type' => 'markup',
- '#value' => PelIfd::getTypeName($tag->ifd),
- );
- $form['tags']["{$tag->ifd}_{$tag->tag}"]['ifd'] = array(
- '#type' => 'hidden',
- '#value' => $tag->ifd,
- );
- $form['tags']["{$tag->ifd}_{$tag->tag}"]['tag'] = array(
- '#type' => 'hidden',
- '#value' => $tag->tag,
- );
- $form['tags']["{$tag->ifd}_{$tag->tag}"]['status'] = array(
- '#type' => 'checkbox',
- '#title' => utf8_encode(PelTag::getTitle($tag->ifd, $tag->tag)),
- '#default_value' => $tag->status,
- );
- $form['tags']["{$tag->ifd}_{$tag->tag}"]['weight'] = array(
- '#type' => 'weight',
- '#delta' => 10,
- '#default_value' => $tag->weight,
- );
- $form['tags']["{$tag->ifd}_{$tag->tag}"]['#tree'] = TRUE;
- $form['tags']["{$tag->ifd}_{$tag->tag}"]['#weight'] = $tag->weight;
- }
- $form['buttons']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save configuration')
- );
- $form['buttons']['reset'] = array(
- '#type' => 'submit',
- '#value' => t('Reset to defaults')
- );
-
- return $form;
+function exif_date_format_types() {
+ return array('exif' => 'EXIF');
}
-function exif_admin_settings_form_submit($form_id, $values) {
- $op = isset($_POST['op']) ? $_POST['op'] : '';
+/**
+ * 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',
+ ),
+ );
+}
- if ($op == t('Reset to defaults')) {
- exif_reset_settings();
- drupal_set_message(t('The configuration options have been reset to their default values.'));
+/**
+ * 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);
}
- elseif ($op == t('Save configuration')) {
- exif_save_settings($values);
- drupal_set_message(t('The configuration options have been saved.'));
+
+ 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,
+ );
}
/**
- * Fetch exif data.
+ * Let's check if this node type contains an image field.
+ *
+ * @param $fields fields from this content type
+ * @return boolean
*/
-function _exif_get_exif($fid) {
- $data = array();
- if ($result = db_query('SELECT * FROM {exif} WHERE fid = %d', $fid)) {
- while ($row = db_fetch_object($result)) {
- $data[$row->ifd][$row->tag] = $row->value;
+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;
}
}
-
- return $data;
+ if (in_array($node_type, $new_types)) {
+ return TRUE;
+ }
+ return FALSE;
}
/**
- * Reads exif data from a file.
+ * From a given node we are going to get the imagepath of the image. if it's an image node
+ * it's just going to be images[IMAGE_ORIGINAL]. If it's an imagefield node, we have to go
+ * through the fields and look if there is an imagefield and then return the path
+ *
+ * @param $fields
+ * @param $node
+ * @return unknown_type
*/
-function _exif_read_exif($file) {
- _exif_bootstrap();
- $data = array();
- if (!file_exists($file)) {
- watchdog('exif', t('Image %file not found.', array('%file' => $file)), WATCHDOG_WARNING);
- return $exif;
- }
- if (exif_imagetype($file) != IMAGETYPE_JPEG) {
- return $data;
+function _exif_get_image_path($fields, &$node) {
+ if ($node->type == 'image') {
+ return $node->images[IMAGE_ORIGINAL];
}
- $jpeg = new PelJpeg($file);
- $exif = $jpeg->getExif();
- if (!$exif) {
- return $data;
- }
- $tiff = $exif->getTiff();
- if (!$tiff) {
- return $data;
- }
- $ifd0 = $tiff->getIfd();
- if (!$ifd0) {
- return $data;
- }
- $ifds[PelIfd::IFD0] = $ifd0;
- if ($exif = $ifd0->getSubIfd(PelIfd::EXIF)) {
- $ifds[PelIfd::EXIF] = $exif;
- }
- if ($gps = $ifd0->getSubIfd(PelIfd::GPS)) {
- $ifds[PelIfd::GPS] = $gps;
- }
- $tags = exif_get_enabled_tags();
- $data = array();
- foreach ($tags as $tag) {
- $entry = $ifds[$tag->ifd]->getEntry($tag->tag);
- if ($entry) {
- $row = array();
- switch($tag->tag) {
- case PelTag::DATE_TIME:
- case PelTag::DATE_TIME_ORIGINAL:
- case PelTag::DATE_TIME_DIGITIZED:
- // Return a unixtimestamp. Theme will handle date formating.
- $data[$tag->ifd][$tag->tag] = $entry->getValue();
- break;
-
- default:
- $data[$tag->ifd][$tag->tag] = utf8_encode($entry->getText());
- }
+
+ foreach ($fields as $field) {
+ if ($field['type'] == 'filefield') {
+ $tmp = $node->$field['field_name'];
+ return $tmp[0]['filepath'];
}
}
- return $data;
+ return NULL;
}
+
/**
- * Return an array containing only the tags that were enabled.
+ * Helper function to reformat fields where required.
+ *
+ * Some values (lat/lon) break down into structures, not strings.
*/
-function exif_get_enabled_tags() {
- static $tags = array();
+function _exif_reformat($data) {
+ $date_array = array('datetimeoriginal', 'datetime', 'datetimedigitized');
+
+ // Make the key lowercase as CCK field names must be
+ $data = array_change_key_case($data, CASE_LOWER);
- if (!count($tags)) {
- $result = db_query('SELECT * FROM {exif_tags} WHERE status = 1');
- while ($tag = db_fetch_object($result)) {
- $tags[] = $tag;
+ foreach ($data as $key => &$value) {
+ if (is_array($value)) {
+ $value = array_change_key_case($value, CASE_LOWER);
}
- if (!count($tags)) {
- // Table is empty, get some defaults
- $tags = exif_get_default_settings();
- foreach ($tags as $key => $tag) {
- if (!$tag->status) {
- unset($tags[$key]);
- }
- }
+
+ // Check for individual keys
+ switch ($key) {
+ case 'gpslatitude':
+ $value = _exif_DMS2D($value, $data['gpslatituderef']);
+ break;
+
+ case 'gpslongitude':
+ $value = _exif_DMS2D($value, $data['gpslongituderef']);
+ break;
+
+ case 'gps_gpslatitude':
+ $value = _exif_DMS2D($value, $data['gps_gpslatituderef']);
+ break;
+
+ case 'gps_gpslongitude':
+ $value = _exif_DMS2D($value, $data['gps_gpslongituderef']);
+ break;
+
}
- usort($tags, '_exif_compare_tags');
}
-
- return $tags;
+ return $data;
}
/**
- * Return an array with all the valid tags and their settings.
+ * Helper function to change GPS co-ords into decimals.
*/
-function exif_load_settings() {
- $tags = exif_get_default_settings();
+function _exif_DMS2D($value, $ref) {
+ $parts = split('/', $value[0]);
+ $dec = (float) ((float) $parts[0] / (float) $parts[1]);
- $result = db_query('SELECT * FROM {exif_tags}');
- while ($tag = db_fetch_object($result)) {
- $tags["{$tag->ifd}_{$tag->tag}"] = $tag;
- }
- usort($tags, '_exif_compare_tags');
+ $parts = split('/', $value[1]);
+ $dec += (float) (((float) $parts[0] / (float) $parts[1]) / 60);
- return $tags;
-}
+ $parts = split('/', $value[2]);
+ $dec += (float) (((float) $parts[0] / (float) $parts[1]) / 3600);
-function exif_save_settings($values) {
- db_lock_table('exif_tags');
- foreach ($values as $tag) {
- if (!is_array($tag) || !isset($tag['ifd'])) {
- continue; // Save only appropriate form values
- }
- db_query('DELETE FROM {exif_tags} WHERE ifd = %d AND tag = %d', $tag['ifd'], $tag['tag']);
- db_query('INSERT INTO {exif_tags} (ifd, tag, status, weight) VALUES (%d, %d, %d, %d)', $tag['ifd'], $tag['tag'], $tag['status'], $tag['weight']);
- }
- db_unlock_tables();
-}
-
-function exif_reset_settings() {
- db_query('DELETE FROM {exif_tags}');
+ if ($ref == 'S' || $ref == 'W') $dec *= -1;
+ return $dec;
}
/**
- * Return an array with all the valid tags, with some useful default settings.
+ * Helper function to get the exif class
+ * @return Exif
*/
-function exif_get_default_settings() {
- $tags = exif_get_valid_tags();
- $tags[PelIfd::EXIF .'_'. PelTag::DATE_TIME_ORIGINAL]->status = 1;
- $tags[PelIfd::EXIF .'_'. PelTag::DATE_TIME_ORIGINAL]->weight = -10;
- $tags[PelIfd::IFD0 .'_'. PelTag::MODEL]->status = 1;
- $tags[PelIfd::IFD0 .'_'. PelTag::MODEL]->weight = -8;
- $tags[PelIfd::EXIF .'_'. PelTag::FOCAL_LENGTH]->status = 1;
- $tags[PelIfd::EXIF .'_'. PelTag::FOCAL_LENGTH]->weight = -6;
- $tags[PelIfd::EXIF .'_'. PelTag::APERTURE_VALUE]->status = 1;
- $tags[PelIfd::EXIF .'_'. PelTag::APERTURE_VALUE]->weight = -4;
- $tags[PelIfd::EXIF .'_'. PelTag::EXPOSURE_TIME]->status = 1;
- $tags[PelIfd::EXIF .'_'. PelTag::EXPOSURE_TIME]->weight = -2;
- $tags[PelIfd::EXIF .'_'. PelTag::ISO_SPEED_RATINGS]->status = 1;
- $tags[PelIfd::EXIF .'_'. PelTag::ISO_SPEED_RATINGS]->weight = 0;
- return $tags;
+function _exif_get_class() {
+ include_once drupal_get_path('module', 'exif') .'/exif.class.php';
+ $exif = Exif::getInstance();
+ return $exif;
}
/**
- * Helper function to return all the valid tags (well, at least those this module cares about).
- *
- * For convenience, each tag has a key in the form: "ifd_tag", where ifd and tag
- * are standard Exif ids. Those ids can be found in PelIfd.php and PelTag.php.
+ * Implementation of hook_hoken_list
+ * @param array $type
*/
-function exif_get_valid_tags() {
- $valid_tags = array();
- $valid_tags = array_merge($valid_tags, _exif_get_valid_ifd_tags(PelIfd::IFD0, new PelIfd(PelIfd::IFD0)));
- $valid_tags = array_merge($valid_tags, _exif_get_valid_ifd_tags(PelIfd::EXIF, new PelIfd(PelIfd::EXIF)));
- $valid_tags = array_merge($valid_tags, _exif_get_valid_ifd_tags(PelIfd::GPS, new PelIfd(PelIfd::GPS)));
- return $valid_tags;
-}
-
-function _exif_get_valid_ifd_tags($ifd_id, $ifd) {
- $tags = array();
- $pel_tags = $ifd->getValidTags();
- foreach ($pel_tags as $pel_tag) {
- $tag = new StdClass();
- $tag->ifd = $ifd_id;
- $tag->tag = $pel_tag;
- $tags["{$tag->ifd}_{$tag->tag}"] = $tag;
- }
- return $tags;
-}
-
-function _exif_compare_tags($a, $b) {
- $status = $b->status - $a->status;
- // Separate enabled from disabled.
- if ($status) {
- return $status;
- }
- // Enabled tags
- if ($a->status) {
- $weight = $a->weight - $b->weight;
- if ($weight) {
- return $weight;
+function fast_gallery_token_list($type = 'node') {
+ if ($type == 'node') {
+ $exif = _exif_get_class();
+ $ar_iptc = $exif->getHumanReadableIPTCkey();
+ foreach ($ar_iptc as $iptc) {
+ $tokens['iptc']['iptc_' . $iptc] = 'IPTC Field: ' . $iptc;
}
- return $a->ifd - $b->ifd;
- }
- // Disabled tags
- else {
- return $a->ifd - $b->ifd;
+ return $tokens;
}
}
-function theme_exif_table($node) {
- _exif_bootstrap();
- // Retrieve the desired tag values from the file
- $tags = exif_get_enabled_tags();
- $rows = array();
- $data = $node->exif_data;
-
- foreach ($tags as $tag) {
- if (!empty($data[$tag->ifd][$tag->tag])) {
- $row = array();
- $row[] = array('data' => check_plain(utf8_encode(PelTag::getTitle($tag->ifd, $tag->tag))), 'class' => 'exif-title');
- $val = $data[$tag->ifd][$tag->tag];
- switch($tag->tag) {
- case PelTag::DATE_TIME:
- case PelTag::DATE_TIME_ORIGINAL:
- case PelTag::DATE_TIME_DIGITIZED:
- // Use Drupal's date formatting instead of Pel's
- $row[] = array('data' => format_date($val, 'medium', '', 0), 'class' => 'exif-value');
- break;
-
- default:
- $row[] = array('data' => check_plain($val), 'class' => 'exif-value');
- }
- $rows[] = $row;
+/**
+ * implementation of hook_token_values
+ * @param unknown_type $type
+ * @param unknown_type $object
+ * @param unknown_type $options
+ */
+function fast_gallery_token_values($type, $object = NULL, $options = array()) {
+ if ($type == 'node') {
+ $node = $object;
+ $exif = _exif_get_class();
+ $ar_iptc = $exif->getHumanReadableIPTCkey();
+
+ $info = content_types($node->type);
+ $fields = $info['fields'];
+ //get the path to the image
+ $image_path = _exif_get_image_path($fields, $node);
+
+ //dsm("start reading");
+ $iptc_values = $exif->readIPTCTags($image_path, array(), array('style' => 'fullSmall'));
+ //dsm($iptc_values);
+
+ // TODO: needs to be finished
+ foreach ($iptc_values as $key => $iptc) {
+ $tokens['iptc_' . $key] = 'IPTC Field: ' . utf8_encode($iptc);
}
+ //dsm($tokens);
+ return $tokens;
}
-
- if (empty($rows)) {
- return '';
- }
- $header = array(array('data' => t('Image information'), 'colspan' => 2));
- return theme('table', $header, $rows, array('class' => 'exif'));
-}
-
-function theme_exif_admin_settings_form($form) {
- $header = array(t('Tag'), t('Weight'), t('Type'));
- $rows = array();
- foreach (element_children($form['tags']) as $key) {
- $row = array();
- $row[] = drupal_render($form['tags'][$key]['status']);
- $row[] = drupal_render($form['tags'][$key]['weight']);
- $row[] = drupal_render($form['tags'][$key]['type']);
- $rows[] = $row;
- }
- $output .= theme('table', $header, $rows, array('class' => 'admin-settings-exif'));
- $output .= drupal_render($form);
- return $output;
-}
-
-function _exif_bootstrap() {
- include_once drupal_get_path('module', 'exif') .'/pel/PelJpeg.php';
-}
-
+} \ No newline at end of file