source: extensions/AMetaData/amd_ajax.php @ 6977

Last change on this file since 6977 was 6977, checked in by grum, 14 years ago

Migration from version 0.4.0 to 0.5.1 implemented

File size: 54.5 KB
Line 
1<?php
2/*
3 * -----------------------------------------------------------------------------
4 * Plugin Name: Advanced MetaData
5 * -----------------------------------------------------------------------------
6 * Author     : Grum
7 *   email    : grum@piwigo.org
8 *   website  : http://photos.grum.fr
9 *   PWG user : http://forum.piwigo.org/profile.php?id=3706
10 *
11 *   << May the Little SpaceFrog be with you ! >>
12 *
13 * -----------------------------------------------------------------------------
14 *
15 * See main.inc.php for release information
16 *
17 * manage all the ajax requests
18 * -----------------------------------------------------------------------------
19 */
20
21  define('PHPWG_ROOT_PATH',dirname(dirname(dirname(__FILE__))).'/');
22
23  /*
24   * set ajax module in admin mode if request is used for admin interface
25   */
26  if(!isset($_REQUEST['ajaxfct'])) $_REQUEST['ajaxfct']='';
27  if(preg_match('/^admin\./i', $_REQUEST['ajaxfct']))
28  {
29    define('IN_ADMIN', true);
30  }
31
32  // the common.inc.php file loads all the main.inc.php plugins files
33  include_once(PHPWG_ROOT_PATH.'include/common.inc.php' );
34  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCAjax.class.inc.php');
35  include_once('amd_root.class.inc.php');
36
37  load_language('plugin.lang', AMD_PATH);
38
39
40  class AMD_ajax extends AMD_root
41  {
42    /**
43     * constructor
44     */
45    public function __construct($prefixeTable, $filelocation)
46    {
47      parent::__construct($prefixeTable, $filelocation);
48      $this->loadConfig();
49      $this->checkRequest();
50      $this->returnAjaxContent();
51    }
52
53    /**
54     * check the $_REQUEST values and set default values
55     *
56     */
57    protected function checkRequest()
58    {
59      global $user;
60
61      if(!isset($_REQUEST['ajaxfct'])) $_REQUEST['ajaxfct']='';
62
63      // check if asked function is valid
64      if(!(
65           $_REQUEST['ajaxfct']=='admin.makeStats.getList' or
66           $_REQUEST['ajaxfct']=='admin.makeStats.doAnalyze' or
67           $_REQUEST['ajaxfct']=='admin.makeStats.consolidate' or
68           $_REQUEST['ajaxfct']=='admin.showStats.getListTags' or
69           $_REQUEST['ajaxfct']=='admin.showStats.getListImages' or
70           $_REQUEST['ajaxfct']=='admin.updateTag.select' or
71           $_REQUEST['ajaxfct']=='admin.config.setOption' or
72           $_REQUEST['ajaxfct']=='admin.group.getList' or
73           $_REQUEST['ajaxfct']=='admin.group.delete' or
74           $_REQUEST['ajaxfct']=='admin.group.getNames' or
75           $_REQUEST['ajaxfct']=='admin.group.setNames' or
76           $_REQUEST['ajaxfct']=='admin.group.setOrder' or
77           $_REQUEST['ajaxfct']=='admin.group.getTagList' or
78           $_REQUEST['ajaxfct']=='admin.group.setTagList' or
79           $_REQUEST['ajaxfct']=='admin.group.getOrderedTagList' or
80           $_REQUEST['ajaxfct']=='admin.group.setOrderedTagList' or
81           $_REQUEST['ajaxfct']=='admin.userDefined.getList' or
82           $_REQUEST['ajaxfct']=='admin.userDefined.getTag' or
83           $_REQUEST['ajaxfct']=='admin.userDefined.setTag' or
84           $_REQUEST['ajaxfct']=='admin.userDefined.deleteTag' or
85           $_REQUEST['ajaxfct']=='admin.tag.getValues' or
86           $_REQUEST['ajaxfct']=='admin.tags.getKeywords' or
87           $_REQUEST['ajaxfct']=='admin.tags.convertKeywords' or
88
89           $_REQUEST['ajaxfct']=='public.makeStats.doPictureAnalyze')) $_REQUEST['ajaxfct']='';
90
91      if(preg_match('/^admin\./i', $_REQUEST['ajaxfct']) and !is_admin()) $_REQUEST['ajaxfct']='';
92
93      if($_REQUEST['ajaxfct']!='')
94      {
95        /*
96         * check admin.makeStats.getList values
97         */
98        if($_REQUEST['ajaxfct']=="admin.makeStats.getList")
99        {
100          if(!isset($_REQUEST['selectMode'])) $_REQUEST['selectMode']="caddieAdd";
101
102          if(!($_REQUEST['selectMode']=="notAnalyzed" or
103               $_REQUEST['selectMode']=="caddieAdd" or
104               $_REQUEST['selectMode']=="caddieReplace" or
105               $_REQUEST['selectMode']=="analyzed" or
106               $_REQUEST['selectMode']=="all")) $_REQUEST['selectMode']="caddieAdd";
107
108          if(!isset($_REQUEST['numOfItems'])) $_REQUEST['numOfItems']=25;
109
110          if(!isset($_REQUEST['ignoreOptions'])) $_REQUEST['ignoreOptions']=array();
111        }
112
113        /*
114         * check admin.makeStats.doAnalyze values
115         */
116        if($_REQUEST['ajaxfct']=="admin.makeStats.doAnalyze")
117        {
118          if(!isset($_REQUEST['imagesList'])) $_REQUEST['imagesList']="";
119        }
120
121        /*
122         * check admin.makeStats.consolidate values
123         */
124        if($_REQUEST['ajaxfct']=="admin.makeStats.consolidate")
125        {
126          if(!isset($_REQUEST['step'])) $_REQUEST['step']="*";
127        }
128
129        /*
130         * check admin.showStats.getListTags values
131         */
132        if($_REQUEST['ajaxfct']=="admin.showStats.getListTags")
133        {
134          if(!isset($_REQUEST['orderType'])) $_REQUEST['orderType']="tag";
135
136          if(!($_REQUEST['orderType']=="tag" or
137               $_REQUEST['orderType']=="label" or
138               $_REQUEST['orderType']=="num")) $_REQUEST['orderType']="tag";
139
140          if(!isset($_REQUEST['filterType'])) $_REQUEST['filterType']="";
141
142          if(!($_REQUEST['filterType']=="" or
143               ($_REQUEST['filterType']=="magic" and !in_array('magic', $this->config['amd_FillDataBaseExcludeFilters'])) or
144               $_REQUEST['filterType']=="userDefined" or
145               ($_REQUEST['filterType']=="exif" and !in_array('exif', $this->config['amd_FillDataBaseExcludeFilters'])) or
146               ($_REQUEST['filterType']=="exif.maker.Canon" and !in_array('maker', $this->config['amd_FillDataBaseExcludeFilters'])) or
147               ($_REQUEST['filterType']=="exif.maker.Nikon" and !in_array('maker', $this->config['amd_FillDataBaseExcludeFilters'])) or
148               ($_REQUEST['filterType']=="exif.maker.Pentax" and !in_array('maker', $this->config['amd_FillDataBaseExcludeFilters'])) or
149               ($_REQUEST['filterType']=="xmp" and !in_array('xmp', $this->config['amd_FillDataBaseExcludeFilters'])) or
150               ($_REQUEST['filterType']=="iptc"  and !in_array('iptc', $this->config['amd_FillDataBaseExcludeFilters']))
151               )) $_REQUEST['filterType']="";
152
153          if(!isset($_REQUEST['excludeUnusedTag'])) $_REQUEST['excludeUnusedTag']="n";
154
155          if(!($_REQUEST['excludeUnusedTag']=="y" or
156               $_REQUEST['excludeUnusedTag']=="n" )) $_REQUEST['excludeUnusedTag']="n";
157
158          if(!isset($_REQUEST['selectedTagOnly'])) $_REQUEST['selectedTagOnly']="n";
159
160          if(!($_REQUEST['selectedTagOnly']=="y" or
161               $_REQUEST['selectedTagOnly']=="n" )) $_REQUEST['selectedTagOnly']="n";
162        }
163
164        /*
165         * check admin.showStats.getListImages values
166         */
167        if($_REQUEST['ajaxfct']=="admin.showStats.getListImages")
168        {
169          if(!isset($_REQUEST['orderType'])) $_REQUEST['orderType']="num";
170
171          if(!($_REQUEST['orderType']=="value" or
172               $_REQUEST['orderType']=="num")) $_REQUEST['orderType']="num";
173
174          if(!isset($_REQUEST['tagId'])) $_REQUEST['tagId']="*";
175        }
176
177        /*
178         * check admin.updateTag.select values
179         */
180        if($_REQUEST['ajaxfct']=="admin.updateTag.select")
181        {
182          if(!isset($_REQUEST['numId'])) $_REQUEST['numId']="";
183
184          if(!isset($_REQUEST['tagSelected'])) $_REQUEST['tagSelected']="";
185        }
186
187        /*
188         * check admin.config.setOption values
189         */
190        if($_REQUEST['ajaxfct']=="admin.config.setOption")
191        {
192          if(!isset($_REQUEST['id'])) $_REQUEST['ajaxfct']='';
193          if(!isset($_REQUEST['value'])) $_REQUEST['ajaxfct']='';
194        }
195
196        /*
197         * check admin.group.delete values
198         */
199        if($_REQUEST['ajaxfct']=="admin.group.delete" and !isset($_REQUEST['id']))
200        {
201          $_REQUEST['id']="";
202        }
203
204        /*
205         * check admin.groupSetOrder values
206         */
207        if($_REQUEST['ajaxfct']=="admin.group.setOrder" and !isset($_REQUEST['listGroup']))
208        {
209          $_REQUEST['listGroup']="";
210        }
211
212        /*
213         * check admin.group.getNames values
214         */
215        if($_REQUEST['ajaxfct']=="admin.group.getNames" and !isset($_REQUEST['id']))
216        {
217          $_REQUEST['id']="";
218        }
219
220        /*
221         * check admin.group.setNames values
222         */
223        if($_REQUEST['ajaxfct']=="admin.group.setNames")
224        {
225          if(!isset($_REQUEST['listNames'])) $_REQUEST['listNames']="";
226
227          if(!isset($_REQUEST['id'])) $_REQUEST['id']="";
228        }
229
230        /*
231         * check admin.group.getTagList values
232         */
233        if($_REQUEST['ajaxfct']=="admin.group.getTagList" and !isset($_REQUEST['id']))
234        {
235          $_REQUEST['id']="";
236        }
237
238        /*
239         * check admin.group.setTagList values
240         */
241        if($_REQUEST['ajaxfct']=="admin.group.setTagList")
242        {
243          if(!isset($_REQUEST['id'])) $_REQUEST['id']="";
244
245          if(!isset($_REQUEST['listTag'])) $_REQUEST['listTag']="";
246        }
247
248        /*
249         * check admin.group.getOrderedTagList values
250         */
251        if($_REQUEST['ajaxfct']=="admin.group.getOrderedTagList" and !isset($_REQUEST['id']))
252        {
253          $_REQUEST['id']="";
254        }
255
256        /*
257         * check admin.group.setOrderedTagList values
258         */
259        if($_REQUEST['ajaxfct']=="admin.group.setOrderedTagList")
260        {
261          if(!isset($_REQUEST['id'])) $_REQUEST['id']="";
262
263          if(!isset($_REQUEST['listTag'])) $_REQUEST['listTag']="";
264        }
265
266        /*
267         * check admin.userDefined.getTag values
268         */
269        if($_REQUEST['ajaxfct']=="admin.userDefined.getTag" and !isset($_REQUEST['id']))
270        {
271          $_REQUEST['id']="";
272        }
273
274        /*
275         * check admin.userDefined.setTag values
276         */
277        if($_REQUEST['ajaxfct']=="admin.userDefined.setTag")
278        {
279          if(!isset($_REQUEST['id'])) $_REQUEST['id']="";
280          if($_REQUEST['id']!='' and !preg_match('/\d+/', $_REQUEST['id'])) $_REQUEST['id']="";
281
282          if(!isset($_REQUEST['properties']) or
283              (isset($_REQUEST['properties']) and
284               !(isset($_REQUEST['properties']['name']) and
285                 isset($_REQUEST['properties']['rules']) and
286                 isset($_REQUEST['properties']['tagId'])
287                )
288              )
289            ) $_REQUEST['ajaxfct']='';
290
291          if(isset($_REQUEST['properties']['rules']))
292          {
293            foreach($_REQUEST['properties']['rules'] as $val)
294            {
295              if(!(isset($val['order']) and
296                   isset($val['value']) and
297                   isset($val['parentId']) and
298                   isset($val['type']) and
299                   isset($val['defId']))) $_REQUEST['ajaxfct']='';
300            }
301          }
302        }
303
304        /*
305         * check admin.userDefined.deleteTag values
306         */
307        if($_REQUEST['ajaxfct']=="admin.userDefined.deleteTag" and !isset($_REQUEST['id']))
308        {
309          $_REQUEST['id']="";
310        }
311
312
313        /*
314         * check admin.tag.getValues values
315         */
316        if($_REQUEST['ajaxfct']=="admin.tag.getValues" and !isset($_REQUEST['id']))
317        {
318          $_REQUEST['ajaxfct']='';
319        }
320
321        /*
322         * check admin.tags.convertKeywords values
323         */
324        if($_REQUEST['ajaxfct']=="admin.tags.convertKeywords")
325        {
326          if(!isset($_REQUEST['keywords'])) $_REQUEST['keywords']=array();
327          if(!is_array($_REQUEST['keywords'])) $_REQUEST['keywords']=array();
328          if(count($_REQUEST['keywords'])==0) $_REQUEST['ajaxfct']='';
329        }
330
331
332
333
334
335        /*
336         * check public.makeStats.doPictureAnalyze values
337         */
338        if($_REQUEST['ajaxfct']=="public.makeStats.doPictureAnalyze")
339        {
340          if(!isset($_REQUEST['id'])) $_REQUEST['id']="0";
341        }
342      }
343    }
344
345
346    /**
347     * return ajax content
348     */
349    protected function returnAjaxContent()
350    {
351      $result="<p class='errors'>An error has occured</p>";
352      switch($_REQUEST['ajaxfct'])
353      {
354        case 'admin.makeStats.getList':
355          $result=$this->ajax_amd_admin_makeStatsGetList($_REQUEST['selectMode'], $_REQUEST['numOfItems'], $_REQUEST['ignoreOptions']);
356          break;
357        case 'admin.makeStats.doAnalyze':
358          $result=$this->ajax_amd_admin_makeStatsDoAnalyze($_REQUEST['imagesList']);
359          break;
360        case 'admin.makeStats.consolidate':
361          $result=$this->ajax_amd_admin_makeStatsConsolidate();
362          break;
363        case 'admin.showStats.getListTags':
364          $result=$this->ajax_amd_admin_showStatsGetListTags($_REQUEST['orderType'], $_REQUEST['filterType'], $_REQUEST['excludeUnusedTag'], $_REQUEST['selectedTagOnly']);
365          break;
366        case 'admin.showStats.getListImages':
367          $result=$this->ajax_amd_admin_showStatsGetListImages($_REQUEST['tagId'], $_REQUEST['orderType']);
368          break;
369        case 'admin.updateTag.select':
370          $result=$this->ajax_amd_admin_updateTagSelect($_REQUEST['numId'], $_REQUEST['tagSelected']);
371          break;
372        case 'admin.config.setOption':
373          $result=$this->ajax_amd_admin_configSetOption($_REQUEST['id'], $_REQUEST['value']);
374          break;
375        case 'admin.group.getList':
376          $result=$this->ajax_amd_admin_groupGetList();
377          break;
378        case 'admin.group.delete':
379          $result=$this->ajax_amd_admin_groupDelete($_REQUEST['id']);
380          break;
381        case 'admin.group.getNames':
382          $result=$this->ajax_amd_admin_groupGetNames($_REQUEST['id']);
383          break;
384        case 'admin.group.setNames':
385          $result=$this->ajax_amd_admin_groupSetNames($_REQUEST['id'], $_REQUEST['listNames']);
386          break;
387        case 'admin.group.setOrder':
388          $result=$this->ajax_amd_admin_groupSetOrder($_REQUEST['listGroup']);
389          break;
390        case 'admin.group.getTagList':
391          $result=$this->ajax_amd_admin_groupGetTagList($_REQUEST['id']);
392          break;
393        case 'admin.group.setTagList':
394          $result=$this->ajax_amd_admin_groupSetTagList($_REQUEST['id'], $_REQUEST['listTag']);
395          break;
396        case 'admin.group.getOrderedTagList':
397          $result=$this->ajax_amd_admin_groupGetOrderedTagList($_REQUEST['id']);
398          break;
399        case 'admin.group.setOrderedTagList':
400          $result=$this->ajax_amd_admin_groupSetOrderedTagList($_REQUEST['id'], $_REQUEST['listTag']);
401          break;
402        case 'admin.userDefined.getList':
403          $result=$this->ajax_amd_admin_userDefinedGetList();
404          break;
405        case 'admin.userDefined.getTag':
406          $result=$this->ajax_amd_admin_userDefinedGetTag($_REQUEST['id']);
407          break;
408        case 'admin.userDefined.setTag':
409          $result=$this->ajax_amd_admin_userDefinedSetTag($_REQUEST['id'], $_REQUEST['properties']);
410          break;
411        case 'admin.userDefined.deleteTag':
412          $result=$this->ajax_amd_admin_userDefinedDeleteTag($_REQUEST['id']);
413          break;
414        case 'admin.tag.getValues':
415          $result=$this->ajax_amd_admin_tagGetValues($_REQUEST['id']);
416          break;
417        case 'admin.tags.getKeywords':
418          $result=$this->ajax_amd_admin_tagsGetKeywords();
419          break;
420        case 'admin.tags.convertKeywords':
421          $result=$this->ajax_amd_admin_tagsConvertKeywords($_REQUEST['keywords']);
422          break;
423
424
425        case 'public.makeStats.doPictureAnalyze':
426          $result=$this->ajax_amd_public_makeStatsDoPictureAnalyze($_REQUEST['id']);
427          break;
428      }
429      GPCAjax::returnResult($result);
430    }
431
432    /*------------------------------------------------------------------------*
433     *
434     * PUBLIC FUNCTIONS
435     *
436     *----------------------------------------------------------------------- */
437    private function ajax_amd_public_makeStatsDoPictureAnalyze($imageId)
438    {
439      if($imageId==0)
440      {
441        // get a randomly picture...
442        $sql="SELECT pai.imageId, pi.path, pi.has_high
443              FROM ".$this->tables['images']." pai
444                LEFT JOIN ".IMAGES_TABLE." pi ON pai.imageId=pi.id
445              WHERE analyzed='n'
446              ORDER BY RAND() LIMIT 1;";
447      }
448      else
449      {
450        $sql="SELECT path, id AS imageId
451              FROM ".IMAGES_TABLE."
452              WHERE id='$imageId';";
453      }
454
455      $result=pwg_query($sql);
456      if($result)
457      {
458        $path=dirname(dirname(dirname(__FILE__)));
459        while($row=pwg_db_fetch_assoc($result))
460        {
461          $imageId=$row['imageId'];
462          if($row['has_high']==='true' and $this->config['amd_UseMetaFromHD']=='y')
463          {
464            $filename=$path."/".dirname($row['path'])."/pwg_high/".basename($row['path']);
465          }
466          else
467          {
468            $filename=$path."/".$row['path'];
469          }
470        }
471
472        $this->analyzeImageFile($filename, $imageId);
473        $this->makeStatsConsolidation();
474
475        return("Analyze of image #$imageId is a success !");
476      }
477
478      return("Try to analyze image #$imageId failed...");
479
480    }
481
482
483
484    /*------------------------------------------------------------------------*
485     *
486     * ADMIN FUNCTIONS
487     *
488     *----------------------------------------------------------------------- */
489
490    /**
491     * return a list of picture Id
492     *
493     * picture id are separated with a space " "
494     * picture id are grouped in blocks of 'amd_NumberOfItemsPerRequest' items and
495     * are separated with a semi-colon ";"
496     *
497     * client side just have to split blocks, and transmit it to the server
498     *
499     * There is two mode to determine the pictures being analyzed :
500     *  - "all"         : analyze all the images
501     *  - "notAnalyzed" : analyze only the images not yet analyzed
502     *
503     * @param String $mode
504     * @param Integer $nbOfItems : number of items per request
505     * @return String : list of image id to be analyzed, separated with a space
506     *                      "23 78 4523 5670"
507     */
508    private function ajax_amd_admin_makeStatsGetList($mode, $nbOfItems, $ignoreSchemas)
509    {
510      global $user;
511
512      $returned="";
513      $this->config['amd_FillDataBaseIgnoreSchemas']=$ignoreSchemas;
514      $this->config['amd_NumberOfItemsPerRequest']=$nbOfItems;
515      $this->saveConfig();
516
517      $sql="SELECT ait.imageId FROM ".$this->tables['images']." ait";
518      if($mode=='notAnalyzed')
519      {
520        $sql.=" WHERE ait.analyzed='n'";
521      }
522      elseif($mode=='caddieAdd' or $mode=='caddieReplace')
523      {
524        $sql.=" LEFT JOIN ".CADDIE_TABLE." ct ON ait.imageId = ct.element_id
525              WHERE ct.user_id = ".$user['id']." ";
526
527        if($mode=='caddieAdd') $sql.=" AND ait.analyzed='n'";
528      }
529      elseif($mode=='analyzed')
530      {
531        $sql.=" WHERE ait.analyzed='y'";
532
533        pwg_query("UPDATE ".$this->tables['images']." SET nbTags=0 WHERE analyzed='y';");
534        pwg_query("UPDATE ".$this->tables['used_tags']." SET numOfImg=0");
535        pwg_query("DELETE FROM ".$this->tables['images_tags']);
536      }
537
538      if($mode=='all' or $mode=='caddieReplace')
539      {
540        pwg_query("UPDATE ".$this->tables['images']." SET analyzed='n', nbTags=0");
541        pwg_query("UPDATE ".$this->tables['used_tags']." SET numOfImg=0");
542        pwg_query("DELETE FROM ".$this->tables['images_tags']);
543      }
544
545      $result=pwg_query($sql);
546      if($result)
547      {
548        $i=0;
549        while($row=pwg_db_fetch_row($result))
550        {
551          $returned.=$row[0];
552          $i++;
553          if($i>=$nbOfItems)
554          {
555            $returned.=";";
556            $i=0;
557          }
558          else
559          {
560            $returned.=" ";
561          }
562        }
563      }
564      return(trim($returned).";");
565    }
566
567
568    /**
569     * extract metadata from images
570     *
571     * @param String $imageList : list of image id to be analyzed, separated with
572     *                            a space
573     *                                "23 78 4523 5670"
574     * @return String : list of the analyzed pictures, with number of tags found
575     *                  for each picture
576     *                    "23=0;78=66;4523=33;5670=91;"
577     */
578    private function ajax_amd_admin_makeStatsDoAnalyze($imagesList)
579    {
580      $list=explode(" ", trim($imagesList));
581
582      $returned="";
583
584      if(count($list)>0 and trim($imagesList)!='')
585      {
586        // $path = path of piwigo's on the server filesystem
587        $path=dirname(dirname(dirname(__FILE__)));
588
589        $sql="SELECT id, path, has_high FROM ".IMAGES_TABLE." WHERE id IN (".implode(", ", $list).")";
590        $result=pwg_query($sql);
591        if($result)
592        {
593          while($row=pwg_db_fetch_assoc($result))
594          {
595            /*
596             * in some case (in a combination of some pictures), when there is too
597             * much pictures to analyze in the same request, a fatal error occurs
598             * with the message : "Allowed memory size of XXXXX bytes exhausted"
599             *
600             *
601             * tracking memory leak is not easy... :-(
602             *
603             */
604            //echo "analyzing:".$row['id']."\n";
605            //$mem1=memory_get_usage();
606            //echo "memory before analyze:".$mem1."\n";
607            if($row['has_high']==='true' and $this->config['amd_UseMetaFromHD']=='y')
608            {
609              $returned.=$this->analyzeImageFile($path."/".dirname($row['path'])."/pwg_high/".basename($row['path']), $row['id']);
610            }
611            else
612            {
613              $returned.=$this->analyzeImageFile($path."/".$row['path'], $row['id']);
614            }
615            //echo $returned."\n";
616            //$mem2=memory_get_usage();
617            //echo "memory after analyze:".$mem2." (".($mem2-$mem1).")\n";
618          }
619        }
620      }
621      return($returned);
622    }
623
624    /**
625     * do some consolidation on database to optimize other requests
626     *
627     */
628    private function ajax_amd_admin_makeStatsConsolidate()
629    {
630      $this->makeStatsConsolidation();
631    }
632
633    /**
634     * return a formatted <table> (using the template "amd_stat_show_iListTags")
635     * of used tag with, for each tag, the number and the percentage of pictures
636     * where the tag was found
637     *
638     * @param String $orderType : order for the list (by tag 'tag' or by number of
639     *                            pictures 'num')
640     * @param String $filterType : filter for the list ('exif', 'xmp', 'iptc' or '')
641     * @return String
642     */
643    private function ajax_amd_admin_showStatsGetListTags($orderType, $filterType, $excludeUnusedTag, $selectedTagOnly)
644    {
645      global $template;
646
647      $this->config['amd_GetListTags_OrderType'] = $orderType;
648      $this->config['amd_GetListTags_FilterType'] = $filterType;
649      $this->config['amd_GetListTags_ExcludeUnusedTag'] = $excludeUnusedTag;
650      $this->config['amd_GetListTags_SelectedTagOnly'] = $selectedTagOnly;
651      $this->saveConfig();
652
653      $local_tpl = new Template(AMD_PATH."admin/", "");
654      $local_tpl->set_filename('body_page',
655                    dirname($this->getFileLocation()).'/admin/amd_metadata_select_iListTags.tpl');
656
657      $numOfPictures=$this->getNumOfPictures();
658
659      $datas=array();
660      $sql="SELECT ut.numId, ut.tagId, ut.translatable, ut.name, ut.numOfImg, if(st.tagId IS NULL, 'n', 'y') as checked, ut.translatedName
661              FROM ".$this->tables['used_tags']." ut
662                LEFT JOIN ".$this->tables['selected_tags']." st
663                  ON st.tagId = ut.tagId ";
664      $where="";
665
666      if($filterType!='')
667      {
668        if($filterType=='exif')
669        {
670          $where.=" WHERE ut.tagId LIKE 'exif.tiff.%'
671                      OR ut.tagId LIKE 'exif.exif.%'
672                      OR ut.tagId LIKE 'exif.gps.%'  ";
673        }
674        else
675        {
676          $where.=" WHERE ut.tagId LIKE '".$filterType.".%' ";
677        }
678      }
679
680      if($excludeUnusedTag=='y')
681      {
682        ($where=="")?$where=" WHERE ":$where.=" AND ";
683        $where.=" ut.numOfImg > 0 ";
684      }
685
686      if($selectedTagOnly=='y')
687      {
688        ($where=="")?$where=" WHERE ":$where.=" AND ";
689        $where.=" st.tagId IS NOT NULL ";
690      }
691
692      $sql.=$where;
693
694      switch($orderType)
695      {
696        case 'tag':
697          $sql.=" ORDER BY tagId ASC";
698          break;
699        case 'num':
700          $sql.=" ORDER BY numOfImg DESC, tagId ASC";
701          break;
702        case 'label':
703          $sql.=" ORDER BY translatedName ASC, tagId ASC";
704          break;
705      }
706
707      $result=pwg_query($sql);
708      if($result)
709      {
710        while($row=pwg_db_fetch_assoc($result))
711        {
712          $datas[]=array(
713            "numId" => $row['numId'],
714            "tagId" => $row['tagId'],
715            "label" => L10n::get($row['name']),
716            "nb"    => $row['numOfImg'],
717            "pct"   => ($numOfPictures!=0)?sprintf("%.2f", 100*$row['numOfImg']/$numOfPictures):"0",
718            "tagChecked" => ($row['checked']=='y')?"checked":""
719          );
720        }
721      }
722
723      $local_tpl->assign('themeconf', Array('name' => $template->get_themeconf('name')));
724      $local_tpl->assign('datas', $datas);
725
726      return($local_tpl->parse('body_page', true));
727    }
728
729
730    /*
731     *
732     *
733     */
734    private function ajax_amd_admin_showStatsGetListImages($tagId, $orderType)
735    {
736      global $template;
737
738      $this->config['amd_GetListImages_OrderType'] = $orderType;
739      $this->saveConfig();
740
741      $local_tpl = new Template(AMD_PATH."admin/", "");
742      $local_tpl->set_filename('body_page',
743                    dirname($this->getFileLocation()).'/admin/amd_metadata_select_iListImages.tpl');
744
745
746
747      $datas=array();
748      $sql="SELECT ut.translatable, ut.numOfImg, COUNT(it.imageId) AS Nb, it.value
749              FROM ".$this->tables['used_tags']." ut
750                LEFT JOIN ".$this->tables['images_tags']." it
751                ON ut.numId = it.numId
752              WHERE ut.tagId = '".$tagId."'
753                AND it.value IS NOT NULL
754              GROUP BY it.value
755              ORDER BY ";
756      switch($orderType)
757      {
758        case 'value':
759          $sql.="it.value ASC";
760          break;
761        case 'num':
762          $sql.="Nb DESC";
763          break;
764      }
765
766      $result=pwg_query($sql);
767      if($result)
768      {
769        while($row=pwg_db_fetch_assoc($result))
770        {
771          $datas[]=array(
772            "value" => AMD_root::prepareValueForDisplay($row['value'], ($row['translatable']=='y'), ", "),
773            "nb"    => $row['Nb'],
774            "pct"   => ($row['numOfImg']!=0)?sprintf("%.2f", 100*$row['Nb']/$row['numOfImg']):"-"
775          );
776        }
777      }
778
779      if(count($datas)>0)
780      {
781        $local_tpl->assign('themeconf', Array('name' => $template->get_themeconf('name')));
782        $local_tpl->assign('datas', $datas);
783        return($local_tpl->parse('body_page', true));
784      }
785      else
786      {
787        return("<div style='width:100%;text-align:center;padding-top:20px;'>".l10n('g003_selected_tag_isnot_linked_with_any_picture')."</div>");
788      }
789    }
790
791
792    /*
793     *
794     *
795     */
796    private function ajax_amd_admin_updateTagSelect($numId, $selected)
797    {
798      if($selected=='y')
799      {
800        $sql="SELECT ut.tagId FROM ".$this->tables['selected_tags']." st
801                LEFT JOIN ".$this->tables['used_tags']." ut
802                  ON ut.tagID = st.tagId
803                WHERE ut.numId = $numId;";
804        $result=pwg_query($sql);
805        if($result)
806        {
807          if(pwg_db_num_rows($result)==0)
808          {
809            $sql="INSERT INTO ".$this->tables['selected_tags']."
810                    SELECT ut.tagId, 0, -1
811                    FROM ".$this->tables['used_tags']." ut
812                      LEFT JOIN ".$this->tables['selected_tags']." st
813                        ON ut.tagID = st.tagId
814                    WHERE ut.numId = $numId;";
815            pwg_query($sql);
816          }
817        }
818      }
819      elseif($selected=='n')
820      {
821        $sql="DELETE FROM ".$this->tables['selected_tags']." st
822                USING ".$this->tables['used_tags']." ut
823                  LEFT JOIN ".$this->tables['selected_tags']." st
824                    ON ut.tagID = st.tagId
825                WHERE ut.numId = $numId;";
826        pwg_query($sql);
827      }
828
829    }
830
831
832    /**
833     * this function return the list of tags :
834     *  - associated with the group
835     *  - not associated with a group
836     * the list is used to make tags selection
837     *
838     * @param String $id      : Id of the current group
839     * @return String : an HTML formatted list with checkbox
840     */
841    private function ajax_amd_admin_groupGetTagList($id)
842    {
843      global $template;
844
845      if($id!="")
846      {
847        $sql="SELECT st.tagId, st.groupId, ut.name, ut.numId
848              FROM ".$this->tables['selected_tags']." st
849                LEFT JOIN ".$this->tables['used_tags']." ut
850                  ON st.tagId = ut.tagId
851              ORDER BY tagId";
852        $result=pwg_query($sql);
853        if($result)
854        {
855          $datas=Array();
856          while($row=pwg_db_fetch_assoc($result))
857          {
858            if($row['groupId']==$id)
859            {
860              $state="checked";
861            }
862            elseif($row['groupId']==-1)
863            {
864              $state="";
865            }
866            else
867            {
868              $state="n/a";
869            }
870
871            if($state!="n/a")
872              $datas[]=Array(
873                'tagId' => $row['tagId'],
874                'name'  => L10n::get($row['name']),
875                'state' => $state,
876                'numId' => $row['numId']
877              );
878          }
879
880          if(count($datas)>0)
881          {
882            $local_tpl = new Template(AMD_PATH."admin/", "");
883            $local_tpl->set_filename('body_page',
884                          dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupListTagSelect.tpl');
885            $local_tpl->assign('themeconf', Array('name' => $template->get_themeconf('name')));
886            $local_tpl->assign('datas', $datas);
887            return($local_tpl->parse('body_page', true));
888          }
889          else
890          {
891            return(l10n("g003_no_tag_can_be_selected"));
892          }
893        }
894      }
895      else
896      {
897        return(l10n("g003_invalid_group_id"));
898      }
899    }
900
901
902    /**
903     * this function associate tags to a group
904     *
905     * @param String $id      : Id of group
906     * @param String $listTag : list of selected tags, items are separated by a
907     *                          semi-colon ";" char
908     */
909    private function ajax_amd_admin_groupSetTagList($id, $listTag)
910    {
911      if($id!="")
912      {
913        $sql="UPDATE ".$this->tables['selected_tags']."
914              SET groupId = -1
915              WHERE groupId = $id;";
916        pwg_query($sql);
917
918        if($listTag!="")
919        {
920          $sql="UPDATE ".$this->tables['selected_tags']." st, ".$this->tables['used_tags']." ut
921                SET st.groupId = $id
922                WHERE st.tagId = ut.tagId
923                  AND ut.numId IN ($listTag);";
924          pwg_query($sql);
925        }
926      }
927      else
928      {
929        return("KO");
930      }
931    }
932
933
934    /**
935     * this function returns an ordered list of tags associated with a group
936     *
937     * @param String $id        : the group Id
938     * @return String : an HTML formatted list
939     */
940    private function ajax_amd_admin_groupGetOrderedTagList($id)
941    {
942      global $template;
943      if($id!="")
944      {
945        $numOfPictures=$this->getNumOfPictures();
946
947        $sql="SELECT st.tagId, ut.name, ut.numId, ut.numOfImg
948              FROM ".$this->tables['selected_tags']." st
949                LEFT JOIN ".$this->tables['used_tags']." ut
950                  ON st.tagId = ut.tagId
951              WHERE st.groupId = $id
952              ORDER BY st.order ASC, st.tagId ASC";
953        $result=pwg_query($sql);
954        if($result)
955        {
956          $datas=Array();
957          while($row=pwg_db_fetch_assoc($result))
958          {
959            $datas[]=Array(
960              'tagId' => $row['tagId'],
961              'name'  => L10n::get($row['name']),
962              'numId' => $row['numId'],
963              'nbItems' => ($this->config['amd_InterfaceMode']=='advanced')?$row['numOfImg']:'',
964              'pct'   => ($this->config['amd_InterfaceMode']=='advanced')?(($numOfPictures==0)?"0":sprintf("%.2f", 100*$row['numOfImg']/$numOfPictures)):''
965            );
966          }
967
968          if(count($datas)>0)
969          {
970            $template->set_filename('list_page',
971                          dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupListTagOrder.tpl');
972            $template->assign('datas', $datas);
973            $template->assign('group', $id);
974            return($template->parse('list_page', true));
975          }
976          else
977          {
978            return(l10n("g003_no_tag_can_be_selected"));
979          }
980        }
981      }
982      else
983      {
984        return(l10n("g003_invalid_group_id"));
985      }
986    }
987
988
989    /**
990     * this function update the tags order inside a group
991     *
992     * @param String $id        : the group Id
993     * @param String $listGroup : the ordered list of tags, items are separated
994     *                            by a semi-colon ";" char
995     */
996    private function ajax_amd_admin_groupSetOrderedTagList($id, $listTag)
997    {
998      $tags=explode(';', $listTag);
999      if($id!="" and count($tags)>0)
1000      {
1001        /*
1002         * by default, all items are set with order equals -1 (if list is not
1003         * complete, forgotten items are sorted in head)
1004         */
1005        pwg_query("UPDATE ".$this->tables['selected_tags']." st
1006                    SET st.order = -1
1007                    WHERE st.groupId = $id;");
1008
1009        foreach($tags as $key=>$val)
1010        {
1011          $sql="UPDATE ".$this->tables['selected_tags']." st, ".$this->tables['used_tags']." ut
1012                SET st.order = $key
1013                WHERE st.groupId = $id
1014                  AND st.tagId = ut.tagId
1015                  AND ut.numId = $val;";
1016          $result=pwg_query($sql);
1017        }
1018      }
1019    }
1020
1021
1022
1023    /**
1024     * this function update the groups order
1025     *
1026     * @param String $listGroup : the ordered list of groups, items are separated
1027     *                            by a semi-colon ";" char
1028     */
1029    private function ajax_amd_admin_groupSetOrder($listGroup)
1030    {
1031      $groups=explode(";",$listGroup);
1032      if(count($groups)>0)
1033      {
1034        /*
1035         * by default, all items are set with order equals -1 (if list is not
1036         * complete, forgotten items are sorted in head)
1037         */
1038        pwg_query("UPDATE ".$this->tables['groups']." g SET g.order = -1;");
1039
1040        foreach($groups as $key=>$val)
1041        {
1042          $sql="UPDATE ".$this->tables['groups']." g
1043                SET g.order = $key
1044                WHERE g.groupId = $val;";
1045          $result=pwg_query($sql);
1046        }
1047      }
1048    }
1049
1050    /**
1051     * this function is used to create a new group ($groupId = "") or update the
1052     * group name (names are given in all langs in a list)
1053     *
1054     * @param String $groupId : the groupId to update, or "" to create a new groupId
1055     * @param String $listNames : name of the group, in all language given as a
1056     *                            list ; each lang is separated by a carraige
1057     *                            return "\n" char, each items is defined as
1058     *                            lang=value
1059     *                              en_UK=the name group
1060     *                              fr_FR=le nom du groupe
1061     */
1062    private function ajax_amd_admin_groupSetNames($groupId, $listNames)
1063    {
1064      $names=explode("\n", $listNames);
1065      if($groupId=="" and count($names)>0)
1066      {
1067        $sql="INSERT INTO ".$this->tables['groups']." VALUES('', 9999)";
1068        $result=pwg_query($sql);
1069        $groupId=pwg_db_insert_id();
1070      }
1071
1072      if(is_numeric($groupId) and count($names)>0)
1073      {
1074        $sql="DELETE FROM ".$this->tables['groups_names']."
1075              WHERE groupId = $groupId;";
1076        pwg_query($sql);
1077
1078
1079        $sql="";
1080        foreach($names as $val)
1081        {
1082          $tmp=explode("=", $val);
1083          if($sql!="") $sql.=", ";
1084          $sql.=" ($groupId, '".$tmp[0]."', '".$tmp[1]."')";
1085        }
1086        $sql="INSERT INTO ".$this->tables['groups_names']." VALUES ".$sql;
1087        pwg_query($sql);
1088      }
1089    }
1090
1091    /**
1092     * this function returns an html form, allowing to manage the group
1093     *
1094     * @param String $groupId : the groupId to manage, or "" to return a creation
1095     *                          form
1096     * @return String : the form
1097     */
1098    private function ajax_amd_admin_groupGetNames($groupId)
1099    {
1100      global $user;
1101
1102      $local_tpl = new Template(AMD_PATH."admin/", "");
1103      $local_tpl->set_filename('body_page',
1104                    dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupEdit.tpl');
1105
1106      $datasLang=array(
1107        'language_list' => Array(),
1108        'lang_selected' => $user['language'],
1109        'fromlang' => substr($user['language'],0,2),
1110        'default' => ''
1111      );
1112
1113      $langs=get_languages();
1114      foreach($langs as $key => $val)
1115      {
1116        $datasLang['language_list'][$key] = Array(
1117          'langName' => str_replace("\n", "", $val),
1118          'name' => ""
1119        );
1120      }
1121
1122      if($groupId!="")
1123      {
1124        $sql="SELECT lang, name FROM ".$this->tables['groups_names']."
1125              WHERE groupId = $groupId;";
1126        $result=pwg_query($sql);
1127        if($result)
1128        {
1129          while($row=pwg_db_fetch_assoc($result))
1130          {
1131            if(array_key_exists($row['lang'], $datasLang['language_list']))
1132            {
1133              $datasLang['language_list'][$row['lang']]['name']=htmlentities($row['name'], ENT_QUOTES, 'UTF-8');
1134              if($user['language']==$row['lang'])
1135              {
1136                $datasLang['default']=$datasLang['language_list'][$row['lang']]['name'];
1137              }
1138            }
1139          }
1140        }
1141      }
1142
1143      $local_tpl->assign('datasLang', $datasLang);
1144
1145      return($local_tpl->parse('body_page', true));
1146    }
1147
1148
1149    /**
1150     * this function returns an html form, allowing to manage the group
1151     *
1152     * @param String $groupId : the groupId to manage, or "" to return a creation
1153     *                          form
1154     * @return String : the form
1155     */
1156    private function ajax_amd_admin_groupGetList()
1157    {
1158      global $user, $template;
1159
1160      //$local_tpl = new Template(AMD_PATH."admin/", "");
1161      $template->set_filename('group_list',
1162                    dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupList.tpl');
1163
1164
1165      $datas=array(
1166        'groups' => Array(),
1167      );
1168
1169      $sql="SELECT g.groupId, gn.name
1170            FROM ".$this->tables['groups']." g
1171              LEFT JOIN ".$this->tables['groups_names']." gn
1172                ON g.groupId = gn.groupId
1173            WHERE gn.lang = '".$user['language']."'
1174            ORDER BY g.order;";
1175      $result=pwg_query($sql);
1176      if($result)
1177      {
1178        while($row=pwg_db_fetch_assoc($result))
1179        {
1180          $datas['groups'][]=Array(
1181            'id' => $row['groupId'],
1182            'name' => htmlentities($row['name'], ENT_QUOTES, "UTF-8")
1183          );
1184        }
1185      }
1186
1187      $template->assign('datas', $datas);
1188      return($template->parse('group_list', true));
1189    }
1190
1191
1192    /**
1193     * delete the group
1194     * associated tag returns in the available tag list
1195     *
1196     * @param String $groupId : the groupId to delete
1197     */
1198    private function ajax_amd_admin_groupDelete($groupId)
1199    {
1200      if($groupId!="")
1201      {
1202        $sql="DELETE FROM ".$this->tables['groups']."
1203              WHERE groupId = $groupId;";
1204        pwg_query($sql);
1205
1206        $sql="DELETE FROM ".$this->tables['groups_names']."
1207              WHERE groupId = $groupId;";
1208        pwg_query($sql);
1209
1210        $sql="UPDATE ".$this->tables['selected_tags']."
1211              SET groupId = -1
1212              WHERE groupId = $groupId;";
1213        pwg_query($sql);
1214      }
1215    }
1216
1217
1218    /**
1219     * return the list of userDefined tag
1220     *
1221     * @return String : an HTML list ready to use
1222     */
1223    private function ajax_amd_admin_userDefinedGetList()
1224    {
1225      global $user, $template;
1226
1227      //$local_tpl = new Template(AMD_PATH."admin/", "");
1228      $template->set_filename('userDefList',
1229                    dirname($this->getFileLocation()).'/admin/amd_metadata_personnal_iListTags.tpl');
1230
1231      $datas=array();
1232
1233      $sql="SELECT aut.numId, aut.tagId, aut.translatedName, COUNT(autd.defId) AS numOfRules
1234            FROM ".$this->tables['used_tags']." aut
1235              LEFT JOIN ".$this->tables['user_tags_def']." autd ON aut.numId=autd.numId
1236            WHERE aut.tagId LIKE 'userDefined.%'
1237            GROUP BY aut.numId
1238            ORDER BY aut.tagId;";
1239      $result=pwg_query($sql);
1240      if($result)
1241      {
1242        while($row=pwg_db_fetch_assoc($result))
1243        {
1244          $datas[]=Array(
1245            'numId' => $row['numId'],
1246            'tagId' => $row['tagId'],
1247            'label' => htmlspecialchars($row['translatedName'], ENT_QUOTES, "UTF-8"),
1248            'numOfRules' => $row['numOfRules']
1249          );
1250        }
1251      }
1252
1253      $template->assign('datas', $datas);
1254      return($template->parse('userDefList', true));
1255    }
1256
1257    /**
1258     * returns a userDefined tag
1259     *
1260     * @param String $id :
1261     * @return String :
1262     */
1263    private function ajax_amd_admin_userDefinedGetTag($id)
1264    {
1265      $returned=array(
1266        'numId' => 0,
1267        'tagId' => '',
1268        'label' => '',
1269        'rules' => Array(),
1270        'lastDefId' => 1,
1271      );
1272
1273      $sql="SELECT aut.numId, aut.tagId, aut.name, MAX(autd.defId) AS lastDefId
1274            FROM ".$this->tables['used_tags']." aut
1275              LEFT JOIN ".$this->tables['user_tags_def']." autd ON autd.numId=aut.numId
1276            WHERE aut.numId='$id'
1277            GROUP BY aut.numId";
1278      $result=pwg_query($sql);
1279      if($result)
1280      {
1281        while($row=pwg_db_fetch_assoc($result))
1282        {
1283          $returned['numId']=$row['numId'];
1284          $returned['tagId']=$row['tagId'];
1285          $returned['label']=$row['name'];
1286          $returned['lastDefId']=$row['lastDefId'];
1287        }
1288
1289        $sql="SELECT numId, defId, parentId, `order`, type, value, conditionType, conditionValue
1290              FROM ".$this->tables['user_tags_def']."
1291              WHERE numId='$id'
1292              ORDER BY numId, `order`";
1293        $result=pwg_query($sql);
1294        if($result)
1295        {
1296          while($row=pwg_db_fetch_assoc($result))
1297          {
1298            $returned['rules'][]=$row;
1299          }
1300        }
1301      }
1302
1303      return(json_encode($returned));
1304    }
1305
1306
1307    /**
1308     * set a userDefined tag
1309     *
1310     * @param String $id :
1311     * @param Array $properties :
1312     * @return String : ok or ko
1313     */
1314    private function ajax_amd_admin_userDefinedSetTag($id, $properties)
1315    {
1316      global $user;
1317
1318      $currentTagId='';
1319
1320      if(!preg_match('/^userDefined\./', $properties['tagId']))
1321      {
1322        $properties['tagId']='userDefined.'.$properties['tagId'];
1323      }
1324
1325      $sql="SELECT numId, tagId FROM ".$this->tables['used_tags']."
1326            WHERE tagId='".$properties['tagId']."';";
1327      $result=pwg_query($sql);
1328      if($result)
1329      {
1330        while($row=pwg_db_fetch_assoc($result))
1331        {
1332          if($row['numId']!=$id)
1333          {
1334            return('iBDTagId!'.l10n('g003_tagIdAlreadyExist'));
1335          }
1336          $currentTagId=$row['tagId'];
1337        }
1338      }
1339
1340      /*
1341       * to set a user defined tag
1342       *  1/ if it's a new user tag, create the tag into the used_tags table to
1343       *     get a new numId for the tag
1344       *  2/ delete all properties into the user_tags_def
1345       *  3/ insert the properties
1346       */
1347      if($id=='')
1348      {
1349        // add a new metadata
1350        $sql="INSERT INTO ".$this->tables['used_tags']."
1351              VALUES ('', '".$properties['tagId']."', 'n', '".$properties['name']."', 0, '".$properties['name']."')";
1352        $result=pwg_query($sql);
1353        $id=pwg_db_insert_id();
1354
1355        /*
1356         * multilanguage management will be coded later....
1357        $sql="INSERT INTO ".$this->tables['user_tags_label']."
1358              VALUES ('$id', '".$user['language']."', '".$properties['name']."');";
1359        $result=pwg_query($sql);
1360        */
1361
1362        if($this->config['amd_InterfaceMode']=='basic')
1363        {
1364          $sql="INSERT INTO ".$this->tables['selected_tags']." VALUES ('".$properties['tagId']."', 0, -1);";
1365          pwg_query($sql);
1366        }
1367      }
1368      else
1369      {
1370        //update an existing metadata
1371        $sql="UPDATE ".$this->tables['used_tags']."
1372              SET tagId='".$properties['tagId']."',
1373                  name='".$properties['name']."',
1374                  translatedName='".$properties['name']."'
1375              WHERE numId='$id';";
1376        $result=pwg_query($sql);
1377
1378        $sql="DELETE FROM ".$this->tables['user_tags_def']."
1379              WHERE numId='$id';";
1380        $result=pwg_query($sql);
1381
1382        $sql="DELETE FROM ".$this->tables['images_tags']."
1383              WHERE numId='$id';";
1384        $result=pwg_query($sql);
1385
1386        if($currentTagId!='' and $currentTagId!=$properties['tagId'])
1387        {
1388          $sql="UPDATE ".$this->tables['selected_tags']."
1389                SET tagId='".$properties['tagId']."'
1390                WHERE tagId='$currentTagId'";
1391          $result=pwg_query($sql);
1392        }
1393      }
1394
1395      $inserts=array();
1396      foreach($properties['rules'] as $rule)
1397      {
1398        //print_r($rule['value']);
1399        $inserts[]="('$id', '".$rule['defId']."', '".$rule['parentId']."', '".$rule['order']."', '".$rule['type']."', '".$rule['value']."', '".$rule['conditionType']."', '".$rule['conditionValue']."')";
1400      }
1401      $sql="INSERT INTO ".$this->tables['user_tags_def']."
1402            VALUES ".implode(',', $inserts);
1403      $result=pwg_query($sql);
1404
1405      if($this->config['amd_InterfaceMode']=='advanced')
1406      {
1407        $nbImg=$this->buildUserDefinedTags($id);
1408      }
1409      else
1410      {
1411        $nbImg=0;
1412      }
1413
1414      $this->makeStatsConsolidation();
1415
1416      return($id.','.$nbImg);
1417    }
1418
1419
1420    /**
1421     * delete a userDefined tag
1422     *
1423     * @param String $id :
1424     * @return String : ok or ko
1425     */
1426    private function ajax_amd_admin_userDefinedDeleteTag($id)
1427    {
1428      $tagId='';
1429      $sql="SELECT tagId
1430            FROM ".$this->tables['used_tags']."
1431            WHERE numId='$id';";
1432      $result=pwg_query($sql);
1433      if($result)
1434      {
1435        while($row=pwg_db_fetch_assoc($result))
1436        {
1437          $tagId=$row['tagId'];
1438        }
1439      }
1440
1441      if($tagId!='')
1442      {
1443        $sql="DELETE FROM ".$this->tables['selected_tags']."
1444              WHERE tagId='$tagId';";
1445        $result=pwg_query($sql);
1446      }
1447
1448      $sql="DELETE FROM ".$this->tables['used_tags']."
1449            WHERE numId='$id';";
1450      $result=pwg_query($sql);
1451
1452      $sql="DELETE FROM ".$this->tables['user_tags_label']."
1453            WHERE numId='$id';";
1454      $result=pwg_query($sql);
1455
1456      $sql="DELETE FROM ".$this->tables['user_tags_def']."
1457            WHERE numId='$id';";
1458      $result=pwg_query($sql);
1459
1460      $sql="DELETE FROM ".$this->tables['images_tags']."
1461            WHERE numId='$id';";
1462      $result=pwg_query($sql);
1463    }
1464
1465
1466    /**
1467     * return the known values for a given tag id
1468     *
1469     * @param String $id : a tag numId
1470     * @return String : an HTML list ready to use
1471     */
1472    private function ajax_amd_admin_tagGetValues($numId)
1473    {
1474      $returned="";
1475
1476      $sql="SELECT DISTINCT pait.value, COUNT(pait.imageId) AS nbImg, paut.translatable
1477            FROM ".$this->tables['images_tags']." pait
1478              LEFT JOIN ".$this->tables['used_tags']." paut
1479                ON pait.numId=paut.numId
1480            WHERE pait.numId = '$numId'
1481            GROUP BY pait.value
1482            ORDER BY pait.value";
1483      $result=pwg_query($sql);
1484      if($result)
1485      {
1486        while($row=pwg_db_fetch_assoc($result))
1487        {
1488          $value=htmlspecialchars(AMD_root::prepareValueForDisplay($row['value'], ($row['translatable']=='y'), ", "), ENT_QUOTES);
1489          $returned.="<option displayvalue='$value' rawvalue='".$row['value']."'>$value (".$row['nbImg']." ".l10n('images').")</option>";
1490        }
1491      }
1492      return($returned);
1493    }
1494
1495
1496    /**
1497     * return an html list of found keywords in the images_tags table
1498     *
1499     * @return String : html formatted list
1500     */
1501    private function ajax_amd_admin_tagsGetKeywords()
1502    {
1503      global $template;
1504
1505      $returned=array();
1506      $keywordsList=array();
1507      $sql="SELECT pait.value, pait.imageId, paut.numId
1508            FROM (".$this->tables['images_tags']." pait
1509              JOIN ".$this->tables['used_tags']." paut ON pait.numId = paut.numId)
1510
1511            WHERE (paut.tagId = 'xmp.dc:subject' OR
1512                   paut.tagId = 'xmp.digiKam:tagsList' OR
1513                   paut.tagId = 'iptc.Keywords');";
1514      $result=pwg_query($sql);
1515      if($result)
1516      {
1517        while($row=pwg_db_fetch_assoc($result))
1518        {
1519          if(preg_match('/^a:\d+:{/', $row['value']))
1520          {
1521            /*
1522             *  if value is a serialized string, unserialize and process it
1523             */
1524            $tmp=unserialize($row['value']);
1525            foreach($tmp['values'] as $val)
1526            {
1527              $keywordsList[]="('".mysql_escape_string($val)."', ".$row['imageId'].")";
1528            }
1529          }
1530          else
1531          {
1532            $keywordsList[]="('".mysql_escape_string($row['value'])."', ".$row['imageId'].")";
1533          }
1534        }
1535
1536        if(count($keywordsList)>0)
1537        {
1538          $sql="CREATE TEMPORARY TABLE amd_temp_tags (
1539                  `value` CHAR(255) default '',
1540                  `imageId` mediumint(8) unsigned NOT NULL default '0',
1541                  PRIMARY KEY  USING BTREE (`value`,`imageId`)
1542                ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
1543          if(pwg_query($sql))
1544          {
1545            $sql="INSERT IGNORE INTO amd_temp_tags
1546              VALUES ".implode(',', $keywordsList);
1547            if(pwg_query($sql))
1548            {
1549              $sql="SELECT att.value AS value,
1550                      COUNT(DISTINCT att.imageId) AS nbPictures,
1551                      IF(ptt.name IS NULL, 'n', 'y') AS tagExists,
1552                      COUNT(DISTINCT pit.image_id) AS nbPicturesTagged
1553                    FROM (amd_temp_tags att LEFT JOIN ".TAGS_TABLE."  ptt ON att.value = ptt.name)
1554                      LEFT JOIN ".IMAGE_TAG_TABLE." pit ON pit.tag_id = ptt.id
1555                    GROUP BY att.value
1556                    HAVING nbPicturesTagged < nbPictures";
1557              $result=pwg_query($sql);
1558              if($result)
1559              {
1560                $i=0;
1561                while($row=pwg_db_fetch_assoc($result))
1562                {
1563                  $row['id']=$i;
1564                  $returned[]=$row;
1565                  $i++;
1566                }
1567              }
1568            }
1569          }
1570        }
1571      }
1572
1573      $template->set_filename('keywordsList',
1574                    dirname($this->getFileLocation()).'/admin/amd_metadata_tags_iKeywordsList.tpl');
1575
1576      $template->assign('datas', $returned);
1577      return($template->parse('keywordsList', true));
1578    }
1579
1580
1581    /**
1582     * convert given keywords into tags, and associate them to pictures
1583     *
1584     * @param Array $keywords : an array of strings
1585     * @return String : ok or ko
1586     */
1587    private function ajax_amd_admin_tagsConvertKeywords($keywords)
1588    {
1589      global $template;
1590
1591      $returned='ko';
1592
1593      /*
1594       * 1/ build a temp table with all couple of keywords/imageId
1595       */
1596      $keywordsList=array();
1597      $sql="SELECT pait.value, pait.imageId, paut.numId
1598            FROM (".$this->tables['images_tags']." pait
1599              JOIN ".$this->tables['used_tags']." paut ON pait.numId = paut.numId)
1600
1601            WHERE (paut.tagId = 'xmp.dc:subject' OR
1602                   paut.tagId = 'xmp.digiKam:tagsList' OR
1603                   paut.tagId = 'iptc.Keywords');";
1604      $result=pwg_query($sql);
1605      if($result)
1606      {
1607        while($row=pwg_db_fetch_assoc($result))
1608        {
1609          if(preg_match('/^a:\d+:{/', $row['value']))
1610          {
1611            /*
1612             *  if value is a serialized string, unserialize and process it
1613             */
1614            $tmp=unserialize($row['value']);
1615            foreach($tmp['values'] as $val)
1616            {
1617              $keywordsList[]="('".mysql_escape_string($val)."', ".$row['imageId'].")";
1618            }
1619          }
1620          else
1621          {
1622            $keywordsList[]="('".mysql_escape_string($row['value'])."', ".$row['imageId'].")";
1623          }
1624        }
1625        $sql="CREATE TEMPORARY TABLE amd_temp_tags (
1626                `value` CHAR(255) default '',
1627                `imageId` mediumint(8) unsigned NOT NULL default '0',
1628                PRIMARY KEY  USING BTREE (`value`,`imageId`)
1629              ) CHARACTER SET utf8 COLLATE utf8_general_ci;";
1630        if(pwg_query($sql))
1631        {
1632          $sql="INSERT IGNORE INTO amd_temp_tags
1633            VALUES ".implode(',', $keywordsList);
1634          if(pwg_query($sql))
1635          {
1636            foreach($keywords as $key => $val)
1637            {
1638              $keywords[$key]="(att.value LIKE '".mysql_escape_string($val)."')";
1639            }
1640            /*
1641             * 2/ join temp table with piwigo tags table, found the keywords
1642             *    that don't have a corresponding keyword
1643             */
1644            $sql="SELECT DISTINCT att.value
1645                  FROM amd_temp_tags att LEFT JOIN ".TAGS_TABLE." ptt ON att.value = ptt.name
1646                  WHERE ptt.id IS NULL
1647                    AND".implode(' OR ', $keywords);
1648            $result=pwg_query($sql);
1649            if($result)
1650            {
1651              $sql=array();
1652              while($row=pwg_db_fetch_assoc($result))
1653              {
1654                $sql[]="('', '".mysql_escape_string($row['value'])."', '".mysql_escape_string(str2url($row['value']))."')";
1655              }
1656              if(count($sql)>0)
1657              {
1658                $sql="INSERT INTO ".TAGS_TABLE." VALUES ".implode(',', $sql);
1659                pwg_query($sql);
1660              }
1661            }
1662
1663            /*
1664             * 3/ join temp table with piwigo tags table, associate piwigo tagId
1665             *    to the keywords (at this step, all keyword can be associated
1666             *    with a piwigo tagId)
1667             */
1668            $sql="INSERT IGNORE INTO ".IMAGE_TAG_TABLE."
1669                    SELECT DISTINCT att.imageId, ptt.id
1670                    FROM amd_temp_tags att LEFT JOIN ".TAGS_TABLE." ptt ON att.value = ptt.name
1671                    WHERE ".implode(' OR ', $keywords);
1672            $result=pwg_query($sql);
1673            $returned='ok';
1674          }
1675        }
1676      }
1677
1678      return($returned);
1679    }
1680
1681
1682    /**
1683     * set value(s) for option(s)
1684     *
1685     * @param Array or String $ids : a string or an array of string (id)
1686     * @param Array or String $values : a string or an array of string
1687     * @return String : ok or ko
1688     */
1689    private function ajax_amd_admin_configSetOption($ids, $values)
1690    {
1691      if(is_array($ids) and is_array($values) and count($ids)==count($values))
1692      {
1693        foreach($ids as $key=>$id)
1694        {
1695          if(isset($id, $this->config))
1696          {
1697            $this->config[$id]=$values[$key];
1698          }
1699        }
1700        $this->saveConfig();
1701        return('ok');
1702      }
1703      elseif(is_string($ids) and is_string($values))
1704      {
1705        if(isset($ids, $this->config))
1706        {
1707          $this->config[$ids]=$values;
1708        }
1709        $this->saveConfig();
1710        return('ok');
1711      }
1712
1713      return('ko');
1714    }
1715
1716
1717  } //class
1718
1719
1720  $returned=new AMD_ajax($prefixeTable, __FILE__);
1721?>
Note: See TracBrowser for help on using the repository browser.