Changeset 6722


Ignore:
Timestamp:
Jul 28, 2010, 10:48:17 AM (14 years ago)
Author:
grum
Message:

bug:1686, feature:1718, feature:1719, feature:1688, feature:1692

  • Picture analysis finish with an Error 500 or with a problem of memory limit
  • Coding a DateTime class
  • Make JpegMetadata class tests images lighter
  • Improve performance when the database is filled
  • Add possibility for user to build their own tags
  • ajax management entirely rewritted
Location:
extensions/AMetaData
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • extensions/AMetaData/JpegMetaData/JpegMetaData.class.php

    r5789 r6722  
    33 * --:: JPEG MetaDatas ::-------------------------------------------------------
    44 *
    5  * Version : 1.0.0
    6  * Date    : 2009/12/26
     5 * Version : 1.0.1
     6 * Date    : 2010-07-24
    77 *
    88 *  Author    : Grum
     
    3939 * | 0.1.0a  | 2009-12-26 |
    4040 * |         |            |
    41  * |         |            |
    42  * |         |            |
     41 * | 1.0.0   |            | * first public release
     42 * |         |            |
     43 * | 1.0.1   | 2010-07-24 | * mantis bug:1686
     44 * |         |            |   . bug reported on IfdReader
     45 * |         |            |     When sub IFD (0x8769) refers to a sub IFD with
     46 * |         |            |     an offset lower than the current IFD, the reader
     47 * |         |            |     loops on the current data block and terminate
     48 * |         |            |     with an error 500 ; fix consist to ignore this
     49 * |         |            |     kind of offset, but it's not the right solution
     50 * |         |            |     (right solution: to be able to read negative
     51 * |         |            |     offset)
     52 * |         |            | * mantis feature : 1719
     53 * |         |            |   . Coding a DateTime class ; used only if there is
     54 * |         |            |     no PHP built-in DateTime class
    4355 * |         |            |
    4456 * |         |            |
     
    112124  define("JPEG_METADATA_DIR", dirname(__FILE__)."/");
    113125
     126  require_once(JPEG_METADATA_DIR."Common/DateTime.class.php");
    114127  require_once(JPEG_METADATA_DIR."Readers/JpegReader.class.php");
    115128  require_once(JPEG_METADATA_DIR."TagDefinitions/MagicTags.class.php");
  • extensions/AMetaData/JpegMetaData/Readers/IfdReader.class.php

    r5222 r6722  
    107107      $this->dataOffset=$offset;
    108108
     109
    109110      $this->skipHeader($this->headerSize);
    110111
     112
     113
    111114      $dataPointer = $this->data->offset();
     115
    112116      /*
    113117       * number of entries is defined byte an UShort at the begining of the
     
    422426           * the returned value is a parsed sub IFD
    423427           */
    424           $returned=new IfdReader($this->data->readASCII(-1,$values-$this->dataOffset), $values, $this->byteOrder);
     428          if($values>$this->dataOffset)
     429          {
     430            $returned=new IfdReader($this->data->readASCII(-1,$values-$this->dataOffset), $values, $this->byteOrder);
     431          }
     432          else
     433          {
     434            /* ELSE implemented with the mantis bug:1686
     435             * when the offset of a sub IFD tag is lower than the offset of the
     436             * current IFD, ignore the sub IFD
     437             *
     438             * A method have to be coded to manage this kind of sub IFD
     439             */
     440            $returned="Feature not implemented: read negative offset";
     441          }
    425442          break;
    426443        case 0x8825: // GPS IFD Pointer, tag 0x8825
  • extensions/AMetaData/admin/amd_metadata_database.tpl

    r5959 r6722  
    3434  function getStatus()
    3535  {
    36     data=$.ajax(
    37       {
    38         type: "POST",
    39         url: "{/literal}{$datas.urlRequest}{literal}",
    40         async: false,
    41         data: { ajaxfct:"makeStatsGetStatus" }
    42       }
    43     ).responseText;
    44 
    45     list=data.split(";");
    46     $("#ianalyzestatus").html("<ul><li>"+list[0]+"</li><li>"+list[1]+"</li><li>"+list[2]+"</li></ul>");
     36    $.ajax(
     37      {
     38        type: "POST",
     39        url: "{/literal}{$datas.urlRequest}{literal}",
     40        async: true,
     41        data: { ajaxfct:"admin.makeStats.getStatus" },
     42        success: function (msg) {
     43          list=msg.split(";");
     44          $("#ianalyzestatus").html("<ul><li>"+list[0]+"</li><li>"+list[1]+"</li><li>"+list[2]+"</li></ul>");
     45        }
     46      }
     47    );
    4748  }
    4849
     
    103104        url: "{/literal}{$datas.urlRequest}{literal}",
    104105        async: true,
    105         data: { ajaxfct:"makeStatsGetList", selectMode:mode, numOfItems:NumberOfItemsPerRequest },
     106        data: { ajaxfct:"admin.makeStats.getList", selectMode:mode, numOfItems:NumberOfItemsPerRequest },
    106107        success: function(msg)
    107108          {
     
    133134    if(processAnalyze.step < processAnalyze.lists.length)
    134135    {
    135       tmp = $.ajax({
     136      $.ajax({
    136137        type: "POST",
    137138        url: "{/literal}{$datas.urlRequest}{literal}",
    138139        async: true,
    139         data: { ajaxfct:"makeStatsDoAnalyze", imagesList:processAnalyze.lists[processAnalyze.step] },
     140        data: { ajaxfct:"admin.makeStats.doAnalyze", imagesList:processAnalyze.lists[processAnalyze.step] },
    140141        success: function(msg)
    141142          {
     
    152153    {
    153154      // list completely processed
    154 
    155155      tmp = $.ajax({
    156156        type: "POST",
    157157        url: "{/literal}{$datas.urlRequest}{literal}",
    158158        async: false,
    159         data: { ajaxfct:"makeStatsConsolidation" }
     159        data: { ajaxfct:"admin.makeStats.consolidate" }
    160160       }).responseText;
    161 
    162161
    163162      processAnalyze.timeEnd = new Date();
    164163      timeElapsed=processAnalyze.timeEnd.getTime()-processAnalyze.timeStart.getTime();
    165 
    166164
    167165      $("#dialog")
  • extensions/AMetaData/admin/amd_metadata_display.tpl

    r5959 r6722  
    1 
    2 
    31{literal}
    4 <style>
    5  .ui-widget-overlay {
    6     background:#000000;
    7     opacity:0.88;
    8     filter:alpha(opacity:88);
    9  }
    10 </style>
    11 
    122<script type="text/javascript">
    133
     
    2111          url: "{/literal}{$datas.urlRequest}{literal}",
    2212          async: false,
    23           data: { ajaxfct:"groupGetList" }
     13          data: { ajaxfct:"admin.group.getList" }
    2414        }
    2515      ).responseText
     
    5343                url: "{/literal}{$datas.urlRequest}{literal}",
    5444                async: false,
    55                 data: { ajaxfct:"groupSetOrder", listGroup:list }
     45                data: { ajaxfct:"admin.group.setOrder", listGroup:list }
    5646              }
    5747            ).responseText;
     
    9383                url: "{/literal}{$datas.urlRequest}{literal}",
    9484                async: false,
    95                 data: { ajaxfct:"groupSetOrderedTagList", id:groupId, listTag:list }
     85                data: { ajaxfct:"admin.group.setOrderedTagList", id:groupId, listTag:list }
    9686              }
    9787            ).responseText;
     
    110100          url: "{/literal}{$datas.urlRequest}{literal}",
    111101          async: false,
    112           data: { ajaxfct:"groupGetOrderedTagList", id:groupId }
     102          data: { ajaxfct:"admin.group.getOrderedTagList", id:groupId }
    113103        }
    114104      ).responseText
     
    179169                    url: "{/literal}{$datas.urlRequest}{literal}",
    180170                    async: false,
    181                     data: { ajaxfct:"groupDelete", id:groupId }
     171                    data: { ajaxfct:"admin.group.delete", id:groupId }
    182172                  }
    183173                ).responseText;
     
    188178                      url: "{/literal}{$datas.urlRequest}{literal}",
    189179                      async: false,
    190                       data: { ajaxfct:"groupGetList" }
     180                      data: { ajaxfct:"admin.group.getList" }
    191181                    }
    192182                  ).responseText
     
    247237                  url: "{/literal}{$datas.urlRequest}{literal}",
    248238                  async: false,
    249                   data: { ajaxfct:"groupSetNames", id:groupId, listNames:list }
     239                  data: { ajaxfct:"admin.group.setNames", id:groupId, listNames:list }
    250240                }
    251241              ).responseText;
     
    256246                    url: "{/literal}{$datas.urlRequest}{literal}",
    257247                    async: false,
    258                     data: { ajaxfct:"groupGetList" }
     248                    data: { ajaxfct:"admin.group.getList" }
    259249                  }
    260250                ).responseText
     
    276266          url: "{/literal}{$datas.urlRequest}{literal}",
    277267          async: false,
    278           data: { ajaxfct:"groupGetNames", id:groupId }
     268          data: { ajaxfct:"admin.group.getNames", id:groupId }
    279269        }
    280270      ).responseText
     
    323313                  url: "{/literal}{$datas.urlRequest}{literal}",
    324314                  async: false,
    325                   data: { ajaxfct:"groupSetTagList", id:groupId, listTag:list }
     315                  data: { ajaxfct:"admin.group.setTagList", id:groupId, listTag:list }
    326316                }
    327317              ).responseText;
     
    345335        url: "{/literal}{$datas.urlRequest}{literal}",
    346336        async: true,
    347         data: { ajaxfct:"groupGetTagList", id:groupId },
     337        data: { ajaxfct:"admin.group.getTagList", id:groupId },
    348338        success:
    349339          function(msg)
  • extensions/AMetaData/admin/amd_metadata_display_groupList.tpl

    r5935 r6722  
    66
    77    <a onclick="deleteGroup('{$data.id}');">
    8       <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/delete.png"  class="button drag_button" alt="{'g003_click_to_delete_group'|@translate}" title="{'g003_click_to_delete_group'|@translate}"
     8      <img src="{$themeconf.admin_icon_dir}/delete.png"  class="button drag_button" alt="{'g003_click_to_delete_group'|@translate}" title="{'g003_click_to_delete_group'|@translate}"
    99            style="float:right;"/>
    1010    </a>
    1111
    1212    <a onclick="editGroup('{$data.id}');">
    13       <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/category_edit.png"  class="button drag_button" alt="{'g003_click_to_edit_group'|@translate}" title="{'g003_click_to_edit_group'|@translate}"
     13      <img src="{$themeconf.admin_icon_dir}/category_edit.png"  class="button drag_button" alt="{'g003_click_to_edit_group'|@translate}" title="{'g003_click_to_edit_group'|@translate}"
    1414            style="float:right;"/>
    1515    </a>
    1616
    1717    <a onclick="manageGroup('{$data.id}', '');">
    18       <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/preferences.png"  class="button drag_button" alt="{'g003_click_to_manage_group'|@translate}" title="{'g003_click_to_manage_group'|@translate}"
     18      <img src="{$themeconf.admin_icon_dir}/preferences.png"  class="button drag_button" alt="{'g003_click_to_manage_group'|@translate}" title="{'g003_click_to_manage_group'|@translate}"
    1919            style="float:right;"/>
    2020    </a>
     
    2323    <div name="fGroupId{$data.id}_content" id="iGroupId{$data.id}_content" style="visibility:hidden;height:0px;" class="groupTags">
    2424      <a onclick="editGroupList('{$data.id}');" class="button editGroupListButton">
    25       <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/edit_s.png"  class="button drag_button" alt="{'g003_click_to_manage_list'|@translate}" title="{'g003_click_to_manage_list'|@translate}"/>
     25      <img src="{$themeconf.admin_icon_dir}/edit_s.png"  class="button drag_button" alt="{'g003_click_to_manage_list'|@translate}" title="{'g003_click_to_manage_list'|@translate}"/>
    2626      </a>
    2727      <ul id="iGroupId{$data.id}_tags" class="tagListOrder g{$data.id}_connectedSortableTags">
  • extensions/AMetaData/admin/amd_metadata_select.tpl

    r5959 r6722  
    11{literal}
    2 <style>
    3  .ui-widget-overlay {
    4     background:#000000;
    5     opacity:0.88;
    6     filter:alpha(opacity:88);
    7  }
    8 </style>
    9 
    10 
    112<script type="text/javascript">
    123
     
    6253        url: "{/literal}{$datas.urlRequest}{literal}",
    6354        async: true,
    64         data: { ajaxfct:"showStatsGetListTags", orderType:order, filterType:filter, excludeUnusedTag:unusedTag, selectedTagOnly:selectedOnly },
     55        data: { ajaxfct:"admin.showStats.getListTags", orderType:order, filterType:filter, excludeUnusedTag:unusedTag, selectedTagOnly:selectedOnly },
    6556        success:
    6657          function(msg)
     
    110101        url: "{/literal}{$datas.urlRequest}{literal}",
    111102        async: true,
    112         data: { ajaxfct:"showStatsGetListImages", orderType:order, tagId:tag,  },
     103        data: { ajaxfct:"admin.showStats.getListImages", orderType:order, tagId:tag,  },
    113104        success:
    114105          function(msg)
     
    138129        url: "{/literal}{$datas.urlRequest}{literal}",
    139130        async: false,
    140         data: { ajaxfct:"updateTagSelect", tagSelected:selected, numId:numId.substr(6) }
     131        data: { ajaxfct:"admin.updateTag.select", tagSelected:selected, numId:numId.substr(6) }
    141132       }).responseText
    142133    );
     
    211202      <option value="" {if $datas.config_GetListTags_FilterType==""}selected{/if}>{'g003_no_filter'|@translate}</option>
    212203      <option value="magic" {if $datas.config_GetListTags_FilterType=="magic"}selected{/if}>{'g003_magic_filter'|@translate}</option>
     204      <option value="userDefined" {if $datas.config_GetListTags_FilterType=="userDefined"}selected{/if}>{'g003_userDefined_filter'|@translate}</option>
    213205      <option value="exif" {if $datas.config_GetListTags_FilterType=="exif"}selected{/if}>Exif</option>
    214206      <option value="exif.Canon" {if $datas.config_GetListTags_FilterType=="exif.Canon"}selected{/if}>Exif [Canon]</option>
  • extensions/AMetaData/amd.css

    r6173 r6722  
    1010#iHeaderListImages { width:100%; border-bottom:1px solid; }
    1111div.addGroup { padding-left:40px; text-align:left; }
     12div.addMetadata { text-align:left; }
    1213#iGroups { list-style: none; }
    1314
    1415.tagListOrder { list-style: none; padding:0px; margin-right:8px; margin-left:35px; }
    15 .tagListOrder li { border:none; padding:1px; margin-bottom:2px; width:100%; }
     16.tagListOrder li { border:none; padding:1px; margin-bottom:2px; width:100%;
     17-moz-border-radius:4px;
     18-webkit-border-radius:4px;
     19-khtml-border-radius:4px;
     20border-radius:4px;
     21}
    1622.groupTags { padding-top:8px; }
    1723.editGroupListButton { margin-left:8px; position:absolute; z-index:1000; }
     
    2632.helpBody li { margin-left:30px; }
    2733
     34.ui-widget-overlay { background:#000000; opacity:0.88; filter:alpha(opacity:88); }
     35#mdRulesArea { border-top:1px solid; overflow:auto; }
     36#iBDRules { list-style-type:none; padding:0px; }
     37#iBDRules li.groupItems { margin:4px 4px 4px 12px; width:auto; cursor:default; }
     38
     39img.pointer, span.pointer, div.pointer { cursor:pointer; }
     40img.drag_button { margin-right:8px; }
     41li.groupItems input, li.groupItems select { margin-right:4px; }
     42
     43#iBDRules ul { list-style-type:none; }
     44#iBDRules li.groupItems img.rmSortHandle { cursor:move; }
     45#dragHelper { z-index: 4500;  text-align:left; }
     46#dragHelper ul li.cbItem { padding:2px; }
     47#dragHelper ul li {
     48  clear:both;
     49  min-height:32px;
     50  list-style-image:none;
     51  list-style-position:outside;
     52  list-style-type:none;
     53  margin:4px;
     54  padding:0px;
     55  width:auto;
     56}
     57.helper {
     58  -moz-border-radius:8px;
     59  -webkit-border-radius:8px;
     60  -khtml-border-radius:8px;
     61  border-radius:8px;
     62  border:2px dashed #777777;
     63  margin:4px 4px 4px 12px;
     64}
     65
     66#iTagList { list-style-type:none; padding:0px; margin:0px; }
     67span.tagName {
     68  border-right:1px dotted #666666;
     69  display:inline-block;
     70  margin-right:2px;
     71  padding:2px 0 1px;
     72  width:240px;
     73}
     74
     75#iTagList li { padding: 0px 2px; }
     76#iTagList.clear li:hover { cursor:pointer; color: #D54E21; background:#dbe8f3; }
     77#iTagList.roma li:hover { cursor:pointer; background:#303030; }
     78#iTagList.selectedroma { background:#303030; }
     79#iTagList.selectedclear { background:#dbe8f3; }
     80.ruleTypeM, .ruleTypeM2 {
     81  border:1px solid #666666;
     82  display:inline-block;
     83  padding:0 2px 0;
     84}
     85div.ruleTypeM { width:493px; }
     86div.ruleTypeM2 { width:400px; }
     87div.ruleSelector {
     88  float:left;
     89  width:150px;
     90}
     91div.ruleProperties {
     92  padding-top:2px;
     93}
     94.error, input.error {
     95  background:#FFAAAA;
     96  border:1px solid #800000;
     97  color:#800000;
     98}
     99ul.error {
     100  min-height:30px;
     101  -moz-border-radius:8px;
     102  -webkit-border-radius:8px;
     103  -khtml-border-radius:8px;
     104  border-radius:8px;
     105}
  • extensions/AMetaData/amd_aip.class.inc.php

    r6173 r6722  
    4848
    4949    $this->tabsheet = new tabsheet();
     50    $this->tabsheet->add('database',
     51                          l10n('g003_database'),
     52                          $this->getAdminLink().'&amp;fAMD_tabsheet=database');
    5053    $this->tabsheet->add('metadata',
    5154                          l10n('g003_metadata'),
    5255                          $this->getAdminLink().'&amp;fAMD_tabsheet=metadata');
     56    $this->tabsheet->add('search',
     57                          l10n('g003_search'),
     58                          $this->getAdminLink().'&amp;fAMD_tabsheet=search');
    5359    $this->tabsheet->add('help',
    5460                          l10n('g003_help'),
     
    7884    global $template, $page;
    7985
     86    $this->initRequest();
     87
    8088    $template->set_filename('plugin_admin_content', dirname(__FILE__)."/admin/amd_admin.tpl");
    81 
    82     $this->initRequest();
    83 
    84     $this->returnAjaxContent();
    8589
    8690    $this->tabsheet->select($_REQUEST['fAMD_tabsheet']);
     
    8993    $template->assign($this->tabsheet->get_titlename(), "[".$selected_tab['caption']."]");
    9094
    91     $template_plugin["AMD_VERSION"] = "<i>".$this->getPluginName()."</i> ".l10n('g003_version').AMD_VERSION;
    92     $template_plugin["AMD_PAGE"] = $_REQUEST['fAMD_tabsheet'];
    93     $template_plugin["PATH"] = AMD_PATH;
    94 
    95     $template->assign('plugin', $template_plugin);
    96 
    97     if($_REQUEST['fAMD_tabsheet']=='help')
    98     {
    99       $this->displayHelp();
    100     }
    101     elseif($_REQUEST['fAMD_tabsheet']=='metadata')
    102     {
    103       $this->displayMetaData($_REQUEST['fAMD_page']);
     95    $pluginInfo=array(
     96      'AMD_VERSION' => "<i>".$this->getPluginName()."</i> ".l10n('g003_version').AMD_VERSION,
     97      'AMD_PAGE' => $_REQUEST['fAMD_tabsheet'],
     98      'PATH' => AMD_PATH
     99    );
     100
     101    $template->assign('plugin', $pluginInfo);
     102
     103    switch($_REQUEST['fAMD_tabsheet'])
     104    {
     105      case 'help':
     106        $this->displayHelp();
     107        break;
     108      case 'database':
     109        $this->displayDatabase($_REQUEST['fAMD_page']);
     110        break;
     111      case 'metadata':
     112        $this->displayMetaData($_REQUEST['fAMD_page']);
     113        break;
     114      case 'search':
     115        //$this->displaySearch($_REQUEST['fAMD_page']);
     116        break;
    104117    }
    105118
     
    125138
    126139  /**
    127    * manage the ajax requests
    128    * this function function determine if there is an ajax call, manage the
    129    * request and returns the content of the request
    130    *
    131    * no params are given, the function works with the "$_REQUEST" var
    132    *
    133    * @return String
    134    */
    135   protected function returnAjaxContent()
    136   {
    137     global $ajax, $template;
    138 
    139     if(isset($_REQUEST['ajaxfct']))
    140     {
    141       //$this->debug("AJAXFCT:".$_REQUEST['ajaxfct']);
    142       $result="<p class='errors'>".l10n('g002_error_invalid_ajax_call')."</p>";
    143       switch($_REQUEST['ajaxfct'])
     140   * if empty, initialize the $_REQUEST var
     141   *
     142   * if not empty, check validity for the request values
     143   *
     144   */
     145  private function initRequest()
     146  {
     147    //initialise $REQUEST values if not defined
     148
     149    if(!isset($_REQUEST['fAMD_tabsheet']))
     150    {
     151      if($this->getNumOfPictures()==0)
    144152      {
    145         case 'makeStatsGetList':
    146           $result=$this->ajax_amd_makeStatsGetList($_REQUEST['selectMode'], $_REQUEST['numOfItems']);
    147           break;
    148         case 'makeStatsDoAnalyze':
    149           $result=$this->ajax_amd_makeStatsDoAnalyze($_REQUEST['imagesList']);
    150           break;
    151         case 'makeStatsConsolidation':
    152           $result=$this->ajax_amd_makeStatsConsolidation();
    153           break;
    154         case 'makeStatsGetStatus':
    155           $result=$this->ajax_amd_makeStatsGetStatus();
    156           break;
    157         case 'showStatsGetListTags':
    158           $result=$this->ajax_amd_showStatsGetListTags($_REQUEST['orderType'], $_REQUEST['filterType'], $_REQUEST['excludeUnusedTag'], $_REQUEST['selectedTagOnly']);
    159           break;
    160         case 'showStatsGetListImages':
    161           $result=$this->ajax_amd_showStatsGetListImages($_REQUEST['tagId'], $_REQUEST['orderType']);
    162           break;
    163         case 'updateTagSelect':
    164           $result=$this->ajax_amd_updateTagSelect($_REQUEST['numId'], $_REQUEST['tagSelected']);
    165           break;
    166         case 'groupGetList':
    167           $result=$this->ajax_amd_groupGetList();
    168           break;
    169         case 'groupDelete':
    170           $result=$this->ajax_amd_groupDelete($_REQUEST['id']);
    171           break;
    172         case 'groupGetNames':
    173           $result=$this->ajax_amd_groupGetNames($_REQUEST['id']);
    174           break;
    175         case 'groupSetNames':
    176           $result=$this->ajax_amd_groupSetNames($_REQUEST['id'], $_REQUEST['listNames']);
    177           break;
    178         case 'groupSetOrder':
    179           $result=$this->ajax_amd_groupSetOrder($_REQUEST['listGroup']);
    180           break;
    181         case 'groupGetTagList':
    182           $result=$this->ajax_amd_groupGetTagList($_REQUEST['id']);
    183           break;
    184         case 'groupSetTagList':
    185           $result=$this->ajax_amd_groupSetTagList($_REQUEST['id'], $_REQUEST['listTag']);
    186           break;
    187         case 'groupGetOrderedTagList':
    188           $result=$this->ajax_amd_groupGetOrderedTagList($_REQUEST['id']);
    189           break;
    190         case 'groupSetOrderedTagList':
    191           $result=$this->ajax_amd_groupSetOrderedTagList($_REQUEST['id'], $_REQUEST['listTag']);
    192           break;
     153        $_REQUEST['fAMD_tabsheet']="database";
     154        $_REQUEST['fAMD_page']="state";
    193155      }
    194       GPCAjax::returnResult($result);
    195     }
    196   }
    197 
    198 
    199   /**
    200    * if empty, initialize the $_REQUEST var
    201    *
    202    * if not empty, check validity for the request values
    203    *
    204    */
    205   private function initRequest()
    206   {
    207     //initialise $REQUEST values if not defined
    208     if($this->getNumOfPictures()==0)
    209     {
    210       $defautTabsheet="database";
    211     }
    212     else
    213     {
    214       $defautTabsheet="select";
    215     }
    216 
    217     if(!isset($_REQUEST['fAMD_tabsheet']))
    218     {
    219       $_REQUEST['fAMD_tabsheet']=$defautTabsheet;
    220     }
    221 
    222     if($_REQUEST['fAMD_tabsheet']!="metadata" and
    223        $_REQUEST['fAMD_tabsheet']!="help")
     156      else
     157      {
     158        $_REQUEST['fAMD_tabsheet']="metadata";
     159        $_REQUEST['fAMD_page']="select";
     160      }
     161    }
     162
     163    if(!($_REQUEST['fAMD_tabsheet']=="metadata" or
     164         $_REQUEST['fAMD_tabsheet']!="help" or
     165         $_REQUEST['fAMD_tabsheet']!="database" or
     166         $_REQUEST['fAMD_tabsheet']!="search"))
    224167    {
    225168      $_REQUEST['fAMD_tabsheet']="metadata";
    226169    }
    227170
    228     if($_REQUEST['fAMD_tabsheet']=="metadata" and !isset($_REQUEST['fAMD_page']))
    229     {
    230       $_REQUEST['fAMD_page']=$defautTabsheet;
    231     }
    232 
    233     if($_REQUEST['fAMD_tabsheet']=="metadata" and
    234        !($_REQUEST['fAMD_page']=="select" or
    235          $_REQUEST['fAMD_page']=="database" or
    236          $_REQUEST['fAMD_page']=="display"))
    237     {
    238       $_REQUEST['fAMD_page']=$defautTabsheet;
    239     }
    240 
    241 
    242     if($_REQUEST['fAMD_tabsheet']=="help" and !isset($_REQUEST['fAMD_page']))
    243     {
    244       $_REQUEST['fAMD_page']="exif";
    245     }
    246 
    247     if($_REQUEST['fAMD_tabsheet']=="help" and
    248        !($_REQUEST['fAMD_page']=="exif" or
    249          $_REQUEST['fAMD_page']=="iptc" or
    250          $_REQUEST['fAMD_page']=="xmp" or
    251          $_REQUEST['fAMD_page']=="magic"))
    252     {
    253       $_REQUEST['fAMD_page']="exif";
    254     }
    255 
    256 
    257     /*
    258      * check ajax
    259      */
    260     if(isset($_REQUEST['ajaxfct']))
    261     {
    262       /*
    263        * check makeStatsGetList values
    264        */
    265       if($_REQUEST['ajaxfct']=="makeStatsGetList" and !isset($_REQUEST['selectMode']))
    266       {
    267         $_REQUEST['selectMode']="caddieAdd";
    268       }
    269 
    270       if($_REQUEST['ajaxfct']=="makeStatsGetList" and
    271          !($_REQUEST['selectMode']=="notAnalyzed" or
    272            $_REQUEST['selectMode']=="caddieAdd" or
    273            $_REQUEST['selectMode']=="caddieReplace" or
    274            $_REQUEST['selectMode']=="all"))
    275       {
    276         $_REQUEST['selectMode']="caddieAdd";
    277       }
    278 
    279       if($_REQUEST['ajaxfct']=="makeStatsGetList" and !isset($_REQUEST['numOfItems']))
    280       {
    281         $_REQUEST['numOfItems']=25;
    282       }
    283 
    284       /*
    285        * check makeStatsDoAnalyze values
    286        */
    287       if($_REQUEST['ajaxfct']=="makeStatsDoAnalyze" and !isset($_REQUEST['imagesList']))
    288       {
    289         $_REQUEST['imagesList']="";
    290       }
    291 
    292       /*
    293        * check makeStatsConsolidate values
    294        */
    295       if($_REQUEST['ajaxfct']=="makeStatsConsolidate" and !isset($_REQUEST['step']))
    296       {
    297         $_REQUEST['step']="*";
    298       }
    299 
    300       /*
    301        * check showStatsGetListTags values
    302        */
    303       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['orderType']))
    304       {
    305         $_REQUEST['orderType']="tag";
    306       }
    307 
    308       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
    309          !($_REQUEST['orderType']=="tag" or
    310            $_REQUEST['orderType']=="label" or
    311            $_REQUEST['orderType']=="num"))
    312       {
    313         $_REQUEST['orderType']="tag";
    314       }
    315 
    316       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['filterType']))
    317       {
    318         $_REQUEST['filterType']="";
    319       }
    320 
    321       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
    322          !($_REQUEST['filterType']=="" or
    323            $_REQUEST['filterType']=="magic" or
    324            $_REQUEST['filterType']=="exif" or
    325            $_REQUEST['filterType']=="exif.Canon" or
    326            $_REQUEST['filterType']=="exif.Nikon" or
    327            $_REQUEST['filterType']=="exif.Pentax" or
    328            $_REQUEST['filterType']=="xmp" or
    329            $_REQUEST['filterType']=="iptc"))
    330       {
    331         $_REQUEST['filterType']="";
    332       }
    333 
    334       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['excludeUnusedTag']))
    335       {
    336         $_REQUEST['excludeUnusedTag']="n";
    337       }
    338 
    339       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
    340          !($_REQUEST['excludeUnusedTag']=="y" or
    341            $_REQUEST['excludeUnusedTag']=="n" ))
    342       {
    343         $_REQUEST['excludeUnusedTag']="n";
    344       }
    345 
    346       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and !isset($_REQUEST['selectedTagOnly']))
    347       {
    348         $_REQUEST['selectedTagOnly']="n";
    349       }
    350 
    351       if($_REQUEST['ajaxfct']=="showStatsGetListTags" and
    352          !($_REQUEST['selectedTagOnly']=="y" or
    353            $_REQUEST['selectedTagOnly']=="n" ))
    354       {
    355         $_REQUEST['selectedTagOnly']="n";
    356       }
    357 
    358 
    359       /*
    360        * check showStatsGetListImagess values
    361        */
    362       if($_REQUEST['ajaxfct']=="showStatsGetListImages" and !isset($_REQUEST['orderType']))
    363       {
    364         $_REQUEST['orderType']="num";
    365       }
    366 
    367       if($_REQUEST['ajaxfct']=="showStatsGetListImages" and
    368          !($_REQUEST['orderType']=="value" or
    369            $_REQUEST['orderType']=="num"))
    370       {
    371         $_REQUEST['orderType']="num";
    372       }
    373 
    374       if($_REQUEST['ajaxfct']=="showStatsGetListImages" and !isset($_REQUEST['tagId']))
    375       {
    376         $_REQUEST['tagId']="*";
    377       }
    378 
    379 
    380       /*
    381        * check showStatsGetListImagess values
    382        */
    383       if($_REQUEST['ajaxfct']=="updateTagSelect" and !isset($_REQUEST['numId']))
    384       {
    385         $_REQUEST['numId']="";
    386       }
    387 
    388       if($_REQUEST['ajaxfct']=="updateTagSelect" and !isset($_REQUEST['tagSelected']))
    389       {
    390         $_REQUEST['tagSelected']="";
    391       }
    392 
    393 
    394 
    395 
    396       /*
    397        * check groupDelete values
    398        */
    399       if($_REQUEST['ajaxfct']=="groupDelete" and !isset($_REQUEST['id']))
    400       {
    401         $_REQUEST['id']="";
    402       }
    403 
    404 
    405 
    406       /*
    407        * check groupSetOrder values
    408        */
    409       if($_REQUEST['ajaxfct']=="groupSetOrder" and !isset($_REQUEST['listGroup']))
    410       {
    411         $_REQUEST['listGroup']="";
    412       }
    413 
    414       /*
    415        * check groupGetNames values
    416        */
    417       if($_REQUEST['ajaxfct']=="groupGetNames" and !isset($_REQUEST['id']))
    418       {
    419         $_REQUEST['id']="";
    420       }
    421 
    422       /*
    423        * check groupSetNames values
    424        */
    425       if($_REQUEST['ajaxfct']=="groupSetNames" and !isset($_REQUEST['listNames']))
    426       {
    427         $_REQUEST['listNames']="";
    428       }
    429 
    430       if($_REQUEST['ajaxfct']=="groupSetNames" and !isset($_REQUEST['id']))
    431       {
    432         $_REQUEST['id']="";
    433       }
    434 
    435 
    436       /*
    437        * check groupGetTagList values
    438        */
    439       if($_REQUEST['ajaxfct']=="groupGetTagList" and !isset($_REQUEST['id']))
    440       {
    441         $_REQUEST['id']="";
    442       }
    443 
    444       /*
    445        * check groupSetTagList values
    446        */
    447       if($_REQUEST['ajaxfct']=="groupSetTagList" and !isset($_REQUEST['id']))
    448       {
    449         $_REQUEST['id']="";
    450       }
    451 
    452       if($_REQUEST['ajaxfct']=="groupSetTagList" and !isset($_REQUEST['listTag']))
    453       {
    454         $_REQUEST['listTag']="";
    455       }
    456 
    457 
    458       /*
    459        * check groupGetOrderedTagList values
    460        */
    461       if($_REQUEST['ajaxfct']=="groupGetOrderedTagList" and !isset($_REQUEST['id']))
    462       {
    463         $_REQUEST['id']="";
    464       }
    465 
    466       /*
    467        * check groupSetOrderedTagList values
    468        */
    469       if($_REQUEST['ajaxfct']=="groupSetOrderedTagList" and !isset($_REQUEST['id']))
    470       {
    471         $_REQUEST['id']="";
    472       }
    473 
    474       if($_REQUEST['ajaxfct']=="groupSetOrderedTagList" and !isset($_REQUEST['listTag']))
    475       {
    476         $_REQUEST['listTag']="";
    477       }
    478 
    479     }
     171    /*
     172     * metadata tabsheet
     173     */
     174    if($_REQUEST['fAMD_tabsheet']=="metadata")
     175    {
     176      if(!isset($_REQUEST['fAMD_page'])) $_REQUEST['fAMD_page']="select";
     177
     178      if(!($_REQUEST['fAMD_page']=="personnal" or
     179           $_REQUEST['fAMD_page']=="select" or
     180           $_REQUEST['fAMD_page']=="display")) $_REQUEST['fAMD_page']="select";
     181    }
     182
     183    /*
     184     * help tabsheet
     185     */
     186    if($_REQUEST['fAMD_tabsheet']=="help")
     187    {
     188      if(!isset($_REQUEST['fAMD_page'])) $_REQUEST['fAMD_page']="exif";
     189
     190      if(!($_REQUEST['fAMD_page']=="exif" or
     191           $_REQUEST['fAMD_page']=="iptc" or
     192           $_REQUEST['fAMD_page']=="xmp" or
     193           $_REQUEST['fAMD_page']=="magic")) $_REQUEST['fAMD_page']="exif";
     194    }
     195
     196    /*
     197     * search tabsheet
     198     */
     199    if($_REQUEST['fAMD_tabsheet']=="search")
     200    {
     201      if(!isset($_REQUEST['fAMD_page'])) $_REQUEST['fAMD_page']="search";
     202
     203      if(!($_REQUEST['fAMD_page']=="config" or
     204           $_REQUEST['fAMD_page']=="search")) $_REQUEST['fAMD_page']="search";
     205    }
     206
     207    /*
     208     * database tabsheet
     209     */
     210    if($_REQUEST['fAMD_tabsheet']=="database")
     211    {
     212      if(!isset($_REQUEST['fAMD_page'])) $_REQUEST['fAMD_page']="state";
     213
     214      if(!($_REQUEST['fAMD_page']=="state" or
     215           $_REQUEST['fAMD_page']=="update")) $_REQUEST['fAMD_page']="state";
     216    }
     217
    480218  } //init_request
    481219
     
    501239   * display and manage the metadata page
    502240   * the page have three tabsheet :
     241   *  - personnal tag management, to build personnal tags
    503242   *  - select tag management, to manage tags to be selected on the galerie
    504243   *  - display tag management, to choose how the tags are displayed
    505    *  - manage database
    506244   *
    507245   * @param String $tab : the selected tab on the stat page
     
    514252    $statTabsheet = new GPCTabSheet('statTabsheet', $this->tabsheet->get_titlename(), 'tabsheet2 gcBorder', 'itab2');
    515253    $statTabsheet->select($tab);
    516     $statTabsheet->add('database',
    517                           l10n('g003_database'),
    518                           $this->getAdminLink().'&amp;fAMD_tabsheet=metadata&amp;fAMD_page=database');
     254    $statTabsheet->add('personnal',
     255                          l10n('g003_personnal'),
     256                          $this->getAdminLink().'&amp;fAMD_tabsheet=metadata&amp;fAMD_page=personnal');
    519257    $statTabsheet->add('select',
    520258                          l10n('g003_select'),
     
    525263    $statTabsheet->assign();
    526264
    527 
    528 
    529     if($tab=="select")
    530     {
    531       $template->assign('sheetContent', $this->displayMetaDataSelect());
    532     }
    533     elseif($tab=="display")
    534     {
    535       $template->assign('sheetContent', $this->displayMetaDataDisplay());
    536     }
    537     else
    538     {
    539       $template->assign('sheetContent', $this->displayMetaDataDatabase());
     265    switch($tab)
     266    {
     267      case 'select':
     268        $template->assign('sheetContent', $this->displayMetaDataSelect());
     269        break;
     270      case 'display':
     271        $template->assign('sheetContent', $this->displayMetaDataDisplay());
     272        break;
     273      case 'personnal':
     274        $template->assign('sheetContent', $this->displayMetaDataPersonnal());
     275        break;
    540276    }
    541277
     
    543279  }
    544280
     281
     282  /**
     283   * display and manage the metadata page allowing to build user defined tags
     284   *
     285   * @return String : the content of the page
     286   */
     287  protected function displayMetaDataPersonnal()
     288  {
     289    global $template, $theme, $themes, $themeconf;
     290
     291    $template->set_filename('sheet_page',
     292                  dirname($this->getFileLocation()).'/admin/amd_metadata_personnal.tpl');
     293
     294    $datas=array(
     295      'urlRequest' => $this->getAdminLink('ajax'),
     296      'tagList' => array(),
     297    );
     298
     299    /*
     300     * build tagList
     301     */
     302    $sql="SELECT ut.name, ut.numId, ut.tagId
     303          FROM ".$this->tables['used_tags']." ut
     304            JOIN ".$this->tables['selected_tags']." st ON st.tagId = ut.tagId
     305          ORDER BY tagId";
     306    $result=pwg_query($sql);
     307    if($result)
     308    {
     309      while($row=pwg_db_fetch_assoc($result))
     310      {
     311        $datas['tagList'][]=Array(
     312          'tagId' => $row['tagId'],
     313          'name'  => L10n::get($row['name']),
     314          'numId' => $row['numId']
     315        );
     316      }
     317    }
     318
     319    $template->assign('datas', $datas);
     320    return($template->parse('sheet_page', true));
     321  }
     322
     323
    545324  /**
    546325   * display and manage the metadata page allowing to make tags selection
     
    551330  {
    552331    global $template, $theme, $themes, $themeconf;
    553     /*echo "A".print_r($theme, true)."<br>";
    554     echo "B".print_r($themes, true)."<br>";
    555     echo "C".print_r($themeconf, true)."<br>";
    556     echo "D".print_r($template->smarty->[], true)."<br>";*/
    557332
    558333    $template->set_filename('sheet_page',
     
    560335
    561336    $datas=array(
    562       'urlRequest' => $this->getAdminLink(),
     337      'urlRequest' => $this->getAdminLink('ajax'),
    563338      'config_GetListTags_OrderType' => $this->config['amd_GetListTags_OrderType'],
    564339      'config_GetListTags_FilterType' => $this->config['amd_GetListTags_FilterType'],
     
    568343    );
    569344
    570 
    571345    $template->assign('datas', $datas);
    572 
    573346    return($template->parse('sheet_page', true));
    574347  }
     
    588361                  dirname($this->getFileLocation()).'/admin/amd_metadata_display.tpl');
    589362
    590 
    591363    $datas=array(
    592       'urlRequest' => $this->getAdminLink(),
     364      'urlRequest' => $this->getAdminLink('ajax'),
    593365      'selectedTags' => Array(),
    594366      'groups' => Array(),
     
    650422  /**
    651423   * display and manage the database page
     424   * the page have two tabsheet :
     425   *  - state, to have general information about the database
     426   *  - update, to manage database fill-in
     427   *
     428   * @param String $tab : the selected tab on the stat page
     429   */
     430  protected function displayDatabase($tab)
     431  {
     432    global $template, $user;
     433    $template->set_filename('body_page', dirname(__FILE__).'/admin/amd_metadata.tpl');
     434
     435    $statTabsheet = new GPCTabSheet('statTabsheet', $this->tabsheet->get_titlename(), 'tabsheet2 gcBorder', 'itab2');
     436    $statTabsheet->select($tab);
     437    $statTabsheet->add('state',
     438                          l10n('g003_state'),
     439                          $this->getAdminLink().'&amp;fAMD_tabsheet=database&amp;fAMD_page=state');
     440    $statTabsheet->add('update',
     441                          l10n('g003_update'),
     442                          $this->getAdminLink().'&amp;fAMD_tabsheet=database&amp;fAMD_page=update');
     443    $statTabsheet->assign();
     444
     445    switch($tab)
     446    {
     447      case 'state':
     448        break;
     449      case 'update':
     450        $template->assign('sheetContent', $this->displayDatabaseDatabase());
     451        break;
     452    }
     453
     454    $template->assign_var_from_handle('AMD_BODY_PAGE', 'body_page');
     455  }
     456
     457
     458  /**
     459   * display and manage the database page
    652460   *
    653461   * the function automatically update the AMD tables :
     
    658466   * @return String : the content of the page
    659467   */
    660   private function displayMetaDataDatabase()
     468  private function displayDatabaseDatabase()
    661469  {
    662470    global $template, $page;
     
    693501
    694502    $datas=array(
    695       'urlRequest' => $this->getAdminLink(),
     503      'urlRequest' => $this->getAdminLink('ajax'),
    696504      'NumberOfItemsPerRequest' => $this->config['amd_NumberOfItemsPerRequest'],
    697505    );
     
    747555  }
    748556
    749 
    750   /*
    751    * ---------------------------------------------------------------------------
    752    * ajax functions
    753    * ---------------------------------------------------------------------------
    754    */
    755 
    756   /**
    757    * return a list of picture Id
    758    *
    759    * picture id are separated with a space " "
    760    * picture id are grouped in blocks of 'amd_NumberOfItemsPerRequest' items and
    761    * are separated with a semi-colon ";"
    762    *
    763    * client side just have to split blocks, and transmit it to the server
    764    *
    765    * There is two mode to determine the pictures being analyzed :
    766    *  - "all"         : analyze all the images
    767    *  - "notAnalyzed" : analyze only the images not yet analyzed
    768    *
    769    * @param String $mode
    770    * @param Integer $nbOfItems : number of items per request
    771    * @return String : list of image id to be analyzed, separated with a space
    772    *                      "23 78 4523 5670"
    773    */
    774   private function ajax_amd_makeStatsGetList($mode, $nbOfItems)
    775   {
    776     global $user;
    777 
    778     $returned="";
    779     $this->config['amd_NumberOfItemsPerRequest']=$nbOfItems;
    780     $this->saveConfig();
    781 
    782     $sql="SELECT ait.imageId FROM ".$this->tables['images']." ait";
    783     if($mode=="notAnalyzed")
    784     {
    785       $sql.=" WHERE ait.analyzed='n'";
    786     }
    787     elseif($mode=="caddieAdd" or $mode=="caddieReplace")
    788     {
    789 
    790       $sql.=" LEFT JOIN ".CADDIE_TABLE." ct ON ait.imageId = ct.element_id
    791             WHERE ct.user_id = ".$user['id']." ";
    792 
    793       if($mode=="caddieAdd") $sql.=" AND ait.analyzed='n'";
    794     }
    795 
    796     if($mode=="all" or $mode=="caddieReplace")
    797     {
    798       pwg_query("UPDATE ".$this->tables['images']." SET analyzed='n', nbTags=0");
    799       pwg_query("UPDATE ".$this->tables['used_tags']." SET numOfImg=0");
    800       pwg_query("DELETE FROM ".$this->tables['images_tags']);
    801     }
    802 
    803     $result=pwg_query($sql);
    804     if($result)
    805     {
    806       $i=0;
    807       while($row=pwg_db_fetch_row($result))
    808       {
    809         $returned.=$row[0];
    810         $i++;
    811         if($i>=$nbOfItems)
    812         {
    813           $returned.=";";
    814           $i=0;
    815         }
    816         else
    817         {
    818           $returned.=" ";
    819         }
    820       }
    821     }
    822     return(trim($returned).";");
    823   }
    824 
    825 
    826   /**
    827    * extract metadata from images
    828    *
    829    * @param String $imageList : list of image id to be analyzed, separated with
    830    *                            a space
    831    *                                "23 78 4523 5670"
    832    * @return String : list of the analyzed pictures, with number of tags found
    833    *                  for each picture
    834    *                    "23=0;78=66;4523=33;5670=91;"
    835    */
    836   private function ajax_amd_makeStatsDoAnalyze($imagesList)
    837   {
    838     $list=explode(" ", trim($imagesList));
    839 
    840     $returned="";
    841 
    842     if(count($list)>0 and trim($imagesList)!='')
    843     {
    844       // $path = path of piwigo's on the server filesystem
    845       $path=dirname(dirname(dirname(__FILE__)));
    846 
    847       $sql="SELECT id, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(", ", $list).")";
    848       $result=pwg_query($sql);
    849       if($result)
    850       {
    851         while($row=pwg_db_fetch_assoc($result))
    852         {
    853           /*
    854            * in some case (in a combination of some pictures), when there is too
    855            * much pictures to analyze in the same request, a fatal error occurs
    856            * with the message : "Allowed memory size of XXXXX bytes exhausted"
    857            *
    858            *
    859            * tracking memory leak is not easy... :-(
    860            *
    861            */
    862           //echo "analyzing:".$row['id']."\n";
    863           //$mem1=memory_get_usage();
    864           //echo "memory before analyze:".$mem1."\n";
    865           $returned.=$this->analyzeImageFile($path."/".$row['path'], $row['id']);
    866           //echo $returned."\n";
    867           //$mem2=memory_get_usage();
    868           //echo "memory after analyze:".$mem2." (".($mem2-$mem1).")\n";
    869         }
    870       }
    871     }
    872     return($returned);
    873   }
    874 
    875   /**
    876    * do some consolidation on database to optimize other requests
    877    *
    878    */
    879   private function ajax_amd_makeStatsConsolidation()
    880   {
    881     $this->makeStatsConsolidation();
    882   }
    883 
    884   /**
    885    * returns a list of formated string, separated with a semi-colon :
    886    *  - number of current analyzed pictures + number of current analyzed tags
    887    *    for the analyzed pictures
    888    *  - number of pictures not analyzed
    889    *  - number of pictures without tag
    890    *
    891    * @return String
    892    */
    893   private function ajax_amd_makeStatsGetStatus()
    894   {
    895     $numOfMetaData=0;
    896     $numOfPictures=0;
    897     $numOfPicturesNotAnalyzed=0;
    898 
    899     $sql="SELECT COUNT(imageId), SUM(nbTags) FROM ".$this->tables['images']."
    900             WHERE analyzed='y';";
    901     $result=pwg_query($sql);
    902     if($result)
    903     {
    904       while($row=pwg_db_fetch_row($result))
    905       {
    906         $numOfPictures=$row[0];
    907         $numOfMetaData=$row[1];
    908       }
    909     }
    910 
    911 
    912     $sql="SELECT COUNT(imageId) FROM ".$this->tables['images']."
    913             WHERE analyzed='n';";
    914     $result=pwg_query($sql);
    915     if($result)
    916     {
    917       while($row=pwg_db_fetch_row($result))
    918       {
    919         $numOfPicturesNotAnalyzed=$row[0];
    920       }
    921     }
    922 
    923     $sql="SELECT COUNT(imageId) FROM ".$this->tables['images']."
    924             WHERE nbTags=0;";
    925     $result=pwg_query($sql);
    926     if($result)
    927     {
    928       while($row=pwg_db_fetch_row($result))
    929       {
    930         $numOfPicturesWithoutTags=$row[0];
    931       }
    932     }
    933 
    934     return(sprintf(l10n("g003_numberOfAnalyzedPictures"), $numOfPictures, $numOfMetaData).";".
    935               sprintf(l10n("g003_numberOfNotAnalyzedPictures"), $numOfPicturesNotAnalyzed).";".
    936               sprintf(l10n("g003_numberOfPicturesWithoutTags"), $numOfPicturesWithoutTags));
    937   }
    938 
    939 
    940   /**
    941    * return a formatted <table> (using the template "amd_stat_show_iListTags")
    942    * of used tag with, for each tag, the number and the percentage of pictures
    943    * where the tag was found
    944    *
    945    * @param String $orderType : order for the list (by tag 'tag' or by number of
    946    *                            pictures 'num')
    947    * @param String $filterType : filter for the list ('exif', 'xmp', 'iptc' or '')
    948    * @return String
    949    */
    950   private function ajax_amd_showStatsGetListTags($orderType, $filterType, $excludeUnusedTag, $selectedTagOnly)
    951   {
    952     global $template;
    953 
    954     $this->config['amd_GetListTags_OrderType'] = $orderType;
    955     $this->config['amd_GetListTags_FilterType'] = $filterType;
    956     $this->config['amd_GetListTags_ExcludeUnusedTag'] = $excludeUnusedTag;
    957     $this->config['amd_GetListTags_SelectedTagOnly'] = $selectedTagOnly;
    958     $this->saveConfig();
    959 
    960     $local_tpl = new Template(AMD_PATH."admin/", "");
    961     $local_tpl->set_filename('body_page',
    962                   dirname($this->getFileLocation()).'/admin/amd_metadata_select_iListTags.tpl');
    963 
    964     $numOfPictures=$this->getNumOfPictures();
    965 
    966     $datas=array();
    967     $sql="SELECT ut.numId, ut.tagId, ut.translatable, ut.name, ut.numOfImg, if(st.tagId IS NULL, 'n', 'y') as checked, ut.translatedName
    968             FROM ".$this->tables['used_tags']." ut
    969               LEFT JOIN ".$this->tables['selected_tags']." st
    970                 ON st.tagId = ut.tagId ";
    971     $where="";
    972 
    973     if($filterType!='')
    974     {
    975       if($filterType=='exif')
    976       {
    977         $where.=" WHERE ut.tagId LIKE 'exif.tiff.%'
    978                     OR ut.tagId LIKE 'exif.exif.%'
    979                     OR ut.tagId LIKE 'exif.gps.%'  ";
    980       }
    981       else
    982       {
    983         $where.=" WHERE ut.tagId LIKE '".$filterType.".%' ";
    984       }
    985     }
    986 
    987     if($excludeUnusedTag=='y')
    988     {
    989       ($where=="")?$where=" WHERE ":$where.=" AND ";
    990       $where.=" ut.numOfImg > 0 ";
    991     }
    992 
    993     if($selectedTagOnly=='y')
    994     {
    995       ($where=="")?$where=" WHERE ":$where.=" AND ";
    996       $where.=" st.tagId IS NOT NULL ";
    997     }
    998 
    999     $sql.=$where;
    1000 
    1001     switch($orderType)
    1002     {
    1003       case 'tag':
    1004         $sql.=" ORDER BY tagId ASC";
    1005         break;
    1006       case 'num':
    1007         $sql.=" ORDER BY numOfImg DESC, tagId ASC";
    1008         break;
    1009       case 'label':
    1010         $sql.=" ORDER BY translatedName ASC, tagId ASC";
    1011         break;
    1012     }
    1013 
    1014     $result=pwg_query($sql);
    1015     if($result)
    1016     {
    1017       while($row=pwg_db_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):"0",
    1025           "tagChecked" => ($row['checked']=='y')?"checked":""
    1026         );
    1027       }
    1028     }
    1029 
    1030     $local_tpl->assign('themeconf', Array('name' => $template->get_themeconf('name')));
    1031     $local_tpl->assign('datas', $datas);
    1032 
    1033     return($local_tpl->parse('body_page', true));
    1034   }
    1035 
    1036 
    1037   /*
    1038    *
    1039    *
    1040    */
    1041   private function ajax_amd_showStatsGetListImages($tagId, $orderType)
    1042   {
    1043     global $template;
    1044 
    1045     $this->config['amd_GetListImages_OrderType'] = $orderType;
    1046     $this->saveConfig();
    1047 
    1048     $local_tpl = new Template(AMD_PATH."admin/", "");
    1049     $local_tpl->set_filename('body_page',
    1050                   dirname($this->getFileLocation()).'/admin/amd_metadata_select_iListImages.tpl');
    1051 
    1052 
    1053 
    1054     $datas=array();
    1055     $sql="SELECT ut.translatable, ut.numOfImg, COUNT(it.imageId) AS Nb, it.value
    1056             FROM ".$this->tables['used_tags']." ut
    1057               LEFT JOIN ".$this->tables['images_tags']." it
    1058               ON ut.numId = it.numId
    1059             WHERE ut.tagId = '".$tagId."'
    1060               AND it.value IS NOT NULL
    1061             GROUP BY it.value
    1062             ORDER BY ";
    1063     switch($orderType)
    1064     {
    1065       case 'value':
    1066         $sql.="it.value ASC";
    1067         break;
    1068       case 'num':
    1069         $sql.="Nb DESC";
    1070         break;
    1071     }
    1072 
    1073     $result=pwg_query($sql);
    1074     if($result)
    1075     {
    1076       while($row=pwg_db_fetch_assoc($result))
    1077       {
    1078         $datas[]=array(
    1079           "value" => $this->prepareValueForDisplay($row['value'], ($row['translatable']=='y'), ", "),
    1080           "nb"    => $row['Nb'],
    1081           "pct"   => ($row['numOfImg']!=0)?sprintf("%.2f", 100*$row['Nb']/$row['numOfImg']):"-"
    1082         );
    1083       }
    1084     }
    1085 
    1086     if(count($datas)>0)
    1087     {
    1088       $local_tpl->assign('themeconf', Array('name' => $template->get_themeconf('name')));
    1089       $local_tpl->assign('datas', $datas);
    1090       return($local_tpl->parse('body_page', true));
    1091     }
    1092     else
    1093     {
    1094       return("<div style='width:100%;text-align:center;padding-top:20px;'>".l10n('g003_selected_tag_isnot_linked_with_any_picture')."</div>");
    1095     }
    1096   }
    1097 
    1098 
    1099   /*
    1100    *
    1101    *
    1102    */
    1103   private function ajax_amd_updateTagSelect($numId, $selected)
    1104   {
    1105     if($selected=='y')
    1106     {
    1107       $sql="SELECT ut.tagId FROM ".$this->tables['selected_tags']." st
    1108               LEFT JOIN ".$this->tables['used_tags']." ut
    1109                 ON ut.tagID = st.tagId
    1110               WHERE ut.numId = $numId;";
    1111       $result=pwg_query($sql);
    1112       if($result)
    1113       {
    1114         if(pwg_db_num_rows($result)==0)
    1115         {
    1116           $sql="INSERT INTO ".$this->tables['selected_tags']."
    1117                   SELECT ut.tagId, 0, -1
    1118                   FROM ".$this->tables['used_tags']." ut
    1119                     LEFT JOIN ".$this->tables['selected_tags']." st
    1120                       ON ut.tagID = st.tagId
    1121                   WHERE ut.numId = $numId;";
    1122           pwg_query($sql);
    1123         }
    1124       }
    1125     }
    1126     elseif($selected=='n')
    1127     {
    1128       $sql="DELETE FROM ".$this->tables['selected_tags']." st
    1129               USING ".$this->tables['used_tags']." ut
    1130                 LEFT JOIN ".$this->tables['selected_tags']." st
    1131                   ON ut.tagID = st.tagId
    1132               WHERE ut.numId = $numId;";
    1133       pwg_query($sql);
    1134     }
    1135 
    1136   }
    1137 
    1138 
    1139   /**
    1140    * this function return the list of tags :
    1141    *  - associated with the group
    1142    *  - not associated with a group
    1143    * the list is used to make tags selection
    1144    *
    1145    * @param String $id      : Id of the current group
    1146    * @return String : an HTML formatted list with checkbox
    1147    */
    1148   private function ajax_amd_groupGetTagList($id)
    1149   {
    1150     global $template;
    1151 
    1152     if($id!="")
    1153     {
    1154       $sql="SELECT st.tagId, st.groupId, ut.name, ut.numId
    1155             FROM ".$this->tables['selected_tags']." st
    1156               LEFT JOIN ".$this->tables['used_tags']." ut
    1157                 ON st.tagId = ut.tagId
    1158             ORDER BY tagId";
    1159       $result=pwg_query($sql);
    1160       if($result)
    1161       {
    1162         $datas=Array();
    1163         while($row=pwg_db_fetch_assoc($result))
    1164         {
    1165           if($row['groupId']==$id)
    1166           {
    1167             $state="checked";
    1168           }
    1169           elseif($row['groupId']==-1)
    1170           {
    1171             $state="";
    1172           }
    1173           else
    1174           {
    1175             $state="n/a";
    1176           }
    1177 
    1178           if($state!="n/a")
    1179             $datas[]=Array(
    1180               'tagId' => $row['tagId'],
    1181               'name'  => L10n::get($row['name']),
    1182               'state' => $state,
    1183               'numId' => $row['numId']
    1184             );
    1185         }
    1186 
    1187         if(count($datas)>0)
    1188         {
    1189           $local_tpl = new Template(AMD_PATH."admin/", "");
    1190           $local_tpl->set_filename('body_page',
    1191                         dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupListTagSelect.tpl');
    1192           $local_tpl->assign('themeconf', Array('name' => $template->get_themeconf('name')));
    1193           $local_tpl->assign('datas', $datas);
    1194           return($local_tpl->parse('body_page', true));
    1195         }
    1196         else
    1197         {
    1198           return(l10n("g003_no_tag_can_be_selected"));
    1199         }
    1200       }
    1201     }
    1202     else
    1203     {
    1204       return(l10n("g003_invalid_group_id"));
    1205     }
    1206   }
    1207 
    1208 
    1209   /**
    1210    * this function associate tags to a group
    1211    *
    1212    * @param String $id      : Id of group
    1213    * @param String $listTag : list of selected tags, items are separated by a
    1214    *                          semi-colon ";" char
    1215    */
    1216   private function ajax_amd_groupSetTagList($id, $listTag)
    1217   {
    1218     if($id!="")
    1219     {
    1220       $sql="UPDATE ".$this->tables['selected_tags']."
    1221             SET groupId = -1
    1222             WHERE groupId = $id;";
    1223       pwg_query($sql);
    1224 
    1225       if($listTag!="")
    1226       {
    1227         $sql="UPDATE ".$this->tables['selected_tags']." st, ".$this->tables['used_tags']." ut
    1228               SET st.groupId = $id
    1229               WHERE st.tagId = ut.tagId
    1230                 AND ut.numId IN ($listTag);";
    1231         pwg_query($sql);
    1232       }
    1233     }
    1234     else
    1235     {
    1236       return("KO");
    1237     }
    1238   }
    1239 
    1240 
    1241   /**
    1242    * this function returns an ordered list of tags associated with a group
    1243    *
    1244    * @param String $id        : the group Id
    1245    * @return String : an HTML formatted list
    1246    */
    1247   private function ajax_amd_groupGetOrderedTagList($id)
    1248   {
    1249     global $template;
    1250     if($id!="")
    1251     {
    1252       $numOfPictures=$this->getNumOfPictures();
    1253 
    1254       $sql="SELECT st.tagId, ut.name, ut.numId, ut.numOfImg
    1255             FROM ".$this->tables['selected_tags']." st
    1256               LEFT JOIN ".$this->tables['used_tags']." ut
    1257                 ON st.tagId = ut.tagId
    1258             WHERE st.groupId = $id
    1259             ORDER BY st.order ASC, st.tagId ASC";
    1260       $result=pwg_query($sql);
    1261       if($result)
    1262       {
    1263         $datas=Array();
    1264         while($row=pwg_db_fetch_assoc($result))
    1265         {
    1266           $datas[]=Array(
    1267             'tagId' => $row['tagId'],
    1268             'name'  => L10n::get($row['name']),
    1269             'numId' => $row['numId'],
    1270             'nbItems' => $row['numOfImg'],
    1271             'pct'   => ($numOfPictures==0)?"0":sprintf("%.2f", 100*$row['numOfImg']/$numOfPictures)
    1272           );
    1273         }
    1274 
    1275         if(count($datas)>0)
    1276         {
    1277           $template->set_filename('list_page',
    1278                         dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupListTagOrder.tpl');
    1279           $template->assign('datas', $datas);
    1280           $template->assign('group', $id);
    1281           return($template->parse('list_page', true));
    1282         }
    1283         else
    1284         {
    1285           return(l10n("g003_no_tag_can_be_selected"));
    1286         }
    1287       }
    1288     }
    1289     else
    1290     {
    1291       return(l10n("g003_invalid_group_id"));
    1292     }
    1293   }
    1294 
    1295 
    1296   /**
    1297    * this function update the tags order inside a group
    1298    *
    1299    * @param String $id        : the group Id
    1300    * @param String $listGroup : the ordered list of tags, items are separated
    1301    *                            by a semi-colon ";" char
    1302    */
    1303   private function ajax_amd_groupSetOrderedTagList($id, $listTag)
    1304   {
    1305     $tags=explode(';', $listTag);
    1306     if($id!="" and count($tags)>0)
    1307     {
    1308       /*
    1309        * by default, all items are set with order equals -1 (if list is not
    1310        * complete, forgotten items are sorted in head)
    1311        */
    1312       pwg_query("UPDATE ".$this->tables['selected_tags']." st
    1313                   SET st.order = -1
    1314                   WHERE st.groupId = $id;");
    1315 
    1316       foreach($tags as $key=>$val)
    1317       {
    1318         $sql="UPDATE ".$this->tables['selected_tags']." st, ".$this->tables['used_tags']." ut
    1319               SET st.order = $key
    1320               WHERE st.groupId = $id
    1321                 AND st.tagId = ut.tagId
    1322                 AND ut.numId = $val;";
    1323         $result=pwg_query($sql);
    1324       }
    1325     }
    1326   }
    1327 
    1328 
    1329 
    1330   /**
    1331    * this function update the groups order
    1332    *
    1333    * @param String $listGroup : the ordered list of groups, items are separated
    1334    *                            by a semi-colon ";" char
    1335    */
    1336   private function ajax_amd_groupSetOrder($listGroup)
    1337   {
    1338     $groups=explode(";",$listGroup);
    1339     if(count($groups)>0)
    1340     {
    1341       /*
    1342        * by default, all items are set with order equals -1 (if list is not
    1343        * complete, forgotten items are sorted in head)
    1344        */
    1345       pwg_query("UPDATE ".$this->tables['groups']." g SET g.order = -1;");
    1346 
    1347       foreach($groups as $key=>$val)
    1348       {
    1349         $sql="UPDATE ".$this->tables['groups']." g
    1350               SET g.order = $key
    1351               WHERE g.groupId = $val;";
    1352         $result=pwg_query($sql);
    1353       }
    1354     }
    1355   }
    1356 
    1357   /**
    1358    * this function is used to create a new group ($groupId = "") or update the
    1359    * group name (names are given in all langs in a list)
    1360    *
    1361    * @param String $groupId : the groupId to update, or "" to create a new groupId
    1362    * @param String $listNames : name of the group, in all language given as a
    1363    *                            list ; each lang is separated by a carraige
    1364    *                            return "\n" char, each items is defined as
    1365    *                            lang=value
    1366    *                              en_UK=the name group
    1367    *                              fr_FR=le nom du groupe
    1368    */
    1369   private function ajax_amd_groupSetNames($groupId, $listNames)
    1370   {
    1371     $names=explode("\n", $listNames);
    1372     if($groupId=="" and count($names)>0)
    1373     {
    1374       $sql="INSERT INTO ".$this->tables['groups']." VALUES('', 9999)";
    1375       $result=pwg_query($sql);
    1376       $groupId=pwg_db_insert_id();
    1377     }
    1378 
    1379     if(is_numeric($groupId) and count($names)>0)
    1380     {
    1381       $sql="DELETE FROM ".$this->tables['groups_names']."
    1382             WHERE groupId = $groupId;";
    1383       pwg_query($sql);
    1384 
    1385 
    1386       $sql="";
    1387       foreach($names as $val)
    1388       {
    1389         $tmp=explode("=", $val);
    1390         if($sql!="") $sql.=", ";
    1391         $sql.=" ($groupId, '".$tmp[0]."', '".$tmp[1]."')";
    1392       }
    1393       $sql="INSERT INTO ".$this->tables['groups_names']." VALUES ".$sql;
    1394       pwg_query($sql);
    1395     }
    1396   }
    1397 
    1398   /**
    1399    * this function returns an html form, allowing to manage the group
    1400    *
    1401    * @param String $groupId : the groupId to manage, or "" to return a creation
    1402    *                          form
    1403    * @return String : the form
    1404    */
    1405   private function ajax_amd_groupGetNames($groupId)
    1406   {
    1407     global $user;
    1408 
    1409     $local_tpl = new Template(AMD_PATH."admin/", "");
    1410     $local_tpl->set_filename('body_page',
    1411                   dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupEdit.tpl');
    1412 
    1413     $datasLang=array(
    1414       'language_list' => Array(),
    1415       'lang_selected' => $user['language'],
    1416       'fromlang' => substr($user['language'],0,2),
    1417       'default' => ''
    1418     );
    1419 
    1420     $langs=get_languages();
    1421     foreach($langs as $key => $val)
    1422     {
    1423       $datasLang['language_list'][$key] = Array(
    1424         'langName' => str_replace("\n", "", $val),
    1425         'name' => ""
    1426       );
    1427     }
    1428 
    1429     if($groupId!="")
    1430     {
    1431       $sql="SELECT lang, name FROM ".$this->tables['groups_names']."
    1432             WHERE groupId = $groupId;";
    1433       $result=pwg_query($sql);
    1434       if($result)
    1435       {
    1436         while($row=pwg_db_fetch_assoc($result))
    1437         {
    1438           if(array_key_exists($row['lang'], $datasLang['language_list']))
    1439           {
    1440             $datasLang['language_list'][$row['lang']]['name']=htmlentities($row['name'], ENT_QUOTES, 'UTF-8');
    1441             if($user['language']==$row['lang'])
    1442             {
    1443               $datasLang['default']=$datasLang['language_list'][$row['lang']]['name'];
    1444             }
    1445           }
    1446         }
    1447       }
    1448     }
    1449 
    1450     $local_tpl->assign('datasLang', $datasLang);
    1451 
    1452     return($local_tpl->parse('body_page', true));
    1453   }
    1454 
    1455 
    1456   /**
    1457    * this function returns an html form, allowing to manage the group
    1458    *
    1459    * @param String $groupId : the groupId to manage, or "" to return a creation
    1460    *                          form
    1461    * @return String : the form
    1462    */
    1463   private function ajax_amd_groupGetList()
    1464   {
    1465     global $user, $template;
    1466 
    1467     //$local_tpl = new Template(AMD_PATH."admin/", "");
    1468     $template->set_filename('group_list',
    1469                   dirname($this->getFileLocation()).'/admin/amd_metadata_display_groupList.tpl');
    1470 
    1471 
    1472     $datas=array(
    1473       'groups' => Array(),
    1474     );
    1475 
    1476     $sql="SELECT g.groupId, gn.name
    1477           FROM ".$this->tables['groups']." g
    1478             LEFT JOIN ".$this->tables['groups_names']." gn
    1479               ON g.groupId = gn.groupId
    1480           WHERE gn.lang = '".$user['language']."'
    1481           ORDER BY g.order;";
    1482     $result=pwg_query($sql);
    1483     if($result)
    1484     {
    1485       while($row=pwg_db_fetch_assoc($result))
    1486       {
    1487         $datas['groups'][]=Array(
    1488           'id' => $row['groupId'],
    1489           'name' => htmlentities($row['name'], ENT_QUOTES, "UTF-8")
    1490         );
    1491       }
    1492     }
    1493 
    1494     $template->assign('datas', $datas);
    1495     return($template->parse('group_list', true));
    1496   }
    1497 
    1498 
    1499   /**
    1500    * delete the group
    1501    * associated tag returns in the available tag list
    1502    *
    1503    * @param String $groupId : the groupId to delete
    1504    */
    1505   private function ajax_amd_groupDelete($groupId)
    1506   {
    1507     if($groupId!="")
    1508     {
    1509       $sql="DELETE FROM ".$this->tables['groups']."
    1510             WHERE groupId = $groupId;";
    1511       pwg_query($sql);
    1512 
    1513       $sql="DELETE FROM ".$this->tables['groups_names']."
    1514             WHERE groupId = $groupId;";
    1515       pwg_query($sql);
    1516 
    1517       $sql="UPDATE ".$this->tables['selected_tags']."
    1518             SET groupId = -1
    1519             WHERE groupId = $groupId;";
    1520       pwg_query($sql);
    1521     }
    1522   }
    1523 
    1524557} // AMD_AIP class
    1525558
  • extensions/AMetaData/amd_install.class.inc.php

    r5959 r6722  
    9191  `order` INTEGER UNSIGNED NOT NULL DEFAULT 0,
    9292  PRIMARY KEY (`groupId`)
    93 );"
    94 );
    95       //$table_def array
     93);",
     94"CREATE TABLE `".$this->tables['user_tags_label']."` (
     95  `numId` INTEGER UNSIGNED NOT NULL,
     96  `lang` CHAR(5)  NOT NULL,
     97  `label` VARCHAR(200)  NOT NULL,
     98  PRIMARY KEY (`numId`, `lang`)
     99);",
     100"CREATE TABLE `".$this->tables['user_tags_def']."` (
     101  `defId` int(10) unsigned NOT NULL auto_increment,
     102  `parentId` int(10) unsigned NOT NULL default '0' COMMENT 'Id of the parent',
     103  `numId` int(10) unsigned NOT NULL COMMENT 'Id of the tag',
     104  `order` int(10) unsigned NOT NULL COMMENT 'Order, relative to the parent',
     105  `type` char(1) NOT NULL default 'T' COMMENT 'T = static text ; M = metadata value ; C = condition',
     106  `value` varchar(200) NOT NULL,
     107  `conditionType` char(2) NOT NULL default 'E',
     108  `conditionValue` varchar(200) NOT NULL,
     109  PRIMARY KEY  (`defId`),
     110  KEY `byTagNumId` (`numId`,`parentId`,`order`),
     111  KEY `byTagParentId` (`parentId`,`order`)
     112);",
     113      );
     114
     115
    96116      $tables_def = create_table_add_character_set($tables_def);
    97117      $result=$this->tablef->create($tables_def);
     
    133153    {
    134154      global $template, $user;
     155
     156      $this->initConfig();
     157      $this->loadConfig();
     158
     159      /*
     160       * if there is no version information available, assume the previous
     161       *  installed release of the plugin is 0.4.0
     162       */
     163      if(!isset($this->config['installed'])) $this->config['installed']='00.04.00';
     164
     165      switch($this->config['installed'])
     166      {
     167        case '00.04.00':
     168          $this->updateFrom_000400();
     169          break;
     170        default:
     171          /*
     172           * default is applied for fresh install, and consist to fill the
     173           * database with default values
     174           */
     175          $this->initializeDatabase();
     176          break;
     177      }
     178
     179      $this->config['installed']=AMD_VERSION2; //update the installed release number
     180      $this->saveConfig();
     181    }
     182
     183
     184    public function deactivate()
     185    {
     186    }
     187
     188    /**
     189     * update the database from the release 0.4.0
     190     */
     191    private function updateFrom_000400()
     192    {
     193      /*
     194       * create new tables
     195       */
     196      $tableDef=array(
     197"CREATE TABLE `".$this->tables['user_tags_label']."` (
     198  `numId` INTEGER UNSIGNED NOT NULL,
     199  `lang` CHAR(5)  NOT NULL,
     200  `label` VARCHAR(200)  NOT NULL,
     201  PRIMARY KEY (`numId`, `lang`)
     202);",
     203"CREATE TABLE `".$this->tables['user_tags_def']."` (
     204  `defId` int(10) unsigned NOT NULL auto_increment,
     205  `parentId` int(10) unsigned NOT NULL default '0' COMMENT 'Id of the parent',
     206  `numId` int(10) unsigned NOT NULL COMMENT 'Id of the tag',
     207  `order` int(10) unsigned NOT NULL COMMENT 'Order, relative to the parent',
     208  `type` char(1) NOT NULL default 'T' COMMENT 'T = static text ; M = metadata value ; C = condition',
     209  `value` varchar(200) NOT NULL,
     210  `conditionType` char(2) NOT NULL default 'E',
     211  `conditionValue` varchar(200) NOT NULL,
     212  PRIMARY KEY  (`defId`),
     213  KEY `byTagNumId` (`numId`,`parentId`,`order`),
     214  KEY `byTagParentId` (`parentId`,`order`)
     215);"
     216      );
     217      $tablesDef = create_table_add_character_set($tablesDef);
     218      $result=$this->tablef->create($tablesDef);
     219      unset($tablesDef);
     220
     221      /*
     222       * update old tables
     223       */
     224
     225      // no tables to update
     226    }
     227
     228
     229
     230
     231    /**
     232     * fill the database with some default value
     233     */
     234    private function initializeDatabase()
     235    {
    135236      L10n::setLanguage('en_UK');
    136237
     
    212313        $this->makeStatsConsolidation();
    213314      }
    214 
    215       $this->initConfig();
    216       $this->loadConfig();
    217       $this->config['installed']=AMD_VERSION2; //update the installed release number
    218       $this->saveConfig();
    219     }
    220 
    221 
    222     public function deactivate()
    223     {
    224315    }
    225316
  • extensions/AMetaData/amd_pip.class.inc.php

    r5959 r6722  
    2222
    2323include_once('amd_root.class.inc.php');
    24 include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCAjax.class.inc.php');
    2524
    2625class AMD_PIP extends AMD_root
    2726{
     27  private $pictureProperties=array(
     28    'id' => 0,
     29    'analyzed' => 'n'
     30  );
    2831  function AMD_PIP($prefixeTable, $filelocation)
    2932  {
     
    4750    parent::initEvents();
    4851    add_event_handler('loc_begin_picture', array(&$this, 'loadMetadata'));
     52    add_event_handler('loc_end_page_tail', array(&$this, 'applyJS'));
    4953  }
    5054
     
    6165    $path=dirname(dirname(dirname(__FILE__)));
    6266    $filename="";
    63     $analyzed='n';
     67    $this->pictureProperties['id']=$page['image_id'];
    6468
    6569    $sql="SELECT ti.path, tai.analyzed FROM ".IMAGES_TABLE." ti
     
    7276      {
    7377        $filename=$row['path'];
    74         $analyzed=$row['analyzed'];
     78        $this->pictureProperties['analyzed']=$row['analyzed'];
    7579      }
    7680      $filename=$path."/".$filename;
     
    9296    $conf['show_iptc']=false;
    9397
     98    $picturesTags=$this->jpegMD->getTags();
    9499    $tagsList=Array();
    95     $sql="SELECT st.tagId, gn.name as gName
    96           FROM (".$this->tables['selected_tags']." st
     100    $userDefinedList=array(
     101      'list' => array(),
     102      'values' => array(),
     103    );
     104    $sql="SELECT st.tagId, gn.name as gName, ut.numId, ut.name
     105          FROM ((".$this->tables['selected_tags']." st
    97106            LEFT JOIN ".$this->tables['groups']." gr
    98107              ON gr.groupId = st.groupId)
    99108            LEFT JOIN ".$this->tables['groups_names']." gn
    100               ON st.groupId = gn.groupId
     109              ON st.groupId = gn.groupId)
     110            LEFT JOIN ".$this->tables['used_tags']." ut
     111              ON ut.tagId = st.tagId
    101112          WHERE gn.lang='".$user['language']."'
    102113            AND st.groupId <> -1
     
    107118      while($row=pwg_db_fetch_assoc($result))
    108119      {
    109         $tagsList[$row['tagId']]=$row['gName'];
     120        $tagsList[$row['tagId']]=$row;
     121        if(preg_match('/^userDefined\./i', $row['tagId']))
     122        {
     123          $userDefinedList['list'][]=$row['numId'];
     124        }
     125        else
     126        {
     127          if(array_key_exists($row['tagId'], $picturesTags))
     128          {
     129            $value=$picturesTags[$row['tagId']]->getLabel();
     130
     131            if($value instanceof DateTime)
     132            {
     133              $value=$value->format("Y-m-d H:i:s");
     134            }
     135            elseif(is_array($value))
     136            {
     137              /*
     138               * array values are stored in a serialized string
     139               */
     140              $value=serialize($value);
     141            }
     142            $userDefinedList['values'][$row['numId']]=$this->prepareValueForDisplay($value, $picturesTags[$row['tagId']]->isTranslatable());;
     143          }
     144        }
    110145      }
    111146    }
     
    115150    $group=null;
    116151
    117     $picturesTags=$this->jpegMD->getTags();
    118 
    119     foreach($tagsList as $key => $val)
    120     {
    121       if(array_key_exists($key, $picturesTags))
     152    $userDefinedValues=$this->pictureGetUserDefinedTags($userDefinedList['list'], $userDefinedList['values']);
     153
     154    foreach($tagsList as $key => $tagProperties)
     155    {
     156      $keyExist=array_key_exists($key, $picturesTags);
     157      $userDefined=preg_match('/^userDefined\./i', $key);
     158
     159      if(($group!=$tagProperties['gName']) and
     160         ( $keyExist or $userDefined) )
     161      {
     162        $group=$tagProperties['gName'];
     163        if(!is_null($md))
     164        {
     165          $metadata[]=$md;
     166          unset($md);
     167        }
     168        $md=Array(
     169          'TITLE' => $tagProperties['gName'],
     170          'lines' => Array()
     171        );
     172      }
     173
     174      if($keyExist)
    122175      {
    123176        $value=$picturesTags[$key]->getLabel();
     
    134187          $value=serialize($value);
    135188        }
    136 
    137         if($group!=$val)
    138         {
    139           $group=$val;
    140           if(!is_null($md))
    141           {
    142             $metadata[]=$md;
    143             unset($md);
    144           }
    145           $md=Array(
    146             'TITLE' => $val,
    147             'lines' => Array()
    148           );
    149         }
    150189        $md['lines'][L10n::get($picturesTags[$key]->getName())]=$this->prepareValueForDisplay($value, $picturesTags[$key]->isTranslatable());
    151190      }
     191      elseif($userDefined)
     192      {
     193        $md['lines'][$tagProperties['name']]=$userDefinedValues[$tagProperties['numId']];
     194      }
    152195    }
    153196
     
    157200    }
    158201
    159 
    160     if($analyzed=='n' and
    161        $this->config['amd_FillDataBaseContinuously']=='y' and
     202    $template->assign('metadata', $metadata);
     203  }
     204
     205  /**
     206   * used by the 'loc_end_page_tail' event
     207   *
     208   * on each public page viewed, add a script to do an ajax call to the "public.makeStats.doPictureAnalyze" function
     209   */
     210  public function applyJS()
     211  {
     212    global $template;
     213
     214    if($this->config['amd_FillDataBaseContinuously']=='y' and
    162215       $this->config['amd_AllPicturesAreAnalyzed']=='n')
    163216    {
    164       /* if picture is not analyzed, do analyze
    165        *
    166        * note : the $loaded parameter is set to true, in this case the function
    167        *        analyzeImageFile uses data from the $this->jpegMD object which
    168        *        have data already loaded => the picture is not analyzed twice,
    169        *        the function only do the database update
    170        */
    171       $this->analyzeImageFile($filename, $page['image_id'], true);
    172       $this->makeStatsConsolidation();
    173     }
    174 
    175     $template->assign('metadata', $metadata);
     217      $template->set_filename('applyJS',
     218                    dirname($this->getFileLocation()).'/templates/doAnalyze.tpl');
     219
     220      $datas=array(
     221        'urlRequest' => $this->getAdminLink('ajax'),
     222        'id' => ($this->pictureProperties['analyzed']=='n')?$this->pictureProperties['id']:'0'
     223      );
     224
     225      $template->assign('datas', $datas);
     226      $template->append('footer_elements', $template->parse('applyJS', true));
     227    }
    176228  }
    177229
  • extensions/AMetaData/amd_root.class.inc.php

    r5959 r6722  
    4040    parent::__construct($prefixeTable, $filelocation);
    4141
    42     $tableList=array('used_tags', 'images_tags', 'images', 'selected_tags', 'groups_names', 'groups');
     42    $tableList=array(
     43      'used_tags',
     44      'images_tags',
     45      'images',
     46      'selected_tags',
     47      'groups_names',
     48      'groups',
     49      'user_tags_label',
     50      'user_tags_def');
    4351    $this->setTablesList($tableList);
    4452
     
    8795  {
    8896    parent::initEvents();
    89 
    90 
    91     if(!isset($_REQUEST['ajaxfct']) and
    92        $this->config['amd_FillDataBaseContinuously']=='y' and
    93        $this->config['amd_AllPicturesAreAnalyzed']=='n')
    94     {
    95       /* do analyze for a random picture only if :
    96        *  - config is set to fill database continuously
    97        *  - we are not in an ajax call
    98        */
    99       add_event_handler('init', array(&$this, 'doRandomAnalyze'));
    100     }
    101   }
    102 
     97  }
     98
     99  public function getAdminLink($mode='')
     100  {
     101    if($mode=='ajax')
     102    {
     103      return('plugins/'.basename(dirname($this->getFileLocation())).'/amd_ajax.php');
     104    }
     105    else
     106    {
     107      return(parent::getAdminLink());
     108    }
     109  }
    103110
    104111  /**
     
    245252    return("$imageId=$nbTags;");
    246253  }
     254
     255
     256  /**
     257   * returns the userDefined tag for one image (without searching in the
     258   * database)
     259   *
     260   * @param Array $numId : array of userDefeined numId to get
     261   * @param Array $values : array of existing tag for the images
     262   * @return Array : associated array of numId=>value
     263   */
     264  protected function pictureGetUserDefinedTags($listId, $values)
     265  {
     266    $listIds=implode(',', $listId);
     267    $rules=array();
     268    $returned=array();
     269
     270    $sql="SELECT numId, defId, parentId, `order`, `type`, value, conditionType, conditionValue
     271          FROM ".$this->tables['user_tags_def']."
     272          WHERE numId IN ($listIds)
     273          ORDER BY numId, parentId, `order`;";
     274    $result=pwg_query($sql);
     275    if($result)
     276    {
     277      while($row=pwg_db_fetch_assoc($result))
     278      {
     279        $rules[$row['numId']][$row['parentId']][$row['defId']]=$row;
     280      }
     281    }
     282
     283    foreach($listId as $numId)
     284    {
     285      $returned[$numId]=$this->buildUserDefinedTagConditionRule(0, $values, $rules[$numId]);
     286    }
     287
     288    return($returned);
     289  }
     290
     291  /**
     292   *
     293   * @param String $id : id of the metadata to build
     294   */
     295  protected function buildUserDefinedTags($id)
     296  {
     297    $num=0;
     298    $sql="SELECT GROUP_CONCAT(DISTINCT value ORDER BY value SEPARATOR ',')
     299          FROM ".$this->tables['user_tags_def']."
     300          WHERE `type`='C' or `type`='M'
     301            AND numId='$id'";
     302    $result=pwg_query($sql);
     303    if($result)
     304    {
     305      // get the list of tags used to build the user defined tag
     306      $list='';
     307      while($row=pwg_db_fetch_row($result))
     308      {
     309        $list=$row[0];
     310      }
     311
     312      $sql="(SELECT ait.imageId, ait.numId, ait.value
     313             FROM ".$this->tables['images_tags']." ait
     314             WHERE ait.numId IN ($list)
     315            )
     316            UNION
     317            (SELECT pai.imageId, 0, ''
     318            FROM ".$this->tables['images']." pai)
     319            ORDER BY imageId, numId";
     320      $result=pwg_query($sql);
     321      if($result)
     322      {
     323        //build a list of properties for each image
     324        $images=array();
     325        while($row=pwg_db_fetch_assoc($result))
     326        {
     327          if(!array_key_exists($row['imageId'], $images))
     328          {
     329            $images[$row['imageId']]=array();
     330          }
     331          $images[$row['imageId']][$row['numId']]=$row['value'];
     332        }
     333
     334        //load the rules
     335        $sql="SELECT defId, parentId, `order`, `type`, value, conditionType, conditionValue
     336              FROM ".$this->tables['user_tags_def']."
     337              WHERE numId='$id'
     338              ORDER BY parentId, `order`;";
     339        $result=pwg_query($sql);
     340        if($result)
     341        {
     342          $rules=array();
     343          while($row=pwg_db_fetch_assoc($result))
     344          {
     345            $rules[$row['parentId']][$row['defId']]=$row;
     346          }
     347
     348          $inserts=array();
     349          // calculate tag values for each image
     350          foreach($images as $key=>$val)
     351          {
     352            $buildValue=$this->buildUserDefinedTag($key, $val, $id, $rules);
     353
     354            if(!is_null($buildValue['value']))
     355            {
     356              $inserts[]=$buildValue;
     357              $num++;
     358            }
     359          }
     360
     361          mass_inserts($this->tables['images_tags'], array('imageId', 'numId', 'value'), $inserts);
     362        }
     363      }
     364    }
     365    return($num);
     366  }
     367
     368
     369  /**
     370   * build the userDefined tag for an image
     371   *
     372   * @param String $imageId : id of the image
     373   * @param Array $values : array of existing tag for the images
     374   * @param String $numId : id of the metadata to build
     375   * @param Array $rules  : rules to apply to build the metadata
     376   */
     377  protected function buildUserDefinedTag($imageId, $values, $numId, $rules)
     378  {
     379    $returned=array(
     380      'imageId' => $imageId,
     381      'numId' => $numId,
     382      'value' => $this->buildUserDefinedTagConditionRule(0, $values, $rules)
     383    );
     384
     385    return($returned);
     386  }
     387
     388
     389  /**
     390   * build the userDefined tag for an image
     391   *
     392   * @param String $imageId : id of the image
     393   * @param Array $values : array of existing tag for the images
     394   * @param String $numId : id of the metadata to build
     395   * @param Array $rules  : rules to apply to build the metadata
     396   */
     397  protected function buildUserDefinedTagConditionRule($parentId, $values, $rules)
     398  {
     399    $null=true;
     400    $returned='';
     401    foreach($rules[$parentId] as $rule)
     402    {
     403      switch($rule['type'])
     404      {
     405        case 'T':
     406          $returned.=$rule['value'];
     407          $null=false;
     408          break;
     409        case 'M':
     410          if(isset($values[$rule['value']]))
     411          {
     412            $returned.=$values[$rule['value']];
     413            $null=false;
     414          }
     415          break;
     416        case 'C':
     417          $ok=false;
     418          switch($rule['conditionType'])
     419          {
     420            case 'E':
     421              if(isset($values[$rule['value']])) $ok=true;
     422              break;
     423            case '!E':
     424              if(!isset($values[$rule['value']])) $ok=true;
     425              break;
     426            case '=':
     427              if(isset($values[$rule['value']]) and
     428                 $values[$rule['value']]==$rule['conditionValue']) $ok=true;
     429              break;
     430            case '!=':
     431              if(isset($values[$rule['value']]) and
     432                 $values[$rule['value']]!=$rule['conditionValue']) $ok=true;
     433              break;
     434            case '%':
     435              if(isset($values[$rule['value']]) and
     436                 preg_match('/'.$rule['conditionValue'].'/i', $values[$rule['value']])) $ok=true;
     437              break;
     438            case '!%':
     439              if(isset($values[$rule['value']]) and
     440                 !preg_match('/'.$rule['conditionValue'].'/i', $values[$rule['value']])) $ok=true;
     441              break;
     442          }
     443          if($ok)
     444          {
     445            $subRule=$this->buildUserDefinedTagConditionRule($rule['defId'], $values, $rules);
     446            if(!is_null($subRule))
     447            {
     448              $null=false;
     449              $returned.=$subRule;
     450            }
     451          }
     452          break;
     453      }
     454    }
     455    if($null)
     456    {
     457      return(null);
     458    }
     459    return($returned);
     460  }
     461
     462
    247463
    248464
  • extensions/AMetaData/amd_version.inc.php

    r5935 r6722  
    1717  if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
    1818
    19   define('AMD_VERSION',  '0.4.0');
    20   define('AMD_VERSION2', '00.04.00');
     19  define('AMD_VERSION',  '0.5.0');
     20  define('AMD_VERSION2', '00.05.00');
    2121?>
  • extensions/AMetaData/language/fr_FR/plugin.lang.php

    r5249 r6722  
    165165[/ul]";
    166166
     167
     168// release 0.5.0
     169
     170$lang['g003_y'] = "Oui";
     171$lang['g003_n'] = "Non";
     172
     173
     174$lang['g003_state'] = "Etat";
     175$lang['g003_update'] = "Mise à jour";
     176$lang['g003_state'] = "Etat";
     177$lang['g003_personnal'] = "Personnelles";
     178$lang['g003_search'] = "Recherche";
     179
     180$lang['g003_personnal_metadata'] = "Métadonnées personnalisées";
     181$lang['g003_add_a_new_md'] = "Ajouter une nouvelle métadonnée";
     182$lang['g003_fill_database'] = "Alimente le référentiel";
     183$lang['g003_num_of_rules'] = "Nombre de règles";
     184$lang['g003_metadatId'] = "Identifiant de la métadonnée";
     185$lang['g003_rules'] = "Règles";
     186$lang['g003_add_a_rule'] = "Ajouter une règle";
     187$lang['g003_typeText'] = "Texte";
     188$lang['g003_typeMetadata'] = "Métadonnée";
     189$lang['g003_typeCondition'] = "Condition";
     190$lang['g003_typeCIfExist'] = "existe";
     191$lang['g003_typeCIfNotExist'] = "n'existe pas";
     192$lang['g003_typeCIfEqual'] = "est égale à";
     193$lang['g003_typeCIfNotEqual'] = "n'est pas égale à";
     194$lang['g003_typeCIfLike'] = "contient";
     195$lang['g003_typeCIfNotLike'] = "ne contient pas";
     196$lang['g003_conditionIf'] = "Tester si la métadonnée";
     197
     198$lang['g003_invalidId'] = "L\'identifiant de la métadonnée est invalide";
     199$lang['g003_oneRuleIsNeeded'] = "Il doit y avoir au moins une règle de gestion";
     200$lang['g003_textRuleInvalid'] = "Règle de type \"Texte\" : le texte ne doit pas être vide";
     201$lang['g003_metadataRuleInvalid'] = "Règle de type \"Métadonnée\" : une métadonnée doit être sélectionnée";
     202$lang['g003_conditionMdRuleInvalid'] = "Règle de type \"Condition\" : une métadonnée doit être sélectionnée";
     203$lang['g003_conditionRulesRuleInvalid'] = "Règle de type \"Condition\" : il doit y avoir au moins une règle de gestion";
     204
     205$lang['g003_tagIdAlreadyExist'] = "Une métadonnée avec cet identifiant existe déjà !";
     206
     207$lang['g003_pleaseConfirmMetadataDelete'] = "Confirmez-vous la suppression de la métadonnée ?";
     208$lang['g003_deleteMetadata'] = "Suppression de la métadonnée";
     209$lang['g003_delete']= "Supprimer";
     210
     211$lang['g003_userDefined_filter'] = "Métadonnées personnalisées";
     212
    167213?>
  • extensions/AMetaData/main.inc.php

    r6232 r6722  
    22/*
    33Plugin Name: Advanced MetaData
    4 Version: 0.4
     4Version: 0.5.0
    55Description: An advanced metadata manager
    66Plugin URI: http://piwigo.org/ext/extension_view.php?eid=364
     
    3030| 0.3b    | 2010/04/11 | * beta release
    3131|         |            |
    32 | 0.4     | 2010/04/24 | * release for Piwigo 2.1
     32| 0.4.0   | 2010/04/24 | * release for Piwigo 2.1
    3333|         |            | * uses some GPC 3.1.0 functions
    3434|         |            | * optimize ajax request to fill the metadata database
     
    3636|         |            |   functions
    3737|         |            | * update some html/css
     38|         |            |
     39| 0.5.0   | 2010/07/24 | * update to the JpegMetadata class 1.0.1 to fix the
     40|         |            |   mantis bugs&features 1686, 1718 and 1719
     41|         |            | * mantis : bug 1686
     42|         |            |   . Picture analysis finish with an Error 500 or with a
     43|         |            |     problem of memory limit
     44|         |            | * mantis : feature 1719
     45|         |            |   . Coding a DateTime class
     46|         |            | * mantis : feature 1718
     47|         |            |   . Make test images lighter
     48|         |            |     The weight of tests images provided with the
     49|         |            |     JpegMetadata class was to heavy ; the file size has
     50|         |            |     been reduced from 9Mb to 230Kb
     51|         |            | * mantis : feature 1688
     52|         |            |   . Improve performance when the database is filled
     53|         |            |     each time a page is displayed (now using an ajax
     54|         |            |     call)
     55|         |            | * mantis : feature 1692
     56|         |            |   . Add possibility for user to build their own "magic"
     57|         |            |     tags
     58|         |            | * ajax management was entirely rewritted
     59|         |            | * user interface reviewed
     60|         |            |
     61|         |            |
     62|         |            |
     63|         |            |
     64|         |            |
     65|         |            |
     66|         |            |
    3867|         |            |
    3968|         |            |
  • extensions/AMetaData/maintain.inc.php

    r5959 r6722  
    3535 * -------------------------------------------------------------------------- */
    3636$gpc_installed=false;
    37 $gpcNeeded="3.1.0";
     37$gpcNeeded="3.2.0";
    3838if(file_exists(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php'))
    3939{
    4040  @include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php');
    41   // need GPC release greater or equal than 3.1.0
    42   if(CommonPlugin::checkGPCRelease(3,1,0))
     41  // need GPC release greater or equal than 3.2.0
     42  if(CommonPlugin::checkGPCRelease(3,2,0))
    4343  {
    4444    @include_once("amd_install.class.inc.php");
     
    8787  $amd=new AMD_install($prefixeTable, __FILE__);
    8888  $result=$amd->activate();
     89  GPCCore::register($amd->getPluginName(), AMD_VERSION, $gpcNeeded);
    8990}
    9091
Note: See TracChangeset for help on using the changeset viewer.