source: extensions/AMetaData/amd_aip.class.inc.php @ 4915

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

Unable to analyze the gallery : bug fixed !
and other little bugs fixed

  • Property svn:executable set to *
File size: 41.7 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 * AIP classe => manage integration in administration interface
18 *
19 * -----------------------------------------------------------------------------
20 */
21
22if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
23
24include_once('amd_root.class.inc.php');
25include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
26include_once(PHPWG_PLUGINS_PATH.'grum_plugins_classes-2/ajax.class.inc.php');
27include_once(PHPWG_PLUGINS_PATH.'grum_plugins_classes-2/genericjs.class.inc.php');
28
29
30
31class AMD_AIP extends AMD_root
32{
33  protected $tabsheet;
34  protected $ajax;
35  protected $jpegMD;
36
37  /**
38   *
39   * constructor needs the prefix of piwigo's tables and the location of plugin
40   *
41   * @param String $prefixeTable
42   * @param String $filelocation
43   */
44  function __construct($prefixeTable, $filelocation)
45  {
46    parent::__construct($prefixeTable, $filelocation);
47
48    $this->load_config();
49    $this->init_events();
50
51    $this->tabsheet = new tabsheet();
52    $this->tabsheet->add('metadata',
53                          l10n('g003_metadata'),
54                          $this->page_link.'&amp;fAMD_tabsheet=metadata');
55    $this->tabsheet->add('database',
56                          l10n('g003_database'),
57                          $this->page_link.'&amp;fAMD_tabsheet=database');
58    $this->ajax = new Ajax();
59    $this->jpegMD=new JpegMetaData();
60  }
61
62  function __destruct()
63  {
64    unset($this->tabsheet);
65    unset($this->ajax);
66    unset($this->jpegMD);
67  }
68
69
70  /*
71   * ---------------------------------------------------------------------------
72   * Public classe functions
73   * ---------------------------------------------------------------------------
74   */
75
76
77  /**
78   * manage the plugin integration into piwigo's admin interface
79   */
80  public function manage()
81  {
82    global $template, $page;
83
84    $template->set_filename('plugin_admin_content', dirname(__FILE__)."/admin/amd_admin.tpl");
85
86    $this->initRequest();
87
88    $this->returnAjaxContent();
89
90    $this->tabsheet->select($_REQUEST['fAMD_tabsheet']);
91    $this->tabsheet->assign();
92    $selected_tab=$this->tabsheet->get_selected();
93    $template->assign($this->tabsheet->get_titlename(), "[".$selected_tab['caption']."]");
94
95    $template_plugin["AMD_VERSION"] = "<i>".$this->plugin_name."</i> ".l10n('g003_version').AMD_VERSION;
96    $template_plugin["AMD_PAGE"] = $_REQUEST['fAMD_tabsheet'];
97    $template_plugin["PATH"] = AMD_PATH;
98
99    $template->assign('plugin', $template_plugin);
100
101    if($_REQUEST['fAMD_tabsheet']=='database')
102    {
103      $this->displayDatabase();
104    }
105    elseif($_REQUEST['fAMD_tabsheet']=='metadata')
106    {
107      $this->displayMetaData($_REQUEST['fAMD_page']);
108    }
109
110    $template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
111  }
112
113  /**
114   * initialize events call for the plugin
115   */
116  public function init_events()
117  {
118    add_event_handler('loc_end_page_header', array(&$this->css, 'apply_CSS'));
119  }
120
121  /**
122   * ---------------------------------------------------------------------------
123   * Private & protected functions
124   * ---------------------------------------------------------------------------
125   */
126
127  /**
128   * manage the ajax requests
129   * this function function determine if there is an ajax call, manage the
130   * request and returns the content of the request
131   *
132   * no params are given, the function works with the "$_REQUEST" var
133   *
134   * @return String
135   */
136  protected function returnAjaxContent()
137  {
138    global $ajax, $template;
139
140    if(isset($_REQUEST['ajaxfct']))
141    {
142      //$this->debug("AJAXFCT:".$_REQUEST['ajaxfct']);
143      $result="<p class='errors'>".l10n('g002_error_invalid_ajax_call')."</p>";
144      switch($_REQUEST['ajaxfct'])
145      {
146        case 'makeStatsGetList':
147          $result=$this->ajax_amd_makeStatsGetList($_REQUEST['selectMode'], $_REQUEST['numOfItems']);
148          break;
149        case 'makeStatsDoAnalyze':
150          $result=$this->ajax_amd_makeStatsDoAnalyze($_REQUEST['imagesList']);
151          break;
152        case 'makeStatsGetStatus':
153          $result=$this->ajax_amd_makeStatsGetStatus();
154          break;
155        case 'showStatsGetListTags':
156          $result=$this->ajax_amd_showStatsGetListTags($_REQUEST['orderType'], $_REQUEST['filterType'], $_REQUEST['excludeUnusedTag'], $_REQUEST['selectedTagOnly']);
157          break;
158        case 'showStatsGetListImages':
159          $result=$this->ajax_amd_showStatsGetListImages($_REQUEST['tagId'], $_REQUEST['orderType']);
160          break;
161        case 'updateTagSelect':
162          $result=$this->ajax_amd_updateTagSelect($_REQUEST['numId'], $_REQUEST['tagSelected']);
163          break;
164        case 'groupGetList':
165          $result=$this->ajax_amd_groupGetList();
166          break;
167        case 'groupDelete':
168          $result=$this->ajax_amd_groupDelete($_REQUEST['id']);
169          break;
170        case 'groupGetNames':
171          $result=$this->ajax_amd_groupGetNames($_REQUEST['id']);
172          break;
173        case 'groupSetNames':
174          $result=$this->ajax_amd_groupSetNames($_REQUEST['id'], $_REQUEST['listNames']);
175          break;
176        case 'groupSetOrder':
177          $result=$this->ajax_amd_groupSetOrder($_REQUEST['listGroup']);
178          break;
179        case 'groupGetTagList':
180          $result=$this->ajax_amd_groupGetTagList($_REQUEST['id']);
181          break;
182        case 'groupSetTagList':
183          $result=$this->ajax_amd_groupSetTagList($_REQUEST['id'], $_REQUEST['listTag']);
184          break;
185        case 'groupGetOrderedTagList':
186          $result=$this->ajax_amd_groupGetOrderedTagList($_REQUEST['id']);
187          break;
188        case 'groupSetOrderedTagList':
189          $result=$this->ajax_amd_groupSetOrderedTagList($_REQUEST['id'], $_REQUEST['listTag']);
190          break;
191      }
192      $this->ajax->return_result($result);
193    }
194  }
195
196
197  /**
198   * if empty, initialize the $_REQUEST var
199   *
200   * if not empty, check validity for the request values
201   *
202   */
203  private function initRequest()
204  {
205    //initialise $REQUEST values if not defined
206    if($this->getNumOfPictures()==0)
207    {
208      $defautTabsheet="database";
209    }
210    else
211    {
212      $defautTabsheet="metadata";
213    }
214
215    if(!isset($_REQUEST['fAMD_tabsheet']))
216    {
217      $_REQUEST['fAMD_tabsheet']=$defautTabsheet;
218    }
219
220    if($_REQUEST['fAMD_tabsheet']!="metadata" and
221       $_REQUEST['fAMD_tabsheet']!="database")
222    {
223      $_REQUEST['fAMD_tabsheet']=$defautTabsheet;
224    }
225
226    if($_REQUEST['fAMD_tabsheet']=="metadata" and !isset($_REQUEST['fAMD_page']))
227    {
228      $_REQUEST['fAMD_page']="select";
229    }
230
231    if($_REQUEST['fAMD_tabsheet']=="metadata" and
232       !($_REQUEST['fAMD_page']=="select" or
233         $_REQUEST['fAMD_page']=="display"))
234    {
235      $_REQUEST['fAMD_page']="select";
236    }
237
238    /*
239     * check ajax
240     */
241    if(isset($_REQUEST['ajaxfct']))
242    {
243      /*
244       * check makeStatsGetList values
245       */
246      if($_REQUEST['ajaxfct']=="makeStatsGetList" and !isset($_REQUEST['selectMode']))
247      {
248        $_REQUEST['selectMode']="notAnalyzed";
249      }
250
251      if($_REQUEST['ajaxfct']=="makeStatsGetList" and
252         !($_REQUEST['selectMode']=="notAnalyzed" or
253           $_REQUEST['selectMode']=="all"))
254      {
255        $_REQUEST['selectMode']="notAnalyzed";
256      }
257
258      if($_REQUEST['ajaxfct']=="makeStatsGetList" and !isset($_REQUEST['numOfItems']))
259      {
260        $_REQUEST['numOfItems']=25;
261      }
262
263      /*
264       * check makeStatsDoAnalyze values
265       */
266      if($_REQUEST['ajaxfct']=="makeStatsDoAnalyze" and !isset($_REQUEST['imagesList']))
267      {
268        $_REQUEST['imagesList']="";
269      }
270
271      /*
272       * check makeStatsConsolidate values
273       */
274      if($_REQUEST['ajaxfct']=="makeStatsConsolidate" and !isset($_REQUEST['step']))
275      {
276        $_REQUEST['step']="*";
277      }
278
279      /*
280       * check showStatsGetListTags values
281       */
282      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['orderType']))
283      {
284        $_REQUEST['orderType']="tag";
285      }
286
287      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
288         !($_REQUEST['orderType']=="tag" or
289           $_REQUEST['orderType']=="num"))
290      {
291        $_REQUEST['orderType']="tag";
292      }
293
294      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['filterType']))
295      {
296        $_REQUEST['filterType']="";
297      }
298
299      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
300         !($_REQUEST['filterType']=="" or
301           $_REQUEST['filterType']=="exif" or
302           $_REQUEST['filterType']=="xmp" or
303           $_REQUEST['filterType']=="iptc"))
304      {
305        $_REQUEST['filterType']="";
306      }
307
308      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['excludeUnusedTag']))
309      {
310        $_REQUEST['excludeUnusedTag']="n";
311      }
312
313      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
314         !($_REQUEST['excludeUnusedTag']=="y" or
315           $_REQUEST['excludeUnusedTag']=="n" ))
316      {
317        $_REQUEST['excludeUnusedTag']="n";
318      }
319
320      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['selectedTagOnly']))
321      {
322        $_REQUEST['selectedTagOnly']="n";
323      }
324
325      if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
326         !($_REQUEST['selectedTagOnly']=="y" or
327           $_REQUEST['selectedTagOnly']=="n" ))
328      {
329        $_REQUEST['selectedTagOnly']="n";
330      }
331
332
333      /*
334       * check showStatsGetListImagess values
335       */
336      if($_REQUEST['ajaxfct']=="showStatsGetListImages" and !isset($_REQUEST['orderType']))
337      {
338        $_REQUEST['orderType']="num";
339      }
340
341      if($_REQUEST['ajaxfct']=="showStatsGetListImages" and
342         !($_REQUEST['orderType']=="value" or
343           $_REQUEST['orderType']=="num"))
344      {
345        $_REQUEST['orderType']="num";
346      }
347
348      if($_REQUEST['ajaxfct']=="showStatsGetListImages" and !isset($_REQUEST['tagId']))
349      {
350        $_REQUEST['tagId']="*";
351      }
352
353
354      /*
355       * check showStatsGetListImagess values
356       */
357      if($_REQUEST['ajaxfct']=="updateTagSelect" and !isset($_REQUEST['numId']))
358      {
359        $_REQUEST['numId']="";
360      }
361
362      if($_REQUEST['ajaxfct']=="updateTagSelect" and !isset($_REQUEST['tagSelected']))
363      {
364        $_REQUEST['tagSelected']="";
365      }
366
367
368
369
370      /*
371       * check groupDelete values
372       */
373      if($_REQUEST['ajaxfct']=="groupDelete" and !isset($_REQUEST['id']))
374      {
375        $_REQUEST['id']="";
376      }
377
378
379
380      /*
381       * check groupSetOrder values
382       */
383      if($_REQUEST['ajaxfct']=="groupSetOrder" and !isset($_REQUEST['listGroup']))
384      {
385        $_REQUEST['listGroup']="";
386      }
387
388      /*
389       * check groupGetNames values
390       */
391      if($_REQUEST['ajaxfct']=="groupGetNames" and !isset($_REQUEST['id']))
392      {
393        $_REQUEST['id']="";
394      }
395
396      /*
397       * check groupSetNames values
398       */
399      if($_REQUEST['ajaxfct']=="groupSetNames" and !isset($_REQUEST['listNames']))
400      {
401        $_REQUEST['listNames']="";
402      }
403
404      if($_REQUEST['ajaxfct']=="groupSetNames" and !isset($_REQUEST['id']))
405      {
406        $_REQUEST['id']="";
407      }
408
409
410      /*
411       * check groupGetTagList values
412       */
413      if($_REQUEST['ajaxfct']=="groupGetTagList" and !isset($_REQUEST['id']))
414      {
415        $_REQUEST['id']="";
416      }
417
418      /*
419       * check groupSetTagList values
420       */
421      if($_REQUEST['ajaxfct']=="groupSetTagList" and !isset($_REQUEST['id']))
422      {
423        $_REQUEST['id']="";
424      }
425
426      if($_REQUEST['ajaxfct']=="groupSetTagList" and !isset($_REQUEST['listTag']))
427      {
428        $_REQUEST['listTag']="";
429      }
430
431
432      /*
433       * check groupGetOrderedTagList values
434       */
435      if($_REQUEST['ajaxfct']=="groupGetOrderedTagList" and !isset($_REQUEST['id']))
436      {
437        $_REQUEST['id']="";
438      }
439
440      /*
441       * check groupSetOrderedTagList values
442       */
443      if($_REQUEST['ajaxfct']=="groupSetOrderedTagList" and !isset($_REQUEST['id']))
444      {
445        $_REQUEST['id']="";
446      }
447
448      if($_REQUEST['ajaxfct']=="groupSetOrderedTagList" and !isset($_REQUEST['listTag']))
449      {
450        $_REQUEST['listTag']="";
451      }
452
453    }
454  } //init_request
455
456
457  /**
458   * manage adviser profile
459   *
460   * @return Boolean : true if user is adviser, otherwise false (and push a
461   *                   message in the error list)
462   */
463  protected function adviser_abort()
464  {
465    if(is_adviser())
466    {
467      $this->display_result(l10n("g003_adviser_not_allowed"), false);
468      return(true);
469    }
470    return(false);
471  }
472
473
474  /**
475   * display and manage the database page
476   *
477   * the function automatically update the AMD tables :
478   *  - add new pictures in the AMD image table (assuming image is not analyzed
479   *    yet)
480   *  - remove deleted pictures in the AMD image & image_tags table
481   *
482   * @return String : the content of the page
483   */
484  private function displayDatabase()
485  {
486    global $template, $page;
487
488    /*
489     * insert new image (from piwigo images table) in the AMD images table, with
490     * statut 'not analyzed'
491     */
492    $sql="INSERT INTO ".$this->tables['images']."
493            SELECT id, 'n', 0
494              FROM ".IMAGES_TABLE."
495              WHERE id NOT IN (SELECT imageId FROM ".$this->tables['images'].")";
496    pwg_query($sql);
497
498
499    /*
500     * delete image who are in the AMD images table and not in the piwigo image
501     * table
502     */
503    $sql="DELETE FROM ".$this->tables['images']."
504            WHERE imageId NOT IN (SELECT id FROM ".IMAGES_TABLE.")";
505    pwg_query($sql);
506
507
508    /*
509     * delete metdata for images that are not in the AMD image table
510     */
511    $sql="DELETE FROM ".$this->tables['images_tags']."
512            WHERE imageId NOT IN (SELECT imageId FROM ".$this->tables['images'].")";
513    pwg_query($sql);
514
515
516    $template->set_filename('body_page', dirname(__FILE__).'/admin/amd_database.tpl');
517
518    $datas=array(
519      'urlRequest' => $this->page_link,
520      'NumberOfItemsPerRequest' => $this->my_config['amd_NumberOfItemsPerRequest'],
521    );
522
523    $template->assign("datas", $datas);
524
525    $template->assign_var_from_handle('AMD_BODY_PAGE', 'body_page');
526  } // displayDatabase
527
528
529
530  /**
531   * display and manage the metadata page
532   * the page have two tabsheet :
533   *  - select tag management, to manage tags to be selected on the galerie
534   *  - display tag management, to choose how the tags are displayed
535   *
536   * @param String $tab : the selected tab on the stat page
537   */
538  protected function displayMetaData($tab)
539  {
540    global $template, $user;
541    $template->set_filename('body_page', dirname(__FILE__).'/admin/amd_metadata.tpl');
542
543    $statTabsheet = new tabsheet('statTabsheet', $this->tabsheet->get_titlename());
544    $statTabsheet->select($tab);
545    $statTabsheet->add('select',
546                          l10n('g003_select'),
547                          $this->page_link.'&amp;fAMD_tabsheet=stat&amp;fAMD_page=select');
548    $statTabsheet->add('display',
549                          l10n('g003_display'),
550                          $this->page_link.'&amp;fAMD_tabsheet=stat&amp;fAMD_page=display');
551    $statTabsheet->assign();
552
553
554
555    if($tab=="select")
556    {
557      $template->assign('sheetContent', $this->displayMetaDataSelect());
558    }
559    else
560    {
561      $template->assign('sheetContent', $this->displayMetaDataDisplay());
562    }
563
564    $template->assign_var_from_handle('AMD_BODY_PAGE', 'body_page');
565  }
566
567  /**
568   * display and manage the metadata page allowing to make tags selection
569   *
570   * @return String : the content of the page
571   */
572  protected function displayMetaDataSelect()
573  {
574    global $template;
575
576    $template->set_filename('sheet_page',
577                  dirname($this->filelocation).'/admin/amd_metadata_select.tpl');
578
579    $datas=array(
580      'urlRequest' => $this->page_link,
581      'config_GetListTags_OrderType' => $this->my_config['amd_GetListTags_OrderType'],
582      'config_GetListTags_FilterType' => $this->my_config['amd_GetListTags_FilterType'],
583      'config_GetListTags_ExcludeUnusedTag' => $this->my_config['amd_GetListTags_ExcludeUnusedTag'],
584      'config_GetListTags_SelectedTagOnly' => $this->my_config['amd_GetListTags_SelectedTagOnly'],
585      'config_GetListImages_OrderType' => $this->my_config['amd_GetListImages_OrderType']
586    );
587
588
589    $template->assign('datas', $datas);
590
591    return($template->parse('sheet_page', true));
592  }
593
594
595  /**
596   * display and manage the metadata page allowing to choose tags order
597   *
598   * @return String : the content of the page
599   */
600  protected function displayMetaDataDisplay()
601  {
602    global $user, $template;
603
604    //$local_tpl = new Template(AMD_PATH."admin/", "");
605    $template->set_filename('sheet_page',
606                  dirname($this->filelocation).'/admin/amd_metadata_display.tpl');
607
608
609    $datas=array(
610      'urlRequest' => $this->page_link,
611      'selectedTags' => Array(),
612      'groups' => Array(),
613      'tagByGroup' => Array(),
614    );
615
616    $sql="SELECT st.tagId, st.order, st.groupId, ut.numId
617          FROM ".$this->tables['selected_tags']." st
618            LEFT JOIN ".$this->tables['used_tags']." ut
619              ON ut.tagId = st.tagId
620          ORDER BY st.groupId ASC, st.order ASC, st.tagId ASC";
621    $result=pwg_query($sql);
622    if($result)
623    {
624      while($row=mysql_fetch_assoc($result))
625      {
626        if($row['groupId']==-1)
627        {
628          $datas['selectedTags'][]=Array(
629            'numId' => $row['numId'],
630            'tagId' => $row['tagId']
631          );
632        }
633        else
634        {
635          $datas['tagByGroup'][]=Array(
636            'numId' => $row['numId'],
637            'tagId' => $row['tagId'],
638            'group' => $row['groupId'],
639            'order' => $row['order']
640          );
641        }
642      }
643    }
644
645    $sql="SELECT g.groupId, gn.name
646          FROM ".$this->tables['groups']." g
647            LEFT JOIN ".$this->tables['groups_names']." gn
648              ON g.groupId = gn.groupId
649          WHERE gn.lang = '".$user['language']."'
650          ORDER BY g.order;";
651    $result=pwg_query($sql);
652    if($result)
653    {
654      while($row=mysql_fetch_assoc($result))
655      {
656        $datas['groups'][]=Array(
657          'id' => $row['groupId'],
658          'name' => $row['name']
659        );
660      }
661    }
662
663    $template->assign('datas', $datas);
664    return($template->parse('sheet_page', true));
665  }
666
667
668
669  /**
670   * this function analyze tags from a picture, and insert the result into the
671   * database
672   *
673   * NOTE : only implemented tags are analyzed and stored
674   *
675   * @param String $fileName : filename of picture to analyze
676   * @param Integer $imageId : id of image in piwigo's database
677   */
678  protected function analyzeImageFile($fileName, $imageId)
679  {
680    /*
681     * the JpegMetaData object is instancied in the constructor
682     */
683    $this->jpegMD->load($fileName, Array(
684      'filter' => JpegMetaData::TAGFILTER_IMPLEMENTED,
685      'optimizeIptcDateTime' => true)
686    );
687
688    $sqlInsert="";
689    $massInsert=array();
690    $nbTags=0;
691    foreach($this->jpegMD->getTags() as $key => $val)
692    {
693      $value=$val->getLabel();
694
695      if($val->isTranslatable())
696        $translatable="y";
697      else
698        $translatable="n";
699
700      if($value instanceof DateTime)
701      {
702        $value=$value->format("Y-m-d H:i:s");
703      }
704      elseif(is_array($value))
705      {
706        /*
707         * array values are stored in a serialized string
708         */
709        $value=serialize($value);
710      }
711
712      $sql="SELECT numId FROM ".$this->tables['used_tags']." WHERE tagId = '$key'";
713      $result=pwg_query($sql);
714      if($result)
715      {
716        $numId=-1;
717        while($row=mysql_fetch_assoc($result))
718        {
719          $numId=$row['numId'];
720        }
721
722        if($numId>0)
723        {
724          $nbTags++;
725          if($sqlInsert!="") $sqlInsert.=", ";
726          $sqlInsert.="($imageId, '$numId', '".addslashes($value)."')";
727          $massInsert[]=array(
728            'imageId' => $imageId,
729            'numId' => $numId,
730            'value' => addslashes($value)
731          );
732        }
733      }
734    }
735
736    /*if($sqlInsert!="")
737    {
738      $sqlInsert="INSERT INTO ".$this->tables['images_tags']." VALUES ".$sqlInsert;
739      pwg_query($sqlInsert);
740    }*/
741    mass_inserts($this->tables['images_tags'], array('imageId', 'numId', 'value'), $massInsert);
742
743    $sql="UPDATE ".$this->tables['images']."
744            SET analyzed = 'y', nbTags=".$nbTags."
745            WHERE imageId=$imageId;";
746    pwg_query($sql);
747
748
749    return("$imageId=$nbTags;");
750  }
751
752
753  /**
754   * returns the number of pictures analyzed
755   *
756   * @return Integer
757   */
758  protected function getNumOfPictures()
759  {
760    $numOfPictures=0;
761    $sql="SELECT COUNT(imageId) FROM ".$this->tables['images']."
762            WHERE analyzed='y';";
763    $result=pwg_query($sql);
764    if($result)
765    {
766      while($row=mysql_fetch_row($result))
767      {
768        $numOfPictures=$row[0];
769      }
770    }
771    return($numOfPictures);
772  }
773
774
775  /*
776   * ---------------------------------------------------------------------------
777   * ajax functions
778   * ---------------------------------------------------------------------------
779   */
780
781  /**
782   * return a list of picture Id
783   *
784   * picture id are separated with a space " "
785   * picture id are grouped in blocks of 'amd_NumberOfItemsPerRequest' items and
786   * are separated with a semi-colon ";"
787   *
788   * client side just have to split blocks, and transmit it to the server
789   *
790   * There is two mode to determine the pictures being analyzed :
791   *  - "all"         : analyze all the images
792   *  - "notAnalyzed" : analyze only the images not yet analyzed
793   *
794   * @param String $mode
795   * @param Integer $nbOfItems : number of items per request
796   * @return String : list of image id to be analyzed, separated with a space
797   *                      "23 78 4523 5670"
798   */
799  private function ajax_amd_makeStatsGetList($mode, $nbOfItems)
800  {
801    $returned="";
802    $this->my_config['amd_NumberOfItemsPerRequest']=$nbOfItems;
803    $this->save_config();
804
805    $sql="SELECT imageId FROM ".$this->tables['images'];
806    if($mode=="notAnalyzed")
807    {
808      $sql.=" WHERE analyzed='n'";
809    }
810    else
811    {
812      pwg_query("UPDATE ".$this->tables['images']." SET analyzed='n', nbTags=0");
813      pwg_query("UPDATE ".$this->tables['used_tags']." SET numOfImg=0");
814      pwg_query("DELETE FROM ".$this->tables['images_tags']);
815    }
816
817    $result=pwg_query($sql);
818    if($result)
819    {
820      $i=0;
821      while($row=mysql_fetch_row($result))
822      {
823        $returned.=$row[0];
824        $i++;
825        if($i>=$nbOfItems)
826        {
827          $returned.=";";
828          $i=0;
829        }
830        else
831        {
832          $returned.=" ";
833        }
834      }
835    }
836
837    $sql="UPDATE ".$this->tables['used_tags']." ut,
838            (SELECT COUNT(imageId) AS nb, numId
839              FROM ".$this->tables['images_tags']."
840              GROUP BY numId) nb
841          SET ut.numOfImg = nb.nb
842          WHERE ut.numId = nb.numId;";
843    pwg_query($sql);
844
845    return(trim($returned).";");
846  }
847
848
849  /**
850   * extract metadata from images
851   *
852   * @param String $imageList : list of image id to be analyzed, separated with
853   *                            a space
854   *                                "23 78 4523 5670"
855   * @return String : list of the analyzed pictures, with number of tags found
856   *                  for each picture
857   *                    "23=0;78=66;4523=33;5670=91;"
858   */
859  private function ajax_amd_makeStatsDoAnalyze($imagesList)
860  {
861    $list=explode(" ", trim($imagesList));
862
863    $returned="";
864
865    if(count($list)>0)
866    {
867      // $path = path of piwigo's on the server filesystem
868      $path=dirname(dirname(dirname(__FILE__)));
869
870      $sql="SELECT id, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(", ", $list).")";
871      $result=pwg_query($sql);
872      if($result)
873      {
874        while($row=mysql_fetch_assoc($result))
875        {
876          /*
877           * in some case (in a combination of some pictures), when there is too
878           * much pictures to analyze in the same request, a fatal error occurs
879           * with the message : "Allowed memory size of XXXXX bytes exhausted"
880           *
881           *
882           * tracking memory leak is not easy... :-(
883           *
884           */
885          //echo "analyzing:".$row['id']."\n";
886          //$mem1=memory_get_usage();
887          //echo "memory before analyze:".$mem1."\n";
888          $returned.=$this->analyzeImageFile($path."/".$row['path'], $row['id']);
889          //echo $returned."\n";
890          //$mem2=memory_get_usage();
891          //echo "memory after analyze:".$mem2." (".($mem2-$mem1).")\n";
892        }
893      }
894    }
895    return($returned);
896  }
897
898  /**
899   * returns a list of formated string, separated with a semi-colon :
900   *  - number of current analyzed pictures + number of current analyzed tags
901   *    for the analyzed pictures
902   *  - number of pictures not analyzed
903   *  - number of pictures without tag
904   *
905   * @return String
906   */
907  private function ajax_amd_makeStatsGetStatus()
908  {
909    $numOfMetaData=0;
910    $numOfPictures=0;
911    $numOfPicturesNotAnalyzed=0;
912
913    $sql="SELECT COUNT(imageId), SUM(nbTags) FROM ".$this->tables['images']."
914            WHERE analyzed='y';";
915    $result=pwg_query($sql);
916    if($result)
917    {
918      while($row=mysql_fetch_row($result))
919      {
920        $numOfPictures=$row[0];
921        $numOfMetaData=$row[1];
922      }
923    }
924
925
926    $sql="SELECT COUNT(imageId) FROM ".$this->tables['images']."
927            WHERE analyzed='n';";
928    $result=pwg_query($sql);
929    if($result)
930    {
931      while($row=mysql_fetch_row($result))
932      {
933        $numOfPicturesNotAnalyzed=$row[0];
934      }
935    }
936
937    $sql="SELECT COUNT(imageId) FROM ".$this->tables['images']."
938            WHERE nbTags=0;";
939    $result=pwg_query($sql);
940    if($result)
941    {
942      while($row=mysql_fetch_row($result))
943      {
944        $numOfPicturesWithoutTags=$row[0];
945      }
946    }
947
948    return(sprintf(l10n("g003_numberOfAnalyzedPictures"), $numOfPictures, $numOfMetaData).";".
949              sprintf(l10n("g003_numberOfNotAnalyzedPictures"), $numOfPicturesNotAnalyzed).";".
950              sprintf(l10n("g003_numberOfPicturesWithoutTags"), $numOfPicturesWithoutTags));
951  }
952
953
954  /**
955   * return a formatted <table> (using the template "amd_stat_show_iListTags")
956   * of used tag with, for each tag, the number and the percentage of pictures
957   * where the tag was found
958   *
959   * @param String $orderType : order for the list (by tag 'tag' or by number of
960   *                            pictures 'num')
961   * @param String $filterType : filter for the list ('exif', 'xmp', 'iptc' or '')
962   * @return String
963   */
964  private function ajax_amd_showStatsGetListTags($orderType, $filterType, $excludeUnusedTag, $selectedTagOnly)
965  {
966    $this->my_config['amd_GetListTags_OrderType'] = $orderType;
967    $this->my_config['amd_GetListTags_FilterType'] = $filterType;
968    $this->my_config['amd_GetListTags_ExcludeUnusedTag'] = $excludeUnusedTag;
969    $this->my_config['amd_GetListTags_SelectedTagOnly'] = $selectedTagOnly;
970    $this->save_config();
971
972    $local_tpl = new Template(AMD_PATH."admin/", "");
973    $local_tpl->set_filename('body_page',
974                  dirname($this->filelocation).'/admin/amd_metadata_select_iListTags.tpl');
975
976    $numOfPictures=$this->getNumOfPictures();
977
978    $datas=array();
979    $sql="SELECT ut.numId, ut.tagId, ut.translatable, ut.name, ut.numOfImg, if(st.tagId IS NULL, 'n', 'y') as checked
980            FROM ".$this->tables['used_tags']." ut
981              LEFT JOIN ".$this->tables['selected_tags']." st
982                ON st.tagId = ut.tagId ";
983    $where="";
984
985    if($filterType!='')
986    {
987      $where.=" WHERE ut.tagId LIKE '".$filterType.".%' ";
988    }
989
990    if($excludeUnusedTag=='y')
991    {
992      ($where=="")?$where=" WHERE ":$where.=" AND ";
993      $where.=" ut.numOfImg > 0 ";
994    }
995
996    if($selectedTagOnly=='y')
997    {
998      ($where=="")?$where=" WHERE ":$where.=" AND ";
999      $where.=" st.tagId IS NOT NULL ";
1000    }
1001
1002    $sql.=$where;
1003
1004    switch($orderType)
1005    {
1006      case 'tag':
1007        $sql.=" ORDER BY tagId ASC";
1008        break;
1009      case 'num':
1010        $sql.=" ORDER BY numOfImg DESC, tagId ASC";
1011        break;
1012    }
1013
1014    $result=pwg_query($sql);
1015    if($result)
1016    {
1017      while($row=mysql_fetch_assoc($result))
1018      {
1019        $datas[]=array(
1020          "numId" => $row['numId'],
1021          "tagId" => $row['tagId'],
1022          "label" => L10n::get($row['name']),
1023          "nb"    => $row['numOfImg'],
1024          "pct"   => ($numOfPictures!=0)?sprintf("%.2f", 100*$row['numOfImg']/$numOfPictures):"-",
1025          "tagChecked" => ($row['checked']=='y')?"checked":""
1026        );
1027      }
1028    }
1029
1030    $local_tpl->assign('datas', $datas);
1031
1032    return($local_tpl->parse('body_page', true));
1033  }
1034
1035
1036  /*
1037   *
1038   *
1039   */
1040  private function ajax_amd_showStatsGetListImages($tagId, $orderType)
1041  {
1042    $this->my_config['amd_GetListImages_OrderType'] = $orderType;
1043    $this->save_config();
1044
1045    $local_tpl = new Template(AMD_PATH."admin/", "");
1046    $local_tpl->set_filename('body_page',
1047                  dirname($this->filelocation).'/admin/amd_metadata_select_iListImages.tpl');
1048
1049
1050
1051    $datas=array();
1052    $sql="SELECT ut.translatable, ut.numOfImg, COUNT(it.imageId) AS Nb, it.value
1053            FROM ".$this->tables['used_tags']." ut
1054              LEFT JOIN ".$this->tables['images_tags']." it
1055              ON ut.numId = it.numId
1056            WHERE ut.tagId = '".$tagId."'
1057              AND it.value IS NOT NULL
1058            GROUP BY it.value
1059            ORDER BY ";
1060    switch($orderType)
1061    {
1062      case 'value':
1063        $sql.="it.value ASC";
1064        break;
1065      case 'num':
1066        $sql.="Nb DESC";
1067        break;
1068    }
1069
1070    $result=pwg_query($sql);
1071    if($result)
1072    {
1073      while($row=mysql_fetch_assoc($result))
1074      {
1075        $datas[]=array(
1076          "value" => ($row['translatable']=='y')?L10n::get($row['value']):$row['value'],
1077          "nb"    => $row['Nb'],
1078          "pct"   => ($row['numOfImg']!=0)?sprintf("%.2f", 100*$row['Nb']/$row['numOfImg']):"-"
1079        );
1080      }
1081    }
1082
1083    if(count($datas)>0)
1084    {
1085      $local_tpl->assign('datas', $datas);
1086      return($local_tpl->parse('body_page', true));
1087    }
1088    else
1089    {
1090      return("<div style='width:100%;text-align:center;padding-top:20px;'>".l10n('g003_selected_tag_isnot_linked_with_any_picture')."</div>");
1091    }
1092  }
1093
1094
1095  /*
1096   *
1097   *
1098   */
1099  private function ajax_amd_updateTagSelect($numId, $selected)
1100  {
1101    if($selected=='y')
1102    {
1103      $sql="SELECT ut.tagId FROM ".$this->tables['selected_tags']." st
1104              LEFT JOIN ".$this->tables['used_tags']." ut
1105                ON ut.tagID = st.tagId
1106              WHERE ut.numId = $numId;";
1107      $result=pwg_query($sql);
1108      if($result)
1109      {
1110        if(mysql_num_rows($result)==0)
1111        {
1112          $sql="INSERT INTO ".$this->tables['selected_tags']."
1113                  SELECT ut.tagId, 0, -1
1114                  FROM ".$this->tables['used_tags']." ut
1115                    LEFT JOIN ".$this->tables['selected_tags']." st
1116                      ON ut.tagID = st.tagId
1117                  WHERE ut.numId = $numId;";
1118          pwg_query($sql);
1119        }
1120      }
1121    }
1122    elseif($selected=='n')
1123    {
1124      $sql="DELETE FROM ".$this->tables['selected_tags']." st
1125              USING phpwebgallery_amd_used_tags ut
1126                LEFT JOIN phpwebgallery_amd_selected_tags st
1127                  ON ut.tagID = st.tagId
1128              WHERE ut.numId = $numId;";
1129      pwg_query($sql);
1130    }
1131
1132  }
1133
1134
1135  /**
1136   * this function return the list of tags :
1137   *  - associated with the group
1138   *  - not associated with a group
1139   * the list is used to make tags selection
1140   *
1141   * @param String $id      : Id of the current group
1142   * @return String : an HTML formatted list with checkbox
1143   */
1144  private function ajax_amd_groupGetTagList($id)
1145  {
1146    if($id!="")
1147    {
1148      $sql="SELECT st.tagId, st.groupId, ut.name, ut.numId
1149            FROM ".$this->tables['selected_tags']." st
1150              LEFT JOIN ".$this->tables['used_tags']." ut
1151                ON st.tagId = ut.tagId
1152            ORDER BY tagId";
1153      $result=pwg_query($sql);
1154      if($result)
1155      {
1156        $datas=Array();
1157        while($row=mysql_fetch_assoc($result))
1158        {
1159          if($row['groupId']==$id)
1160          {
1161            $state="checked";
1162          }
1163          elseif($row['groupId']==-1)
1164          {
1165            $state="";
1166          }
1167          else
1168          {
1169            $state="n/a";
1170          }
1171
1172          if($state!="n/a")
1173            $datas[]=Array(
1174              'tagId' => $row['tagId'],
1175              'name'  => L10n::get($row['name']),
1176              'state' => $state,
1177              'numId' => $row['numId']
1178            );
1179        }
1180
1181        if(count($datas)>0)
1182        {
1183          $local_tpl = new Template(AMD_PATH."admin/", "");
1184          $local_tpl->set_filename('body_page',
1185                        dirname($this->filelocation).'/admin/amd_metadata_display_groupListTagSelect.tpl');
1186          $local_tpl->assign('datas', $datas);
1187          return($local_tpl->parse('body_page', true));
1188        }
1189        else
1190        {
1191          return(l10n("g003_no_tag_can_be_selected"));
1192        }
1193      }
1194    }
1195    else
1196    {
1197      return(l10n("g003_invalid_group_id"));
1198    }
1199  }
1200
1201
1202  /**
1203   * this function associate tags to a group
1204   *
1205   * @param String $id      : Id of group
1206   * @param String $listTag : list of selected tags, items are separated by a
1207   *                          semi-colon ";" char
1208   */
1209  private function ajax_amd_groupSetTagList($id, $listTag)
1210  {
1211    if($id!="")
1212    {
1213      $sql="UPDATE ".$this->tables['selected_tags']."
1214            SET groupId = -1
1215            WHERE groupId = $id;";
1216      pwg_query($sql);
1217
1218      if($listTag!="")
1219      {
1220        $sql="UPDATE ".$this->tables['selected_tags']." st, ".$this->tables['used_tags']." ut
1221              SET st.groupId = $id
1222              WHERE st.tagId = ut.tagId
1223                AND ut.numId IN ($listTag);";
1224        pwg_query($sql);
1225      }
1226    }
1227    else
1228    {
1229      return("KO");
1230    }
1231  }
1232
1233
1234  /**
1235   * this function returns an ordered list of tags associated with a group
1236   *
1237   * @param String $id        : the group Id
1238   * @return String : an HTML formatted list
1239   */
1240  private function ajax_amd_groupGetOrderedTagList($id)
1241  {
1242    global $template;
1243    if($id!="")
1244    {
1245      $numOfPictures=$this->getNumOfPictures();
1246
1247      $sql="SELECT st.tagId, ut.name, ut.numId, ut.numOfImg
1248            FROM ".$this->tables['selected_tags']." st
1249              LEFT JOIN ".$this->tables['used_tags']." ut
1250                ON st.tagId = ut.tagId
1251            WHERE st.groupId = $id
1252            ORDER BY st.order ASC, st.tagId ASC";
1253      $result=pwg_query($sql);
1254      if($result)
1255      {
1256        $datas=Array();
1257        while($row=mysql_fetch_assoc($result))
1258        {
1259          $datas[]=Array(
1260            'tagId' => $row['tagId'],
1261            'name'  => L10n::get($row['name']),
1262            'numId' => $row['numId'],
1263            'nbItems' => $row['numOfImg'],
1264            'pct'   => sprintf("%.2f", 100*$row['numOfImg']/$numOfPictures)
1265          );
1266        }
1267
1268        if(count($datas)>0)
1269        {
1270          $template->set_filename('list_page',
1271                        dirname($this->filelocation).'/admin/amd_metadata_display_groupListTagOrder.tpl');
1272          $template->assign('datas', $datas);
1273          $template->assign('group', $id);
1274          return($template->parse('list_page', true));
1275        }
1276        else
1277        {
1278          return(l10n("g003_no_tag_can_be_selected"));
1279        }
1280      }
1281    }
1282    else
1283    {
1284      return(l10n("g003_invalid_group_id"));
1285    }
1286  }
1287
1288
1289  /**
1290   * this function update the tags order inside a group
1291   *
1292   * @param String $id        : the group Id
1293   * @param String $listGroup : the ordered list of tags, items are separated
1294   *                            by a semi-colon ";" char
1295   */
1296  private function ajax_amd_groupSetOrderedTagList($id, $listTag)
1297  {
1298    $tags=explode(';', $listTag);
1299    if($id!="" and count($tags)>0)
1300    {
1301      /*
1302       * by default, all items are set with order equals -1 (if list is not
1303       * complete, forgotten items are sorted in head)
1304       */
1305      pwg_query("UPDATE ".$this->tables['selected_tags']." st
1306                  SET st.order = -1
1307                  WHERE st.groupId = $id;");
1308
1309      foreach($tags as $key=>$val)
1310      {
1311        $sql="UPDATE ".$this->tables['selected_tags']." st, ".$this->tables['used_tags']." ut
1312              SET st.order = $key
1313              WHERE st.groupId = $id
1314                AND st.tagId = ut.tagId
1315                AND ut.numId = $val;";
1316        $result=pwg_query($sql);
1317      }
1318    }
1319  }
1320
1321
1322
1323  /**
1324   * this function update the groups order
1325   *
1326   * @param String $listGroup : the ordered list of groups, items are separated
1327   *                            by a semi-colon ";" char
1328   */
1329  private function ajax_amd_groupSetOrder($listGroup)
1330  {
1331    $groups=explode(";",$listGroup);
1332    if(count($groups)>0)
1333    {
1334      /*
1335       * by default, all items are set with order equals -1 (if list is not
1336       * complete, forgotten items are sorted in head)
1337       */
1338      pwg_query("UPDATE ".$this->tables['groups']." g SET g.order = -1;");
1339
1340      foreach($groups as $key=>$val)
1341      {
1342        $sql="UPDATE ".$this->tables['groups']." g
1343              SET g.order = $key
1344              WHERE g.groupId = $val;";
1345        $result=pwg_query($sql);
1346      }
1347    }
1348  }
1349
1350  /**
1351   * this function is used to create a new group ($groupId = "") or update the
1352   * group name (names are given in all langs in a list)
1353   *
1354   * @param String $groupId : the groupId to update, or "" to create a new groupId
1355   * @param String $listNames : name of the group, in all language given as a
1356   *                            list ; each lang is separated by a carraige
1357   *                            return "\n" char, each items is defined as
1358   *                            lang=value
1359   *                              en_UK=the name group
1360   *                              fr_FR=le nom du groupe
1361   */
1362  private function ajax_amd_groupSetNames($groupId, $listNames)
1363  {
1364    $names=explode("\n", $listNames);
1365    if($groupId=="" and count($names)>0)
1366    {
1367      $sql="INSERT INTO ".$this->tables['groups']." VALUES('', 9999)";
1368      $result=pwg_query($sql);
1369      $groupId=mysql_insert_id();
1370    }
1371
1372    if(is_numeric($groupId) and count($names)>0)
1373    {
1374      $sql="DELETE FROM ".$this->tables['groups_names']."
1375            WHERE groupId = $groupId;";
1376      pwg_query($sql);
1377
1378
1379      $sql="";
1380      foreach($names as $val)
1381      {
1382        $tmp=explode("=", $val);
1383        if($sql!="") $sql.=", ";
1384        $sql.=" ($groupId, '".$tmp[0]."', '".$tmp[1]."')";
1385      }
1386      $sql="INSERT INTO ".$this->tables['groups_names']." VALUES ".$sql;
1387      pwg_query($sql);
1388    }
1389  }
1390
1391  /**
1392   * this function returns an html form, allowing to manage the group
1393   *
1394   * @param String $groupId : the groupId to manage, or "" to return a creation
1395   *                          form
1396   * @return String : the form
1397   */
1398  private function ajax_amd_groupGetNames($groupId)
1399  {
1400    global $user;
1401
1402    $local_tpl = new Template(AMD_PATH."admin/", "");
1403    $local_tpl->set_filename('body_page',
1404                  dirname($this->filelocation).'/admin/amd_metadata_display_groupEdit.tpl');
1405
1406    $datasLang=array(
1407      'language_list' => Array(),
1408      'lang_selected' => $user['language'],
1409      'fromlang' => substr($user['language'],0,2),
1410      'default' => ''
1411    );
1412
1413    $langs=get_languages();
1414    foreach($langs as $key => $val)
1415    {
1416      $datasLang['language_list'][$key] = Array(
1417        'langName' => str_replace("\n", "", $val),
1418        'name' => ""
1419      );
1420    }
1421
1422    if($groupId!="")
1423    {
1424      $sql="SELECT lang, name FROM ".$this->tables['groups_names']."
1425            WHERE groupId = $groupId;";
1426      $result=pwg_query($sql);
1427      if($result)
1428      {
1429        while($row=mysql_fetch_assoc($result))
1430        {
1431          if(array_key_exists($row['lang'], $datasLang['language_list']))
1432          {
1433            $datasLang['language_list'][$row['lang']]['name']=htmlentities($row['name'], ENT_QUOTES, 'UTF-8');
1434            if($user['language']==$row['lang'])
1435            {
1436              $datasLang['default']=$datasLang['language_list'][$row['lang']]['name'];
1437            }
1438          }
1439        }
1440      }
1441    }
1442
1443    $local_tpl->assign('datasLang', $datasLang);
1444
1445    return($local_tpl->parse('body_page', true));
1446  }
1447
1448
1449  /**
1450   * this function returns an html form, allowing to manage the group
1451   *
1452   * @param String $groupId : the groupId to manage, or "" to return a creation
1453   *                          form
1454   * @return String : the form
1455   */
1456  private function ajax_amd_groupGetList()
1457  {
1458    global $user, $template;
1459
1460    //$local_tpl = new Template(AMD_PATH."admin/", "");
1461    $template->set_filename('group_list',
1462                  dirname($this->filelocation).'/admin/amd_metadata_display_groupList.tpl');
1463
1464
1465    $datas=array(
1466      'groups' => Array(),
1467    );
1468
1469    $sql="SELECT g.groupId, gn.name
1470          FROM ".$this->tables['groups']." g
1471            LEFT JOIN ".$this->tables['groups_names']." gn
1472              ON g.groupId = gn.groupId
1473          WHERE gn.lang = '".$user['language']."'
1474          ORDER BY g.order;";
1475    $result=pwg_query($sql);
1476    if($result)
1477    {
1478      while($row=mysql_fetch_assoc($result))
1479      {
1480        $datas['groups'][]=Array(
1481          'id' => $row['groupId'],
1482          'name' => htmlentities($row['name'], ENT_QUOTES, "UTF-8")
1483        );
1484      }
1485    }
1486
1487    $template->assign('datas', $datas);
1488    return($template->parse('group_list', true));
1489  }
1490
1491
1492  /**
1493   * delete the group
1494   * associated tag returns in the available tag list
1495   *
1496   * @param String $groupId : the groupId to delete
1497   */
1498  private function ajax_amd_groupDelete($groupId)
1499  {
1500    if($groupId!="")
1501    {
1502      $sql="DELETE FROM ".$this->tables['groups']."
1503            WHERE groupId = $groupId;";
1504      pwg_query($sql);
1505
1506      $sql="DELETE FROM ".$this->tables['groups_names']."
1507            WHERE groupId = $groupId;";
1508      pwg_query($sql);
1509
1510      $sql="UPDATE ".$this->tables['selected_tags']."
1511            SET groupId = -1
1512            WHERE groupId = $groupId;";
1513      pwg_query($sql);
1514    }
1515  }
1516
1517} // AMD_AIP class
1518
1519
1520?>
Note: See TracBrowser for help on using the repository browser.