Index: /extensions/GrumPluginClasses/admin/gpc_admin.tpl
===================================================================
--- /extensions/GrumPluginClasses/admin/gpc_admin.tpl	(revision 5550)
+++ /extensions/GrumPluginClasses/admin/gpc_admin.tpl	(revision 5550)
@@ -0,0 +1,10 @@
+<h2 style="float:right;top:-24px;position:relative;height:auto;font-size:12px;font-weight:normal;">{$plugin.GPC_VERSION}</h2>
+
+<div style="position:relative;top:-24px;clear:right;">
+
+</div>
+
+{$tabsheet}
+
+{$GPC_BODY_PAGE}
+
Index: /extensions/GrumPluginClasses/admin/gpc_infos.tpl
===================================================================
--- /extensions/GrumPluginClasses/admin/gpc_infos.tpl	(revision 5550)
+++ /extensions/GrumPluginClasses/admin/gpc_infos.tpl	(revision 5550)
@@ -0,0 +1,43 @@
+
+<h3>{'List of shared modules'|@translate}</h3>
+<div class="table">
+
+  <table class="table2 littlefont" >
+    <tr class="throw">
+      <td>{'Module'|@translate}</td>
+      <td>{'Version'|@translate}</td>
+    </tr>
+    {foreach from=$datas.modules key=name item=data name=plugins_loop}
+      <tr class="StatTableRow {if $smarty.foreach.plugins_loop.index is odd}row1{else}row2{/if}">
+        <td>{$data.name}</td>
+        <td>{$data.version}</td>
+      </tr>
+    {/foreach}
+  </table>
+
+</div>
+
+
+<h3>{'List of installed plugins using Grum Plugin Classes'|@translate}</h3>
+<div class="table">
+
+  <table class="table2 littlefont" >
+    <tr class="throw">
+      <td>{'Plugin'|@translate}</td>
+      <td>{'Version'|@translate}</td>
+      <td>{'GPC required'|@translate}</td>
+      <td>{'Installed'|@translate}</td>
+    </tr>
+
+    {foreach from=$datas.plugins key=name item=data name=plugins_loop}
+      <tr class="StatTableRow {if $smarty.foreach.plugins_loop.index is odd}row1{else}row2{/if}">
+        <td>{$data.name}</td>
+        <td>{$data.release}</td>
+        <td>{$data.needed}</td>
+        <td>{$data.date}</td>
+      </tr>
+    {/foreach}
+
+  </table>
+
+</div>
Index: /extensions/GrumPluginClasses/admin/plugin_admin.php
===================================================================
--- /extensions/GrumPluginClasses/admin/plugin_admin.php	(revision 5550)
+++ /extensions/GrumPluginClasses/admin/plugin_admin.php	(revision 5550)
@@ -0,0 +1,28 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Grum Plugin Class
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+    PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  --------------------------------------------------------------------------- */
+
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+
+include(GPC_PATH."gpc_aip.class.inc.php");
+
+global $prefixeTable;
+
+load_language('plugin.lang', GPC_PATH);
+
+$main_plugin_object = get_plugin_data($plugin_id);
+
+$plugin_ai = new GPC_AIP($prefixeTable, $main_plugin_object->getFileLocation());
+$plugin_ai->manage();
+
+?>
Index: /extensions/GrumPluginClasses/classes/CommonPlugin.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/CommonPlugin.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/CommonPlugin.class.inc.php	(revision 5550)
@@ -0,0 +1,272 @@
+<?php
+/* -----------------------------------------------------------------------------
+  class name: CommonPlugin
+  class version  : 2.1.0
+  plugin version : 3.0.0
+  date           : 2010-03-30
+
+  ------------------------------------------------------------------------------
+  Author     : Grum
+    email    : grum@grum.dnsalias.com
+    website  : http://photos.grum.dnsalias.com
+    PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+
+  this class provides base functions to manage a plugin
+  public
+    ADMINISTRATION RELATED
+    - manage()
+    - pluginAdminMenu($menu)
+    INITIALIZATION RELATED
+    - initEvents()
+    CONFIG RELATED
+    - getFileLocation()
+    - getAdminLink()
+    - initConfig()
+    - loadConfig()
+    - saveConfig()
+    - deleteConfig()
+
+  protected
+    INITIALIZATION RELATED
+    - setTablesList($list)
+  ------------------------------------------------------------------------------
+  :: HISTORY
+
+| release | date       |
+| 2.0.0   | 2008/07/13 | * migrate to piwigo 2.0
+|         |            | * use of PHP5 classes possibilities
+|         |            |
+| 2.0.1   | 2009/07/24 | * config loader : better management for arrays items
+|         |            |
+| 2.1.0   | 2010/03/28 | * Uses piwigo pwg_db_* functions instead of mysql_*
+|         |            |   functions
+|         |            | * Update class & function names
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+
+  --------------------------------------------------------------------------- */
+
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/gpc_version.inc.php'); // => Don't forget to update this file !!
+include_once('GPCCore.class.inc.php');
+
+class CommonPlugin
+{
+  private $prefixeTable;  // prefixe for tables names
+  private $page_link; //link to admin page
+  private $fileLocation; //files plugin location on server
+  private $displayResult_ok;
+  private $displayResult_ko;
+  private $plugin_name;   // used for interface display
+  private $plugin_name_files;   // used for files
+  private $plugin_admin_file = "plugin_admin";
+  private $debug_file;
+  protected $tables;   // list of all tables names used by plugin
+  public $config;     // array of config parameters
+
+
+  /**
+   * this function return true if class release if greater or equal than needed by the plugin
+   */
+  static public function checkGPCRelease($major, $minor, $minor2)
+  {
+    $release = explode(".", GPC_VERSION);
+
+    if(($release[0]>$major) ||
+       ($release[0]==$major)&&($release[1]>$minor) ||
+       ($release[0]==$major)&&($release[1]==$minor)&&($release[2]>=$minor2))
+    {
+      return(true);
+    }
+    return(false);
+  }
+
+  /* constructor allows to initialize $prefixeTable value */
+  public function __construct($prefixeTable, $filelocation)
+  {
+    $this->debug_file="debug.txt";
+
+    $this->fileLocation=$filelocation;
+    $this->prefixeTable=$prefixeTable;
+    $this->page_link="admin.php?page=plugin&section=".basename(dirname($this->getFileLocation()))."/admin/".$this->plugin_admin_file.".php";
+    $this->initConfig();
+    $this->displayResult_ok="OK";
+    $this->displayResult_ko="KO";
+  }
+
+  public function __destruct()
+  {
+    unset($this->prefixeTable);
+    unset($this->page_link);
+    unset($this->fileLocation);
+    unset($this->displayResult_ok);
+    unset($this->displayResult_ko);
+    unset($this->plugin_name);
+    unset($this->plugin_name_files);
+    unset($this->tables);
+    unset($this->debug_file);
+    unset($this->config);
+  }
+
+  public function getFileLocation()
+  {
+    return($this->fileLocation);
+  }
+
+  public function getAdminLink()
+  {
+    return($this->page_link);
+  }
+
+  public function setAdminLink($link)
+  {
+    $this->page_link=$link;
+    return($this->page_link);
+  }
+
+  public function setPluginName($name)
+  {
+    $this->plugin_name=$name;
+    return($this->plugin_name);
+  }
+
+  public function setPluginNameFiles($name)
+  {
+    $this->plugin_name_files=$name;
+    return($this->plugin_name_files);
+  }
+
+  public function getPluginName()
+  {
+    return($this->plugin_name);
+  }
+
+  public function getPluginNameFiles()
+  {
+    return($this->plugin_name_files);
+  }
+
+  /* ---------------------------------------------------------------------------
+     CONFIGURATION RELATED FUNCTIONS
+  --------------------------------------------------------------------------- */
+
+  /* this function initialize var $config with default values */
+  public function initConfig()
+  {
+    $this->config=array();
+  }
+
+  /* load config from CONFIG_TABLE into var $my_config */
+  public function loadConfig()
+  {
+    $this->initConfig();
+    return(GPCCore::loadConfig($this->plugin_name_files, $this->config));
+  }
+
+  /* save var $my_config into CONFIG_TABLE */
+  public function saveConfig()
+  {
+    return(GPCCore::saveConfig($this->plugin_name_files, $this->config));
+  }
+
+  /* delete config from CONFIG_TABLE */
+  public function deleteConfig()
+  {
+    return(GPCCore::deleteConfig($this->plugin_name_files));
+  }
+
+  /* ---------------------------------------------------------------------------
+     PLUGIN INITIALIZATION RELATED FUNCTIONS
+  --------------------------------------------------------------------------- */
+
+  /*
+      initialize tables list used by the plugin
+        $list = array('table1', 'table2')
+        $this->tables_list['table1'] = $prefixeTable.$plugin_name.'_table1'
+  */
+  protected function setTablesList($list)
+  {
+    for($i=0;$i<count($list);$i++)
+    {
+      $this->tables[$list[$i]]=$this->prefixeTable.$this->plugin_name_files.'_'.$list[$i];
+    }
+  }
+
+  /* ---------------------------------------------------------------------------
+     ADMINISTRATOR CONSOLE RELATED FUNCTIONS
+  --------------------------------------------------------------------------- */
+
+  /* add plugin into administration menu */
+  public function pluginAdminMenu($menu)
+  {
+    array_push($menu,
+               array(
+                  'NAME' => $this->plugin_name,
+                  'URL' => get_admin_plugin_menu_link(dirname($this->getFileLocation()).
+                                '/admin/'.$this->plugin_admin_file.'.php')
+                   ));
+    return $menu;
+  }
+
+  /*
+    manage plugin integration into piwigo's admin interface
+
+    to be surcharged by child's classes
+  */
+  public function manage()
+  {
+  }
+
+  /*
+    intialize plugin's events
+    to be surcharged by child's classes
+  */
+  public function initEvents()
+  {
+  }
+
+  protected function debug($text, $rewrite=false)
+  {
+    if($rewrite)
+    {
+      $fhandle=fopen($this->debug_file, "w");
+    }
+    else
+    {
+      $fhandle=fopen($this->debug_file, "a");
+    }
+
+    if($fhandle)
+    {
+      fwrite($fhandle, date("Y-m-d h:i:s")." [".$this->plugin_name."] : ".print_r($text,true).chr(10));
+      fclose($fhandle);
+    }
+  }
+
+  /*
+    manage infos & errors display
+  */
+  protected function displayResult($action_msg, $result)
+  {
+    global $page;
+
+    if($result)
+    {
+      array_push($page['infos'], $action_msg);
+      array_push($page['infos'], $this->displayResult_ok);
+    }
+    else
+    {
+      array_push($page['errors'], $action_msg);
+      array_push($page['errors'], $this->displayResult_ko);
+    }
+  }
+} //class CommonPlugin
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCAjax.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCAjax.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCAjax.class.inc.php	(revision 5550)
@@ -0,0 +1,43 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name     : GPCAjax
+  class version  : 3.0.0
+  plugin version : 3.0.0
+  date           : 2010-03-30
+  ------------------------------------------------------------------------------
+  author: grum at piwigo.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+  :: HISTORY
+
+| release | date       |
+| 3.0.0   | 2010/03/30 | * Update class & function names
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+
+  ------------------------------------------------------------------------------
+    no constructor, only static function are provided
+    - static function return_result($str)
+   ---------------------------------------------------------------------- */
+
+
+
+class GPCAjax
+{
+  static public function returnResult($str)
+  {
+    //$chars=get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
+    $chars['<']='<';
+    $chars['>']='>';
+    $chars['&']='&';
+    exit(strtr($str, $chars));
+  }
+} //class
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCCore.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCCore.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCCore.class.inc.php	(revision 5550)
@@ -0,0 +1,226 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name     : GPCCore
+  class version  : 3.0.0
+  plugin version : 3.0.0
+  date           : 2010-03-30
+  ------------------------------------------------------------------------------
+  author: grum at piwigo.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+  :: HISTORY
+
+| release | date       |
+| 3.0.0   | 2010/03/30 | * Update class & function names
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+
+  ------------------------------------------------------------------------------
+    no constructor, only static function are provided
+    - static function loadConfig
+    - static function saveConfig
+    - static function deleteConfig
+    - static function getRegistered
+    - static function getModulesInfos
+    - static function register
+    - static function unregister
+   ---------------------------------------------------------------------- */
+
+
+
+class GPCCore
+{
+  static public $pluginName = "GPCCore";
+
+  /* ---------------------------------------------------------------------------
+   * grum plugin classes informations functions
+   * -------------------------------------------------------------------------*/
+  static public function getModulesInfos()
+  {
+    return(
+      Array(
+        Array('name' => "CommonPlugin", 'version' => "2.1.0"),
+        Array('name' => "GPCAjax", 'version' => "3.0.0"),
+        Array('name' => "GPCCore", 'version' => "1.0.0"),
+        Array('name' => "GPCCss", 'version' => "3.0.0"),
+        Array('name' => "GPCPagesNavigations", 'version' => "2.0.0"),
+        Array('name' => "GPCPublicIntegration", 'version' => "2.0.0"),
+        Array('name' => "GPCTables", 'version' => "1.5.0"),
+        Array('name' => "GPCTranslate", 'version' => "2.1.0"),
+        Array('name' => "GPCUsersGroups", 'version' => "2.0.0"),
+      )
+    );
+  }
+
+
+  /* ---------------------------------------------------------------------------
+   * register oriented functions
+   * -------------------------------------------------------------------------*/
+
+  /**
+   * register a plugin using GPC
+   *
+   * @param String $pluginName : the plugin name
+   * @param String $release : the plugin version like "2.0.0"
+   * @param String $GPCNeed : the minimal version of GPC needed by the plugin to
+   *                          work
+   * @return Boolean : true if registering is Ok, otherwise false
+   */
+  static public function register($plugin, $release, $GPCneeded)
+  {
+    $config=Array();
+    if(self::loadConfig(self::$pluginName, $config))
+    {
+      $config['registered'][$plugin]=Array(
+        'name' => $plugin,
+        'release' => $release,
+        'needed' => $GPCneeded,
+        'date' => date("Y-m-d"),
+      );
+      return(self::saveConfig(self::$pluginName, $config));
+    }
+    return(false);
+  }
+
+  /**
+   * unregister a plugin using GPC
+   *
+   * assume that if the plugin was not registerd before, unregistering returns
+   * a true value
+   *
+   * @param String $pluginName : the plugin name
+   * @return Boolean : true if registering is Ok, otherwise false
+   */
+  static public function unregister($plugin)
+  {
+    $config=Array();
+    if(self::loadConfig(self::$pluginName, $config))
+    {
+      if(array_key_exists('registered', $config))
+      {
+        if(array_key_exists($plugin, $config['registered']))
+        {
+          unset($config['registered'][$plugin]);
+          return(self::saveConfig(self::$pluginName, $config));
+        }
+      }
+    }
+    // assume if the plugin was not registered before, unregistering it is OK
+    return(true);
+  }
+
+  /**
+   * @return Array : list of registered plugins
+   */
+  static public function getRegistered()
+  {
+    $config=Array();
+    if(self::loadConfig(self::$pluginName, $config))
+    {
+      if(array_key_exists('registered', $config))
+      {
+        return($config['registered']);
+      }
+    }
+    return(Array());
+  }
+
+
+
+  /* ---------------------------------------------------------------------------
+   * config oriented functions
+   * -------------------------------------------------------------------------*/
+
+  /**
+   *  load config from CONFIG_TABLE into an array
+   *
+   * @param String $pluginName : the plugin name, must contain only alphanumerical
+   *                             character
+   * @param Array $config : array, initialized or not with default values ; the
+   *                        config values are loaded in this value
+   * @return Boolean : true if config is loaded, otherwise false
+   */
+  static public function loadConfig($pluginName, &$config=Array())
+  {
+    if(!is_array($config))
+    {
+      return(false);
+    }
+
+    $sql="SELECT value FROM ".CONFIG_TABLE."
+          WHERE param = '".$pluginName."_config'";
+    $result=pwg_query($sql);
+    if($result)
+    {
+      $row=pwg_db_fetch_row($result);
+      if(is_string($row[0]))
+      {
+        $configValues = unserialize($row[0]);
+        reset($configValues);
+        while (list($key, $val) = each($configValues))
+        {
+          if(is_array($val))
+          {
+            foreach($val as $key2 => $val2)
+            {
+              $config[$key][$key2]=$val2;
+            }
+          }
+          else
+          {
+            $config[$key] =$val;
+          }
+        }
+      }
+      return(true);
+    }
+    return(false);
+  }
+
+  /**
+   * save var $my_config into CONFIG_TABLE
+   *
+   * @param String $pluginName : the plugin name, must contain only alphanumerical
+   *                             character
+   * @param Array $config : array of configuration values
+   * @return Boolean : true if config is saved, otherwise false
+   */
+  static public function saveConfig($pluginName, $config)
+  {
+    $sql="REPLACE INTO ".CONFIG_TABLE."
+           VALUES('".$pluginName."_config', '"
+           .serialize($config)."', '')";
+    $result=pwg_query($sql);
+    if($result)
+    { return true; }
+    else
+    { return false; }
+  }
+
+  /**
+   * delete config from CONFIG_TABLE
+   *
+   * @param String $pluginName : the plugin name, must contain only alphanumerical
+   *                             character
+   * @return Boolean : true if config is deleted, otherwise false
+   */
+  static public function deleteConfig($pluginName)
+  {
+    $sql="DELETE FROM ".CONFIG_TABLE."
+          WHERE param='".$pluginName."_config'";
+    $result=pwg_query($sql);
+    if($result)
+    { return true; }
+    else
+    { return false; }
+  }
+
+} //class
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCCss.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCCss.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCCss.class.inc.php	(revision 5550)
@@ -0,0 +1,95 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name: GPCCss
+  class version  : 3.0.0
+  plugin version : 3.0.0
+  date           : 2010-03-30
+
+  ------------------------------------------------------------------------------
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+    PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+
+  :: HISTORY
+
+| release | date       |
+| 3.0.0   | 2010/03/30 | * Update class & function names
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+
+  ------------------------------------------------------------------------------
+
+   this classes provides base functions to manage css
+    classe consider that $filename is under plugins/ directory
+
+
+    - constructor Css($filename)
+    - (public) function fileExists()
+    - (public) function makeCSS($css)
+    - (public) function applyCSS()
+   ---------------------------------------------------------------------- */
+class GPCCss
+{
+  private $filename;
+
+  public function __construct($filename)
+  {
+    $this->filename=$filename;
+  }
+
+  public function __destruct()
+  {
+    unset($this->filename);
+  }
+
+  /*
+    make the css file
+  */
+  public function makeCSS($css)
+  {
+    if($css!="")
+    {
+      $handle=fopen($this->filename, "w");
+      if($handle)
+      {
+        fwrite($handle, $css);
+        fclose($handle);
+      }
+    }
+  }
+
+  /*
+    return true if css file exists
+  */
+  public function fileExists()
+  {
+    return(file_exists($this->filename));
+  }
+
+  /*
+    put a link in the template to load the css file
+    this function have to be called in a 'loc_end_page_header' trigger
+
+    if $text="", insert link to css file, otherwise insert directly a <style> markup
+  */
+  public function applyCSS()
+  {
+    global $template;
+
+    if($this->fileExists())
+    {
+      $template->append('head_elements', '<link rel="stylesheet" type="text/css" href="plugins/'.basename(dirname($this->filename))."/".basename($this->filename).'">');
+    }
+  }
+} //class
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCPagesNavigation.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCPagesNavigation.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCPagesNavigation.class.inc.php	(revision 5550)
@@ -0,0 +1,347 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name     : GPCPagesNavigation
+  class version  : 2.0.0
+  plugin version : 3.0.0
+  date           : 2010-03-30
+  ------------------------------------------------------------------------------
+  author: grum at piwigo.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+  :: HISTORY
+
+| release | date       |
+| 2.0.0   | 2010/03/30 | * Update class & function names
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+
+  ------------------------------------------------------------------------------
+
+   this classes provides base functions to manage pages navigation
+
+    - constructor GPCPagesNavigation()
+    - (public) function setNbItems($nbitems)
+    - (public) function getNbItems()
+    - (public) function setNbItemsPerPage($nbitems)
+    - (public) function getNbItemsPerPage()
+    - (public) function getNbPages()
+    - (public) function setCurrentPage($page)
+    - (public) function getCurrentPage()
+    - (public) function setBaseUrl($url)
+    - (public) function getBaseUrl()
+    - (public) function setOptions($var)
+    - (public) function getOptions()
+    - (public) function makeNavigation()
+    - (private) function calcNbPages()
+   ---------------------------------------------------------------------- */
+class GPCPagesNavigation
+{
+  protected $nbitems;
+  protected $nbitemsperpages;
+  protected $nbpages;
+  protected $currentpage;
+  protected $baseurl;
+  protected $pagevarurl;
+  protected $options;
+
+  public function __construct()
+  {
+    $this->nbitems=0;
+    $this->nbitemsperpages=0;
+    $this->nbpages=0;
+    $this->currentpage=0;
+    $this->baseurl='';
+    $this->pagevarurl='';
+    $this->options=array(
+      'prev_next' => true,
+      'first_last' => true,
+      'display_all' => true,
+      'number_displayed' => 2, //number of page displayed before and after current page
+      'text_prev' => "&lt;",
+      'text_first' => "&lt;&lt;",
+      'text_next' => "&gt;",
+      'text_last' => "&gt;&gt;",
+    );
+  }
+
+  public function __destruct()
+  {
+    unset($this->nbitems);
+    unset($this->nbitemsperpages);
+    unset($this->nbpages);
+    unset($this->currentpage);
+    unset($this->baseurl);
+    unset($this->pagevarurl);
+    unset($this->options);
+  }
+
+  /*
+    define value for total number of items
+  */
+  public function setNbItems($nbitems)
+  {
+    if($nbitems!=$this->nbitems)
+    {
+      $this->nbitems=$nbitems;
+      $this->calcNbPages();
+    }
+    return($nbitems);
+  }
+
+  public function getNbItems()
+  {
+    return($nbitems);
+  }
+
+  /*
+    define value for number of items displayed per pages
+  */
+  public function setNbItemsPerPage($nbitems)
+  {
+    if(($nbitems!=$this->nbitemsperpages)&&($nbitems>0))
+    {
+      $this->nbitemsperpages=$nbitems;
+      $this->calcNbPages();
+    }
+    return($this->nbitemsperpages);
+  }
+
+  public function getNbItemsPerPage()
+  {
+    return($this->nbitemsperpages);
+  }
+
+  /*
+    return numbers of pages
+  */
+  public function getNbPages()
+  {
+    return($this->nbpages);
+  }
+
+  /*
+    define the current page number
+  */
+  public function setCurrentPage($page)
+  {
+    if(($page!=$this->currentpage)&&($page<=$this->nbpages)&&($page>0))
+    {
+      $this->currentpage=$page;
+    }
+    return($this->currentpage);
+  }
+
+  /*
+    returns the current page number
+  */
+  public function getCurrentPage()
+  {
+    return($this->currentpage);
+  }
+
+  /*
+    define the value for url
+    ex: "http://mysite.com/admin.php?var1=xxx&var2=xxx"
+  */
+  public function setBaseUrl($url)
+  {
+    if($url!=$this->baseurl)
+    {
+      $this->baseurl=$url;
+    }
+    return($this->baseurl);
+  }
+
+  public function getBaseUrl()
+  {
+    return($this->baseurl);
+  }
+
+  /*
+    define the value for variables's name
+    ex: url = "http://mysite.com/admin.php?var1=xxx&var2=xxx"
+        pagevar = "pagenumber"
+    url made is "http://mysite.com/admin.php?var1=xxx&var2=xxx&pagenumber=xxx"
+  */
+  public function setPageVarUrl($var)
+  {
+    if($var!=$this->pagevarurl)
+    {
+      $this->pagevarurl=$var;
+    }
+    return($this->pagevarurl);
+  }
+
+  public function getPageVarUrl()
+  {
+    return($this->pagevarurl);
+  }
+
+  /*
+    define the navigation bar options
+  */
+  public function setOptions($var)
+  {
+    if(is_array($var))
+    {
+      foreach($this->options as $key=>$val)
+      {
+        if(isset($var[$key]))
+        {
+          $this->options[$key]=$var[$key];
+        }
+      }
+    }
+    return($this->options);
+  }
+
+  public function getOptions()
+  {
+    return($this->options);
+  }
+
+
+  /*
+    returns an html formatted string
+  */
+  public function makeNavigation($functionname='')
+  {
+    $text='';
+    if(($this->options['display_all'])||($this->options['number_displayed']>=$this->nbpages))
+    {
+      for($i=1;$i<=$this->nbpages;$i++)
+      {
+        if($i!=$this->currentpage)
+        {
+          if($functionname=='')
+          {
+            $text.='<a href="'.$this->baseurl.'&'.$this->pagevarurl.'='.$i.'">'.$i.'</a>&nbsp;';
+          }
+          else
+          {
+            $text.='<a style="cursor:pointer;" onclick="'.$functionname.'('.$i.');">'.$i.'</a>&nbsp;';
+          }
+        }
+        else
+        {
+          $text.=$i.'&nbsp;';
+        }
+      }
+    }
+    else
+    {
+      for($i=$this->currentpage-$this->options['number_displayed'];$i<=$this->currentpage+$this->options['number_displayed'];$i++)
+      {
+        if(($i>0)&&($i<=$this->nbpages))
+        {
+          if($i!=$this->currentpage)
+          {
+            if($functionname=='')
+            {
+              $text.='<a href="'.$this->baseurl.'&'.$this->pagevarurl.'='.$i.'">'.$i.'</a>&nbsp;';
+            }
+            else
+            {
+              $text.='<a style="cursor:pointer;" onclick="'.$functionname.'('.$i.');">'.$i.'</a>&nbsp;';
+            }
+          }
+          else
+          {
+            $text.=$i.'&nbsp;';
+          }
+        }
+      }
+      if($this->currentpage-$this->options['number_displayed']>0)
+      {
+        $text='&nbsp;...&nbsp;'.$text;
+      }
+      if($this->currentpage+$this->options['number_displayed']<$this->nbpages)
+      {
+        $text.='&nbsp;...&nbsp;';
+      }
+    }
+
+    if($this->options['prev_next'])
+    {
+      $prevp='';
+      $nextp='';
+      if($this->currentpage>1)
+      {
+        if($functionname=='')
+        {
+          $prevp='<a href="'.$this->baseurl.'&'.$this->pagevarurl.'='.($this->currentpage-1).'">&nbsp;'.$this->options['text_prev'].'&nbsp;</a>';
+        }
+        else
+        {
+          $prevp='<a style="cursor:pointer;" onclick="'.$functionname.'('.($this->currentpage-1).');">&nbsp;'.$this->options['text_prev'].'&nbsp;</a>';
+        }
+      }
+      if($this->currentpage<$this->nbpages)
+      {
+        if($functionname=='')
+        {
+          $nextp='<a href="'.$this->baseurl.'&'.$this->pagevarurl.'='.($this->currentpage+1).'">&nbsp;'.$this->options['text_next'].'&nbsp;</a>';
+        }
+        else
+        {
+          $nextp='<a style="cursor:pointer;" onclick="'.$functionname.'('.($this->currentpage+1).');">&nbsp;'.$this->options['text_next'].'&nbsp;</a>';
+        }
+      }
+
+      $text=$prevp.$text.$nextp;
+    }
+
+    if($this->options['first_last'])
+    {
+      $firstp='';
+      $lastp='';
+      if($this->currentpage>1)
+      {
+        if($functionname=='')
+        {
+          $firstp='<a href="'.$this->baseurl.'&'.$this->pagevarurl.'=1">&nbsp;'.$this->options['text_first'].'&nbsp;</a>';
+        }
+        else
+        {
+          $firstp='<a style="cursor:pointer;" onclick="'.$functionname.'(1);">&nbsp;'.$this->options['text_first'].'&nbsp;</a>';
+        }
+      }
+      if($this->currentpage<$this->nbpages)
+      {
+        if($functionname=='')
+        {
+          $lastp='<a href="'.$this->baseurl.'&'.$this->pagevarurl.'='.$this->nbpages.'">&nbsp;'.$this->options['text_last'].'&nbsp;</a>';
+        }
+        else
+        {
+          $lastp='<a style="cursor:pointer;" onclick="'.$functionname.'('.$this->nbpages.');">&nbsp;'.$this->options['text_last'].'&nbsp;</a>';
+        }
+      }
+
+      $text=$firstp.$text.$lastp;
+    }
+
+    return($text);
+  }
+
+
+  /*
+    calculate the number of pages...
+  */
+  public function calcNbPages()
+  {
+    if($this->nbitemsperpages>0)
+    {
+      $this->nbpages=ceil($this->nbitems/$this->nbitemsperpages);
+    }
+  }
+
+} //class
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCPublicIntegration.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCPublicIntegration.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCPublicIntegration.class.inc.php	(revision 5550)
@@ -0,0 +1,96 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name: GPCPublicIntegration
+  class version  : 2.0.0
+  plugin version : 3.0.0
+  date           : 2010-03-30
+  ------------------------------------------------------------------------------
+  author: grum at piwigo.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+  :: HISTORY
+
+| release | date       |
+| 2.0.0   | 2010/03/30 | * Update class & function names
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+  ------------------------------------------------------------------------------
+
+  this class provides base functions to manage an integration into main index
+  page
+
+  - constructor GPCPublicIntegration($section)
+  - (public) function init_events()
+  - (public) function setCallbackPageFunction($value)
+  - (private) function init_section()
+  - (private) function call_page()
+
+  use initEvents() function to initialize needed triggers for updating menubar
+
+  the "callback_page_function" is called everytime a specific page is displayed
+
+----------------------------------------------------------------------------- */
+
+class GPCPublicIntegration
+{
+  var $section;         //section applied to the page viewed
+  var $callback_page_function;        //called function to display page
+
+  public function __construct($section)
+  {
+    $this->section=$section;
+    $this->callback_page_function='';
+  }
+
+  public function __destruct()
+  {
+    unset($this->section);
+    unset($this->callback_page_function);
+  }
+
+  //initialize events to manage menu & page integration
+  public function initEvents()
+  {
+    add_event_handler('loc_end_section_init', array(&$this, 'initSection'));
+    add_event_handler('loc_end_index', array(&$this, 'callPage'));
+  }
+
+  public function setCallbackPageFunction($value)
+  {
+    $this->callback_page_function=$value;
+  }
+
+  /*
+    init section
+  */
+  public function initSection()
+  {
+    global $tokens, $page;
+
+    if ($tokens[0] == $this->section)
+    { $page['section'] = $this->section; }
+  }
+
+  /*
+    loads a page
+  */
+  public function callPage()
+  {
+    global $page, $user;
+
+    if($page['section'] == $this->section)
+    {
+      @call_user_func($this->callback_page_function);
+    }
+  }
+
+} //class GPCPublicIntegration
+
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCTables.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCTables.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCTables.class.inc.php	(revision 5550)
@@ -0,0 +1,462 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name: GPCTables
+  class version: 1.5
+  date: 2010-03-28
+  ------------------------------------------------------------------------------
+  author: grum at piwigo.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+  this class provides base functions to manage tables while plugin installation
+    - constructor GPCTables($tables)
+    - (public) function create($tables_def)
+    - (public) function updateTablesFields($tables_alteration)
+    - (public) function drop()
+    - (public) function rename($list)  -v1.1
+    - (public) function exists()  -v1.1
+    - (public) function export($filename, $options, $tables, $infos)  -v1.3
+    - (public) function multi_queries($queries)  -v1.3
+    - (public) function import($filename)  -v1.3
+
+  ------------------------------------------------------------------------------
+  v1.1              + add rename($list) function
+                    + add exists() function
+  v1.2              + add export($filename, $options, $tables) function
+  v1.3              + modify export($filename, $options, $tables, $infos, $resultboolean) function
+                        + new parameters '$infos' allows to add some information on the
+                          exported file
+                        + add 'delete' and 'colnames' options
+                        + $resultbooelan option for return
+                    + add multi_queries($queries) function
+                    + add import($filename) function
+  v1.4 - 2009-03-01 + PHP5 migration (use of public/protected/private)
+                    + export => DROP TABLE IF EXISTS
+                    + import => if DROP TABLE without IF EXISTS, add IF EXISTS
+  v1.5 - 2010-03-28 + Uses piwigo pwg_db_* functions instead of mysql_* functions
+
+   -------------------------------------------------------------------------- */
+class GPCTables
+{
+  public $tables;    //array of tables names
+  public $version = "1.4";
+
+  public function __construct($tables)
+  {
+    $this->tables = $tables;
+  }
+
+  public function __destruct()
+  {
+    unset($this->tables);
+    unset($this->version);
+  }
+
+
+  /*
+      create tables
+      $tables_def is an array of SQL CREATE queries
+
+      return true if everything is ok, otherwise tablename
+  */
+  public function create($tables_def)
+  {
+    //deleting tables if exists
+    $this->drop();
+
+    for($i=0;$i<count($tables_def);$i++)
+    {
+      $result=pwg_query($tables_def[$i]);
+      if(!$result)
+      {
+        //if an error occurs, deleting created tables
+        $this->drop();
+        return(false);
+      }
+    }
+    return(true);
+  }
+
+  /* update tables definition
+     $tables_alteration : array of arrays
+      example :
+      $tables_alteration['table1']=array(
+        "attribute1" => " ADD COLUMN `attribute1` text null default ''",
+        "attribute2" => " ADD COLUMN `attribute2` text null default ''"));
+      $tables_alteration['table2']=array(
+        "attribute1" => " ADD COLUMN `attribute1` text null default ''",
+        "attribute2" => " ADD COLUMN `attribute2` text null default ''"));
+
+      return true if no error, otherwise return table.fields of error
+  */
+  public function updateTablesFields($tables_alteration)
+  {
+    if(!is_array($tables_alteration))
+    {
+      return('');
+    }
+
+    reset($tables_alteration);
+    while (list($key, $val) = each($tables_alteration))
+    {
+      $sql="SHOW COLUMNS FROM $key";
+      $result=pwg_query($sql);
+      if($result)
+      {
+        $columns=array();
+        while($row=pwg_db_fetch_assoc($result))
+        {
+          array_push($columns, $row['Field']);
+        }
+
+        reset($val);
+        while (list($attname, $sql) = each($val))
+        {
+          if(!in_array($attname, $columns))
+          {
+            $result=pwg_query("ALTER TABLE `$key` ".$sql);
+            if(!$result)
+            {
+              return($key.".".$attname);
+            }
+          }
+        }
+      }
+    }
+    return(true);
+  }
+
+
+  /*
+      delete tables listed in $this->tables_list
+  */
+  public function drop()
+  {
+    foreach($this->tables as $key => $table_name)
+    {
+      $sql="DROP TABLE IF EXISTS ".$table_name;
+      $result=pwg_query($sql);
+    }
+  }
+
+  /*
+      rename tables name of list
+        $list is an array('old_name' => 'new_name')
+      return true if ok, else old table name
+  */
+  public function rename($list)
+  {
+    $tmplist=array_flip($this->tables);
+    foreach($list as $key => $val)
+    {
+      if(isset($tmplist[$key]))
+      {
+        $this->tables[$tmplist[$key]] = $val;
+        $sql="ALTER TABLE `$key` RENAME TO `$val`";
+        if(!pwg_query($sql))
+        {
+          return($key);
+        }
+      }
+      else
+      {
+        return($key);
+      }
+    }
+    return(true);
+  }
+
+  /*
+    return true if all listed tables exists
+  */
+  public function exists()
+  {
+    $list=array_flip($this->tables);
+    $sql="SHOW TABLES";
+    $result=pwg_query($sql);
+    if($result)
+    {
+      while($row=pwg_db_fetch_row($result))
+      {
+        if(isset($list[$row[0]]))
+        {
+          array_splice($list, $row[0],1);
+        }
+      }
+    }
+    if(count($list)>0)
+    {
+      return(false);
+    }
+    else
+    {
+      return(true);
+    }
+  }
+
+  /*
+    export all tables as SQL in a text file
+
+    each query end with a " -- EOQ" ; it's just a method to increase parsing for
+    import function
+
+      $filename : name of the file
+      $options : array of options like
+                    array(
+                      'drop' => true/false,  //add DROP TABLE statements
+                      'create' => true/false,  //add CREATE TABLE statements
+                      'insert' => true/false,  //add INSERT statements
+                      'delete' => true/false, //add delete statements
+                      'colnames' => true/false, //add columns names for inserts statements
+                    )
+      $tables : array of tables names to export
+                    array('tablename1', 'tablenamen', 'tablename3', ...)
+                  if empty, assume that all tables have to be exported
+      $infos : additional info written in exported file (as comment)
+      $resultboolean : if true, result is true/false ;
+                       if false, if result, return a string with nfo about export
+  */
+  public function export($filename, $options=array(), $tables=array(), $infos="", $resultboolean=true)
+  {
+    $defaultopt=array(
+      'drop' => true,
+      'create' => true,
+      'insert' => true,
+      'delete' => false,
+      'colnames' => false
+    );
+
+    if(!isset($options['drop']))
+    {
+      $options['drop']=$defaultopt['drop'];
+    }
+    if(!isset($options['create']))
+    {
+      $options['create']=$defaultopt['create'];
+    }
+    if(!isset($options['insert']))
+    {
+      $options['insert']=$defaultopt['insert'];
+    }
+    if(!isset($options['delete']))
+    {
+      $options['delete']=$defaultopt['delete'];
+    }
+    if(!isset($options['colnames']))
+    {
+      $options['colnames']=$defaultopt['colnames'];
+    }
+    if(count($tables)==0)
+    {
+      $tables=$this->tables;
+    }
+
+    $resultnfo='';
+
+    $returned=true;
+    $text='
+-- ***************************************************************              -- EOQ
+-- * SQL export made with Grum Plugins Classes (Export tool r'.$this->version.')         -- EOQ
+-- * Export date    :'.date('Y-m-d H:i:s').'                                    -- EOQ
+-- * Export options :';
+if($options['drop']){$text.=' [drop]';}
+if($options['delete']){$text.=' [delete]';}
+if($options['create']){$text.=' [create]';}
+if($options['insert']){$text.=' [insert]';}
+if($options['colnames']){$text.=' [colnames]';}
+$text.="                            -- EOQ";
+if($infos!="")
+{
+  $text.='
+-- * '.$infos." -- EOQ";
+}
+$text.='
+-- ***************************************************************              -- EOQ
+
+';
+    foreach($tables as $key => $val)
+    {
+      $countelems=0;
+
+      $text.="
+
+-- ***************************************************************              -- EOQ
+-- * Statements for ".$this->tables[$key]." table                               -- EOQ
+-- ***************************************************************              -- EOQ
+";
+
+      if($options['drop'])
+      {
+        $text.=sprintf("DROP TABLE IF EXISTS `%s`; -- EOQ\n", $this->tables[$key]);
+      }
+
+      if($options['delete'])
+      {
+        $text.=sprintf("DELETE FROM `%s`; -- EOQ\n", $this->tables[$key]);
+      }
+
+      if($options['create'])
+      {
+        $sql='SHOW CREATE TABLE '.$this->tables[$key];
+        $result=pwg_query($sql);
+        if($result)
+        {
+          while($row=pwg_db_fetch_row($result))
+          {
+            $text.=sprintf("%s; -- EOQ\n", $row[1]);
+          }
+        }
+        else
+        {
+          $returned=false;
+        }
+      }
+
+      if($options['insert'])
+      {
+        $colnames="";
+        if($options['colnames'])
+        {
+          $sql='SHOW COLUMNS FROM `'.$this->tables[$key].'`';
+          $result=pwg_query($sql);
+          if($result)
+          {
+            $tmp=array();
+            while($row=pwg_db_fetch_row($result))
+            {
+              $tmp[]=$row[0];
+            }
+          }
+          $colnames='('.implode(',', $tmp).')';
+        }
+
+        $sql='SELECT * FROM '.$this->tables[$key];
+        $result=pwg_query($sql);
+        if($result)
+        {
+          while($row=pwg_db_fetch_row($result))
+          {
+            foreach($row as $key2 => $val2)
+            {
+              $row[$key2]="'".addslashes($val2)."'";
+            }
+            $text.=sprintf("INSERT INTO `%s` %s VALUES(%s); -- EOQ\n", $this->tables[$key], $colnames, implode(', ', $row));
+            $countelems++;
+          }
+        }
+        else
+        {
+          $returned=false;
+        }
+        $resultnfo.=$key.':'.$countelems.'@';
+      }
+    }
+    $fhandle=fopen($filename, 'wb');
+    if($fhandle)
+    {
+      fwrite($fhandle, $text);
+      fclose($fhandle);
+    }
+    else
+    {
+      $returned=false;
+    }
+    if(($resultboolean==false)&&($returned))
+    {
+      $returned=$resultnfo;
+    }
+    return($returned);
+  }
+
+  /*
+    import an .sql file
+      $filename : name of the file
+      'errors' : -1 file don't exists
+                 -2 can't open file
+  */
+  public function import($filename)
+  {
+    $return = array(
+      'numinsert'=>0,
+      'numdelete'=>0,
+      'numdrop'=>0,
+      'numcreate'=>0,
+      'errors'=>array(),
+      'total_ok'=>0
+    );
+
+    if(file_exists($filename))
+    {
+      $fhandle=fopen($filename, 'r');
+      if($fhandle)
+      {
+        $queries=fread($fhandle, filesize($filename));
+        fclose($fhandle);
+        $return=$this->multi_queries($queries);
+      }
+      else
+      {
+        $return['errors']=-2;
+      }
+    }
+    else
+    {
+      $return['errors']=-1;
+    }
+    return($return);
+  }
+
+  /*
+    execute multiple query
+      each query have to be separated by a "-- EOQ\n"
+
+      $queries : sql queries
+  */
+  public function multi_queries($queries)
+  {
+    $queries_list=preg_split(
+      '/\s*;?\s*--\s+EOQ[\r\n]{1}/i', $queries, -1, PREG_SPLIT_NO_EMPTY);
+
+    $return = array(
+      'numinsert'=>0,
+      'numdelete'=>0,
+      'numdrop'=>0,
+      'numcreate'=>0,
+      'errors'=>array(),
+      'total_ok'=>0
+    );
+
+    $i=0;
+    foreach($queries_list as $key => $sql)
+    {
+      $i++;
+
+      // replace " DROP TABLE `xxxx`; " by " DROP TABLE IF EXISTS `xxxx`; "
+      $sql=preg_replace("/(.*DROP TABLE)\s*(`.*)/i", "$1 IF EXISTS $2", $sql);
+
+      @$result=pwg_query($sql);
+      if($result)
+      {
+        $return['total_ok']++;
+        if(preg_match('/\b[\s]*insert[\s]+/i', $sql)>0)
+        {$return['numinsert']++;}
+        elseif(preg_match('/\b[\s]*drop[\s]+/i', $sql)>0)
+        {$return['numdrop']++;}
+        elseif(preg_match('/\b[\s]*delete[\s]+/i', $sql)>0)
+        {$return['numdelete']++;}
+        elseif(preg_match('/\b[\s]*create[\s]+/i',$sql)>0)
+        {$return['numcreate']++;}
+      }
+      else
+      {
+        array_push($return['errors'], '['.$i.'] '.$sql);
+      }
+    }
+    return($return);
+  }
+
+} //class
+
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCTranslate.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCTranslate.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCTranslate.class.inc.php	(revision 5550)
@@ -0,0 +1,55 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name     : GPCTranslate
+  class version  : 2.1.0
+  plugin version : 3.0.0
+  date           : 2010-03-31
+  ------------------------------------------------------------------------------
+  author: grum at piwigo.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+
+  ------------------------------------------------------------------------------
+
+  :: HISTORY
+
+| release | date       |
+| 2.1.0   | 2010/03/31 | * update class & functions names
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+
+  ------------------------------------------------------------------------------
+
+
+   class call API in HTML header, and provide a .js file manage API call
+        >>  http://code.google.com/apis/ajaxlanguage/
+
+    - constructor
+
+   ---------------------------------------------------------------------- */
+class GPCTranslate
+{
+  public function __construct()
+  {
+    add_event_handler('loc_end_page_header', array(&$this, 'loadJS'));
+  }
+
+  public function loadJS()
+  {
+    global $template;
+
+    $googleload='
+<script type="text/javascript" src="http://www.google.com/jsapi"></script>
+<script type="text/javascript" src="plugins/'.basename(dirname(__FILE__)).'/google_translate.js"></script>';
+
+    $template->append('head_elements', $googleload);
+  }
+
+} //class
+
+?>
Index: /extensions/GrumPluginClasses/classes/GPCUsersGroups.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/GPCUsersGroups.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/GPCUsersGroups.class.inc.php	(revision 5550)
@@ -0,0 +1,307 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name: GPCAllowedAccess, GPCGroups, GPCUsers
+  class version  : 2.0.0
+  plugin version : 3.0.0
+  date           : 2010-03-30
+  ------------------------------------------------------------------------------
+  author: grum at piwog.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+   this classes provides base functions to manage users/groups access
+  groups and users classes extends GPCAllowedAccess classes
+
+    - constructor GPCAllowedAccess($alloweds="")
+    - constructor groups($alloweds="")
+    - constructor users($alloweds="")
+    - (public) function getList()
+    - (public) function setAllowed($id, $allowed)
+    - (public) function setAlloweds()
+    - (public) function getAlloweds($return_type)
+    - (public) function isAllowed($id)
+    - (public) function htmlView($sep=", ", $empty="")
+    - (public) function htmlForm($basename)
+    - (private) function initList()
+
+
+| release | date       |
+| 1.1.0   | 2009/11/29 | * add 'webmaster' status for users
+|         |            |
+| 2.0.0   | 2010/03/28 | * Uses piwigo pwg_db_* functions instead of mysql_*
+|         |            |   functions
+|         |            | * update classes & functions names
+|         |            |
+|         |            |
+
+   ---------------------------------------------------------------------- */
+class GPCAllowedAccess
+{
+  public $access_list;
+
+  /*
+    constructor initialize the groups_getListgetListlist
+  */
+  public function __construct($alloweds = "")
+  {
+    $this->initList();
+    $this->setAlloweds($alloweds);
+  }
+
+  public function __destruct()
+  {
+    unset($this->access_list);
+  }
+
+  /*
+    initialize the groups list
+  */
+  protected function initList()
+  {
+    $this->access_list=array();
+  }
+
+  /*
+    returns list (as an array)
+  */
+  function getList()
+  {
+    return($this->access_list);
+  }
+
+  /*
+    set element an allowed state
+  */
+  function setAllowed($id, $allowed)
+  {
+    if(isset($this->access_list[$id]))
+    {
+      $this->access_list[$id]['allowed']=$allowed;
+    }
+  }
+
+  /*
+    set a group enabled/disabled state
+  */
+  function setState($id, $enabled)
+  {
+    if(isset($this->access_list[$id]))
+    {
+      $this->access_list[$id]['enabled']=$enabled;
+    }
+  }
+
+  /*
+    set alloweds list
+    $list is string of id, separated with "/"
+  */
+  function setAlloweds($list)
+  {
+    $alloweds=explode("/", $list);
+    $alloweds=array_flip($alloweds);
+    foreach($this->access_list as $key => $val)
+    {
+      if(isset($alloweds[$key]))
+      {
+        $this->access_list[$key]['allowed']=true;
+      }
+      else
+      {
+        $this->access_list[$key]['allowed']=false;
+      }
+    }
+  }
+
+  /*
+    get alloweds list
+    return a string of groups, separated with "/"
+  */
+  function getAlloweds($return_type = 'name')
+  {
+    $returned="";
+    foreach($this->access_list as $key => $val)
+    {
+      if($val['allowed'])
+      { $returned.=$val[$return_type]."/"; }
+    }
+    return($returned);
+  }
+
+
+  /*
+    returns true if is allowed
+  */
+  function isAllowed($id)
+  {
+    if(isset($this->access_list[$id]))
+    { return($this->access_list[$id]['allowed']); }
+    else
+    { return(false); }
+  }
+
+  /*
+    returns true if all or one is allowed
+      ids is an array
+  */
+  function areAllowed($ids, $all=false)
+  {
+    foreach($ids as $val)
+    {
+      if($all)
+      {
+        if(!$this->isAllowed($val))
+        {
+          return(false);
+        }
+      }
+      else
+      {
+        if($this->isAllowed($val))
+        {
+          return(true);
+        }
+      }
+    }
+    return(false);
+  }
+
+  /*
+    returns an HTML list with label rather than id
+  */
+  function htmlView($sep=", ", $empty="")
+  {
+    $returned="";
+    foreach($this->access_list as $key => $val)
+    {
+      if($val['allowed'])
+      {
+        if($returned!="")
+        {
+          $returned.=$sep;
+        }
+        $returned.=$val['name'];
+      }
+    }
+    if($returned=="")
+    {
+      $returned=$empty;
+    }
+    return($returned);
+  }
+  /*
+    returns a generic HTML form to manage the groups access
+  */
+  function htmlForm($basename)
+  {
+    /*
+    <!-- BEGIN allowed_group_row -->
+    <label><input type="checkbox" name="fmypolls_att_allowed_groups_{allowed_group_row.ID}" {allowed_group_row.CHECKED}/>&nbsp;{allowed_group_row.NAME}</label>
+    <!-- END allowed_group_row -->
+    */
+    $text='';
+    foreach($this->access_list as $key => $val)
+    {
+      if($val['allowed'])
+      {
+        $checked=' checked';
+      }
+      else
+      {
+        $checked='';
+      }
+
+      if($val['enabled'])
+      {
+        $enabled='';
+      }
+      else
+      {
+        $enabled=' disabled';
+      }
+
+      $text.='<label><input type="checkbox" name="'.$basename.$val['id'].'" '.$checked.$enabled.'/>
+          &nbsp;'.$val['name'].'</label>&nbsp;';
+    }
+    return($text);
+  }
+} //GPCAllowedAccess
+
+
+
+
+
+
+
+
+/* ----------------------------------------------------------------------
+   this class provides base functions to manage groups access
+    initList redefined to initialize access_list from database GROUPS
+   ---------------------------------------------------------------------- */
+class GPCGroups extends GPCAllowedAccess
+{
+  /*
+    initialize the groups list
+  */
+  protected  function initList()
+  {
+    $this->access_list=array();
+    $sql="SELECT id, name FROM ".GROUPS_TABLE." ORDER BY name";
+    $result=pwg_query($sql);
+    if($result)
+    {
+      while($row=pwg_db_fetch_assoc($result))
+      {
+        $this->access_list[$row['id']] =
+                   array('id' => $row['id'],
+                         'name' => $row['name'],
+                         'allowed' => false,
+                         'enabled' => true);
+      }
+    }
+  }
+}
+
+
+
+
+
+
+
+
+/* -----------------------------------------------------------------------------
+   this class provides base functions to manage users access
+----------------------------------------------------------------------------- */
+class GPCUsers extends GPCAllowedAccess
+{
+  /*
+    constructor
+  */
+  public function __construct($alloweds = "")
+  {
+    parent::__construct($alloweds);
+    $this->setState('admin', false);
+    $this->setAllowed('admin', true);
+  }
+
+  /*
+    initialize the groups list
+  */
+  protected function initList()
+  {
+    $users_list = array('guest', 'generic', 'normal', 'webmaster', 'admin');
+    $this->access_list=array();
+    foreach($users_list as $val)
+    {
+      $this->access_list[$val] =
+                  array('id' => $val,
+                        'name' => l10n('user_status_'.$val),
+                        'allowed' => false,
+                        'enabled' => true);
+    }
+  }
+} //class users
+
+
+
+?>
Index: /extensions/GrumPluginClasses/classes/genericjs.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/classes/genericjs.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/classes/genericjs.class.inc.php	(revision 5550)
@@ -0,0 +1,41 @@
+<?php
+
+/* -----------------------------------------------------------------------------
+  class name: genericjs
+  class version: 2.0
+  date: 2008-07-20
+  ------------------------------------------------------------------------------
+  author: grum at grum.dnsalias.com
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+   this classes provides base functions to add genericjs.js file into html page
+
+   > see genericjs.js file to know javascript functions added 
+
+    - constructor genericjs()
+   ---------------------------------------------------------------------- */
+
+
+class genericjs
+{
+  function genericjs()
+  {
+    add_event_handler('loc_end_page_header', array(&$this, 'load_JS'));
+  }
+
+  function load_JS()
+  {
+    global $template;
+
+    $name='plugins/'.basename(dirname(__FILE__)).'/genericjs.js';
+
+    $template->append('head_elements', '<script src="'.$name.'" type="text/javascript"></script>');
+
+  }
+
+} //class
+
+$genericjs=new genericjs();
+
+?>
Index: /extensions/GrumPluginClasses/gpc.css
===================================================================
--- /extensions/GrumPluginClasses/gpc.css	(revision 5550)
+++ /extensions/GrumPluginClasses/gpc.css	(revision 5550)
@@ -0,0 +1,13 @@
+
+.StatTableRow:hover { background-color:#; }
+.formtable, .formtable P { text-align:left; display:block; }
+.formtable tr { vertical-align:top; }
+.invisible { visibility:hidden; display:none; }
+.littlefont { font-size:90%; }
+table.table2.littlefont td { text-align:center;padding:0px;padding-left:3px;padding-right:3px; }
+.throw { line-height:auto; font-size:100%; }
+table.table2 tr.throw { height:26px; }
+table.table2 td.toLeft  { text-align:left; }
+div.table { margin-bottom:15px; }
+pointerHand { cursor:pointer; }
+    
Index: /extensions/GrumPluginClasses/gpc_aim.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/gpc_aim.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/gpc_aim.class.inc.php	(revision 5550)
@@ -0,0 +1,102 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Grum Plugin Classes - 3
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  UserStat_AIM : classe to manage plugin integration into plugin menu
+
+  --------------------------------------------------------------------------- */
+
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php');
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCCss.class.inc.php');
+
+class GPC_AIM extends CommonPlugin
+{
+  protected $css = null;
+
+  public function __construct($prefixeTable, $filelocation)
+  {
+    $this->setPluginName("Grum Plugin Classes");
+    $this->setPluginNameFiles("gpc");
+    parent::__construct($prefixeTable, $filelocation);
+    $this->css = new GPCCss(dirname($this->getFileLocation()).'/'.$this->getPluginNameFiles().".css");
+  }
+
+  public function __destruct()
+  {
+    unset($this->css);
+    parent::__destruct();
+  }
+
+  /*
+    initialize events call for the plugin
+  */
+  function initEvents()
+  {
+    add_event_handler('get_admin_plugin_menu_links', array(&$this, 'pluginAdminMenu') );
+  }
+
+  /*
+    surchage of CommonPlugin->saveConfig function
+  */
+  function loadConfig()
+  {
+    parent::loadConfig();
+    if(!$this->css->fileExists())
+    {
+      $this->css->makeCSS($this->generate_CSS());
+    }
+  }
+
+  /*
+    surchage of CommonPlugin->saveConfig function
+  */
+  function saveConfig()
+  {
+    if(parent::saveConfig())
+    {
+      $this->css->makeCSS($this->generate_CSS());
+      return(true);
+    }
+    return(false);
+  }
+
+  /*
+    generate the css code
+  */
+  function generate_CSS()
+  {
+    $text = "
+.formtable, .formtable P { text-align:left; display:block; }
+.formtable tr { vertical-align:top; }
+.invisible { visibility:hidden; display:none; }
+.littlefont { font-size:90%; }
+table.table2.littlefont td { text-align:center;padding:0px;padding-left:3px;padding-right:3px; }
+.throw { line-height:auto; font-size:100%; }
+table.table2 tr.throw { height:26px; }
+table.table2 td.toLeft  { text-align:left; }
+div.table { margin-bottom:15px; }
+pointerHand { cursor:pointer; }
+    ";
+
+    return($text);
+  }
+
+  /* ---------------------------------------------------------------------------
+  Function needed for plugin activation
+  --------------------------------------------------------------------------- */
+
+
+
+} // GPC_AIM class
+
+
+?>
Index: /extensions/GrumPluginClasses/gpc_aip.class.inc.php
===================================================================
--- /extensions/GrumPluginClasses/gpc_aip.class.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/gpc_aip.class.inc.php	(revision 5550)
@@ -0,0 +1,105 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Grum Plugin Classes - 3
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  AI classe => manage integration in administration interface
+
+  --------------------------------------------------------------------------- */
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+
+include_once('gpc_aim.class.inc.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCCore.class.inc.php');
+
+class GPC_AIP extends GPC_AIM
+{
+  protected $tabsheet;
+
+  public function __construct($prefixeTable, $filelocation)
+  {
+    parent::__construct($prefixeTable, $filelocation);
+
+    $this->loadConfig();
+    $this->initEvents();
+
+    $this->tabsheet = new tabsheet();
+    $this->tabsheet->add('infos',
+                          l10n('Infos'),
+                          '');
+  }
+
+  public function __destruct()
+  {
+    parent::__destruct();
+  }
+
+  /*
+    initialize events call for the plugin
+  */
+  function initEvents()
+  {
+    add_event_handler('loc_end_page_header', array(&$this->css, 'applyCSS'));
+  }
+
+
+  /* ---------------------------------------------------------------------------
+  Public classe functions
+  --------------------------------------------------------------------------- */
+
+  /*
+    manage plugin integration into piwigo's admin interface
+  */
+  public function manage()
+  {
+    global $template;
+
+    $template->set_filename('plugin_admin_content', dirname(__FILE__)."/admin/gpc_admin.tpl");
+
+    $this->displayStats();
+
+    $this->tabsheet->select('infos');
+    $this->tabsheet->assign();
+    $selected_tab=$this->tabsheet->get_selected();
+    $template->assign($this->tabsheet->get_titlename(), "[".$selected_tab['caption']."]");
+
+    $template_plugin["GPC_VERSION"] = "<i>".$this->getPluginName()."</i> ".l10n('version').GPC_VERSION;
+
+    $template->assign('plugin', $template_plugin);
+    $template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
+  }
+
+  /* ---------------------------------------------------------------------------
+  Private classe functions
+  --------------------------------------------------------------------------- */
+
+
+  private function displayStats()
+  {
+    global $template;
+
+    $template->set_filename('body_page', dirname(__FILE__)."/admin/gpc_infos.tpl");
+
+    $template_datas = array();
+
+    $template_datas['modules']=GPCCore::getModulesInfos();
+    $template_datas['plugins']=GPCCore::getRegistered();
+
+    $template->assign('datas', $template_datas);
+    $template->assign_var_from_handle('GPC_BODY_PAGE', 'body_page');
+  }
+
+  /* ---------------------------------------------------------------------------
+   * AJAX functions
+   * ------------------------------------------------------------------------- */
+
+} // GPC_AIP class
+
+
+?>
Index: /extensions/GrumPluginClasses/gpc_version.inc.php
===================================================================
--- /extensions/GrumPluginClasses/gpc_version.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/gpc_version.inc.php	(revision 5550)
@@ -0,0 +1,19 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : GPC3
+  Author     : Grum
+    email    : grum@grum.fr
+    website  : http://photos.grum.fr
+    PWG user : http://forum.piwigo.org/profile.php?id=3706
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  if(!defined('GPC_VERSION')) define('GPC_VERSION',  '3.0.0');
+  if(!defined('GPC_VERSION2')) define('GPC_VERSION2', '03.03.00');
+?>
Index: /extensions/GrumPluginClasses/index.php
===================================================================
--- /extensions/GrumPluginClasses/index.php	(revision 5550)
+++ /extensions/GrumPluginClasses/index.php	(revision 5550)
@@ -0,0 +1,33 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $
+// | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $
+// | last modifier : $Author: rub $
+// | revision      : $Revision: 1912 $
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /extensions/GrumPluginClasses/js/genericjs.js
===================================================================
--- /extensions/GrumPluginClasses/js/genericjs.js	(revision 5550)
+++ /extensions/GrumPluginClasses/js/genericjs.js	(revision 5550)
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------------------
+  file: genricjs.js
+  file version: 1.0
+  date: 2008-01-02
+  ------------------------------------------------------------------------------
+  author: grum at grum.dnsalias.com
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+
+  this classes provides base functions to make easiest a compliant code with
+  FF2.0 & IE7.0
+  
+
+  ------------------------------------------------------------------------------
+  HISTORY VERSION
+              
+   -------------------------------------------------------------------------- */
+
+
+
+/*
+  this is an implementation of the function <indexOf> to the Array class, as
+  defined in the ECMA-262 standard
+  for more information, see at http://developer.mozilla.org/fr/docs/R%C3%A9f%C3%A9rence_de_JavaScript_1.5_Core:Objets_globaux:Array:indexOf
+
+  not implemented in IE 7.0
+*/
+if (!Array.prototype.indexOf)
+{
+  Array.prototype.indexOf = function(elt /*, from*/)
+  {
+    var len = this.length;
+
+    var from = Number(arguments[1]) || 0;
+    from = (from < 0)
+         ? Math.ceil(from)
+         : Math.floor(from);
+    if (from < 0)
+      from += len;
+
+    for (; from < len; from++)
+    {
+      if (from in this &&
+          this[from] === elt)
+        return from;
+    }
+    return -1;
+  };
+}
Index: /extensions/GrumPluginClasses/js/google_translate.js
===================================================================
--- /extensions/GrumPluginClasses/js/google_translate.js	(revision 5550)
+++ /extensions/GrumPluginClasses/js/google_translate.js	(revision 5550)
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+  file: google_translate.js
+  file version: 2.0.0
+  date: 2008-05-25
+  ------------------------------------------------------------------------------
+  author: grum at piwigo.org
+  << May the Little SpaceFrog be with you >>
+  ------------------------------------------------------------------------------
+   this classes provides base functions to use Google Translate AJAX API
+    >>  http://code.google.com/apis/ajaxlanguage/
+  ------------------------------------------------------------------------------
+  HISTORY VERSION
+  v2.0.0  +
+  --------------------------------------------------------------------------- */
+
+  google.load("language", "1");
+
+  var global_google_translate_plugin_objdest;
+  var global_google_translate_plugin_objproperty;
+
+  function google_translate(text, pfrom, pto, objdest, objproperty)
+  {
+    global_google_translate_plugin_objdest = objdest;
+    global_google_translate_plugin_objproperty = objproperty;
+    google.language.translate(text, pfrom, pto, google_translate_do);
+  }
+
+  function google_translate_do(result)
+  {
+    if (!result.error)
+    {
+      if(global_google_translate_plugin_objproperty=='value')
+      {
+        global_google_translate_plugin_objdest.value = result.translation;
+      }
+      else if(global_google_translate_plugin_objproperty=='innerHTML')
+      {
+        global_google_translate_plugin_objdest.innerHTML = result.translation;
+      }
+    }
+  }
Index: /extensions/GrumPluginClasses/language/en_UK/description.txt
===================================================================
--- /extensions/GrumPluginClasses/language/en_UK/description.txt	(revision 5550)
+++ /extensions/GrumPluginClasses/language/en_UK/description.txt	(revision 5550)
@@ -0,0 +1,1 @@
+Classes shared between plugins
Index: /extensions/GrumPluginClasses/language/fr_FR/description.txt
===================================================================
--- /extensions/GrumPluginClasses/language/fr_FR/description.txt	(revision 5550)
+++ /extensions/GrumPluginClasses/language/fr_FR/description.txt	(revision 5550)
@@ -0,0 +1,1 @@
+Classes partagées entre les plugins
Index: /extensions/GrumPluginClasses/language/fr_FR/plugin.lang.php
===================================================================
--- /extensions/GrumPluginClasses/language/fr_FR/plugin.lang.php	(revision 5550)
+++ /extensions/GrumPluginClasses/language/fr_FR/plugin.lang.php	(revision 5550)
@@ -0,0 +1,12 @@
+<?php
+
+$lang['Module'] = 'Module';
+$lang['Version'] = 'Version';
+$lang['List of shared modules'] = 'Liste des modules partagés';
+$lang['List of installed plugins using Grum Plugin Classes'] = 'Liste des plugins installés et utilisant Grum Plugin Classes';
+$lang['Plugin'] = 'Plugin';
+$lang['GPC required'] = 'GPC requis';
+$lang['Installed'] = 'Installé le';
+$lang['Infos'] = 'Informations';
+
+?>
Index: /extensions/GrumPluginClasses/main.inc.php
===================================================================
--- /extensions/GrumPluginClasses/main.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/main.inc.php	(revision 5550)
@@ -0,0 +1,82 @@
+<?php
+/*
+Plugin Name: Grum Plugins Classes.3
+Version: 3.0.0
+Description: Collection de classes partagées entre mes plugins (existants, ou à venir) / Partaged classes between my plugins (actuals or futures)
+Plugin URI: http://phpwebgallery.net/ext/extension_view.php?eid=199
+Author: grum@piwigo.org
+Author URI: http://photos.grum.fr/
+*/
+
+/*
+--------------------------------------------------------------------------------
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+    PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
+
+    << May the Little SpaceFrog be with you ! >>
+--------------------------------------------------------------------------------
+
+:: HISTORY
+
+| release | date       |
+| 2.0.0   | 2008/07/20 | * convert classes for piwigo 2.0
+|         |            |
+| 2.0.1   | 2008/12/28 | * convert classe tables.class.inc to php5
+|         |            |
+| 2.0.2   | 2009/04/26 | * add setOptions/getOptions for GPCPagesNavigation class
+|         |            | * add option to set first/prev/next/last textes
+|         |            |
+| 2.0.3   | 2009/07/24 | * modify common_plugin class config loader (r2.0.1)
+|         |            |
+| 2.0.4   | 2009/11/29 | * modify users class
+|         |            |
+| 3.0.0   | 2010/03/28 | * Uses piwigo pwg_db_* functions instead of mysql_* functions
+|         |            | * update classes & functions names
+|         |            | * include the JpegMetaData class
+|         |            |
+|         |            |
+
+
+:: TO DO
+
+:: WHAT ? WHY ?
+This plugin doesn't do anything itself. It just provide classes for others plugins.
+
+Classes version for this package
+    CommonPlugin.class.php
+    GPCAjax.class.php
+    GPCCss.class.php
+    GPCPagesNavigation.class.php
+    GPCPublicIntegration.class.php
+    GPCTables.class.php -v1.5
+    GPCTranslate.class.inc.php + google_translate.js
+    GPCUsersGroups.class.inc.php
+
+    genericjs.class.inc.php  + genericjs.js
+
+See each file to know more about them
+--------------------------------------------------------------------------------
+*/
+
+if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+define('GPC_DIR' , basename(dirname(__FILE__)));
+define('GPC_PATH' , PHPWG_PLUGINS_PATH . GPC_DIR . '/');
+
+include_once('gpc_version.inc.php'); // => Don't forget to update this file !!
+
+global $prefixeTable;
+
+//GPC admin interface is loaded and active only if in admin page
+if(basename($_SERVER["PHP_SELF"])=='admin.php')
+{
+  include_once("gpc_aim.class.inc.php");
+
+  $obj = new GPC_AIM($prefixeTable, __FILE__);
+  $obj->initEvents();
+  set_plugin_data($plugin['id'], $obj);
+}
+
+?>
Index: /extensions/GrumPluginClasses/maintain.inc.php
===================================================================
--- /extensions/GrumPluginClasses/maintain.inc.php	(revision 5550)
+++ /extensions/GrumPluginClasses/maintain.inc.php	(revision 5550)
@@ -0,0 +1,29 @@
+<?php
+
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+
+// ini_set('error_reporting', E_ALL);
+// ini_set('display_errors', true);
+
+include_once('gpc_version.inc.php'); // => Don't forget to update this file !!
+
+
+
+function plugin_install($plugin_id, $plugin_version, &$errors)
+{
+}
+
+function plugin_activate($plugin_id, $plugin_version, &$errors)
+{
+}
+
+function plugin_deactivate($plugin_id)
+{
+}
+
+function plugin_uninstall($plugin_id)
+{
+}
+
+
+?>
