- Update HEAD to 5.x-2.0 release version
authorThilo Wawrzik
Fri, 23 Nov 2007 10:04:31 +0000 (10:04 +0000)
committerThilo Wawrzik
Fri, 23 Nov 2007 10:04:31 +0000 (10:04 +0000)
29 files changed:
CREDITS.txt [deleted file]
G2EmbedDiscoveryUtilities.class
G2EmbedTestUtilities.class [deleted file]
INSTALL.txt [deleted file]
README.txt
drupal_g2.css [deleted file]
g2image.js
gallery.css [new file with mode: 0755]
gallery.info
gallery.install [new file with mode: 0644]
gallery.module
gallery_base.inc
gallery_block.inc
gallery_filter.css
gallery_filter.inc
gallery_g2image.inc
gallery_groups.inc [new file with mode: 0644]
gallery_help.inc
gallery_install.inc [new file with mode: 0644]
gallery_menu/gallery_menu.info [new file with mode: 0644]
gallery_menu/gallery_menu.module [new file with mode: 0644]
gallery_profile/gallery_profile.info [new file with mode: 0644]
gallery_profile/gallery_profile.module [new file with mode: 0644]
gallery_report.inc [new file with mode: 0644]
gallery_roles.inc [deleted file]
gallery_search.inc
gallery_settings.inc
gallery_user.inc
gallery_user_admin.inc [new file with mode: 0644]

diff --git a/CREDITS.txt b/CREDITS.txt
deleted file mode 100644 (file)
index 0e9d206..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// $Id$
-
-kiz_0987:
-This gallery.module was based on original code by walkah. The gallery_filter part is almost
-entirely based on work by MichelleC and Waldemar. The g2image application is by capt_kirk. 
-Thanks for all your efforts.
-
-MichelleC (g2_filter):
-This module would not exist without image_filter by Eric Scouten (http://drupal.org/node/9707). I started with that module and transformed it bit by bit into this module. While there's not a lot of original code left, I wouldn't have been able to do this without using image_filter as a template.\r
-\r
-This module is dependent on Drupal (of course), Gallery 2, and the gallery.module (http://drupal.org/project/gallery) so thanks to everyone for all the work on those. Without them, this module would be useless. :)
\ No newline at end of file
index ab5fcdc..2ea50cb 100755 (executable)
@@ -1,7 +1,5 @@
 <?php
 /*
- * $RCSfile$
- *
  * Gallery - a web based photo album viewer and editor
  * Copyright (C) 2000-2006 Bharat Mediratta
  *
@@ -464,4 +462,5 @@ class G2EmbedDiscoveryUtilities {
        return true;
     }
 }
-?>
\ No newline at end of file
+
+?>
diff --git a/G2EmbedTestUtilities.class b/G2EmbedTestUtilities.class
deleted file mode 100755 (executable)
index 1e7c81e..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-<?php
-// $Id$
-
-/**
- * @version 
- * @package GalleryCore
- * @author Kieran Parsons
- */
-
-/**
- * A collection of useful G2Embed related utilities to test that all the required 
- * parameters and modules are correctly configures
- *
- * @package GalleryCore
- * @subpackage GalleryEmbed
- * @static
- */
-class G2EmbedTestUtilities {
-  
-  /**
-   * Validate the Gallery2 Embed variables
-   *
-   * Returns false if any test failed
-   * @param $orig, $autodetect
-   * @return array($gallery_valid, $new, $results)
-   */
-    function checkLocations($orig, $autodetect=true) {
-        $gallery_valid = 1;
-        // Normalise the G2 URI 
-        $g2Uri = G2EmbedDiscoveryUtilities::normalizeG2Uri($orig['g2Uri']); 
-        $new['g2Uri'] = $g2Uri;
-        if ($g2Uri != $orig['g2Uri']) {
-            $results['g2Uri']['title'] = G2EmbedTestUtilities::_trans('\'URI of Gallery2\' variable:');
-            $results['g2Uri']['advise'] = true;
-            $results['g2Uri']['notice'] = G2EmbedTestUtilities::_trans('%origG2Uri automatically updated to %g2Uri to adhere to Gallery2 requirements.',
-              array('%origG2Uri' => $orig['g2Uri'], '%g2Uri' => $g2Uri));
-        }
-        
-        // Find the Gallery Directory and Embed URI
-        if ($autodetect) {
-        // Auto-Detect the G2 embed path 
-        list ($success, $embedPhpPath, $errorString) = 
-            G2EmbedDiscoveryUtilities::getG2EmbedPathByG2Uri($g2Uri); 
-        if (!$success) {
-            // Something is wrong with the G2 URI given as the G2 embed path is not found
-            $results['g2Uri2']['title'] = G2EmbedTestUtilities::_trans('\'URI of Gallery2\' variable:');
-            $results['g2Uri2']['error'] = true;
-            $results['g2Uri2']['notice'] = $errorString;
-            $new['g2EmbedPath'] = rtrim($embedPhpPath, 'embed.php'); 
-            $gallery_valid = 0;
-        } else {
-            // G2 Embed Path is found OK
-            $results['g2Uri2']['title'] = G2EmbedTestUtilities::_trans('\'URI of Gallery2\' variable:');
-            $results['g2Uri2']['success'] = true;
-            $new['g2EmbedPath'] = rtrim($embedPhpPath, 'embed.php'); 
-        }
-        
-        // Auto-Detect the Embed Application URI
-        $embedUri =  G2EmbedTestUtilities::_autodetectEmbedUri();
-        // Normalise the Embed Application URI
-        $embedUri = G2EmbedDiscoveryUtilities::normalizeEmbedUri($embedUri); 
-        $new['embedUri'] = $embedUri; 
-        
-        } else {
-            // Do not autodetect the variables, but check the manually entered ones.
-            $results['g2Uri2']['title'] = G2EmbedTestUtilities::_trans('\'URI of Gallery2\' variable:');
-            $results['g2Uri2']['advise'] = true;
-            $results['g2Uri2']['notice'] = 
-                G2EmbedTestUtilities::_trans('Cannot fully check this when not in auto-detect mode.');
-    
-            $embedPhpPath = $orig['g2EmbedPath'];
-            // Check path can be read, adding embed.php if needed
-            if (substr($embedPhpPath, -1) != '/') {       
-                $embedPhpPath = $embedPhpPath . '/';
-                $results['g2EmbedPath']['title'] = 
-                    G2EmbedTestUtilities::_trans('\'Location of Gallery2\' variable:');
-                $results['g2EmbedPath']['advise'] = true;
-                $results['g2EmbedPath']['notice'] = 
-                    G2EmbedTestUtilities::_trans('%g2EmbedPath automatically updated to %embedPhpPath to adhere to Gallery2 requirements.',
-                    array('%g2EmbedPath' => $orig['g2EmbedPath'],
-                          '%embedPhpPath' => $embedPhpPath));
-            }
-            list ($ok, $errorString) = 
-                G2EmbedDiscoveryUtilities::isFileReadable($embedPhpPath.'embed.php');
-            $new['g2EmbedPath'] = $embedPhpPath;
-            if (!$ok) {
-                // Something is wrong with the G2 embed path
-                $results['g2EmbedPath2']['title'] = 
-                    G2EmbedTestUtilities::_trans('\'Location of Gallery2\' variable:');
-                $results['g2EmbedPath2']['error'] = true;
-                $results['g2EmbedPath2']['notice'] = $errorString;
-                $gallery_valid = 0;
-            } else {
-                // G2 Embed Path is found OK
-                $results['g2EmbedPath2']['title'] = 
-                    G2EmbedTestUtilities::_trans('\'Location of Gallery2\' variable:');
-                $results['g2EmbedPath2']['success'] = true;
-            }
-            $embedUri = $orig['embedUri'];
-            $embedUri = G2EmbedDiscoveryUtilities::normalizeEmbedUri($embedUri); 
-            $new['embedUri'] = $embedUri;
-            if ($embedUri != $orig['embedUri']) {
-                $results['embedUri']['title'] = 
-                    G2EmbedTestUtilities::_trans('\'Embed URI\' variable:');
-                $results['embedUri']['advise'] = true;
-                $results['embedUri']['notice'] = 
-                    G2EmbedTestUtilities::_trans('%origEmbedUri automatically updated to %embedUri to adhere to Gallery2 requirements.',
-                        array('%origEmbedUri' => $orig['embedUri'], 
-                              '%embedUri' => $embedUri));
-            }
-            $results['embedUri2']['title'] =
-                                G2EmbedTestUtilities::_trans('\'Embed URI\' variable:');
-            $results['embedUri2']['advise'] = true;
-            $results['embedUri2']['notice'] = 
-                G2EmbedTestUtilities::_trans('Cannot fully check this when not in auto-detect mode.');
-        }
-
-    list ($numErrors, $numWarnings) = G2EmbedTestUtilities::_getNumErrorsAndWarnings($results);
-    return array($numErrors, $numWarnings, $new, $results); 
- //   return array($gallery_valid, $new, $results);
-    }
-
-       /**
-        * Check the status of Gallery2 Modules before Gallery Init
-        *
-        * @param $testsToRun
-        * @return array results
-        */
-    function preInitTests($testsToRun = null) {
-        if (!$testsToRun) {
-            $testsToRun['php_memory']['errorlevel'] = 'error';
-            $testsToRun['php_memory']['minimumMemoryLimit'] = 24;
-        }
-        /* Check for adequate PHP Memory Limit */
-        if (isset($testsToRun['php_memory'])) {
-            $results['php_memory'] = G2EmbedTestUtilities::phpMemoryCheck(
-                $testsToRun['php_memory']['minimumMemoryLimit']); 
-        }
-        list ($numErrors, $numWarnings) = G2EmbedTestUtilities::_getNumErrorsAndWarnings($results);
-        return array($numErrors, $numWarnings, $results); 
-    }
-
-       /**
-        * Check the status of Gallery2 Modules after Gallery Init
-        *
-        * @param $testsToRun
-        * @return array results
-        */
-    function postInitTests($testsToRun = null) {
-  
-        if (!$testsToRun) {
-            $testsToRun['imageblock']['errorlevel'] = 'error';
-            $testsToRun['imageframe']['errorlevel'] = 'warning';         
-            $testsToRun['urlrewrite']['errorlevel'] = 'advise';                 
-        }
-       
-        list ($ret, $allModulesStatus) = GalleryCoreApi::fetchPluginStatus('module');
-        /* Check for ImageBlock Module */
-        if (isset($testsToRun['imageblock'])) {
-            $results['imageblock'] = 
-                G2EmbedTestUtilities::moduleCheck('imageblock', 'Image Block', 
-                    $testsToRun['imageblock']['errorlevel'], $allModulesStatus); 
-        }
-        /* Check for ImageFrame Module */
-        if (isset($testsToRun['imageframe'])) {
-            $results['imageframe'] = 
-                G2EmbedTestUtilities::moduleCheck('imageframe', 'Image Frame', 
-                    $testsToRun['imageframe']['errorlevel'], $allModulesStatus); 
-        }      
-        if (isset($testsToRun['urlrewrite'])) {
-            $results['urlrewrite'] = 
-                G2EmbedTestUtilities::urlRewriteCheck($testsToRun['urlrewrite']['errorlevel']); 
-        }
-        list ($numErrors, $numWarnings) = G2EmbedTestUtilities::_getNumErrorsAndWarnings($results);
-        return array($numErrors, $numWarnings, $results); 
-    }
-
-    /**
-     * Warn if memory_limit is set and is too low
-     * (from Gallery2 install code)
-     *
-     * @param minimumMemoryLimit
-     * @return array results
-     */
-       function phpMemoryCheck($minimumMemoryLimit = 24) {
-        $memoryLimit = ini_get('memory_limit');                 
-        $title = G2EmbedTestUtilities::_trans('PHP Memory Limit:');
-        if ($memoryLimit != '' && (G2EmbedTestUtilities::_getBytes($memoryLimit) / (1024 * 1024)) < $minimumMemoryLimit) {
-            $results = array(
-                                       'title' => $title,
-                                       'error' => true,
-                                   'notice' => G2EmbedTestUtilities::_trans(
-                        'Your PHP is configured to limit the memory to %memLimit (<b> 
-                         memory_limit</b> parameter in php.ini). You should raise this limit 
-                         to at least <b>%minMemLimitMB</b> for proper Embedded Gallery2 operation',
-                        array('%memLimit' => $memoryLimit, '%minMemLimit' => $minimumMemoryLimit)),
-                                       );                      
-        } else {
-            $results = array(
-                                       'title' => $title,
-                                       'success' => true,
-                                       );              
-        }
-        return $results;
-    }
-    
-       /**
-        * Check the status of Gallery2 URL Rewrite Module
-        *
-        * @param $errorLevel
-        * @return array results
-        */
-       function urlRewriteCheck($errorLevel) {
-        /* Check for URL Rewrite Module */
-        $title = 'Gallery2 URL Rewrite Module Status:';
-        list ($ret, $rewriteApi) = GalleryCoreApi::newFactoryInstance('RewriteApi');
-        if ($ret) {
-        /* G2 Error handling */
-            $results = array(
-                'title' => $title,
-                'installed' => false,
-                'active' => false,
-                'available' => false,
-                $errorLevel => true,
-                'notice' => G2EmbedTestUtilities::_trans(
-                        'Gallery2 Error when trying to access URL Rewrite Module status. %ret',
-                        array('%ret' => $ret->getAsHtml())),
-                );
-        }
-        if (empty($rewriteApi)) {
-            $results = array(
-                'title' => $title,
-                'installed' => false,
-                'active' => false,
-                'available' => false,
-                $errorLevel => true,
-                               'notice' =>  G2EmbedTestUtilities::_trans(
-                               'Either the URL rewrite module is not installed or the version is too old.'),
-                );
-        } else {
-            /* Check compatibility */
-            $required = array(1, 0);
-            list ($ret, $isCompatible) = $rewriteApi->isCompatibleWithApi($required);
-            if ($ret) {
-                /* Error handeling */
-                $results = array(
-                    'title' => $title,
-                    'installed' => false,
-                    'active' => false,
-                    'available' => false,
-                    $errorLevel => true,
-                    'notice' => G2EmbedTestUtilities::_trans(
-                        'Gallery2 Error when trying to access URL Rewrite Module status. %ret',
-                        array('%ret' => $ret->getAsHtml())),
-                    );           
-            } else {
-                if (!$isCompatible) {
-                    $results = array(
-                        'title' => $title,
-                        'installed' => false,
-                        'active' => false,
-                        'available' => false,
-                        $errorLevel => true,
-                                       'notice' =>  G2EmbedTestUtilities::_trans(
-                                          'The installed URL Rewrite module version is not compatible.'),
-                        );
-                } else {
-                /* Add rules checking etc */
-                $results = array(
-                    'title' => $title,
-                    'success' => true,
-                    );
-                }
-            }
-        }
-        return $results;
-    }
-    
-       /**
-        * Check the status of a Gallery2 Module
-        *
-        * @param $moduleId, $moduleName, $errorLevel, $allModulesStatus
-        * @return array moduleStatus
-        */
-       function moduleCheck($moduleId, $moduleName, $errorLevel, $allModulesStatus) {
-               $moduleStatus = array();
-               if (isset($allModulesStatus[$moduleId])) {
-                       $moduleStatus['installed'] = true;
-                       $moduleStatus['active'] = $allModulesStatus[$moduleId]['active'];
-                       $moduleStatus['available'] = $allModulesStatus[$moduleId]['available'];            
-               } else {
-                       $moduleStatus['installed'] = false;
-                       $moduleStatus['active'] = false;
-                       $moduleStatus['available'] = false;
-               }  
-               $moduleStatus['title'] = 'Gallery2 ' . $moduleName .' Module Status:';
-               if (!$moduleStatus['installed']) {
-                               $moduleStatus[$errorLevel] = true;
-                               $moduleStatus['notice'] = G2EmbedTestUtilities::_trans(
-                                   'The %moduleName Module is not installed.', 
-                                   array('%moduleName' => $moduleName));
-               } else {
-                       if ($moduleStatus['active'] && $moduleStatus['available']) {
-                               $moduleStatus['success'] = true;
-                       } else {
-                               $moduleStatus[$errorLevel] = true;
-                               $moduleStatus['notice'] =  G2EmbedTestUtilities::_trans(
-                                   'The %moduleName Module is installed but not active or configured correctly.', 
-                                   array('%moduleName' => $moduleName));
-                  }
-               } 
-               return $moduleStatus;
-       }
-       
-           /*
-     * Returns the exact bytes value from a php.ini setting
-     *     * Copied from PHP.net's manual entry for ini_get()
-     */
-    function _getBytes($val) {
-        $val = trim($val);
-        $last = $val{strlen($val)-1};
-        switch($last) {
-        case 'k':
-        case 'K':
-            return (int) $val * 1024;
-            break;
-        case 'm':
-        case 'M':
-            return (int) $val * 1048576;
-            break;
-        default:
-            return $val;
-        }
-    }
-    
-       /**
-        * Calculate the number of errors and warnings
-        *
-        * @param $results 
-        * @return array($numErrors, $numWarnings)
-        */
-    function _getNumErrorsAndWarnings($results) {
-        $numErrors = 0;
-        $numWarnings = 0;
-        foreach ($results as $key=>$result) {
-            if ($result['error']) {
-              $numErrors++;
-            }
-            if ($result['warning']) {
-              $numWarnings++;
-            }
-        }
-        return array($numErrors, $numWarnings);       
-    }
-       
-       /**
-        * Translate the message string
-        * This needs to be implemented by each embed application individually.
-        *
-        * Returns the translated string.
-        * @param $string A string containing the English string to translate.
-     *        $args An associative array of replacements to make after translation. 
-     *              Incidences of any key in this array are replaced with the corresponding value.
-        * @return string Translated String
-        */
-       function _trans($string, $args = 0) {
-          return t($string, $args);
-       }
-       
-    /**
-        * Autodetect the Embed URI
-        * This needs to be implemented by each embed application individually.
-        *
-        * @param none
-        * @return string autodetected URI
-        */
-       function _autodetectEmbedUri() {
-     $uri = url('gallery', null, null, false);
-     if (substr($uri, -8) == '/gallery') {
-        $uri = substr($uri, 0, strlen($string)-7) . 'index.php?q=gallery';
-     }
-     // strip the end /gallery if present and replace with index.php?q=gallery to avoid any 
-     // url rewrite issues. See http://gallery.menalto.com/node/46181
-     // Note the use of index.php in all cases. Not needed for Apache, but is for IIS
-     // see drupaldocs documentation for url.
-      return $uri;
-    }
-}
-?>
\ No newline at end of file
diff --git a/INSTALL.txt b/INSTALL.txt
deleted file mode 100644 (file)
index 71f6368..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-$Id$
-
-HELP
-----
-For more help, check out: http://drupal.galleryembedded.com
-
-Requirements
-------------
-Gallery2.1 (or above) installed and working (see http://gallery.menalto.com)
-Image Block module installed and activated in Gallery2
-Image Frame module installed and activated in Gallery2
-Drupal 5.x
-Gallery module (this Drupal module)
-
-Note that this module does not provide any photo/album functions itelf, but uses
-Gallery2 (http://gallery.menalto.com) to provide this functionality.
-
-Installation Instructions
--------------------------
-
-1. Install Gallery 2.1 and Drupal 5.x (see their respective installation
-   documents).  
-   
-   ***Warning*** - Do not name your Gallery2 directory "gallery", call it something else 
-   (eg "gallery2"). Calling it "gallery" will cause a conflict with the Drupal gallery.module 
-   as Drupal assumes that http://www.example.com/gallery refers to the Drupal module.
-
-2. Ensure that "Image Block" and "Image Frame" modules are installed and activated in Gallery2.
-   Check them in the non-embedded Gallery. See 
-   http://codex.gallery2.org/index.php/Gallery2:Download for instructions to download it 
-   if it was not included in your installation.
-
-3. Log out of Gallery2 (non-embedded) - people have reported errors relating to sessions if this 
-   is not done.
-
-4. Copy the entire gallery module directory to your Drupal modules/ directory.
-
-5. Enable the gallery module in Administer -> Site building -> Modules in your Drupal
-   installation.
-
-6. Go to Administer -> Site configuration -> Gallery and enter the URI of Gallery2. 
-   Leave "autodetect" selected and click "Save configuration". A series of tests will run to check
-   if everything is OK. There is a HELP link.
-
-7. Enable the "Gallery Block" in Administer -> Site building -> Blocks, and optionally the 
-   "Gallery Navigation" block and the "Gallery Grid Block".
-   
-8. Enable the "Access Gallery" permission for the roles that you want to be able to see the gallery
-   and gallery blocks. Go to Administer -> User management -> Access control.
-   
-9. If necessary, disable the Register module in Gallery2 and remove the Login item from the sidebar
-   block. All login and registration functions now need to go through Drupal (and from there
-   automatically to Gallery2, not Gallery2 directly.)
-
-Optional Steps
---------------
-                       
- 1. Sidebar.     Go to your Gallery2 site admin and include the blocks you want in the sidebar
-                 (under Themes). I use "Item Actions" and "Album Quick Links (DHTML)". To use 
-                 the latter you need to have installed the Album Select module.
-
- 2. URL Rewrite. 
- 3. g2image. If you install g2image http://g2image.steffensenfamily.com as either a standalone or
-             TinyMCE plugin you will have an excellent image chooser for Drupal/Gallery2. The
-             configuration is automatic when you hit the "Save configuration' button on the gallery
-             settings page.
-
-Troubleshooting
----------------
-See http://drupal.galleryembedded.com
\ No newline at end of file
index 38db55b..6d8af8c 100644 (file)
@@ -1,23 +1,73 @@
-$Id$
+// $Id$
 
 Overview
 ---------
-This module embeds Gallery2 (http://gallery.menalto.com) inside your drupal installation 
-to support photos, videos and other content. There is support for 2 types of image block (can be
-placed in the sidebar) and a navigation menu, inserting of images into nodes via an input filter,
-TinyMCE support, syncing of users between the 2 applications, ...
+This module embeds Gallery2 (http://gallery.menalto.com) inside your Drupal
+installation to support photos, videos and other content. There is support for
+2 types of image blocks and a navigation menu, inserting of images into nodes
+via an input filter, TinyMCE support, syncing of users between the two
+applications, ...
 
-Note that you will need to download and install Gallery2 
-(http://codex.gallery2.org/index.php/Gallery2:Download) prior to installing this module.
+Note that you will need to download and install Gallery2
+(http://gallery.menalto.com/downloads) prior to installing this module.
 
 Requirements
 ------------
-* Gallery 2.1 or above (with ImageBlock and ImageFrame modules installed and activated)
+* Gallery 2.2
 * Drupal 5.x
 
-For installation instructions please see INSTALL.txt
+Installation
+------------
+
+1. Install Gallery 2 and Drupal (see their respective installation documents).
+Gallery2 should be *inside* your Drupal installation so that it's accessible
+by the same website. If you installed Gallery somewhere else, you can create
+a symlink to it from inside your Drupal site or you can move Gallery2.
+
+Warning - Do not name your G2 directory 'gallery', call it something else
+(e.g. 'gallery2'). Calling it 'gallery' will cause a conflict with the Drupal
+gallery.module as Drupal assumes that http://www.example.com/gallery refers
+to the Drupal module.
+
+2. Ensure that 'Image Block' and 'Image Frame' plugins are installed and
+activated in Gallery2. Check them in the non-embedded Gallery.
+
+3. Log out of Gallery 2 (non-embedded) - people have reported errors relating
+to sessions if this is not done.
+
+4. Copy gallery.module to your Drupal modules/ directory.
+
+5. Enable the gallery module in Administer ->  Site building -> Modules in
+your Drupal installation (admin/build/modules).
+
+6. Go to Administer ->  Site configuration -> Gallery (admin/settings/gallery)
+and configure the path to your Gallery2 installation using the install wizard
+provided there.
+
+7. Enable the 'Gallery Block' in Administer -> Site building -> Blocks
+(admin/build/block).
+
+- Optional -
+8. The Gallery user administration is now available in Administer -> User
+management -> Gallery users (admin/user/gallery). You should at least check
+the 'User settings' (admin/user/gallery/settings).
+
+9. G2Image:
+If you install G2Image (http://g2image.steffensenfamily.com) as either a
+standalone or TinyMCE plugin you will have an excellent image chooser for
+Drupal/Gallery2. The configuration is automatic when you hit the 'Save
+configuration' button on the G2Image settings page
+(admin/settings/gallery/g2image).
+
+Support
+-------
+Please post bug reports and feature requests in the Issues tracker
+(http://drupal.org/project/issues/gallery), support requests should generally
+go to the Gallery 2 Integrations Forums (http://gallery.menalto.com/forum/78)
+first.
 
 Authors
 -------
 James Walker <walkah@walkah.net>
 Kieran Parsons <kiz_0987@yahoo.com>
+Thilo Wawrzik <drupal@profix898.de>
diff --git a/drupal_g2.css b/drupal_g2.css
deleted file mode 100755 (executable)
index 5c4166a..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/* $Id$ */
-
-/**
- * Drupal embeded Gallery2 css overrides.
- * These do not make a perfect theme, but are not bad as a first step.
- */
- /* Increase font size */
- #gallery {
-    font-size: 100%;
- }
- /* Remove the header */
-#gsHeader {
-  display: none;
-}
-
-/* Removes the Gallery Title (as Drupal displays it)*/
-#gallery .gbBlock table h2 {
-   display: none;
-}
-
-/* Brings h2 back for siteAdmin pages */
-#siteAdminForm .gbBlock h2 {
-   display: block;
-}
-
-/* Do not display the breadcrumb */
-#gsNavBar div.gbBreadCrumb {
-  display: none;
-}
-
-/* The system links ("Site Admin", "Your Album") should no longer float as the 
-   breadcrumb has been removed. Just align right */
-#gsNavBar div.gbSystemLinks {
-  text-align: right;
-  float: none;
-}
-
-/* .block-gallery is in the sidebar */ 
-.block-gallery #gsSidebar {
-    border: none;
-    width: auto;
-    overflow: hidden;
-}
-
-.block-gallery div.block-core-ItemLinks {
-  margin: 0;
-  border-bottom: 1px solid #aaa;
-}
-
-.block-gallery .gbBlock {
-    padding: 0 5px 3px 5px;
-}
-
-/* Navigation Tree */
-.block-gallery .dtree {
-    font-size: 1em;
-}
-
-/* For g2ic_plugin */
-img.g2image_float_left, div.g2image_float_left 
-{
-  float: left;
-  margin: 4px;
-}
-
-img.g2image_float_right, div.g2image_float_right {
-  float: right;
-  margin: 4px;
-}
-
-img.g2image_centered, div.g2image_centered {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-  text-align: center;
-}
-
-/* Neeed to centre images with frames */
-.g2image_centered table {
-  margin: auto;
-}
-
-.g2image_clear_images {
-  clear: both;
-  }
-
-.post-content img
-{
-float: left;
-clear: both;
-margin: 4px;
-}
-
-.page-content img
-{
-float: left;
-clear: both;
-margin: 4px;
-}
-
-/* Embed success, warning, error messages */
-.g2_embed_success {
-   color: green;
-}
-
-.g2_embed_warning {
-   color: #f63;
-}
-.g2_embed_error {
-   color: red;
-   font-weight: bold;
-}
-
-/* Gallery Grid Block */
-.gallery-grid-block {
-  padding: 1px;
-/*  width: 500px;
-  display: block;
-  margin-left: auto;
-  margin-right: auto;*/
-}
-
-/*.gallery-grid-block .image-grid {
-  width: 182px;
-  width: 300px;
-}*/
-
-/*.gallery-grid-block .one-image {
-  float: left;
-  display: inline;
-  padding: 3px;
-}*/
-
-/*.gallery-grid-block .one-image {
-//  float: left;
-  width: 90px;
-  margin-left: auto;
-  margin-right: auto;
-  display: block;
-  padding: 1px;
-}*/
-.gallery-grid-block .one-image {
-  margin: 1px;
-}
-
-td.gallery-grid-block {
-  text-align:center;
-}
-
-/* So imageframed thumbs can be centered */
-/*td.gallery-grid-block table {
-  margin: auto;
-}*/
-
-.gallery-grid-block table,
-.gallery-grid-block .one-image td, 
-.gallery-grid-block .one-image table {
-  margin: auto;
-}
-
-.dtree {
-  line-height: 100%;
-}
-
-.dtree a.node, .dtree a.nodeSel {
-  margin-left: 0;
-}
index 8fdaf65..9c59a5a 100644 (file)
@@ -1,19 +1,23 @@
 // $Id$
 
-function g2ic_open(field) {
-  // Find the form id by going back through the hierarchy. Kludge until can get the form id
-  // directly from drupal.
-  var element = document.getElementById(field).parentNode;
-  while (element.tagName != 'FORM') {
-    element = element.parentNode;
-  }
-  var form = element.id;
-  var url = G2IMAGE_URI + 'g2image.php?g2ic_form='+form+'&g2ic_field='+field+'&g2ic_tinymce=0';
+function g2image_open(field) {
+  // Set some properties
+  var form = $('#'+field).parents('form').attr('id');
+  var url = G2IMAGE_URI+'g2image.php?g2ic_form='+form+'&g2ic_field='+field+'&g2ic_tinymce=0';
        var name = 'g2image';
        var w = 600;
        var h = 600;
        var valLeft = (screen.width) ? (screen.width-w)/2 : 0;
        var valTop = (screen.height) ? (screen.height-h)/2 : 0;
        var features = 'width='+w+',height='+h+',left='+valLeft+',top='+valTop+',resizable=1,scrollbars=1';
+
+       // Open the G2Image window
        window.open(url, name, features);
 }
+
+// BUEditor
+function g2bueditor_open() {
+  if (editor.active) {
+    g2image_open(editor.active.textArea.id);
+  }
+}
diff --git a/gallery.css b/gallery.css
new file mode 100755 (executable)
index 0000000..756d3f8
--- /dev/null
@@ -0,0 +1,232 @@
+/* $Id$ */
+
+/**
+ * Drupal embeded Gallery2 css overrides.
+ * These do not make a perfect theme, but are not bad as a first step.
+ */
+
+/* Increase font size */
+#gallery {
+  font-size: 100%;
+}
+
+ /* Remove the header */
+#gsHeader {
+  display: none;
+}
+
+/* Removes the Gallery Title (as Drupal displays it) */
+#gallery .gbBlock table h2 {
+  display: none;
+}
+
+/* Drupal 5.x system.css adds a border to tbody */
+#gallery tbody {
+  border-top: none;
+}
+
+/* Garland adds a width: 100% to all tables */
+td.giAlbumCell table, td.giItemCell table {
+  width: auto;
+}
+
+/* Garland adds td and th padding which needs to be removed for imageframes.
+   Have to manually add each imageframe type -- annoying. */
+table.ImageFrame_bamboo, table.ImageFrame_bamboo td,
+table.ImageFrame_book, table.ImageFrame_book td,
+table.ImageFrame_brand, table.ImageFrame_brand td,
+table.ImageFrame_dotapple, table.ImageFrame_dotapple td,
+table.ImageFrame_filmedges, table.ImageFrame_filmedges td,
+table.ImageFrame_flicking, table.ImageFrame_flicking td,
+table.ImageFrame_gold, table.ImageFrame_gold td,
+table.ImageFrame_gold2, table.ImageFrame_gold2 td,
+table.ImageFrame_notebook, table.ImageFrame_notebook td,
+table.ImageFrame_notebooksquare, table.ImageFrame_notebooksquare td,
+table.ImageFrame_photocorners, table.ImageFrame_photocorners td,
+table.ImageFrame_photocorners_small, table.ImageFrame_photocorners_small td,
+table.ImageFrame_polaroid, table.ImageFrame_polaroid td,
+table.ImageFrame_polaroids, table.ImageFrame_polaroids td,
+table.ImageFrame_postage, table.ImageFrame_postage td,
+table.ImageFrame_shell, table.ImageFrame_shell td,
+table.ImageFrame_shadow, table.ImageFrame_shadow td,
+table.ImageFrame_slide, table.ImageFrame_slide td,
+table.ImageFrame_slidesquare, table.ImageFrame_slidesquare td,
+table.ImageFrame_wood, table.ImageFrame_wood td {
+  width: auto;
+  padding: 0px;
+}
+
+/* Brings h2 back for siteAdmin pages */
+#siteAdminForm .gbBlock h2 {
+  display: block;
+}
+
+/* Do not display the breadcrumb */
+#gsNavBar div.gbBreadCrumb {
+  display: none;
+}
+
+/* The system links ("Site Admin", "Your Album") should no longer float as the
+   breadcrumb has been removed. Just align right */
+#gsNavBar div.gbSystemLinks {
+  text-align: right;
+  float: none;
+}
+
+/* .block-gallery is in the sidebar */
+.block-gallery #gsSidebar {
+  border: none;
+  width: auto;
+  overflow: hidden;
+}
+
+/* Flatten left margin for SiteAdminLinks if moved to Drupal sidebar */
+.block-gallery #gsSidebar ul#gbSiteAdminLinks,
+.block-gallery #gsSidebar ul#gbSiteAdminLinks li,
+.block-gallery #gsSidebar ul#gbSiteAdminLinks li ul,
+.block-gallery #gsSidebar ul#gbSiteAdminLinks li ul li {
+  margin-left: 2px;
+}
+
+/* Remove bold font from SiteAdminLinks if moved to Drupal sidebar */
+.block-gallery #gsSidebar #gbSiteAdminLinks a {
+  font-weight: normal;
+}
+
+.block-gallery div.block-core-ItemLinks {
+  margin: 0;
+  border-bottom: 1px solid #aaa;
+}
+
+.block-gallery .gbBlock {
+  padding: 0 5px 3px 5px;
+}
+
+/* Drupal 5.x system.css adds a border to tbody */
+.block-gallery tbody {
+  border-top: none;
+}
+
+/* Garland adds padding which needs to be removed */
+.block-gallery td, th {
+  padding: 0;
+}
+
+/* Navigation Tree */
+.block-gallery .dtree {
+  font-size: 1em;
+}
+
+/* For G2Image */
+img.g2image_float_left, div.g2image_float_left {
+  float: left;
+  margin: 0px 4px 4px 0px;
+}
+
+img.g2image_float_right, div.g2image_float_right {
+  float: right;
+  margin: 0px 4px 4px 0px;
+}
+
+img.g2image_centered, div.g2image_centered {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+  text-align: center;
+}
+
+/* Need to center images with frames */
+.g2image_centered table {
+  margin: auto;
+}
+
+.g2image_clear_images {
+  clear: both;
+}
+
+.post-content img {
+  float: left;
+  clear: both;
+  margin: 4px;
+}
+
+.page-content img {
+  float: left;
+  clear: both;
+  margin: 4px;
+}
+
+/* Embed success, warning, error messages */
+.g2_embed_success {
+  color: #008800;
+}
+
+.g2_embed_warning {
+  color: #f63;
+}
+.g2_embed_error {
+  color: #880000;
+  font-weight: bold;
+}
+
+/* Gallery Grid Block */
+.gallery-grid-block {
+  padding: 1px;
+/*  width: 500px;
+  display: block;
+  margin-left: auto;
+  margin-right: auto;*/
+}
+
+/*.gallery-grid-block .image-grid {
+  width: 182px;
+  width: 300px;
+}*/
+
+/*.gallery-grid-block .one-image {
+  float: left;
+  display: inline;
+  padding: 3px;
+}*/
+
+/*.gallery-grid-block .one-image {
+//  float: left;
+  width: 90px;
+  margin-left: auto;
+  margin-right: auto;
+  display: block;
+  padding: 1px;
+}*/
+.gallery-grid-block .one-image {
+  margin: 1px;
+}
+
+/* Drupal 5.x system.css adds a border to tbody */
+.gallery-grid-block tbody {
+  border-top: none;
+}
+
+td.gallery-grid-block {
+  text-align:center;
+}
+
+/* So imageframed thumbs can be centered */
+/*td.gallery-grid-block table {
+  margin: auto;
+}*/
+
+/* Garland adds padding which needs to be removed */
+.gallery-grid-block table,
+.gallery-grid-block .one-image td,
+.gallery-grid-block .one-image table {
+  padding: 0;
+  margin: auto;
+}
+
+.dtree {
+  line-height: 100%;
+}
+
+.dtree a.node, .dtree a.nodeSel {
+  margin-left: 0;
+}
index 0059eb7..cbc10a9 100644 (file)
@@ -1,3 +1,6 @@
 ; $Id$
-name = Gallery 
-description = Embeds Gallery2 into Drupal. 
+
+name = "Gallery"
+description = "Embeds Gallery2 into Drupal."
+
+package = "Gallery2"
diff --git a/gallery.install b/gallery.install
new file mode 100644 (file)
index 0000000..74e60c6
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+// $Id$
+
+/**
+ * gallery.module : gallery.install
+ * Install/Uninstall functions
+ */
+
+/**
+ * Implementation of hook_install().
+ */
+function gallery_install() {
+}
+
+/**
+ * Implementation of hook_update_N().
+ * Migrate settings from the 5.x-1.x to 5.x-2.x series
+ */
+function gallery_update_1() {
+  // Array containing 'old name' => 'new name' map
+  $migrate = array(
+    // Image block settings
+    'gallery_album_frame'               => 'gallery_block_image_0_album_frame',
+    'gallery_block_block'               => 'gallery_block_image_0_block_block',
+    'gallery_block_show'                => 'gallery_block_image_0_block_show',
+    'gallery_item_frame'                => 'gallery_block_image_0_item_frame',
+    'gallery_item_id'                   => 'gallery_block_image_0_item_id',
+    'gallery_link_target'               => 'gallery_block_image_0_link_target',
+    'gallery_block_num_images'          => 'gallery_block_image_0_num_images',
+    'gallery_maxsize'                   => 'gallery_block_image_0_size',
+    // Grid block settings
+    'gallery_grid_album_frame'          => 'gallery_block_grid_0_album_frame',
+    'gallery_grid_block_block'          => 'gallery_block_grid_0_block_block',
+    'gallery_grid_block_show'           => 'gallery_block_grid_0_block_show',
+    'gallery_grid_item_frame'           => 'gallery_block_grid_0_item_frame',
+    'gallery_grid_item_id'              => 'gallery_block_grid_0_item_id',
+    'gallery_grid_link_target'          => 'gallery_block_grid_0_link_target',
+    'gallery_grid_maxsize'              => 'gallery_block_grid_0_size',
+    'gallery_grid_num_cols'             => 'gallery_block_grid_0_num_cols',
+    'gallery_grid_num_rows'             => 'gallery_block_grid_0_num_rows',
+    // G2 filter settings
+    'gallery_filter_default_size'       => 'gallery_filter_default_maxsize',
+    // Search settings
+    'gallery_search_max_rows_per_pager' => 'gallery_search_rows_per_pager',
+    'gallery_search_maxsize'            => 'gallery_search_size',
+    // Fullname support
+    'gallery_use_full_name'             => 'gallery_use_fullname',
+    'gallery_profile_full_name_field'   => 'gallery_profile_fullname_field'
+  );
+  // Array containing obsolete variables
+  $obsolete = array('gallery_search_max_items', 'gallery_autodetect_dir', 'gallery_uri', 'gallery_dir');
+
+  // Update variables
+  $ret = gallery_update_variables($migrate, $obsolete);
+  
+  // Update the blocks
+  $ret[] = update_sql("UPDATE {blocks} SET delta = 'image-0' WHERE module = 'gallery' AND delta = 0");
+  $ret[] = update_sql("UPDATE {blocks} SET delta = 'navigation' WHERE module = 'gallery' AND delta = 1");
+  $ret[] = update_sql("UPDATE {blocks} SET delta = 'grid-0' WHERE module = 'gallery' AND delta = 2");
+  
+  // Mark gallery configuration invalid. This does NOT reset the configuration, but
+  // forces the user to run the install wizard to (re)set and verify critical settings.
+  variable_set('gallery_valid', FALSE);
+  variable_set('gallery_config_reset', TRUE);
+  drupal_set_message('You were updating from gallery module 5.x-1.x (or earlier) to the 5.x-2.x
+                      series of the module. All your settings were migrated automatically (see below),
+                      but you will need to re-configure some basic options. Please visit the
+                      Gallery settings page (admin/settings/gallery) to complete the update.',
+                      'error');
+  
+  cache_clear_all('variables', 'cache');
+  menu_rebuild();
+  
+  return $ret;
+}
+
+/**
+ * Function gallery_update_variables().
+ */
+function gallery_update_variables($migrate, $obsolete) {
+  $ret = array();
+
+  $variables = array();
+  // Fetch all gallery-related variables
+  $result = db_query("SELECT * FROM {variable} WHERE name LIKE 'gallery_%'");
+  while ($var = db_fetch_object($result)) {
+    $variables[$var->name] = $var->value;
+  }
+
+  // Remove old variables
+  db_query("DELETE FROM {variable} WHERE name LIKE 'gallery_%'");
+
+  // Migrate old variables
+  foreach ($migrate as $old => $new) {
+    if (isset($variables[$old])) {
+      $variables[$new] = $variables[$old];
+      unset($variables[$old]);
+      $ret[] = array('success' => TRUE, 'query' => 'Migrating variable ['. $old .' => '. $new .']');
+    }
+  }
+
+  // Unset obsolete variables
+  foreach ($obsolete as $var) {
+    if (isset($variables[$var])) {
+      unset($variables[$var]);
+      $ret[] = array('success' => TRUE, 'query' => 'Removing variable ['. $var .']');
+    }
+  }
+
+  // Save resulting variables array
+  // (all variables not migrated or unset are taken over directly)
+  foreach ($variables as $name => $value) {
+    // We dont use variable_set() to reduce overhead
+    // (i.e. unserialize => serialize and cache_clear_all() for each variable)
+    db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, $value);
+  }
+
+  return $ret;
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function gallery_uninstall() {
+  // Remove all gallery related variables and blocks
+  db_query("DELETE FROM {variable} WHERE name LIKE 'gallery_%'");
+  db_query("DELETE FROM {blocks} WHERE module = 'gallery'");
+  cache_clear_all('variables', 'cache');
+}
index f75596d..44661a2 100644 (file)
 <?php
 // $Id$
-// For Drupal 4.7 with Gallery 2.1
 
-$path = drupal_get_path('module', 'gallery');
-require_once($path . '/gallery_base.inc');
+require_once(drupal_get_path('module', 'gallery') .'/gallery_base.inc');
+
+// Default variable values
+define(GALLERY_IMAGEBLOCK_SIZE_METHOD_DEFAULT, 'maxsize');
+define(GALLERY_IMAGEBLOCK_SIZE_DEFAULT, 150);
+define(GALLERY_GRID_SIZE_METHOD_DEFAULT, 'maxsize');
+define(GALLERY_GRID_SIZE_DEFAULT, 90);
+define(GALLERY_SEARCH_SIZE_METHOD_DEFAULT, 'maxsize');
+define(GALLERY_SEARCH_SIZE_DEFAULT, 150);
+define(GALLERY_FILTER_MAXSIZE_DEFAULT, 150);
+define(GALLERY_FILTER_EXACTSIZE_DEFAULT, '');
 
 /**
- * Implementation of hook_menu
+ * Implementation of hook_perm().
+ */
+function gallery_perm() {
+  return array('administer gallery settings', 'access gallery', 'access standalone g2image');
+}
+
+/**
+ * Implementation of hook_menu().
  */
 function gallery_menu($may_cache) {
-  global $user;
+  global $custom_theme;
+  
   $items = array();
-  $view_access = (user_access('access user profiles') || ($user->uid == arg(1)));
   if ($may_cache) {
-    $items[] = array(
-      'path' => 'gallery',
-      'title' => t('Gallery'),
-      'callback' => 'gallery_page',
-      'access' => user_access('access gallery'),
-      'type' => MENU_NORMAL_ITEM,
-      ); 
-    $items[] = array(
-      'path' => 'admin/user/gallery', 
-      'title' => t('Gallery user and role sync'),
-      'description' => t('Show user sync status between Gallery2 and Drupal.'),
-      'callback' => 'gallery_users',
-      'access' => user_access('administer users'),
+    if (variable_get('gallery_valid', 0)) {
+      $items[] = array(
+        'path' => 'gallery',
+        'title' => t('Gallery'),
+        'description' => t('Visit your embedded Gallery2.'),
+        'callback' => 'gallery_page',
+        'access' => user_access('access gallery'),
       );
+    }
+    // settings / general administration
     $items[] = array(
       'path' => 'admin/settings/gallery',
       'title' => t('Gallery settings'),
+      'callback' => 'gallery_settings',
+      'callback arguments' => '_gallery_settings_general',
       'description' => t('Configure settings for embedding Gallery2 into Drupal.'),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => 'gallery_admin_settings',
-      'access' => user_access('administer site configuration'),
-      'type' => MENU_NORMAL_ITEM,
+      'access' => user_access('administer gallery settings'),
+    );
+    $items[] = array(
+      'path' => 'admin/settings/gallery/install',
+      'title' => t('Install'),
+      'callback' => 'gallery_settings',
+      'callback arguments' => '_gallery_settings_install',
+      'access' => user_access('administer gallery settings'),
+      'type' => variable_get('gallery_valid', 0) ? MENU_LOCAL_TASK : MENU_DEFAULT_LOCAL_TASK,
+      'weight' => 0
+    );
+    if (variable_get('gallery_valid', 0)) {
+      $items[] = array(
+        'path' => 'admin/settings/gallery/general',
+        'title' => t('General'),
+        'access' => user_access('administer gallery settings'),
+        'type' => MENU_DEFAULT_LOCAL_TASK,
+        'weight' => 1
+      );
+      $items[] = array(
+        'path' => 'admin/settings/gallery/filter',
+        'title' => t('Filter'),
+        'callback' => 'gallery_settings',
+        'callback arguments' => '_gallery_settings_filter',
+        'access' => user_access('administer gallery settings'),
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 2
+      );
+      $items[] = array(
+        'path' => 'admin/settings/gallery/g2image',
+        'title' => t('G2Image'),
+        'callback' => 'gallery_settings',
+        'callback arguments' => '_gallery_settings_g2image',
+        'access' => user_access('administer gallery settings'),
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 3
+      );
+      if (module_exists('search')) {
+        $items[] = array(
+          'path' => 'admin/settings/gallery/search',
+          'title' => t('Search'),
+          'callback' => 'gallery_settings',
+          'callback arguments' => '_gallery_settings_search',
+          'access' => user_access('administer gallery settings'),
+          'type' => MENU_LOCAL_TASK,
+          'weight' => 4
+        );
+      }
+      $items[] = array(
+        'path' => 'admin/settings/gallery/report',
+        'callback' => 'gallery_report',
+        'access' => user_access('administer site configuration'),
+        'type' => MENU_CALLBACK
+      );
+      // user administration
+      $items[] = array(
+        'path' => 'admin/user/gallery', 
+        'title' => t('Gallery users'),
+        'description' => t('Gallery2 user integration and synchronization'),
+        'callback' => 'gallery_users',
+        'access' => user_access('administer users'),
+      );
+      $items[] = array(
+        'path' => 'admin/user/gallery/users',
+        'title' => t('User Status'),
+        'access' => user_access('administer users'),
+        'type' => MENU_DEFAULT_LOCAL_TASK,
+        'weight' => 0
+      );
+      $items[] = array(
+        'path' => 'admin/user/gallery/advanced',
+        'title' => t('Advanced Sync'),
+        'callback' => 'gallery_user_admin',
+        'callback arguments' => '_gallery_user_advanced',
+        'access' => user_access('administer users'),
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 1
+      );
+      $items[] = array(
+        'path' => 'admin/user/gallery/settings',
+        'title' => t('User Settings'),
+        'callback' => 'gallery_user_admin',
+        'callback arguments' => '_gallery_user_settings',
+        'access' => user_access('administer users') && user_access('administer gallery settings'),
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 2
       );
-  } else {
-    drupal_add_css(drupal_get_path('module', 'gallery') .'/drupal_g2.css', 'module', 'all');
+      $items[] = array(
+        'path' => 'admin/user/gallery/advanced_progress',
+        'callback' => 'gallery_user_admin_advanced_progress',
+        'access' => user_access('administer users'),
+        'type' => MENU_CALLBACK
+      );
+      $items[] = array(
+        'path' => 'admin/user/gallery/users/sync',
+        'callback' => 'gallery_users',
+        'access' => user_access('administer users'),
+        'type' => MENU_CALLBACK
+      );
+    }
   }
+  else {
+    drupal_add_css(drupal_get_path('module', 'gallery') .'/gallery.css');
+    drupal_add_css(drupal_get_path('module', 'gallery') .'/gallery_filter.css');
+    // Switch theme for gallery pages
+    if (arg(0) == 'gallery' && ($custom_theme = variable_get('gallery_page_theme', NULL)) != 'default') {
+      init_theme();
+    }
+  }
+  
   return $items;
 } 
 
 /**
- * Implementation of hook_help
+ * Implementation of hook_help().
  */
 function gallery_help($section) {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_help.inc');
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_help.inc');
   return _gallery_help($section);
 }
 
 /**
- * Implementation of hook_settings
+ * Function gallery_settings().
  */
-function gallery_admin_settings() {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_settings.inc');
-  return system_settings_form(_gallery_settings());
+function gallery_settings($form = '_gallery_settings_general') {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_settings.inc');
+  return drupal_get_form(variable_get('gallery_valid', 0) ? $form : '_gallery_settings_install');
+}
+
+/**
+ * Function gallery_report().
+ */
+function gallery_report($download = NULL) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_report.inc');
+  return _gallery_report(isset($download));
+}
+
+/**
+ * Implementation of hook_info().
+ */
+function gallery_info($field = NULL) {
+  $info['name'] = 'Gallery2';
+  $info['protocol'] = 'internal';
+
+  return isset($field) ? $info[$field] : $info;
+}
+
+/**
+ * Implementation of hook_auth().
+ */
+function gallery_auth($username, $password, $server) {
+  if (_gallery_init()) {
+    // Is the user allowed to login?
+    list($ret, $disabled) = GalleryCoreApi::isDisabledUsername($username);
+    if (!$ret && !$disabled) {
+      // Load G2 user to get the hashed password
+      list($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($username);
+      if (!$ret) {
+        // Authenticate the G2 user
+        if (GalleryUtilities::isCorrectPassword($password, $g2_user->hashedPassword)) {
+          // Does this user exist in Drupal, then override password
+          // (so that next time the user can be authenticated directly)
+          if ($user = user_load(array('name' => $username, 'status' => 1))) {
+            user_save($user, array('pass' => $password));
+            return TRUE;
+          }
+        }
+      }
+    }
+  }
+
+  return FALSE;
 }
 
 /**
- * Implementation of hook_user
+ * Implementation of hook_user().
  */
 function gallery_user($op, &$edit, &$user, $category = NULL) {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_user.inc');
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_user.inc');
 
   switch ($op) {
   case 'login':
-    /* _gallery_init() will try to create the user, if necessary */
-    list ($success, $ret) = _gallery_init();
-    if (!$success) {
-      gallery_error(t('Unable to log in to Gallery'), $ret);
-      return;
-    }
+    gallery_login();
     break;
   case 'logout':
-    if (variable_get('gallery_valid', 0)) {
-      $embedPath = variable_get('gallery_dir', './gallery2/') . 'embed.php';
-      require_once($embedPath);
-      $ret = GalleryEmbed::logout();
-      break;
-    }
+    gallery_logout();
+    break;
   case 'view':
-    return gallery_view_user($user);
+    return gallery_user_view($user);
   case 'insert':
-    return gallery_insert_user($edit, $user);
+    return gallery_user_insert($edit, drupal_clone($user));
   case 'update':
-    return gallery_update_user($edit, $user);
+    return gallery_user_update($edit, drupal_clone($user));
   case 'delete':
-    return gallery_delete_user($user);
+    return gallery_user_delete($user);
   }
 }
 
 /**
- * Gallery Users Page - view a set of users
+ * Function gallery_users().
+ * (gallery user administration)
  */
-function gallery_users() {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_user.inc');
-  return _gallery_users();
+function gallery_users($args = NULL) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_user_admin.inc');
+  return _gallery_user_users($args);
 }
 
 /**
- * implementation of hook_search
+ * Function gallery_user_admin().
  */
-function gallery_search($op = 'search', $keys = null) {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_search.inc');
+function gallery_user_admin($form) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_user_admin.inc');
+  return drupal_get_form($form);
+}
+
+/**
+ * Function gallery_user_admin_advanced_progress().
+ */
+function gallery_user_admin_advanced_progress() {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_user_admin.inc');
+  return _gallery_user_advanced_progress();
+}
+
+/**
+ * Implementation of hook_search().
+ */
+function gallery_search($op = 'search', $keys = NULL) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_search.inc');
   return _gallery_search($op, $keys); 
 }
 
 /**
- * Implementation of hook_search_item to override how to display the item
+ * Implementation of hook_search_item().
+ * (override how to display the item)
  */
 function gallery_search_page($results) {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_search.inc');
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_search.inc');
   return _gallery_search_page($results); 
-}  
+}
 
 /**
- * Implementation of hook_filter
+ * Implementation of hook_form_alter().
  */
-function gallery_filter($op, $delta = 0, $format = -1, $text = '') {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_filter.inc');
-       switch ($op) {
-               case 'list' :
-                       return array (0 => t('Gallery2 filter'));
-               case 'description' :
-                       return t('Allow users to easily reference Gallery2 items from nodes.');
-               case 'process' :
-                       return gallery_filter_process($text);
-               case 'no cache': 
-                 return !variable_get('gallery_filter_can_cache', 1);
-               default :
-                       return $text;
-       }
+function gallery_form_alter($form_id, &$form) {
+  if (($form_id == 'user_admin_role') || ($form_id == 'user_admin_new_role')) {
+    require_once(drupal_get_path('module', 'gallery') .'/gallery_groups.inc');
+    $form['#submit']['_gallery_groups_submit'] = array();
+  }
+  elseif ($form_id == 'search_form' && arg(1) == 'gallery' && variable_get('gallery_search_advanced', 1) && user_access('access gallery')) {
+    require_once(drupal_get_path('module', 'gallery') .'/gallery_search.inc');
+    _gallery_search_form($form);
+  }
+  elseif ($form_id == 'user_register' && count(module_implements('info')) < 2) {
+    unset($form['affiliates']);
+  }
 }
 
 /**
- * Implementation of hook_filter_tips
+ * Implementation of hook_filter().
  */
-function gallery_filter_tips($delta = 0, $format = -1, $long = false) {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_help.inc');
-       if ($long) {
-               return gallery_filter_long_tip_translated();
-       } else {
-               return gallery_filter_short_tip_translated();
-       }
+function gallery_filter($op, $delta = 0, $format = -1, $text = '') {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_filter.inc');
+  switch ($op) {
+    case 'list' :
+      return array(0 => t('Gallery2 filter'));
+    case 'description' :
+      return t('Allow users to easily reference Gallery2 items from nodes.');
+    case 'process' :
+      return gallery_filter_process($text);
+    case 'no cache': 
+      return !variable_get('gallery_filter_can_cache', TRUE);
+    default:
+      return $text;
+  }
 }
 
 /**
- * Implementation of hook_perm().
+ * Implementation of hook_filter_tips().
  */
-function gallery_perm() {
-  return array('access gallery', 'access standalone g2image');
+function gallery_filter_tips($delta = 0, $format = -1, $long = FALSE) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_help.inc');
+  if ($long) {
+    return gallery_filter_long_tip_translated();
+  }
+  else {
+    return gallery_filter_short_tip_translated();
+  }
 }
 
 /**
- * Implementation of hook_elements() - from img_assist
+ * Implementation of hook_elements().
  */
 function gallery_elements() {
   $type['textarea'] = array('#process' => array('gallery_g2image_textarea' => array()));
   return $type;
 }
 
-/*
- * Add image link underneath textareas
+/**
+ * Function gallery_g2image_textarea().
+ * (add image link underneath textareas)
  */
 function gallery_g2image_textarea($element) {
-    $path = drupal_get_path('module', 'gallery');
-    require_once($path . '/gallery_g2image.inc');
-    if (_gallery_g2image_page_match() && !strstr($_GET['q'], 'gallery') && 
-      (variable_get('gallery_g2image_mode', 'disabled') == 'standalone') &&
-      (user_access('access standalone g2image'))) {
+    require_once(drupal_get_path('module', 'gallery') .'/gallery_g2image.inc');
+    if (_gallery_g2image_page_match() && !strstr($_GET['q'], 'gallery')
+      && (variable_get('gallery_g2image_mode', 'disabled') == 'standalone')
+      && (user_access('access standalone g2image'))) {
     gallery_g2image_add_js();
     $output = theme('gallery_g2image_textarea_link', $element, $link);
     $element['#suffix'] .= $output;
   }
+  
   return $element;
 }
 
 /**
- * Implementation of hook_block
- *
+ * Implementation of hook_block().
  */
 function gallery_block($op = 'list', $delta = 0, $edit = array()) {
-  $path = drupal_get_path('module', 'gallery');
-  require_once($path . '/gallery_block.inc');
-  return _gallery_block($op, $delta, $edit);
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_block.inc');
+  if (variable_get('gallery_valid', 0)) {
+    return _gallery_block($op, $delta, $edit);
+  }
 }
 
 /**
- * Main gallery display page
+ * Function gallery_page().
+ * (main gallery display page)
  */
 function gallery_page() {
-  global $gallery_sidebar;
-  list ($success, $ret) = _gallery_init(true);
-  if (!$success) {
-    gallery_error(t('Unable to initialize embedded Gallery'), $ret);
-    $err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link">
-              configure your embedded Gallery</a>.', 
-              array('@link' => url('admin/settings/gallery')));
-    return $err_msg;
+  if (!_gallery_init()) {
+    return '';
   }
   // Turn off sidebar
-  GalleryCapabilities::set('showSidebarBlocks', false);
-  $result = GalleryEmbed::handleRequest();
-  if (!$result['isDone']) {
-    list($title, $css, $javascript) = GalleryEmbed::parseHead($result['headHtml']);
-    if (!empty($javascript)) {
-      gallery_set_html_head(implode("\n", $javascript));
-    }
-    gallery_set_html_head(implode("\n", $css));
-    drupal_set_title($title);
-    // Add pathbar. See http://gallery.menalto.com/node/33447
+  if (variable_get('gallery_move_sidebar_to_block', 1)) {
+    GalleryCapabilities::set('showSidebarBlocks', FALSE);
+  }
+  $result = gallery_handle_request();
+  // Pass $result to gallery_menu_page() if available
+  if (module_exists('gallery_menu')) {
+    gallery_menu_page($result);
+  }
+  // Now format the page, breadcrumb and sidebars
+  if ($result && !$result['isDone']) {
+    gallery_set_head($result['headHtml'], TRUE);
+    // Add pathbar (see http://gallery.menalto.com/node/33447)
     if (isset($result['themeData'])) {
-      $urlGenerator =& $GLOBALS['gallery']->getUrlGenerator();
       $breadcrumb = array(l(t('Home'), ''));
       // Some themes (eg hybrid) do not set $result['themeData']['parents']
       if ($result['themeData']['parents']) {
         foreach ($result['themeData']['parents'] as $parent) {
-          $parent_title = $parent['title'];
-          // Simple strip of bbcode (italics) 
-          $parent_title = str_replace("[i]", "<i>", $parent_title);
-          $parent_title = str_replace("[/i]", "</i>", $parent_title);
+          $parent_title = _gallery_htmlcharsdecode($parent['title']);
+          // Simple strip of bbcode (italic, bold)
+          $parent_title = str_replace(
+            array('[i]', '[/i]', '[b]', '[/b]'),
+            array('<i>', '</i>', '<strong>', '</strong>'),
+            $parent_title
+          );
+          $parent_title = str_replace('[/i]', '</i>', $parent_title);
           // Still does not generate a clean url for /gallery (uses index.php?q=gallery)
-          $link = $urlGenerator->generateUrl(
-            array('view' => 'core.ShowItem', 
-                  'itemId' => $parent['id']), 
-            array('forceFullUrl' => 1,
-                 'htmlEntities' => false));
+          $link = gallery_generate_url(array('itemId' => $parent['id']), FALSE);
           $breadcrumb[] = l($parent_title, $link);
         }
       }
       drupal_set_breadcrumb($breadcrumb);
     }
-    // Store the sidebar info in a global variable for use in the gallery navigation block 
-    $gallery_sidebar = $result['sidebarBlocksHtml'];
-
+    // Hack to get the admin sidebar
+    if (variable_get('gallery_move_admin_sidebar_to_block', 0)) {
+      if (preg_match("/^(.*<td id=\"gsSidebarCol\">)(.*?)(<\/td>.*?)$/s", $result['bodyHtml'], $match)) {
+        // New body
+        $result['bodyHtml'] = $match[1] . $match[3];
+        // Insert admin sidebar in $result['sidebarBlocksHtml']
+        if (empty($result['sidebarBlocksHtml'][1])) {
+          $result['sidebarBlocksHtml'][1] = $match[2];
+        } 
+        else {
+          $result['sidebarBlocksHtml'][] = $match[2];
+        }
+      }
+    }
+    // Store the sidebar info in a global variable for use in the gallery navigation block
+    $GLOBALS['gallery_sidebar'] = $result['sidebarBlocksHtml'];
+    
     return $result['bodyHtml'];
   }
+  
+  return '';
 }
 
-?>
+/**
+ * Implementation of hook_xmlsitemap_links().
+ * (define additional links to add to the site map)
+ */
+function gallery_xmlsitemap_links($type = NULL, $excludes = array()) {
+  if (($type != 'xml') || !variable_get('gallery_enable_sitemap', 1) || !_gallery_init(TRUE)) {
+    return;
+  }
+  
+  list($ret, $view) = GalleryView::loadView('sitemap.Sitemap');
+  if ($ret) {
+    gallery_error(t('Error loading the Gallery2 Sitemap. Make sure the \'Sitemap\' plugin is enabled in Gallery2.'), $ret);
+    return;
+  }
+  list($ret, $root) = GalleryCoreApi::getDefaultAlbumId();
+  if ($ret) {
+    gallery_error(t('Error calling getDefaultAlbumId()'), $ret);
+    return;
+  }
+  
+  // Get the sitemap from Gallery2
+  ob_start();
+  $ret = $view->renderSitemap($root);
+  $g2_sitemap = ob_get_contents();
+  ob_end_clean();
+  
+  if ($ret) {
+    gallery_error(t('Error getting sitemap from Gallery2.'), $ret);
+    return;
+  }
+  
+  return $g2_sitemap;
+}
index 11b4be0..c4c2e10 100644 (file)
  * gallery.module : gallery_base.inc
  * Base functions
  */
-/* --------------------------------------------------------------------------
- * Gallery init and misc functions
- * --------------------------------------------------------------------------
+
+define(GALLERY_ERROR_WATCHDOG,  1);
+define(GALLERY_ERROR_BROWSER,   2);
+define(GALLERY_ERROR_VERBOSE,   3);
+
+define(GALLERY_SEVERITY_SUCCESS,       1);
+define(GALLERY_SEVERITY_ERROR,        -1);
+define(GALLERY_SEVERITY_WARNING,      -2);
+define(GALLERY_SEVERITY_ADVISE,       -3);
+define(GALLERY_SEVERITY_UNKNOWN,      -4);
+
+define(GALLERY_PLUGIN_ENABLED,         1);
+define(GALLERY_PLUGIN_DISABLED,        0);
+define(GALLERY_PLUGIN_STATUS_UNKNOWN, -1);
+define(GALLERY_PLUGIN_NOT_ACTIVE,     -2);
+define(GALLERY_PLUGIN_NOT_INSTALLED,  -3);
+define(GALLERY_PLUGIN_MISSING,        -4);
+
+define(GALLERY_DEBUGTRACE, TRUE);
+
+/**
+ * Function gallery_login().
+ * (login user into embedded gallery)
  */
+function gallery_login() {
+  _gallery_init();
+}
+
+/**
+ * Function gallery_logout().
+ * (end user session)
+ */
+function gallery_logout() {
+  if (variable_get('gallery_valid', FALSE)) {
+    require_once(variable_get('gallery_dir', './gallery2/') .'embed.php');
+    GalleryEmbed::logout();
+  }
+}
+
 /**
- * fetch a galleryEmbed object
+ * Function _gallery_init().
+ * (initialize embedded gallery)
  */
-function _gallery_init($full = false, $vars = null) {
+function _gallery_init($full = FALSE, $vars = NULL, $report_error = TRUE) {
   global $user;
+  static $ready = array('half' => FALSE, 'full' => FALSE);
+  
+  // Initialize only once
+  if ($ready[$full ? 'full' : 'half']) {
+    return TRUE;
+  }
   
   if (!$vars) {
-    $embedPath = variable_get('gallery_dir', './gallery2/') . 'embed.php';
-    $g2Uri =  variable_get('gallery_uri', '/gallery2/');
-    $embedUri = variable_get('gallery_embed_uri', '?q=gallery'); 
+    $embed_path = variable_get('gallery_dir', './gallery2/') .'embed.php';
+    $g2_uri =  variable_get('gallery_uri', '/gallery2/');
+    $embed_uri = variable_get('gallery_embed_uri', '?q=gallery');
     $gallery_valid = variable_get('gallery_valid', 0);
-  } else {
-    $embedPath = $vars['gallery_dir'] . 'embed.php';
-    $g2Uri = $vars['gallery_uri'];
-    $embedUri = $vars['gallery_embed_uri']; 
-    $gallery_valid = $vars['gallery_valid']; 
-  }
-
-  if ((!$gallery_valid) || (!is_readable($embedPath))) {
-    // It's probably now bad practice to return a null here, given that $ret=null is a gallery2
-    // success response
-    return array(false, null);
-  }
-
-  include_once($embedPath);
-  $new_user_needed = false;
-  $active_id = ($user->uid>0) ? $user->uid : '';
-  $params = array('embedUri' => $embedUri,
-                  'g2Uri' => $g2Uri,
-                  'loginRedirect' => url('user/login', null, null, true),
-                  'activeUserId' => $active_id,
-                  'activeLanguage' => gallery_get_language($user),
-                  'fullInit' => $full);
+    $uid = ($user->uid > 0) ? $user->uid : '';
+  } 
+  else {
+    $embed_path = $vars['gallery_dir'] .'embed.php';
+    $g2_uri = $vars['gallery_uri'];
+    $embed_uri = $vars['gallery_embed_uri'];
+    $gallery_valid = $vars['gallery_valid'];
+    $uid = '';
+  }
+  
+  $init_err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link"> configure your embedded Gallery</a>.',
+                      array('@link' => url('admin/settings/gallery/install')));
+  
+  if ((!$gallery_valid) || (!is_readable($embed_path))) {
+    if ($report_error) {
+      gallery_error($init_err_msg);
+    }
+    return FALSE;
+  }
+
+  include_once($embed_path);
+  
+  // i18n url rewrite
+  $language = gallery_get_language($user);
+  if (module_exists('i18n')) {
+    $embed_uri = preg_replace('/index.php\?q=/', i18n_path('index.php?q=', $language), $embed_uri);
+  }
+  
+  $params = array('embedUri' => $embed_uri,
+                  'g2Uri' => $g2_uri,
+                  'loginRedirect' => url('user/login', drupal_get_destination(), NULL, TRUE),
+                  'activeUserId' => $uid,
+                  'activeLanguage' => $language,
+                  'fullInit' => $full,
+                  'apiVersion' => array(1, 2));
 
   $ret = GalleryEmbed::init($params);
-  if (!$ret) {
-    // No error returned, but it is still possible that the ExternalID mapping has not been done
-    $ret2 = GalleryEmbed::isExternalIdMapped($user->uid, 'GalleryUser');
-    if ($ret2 && ($ret2->getErrorCode() & ERROR_MISSING_OBJECT)) {
-      // Need to make a new user, but don't try to map anonymous user.
-      $new_user_needed = ($user->uid>0);
-    }    
-  } 
-  if (($new_user_needed) || ($ret && ($ret->getErrorCode() & ERROR_MISSING_OBJECT))) {
-    // Our user mapping is missing.  Make a mapping, or create a new user.
-    $g2_user = null;
-    // Get the G2 user that matches the Drupal username
-    list ($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($user->name);
-    if ($ret && !($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
-      return array(false, $ret);
-    }
-    if (!isset($g2_user)) {
-      // No G2 user with a matching username.  If this is the admin user, we're going to
-      // try a little harder and match it to the oldest admin in G2.
-      if ($user->uid == 1) {
-        list ($ret, $admin_group_id) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.adminGroup');
-        if ($ret) {
-          return array(false, $ret);
-        }
-        list ($ret, $g2_users) = GalleryCoreApi::fetchUsersForGroup($admin_group_id);
-        if ($ret) {
-          return array(false, $ret);
-        }
-        $keys = array_keys($g2_users);
-        $g2_user_name = $g2_users[$keys[0]];
-        list ($ret, $g2_user) = GalleryCoreApi::fetchUserByUsername($g2_user_name);
-        if ($ret) {
-          return array(false, $ret);
-        }
+  if ($ret) {
+    if ($ret->getErrorCode() & ERROR_PLUGIN_VERSION_MISMATCH) {
+      if ($report_error) {
+        gallery_error($vars ? t('Embedding API version is incompatible.') : $init_err_msg, $ret, TRUE);
       }
+      return FALSE;
     }
-    
-    if (isset($g2_user)) {
-      // The G2 user was found so add to the External ID Map
-      $ret = GalleryEmbed::addExternalIdMapEntry($user->uid, $g2_user->getId(), 'GalleryUser');
-      if ($ret) {
-        return array(false, $ret);
+    else {
+      if ($report_error) {
+        gallery_error($init_err_msg, $ret, TRUE);
       }
-    } else {
-      // No matching G2 user found -- create one. 
-      $path = drupal_get_path('module', 'gallery');
-      require_once($path . '/gallery_user.inc');
-      return gallery_modify_user($user, 'create');
+      return FALSE;
     }
   }
-  return array(true, null);
+  
+  if (!class_exists('GalleryEmbed') || !class_exists('GalleryCoreApi')) {
+    if ($report_error) {
+      gallery_error(t('Classes \'GalleryEmbed\' and/or \'GalleryCoreApi\' are not available,
+                       although initialization seemed successful.'));
+    }
+    return FALSE;
+  }
+  
+  $ready['half'] = $full ? ($ready['full'] = TRUE) : TRUE;
+  
+  return TRUE;
 }
 
 /**
- * Include head information with check made for uniqueness (see drupal_add_js)
+ * Function gallery_handle_request().
+ * (handleRequest extension with error handling)
  */
-function gallery_set_html_head($info, $unique=true) {
-  static $sent = array(); 
-  if ($unique) {
-  // Only set html head if this info has not been sent before. 
-    $hash_info = md5($info);
-    if (!isset($sent[$hash_info])) {
-      drupal_set_html_head($info);
-      $sent[$hash_info] = true;
-    } 
-  } else {
-    drupal_set_html_head($info);
+function gallery_handle_request() {
+  // Remove the language-prefix for G2
+  if (!empty($_GET['g2_path']) && module_exists('i18n')) {
+    i18n_get_lang_prefix($_GET['g2_path'], TRUE);
+  }
+  
+  ob_start();
+  $result = GalleryEmbed::handleRequest();
+  $output = ob_get_contents();
+  ob_end_clean();
+  
+  if ($output) {
+    if (!preg_match('%<h2>\sError\s</h2>%', $output)) {
+      // If $output does not contain '<h2>Error</h2>', this is an AJAX/Image callback
+      print $output;
+      exit();
+    }
+    else {
+      // Otherwise (on regular pages) $output means that an error occured
+      if (variable_get('gallery_error_redirect', 0) && user_access('search content')) {
+        drupal_set_message('The requested Gallery URL does not exist. The item may have been
+                            moved or deleted. You can search for it below.', 'notice');
+        drupal_goto('search/gallery');
+      }
+      preg_match('%<div id="giStackTrace" [^>]*>(.*?)</div>%is', $output, $matches);
+      gallery_error(t('Error handling request (invalid request)<br />or the requested Gallery URL does not exist.'), $matches[1], TRUE);
+      return NULL;
+    }
   }
+  
+  return $result;
 }
 
 /**
- * Get the language for the user. If unknown, make a best guess.
+ * Function gallery_get_language().
+ * (get the language for $user)
  */
 function gallery_get_language($user) {
-  // Added depdev patch for language support (http://drupal.org/node/32374)
-  // without i18 part (I seem to remember a Rewrite issue with it
-  // Added test for no user language defined
-  if (($user->uid==0 || !($user->language)) && module_exists('locale')) { 
-    // This is a visitor and locale module is enabled 
-    // Get drupal's default language
-    $result = db_query('SELECT locale, name FROM {locales_meta} WHERE isdefault = 1'); 
-    $row = db_fetch_object($result);
-    return $row->locale;
-  } else {
-    return $user->language;
-  }   
+  // Default is the user-specific language
+  $language = $user->uid ? $user->language : '';
+  // If i18n is enabled, use that language instead
+  if (module_exists('i18n')) {
+    $language = i18n_get_lang();
+  }
+  // If there is still no language available, try to get the default one
+  if (empty($language)) {
+    $language = 'en';
+    if (module_exists('locale')) {
+      $result = db_query('SELECT locale FROM {locales_meta} WHERE isdefault = 1');
+      $language = db_result($result);
+    }
+  }
+  // Convert certain lang codes, e.g. 'esl/spa es' => 'es' or 'fr-ca' => 'fr'
+  return preg_replace(array('/([\w\/]+) ([a-z]{2,3})/i', '/([a-z]{2,3})-(\w+)/i'), array('${2}', '${1}'), $language);
 }
 
 /**
- * Split an image block result into individual images
- * (Kludge until imageblock has this option)
+ * Function gallery_get_themes().
+ * (retrieve all (active) themes from Gallery2)
+ */
+function gallery_get_themes() {
+  if (!_gallery_init()) {
+    return array();
+  }
+  // List of themes
+  list($ret, $g2_themes) = GalleryCoreApi::fetchPluginStatus('theme', TRUE);
+  if ($ret) {
+    gallery_error(t('Error retrieving theme list'), $ret);
+    return array();
+  }
+
+  $themes = array();
+  foreach (array_keys($g2_themes) as $themeid) {
+    // Only active themes
+    if (!empty($g2_themes[$themeid]['active'])) {
+      // Get theme details
+      list($ret, $theme) = GalleryCoreApi::loadPlugin('theme', $themeid, TRUE);
+      if ($ret) {
+        gallery_error(t('Error getting theme (:themeid) details',
+          array(':themeid' => $themeid)), $ret);
+        return array();
+      }
+      $themes[$themeid] = $theme->getName();
+    }
+  }
+
+  return $themes;
+}
+
+/**
+ * Function gallery_get_image_frames().
+ * (retrieve all image frames from Gallery2)
+ */
+function gallery_get_image_frames() {
+  if (!_gallery_init()) {
+    return array('none' => t('None'));
+  }
+  // List of available image frames
+  list($ret, $imageframe) = GalleryCoreApi::newFactoryInstance('ImageFrameInterface_1_1');
+  if ($ret || !isset($imageframe)) {
+      return array('none' => t('None'));
+  }
+  list($ret, $list) = $imageframe->getImageFrameList();
+  if ($ret) {
+      return array('none' => t('None'));
+  }
+  
+  return $list;
+}
+
+/**
+ * Function gallery_generate_url().
+ */
+function gallery_generate_url($params, $html = TRUE, $full = TRUE) {
+  if (!_gallery_init(TRUE)) {
+    return '';
+  }
+  // Get URL generator and generate the url
+  $url_generator =& $GLOBALS['gallery']->getUrlGenerator();
+  if (!$url_generator) {
+    gallery_error(t('Error: UrlGenerator not available'));
+    return '';
+  }
+  
+  $options = array();
+  $options['forceFullUrl'] = $full;
+  $options['htmlEntities'] = $html;
+  
+  if (!isset($params['view'])) {
+    $params['view'] = 'core.ShowItem';
+  }
+  
+  return $url_generator->generateUrl($params, $options);
+}
+
+/**
+ * Function gallery_album_tree().
+ */
+function gallery_album_tree($root = NULL, $depth = NULL, $uid = NULL) {
+  if (!_gallery_init(TRUE)) {
+    return array();
+  }
+  // If this is called for the Drupal guest user, pass in G2
+  // anonymous user id (otherwise fetchAlbumTree() returns nothing)
+  global $user;
+  if (!$uid && !$user->uid) {
+    list($ret, $uid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.anonymousUser');
+    if ($ret) {
+      return array();
+    }
+  }
+  // Fetch G2 album tree
+  list($ret, $tree) = GalleryCoreApi::fetchAlbumTree($root, $depth, $uid);
+  if ($ret) {
+    gallery_error(t('Error fetching album tree'), $ret);
+    return array();
+  }
+
+  return $tree;
+}
+
+/**
+ * Function gallery_item_details().
+ */
+function gallery_item_details($id, $verbose = FALSE) {
+  $details = array();
+  if (!_gallery_init(TRUE)) {
+    return $details;
+  }
+  // Load entity
+  list($ret, $entity) = GalleryCoreApi::loadEntitiesById($id);
+  if ($ret) {
+    gallery_error(t('Error fetching item details (entityId: :id)',
+      array(':id' => $id)), $ret);
+    return $details;
+  }
+  // Extract details
+  $details['g2type'] = $entity->entityType;
+  $details['g2owner'] = $entity->ownerId;
+  $details['g2parent'] = $entity->parentId;
+  // Drupal node properties (no g2 prefix)
+  $details['title'] = _gallery_htmlcharsdecode($entity->title);
+  $details['created'] = $entity->creationTimestamp;
+
+  if ($verbose) {
+    $details['g2description'] = _gallery_htmlcharsdecode($entity->description);
+    $details['g2summary'] = _gallery_htmlcharsdecode($entity->summary);
+    $details['g2keywords'] = $entity->keywords;
+    $details['g2theme'] = isset($entity->theme) ? $entity->theme : NULL;
+  }
+
+  return $details;
+}
+
+/**
+ * Function gallery_db_query().
+ */
+function gallery_db_query($query, $data = NULL) {
+  if (!_gallery_init(TRUE)) {
+    return FALSE;
+  }
+  // Perform query
+  list ($ret, $search) = $GLOBALS['gallery']->search($query, $data);
+       if ($ret) {
+    return FALSE;
+       }
+       $results = array();
+       while ($result = $search->nextResult()) {
+    $results += $result;
+  }
+
+  return $results;
+}
+
+/**
+ * Function gallery_flush_entity_cache().
+ */
+function gallery_flush_entity_cache() {
+  if (!_gallery_init()) {
+    return FALSE;
+  }
+  // Flush entity cache
+  $platform =& $GLOBALS['gallery']->getPlatform();
+  $cache_basedir = $GLOBALS['gallery']->getConfig('data.gallery.cache');
+  $cache_dir = $cache_basedir .'entity';
+
+  if ($platform->file_exists($cache_dir)) {
+    if (!$platform->recursiveRmDir($cache_dir)) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+ * Function gallery_set_head().
+ */
+function gallery_set_head($html, $settitle = FALSE) {
+  if (!empty($html)) {
+    list($title, $css, $javascript) = GalleryEmbed::parseHead($html);
+    if ($settitle) {
+      drupal_set_title($title);
+    }
+    gallery_set_css($css);
+    gallery_set_javascript($javascript);
+  }
+}
+
+/**
+ * Function gallery_set_css().
+ */
+function gallery_set_css($css) {
+  global $base_url;
+  static $css_memory = array();
+  
+  if (count($css)) {
+    $css = preg_replace('/<link(.*?)href="([^"]*)"(.*?)\/>/i', '${2}', $css);
+    foreach ($css as $include) {
+      if (!in_array(($md5 = md5($include)), $css_memory)) {
+        $css_memory[] = $md5;
+        if (variable_get('gallery_outside', 0)) {
+          // drupal_add_css() does not support external paths
+          drupal_set_html_head('<link type="text/css" rel="stylesheet" media="all" href="'. $include .'" />');
+        }
+        else {
+          $include = preg_replace(array('#^'. $base_url .'#', '#^'. base_path() .'#', '#^/#'), '', $include);
+          // Workaround for urls containing '&amp;' with @import directive (#157978)
+          $include = str_replace('&amp;g2_frames', '&g2_frames', $include);
+          if (substr($include, 0, 6) == '<style') {
+            // drupal_add_css() does not support inline styles
+            drupal_set_html_head($include);
+          }
+          elseif (substr($include, 0, 4) == 'http') {
+            // drupal_add_css() does not support external paths
+            drupal_set_html_head('<style type="text/css" media="all">@import "'. $include .'";</style>');
+          }
+          else {
+            // Gallery's css must always be added first to allow overriding from the module(s)
+            drupal_add_css($include, 'module', 'all', FALSE);
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Function gallery_set_javascript().
+ * (druapl_add_js() ensures proper cascading of included G2 javascript)  
+ */
+function gallery_set_javascript($javascript) {
+  global $base_url;
+  static $js_memory = array();
+  
+  if (!empty($javascript)) {
+    $files = preg_grep('/<script(.*?)src=/i', $javascript);
+    // Inline Javascript
+    $inline = array_diff($javascript, $files);
+    $inline = preg_replace('/<script([^>]*)>(.*?)<\/script>/is', '\2', $inline);
+    drupal_add_js(implode("\n", $inline), 'inline');
+    // Javascript files
+    $files = preg_replace('/<script(.*?)src="([^"]*)"([^>]*)>(.*?)<\/script>/i', '${2}', $files);
+    foreach ($files as $include) {
+      if (!in_array(($md5 = md5($include)), $js_memory)) {
+        $js_memory[] = $md5;
+        if (variable_get('gallery_outside', 0)) {
+          // drupal_add_js() does not support external paths
+          drupal_set_html_head('<script type="text/javascript" src="'. $include .'"></script>');
+        }
+        else {
+          $include = preg_replace(array('#^'. $base_url .'#', '#^'. base_path() .'#', '#^/#'), '', $include);
+          if (substr($include, 0, 4) == 'http') {
+            // drupal_add_js() does not support external paths
+            drupal_set_html_head('<script type="text/javascript" src="'. $include .'"></script>');
+          }
+          else {
+            drupal_add_js($include);
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Function gallery_get_block().
+ *
+ * This function allows developers to fetch an image or grid block with certain
+ * parameters from Gallery2.
+ *
+ * @param $params
+ *   An array of parameters to be passed to getImageBlock().
+ *   (http://gallery.menalto.com/apidoc/GalleryCore/Classes/GalleryEmbed.html#methodgetImageBlock)
+ *   If 'itemId' is set to 'user' (or 'user:uid') items are be taken from the
+ *   current (or specified) user's useralbum.
+ * @param $block
+ *   Reserved (for future use)
+ *   For compatibility with future versions of gallery module you should set this to 'ImageBlock'
+ *   although the parameter is not used at the moment.
+ * @param $extra
+ *   $extra['class']:
+ *     Optional class to apply to the block (if customized css styles are required).
+ *   $extra['num_colums']:
+ *     If given a grid block with 'num_cols' columns is generated.
+ *     Otherwise (default) a 'normal' image block is returned.
+ */
+function gallery_get_block($params, $block = 'ImageBlock', $extra = array()) {
+  if (!_gallery_init(TRUE)) {
+    return array('content' => '');
+  }
+  // Include gallery_block.inc and call the private implementation
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_block.inc');
+  return _gallery_block_get_block($params, $extra);
+}
+
+/**
+ * Function _gallery_split_imageblock().
+ * (split an image block result into individual images)
  */
 function _gallery_split_imageblock($html) {
-  /**
-   * From http://uk.php.net/manual/en/function.preg-split.php
-   * Split the html from image block into <...> parts
-   */
+  // From http://uk.php.net/manual/en/function.preg-split.php
+  // Split the html from image block into <...> parts
   $pattern = '/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/';
-  $html_array = preg_split ($pattern, trim ($html), -1, 
-    PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+  $html_array = preg_split($pattern, trim($html), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
   
   $ndx = 0;
   $images = array();
   $image_html = '';
-  // Now iterate through this array and combine again, but on a per-image basis
+  // Iterate through this array and combine again, but on a per-image basis
   foreach ($html_array as $value) {
     $value = trim($value);
     $image_html .= $value; 
     if (!strcmp($value, '<div class="one-image">')) {
       // Found the opening <div> for the image
       $open_divs = 0;
-    } else if (!strncmp($value, '<div', 4)) {
+    }
+    elseif (!strncmp($value, '<div', 4)) {
       // Found a <div> but not the main image one (eg a frame)
       $open_divs++;
-    } else if (!strcmp($value, '</div>')) {
+    }
+    elseif (!strcmp($value, '</div>')) {
       // Found a </div> but check if it's for the main image or a subcomponent (eg frame)
-      if ($open_divs>0) {
+      if ($open_divs > 0) {
         $open_divs--;
-      } else {
+      }
+      else {
         // This must be the closing div for "one-image" so move to next image
         $images[] = $image_html;
         $image_html = '';
       }
     }
   }
+  
   return $images;  
 }
 
+/**
+ * Function _gallery_htmlcharsdecode().
+ * (recover special character's HTML entities, see htmlspecialchars_decode() for php5)
+ */
+function _gallery_htmlcharsdecode($string) {
+  return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
+}
 
 /* 
  * --------------------------------------------------------------------------
- * Error Functions
+ * Error, Debug and Status Functions
  * --------------------------------------------------------------------------
  */
-function gallery_error($message, $ret) {
-// Changed default, just in case!
-  $error_mode = variable_get('gallery_error_mode', array(1));
-  if (in_array(2, $error_mode)) {
-    drupal_set_message($message);
+
+/**
+ * Function gallery_error().
+ */
+function gallery_error($msg, $ret = NULL, $serious = FALSE) {
+  $error_mode = variable_get('gallery_error_mode', array(GALLERY_ERROR_WATCHDOG));
+  $admin = user_access('administer site configuration');
+  $report = $admin && variable_get('gallery_report', 1);
+  // Verbose error messages
+  $debug_info = array();
+  if (in_array(GALLERY_ERROR_VERBOSE, $error_mode) || variable_get('gallery_debug', 0) || $admin) {
+    $msg = $ret ? (is_object($ret) ? ($msg .'<br />'. $ret->getAsHtml()) : $ret) : $msg;
+    if (GALLERY_DEBUGTRACE && function_exists('debug_backtrace')) {
+      $trace = debug_backtrace();
+      $source = t('Error in function \':func()\' (:file::line):<br />',
+        array(':func' => $trace[1]['function'], ':file' => basename($trace[0]['file']), ':line' => $trace[0]['line']));
+      $message  = $source .'<ul><li>'. $msg .'</li></ul>';
+      $debug_info = array('Debug Trace' => $trace);
+    }
+  }
+  $message = !empty($message) ? $message : $msg;
+  // Debug output (skip watchdog)
+  if (variable_get('gallery_debug', 0) && $admin) {
+    if ($report) {
+      _gallery_report_error($debug_info);
+    }
+    drupal_set_message($message, 'error');
+    return;
+  }
+  // Error output to browser
+  if (in_array(GALLERY_ERROR_BROWSER, $error_mode)) {
+    if ($report) {
+      _gallery_report_error($debug_info);
+    }
+    drupal_set_message($message, 'error');
+  }
+  elseif ($serious) {
+    if ($report) {
+      _gallery_report_error($debug_info);
+    }
+    drupal_set_message($admin ? $message : t('Embedded Gallery2 is not available or requested Gallery URL does not exist.'), 'error');
+  }
+  // Error output to watchdog
+  if (in_array(GALLERY_ERROR_WATCHDOG, $error_mode)) {
+    watchdog('gallery', $message, WATCHDOG_ERROR);
+  }
+}
+
+/**
+ * Function _gallery_report_error().
+ */
+function _gallery_report_error($report = array()) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_help.inc');
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_report.inc');
+
+  drupal_set_message(_gallery_report_help(), 'error');
+  _gallery_report(FALSE, $report, TRUE);
+}
+
+/**
+ * Function gallery_debug().
+ */
+function gallery_debug($array, $label = 'Gallery Debug') {
+  if (variable_get('gallery_debug', 0) && user_access('administer site configuration')) {
+    drupal_set_message('<strong>'. $label .':</strong><br />'. nl2br(htmlspecialchars(print_r($array, TRUE))), 'error');
+  }
+}
+
+/**
+ * Function gallery_plugin_status().
+ */
+function gallery_plugin_status($plugin_names) {
+  static $all_plugins_status = array();
+
+  $plugins_status = array();
+  if (!_gallery_init()) {
+    foreach ($plugin_names as $plugin) {
+      $plugins_status[$plugin] = GALLERY_PLUGIN_STATUS_UNKNOWN;
+    }
+    
+    return $plugins_status;
+  }
+  // Fetch status of G2 modules
+  if (empty($plugins_status_cache)) {
+    list($ret, $plugins_status_cache) = GalleryCoreApi::fetchPluginStatus('module');
+    if ($ret) {
+      gallery_error(t('Unable to get Gallery2 module status.'), $ret);
+      foreach ($plugin_names as $plugin) {
+        $plugins_status[$plugin] = GALLERY_PLUGIN_STATUS_UNKNOWN;
+      }
+      
+      return $plugins_status;
+    }
+  }
+  // Generate array containing module status
+  foreach ($plugin_names as $plugin) {
+    if (isset($plugins_status_cache[$plugin])) {
+      if ($plugins_status_cache[$plugin]['active'] && $plugins_status_cache[$plugin]['available']) {
+        $plugins_status[$plugin] = GALLERY_PLUGIN_ENABLED;
+      }
+      elseif (!isset($plugins_status_cache[$plugin]['active']) && $plugins_status_cache[$plugin]['available']) {
+        $plugins_status[$plugin] = GALLERY_PLUGIN_NOT_INSTALLED;
+      }
+      elseif (($plugins_status_cache[$plugin]['active'] == 0) && $plugins_status_cache[$plugin]['available']) {
+        $plugins_status[$plugin] = GALLERY_PLUGIN_NOT_ACTIVE;
+      }
+      else {
+        $plugins_status[$plugin] = GALLERY_PLUGIN_DISABLED;
+      }
+    }
+    else {
+      $plugins_status[$plugin] = GALLERY_PLUGIN_MISSING;
+    }
   }
+  
+  return $plugins_status;
+}
+
+/**
+ * Function gallery_single_plugin_status().
+ */
+function gallery_single_plugin_status($plugin_name) {
+  $status = gallery_plugin_status(array($plugin_name));
+  return $status[$plugin_name];
+}
 
-  if (isset($ret)) {
-    $full_message = $message . '<br/>' . $ret->getAsHtml();
-      } else {
-    $full_message = $message;
+/**
+ * Function gallery_set_status().
+ */
+function gallery_set_status($status = array(), $reset = FALSE) {
+  $status_array = $status;
+  if (!$reset) {
+    $status_array = unserialize(variable_get('gallery_status', serialize(array())));
+    foreach ($status as $key => $value) {
+      if (!empty($value)) {
+        $status_array[$key] = $value;
+      }
+      elseif (isset($status_array[$key])) {
+        unset($status_array[$key]);
+      }
+    }
   }
+  
+  variable_set('gallery_status', serialize($status_array));
+}
 
-  if (in_array(1, $error_mode)) {
-    watchdog('gallery', $full_message, WATCHDOG_ERROR);
+/**
+ * Function gallery_get_status().
+ */
+function gallery_get_status() {
+  return unserialize(variable_get('gallery_status', serialize(array())));
+}
+
+/**
+ * Function gallery_version().
+ */
+function gallery_version() {
+  if (!_gallery_init()) {
+    return array();
   }
+  // Get API version
+  list($core_major, $core_minor) = GalleryCoreApi::getApiVersion();
+  list($embed_major, $embed_minor) = GalleryEmbed::getApiVersion();
+  $version = array(
+    'core' => array('major' => $core_major, 'minor' => $core_minor),
+    'embed' => array('major' => $embed_major, 'minor' => $embed_minor)
+  );
+
+  // Update version in status messages
+  $status = array('version' => array(
+    'title' => t('Gallery2 API version'),
+    'info' => "$core_major.$core_minor / $embed_major.$embed_minor")
+  );
+  gallery_set_status($status);
+      
+  return $version;
 }
-?>
\ No newline at end of file
index 1fbb9da..cc5bfb5 100644 (file)
  * Block functions
  */
  
- /**
- * Implementation of hook_block
- *
- * 0 - gallery imageblock (random, most viewed, etc)
- * 1 - gallery navigation block (recommended)
- * 2 - gallery grid block
+/**
+ * Implementation of hook_block().
  */
 function _gallery_block($op = 'list', $delta = 0, $edit = array()) {
-  $typeMap = array('none' => t('None'),
-                    'randomImage' => t('Random Image'),
-                    'recentImage' => t('Newest Image'),
-                    'viewedImage' => t('Most Viewed Image'),
-                    'randomAlbum' => t('Random Album'),
-                    'recentAlbum' => t('Newest Album'),
-                    'viewedAlbum' => t('Most Viewed Album'),
-                    'dailyImage' => t('Picture of the Day'),
-                    'weeklyImage' => t('Picture of the Week'),
-                    'monthlyImage' => t('Picture of the Month'),
-                    'dailyAlbum' => t('Album of the Day'),
-                    'weeklyAlbum' => t('Album of the Week'),
-                    'monthlyAlbum' => t('Album of the Month'));
-
+  $type_map = $param_map = array();
+  _gallery_block_options($type_map, $param_map);
+  
+  list($type, $delta) = explode('-', $delta);
   switch ($op) {
-  case 'list':
-    $blocks[0]['info'] = t('Gallery Block');
-    $blocks[1]['info'] = t('Gallery Navigation'); 
-    $blocks[2]['info'] = t('Gallery Grid Block'); 
-   return $blocks;
-
-  case 'view':
-    if (!user_access('access gallery')) {
+    case 'list':
+      $blocks['navigation']['info'] = t('Gallery Navigation');
+      $imageblock_num = variable_get('gallery_block_image_num', 1);
+      for ($i=0; $i<$imageblock_num; $i++) {
+        $id = variable_get('gallery_block_image_'. $i .'_blockid', '');
+        $blocks['image-'. $i]['info'] = t('Gallery Image Block @id',
+          array('@id' => ($imageblock_num > 1) ? ('['. ($id ? $id : $i+1) .']') : ''));
+      }
+      $gridblock_num = variable_get('gallery_block_grid_num', 1);
+      for ($i=0; $i<$gridblock_num; $i++) {
+        $id = variable_get('gallery_block_grid_'. $i .'_blockid', '');
+        $blocks['grid-'. $i]['info'] = t('Gallery Grid Block @id',
+          array('@id' => ($gridblock_num > 1) ? ('['. ($id ? $id : $i+1) .']') : ''));
+      }
+      return $blocks;
+    case 'view':
+      if (!user_access('access gallery') || !_gallery_init(TRUE) || $_GET['q'] == 'admin/settings/gallery/install') {
         return;
-    }    
-    list ($success, $ret) = _gallery_init(true);
-    if (!$success) {
-      $err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link">
-                    configure your embedded Gallery</a>.', 
-                   array('@link' => url('admin/settings/gallery')));
-      gallery_error($err_msg, $ret);
-      return;
-    }
-    switch ($delta) {
-    // 0 = Image Block
-      case 0: 
-        // Allow for multiple image types
-        $param_blocks_array = variable_get('gallery_block_block', array('randomImage'));        
-        $params['blocks'] = is_array($param_blocks_array) ? implode('|', $param_blocks_array) : ""; 
-        $param_show_array = variable_get('gallery_block_show', array());
-        $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : ""; 
-        $params['maxSize'] = variable_get('gallery_maxsize', 160);
-        // Add frames and link target using g2_filter code from MichelleC
-        $params['albumFrame'] =  variable_get('gallery_album_frame', 'none');
-        $params['itemFrame'] =  variable_get('gallery_item_frame', 'none');
-        $params['linkTarget'] =  variable_get('gallery_link_target', '');
-        if (variable_get('gallery_item_id', '') != '') {
-            $params['itemId'] =  variable_get('gallery_item_id', '');
-        }
-        $block = array();
-        list($ret, $content, $head) = GalleryEmbed::getImageBlock($params);
-        if ($ret) {
-          gallery_error(t('Unable to get Gallery image block'), $ret);
-          return;
-        } else {
-          if ($content) {
-            // If more than one image type selected then default the subject to 'Gallery' 
-            if (count(variable_get('gallery_block_block', 'randomImage')) > 1) {
-              $block['subject'] = t('Gallery');
-            } else {
-              $block['subject'] = $typeMap[$params['blocks']]; 
-            }
-            // TODO: This should not be hardcoded, but included in the CSS.
-            $block['content'] = '<center>' . $content . '</center>';
-          }
-        }
-        if ($head) {
-          gallery_set_html_head($head);
-        }
-        break;
-    // 1 = Navigation Block
-      case 1:
-        global $gallery_sidebar;
-        if ((arg(0) == 'gallery') && (isset($gallery_sidebar) && !empty($gallery_sidebar))) {
-          $block['subject'] = t('Gallery Navigation');
-          $block['content'] = '<div id="gsSidebar" class="gcBorder1">' . join('', $gallery_sidebar) . '</div>';    
-        }
-        break;
-      // 2 = Image Grid Block
-      case 2:     
-        $num_cols = variable_get('gallery_grid_num_cols', 2);
-        $num_rows = variable_get('gallery_grid_num_rows', 2);
-        $num_images = $num_cols * $num_rows; 
-        // Allow for multiple image types
-        $param_blocks_array = array_fill(0, $num_images, variable_get('gallery_grid_block_block', 
-          'randomImage'));        
-        $params['blocks'] = is_array($param_blocks_array) ? implode('|', $param_blocks_array) : ""; 
-        $param_show_array = variable_get('gallery_grid_block_show', array());
-        $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : ""; 
-        $params['maxSize'] = variable_get('gallery_grid_maxsize', 90);
-        $params['albumFrame'] =  variable_get('gallery_grid_album_frame', 'none');
-        $params['itemFrame'] =  variable_get('gallery_grid_item_frame', 'none');
-        $params['linkTarget'] =  variable_get('gallery_grid_link_target', '');
-        if (variable_get('gallery_grid_item_id', '') != '') {
-            $params['itemId'] =  variable_get('gallery_grid_item_id', '');
-        }
-        $block = array();
-        list($ret, $content, $head) = GalleryEmbed::getImageBlock($params);
-        if ($ret) {
-          gallery_error(t('Unable to get Gallery image block'), $ret);
-          return;
-        } else {
-          if ($content) {
-            $block['subject'] = t('Gallery');       
-            // Split the images from the html so that can put each only in a <td>            
-            $images = _gallery_split_imageblock($content);
-            $new_html =  '<div class="gallery-grid-block"><div class="image-grid">';
-            $new_html .= '<table>';
-            $col = 0;
-            foreach ($images as $current_image) {
-              if ($col == 0) {
-                $new_html .= '<tr>';
-              }
-              $new_html .= '<td style="text-align:center;">' . $current_image . '</td>';
-              $col++;
-              if ($col >= $num_cols) {
-                $col = 0;
-                $new_html .= '</tr>';
-              }
-            }
-            $new_html .= '</table>'; 
-            $new_html .= '</div></div>';
-            $block['content'] .= $new_html;                 
+      }
+      switch ($type) {
+        case 'navigation': // Navigation Block
+          if ((arg(0) == 'gallery') && !empty($GLOBALS['gallery_sidebar'])) {
+            $block['subject'] = t('Gallery Navigation');
+            $block['content'] = '<div id="gsSidebar" class="gcBorder1">'. implode('', $GLOBALS['gallery_sidebar']) .'</div>';
           }
-        }
-        if ($head) {
-          gallery_set_html_head($head);
-        }
-        break;
+          break;
+        case 'image': // Image Block
+          $block = _gallery_block_image_block($delta, $type_map);
+          break;
+        case 'grid': // Image Grid Block
+          $block = _gallery_block_grid_block($delta, $type_map);
+          break;
+      }
+      GalleryEmbed::done();
+      return $block;
+    case 'configure':
+      require_once(drupal_get_path('module', 'gallery') .'/gallery_settings.inc');
+      switch ($type) {
+        case 'image': // Image Block
+          return _gallery_settings_block_image($delta);
+        case 'grid': // Image Grid Block
+          return _gallery_settings_block_grid($delta);
       }
-    $ret = GalleryEmbed::done();
-    if ($ret) {
-      gallery_error(t('Unable to complete Gallery request'), $ret);
-      return;
+      break;
+    case 'save':
+      require_once(drupal_get_path('module', 'gallery') .'/gallery_settings.inc');
+      _gallery_settings_block_save($delta, $edit);
+      break;
+  }
+}
+
+/**
+ * Function _gallery_block_options().
+ */
+function _gallery_block_options(&$type_map, &$param_map) {
+  $type_map = array(
+    'randomImage'   => t('Random image'),
+    'recentImage'   => t('Recent image'),
+    'viewedImage'   => t('Viewed image'),
+    'randomAlbum'   => t('Random album'),
+    'recentAlbum'   => t('Recent album'),
+    'viewedAlbum'   => t('Viewed album'),
+    'dailyImage'    => t('Daily image'),
+    'weeklyImage'   => t('Weekly image'),
+    'monthlyImage'  => t('Monthly image'),
+    'dailyAlbum'    => t('Daily album'),
+    'weeklyAlbum'   => t('Weekly album'),
+    'monthlyAlbum'  => t('Monthly album')
+  );
+  $param_map = array(
+    'title'   => t('Title'),
+    'date'    => t('Date'),
+    'views'   => t('View Count'),
+    'owner'   => t('Item owner'),
+    'heading' => t('Heading')
+  );
+}
+
+/**
+ * Function _gallery_block_image_block().
+ */
+function _gallery_block_image_block($delta, $type_map) {
+  $param_blocks_array = array_filter(variable_get('gallery_block_image_'. $delta .'_block_block', array('randomImage')));
+  $params['blocks'] = is_array($param_blocks_array) ? implode('|', $param_blocks_array) : ''; 
+  $params['itemId'] = variable_get('gallery_block_image_'. $delta .'_item_id', '');
+  $param_show_array = variable_get('gallery_block_image_'. $delta .'_block_show', array());
+  $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : '';
+  if (variable_get('gallery_block_image_'. $delta .'_size_method', GALLERY_IMAGEBLOCK_SIZE_METHOD_DEFAULT) == 'maxsize') {
+    $params['maxSize'] = variable_get('gallery_block_image_'. $delta .'_size', GALLERY_IMAGEBLOCK_SIZE_DEFAULT);
+  } 
+  else {
+    $params['exactSize'] = variable_get('gallery_block_image_'. $delta .'_size', GALLERY_IMAGEBLOCK_SIZE_DEFAULT);
+  }
+  $params['albumFrame'] = variable_get('gallery_block_image_'. $delta .'_album_frame', 'none');
+  $params['itemFrame'] = variable_get('gallery_block_image_'. $delta .'_item_frame', 'none');
+  $params['linkTarget'] = variable_get('gallery_block_image_'. $delta .'_link_target', '');
+  $params['link'] = variable_get('gallery_block_image_'. $delta .'_link', '');
+  
+  $block = _gallery_block_get_block($params);
+  $block['subject'] = (count($param_blocks_array) > 1) ? t('Gallery') : $type_map[$params['blocks']];
+  
+  return $block;
+}
+
+/**
+ * Function _gallery_block_grid_block().
+ */
+function _gallery_block_grid_block($delta, $type_map) {
+  $num_cols = variable_get('gallery_block_grid_'. $delta .'_num_cols', 2);
+  $num_rows = variable_get('gallery_block_grid_'. $delta .'_num_rows', 2);
+  $num_images = $num_cols * $num_rows; 
+  
+  $param_blocks_array = array_fill(0, $num_images, variable_get('gallery_block_grid_'. $delta .'_block_block', 'randomImage'));
+  $params['blocks'] = is_array($param_blocks_array) ? implode('|', $param_blocks_array) : '';
+  $params['itemId'] = variable_get('gallery_block_grid_'. $delta .'_item_id', '');
+  $param_show_array = variable_get('gallery_block_grid_'. $delta .'_block_show', array());
+  $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : '';
+  if (variable_get('gallery_block_grid_'. $delta .'_size_method', GALLERY_GRID_SIZE_METHOD_DEFAULT) == 'maxsize') {
+    $params['maxSize'] = variable_get('gallery_block_grid_'. $delta .'_size', GALLERY_GRID_SIZE_DEFAULT);
+  } 
+  else {
+    $params['exactSize'] = variable_get('gallery_block_grid_'. $delta .'_size', GALLERY_GRID_SIZE_DEFAULT);
+  }
+  $params['albumFrame'] =  variable_get('gallery_block_grid_'. $delta .'_album_frame', 'none');
+  $params['itemFrame'] =  variable_get('gallery_block_grid_'. $delta .'_item_frame', 'none');
+  $params['linkTarget'] =  variable_get('gallery_block_grid_'. $delta .'_link_target', '');
+  $params['link'] = variable_get('gallery_block_grid_'. $delta .'_link', '');
+  
+  return _gallery_block_get_block($params, array('num_cols' => $num_cols));
+}
+
+/**
+ * Function _gallery_block_get_block().
+ */
+function _gallery_block_get_block($params, $extra = array()) {
+  // Handle useralbum feature
+  if (preg_match('/user(:([\d]+))?/i', $params['itemId'], $param_uid)) {
+    require_once(drupal_get_path('module', 'gallery') .'/gallery_user.inc');
+    $params['itemId'] = gallery_user_useralbum(isset($param_uid[2]) ? $param_uid[2] : NULL, FALSE);
+  }
+  if (empty($params['itemId']) || $params['itemId'] === FALSE) {
+    unset($params['itemId']);
+  }
+  gallery_debug($params, t('Block parameters'));
+  // Get the image(s) from G2
+  list($ret, $content, $head) = GalleryEmbed::getImageBlock($params);
+  if ($ret) {
+    gallery_error(t('Error trying to get image block.'), $ret);
+    return array();
+  }
+  // Format the block content
+  $block = array();
+  if ($content) {
+    $block['subject'] = t('Gallery');
+    if (isset($extra['num_cols'])) {
+      $class = isset($extra['class']) ? $extra['class'] : 'gallery-grid-block';
+      $block['content'] = theme('gallery_block_grid_block', $content, $extra['num_cols'], $class);
+    }
+    else {
+      $class = isset($extra['class']) ? $extra['class'] : 'g2image_centered';
+      $block['content'] = theme('gallery_block_image_block', $content, $class);
+    }
+    // Add css/js to the page
+    if ($head) {
+      gallery_set_head($head);
     }
-    return $block;
   }
+
+  return $block;
 }
 
-?>
+/**
+ * Theme function : theme_gallery_block_image_block().
+ */
+function theme_gallery_block_image_block($content, $class = 'g2image_centered') {
+  return '<div class="'. $class .'">'. $content .'</div>';
+}
+
+/**
+ * Theme function : theme_gallery_block_grid_block().
+ */
+function theme_gallery_block_grid_block($content, $num_cols, $class = 'gallery-grid-block') {
+  $images = _gallery_split_imageblock($content);
+  $images = array_chunk($images, $num_cols);
+  
+  $rows = array();
+  foreach ($images as $image_row) {
+    $row = array();
+    foreach ($image_row as $image) {
+      $row[] = array('data' => $image, 'style' => 'text-align:center;');
+    }
+    $rows[] = $row;
+  }
+
+  $html  = '<div class="'. $class .'"><div class="image-grid">';
+  $html .= theme('table', array(), $rows);
+  $html .= '</div></div>';
+
+  return $html;
+}
index 62bd88c..4db5559 100755 (executable)
@@ -1,20 +1,20 @@
 /* $Id$ */
 
-div.giImageBlock.left {\r
-       float: left;\r
-       margin: 1em;\r
-}\r
-\r
-div.giImageBlock.right {\r
-       float: right;\r
-       margin: 1em;\r
-}\r
-\r
-div.giImageBlock.nowrap {\r
-       float: none;\r
-       margin: 1em\r
+div.giImageBlock.left {
+       float: left;
+       margin: 1em;
 }
 
-.giImageBlock-clear-both {\r
-  clear: both;\r
+div.giImageBlock.right {
+       float: right;
+       margin: 1em;
+}
+
+div.giImageBlock.nowrap {
+       float: none;
+       margin: 1em
+}
+
+.giImageBlock-clear-both {
+  clear: both;
 }
index bc0b91c..c9adc9b 100644 (file)
 
 /**
  * gallery.module : gallery_filter.inc
- * Gallery Filter functions (originally by MichelleC and Waldemar)
+ * Gallery Filter functions
  */
-// ***************** The Filter in Action ***********************
 
-define('GALLERY__FILTER_WORD', 1);
-define('GALLERY_FILTER_INTEGER', 2);
-define('GALLERY_FILTER_STRING', 3);
-
-function gallery_filter_attr_value($text, $value_type = GALLERY_FILTER_WORD) {
-  // Strip off initial and final quotes.
-       $first = substr($text, 0, 1);
-       if ($first == "\"" || $first == "\'") {
-               if (substr($text, -1, 1) == $first) {
-                       $text = substr($text, 1, -1);
-               }
-       }
-       switch ($value_type) {
-               case GALLERY_FILTER_WORD :
-                       return preg_replace("/\W/", '', $text);
-               case GALLERY_FILTER_INTEGER :
-                       return preg_replace("/\D/", '', $text);
-               default :
-                       return check_plain($text);
-       }
-}
-
-// Execute filter on given text.
+/**
+ * Function gallery_filter_process().
+ * (implementation of the main filter routine)
+ */
 function gallery_filter_process($text) {
-       // Find all the image codes and loop over them, replacing each with the Gallery2 image block
-       $prefix = variable_get('gallery_filter_prefix', 'G2');
-
-       $matchetxt = "/\[".trim($prefix).":(\d+)(\s*,)?\s*(.*?)\]/i";
-       preg_match_all($matchetxt, $text, $matches, PREG_SET_ORDER);
-       // If we have at least one match, set everything up
-       if (count($matches) > 0) {
-               // Set the default and path variables based on module settings
-               $default_size = variable_get('gallery_filter_default_size', 150);
-               $default_div_class = variable_get('gallery_filter_default_div_class', 'nowrap');
-               $default_album_frame = variable_get('gallery_filter_default_album_frame', '');
-               $default_item_frame = variable_get('gallery_filter_default_item_frame', '');
-               $default_block_type = variable_get('gallery_filter_default_block_type', 'recentImage');
-               $default_n_images = variable_get('gallery_filter_n_images', 1);
-               $default_show = variable_get('gallery_filter_default_show', 'none');
-               $default_link_target = variable_get('gallery_filter_default_link_target', '');
-
-               if ($default_album_frame == 'none') {
-                       $default_album_frame = '';
-               }
-               if ($default_item_frame == 'none') {
-                       $default_item_frame = '';
-               }
-
-               // This will hold the list of frames used for images so we can add the CSS link(s) at the end
-               $frame_list = array ();
-
-               // This sets up the embedding
-               list ($success, $ret) = _gallery_init(true);
-               if (!$success) {
-                       gallery_error(t('Unable to initialize embedded Gallery'), $ret);
-                       return;
-               }
-       }
-       foreach ($matches as $match) {
-               // Pull out the arguments into the $args array
-               $args = array ();
-               preg_match_all("/(\w+)\=(\"[^\"]*\"|\S*)/", $match[3], $a, PREG_SET_ORDER);
-
-               foreach ($a as $arg) {
-                       $args[strtolower($arg[1])] = $arg[2];
-               }
-
-               // Set number of images to show
-               $n_images = gallery_filter_attr_value($args['n'], GALLERY_FILTER_INTEGER);
-               if ($n_images == 0) {
-                       // No size specified; use the default
-                       $n_images = $default_n_images;
-               }
-
-               // Set the block type
-               $block_type = gallery_filter_attr_value($args['type'], GALLERY_FILTER_WORD);
-               if (empty($block_type)) {
-                       // No block type specified; use the default
-                       $block_type = $default_block_type;
-               }
-               if ($n_images <= 1)
-                       $block_type = 'specificItem'; //so it shows something if n=1 and an album is selected
-
-               // Set the size of the thumbnail
-               $size = gallery_filter_attr_value($args['size'], GALLERY_FILTER_INTEGER);
-               if ($size == 0) {
-                       // No size specified; use the default
-                       $size = $default_size;
-               }
-
-               // Set the class of the div
-               $div_class = gallery_filter_attr_value($args['class'], GALLERY_FILTER_WORD);
-               if (empty ($div_class)) {
-                       // No class specified; use the default
-                       $div_class = $default_div_class;
-               }
-               // Switch the class to g2image versions (adds consistency)
-               switch ($div_class) {
-               case 'left':
-                 $div_class = "g2image_float_left";
-                 break;
-               case 'right':
-                 $div_class = "g2image_float_right";
-                 break;
-               case 'center':
-               case 'centre':
-                 $div_class = "g2image_centered";
-                 break;
-               case 'normal':
-                 $div_class = "g2image_normal";
-                 break;
-               }
-               // Set the overriding, album, and item frames
-               $frame = gallery_filter_attr_value($args['frame'], GALLERY_FILTER_WORD);
-               $album_frame = gallery_filter_attr_value($args['aframe'], GALLERY_FILTER_WORD);
-               $item_frame = gallery_filter_attr_value($args['iframe'], GALLERY_FILTER_WORD);
-
-               if (empty ($frame)) {
-                       // No overriding frame given; check for album_frame and item_frame
-                       if (empty ($album_frame)) {
-                               // No album frame specified; use the default one
-                               $album_frame = $default_album_frame;
-                       }
-
-                       if (empty ($item_frame)) {
-                               // No item frame specified; use the default one
-                               $item_frame = $default_item_frame;
-                       }
-
-               } else {
-                       // Overriding frame given; use it
-                       $album_frame = $frame;
-                       $item_frame = $frame;
-               }
-
-               // Add the requested frames to the array so we can get the CSS later. Don't worry about
-               // dupes at this point; they will be filtered out later.
-               array_push($frame_list, $frame);
-               array_push($frame_list, $album_frame);
-               array_push($frame_list, $item_frame);
-
-               // This part actually fetches the image block. It uses the same paramaters as the code
-               // found under "Image Block" in site admin in Gallery2. 
-
-               $show = $default_show;
-
-               // Not customized yet:
-               $link_target = $default_link_target;
-
-               $param_blocks_array = array_fill(0, $n_images, $block_type);
-               $params['itemId'] = $match[1];
-               $params['blocks'] = is_array($param_blocks_array) ? implode('|', $param_blocks_array) : "";
-               $param_show_array = $show;
-               $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : "";
-               $params['maxSize'] = $size;
-               // Add frames and link target using g2_filter code from MichelleC
-               $params['albumFrame'] = $album_frame;
-               $params['itemFrame'] = $item_frame;
-               $params['linkTarget'] = $link_target;
-
-    $g2_head = array();
-    $block = array ();
-               list ($ret, $content, $head) = GalleryEmbed::getImageBlock($params);
-               if ($ret) {
-                       gallery_error(t('Unable to get Gallery image block'), $ret);
-                       return;
-               } else {
-                       if ($content) { 
-        // Add a div around the table for styling
-        if ($div_class != 'none') {
-          $content = '<div class ="giImageBlock '.$div_class.'">'.$content.'</div>';
+  $prefix = trim(variable_get('gallery_filter_prefix', 'G2'));
+  preg_match_all("/\[$prefix:(\d+)\s*(.*?)\]/i", $text, $matches, PREG_SET_ORDER);
+  
+  // Initialize G2 and set default arguments
+  if (count($matches) > 0) {
+    if (!_gallery_init(TRUE)) {
+      return $text;
+    }
+    $default['n'] = variable_get('gallery_filter_n_images', 1);
+    $default['type'] = variable_get('gallery_filter_default_block_type', 'recentImage');
+    $default['maxsize'] = variable_get('gallery_filter_default_maxsize', GALLERY_FILTER_MAXSIZE_DEFAULT); 
+    $default['exactsize'] = variable_get('gallery_filter_default_exactsize', GALLERY_FILTER_EXACTSIZE_DEFAULT);
+    $default['class'] = variable_get('gallery_filter_default_div_class', 'nowrap');
+    $default['album_frame'] = variable_get('gallery_filter_default_album_frame', 'none');
+    $default['item_frame'] = variable_get('gallery_filter_default_item_frame', 'none');
+    $default['show'] = array_filter(variable_get('gallery_filter_default_show', array('none')));
+    $default['target'] = variable_get('gallery_filter_default_link_target', '');
+    $default['link'] = variable_get('gallery_filter_default_link', '');
+  }
+  else {
+    return $text;
+  }
+  
+  $head_array = array();
+  // Loop over all matches
+  foreach ($matches as $match) {
+    // First argument is numeric => valid G2 filter tag
+    if (is_numeric($match[1])) {
+      $args = array_filter(preg_split('/[\s,]+/', $match[2]));
+      $params = array('itemId' => intval($match[1]));
+      // If this item is not an album (e.g. photo, movie, ...) set block type to 'specificItem'
+      $details = gallery_item_details($params['itemId']);
+      if (isset($details['g2type']) && $details['g2type'] != 'GalleryAlbumItem') {
+        $params['n'] = 1;
+        $params['type'] = 'specificItem';
+      }
+      if (preg_match('/user(:([\d]+))?/i', $params['itemId'], $param_uid)) {
+        require_once(drupal_get_path('module', 'gallery') .'/gallery_user.inc');
+        $params['itemId'] = gallery_user_useralbum(isset($param_uid[2]) ? $param_uid[2] : NULL, FALSE);
+      }
+      // Loop over all (optional) arguments
+      foreach ($args as $arg) {
+        list($key, $value) = array_filter(explode('=', $arg));
+        if (!empty($value)) {
+          $key = preg_replace('/\W/', '', $key);
+          $params[$key] = _gallery_filter_sanitize($key, $value);
         }
-        // This puts the image block HTML back into the rest of the text
+      }
+      // Treat 'maxsize' and 'size' as the same
+      if (isset($params['size'])) {
+        $params['maxsize'] = $params['size'];
+        unset($params['size']);
+      }
+      // Carefully treat the default size method (cannot just merge them as the
+      // entered value must take precedence over the default)
+      if (isset($params['maxsize'])) {
+        unset($default['exactsize']);
+      }
+      else if (isset($params['exactsize'])) {
+        unset($default['maxsize']);
+      }
+      // Merge params with default values
+      $params = array_merge($default, $params);
+      // Transform 'type' into a valid parameter
+      if ($params['n'] > 1 && $params['type'] == 'specificItem') {
+        $params['type'] = $default['type'];
+      }
+      if (is_array($params['type'])) {
+        // Ensure 'type' contains 'n' elements (auto-append if necessary)
+        $count = count($params['type']);
+        if (($num = $params['n'] - $count) > 0) {
+          $params['type'] += array_fill($count, $num, end($params['type']));
+        }
+      }
+      else {
+        $params['type'] = array_fill(0, $params['n'], $params['type']);
+      }
+      // 'frame' overrides 'album_frame' and 'item_frame'
+      if ($params['frame']) {
+        $params['album_frame'] = $params['item_frame'] = $params['frame'];
+      }
+      // Convert into G2-compatible arguments
+      $params['blocks'] = implode('|', $params['type']);
+      if (isset($params['maxsize']) && !empty($params['maxsize'])) {
+        $params['maxSize'] = $params['maxsize'];
+      }
+      else if (isset($params['exactsize']) && !empty($params['exactsize'])) {
+        $params['exactSize'] = $params['exactsize'];
+      }
+      $params['albumFrame'] = $params['album_frame'];
+      $params['itemFrame'] = $params['item_frame'];
+      $params['show'] = implode('|', $params['show']);
+      $params['linkTarget'] = $params['target'];
+      // Unset redundant parameters
+      unset(
+        $params['n'],
+        $params['type'],
+        $params['exactsize'],
+        $params['maxsize'],
+        $params['frame'],
+        $params['album_frame'],
+        $params['item_frame'],
+        $params['target']
+      );
+      gallery_debug($params, t('Filter parameters'));
+      // Fetch the images and format output
+      list($ret, $content, $head) = GalleryEmbed::getImageBlock($params);
+      if ($ret) {
+        gallery_error(t('Error trying to get image block.'), $ret);
+        continue;
+      }
+      if ($content) {
+        // Replace G2 filter tag with image block html
+        $params['class'] = 'giImageBlock'. ($params['class'] ? ' '. $params['class'] : '');
+        $content = '<div class ="'. $params['class'] .'">'. $content .'</div>';
         $text = str_replace($match[0], $content, $text);
-                       }
+      }
       if ($head) {
-        $g2_head[] = $head;
-      }          
-               }
-       } // end of for loop through matches
-       // If we had at least one match, finish up by adding the css. Unfotunately if there are multiple
-       // images on a page this will get added multiple times.
-       if (count($matches) > 0) {
-               GalleryEmbed :: done();
-    if ($g2_head) {
-      gallery_set_html_head(implode("\n", array_unique($g2_head)));
+        $head_array[] = trim($head);
+      }
     }
-    drupal_add_css(drupal_get_path('module', 'gallery') .'/gallery_filter.css', 'module', 'all');
-       }
-       return $text . "<br class=\"giImageBlock-clear-both\" />";;
+  }
+  
+  // Add html head items and css
+  if (count($head_array)) {
+    gallery_set_head(implode("\n", array_unique($head_array)));
+  }
+  GalleryEmbed::done();
+    
+  return $text .'<br class="giImageBlock-clear-both" />';
+}
+
+/**
+ * Function _gallery_filter_sanitize().
+ * (sanitize filter parameters)
+ */
+function _gallery_filter_sanitize($key, $value) {
+  switch (strtolower($key)) {
+    case 'n':
+    case 'size':
+    case 'maxsize':
+    case 'exactsize':
+      return intval(preg_replace('/\D/', '', $value));
+    case 'class':
+    case 'frame':
+    case 'album_frame':
+    case 'item_frame':
+    case 'target':
+    case 'link':
+      return preg_replace('/\W/', '', $value);
+    case 'type':
+    case 'show':
+      return explode('|', preg_replace('/[^\w\x7c]/', '', $value));
+    default :
+      return check_plain($value);
+  }
+  
+  return $value;
 }
-?>
\ No newline at end of file
index 1920633..03f6135 100644 (file)
@@ -5,58 +5,55 @@
  * gallery.module : gallery_g2image.inc
  * Support functions for g2image by capt_kirk (from http://g2image.steffensenfamily.com)
  */
- /**
- * Add js to page
+
+/**
+ * Function gallery_g2image_add_js().
  */
- function gallery_g2image_add_js() {
+function gallery_g2image_add_js() {
   // Ensure only sent once
-  static $sent = false;
+  static $sent = FALSE;
   if (!$sent) {
     $path = drupal_get_path('module', 'gallery');
-    $g2image_uri = base_path() . $path . '/g2image/';
-  
-    $output .= '<script type="text/javascript">';
-    $output .= '  var G2IMAGE_URI = "' . $g2image_uri . '";';
-    $output .= '</script>';
+    $g2image_uri = base_path() . $path .'/g2image/';
+    
+    drupal_add_js('var G2IMAGE_URI = "'. $g2image_uri .'";', 'inline');
+    drupal_add_js($path .'/g2image.js');
     
-    drupal_set_html_head($output);
-    drupal_add_js($path . '/g2image.js');
-    $sent = true;
+    $sent = TRUE;
   }
 }
- /**
- * Theme for adding an image link underneath textareas
+
+/**
+ * Theme function : theme_gallery_g2image_textarea_link().
+ * (for adding an image link underneath textareas)
  */
 function theme_gallery_g2image_textarea_link($element, $link) {
   $output = '<div class="g2image-button"><a class="g2image-link" id="g2image-link-'. $element['#id']
-    . '" title="'. t('Click here to add images from Gallery2 albums') 
-    . '" href="#" onclick="g2ic_open(\''.$element['#id'].'\');">';  
-  $output .= t('add Gallery2 images');
+    .'" title="'. t('Click here to add images from Gallery2 albums') 
+    .'" href="#" onclick="g2image_open(\''. $element['#id'] .'\');">';
+  $output .= t('Add Gallery2 images');
   $output .= '</a></div>';
   
   return $output;
 }
 
 /**
- * Determine if g2image button should be attached to the page/textarea.
- * (from img_assist and tinymce code)
+ * Function _gallery_g2image_page_match().
+ * (determine if g2image button should be attached to the page/textarea)
  *
  * @return
  *   TRUE if can render, FALSE if not allowed.
  */     
 function _gallery_g2image_page_match() {
-  //if (variable_get('gallery_g2image_std_all', 1)) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_help.inc');
+  
   $page_match = FALSE;
   $only_listed_pages = variable_get('gallery_g2image_only_listed_pages', 1);
-  $pages = variable_get('gallery_g2image_std_pages', gallery_help('admin/settings/gallery_g2image#pages'));
-  if ($pages) {
+  if ($pages = variable_get('gallery_g2image_std_pages', gallery_help('admin/settings/gallery_g2image#pages'))) {
     $path = drupal_get_path_alias($_GET['q']);
     $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. variable_get('site_frontpage', 'node') .'\2'), preg_quote($pages, '/')) .')$/';      
     $page_match = !($only_listed_pages xor preg_match($regexp, $path));    
   }
+  
   return $page_match;  
 } 
- ?>
\ No newline at end of file
diff --git a/gallery_groups.inc b/gallery_groups.inc
new file mode 100644 (file)
index 0000000..dd6bfb9
--- /dev/null
@@ -0,0 +1,307 @@
+<?php
+// $Id$
+
+/**
+ * gallery.module : gallery_groups.inc
+ * Group/Role Functions (sync groups, ...)
+ */
+
+/**
+ * Function _gallery_groups_user().
+ * (sync Drupal roles and Gallery groups for a specific user)
+ */
+function _gallery_groups_user($user, $groups = FALSE) {
+  // Sync the Drupal roles and Gallery groups
+  if ($groups) {
+    _gallery_groups_sync();
+  }
+  
+  // Get the Gallery groups for this user
+  // First get the G2 Id from the Drupal uid
+  list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
+  if ($ret) {
+    gallery_error(t('Error loading Gallery user from Drupal user id (:uid)',
+      array(':uid' => $user->uid)), $ret);
+    return;
+  }
+  // Then get the groups for this user currently set in G2
+  list($ret, $g2_user_groups) = GalleryCoreApi::fetchGroupsForUser($g2_user->id);
+  if ($ret) {
+    gallery_error(t('Error getting Gallery group info for user (:uid)',
+      array(':uid' => $g2_user->id)), $ret);
+    return;
+  }
+  gallery_debug($g2_user_groups, t('G2 groups for G2 user (uid: :g2uid)', array(':g2uid' => $g2_user->id)));
+  
+  // Convert the Drupal role Ids into Gallery Group Ids
+  $user->roles[DRUPAL_ANONYMOUS_RID] = DRUPAL_ANONYMOUS_RID;
+  $user->roles[DRUPAL_AUTHENTICATED_RID] = DRUPAL_AUTHENTICATED_RID;
+  gallery_debug($user->roles, t('Drupal roles for Drupal user (uid: :uid)', array(':uid' => $user->uid)));
+  if (($g2_rid_map = _gallery_groups_map(array_keys($user->roles), TRUE)) === FALSE) {
+    return;
+  }
+  gallery_debug($g2_rid_map, t('Drupal roles <> G2 groups map (for Drupal user)'));
+  if (($g2_groups_map = array_flip(_gallery_groups_map(array_keys($g2_user_groups), FALSE))) === FALSE) {
+    return;
+  }
+  gallery_debug($g2_groups_map, t('Drupal roles <> G2 groups map (for G2 user)'));
+  
+  // Find if the user needs to be deleted from any G2 groups (only mapped groups)
+  $delete_list = array_diff($g2_groups_map, $g2_rid_map);
+  gallery_debug($delete_list, t('Remove user from these groups'));
+  foreach ($delete_list as $rid => $gid) {
+    $ret = GalleryCoreApi::removeUserFromGroup($g2_user->id, $gid);
+    if ($ret) {
+      gallery_error(t('Error removing user from Gallery group (Gallery Group Id: :gid)',
+        array(':gid' => $gid)), $ret);
+      return;
+    }
+  }
+  
+  // Find if the user needs to be added to any G2 groups
+  $add_list = array_diff($g2_rid_map, $g2_groups_map);
+  gallery_debug($add_list, t('Add user to these groups'));
+  foreach ($add_list as $rid => $gid) {
+    $ret = GalleryCoreApi::addUserToGroup($g2_user->id, $gid);
+    if ($ret) {
+      gallery_error(t('Error adding user to Gallery group (:gid)',
+        array(':gid' => $gid)), $ret);
+    return;
+    }
+  }
+}
+
+/**
+ * Function _gallery_groups_sync().
+ * (sync Drupal roles and Gallery groups)
+ */ 
+function _gallery_groups_sync() {
+  static $sync_groups = TRUE;
+  // Sync groups only once
+  if (!$sync_groups) {
+    return;
+  }
+  $sync_groups = FALSE;
+  // Check if the Drupal role <> G2 group mapping exists
+  $roles = user_roles();
+  $admin_role = variable_get('gallery_user_admin_role', 0);
+  foreach ($roles as $rid => $role_name) {
+    // Add Drupal <> G2 mapping if needed
+    $ret = GalleryEmbed::isExternalIdMapped($rid, 'GalleryGroup');
+    if ($ret && ($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
+      switch ($rid) {
+        case DRUPAL_ANONYMOUS_RID:
+          list($ret, $g2_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.everybodyGroup');
+          if ($ret) {
+            gallery_error(t('Error retrieving Gallery group Id for \'Everybody\' group'), $ret);
+            return;
+          }
+          $ret = GalleryEmbed::addExternalIdMapEntry($rid, $g2_gid, 'GalleryGroup');
+          if ($ret) {
+              gallery_error(t('Error creating Drupal role <> Gallery group mapping for \'anonymous user\' role (Drupal Role Id: :rid, Gallery Group Id: :gid)',
+                array(':rid' => $rid, ':gid' => $g2_gid)), $ret);
+              return;
+          }
+          break;
+        case DRUPAL_AUTHENTICATED_RID:
+          list($ret, $g2_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.allUserGroup');
+          if ($ret) {
+            gallery_error(t('Error retrieving Gallery group Id for \'Registered Users\' group'), $ret);
+            return;
+          }
+          $ret = GalleryEmbed::addExternalIdMapEntry($rid, $g2_gid, 'GalleryGroup');
+          if ($ret) {
+            gallery_error(t('Error creating Drupal role <> Gallery group mapping for \'authenticated user\' role (Drupal Role Id: :rid, Gallery Group Id: :gid)',
+              array(':rid' => $rid, ':gid' => $g2_gid)), $ret);
+            return;
+          }
+          break;
+        default:
+          // Special handling of the 'admin' role
+          if ($rid == $admin_role) {
+            // Get G2 admin group id
+            list($ret, $g2_admin_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.adminGroup');
+            if ($ret) {
+              gallery_error(t('Error getting \'adminGroup\' id'), $ret);
+              return;
+            }
+            $ret = GalleryEmbed::addExternalIdMapEntry($rid, $g2_admin_gid, 'GalleryGroup');
+            if ($ret) {
+              gallery_error(t('Error creating Drupal role <> Gallery \'Site Admin\' group mapping (Drupal Role Id: :rid, Gallery Group Id: :gid)',
+                array(':rid' => $rid, ':gid' => $g2_gid)), $ret);
+              return;
+            }
+          }
+          else {
+            // Is there a group with this name already?
+            list($ret, $g2_group) = GalleryCoreApi::fetchGroupByGroupName($role_name);
+            if ($ret && ($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
+              $ret = GalleryEmbed::createGroup($rid, $role_name);
+              if ($ret) {
+                gallery_error(t('Error creating Gallery group (Drupal Role Id: :rid, Drupal Role Name: :rname)',
+                  array(':rid' => $rid, ':rname' => $role_name)), $ret);
+                return;
+              }
+            }
+            else {
+              $ret = GalleryEmbed::addExternalIdMapEntry($rid, $g2_group->id, 'GalleryGroup');
+              if ($ret) {
+                gallery_error(t('Error creating Drupal role <> Gallery group mapping (Drupal Role Id: :rid, Gallery Group Id: :gid)',
+                  array(':rid' => $rid, ':gid' => $g2_group->id)), $ret);
+                return;
+              }
+            }
+          }
+          break;
+      }
+    }
+    else {
+      // Update group name if needed
+      list($ret, $g2_group) = GalleryCoreApi::loadEntityByExternalId($rid, 'GalleryGroup');
+      if ($ret) {
+        gallery_error(t('Error retrieving Gallery Group Id from Drupal Role Id (Drupal Role Id: :rid)',
+          array(':rid' => $rid)), $ret);
+        return;
+      }
+      if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID, $admin_role)) && ($role_name != $g2_group->getGroupName())) {
+        $ret = GalleryEmbed::updateGroup($rid, array('groupname' => $role_name));
+        if ($ret) {
+          gallery_error(t('Error updating Gallery group (Drupal Role Id: :rid, Drupal Role Name: :rname)',
+            array(':rid' => $rid, ':rname' => $role_name)), $ret);
+          return;
+        }
+      }
+    }
+  }
+  // Now check for any deleted Drupal roles. Only delete those G2 groups that were mapped to Drupal roles
+  // (just in case other groups have been defined which are not meant to be sync'd with Drupal)
+  if (($g2_groups_map = _gallery_groups_map(array(), TRUE)) === FALSE) {
+    return;
+  }
+  foreach ($g2_groups_map as $rid => $g2_gid) {
+    if (!isset($roles[$rid])) {
+      $ret = GalleryEmbed::deleteGroup($rid);
+      if ($ret) {
+        gallery_error(t('Error deleting Gallery group (Gallery Group Id: :gid)',
+          array(':gid' => $g2_gid)), $ret);
+        return;
+      }        
+    }
+  }
+}
+
+/**
+ * Function _gallery_groups_map().
+ * (fetch 'GalleryGroup' entries from G2 'ExternalIdMap')
+ */
+function _gallery_groups_map($ids = array(), $inverse = FALSE) {
+  // g2Id => externalId (default)
+  $match = array('entityType' => 'GalleryGroup');
+  if (count($ids) > 0) {
+    if ($inverse) {
+      $match['externalId'] = $ids;
+    }
+    else {
+      $match['entityId'] = $ids;
+    }
+  }
+  // Fetch the map entries
+  list($ret, $resultMap) = GalleryCoreApi::getMapEntry('ExternalIdMap', array('externalId', 'entityId'), $match);
+  if ($ret) {
+    gallery_error(t('Error fetching \'GalleryGroup\' entries from \'ExternalIdMap\''), $ret);
+    return FALSE;
+  }
+  // Iterate over the results
+  $g2_extIdMap = array();
+  while (($row = $resultMap->nextResult()) !== FALSE) {
+    $g2_extIdMap[($inverse ? $row[0] : $row[1])] = ($inverse ? $row[1] : $row[0]);
+  }
+
+  return $g2_extIdMap;
+}
+
+/**
+ * Function gallery_groups_map_info().
+ * (get info about groups map status)
+ */
+function gallery_groups_map_info($g2_user, $user) {
+  // Get the groups for this G2 user
+  list($ret, $g2_user_groups) = GalleryCoreApi::fetchGroupsForUser($g2_user->id);
+  if ($ret) {
+    gallery_error(t('Error getting Gallery group info for user (:uid)',
+      array(':uid' => $g2_user->id)), $ret);
+    return;
+  }
+  gallery_debug($g2_user_groups, t('G2 groups for G2 user (uid: :g2uid)', array(':g2uid' => $g2_user->id)));
+  if (($g2_user_groups = _gallery_groups_map(array_keys($g2_user_groups))) === FALSE) {
+    return;
+  }
+  gallery_debug($g2_user_groups, t('Mapped Drupal roles for G2 user (uid: :g2uid)', array(':g2uid' => $g2_user->id)));
+  
+  $user->roles[DRUPAL_ANONYMOUS_RID] = DRUPAL_ANONYMOUS_RID;
+  $user->roles[DRUPAL_AUTHENTICATED_RID] = DRUPAL_AUTHENTICATED_RID;
+  gallery_debug($user->roles, t('Drupal roles for Drupal user (uid: :uid)', array(':uid' => $user->uid)));
+  
+  // Compare number of G2 groups and Drupal roles (of the user)
+  $count_g2_groups = count($g2_user_groups);
+  $count_roles = variable_get('gallery_user_admin_role', 0) ? count($user->roles) : count($user->roles) + 1;
+  return ($count_g2_groups == $count_roles);
+}
+
+/**
+ * Function _gallery_groups_import().
+ * (import Gallery groups into Drupal)
+ */
+function _gallery_groups_import() {
+  // Fetch G2 album names
+  list($ret, $g2_groups) = GalleryCoreApi::fetchGroupNames();
+  if ($ret) {
+    gallery_error(t('Error fetching Gallery Group names'), $ret);
+    return FALSE;
+  }
+  // Exlude 'Everybody' and 'Registered Users' groups
+  list($ret, $g2_everybody_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.everybodyGroup');
+  if ($ret) {
+    gallery_error(t('Error retrieving Gallery group Id for \'Everybody\' group'), $ret);
+    return;
+  }
+  list($ret, $g2_users_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.allUserGroup');
+  if ($ret) {
+    gallery_error(t('Error retrieving Gallery group Id for \'Registered Users\' group'), $ret);
+    return;
+  }
+  unset($g2_groups[$g2_everybody_gid], $g2_groups[$g2_users_gid]);
+  // Check for admin roles mapping
+  if (variable_get('gallery_user_admin_role', 0)) {
+    list($ret, $g2_admin_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.adminGroup');
+    if ($ret) {
+      gallery_error(t('Error getting \'adminGroup\' id'), $ret);
+      return FALSE;
+    }
+    unset($g2_groups[$g2_admin_gid]);
+  }
+  // Create missing Drupal roles (using the G2 groupname)
+  $roles = user_roles();
+  $g2_import_groups = array_diff($g2_groups, $roles);
+  foreach ($g2_import_groups as $g2_groupname) {
+    db_query("INSERT INTO {role} (name) VALUES ('%s')", $g2_groupname);
+  }
+  // Map Drupal roles <> Gallery2 group
+  _gallery_groups_sync();
+    
+  return TRUE;
+}
+
+/**
+ * Function _gallery_groups_submit().
+ * (sync Drupal role <> G2 group when Drupal role has changed)
+ */
+function _gallery_groups_submit($form_id, &$form_values) {
+  if (!_gallery_init(TRUE)) {
+    return;
+  }
+  // Drupal roles have changed => resync 
+  _gallery_groups_sync();
+  
+  GalleryEmbed::done();
+}
index dac25e3..1105d7b 100644 (file)
@@ -7,15 +7,14 @@
  */
 
 /**
- * Implementation of hook_help
+ * Implementation of hook_help().
  */
 function _gallery_help($section) {
-
-  switch($section) {
-               case 'filter#short-tip' :
-                       return gallery_filter_short_tip_translated();
-               case 'filter#long-tip' :
-                       return gallery_filter_long_tip_translated();
+  switch ($section) {
+    case 'filter#short-tip' :
+      return gallery_filter_short_tip_translated();
+    case 'filter#long-tip' :
+      return gallery_filter_long_tip_translated();
     case 'admin/help#gallery':
       $output = t('
       <h3>Online Documentation</h3>
@@ -81,37 +80,52 @@ function _gallery_help($section) {
   }
 }
 
+/**
+ * Function gallery_filter_short_tip_translated().
+ */
 function gallery_filter_short_tip_translated() {
-       return t('You may link to Gallery2 items on this site <a href="@explanation-url">using a special syntax</a>.', array ('@explanation-url' => url('filter/tips', NULL, 'filter-gallery-0')));
+  return t('You may link to Gallery2 items on this site <a href="@explanation-url">using a special syntax</a>.', array('@explanation-url' => url('filter/tips', NULL, 'filter-gallery-0')));
 }
 
+/**
+ * Function gallery_filter_long_tip_translated().
+ */
 function gallery_filter_long_tip_translated() {
-       $prefix = variable_get("gallery_filter_prefix", "G2");
+  $prefix = variable_get("gallery_filter_prefix", "G2");
 
   return t('
-         <p><strong>Gallery2 Filter:</strong></p>
+    <p><strong>Gallery2 Filter:</strong></p>
 
     <p>You can link to items in your embedded Gallery2 using a special code. This code will be replaced by a thumbnail image that is linked to the actual item in your Gallery. </p>
 
-         <p><em>Syntax:</em></p>
+    <p><em>Syntax:</em></p>
+
+    <blockquote><code>
+    ['. $prefix .':<em>item_id</em> n=<em>number</em> type=<em>type</em> size=<em>number</em> class=<em>name</em> frame=<em>name</em> album_frame=<em>name</em> item_frame=<em>name</em>]
+    </code></blockquote>
 
-         <blockquote><code>
-         ['. $prefix .':<em>item_id</em> n=<em>number</em> type=<em>type</em> size=<em>number</em> class=<em>name</em> frame=<em>name</em> album_frame=<em>name</em> item_frame=<em>name</em>]
-         </code></blockquote>
+    <ul><li>item_id (required): This is the item ID from Gallery2. If you look at the URL of the item, this is the last number. <em>Note that if the item_id is a single photo, n must be 1.</em></li>
 
-         <ul><li>item_id (required): This is the item ID from Gallery2. If you look at the URL of the item, this is the last number. <em>Note that if the item_id is a single photo, n must be 1.</em></li>
+    <li>n (suggested): This is the number of photos you want the block to show. It will override whatever is set in the defaults (initially 1). Note: this will change past instances where you did not set n -- the reason for its suggested use.</li>
 
-         <li>n (suggested): This is the number of photos you want the block to show. It will override whatever is set in the defaults (initially 1). Note: this will change past instances where you did not set n -- the reason for its suggested use.</li>
+    <li>type: The default type of gallery block. Any of the following may be used: <em>randomImage, recentImage, viewedImage, randomAlbum, recentAlbum, viewedAlbum, dailyImage, weeklyImage, monthlyImage, dailyAlbum, weeklyAlbum, monthlyAlbum, specificItem. </em> Note that for n=1, selectedItem is automatically chosen regardless of this parameter.</li>
 
-         <li>type: The default type of gallery block. Any of the following may be used: <em>randomImage, recentImage, viewedImage, randomAlbum, recentAlbum, viewedAlbum, dailyImage, weeklyImage, monthlyImage, dailyAlbum, weeklyAlbum, monthlyAlbum, specificItem. </em> Note that for n=1, selectedItem is automatically chosen regardless of this parameter.</li>
+    <li>class: The block that Gallery2 returns is wrapped in a DIV so additional styling can be done. The classes for this DIV are located in g2_filter.css.  Included with the module are "left", "right", and "nowrap". These position the image block to the left or right or on a line all its own with the text not wrapping. You can also add your own class(es) to the CSS file and they will automatically be available.</li>
 
-         <li>class: The block that Gallery2 returns is wrapped in a DIV so additional styling can be done. The classes for this DIV are located in g2_filter.css.  Included with the module are "left", "right", and "nowrap". These position the image block to the left or right or on a line all its own with the text not wrapping. You can also add your own class(es) to the CSS file and they will automatically be available.</li>
+    <li>size: The length of the longest side for the thumbnail. The other side is determined automatically to keep the same aspect ratio. This option (for Gallery2.2 and above) will use the gallery image that is closest in size, and so may end up using a smaller image and expanding it (lower quality). If so, use "exactsize". For Gallery2.1, if you want your size to be bigger than
+the thumbnail size for that image as defined in your Gallery2, you must select "Full Size" in
+the gallery settings page (but note that the full image will be returned and then resized by the
+browser, so it may take a while to download).</li>
 
-         <li>size: The length of the longest side for the thumbnail. The other side is determined automatically to keep the same aspect ratio.</li>
+    <li>exactsize: The length of the longest side for the thumbnail. The other side is determined automatically to keep the same aspect ratio. This option always ensures that the image is scaled
+from a larger image and so image quality is maintained. This only works for Gallery2.2 and above.</li>
 
-         <li>frame/album_frame/item_frame: You can use just "frame" to assign a frame to the thumbnail regardless of whether it\'s for an album or a single item. Using aframe will only affect albums and iframe will only affect single items. Frames included with the default Gallery 2 install are: bamboo, book, brand , dots, flicking, gold, gold2, polaroid, polaroids, shadow, shells, slide, solid, notebook, wood.</li></ul>');
+    <li>frame/album_frame/item_frame: You can use just "frame" to assign a frame to the thumbnail regardless of whether it\'s for an album or a single item. Using aframe will only affect albums and iframe will only affect single items. Frames included with the default Gallery 2 install are: bamboo, book, brand , dots, flicking, gold, gold2, polaroid, polaroids, shadow, shells, slide, solid, notebook, wood.</li></ul>');
 }
 
+/**
+ * Function _gallery_g2image_help().
+ */
 function _gallery_g2image_help() {
   return t('
     <h3>Gallery Image Assist (g2image)</h3>
@@ -119,4 +133,10 @@ function _gallery_g2image_help() {
     <p>Caution: By default, Drupal uses the \'Filtered HTML\' input format for adding content to the site and the default settings cause the &lt;img&gt; tags added by g2image to be removed. Check the TinyMCE documentation for instructions on how to avoid this.</p>');
 }
 
-?>
+/**
+ * Function _gallery_report_help().
+ */
+function _gallery_report_help() {
+  return t('<p><strong>A serious error has occured. This can happen due to an incorrect configuration or a bug in the gallery module. If you plan to submit a bug report to the issue queue at <a href="@gallery-issues">drupal.org</a> consider to include the <a href="@report">pre-generated report file</a>.</strong></p>',
+    array('@gallery-issues' => 'http://drupal.org/project/issues/gallery', '@report' => url('admin/settings/gallery/report/download')));
+}
diff --git a/gallery_install.inc b/gallery_install.inc
new file mode 100644 (file)
index 0000000..2ff595d
--- /dev/null
@@ -0,0 +1,1001 @@
+<?php
+// $Id$
+
+/**
+ * gallery.module : gallery_install.inc
+ * Configure embedded Gallery install (directory options, etc.)
+ */
+
+define(GALLERY_INSTALL_STEP_PHPMEMORY,  1);
+define(GALLERY_INSTALL_STEP_LOCATIONS,  2);
+define(GALLERY_INSTALL_STEP_PLUGINS,    3);
+define(GALLERY_INSTALL_STEP_URLREWRITE, 4);
+define(GALLERY_INSTALL_STEP_USERSYNC,   5);
+
+/**
+ * Function _gallery_install().
+ */
+function _gallery_install($form_values = NULL) {
+  $form['#multistep'] = TRUE;
+  $form['#redirect'] = FALSE;
+  $form['#submit']['_gallery_install_submit'] = array();
+  
+  $install_status = array(
+    'phpmemory' => array(
+      'title' => 'PHP Memory Limit',
+      'severity' => GALLERY_SEVERITY_ERROR,
+    ),
+    'locations' => array(
+      'title' => 'Gallery2 locations',
+      'severity' => GALLERY_SEVERITY_ERROR,
+    ),
+    'plugins' => array(
+      'title' => 'Drupal Modules / Gallery2 Plugins',
+      'severity' => GALLERY_SEVERITY_WARNING,
+    ),
+    'cleanurls' => array(
+      'title' => 'Clean URL / URL Rewrite',
+      'severity' => GALLERY_SEVERITY_WARNING,
+    ),
+    'usersync' => array(
+      'title' => 'Initial User Synchronization',
+      'severity' => GALLERY_SEVERITY_ERROR,
+    ),
+  );
+
+  if (!isset($form_values)) {
+    $form_values = array();
+    $form_values['step'] = GALLERY_INSTALL_STEP_PHPMEMORY;
+    $form_values['gallery_valid'] = FALSE;
+    $form_values['initial_check'] = TRUE;
+    if (variable_get('gallery_config_reset', FALSE)) {
+      $form_values['initial_check'] = FALSE;
+      variable_del('gallery_config_reset');
+    }
+  }
+  else {
+    // Work around a D5 design flaw
+    // manage $form_values to allow the same form to be submitted more than once
+    $form_values = unserialize(variable_get('gallery_wizard_data', array()));
+    $form_values['initial_check'] = FALSE;
+  }
+  
+  $form['install_status'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Install status'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#description' => t('Correct configuration of the following items is essential for the embedded gallery to function properly.'),
+  );
+  
+  // Step 1: Check PHP Memory
+  if ($form_values['step'] >= GALLERY_INSTALL_STEP_PHPMEMORY) {
+    _gallery_install_step_php_memory($form, $form_values, $install_status);
+  }
+
+  // Step 2 : Gallery2 Locations
+  if ($form_values['step'] >= GALLERY_INSTALL_STEP_LOCATIONS) {
+    _gallery_install_step_locations($form, $form_values, $install_status);
+  }
+  
+  // Step 3: Drupal Modules and Gallery2 Plugins check
+  if ($form_values['step'] >= GALLERY_INSTALL_STEP_PLUGINS) {
+    _gallery_install_step_plugins($form, $form_values, $install_status);
+  }
+
+  // Step 4: Clean URL configuration
+  if ($form_values['step'] >= GALLERY_INSTALL_STEP_URLREWRITE) {
+    _gallery_install_step_urlrewrite($form, $form_values, $install_status);
+  }
+  
+  // Step 5: User Synchronization
+  if ($form_values['step'] >= GALLERY_INSTALL_STEP_USERSYNC) {
+    _gallery_install_step_usersync($form, $form_values, $install_status);
+  }
+  
+  $form['initial_check'] = array(
+    '#type' => 'hidden',
+    '#value' => $form_values['initial_check'],
+  );
+  $form['gallery_valid'] = array(
+    '#type' => 'hidden',
+    '#value' => $form_values['gallery_valid'],
+  );
+  $form['plugins_valid'] = array(
+    '#type' => 'hidden',
+    '#value' => $form_values['plugins_valid'],
+  );
+  $form['step'] = array(
+    '#type' => 'hidden',
+    '#value' => $form_values['step'],
+  );
+  
+  $form['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset & Restart'));
+
+  // Set the global status variable 'gallery_valid'
+  gallery_set_status(array(
+    'gallery_valid' => array(
+      'title' => t('Overall Status (Installation)'),
+      'severity' => $form_values['gallery_valid'] ? GALLERY_SEVERITY_SUCCESS : GALLERY_SEVERITY_ERROR,
+    ),
+  ));
+  
+  // Create install status table
+  $error = FALSE;
+  $rows = array();
+  foreach ($install_status as $key => $step_status) {
+    // Find the combination of status and severity of the plugin
+    $severity = ($step_status['status'] <= 0) ? $step_status['severity'] : GALLERY_SEVERITY_SUCCESS; 
+    if (!$step_status['status']) {
+      $error = TRUE;
+    }   
+    $row = array();
+    $row[] = array('data' => $step_status['title'], 'align' => 'left', 'width' => '20%');
+    $row[] = array('data' => theme('gallery_severity_message', $severity), 'align' => 'center');
+    $row[] = array('data' => $step_status['info'], 'class' => 'description', 'id' => $key);
+    $rows[] = $row;
+  }
+  if ($error && !$form_values['initial_check']) {
+    $rows[] = array(array(
+      'data' => t('Critical errors are present. Your Gallery is not available.'), 
+      'colspan' => '3', 
+      'align' => 'center', 
+      'class' => 'message')
+    );
+  }
+  $header = array('Step', 'Status', 'Description');
+  $form['install_status']['status']['#value'] = theme('table', $header, $rows, array('class' => 'package'));
+  
+  return $form;
+}
+
+/**
+ * Function _gallery_install_step_php_memory().
+ * Step 1: Check PHP Memory
+ */ 
+function _gallery_install_step_php_memory(&$form, &$form_values, &$install_status) {
+  $phpmemory_info = _gallery_php_mem_check();
+  $desc = $phpmemory_info['info'];
+  if (!$phpmemory_info['status']) {
+    $desc .= ' '. t('Until this is fixed your Gallery2 cannot be installed.');
+    $form_values['step'] = GALLERY_INSTALL_STEP_PHPMEMORY;
+  }
+  else {
+    $form_values['step']++;
+  }
+  
+  $form['phpmemory'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Step 1: PHP Memory Test') . ($phpmemory_info['status'] ? ' '. t('(OK)') : ''),
+    '#description' => $desc,
+    '#collapsible' => ($form_values['step'] > GALLERY_INSTALL_STEP_PHPMEMORY),
+    '#collapsed' => $phpmemory_info['status'],
+  );
+  if (!$phpmemory_info['status']) {
+    $form['phpmemory']['check'] = array('#type' => 'submit', '#value' => t('Check PHP memory again'));      
+  }
+  
+  $install_status['phpmemory']['status'] = $phpmemory_info['status'];
+  $install_status['phpmemory']['info'] = $phpmemory_info['info'];
+}
+
+/**
+ * Function _gallery_install_step_locations().
+ * Step 2: Gallery2 Locations
+ */ 
+function _gallery_install_step_locations(&$form, &$form_values, &$install_status) {
+  if ($form_values['step'] > GALLERY_INSTALL_STEP_LOCATIONS || $form_values['initial_check']) {
+    _gallery_install_locations($form, $form_values, $install_status);
+  }
+  // Check was not successful. Don't proceed with step 3
+  if (!$form_values['gallery_valid']) {
+    $form_values['step'] = GALLERY_INSTALL_STEP_LOCATIONS;
+  }
+  else {
+    $form_values['step']++;
+  }
+
+  $autodetect_dir = variable_get('gallery_autodetect_dir', 1);
+  $extra = $autodetect_dir ? t('- Auto Configuration') : t('- Manual Configuration');
+  // If 'initial_check' = True then this is the first time the user has come through this
+  // step (or the wizard has been restarted). Allow the field to be edited EVEN IF VALID.
+  // If 'initial_check' = False then this step has been completed already, so make read-only.
+  if (!$form_values['gallery_valid']) {
+    $desc = $autodetect_dir ?
+      t('Enter the \'Gallery2 URL or URI\' and click \'Test location settings\'
+        to automatically configure the settings needed for embedding Gallery2 into Drupal. Note that
+        the auto-config will not work for all host configurations. If you have tried it with a value 
+        you know is correct and it did not work then just use the manual configuration instead.') :
+      t('Enter the \'Gallery2 URL or URI\' and \'Gallery2 filesystem path\' and then click 
+        \'Test location settings\'. This will check and configure the settings needed for embedding
+        Gallery2 into Drupal.');
+  }
+  else {
+    $desc = '';
+  }
+  
+  $form['install'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Step 2: Gallery2 location settings') .' '. $extra . ($form_values['gallery_valid'] ? ' '. t('(OK)') : ''),
+    '#description' => isset($form['install']['#description']) ? ($desc .'<p>'. $form['install']['#description'] .'</p>') : $desc,
+    '#collapsible' => ($form_values['step'] > GALLERY_INSTALL_STEP_LOCATIONS),
+    '#collapsed' => $form_values['gallery_valid'],
+  ); 
+  
+  // Only provide these values when autoconfig has been set. Otherwise the user might think
+  // that these had been automatically figured out even though manual config was done.
+  if ($autodetect_dir) {
+    $gallery_uri = isset($form_values['gallery_uri_auto']) ? 
+      $form_values['gallery_uri_auto'] : ($form_values['gallery_valid'] ? 
+      variable_get('gallery_uri', '/gallery2/') : '');
+
+    $gallery_dir = isset($form_values['gallery_dir_auto']) ? 
+      $form_values['gallery_dir_auto'] : ($form_values['gallery_valid'] ? 
+      variable_get('gallery_dir', './gallery2/') : '');
+      
+    $embed_uri = isset($form_values['gallery_embed_uri_auto']) ? 
+      $form_values['gallery_embed_uri_auto'] : ($form_values['gallery_valid'] ? 
+      variable_get('gallery_embed_uri', '?q=gallery') : '');
+    $form['install']['gallery_uri_auto'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Gallery2 URL or URI'),
+      '#default_value' => $gallery_uri,
+      '#size' => 64,
+      '#maxlength' => 128,
+      '#description' => t('URL or URI of the G2 standalone location. This can be either the full
+        URL to Gallery2 (e.g. http://www.example.com/gallery2) or the path from docroot to the
+        Gallery2 directory (e.g. /gallery2). If using a URI the protocol/hostname are both
+        optional.'),
+      '#disabled' => $form_values['gallery_valid'],
+    );
+
+    if (!empty($gallery_dir)) {
+      $form['install']['gallery_dir_auto_item'] = array(
+        '#title' => t('Gallery2 filesystem path'),
+        '#type' => 'item',
+        '#value' => $gallery_dir,
+      );
+    }
+    $form['install']['gallery_dir_auto'] = array(
+      '#type' => 'value',
+      '#value' => $gallery_dir,
+    );
+    
+    if (!empty($gallery_dir)) {
+      $form['install']['gallery_embed_uri_auto_item'] = array(
+        '#title' => t('Embed URI'),
+        '#type' => 'item',
+        '#value' => $embed_uri,
+      );
+    }
+    $form['install']['gallery_embed_uri_auto'] = array(
+      '#type' => 'value',
+      '#value' => $embed_uri,
+    );
+  }
+  else {
+    $gallery_uri = isset($form_values['gallery_uri_man']) ? 
+      $form_values['gallery_uri_man'] : ($form_values['gallery_valid'] ? 
+      variable_get('gallery_uri', '/gallery2/') : '');
+      
+    $gallery_dir = isset($form_values['gallery_dir_man']) ? 
+      $form_values['gallery_dir_man'] : ($form_values['gallery_valid'] ? 
+      variable_get('gallery_dir', './gallery2/') : '');
+      
+    $embed_uri = isset($form_values['gallery_embed_uri_man']) ? 
+      $form_values['gallery_embed_uri_man'] : ($form_values['gallery_valid'] ? 
+      variable_get('gallery_embed_uri', '?q=gallery') : '');
+      
+    $form['install']['gallery_uri_man'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Gallery2 URL or URI'),
+      '#default_value' => $gallery_uri,
+      '#size' => 64,
+      '#maxlength' => 128,
+      '#description' => t('URL or URI of the G2 standalone location. This can be either the full
+        URL to Gallery2 (e.g. http://www.example.com/gallery2) or the path from docroot to the
+        Gallery2 directory (e.g. /gallery2). If using a URI the protocol/hostname are both
+        optional.'),
+      '#disabled' => $form_values['gallery_valid'],
+    );
+    
+    $form['install']['gallery_dir_man'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Gallery2 filesystem path'),
+      '#default_value' => $gallery_dir,
+      '#size' => 64,
+      '#maxlength' => 128,
+      '#description' => t('The filesystem path of your Gallery2 directory. This can be either an
+        absolute path (e.g. /home/mysite/htdocs/gallery2) or relative to the root directory of your
+        Drupal installation (e.g. ../gallery2).'),
+      '#disabled' => $form_values['gallery_valid'],
+    );
+  
+    $form['install']['gallery_embed_uri_man'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Embed URI'),
+      '#default_value' => $embed_uri,
+      '#size' => 64,
+      '#maxlength' => 128,
+      '#description' => t('URI to access G2 via Drupal. Don\'t worry if you are using clean urls in Drupal and this still ends in \'index.php?q=gallery\'. This is needed to get the Gallery2 URL rewrite module to work correctly and will not be visible.'),
+      '#disabled' => $form_values['gallery_valid'],
+    );
+  }
+  
+  if (!$form_values['gallery_valid']) {
+    $form['install']['location_button'] = array(
+      '#type' => 'submit',
+      '#value' => t('Test location settings'),
+    );
+    if ($autodetect_dir) {
+      $form['install']['manual_config_button'] = array(
+        '#type' => 'submit',
+        '#value' => t('Use Manual Configuration'),
+      );
+    }
+    else {
+      $form['install']['auto_config_button'] = array(
+        '#type' => 'submit',
+        '#value' => t('Use Auto Configuration'),
+      );
+    }
+  }
+}
+
+/**
+ * Function _gallery_install_step_plugins().
+ * Step 3: Drupal Modules / Gallery2 Plugins
+ */ 
+function _gallery_install_step_plugins(&$form, &$form_values, &$install_status) {  
+  $form['plugins'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Step 3: Drupal Modules / Gallery2 Plugins'),
+    '#collapsible' => ($form_values['step'] > GALLERY_INSTALL_STEP_PLUGINS),
+    '#collapsed' => FALSE,
+  );
+  
+  $header = array('Name', 'Status', 'Description');
+  $overall_plugin_severity = GALLERY_SEVERITY_UNKNOWN - 1;
+  $overall_plugin_status = GALLERY_PLUGIN_ENABLED;
+  // Wanted (required) G2 plugins 
+  $wanted_g2_plugins = gallery_wanted_plugin_info();
+  $rows = array();
+  foreach ($wanted_g2_plugins as $key => $module) {
+    // Find the combination of status and severity of the plugin
+    $severity = ($module['status'] != GALLERY_PLUGIN_ENABLED) ? $module['severity'] : GALLERY_SEVERITY_SUCCESS;
+    $row = array();
+    $row[] = array('data' => $module['title'], 'align' => 'left', 'width' => '15%');
+    $row[] = array('data' => theme('gallery_severity_status_message', $severity, $module['status']), 'align' => 'center');
+    $row[] = array('data' => $module['info'], 'class' => 'description', 'id' => $key);
+    $rows[] = $row;
+    if ($module['status'] != GALLERY_PLUGIN_ENABLED && $severity > $overall_plugin_severity) {
+      $overall_plugin_severity = $severity;
+      $overall_plugin_status = $module['status'];
+    }
+  }
+  $form['plugins']['wanted_g2_plugins'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Recommended Gallery2 plugins'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#value' => theme('table', $header, $rows, array('class' => 'package')),
+    '#description' => t('These Gallery2 plugins support much of the functionality that the Drupal Gallery module provides.
+                         None of them are strictly required, but you will almost certainly want to activate at least some
+                         of them (particularly the Image Block plugin).'),
+  );  
+     
+  // Unwanted (interfering) G2 plugins  
+  $unwanted_g2_plugins = gallery_unwanted_plugin_info();
+  $rows = array();
+  foreach ($unwanted_g2_plugins as $key => $module) {
+    // Find the combination of status and severity of the plugin
+    $severity = ($module['status'] == GALLERY_PLUGIN_ENABLED) ? 
+      $module['severity'] : GALLERY_SEVERITY_SUCCESS;    
+    $row = array();
+    $row[] = array('data' => $module['title'], 'align' => 'left', 'width' => '15%');
+    $row[] = array('data' => theme('gallery_severity_status_message', $severity, $module['status'], TRUE, TRUE), 'align' => 'center');
+    $row[] = array('data' => $module['info'], 'class' => 'description', 'id' => $key);
+    $rows[] = $row;
+    if ($module['status'] == GALLERY_PLUGIN_ENABLED && $severity > $overall_plugin_severity) {
+      $overall_plugin_severity = $severity;
+      $overall_plugin_status = $module['status'];
+    }
+  }
+  $form['plugins']['unwanted_g2_plugins'] = array(
+    '#type' => 'fieldset',
+    '#title' =>  t('Gallery2 plugins which should not be installed'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#value' => theme('table', $header, $rows, array('class' => 'package')),
+    '#description' => t('These Gallery2 plugins should not be used when Gallery2 is
+                         embedded into Drupal as they may cause problems.'),
+  );  
+    
+  // Wanted (optional) Drupal modules
+  $wanted_modules = gallery_wanted_module_info();
+  $rows = array();
+  foreach ($wanted_modules as $key => $module) {
+    // Find the combination of status and severity of the plugin
+    $severity = (!$module['status']) ? $module['severity'] : GALLERY_SEVERITY_SUCCESS;    
+    $row = array();
+    $row[] = array('data' => $module['title'], 'align' => 'left', 'width' => '15%');
+    $row[] = array('data' => theme('gallery_severity_status_message', $severity, $module['status']), 'align' => 'center');
+    $row[] = array('data' => $module['info'], 'class' => 'description', 'id' => $key);
+    $rows[] = $row;
+    if ($module['status'] != GALLERY_PLUGIN_ENABLED && $severity > $overall_plugin_severity) {
+      $overall_plugin_severity = $severity;
+      $overall_plugin_status = $module['status'];
+    }
+  }
+  $form['plugins']['wanted_modules'] = array(
+    '#type' => 'fieldset',
+    '#title' =>  t('Optional Drupal modules'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#value' => theme('table', $header, $rows, array('class' => 'package')),
+    '#description' => t('These Drupal modules can optionally be used to enhance the functionality of the Gallery module.'),
+  );
+
+  // Check if no issue was found.
+  if ($overall_plugin_severity < GALLERY_SEVERITY_UNKNOWN) {
+    $overall_plugin_severity = GALLERY_SEVERITY_SUCCESS;
+  }
+
+  $install_status['plugins']['status'] = $overall_plugin_status;
+  $install_status['plugins']['severity'] = $overall_plugin_severity;
+  
+  if ($overall_plugin_status <= 0) {
+    // There is a problem with at least one module/plugin
+    $form_values['plugins_valid'] = FALSE;   
+    $form['plugins']['#title'] .= ' ('. strip_tags(theme('gallery_severity_message', $overall_plugin_severity)) .')';       
+    $install_status['plugins']['info'] = t('You may have some loss in functionality in your embedded Gallery2 (see below
+                                            for details). You should check the details and if the functionality is not
+                                            important for your site you can just ignore this.');
+    $form['plugins']['#collapsed'] = !$form_values['initial_check'];
+    if ($form_values['initial_check']) {
+      $form_values['step']++;
+    }
+  }
+  else {
+    $form_values['step']++;
+    $form_values['plugins_valid'] = TRUE;
+    $form['plugins']['#collapsible'] = TRUE;
+    $form['plugins']['#collapsed'] = TRUE;
+    $form['plugins']['#title'] .= ' '. t('(OK)');       
+    $install_status['plugins']['info'] = t('The status of all Drupal modules and Gallery2 plugins
+                                            is optimal for your embedded Gallery2.');
+  }
+}
+
+/**
+ * Function _gallery_install_step_urlrewrite().
+ * Step 4: Clean URL configuration
+ */
+function _gallery_install_step_urlrewrite(&$form, &$form_values, &$install_status) {
+  $form['rewrite'] = array('#type' => 'fieldset');
+  
+  $clean_urls_status = variable_get('clean_url', 0);
+  $rewrite_status = gallery_single_plugin_status('rewrite');
+
+  if ($clean_urls_status) {
+    if ($rewrite_status == GALLERY_PLUGIN_ENABLED) {
+      _gallery_install_urlrewrite($public_path, $htaccess_path, TRUE);
+      $public_path = isset($form_values['htaccess_public_path']) ? $form_values['htaccess_public_path'] : $public_path;
+      $htaccess_path = isset($form_values['htaccess_filesystem_path']) ? $form_values['htaccess_filesystem_path'] : $htaccess_path;
+      // Check for writable .htaccess file
+      if (file_exists($htaccess_path .'.htaccess')) {
+        if (is_writable($htaccess_path .'.htaccess')) {
+          $form_values['rewrite_valid'] = ($form_values['initial_check'] || $form_values['step'] > GALLERY_INSTALL_STEP_URLREWRITE);
+          $result = t('There is a writable .htaccess file in your defined Drupal directory (@dir).',
+                        array('@dir' => $htaccess_path));
+          // Check syntax of the 'Show Item' rule (must start with 'gallery/')
+          list ($ret, $rules) = GalleryCoreApi::getPluginParameter('module', 'rewrite', 'activeRules');
+          if (!$ret) {
+            $rules = unserialize($rules);
+            if (isset($rules['rewrite'][0]['pattern']) && substr($rules['rewrite'][0]['pattern'], 0, 7) != 'gallery') {
+              $result .= ' <strong>'. t('Your \'Show Item\' rule should start with \'gallery/\'.
+                                         Make sure to change the URL Rewrite rule(s) accordingly.') .'</strong>';
+            }
+          }
+        }
+        else {
+          $form_values['rewrite_valid'] = FALSE;
+          $result = t('The .htaccess file in your defined Drupal directory (@dir) is not writable. Please CHMOD it to 644
+                       (or 666 if 644 does not work).', array('@dir' => $htaccess_path));
+        }
+      }
+      else {
+        $form_values['rewrite_valid'] = FALSE;
+        $result = t('There is no .htaccess file in your defined Drupal directory (@dir) or the directory does not exist.',
+                      array('@dir' => $htaccess_path));
+      }
+    }
+    else {
+      $form_values['rewrite_valid'] = FALSE;
+      $result = t('Clean URLs are enabled in Drupal, but the Gallery2 URL Rewrite plugin is unavailable.');
+    }
+  }
+  else {
+    $form_values['rewrite_valid'] = TRUE;
+    $result = t('Clean URLs are disabled in Drupal and the URL Rewrite plugin will not be configured.');
+    $form['rewrite']['#description'] = t('Clean URLs are disabled in Drupal and the URL Rewrite plugin will not be configured.
+                                          If you want to use the URL Rewrite plugin please enable clean URLs in Drupal and
+                                          install and activate the plugin in Gallery2.');
+  }
+  
+  // User selected to skip the URLRewrite step
+  if (variable_get('gallery_rewrite_disable', 0)) {
+    $form_values['rewrite_valid'] = TRUE;
+    $clean_urls_status = FALSE;
+    $result = $form['rewrite']['#description'] = t('URL Rewrite has been disabled manually.');
+    $form['rewrite']['#description'] .= ' '. t('\'Reset & Restart\' your configuration to change these settings.');
+  }
+  
+  if ($form_values['rewrite_valid']) {
+    $form_values['step']++;
+  }
+  
+  $form['rewrite']['#title'] = t('Step 4: Clean URLs / URL Rewrite settings') . ($form_values['rewrite_valid'] ? ' '. t('(OK)') : '');
+  $form['rewrite']['#collapsible'] = ($form_values['step'] > GALLERY_INSTALL_STEP_URLREWRITE);
+  $form['rewrite']['#collapsed'] = $form_values['rewrite_valid'];
+
+  if ($clean_urls_status) {
+    if ($rewrite_status < GALLERY_PLUGIN_ENABLED) {
+      $form['rewrite']['#description'] = t('Clean URLs are enabled in Drupal, but the Gallery2 URL Rewrite plugin is unavailable
+                                            (!status).', array('!status' => theme('gallery_plugin_status_message', $rewrite_status)));
+      if (!$form_values['initial_check'] && !$form_values['rewrite_valid']) {
+        $form_values['step'] = GALLERY_INSTALL_STEP_URLREWRITE;
+        $form['rewrite']['check'] = array('#type' => 'submit', '#value' => t('Check URL Rewrite status again'));
+      }
+    }
+    else {
+      // CleanURL and URLRewrite are both enabled
+      $form['rewrite']['#description'] = t('Clean URLs are !clean_url_status in Drupal and the Gallery2 URL Rewrite plugin is
+                                            !rewrite_status. It is possible to automatically configure the URL Rewrite plugin.
+                                            The configuration assumes that the rules should be placed in your Drupal .htaccess
+                                            file (it will add them to the beginning) which works in most applications. If you
+                                            need a special configuration, enter the desired values manually.',
+        array(
+          '!clean_url_status' => theme('gallery_module_status_message', $clean_urls_status),
+          '!rewrite_status' => theme('gallery_plugin_status_message', $rewrite_status)
+        )
+      );
+      $form['rewrite']['#description'] .= $form_values['rewrite_valid'] ? '' : ('<p>'. $result .'</p>');
+      
+      $form['rewrite']['htaccess_public_path'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Public path to your .htaccess file'),
+        '#size' => 64,
+        '#maxlength' => 255,
+        '#default_value' => $public_path,
+        '#description' => t('This is the location of your Drupal .htaccess file relative to your webserver document root.'),
+        '#disabled' => $form_values['rewrite_valid'],
+      );
+      $form['rewrite']['htaccess_filesystem_path'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Filesystem path to your .htaccess file'),
+        '#size' => 100,
+        '#maxlength' => 255,
+        '#default_value' => $htaccess_path,
+        '#description' => t('This is the absolute directory path of your Drupal .htaccess file.'),
+        '#disabled' => $form_values['rewrite_valid'],
+      );
+      if (!$form_values['initial_check'] && !$form_values['rewrite_valid']) {
+        $form['rewrite']['config'] = array('#type' => 'submit', '#value' => t('Configure URL Rewrite plugin'));
+      }
+    }
+    
+    if (!$form_values['initial_check'] && !$form_values['rewrite_valid']) {
+      $form['rewrite']['skip'] = array('#type' => 'submit', '#value' => t('Skip URL Rewrite Config'));
+    }
+  }
+
+  $install_status['cleanurls']['status'] = $form_values['rewrite_valid'];
+  $install_status['cleanurls']['info'] = $result;
+}
+
+/**
+ * Function _gallery_install_step_usersync().
+ * Step 5: User Synchronization
+ */ 
+function _gallery_install_step_usersync(&$form, &$form_values, &$install_status) {
+  $form_values['gallery_valid'] = variable_get('gallery_valid', 0);
+  
+  if ($form_values['gallery_valid']) {
+    $form_values['step']++;
+  }
+  
+  $form['usersync'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Step 5: Initial User Synchronization') . ($form_values['gallery_valid'] ? ' '. t('(OK)') : ''),
+    '#collapsible' => ($form_values['step'] > GALLERY_INSTALL_STEP_USERSYNC),
+    '#collapsed' => ($form_values['gallery_valid']),
+  );
+  
+  $install_status['usersync']['status'] = $form_values['gallery_valid'];
+  if ($form_values['gallery_valid']) {
+    $install_status['usersync']['info'] = $form['usersync']['#description'] = t('Your initial user synchronization has been
+        completed already.<br />If you want to resync all your users or you want to import users from an existing Gallery2
+        setup, you can always use the <a href= "@gallery-usersync">Advanced Sync</a> options in the Gallery user administration.',
+        array('@gallery-usersync' => url('admin/user/gallery/advanced')));
+  }
+  else {
+    $install_status['usersync']['info'] = $form['usersync']['#description'] = t('User synchronization is essential for the
+        embedded Gallery to work correctly. Drupal users/groups are usually synced with their Gallery counterparts when a
+        user/group is modified in Drupal. Missing user mappings will cause errors in your embedded Gallery.');
+    $form['usersync']['#description'] .= '<br /><br />'. t('It is recommended that you sync your users now. However there
+        can be reasons to skip this step, e.g. if you have a working Gallery with many users and a fresh Drupal installation.
+        Note that the current user and the Drupal superuser (uid=1) will always be sync.');
+    
+    $form['usersync']['sync'] = array('#type' => 'submit', '#value' => t('Sync users/groups'));
+    $form['usersync']['skip'] = array('#type' => 'submit', '#value' => t('Skip sync'));
+  }
+}
+
+/**
+ * Function _gallery_install_submit().
+ */
+function _gallery_install_submit($form_id, $form_values) {
+  switch ($form_values['op']) {
+    case t('Sync users/groups'):
+    case t('Skip sync'):
+      $autodetect = variable_get('gallery_autodetect_dir', 1);
+      if ($autodetect) {
+        variable_set('gallery_uri', $form_values['gallery_uri_auto']);
+        variable_set('gallery_dir', $form_values['gallery_dir_auto']);
+        variable_set('gallery_embed_uri', $form_values['gallery_embed_uri_auto']);
+      }
+      else {
+        variable_set('gallery_uri', $form_values['gallery_uri_man']);
+        variable_set('gallery_dir', $form_values['gallery_dir_man']);
+        variable_set('gallery_embed_uri', $form_values['gallery_embed_uri_man']);
+      }
+      variable_del('gallery_wizard_data');
+      
+      // This is the last step: gallery_valid will be TRUE even
+      // if the admin decides to skip the user/group sync step
+      $form_values['gallery_valid'] = TRUE;
+      
+      // Set gallery_valid variable and rebuild the menu so that
+      // the user sync callback is available for the next step
+      variable_set('gallery_valid', $form_values['gallery_valid']);
+      // Clear cache and rebuild menu
+      cache_clear_all('gallery', 'cache', TRUE);
+      menu_rebuild();
+      
+      // Always sync (at least) the current user to avoid
+      // errors (unknown user) during GalleryEmbed::init()
+      require_once(drupal_get_path('module', 'gallery') .'/gallery_user.inc');
+      global $user;
+      gallery_user_modify($user, 'update', TRUE, $form_values);
+      // Make sure the Drupal superuser (uid=1) always gets admin right
+      if ($user->uid != 1) {
+        gallery_user_modify(user_load(array('uid' => 1)), 'update', FALSE, $form_values);
+      }
+      // Trigger bulk user/group sync
+      if ($form_values['op'] != t('Skip sync')) {
+        require_once(drupal_get_path('module', 'gallery') .'/gallery_user_admin.inc');
+        _gallery_user_advanced_start(array('sync'), 'admin/settings/gallery/install');
+      }
+      drupal_get_messages();
+      drupal_goto('admin/settings/gallery/install');
+      break;
+    case t('Use Manual Configuration'):
+      variable_set('gallery_autodetect_dir', 0);
+      $form_values['step'] = GALLERY_INSTALL_STEP_LOCATIONS;
+      break;
+    case t('Use Auto Configuration'):
+      variable_set('gallery_autodetect_dir', 1);
+      $form_values['step'] = GALLERY_INSTALL_STEP_LOCATIONS;
+      break;
+    case t('Configure URL Rewrite plugin'):
+      if (!_gallery_install_urlrewrite($form_values['htaccess_public_path'], $form_values['htaccess_filesystem_path'])) {
+        $form_values['step'] = GALLERY_INSTALL_STEP_URLREWRITE;
+      }
+      break;
+    case t('Skip URL Rewrite Config'):
+      variable_set('gallery_rewrite_disable', 1);
+      break;
+    case t('Reset & Restart'):
+      // Reset configuration
+      variable_del('gallery_autodetect_dir');
+      variable_del('gallery_uri');
+      variable_del('gallery_dir');
+      variable_del('gallery_embed_uri');
+      variable_del('gallery_valid');
+      variable_del('gallery_rewrite_disable');
+      variable_del('gallery_wizard_data');
+      menu_rebuild();
+      variable_set('gallery_config_reset', TRUE);
+      drupal_get_messages();
+      drupal_goto('admin/settings/gallery/install');
+      break;
+  }
+  
+  variable_set('gallery_wizard_data', serialize($form_values));
+}
+
+/**
+ * Function _gallery_install_locations().
+ */
+function _gallery_install_locations(&$form, &$form_values, &$install_status) {
+  include_once(drupal_get_path('module', 'gallery') .'/G2EmbedDiscoveryUtilities.class');
+
+  $autodetect = variable_get('gallery_autodetect_dir', 1);
+  if ($form_values['initial_check']) {
+    $orig_values['g2_uri'] = variable_get('gallery_uri', '/gallery2/');
+    $orig_values['g2_embed_path'] = variable_get('gallery_dir', './gallery2/');
+    $orig_values['embed_uri'] = variable_get('gallery_embed_uri', '?q=gallery');
+  }
+  else {
+    if ($autodetect) {
+      $orig_values['g2_uri'] = $form_values['gallery_uri_auto'];
+    }
+    else {
+      $orig_values['g2_uri'] = $form_values['gallery_uri_man'];
+      $orig_values['g2_embed_path'] = $form_values['gallery_dir_man'];
+      $orig_values['embed_uri'] = $form_values['gallery_embed_uri_man'];
+    }
+  }
+
+  list($gallery_valid, $detect_values, $result) = _gallery_install_locations_check($orig_values, $autodetect);
+  if (!$gallery_valid) {
+    $form['install']['#description'] = gallery_format_status($result, t('Errors in your current Gallery2 location settings:'));
+  }
+
+  if ($autodetect) {
+    $form_values['gallery_uri_auto'] = $detect_values['g2_uri'];
+    $form_values['gallery_dir_auto'] = $detect_values['g2_embed_path'];
+    $form_values['gallery_embed_uri_auto'] = $detect_values['embed_uri'];
+  }
+  else {
+    $form_values['gallery_uri_man'] = $detect_values['g2_uri'];
+    $form_values['gallery_dir_man'] = $detect_values['g2_embed_path'];
+    $form_values['gallery_embed_uri_man'] = $detect_values['embed_uri'];
+  }
+  $form_values['gallery_valid'] = $gallery_valid;
+
+  $install_status['locations']['status'] = $gallery_valid;
+  $install_status['locations']['info'] = $gallery_valid ?
+    t('The Gallery2 location settings appear to be correct.') :
+    t('There is a problem with the Gallery2 location settings. Please check below and retest.
+       Remember that the auto-config will not work for all hosts.');
+}
+
+/**
+ * Function _gallery_install_locations_check().
+ */
+function _gallery_install_locations_check($orig, $autodetect) {
+  // Set up the result status array. The rest gets filled in later.
+  $result = array(
+    'g2_uri' => array(
+          'title' => t('URI of Gallery2'),
+          'severity' => GALLERY_SEVERITY_ERROR,
+    ),
+    'g2_embed_path' => array(
+          'title' => t('Location of Gallery2'),
+          'severity' => GALLERY_SEVERITY_ERROR,
+    ),
+    'init' => array(
+          'title' => t('Gallery Init'),
+          'severity' => GALLERY_SEVERITY_ERROR,
+    ),
+  );
+  
+  $vars = array();
+  $vars['gallery_valid'] = TRUE;
+  
+  // Strip the end /gallery if present and replace with index.php?q=gallery to avoid any 
+  // url rewrite issues. See http://gallery.menalto.com/node/46181
+  // Note the use of index.php in all cases. Not needed for Apache, but for IIS
+  
+  $embed_uri = $orig['embed_uri'];
+  if ($autodetect || empty($embed_uri)) {
+    $embed_uri = url('gallery', NULL, NULL, FALSE);
+    // i18n overrides the link to gallery to include a ?q=en or something
+    if (module_exists('i18n')) {
+      i18n_get_lang_prefix($embed_uri, TRUE);
+    }
+    if (substr($embed_uri, -8) == '/gallery') {
+      $embed_uri = substr($embed_uri, 0, -7) .'index.php?q=gallery';
+    }
+  }
+  
+  // Normalise the Embed Application URI
+  $embed_uri = G2EmbedDiscoveryUtilities::normalizeEmbedUri($embed_uri); 
+  $vars['embed_uri'] = $embed_uri;     
+     
+  // Normalise the G2 URI 
+  $g2_uri = G2EmbedDiscoveryUtilities::normalizeG2Uri($orig['g2_uri']);
+  $vars['g2_uri'] = $g2_uri;
+
+    // Find the Gallery Directory and Embed URI
+  if ($autodetect) {
+    // Auto-Detect the G2 embed path 
+    list($success, $embed_php_path, $error_string) = 
+      G2EmbedDiscoveryUtilities::getG2EmbedPathByG2Uri($g2_uri); 
+    if ($success) {
+      // G2 Embed Path is found OK
+      $vars['g2_embed_path'] = rtrim($embed_php_path, 'embed.php'); 
+    }
+    else {
+      // Something is wrong with the G2 URI given as the G2 embed path is not found
+      // Try getG2EmbedPathByG2UriEmbedUriAndLocation instead
+      $drupal_path = realpath(".") .'/';  
+      list($success, $embed_php_path, $error_string) =
+        G2EmbedDiscoveryUtilities::getG2EmbedPathByG2UriEmbedUriAndLocation($g2_uri, $embed_uri, $drupal_path);
+      if ($success) {
+        // G2 Embed Path is found OK
+        $vars['g2_embed_path'] = rtrim($embed_php_path, 'embed.php'); 
+      }
+      else {
+        $result['g2_uri']['status'] = FALSE;
+        $result['g2_uri']['info'] = $error_string;
+        $vars['g2_embed_path'] = '';
+        $vars['gallery_valid'] = FALSE;
+      } 
+    }
+    // Check for config.php in the embed_path (not existing => invalid path)
+    //  e.g. this is the path to the G2 codebase, but we have a multisite configuration
+    if (!empty($vars['g2_embed_path'])) {
+      list($ok, $error_string) = G2EmbedDiscoveryUtilities::isFileReadable($vars['g2_embed_path'] .'config.php');
+      if (!$ok) {
+        $result['g2_embed_path']['status'] = FALSE;
+        $result['g2_embed_path']['info'] = $error_string;
+        $vars['g2_embed_path'] = '';
+        $vars['gallery_valid'] = FALSE;
+      }
+    }
+  } 
+  else {
+    // Do not autodetect the variables, but check the manually entered ones.
+    $embed_php_path = $orig['g2_embed_path'];
+    $embed_php_path .= (substr($embed_php_path, -1) != '/') ? '/' : '';
+    // Check path can be read, adding embed.php if needed
+    list($ok, $error_string) = G2EmbedDiscoveryUtilities::isFileReadable($embed_php_path .'embed.php');
+    $vars['g2_embed_path'] = $embed_php_path;
+    if (!$ok) {
+      $result['g2_embed_path']['status'] = FALSE;
+      $result['g2_embed_path']['info'] = $error_string;
+      $vars['gallery_valid'] = FALSE;
+    }
+    else {
+      // Check for config.php in the embed_path (not existing => invalid path)
+      //  e.g. this is the path to the G2 codebase, but we have a multisite configuration
+      list($ok, $error_string) = G2EmbedDiscoveryUtilities::isFileReadable($embed_php_path .'config.php');
+      if (!$ok) {
+        $result['g2_embed_path']['status'] = FALSE;
+        $result['g2_embed_path']['info'] = $error_string;
+        $vars['gallery_valid'] = FALSE;
+      }
+    }
+  }
+  
+  // If the filepaths seem correct then check Gallery2 works and has the correct module configs
+  if ($vars['gallery_valid']) {
+    // Gallery install is thought valid, so init it.
+    $vars['gallery_dir'] = $vars['g2_embed_path'];
+    if (!_gallery_init(TRUE, $vars, FALSE)) {
+      // Gallery install was supposed to be valid, but it still failed. Something is wrong.
+      $result['init']['status'] = FALSE;
+      $result['init']['info'] = t('Everything seemed OK, but the Gallery could still not be initialised.
+                                   Perhaps a manually entered value is incorrect.');
+      $vars['gallery_valid'] = FALSE;
+    }
+    else {
+      // Is Gallery2 installed inside the Drupal root directory?
+      _gallery_install_in_drupal_folder($vars['g2_embed_path']);
+      // Update version info
+      gallery_version();       
+      GalleryEmbed::done();
+    }
+  }
+
+  // Only return items where status has been set
+  foreach ($result as $key => $value) {
+    if (!isset($value['status'])) {
+      unset($result[$key]);
+    }
+  }
+  
+  return array($vars['gallery_valid'], $vars, $result);
+}
+
+/**
+ * Function _gallery_install_in_drupal_folder().
+ */
+function _gallery_install_in_drupal_folder($embed_path) {
+  global $base_url;
+  static $warn = TRUE;
+  
+  // Dont proceed if G2 was not initialized
+  if (!isset($GLOBALS['gallery'])) {
+    return;
+  }
+  
+  if (!empty($embed_path)) {
+    // Reset 'gallery_outside' state
+    variable_del('gallery_outside');
+    // Get location of Drupal, Gallery2, etc.
+    $docroot = strtolower(str_replace('/', '\\' , $_SERVER['DOCUMENT_ROOT']));
+    $base_path = strtolower(str_replace('/', '\\' , base_path()));
+    $g2_base = strtolower($GLOBALS['gallery']->getConfig('galleryBaseUrl'));
+    if ((strpos(strtolower($embed_path), $base_path) === FALSE && strpos(strtolower($embed_path), $docroot) !== FALSE)
+        || (!empty($g2_base) && strpos($g2_base, $base_url) === FALSE) || strpos(strtolower($embed_path), '../') !== FALSE) {
+      // G2 is installed outside the Drupal root directory
+      variable_set('gallery_outside', TRUE);
+      if ($warn) {
+        // Avoid duplicate warning
+        $warn = FALSE;
+        drupal_set_message(t('Your location settings are valid, but your Gallery2 is installed outside the Drupal
+                              root directory. It is highly advisable to move G2 into the Drupal folder or to create
+                              a symbolic link in the Drupal directory pointing to your G2 installation (see
+                              instructions on <a href="@codex">codex.gallery2.org</a>).',
+                              array('@codex' => url('http://codex.gallery2.org/Integration:Drupal:Installation'))), 'error');
+      }
+    }
+  }
+}
+
+/**
+ * Function _gallery_install_urlrewrite().
+ */
+function _gallery_install_urlrewrite(&$public_path, &$htaccess_path, $load_config = FALSE) {
+  list($ret, $rewrite_api) = GalleryCoreApi::newFactoryInstance('RewriteApi');
+  if ($ret || !isset($rewrite_api)) {
+    gallery_error(t('Error trying to create URL Rewrite plugin instance.'), $ret);
+    return FALSE;
+  }
+  
+  list($ret, $params) = $rewrite_api->fetchEmbedConfig();
+  if ($ret) {
+    gallery_error(t('Error trying to fetch Embedded URL Rewrite configuration.'), $ret);
+    return FALSE;
+  }
+  
+  // Load the configuration from G2 (or derive from Drupal path)
+  if ($load_config) {
+    if (empty($params['embeddedHtaccess'])) {
+      $http = 'http'. (isset($_SERVER['HTTPS']) ? (($_SERVER['HTTPS'] == 'on') ? 's' : '') : '');
+      $public_path = str_replace($http .'://'. $_SERVER['HTTP_HOST'], '', base_path());
+      $htaccess_path = realpath(".") .'/';
+    }
+    else {
+      $public_path = $params['embeddedLocation'];
+      $htaccess_path = $params['embeddedHtaccess'];
+    }
+  }
+  
+  // Check for trailing slash
+  $public_path .= (substr($public_path, -1) != '/') ? '/' : '';
+  $htaccess_path .= (substr($htaccess_path, -1) != '/') ? '/' : '';
+  
+  if (!$load_config) {
+    if (!file_exists($htaccess_path .'.htaccess')) {
+      // File .htaccess does not exist
+      if (is_writable($htaccess_path .'.htaccess')) {
+        // Directory exists and is writable => try to create .htaccess
+        $f = fopen($htaccess_path .'.htaccess', 'w');
+        fclose($f);
+      }
+      else {
+        return FALSE;
+      }
+    }
+    // Save the G2 rewrite values
+    $params['embeddedLocation'] = $public_path;
+    $params['embeddedHtaccess'] = $htaccess_path;
+    list($ret, $code, $errstr) = $rewrite_api->saveEmbedConfig($params);
+    if ($ret) {
+      gallery_error(t('Error trying to save Embedded URL Rewrite configuration.'), $ret);
+      return FALSE;
+    }
+    if ($code) {
+      $errstr =  $code .' - '. $errstr;
+      drupal_set_message(t('The Gallery2 URL Rewrite plugin returned the following error:') .'<br /><pre>'. $errstr .'</pre>', 'error');
+      return FALSE;
+    }
+  }
+  
+  return TRUE;
+}
diff --git a/gallery_menu/gallery_menu.info b/gallery_menu/gallery_menu.info
new file mode 100644 (file)
index 0000000..acd7df1
--- /dev/null
@@ -0,0 +1,7 @@
+; $Id$
+
+name = "Gallery Menu"
+description = "Gallery2 albums => Drupal menu items"
+
+package = "Gallery2"
+dependencies = gallery
diff --git a/gallery_menu/gallery_menu.module b/gallery_menu/gallery_menu.module
new file mode 100644 (file)
index 0000000..0329fc9
--- /dev/null
@@ -0,0 +1,279 @@
+<?php
+// $Id$
+
+/**
+ * gallery_menu.module
+ */
+
+/**
+ * Implementation of hook_enable().
+ */
+function gallery_menu_enable() {
+  cache_clear_all('gallery:menu', 'cache', TRUE);
+}
+
+/**
+ * Implementation of hook_menu().
+ */
+function gallery_menu_menu($may_cache) {
+  $items = array();
+  if (variable_get('gallery_valid', 0)) {
+    if ($may_cache) {
+      $items[] = array(
+        'path' => 'admin/settings/gallery/menu',
+        'title' => t('Menu'),
+        'callback' => 'drupal_get_form',
+        'callback arguments' => '_gallery_menu_settings',
+        'access' => user_access('administer gallery settings'),
+        'type' => MENU_LOCAL_TASK,
+        'weight' => 6
+      );
+    }
+    else {
+      // Rebuild the menu if the G2 album structure changed
+      $timestamp = variable_get('gallery_menu_timestamp', 0);
+      $query = 'SELECT COUNT([GalleryEntity::id]) FROM [GalleryEntity], [GalleryAlbumItem] WHERE
+                [GalleryAlbumItem::id] = [GalleryEntity::id] AND [GalleryEntity::modificationTimeStamp] > ?';
+       if (($results = gallery_db_query($query, array($timestamp))) && $results[0]) {
+        cache_clear_all('gallery:menu', 'cache', TRUE);
+        variable_set('gallery_menu_timestamp', time());
+      }
+      // Insert the menu items
+      $items = gallery_menu_build_menu();
+    }
+  }
+
+  return $items;
+}
+
+/**
+ * Function gallery_menu_page().
+ */
+function gallery_menu_page($result) {
+  // Generate the path to set the active menu item
+  if (isset($result['themeData']['item'])) {
+    switch ($result['themeData']['item']['entityType']) {
+      case 'GalleryAlbumItem':
+        $id = $result['themeData']['item']['id'];
+        break;
+      case 'GalleryDynamicAlbum':
+        $id = $result['themeData']['pageUrl']['albumId'];
+        break;
+      default:
+        $id = $result['themeData']['item']['parentId'];
+    }
+    if (!empty($id)) {
+      $url_generator =& $GLOBALS['gallery']->getUrlGenerator();
+      if (isset($url_generator->_shortUrls) && variable_get('gallery_menu_rewrite', 0)) {
+        $path = _gallery_menu_album_path($id);
+      }
+      else {
+        list($ret, $parents) = GalleryCoreApi::fetchParentSequence($id);
+        if ($ret) {
+          gallery_error(t('Error fetching item parents'), $ret);
+        }
+        else {
+          array_shift($parents);
+          $path = 'gallery/'. (count($parents) ? implode('/', $parents) .'/' : '') . $id;
+        }
+      }
+    }
+    list($ret, $root) = GalleryCoreApi::getDefaultAlbumId();
+    if ($ret) {
+      gallery_error(t('Error calling getDefaultAlbumId()'), $ret);
+    }
+    menu_set_active_item(($id == $root) ? 'gallery' : $path);
+  }
+}
+
+/**
+ * Function gallery_menu_album().
+ */
+function gallery_menu_album($id) {
+  // Redirect to true album url (from the virtual menu path)
+  $url = gallery_generate_url(array('itemId' => $id), FALSE);
+  drupal_goto($url);
+}
+
+/**
+ * Function gallery_menu_build_menu().
+ */
+function gallery_menu_build_menu() {
+  global $user;
+  $items = array();
+  
+  $cid = 'gallery:menu:'. $user->uid;
+  if ($cache = cache_get($cid)) {
+    $items = unserialize($cache->data);
+  }
+  else {
+    $depth = variable_get('gallery_menu_depth', 5);
+    $tree = gallery_album_tree(NULL, $depth ? $depth : NULL);
+    if (count($tree)) {
+      _gallery_menu_traverse($tree, $items);
+      cache_set($cid, 'cache', serialize($items), CACHE_TEMPORARY);
+    }
+  }
+  
+  return $items;
+}
+
+/**
+ * Function _gallery_menu_traverse().
+ */
+function _gallery_menu_traverse(&$tree, &$items) {
+  static $parents = array();
+  foreach (array_keys($tree) as $id) {
+    if (variable_get('gallery_menu_show_'. $id, 1)) {
+      $item = array();
+      // Check for URL Rewrite being available
+      $url_generator =& $GLOBALS['gallery']->getUrlGenerator();
+      if (isset($url_generator->_shortUrls) && variable_get('gallery_menu_rewrite', 0)) {
+        $item['path'] = _gallery_menu_album_path($id);
+      }
+      else {
+        $item['path'] = 'gallery/'. (count($parents) ? implode('/', $parents) .'/' : '') . $id;
+        $item['callback'] = 'gallery_menu_album';
+        $item['callback arguments'] = array($id);
+      }
+      $album = gallery_item_details($id);
+      $item['title'] = $album['title'];
+      $item['access'] = user_access('access gallery');
+      $item['type'] = MENU_DYNAMIC_ITEM;
+      $items[] = $item;
+      if (count($tree[$id])) {
+        array_push($parents, $id);
+        _gallery_menu_traverse($tree[$id], $items);
+        array_pop($parents);
+      }
+    }
+  }
+}
+
+/**
+ * Function _gallery_menu_album_path().
+ */
+function _gallery_menu_album_path($id) {
+  $path = urldecode(gallery_generate_url(array('itemId' => $id), FALSE, FALSE));
+  // Strip off the base path ...
+  $path = substr($path, strlen(base_path()));
+  // ... and additional parameter (e.g. session id, etc.)
+  if (($pos = strrpos($path, '/')) !== FALSE) {
+    $path = substr($path, 0, $pos + 1);
+  }
+  // Remove the language-prefix
+  if (module_exists('i18n')) {
+    i18n_get_lang_prefix($path, TRUE);
+  }
+  
+  return rtrim($path, '/');
+}
+
+/**
+ * Function _gallery_menu_settings().
+ */
+function _gallery_menu_settings() {
+  $form['menu'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Gallery menu settings'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+  );
+  $url_generator =& $GLOBALS['gallery']->getUrlGenerator();
+  $form['menu']['gallery_menu_rewrite'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable URL Rewrite mode'),
+    '#default_value' => variable_get('gallery_menu_rewrite', 0),
+    '#description' => t('By default gallery menu paths look like \'gallery/album_id/subalbum_id\'. However if URL Rewrite
+                         plugin is enabled in G2 you can force the module to use the same paths as generated by G2 internally
+                         (i.e. \'gallery/v/album/subalbum\').'),
+    '#disabled' => !isset($url_generator->_shortUrls)
+  );
+  $form['menu']['gallery_menu_depth'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Depth of Gallery albums'),
+    '#size' => 10,
+    '#default_value' => variable_get('gallery_menu_depth', 5),
+    '#description' => 'Depth of album hierarchy to include (\'0\' for infinite).'
+  );
+
+  // Item visibility settings
+  $form['menu']['items'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Menu Items'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE
+  );
+  $form['menu']['items'][] = _gallery_menu_settings_table();
+  
+  $form['#submit']['_gallery_menu_settings_submit'] = array();
+  $form['#submit']['system_settings_form_submit'] = array();
+  return system_settings_form($form);
+}
+
+/**
+ * Function _gallery_menu_settings_submit().
+ */
+function _gallery_menu_settings_submit($form_id, $form_values) {
+  cache_clear_all('gallery:menu', 'cache', TRUE);
+}
+
+/**
+ * Function _gallery_menu_settings_table().
+ */
+function _gallery_menu_settings_table() {
+  $depth = variable_get('gallery_menu_depth', 5);
+  $tree = gallery_album_tree(NULL, $depth ? $depth : NULL);
+  
+  $form = _gallery_menu_settings_traverse($tree);
+  $form['#theme'] = 'gallery_menu_settings_table';
+  
+  GalleryEmbed::done();
+  return $form;
+}
+
+/**
+ * Function _gallery_menu_album_traverse().
+ */
+function _gallery_menu_settings_traverse(&$tree) {
+  static $parents = array();
+  foreach (array_keys($tree) as $id) {
+    $album = gallery_item_details($id);
+    $enabled = variable_get('gallery_menu_show_'. $id, 1);
+    $form[$id]['title'] = array('#value' => implode('', $parents) .' '. $album['title']);
+    $form[$id]['checkbox']['gallery_menu_show_'. $id] = array(
+      '#type' => 'checkbox',
+      '#title' => '',
+      '#default_value' => $enabled
+    );
+    if (count($tree[$id]) && $enabled) {
+      array_push($parents, '-');
+      $form[$id]['children'] = _gallery_menu_settings_traverse($tree[$id]);
+      array_pop($parents);
+    }
+  }
+  
+  return $form;
+}
+
+/**
+ * Theme function : theme_gallery_menu_settings_table().
+ */
+function theme_gallery_menu_settings_table($form, $rows = array()) {
+  static $depth = 0;
+  foreach (element_children($form) as $key) {
+    if (isset($form[$key]['title'])) {
+      $row = array();
+      $row[] = drupal_render($form[$key]['title']);
+      $row[] = drupal_render($form[$key]['checkbox']);
+      $rows[] = $row;
+    }
+    if (isset($form[$key]['children'])) {
+      $depth++;
+      $rows = theme_gallery_menu_settings_table($form[$key]['children'], $rows);
+    }
+  }
+
+  $depth--;
+  return ($depth < 0) ? theme('table', array(t('Album'), t('Show')), $rows) : $rows;
+}
diff --git a/gallery_profile/gallery_profile.info b/gallery_profile/gallery_profile.info
new file mode 100644 (file)
index 0000000..0538bc3
--- /dev/null
@@ -0,0 +1,7 @@
+; $Id$
+
+name = "Gallery Profile"
+description = "Customize user profiles to include Gallery2 content (e.g. useralbum images)."
+
+package = "Gallery2"
+dependencies = gallery
diff --git a/gallery_profile/gallery_profile.module b/gallery_profile/gallery_profile.module
new file mode 100644 (file)
index 0000000..86002ea
--- /dev/null
@@ -0,0 +1,245 @@
+<?php
+// $Id$
+
+/**
+ * gallery_profile.module
+ */
+
+/**
+ * Implementation of hook_profile_alter().
+ */
+function gallery_profile_profile_alter(&$account, &$fields) {
+  if (isset($fields['Gallery2'])) {
+    // Set custom title
+    $title = variable_get('gallery_user_profile_title', 'Gallery2');
+    if ($title != 'Gallery2') {
+      $fields[$title] = $fields['Gallery2'];
+      unset($fields['Gallery2']);
+    }
+    $profile = &$fields[$title];
+    // Remove sync status message
+    if (variable_get('gallery_user_profile_hide_sync', 0)) {
+      unset($profile['user_sync']);
+    }
+    // Useralbum link/gallery
+    $gallery_mode = variable_get('gallery_user_profile_gallery', array('link'));
+    if (in_array('gallery', $gallery_mode) && gallery_user_useralbum($account->uid, FALSE)) {
+      $profile['useralbum_gallery'] = array(
+        'title' => in_array('link', $gallery_mode) ?
+          $profile['useralbum_link']['value'] : t('Album: %username', array('%username' => $account->name)),
+        'value' => _gallery_profile_useralbum($account->uid),
+        'class' => 'gallery_profile_useralbum',
+      );
+      unset($profile['useralbum_link']);
+    }
+    else if (!in_array('link', $gallery_mode)) {
+      unset($profile['useralbum_link']);
+    }
+    // Hide section (if no items are available)
+    if (empty($profile)) {
+      unset($fields[$title]);
+    }
+  }
+}
+
+/**
+ * Implementation of hook_form_alter().
+ */
+function gallery_profile_form_alter($form_id, &$form) {
+  if ($form_id == '_gallery_user_settings') {
+    $form['user']['profile']['#collapsed'] = TRUE;
+    
+    $form['user']['profile']['gallery_user_profile_title'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Title of Gallery2 profile section'),
+      '#default_value' => variable_get('gallery_user_profile_title', 'Gallery2'),
+      '#size' => 40,
+      '#maxlength' => 255,
+      '#description' => t('Title of the Gallery2 section on profile pages.')
+    );
+    
+    $form['user']['profile']['gallery_user_profile_hide_sync'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Hide sync status message'),
+      '#default_value' => variable_get('gallery_user_profile_hide_sync', 0),
+      '#description' => t('Hide \'Gallery2-Drupal Sync Status\' message in the profile.'),
+    );
+    
+    $gallery_mode = variable_get('gallery_user_profile_gallery', array('link'));
+    $form['user']['profile']['gallery_user_profile_gallery'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Useralbum mode'),
+      '#default_value' => $gallery_mode,
+      '#options' => array(
+        'link' => t('Show link to useralbum'),
+        'gallery' => t('Show useralbum gallery/images')
+      ),
+      '#description' => t('By default a link to the useralbum is shown. But you may also insert a gallery of
+                           random/recent images from the useralbum into the user profile.'),
+    );
+    $form['array_filter'] = array('#type' => 'value');
+    // Useralbum settings
+    if (in_array('gallery', $gallery_mode)) {
+      $form['user']['profile'][] = _gallery_profile_useralbum_settings();
+    }
+  }
+}
+
+/**
+ * Function _gallery_profile_useralbum_settings().
+ */
+function _gallery_profile_useralbum_settings() {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_block.inc');
+  
+  $plugin_status =  gallery_plugin_status(array('imageblock', 'imageframe'));
+  
+  $form['useralbum'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Useralbum'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#description' => t('The profile useralbum requires the Gallery2 Image Block plugin (!imageblock_status)
+                         and optionally the Gallery2 Image Frame plugin (!imageframe_status).', array(
+                          '!imageblock_status' => theme('gallery_plugin_status_message', $plugin_status['imageblock']),
+                          '!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe'])
+                        ))
+  );
+  if ($plugin_status['imageblock'] != GALLERY_PLUGIN_ENABLED) {
+    $form['useralbum']['#description'] .= t(' However the Image Block plugin is unavailable.');
+    return $form;
+  }
+  
+  _gallery_block_options($type_map, $param_map);
+  $type_map = array(
+    'randomImage' => t('Random image'),
+    'recentImage' => t('Recent image')
+  );
+  
+  $form['useralbum']['gallery_user_profile_useralbum_num_cols'] = array(
+    '#type' => 'select',
+    '#title' => t('Number of columns'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_num_cols', 2),
+    '#options' => _gallery_range_array(1, 5),
+    '#description' => t('Enter the number of columns in the useralbum.'),
+  );
+  
+  $form['useralbum']['gallery_user_profile_useralbum_num_rows'] = array(
+    '#type' => 'select',
+    '#title' => t('Number of rows'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_num_rows', 2),
+    '#options' => _gallery_range_array(1, 5),
+    '#description' => t('Enter the number of rows in the useralbum.'),
+  );
+  
+  $form['useralbum']['gallery_user_profile_useralbum_block_block'] = array(
+    '#type' => 'select',
+    '#title' => 'Image types',
+    '#default_value' => variable_get('gallery_user_profile_useralbum_block_block', 'randomImage'),
+    '#options' => $type_map,
+    '#description' => 'Pick the type of images you would like to see in the useralbum.',
+  );
+  
+  $form['useralbum']['gallery_user_profile_useralbum_block_show'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Image data'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_block_show', array()),
+    '#options' =>  $param_map,
+    '#description' => t('Choose the item metadata you would like to display.'),
+  );
+
+  $form['useralbum']['gallery_user_profile_useralbum_size_method'] = array(
+    '#type' => 'select',
+    '#title' => t('Image size method'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_size_method', GALLERY_GRID_SIZE_METHOD_DEFAULT),
+    '#options' => array(
+      'maxsize' => t('Max Size'),
+      'exactsize' => t('Exact Size'),
+    ),
+    '#description' => t('\'Max Size\' gives faster image downloading, but the image size
+                         may be smaller than the size defined below. <br />\'Exact Size\' may be slower
+                         (as a larger image is downloaded and then scaled by the browser) but the image
+                         will be guaranteed to be the size defined below. Only supported for G2.2+.'),
+  );
+
+  $form['useralbum']['gallery_user_profile_useralbum_size'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Image size'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_size', GALLERY_GRID_SIZE_DEFAULT),
+    '#size' => 10,
+    '#maxlength' => 10,
+    '#description' => t('Sets the size (in pixels) of the longest side of the image according
+                        to the method defined above.'),
+  );
+  
+  $imageframe_desc = ($plugin_status['imageframe'] != GALLERY_PLUGIN_ENABLED) ?
+      t('Requires the Gallery2 Image Frame plugin (!imageframe_status).',
+      array('!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']))) : '';
+
+  $image_frames = gallery_get_image_frames();
+
+  $form['useralbum']['gallery_user_profile_useralbum_album_frame'] = array(
+    '#type' => 'select',
+    '#title' => t('Album frame'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_album_frame', 'none'),
+    '#options' => $image_frames,
+    '#description' => $imageframe_desc,
+  );
+
+  $form['useralbum']['gallery_user_profile_useralbum_item_frame'] = array(
+    '#type' => 'select',
+    '#title' => t('Item frame'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_item_frame', 'none'),
+    '#options' => $image_frames,
+    '#description' => $imageframe_desc,
+  );
+
+  $form['useralbum']['gallery_user_profile_useralbum_link_target'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Link target'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_link_target', ''),
+    '#size' => 20,
+    '#maxlength' => 20,
+    '#description' => t('Enter a link target (e.g. \'_blank\' to open in a new window).'),
+  );
+
+  $form['useralbum']['gallery_user_profile_useralbum_link'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Image Link'),
+    '#default_value' => variable_get('gallery_user_profile_useralbum_link', ''),
+    '#size' => 60,
+    '#maxlength' => 255,
+    '#description' => t('By default the image has a link to the item in the Gallery. This
+      can be overridden here (or leave empty for the default). Use \'none\' for no link, or a URL
+      to link somewhere else instead.'),
+  );
+  
+  return $form;
+}
+
+/**
+ * Function _gallery_profile_useralbum().
+ */
+function _gallery_profile_useralbum($uid) {
+  $num_cols = variable_get('gallery_user_profile_useralbum_num_cols', 2);
+  $num_rows = variable_get('gallery_user_profile_useralbum_num_rows', 2);
+  $num_images = $num_cols * $num_rows;
+
+  $param_blocks_array = array_fill(0, $num_images, variable_get('gallery_user_profile_useralbum_block_block', 'randomImage'));
+  $params['blocks'] = is_array($param_blocks_array) ? implode('|', $param_blocks_array) : '';
+  $params['itemId'] = 'user:'. $uid;
+  $param_show_array = variable_get('gallery_user_profile_useralbum_block_show', array());
+  $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : '';
+  if (variable_get('gallery_user_profile_useralbum_size_method', GALLERY_GRID_SIZE_METHOD_DEFAULT) == 'maxsize') {
+    $params['maxSize'] = variable_get('gallery_user_profile_useralbum_size', GALLERY_GRID_SIZE_DEFAULT);
+  }
+  else {
+    $params['exactSize'] = variable_get('gallery_user_profile_useralbum_size', GALLERY_GRID_SIZE_DEFAULT);
+  }
+  $params['albumFrame'] =  variable_get('gallery_user_profile_useralbum_album_frame', 'none');
+  $params['itemFrame'] =  variable_get('gallery_user_profile_useralbum_item_frame', 'none');
+  $params['linkTarget'] =  variable_get('gallery_user_profile_useralbum_link_target', '');
+  $params['link'] = variable_get('gallery_user_profile_useralbum_link', '');
+
+  $block = gallery_get_block($params, 'ImageBlock', array('num_cols' => $num_cols));
+  return $block['content'];
+}
diff --git a/gallery_report.inc b/gallery_report.inc
new file mode 100644 (file)
index 0000000..708ff63
--- /dev/null
@@ -0,0 +1,154 @@
+<?php
+// $Id$
+
+/**
+ * gallery.module : gallery_report.inc
+ * Bug report assistance (system info)
+ */
+
+/**
+ * Function _gallery_report().
+ */
+function _gallery_report($download = FALSE, $report = array(), $cache = FALSE) {
+  // provide download of the cached report
+  if ($download && ($content = cache_get('gallery_report_'. session_id()))) {
+    _gallery_report_download($content->data);
+  }
+  
+  //System
+  global $db_url;
+  $report['System']['PHP']['Version'] = phpversion();
+  $report['System']['PHP']['Memory limit'] = ini_get('memory_limit');
+  $report['System']['PHP']['Safe mode'] = ini_get('safe_mode') ? 'On' : 'Off';  
+  $database = is_array($db_url) ? $db_url : array('default' => $db_url);
+  foreach ($database as $key => $value) {
+    db_set_active($key);
+    $db_info = parse_url($value);
+    $report['System']['Database'][drupal_ucfirst($key)]['Type'] =  urldecode(strtoupper($db_info['scheme']));
+    $report['System']['Database'][drupal_ucfirst($key)]['Version'] = db_version();
+  }
+  db_set_active('default');
+  
+  //Drupal
+  $report['Drupal']['Version'] = VERSION;
+  
+  // Module
+  $modules = drupal_system_listing('\.module$', 'modules', 'name', 0);
+  system_get_files_database($modules, 'module');
+  foreach ($modules as $name => $module) {
+    if (in_array($name, array('gallery', 'gallery_menu', 'gallery_content'))) {
+      $info = _module_parse_info_file(dirname($module->filename) .'/'. $module->name .'.info');
+      $report['Module']['Version'][$info['name']] = array(
+        'Version' => $info['version'] ? $info['version'] : 'unknown',
+        'Schema Version' => $module->schema_version,
+        'Location' => dirname($module->filename),
+        'Status' => $module->status
+      );
+      // extract detailed version info from cvsid
+      $files = file_scan_directory(dirname($module->filename), '.*\.(inc|module)$', array('.', '..', 'CVS'), 0, FALSE);
+      foreach ($files as $file) {
+        if (preg_match('/\x24Id: '. $file->basename .',v ([^\\$]+) Exp \x24/i', file_get_contents($file->filename), $cvsid)) {
+          $report['Module']['Version'][$info['name']]['Files'][$file->basename] = 'Rev. '. $cvsid[1];
+        }
+      }
+    }
+  }
+  // Fetch module-related variables
+  $result = db_query('SELECT * FROM {variable} WHERE name LIKE \'gallery_%\'');
+  while ($var = db_fetch_object($result)) {
+    $report['Module']['Variables'][$var->name] = unserialize($var->value);
+  }
+  $status = gallery_get_status();
+  unset($status['version'], $status['gallery_valid']);
+  $report['Module']['Variables']['gallery_status'] = array($status);
+  
+  // Gallery
+  if (variable_get('gallery_valid', 0) && _gallery_init(FALSE, NULL, FALSE)) {
+    $version = gallery_version();
+    $report['Gallery 2']['Version'] = array(
+      'Core API' => $version['core']['major'] .'.'. $version['core']['minor'],
+      'Embed API' => $version['embed']['major'] .'.'. $version['embed']['minor'],
+    );
+    list($ret, $rewrite_api) = GalleryCoreApi::newFactoryInstance('RewriteApi');
+    if (!$ret && $rewrite_api) {
+      list($ret, $rewrite_params) = $rewrite_api->fetchEmbedConfig();
+      $report['Gallery 2']['URL Rewrite'] = $rewrite_params;
+    }
+    // Get some basic information about G2 plugins
+    list($ret, $plugins) = GalleryCoreApi::fetchPluginStatus('module');
+    foreach ($plugins as $name => $info) {
+      $report['Gallery 2']['Active Plugins'][drupal_ucfirst($name)]['Version'] = $info['active'] ? $info['version'] : 'inactive';
+    }
+    // Debug Logs
+    if ($GLOBALS['gallery']->_debug == 'buffered' && !empty($GLOBALS['gallery']->_debugBuffer)) {
+      $report['Gallery 2']['DebugBuffer'] = $GLOBALS['gallery']->_debugBuffer;
+    }
+    else if (!empty($GLOBALS['gallery']->_debugSnippet)) {
+      $report['Gallery 2']['DebugSnippet'] = $GLOBALS['gallery']->_debugSnippet;
+    }
+  }
+  else {
+    $report['Gallery 2'] = 'Gallery2 not available';
+  }
+  
+  $content = theme('gallery_report', $report);
+  
+  if ($cache) {
+    if ($cache_content = cache_get('gallery_report_'. session_id())) {
+      $content .= $cache_content->data;
+    }
+    cache_set('gallery_report_'. session_id(), 'cache', $content, time()+600);
+  }
+  if ($download) {
+    _gallery_report_download($content);
+  }
+  
+  return $content;
+}
+
+/**
+ * Function _gallery_report_download().
+ */
+function _gallery_report_download($content) {
+  header("Content-Type: application/octet-stream");
+  header("Content-Disposition: attachment; filename=gallery_report.html");
+  print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+  print "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n";
+  print " <head>\n  <title>". t('Gallery module : Report Generator') ."</title>\n </head>\n";
+  print " <body>\n ". $content ."\n</body>\n";
+  print "</html>";
+  exit();
+}
+
+/**
+ * Theme function : theme_gallery_report().
+ */
+function theme_gallery_report($report) {
+  return '  <div><table border=1 style=\'empty-cells:hide;\'>'. _gallery_report_walk($report) ."\n".'  </table></div>';
+}
+
+/**
+ * Function _gallery_report_walk().
+ */
+function _gallery_report_walk($element, $level = 1, $sub = FALSE) {
+  $html = '';
+  $element = is_object($element) ? get_object_vars($element) : $element;
+  if (is_array($element)) {
+    foreach ($element as $key => $value) {
+      if (is_array($value) || is_object($value)) {
+        $html .= "\n".'    <tr>';
+        $html .= implode('<td></td>', array_fill(0, $level, ''));
+        $html .= '<td>'. $key .'</td>';
+        $html .= _gallery_report_walk($value, $level+1, TRUE);
+      }
+      else {
+        $html .= $sub ? '' : "\n".'    <tr>'. implode('<td></td>', array_fill(0, $level, ''));
+        $html .= '<td>'. $key .'</td><td>'. $value .'</td>'; 
+        $html .= '</tr>';
+        $sub = FALSE;
+      }
+    }
+  }  
+  
+  return $html;
+}
diff --git a/gallery_roles.inc b/gallery_roles.inc
deleted file mode 100644 (file)
index 4d6522c..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-<?php
-// $Id$
-/**
- * gallery.module : gallery_roles.inc
- * Group/Role Functions (sync groups, ...)
- */
-
-/**
- * Sync Drupal roles and Gallery groups for a specific user
- */ 
- // Check for remove user.
-function gallery_sync_groups_for_user($user) {
-  // Take this opportunity to sync the Drupal roles and Gallery groups
-  gallery_sync_groups();
-  // Find the Ids for the 2 special Drupal roles (from user.module code)
-  $authenticated_role =  db_result(db_query("SELECT rid FROM {role} WHERE name = 'authenticated user'"));
-  $anonymous_role =  db_result(db_query("SELECT rid FROM {role} WHERE name = 'anonymous user'"));
-  
-  // Find the Ids for the special G2 groups 
-  list ($ret, $g2_gid_everybodyGroup) = GalleryCoreApi::getPluginParameter('module', 'core',
-    'id.everybodyGroup');
-  if ($ret) {
-    $msg = t('Error retrieving Gallery group Id for \'Everybody\' group');
-    gallery_error($msg, $ret);
-    return;
-  }
-  
-  // Get the Gallery groups for this user
-  // First get the G2 Id from the Drupal uid
-  list ($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
-  if ($ret) {
-    $msg = t('Error getting Gallery User info from Drupal Id');
-    $msg .= ' ' . t('Drupal User Id: ') . $user->uid;        
-    gallery_error($msg, $ret);
-    return;
-  }
-  // Then get the groups for this user currently set in G2
-  list ($ret, $g2_cur_groups) = GalleryCoreApi::fetchGroupsForUser($g2_user->getId());
-  if ($ret) {
-    $msg = t('Error getting Gallery group info for user');
-    $msg .= ' ' . t('Drupal User Id: ') . $user->uid;        
-    gallery_error($msg, $ret);
-    return;
-  }
-  // Now convert the new Drupal role Ids into Gallery Group Ids(for comparison)
-  foreach ($user->roles as $rid=>$role_name) { 
-    list ($ret, $g2_group) = GalleryCoreApi::loadEntityByExternalId($rid, 'GalleryGroup');
-    if ($ret) {
-      $msg = t('Error getting Gallery Group Id from Drupal Role Id');
-      $msg .= ' ' . t('Drupal Role Id: ') . $rid;        
-      gallery_error($msg, $ret);
-      return;
-    }
-    $g2_rid[$rid] = $g2_group->getId();
-  }
-  // Find if the user needs to be deleted from any G2 groups (only mapped groups)
-  $g2_mapped_groups = gallery_get_mapped_groups();
-  foreach ($g2_cur_groups as $gid=>$gname) {
-    if (!in_array($gid, $g2_rid) && ($gid != $g2_gid_everybodyGroup) && in_array($gid, $g2_mapped_groups)) {
-      $delete_list[] = $gid;
-      $ret = GalleryCoreApi::removeUserFromGroup($g2_user->getId(), $gid);
-      if ($ret) {
-        $msg = t('Error removing user from Gallery group');
-        $msg .= ' ' . t('Gallery Group Id: ') . $gid . ' ' . t('Gallery Group Name: ') . $gname;        
-        gallery_error($msg, $ret);
-        return;
-      }
-    }
-  }
-  // Find if the user needs to be added to any G2 groups
-  foreach ($g2_rid as $rid=>$gid) {
-    if (!isset($g2_cur_groups[$gid])) {
-      $add_list[] = $gid;
-      $ret = GalleryCoreApi::addUserToGroup($g2_user->getId(), $gid);
-      if ($ret) {
-        $msg = t('Error adding user to Gallery group');
-        $msg .= ' ' . t('Gallery Group Id: ') . $gid;        
-        gallery_error($msg, $ret);
-        return;
-      }
-    }
-  }  
-}
-
-/**
- * Sync Drupal roles and Gallery groups. This will add any mappings that are required 
- * (eg on first install, or if a group is added). It will also delete groups in Gallery 
- * that have been deleted from Drupal. 
- */ 
-function gallery_sync_groups() {
-  // Check if the Drupal role <-> G2 group mapping exists
-  $roles = user_roles();
-  // Find the Ids for the 2 special Drupal groups (from user.module code)
-  $authenticated_role =  db_result(db_query("SELECT rid FROM {role} WHERE name = 'authenticated user'"));
-  $anonymous_role =  db_result(db_query("SELECT rid FROM {role} WHERE name = 'anonymous user'"));
-  // Go through each role and add or delete the gallery group if needed
-  foreach ($roles as $rid => $role_name) {
-    // Add Drupal<->G2 mapping if needed
-    $ret = GalleryEmbed::isExternalIdMapped($rid, 'GalleryGroup');
-    if ($ret && ($ret->getErrorCode() & ERROR_MISSING_OBJECT)) {
-    // Need to add the mapping
-      switch ($rid) {
-        // Add mapping for Anonymous and get the G2 group Id
-        case $anonymous_role:
-          list ($ret, $g2_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.everybodyGroup');
-          if ($ret) {
-            $msg = t('Error retrieving Gallery group Id for \'Everybody\' group');
-            gallery_error($msg, $ret);
-            return;
-          }
-          $ret = GalleryEmbed::addExternalIdMapEntry($rid, $g2_gid, 'GalleryGroup');
-          if ($ret) {
-              $msg = t('Error creating new Drupal role <-> Gallery group mapping (for \'anonymous user\' role)');
-              $msg .= ' ' . t('Drupal Role Id: ') . $rid . ' ' . t('Gallery Group Id: ') . $g2_gid;
-              gallery_error($msg, $ret);
-              return;
-          }
-          break;
-        // Add mapping for authenticated users role and get the G2 group Id
-        case $authenticated_role:
-          list ($ret, $g2_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.allUserGroup');
-          if ($ret) {
-            $msg = t('Error retrieving Gallery group Id for \'Registered Users\' group');
-            gallery_error($msg, $ret);
-            return;
-          }
-          $ret = GalleryEmbed::addExternalIdMapEntry($rid, $g2_gid, 'GalleryGroup');
-          if ($ret) {
-            $msg = t('Error creating new Drupal role <-> Gallery group mapping (for \'authenticated user\' role)');
-            $msg .= ' ' . t('Drupal Role Id: ') . $rid . ' ' . t('Gallery Group Id: ') . $g2_gid;
-            gallery_error($msg, $ret);
-            return;
-          }
-          break;
-        default:
-          // Is there already a group by this name? If so, map to it.
-          list ($ret, $g2_group) = GalleryCoreApi::fetchGroupByGroupName($role_name);
-          if (!$ret) {
-            $g2_gid = $g2_group->getId();
-            $ret = GalleryEmbed::addExternalIdMapEntry($rid, $g2_gid, 'GalleryGroup');
-            if ($ret) {
-              $msg = t('Error creating new Drupal role <-> Gallery group mapping (by name)');
-              $msg .= ' ' . t('Drupal Role Id: ') . $rid . ' ' . t('Gallery Group Id: ') . $g2_gid;
-              gallery_error($msg, $ret);
-              return;
-            }
-          } else {
-            // If not, create a new group
-            $ret = GalleryEmbed::createGroup($rid, $role_name);
-            if ($ret) {
-              $msg = t('Error creating new Gallery group');
-              $msg .= ' ' . t('Drupal Role Id: ') . $rid . ' ' . t('Drupal Role Name: ') . $role_name;        
-              gallery_error($msg, $ret);
-              return;
-            }
-          }
-          break;
-      }
-    } else {
-    // Update group name if needed (not for $authenticated_role or $anonymous_role)
-      list($ret, $g2_group) = GalleryCoreApi::loadEntityByExternalId($rid, 'GalleryGroup');
-      // In some cases the ExternalId may be present, but the user may have been deleted
-      if ($ret) {
-        $msg = t('Error retrieving Gallery Group Id from Drupal Role Id');
-        $msg .= ' ' . t('Drupal Role Id: ') . $rid;        
-        gallery_error($msg, $ret);
-        return;
-      }
-      if (($rid != $authenticated_role) && ($rid != $anonymous_role) && ($role_name != $g2_group->getGroupName())) {
-        $ret = GalleryEmbed::updateGroup($rid, array('groupname'=>$role_name));
-        if ($ret) {
-          $msg = t('Error updating Gallery group');
-          $msg .= ' ' . t('Drupal Role Id: ') . $rid . ' ' . t('Drupal Role Name: ') . $role_name;        
-          gallery_error($msg, $ret);
-          return;
-        }
-      }
-    }
-  }
-  // Now check for any deleted Drupal roles. Only delete those G2 groups that were mapped to Drupal roles
-  // (just in case other groups have been defined which are not meant to be sync'd with Drupal)
-  list ($ret, $g2_map) = GalleryEmbed::getExternalIdMap('entityId');
-  if ($ret) {
-    $msg = t('Error retrieving all Drupal<->Gallery Map Ids');
-    gallery_error($msg, $ret);
-    return;
-  }
-  $g2_mapped_groups = gallery_get_mapped_groups();
-  foreach ($g2_mapped_groups as $rid=>$g2_gid) {
-    // Delete if needed
-    if (!isset($roles[$rid])) {
-      $msg = t('Deleting G2 group') . ' (' . t('Gallery Group Id: ') . $g2_gid .')';
-      $ret = GalleryEmbed::deleteGroup($rid);
-      if ($ret) {
-        $msg = t('Error deleting Gallery group');
-        $msg .= ' ' . t('Gallery Group Id: ') . $g2_gid;        
-        gallery_error($msg, $ret);
-        return;
-      }        
-    }
-  }
-}
-
-/**
- * Get G2 Groups that have been mapped to Drupal Roles
- */
-function gallery_get_mapped_groups() {
-  list ($ret, $g2_map) = GalleryEmbed::getExternalIdMap('entityId');
-  if ($ret) {
-    $msg = t('Error retrieving all Drupal<->Gallery Map Ids');
-    gallery_error($msg, $ret);
-    return;
-  }
-  /* 
-   * getExternalIdMap returns groups and user mappings. 
-   * Cannot use 'externalId' as key as is not unique between users & groups
-   */
-  foreach ($g2_map as $g2_gid => $g2_data) {
-    if ($g2_data['entityType'] == 'GalleryGroup') {
-      $g2_mapped_groups[$g2_data['externalId']] = $g2_gid;
-    }
-  }
-  return $g2_mapped_groups;
-}
-?>
\ No newline at end of file
index 4a7a781..8b71518 100644 (file)
 <?php
 // $Id$
+
 /**
  * gallery.module search functions
  */
  
 /**
- * implementation of hook_search
+ * Implementation of hook_search().
  */
-function _gallery_search($op = 'search', $keys = null) {
+function _gallery_search($op = 'search', $keys = NULL) {
   switch ($op) {
-  case 'name':
-    return t('gallery');
-  case 'search':
-    $find = array();
-    $g2_head = array();
-    
-    list ($success, $ret) = _gallery_init(true);
-    if (!$success) {
-      $err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link">
-                    configure your embedded Gallery</a>.', 
-                    array('@link' => url('admin/settings/gallery')));
-      gallery_error($err_msg, $ret);
-      return;
-    }
-
-    // Image block options for search
-    $params['blocks'] = "specificItem"; 
-    $param_show_array = variable_get('gallery_search_block_show', array());
-    $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : ""; 
-    $params['maxSize'] = variable_get('gallery_search_maxsize', 160);
-    $params['albumFrame'] =  variable_get('gallery_search_album_frame', 'none');
-    $params['itemFrame'] =  variable_get('gallery_search_item_frame', 'none');
-    $params['linkTarget'] =  variable_get('gallery_search_link_target', '');
-    $show_g2_thumbs = variable_get('gallery_search_show_thumbs', 1);
-    $max_items = variable_get('gallery_search_max_items', 50);
-
-    list ($ret, $results) = GalleryEmbed::searchScan($keys, $max_items);
-    if (!$ret) {
-      /**
-       * Format of $results is:
-       * [GalleryCoreSearch] => Array(
-            [start] => 1
-            [end] => 13
-            [count] => 13
-            [results] => Array(
-                [0] => Array(
-                            [itemId] => 46
-                            [fields] => Array(
-                                    [0] => Array([key] => Title, [value] => DSCN2884.JPG)
-                                    [1] => Array([key] => Summary, [value] =>  )
-                                    [2] => Array([key] => Keywords, [value] =>  )
-                                    [3] => Array([key] => Description, [value] =>  )
-                                    [4] => Array([key] => Owner, [value] => Me )
-                                    )
-                        )
-                [1] => ...
-            [name] => Gallery Core
-        ) 
-        [comment] => ...
-        [CustomField] => ...
-        [MultiLang] => ...
-        Other modules
-        )
-        
-       * You can set the maximum number of items, but not a start offset, unfortunately.
-       */
-      $urlGenerator =& $GLOBALS['gallery']->getUrlGenerator();
-      // Copy the results to a new array, and overwrite the results portions to a new format
-      $find = $results;
-      $g2_thumb = '';
-      foreach ($results as $name => $module) {
-        if (count($module['results']) > 0) {
-          $this_module_results = array();
-          foreach ($module['results'] as $result) {
-            $excerpt = array();
-            $g2_thumb = '';
-            foreach ($result['fields'] as $field) {
-              if (preg_match("/$keys/i", $field['value'])) {
-                $excerpt[] = '<em>'.$field['key'] .':</em> '.
-                  search_excerpt($keys, $field['value']);
-              }
+    case 'name':
+      return t('Gallery');
+    case 'search':
+      $results = array();
+      $html_head = array();
+      $items_per_row = variable_get('gallery_search_num_per_row', 3);
+      $rows_per_pager = variable_get('gallery_search_rows_per_pager', 4);
+      $matches = _gallery_search_pager_search($keys, $items_per_row * $rows_per_pager);
+      if ($matches['count']) {
+        $results['count'] = $matches['count'];
+        // Parameters for the search results
+        $params = array();
+        $params['blocks'] = 'specificItem';
+        $param_show_array = variable_get('gallery_search_block_show', array());
+        $params['show'] = is_array($param_show_array) ? implode('|', $param_show_array) : '';
+        if (variable_get('gallery_search_size_method', GALLERY_SEARCH_SIZE_METHOD_DEFAULT) == 'maxsize') {
+          $params['maxSize'] = variable_get('gallery_search_size', GALLERY_SEARCH_SIZE_DEFAULT);
+        } 
+        else {
+          $params['exactSize'] = variable_get('gallery_search_size', GALLERY_SEARCH_SIZE_DEFAULT);
+        }
+        $params['albumFrame'] =  variable_get('gallery_search_album_frame', 'none');
+        $params['itemFrame'] =  variable_get('gallery_search_item_frame', 'none');
+        $params['linkTarget'] =  variable_get('gallery_search_link_target', '');
+        $params['link'] = variable_get('gallery_search_link', '');
+       
+        $show_thumbs = variable_get('gallery_search_show_thumbs', 1);
+        // Loop over the results
+        foreach ($matches['results'] as $item) {  
+          $excerpt = array();
+          // Get a thumbnail for this item
+          if ($show_thumbs) {
+            $params['itemId'] = $item['itemId'];
+            list($ret, $thumbnail, $head) = GalleryEmbed::getImageBlock($params);
+            if ($ret) {
+              $thumbnail = t('n/a');
+            }
+            if ($head) {
+              $html_head[] = $head;
             }
-            $link = $urlGenerator->generateUrl(array('itemId' => $result['itemId']), 
-                        array('htmlEntities' => false));
-            if ($show_g2_thumbs) {
-              $params['itemId'] = $result['itemId'];
-              // No error checking. If it failed then no thumb is returned. Should be OK 
-              // (maybe there is no thumb for that item)
-              list($ret, $g2_thumb, $head) = GalleryEmbed::getImageBlock($params);
-              if ($head) {
-                $g2_head[] = $head;
-              }          
+          }
+          // Generate a snippet with highlighted search keys
+          foreach ($item['fields'] as $field) {
+            if (preg_match("/$keys/i", $field['value'])) {
+              $excerpt[] = '<em>'. $field['key'] .':</em> '. search_excerpt($keys, $field['value']);
             }
-            $this_module_results[] = array(
-              'title' => $result['fields'][0]['value'],
-              'link'  => $link,
-              'type'  => '',
-              'snippet' => implode('<br />', $excerpt),
-              'extra' => array(),
-              'g2_thumb' => $g2_thumb,
-               );
-          } 
-          $find[$name]['results'] = $this_module_results;
+          }
+          // Put everything into the $results array
+          $title = reset($item['fields']);
+          $results[] = array(
+            'link' => gallery_generate_url(array('itemId' => $item['itemId']), FALSE),
+            'title' => empty($title['value']) ? t('Gallery item: Untitled') : $title['value'],
+            'snippet' => implode('<br />', $excerpt),
+            'thumbnail' => $thumbnail,
+          );
         }
       }
-      // Try not to send the G2 head information multiple times
-      if ($g2_head) {
-        drupal_set_html_head(implode("\n", array_unique($g2_head)));
+      if ($html_head) {
+        drupal_set_html_head(implode("\n", array_unique($html_head)));
       }
-      return $find;
-    }
+      return $results;
   }
 }
 
 /**
- * Implementation of hook_search_page to override how to display the search results
+ * Function _gallery_search_pager_search().
  */
-function _gallery_search_page($results) {
-  $num_items_per_row = variable_get('gallery_search_num_per_row', 3);
-  $max_rows_per_pager = variable_get('gallery_search_max_rows_per_pager', 5);
-  $max_items = variable_get('gallery_search_max_items', 50);
-  $header = array_fill(0, $num_items_per_row, '');  
-
-  $output = '<dl class="search-results">';
+function _gallery_search_pager_search(&$keys, $limit = 10, $element = 0) {
+  // Adapted version of the pager_query() function (from /includes/pager.inc)
+  // for use with the Gallery2 search() function
+  //
+  global $pager_page_array, $pager_total, $pager_total_items;
+  $page = isset($_GET['page']) ? $_GET['page'] : '';
 
-  foreach ($results as $entry) {
-    $output .= gallery_search_item($entry);
-  }
-  $output .= '</dl>';
+  // Convert comma-separated $page to an array, used by other functions.
+  $pager_page_array = explode(',', $page);
 
+  // We calculate the total of pages as ceil(items / limit).
+  $count = _gallery_search_perform($keys);
+  $pager_total_items[$element] = $count['count'];
+  $pager_total[$element] = ceil($pager_total_items[$element] / $limit);
+  $pager_page_array[$element] = max(0, min((int)$pager_page_array[$element], ((int)$pager_total[$element]) - 1));
+  
+  return _gallery_search_perform($keys, $pager_page_array[$element] * $limit, $limit);
+}
 
 /**
- * From /drupal/includes/pager.inc
- * $pager_page_array[i] = page number (starts at 0) (eg 7)
- * $pager_total[i] = total number of pages = ceil($pager_total_items[i] / limit) (eg 15)
- * $pager_total_items[i] = total number of items in the pager (eg 75)
- * where i is the pager ID (must be a number!!!) (for multiple pagers on a page)
- * eg ?page=1,2,1
- * => page 2 for pager1, page 3 for pager2, page 2 for pager 3
+ * Function _gallery_search_perform().
  */
-  global $pager_page_array, $pager_total, $pager_total_items;
-  $page = isset($_GET['page']) ? $_GET['page'] : '';
-  $pager_page_array = explode(',', $page);
-
-  $output = '';
-  $element = 0;
-  // Split the search results from each module into individual pagers
-  foreach ($results as $module => $table) {
-    $search_items = array();
-    $row = 0;
-    $col = 0;
-    foreach ($table['results'] as $key => $item){
-      // Format the search results
-      $search_items[$row][$col++] = gallery_search_item($item);
-      if ($col >= $num_items_per_row) {
-        $row++;
-        $col = 0;
-      }
-    }
-    // Add the title for that pager
-    $output .= '<h2>';
-    $count = $table['count'];
-    if ($count > $max_items) {
-      $count = $max_items;
-      $count_text = t(' (>@count items found)', array(
-        '@count' => $count));
-    } else {
-      $count_text = t(' (@count @item found)', array(
-        '@item' => ($count == 1) ? t('item') : t('items'),
-        '@count' => $count));
-    }      
-    $output .= t('@name Results', array('@name' => $table['name']));
-    $output .= $count_text . '</h2>';
+function _gallery_search_perform(&$keys, $offset = 0, $limit = -1) {
+  list($search_interface, $options) = _gallery_search_init();
+  if (!isset($search_interface)) {
+    return array();
+  }
+  // Extract query parameters
+  if ($fields = search_query_extract($keys, 'fields')) {
+    $keys = trim(preg_replace('/\s+fields:[\w,]*/', '', $keys));
+  }
+  $fields = $fields ? array_flip(explode(',', $fields)) : $options;
+  foreach ($fields as $key => $value) {
+    $fields[$key] = $key;
+  }
+  // Perform the actual search
+  list($ret, $matches) = $search_interface->search($fields, $keys, $offset, $limit);
+  if ($ret) {
+    gallery_error(t('Error invoking search() method.'), $ret);
+    return array();
+  }
+  
+  return $matches;
+}
 
-    if ($count > 0) {
-      $pager_total_items[$element] = ceil($count/ $num_items_per_row);
-      $pager_total[$element] = ceil($pager_total_items[$element] / $max_rows_per_pager);
-      $first_item = $pager_page_array[$element] * $max_rows_per_pager;
-      // Slice the array to display only the results for this page of the pager
-      $search_items = array_slice($search_items, $first_item, $max_rows_per_pager);          
-      // Add empty cells if needed to complete the last row
-      $last_row = count($search_items) - 1;
-      if (count($search_items[$last_row]) < $num_items_per_row) {
-        $search_items[$last_row] = array_merge(
-          $search_items[$last_row], 
-          array_fill(0, $num_items_per_row - count($search_items[$last_row]), ''));
-       }
+/**
+ * Function _gallery_search_form().
+ */
+function _gallery_search_form(&$form) {
+  list($search_interface, $options) = _gallery_search_init();
+  if (!count($options)) {
+    return;
+  }
+  // Extend search form
+  $form['advanced'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Advanced search'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#attributes' => array('class' => 'search-advanced'),
+  );
+  
+  $form['advanced']['fields'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Only the following fields'),
+    '#prefix' => '<div class="criterion">',
+    '#suffix' => '</div>',
+    '#options' => $options,
+  );
+  
+  $form['advanced']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Advanced search'),
+    '#prefix' => '<div class="action clear-block">',
+    '#suffix' => '</div>',
+  );
+  
+  $form['#validate']['_gallery_search_validate'] = array();
+}
 
-      $output .= theme('table', $header, $search_items);
-      $output .= theme('pager', NULL, $max_rows_per_pager, $element);
-      $element++;
+/**
+ * Function _gallery_search_validate().
+ */
+function _gallery_search_validate($form_id, $form_values, $form) {
+  $keys = $form_values['processed_keys'];
+  // Append field options to query
+  if (isset($form_values['fields']) && is_array($form_values['fields'])) {
+    $form_values['fields'] = array_filter($form_values['fields']);
+    if (count($form_values['fields'])) {
+      $keys = search_query_insert($keys, 'fields', implode(',', array_keys($form_values['fields'])));
+      form_set_value($form['basic']['inline']['processed_keys'], trim($keys));
     }
   }
-  return $output;
-}  
-function gallery_search_item($item) { 
-  $output = ''; 
-  if ($item['g2_thumb']) {
-    $output .= ' <dd>' . $item['g2_thumb'] . '</dd>';
-  } else {
-    $output = '<dt class="title"><a href="'. check_url($item['link']) .'">'. 
-      check_plain($item['title']) .'</a></dt>';
+}
+
+/**
+ * Function _gallery_search_init().
+ */
+function _gallery_search_init() {
+  if (!_gallery_init(TRUE)) {
+    return array();
   }
-    
-  $info = array();
-  if ($item['type']) {
-    $info[] = $item['type'];
+  // Create instance of search interface
+  list($ret, $search_interface) = GalleryCoreApi::newFactoryInstance('GallerySearchInterface_1_0');
+  if ($ret) {
+    gallery_error(t('Error creating instance of GallerySearchInterface. Make sure the \'Search\' plugin is enabled in Gallery2.'), $ret);
+    return array(NULL, array());
   }
-  if ($item['user']) {
-    $info[] = $item['user'];
+  // Get search module info
+  list($ret, $module_info) = $search_interface->getSearchModuleInfo();
+  if ($ret) {
+    gallery_error(t('Error getting \'Search\' module options.'), $ret);
+    return array(NULL, array());
   }
-  if ($item['date']) {
-    $info[] = format_date($item['date'], 'small');
+  $options = array();
+  foreach ($module_info['options'] as $module => $info) {
+    if ($info['enabled']) {
+      $options[$module] = $info['description'];
+    } 
   }
-  if (is_array($item['extra'])) {
-    $info = array_merge($info, $item['extra']);
+  
+  return array($search_interface, $options);
+}
+
+/**
+ * Function _gallery_search_page().
+ */
+function _gallery_search_page($results) {
+  $items_per_row = variable_get('gallery_search_num_per_row', 3);
+  $rows_per_pager = variable_get('gallery_search_rows_per_pager', 4);
+  
+  $output  = '<dl class="search-results">';
+  $output .= t('<p>Total Number of Matches: @count</p>', array('@count' => $results['count']));
+  unset($results['count']);
+  // Arrange items as table
+  $rows = array();
+  $results = array_chunk($results, $items_per_row);
+  foreach ($results as $item_row) {
+    $row = array();
+    foreach ($item_row as $item) {
+      $row[] = array('data' => theme('gallery_search_item', $item));
+    }
+    $rows[] = $row;
   }
-  $output .= ' <dd>'. ($item['snippet'] ? '<p>'. $item['snippet'] . '</p>' : '') . 
-    '<p class="search-info">' . implode(' - ', $info) .'</p></dd>';
+  $output .= theme('table', array(), $rows);
+  $output .= '</dl>';
+  $output .= theme('pager', NULL, $items_per_row * $rows_per_pager, 0);
 
-  return $output; 
-} 
+  return $output;
+}
 
-?>
+/**
+ * Theme function : theme_gallery_search_item().
+ */
+function theme_gallery_search_item($item) {
+  $output  = ' <dt class="title"><a href="'. check_url($item['link']) .'">'. check_plain($item['title']) .'</a></dt>';
+  $output .= '<div class="g2image_centered">'. $item['thumbnail'] .'</div>'; 
+  $output .= ' <dd>'. ($item['snippet'] ? '<p>'. $item['snippet'] .'</p>' : '') .'</dd>';
+  
+  return $output;
+}
index 6a8295c..b7c432f 100644 (file)
  * gallery.module : gallery_settings.inc
  * Settings functions
  */
+
 /**
- * Implementation of hook_settings
+ * Function _gallery_settings_install().
  */
-function _gallery_settings() {
-  $output = '';
-  $extra = l(t('More information about directory settings (including examples).'), 
-    'admin/help/gallery');             
-  $form['directory'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Directory settings'),
-    '#description' => $extra,
-    '#collapsible' => TRUE, 
-    '#collapsed' => variable_get('gallery_valid', 0),
-  );  
-      
-  $form['directory']['gallery_uri'] = array(
-    '#type' => 'textfield',
-    '#title' => t('URI of Gallery2'),
-    '#default_value' =>  variable_get('gallery_uri', '/gallery2/'),
-    '#size' => 64,
-    '#maxlength' => 128,
-    '#description' => t('URI of the G2 standalone location. Path from docroot to the 
-                         Gallery2 directory where main.php is located. Protocol/hostname are 
-                         both optional.'),
-  ); 
-  
-  $form['directory']['gallery_autodetect_dir'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Autodetect Settings'),
-      '#return_value' => 1,
-      '#default_value' => variable_get('gallery_autodetect_dir', 1),
-      '#description' => t('Autodetect the Gallery2 and Drupal settings (recommended). When 
-                           selected the values below are updated with the autodetect settings 
-                           when the submit button is clicked.'),
-      );
-  
-  if (variable_get('gallery_autodetect_dir', 1)) {
-    $extra = t(' (Autodetected value)');
-  } else {
-    $extra = t(' (Manually entered value)');
-  }
-  $form['directory']['gallery_dir'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Location of Gallery2') . $extra,
-    '#default_value' => variable_get('gallery_dir', './gallery2/'),
-    '#size' => 64,
-    '#maxlength' => 128,
-    '#description' => t('Location of your gallery2 directory (absolute path or relative to the root 
-                         directory of your drupal installation).'),
-  );  
-  
-  $form['directory']['gallery_embed_uri'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Embed URI') . $extra,
-    '#default_value' => variable_get('gallery_embed_uri', '?q=gallery'),
-    '#size' => 64,
-    '#maxlength' => 128,
-    '#description' => t('URI to access G2 via drupal. Don\'t worry if you are using clean urls in drupal and this still ends in \'index.php?q=gallery\'. This is needed to get the Gallery2 URL rewrite module to work correctly and will not be visible.'),
-  ); 
-  
+function _gallery_settings_install($form_values = NULL) {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_install.inc');
+  return _gallery_install($form_values);
+}
+
 /**
- * Remove this for now. It is not necessary when URL rewrite is working. Without URL rewrite there
- * can still be issues, but these will be addressed in the documentation for now.
+ * Function _gallery_settings_general().
  */
-/*
-    $form['directory']['gallery_cookie_path'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Cookie Path') . $extra,
-    '#default_value' => variable_get('gallery_cookie_path', ''),
-    '#size' => 64,
-    '#maxlength' => 128,
-    '#description' => t('Cookie path for embedded Gallery2 sessions.'),
-  ); */
-
-  // Fullname settings
-  if (module_exists('profile')) {
-    $form['fullname'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Full Name settings'),
-      '#description' => '',
-      '#collapsible' => TRUE, 
-      '#collapsed' => TRUE,
-    );
-
-    $form['fullname']['gallery_use_full_name'] = array(
-          '#type' => 'checkbox',
-          '#title' => t('Enable Full Name support'),
-          '#return_value' => 1,
-          '#default_value' => variable_get('gallery_use_full_name', 0),
-          '#description' => t('Use full name from profile module in Gallery2 user data. Note that
-                               enabling/disabling this only updates Gallery2 user data when the
-                               Drupal user is updated (ie no sync is done immediately).'),
-          );
-
-    $form['fullname']['gallery_profile_full_name_field'] = array(
-          '#type' => 'textfield',
-          '#title' => t('Full name profile field'),
-          '#default_value' => variable_get('gallery_profile_full_name_field', 'profile_full_name'),
-          '#size' => 64,
-          '#maxlength' => 64,
-          '#description' => t('Name of "Full Name" field in profile module.'),
-          );
-  } else {
-    $form['fullname'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Full Name settings'),
-      '#description' => t('Full names in G2 can be supported using the profile module 
-                              with a "Full Name" field. However the profile module is not 
-                              installed, so this functionality is not available. If you install 
-                              it you will have more options here.'),
-      '#collapsible' => TRUE, 
-      '#collapsed' => FALSE,
-    );
-  }
+function _gallery_settings_general() {
+  // Short Status
+  gallery_version();
+  gallery_plugin_set_status(array('imageblock', 'imageframe', 'search'));
+  $status = gallery_get_status();
   
-  // Image Block settings
-  $typeMap = array(
-    'randomImage' => t('Random image'),
-    'recentImage' => t('Recent image'),
-    'viewedImage' => t('Viewed image'),
-    'randomAlbum' => t('Random album'),
-    'recentAlbum' => t('Recent album'),
-    'viewedAlbum' => t('Viewed album'),
-    'dailyImage' => t('Daily image'),
-    'weeklyImage' => t('Weekly image'),
-    'monthlyImage' => t('Monthly image'),
-    'dailyAlbum' => t('Daily album'),
-    'weeklyAlbum' => t('Weekly album'),
-    'monthlyAlbum' => t('Monthly album'),
-    );
-    
-  $paramMap = array(
-    'title' => t('Title'),
-    'date' => t('Date'),
-    'views' => t('View Count'),
-    'owner' => t('Item owner'),
-    'heading' => t('Heading'),
-    'fullSize' => t('Full Size'),
+  $form['status'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Status'),
+    '#description' => gallery_format_status($status, ''),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
   );
-    
-  $form['block'] = _gallery_block_settings($typeMap , $paramMap);
-  $form['grid'] = _gallery_grid_block_settings($typeMap , $paramMap);
-  $form['filter'] = _gallery_filter_settings($typeMap , $paramMap);
-  $form['g2image'] = _gallery_g2image_settings();
-  $form['search'] = _gallery_search_settings($typeMap , $paramMap);
-  $form['links'] = _gallery_links_settings();   
-       
-  // Debug Settings
-  $form['error'] = array(
+  
+  // Theme Settings
+  $form['theme'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Error Logging settings'),
+    '#title' => t('Theme settings'),
     '#description' => '',
-    '#collapsible' => TRUE, 
+    '#collapsible' => TRUE,
     '#collapsed' => TRUE,
-  );             
-
-  $form['error']['gallery_error_mode'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Error logging'),
-    '#default_value' => variable_get('gallery_error_mode', array(1)),
-    '#options' => array(1 => t('Watchdog'),
-                        2 => t('Output to the browser')),
-    '#description' => t('Choose where errors are displayed.'),
   );
-
-  $form['gallery_valid'] = array(
-    '#type' => 'value', 
-    '#value' => variable_get('gallery_valid', 0),
+  $themes = system_theme_data();
+  ksort($themes);
+  $options = array('default' => t('System default'));
+  foreach ($themes as $theme) {
+    $options[$theme->name] = drupal_ucfirst($theme->name);
+  }
+  $form['theme']['gallery_page_theme'] = array(
+    '#type' => 'select',
+    '#title' => t('Gallery page theme'),
+    '#default_value' => variable_get('gallery_page_theme', 'default'),
+    '#options' => $options,
+    '#description' => t('Drupal theme to be used for all gallery pages (gallery/*).'),
   );
-
-  return $form;
-}
-
-/**
- * Settings for gallery image block
- *
- */
-function _gallery_block_settings($typeMap , $paramMap) {    
-  $form['block'] = array(
+  
+  // Gallery Block Settings
+  $form['blocks'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Gallery Image Block settings'),
-    '#description' => '',
-    '#collapsible' => TRUE, 
+    '#title' => t('Gallery block settings'),
+    '#collapsible' => TRUE,
     '#collapsed' => TRUE,
-  );   
-  
-  $numimages = variable_get('gallery_block_num_images', 3);
-  $form['block']['gallery_block_num_images'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Number of images in block'),
-    '#default_value' => $numimages,
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Choose the number of images to appear. You will need to submit the form if you have increased the number in order to choose the image types.'),
-  );                     
-
-  $gallery_block_block = variable_get('gallery_block_block', array('randomImage'));
-  $form['block']['gallery_block_block'] = array(
-    '#tree' => 1,
-    );  
-  $typeMap2 = array_merge(array('none' => t('None')), $typeMap);
-  for ($i=0; $i<$numimages; $i++) {
-    $form['block']['gallery_block_block'][$i] = array(
-      '#type' => 'select',
-      '#title' => '',
-      '#default_value' => $gallery_block_block[$i],
-      '#options' => $typeMap2,
-      '#description' => '',
-    );   
-  }
-  $form['block']['gallery_block_block'][0]['#title'] = t('Image types');
-  $form['block']['gallery_block_block'][$i-1]['#description'] = 
-    t('Pick the type of images you\'d like to see. You can select the same type more than once.');
-
-  $form['block']['gallery_item_id'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Album or Item ID'),
-    '#default_value' => variable_get('gallery_item_id', ''),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter the Gallery image or album ID (or blank).  If an album or item ID is specified, random images will only be selected from that album and its sub-albums.'),
-  );
-
-  $form['block']['gallery_block_show'] = array(
-  '#type' => 'checkboxes',
-  '#title' => t('Image data'),
-  '#default_value' => variable_get('gallery_block_show', array('title', 'heading')),
-  '#options' =>  $paramMap,
-  '#description' => t('Choose the item metadata you\'d like to display.'),
+    '#description' => t('You can now have multiple image blocks and grid blocks. Use these settings to determine
+                         the number of available blocks.<br /><strong>Warning: If you decrease the number of blocks,
+                         always the last block (with the highest ID) will be removed.</strong>'),
   );
-
-  $form['block']['gallery_maxsize'] = array(
+  $form['blocks']['gallery_block_image_num'] = array(
     '#type' => 'textfield',
-    '#title' => t('Thumbnail size'),
-    '#default_value' => variable_get('gallery_maxsize', 150),
+    '#title' => t('Number of image blocks'),
+    '#default_value' => variable_get('gallery_block_image_num', 1),
     '#size' => 10,
     '#maxlength' => 10,
-    '#description' => t('If you want your size to be bigger than the thumbnail size for that image as defined in your Gallery2, you must select "Full Size" above (but note that the full image will be returned and then resized by the browser, so it may take a while to download).'),        
-    );   
-    
-  $form['block']['gallery_album_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Album frame'),
-    '#default_value' => variable_get('gallery_album_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your Gallery2 install for a complete list. Use "none" or blank for no frame.'),
-  );
-
-  $form['block']['gallery_item_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Item frame'),
-    '#default_value' => variable_get('gallery_item_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your Gallery2 install for a complete list. Use "none" or blank for no frame.'),
-  );
-
-  $form['block']['gallery_link_target'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Link target'),
-    '#default_value' => variable_get('gallery_link_target', ''),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a link target (eg "_blank", "_new").'),
-  );
-  return $form['block'];
-}
-
-/**
- * Settings for gallery grid block
- *
- */
-function _gallery_grid_block_settings($typeMap , $paramMap) {
-  $form['grid'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Gallery Grid Image Block settings'),
-    '#description' => '',
-    '#collapsible' => TRUE, 
-    '#collapsed' => TRUE,
-  );   
-      
-  $form['grid']['gallery_grid_num_cols'] = array(
-    '#type' => 'select',
-    '#title' => t('Number of columns'),
-    '#default_value' => variable_get('gallery_grid_num_cols', 2),
-    '#options' => array(1=>1, 2=>2, 3=>3, 4=>4, 5=>5),
-    '#description' => t('Enter the number of columns in the grid.'),
-  );
-  
-  $form['grid']['gallery_grid_num_rows'] = array(
-    '#type' => 'select',
-    '#title' => t('Number of rows'),
-    '#default_value' => variable_get('gallery_grid_num_rows', 2),
-    '#options' => array(1=>1, 2=>2, 3=>3, 4=>4, 5=>5),
-    '#description' => t('Enter the number of rows in the grid.'),
-  );              
-
-  $form['grid']['gallery_grid_block_block'] = array(
-      '#type' => 'select',
-      '#title' => 'Image types',
-      '#default_value' => variable_get('gallery_grid_block_block', 'randomImage'),
-      '#options' => $typeMap,
-      '#description' => 'Pick the type of images you\'d like to see in the grid.',
-    );   
-
-  $form['grid']['gallery_grid_item_id'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Album or Item ID'),
-    '#default_value' => variable_get('gallery_grid_item_id', ''),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter the Gallery image or album ID (or blank).  If an album or item ID is specified, random images will only be selected from that album and its sub-albums.'),
-  );
-
-  $form['grid']['gallery_grid_block_show'] = array(
-  '#type' => 'checkboxes',
-  '#title' => t('Image data'),
-  '#default_value' => variable_get('gallery_grid_block_show', array()),
-  '#options' =>  $paramMap,
-  '#description' => t('Choose the item metadata you\'d like to display.'),
+    '#description' => t('Select how many image blocks should be available.'),
   );
-
-  $form['grid']['gallery_grid_maxsize'] = array(
+  $form['blocks']['gallery_block_grid_num'] = array(
     '#type' => 'textfield',
-    '#title' => t('Thumbnail size'),
-    '#default_value' => variable_get('gallery_grid_maxsize', 90),
+    '#title' => t('Number of grid image blocks'),
+    '#default_value' => variable_get('gallery_block_grid_num', 1),
     '#size' => 10,
     '#maxlength' => 10,
-    '#description' => t('If you want your size to be bigger than the thumbnail size for that image as defined in your Gallery2, you must select "Full Size" above (but note that the full image will be returned and then resized by the browser, so it may take a while to download).'),        
-    );   
-    
-  $form['grid']['gallery_grid_album_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Album frame'),
-    '#default_value' => variable_get('gallery_grid_album_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your Gallery2 install for a complete list. Use "none" or blank for no frame.'),
-  );
-
-  $form['grid']['gallery_grid_item_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Item frame'),
-    '#default_value' => variable_get('gallery_grid_item_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your Gallery2 install for a complete list. Use "none" or blank for no frame.'),
-  );
-
-  $form['grid']['gallery_grid_link_target'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Link target'),
-    '#default_value' => variable_get('gallery_grid_link_target', ''),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a link target (eg "_blank", "_new").'),
+    '#description' => t('Select how many grid image blocks should be available.'),
   );
-  return $form;
-}
-
-/**
- * Settings for gallery filter
- *
- */
-function _gallery_filter_settings($typeMap , $paramMap) {    
-  $form['filter'] = array(
+  
+  // Gallery2 Sidebar Settings
+  $form['sidebar'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Gallery Filter settings'),
+    '#title' => t('Sidebar settings'),
     '#description' => '',
-    '#collapsible' => TRUE, 
+    '#collapsible' => TRUE,
     '#collapsed' => TRUE,
-  ); 
-//we don't include specificItem, since it can be selected automatically if n=1
-  $form['filter']['gallery_filter_prefix'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Filter prefix'),
-    '#default_value' => variable_get('gallery_filter_prefix', 'G2'),
-    '#size' => 10,
-    '#maxlength' => 10,
-    '#description' => t('Prefix to use with filter. Example: \'G2\' means you use [G2: 999].'),
-  );
-
-  $form['filter']['gallery_filter_default_block_type'] = array(
-    '#type' => 'select',
-    '#title' => t('Image Block Type'),
-    '#default_value' => variable_get('gallery_filter_default_block_type', 'viewedImage'),
-    '#options' => $typeMap,
-    '#description' => t('Pick default type of image block you\'d like to use, default is Recent image. Viewed image is by most clicks.'),
   );
-  
-  $form['filter']['gallery_filter_can_cache'] = array(
+  $form['sidebar']['gallery_move_sidebar_to_block'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Cache gallery filter pages'),
-    '#default_value' => variable_get('gallery_filter_can_cache', 1),
-    '#description' => t('By default the gallery filter output is cached by Drupal to speed up page loading. However, it will not cache the css class info for the frames. The best approach is the make sure that the sidebar image block and the gallery filter images use the same frames. If you are unable to do this you will have to deselect this option to force Drupal not to cache the pages, or else your frames will not appear. If you change this option you will need to go to <a href="@link">admin/filters</a> and re-save the image formats that use gallery filter.', array('@link' => url('admin/filters'))),
-  );  
-  
-  $form['filter']['gallery_filter_n_images'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default Number of Images'),
-    '#default_value' => variable_get('gallery_filter_n_images', 1),
-    '#size' => 3,
-    '#maxlength' => 3,
-    '#description' => t('How many images you want the default block to show.  Best to keep at 1 and use the n parameter.'),
+    '#title' => t('Move Gallery2 sidebar to Drupal Gallery Navigation block'),
+    '#default_value' => variable_get('gallery_move_sidebar_to_block', 1),
+    '#description' => t('When selected, the Gallery2 sidebar will be moved into
+                         the Drupal "Gallery Navigation" block. This typically allows
+                         for a much cleaner embedded gallery and is generally
+                         recommended. Note that you will need to enable the Gallery
+                         Navigation block.'),
   );
-//////*********in fact, should we remove this option all together?  because the way it is now, if you change this to n>1
-//then instances where n was not specified and item_id is a specific item, the block breaks and nothing is shown.
-  $form['filter']['gallery_filter_default_show'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Default Image Block Settings'),
-    '#default_value' => variable_get('gallery_filter_default_show', array('none')),
-    '#options' => $paramMap,
-    '#description' => t('Choose the item metadata you\'d like to display by default.  This will change all instances where show parameter was not specified.'),
+  $form['sidebar']['gallery_move_admin_sidebar_to_block'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Move Gallery2 Admin sidebar to Drupal Gallery Navigation block'),
+    '#default_value' => variable_get('gallery_move_admin_sidebar_to_block', 0),
+    '#description' => t('When selected, the Gallery2 Admin sidebar will be moved into
+                         the Drupal "Gallery Navigation" block. This is not normally
+                         recommended since the Admin Sitebar is very long and the
+                         formatting does not always fit with the rest of the block
+                         (but cannot be changed in the current Gallery2 versions).'),
+    '#disabled' => !variable_get('gallery_move_sidebar_to_block', 1),
   );
   
-  $form['filter']['gallery_filter_default_size'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default thumbnail size'),
-    '#default_value' => variable_get("gallery_filter_default_size", "150"),
-    '#size' => 10,
-    '#maxlength' => 10,
-    '#description' => t('If no size is specified when calling the filter, this size will be used. If you want your size to be bigger than the thumbnail size for that image as defined in your Gallery2, you must select "Full Size" above (but note that the full image will be returned and then resized by the browser, so it may take a while to download).'),        
-  );
+  // Gallery2 Google Sitemap Settings
+  $gallery2_sitemap_status = gallery_single_plugin_status('sitemap');
+  $gallery2_sitemap_status_str = theme('gallery_plugin_status_message', $gallery2_sitemap_status);
+  $gsitemap_status = module_exists('xmlsitemap');
+  $gsitemap_status_str = theme('gallery_module_status_message', $gsitemap_status);
+  $gsitemap_available = $gsitemap_status && ($gallery2_sitemap_status == GALLERY_PLUGIN_ENABLED);
   
-  $form['filter']['gallery_filter_default_album_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default album frame'),
-    '#default_value' => variable_get('gallery_filter_default_album_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your G2 install for a complete list. Use \'none\' or blank for no frame. '),
+  $desc = t('Allows the Gallery2 sitemap to be merged with the Drupal one so that only one URL needs to
+             be supplied to search engines. Requires the Drupal XML Sitemap module (!gsitemap_status) and
+             the Gallery2 sitemap module (!gallery2_sitemap_status) to be installed/activated.',
+    array(
+      '!gsitemap_status' => $gsitemap_status_str, 
+      '!gallery2_sitemap_status' => $gallery2_sitemap_status_str,
+    )
   );
   
-  $form['filter']['gallery_filter_default_item_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default item frame'),
-    '#default_value' => variable_get('gallery_filter_default_item_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your G2 install for a complete list. Use \'none\' or blank for no frame.'),
+  $form['sitemap'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('XML Sitemap settings'),
+    '#description' => '',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#description' => $desc,
   );
-  
-  $form['filter']['gallery_filter_default_link_target'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default Link target'),
-    '#default_value' => variable_get('gallery_filter_default_link_target', ''),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a link target (eg "_blank", "_new").'),
+  $form['sitemap']['gallery_enable_sitemap'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable merge of Gallery2 sitemap with Drupal sitemap'),
+    '#default_value' => $gsitemap_available ? variable_get('gallery_enable_sitemap', 1) : FALSE,
+    '#disabled' => !$gsitemap_available,
   );
   
-  $form['filter']['gallery_filter_default_div_class'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default class'),
-    '#default_value' => variable_get('gallery_filter_default_div_class', 'nowrap'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('left, right, or nowrap. (See gallery_filter.css to add more or modify these.)'),
-  );
-  return $form['filter'];
-}
-
-/**
- * Settings for gallery search
- *
- */
-function _gallery_search_settings($typeMap , $paramMap) {  
-  $form['search'] = array(
+  // Error logging / Debug Settings
+  $form['error'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Search settings'),
+    '#title' => t('Error logging / Debug settings'),
     '#description' => '',
-    '#collapsible' => TRUE, 
+    '#collapsible' => TRUE,
     '#collapsed' => TRUE,
-  ); 
-  
-  $form['search']['gallery_search_max_items'] = array(
-    '#type' => 'select',
-    '#title' => t('Max number of search results'),
-    '#default_value' => variable_get('gallery_search_max_items', 50),
-    '#options' => array(25=>25, 50=>50, 100=>100, 250=>250),
-    '#description' => t('Enter the maximum number of search results returned per Gallery2 Module. Higher numbers will give slower searching.'),
   );
-
-  $form['search']['gallery_search_num_per_row'] = array(
-    '#type' => 'select',
-    '#title' => t('Number of search results per table row'),
-    '#default_value' => variable_get('gallery_search_num_per_row', 3),
-    '#options' => array(1=>1, 2=>2, 3=>3, 4=>4, 5=>5),
-    '#description' => t('Enter the number of search results per row in the paged table.'),
+  $form['error']['gallery_error_mode'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Error logging'),
+    '#default_value' => variable_get('gallery_error_mode', array(GALLERY_ERROR_WATCHDOG)),
+    '#options' => array(GALLERY_ERROR_WATCHDOG => t('Watchdog'),
+                        GALLERY_ERROR_BROWSER => t('Output to the browser'),
+                        GALLERY_ERROR_VERBOSE => t('Verbose error messages')),
+    '#description' => t('Choose where errors are displayed and how detailed they are.'),
   );
-
-  $form['search']['gallery_search_max_rows_per_pager'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Number of rows per page'),
-    '#default_value' => variable_get('gallery_search_max_rows_per_pager', 5),
-    '#size' => 10,
-    '#maxlength' => 10,
-    '#description' => t('Enter the number of search results per row in the paged table.'),
+  $form['error']['gallery_report'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable bug report assistant'),
+    '#default_value' => variable_get('gallery_report', 1),
+    '#description' => t('In case of errors the module can automatically assemble useful data (system info and debug
+                         traces) to help you with detailed bug reports. Only available to users with \'administer
+                         site configuration\' permission.')
   );
-  
-  $form['search']['gallery_search_show_thumbs'] = array(
+  $search_status = module_exists('search') && (gallery_single_plugin_status('search') == GALLERY_PLUGIN_ENABLED);
+  $form['error']['gallery_error_redirect'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Display thumbnails'),
-    '#default_value' => variable_get('gallery_search_show_thumbs', 1),
-    '#description' => t('Display thumbnail images for the search results.'),
+    '#title' => t('Redirect to Gallery search form for invalid paths'),
+    '#default_value' => $search_status ? variable_get('gallery_error_redirect', 0) : 0,
+    '#description' => t('Instead of showing a message that the requested Gallery URL does not exist the user is redirected to the search form.'),
+    '#disabled' => !$search_status,
   );
-          
-  $form['search']['gallery_search_block_show'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Image data'),
-    '#default_value' => variable_get('gallery_search_block_show', array('title' => t('Title'))),
-    '#options' => $paramMap,
-    '#description' => t('Choose the item metadata you\'d like to display.'),
-    ); 
-
-  $form['search']['gallery_search_maxsize'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Thumbnail size'),
-    '#default_value' => variable_get('gallery_search_maxsize', 150),
-    '#size' => 10,
-    '#maxlength' => 10,
-    '#description' => t('If you want your size to be bigger than the thumbnail size for that image as defined in your G2, you must select "Full Size" above (but note that the full image will be returned and then resized by the browser, so it may take a while to download).'),
+  $form['error']['gallery_debug'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable debug mode'),
+    '#default_value' => variable_get('gallery_debug', 0),
+    '#description' => t('Print out debug variables and verbose error messages. Only visible to users with \'administer site configuration\' permission.')
   );
   
-  // Add album frames, item frames and link target (using modified code from MichelleC)
-  $form['search']['gallery_search_album_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Album frame'),
-    '#default_value' => variable_get('gallery_search_album_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your G2 install for a complete list. Use "none" or blank for no frame.'),
-  );
-
-  $form['search']['gallery_search_item_frame'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Item frame'),
-    '#default_value' => variable_get('gallery_search_item_frame', 'none'),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a frame name like notebook, polaroid, shadow, slide, wood, etc. See your G2 install for a complete list. Use "none" or blank for no frame.'),
-  );
-
-  $form['search']['gallery_search_link_target'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Link target'),
-    '#default_value' => variable_get('gallery_search_link_target_', ''),
-    '#size' => 20,
-    '#maxlength' => 20,
-    '#description' => t('Enter a link target (eg "_blank", "_new").'),
-  );
-  return $form['search'];
-}
-
-/**
- * Settings for g2image
- *
- */
-function _gallery_g2image_settings() {
-  $form['g2image'] = array(
+  // Relevant links
+  $form['links'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Gallery Image Assist (g2image) settings'),
-    '#description' => '',
-    '#collapsible' => TRUE, 
+    '#title' => t('Links to the most relevant Drupal & Gallery2 pages'),
+    '#collapsible' => TRUE,
     '#collapsed' => TRUE,
-  );   
-  
-  $form['g2image']['gallery_g2image_mode'] = array(
-    '#type' => 'select',
-    '#title' => t('Mode'),
-    '#default_value' => variable_get('gallery_g2image_mode', 'disabled'),
-    '#options' => array(
-      'disabled' => t('Disabled'),
-      'standalone' => t('Standalone'),
-      'tinymce' => t('TinyMCE'),
-      ),
-    '#description' => t('Determines the mode of operation. For anything other than \'Disabled\' the g2image application has to be installed. See the INSTALL.txt instructions. In \'Standalone\' mode a button will be visible under textfields to launch the g2image window. In \'TinyMCE\' mode the g2image button can be used in the tinymce toolbar. Note that the TinyMCE version will NOT work wih Safari - use the standalone version instead.'),
-  );  
-
-  $options = array(
-    t('Show on every page except the listed pages.'), 
-    t('Show on only the listed pages.')
-  );
-  $description = t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '%blog' for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
-  $form['g2image']['gallery_g2image_only_listed_pages'] = array(
-    '#type' => 'radios', 
-    '#title' => t('Show g2image link on specific pages (Standalone mode only)'),
-    '#default_value' => variable_get('gallery_g2image_only_listed_pages', 1), 
-    '#options' => $options,
-  );
-  
-  $form['g2image']['gallery_g2image_std_pages'] = array(
-    '#type' => 'textarea', 
-    '#title' => t('Pages (Standalone mode only)'), 
-    '#default_value' => variable_get('gallery_g2image_std_pages', gallery_help('admin/settings/gallery_g2image#pages')),
-    '#description' => $description
-  );
-
-  $form['g2image']['gallery_g2image_regex'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Image Types Regular Expression'),
-    '#default_value' => variable_get('gallery_g2image_regex', '@(jpg|jpeg|png|gif|bmp|svg|mov|mpg|mpeg)$@i'),
-    '#size' => 50,
-    '#maxlength' => 50,
-    '#description' => t('Images with these file extensions will be displayed in g2image'),
   );
-
-  $form['g2image']['gallery_g2image_sortby'] = array(
-    '#type' => 'select',
-    '#title' => t('Default Sort Order'),
-    '#default_value' => variable_get('gallery_g2image_sortby', 'title_asc'),
-    '#options' => array(
-      'title_asc' => t('Gallery2 Title (A-z)'),
-      'title_desc' => t('Gallery2 Title (z-A)'),
-      'name_asc' => t('Filename (A-z)'),
-      'name_desc' => t('Filename (z-A)'),
-      'mtime_desc' => t('Last Modification (newest first)'),
-      'mtime_asc' => t('Last Modification (oldest first)'),
-      ),
-    '#description' => t('Determines the default sorting order.'),
-  );  
-  
-  $form['g2image']['gallery_g2image_images_per_page'] = array(
-    '#type' => 'select',
-    '#title' => t('Default Number of images per page'),
-    '#default_value' => variable_get('gallery_g2image_images_per_page', 20),
-    '#options' => array(10=>10, 20=>20, 30=>30, 40=>40, 50=>50, 60=>60),
-    '#description' => t('Choose the default number of images per page.'),
+  // Drupal links
+  $desc  = '<ul>';
+  $desc .= '<li><a href="@gallery-users">Gallery users</a> : Gallery2 user integration and synchronization.</li>';
+  $desc .= '<li><a href="@gallery-report">Report Generator</a> : Collect information about your installation. Useful especially for bug reports.</li>';
+  $desc .= '</ul>';
+  $form['links']['drupal'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Links to Drupal paths'),
+    '#description' => t($desc, array(
+      '@gallery-users' => url('admin/user/gallery'),
+      '@gallery-report' => url('admin/settings/gallery/report/download'))),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
   );
-  
-  $form['g2image']['gallery_g2image_display_filenames'] = array(
-    '#type' => 'select',
-    '#title' => t('Default Display Options'),
-    '#default_value' => variable_get('gallery_g2image_display_filenames', 'thumbnails'),
-    '#options' => array(
-      'thumbnails' => t('Thumbnails only'),
-      'filenames' => t('Thumbnails with title and filename'),
-      ),
-    '#description' => t('Choose the default display option for images.'),
-  );  
-  
-  $form['g2image']['gallery_g2image_click_mode'] = array(
-    '#type' => 'select',
-    '#title' => t('Default Click Mode'),
-    '#default_value' => variable_get('gallery_g2image_click_mode', 'one_click_insert'),
-    '#options' => array(
-      'one_click_insert' => t('Insert using Default settings'),
-      'show_advanced_options' => t('Open the Advanced Options Menu'),
-      ),
-    '#description' => t('The default settings for the "Results of clicking on an image:" option'),
-  );  
-  
-    $form['g2image']['gallery_g2image_click_mode_variable'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('"Results of clicking on an image:" option is available to user'),
-    '#default_value' => variable_get('gallery_g2image_click_mode_variable', 1),
-    '#description' => t('Determines if the user can change the "Results of clicking on an image:" option.'),
-  );     
-  $form['g2image']['gallery_g2image_default_action'] = array(
-    '#type' => 'select',
-    '#title' => t('Default Action'),
-    '#default_value' => variable_get('gallery_g2image_default_action', 'drupal_g2_filter'),
-    '#options' => array(
-      'drupal_g2_filter' => t('Gallery Filter ID'),
-      'thumbnail_image' => t('Thumbnail with link to image'),
-      'thumbnail_album' => t('Thumbnail with link to parent album'),
-      'thumbnail_custom_url' => t('Thumbnail with link to custom URL'),
-      'thumbnail_only' => t('Thumbnail only'),
-      'link_image' => t('Text link to image'),
-      'link_parent' => t('Text link to parent album'),
-      ),
-    '#description' => t('Choose the default method of inserting the image info.'),
-  );  
-  
-  $form['g2image']['gallery_g2image_custom_url'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default custom url'),
-    '#default_value' => variable_get('gallery_g2image_custom_url', 'http://'),
-    '#size' => 50,
-    '#maxlength' => 50,
-    '#description' => t('The default custom url. Used with \'Thumbnail with link to custom URL\' action setting'),
+  // Gallery2 links
+  $desc  = '<ul>';
+  $desc .= '<li><a href="@g2-modules">Plugins</a> : To install, activate or configure the required and optional plugins relating to gallery.module (Image Block, Image Frame, URL Rewrite, Sitemap, Search).</li>';
+  $desc .= '<li><a href="@g2-themes">Themes</a> : To add/remove blocks in the sidebar.</li>';
+  if (gallery_single_plugin_status('rewrite') == GALLERY_PLUGIN_ENABLED) {
+    $desc .= '<li><a href="@g2-rewrite">Embedded URL Rewrite settings</a> : To define the rewrite rules.</li>';
+  }
+  $desc .= '<li><a href="@g2-cookie">Cookie Settings</a> : Only needed for a small number of site configurations, such as the use of different subdomains for Gallery2 and Drupal.</li>';
+  $desc .= '</ul>';
+  $g2_uri = variable_get('gallery_embed_uri', '?q=gallery');
+  $form['links']['gallery'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Links to Gallery2 Site Admin sections'),
+    '#description' => t($desc, array(
+      '@g2-modules' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminModules',
+      '@g2-themes' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminThemes&g2_mode=defaults',
+      '@g2-rewrite' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=rewrite.AdminRewrite&g2_mode=setup',
+      '@g2-cookie' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminCore')),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
   );
   
-  // Fix - G2 prefix
-
-  $gallery_g2image_custom_class = variable_get('gallery_g2image_custom_class', array());
-  $css_options =  array(
-    'none' => t('None'),
-    'g2image_normal' => t('Normal'),
-    'g2image_float_left' => t('Float Left'),
-    'g2image_float_right' => t('Float Right'),
-    'g2image_centered' => t('Centered'),
-    );
+  $form['#validate']['_gallery_settings_general_validate'] = array();
+  $form['#submit']['_gallery_settings_general_submit'] = array();
+  $form['#submit']['system_settings_form_submit'] = array();
+  return system_settings_form($form);
+}
 
-  $add_css_options = array();
-  foreach ($gallery_g2image_custom_class as $key => $value) {
-    if ($value) {
-      $add_css_options[$value] = $value;
-    }
+/**
+ * Function _gallery_settings_general_validate().
+ */
+function _gallery_settings_general_validate($form_id, $form_values) {
+  if (!is_numeric($form_values['gallery_block_image_num']) || $form_values['gallery_block_image_num'] < 1) {
+    form_set_error('gallery_block_image_num', t('Number of image blocks must be a positiv integer greater zero.'));
   }
-  $css_options = array_merge($css_options, $add_css_options);
-
-  $form['g2image']['gallery_g2image_default_alignment'] = array(
-    '#type' => 'select',
-    '#title' => t('Default Alignment'),
-    '#default_value' => variable_get('gallery_g2image_default_alignment', 'none'),
-    '#options' => $css_options,
-    '#description' => t('Choose the default alignment of images.'),
-  );
-
-  $form['g2image']['gallery_g2image_custom_class'] = array(
-    '#tree' => 1,
-    );  
-    
-  for ($i=1; $i<=4; $i++) {
-    $form['g2image']['gallery_g2image_custom_class'][$i] = array(
-      '#type' => 'textfield',
-      '#title' => t('Custom Class @index', array('@index' => $i)),
-      '#default_value' => $gallery_g2image_custom_class[$i],
-      '#size' => 20,
-      '#maxlength' => 50,
-    );   
+  if (!is_numeric($form_values['gallery_block_grid_num']) || $form_values['gallery_block_grid_num'] < 1) {
+    form_set_error('gallery_block_grid_num', t('Number of grid blocks must be a positiv integer greater zero.'));
   }
-  $form['g2image']['gallery_g2image_custom_class'][$i-1]['#description'] = 
-    t('Additional css classes to be available for selection (must be defined in .css file).');
-
-  $form['g2image']['gallery_g2image_class_mode'] = array(
-    '#type' => 'select',
-    '#title' => t('Alignment Class Insertion Point'),
-    '#default_value' => variable_get('gallery_g2image_class_mode', 'img'),
-    '#options' => array(
-      'img' => t('<img class=...>'),
-      'div' => t('<div class=...><img ...>'),
-      ),
-    '#description' => t('Determines where the alignment class will be inserted. If you choose \'&lt;div class=...&gt;&lt;img ...&gt;\', you will have to manually delete any &lt;div&gt; tags manually after deleting images from the TinyMCE window.'),
-  );
-  return $form['g2image'];
 }
 
 /**
- * Settings for links section
- *
+ * Function _gallery_settings_general_submit().
  */
-function _gallery_links_settings() {
-  if (variable_get('gallery_valid', 0)) {
-    $g2Uri = variable_get('gallery_embed_uri', '?q=gallery');
-    $desc = t('Here are some links to the parts of Gallery2 Site Admin most relevant to gallery.module.');
-    $desc .= '<ul>';
-    $desc .= '<li><a href= "' . $g2Uri . '&g2_view=core.SiteAdmin&g2_subView=core.AdminModules">Modules</a> : ' . t('To install, activate or configure the required and optional modules relating to gallery.module (Image Block, Image Frame, URL Rewrite, Album Select).') . '</li>';
-    $desc .= '<li><a href= "' . $g2Uri . '&g2_view=core.SiteAdmin&g2_subView=core.AdminThemes&g2_mode=defaults">Themes</a> : ' . t('To add/remove blocks in the sidebar.') . '</li>';    $desc .= '<li><a href= "' . $g2Uri . '&g2_view=core.SiteAdmin&g2_subView=rewrite.AdminRewrite&g2_mode=setup">Embedded URL Rewrite settings</a> : ' . t('To configure the correct .htaccess path and define the rewrite rules.') . '</li>';
-    $desc .= '<li><a href= "' . $g2Uri . '&g2_view=core.SiteAdmin&g2_subView=core.AdminCore">Cookie Settings</a> : '. t('Only needed for a small number of site configurations, such as the use of different subdomains for Gallery2 and Drupal.') . '</li>';
-    $desc .= '</ul>';
-  } else {
-    $desc = t('This section will contain links to the parts of Gallery2 Site Admin most relevant to gallery.module. It is only available when your Embedded Gallery installation is valid, which it currently is not.');
-  }  
-  $form['links'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Links to Gallery2 Site Admin sections most relevant to Drupal (advanced)'),
-    '#description' => $desc,
-    '#collapsible' => TRUE, 
-    '#collapsed' => TRUE,
-  );   
-  return $form['links'];
+function _gallery_settings_general_submit($form_id, $form_values) {
+  if ($form_values['gallery_enable_sitemap'] != variable_get('gallery_enable_sitemap', 0)) {
+    drupal_set_message('The XML sitemap setting has been updated, but the new sitemap may not be generated
+                        immediately (controlled by XML Sitemap).');
+  }
 }
 
-
 /**
- * Validate the gallery form settings
+ * Function _gallery_settings_block_image().
  */
-function gallery_admin_settings_validate($form_id, &$form) {
-  global $form_values;
-  include_once(drupal_get_path('module', 'gallery') . '/G2EmbedDiscoveryUtilities.class');
-  include_once(drupal_get_path('module', 'gallery') . '/G2EmbedTestUtilities.class');
-  
-  $gallery_valid = 1;
+function _gallery_settings_block_image($delta) {
+  $plugin_status =  gallery_plugin_status(array('imageblock', 'imageframe'));
 
-  // Store the original values for the variables
-  $orig['g2Uri'] = $form_values['gallery_uri'];
-  $orig['g2EmbedPath'] = $form_values['gallery_dir'];
-  $orig['embedUri'] = $form_values['gallery_embed_uri'];
-  
-  // Check these variables
-  list($num_errors, $num_warnings, $new, $results) = 
-    G2EmbedTestUtilities::checkLocations($orig, $form_values['gallery_autodetect_dir']);
-  if ($num_errors) {
-    $gallery_valid = 0;
+  $imageblock_desc = t('The Gallery Image Block requires the Gallery2
+    Image Block plugin (!imageblock_status) and optionally the Gallery2 Image Frame 
+    plugin (!imageframe_status).', array(
+        '!imageblock_status' => theme('gallery_plugin_status_message', $plugin_status['imageblock']), 
+        '!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']),
+    )
+  );
+  if ($plugin_status['imageblock'] != GALLERY_PLUGIN_ENABLED) {
+    $g2_uri = variable_get('gallery_embed_uri', '?q=gallery');
+    $g2_plugins_page = (variable_get('gallery_valid', 0)) ? 
+        t('<a href= "@g2_plugins">Gallery2 Plugins</a>',
+          array('@g2_plugins' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminModules'))
+        : t('Gallery2 Site Admin -> Plugins');
+    $g2_imageblock_desc = t(' However the Image Block plugin is unavailable, so this block is
+      not available and the settings are disabled. To use this block please go to
+      the !g2_plugins page and install/activate the Image Block plugin.', array(
+      '!g2_plugins' => $g2_plugins_page));
+    $imageblock_desc .= $g2_imageblock_desc;
   }
   
-  // Update the variables with the new validated ones
-  $form_values['gallery_uri'] = $new['g2Uri'];
-  $form_values['gallery_dir'] = $new['g2EmbedPath'];
-  $form_values['gallery_embed_uri'] = $new['embedUri'];
-
-  // Perform pre-init tests. If they fail then do not init the gallery as there may be an issue  
-  list($num_errors, $num_warnings, $pre_init_results) = G2EmbedTestUtilities::preInitTests();
-  $results = array_merge($results, $pre_init_results);
-  if ($num_errors) {
-    $gallery_valid = 0;
-  }
-
-  // If the filepaths seem correct then check Gallery2 works and has the correct module configs
-  // This code is modified from the WPG2 integration code -- Thanks.
-  if ($gallery_valid) {
-    // Gallery install is thought valid, so init it.
-    $title = t('Gallery2 Init:');
-    $vars['gallery_uri'] = $form_values['gallery_uri'];
-    $vars['gallery_dir'] = $form_values['gallery_dir'];
-    $vars['gallery_embed_uri'] = $form_values['gallery_embed_uri'];
-    $vars['gallery_valid'] = true;
-    list ($success, $ret) = _gallery_init(true, $vars);
-    if (!$success) {
-      // Gallery install was supposed to be valid, but it still failed. Something is wrong.
-      $results['gallery_init']['title'] = $title;
-      $results['gallery_init']['error'] = true;       
-      $results['gallery_init']['notice'] = t('Everything seemed OK, but the Gallery could still not be initialised. Perhaps a manually entered value is incorrect.');
-      $gallery_valid = 0;
-    } else {
-      $results['gallery_init']['title'] = $title;
-      $results['gallery_init']['success'] = true;
-
-      list($num_errors, $num_warnings, $post_init_results) = G2EmbedTestUtilities::postInitTests();
-      if ($num_errors) {
-        $gallery_valid = 0;
-      }
-      // Check for changed embedUri
-      /* No longer needed as the URL Rewrite config below will do it 
-      if ($form_values['gallery_embed_uri'] != variable_get('gallery_embed_uri', '?q=gallery')) {
-        $post_init_results['urlrewrite3']['title'] = t('Gallery2 URL Rewrite rules:');
-        $post_init_results['urlrewrite3']['warning'] = true;       
-        $post_init_results['urlrewrite3']['notice'] = t('The \'Embed URI\' setting has changed. If you are using the URL Rewrite module in Gallery2 you will need to regenerate the rules (just click the \'save\' button on the Embedded URL Rewrite page).');
-      }*/
-      
-      // Update the URL Rewrite Configuration
-      if ($post_init_results['urlrewrite']['success']) {
-        list($url_conf_num_errors, $url_conf_num_warnings, $post_init_results['urlrewrite2']) = 
-          _gallery_configure_url_rewrite();
-      }
-        
-      $results = array_merge($results, $post_init_results);
-      
-      // Setup the cookie path - removed for now (see above)
-      /*
-      $path = $form_values['gallery_cookie_path'];
-      $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'cookie.path', $path);
-      */
-      
-      GalleryEmbed::done();
-    }
-  }
-  // Validate the g2image settings
-  list($num_errors, $num_warnings, $results_g2image) =
-    _gallery_g2image_settings_form_validate($form_values);
-  if ($results_g2image) {
-    $results['gallery_g2image'] = $results_g2image;
-  }
-  // Test again for validity
-  if ($gallery_valid) {
-      $results['gallery_valid']['title'] = t('Overall Status:');
-      $results['gallery_valid']['success'] = true; 
-   } else {
-    $results['gallery_valid']['title'] = t('Overall Status:');
-    $results['gallery_valid']['error'] = true;       
-    $results['gallery_valid']['notice'] = t('You need to fix the above errors before Gallery2 will be embedded in Drupal.');
-  }
+  $form['#description'] = $imageblock_desc;
 
-  $message = t('Embedded Gallery2 Status: ').'<ul>';
-  foreach ($results as $key=>$result) {
-    $message .= '<li>' . t($result['title']) . ' ';
-    if (isset($result['success']) && $result['success']) {
-      $message .= '<span class=\'g2_embed_success\'>' . t('Success') . '</span>';
-    } else if (isset($result['warning']) && $result['warning']) {
-      $message .= '<span class=\'g2_embed_warning\'>' . t('Warning') . '</span>';
-      $message .= '<ul><li>' . t($result['notice']) . '</li></ul>';
-    } else if (isset($result['error']) && $result['error']) {
-      $message .= '<span class=\'g2_embed_error\'>' . t('Error') . '</span>';
-      $message .= '<ul><li>' . t($result['notice']) . '</li></ul>';
-    } else if (isset($result['advise']) && $result['advise']) {
-      $message .= '<span class=\'g2_embed_warning\'>' . t('Advisory') . '</span>';
-      $message .= '<ul><li>' . t($result['notice']) . '</li></ul>';
-    }
-  }
-  $message .= '</ul>';
-  drupal_set_message($message);
-  $form_values['gallery_valid'] = $gallery_valid;
+  $imageframe_desc = ($plugin_status['imageframe'] != GALLERY_PLUGIN_ENABLED) ?
+    t('Requires the Gallery2 Image Frame plugin (!imageframe_status).',
+        array('!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']))) : '';
+  
+  $image_frames = gallery_get_image_frames();
+  _gallery_block_options($type_map, $param_map);
   
-  // Gallery Image Block Settings validation
-  // Need to truncate the gallery_block_block variable to the entered number of blocks
-  if (count($form_values['gallery_block_block']) != $form_values['gallery_block_num_images']) {
-    $form_values['gallery_block_block'] = array_slice(
-      $form_values['gallery_block_block'], 0, $form_values['gallery_block_num_images']);
+  if (variable_get('gallery_block_image_num', 1) > 1) {
+    $form['gallery_block_image_'. $delta .'_blockid'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Block Identifier [Block @id]', array('@id' => $delta+1)),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_blockid', ''),
+      '#size' => 25,
+      '#maxlength' => 30,
+      '#description' => t('A short identifier to distinguish blocks of the same type. (Blocks are numbered by default)'),
+    );
   }
-}
 
-/**
- * Configure URL rewrite (from WPG2 code)
+  if ($plugin_status['imageblock'] == GALLERY_PLUGIN_ENABLED) {
+    $numimages = variable_get('gallery_block_image_'. $delta .'_num_images', 3);
+    
+    $form['gallery_block_image_'. $delta .'_num_images'] = array(
+      '#type' => 'select',
+      '#title' => t('Number of images in block'),
+      '#default_value' => $numimages,
+      '#options' => _gallery_range_array(1, 20),
+      '#description' => t('Choose the number of images to appear. You will need to submit the form if you have increased the number in order to choose the image types.'),
+    );
+    
+    $gallery_block_block = variable_get('gallery_block_image_'. $delta .'_block_block', array('randomImage'));
+    
+    $form['gallery_block_image_'. $delta .'_block_block'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Image types'),
+      '#collapsible' => FALSE,
+      '#collapsed' => FALSE,
+      '#tree' => TRUE,
+      '#description' => t('Pick the type of images you would like to see. You can select the same type more than once.'),
+    );
+    for ($i=0; $i<$numimages; $i++) {
+      $form['gallery_block_image_'. $delta .'_block_block'][$i] = array(
+        '#type' => 'select',
+        '#title' => '',
+        '#default_value' => $gallery_block_block[$i],
+        '#options' => array_merge(array(NULL => t('None')), $type_map),
+      );
+    }
+    
+    $form['gallery_block_image_'. $delta .'_item_id'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Album or Item ID'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_item_id', ''),
+      '#size' => 20,
+      '#maxlength' => 20,
+      '#description' => t('Enter the Gallery image or album ID (or blank). If an album or item ID is specified, random
+                           images will only be selected from that album and its sub-albums. If \'user\' (or \'user:123\')
+                           is entered, items will be taken from the current (or specified) user\'s useralbum.')
+    );
+    
+    $form['gallery_block_image_'. $delta .'_block_show'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Image data'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_block_show', array('title', 'heading')),
+      '#options' =>  $param_map,
+      '#description' => t('Choose the item metadata you would like to display.'),
+    );
+    
+    $form['gallery_block_image_'. $delta .'_size_method'] = array(
+      '#type' => 'select',
+      '#title' => t('Image size method'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_size_method', GALLERY_IMAGEBLOCK_SIZE_METHOD_DEFAULT),
+      '#options' => array(
+        'maxsize' => t('Max Size'),
+        'exactsize' => t('Exact Size'),
+      ),
+      '#description' => t('\'Max Size\' gives faster image downloading, but the image size 
+                           may be smaller than the size defined below. <br />\'Exact Size\' may be slower
+                           (as a larger image is downloaded and then scaled by the browser) but the image
+                           will be guaranteed to be the size defined below. Only supported for G2.2+.'),
+    );  
+  
+    $form['gallery_block_image_'. $delta .'_size'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image size'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_size', GALLERY_IMAGEBLOCK_SIZE_DEFAULT),
+      '#size' => 10,
+      '#maxlength' => 10,
+      '#description' => t('Sets the size (in pixels) of the longest side of the image according to the method defined above.'),
+    );
+   
+    $form['gallery_block_image_'. $delta .'_album_frame'] = array(
+      '#type' => 'select',
+      '#title' => t('Album frame'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_album_frame', 'none'),
+      '#options' => $image_frames,
+      '#description' => $imageframe_desc,
+    );
+    
+    $form['gallery_block_image_'. $delta .'_item_frame'] = array(
+      '#type' => 'select',
+      '#title' => t('Item frame'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_item_frame', 'none'),
+      '#options' => $image_frames,
+      '#description' => $imageframe_desc,
+    );
+    
+    $form['gallery_block_image_'. $delta .'_link_target'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Link target'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_link_target', ''),
+      '#size' => 20,
+      '#maxlength' => 20,
+      '#description' => t('Enter a link target (e.g. \'_blank\' to open in a new window).'),
+    );
+
+    $form['gallery_block_image_'. $delta .'_link'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image Link'),
+      '#default_value' => variable_get('gallery_block_image_'. $delta .'_link', ''),
+      '#size' => 60,
+      '#maxlength' => 255,
+      '#description' => t('By default the image has a link to the item in the Gallery. This
+        can be overridden here (or leave empty for the default). Use \'none\' for no link, or a URL
+        to link somewhere else instead.'),
+    );
+  }
+  
+  return $form;
+}
+
+/**
+ * Function _gallery_settings_block_grid().
  */
-function _gallery_configure_url_rewrite() {
-  $num_errors = 0;
-  $num_warnings = 0;
+function _gallery_settings_block_grid($delta) {
+  $plugin_status =  gallery_plugin_status(array('imageblock', 'imageframe'));
+
+  $gridblock_desc = t('The Gallery Grid Block requires the Gallery2
+    Image Block plugin (!imageblock_status) and optionally the Gallery2 Image Frame 
+    plugin (!imageframe_status).', array(
+        '!imageblock_status' => theme('gallery_plugin_status_message', $plugin_status['imageblock']), 
+        '!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']),
+    ));
+  if ($plugin_status['imageblock'] != GALLERY_PLUGIN_ENABLED) {
+    $g2_uri = variable_get('gallery_embed_uri', '?q=gallery');
+    $g2_plugins_page = (variable_get('gallery_valid', 0)) ?
+      t('<a href= "@g2_plugins">Gallery2 Plugins</a>',
+        array('@g2_plugins' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminModules'))
+      : t('Gallery2 Site Admin -> Plugins');
+    $g2_imageblock_desc = t(' However the Image Block plugin is unavailable, so this block is
+      not available and the settings are disabled. To use this block please go to
+      the !g2_plugins page and install/activate the Image Block plugin.',
+        array('!g2_plugins' => $g2_plugins_page));
+    $gridblock_desc .= $g2_imageblock_desc;
+  }
   
-  // Find the public path to drupal from the base_url
-  global $base_url;
-  $http = 'http' . (isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] == 'on' ? 's' : '' : '');
-       $public_path = str_replace($http . '://' . $_SERVER['HTTP_HOST'],'', $base_url) . '/';
+  $form['#description'] = $gridblock_desc; 
 
-  // Find the path to drupal. Will this always work?
-  $htaccess_path = realpath(".") . '/';
+  $imageframe_desc = ($plugin_status['imageframe'] != GALLERY_PLUGIN_ENABLED) ?
+    t('Requires the Gallery2 Image Frame plugin (!imageframe_status).',
+      array('!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']))) : '';
   
-  $title = t('Gallery2 URL Rewrite Module Auto-Configuration:');
-  $results['urlrewrite']['title'] = $title;
+  $image_frames = gallery_get_image_frames();
+  _gallery_block_options($type_map, $param_map);
+  
+  if (variable_get('gallery_block_grid_num', 1) > 1) {
+    $form['gallery_block_grid_'. $delta .'_blockid'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Block Identifier [Block @id]', array('@id' => $delta+1)),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_blockid', ''),
+      '#size' => 25,
+      '#maxlength' => 30,
+      '#description' => t('A short identifier to distinguish blocks of the same type. (Blocks are numbered by default)'),
+    );
+  }
+   
+  if ($plugin_status['imageblock'] == GALLERY_PLUGIN_ENABLED) {          
+    $form['gallery_block_grid_'. $delta .'_num_cols'] = array(
+      '#type' => 'select',
+      '#title' => t('Number of columns'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_num_cols', 2),
+      '#options' => _gallery_range_array(1, 5),
+      '#description' => t('Enter the number of columns in the grid.'),
+    );
+    
+    $form['gallery_block_grid_'. $delta .'_num_rows'] = array(
+      '#type' => 'select',
+      '#title' => t('Number of rows'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_num_rows', 2),
+      '#options' => _gallery_range_array(1, 5),
+      '#description' => t('Enter the number of rows in the grid.'),
+    );
+    
+    $form['gallery_block_grid_'. $delta .'_block_block'] = array(
+      '#type' => 'select',
+      '#title' => 'Image types',
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_block_block', 'randomImage'),
+      '#options' => $type_map,
+      '#description' => 'Pick the type of images you would like to see in the grid.',
+    );
+      
+    $form['gallery_block_grid_'. $delta .'_item_id'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Album or Item ID'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_item_id', ''),
+      '#size' => 20,
+      '#maxlength' => 20,
+      '#description' => t('Enter the Gallery image or album ID (or blank). If an album or item ID is specified, random
+                           images will only be selected from that album and its sub-albums. If \'user\' (or \'user:123\')
+                           is entered, items will be taken from the current (or specified) user\'s useralbum.')
+    );
+    
+    $form['gallery_block_grid_'. $delta .'_block_show'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Image data'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_block_show', array()),
+      '#options' =>  $param_map,
+      '#description' => t('Choose the item metadata you would like to display.'),
+    );
+    
+    $form['gallery_block_grid_'. $delta .'_size_method'] = array(
+      '#type' => 'select',
+      '#title' => t('Image size method'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_size_method', GALLERY_GRID_SIZE_METHOD_DEFAULT),
+      '#options' => array(
+        'maxsize' => t('Max Size'),
+        'exactsize' => t('Exact Size'),
+      ),
+      '#description' => t('\'Max Size\' gives faster image downloading, but the image size 
+                           may be smaller than the size defined below. <br />\'Exact Size\' may be slower
+                           (as a larger image is downloaded and then scaled by the browser) but the image
+                           will be guaranteed to be the size defined below. Only supported for G2.2+.'),
+    );  
+  
+    $form['gallery_block_grid_'. $delta .'_size'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image size'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_size', GALLERY_GRID_SIZE_DEFAULT),
+      '#size' => 10,
+      '#maxlength' => 10,
+      '#description' => t('Sets the size (in pixels) of the longest side of the image according
+                          to the method defined above.'),
+    );
+    
+    $form['gallery_block_grid_'. $delta .'_album_frame'] = array(
+      '#type' => 'select',
+      '#title' => t('Album frame'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_album_frame', 'none'),
+      '#options' => $image_frames,
+      '#description' => $imageframe_desc,
+    );
+    
+    $form['gallery_block_grid_'. $delta .'_item_frame'] = array(
+      '#type' => 'select',
+      '#title' => t('Item frame'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_item_frame', 'none'),
+      '#options' => $image_frames,
+      '#description' => $imageframe_desc,
+    );
+    
+    $form['gallery_block_grid_'. $delta .'_link_target'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Link target'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_link_target', ''),
+      '#size' => 20,
+      '#maxlength' => 20,
+      '#description' => t('Enter a link target (e.g. \'_blank\' to open in a new window).'),
+    );
 
-  list ($ret, $rewriteApi) = GalleryCoreApi::newFactoryInstance('RewriteApi');
-  if ($ret) {
-  /* G2 Error handling */
-  // All other tests were run already
-   $results['urlrewrite']['error'] = true;
-   $results['urlrewrite']['notice'] = t(
-                'Gallery2 Error when trying to access URL Rewrite Module status. @ret',
-                array('@ret' => $ret->getAsHtml()));
+    $form['gallery_block_grid_'. $delta .'_link'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image Link'),
+      '#default_value' => variable_get('gallery_block_grid_'. $delta .'_link', ''),
+      '#size' => 60,
+      '#maxlength' => 255,
+      '#description' => t('By default the image has a link to the item in the Gallery. This
+        can be overridden here (or leave empty for the default). Use \'none\' for no link, or a URL
+        to link somewhere else instead.'),
+    );
   }
-       list ($ret, $params) = $rewriteApi->fetchEmbedConfig();
+  
+  return $form;
+}
 
-       // Check if .htaccess exists.  If not and path is writable, create it.
-       // This should only occur for multi-site installs as the main drupal dir always has a .htaccess
-       if (!file_exists($htaccess_path . '.htaccess')) {
-    // Better to check for the file, not the dir as if not writable fopen returns a visible warning
-               if (is_writable($htaccess_path . '.htaccess')) {
-                       $f = fopen($htaccess_path . '.htaccess', 'w');
-                       fclose($f);
-               }       else {
-      $results['urlrewrite']['error'] = true;
-      $results['urlrewrite']['notice'] = t('There is no .htaccess file in your defined Drupal directory (@dir) and the directory is not writable. Please create a writable .htaccess file in that directory.', array('@dir' => $htaccess_path));
-      $num_errors++;
-      return array($num_errors, $num_warnings, $results['urlrewrite']);
+/**
+ * Function _gallery_settings_block_save().
+ */
+function _gallery_settings_block_save($delta, $form_values) {
+  // Validate variable values
+  if (isset($form_values['gallery_block_image_'. $delta .'_size'])) {
+    if (!is_numeric($form_values['gallery_block_image_'. $delta .'_size']) || $form_values['gallery_block_image_'. $delta .'_size'] < 10) {
+      $form_values['gallery_block_image_'. $delta .'_size'] = 10;
+      drupal_set_message(t('Image size must be a number greater than ten pixels. (The value has been updated to \'10\' for your convenience.)'), 'error');
     }
   }
+  if (isset($form_values['gallery_block_grid_'. $delta .'_size'])) {
+    if (!is_numeric($form_values['gallery_block_grid_'. $delta .'_size']) || $form_values['gallery_block_grid_'. $delta .'_size'] < 10) {
+      $form_values['gallery_block_grid_'. $delta .'_size'] = 10;
+      drupal_set_message(t('Image size must be a number greater than ten pixels. (The value has been updated to \'10\' for your convenience.)'), 'error');
+    }
+  }
+  // Save variables
+  foreach ($form_values as $key => $value) {
+    if (strpos($key, 'gallery_block_') == 0) {
+      if (is_array($value)) {
+        $value = array_values(array_filter($value));
+      }
+      variable_set($key, $value);
+    }
+  }
+}
+
+/**
+ * Function _gallery_settings_filter().
+ */
+function _gallery_settings_filter() {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_block.inc');
+  $plugin_status =  gallery_plugin_status(array('imageblock', 'imageframe'));
+  
+  $desc = t('Note that changing the defaults here will change the all the gallery filter images
+    on the site, not just new images. '); 
+  $desc .= t('The Gallery Filter requires the Gallery2 Image Block plugin (!imageblock_status) and
+              optionally the Gallery2 Image Frame plugin (!imageframe_status).',
+              array(
+                '!imageblock_status' => theme('gallery_plugin_status_message', $plugin_status['imageblock']),
+                '!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']),
+              ));
+  if ($plugin_status['imageblock'] != GALLERY_PLUGIN_ENABLED) {
+    $g2_uri = variable_get('gallery_embed_uri', '?q=gallery');
+    $g2_plugins_page = (variable_get('gallery_valid', 0)) ? 
+      t('<a href= "@g2_plugins">Gallery2 Plugins</a>',
+        array('@g2_plugins' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminModules'))
+      : t('Gallery2 Site Admin -> Plugins');
+    $desc .= t(' However the Image Block plugin is unavailable, so the Gallery Filter is
+      not available and the settings are disabled. To use the filter please go to
+      the !g2_plugins page and install/activate the Image Block plugin.',
+        array('!g2_plugins' => $g2_plugins_page));
+  }    
+
+  $imageframe_desc = ($plugin_status['imageframe'] != GALLERY_PLUGIN_ENABLED) ?
+    t('Requires the Gallery2 Image Frame plugin (!imageframe_status).',
+      array('!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']))) : '';
 
-       if (file_exists($htaccess_path . '.htaccess'))   {
-               if (is_writable($htaccess_path . '.htaccess')) {
+  $form['filter'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Gallery Filter settings'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#description' => $desc,
+  );
+  
+  $image_frames = gallery_get_image_frames();
+  _gallery_block_options($type_map, $param_map);
+  
+  if ($plugin_status['imageblock'] == GALLERY_PLUGIN_ENABLED) {          
+    $form['filter']['gallery_filter_prefix'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Filter prefix'),
+      '#default_value' => variable_get('gallery_filter_prefix', 'G2'),
+      '#size' => 10,
+      '#maxlength' => 10,
+      '#description' => t('Prefix to use with filter. Example: \'G2\' means you use [G2: 999].
+        Be careful when changing this as any pages using the previous prefix will not be changed
+        and so will not be filtered correctly.'),
+    );
+    
+    $form['filter']['gallery_filter_default_block_type'] = array(
+      '#type' => 'select',
+      '#title' => t('Default image type'),
+      '#default_value' => variable_get('gallery_filter_default_block_type', 'viewedImage'),
+      '#options' => $type_map,
+      '#description' => t('Pick the default type of image you would like to use.'),
+    );
+    
+    $form['filter']['gallery_filter_can_cache'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Cache gallery filter pages'),
+      '#default_value' => variable_get('gallery_filter_can_cache', 1),
+      '#description' => t('By default the gallery filter output is cached by Drupal to speed up page loading.
+                           However, it will not cache the css class info for the frames. The best approach is the
+                           make sure that the sidebar image block and the gallery filter images use the same frames.
+                           If you are unable to do this you will have to deselect this option to force Drupal not to
+                           cache the pages, or else your frames will not appear. If you change this option you will
+                           need to go to <a href="@link">admin/settings/filters</a> and re-save the image formats
+                           that use gallery filter.', array('@link' => url('admin/settings/filters'))),
+    );
+    
+    $form['filter']['gallery_filter_n_images'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default number of images'),
+      '#default_value' => variable_get('gallery_filter_n_images', 1),
+      '#size' => 3,
+      '#maxlength' => 3,
+      '#description' => t('How many images you want the default block to show.  Best to keep at 1 and use the n parameter.'),
+    );
+    
+    $form['filter']['gallery_filter_default_show'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Default image data'),
+      '#default_value' => variable_get('gallery_filter_default_show', array('none')),
+      '#options' => $param_map,
+      '#description' => t('Choose the item metadata you would like to display by default.  This will change all instances where show parameter was not specified.'),
+    );
+    
+    // parse gallery_filter.css and extract classes
+    $css = implode('', file(drupal_get_path('module', 'gallery') .'/gallery_filter.css'));
+    preg_match_all('/div.giImageBlock.(\w+) {/', $css, $matches);
+    if (count($matches[1])) {
+      $classes = array();
+      foreach ($matches[1] as $class) {
+        $classes[$class] = $class;
+      }
+      $form['filter']['gallery_filter_default_div_class'] = array(
+        '#type' => 'select',
+        '#title' => t('Default class'),
+        '#default_value' => variable_get('gallery_filter_default_div_class', 'nowrap'),
+        '#options' => $classes,
+      );
+    }
+    else {
+      $form['filter']['gallery_filter_default_div_class'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Default class'),
+        '#default_value' => variable_get('gallery_filter_default_div_class', 'nowrap'),
+        '#size' => 20,
+        '#maxlength' => 20,
+        '#description' => t('left, right, or nowrap. (See gallery_filter.css to add more or modify these.)'),
+      );
+    }
+    
+    $form['filter']['gallery_filter_default_maxsize'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default \'Max Size\' thumbnail size'),
+      '#default_value' => variable_get('gallery_filter_default_maxsize', GALLERY_FILTER_MAXSIZE_DEFAULT),
+      '#size' => 10,
+      '#maxlength' => 10,
+    );
+    
+    $form['filter']['gallery_filter_default_exactsize'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default \'Exact Size\' thumbnail size'),
+      '#default_value' => variable_get('gallery_filter_default_exactsize', GALLERY_FILTER_EXACTSIZE_DEFAULT),
+      '#size' => 10,
+      '#maxlength' => 10,
+      '#description' => t('If no size is specified when calling the filter, one of
+        these sizes (and implied method) will be used. <br />\'Max Size\' gives faster
+        image downloading, but the image size 
+        may be smaller than the size defined. <br />\'Exact Size\' may be slower
+        (as a larger image is downloaded and then scaled by the browser) but the image
+        will be guaranteed to be the size defined. Only supported for G2.2+.
+        Only fill in one size box (not both) to set the default method.'),
+    );
+    
+    $form['filter']['gallery_filter_default_album_frame'] = array(
+      '#type' => 'select',
+      '#title' => t('Default album frame'),
+      '#default_value' => variable_get('gallery_filter_default_album_frame', 'none'),
+      '#options' => $image_frames,
+      '#description' => $imageframe_desc,
+    );
+    
+    $form['filter']['gallery_filter_default_item_frame'] = array(
+      '#type' => 'select',
+      '#title' => t('Default item frame'),
+      '#default_value' => variable_get('gallery_filter_default_item_frame', 'none'),
+      '#options' => $image_frames,
+      '#description' => $imageframe_desc,
+    );
+    
+    $form['filter']['gallery_filter_default_link_target'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default link target'),
+      '#default_value' => variable_get('gallery_filter_default_link_target', ''),
+      '#size' => 20,
+      '#maxlength' => 20,
+      '#description' => t('Enter a link target (e.g. "_blank", "_new").'),
+    );
+    
+    $form['filter']['gallery_filter_default_link'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default Image Link'),
+      '#default_value' => variable_get('gallery_filter_default_link', ''),
+      '#size' => 20,
+      '#maxlength' => 20,
+      '#description' => t('By default the image has a link to the item in the Gallery. This
+        can be overridden here (or leave empty for the default). Use \'none\' for no link, or a URL
+        to link somewhere else instead.'),
+    );
+  }
+  
+  $form['array_filter'] = array('#type' => 'value');
+  // Include both #submit handlers so that the default system submit
+  // is also called to save all the variables.
+  $form['#submit']['_gallery_settings_filter_submit'] = array();
+  $form['#submit']['system_settings_form_submit'] = array();
+  return system_settings_form($form);
+}
 
-                       // Set the G2 rewrite Values
-                       $params['embeddedLocation'] = $public_path;
-                       $params['embeddedHtaccess'] = $htaccess_path;
+/**
+ * Function _gallery_settings_filter_validate().
+ */
+function _gallery_settings_filter_validate($form_id, $form_values) {
+  // Only validate if a setting was returned
+  if (isset($form_values['gallery_filter_default_maxsize'])) {
+    if ((strlen($form_values['gallery_filter_default_maxsize']) > 0) &&
+      (strlen($form_values['gallery_filter_default_exactsize']) > 0)) {
+      form_set_error('gallery_filter_default_maxsize',
+        t('You must set either the Max Size or the Exact Size, not both.'));  
+    } 
+    elseif ((strlen($form_values['gallery_filter_default_maxsize']) == 0) &&
+      (strlen($form_values['gallery_filter_default_exactsize']) == 0)) {
+      form_set_error('gallery_filter_default_maxsize',
+        t('You must set either the Max Size or the Exact Size.'));  
+    }
+    if ((strlen($form_values['gallery_filter_default_maxsize']) > 0) &&
+      (!is_numeric($form_values['gallery_filter_default_maxsize']) ||
+      $form_values['gallery_filter_default_maxsize'] < 1)) {
+      form_set_error('gallery_filter_default_maxsize',
+        t('Max Size must be a number greater than zero.'));
+    }
+    if ((strlen($form_values['gallery_filter_default_exactsize']) > 0) &&
+      (!is_numeric($form_values['gallery_filter_default_exactsize']) ||
+      $form_values['gallery_filter_default_exactsize'] < 1)) {
+      form_set_error('gallery_filter_default_exactsize',
+        t('Exact Size must be a number greater than zero.'));
+    }
+    if ((strlen($form_values['gallery_filter_n_images']) > 0) &&
+      (!is_numeric($form_values['gallery_filter_n_images']) ||
+      $form_values['gallery_filter_n_images'] < 1)) {
+      form_set_error('gallery_filter_n_images',
+        t('Number of images must be a number greater than zero.'));
+    }
+  }
+}
 
-                       // Save the G2 rewrite Values
-                       list ($ret, $code, $err) = $rewriteApi->saveEmbedConfig($params);
-                       if ($code != REWRITE_STATUS_OK) {
-                               list ($ret, $errstr) = $err;
-                               $errstr =  $code." - ".$errstr;
-        $results['urlrewrite']['error'] = true;
-        $results['urlrewrite']['notice'] = t('The Gallery2 URL Rewrite module returned the following error:') . '<pre>' . $errstr . '</pre>';
-        $num_errors++;
-                       } else {
-                   $results['urlrewrite']['success'] = true;
-                 }
-               } else {
-        $results['urlrewrite']['error'] = true;
-        $results['urlrewrite']['notice'] = t('The .htaccess file in your defined Drupal directory (@dir) is not writable. Please CHMOD it to 644 (or 666 if 644 does not work).', array('@dir' => $htaccess_path));
-        $num_errors++;
-                       }
-       }
-  return array($num_errors, $num_warnings, $results['urlrewrite']);
+/**
+ * Function _gallery_settings_filter_submit().
+ */
+function _gallery_settings_filter_submit($form_id, $form_values) {
+  // The default values have changed, so the pages containing the gallery filter need
+  // to be updated (or else it would only occur on an edit), so empty the filter cache.
+  
+  // Find out which formats are using the gallery filter
+  $result = db_query("SELECT format FROM {filters} WHERE module = 'gallery'");
+  while ($format = db_fetch_object($result)) {
+    cache_clear_all($format->format .':', 'cache_filter', TRUE);
+  }
+  
+  drupal_set_message('The gallery filter cache has been cleared so that the new defaults apply.');
 }
 
 /**
- * Validate the gallery g2image settings and saves the config file if needed.
+ * Function _gallery_settings_g2image().
  */
-function _gallery_g2image_settings_form_validate(&$form_values) {
+function _gallery_settings_g2image() {
+  $plugin_status =  gallery_plugin_status(array('imageblock'));
+
+  $desc = t('G2Image requires the Gallery2 Image Block plugin (!imageblock_status) and
+             the g2image application to be installed.',
+              array('!imageblock_status' => theme('gallery_plugin_status_message', $plugin_status['imageblock'])));
+  if ($plugin_status['imageblock'] != GALLERY_PLUGIN_ENABLED) {
+    $g2_uri = variable_get('gallery_embed_uri', '?q=gallery');
+    $g2_plugins_page = (variable_get('gallery_valid', 0)) ?
+      t('<a href= "@g2_plugins">Gallery2 Plugins</a>',
+        array('@g2_plugins' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminModules'))
+      : t('Gallery2 Site Admin -> Plugins');
+    $desc .= t(' However the Image Block plugin is unavailable, so G2Image is
+      not available and the settings are disabled. To use G2Image please go to
+      the !g2_plugins page and install/activate the Image Block plugin.', array(
+      '!g2_plugins' => $g2_plugins_page));
+  }
+
+  $form['g2image'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Gallery Image Assist (G2Image) settings'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#description' => $desc,
+  );
+
+  if ($plugin_status['imageblock'] == GALLERY_PLUGIN_ENABLED) {
+    $form['g2image']['gallery_g2image_mode'] = array(
+      '#type' => 'select',
+      '#title' => t('Mode'),
+      '#default_value' => variable_get('gallery_g2image_mode', 'disabled'),
+      '#options' => array(
+        'disabled' => t('Disabled'),
+        'standalone' => t('Standalone'),
+        'tinymce' => t('TinyMCE'),
+      ),
+      '#description' => t('Determines the mode of operation. For anything other than \'Disabled\' the g2image
+                           application has to be installed. See the INSTALL.txt instructions. In \'Standalone\'
+                           mode a button will be visible under textfields to launch the g2image window. In
+                           \'TinyMCE\' mode the g2image button can be used in the TinyMCE toolbar. Note that the
+                           TinyMCE version will NOT work wih Safari - use the standalone version instead.'),
+    );
+    
+    $form['g2image']['gallery_g2image_only_listed_pages'] = array(
+      '#type' => 'radios',
+      '#title' => t('Show g2image link on specific pages (Standalone mode only)'),
+      '#default_value' => variable_get('gallery_g2image_only_listed_pages', 1),
+      '#options' => array(
+        t('Show on every page except the listed pages.'),
+        t('Show on only the listed pages.')
+      )
+    );
+    
+    require_once(drupal_get_path('module', 'gallery') .'/gallery_help.inc');
+    $form['g2image']['gallery_g2image_std_pages'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Pages (Standalone mode only)'),
+      '#default_value' => variable_get('gallery_g2image_std_pages', gallery_help('admin/settings/gallery_g2image#pages')),
+      '#description' => t('Enter one page per line as Drupal paths. The \'*\' character is a wildcard. Example paths are
+                           \'%blog\' for the blog page and %blog-wildcard for every personal blog. %front is the front page.',
+                           array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'))
+    );
+    
+    $form['g2image']['gallery_g2image_sortby'] = array(
+      '#type' => 'select',
+      '#title' => t('Default Sort Order'),
+      '#default_value' => variable_get('gallery_g2image_sortby', 'title_asc'),
+      '#options' => array(
+        'title_asc' => t('Gallery2 Title (A-z)'),
+        'title_desc' => t('Gallery2 Title (z-A)'),
+        'name_asc' => t('Filename (A-z)'),
+        'name_desc' => t('Filename (z-A)'),
+        'mtime_desc' => t('Last Modification (newest first)'),
+        'mtime_asc' => t('Last Modification (oldest first)'),
+      ),
+      '#description' => t('Determines the default sorting order.'),
+    );
+    
+    $form['g2image']['gallery_g2image_images_per_page'] = array(
+      '#type' => 'select',
+      '#title' => t('Default Number of images per page'),
+      '#default_value' => variable_get('gallery_g2image_images_per_page', 20),
+      '#options' => _gallery_range_array(10, 60, 10),
+      '#description' => t('Choose the default number of images per page.'),
+    );
+    
+    $form['g2image']['gallery_g2image_display_filenames'] = array(
+      '#type' => 'select',
+      '#title' => t('Default Display Options'),
+      '#default_value' => variable_get('gallery_g2image_display_filenames', 'thumbnails'),
+      '#options' => array(
+        'thumbnails' => t('Thumbnails only'),
+        'filenames' => t('Thumbnails with title and filename'),
+      ),
+      '#description' => t('Choose the default display option for images.'),
+    );
+    
+    $form['g2image']['gallery_g2image_default_action'] = array(
+      '#type' => 'select',
+      '#title' => t('Default Action'),
+      '#default_value' => variable_get('gallery_g2image_default_action', 'drupal_g2_filter'),
+      '#options' => array(
+        'drupal_g2_filter' => t('Gallery Filter ID'),
+        'thumbnail_image' => t('Thumbnail with link to image'),
+        'thumbnail_album' => t('Thumbnail with link to parent album'),
+        'thumbnail_custom_url' => t('Thumbnail with link to custom URL'),
+        'thumbnail_only' => t('Thumbnail only'),
+        'link_image' => t('Text link to image'),
+        'link_parent' => t('Text link to parent album'),
+      ),
+      '#description' => t('Choose the default method of inserting the image info.'),
+    );
+    
+    $form['g2image']['gallery_g2image_custom_url'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default custom url'),
+      '#default_value' => variable_get('gallery_g2image_custom_url', 'http://'),
+      '#size' => 50,
+      '#maxlength' => 50,
+      '#description' => t('The default custom url. Used with \'Thumbnail with link to custom URL\' action setting'),
+    );
+    
+    $css_options =  array(
+      'none' => t('None'),
+      'g2image_normal' => t('Normal'),
+      'g2image_float_left' => t('Float Left'),
+      'g2image_float_right' => t('Float Right'),
+      'g2image_centered' => t('Centered'),
+    );
+
+    // Merge in custom class options
+    $gallery_g2image_custom_class = array_filter(variable_get('gallery_g2image_custom_class', array()));
+    $css_options = array_merge($css_options, drupal_map_assoc($gallery_g2image_custom_class));
+    
+    $form['g2image']['gallery_g2image_default_alignment'] = array(
+      '#type' => 'select',
+      '#title' => t('Default Alignment'),
+      '#default_value' => variable_get('gallery_g2image_default_alignment', 'none'),
+      '#options' => $css_options,
+      '#description' => t('Choose the default alignment of images.'),
+    );
+  
+    $form['g2image']['gallery_g2image_custom_class'] = array('#tree' => TRUE);
+    for ($i=1; $i<=4; $i++) {
+      $form['g2image']['gallery_g2image_custom_class'][$i] = array(
+        '#type' => 'textfield',
+        '#title' => t('Custom Class @index', array('@index' => $i)),
+        '#default_value' => isset($gallery_g2image_custom_class[$i]) ? $gallery_g2image_custom_class[$i] : '',
+        '#size' => 20,
+        '#maxlength' => 50,
+      );
+    }
+    $form['g2image']['gallery_g2image_custom_class'][$i-1]['#description'] = t('Additional css classes to be available for selection (must be defined in .css file).');
+  
+    $form['g2image']['gallery_g2image_class_mode'] = array(
+      '#type' => 'select',
+      '#title' => t('Alignment Class Insertion Point'),
+      '#default_value' => variable_get('gallery_g2image_class_mode', 'img'),
+      '#options' => array(
+        'img' => t('<img class=...>'),
+        'div' => t('<div class=...><img ...>'),
+      ),
+      '#description' => t('Determines where the alignment class will be inserted. If you choose \'&lt;div
+                           class=...&gt;&lt;img ...&gt;\', you will have to manually delete any &lt;div&gt; tags
+                           manually after deleting images from the TinyMCE window.'),
+    );
+  }
+  
+  $form['#validate']['_gallery_g2image_settings_validate'] = array();
+  return system_settings_form($form);
+}
+
+/**
+ * Function _gallery_g2image_settings_validate().
+ * (saves the G2Image config file)
+ */
+function _gallery_g2image_settings_validate($form_id, $form_values) {
   switch ($form_values['gallery_g2image_mode']) {
     case 'tinymce':
       $mode = t('TinyMCE');
@@ -989,31 +1021,30 @@ function _gallery_g2image_settings_form_validate(&$form_values) {
       $path = drupal_get_path('module', 'gallery');
       $path .= '/g2image';
       break;
-    default: 
-      return array(0, 0, array());
+    default:
+      return;
   }
-  $title = 'Gallery2 Image Assist (g2image) Status:';
+
   // Note that file_check_directory uses &$path and will strip the trailing '/'
-  $filename = $path . '/config.php';
-  if (is_writable($filename) == false && !file_check_directory($path)) {
-    $results['gallery_g2image']['title'] = $title;
-    $results['gallery_g2image']['warning'] = true;       
-    $results['gallery_g2image']['notice'] = t('g2image does not seem to be installed for @mode mode in the required directory (@dir), or the directory is not writable. Please see the INSTALL.txt for instructions.', array('@mode' => $mode, '@dir' => '&lt;drupal_path&gt;'.$path));
-    $num_warnings++;
-    return array($num_errors, $num_warnings, $results['gallery_g2image']);    
-  }  
+  $filename = $path .'/config.php';
+  if (is_writable($filename) == FALSE && !file_check_directory($path)) {
+    form_set_error('', t('G2Image does not seem to be installed for @mode mode in the required directory (@dir), or the
+                          directory is not writable. Please see the INSTALL.txt for instructions.',
+                            array('@mode' => $mode, '@dir' => '<drupal_path>/'. $path)));
+    return;
+  }
+
   $cr = "\n";
-  $g2ic_gallery2_path = $form_values['gallery_dir'];
-  $g2ic_use_full_path = (substr($g2ic_gallery2_path, 0, 1) == '/') ? 'TRUE' : 'FALSE';
-  $form_values['gallery_g2image_custom_url'] = 
-    check_url($form_values['gallery_g2image_custom_url']);
-  $g2ic_display_filenames =  ($form_values['gallery_g2image_display_filenames'] == 'filenames') ?
+  $g2ic_gallery2_path = str_replace('\\', '/', variable_get('gallery_dir', './gallery2/'));
+  $g2ic_use_full_path = (substr($g2ic_gallery2_path, 0, 1) == '/' || substr($g2ic_gallery2_path, $_SERVER['DOCUMENT_ROOT']) !== FALSE) ?
     'TRUE' : 'FALSE';
+  $form_values['gallery_g2image_custom_url'] = check_url($form_values['gallery_g2image_custom_url']);
+  $g2ic_display_filenames =  ($form_values['gallery_g2image_display_filenames'] == 'filenames') ? 'TRUE' : 'FALSE';
   $g2ic_custom_class = array();
   foreach ($form_values['gallery_g2image_custom_class'] as $key => $value) {
     $g2ic_custom_class[$key] = ($value) ? $value : 'not_used';
   }
-  
+
   $g2ic_custom_class_1 = ($form_values['gallery_g2image_custom_class_1']) ?
     $form_values['gallery_g2image_custom_class_1'] : 'not_used';
   $g2ic_custom_class_2 = ($form_values['gallery_g2image_custom_class_2']) ?
@@ -1022,59 +1053,491 @@ function _gallery_g2image_settings_form_validate(&$form_values) {
     $form_values['gallery_g2image_custom_class_3'] : 'not_used';
   $g2ic_custom_class_4 = ($form_values['gallery_g2image_custom_class_4']) ?
     $form_values['gallery_g2image_custom_class_4'] : 'not_used';
-  
-  $content = '<?php' .$cr;
-  $content .= '//  Configuration File for Gallery 2 Image Chooser for TinyMCE' . $cr;
-  $content .= '//  Version 2.0 RC4 and above' . $cr;
-  $content .= '//  By Kirk Steffensen - http://g2image.steffensenfamily.com/' . $cr;
-  $content .= '//  Released under the GPL version 2.' . $cr;
-  $content .= '//  A copy of the license is in the root folder of this plugin.' . $cr;
-  $content .= $cr . '//  Automatically generated by gallery.module (admin/settings/gallery).' . $cr;
-  $content .= '//  DO NOT EDIT' . $cr;
-  $content .= '$g2ic_image_ext_regex = \'' . $form_values['gallery_g2image_regex'] . '\';' . $cr;
-  $content .= '$g2ic_gallery2_path = \'' . $g2ic_gallery2_path . '\';' . $cr;
-  $content .= '$g2ic_embedded_mode = TRUE;' . $cr;
-  $content .= '$g2ic_use_full_path = ' . $g2ic_use_full_path. ';' . $cr;
-  $content .= '$g2ic_gallery2_uri = \'' .  $form_values['gallery_uri'] . '\';' . $cr;
-  $content .= '$g2ic_embed_uri = \'' . $form_values['gallery_embed_uri'] . '\';' . $cr;
-  $content .= '$g2ic_drupal_g2_filter = TRUE;' . $cr;
-  $content .= '$g2ic_drupal_g2_filter_prefix = \'' . $form_values['gallery_filter_prefix'] . '\';' . $cr;
-  $content .= '$g2ic_language = \'en\';' . $cr;
-  $content .= '$g2ic_images_per_page = ' . $form_values['gallery_g2image_images_per_page'] . ';' . $cr;
-  $content .= '$g2ic_display_filenames = ' . $g2ic_display_filenames . ';' . $cr;
-  $content .= '$g2ic_default_alignment = \'' . $form_values['gallery_g2image_default_alignment'] . '\';' . $cr;
-  $content .= '$g2ic_custom_class_1 = \'' . $g2ic_custom_class[1] . '\';' . $cr;
-  $content .= '$g2ic_custom_class_2 = \'' . $g2ic_custom_class[2] . '\';' . $cr;
-  $content .= '$g2ic_custom_class_3 = \'' . $g2ic_custom_class[3] . '\';' . $cr;
-  $content .= '$g2ic_custom_class_4 = \'' . $g2ic_custom_class[4] . '\';' . $cr;
-  $content .= '$g2ic_class_mode = \'' . $form_values['gallery_g2image_class_mode'] . '\';' . $cr;
-  $content .= '$g2ic_click_mode = \'' . $form_values['gallery_g2image_click_mode'] . '\';' . $cr;
-  $content .= '$g2ic_click_mode_variable = ' . $form_values['gallery_g2image_click_mode_variable'] . ';' . $cr;
-  $content .= '$g2ic_default_action = \'' . $form_values['gallery_g2image_default_action'] . '\';' . $cr;
-  $content .= '$g2ic_sortby = \'' . $form_values['gallery_g2image_sortby'] . '\';' . $cr;
-  $content .= '$g2ic_custom_url = \'' . $form_values['gallery_g2image_custom_url'] . '\';' . $cr;
-  $content .= '?>' . $cr;
 
-  $filename = $path . '/config.php';
-  if (is_writable($filename) == false) {
-    $results['gallery_g2image']['title'] = $title;
-    $results['gallery_g2image']['warning'] = true;       
-    $results['gallery_g2image']['notice'] = t('Could not write to g2image config file. Please check the permissions for @filename.', array('@filename' => $filename));
-    $num_warnings++;
-    return array($num_errors, $num_warnings, $results['gallery_g2image']);   
+  $content = '<?php'. $cr;
+  $content .= '/*'. $cr;
+  $content .= '    Gallery 2 Image Chooser'. $cr;
+  $content .= '    Version 3.0 - updated 16 SEP 2007'. $cr;
+  $content .= '    Documentation: http://g2image.steffensenfamily.com/'. $cr;
+  $content .= $cr;
+  $content .= '    Author: Kirk Steffensen with inspiration, code snippets,'. $cr;
+  $content .= '        and assistance as listed in CREDITS.HTML'. $cr;
+  $content .= $cr;
+  $content .= '    Released under the GPL version 2.'. $cr;
+  $content .= '    A copy of the license is in the root folder of this plugin.'. $cr;
+  $content .= $cr;
+  $content .= '    See README.HTML for installation info.'. $cr;
+  $content .= '    See CHANGELOG.HTML for a history of changes.'. $cr;
+  $content .= '*/'. $cr;
+  $content .= $cr;
+  $content .= '//  Automatically generated by gallery.module (admin/settings/gallery/g2image).'. $cr;
+  $content .= '//  DO NOT EDIT'. $cr;
+  $content .= $cr;
+
+  $content .= '$g2ic_embedded_mode = TRUE;'. $cr;
+  $content .= '$g2ic_gallery2_path = \''. $g2ic_gallery2_path .'\';'. $cr;
+  $content .= '$g2ic_use_full_path = '. $g2ic_use_full_path .';'. $cr;
+  $content .= '$g2ic_gallery2_uri = \''.  variable_get('gallery_uri', '/gallery2/') .'\';'. $cr;
+  $content .= '$g2ic_embed_uri = \''. variable_get('gallery_embed_uri', '?q=gallery') .'\';'. $cr;
+
+  $content .= '$g2ic_drupal_g2_filter = TRUE;'. $cr;
+  $content .= '$g2ic_drupal_g2_filter_prefix = \''. variable_get('gallery_filter_prefix', 'G2') .'\';'. $cr;
+
+  $content .= '$g2ic_language = \'en\';'. $cr;
+  $content .= '$g2ic_images_per_page = '. $form_values['gallery_g2image_images_per_page'] .';'. $cr;
+  $content .= '$g2ic_display_filenames = '. $g2ic_display_filenames .';'. $cr;
+
+  $content .= '$g2ic_default_alignment = \''. $form_values['gallery_g2image_default_alignment'] .'\';'. $cr;
+  $content .= '$g2ic_custom_class_1 = \''. $g2ic_custom_class[1] .'\';'. $cr;
+  $content .= '$g2ic_custom_class_2 = \''. $g2ic_custom_class[2] .'\';'. $cr;
+  $content .= '$g2ic_custom_class_3 = \''. $g2ic_custom_class[3] .'\';'. $cr;
+  $content .= '$g2ic_custom_class_4 = \''. $g2ic_custom_class[4] .'\';'. $cr;
+  $content .= '$g2ic_class_mode = \''. $form_values['gallery_g2image_class_mode'] .'\';'. $cr;
+
+  $content .= '$g2ic_default_action = \''. $form_values['gallery_g2image_default_action'] .'\';'. $cr;
+  $content .= '$g2ic_sortby = \''. $form_values['gallery_g2image_sortby'] .'\';'. $cr;
+  $content .= '$g2ic_custom_url = \''. $form_values['gallery_g2image_custom_url'] .'\';'. $cr;
+  $content .= $cr;
+  $content .= '?>'. $cr;
+
+  $filename = $path .'/config.php';
+  if (is_writable($filename) == FALSE) {
+    form_set_error('', t('Could not write to G2Image config file. Please check the permissions for @filename.',
+                            array('@filename' => $filename)));
+    return;
   }
   $handle = fopen($filename, "w");
   if (fwrite($handle, $content) === FALSE) {
-    $results['gallery_g2image']['title'] = $title;
-    $results['gallery_g2image']['warning'] = true;       
-    $results['gallery_g2image']['notice'] = t('Could not write to g2image config file. Please check the permissions for @filename.', array('@filename' => $filename));
-    $num_warnings++;
-     return array($num_errors, $num_warnings, $results['gallery_g2image']);    
-  } else {
-    $results['gallery_g2image']['title'] = $title;
-    $results['gallery_g2image']['success'] = true;
-  }  
-   fclose($handle);
-   return array($num_errors, $num_warnings, $results['gallery_g2image']);
+    form_set_error('', t('Could not write to G2Image config file. Please check the permissions for @filename.',
+                            array('@filename' => $filename)));
+    return;
+  }
+  else {
+    drupal_set_message(t('G2Image configuration file successfully created.'));
+  }
+  fclose($handle);
+}
+
+/**
+ * Function _gallery_settings_search().
+ */
+function _gallery_settings_search() {
+  require_once(drupal_get_path('module', 'gallery') .'/gallery_block.inc');
+  $plugin_status =  gallery_plugin_status(array('imageblock', 'imageframe', 'search'));
+
+  $search_desc = t('The Gallery Search requires the Gallery2 Search plugin (!search_status) and
+    optionally the Gallery2 Image Block plugin (!imageblock_status) and Gallery2 Image Frame 
+    plugin (!imageframe_status).',
+      array(
+        '!search_status' => theme('gallery_plugin_status_message', $plugin_status['search']), 
+        '!imageblock_status' => theme('gallery_plugin_status_message', $plugin_status['imageblock']), 
+        '!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']),
+      )
+    );
+  $g2_uri = variable_get('gallery_embed_uri', '?q=gallery');
+  $g2_plugins_page = (variable_get('gallery_valid', 0)) ? 
+    t('<a href= "@g2_plugins">Gallery2 Plugins</a>',
+      array('@g2_plugins' => $g2_uri .'&g2_view=core.SiteAdmin&g2_subView=core.AdminModules'))
+    : t('Gallery2 Site Admin -> Plugins');
+  $thumbs_desc = '';
+  if ($plugin_status['search'] != GALLERY_PLUGIN_ENABLED) {
+    $search_desc .= t(' However the Search plugin is unavailable, so the search is
+      not available and these settings are disabled. To use the search feature please go to
+      the !g2_plugins page and install/activate the Image Block plugin.',
+        array('!g2_plugins' => $g2_plugins_page));
+  }   
+  if ($plugin_status['imageblock'] != GALLERY_PLUGIN_ENABLED) {
+    $thumbs_desc = t('To display search results with thumbnail images requires the Gallery2 Image
+      Block plugin (!imageblock_status) and optionally the  and Gallery2 Image Frame 
+      plugin (!imageframe_status).',
+        array(
+          '!imageblock_status' => theme('gallery_plugin_status_message', $plugin_status['imageblock']), 
+          '!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']),
+        )
+      );
+    $thumbs_desc .= t(' However the Image Block plugin is unavailable, so the thumbnails are
+      not available and these settings are disabled. To use this feature please go to
+      the !g2_plugins page and install/activate the Image Block plugin.',
+        array('!g2_plugins' => $g2_plugins_page));
+  }    
+
+  $imageframe_desc = ($plugin_status['imageframe'] != GALLERY_PLUGIN_ENABLED) ?
+    t('Requires the Gallery2 Image Frame plugin (!imageframe_status).',
+        array('!imageframe_status' => theme('gallery_plugin_status_message', $plugin_status['imageframe']))) : '';
+     
+  $form['search'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Search settings'),
+    '#collapsible' => FALSE,
+    '#collapsed' => FALSE,
+    '#description' => $search_desc,
+  );
+  
+  $image_frames = gallery_get_image_frames();
+  _gallery_block_options($type_map, $param_map);
+  
+  if ($plugin_status['search'] == GALLERY_PLUGIN_ENABLED) {          
+    $form['search']['gallery_search_advanced'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display advanced search options'),
+      '#default_value' => variable_get('gallery_search_advanced', 1),
+      '#description' => t('Adds options to the search form to select which Gallery fields to search in.'),
+    );
+    
+    $form['search']['gallery_search_num_per_row'] = array(
+      '#type' => 'select',
+      '#title' => t('Number of search results per table row'),
+      '#default_value' => variable_get('gallery_search_num_per_row', 3),
+      '#options' => _gallery_range_array(1, 5),
+      '#description' => t('Select the number of search results per row in the paged table.'),
+    );
+    
+    $form['search']['gallery_search_rows_per_pager'] = array(
+      '#type' => 'select',
+      '#title' => t('Number of rows per page'),
+      '#default_value' => variable_get('gallery_search_rows_per_pager', 4),
+      '#options' => _gallery_range_array(1, 10),
+      '#description' => t('Select the number of rows in the paged table.'),
+    );
+    
+    $form['search']['thumbs'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Search thumbnail settings'),
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+      '#description' => $thumbs_desc,
+    );
+    
+    if ($plugin_status['imageblock'] == GALLERY_PLUGIN_ENABLED) {          
+      $form['search']['thumbs']['gallery_search_show_thumbs'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Display thumbnails'),
+        '#default_value' => variable_get('gallery_search_show_thumbs', 1),
+        '#description' => t('Display thumbnail images for the search results.'),
+      );
+      
+      $form['search']['thumbs']['gallery_search_block_show'] = array(
+        '#type' => 'checkboxes',
+        '#title' => t('Image data'),
+        '#default_value' => variable_get('gallery_search_block_show', array('title' => t('Title'))),
+        '#options' => $param_map,
+        '#description' => t('Choose the item metadata you would like to display.'),
+        );
+        
+      $form['search']['thumbs']['gallery_search_size_method'] = array(
+        '#type' => 'select',
+        '#title' => t('Image size method'),
+        '#default_value' => variable_get('gallery_search_size_method', GALLERY_SEARCH_SIZE_METHOD_DEFAULT),
+        '#options' => array(
+          'maxsize' => t('Max Size'),
+          'exactsize' => t('Exact Size'),
+        ),
+        '#description' => t('\'Max Size\' gives faster image downloading, but the image size 
+          may be smaller than the size defined below. <br />\'Exact Size\' may be slower
+          (as a larger image is downloaded and then scaled by the browser) but the image
+          will be guaranteed to be the size defined below. Only supported for G2.2+.'),
+      );  
+    
+      $form['search']['thumbs']['gallery_search_size'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Image size'),
+        '#default_value' => variable_get('gallery_search_size', GALLERY_SEARCH_SIZE_DEFAULT),
+        '#size' => 10,
+        '#maxlength' => 10,
+        '#description' => t('Sets the size (in pixels) of the longest side of the image
+          according to the method defined above.'),
+      );
+       
+      $form['search']['thumbs']['gallery_search_album_frame'] = array(
+        '#type' => 'select',
+        '#title' => t('Album frame'),
+        '#default_value' => variable_get('gallery_search_album_frame', 'none'),
+        '#options' => $image_frames,
+        '#description' => $imageframe_desc,
+      );
+      
+      $form['search']['thumbs']['gallery_search_item_frame'] = array(
+        '#type' => 'select',
+        '#title' => t('Item frame'),
+        '#default_value' => variable_get('gallery_search_item_frame', 'none'),
+        '#options' => $image_frames,
+        '#description' => $imageframe_desc,
+      );
+      
+      $form['search']['thumbs']['gallery_search_link_target'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Link target'),
+        '#default_value' => variable_get('gallery_search_link_target', ''),
+        '#size' => 20,
+        '#maxlength' => 20,
+        '#description' => t('Enter a link target (e.g. "_blank", "_new").'),
+      );
+      
+      $form['search']['thumbs']['gallery_search_default_link'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Image Link'),
+        '#default_value' => variable_get('gallery_search_default_link', ''),
+        '#size' => 20,
+        '#maxlength' => 20,
+        '#description' => t('By default the image has a link to the item in the Gallery. This
+          can be overridden here (or leave empty for the default). Use \'none\' for no link, or a
+          URL to link somewhere else instead.'),
+      );
+    }
+  }
+  
+  $form['array_filter'] = array('#type' => 'value');
+  return system_settings_form($form);
+}
+
+/**
+ * Function _gallery_settings_search_validate().
+ */
+function _gallery_settings_search_validate($form_id, $form_values) {
+  if (isset($form_values['gallery_search_size']) && 
+    (!is_numeric($form_values['gallery_search_size']) || $form_values['gallery_search_size'] < 1)) {
+    form_set_error('gallery_search_size',
+      t('Image size must be a number greater than zero.'));
+  }
+}
+
+/**
+ * Function _gallery_range_array().
+ * (create an associative range array
+ *  like array($min=>$min, ..., $max=>$max))
+ */
+function _gallery_range_array($min, $max, $interval = 1) {
+  $range_array = array();
+  for ($i=$min; $i<=$max; $i+=$interval) {
+    $range_array[$i] = $i;
+  }
+
+  return $range_array;
+}
+
+/**
+ * Function _gallery_php_mem_check().
+ * (check the amount of PHP memory)
+ */
+function _gallery_php_mem_check($min_memory = 24) {
+  $mem_limit = trim(ini_get('memory_limit'));
+  $mem_limit_bytes = parse_size($mem_limit);
+  
+  if (empty($mem_limit)) {
+    return array(
+      'status' => TRUE,
+      'info' => t('There is no memory limit restricting your PHP installation.'),
+    );
+  }
+  elseif (($mem_limit_bytes / (1024 * 1024)) < $min_memory) {
+    return array(
+      'status' => FALSE,
+      'info' => t('Your PHP is configured to limit the memory to @mem_limit
+        (memory_limit parameter in php.ini). You must raise this limit 
+        to at least @min_mem_limitM for proper embedded Gallery2 operation.',
+        array(
+          '@mem_limit' => $mem_limit, 
+          '@min_mem_limit' => $min_memory,
+        )
+      )
+    );
+  } 
+  else {
+    return array(
+      'status' => TRUE,
+      'info' => t('Your PHP is configured to limit the memory to @mem_limit
+        (memory_limit parameter in php.ini). This should be fine for embedded Gallery2 operation.',
+        array(
+          '@mem_limit' => $mem_limit, 
+        )
+      )
+    );
+  }
+}
+
+/**
+ * Function gallery_wanted_plugin_info().
+ */
+function gallery_wanted_plugin_info() {
+  return array(
+    'imageblock' => array(
+      'title' => 'Image Block',
+      'info' => t('Allows images to be included in the Drupal sidebar or in nodes.'),
+      'severity' => GALLERY_SEVERITY_ERROR,
+      'status' => gallery_single_plugin_status('imageblock'),
+    ),
+    'imageframe' => array(
+      'title' => 'ImageFrame',
+      'info' => t('Provides a variety of frames around the images.'),
+      'severity' => GALLERY_SEVERITY_WARNING,
+      'status' => gallery_single_plugin_status('imageframe'),
+    ),
+    'search' => array(
+      'title' => 'Search',
+      'info' => t('Allow the Drupal search to also search the Gallery.'),
+      'severity' => GALLERY_SEVERITY_WARNING,
+      'status' => gallery_single_plugin_status('search'),
+    ),
+    'rewrite' => array(
+      'title' => 'URL Rewrite',
+      'info' => t('Allow short URLs (clean URLs).'),
+      'severity' => GALLERY_SEVERITY_ADVISE,
+      'status' => gallery_single_plugin_status('rewrite'),
+    ),
+  );
+}
+
+/**
+ * Function gallery_unwanted_plugin_info().
+ */
+function gallery_unwanted_plugin_info() {
+  return array(
+    'register' => array(
+      'title' => 'Registration',
+      'info' => t('All user registration must take place via Drupal to ensure that the users
+        are synchronized between Drupal and Gallery2. This plugin would allow a user to register
+        only in Gallery2 and not in Drupal and so should not be used.'),
+      'severity' => GALLERY_SEVERITY_WARNING,
+      'status' => gallery_single_plugin_status('register'),
+    ),
+  ); 
+}
+
+/**
+ * Function gallery_wanted_module_info().
+ */
+function gallery_wanted_module_info() {
+  return array(
+    'gsitemap' => array(
+      'title' => 'Google Sitemap',
+      'status' => module_exists('gsitemap'),
+      'severity' => GALLERY_SEVERITY_ADVISE,
+      'info' => t('Allows the Drupal and Gallery2 Google Sitemaps to be merged which allows for
+               a single sitemap to be sent to Google (and other web search sites).'),
+    ),
+    'profile' => array(
+      'title' => 'Profile',
+      'status' => module_exists('profile'),
+      'severity' => GALLERY_SEVERITY_ADVISE,
+      'info' => t('Allows support of the \'Full Name\' field in Gallery2.'),
+    ),
+  );
+}
+
+/**
+ * Function gallery_plugin_set_status().
+ */
+function gallery_plugin_set_status($plugin_names) {
+  $plugins_status = gallery_plugin_status($plugin_names);
+  $plugin_info = gallery_wanted_plugin_info();
+  // Generate array containing module status
+  $status = array();
+  foreach ($plugins_status as $plugin => $plugin_status) {
+    if ($plugin_status == GALLERY_PLUGIN_ENABLED) {
+      $status[$plugin] = '';
+    }
+    else {
+      $status[$plugin]['title'] = t('Gallery2 plugin \'@plugin\' is not available',
+        array('@plugin' => isset($plugin_info[$plugin]) ? $plugin_info[$plugin]['title'] : drupal_ucfirst($plugin)));
+      $status[$plugin]['severity'] = isset($plugin_info[$plugin]['severity']) ? $plugin_info[$plugin]['severity'] : GALLERY_SEVERITY_WARNING;
+      $status[$plugin]['url'] = url('admin/settings/gallery/install', NULL, $plugin);
+    }
+  }
+  gallery_set_status($status);
+}
+
+/**
+ * Function gallery_format_status().
+ */
+function gallery_format_status($status = array(), $title = 'Gallery message(s):') {
+  $message = $title .'<ul>';
+  if (count($status)) {
+    foreach ($status as $item) {
+      $message .= '<li>';
+      $message .= empty($item['url']) ? t($item['title']) : '<a href="'. $item['url'] .'">'. t($item['title']) .'</a>';
+      $message .= (isset($item['info']) && !empty($item['info'])) ? (': '. t($item['info'])) : '';
+      $message .= isset($item['severity'])  ? (' ['. theme('gallery_severity_message', $item['severity']) .']') : '';
+      $message .= '</li>';
+    }
+  }
+  else {
+    $message = t('Status not available');
+  }
+  $message .= '</ul>';
+  
+  return $message;
+}
+
+/**
+ * Theme function : theme_gallery_module_status_message().
+ */
+function theme_gallery_module_status_message($status) {
+  if ($status) {
+    return '<span class="admin-enabled">'. t('enabled') .'</span>';
+  } 
+  else {
+    return '<span class="admin-disabled">'. t('disabled') .'</span>';
+  }
+}
+
+/**
+ * Theme function : theme_gallery_severity_message().
+ */
+function theme_gallery_severity_message($severity = NULL) {
+  switch ($severity) {
+    case GALLERY_SEVERITY_SUCCESS:
+      return '<span class=\'g2_embed_success\'>'. t('OK') .'</span>';
+    case GALLERY_SEVERITY_ERROR:
+      return '<span class=\'g2_embed_error\'>'. t('Error') .'</span>';
+    case GALLERY_SEVERITY_WARNING:
+      return '<span class=\'g2_embed_warning\'>'. t('Warning') .'</span>';
+    case GALLERY_SEVERITY_ADVISE:
+      return '<span class=\'g2_embed_warning\'>'. t('Advisory') .'</span>';
+    case GALLERY_SEVERITY_UNKNOWN:
+      return '<span class=\'g2_embed_warning\'>'. t('Unknown') .'</span>';
+    default:
+  }      
+}
+
+/**
+ * Theme function : theme_gallery_plugin_status_message().
+ */
+function theme_gallery_plugin_status_message($status, $invert = FALSE) {
+  $classes = array('enabled' => 'admin-enabled', 'disabled' => 'admin-disabled');
+  if ($invert) {
+    $classes = array_reverse($classes, TRUE);
+  }
+
+  switch ($status) {
+    case GALLERY_PLUGIN_ENABLED:
+      return '<span class="'. $classes['enabled'] .'">'. t('activated') .'</span>';
+    case GALLERY_PLUGIN_DISABLED:
+      return '<span class="'. $classes['disabled'] .'">'. t('disabled') .'</span>';
+    case GALLERY_PLUGIN_NOT_ACTIVE:
+      return '<span class="'. $classes['disabled'] .'">'. t('deactivated') .'</span>';
+    case GALLERY_PLUGIN_NOT_INSTALLED:
+      return '<span class="'. $classes['disabled'] .'">'. t('not installed') .'</span>';
+    case GALLERY_PLUGIN_MISSING:
+      return '<span class="'. $classes['disabled'] .'">'. t('missing') .'</span>';
+    case GALLERY_PLUGIN_STATUS_UNKNOWN:
+    default:
+      return '<span class="'. $classes['disabled'] .'">'. t('unknown') .'</span>';
+  }
+}
+
+/**
+ * Theme function : theme_gallery_severity_status_message().
+ */
+function theme_gallery_severity_status_message($severity, $status, $full_msg = FALSE, $invert = FALSE) {
+  // In some cases (e.g. unwanted plugins) it makes sense to return the full 2 part message
+  // even on a success, but in most cases a simple "OK" is sufficient.
+  if ($full_msg) {
+    return theme('gallery_severity_message', $severity) .' ('. theme('gallery_plugin_status_message', $status, $invert) .')';
+  }
+  switch ($severity) {
+    case GALLERY_SEVERITY_SUCCESS:
+      return theme('gallery_severity_message', $severity);
+    default:
+      return theme('gallery_severity_message', $severity) .' ('. theme('gallery_plugin_status_message', $status, $invert) .')';
+  }
 }
-?>
index d9afe41..d538a50 100644 (file)
 <?php
 // $Id$
 
+require_once(drupal_get_path('module', 'gallery') .'/gallery_groups.inc');
+
 /**
  * gallery.module : gallery_user.inc
- * User Modification Functions (create, update, delete...)
+ * User Functions (insert, update, delete, view, details, ...)
  */
+define(GALLERY_MAP_UNKNOWN,                             0);
+define(GALLERY_MAP_USER_EXISTS,                         1);
+define(GALLERY_MAP_USER_EXISTS_BUT_NEEDS_MAPPING,       2);
+define(GALLERY_MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED,   3);
+define(GALLERY_MAP_USER_DOES_NOT_EXIST,                 4);
 
-define("G2_USER_EXISTS", 1);
-define("G2_USER_EXISTS_BUT_NEEDS_MAPPING", 2);
-define("G2_USER_DOES_NOT_EXIST_BUT_IS_MAPPED", 3);
-define("G2_USER_DOES_NOT_EXIST", 4);
+define(GALLERY_USERINFO_NOERROR,                        1);
+define(GALLERY_USERINFO_ERROR,                          2);
+define(GALLERY_USERINFO_ERROR_MISSING,                  3);
+define(GALLERY_USERINFO_ERROR_USERNAME,                 4);
+define(GALLERY_USERINFO_ERROR_FULLNAME,                 5);
+define(GALLERY_USERINFO_ERROR_FULLNAME_MISSING,         6);
+define(GALLERY_USERINFO_ERROR_EMAIL,                    7);
+define(GALLERY_USERINFO_ERROR_PASSWORD,                 8);
+define(GALLERY_USERINFO_ERROR_HASHMETHOD,               9);
+define(GALLERY_USERINFO_ERROR_GROUPS,                  10);
 
-$path = drupal_get_path('module', 'gallery');
-require_once($path . '/gallery_roles.inc');
+define(GALLERY_IMPORT_CONFLICT_DUPLICATE,               1);
+define(GALLERY_IMPORT_CONFLICT_INVALID,                 2);
  
 /**
- * Insert new user
+ * Function gallery_user_insert().
+ * (insert new user)
  */
-function gallery_insert_user(&$edit, $user) {
-    list ($success, $ret) = _gallery_init();
-    if (!$success) {
-      $err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link">
-                    configure your embedded Gallery</a>.', 
-                    array('@link' => url('admin/settings/gallery')));
-      gallery_error($err_msg, $ret);
-      return;
-    }
+function gallery_user_insert(&$edit, $user) {
+    $user->roles = isset($edit['roles']) ? $edit['roles'] : $user->roles;
+    $user->status = isset($edit['status']) ? $edit['status'] : TRUE;
     
-    list ($success, $ret) = gallery_modify_user($user, 'create');
-    if ($ret) {
-      gallery_error(t('Error creating Gallery user'), $ret);
-      return;
-    }
-
-    GalleryEmbed::done();
-    return;
+    gallery_user_modify($user, 'create');
 }
 
 /**
- * Update a user with new information
+ * Function gallery_user_update().
+ * (update a user with new information)
  */
-function gallery_update_user(&$edit, $user) {
-  list ($success, $ret) = _gallery_init();
-  if (!$success) {
-      $err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link">
-                    configure your embedded Gallery</a>.', 
-                    array('@link' => url('admin/settings/gallery')));
-      gallery_error($err_msg, $ret);
-      return;
-  }
-
-  // on update we can't be sure how much info $edit will contain.
-  // $user is a copy, so we can modify it here.
-  $user->name = ($edit['name']) ? $edit['name'] : $user->name;
-  $user->language = ($edit['language']) ? $edit['language'] : gallery_get_language($user);
-  $user->pass = ($edit['pass']) ? md5($edit['pass']) : $user->pass;
-  $user->status = ($edit['status']) ? $edit['status'] : $user->status;
-  $user->mail = ($edit['mail']) ? $edit['mail'] : $user->mail;
-  // Note: $user->roles is organized as [$rid]=>[$role_name], but edit['roles'] is [$rid]=>[$position]
-  $user->roles = ($edit['roles']) ? $edit['roles'] : $user->roles;
-  // Use full name from profile if it exists 
-  $fullnamefield = variable_get('gallery_profile_full_name_field', 'profile_full_name');
-  $usefullname = variable_get('gallery_use_full_name', 0) && module_exists('profile');
-  if (($edit[$fullnamefield] || $user->$fullnamefield) && $usefullname) {
-    $user->$fullnamefield = ($edit[$fullnamefield]) ? $edit[$fullnamefield] : $user->$fullnamefield;
-  } else {
-    $user->$fullnamefield = $name;
-  } 
+function gallery_user_update(&$edit, $user) {
+  $user->language = isset($edit['language']) ? $edit['language'] : gallery_get_language($user);
+  $user->pass = !empty($edit['pass']) ? md5($edit['pass']) : $user->pass;
+  $user->status = isset($edit['status']) ? $edit['status'] : $user->status;
+  $user->mail = !empty($edit['mail']) ? $edit['mail'] : $user->mail;
+  $user->roles = isset($edit['roles']) ? $edit['roles'] : $user->roles;
 
-  list ($success, $ret) = gallery_modify_user($user, 'update');
-  if ($ret) {
-    gallery_error(t('Error updating Gallery user'), $ret);
-    return;
-  }  
-  GalleryEmbed::done();
-  return;
+  // Fullname support
+  if (module_exists('profile') && variable_get('gallery_use_fullname', 0)) {
+    $fullname_field = variable_get('gallery_profile_fullname_field', 'profile_fullname');
+    $user->$fullname_field = isset($edit[$fullname_field]) ? $edit[$fullname_field] : $user->$fullname_field;
+  }
+  
+  // Username is about to change
+  if ($namechange = (isset($edit['name']) && ($edit['name'] != $user->name))) {
+    // Make sure the original user is up to date
+    gallery_user_modify($user, 'update', TRUE);
+  }
+  
+  $user->name = isset($edit['name']) ? $edit['name'] : $user->name;
+  
+  if ($namechange) {
+    // Change username
+    gallery_user_modify($user, 'username');
+  }
+  else {
+    // Update user
+    gallery_user_modify($user, 'update', TRUE);
+  }
 }
 
 /**
- * Delete the user from the Gallery 
+ * Function gallery_user_delete().
+ * (delete the user from the Gallery)
  */ 
-function gallery_delete_user($user) {
-    list ($success, $ret) = _gallery_init();
-    if (!$success) {
-      $err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link">
-                    configure your embedded Gallery</a>.', 
-                    array('@link' => url('admin/settings/gallery')));
-      gallery_error($err_msg, $ret);
-      return;
-    }
-    $ret = GalleryEmbed::deleteUser($user->uid);
-    if ($ret) {
-      gallery_error(t('Error deleting Gallery user'), $ret);
-    }
-    GalleryEmbed::done();
-    return;
+function gallery_user_delete($user) {
+  gallery_user_modify($user, 'delete');
 }
 
 /**
- * Modify (create/update) a user
+ * Function gallery_user_modify().
+ * (modify (create/update/delete) a user)
  */
-function gallery_modify_user($user, $action = 'create') {
-  $fullnamefield = variable_get('gallery_profile_full_name_field', 'profile_full_name');
-  $usefullname = variable_get('gallery_use_full_name', 0) && module_exists('profile');
-  $fullname = ($user->$fullnamefield && $usefullname) ? $user->$fullnamefield : $user->name;
-  // Generate random password for gallery2 if user is blocked, to avoid them being able to login
-  // to gallery2 if not-embedded operation is allowed.
-  $pass = ($user->status == 1) ? $user->pass : user_password(20);
-     
+function gallery_user_modify($user, $action = 'create', $groups = FALSE, $vars = NULL) {
+  if (!_gallery_init(TRUE, $vars)) {
+    return FALSE;
+  }
+  // Check for fullname support
+  $fullname_field = variable_get('gallery_profile_fullname_field', 'profile_fullname');
+  $usefullname = module_exists('profile') && variable_get('gallery_use_fullname', 0);
+  $fullname = $usefullname ? (isset($user->$fullname_field) ? $user->$fullname_field : '') : $user->name;
+
+  // Generate random password for G2 if user is blocked
+  $pass = ($user->status) ? $user->pass : user_password(20);
+
   switch ($action) {
+    case 'username':
+      $ret = GalleryEmbed::updateUser($user->uid,
+              array('username' => $user->name,
+                    'fullname' => $fullname,
+                    'email' => $user->mail,
+                    'language' => gallery_get_language($user),
+                    'hashedpassword' => $pass,
+                    'hashmethod' => 'md5'));
+      if ($ret) {
+        gallery_error(t('Error updating Gallery user (username changed)'), $ret);
+        return FALSE;
+      }
+      break;
     case 'create' :
-    case 'update' : 
-      // See if user already exists in Gallery2
-      list ($g2_user_state, $g2_user, $ret) = _gallery_check_user_status($user);
+    case 'update' :
+      // Get map state of the user
+      list($g2_user_state, $g2_user, $ret) = gallery_user_map_state($user);
       if ($ret) {
-        // An unmasked error, so exit now
-        return array(false, $ret);
+        gallery_error(t('Error determining user map state'), $ret);
+        return FALSE;
       }
-    
+      
+      // Complete user mapping
       switch ($g2_user_state) {
-        case G2_USER_EXISTS_BUT_NEEDS_MAPPING:
-          // No mapping found, so add one
-          $ret = GalleryEmbed::addExternalIdMapEntry($user->uid, $g2_user->getId(), 'GalleryUser');
+        case GALLERY_MAP_USER_EXISTS_BUT_NEEDS_MAPPING:
+          // create map entry for the user
+          $ret = GalleryEmbed::addExternalIdMapEntry($user->uid, $g2_user->id, 'GalleryUser');
           if ($ret) {
-            // mapping the user failed for some reason, so exit
-            return array(false, $ret);
-          } 
-          // Continue to update
-        case G2_USER_EXISTS:
-          // May need to update the user info with that from Drupal
+            gallery_error(t('Error creating map entry (ExternlIdMapEntry)'), $ret);
+            return FALSE;
+          }
+        case GALLERY_MAP_USER_EXISTS:
+          // Update user (Drupal -> G2)
           $ret = GalleryEmbed::updateUser($user->uid,
                   array('username' => $user->name,
                         'fullname' => $fullname,
@@ -137,19 +140,23 @@ function gallery_modify_user($user, $action = 'create') {
                         'hashedpassword' => $pass,
                         'hashmethod' => 'md5'));
           if ($ret) {
-            return array(false, $ret);
+            gallery_error(t('Error updating Gallery user'), $ret);
+            return FALSE;
           }
           break;
-        case G2_USER_DOES_NOT_EXIST_BUT_IS_MAPPED:
+        case GALLERY_MAP_USER_DOES_NOT_EXIST_BUT_IS_MAPPED:
+          // Remove mapping for non-existing user
+          // (also happens if gallery_user_modify() is called with a changed username)
           $ret = GalleryCoreApi::removeMapEntry('ExternalIdMap', array('externalId' => $user->uid, 'entityType' => 'GalleryUser'));
           if ($ret) {
-            // There was an error on removeMapEntry
-            return array(false, $ret2);
-          } 
-          // Continue to creation
-        case G2_USER_DOES_NOT_EXIST:
-          // Create the new user
-          $ret = GalleryEmbed::createUser($user->uid, 
+            gallery_error(t('Error removing map entry (ExternlIdMapEntry)'), $ret);
+            return FALSE;
+          }
+        case GALLERY_MAP_USER_DOES_NOT_EXIST:
+          // Create new user
+          if (!$user->uid)
+            return FALSE;
+          $ret = GalleryEmbed::createUser($user->uid,
                   array('username' => $user->name,
                         'email' => $user->mail,
                         'fullname' => $fullname,
@@ -157,278 +164,477 @@ function gallery_modify_user($user, $action = 'create') {
                         'hashedpassword' => $pass,
                         'hashmethod' => 'md5'));
           if ($ret) {
-            // There was an error on user creation
-            return array(false, $ret);
+            gallery_error(t('Error creating Gallery user'), $ret);
+            return FALSE;
+          }
+          list($ret, $g2_user) = GalleryCoreApi::loadEntityByExternalId($user->uid, 'GalleryUser');
+          if ($ret) {
+            gallery_error(t('Error loading newly created Gallery user'), $ret);
+            return FALSE;
           }
           break;
       }
+      // Update group info
+      _gallery_groups_user($user, $groups);
+      // Admin role mapping
+      $admin_role = variable_get('gallery_user_admin_role', 0);
+      if (($admin_role && in_array($admin_role, array_keys($user->roles))) || ($user->uid == 1)) {
+        // Get G2 admin group id
+        list($ret, $g2_admin_gid) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.adminGroup');
+        if ($ret) {
+          gallery_error(t('Error getting \'adminGroup\' id'), $ret);
+          return FALSE;
+        }
+        // Add user to admin group
+        $ret = GalleryCoreApi::addUserToGroup($g2_user->id, $g2_admin_gid);
+        if ($ret) {
+          gallery_error(t('Error adding user to Gallery group (:gid)',
+            array(':gid' => $g2_admin_gid)), $ret);
+          return FALSE;
+        }
+      }
+      break;
+    case 'delete' :
+      $ret = GalleryEmbed::deleteUser($user->uid);
       if ($ret) {
-        return array(false, $ret);
+        gallery_error(t('Error deleting Gallery user'), $ret);
+        return FALSE;
       }
-      // Add group info</