Index: extensions/AMenuManager/amm_pip.class.inc.php
===================================================================
--- extensions/AMenuManager/amm_pip.class.inc.php	(revision 5545)
+++ extensions/AMenuManager/amm_pip.class.inc.php	(revision 8962)
@@ -22,4 +22,9 @@
 {
   protected $displayRandomImageBlock=true;
+  protected $registeredBlocks;
+  protected $randomPictProp=null;
+  protected $users;
+  protected $groups;
+  protected $currentBuiltMenu=-1;
 
   function AMM_PIP($prefixeTable, $filelocation)
@@ -28,4 +33,7 @@
     $this->css = new GPCCss(dirname($this->getFileLocation()).'/'.$this->getPluginNameFiles()."2.css");
 
+    $this->users=new GPCUsers();
+    $this->groups=new GPCGroups();
+
     $this->loadConfig();
     $this->initEvents();
@@ -33,54 +41,60 @@
 
 
-  /* ---------------------------------------------------------------------------
-  Public classe functions
-  --------------------------------------------------------------------------- */
-
-
-  /*
-    initialize events call for the plugin
-  */
+  /**
+   * initialize events call for the plugin
+   */
   public function initEvents()
   {
-    //TODELETE: add_event_handler('loc_begin_menubar', array(&$this, 'modify_menu') );
     parent::initEvents();
-    add_event_handler('loading_lang', array(&$this, 'load_lang'));
-    add_event_handler('blockmanager_apply', array(&$this, 'blockmanager_apply') );
+
+    add_event_handler('blockmanager_prepare_display', array(&$this, 'blockmanagerSortBlocks') );
+    add_event_handler('blockmanager_apply', array(&$this, 'blockmanagerApply') );
     add_event_handler('loc_end_page_header', array(&$this->css, 'applyCSS'));
-    add_event_handler('loc_end_page_tail', array(&$this, 'applyJS'));
-  }
-
-  /*
-    load language file
-  */
-  public function load_lang()
-  {
-    global $lang;
-
-    //load_language('plugin.lang', AMM_PATH);
-
-    // ajax is managed here ; this permit to use user&language properties inside
-    // ajax content
-    $this->return_ajax_content();
-  }
-
-  public function blockmanager_apply( $menu_ref_arr )
-  {
-    global $user, $page;
-    $menu = & $menu_ref_arr[0];
-
-
-    /*
-      Add a new random picture section
-    */
-    if ( ( ($block = $menu->get_block( 'mbAMM_randompict' ) ) != null ) && ($user['nb_total_images'] > 0) )
-    {
-      $block->set_title(  base64_decode($this->config['amm_randompicture_title'][$user['language']]) );
-      $block->data = array(
-        "delay" => $this->config['amm_randompicture_periodicchange'],
-        "blockHeight" => $this->config['amm_randompicture_height'],
-        "firstPicture" => $this->ajax_amm_get_random_picture()
+    add_event_handler('loc_end_page_header', array(&$this, 'applyJS'));
+    add_event_handler('get_categories_menu_sql_where', array(&$this, 'buildMenuFromCat'), 75);
+  }
+
+
+  public function blockmanagerApply($menu_ref_arr)
+  {
+    $menu=&$menu_ref_arr[0];
+
+    $this->addBlockRandomPicture($menu);
+    $this->addBlockLinks($menu);
+    $this->addBlockPersonnal($menu);
+    $this->addBlockAlbum($menu);
+    $this->manageBlocksContent($menu);
+    $this->manageBlocks($menu);
+  }
+
+
+  /**
+   * Add a new random picture block
+   */
+  private function addBlockRandomPicture(&$menu)
+  {
+    global $user;
+
+    if((
+        ($block=$menu->get_block('mbAMM_randompict'))!=null) and
+        ($user['nb_total_images']>0) and
+        isset($this->config['amm_randompicture_title'][$user['language']])
+      )
+    {
+      GPCCore::addHeaderJS('jquery', 'themes/default/js/jquery.packed.js');
+      GPCCore::addHeaderJS('amm.randomPictPublic', 'plugins/AMenuManager/js/amm_randomPictPublic'.GPCCore::getMinified().'.js');
+
+      $block->set_title(base64_decode($this->config['amm_randompicture_title'][$user['language']]));
+      $block->template=dirname(__FILE__).'/menu_templates/menubar_randompic.tpl';
+
+      $this->randomPictProp = array(
+        'delay' => $this->config['amm_randompicture_periodicchange'],
+        'blockHeight' => $this->config['amm_randompicture_height'],
+        'showname' => $this->config['amm_randompicture_showname'],
+        'showcomment' => $this->config['amm_randompicture_showcomment'],
+        'pictures' => $this->getRandomPictures($this->config['amm_randompicture_preload'])
       );
-      $block->template = dirname(__FILE__).'/menu_templates/menubar_randompic.tpl';
+
+      if(count($this->randomPictProp['pictures'])==0) $this->displayRandomImageBlock=false;
     }
     else
@@ -88,23 +102,56 @@
       $this->displayRandomImageBlock=false;
     }
-
-    /*
-      Add a new section (links)
-    */
-    if ( ($block = $menu->get_block( 'mbAMM_links' ) ) != null )
-    {
-      $urls=$this->get_urls(true);
-      if ( count($urls)>0 )
-      {
+  }
+
+
+  /**
+   * Add a new block (links)
+   */
+  private function addBlockLinks(&$menu)
+  {
+    global $user;
+
+    $nbLink=0;
+
+    if(($block=$menu->get_block('mbAMM_links'))!=null &&
+       isset($this->config['amm_links_title'][$user['language']])
+      )
+    {
+      $urls=$this->getLinks(true);
+
+      if(count($urls)>0)
+      {
+        $userGroups=$this->getUserGroups($user['id']);;
+
+        foreach($urls as $key => $val)
+        {
+          $this->users->setAlloweds(explode(",", $val['accessUsers']), false);
+          $this->groups->setAlloweds(explode(",", $val['accessGroups']), false);
+
+          if(!$this->users->isAllowed($user['status']))
+          {
+            unset($urls[$key]);
+          }
+          else
+          {
+            $ok=true;
+            foreach($userGroups as $group)
+            {
+              if(!$this->groups->isAllowed($group)) $ok=false;
+            }
+            if(!$ok) unset($urls[$key]);
+          }
+        }
+
         if($this->config['amm_links_show_icons']=='y')
         {
-          for($i=0;$i<count($urls);$i++)
+          foreach($urls as $key => $url)
           {
-            $urls[$i]['icon']=get_root_url().'plugins/'.AMM_DIR."/links_pictures/".$urls[$i]['icon'];
+            $urls[$key]['icon']=get_root_url().'plugins/'.AMM_DIR."/links_pictures/".$url['icon'];
           }
         }
 
-        $block->set_title( base64_decode($this->config['amm_links_title'][$user['language']]) );
-        $block->template = dirname(__FILE__).'/menu_templates/menubar_links.tpl';
+        $block->set_title(base64_decode($this->config['amm_links_title'][$user['language']]));
+        $block->template=dirname(__FILE__).'/menu_templates/menubar_links.tpl';
 
         $block->data = array(
@@ -114,39 +161,88 @@
       }
     }
-
-    /*
-      Add personnal blocks random picture section
-    */
-    $sections=$this->get_sections(true);
+  }
+
+
+  /**
+   * Add personnal blocks
+   */
+  private function addBlockPersonnal(&$menu)
+  {
+    $sections=$this->getPersonalisedBlocks(true);
 
     if(count($sections))
     {
-      $id_done=array();
+      $idDone=array();
       foreach($sections as $key => $val)
       {
-        if(!isset($id_done[$val['id']]))
+        if(!isset($idDone[$val['id']]))
         {
-          if ( ($block = $menu->get_block( 'mbAMM_personalised'.$val['id'] ) ) != null )
+          if(($block=$menu->get_block('mbAMM_personalised'.$val['id']))!= null)
           {
-            $block->set_title( $val['title'] );
+            $block->set_title($val['title']);
             $block->template = dirname(__FILE__).'/menu_templates/menubar_personalised.tpl';
             $block->data = stripslashes($val['content']);
           }
-          $id_done[$val['id']]="";
+          $idDone[$val['id']]="";
         }
       }
     }
-
-
-    /* manage items from special & menu sections
-     *  reordering items
-     *  grouping items
-     *  managing rights to access
-    */
+  }
+
+
+
+
+  /**
+   * Add album to menu
+   */
+  private function addBlockAlbum(&$menu)
+  {
+    if(count($this->config['amm_albums_to_menu'])>0)
+    {
+      $sql="SELECT id, name, permalink, global_rank
+            FROM ".CATEGORIES_TABLE."
+            WHERE id IN(".implode(',', $this->config['amm_albums_to_menu']).");";
+
+      $result=pwg_query($sql);
+      if($result)
+      {
+        while($row=pwg_db_fetch_assoc($result))
+        {
+          $this->currentBuiltMenu=$row['id'];
+
+          $row['name']=trigger_event('render_category_name', $row['name'], 'amm_album_to_menu');
+
+          if(($block=$menu->get_block('mbAMM_album'.$row['id']))!= null)
+          {
+            $block->set_title($row['name']);
+            $block->template = dirname(__FILE__).'/menu_templates/menubar_album.tpl';
+            $block->data = array(
+              'album' => get_categories_menu(),
+              'name' => $row['name'],
+              'link' => make_index_url(array('category' => $row)),
+              'nbPictures' => ''
+            );
+          }
+        }
+      }
+      $this->currentBuiltMenu=-1;
+    }
+  }
+
+  /**
+   * manage items from special & menu blocks
+   *  - reordering items
+   *  - grouping items
+   *  - managing rights to access
+   */
+  private function manageBlocksContent(&$menu)
+  {
+    global $user;
+
     $blocks=Array();
 
     if($menu->is_hidden('mbMenu'))
     {
-      // if block is hidden, make a fake to manage AMM features
+      // if block is hidden, make a fake to manage AMM submenu features
       // the fake block isn't displayed
       $blocks['menu']=new DisplayBlock('amm_mbMenu');
@@ -160,5 +256,5 @@
     if($menu->is_hidden('mbSpecials'))
     {
-      // if block is hidden, make a fake to manage AMM features
+      // if block is hidden, make a fake to manage AMM submenu features
       // the fake block isn't displayed
       $blocks['special']=new DisplayBlock('amm_mbSpecial');
@@ -171,30 +267,30 @@
 
     $menuItems=array_merge($blocks['menu']->data, $blocks['special']->data);
-    $this->sortSectionsItems();
+    $this->sortCoreBlocksItems();
 
     $blocks['menu']->data=Array();
     $blocks['special']->data=Array();
-
-    $users=new GPCUsers("");
-    $groups=new GPCGroups("");
-    $user_groups=$this->get_user_groups($user['id']);
-
-    foreach($this->config['amm_sections_items'] as $key => $val)
+    $userGroups=$this->getUserGroups($user['id']);
+
+    foreach($this->config['amm_blocks_items'] as $key => $val)
     {
       if(isset($menuItems[$key]))
       {
         $access=explode("/",$val['visibility']);
-        $users->setAlloweds(str_replace(",", "/", $access[0]));
-        $groups->setAlloweds(str_replace(",", "/", $access[1]));
-
-        /* test if user status is allowed to access the menu item
+        $this->users->setAlloweds(str_replace(",", "/", $access[0]), false);
+        $this->groups->setAlloweds(str_replace(",", "/", $access[1]), false);
+
+        /*
+         * test if user status is allowed to access the menu item
          * if access is managed by group, the user have to be associated with an allowed group to access the menu item
-        */
-        if($users->isAllowed($user['status']) && (
-            ($access[1]=='') ||
-            (($access[1]!='') && $groups->areAllowed($user_groups)))
-        )
+         */
+        if($this->users->isAllowed($user['status']))
         {
-          $blocks[$val['container']]->data[$key]=$menuItems[$key];
+          $ok=true;
+          foreach($userGroups as $group)
+          {
+            if(!$this->groups->isAllowed($group)) $ok=false;
+          }
+          if($ok) $blocks[$val['container']]->data[$key]=$menuItems[$key];
         }
       }
@@ -205,9 +301,17 @@
 
 
-  protected function get_user_groups($user_id)
-  {
+  /**
+   * return groups for a user
+   *
+   * @param String $userId
+   * @return Array
+   */
+  private function getUserGroups($userId)
+  {
+    global $user;
+
     $returned=array();
-    $sql="SELECT group_id FROM ".USER_GROUP_TABLE."
-          WHERE user_id = ".$user_id." ";
+
+    $sql="SELECT group_id FROM ".USER_GROUP_TABLE." WHERE user_id='".$user['id']."';";
     $result=pwg_query($sql);
     if($result)
@@ -215,5 +319,5 @@
       while($row=pwg_db_fetch_assoc($result))
       {
-        array_push($returned, $row['group_id']);
+        $returned[]=$row['group_id'];
       }
     }
@@ -221,80 +325,125 @@
   }
 
-  /*
-    return ajax content
-  */
-  protected function return_ajax_content()
-  {
-    global $ajax, $template;
-
-    if(isset($_REQUEST['ajaxfct']))
-    {
-      if($_REQUEST['ajaxfct']=='randompic')
-      {
-        $result="<p class='errors'>".l10n('g002_error_invalid_ajax_call')."</p>";
-        switch($_REQUEST['ajaxfct'])
+
+  /**
+   * reordering blocks and manage access right
+   *
+   */
+  private function manageBlocks($menu)
+  {
+    $this->registeredBlocks=$this->getRegisteredBlocks(true);
+
+    foreach($menu->get_registered_blocks() as $key => $block)
+    {
+      if(!isset($this->registeredBlocks[$block->get_id()]))
+      {
+        $menu->hide_block($block->get_id());
+      }
+    }
+
+  }
+
+
+  /**
+   * sort menu blocks according to AMM rules (overriding piwigo's sort rules)
+   */
+  public function blockmanagerSortBlocks($blocks)
+  {
+    $this->registeredBlocks=$this->getRegisteredBlocks(true);
+
+    foreach($blocks[0]->get_registered_blocks() as $key => $block)
+    {
+      if(isset($this->registeredBlocks[$block->get_id()]))
+      {
+        $blocks[0]->set_block_position($block->get_id(), $this->registeredBlocks[$block->get_id()]['order']);
+      }
+    }
+  }
+
+
+
+
+
+
+
+  /**
+   * return a list of thumbnails
+   * each array items is an array
+   *  'imageId'   => (integer)
+   *  'imageFile' => (String)
+   *  'comment'   => (String)
+   *  'path'      => (String)
+   *  'tn_ext'    => (String)
+   *  'catId'     => (String)
+   *  'name'      => (String)
+   *  'permalink' => (String)
+   *  'imageName' => (String)
+   *
+   * @param Integer $number : number of returned images
+   * @return Array
+   */
+  private function getRandomPictures($num=25)
+  {
+    global $user;
+
+    $returned=array();
+
+    $sql=array();
+
+    $sql['select']="SELECT i.id as image_id, i.file as image_file, i.comment, i.path, i.tn_ext, c.id as catid, c.name, c.permalink, RAND() as rndvalue, i.name as imgname ";
+    $sql['from']="FROM ".CATEGORIES_TABLE." c, ".IMAGES_TABLE." i, ".IMAGE_CATEGORY_TABLE." ic ";
+    $sql['where']="WHERE c.id = ic.category_id
+            AND ic.image_id = i.id
+            AND i.level <= ".$user['level']." ";
+
+    if($user['forbidden_categories']!="")
+    {
+      $sql['where'].=" AND c.id NOT IN (".$user['forbidden_categories'].") ";
+    }
+
+    switch($this->config['amm_randompicture_selectMode'])
+    {
+      case 'f':
+        $sql['from'].=", ".USER_INFOS_TABLE." ui
+          LEFT JOIN ".FAVORITES_TABLE." f ON ui.user_id=f.user_id ";
+        $sql['where'].=" AND ui.status='webmaster'
+                         AND f.image_id = i.id ";
+        break;
+      case 'c':
+        $sql['where'].="AND (";
+        foreach($this->config['amm_randompicture_selectCat'] as $key => $val)
         {
-          case 'randompic':
-            $result=$this->ajax_amm_get_random_picture();
-            break;
+          $sql['where'].=($key==0?'':' OR ')." FIND_IN_SET($val, c.uppercats) ";
         }
-        GPCAjax::returnResult($result);
-      }
-    }
-  }
-
-
-  // return the html content for the random picture block
-  private function ajax_amm_get_random_picture()
-  {
-    global $user;
-
-    $local_tpl = new Template(AMM_PATH."menu_templates/", "");
-    $local_tpl->set_filename('body_page',
-                  dirname($this->getFileLocation()).'/menu_templates/menubar_randompic_inner.tpl');
-
-      $sql="SELECT i.id as image_id, i.file as image_file, i.comment, i.path, i.tn_ext, c.id as catid, c.name, c.permalink, RAND() as rndvalue, i.name as imgname
-            FROM ".CATEGORIES_TABLE." c, ".IMAGES_TABLE." i, ".IMAGE_CATEGORY_TABLE." ic
-            WHERE c.id = ic.category_id
-              AND ic.image_id = i.id
-              AND i.level <= ".$user['level']." ";
-      if($user['forbidden_categories']!="")
-      {
-        $sql.=" AND c.id NOT IN (".$user['forbidden_categories'].") ";
-      }
-
-      $sql.=" ORDER BY rndvalue
-            LIMIT 0,1";
-
-
-      $result = pwg_query($sql);
-      if($result and $nfo = pwg_db_fetch_assoc($result))
-      {
-        $nfo['section']='category';
-        $nfo['category']=array(
-          'id' => $nfo['catid'],
-          'name' => $nfo['name'],
-          'permalink' => $nfo['permalink']
+        $sql['where'].=") ";
+        break;
+    }
+
+    $sql=$sql['select'].$sql['from'].$sql['where']." ORDER BY rndvalue LIMIT 0,$num";
+
+
+    $result = pwg_query($sql);
+    if($result)
+    {
+      while($row=pwg_db_fetch_assoc($result))
+      {
+        $row['section']='category';
+        $row['category']=array(
+          'id' => $row['catid'],
+          'name' => $row['name'],
+          'permalink' => $row['permalink']
         );
 
-        $template_datas = array(
-          'LINK' => make_picture_url($nfo),
-          'IMG' => get_thumbnail_url($nfo),
-          'IMGNAME' => $nfo['imgname'],
-          'IMGCOMMENT' => $nfo['comment'],
-          'SHOWNAME' => $this->config['amm_randompicture_showname'],
-          'SHOWCOMMENT' => $this->config['amm_randompicture_showcomment']
-        );
-      }
-      else
-      {
-        $template_datas = array();
-      }
-
-    $local_tpl->assign('datas', $template_datas);
-    $local_tpl->assign('plugin', array('PATH' => AMM_PATH));
-
-    return($local_tpl->parse('body_page', true));
-  }
+        $row['link']=make_picture_url($row);
+        $row['thumb']=get_thumbnail_url($row);
+
+        $returned[]=$row;
+      }
+    }
+
+    return($returned);
+  }
+
+
 
 
@@ -315,4 +464,5 @@
     }
 
+
     if($this->displayRandomImageBlock && $page['body_id'] == 'theCategoryPage')
     {
@@ -320,15 +470,31 @@
       $local_tpl->set_filename('body_page', dirname($this->getFileLocation()).'/menu_templates/menubar_randompic.js.tpl');
 
-      $data = array(
-        "delay" => $this->config['amm_randompicture_periodicchange'],
-        "blockHeight" => $this->config['amm_randompicture_height'],
-        "firstPicture" => $this->ajax_amm_get_random_picture()
-      );
-
-      $local_tpl->assign('data', $data);
-
-      $template->append('footer_elements', $local_tpl->parse('body_page', true));
-    }
-
+      $local_tpl->assign('data', $this->randomPictProp);
+
+      $template->append('head_elements', $local_tpl->parse('body_page', true));
+    }
+  }
+
+
+
+  public function buildMenuFromCat($where)
+  {
+    global $user;
+
+    if($this->currentBuiltMenu>-1)
+    {
+      if($user['expand'])
+      {
+        $where=preg_replace('/id_uppercat\s+is\s+NULL/i', 'id_uppercat is NOT NULL', $where);
+      }
+      else
+      {
+        $where=preg_replace('/id_uppercat\s+is\s+NULL/i', 'id_uppercat is NULL OR id_uppercat IN ('.$this->currentBuiltMenu.')', $where);
+      }
+
+      $where.=" AND FIND_IN_SET(".$this->currentBuiltMenu.", uppercats) AND cat_id!=".$this->currentBuiltMenu." ";
+    }
+
+    return($where);
   }
 
