/[drupal]/contributions/modules/exif/exif.module
ViewVC logotype

Contents of /contributions/modules/exif/exif.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download) (as text)
Sat Apr 5 23:22:05 2008 UTC (19 months, 3 weeks ago) by davidlesieur
Branch: MAIN
CVS Tags: DRUPAL-6--1-0, HEAD
Branch point for: DRUPAL-6--1
Changes since 1.8: +141 -75 lines
File MIME type: text/x-php
Updated from DRUPAL-5 branch.
1 <?php
2 // $Id: exif.module,v 1.4.2.6 2008/02/06 23:30:16 davidlesieur Exp $
3
4 /**
5 * Implementation of hook_menu().
6 */
7 function exif_menu($may_cache) {
8 $items = array();
9
10 if ($may_cache) {
11 $items[] = array(
12 'path' => 'admin/settings/exif',
13 'title' => t('Exif'),
14 'callback' => 'drupal_get_form',
15 'callback arguments' => array('exif_admin_settings_form'),
16 'access' => user_access('administer site configuration'),
17 'description' => t('Configure what Exif tags to display.'),
18 );
19 }
20
21 return $items;
22 }
23
24 /**
25 * Implementation of hook_nodeapi().
26 */
27 function exif_nodeapi(&$node, $op, $teaser) {
28 if ($teaser || $node->type != 'image') {
29 return;
30 }
31
32 switch ($op) {
33 case 'insert':
34 case 'update':
35 $fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $node->images[IMAGE_ORIGINAL]));
36 $file = file_create_path($node->images[IMAGE_ORIGINAL]);
37 $data = _exif_read_exif($file);
38 db_query('DELETE FROM {exif} WHERE fid = %d', $fid);
39
40 // Cache data in db.
41 foreach ($data as $ifd => $tags) {
42 foreach ($tags as $tag => $value) {
43 db_query("INSERT INTO {exif} (fid, ifd, tag, value) VALUES (%d, %d, %d, '%s')",
44 $fid, $ifd, $tag, $value);
45 }
46 }
47 break;
48
49 case 'load':
50 $fid = db_result(db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $node->images[IMAGE_ORIGINAL]));
51 return array('exif_data' => _exif_get_exif($fid));
52 case 'view':
53 $node->content['exif'] = array(
54 '#value' => theme('exif_table', $node),
55 '#weight' => 10,
56 );
57 break;
58 }
59 }
60
61 /**
62 * Administration page callback.
63 */
64 function exif_admin_settings_form() {
65 _exif_bootstrap();
66 $tags = exif_load_settings();
67 foreach ($tags as $tag) {
68 $form['tags']["{$tag->ifd}_{$tag->tag}"]['type'] = array(
69 '#type' => 'markup',
70 '#value' => PelIfd::getTypeName($tag->ifd),
71 );
72 $form['tags']["{$tag->ifd}_{$tag->tag}"]['ifd'] = array(
73 '#type' => 'hidden',
74 '#value' => $tag->ifd,
75 );
76 $form['tags']["{$tag->ifd}_{$tag->tag}"]['tag'] = array(
77 '#type' => 'hidden',
78 '#value' => $tag->tag,
79 );
80 $form['tags']["{$tag->ifd}_{$tag->tag}"]['status'] = array(
81 '#type' => 'checkbox',
82 '#title' => utf8_encode(PelTag::getTitle($tag->ifd, $tag->tag)),
83 '#default_value' => $tag->status,
84 );
85 $form['tags']["{$tag->ifd}_{$tag->tag}"]['weight'] = array(
86 '#type' => 'weight',
87 '#delta' => 10,
88 '#default_value' => $tag->weight,
89 );
90 $form['tags']["{$tag->ifd}_{$tag->tag}"]['#tree'] = TRUE;
91 $form['tags']["{$tag->ifd}_{$tag->tag}"]['#weight'] = $tag->weight;
92 }
93 $form['buttons']['submit'] = array(
94 '#type' => 'submit',
95 '#value' => t('Save configuration')
96 );
97 $form['buttons']['reset'] = array(
98 '#type' => 'submit',
99 '#value' => t('Reset to defaults')
100 );
101
102 return $form;
103 }
104
105 function exif_admin_settings_form_submit($form_id, $values) {
106 $op = isset($_POST['op']) ? $_POST['op'] : '';
107
108 if ($op == t('Reset to defaults')) {
109 exif_reset_settings();
110 drupal_set_message(t('The configuration options have been reset to their default values.'));
111 }
112 elseif ($op == t('Save configuration')) {
113 exif_save_settings($values);
114 drupal_set_message(t('The configuration options have been saved.'));
115 }
116 }
117
118 /**
119 * Fetch exif data.
120 */
121 function _exif_get_exif($fid) {
122 $data = array();
123 if ($result = db_query('SELECT * FROM {exif} WHERE fid = %d', $fid)) {
124 while ($row = db_fetch_object($result)) {
125 $data[$row->ifd][$row->tag] = $row->value;
126 }
127 }
128
129 return $data;
130 }
131
132 /**
133 * Reads exif data from a file.
134 */
135 function _exif_read_exif($file) {
136 _exif_bootstrap();
137 $data = array();
138 if (!file_exists($file)) {
139 watchdog('exif', t('Image %file not found.', array('%file' => $file)), WATCHDOG_WARNING);
140 return $exif;
141 }
142 if (exif_imagetype($file) != IMAGETYPE_JPEG) {
143 return $data;
144 }
145 $jpeg = new PelJpeg($file);
146 $exif = $jpeg->getExif();
147 if (!$exif) {
148 return $data;
149 }
150 $tiff = $exif->getTiff();
151 if (!$tiff) {
152 return $data;
153 }
154 $ifd0 = $tiff->getIfd();
155 if (!$ifd0) {
156 return $data;
157 }
158 $ifds[PelIfd::IFD0] = $ifd0;
159 if ($exif = $ifd0->getSubIfd(PelIfd::EXIF)) {
160 $ifds[PelIfd::EXIF] = $exif;
161 }
162 if ($gps = $ifd0->getSubIfd(PelIfd::GPS)) {
163 $ifds[PelIfd::GPS] = $gps;
164 }
165 $tags = exif_get_enabled_tags();
166 $data = array();
167 foreach ($tags as $tag) {
168 $entry = $ifds[$tag->ifd]->getEntry($tag->tag);
169 if ($entry) {
170 $row = array();
171 switch($tag->tag) {
172 case PelTag::DATE_TIME:
173 case PelTag::DATE_TIME_ORIGINAL:
174 case PelTag::DATE_TIME_DIGITIZED:
175 // Return a unixtimestamp. Theme will handle date formating.
176 $data[$tag->ifd][$tag->tag] = $entry->getValue();
177 break;
178
179 default:
180 $data[$tag->ifd][$tag->tag] = utf8_encode($entry->getText());
181 }
182 }
183 }
184 return $data;
185 }
186
187 /**
188 * Return an array containing only the tags that were enabled.
189 */
190 function exif_get_enabled_tags() {
191 static $tags = array();
192
193 if (!count($tags)) {
194 $result = db_query('SELECT * FROM {exif_tags} WHERE status = 1');
195 while ($tag = db_fetch_object($result)) {
196 $tags[] = $tag;
197 }
198 if (!count($tags)) {
199 // Table is empty, get some defaults
200 $tags = exif_get_default_settings();
201 foreach ($tags as $key => $tag) {
202 if (!$tag->status) {
203 unset($tags[$key]);
204 }
205 }
206 }
207 usort($tags, '_exif_compare_tags');
208 }
209
210 return $tags;
211 }
212
213 /**
214 * Return an array with all the valid tags and their settings.
215 */
216 function exif_load_settings() {
217 $tags = exif_get_default_settings();
218
219 $result = db_query('SELECT * FROM {exif_tags}');
220 while ($tag = db_fetch_object($result)) {
221 $tags["{$tag->ifd}_{$tag->tag}"] = $tag;
222 }
223 usort($tags, '_exif_compare_tags');
224
225 return $tags;
226 }
227
228 function exif_save_settings($values) {
229 db_lock_table('exif_tags');
230 foreach ($values as $tag) {
231 if (!is_array($tag) || !isset($tag['ifd'])) {
232 continue; // Save only appropriate form values
233 }
234 db_query('DELETE FROM {exif_tags} WHERE ifd = %d AND tag = %d', $tag['ifd'], $tag['tag']);
235 db_query('INSERT INTO {exif_tags} (ifd, tag, status, weight) VALUES (%d, %d, %d, %d)', $tag['ifd'], $tag['tag'], $tag['status'], $tag['weight']);
236 }
237 db_unlock_tables();
238 }
239
240 function exif_reset_settings() {
241 db_query('DELETE FROM {exif_tags}');
242 }
243
244 /**
245 * Return an array with all the valid tags, with some useful default settings.
246 */
247 function exif_get_default_settings() {
248 $tags = exif_get_valid_tags();
249 $tags[PelIfd::EXIF .'_'. PelTag::DATE_TIME_ORIGINAL]->status = 1;
250 $tags[PelIfd::EXIF .'_'. PelTag::DATE_TIME_ORIGINAL]->weight = -10;
251 $tags[PelIfd::IFD0 .'_'. PelTag::MODEL]->status = 1;
252 $tags[PelIfd::IFD0 .'_'. PelTag::MODEL]->weight = -8;
253 $tags[PelIfd::EXIF .'_'. PelTag::FOCAL_LENGTH]->status = 1;
254 $tags[PelIfd::EXIF .'_'. PelTag::FOCAL_LENGTH]->weight = -6;
255 $tags[PelIfd::EXIF .'_'. PelTag::APERTURE_VALUE]->status = 1;
256 $tags[PelIfd::EXIF .'_'. PelTag::APERTURE_VALUE]->weight = -4;
257 $tags[PelIfd::EXIF .'_'. PelTag::EXPOSURE_TIME]->status = 1;
258 $tags[PelIfd::EXIF .'_'. PelTag::EXPOSURE_TIME]->weight = -2;
259 $tags[PelIfd::EXIF .'_'. PelTag::ISO_SPEED_RATINGS]->status = 1;
260 $tags[PelIfd::EXIF .'_'. PelTag::ISO_SPEED_RATINGS]->weight = 0;
261 return $tags;
262 }
263
264 /**
265 * Helper function to return all the valid tags (well, at least those this module cares about).
266 *
267 * For convenience, each tag has a key in the form: "ifd_tag", where ifd and tag
268 * are standard Exif ids. Those ids can be found in PelIfd.php and PelTag.php.
269 */
270 function exif_get_valid_tags() {
271 $valid_tags = array();
272 $valid_tags = array_merge($valid_tags, _exif_get_valid_ifd_tags(PelIfd::IFD0, new PelIfd(PelIfd::IFD0)));
273 $valid_tags = array_merge($valid_tags, _exif_get_valid_ifd_tags(PelIfd::EXIF, new PelIfd(PelIfd::EXIF)));
274 $valid_tags = array_merge($valid_tags, _exif_get_valid_ifd_tags(PelIfd::GPS, new PelIfd(PelIfd::GPS)));
275 return $valid_tags;
276 }
277
278 function _exif_get_valid_ifd_tags($ifd_id, $ifd) {
279 $tags = array();
280 $pel_tags = $ifd->getValidTags();
281 foreach ($pel_tags as $pel_tag) {
282 $tag = new StdClass();
283 $tag->ifd = $ifd_id;
284 $tag->tag = $pel_tag;
285 $tags["{$tag->ifd}_{$tag->tag}"] = $tag;
286 }
287 return $tags;
288 }
289
290 function _exif_compare_tags($a, $b) {
291 $status = $b->status - $a->status;
292 // Separate enabled from disabled.
293 if ($status) {
294 return $status;
295 }
296 // Enabled tags
297 if ($a->status) {
298 $weight = $a->weight - $b->weight;
299 if ($weight) {
300 return $weight;
301 }
302 return $a->ifd - $b->ifd;
303 }
304 // Disabled tags
305 else {
306 return $a->ifd - $b->ifd;
307 }
308 }
309
310 function theme_exif_table($node) {
311 _exif_bootstrap();
312 // Retrieve the desired tag values from the file
313 $tags = exif_get_enabled_tags();
314 $rows = array();
315 $data = $node->exif_data;
316
317 foreach ($tags as $tag) {
318 if (!empty($data[$tag->ifd][$tag->tag])) {
319 $row = array();
320 $row[] = array('data' => check_plain(utf8_encode(PelTag::getTitle($tag->ifd, $tag->tag))), 'class' => 'exif-title');
321 $val = $data[$tag->ifd][$tag->tag];
322 switch($tag->tag) {
323 case PelTag::DATE_TIME:
324 case PelTag::DATE_TIME_ORIGINAL:
325 case PelTag::DATE_TIME_DIGITIZED:
326 // Use Drupal's date formatting instead of Pel's
327 $row[] = array('data' => format_date($val, 'medium', '', 0), 'class' => 'exif-value');
328 break;
329
330 default:
331 $row[] = array('data' => check_plain($val), 'class' => 'exif-value');
332 }
333 $rows[] = $row;
334 }
335 }
336
337 if (empty($rows)) {
338 return '';
339 }
340 $header = array(array('data' => t('Image information'), 'colspan' => 2));
341 return theme('table', $header, $rows, array('class' => 'exif'));
342 }
343
344 function theme_exif_admin_settings_form($form) {
345 $header = array(t('Tag'), t('Weight'), t('Type'));
346 $rows = array();
347 foreach (element_children($form['tags']) as $key) {
348 $row = array();
349 $row[] = drupal_render($form['tags'][$key]['status']);
350 $row[] = drupal_render($form['tags'][$key]['weight']);
351 $row[] = drupal_render($form['tags'][$key]['type']);
352 $rows[] = $row;
353 }
354 $output .= theme('table', $header, $rows, array('class' => 'admin-settings-exif'));
355 $output .= drupal_render($form);
356 return $output;
357 }
358
359 function _exif_bootstrap() {
360 include_once drupal_get_path('module', 'exif') .'/pel/PelJpeg.php';
361 }
362

  ViewVC Help
Powered by ViewVC 1.1.2