source: trunk/admin/include/functions_metadata.php @ 31097

Last change on this file since 31097 was 31097, checked in by plg, 9 years ago

feature 2955: make the keywords separator configurable

  • Property svn:eol-style set to LF
File size: 8.5 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2014 Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24/**
25 * @package functions\admin\metadata
26 */
27
28
29include_once(PHPWG_ROOT_PATH.'/include/functions_metadata.inc.php');
30
31
32/**
33 * Returns IPTC metadata to sync from a file, depending on IPTC mapping.
34 * @toto : clean code (factorize foreach)
35 *
36 * @param string $file
37 * @return array
38 */
39function get_sync_iptc_data($file)
40{
41  global $conf;
42
43  $map = $conf['use_iptc_mapping'];
44
45  $iptc = get_iptc_data($file, $map);
46
47  foreach ($iptc as $pwg_key => $value)
48  {
49    if (in_array($pwg_key, array('date_creation', 'date_available')))
50    {
51      if (preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
52      {
53        $year = $matches[1];
54        $month = $matches[2];
55        $day = $matches[3];
56
57        if (!checkdate($month, $day, $year))
58        {
59          // we suppose the year is correct
60          $month = 1;
61          $day = 1;
62        }
63
64        $iptc[$pwg_key] = $year.'-'.$month.'-'.$day;
65      }
66    }
67  }
68
69  if (isset($iptc['keywords']))
70  {
71    $iptc['keywords'] = metadata_normalize_keywords_string($iptc['keywords']);
72  }
73
74  foreach ($iptc as $pwg_key => $value)
75  {
76    $iptc[$pwg_key] = addslashes($iptc[$pwg_key]);
77  }
78
79  return $iptc;
80}
81
82/**
83 * Returns EXIF metadata to sync from a file, depending on EXIF mapping.
84 *
85 * @param string $file
86 * @return array
87 */
88function get_sync_exif_data($file)
89{
90  global $conf;
91
92  $exif = get_exif_data($file, $conf['use_exif_mapping']);
93
94  foreach ($exif as $pwg_key => $value)
95  {
96    if (in_array($pwg_key, array('date_creation', 'date_available')))
97    {
98      if (preg_match('/^(\d{4}).(\d{2}).(\d{2}) (\d{2}).(\d{2}).(\d{2})/', $value, $matches))
99      {
100        $exif[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3].' '.$matches[4].':'.$matches[5].':'.$matches[6];
101      }
102      elseif (preg_match('/^(\d{4}).(\d{2}).(\d{2})/', $value, $matches))
103      {
104        $exif[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
105      }
106      else
107      {
108        unset($exif[$pwg_key]);
109        continue;
110      }
111    }
112
113    if (in_array($pwg_key, array('keywords', 'tags')))
114    {
115      $exif[$pwg_key] = metadata_normalize_keywords_string($exif[$pwg_key]);
116    }
117   
118    $exif[$pwg_key] = addslashes($exif[$pwg_key]);
119  }
120
121  return $exif;
122}
123
124/**
125 * Get all potential file metadata fields, including IPTC and EXIF.
126 *
127 * @return string[]
128 */
129function get_sync_metadata_attributes()
130{
131  global $conf;
132
133  $update_fields = array('filesize', 'width', 'height');
134
135  if ($conf['use_exif'])
136  {
137    $update_fields =
138      array_merge(
139        $update_fields,
140        array_keys($conf['use_exif_mapping']),
141        array('latitude', 'longitude')
142        );
143  }
144
145  if ($conf['use_iptc'])
146  {
147    $update_fields =
148      array_merge(
149        $update_fields,
150        array_keys($conf['use_iptc_mapping'])
151        );
152  }
153
154  return array_unique($update_fields);
155}
156
157/**
158 * Get all metadata of a file.
159 *
160 * @param array $infos - (path[, representative_ext])
161 * @return array - includes data provided in $infos
162 */
163function get_sync_metadata($infos)
164{
165  global $conf;
166  $file = PHPWG_ROOT_PATH.$infos['path'];
167  $fs = @filesize($file);
168
169  if ($fs===false)
170  {
171    return false;
172  }
173
174  $infos['filesize'] = floor($fs/1024);
175
176  if (isset($infos['representative_ext']))
177  {
178    $file = original_to_representative($file, $infos['representative_ext']);
179  }
180
181  if ($image_size = @getimagesize($file))
182  {
183    $infos['width'] = $image_size[0];
184    $infos['height'] = $image_size[1];
185  }
186
187  if ($conf['use_exif'])
188  {
189    $exif = get_sync_exif_data($file);
190    $infos = array_merge($infos, $exif);
191  }
192
193  if ($conf['use_iptc'])
194  {
195    $iptc = get_sync_iptc_data($file);
196    $infos = array_merge($infos, $iptc);
197  }
198
199  return $infos;
200}
201
202/**
203 * Sync all metadata of a list of images.
204 * Metadata are fetched from original files and saved in database.
205 *
206 * @param int[] $ids
207 */
208function sync_metadata($ids)
209{
210  global $conf;
211
212  if (!defined('CURRENT_DATE'))
213  {
214    define('CURRENT_DATE', date('Y-m-d'));
215  }
216
217  $datas = array();
218  $tags_of = array();
219
220  $query = '
221SELECT id, path, representative_ext
222  FROM '.IMAGES_TABLE.'
223  WHERE id IN (
224'.wordwrap(implode(', ', $ids), 160, "\n").'
225)
226;';
227
228  $result = pwg_query($query);
229  while ($data = pwg_db_fetch_assoc($result))
230  {
231    $data = get_sync_metadata($data);
232    if ($data === false)
233    {
234      continue;
235    }
236
237    $id = $data['id'];
238    foreach (array('keywords', 'tags') as $key)
239    {
240      if (isset($data[$key]))
241      {
242        if (!isset($tags_of[$id]))
243        {
244          $tags_of[$id] = array();
245        }
246
247        foreach (explode(',', $data[$key]) as $tag_name)
248        {
249          $tags_of[$id][] = tag_id_from_tag_name($tag_name);
250        }
251      }
252    }
253
254    $data['date_metadata_update'] = CURRENT_DATE;
255
256    $datas[] = $data;
257  }
258
259  if (count($datas) > 0)
260  {
261    $update_fields = get_sync_metadata_attributes();
262    $update_fields[] = 'date_metadata_update';
263
264    $update_fields = array_diff(
265      $update_fields,
266      array('tags', 'keywords')
267            );
268
269    mass_updates(
270      IMAGES_TABLE,
271      array(
272        'primary' => array('id'),
273        'update'  => $update_fields
274        ),
275      $datas,
276      MASS_UPDATES_SKIP_EMPTY
277      );
278  }
279
280  set_tags_of($tags_of);
281}
282
283/**
284 * Returns an array associating element id (images.id) with its complete
285 * path in the filesystem
286 *
287 * @param int $category_id
288 * @param int $site_id
289 * @param boolean $recursive
290 * @param boolean $only_new
291 * @return array
292 */
293function get_filelist($category_id = '', $site_id=1, $recursive = false,
294                      $only_new = false)
295{
296  // filling $cat_ids : all categories required
297  $cat_ids = array();
298
299  $query = '
300SELECT id
301  FROM '.CATEGORIES_TABLE.'
302  WHERE site_id = '.$site_id.'
303    AND dir IS NOT NULL';
304  if (is_numeric($category_id))
305  {
306    if ($recursive)
307    {
308      $query.= '
309    AND uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$category_id.'(,|$)\'
310';
311    }
312    else
313    {
314      $query.= '
315    AND id = '.$category_id.'
316';
317    }
318  }
319  $query.= '
320;';
321  $result = pwg_query($query);
322  while ($row = pwg_db_fetch_assoc($result))
323  {
324    $cat_ids[] = $row['id'];
325  }
326
327  if (count($cat_ids) == 0)
328  {
329    return array();
330  }
331
332  $query = '
333SELECT id, path, representative_ext
334  FROM '.IMAGES_TABLE.'
335  WHERE storage_category_id IN ('.implode(',', $cat_ids).')';
336  if ($only_new)
337  {
338    $query.= '
339    AND date_metadata_update IS NULL
340';
341  }
342  $query.= '
343;';
344  return hash_from_query($query, 'id');
345}
346
347/**
348 * Returns the list of keywords (future tags) correctly separated with
349 * commas. Other separators are converted into commas.
350 *
351 * @param string $keywords_string
352 * @return string
353 */
354function metadata_normalize_keywords_string($keywords_string)
355{
356  global $conf;
357 
358  $keywords_string = preg_replace($conf['metadata_keyword_separator_regex'], ',', $keywords_string);
359  $keywords_string = preg_replace('/,+/', ',', $keywords_string);
360  $keywords_string = preg_replace('/^,+|,+$/', '', $keywords_string);
361     
362  $keywords_string = implode(
363    ',',
364    array_unique(
365      explode(
366        ',',
367        $keywords_string
368        )
369      )
370    );
371
372  return $keywords_string;
373}
374?>
Note: See TracBrowser for help on using the repository browser.