aboutsummaryrefslogtreecommitdiff
path: root/exif.module
diff options
context:
space:
mode:
authorSilvio <silvio@devlet.com.br>2010-10-07 18:44:31 -0300
committerSilvio <silvio@devlet.com.br>2010-10-07 18:44:31 -0300
commitca7d08e2b8124353bc56f8dbdfc3ea32da669b7e (patch)
tree4a64378f63532ebf8c1d867d163f35c7d841f3f9 /exif.module
parent21c3a1c6999459420a7343e4c9af2c1683bcc07d (diff)
downloadexif-ca7d08e2b8124353bc56f8dbdfc3ea32da669b7e.tar.gz
exif-ca7d08e2b8124353bc56f8dbdfc3ea32da669b7e.tar.bz2
CVS update
Diffstat (limited to 'exif.module')
-rwxr-xr-xexif.module566
1 files changed, 299 insertions, 267 deletions
diff --git a/exif.module b/exif.module
index 7d955f1..2f41afb 100755
--- a/exif.module
+++ b/exif.module
@@ -1,61 +1,50 @@
<?php
-// $Id: exif.module,v 1.9.2.18 2010/07/23 17:47:46 rapsli Exp $:
+// $Id: exif.module,v 1.9 2008/04/05 23:22:05 davidlesieur Exp $
/**
- * @file implementing the drupal api
- */
-/**
- * @author: Raphael Schär - www.rapsli.ch
+ * Implementation of hook_menu().
*/
+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 = NULL, $page = NULL) {
-
- if ($teaser) {
+function exif_nodeapi(&$node, $op, $teaser) {
+ if ($teaser || $node->type != 'image') {
return;
}
switch ($op) {
-
+ case 'insert':
case 'update':
- //we are only going to update if we have said so
- if (!variable_get('exif_update', TRUE)) {
- break;
+ $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);
+ }
}
+<<<<<<< exif.module
case 'insert':
if (! _exif_check_for_exif_data($node->type)) {
return;
@@ -67,282 +56,325 @@ function exif_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
//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);
-
- 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;
+>>>>>>> 1.9
+
+ 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,
+ );
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.
+ * Administration page callback.
*/
-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',
- ),
+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;
}
-/**
- * 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);
- }
+function exif_admin_settings_form_submit($form_id, $values) {
+ $op = isset($_POST['op']) ? $_POST['op'] : '';
- 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));
+ if ($op == t('Reset to defaults')) {
+ exif_reset_settings();
+ drupal_set_message(t('The configuration options have been reset to their default values.'));
+ }
+ elseif ($op == t('Save configuration')) {
+ exif_save_settings($values);
+ drupal_set_message(t('The configuration options have been saved.'));
}
-
- // 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
- * @return boolean
+ * Fetch exif data.
*/
-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;
+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;
}
}
- if (in_array($node_type, $new_types)) {
- return TRUE;
- }
- return FALSE;
+
+ return $data;
}
/**
- * 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
+ * Reads exif data from a file.
*/
-function _exif_get_image_path($fields, &$node) {
- if ($node->type == 'image') {
- return $node->images[IMAGE_ORIGINAL];
+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;
}
-
- foreach ($fields as $field) {
- if ($field['type'] == 'filefield') {
- $tmp = $node->$field['field_name'];
- return $tmp[0]['filepath'];
+ if (exif_imagetype($file) != IMAGETYPE_JPEG) {
+ return $data;
+ }
+ $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());
+ }
}
}
- return NULL;
+ return $data;
}
-
/**
- * Helper function to reformat fields where required.
- *
- * Some values (lat/lon) break down into structures, not strings.
+ * Return an array containing only the tags that were enabled.
*/
-function _exif_reformat($data) {
- $date_array = array('datetimeoriginal', 'datetime', 'datetimedigitized');
+function exif_get_enabled_tags() {
+ static $tags = array();
- // Make the key lowercase as CCK field names must be
- $data = array_change_key_case($data, CASE_LOWER);
-
- foreach ($data as $key => &$value) {
- if (is_array($value)) {
- $value = array_change_key_case($value, CASE_LOWER);
+ if (!count($tags)) {
+ $result = db_query('SELECT * FROM {exif_tags} WHERE status = 1');
+ while ($tag = db_fetch_object($result)) {
+ $tags[] = $tag;
}
-
- // 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;
-
+ 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]);
+ }
+ }
}
+ usort($tags, '_exif_compare_tags');
}
- return $data;
+
+ return $tags;
}
/**
- * Helper function to change GPS co-ords into decimals.
+ * Return an array with all the valid tags and their settings.
*/
-function _exif_DMS2D($value, $ref) {
- $parts = split('/', $value[0]);
- $dec = (float) ((float) $parts[0] / (float) $parts[1]);
+function exif_load_settings() {
+ $tags = exif_get_default_settings();
- $parts = split('/', $value[1]);
- $dec += (float) (((float) $parts[0] / (float) $parts[1]) / 60);
+ $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[2]);
- $dec += (float) (((float) $parts[0] / (float) $parts[1]) / 3600);
+ return $tags;
+}
+
+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();
+}
- if ($ref == 'S' || $ref == 'W') $dec *= -1;
- return $dec;
+function exif_reset_settings() {
+ db_query('DELETE FROM {exif_tags}');
}
/**
- * Helper function to get the exif class
- * @return Exif
+ * Return an array with all the valid tags, with some useful default settings.
*/
-function _exif_get_class() {
- include_once drupal_get_path('module', 'exif') .'/exif.class.php';
- $exif = Exif::getInstance();
- 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;
}
/**
- * Implementation of hook_hoken_list
- * @param array $type
+ * 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.
*/
-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;
+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;
}
- return $tokens;
+ return $a->ifd - $b->ifd;
+ }
+ // Disabled tags
+ else {
+ return $a->ifd - $b->ifd;
}
}
-/**
- * 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);
+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;
}
- //dsm($tokens);
- return $tokens;
}
+<<<<<<< exif.module
+}
+=======
+
+ 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';
+}
+
+>>>>>>> 1.9