new revamp for troutcreek
authorSteve Sutton <steve@gaslightmedia.com>
Fri, 5 Feb 2010 19:29:28 +0000 (19:29 +0000)
committerSteve Sutton <steve@gaslightmedia.com>
Fri, 5 Feb 2010 19:29:28 +0000 (19:29 +0000)
201 files changed:
.htaccess [new file with mode: 0644]
Toolkit/.htaccess [new file with mode: 0644]
Toolkit/CKImages/Connector.php [new file with mode: 0644]
Toolkit/CKImages/Factory.php [new file with mode: 0644]
Toolkit/CKImages/Folders.php [new file with mode: 0644]
Toolkit/CKImages/assets/.keepme [new file with mode: 0644]
Toolkit/CKImages/browser.php [new file with mode: 0644]
Toolkit/CKImages/connector.php [new file with mode: 0644]
Toolkit/CKImages/database/ckeditorImages.sql [new file with mode: 0644]
Toolkit/CKImages/libjs/image_selector.js [new file with mode: 0644]
Toolkit/CKImages/styles.css [new file with mode: 0755]
Toolkit/CKImages/templates/compiled/.cvsignore [new file with mode: 0644]
Toolkit/CKImages/templates/compiled/.keepme [new file with mode: 0644]
Toolkit/CKImages/templates/thumbnails.html [new file with mode: 0755]
Toolkit/Common.php [new file with mode: 0644]
Toolkit/Contacts/BrochureRequest.php [new file with mode: 0755]
Toolkit/Contacts/ContactUs.php [new file with mode: 0755]
Toolkit/Contacts/PdfForm.php [new file with mode: 0755]
Toolkit/Contacts/SaveTripPlanner.php [new file with mode: 0755]
Toolkit/Contacts/SendTripPlanner.php [new file with mode: 0755]
Toolkit/Contacts/StreamSend.php [new file with mode: 0755]
Toolkit/Contacts/TellAFriend.php [new file with mode: 0755]
Toolkit/Contacts/assets/.keepme [new file with mode: 0644]
Toolkit/Contacts/database-table-modifiers.sql [new file with mode: 0644]
Toolkit/Contacts/database-tables.sql [new file with mode: 0644]
Toolkit/Contacts/templates/brochurePage.html [new file with mode: 0755]
Toolkit/Contacts/templates/compiled/.cvsignore [new file with mode: 0644]
Toolkit/Contacts/templates/compiled/.keepme [new file with mode: 0644]
Toolkit/Contacts/templates/currentTables/Element.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/Form.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/Group.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/GroupElement.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/Header.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/currentTables/RequiredNote.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/direct-list.html [new file with mode: 0755]
Toolkit/Contacts/templates/emailOwner.tpl [new file with mode: 0755]
Toolkit/Contacts/templates/friendEmail.html [new file with mode: 0644]
Toolkit/Contacts/templates/pdfDownloadEmail.html [new file with mode: 0755]
Toolkit/Coupons/Category.php [new file with mode: 0644]
Toolkit/Coupons/Coupon.php [new file with mode: 0644]
Toolkit/Coupons/Database/application.sql [new file with mode: 0644]
Toolkit/Coupons/Database/tables/coupon_category.sql [new file with mode: 0644]
Toolkit/Coupons/Database/tables/coupons.sql [new file with mode: 0644]
Toolkit/Coupons/ICoupon.php [new file with mode: 0644]
Toolkit/Coupons/IFactory.php [new file with mode: 0644]
Toolkit/Coupons/MemberCoupon.php [new file with mode: 0644]
Toolkit/Coupons/MemberFactory.php [new file with mode: 0644]
Toolkit/DataGridBuilder.php [new file with mode: 0644]
Toolkit/Database.php [new file with mode: 0644]
Toolkit/FlexyDataGridBuilder.php [new file with mode: 0644]
Toolkit/Form.php [new file with mode: 0644]
Toolkit/FormBuilder.php [new file with mode: 0644]
Toolkit/Forms/Rules/Date.php [new file with mode: 0644]
Toolkit/Forms/templates/tables/Element.tpl [new file with mode: 0644]
Toolkit/Forms/templates/tables/Form.tpl [new file with mode: 0644]
Toolkit/Forms/templates/tables/Group.tpl [new file with mode: 0644]
Toolkit/Forms/templates/tables/GroupElement.tpl [new file with mode: 0644]
Toolkit/Forms/templates/tables/Header.tpl [new file with mode: 0644]
Toolkit/Forms/templates/tables/RequiredNote.tpl [new file with mode: 0644]
Toolkit/INavigation.php [new file with mode: 0644]
Toolkit/Image/Server.php [new file with mode: 0755]
Toolkit/Logger.php [new file with mode: 0644]
Toolkit/Navigation.php [new file with mode: 0644]
Toolkit/Page.php [new file with mode: 0755]
Toolkit/ShortURL.php [new file with mode: 0755]
Toolkit/SiteMap.php [new file with mode: 0755]
Toolkit/SortForm.php [new file with mode: 0644]
Toolkit/Toolbox/Admin/EditPage.php [new file with mode: 0644]
Toolkit/Toolbox/Admin/EditParagraph.php [new file with mode: 0644]
Toolkit/Toolbox/Admin/toolbox.sql [new file with mode: 0644]
Toolkit/Toolbox/assets/.keepme [new file with mode: 0644]
Toolkit/Tree.php [new file with mode: 0644]
Toolkit/Weather.php [new file with mode: 0755]
Toolkit/qfcaptcha.php [new file with mode: 0755]
admin/.htaccess [new file with mode: 0644]
admin/Photos/edit-default.php [new file with mode: 0644]
admin/Photos/edit_display.phtml [new file with mode: 0644]
admin/Photos/edit_photo.phtml [new file with mode: 0644]
admin/Photos/edit_photo_category.phtml [new file with mode: 0755]
admin/Photos/export-images-is0.php [new file with mode: 0755]
admin/Photos/index.php [new file with mode: 0644]
admin/Photos/list_photo.phtml [new file with mode: 0755]
admin/Photos/list_photo_category.phtml [new file with mode: 0755]
admin/Photos/photo-setup.inc [new file with mode: 0644]
admin/Photos/photo.sql [new file with mode: 0755]
admin/Photos/photo_config.sql [new file with mode: 0755]
admin/Photos/update_display.php [new file with mode: 0644]
admin/Photos/update_photo.phtml [new file with mode: 0644]
admin/Photos/update_photo_category.phtml [new file with mode: 0644]
admin/Toolbox/business.sql [new file with mode: 0644]
admin/Toolbox/cktoolbox.js [new file with mode: 0644]
admin/Toolbox/collapse.png [new file with mode: 0755]
admin/Toolbox/convert_files.php [new file with mode: 0644]
admin/Toolbox/edit_bus.phtml [new file with mode: 0755]
admin/Toolbox/edit_bus_category.phtml [new file with mode: 0755]
admin/Toolbox/expand.png [new file with mode: 0755]
admin/Toolbox/export-images-is0.php [new file with mode: 0755]
admin/Toolbox/file-repos-xml.php [new file with mode: 0644]
admin/Toolbox/file-xml.php [new file with mode: 0644]
admin/Toolbox/file_load.js [new file with mode: 0644]
admin/Toolbox/files.sql [new file with mode: 0644]
admin/Toolbox/htmlarea.css [new file with mode: 0644]
admin/Toolbox/images/collapse.png [new file with mode: 0755]
admin/Toolbox/images/expand.png [new file with mode: 0755]
admin/Toolbox/index.phtml [new file with mode: 0755]
admin/Toolbox/jake-handler.js [new file with mode: 0644]
admin/Toolbox/list_bus.phtml [new file with mode: 0755]
admin/Toolbox/list_bus_category.phtml [new file with mode: 0755]
admin/Toolbox/member-code-line.php [new file with mode: 0644]
admin/Toolbox/member-code-query.php [new file with mode: 0644]
admin/Toolbox/member-toolbox.js [new file with mode: 0644]
admin/Toolbox/member-toolbox.php [new file with mode: 0644]
admin/Toolbox/threads.phtml [new file with mode: 0755]
admin/Toolbox/toolbox_setup.inc [new file with mode: 0755]
admin/Toolbox/update_bus.phtml [new file with mode: 0755]
admin/Toolbox/update_bus_category.phtml [new file with mode: 0755]
admin/Toolbox/updatetoolset.php [new file with mode: 0755]
admin/Toolbox/upgradefiles2.php [new file with mode: 0644]
admin/form.js [new file with mode: 0644]
admin/index.phtml [new file with mode: 0644]
admin/main.css [new file with mode: 0644]
admin/msg.js [new file with mode: 0644]
admin/nav.phtml [new file with mode: 0644]
admin/splash.phtml [new file with mode: 0644]
admin/template1.gif [new file with mode: 0644]
admin/template2.gif [new file with mode: 0644]
admin/template3.gif [new file with mode: 0644]
admin/template4.gif [new file with mode: 0644]
admin/template5.gif [new file with mode: 0644]
admin/template6.gif [new file with mode: 0644]
admin/verify.js [new file with mode: 0644]
admin/wm.js [new file with mode: 0644]
cache/.cvsignore [new file with mode: 0644]
cache/.keepme [new file with mode: 0644]
classes/class_db.inc [new file with mode: 0755]
classes/class_template.inc [new file with mode: 0644]
classes/class_threads.inc [new file with mode: 0644]
classes/class_toolbox.inc [new file with mode: 0755]
contactform.css [new file with mode: 0644]
coupons.css [new file with mode: 0644]
download.php [new file with mode: 0644]
email.css [new file with mode: 0644]
event.css [new file with mode: 0644]
gsearch.css [new file with mode: 0644]
images/add.png [new file with mode: 0755]
images/application_edit.png [new file with mode: 0644]
images/cross.png [new file with mode: 0644]
images/delete.png [new file with mode: 0644]
images/error.gif [new file with mode: 0644]
images/file-ext/avi.gif [new file with mode: 0644]
images/file-ext/cad.gif [new file with mode: 0644]
images/file-ext/doc.gif [new file with mode: 0644]
images/file-ext/download.gif [new file with mode: 0644]
images/file-ext/gif.gif [new file with mode: 0644]
images/file-ext/html.gif [new file with mode: 0644]
images/file-ext/jpg.gif [new file with mode: 0644]
images/file-ext/mov.gif [new file with mode: 0644]
images/file-ext/mp3.gif [new file with mode: 0644]
images/file-ext/pdf.png [new file with mode: 0644]
images/file-ext/ppt.gif [new file with mode: 0644]
images/file-ext/rm.gif [new file with mode: 0644]
images/file-ext/txt.png [new file with mode: 0644]
images/file-ext/wmv.gif [new file with mode: 0644]
images/file-ext/xls.gif [new file with mode: 0644]
images/file-ext/zip.png [new file with mode: 0644]
images/find.png [new file with mode: 0644]
images/flag_green.png [new file with mode: 0644]
images/folder.png [new file with mode: 0755]
images/folder_add.png [new file with mode: 0755]
images/folder_delete.png [new file with mode: 0755]
images/grnball.gif [new file with mode: 0755]
images/help.gif [new file with mode: 0755]
images/html.gif [new file with mode: 0755]
images/img.gif [new file with mode: 0755]
images/left.gif [new file with mode: 0644]
images/loadingAnimation.gif [new file with mode: 0644]
images/logo.gif [new file with mode: 0755]
images/magnifier.png [new file with mode: 0755]
images/note_edit.png [new file with mode: 0644]
images/page_edit.png [new file with mode: 0644]
images/redball.gif [new file with mode: 0755]
images/right.gif [new file with mode: 0644]
images/shadowb.gif [new file with mode: 0644]
images/shadowr.gif [new file with mode: 0644]
images/size.sh [new file with mode: 0755]
images/tick.png [new file with mode: 0644]
images/top2.jpg [new file with mode: 0755]
images/user_add.png [new file with mode: 0644]
images/user_edit.png [new file with mode: 0644]
index.php [new file with mode: 0644]
libjs/.keepme [new file with mode: 0644]
libjs/external.js [new file with mode: 0644]
libjs/gsearch.php [new file with mode: 0755]
setup.phtml [new file with mode: 0644]
setup_functions.phtml [new file with mode: 0644]
static/.keepme [new file with mode: 0644]
templates/404-template.html [new file with mode: 0755]
templates/template.html [new file with mode: 0755]
toolbox.css [new file with mode: 0644]
uploads/.cvsignore [new file with mode: 0644]
uploads/.keepme [new file with mode: 0644]

diff --git a/.htaccess b/.htaccess
new file mode 100644 (file)
index 0000000..b5b8cd6
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,31 @@
+<Files ~ "^\.ht">
+Order allow,deny
+Deny from all
+</Files>
+<Files ~ "^setup.phtml">
+Order allow,deny
+Deny from all
+</Files>
+#ErrorDocument 404 /404.html
+RewriteEngine On
+AddDefaultCharset utf-8
+RewriteBase /www.troutcreek.com/
+#RewriteCond %{HTTP_HOST} !^(.*)\.troutcreek\.com$ [NC]
+#RewriteRule ^(.*)$ http://www.troutcreek.com/$1 [R=301,L]
+RewriteRule ^VisitorGuide/(.*)/$ pdf-download.php?uidpdf=$1&pdf_file=VisitorGuide [L]
+RewriteRule ^.*-([0-9]*)/([0-9]*)/$ index.php?catid=$1&photo_catid=$2 [L]
+# rewrites for the toolbox pages
+RewriteRule ^.*-([0-9]*)/index.php index\.php?%{QUERY_STRING}
+RewriteRule ^.*-([0-9]*)/$ index\.php?catid=$1 [L]
+
+RewriteRule site-map index.php?catid=1&sitemap=1
+
+# short urls
+RewriteCond %{REQUEST_URI} !(^.*-([0-9]*)/$) 
+RewriteRule ^([A-Za-z0-9_-]*)/$ index.php?glmPage=$1 [L]
+
+###############
+## Templates ##
+###############
+# View flexy templates as php files
+AddType application/x-httpd-php .tpl
diff --git a/Toolkit/.htaccess b/Toolkit/.htaccess
new file mode 100644 (file)
index 0000000..532b751
--- /dev/null
@@ -0,0 +1,2 @@
+#IndexIgnore */*
+#Options All -Indexes
diff --git a/Toolkit/CKImages/Connector.php b/Toolkit/CKImages/Connector.php
new file mode 100644 (file)
index 0000000..9f288b2
--- /dev/null
@@ -0,0 +1,360 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Connects the CKImage browser to the server for image manipulation
+ * 
+ * PHP version 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Connector.php,v 1.8 2009/11/15 19:12:23 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+
+/**
+ * Connects the CKImage browser to the server for image manipulation
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_CKImages_Connector
+{
+    //  {{{ setDbh()
+
+
+    /**
+     * Sets the database handler for the object to use
+     * 
+     * @param PDO $pdo PHP Data Object
+     *
+     * @return void   
+     * @access public 
+     */
+    public function setDbh(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+
+    //  {{{ createFolder()
+
+
+    /**
+     * Creates a new folder
+     * 
+     * @return void 
+     * @access public 
+     */
+    public function createFolder()
+    {
+        //  get the folder id
+        $folder = $_GET['name'];
+        $parent = ctype_digit((string) $_GET['folder']) ? $_GET['folder'] : 1;
+
+        if (ctype_digit((string) $_GET['parentFolder'])) {
+            $parent = $_GET['parentFolder'];
+        }
+        //  unset unneeded param values
+        unset($_GET['command'], $_GET['name'], $_GET['parentFolder']);
+
+        try {
+            $sql = "
+                INSERT INTO ckeditor_folders(name, parent)
+                VALUES (:name, :parent)";
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':name', $folder, PDO::PARAM_INT);
+            $stmt->bindParam(':parent', $parent, PDO::PARAM_INT);
+            $stmt->execute();
+            header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ deleteFile()
+
+
+    /**
+     * Deletes a file from the image server for client
+     * 
+     * @param Toolkit_Image_Server $is Image Server Object
+     *
+     * @return void
+     * @access public 
+     */
+    public function deleteFile(Toolkit_Image_Server $is)
+    {
+        //  Get offset where target img starts at
+        $start = strrpos($_GET['img'], '/') + 1;
+        //  get the image name
+        $img = substr($_GET['img'], $start);
+        //  unset unneeded param values
+        unset($_GET['command'], $_GET['img']);
+
+        $is->imageDelete($img);
+        
+        try {
+            $sql = "
+                DELETE FROM ckeditor_images
+                 WHERE name_on_disk = :nod";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':nod', $img, PDO::PARAM_STR);
+            $stmt->execute();
+            header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ deleteFolder()
+
+
+    /**
+     * Deletes a folder and any sub folders
+     * 
+     * Moves all containing images to home folder so they are not
+     * inadvertently deleted
+     * 
+     * @param Toolkit_Image_Server $is Image Server used to delete photo
+     *
+     * @return void
+     * @access public 
+     */
+    public function deleteFolder(Toolkit_Image_Server $is)
+    {
+        //  get the folder id
+        $folder = $_GET['folder'];
+        if ($folder == 1) {
+            return false;
+        }
+        //  unset unneeded param values
+        unset($_GET['command'], $_GET['tgt']);
+        $_GET['folder'] = 1;
+
+        try {
+            $tree = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'ckeditor_folders',
+                'id',
+                'parent',
+                'id',
+                $folder,
+                0,
+                false
+            );
+
+            $sql = "
+                UPDATE ckeditor_images
+                   SET folder = 1
+                 WHERE folder = :folder";
+
+            $imgStmt = $this->dbh->prepare($sql);
+
+            $sql = "
+                DELETE FROM ckeditor_folders
+                 WHERE id = :folder";
+            $fldrStmt = $this->dbh->prepare($sql);
+            while (list($tgt) = each($tree)) {
+                $imgStmt->bindParam(':folder', $tgt, PDO::PARAM_INT);
+                $imgStmt->execute();
+
+                $fldrStmt->bindParam(':folder', $tgt, PDO::PARAM_INT);
+                $fldrStmt->execute();
+            }
+            //  These cookies are defined in the libjs/image_selector.js file
+            //  when the tree is created.
+            unset($_COOKIE['glm_image_browser_open'], $_COOKIE['glm_image_browser_selected']);
+            header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ browseImages()
+
+
+    /**
+     * Creates the browser window
+     * 
+     * @param HTML_Template_Flexy  $tEngine Flexy Rendering Engine Object
+     * @param Toolkit_Image_Server $is      Image Server
+     *
+     * @return string HTML page to browse images
+     * @access public 
+     */
+    public function browseImages(
+        HTMl_Template_Flexy $tEngine,
+        Toolkit_Image_Server $is
+    ) {
+        $page = new stdClass();
+        $page->originalPath  = ORIGINAL;
+        $page->imageManager  = IMAGE_MANAGER;
+
+        $folder = ctype_digit((string) $_GET['folder'])
+                 ? "&folder={$_GET['folder']}" : '';
+        $form = new HTML_QuickForm(
+            'quick_upload',
+            'post',
+            BASE_URL . "Toolkit/CKImages/connector.php?CKEditor={$_GET['CKEditor']}&CKEditorFuncNum={$_GET['CKEditorFuncNum']}&langCode={$_GET['langCode']}&command=UploadFile$folder"
+        );
+        $form->addElement('file', 'upload');
+        $page->quickUploadForm = $form->toHtml();
+
+        $folders = new Toolkit_CKImages_Folders($this->dbh);
+        $page->folders = $folders->getFolders(0);
+
+        try {
+            $folder = ctype_digit((string) $_GET['folder'])
+                     ? $_GET['folder'] : 1;
+            $sql = "
+                SELECT *
+                  FROM ckeditor_images
+                 WHERE folder = :folder
+                 ORDER BY id ASC";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':folder', $folder, PDO::PARAM_INT);
+            $stmt->execute();
+
+            $images = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+            foreach ($images as &$i) {
+                $dimensions = $is->getImageSize($page->originalPath . $i['name_on_disk']);
+                list($i['width'], $i['height'],) = $dimensions;
+            }
+
+            $page->images = $images;
+
+            $tEngine->compile('thumbnails.html');
+            $tEngine->outputObject($page);
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ handleUpload()
+
+
+    /**
+     * Handles inserting the upload into the database
+     * 
+     * @param string $imageName  image to insert
+        * @param array  $dimensions dimensions of the image
+     *
+     * @return object    Return description (if any) ...
+     * @access protected
+     */
+    protected function handleUpload($imageName, array $dimensions)
+    {
+        try {
+            $folder = ctype_digit((string) $_GET['folder'])
+                     ? $_GET['folder'] : 1;
+            $sql = "
+                INSERT INTO ckeditor_images (file_name, name_on_disk, folder,
+                original_width, original_height)
+                VALUES (:fname, :nod, :folder, :width, :height)";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(
+                ':fname',
+                $_FILES['upload']['name'],
+                PDO::PARAM_STR
+            );
+            $stmt->bindParam(':nod', $imageName, PDO::PARAM_STR);
+            $stmt->bindValue(':folder', $folder, PDO::PARAM_INT);
+            $stmt->bindValue(':width', $dimensions['oWidth'], PDO::PARAM_INT);
+            $stmt->bindValue(':height', $dimensions['oHeight'], PDO::PARAM_INT);
+
+
+            return $stmt->execute();
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ quickUpload()
+
+
+    /**
+     * send uploaded image to image server
+     * 
+     * @param Toolkit_Image_Server $is Image Server
+     *
+     * @return void  
+     * @access public
+     */
+    public function quickUpload(Toolkit_Image_Server $is)
+    {
+        ob_start();
+        $imageName = $is->imageUpload('upload');
+        ob_end_clean();
+        if ($imageName) {
+            $dimensions = $is->getImageSize(ORIGINAL . $imageName);
+            list($i['oWidth'], $i['oHeight'],) = $dimensions;
+            $this->handleUpload($imageName, $i);
+        }
+
+        unset($_GET['command']);
+        header('Location:' . BASE_URL . 'Toolkit/CKImages/browser.php?' . http_build_query($_GET));
+    }
+
+    //  }}}
+
+    //  {{{ uploadFile()
+
+
+    /**
+     * send uploaded image to image server and select that file to be used
+     * 
+     * @param Toolkit_Image_Server $is Image server object
+     *
+     * @return void  
+     * @access public
+     */
+    public function uploadFile(Toolkit_Image_Server $is)
+    {
+        ob_start();
+        $imageName = $is->imageUpload('upload');
+        ob_end_clean();
+        $funcNum = ctype_digit((string) $_GET['CKEditorFuncNum'])
+                  ? $_GET['CKEditorFuncNum'] : 1;
+
+        echo '<script type="text/javascript">';
+        if (!$imageName) {
+            echo "window.parent.CKEDITOR.tools.callFunction($funcNum, '', 'Invalid Image Format');";
+        } else {
+            $dimensions = $is->getImageSize(ORIGINAL . $imageName);
+            list($i['oWidth'], $i['oHeight'],) = $dimensions;
+            $this->handleUpload($imageName, $i);
+
+            //  path to image we are going to use
+            $ip = RESIZED . $imageName;
+            echo "window.parent.CKEDITOR.tools.callFunction($funcNum, '$ip', '');";
+        }
+        echo '</script>';
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/CKImages/Factory.php b/Toolkit/CKImages/Factory.php
new file mode 100644 (file)
index 0000000..a693896
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * CKImage Factory
+ * 
+ * PHP version 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Factory.php,v 1.1 2009/09/24 14:43:02 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+
+
+/**
+ * CKImage Factory
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_CKImages_Factory
+{
+    //  {{{ properties
+
+    /**
+     * array of instances
+     * @var    array 
+     * @access public
+     * @static
+     */
+    public static $instances = array();
+
+    //  }}} 
+    //  {{{ init()
+
+    /**
+     * initialize the factory
+     * 
+     * @return void  
+     * @access public
+     * @static
+     */
+    public static function init()
+    {
+    }
+
+    //  }}}
+    //  {{{ &instance()
+
+    /**
+     * Get a single instance of an object
+     * 
+     * @param string $class Class name to create
+     *
+     * @return mixed instantiated object
+     * @access public
+     * @static
+     */
+    public static function &instance($class)
+    {
+        $class = "Toolkit_CKImages_$class";
+
+        if (empty(Toolkit_CKImages_Factory::$instances)) {
+            Toolkit_CKImages_Factory::$instances[$class] = new $class;
+        }
+
+        return Toolkit_CKImages_Factory::$instances[$class];
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/CKImages/Folders.php b/Toolkit/CKImages/Folders.php
new file mode 100644 (file)
index 0000000..2858948
--- /dev/null
@@ -0,0 +1,243 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Handles create a UL list to simulate a folder hierarchy
+ * 
+ * PHP version 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Folders.php,v 1.6 2009/10/27 14:39:27 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Handles create a UL list to simulate a folder hierarchy
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      http://demo.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_CKImages_Folders
+{
+    //  {{{ properties
+
+
+    /**
+     * Levels deep we are into the hierarchy
+     * @var    integer
+     * @access private
+     */
+    private $_lvlsOpen = 0;
+
+    /**
+     * The previous level we were at
+     * @var    integer
+     * @access private
+     */
+    private $_prevLvl = 0;
+
+    //  }}}
+
+    //  {{{ __construct()
+
+    /**
+     * Constructor
+     * 
+     * @param PDO $pdo PHP Data Object
+     *                     
+     * @return void  
+     * @access public
+     */
+    public function __construct(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    //  }}}
+
+    //  {{{ closeFolder()
+
+
+    /**
+     * Closes a folder level
+     * 
+     * @return string    closing ul tag
+     * @access protected
+     */
+    protected function closeFolder()
+    {
+        return "\n</ul>";
+    }
+
+    //  }}}
+    //  {{{ closeNode()
+
+
+    /**
+     * Closes a node
+     * 
+     * @return string    closing li tag
+     * @access protected
+     */
+    protected function closeNode()
+    {
+        return "\n\t</li>";
+    }
+
+    //  }}}
+    //  {{{ createFolder()
+
+
+    /**
+     * Creates a folder level
+     * 
+     * @return string    opening ul tag
+     * @access protected
+     */
+    protected function createFolder()
+    {
+        return "\n<ul>";
+    }
+
+    //  }}}
+    //  {{{ createLink()
+
+
+    /**
+     * Creates a folder link so we can browse to each folder
+     * 
+     * @param array $row Folder information
+     *
+     * @return string anchor link for folder
+     * @access protected
+     */
+    protected function createLink(array $row)
+    {
+        $format = '<a class="%s" href="'.BASE_URL.'Toolkit/CKImages/browser.php?CKEditor=%s&CKEditorFuncNum=%s&langCode=%s&folder=%s">%s</a>';
+
+        $link = sprintf(
+            $format,
+            ($_GET['folder'] == $row['id']) ? 'clicked' : null,
+            $_GET['CKEditor'],
+            $_GET['CKEditorFuncNum'],
+            $_GET['langCode'],
+            $row['id'],
+            $row['name']
+        );
+
+        return $link;
+    }
+
+    //  }}}
+
+    //  {{{ fetchFoldersArray()
+
+
+    /**
+     * Fetches a tree hierarchy of the folder structure into a linear array
+     * 
+     * @param integer $start node to start at
+     *
+     * @return array folder structure with levels
+     * @access protected
+     */
+    protected function fetchFoldersArray($start)
+    {
+        return Toolkit_Common::getHierarchicalTreeStructure(
+            $this->dbh,
+            'ckeditor_folders',
+            'id',
+            'parent',
+            'id',
+            $start
+        );
+    }
+
+    //  }}}
+
+    //  {{{ getFolders()
+
+
+    /**
+     * Gets the folders ul list
+     * 
+     * @param integer $parent start at a certain level
+     *                         
+     * @return string  list of folders
+     * @access public 
+     */
+    public function getFolders($parent = 0)
+    {
+        $folders = $this->fetchFoldersArray($parent);
+        try {
+            $sql = "
+                SELECT *
+                  FROM ckeditor_folders
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            foreach ($folders as $i => $j) {
+                $stmt->bindParam(':id', $i, PDO::PARAM_INT);
+                $stmt->execute();
+                $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                if ($j == $this->_prevLvl) {
+                    $tree .= $this->openNode($row);
+                    $tree .= $this->createLink($row);
+                    $this->_prevLvl = $j;
+                } elseif ($j > $this->_prevLvl) {
+                    ++$this->_lvlsOpen;
+                    $tree .= $this->createFolder();
+                    $tree .= $this->openNode($row);
+                    $tree .= $this->createLink($row);
+                    $this->_prevLvl = $j;
+                } elseif ($j < $this->_prevLvl) {
+                    do {
+                        $tree .= $this->closeNode();
+                        $tree .= $this->closeFolder();
+                    } while (--$this->_lvlsOpen > $j);
+                    $tree .= $this->closeNode();
+                    $tree .= $this->openNode($row);
+                    $tree .= $this->createLink($row);
+                    $this->_prevLvl = $this->_lvlsOpen;
+                }
+            }
+            $tree .= $this->closeFolder();
+            return $tree;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ openNode()
+
+
+    /**
+     * Opens a branch or leaf node
+     * 
+     * @param array $row Folder information
+     *
+     * @return string opening li tag
+     * @access protected
+     */
+    protected function openNode(array $row)
+    {
+        return "\n\t<li id=\"pred_{$row['id']}\">";
+    }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/CKImages/assets/.keepme b/Toolkit/CKImages/assets/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Toolkit/CKImages/browser.php b/Toolkit/CKImages/browser.php
new file mode 100644 (file)
index 0000000..5a30721
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * popup browser window
+ * 
+ * This file creates the popup browser window to manage images
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: browser.php,v 1.3 2009/11/15 19:12:23 jamie Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * bootstrap
+ */
+require_once '../../setup.phtml';
+
+Toolkit_CKImages_Factory::init();
+$connector = Toolkit_CKImages_Factory::instance('Connector');
+$connector->setDbh(Toolkit_Database::getInstance());
+$flexyOpts = $GLOBALS['flexyOptions'];
+$flexyOpts['templateDir'] = BASE . 'Toolkit/CKImages/templates/';
+$flexyOpts['compileDir'] = BASE . 'Toolkit/CKImages/templates/compiled/';
+$tEngine = new HTML_Template_Flexy($flexyOpts);
+$is      = new Toolkit_Image_Server;
+
+$connector->browseImages($tEngine, $is);
+?>
diff --git a/Toolkit/CKImages/connector.php b/Toolkit/CKImages/connector.php
new file mode 100644 (file)
index 0000000..fa87860
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Controller file
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  CKImages
+ * @package   Toolkit_CKImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: connector.php,v 1.3 2009/11/15 19:12:23 jamie Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * bootstrap
+ */
+require_once '../../setup.phtml';
+
+Toolkit_CKImages_Factory::init();
+$connector = Toolkit_CKImages_Factory::instance('Connector');
+$connector->setDbh(Toolkit_Database::getInstance());
+
+switch ($_GET['command']) {
+case 'CreateFolder' :
+    $connector->createFolder();
+    break;
+
+case 'DeleteFile' :
+    $connector->deleteFile(new Toolkit_Image_Server);
+    break;
+
+case 'DeleteFolder' :
+    $connector->deleteFolder(new Toolkit_Image_Server);
+    break;
+
+case 'Upload' :
+    $connector->uploadFile(new Toolkit_Image_Server);
+    break;
+
+case 'UploadFile' :
+    $connector->quickUpload(new Toolkit_Image_Server);
+    break;
+
+default :
+       die('not yet implemented');
+    $connector->throwError();
+    break;
+}
+?>
diff --git a/Toolkit/CKImages/database/ckeditorImages.sql b/Toolkit/CKImages/database/ckeditorImages.sql
new file mode 100644 (file)
index 0000000..1f0ae0d
--- /dev/null
@@ -0,0 +1,27 @@
+drop table ckeditor_folders;
+
+create table ckeditor_folders(
+id      serial primary key,
+name    text not null,
+parent  integer default 1 not null
+);
+
+grant all on ckeditor_folders_id_seq to nobody;
+grant all on ckeditor_folders to nobody;
+
+insert into ckeditor_folders(id, name, parent) values(1, 'root', 0);
+
+drop table ckeditor_images;
+
+create table ckeditor_images(
+id                  serial primary key,
+create_date         date default current_date,
+file_name text      not null,
+name_on_disk text   not null,
+original_width      text not null,
+original_height     text not null,
+folder              integer default 1 references ckeditor_folders (id) on delete set default
+);
+
+grant all on ckeditor_images_id_seq to nobody;
+grant all on ckeditor_images to nobody;
\ No newline at end of file
diff --git a/Toolkit/CKImages/libjs/image_selector.js b/Toolkit/CKImages/libjs/image_selector.js
new file mode 100644 (file)
index 0000000..c6becfb
--- /dev/null
@@ -0,0 +1,123 @@
+var IMAGE_SELECTOR =
+{
+    parentFolder: null,
+
+    init: function()
+    {
+               tree1 = new tree_component();
+               tree1.init($("#folders"), {
+                       cookies : {
+                               prefix : "glm_image_browser",
+                               opts : { path : '/' }
+                       },
+                       ui : {
+                               animation : 500
+                       }
+               });
+
+        //  Make the tree default to all opened
+               $('#folders li.closed')
+            .toggleClass('open')
+                   .toggleClass('closed');
+
+               $('#folders a').click(IMAGE_SELECTOR.viewFolder);
+
+        //  Stop clicks on the LI elements, so the folders branches
+        //  will not close.
+        $('#folders li').click(function(event) {
+            event.stopImmediatePropagation();
+        });
+
+        $('div.thumb a.CKImageUse').click(function() {
+            var img = $(this).siblings('img');
+            window.opener.CKEDITOR.tools.callFunction(1, img.attr('title'));
+            window.close();
+        });
+
+        $('div.thumb a.CKImageDelete').click(function(event) {
+            event.preventDefault();
+            if (confirm('Are you sure you want to delete this image?')) {
+                var img = $(this).siblings('img').attr('title');
+                var href = window.location.href.replace(/(.*)browser.php(.*)/, '$1connector.php$2&command=DeleteFile&img=' + img);
+
+                window.location.href = href;
+            }
+        });
+
+        $('#imageDialog').dialog({
+            bgiframe : true,
+            autoOpen : false,
+            resizable: false,
+            modal : true,
+            buttons : {
+                Cancel : function() {
+                    $(this).dialog('close');
+                },
+                'Upload Selected File' : function() {
+                    if ($('#imageDialog form input[type=file]').val()) {
+                        $('.ui-dialog-buttonpane button').attr('disabled', true);
+                        $('#imageDialog form').trigger('submit');
+                    } else {
+                        alert('You need to select a file first');
+                    }
+                }
+            }
+        });
+
+        $('#upload').click(function() {
+            $('#imageDialog').dialog('open');
+        });
+
+        $('#newFolder').submit(IMAGE_SELECTOR.createFolder);
+        $('#folderDialog').dialog({
+            bgiframe : true,
+            autoOpen : false,
+            resizable: false,
+            modal : true,
+            buttons: {
+                Cancel : function() {
+                    $('#folderName').removeClass('ui-state-error');
+                    $(this).dialog('close');
+                },
+                'Create' : IMAGE_SELECTOR.createFolder
+            }
+        });
+        $('#folderNew').click(function() {
+            $('#folderDialog').dialog('open');
+        });
+        $('#folderDelete').click(function() {
+            if (confirm('Are you sure you want to delete this folder?')) {
+                var href = window.location.href.replace(/(.*)browser.php(.*)/, '$1connector.php$2&command=DeleteFolder');
+
+                window.location.href = href;
+            }
+        });
+    },
+
+    createFolder: function(event)
+    {
+        event.preventDefault();
+        //  don't submit empty folder
+        var folderName = $('#folderName');
+        var val = folderName.val();
+        if (val == '') {
+            alert('You need to type a folder name first');
+            return false;
+        } else {
+            $('.ui-dialog-buttonpane button').attr('disabled', true);
+            var href = window.location.href.replace(/(.*)browser.php(.*)/, '$1connector.php$2&command=CreateFolder&name=' + $('#folderName').val());
+            if (IMAGE_SELECTOR.parentFolder != null) {
+                href += '&parentFolder=' + IMAGE_SELECTOR.parentFolder;
+                IMAGE_SELECTOR.parentFolder = null;
+            }
+            window.location.href = href;
+        }
+    },
+
+       viewFolder: function(event)
+       {
+               location.href = $(this).attr('href');
+       }
+};
+
+$(document).ready(IMAGE_SELECTOR.init);
diff --git a/Toolkit/CKImages/styles.css b/Toolkit/CKImages/styles.css
new file mode 100755 (executable)
index 0000000..3787fea
--- /dev/null
@@ -0,0 +1,146 @@
+body {
+       font-family: arial, sans-serif;
+       font-size: 11px;
+       background: #E3E3C7;
+       margin: 0;
+       padding: 0;
+}
+#wrapper {
+       width: 720px;
+       height: 1%;
+       overflow: hidden;
+       margin: 10px 0px 5px 10px;
+}
+h1 {
+       font-size: 24px;
+       margin: 0 0 10px 0;
+}
+#toolbar {
+       background: #F1F1E3;
+       width: 124px;
+       border: 1px solid #D5D59D;
+       float: left;
+       padding: 8px;
+       margin-right: 10px;
+}
+#toolbar > ul {
+       border-bottom: 1px solid #333;
+       padding: 0 0 6px 0;
+       margin: 0 0 6px 0;
+       }
+#toolbar > ul, #toolbar > ul li {
+       list-style: none;
+       display: block;
+}
+#toolbar > ul li {
+       padding: 2px 2px 2px 26px;
+       line-height: 18px;
+       border: 1px solid #F1F1E3;
+       margin: 0;
+       background-position: 2px center;
+       background-repeat: no-repeat;
+       text-decoration: underline;
+       cursor: hand;
+       cursor: pointer;
+}
+#toolbar > ul li:hover {
+       border: 1px solid #D5D59D;
+       text-decoration: none;
+}
+#toolbar #upload {
+       background-image: url(http://app.gaslightmedia.com/assets/icons/image_add.png);
+}
+#toolbar #folderNew {
+       background-image: url(http://app.gaslightmedia.com/assets/icons/folder_add.png);
+}
+#toolbar #folderDelete {
+       background-image: url(http://app.gaslightmedia.com/assets/icons/folder_delete.png);
+}
+.tree ul {
+       margin: 0;
+       padding-top: 1px;
+}
+.tree li a {
+        background-image: url(http://app.gaslightmedia.com/assets/icons/folder.png);
+}
+.tree li.open {
+       background: none;
+       }
+#pred_1 {
+       padding-left: 3px;
+       padding-top: 3px;
+}
+.tree li li.open {
+       background: transparent url(http://app.gaslightmedia.com/libjs/jsTree/source/images/li.gif) no-repeat scroll 7px 7px;
+}
+/* Main Section */
+#photo-gallery {
+       width: 560px;   
+       height: 1%;
+       overflow: hidden;
+}
+.thumb {
+       width: 120px;
+       height: 150px;
+       float: left;
+       margin-right: 20px;
+       margin-bottom: 20px;
+       background: white;
+       font-size: 10px;
+}
+.rowTop {
+       height: 1%;
+       overflow: hidden;
+}
+.thumb img {
+       display: block;
+       margin: 0px 10px 2px 10px;
+       border: 1px dotted #ccc;
+       clear: left;
+}
+.CKImageUse {
+       display: block;
+       background: url(http://app.gaslightmedia.com/assets/icons/accept.png) no-repeat;
+       padding-left: 20px;
+       line-height: 16px;
+       margin: 5px 10px 0px 10px;
+       border: 1px solid #fff;
+       text-decoration: underline;
+}
+.CKImageUse:link {color: black;}
+.CKImageUse:visited {color: black;}
+.CKImageUse:hover {color: green; text-decoration: none; border: 1px solid white}
+.CKImageUse:actove {color: black;}
+
+.CKImageName {
+       display: none;
+}
+.CKImageDelete {
+       background: url(http://app.gaslightmedia.com/assets/icons/cross.png) no-repeat;
+       width: 16px;
+       height: 16px;
+       display: block;
+       float:  right;
+       text-indent: -9000px;
+       margin: 3px 2px;
+       margin-right: 6px;
+       }
+.CKImageView {
+       background: url(http://app.gaslightmedia.com/assets/icons/image.png) no-repeat;
+       width: 16px;
+       height: 16px;
+       display: block;
+       float:  left;
+       text-indent: -9000px;
+       margin: 3px 10px;
+}
+.CKImageProperties {
+       margin: 3px;
+       float: left;
+}
+.CKImageDate {
+       display: none;
+}
+#menuFolder, #menuImage, #column {
+       display: none;
+}
\ No newline at end of file
diff --git a/Toolkit/CKImages/templates/compiled/.cvsignore b/Toolkit/CKImages/templates/compiled/.cvsignore
new file mode 100644 (file)
index 0000000..7f1398d
--- /dev/null
@@ -0,0 +1 @@
+* */*
diff --git a/Toolkit/CKImages/templates/compiled/.keepme b/Toolkit/CKImages/templates/compiled/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Toolkit/CKImages/templates/thumbnails.html b/Toolkit/CKImages/templates/thumbnails.html
new file mode 100755 (executable)
index 0000000..e0e6289
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Thumbnail Images</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<link rel="stylesheet" type="text/css" href="glmappbaseurl/libjs/jqueryui/1.7.1/themes/base/ui.all.css">
+<link rel="stylesheet" type="text/css" href="glmappbaseurl/libjs/jsTree/source/tree_component.css">
+<link rel="stylesheet" type="text/css" href="styles.css">
+<script type="text/javascript" src="glmappbaseurl/libjs/jquery-1.3.2.min.js"></script>
+<script type="text/javascript" src="glmappbaseurl/libjs/jqueryui/1.7.1/ui/jquery-ui-1.7.1.custom.js"></script>
+<script type="text/javascript" src="glmappbaseurl/libjs/jsTree/libjs/css.js"></script>
+<script type="text/javascript" src="glmappbaseurl/libjs/jquery.listen.js"></script>
+<script type="text/javascript" src="glmappbaseurl/libjs/jquery.cookie.js"></script>
+<script type="text/javascript" src="glmappbaseurl/libjs/jsTree/source/tree_component.js"></script>
+<script type="text/javascript" src="libjs/image_selector.js"></script>
+</head>
+<body>
+       <div id="wrapper">
+        <h1>GLM Image Browser</h1>
+               <div id="main">
+                       <div id="toolbar">
+                               <ul>
+                                       <li id="upload">Upload New Image</li>
+                               </ul>
+                               <ul>
+                                       <li id="folderNew">Create New Folder</li>
+                                       <li id="folderDelete">Delete This Folder</li>
+                               </ul>
+                               <div id="folders" class="tree">
+                    Folders
+                    {folders:h}
+                               </div>
+                       </div><!-- /#toolbar -->
+
+                       <div id="photo-gallery" class="galleryRow">
+                               <div flexy:foreach="images,i" class="thumb">
+                                       <a href="{originalPath}{i[name_on_disk]:h}" target="_blank" class="CKImageView" title="View Full Image">View Full Image</a>
+                                       <div class="CKImageProperties">{i[width]:h}x{i[height]:h}</div>
+                                       <a href="#" class="CKImageDelete" title="Delete Image">Delete Image</a>
+                                       <img src="{imageManager}{i[name_on_disk]:h}" title="{originalPath}{i[name_on_disk]:h}" alt="{i[file_name]:h}">
+                                       <a href="#" class="CKImageUse">Insert this image</a>
+                                       <div class="CKImageName">{i[file_name]:h}</div>
+                                       <div class="CKImageDate">{i[create_date]:h}</div>
+                               </div>
+                       </div><!-- /#photo-gallery -->
+               </div><!--/#main -->
+    </div><!-- /#wrapper -->
+
+    <!-- dialog box for adding new folders -->
+    <div id="folderDialog" class="dialog" title="Create new folder">
+        <form id="newFolder">
+            <label for="folderName">Name</label>
+            <input type="text" name="folderName" id="folderName">
+        </form>
+    </div>
+
+    <!-- dialog box for adding new images -->
+    <div id="imageDialog" class="dialog" title="Upload new image">
+        {quickUploadForm:h}
+    </div>
+</body>
+</html>
diff --git a/Toolkit/Common.php b/Toolkit/Common.php
new file mode 100644 (file)
index 0000000..7f3eafb
--- /dev/null
@@ -0,0 +1,1217 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Common Toolkit application function repository
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Toolkit_Common
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @release     CVS: $Id: Common.php,v 1.51 2010/01/28 20:15:40 matrix Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Common collection of functions used throughout the GLM Toolkit
+ *
+ * @category  Toolkit
+ * @package      Toolkit_Common
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_Common
+{
+       //      {{{     properties
+
+       /**
+        * Who to send email to when a problem occurs on a live site
+        *
+        * This property doesn't matter for the development servers b/c the
+        * script will display the error encountered and terminate immediately.
+        * On the live site, a notification will be displayed to the user that
+        * an unexpected error has occured and will inform them to try again later.
+        * It will then send an email to the admin alerting them of the email.
+        *
+        * @var string
+        * @access protected
+        * @see Toolkit_Common::handleError()
+        */
+       protected static $admin = 'jamie@gaslightmedia.com';
+
+       /**
+        * Who to set the mail from when emailing errors
+        *
+        * @var string
+        * @access protected
+        * @see Toolkit_Common::handleError()
+        */
+    protected static $from = 'Gaslight Media Toolkit <server@gaslightmedia.com>';
+
+       //      }}}
+
+       //      {{{ arrayFlatten()
+
+       /**
+        * Recursively reduces multi-dimensional arrays to single-dimensional arrays
+        *
+        * @param array $array            The array to flatten.
+        * @param int   $preserveKeys How to handle array keys
+        *                                                         0 = Never
+        *                                                         1 = Strings
+        *                                                         2 = Always
+        * @param array &$newArray        The new created from the flattening
+        *
+        * @return array Single dimensional array.
+        * @access public
+        */
+       public function arrayFlatten($array,
+        $preserveKeys = 1,
+        &$newArray = Array()
+    ) {
+               foreach ($array as $key => $child) {
+                       if (is_array($child)) {
+                               $newArray =& Toolkit_Common::arrayFlatten(
+                    $child,
+                    $preserveKeys,
+                    $newArray
+                );
+                       } elseif ((int) $preserveKeys + (int) is_string($key) > 1) {
+                               $newArray[$key] = $child;
+                       } else {
+                               $newArray[] = $child;
+                       }
+               }
+               return $newArray;
+       }
+
+       //      }}}
+
+    //  {{{ cleanArray()
+
+    /**
+     * removes values from an array where the key ends in '_rmv'
+     *
+     * @param array &$values array to clean
+     *
+     * @return array  array w/ unneeded elements removed
+     * @access public
+     * @static
+     */
+    public static function cleanArray(&$values)
+    {
+               //      Get rid of any defined un-needed elements.
+               //      un-needed elements after the form is submitted are defined
+               //      by the ending _rmv name.
+               foreach ($values as $k => &$v) {
+                       if (preg_match('/^.+_rmv$/', $k)) {
+                               unset($values[$k]);
+                       }
+               }
+
+        return $values;
+    }
+
+    //  }}}
+       //      {{{     createEmailBody()
+
+       /**
+        * Convert the form into an acceptable table to include in email
+        *
+        * This function can be called from any form class to generate
+        * a HTML table that we can use in an email. Elements can be dynamically
+        * rendered to meet your needs if you wish.
+        *
+        * If you wish to have any element(s) rendered differently than what the
+        * form already rendered them as, you need to define a public method
+        * named "emailRenderElement" in the calling class that will accept an
+        * elements name and you can create the rendering template in that class.
+        *
+        * Example:
+        * This example will turn groups like radio buttons or checkboxes
+        * from lists like:
+        * [ ] element_one [x] element_two [x] element_three
+        * ( ) element_one (x) element_two ( ) element_three
+        * into lists like:
+        * [ ] element_one              ( ) element_one
+        * [x] element_two              (x) element_two
+        * [x] element_three    ( ) element_three
+        * <code>
+        * public function &emailRenderElement($e)
+        * {
+        *              switch ($e) {
+        *                      case 'element_one' :
+        *                      case 'element_two' :
+        *                      case 'element_three' :
+        *                              $renderer =& $this->defaultRenderer();
+        *                              $renderer->clearAllTemplates();
+        *                              $renderer->setGroupTemplate('{content}', $e);
+        *                              $renderer->setGroupElementTemplate('{element}<br>', $e);
+        *                              break;
+        *
+        *                      default :
+        *                              $renderer = null;
+        *                              break;
+        *              }
+        *
+        *              return $renderer;
+        *      }
+        * </code>
+        *
+        * @param array $newLabels       Assoc array of element names and new
+        *                                                       labels to be used in the email form.
+        *                                                       eg [$newLabels['element'] => 'Label']
+        * @param array $excludeList Any element that needs to be removed
+        *                                                       from the form when creating the table
+        *                                                       eg [$list = array(e1, e2, e3, etc..)]
+        *
+        * @return mixed The table body for the email.
+        */
+       public function createEmailBody(
+        array $newLabels = array(),
+        array $excludeList = array()
+    ) {
+               $this->freeze();
+               //      Get the values corresponding to the elements present in the form.
+               $formData = $this->exportValues();
+               //      The array keys holds all the names of the elements.
+               $elements = array_keys($formData);
+               //      Remove any unwanted elements from our elements array.
+               foreach ($excludeList as $trgt) {
+                       unset($elements[array_search($trgt, $elements)]);
+               }
+
+               //      Which row we are at.
+               $i     = 0;
+               $table = new HTML_Table(array('class' => 'data'));
+               //      Auto grow the table, since the forms will by dynamic in size.
+               $table->setAutoGrow(true);
+               //      Get the labels and values of the elements.
+               foreach ($elements as $name) {
+                       $e =& $this->getElement($name);
+                       //      Get the default HTML for each element.
+                       $html = $e->toHtml();
+                       //      If any elements need to have their html
+                       //      changed for an email, this function in the
+                       //      class should exist and will return a renderer
+                       //      object of how the element should be rendered.
+                       if (method_exists($this, 'emailRenderElement')) {
+                               $renderer =& $this->emailRenderElement($name);
+                               //      make sure we have an actual rendering object
+                               //      if the element doesn't need to be altered it should
+                               //      just return null.
+                               if (is_object($renderer)) {
+                                       $e->accept(&$renderer);
+                                       $html = $renderer->toHtml($name);
+                                       //      We have to reset the entire forms html
+                                       //      otherwise we'll just keep adding to it everytime
+                                       //      we render a new element.
+                                       //      This is a bit of a hack to make this work (because
+                                       //      the _html element is supposed to be a private
+                                       //      property)
+                                       $renderer->_html = null;
+                               }
+                       }
+                       //      Get the label for the element.
+                       $label = array_key_exists($name, $newLabels) ?
+                                       $newLabels[$name] :
+                                       $e->getLabel();
+
+                       //      Make the row and increment the row counter.
+                       $table->setCellContents($i, 0, $label);
+                       $table->setCellAttributes($i, 0, array('class' => 'label'));
+                       $table->setCellAttributes($i, 1, array('class' => 'field'));
+                       $table->setCellContents($i++, 1, $html);
+               }
+               return $table->toHtml();;
+       }
+
+       //      }}}
+       //      {{{     createSQLInsert()
+
+    /**
+     * Generates a properly formatted sql query to insert data into a table
+     *
+     * @param string $table   Name of the table to insert into
+     * @param array  $columns Array of column names you want to set in the
+        *                                                insert statement and bind names
+        *
+        * <code>
+        * Toolkit_Common::createSQLInsert('member', array('name', 'pos'));
+        * will create the sql statement
+        * INSERT INTO member (name, pos) VALUES(:name, :pos)
+        * </code>
+        *
+     * @return string Formatted SQL string
+     * @access public
+     * @static
+     */
+       public static function createSQLInsert($table, array $columns)
+       {
+               $params     = implode(', ', $columns);
+               $bindParams = ':' . implode(', :', $columns);
+
+               return "INSERT INTO $table ($params) VALUES ($bindParams)";
+       }
+
+       //      }}}
+       //      {{{     createSQLUpdate()
+
+    /**
+     * Generates a properly formatted sql query to update data in a table
+        *
+        * <code>
+        * Toolkit_Common::createSQLUpdate('member',
+        *                                                                 array('name', 'pos'),
+        *                                                                 array('id = :id');
+        * will create the sql statement
+        * UPDATE member SET name = :name, pos = :pos WHERE id = :id
+        * </code>
+     *
+     * @param string $table       Name of the table to update
+     * @param array  $columns     Array of columns names you want to update
+     * @param array  $constraints Constraints to apply to the table to prevent
+        *                                                        running the update on every row in the db
+        *
+     * @return string formatted query string
+     * @access public
+     * @static
+     */
+       public static function createSQLUpdate(
+        $table,
+        array $columns,
+        array $constraints = null
+    ) {
+               $length = count($columns);
+               for ($i = 0; $i < $length; ++$i) {
+                       $bindParams .= "{$columns[$i]} = :{$columns[$i]}";
+                       if ($i < ($length - 1)) {
+                               $bindParams .= ', ';
+                       }
+               }
+               $sql = "UPDATE $table SET $bindParams";
+
+               if (!empty($constraints)) {
+                       $sql .= ' WHERE ' . implode(' AND ', $constraints);
+               }
+
+               return $sql;
+       }
+
+       //      }}}
+    //  {{{ createTables()
+
+    /**
+     * Read file from parameter and use the PDO parameter to create process file
+     *
+     * @param PDO    $pdo  PHP Data Object to use for DB calls
+     * @param string $file full path of file to parse
+     *
+     * @return void
+     * @access public
+     * @static
+     */
+    public static function createTables(PDO $pdo, $file)
+    {
+        $sql = file_get_contents($file);
+        //  break multiple queries apart by ';'
+        $tok = strtok($sql, ';');
+        try {
+               //  while we have valid tokens, execute the query
+               //  and grab the next token
+               while ($tok !== false) {
+                   $pdo->query($tok);
+                   $tok = strtok(';');
+               }
+        } catch (PDOException $e) {
+               Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+       //      {{{ dieGracefully()
+
+    /**
+     * Gracefully exit from the script when an unrecoverable error is created
+     *
+     * @param string  $msg      Message to display to user
+     * @param mixed   $e        Error object
+     * @param boolean $moreInfo More debugging info when in development
+        *
+     * @return void
+     * @access public
+     */
+       public function dieGracefully($msg = null, $e = null, $moreInfo = false)
+       {
+               if (is_null($e)) {
+                       if (is_null($msg)) {
+                               die('There was an error, please try again later!');
+                       } else {
+                               die($msg);
+                       }
+               } else {
+                       echo $msg . '<br>';
+                       echo 'Error Caught.  <br>';
+                       echo 'Error: ' . $e->getMessage() . '<br>';
+                       if ($moreInfo) {
+                               echo 'Code: <pre>' . $e->getCode() . '</pre><br>';
+                               echo 'Debug Info: <pre>' . $e->getDebugInfo() . '</pre><br>';
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{     errorException()
+
+       /**
+        * Stops script on Exception error
+        *
+        * Stops the script when an Exception is raised inside a
+        * try/catch block.
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * Example usage:
+        * <code>
+        * try {
+               if ($foo != $bar) {
+                       throw new Exception ("Foo Doesn't equal Bar");
+               }
+        * } catch (Exception $e) {
+        *      return Toolkit_Common::handleError($e);
+        * }
+        * </code>
+        *
+        * @param Exception $e    Exception Object
+     * @param Mail      $mail What to use to send mail to admin
+        *
+        * @return false
+        * @access public
+     * @static
+        */
+       public static function errorException(Exception $e, Mail $mail = null)
+       {
+               if (!is_null($mail)) {
+            $subject = 'Exception Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorHTMLQuickFormError()
+
+       /**
+        * Handles PEAR Errors for our developers
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * HTML_QuickForm Example usage:
+        * <code>
+        * $e =& $this->getElement('elementName');
+        * if (PEAR::isError($e)) {
+        *      return Toolkit_Common::handleError($e);
+        * }
+        * </code>
+        *
+        * @param HTML_QuickForm_Error $e    QuickFormError Object
+     * @param Mail                 $mail What to use to send mail to admin
+        *
+        * @return false
+        * @access public
+        * @since Method available since Release 1.0.1
+     * @static
+        */
+       public static function errorHTMLQuickFormError(
+        HTML_QuickForm_Error $e,
+        Mail $mail = null
+    ) {
+               if (!is_null($mail)) {
+            $subject = 'PEAR Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+            echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorPDOException()
+
+       /**
+        * Stops script on database error
+        *
+        * Stops the script when a PDOException is raised inside a
+        * try/catch block.
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * Example usage:
+        * <code>
+        * try {
+        *      $sql = "
+        *               SELECT *
+        *                 FROM table_name
+        *                WHERE id = :id";
+        *
+        *      $stmt = $this->dbh->prepare($sql);
+        *      $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+        *      return $stmt->execute();
+        * } catch (PDOException $e) {
+        *      return Toolkit_Common::handleError($e);
+        * }
+        * </code>
+        *
+        * @param PDOException $e    PDO Error Object.
+     * @param Mail         $mail Mail object used to send admin email
+        *
+        * @return false
+        * @access public
+        * @since Method available since Release 1.0.1
+        */
+       public function errorPDOException(PDOException $e, Mail $mail = null)
+       {
+               if (!is_null($mail)) {
+            $subject = 'SQL Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorPEARError()
+
+       /**
+        * Handles PEAR Errors for our developers
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * @param PEAR_Error $e    PEARError Object
+     * @param Mail       $mail Mail object used to send admin email
+        *
+        * @return false
+        * @access public
+        * @since Method available since Release 1.0.1
+        */
+       public function errorPEARError(PEAR_Error $e, Mail $mail = null)
+       {
+               if (!is_null($mail)) {
+            $subject = 'PEAR Error for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorRuntimeException()
+
+       /**
+        * Stops script on runtime error
+        *
+        * Stops the script when a runtimeException is raised inside a
+        * try/catch block.
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * @param RuntimeException $e    PDO Error Object.
+     * @param Mail             $mail Mail object used to send admin email
+        *
+        * @return false
+        * @access public
+        * @since Method available since Release 1.0.2
+        */
+       public function errorRuntimeException(
+               RuntimeException $e,
+               Mail $mail = null
+       ) {
+               if (!is_null($mail)) {
+            $subject = 'Runtime Exception for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+       //      {{{     errorBadMethodCallException()
+
+       /**
+        * Stops script on bad method call error
+        *
+        * Stops the script when a badMethodCallException is raised inside a
+        * try/catch block.
+        *
+        * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+        * We don't show any error info, but let the user know an unexpected
+        * error has occured and then mail the error info the the admin.
+        *
+        * @param BadMethodCallException $e    PDO Error Object.
+     * @param Mail                   $mail Mail object used to send admin email
+        *
+        * @return false
+        * @access public
+        * @since Method available since Release 1.0.3
+        */
+       public function errorBadMethodCallException(
+               BadMethodCallException $e,
+               Mail $mail = null
+       ) {
+               if (!is_null($mail)) {
+            $subject = 'Bad Method Call Exception for ' . SITENAME;
+            self::mailError($mail, $subject);
+               } else {
+                       echo self::getErrorInfo($e);
+               }
+
+               return false;
+       }
+
+       //      }}}
+
+    //  {{{ filterURI()
+
+    /**
+     * Filters uri's before they are validated
+     *
+     * @param string $uri URI to filter
+     *
+     * @return mixed new uri if missing scheme
+     * @access public
+     * @static
+     */
+    public static function filterURI($uri)
+    {
+       $validProtocol = '/^https?\:\/\/.*/';
+       $invalidProtocol = '/^.*?\:\/\/.*/';
+       if (empty($uri)) {
+               //      Empty field, just return
+               return $uri;
+       } elseif (preg_match($validProtocol, $uri)) {
+               //      has valid protocol, return unchanged
+               //      should pass validation.
+               return $uri;
+       } elseif (!preg_match($invalidProtocol, $uri)) {
+               //      missing protocol, prepend default
+               //      http:// protocol and return.
+               return "http://$uri";
+       } else {
+               //      has invalid protocol, return unchanged
+               //      validation should catch this and throw error.
+               return $uri;
+       }
+    }
+
+    //  }}}
+    //  {{{ filterPhone()
+
+    /**
+     * Filters phone numbers before they are validated
+     *
+     * @param string $phone number to filter
+     *
+     * @return mixed newly formatted phone number
+     * @access public
+     * @static
+     */
+    public static function filterPhone($phone)
+    {
+        //  Ditch anything that is not a number
+        $number = preg_replace('/[^0-9]/', '', $phone);
+
+        //  Invalid Number, validation will catch error
+        $len = strlen($number);
+        if (($len < 10) || ($len > 11)) {
+            return $phone;
+        }
+
+        //  subscriber number
+        $sn = substr($number, -4);
+        //  city code
+        $cc = substr($number, -7, 3);
+        //  area code
+        $ac = substr($number, -10, 3);
+        if ($len == 11) {
+            //  country prefix
+            $cp = $number[0];
+        }
+
+        $filteredNumber = "($ac) $cc-$sn";
+        if (!is_null($cp)) {
+            $filteredNumber = "$cp $filteredNumber";
+        }
+
+        return $filteredNumber;
+    }
+
+    //  }}}
+
+       //      {{{ getCities()
+
+    /**
+     * Get an array of cities from the database
+     *
+     * @param PDO     $dbh    Database handler
+     * @param integer $state  State id the city is in
+     * @param integer $county County id the city is in
+     * @param integer $region Region id the city is in
+     *
+     * @return array states
+     * @access public
+     * @static
+     */
+       public static function getCities(
+               PDO $dbh,
+               $state = null,
+               $county = null,
+               $region = null
+       ) {
+               $param = array();
+               if (ctype_digit((string)$state)) {
+                       $param[] = 'state_id = ' . $dbh->quote($state);
+               }
+               if (ctype_digit((string)$county)) {
+                       $param[] = 'county_id = ' . $dbh->quote($county);
+               }
+               if (ctype_digit((string)$region)) {
+                       $param[] = 'region_id = ' . $dbh->quote($region);
+               }
+
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM city";
+
+                       if (!empty($params)) {
+                               $sql .= ' WHERE ' . implode(' AND ', $params);
+                       }
+                       $sql .= ' ORDER BY city_name';
+
+                       $stmt = $dbh->prepare($sql);
+                       $stmt->execute();
+
+                       $cities = array();
+                       while ($row = $stmt->fetch()) {
+                               $cities[$row['city_id']] = $row['city_name'];
+                       }
+
+                       return $cities;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+    //  {{{ getErrorInfo()
+
+    /**
+     * extract error info from error object
+     *
+     * @param mixed $obj Error object to get info for
+     *
+     * @return string formatted error information
+     * @access public
+     */
+    public function getErrorInfo($obj)
+    {
+        $state = '<b>' . get_class($obj) . ' error: </b>';
+
+        if (method_exists($obj, 'getMessage')) {
+            $state .= $obj->getMessage();
+            if (method_exists($obj, 'getDebugInfo')) {
+                $state .= '; ' . $obj->getDebugInfo();
+            }
+        }
+        if (method_exists($obj, 'getFile')) {
+            $state .= ' in <b>' . $obj->getFile() . '</b>';
+        }
+        if (method_exists($obj, 'getLine')) {
+            $state .= ' on line <b>' . $obj->getLine() . '</b>';
+        }
+        $state .= '<br>$_SERVER[\'QUERY_STRING\']: ' . $_SERVER['QUERY_STRING'] . "\n";
+        $state .= '<br>$_GET: <pre>' . print_r($_GET, true) . '</pre>';
+        $state .= '<br>$_POST: <pre>' . print_r($_POST, true) . '</pre>';
+        /*
+        if (method_exists($obj, 'getBacktrace')) {
+            $backtrace = print_r($obj->getBacktrace(), true);
+
+            $state .= "<br><pre>$backtrace</pre>";
+        }
+        */
+
+        return $state;
+    }
+
+    //  }}}
+       //      {{{     getHierarchicalTreeStructure()
+
+    /**
+     * Create a hierarchical tree stored in an linear array
+     *
+        * Produces a representation of a hierarchical tree structure into a
+        * linear array so you can iterate straight through to get the tree
+        * structure.
+     *
+     * @param PDO     $pdo         Database handler
+     * @param string  $table       Name of the source relation
+     * @param string  $key         Name of the key field
+     * @param string  $parent      Name of the parent-key field
+     * @param string  $order       Name of the field to order siblings by
+     * @param integer $start       Key value of the row to start at
+     * @param integer $maxDepth    Maximum depth to descend to, or zero
+        *                                                     for unlimited depth
+        * @param boolean $validParent exclude branches that have null
+     *                             parent values
+        *
+     * @return array   Linear array of tree structure
+     * @access public
+        * @see http://www.postgresql.org/doc/8.3/interactive/tablefunc.html#AEN104085
+     */
+       public function getHierarchicalTreeStructure(
+               PDO $pdo,
+        $table = 'bus_category',
+        $key = 'id',
+        $parent = 'parent',
+        $order = 'pos',
+        $start = 0,
+        $maxDepth = 0,
+        $validParent = true
+    ) {
+               try {
+                       $tree = array();
+
+                       $sql = "
+                SELECT *
+                  FROM connectby('$table', '$key', '$parent',
+                                                                '$order', '$start', $maxDepth)
+                                               as t(id text, parent text, level int, pos int)";
+
+                       if ($validParent) {
+                 $sql .= " WHERE parent is not null";
+                       }
+                       foreach ($pdo->query($sql) as $row) {
+                               $tree[$row['id']] = $row['level'];
+                       }
+
+                       return $tree;
+               } catch (PDOException $e) {
+                       return self::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     scriptsCompare()
+
+       /**
+        * make sure jquery lib is loaded first
+        *
+        * @param string $i script 1 to compare against script 2 ($j)
+        * @param string $j script 2 to compare against script 1 ($i)
+        *
+        * @return integer result of comparison
+        * @access public
+        * @static
+        */
+       public static function scriptsCompare($i, $j)
+       {
+               if ($i == GLM_APP_BASE_URL . 'libjs/jquery-1.3.2.min.js') {
+                       return -1;
+               } elseif ($j == GLM_APP_BASE_URL . 'libjs/jquery-1.3.2.min.js') {
+                       return 1;
+               } else {
+                       return 0;
+               }
+       }
+
+       //      }}}
+       //      {{{     getScripts()
+
+       /**
+        * Gets all scripts for the page
+        *
+        * @return string HTML markup for scripts
+        * @access public
+        * @static
+        */
+       public static function getScripts()
+       {
+               if (   !isset($GLOBALS['scripts'])
+                       || !is_array($GLOBALS['scripts'])
+                       || empty($GLOBALS['scripts'])
+               ) {
+                       return false;
+               }
+
+               $uniqueScripts = array_unique($GLOBALS['scripts']);
+               usort($uniqueScripts, array(self, 'scriptsCompare'));
+               $format = '<script type="text/javascript" src="%s"></script>';
+
+               $ret = '';
+               foreach ($uniqueScripts as $v) {
+                       $ret .= sprintf($format, $v) . "\n";
+               }
+
+               return $ret;
+       }
+
+       //      }}}
+       //      {{{ getStates()
+
+
+    /**
+     * Get an array of states from the database
+     *
+     * @param PDO     $dbh             Database handler
+     * @param boolean $unionStatesOnly If we want to only retrieve
+     *                                 the 50 US states
+     *
+     * @return array states
+     * @access public
+     * @static
+     */
+       public static function getStates(PDO $dbh, $unionStatesOnly = false)
+       {
+               if ($unionStatesOnly) {
+                       //      Just grab the 50 states of the union
+                       $where = "WHERE us_state = :bool";
+               }
+
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM state
+                           $where
+                                ORDER BY state_name";
+
+                       $stmt = $dbh->prepare($sql);
+                       if ($unionStatesOnly) {
+                               $stmt->bindValue(':bool', 1, PDO::PARAM_BOOL);
+                       }
+                       $stmt->execute();
+
+                       $states = array();
+                       while ($row = $stmt->fetch()) {
+                               $states[$row['state_id']] = $row['state_name'];
+                       }
+
+                       return $states;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     getStyleSheets()
+
+       /**
+        * Gets all style sheets for the page
+        *
+        * @return string HTML markup for stylesheets
+        * @access public
+        * @static
+        */
+       public static function getStyleSheets()
+       {
+               if (   !isset($GLOBALS['styleSheets'])
+                       || !is_array($GLOBALS['styleSheets'])
+                       || empty($GLOBALS['styleSheets'])
+               ) {
+                       return false;
+               }
+
+               $uniqueStyleSheets = array_unique($GLOBALS['styleSheets']);
+               $format = '<link type="text/css" rel="stylesheet" href="%s">';
+
+               $ret = '';
+               foreach ($uniqueStyleSheets as $v) {
+                       $ret .= sprintf($format, $v) . "\n";
+               }
+
+               return $ret;
+       }
+
+       //      }}}
+       //      {{{ getTableMetaData()
+
+       /**
+        * Gets the meta data of the calling classes table columns
+        *
+        * The table used when retrieving the meta data is defined
+        * in the class property $tableName. The class or parent class
+        * must also have a $tableMetaData property
+        *
+        * @param PDO    $pdo       Database Handler
+        * @param string $tableName The name of the table to get the meta data for.
+        * @param array  $clauses       Only retrieve meta data for certain column types
+        *
+        * @return array metadata for table
+        * @access protected
+        */
+       public function getTableMetaData(
+        PDO $pdo,
+        $tableName,
+        array $clauses = null
+    ) {
+               if (is_array($clauses)) {
+                       while ($c = current($clauses)) {
+                               $ands .= " data_type = '{$c}'";
+                               if (false !== next($clauses)) {
+                                       $ands .= " OR ";
+                               }
+                       }
+                       $ands = " AND ($ands)";
+               }
+               try {
+                       $sql  = "
+                               SELECT column_name, data_type
+                                 FROM information_schema.columns
+                                WHERE table_name = :tname
+                                $ands";
+                       $stmt = $pdo->prepare($sql);
+                       $stmt->bindParam(':tname', $tableName, PDO::PARAM_STR);
+
+                       $stmt->execute();
+
+            $metaData = array();
+                       while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $metaData[$row['column_name']] = $row['data_type'];
+                       }
+
+            return $metaData;
+               } catch (PDOException $e) {
+                       return self::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ handleError()
+
+       /**
+        * Handles various script error
+        *
+        * @param Object  $e                 Error Object
+        * @param boolean $developmentServer If we are on a development server
+        *
+        * @return false
+        * @access public
+     * @static
+        */
+       public static function handleError($e, $developmentServer = DEVELOPMENT)
+       {
+               $errorType = str_replace('_', '', get_class($e));
+        $errorType = "error$errorType";
+
+               if (method_exists(__CLASS__, $errorType)) {
+            if (!$developmentServer) {
+                //     Tell the user we encountered an Error.
+                               include_once BASE . "404.html";
+
+                $mail = Mail::factory('mail');
+                               self::$errorType($e, $mail);
+                               exit();
+            } else {
+                               return self::$errorType($e, $mail);
+                       }
+               } else {
+                       echo '<p>The system has encountered an un-recoverable error!</p>';
+               }
+       }
+
+       //      }}}
+
+    //  {{{ mailError()
+
+    /**
+     * Mails the error to the site admin
+     *
+     * @param Mail   $mail    Mail object to use
+     * @param string $subject Subject of email
+     *
+     * @return void
+     * @access public
+     * @static
+     */
+    public static function mailError(Mail $mail, $subject)
+    {
+        $msg = '<p>' . self::getErrorInfo($e) . '</p>';
+
+        $htmlMsg  = "<html><head></head><body>$msg</body></html>";
+        $crlf     = "\n";
+        $mimeMail = new Mail_mime($crlf);
+        $mimeMail->setFrom(self::$from);
+        $mimeMail->setSubject($subject);
+        $mimeMail->setHTMLBody($htmlMsg);
+        $mimeMail->setTXTBody($msg);
+
+        $body    = $mimeMail->get();
+        $headers = $mimeMail->headers();
+
+        $mail->send(self::$admin, $headers, $body);
+    }
+
+    //  }}}
+       //      {{{ multiDimArrayLocate()
+
+       /**
+        * Locates an array value in a multi-dimensional array
+        *
+        * @param array $array The Array which holds the value you need.
+        * @param mixed $text  The value that you are looking for.
+        *
+        * @return mixed The search result.
+        */
+    public function multiDimArrayLocate($array, $text)
+    {
+               if (!is_array($array)) {
+                       return;
+               }
+
+        foreach ($array as $k => $v) {
+            if (is_array($v)) {
+                $temp[$k] = self::multiDimArrayLocate($v, $text);
+                if ($temp[$k]) {
+                    $arrayResult[$k] = $temp[$k];
+                }
+            } else {
+                if ($v == $text) {
+                    $arrayResult[$k] = $v;
+                }
+            }
+        }
+        return $arrayResult;
+    }
+
+       //      }}}
+
+       //      {{{     processQuery()
+
+    /**
+     * Performs the sql insert statement
+     *
+     * If using a Postgresql driver for the PDO, metadata is used when
+        * binding parameters to the prepared statement.
+     *
+     * @param object $dbh       Database handler object
+        * @param string $tableName table used in query
+     * @param string $sql       sql query string
+     * @param array  $values    associative array of key/value pairs that will
+        *                                                  be used to bind to the sql query string
+        *
+     * @return boolean result of the execute statement on the database
+     * @access public
+     * @static
+     */
+       public static function processQuery(
+               PDO $dbh,
+               $tableName,
+               $sql,
+               array $values = null
+       ) {
+               $dbType = $dbh->getAttribute(PDO::ATTR_DRIVER_NAME);
+               if ($dbType == 'pgsql') {
+                       $md = Toolkit_Common::getTableMetaData($dbh, $tableName);
+               }
+               $stmt = $dbh->prepare($sql);
+               foreach ($values as $k => &$v) {
+                       if ($dbType == 'pgsql') {
+                               $metaData = $md[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } elseif ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      for empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               //      as empty values '', are not considered unique
+                               if (   empty($v)
+                    && $dataType !== PDO::PARAM_BOOL
+                    && $dataType !== PDO::PARAM_INT
+                ) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       } else {
+                               $stmt->bindParam(":$k", $v);
+                       }
+               }
+
+               return $stmt->execute();
+       }
+
+       //      }}}
+
+    //  {{{ recursiveArraySearch()
+
+    /**
+     * Recursive multi-dimensional array search
+     *
+     * @param string $n Needle
+     * @param array  $h Haystack
+     *
+     * @return mixed search result - false if not found
+     * @access public
+     * @static
+     */
+    public static function recursiveArraySearch($n, array $h)
+    {
+        foreach ($h as $i => $j) {
+            $curr = $i;
+            if ($n === $j
+                || (is_array($j) && self::recursiveArraySearch($n, $j) !== false)
+            ) {
+                    return $curr;
+            }
+        }
+
+        return false;
+    }
+
+    //  }}}
+
+       //      {{{ show()
+
+       /**
+        * Renders the calling class to the screen
+        *
+        * @access public
+        * @return string calls the toHTML function of calling class
+        */
+       public function show()
+       {
+               echo $this->toHTML();
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/BrochureRequest.php b/Toolkit/Contacts/BrochureRequest.php
new file mode 100755 (executable)
index 0000000..c8eb6b7
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+
+/**
+ * Brochure Request Guide
+ *
+ * PHP version 5
+ *
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: BrochureRequest.php,v 1.5 2010/01/28 16:34:53 jamie Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Short description for class
+ *
+ * Long description (if any) ...
+ *
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_Contacts_BrochureRequest
+{
+    // {{{ Class Properties
+    /**
+     * the name of the brochure download file
+     * @var    unknown
+     * @access protected
+     */
+    protected $pdfFile;
+
+    /**
+     * template for brochure
+     * @var    string
+     * @access protected
+     */
+    protected $template = 'brochurePage.html';
+
+    /**
+     * name of the brochure
+     * @var    unknown
+     * @access protected
+     */
+    protected $brochureName;
+    // }}}
+    // {{{ __construct()
+    /**
+        * Class constructor
+     *
+     * @param object $pdo PHP Data Object
+     *
+     * @return void
+     * @access public
+     */
+    function __construct(PDO $pdo)
+    {
+        $this->brochureName = SITENAME.' Brochure';
+        $this->dbh = $pdo;
+    }
+    // }}}
+    // {{{ show()
+    /**
+     * call toHtml
+     *
+     * @return void
+     * @access public
+     */
+    function show()
+    {
+        echo $this->toHtml();
+    }
+    // }}}
+    // {{{ toHtml()
+    /**
+     * create HTML output
+     *
+     * @return object html
+     * @access public
+     */
+    function toHtml()
+    {
+        $options                = $GLOBALS['flexyOptions'];
+        $options['templateDir'] = BASE.'Toolkit/Contacts/templates';
+        $options['compileDir']  = BASE.'Toolkit/Contacts/templates/compiled';
+        $tpl                    = new HTML_Template_Flexy($options);
+
+        $page           = new StdClass;
+        $page->brochure = $this->brochureName;
+
+        // set the pdf form
+        $pdfForm = new Toolkit_Contacts_PdfForm(
+                       'pdf_form',
+            'post',
+            null,
+            null,
+            null,
+            true
+               );
+
+        $page->pdfForm = $pdfForm->toHtml();
+
+        // set the contact form
+        $contactForm = new Toolkit_Contacts_ContactUs(
+            $this->dbh,
+            'contact',
+            'post',
+            null,
+            null,
+            null,
+            true
+               );
+
+        $contactForm->subject = 'Brochure Request from demo site';
+        $contactForm->configureForm();
+        $contactForm->useCaptcha(true);
+        $page->contactForm    = $contactForm->toHtml();
+
+        if ($pdfForm->sent) {
+            $page->contactForm = '';
+        } elseif ($contactForm->sent) {
+            $page->pdfForm = '';
+        }
+
+        $tpl->compile($this->template);
+        return $tpl->bufferedOutputObject($page);
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/Contacts/ContactUs.php b/Toolkit/Contacts/ContactUs.php
new file mode 100755 (executable)
index 0000000..824f31d
--- /dev/null
@@ -0,0 +1,1110 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Contacts
+ * @package  Toolkit_Contacts
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: ContactUs.php,v 1.30 2010/01/28 16:33:01 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Error codes for Toolkit_Contacts_ContactUs
+ *
+ * Codes are mapped to textual messaged by errorMessage() method,
+ * if you add a new code be sure to add a new message for it to errorMessage()
+ *
+ * @see Toolkit_Contacts_ContactUs::errorMessage()
+ */
+define('FORM_OK', 1);
+define('FORM_ERROR', -1);
+define('NO_RECORD', -2);
+define('INVALID_DB', -3);
+define('MISSING_CONSTANT', -4);
+define('MISSING_CONTACT_TYPE', -5);
+
+/**
+ * GLM Contact Us form
+ *
+ * This form handles rendering and processing the contact us form.
+ * Controls the email functionality of the form, whether the client
+ * has a contact DB to store contact records and how to insert/update
+ * submitted form values.
+ *
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ * @see       Toolkit_FormBuilder
+ */
+class Toolkit_Contacts_ContactUs
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+       //      {{{     properties
+
+    /**
+     * Table in Database which holds the contact data
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'contact';
+
+    /**
+     * Table meta data
+        *
+        * This is used when inserting/updating data for the records
+        * so the PDO's can use explicit data types for the parameters.
+        *
+     * @var    array
+     * @access public
+     */
+       public $tableMetaData = array();
+
+       /**
+        * Contact type to be inserted into the DB as when the form is submitted
+        *
+        * This property is only valid when the [hasContactDB] property is set
+        * to true.
+        *
+        * N.B.
+        * If you subclass this class out to other forms that are
+        * inserted into the contact db, be sure to make each one of their
+        * contactType properties unique.  We don't check for duplicates.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $contactType = '1';
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * protected $email = false;
+        * </code>
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $email;
+
+    /**
+     * From header in the owner email
+        *
+        * This just sets the From header in the owner email
+        * SITENAME <from@email.com>
+        *
+        * It gets set to the constant SITENAME in the constructor if you leave
+        * empty here, but you can set it to something different here to override
+        * that if you desire.
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $siteName;
+
+    /**
+        * Email subject and <h1> header in email
+        *
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string
+     * @access protected
+     */
+       public $subject;
+
+    /**
+     * Whether the site has a contact DB to store contact records
+        *
+        * If this value is set to false, an email will still be sent to the
+        * addressed specified in the email property.
+        *
+     * @var    boolean
+     * @access protected
+     */
+       protected $hasContactDB = true;
+
+    /**
+     * The interests from the contact db
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $inquiries = array();
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $successMsg = '
+               <div id="form-success-top">
+                       Thank you for your questions or comments!
+               </div>';
+
+    /**
+     * Extra rules for processesing
+        *
+        * This registers the Zip validation rules (and any others listed) for
+        * QuickForm.
+        *
+        * Zip validation checks both US and Canadian Zip codes
+        *
+     * @var    array
+     * @access protected
+        * @see    app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rules/Zip.php
+     */
+       protected $registeredRules = array(
+        'zip',
+        'phone',
+        array(
+            'checkEmail',
+            'callback',
+            'email',
+            'Validate'
+        ),
+    );
+
+    /**
+     * Options for flexy templating engine
+        *
+        * Pulls the preset options from the setup.phtml file
+        * overwrites the templateDir and compileDir to match this classes needs
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $flexyOptions;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param object $pdo         PHP Data Object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access public
+        * @link   http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html
+        * @see    HTML_QuickForm
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               //      Make sure these end cases are never met.
+               //      These are more for the development phase.
+               if ($this->email === false && $this->hasContactDB === false) {
+                       PEAR::raiseError(
+                null,
+                NO_RECORD,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_bool($this->hasContactDB)) {
+                       PEAR::raiseError(
+                null,
+                INVALID_DB,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               //      we haven't defined the FROM_NEWS_EMAIL constant and
+               //      the email will default to relying on it.
+               if (   !defined('FROM_NEWS_EMAIL')
+            && (empty($this->email) && $this->email !== false)
+        ) {
+                       PEAR::raiseError(
+                'You need to define the FROM_NEWS_EMAIL
+                                constant for this form to work correctly',
+                MISSING_CONSTANT,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_numeric($this->contactType) && $this->hasContactDB) {
+                       PEAR::raiseError(
+                null,
+                MISSING_CONTACT_TYPE,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+
+               //      Default Renderer Form templates for QuickForm in respect to this
+               //      classes needs.
+               if ($this->email !== false && empty($this->email)) {
+                       //      Set to false to turn off email function.
+                       $this->email = OWNER_EMAIL;
+               }
+               if (empty($this->siteName)) {
+                       $this->siteName = SITENAME;
+               }
+               if (empty($this->subject)) {
+                       $this->subject = 'Contact Request from website ' . SITENAME;
+               }
+
+               /**
+                * Where are the flexy templates stored at for this class.
+                */
+               define('TEMPLATES_DIR', BASE . 'Toolkit/Contacts/templates');
+
+               /**
+                * Where are the compiled flexy templates stored at for this class.
+                */
+               define('COMPILED_DIR', BASE . 'Toolkit/Contacts/templates/compiled');
+               $oldUmask = umask(0);
+               if (!is_dir(TEMPLATES_DIR)) {
+                       mkdir(TEMPLATES_DIR, 0770, true);
+               }
+               if (!is_dir(COMPILED_DIR)) {
+                       mkdir(COMPILED_DIR, 0770, true);
+               }
+               umask($oldUmask);
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+
+               $var = basename(__FILE__, '.php');
+
+               $callbackUrl = ($_SERVER['HTTPS'] == 'on') ?
+                                                         BASE_SECURE_URL : BASE_URL;
+
+               $this->captchaOptions = array(
+                       'width' => 100,
+                       'height' => 50,
+                       'callback' => "{$callbackUrl}Toolkit/qfcaptcha.php?var=$var",
+                       'sessionVar' => $var,
+                       'imageOptions' => array(
+                               'font_size' => 20,
+                               'font_path' => GLM_APP_BASE . 'glmPEAR/Image/Canvas/Fonts/',
+                               'font_file' => 'times.ttf',
+                               'background_color' => '#cccccc',
+                               'obfuscation' => false,
+                               'angle' => true,
+                       ),
+               );
+       }
+
+       //      }}}
+
+       //      {{{     configureConstats()
+
+    /**
+     * Constant variables for the form
+        *
+        * These values won't get overridden by POST or GET vars
+     *
+     * @return void
+     * @access public
+     */
+       public function configureConstants()
+       {
+               $constants = array(
+                       'user_agent' => $_SERVER['HTTP_USER_AGENT'],
+                       'remote_addr' => $_SERVER['REMOTE_ADDR'],
+               );
+               $this->setupConstants($constants);
+       }
+
+       //      }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     *
+     * @return void
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        $defaults = array(
+            'state' => '',
+            'mail_ok' => 1
+        );
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     *
+     * @return void
+     * @access public
+     */
+       public function configureElements()
+       {
+               $e = array();
+               $this->setInterestFields();
+               //      Grouped Elements are defined here.
+               $this->interestsGroups =& $this->getInterestFields();
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'user_agent'
+               );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'remote_addr'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fname',
+                       'display' => 'First Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'lname',
+                       'display' => 'Last Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address',
+                       'display' => 'Address 1'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address2',
+                       'display' => 'Address 2'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'city',
+                       'display' => 'City'
+               );
+        $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'state',
+                       'display' => 'State/Province',
+                       'opts'    => $GLOBALS['states']
+               );
+        $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'zip',
+                       'display' => 'ZIP/Postal Code'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email',
+                       'display' => 'Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email_rmv',
+                       'display' => 'Verify Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Phone'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fax',
+                       'display' => 'Fax'
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'comments',
+                       'display' => 'Comments'
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'mail_ok',
+                       'display' => 'Yes, I would like to receive Email Newsletters',
+                       'opts'    => 'Yes',
+                       'val'     => array(0, 1)
+               );
+        if (is_array($this->interestsGroups)) {
+            foreach ($this->interestsGroups as $group => $gData) {
+                $this->myGroups[] = $gData;
+                $e[] = array(
+                    'type'       => 'group',
+                    'req'        => false,
+                    'name'       => 'interest['.$group.']',
+                    'group'         => $gData,
+                    'label'      => $group,
+                    'seperator'  => ' ',
+                    'appendName' => true
+                );
+            }
+        }
+               $e[] = array(
+                       'type'    => 'CAPTCHA_Image',
+                       'req'     => false,
+                       'name'    => 'captcha_question',
+                       'display' => 'Verification code',
+                       'opts'    => $this->captchaOptions
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'captcha_rmv',
+                       'display' => 'Enter verification code'
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'submit_rmv',
+                       'display' => 'Submit Form'
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     *
+        * Adds validation rules for the given fields
+     *
+     * @return void
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+               //      Form Rules
+               $r[] = array(
+                       'element'    => array('email', 'email_rmv'),
+                       'message'    => 'ERROR: Your Email Addresses Do Not Match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'email',
+                       'message'    => 'ERROR: Invalid Email Format!',
+                       'type'       => 'checkEmail',
+                       'format'     => array('use_rfc822' => true),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        /*
+               $r[] = array(
+                       'element'    => 'state',
+                       'message'    => 'ERROR: Invalid State!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        */
+               $r[] = array(
+                       'element'    => 'phone',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'fax',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'zip',
+                       'message'    => 'ERROR: Invalid Zip!',
+                       'type'       => 'zip',
+                       'format'     => array('requireDBCheck' => false),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'mail_ok',
+                       'message'    => 'ERROR: Invalid Value!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'captcha_rmv',
+                       'message'    => 'ERROR: Incorrect verification code!',
+                       'type'       => 'CAPTCHA',
+                       'format'     => $this->captchaQuestion,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     *
+        * Applies a data filter for the given fields when the form is submitted
+     *
+     * @return void
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Helper function, configures the entire form
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm()
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules();
+        $this->configureDefaults();
+        $this->configureConstants();
+    }
+
+    //  }}}
+    //  {{{ contactExists()
+
+    /**
+     * Checks for a duplicate email address already in the DB.
+     *
+     * @param string $email The email address to check for in the DB
+     *
+     * @return boolean If the email address already exists
+     * @access protected
+     */
+    protected function contactExists($email)
+    {
+               //      Check if a contact w/ the submitted email already exists.
+               //      if so, then we need to update, if not then do a fresh insert.
+               try {
+                       $sql = "
+                               SELECT count(*) AS count
+                                 FROM {$this->tableName}
+                                WHERE email   = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $email, PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('count', $contactExists);
+                       $stmt->fetch();
+
+            return (bool) $contactExists;
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+    }
+
+    //  }}}
+
+       //      {{{     emailOwner()
+
+    /**
+     * Emails the owner the submitted data from the submitted form
+     *
+        * Uses a flexy template to render a nice looking html email.
+        * Fills in the supplied data from the form and doesn't add the
+        * empty fields the user didn't fill in.
+        *
+     * @param string $mailFactory What type of mail factory should we use
+     *
+     * @return boolean result of the mailing
+     * @access protected
+     */
+       protected function emailOwner($mailFactory = 'mail')
+       {
+               if (!$this->email) {
+                       return;
+               }
+
+               $hasInterestField = $this->elementExists('interest');
+
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+        // for comments textarea need to replace newlines with br
+        $this->formData['comments']['element'] = nl2br($this->getSubmitValue('comments'));
+
+               $page->email_from  = OWNER_EMAIL;
+               $page->subject     = $this->subject;
+               $page->client_info = $this->clientInfo;
+               $page->fname       = $this->getSubmitValue('fname');
+               $page->lname       = $this->getSubmitValue('lname');
+               $page->formData    = $this->formData;
+
+               if ($hasInterestField) {
+                       //      Clean up the interests so they will look nice in the email
+                       $page->formData['interest']['nowrap']  = 'nowrap';
+                       $page->formData['interest']['element'] = null;
+
+                       $g  =& $this->getElement('interest');
+            $ge =& $g->getElements();
+
+                       $interests = array();
+                       foreach ($ge as $e) {
+                               if ($e->getChecked()) {
+                                       $interests[] = $e->getText();
+                               }
+                       }
+                       $page->formData['interest']['element'] = implode('<br>', $interests);
+               }
+
+               if ($this->elementExists('mail_ok')) {
+                       //      Clean up the mail_ok flag so its human readable
+                       $page->formData['mail_ok']['element']
+                = ($page->formData['mail_ok']['element']) ? 'Yes' : 'No';
+               }
+
+               $template->compile('emailOwner.tpl');
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               if ($hasInterestField) {
+                       //      Text version can't have HTML in it
+                       //      so reset the interests to use commas
+                       $page->formData['interest']['element'] = implode(", ", $interests);
+               }
+               $msg  = "{$page->subject}\n\n";
+               $msg .= "From {$page->fname} {$page->lname}\n\n";
+               $msg .= "Information\n\n";
+               foreach ($page->formData as $i) {
+                       $msg .= "{$i['label']}: {$i['element']}\n";
+               }
+
+        $mimeMail = new Mail_mime("\n");
+               $mimeMail->setFrom("Online Form <{$page->email_from}>");
+               $mimeMail->setSubject($this->subject);
+               $mimeMail->setHTMLBody($htmlMsg);
+               $mimeMail->setTXTBody($msg);
+
+               $mail =& Mail::factory($mailFactory);
+               $body = $mimeMail->get();
+
+        $setHeader['Reply-To'] = "{$this->getSubmitValue('fname')} {$this->getSubmitValue('lname')} <{$this->getSubmitValue('email')}>";
+
+               $headers = $mimeMail->headers($setHeader);
+
+               $res = $mail->send($this->email, $headers, $body);
+               if (PEAR::isError($res)) {
+                       return Toolkit_Common::handleError($res);
+               } else {
+                       return $res;
+               }
+       }
+
+       //      }}}
+       //      {{{     error()
+
+    /**
+     * Display errors with the form to the user
+     *
+     * @param object $error PEAR Error Object
+        *
+     * @return void
+     * @access public
+     */
+       public function error($error)
+       {
+               //      make the variables static so that is only has to do the defining
+               //      on the first call.
+               static $errorMessages;
+               static $className;
+
+               //      define the various error messages
+               if (!isset($errorMessages)) {
+                       $className     = get_class($this);
+                       $errorMessages = array(
+                               FORM_OK                      => 'No error',
+                               FORM_ERROR                   => 'Unknown error',
+                               NO_RECORD                    => 'Setting both properties (email and hasContactDB) to false in the <i>' . $className . '</i> class will result in no email record being sent and no record being inserted into the database.  There will be no record that this form was ever filled out.',
+                               INVALID_DB                   => 'Please set the property hasContactDB to a boolean value in the class <i>' . $className . '</i> before continuing',
+                               MISSING_CONSTANT     => 'You have failed to set a CONSTANT for the class <i>' . $className . '</i> to function properly',
+                               MISSING_CONTACT_TYPE => 'Please set the property contactType in the class <i>'. $className . '</i> before continuing',);
+               }
+
+               if (!is_null($error->message)) {
+                       $message = $error->message;
+               } elseif (isset($errorMessages[$error->code])) {
+                       $message = $errorMessages[$error->code];
+               } else {
+                       $message = $errorMessages[$error->code];
+                       $message = $errorMessages[FORM_ERROR];
+               }
+
+               echo "<div id=\"form-warning-top\">{$message}</div>";
+       }
+
+       //      }}}
+
+       //      {{{     getInterestFields()
+
+    /**
+     * Returns the field definitions of the contact db interest fields
+     *
+     * @return array     Group definitions for the interest fields
+     * @access protected
+     */
+       protected function getInterestFields()
+       {
+               if (is_array($this->inquiries)) {
+            foreach ($this->inquiries as $group => $data) {
+                foreach ($data as $k => $v) {
+                    $interests[$group][] = array('type' => 'checkbox',
+                                             'req' => false,
+                                             'name' => $k,
+                                             'opts' => $v);
+                }
+                       }
+               }
+
+               return $interests;
+       }
+
+       //      }}}
+
+       //      {{{     insertData()
+
+    /**
+     * Inserts contact data into the contact db
+     *
+     * @param array $values submitted values
+        *
+     * @return object result of db insert query
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        unset($values['comments']);
+               $values['contact_type'] = ":{$this->contactType}:";
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+            foreach ($values['interest'] as $iGroup => $interests) {
+                           $newInterest[] = implode(':', array_keys($interests));
+            }
+            if (is_array($newInterest)) {
+                $values['interest'] = ':' . implode(':', $newInterest) . ':';
+            }
+               }
+               try {
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     *
+     * @param array $values Form submitted values
+        *
+     * @return array     Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+               //      Form data used for the insert/update sql queries and
+               //      the form email.
+               $e = array(
+                       'user_agent',
+                       'remote_addr',
+                       'contact_type',
+               );
+               $this->setFormData($e);
+
+
+               //      If no contact db, return true so we can send owner email.
+               if (!$this->hasContactDB) {
+                       return true;
+               }
+
+        //  Get rid of any elements in the values array that
+        //  aren't going to be used when inserting/updating the db.
+        $values = Toolkit_Common::cleanArray($values);
+
+        //  Send data off to StreamSend
+        if (   defined('STREAMSEND_FORMS_API')
+            && STREAMSEND_FORMS_API
+            && $values['mail_ok']
+        ) {
+            // Insert the record into the streamsend server
+            $streamSend = new Toolkit_Contacts_StreamSend();
+            $streamSend->addContact($values);
+        }
+
+        //  Check if we are updating an existing contact or not
+        //  question: is this the best approach?  what if someone else
+        //  sends a form through w/ different data but the same emil addy
+        //  the old users data can be completely wiped out.
+        $existingContact = $this->contactExists($values['email']);
+
+               if ($existingContact) {
+                       return $this->updateData($values);
+               } else {
+                       return $this->insertData($values);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setInterestFields()
+
+    /**
+     * Contact DB interests
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setInterestFields()
+       {
+               try {
+                       $sql = "
+                SELECT contact_inq.*, inq_group.name
+                  FROM contact_inq LEFT OUTER JOIN inq_group ON (contact_inq.groupid = inq_group.id)
+                 ORDER BY groupid, pos";
+
+            $i = array();
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $i[$row['name']][$row['id']] = $row['header'];
+                       }
+
+                       $this->inquiries = $i;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setupRenderers()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Custom rendering templates for special fields on the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req"> * </span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="req"> {error} </div><!-- END error -->';
+               $renderer->setElementTemplate('<tr><td colspan="2" class="fieldcell checkbox">'.$required.'{label}'.$error.'{element}</td></tr>', 'interest');
+        if (is_array($this->interestsGroups)) {
+            foreach ($this->interestsGroups as $group => $gData) {
+                $renderer->setGroupTemplate('<br>{content}', 'interest['.$group.']');
+                $renderer->setGroupElementTemplate('{element}', 'interest['.$group.']');
+                       $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'interest['.$group.']');
+            }
+        }
+               $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'comments');
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'submit_rmv');
+
+               $renderer->setElementTemplate('<tr><td class="labelcell"><label>{label}</label></td><td class="fieldcell captcha">{element}</td></tr>', 'captcha_question');
+               $renderer->setElementTemplate('<tr><td class="labelcell">'.$required.'<label>{label}</label></td><td class="fieldcell">'.$error.'{element}<span class="tooltip" title="Verification Code|To help us distinguish between information submitted by individuals and those automatically entered by software robots, please type the letters shown.">What is this?</span></td></tr>', 'captcha_rmv');
+       }
+
+    //  @codeCoverageIgnoreEnd
+       //      }}}
+       //      {{{     toHtml()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     *
+        * destroying and resetting the captcha value dis-allows someone from
+        * re-sending a form on a previous captcha.
+        *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHtml()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->captchaQuestion->destroy();
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                               $this->emailOwner();
+                               $output = $this->successMsg;
+                       }
+            $this->sent = true;
+               } elseif ($this->isSubmitted()) {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+
+       //      {{{     updateData()
+
+    /**
+     * Updates the contact in the contact db
+     *
+     * @param array $values Form submitted values
+        *
+     * @return object    Result of the update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+        unset($values['comments']);
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+            foreach ($values['interest'] as $iGroup => $interests) {
+                           $newInterest[] = implode(':', array_keys($interests));
+            }
+            if (is_array($newInterest)) {
+                $values['interest'] = ':' . implode(':', $newInterest) . ':';
+            }
+               }
+
+               try {
+                       //      Get all the existing contact type data
+                       $sql = "
+                               SELECT contact_type
+                                 FROM {$this->tableName}
+                                WHERE email = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $values['email'], PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('contact_type', $cType);
+                       $stmt->fetch();
+
+                       $existingTypes = explode(':', $cType);
+                       if (!in_array($this->contactType, $existingTypes)) {
+                               $values['contact_type'] = "$cType{$this->contactType}:";
+                       }
+
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('email = :email')
+            );
+
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/PdfForm.php b/Toolkit/Contacts/PdfForm.php
new file mode 100755 (executable)
index 0000000..0d6ff50
--- /dev/null
@@ -0,0 +1,895 @@
+<?php
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Contacts
+ * @package  Toolkit_Contacts
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: PdfForm.php,v 1.9 2010/01/28 16:33:27 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Error codes for Toolkit_Contacts_PdfForm
+ *
+ * Codes are mapped to textual messaged by errorMessage() method,
+ * if you add a new code be sure to add a new message for it to errorMessage()
+ *
+ * @see Toolkit_Contacts_ContactUs::errorMessage()
+ */
+define('FORM_OK', 1);
+define('FORM_ERROR', -1);
+define('NO_RECORD', -2);
+define('INVALID_DB', -3);
+define('MISSING_CONSTANT', -4);
+
+/**
+ * GLM Contact Us form
+ *
+ * This form handles rendering and processing the contact us form.
+ * Controls the email functionality of the form, whether the client
+ * has a contact DB to store contact records and how to insert/update
+ * submitted form values.
+ *
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Contacts_PdfForm extends Toolkit_FormBuilder
+{
+       //      {{{     properties
+
+    /**
+     * Table in Database which holds the contact data
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'contact';
+
+    /**
+     * Table meta data
+        *
+        * This is used when inserting/updating data for the records
+        * so the PDO's can use explicit data types for the parameters.
+        *
+     * @var    array
+     * @access public
+     */
+       public $tableMetaData;
+
+    /**
+     * Used in the email template for the client info string at the bottom
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $clientInfo = array(
+               'name'    => 'Gaslight Media',
+               'address' => '120 E. Lake St.',
+               'city'    => 'Petoskey',
+               'state'   => 'MI',
+               'zip'     => '49770',
+               'phone'   => '231.487.0697',
+       );
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * protected $email = false;
+        * </code>
+        *
+     * @var    unknown
+     * @access protected
+     */
+       protected $email;
+
+    /**
+     * From header in the owner email
+        *
+        * This just sets the From header in the owner email
+        * SITENAME <from@email.com>
+        *
+        * It gets set to the constant SITENAME in the constructor if you leave
+        * empty here, but you can set it to something different here to override
+        * that if you desire.
+        *
+     * @var    unknown
+     * @access protected
+     */
+       protected $siteName;
+
+    /**
+        * Email subject and <h1> header in email
+        *
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $subject;
+
+    /**
+        * pdfFileName
+        *
+        * Just the filename not the path.  File needs to be in BASE.'assets/' dir
+        *
+     * @var    string
+     * @access protected
+     */
+    protected $pdfFileName = 'brochure.pdf';
+
+    /**
+     * Whether the site has a contact DB to store contact records
+        *
+        * If this value is set to false, an email will still be sent to the
+        * addressed specified in the email property.
+        *
+     * @var    boolean
+     * @access protected
+     */
+       protected $hasContactDB = true;
+
+    /**
+     * The interests from the contact db
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $inquiries = array();
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $successMsg = '
+               <div id="form-success-top">
+        Thank you for your Request.  An email has been sent with
+        directions for the pdf download.
+               </div>';
+
+    /**
+     * Extra rules for processesing
+        *
+        * This registers the Zip validation rules (and any others listed) for
+        * QuickForm.
+        *
+        * Zip validation checks both US and Canadian Zip codes
+        *
+     * @var    array
+     * @access protected
+        * @see    app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rules/Zip.php
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Options for flexy templating engine
+        *
+        * Pulls the preset options from the setup.phtml file
+        * overwrites the templateDir and compileDir to match this classes needs
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $flexyOptions;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        *
+        * @access public
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               //      Make sure these end cases are never met.
+               //      These are more for the development phase.
+               if ($this->email === false && $this->hasContactDB === false) {
+                       PEAR::raiseError(
+                null,
+                NO_RECORD,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_bool($this->hasContactDB)) {
+                       PEAR::raiseError(
+                null,
+                INVALID_DB,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               //      we haven't defined the FROM_NEWS_EMAIL constant and
+               //      the email will default to relying on it.
+               if (   !defined('FROM_NEWS_EMAIL')
+            && (empty($this->email) && $this->email !== false)
+        ) {
+                       PEAR::raiseError(
+                'You need to define the FROM_NEWS_EMAIL
+                                constant for this form to work correctly',
+                MISSING_CONSTANT,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+        }
+
+           $this->successMsg = '
+               <div id="form-success-top">
+        Thank you for requesting the '.SITENAME.' Brochure. You have been sent
+        an email with a link to download our Brochure, which has been saved as
+        a PDF. You will need Adobe Acrobat Reader to view this document. If you
+        do not have Adobe Acrobat Reader, <a
+        href="http://www.adobe.com/products/acrobat/readstep2.html"
+        target="_blank">click here</a> to install.
+               </div>';
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               if ($this->email !== false && empty($this->email)) {
+                       //      Set to false to turn off email function.
+                       $this->email = OWNER_EMAIL;
+               }
+               if (empty($this->siteName)) {
+                       $this->siteName = SITENAME;
+               }
+               if (empty($this->subject)) {
+                       $this->subject = "Your Pdf request from website " . SITENAME;
+               }
+
+               /**
+                * Where are the flexy templates stored at for this class.
+                */
+               define('TEMPLATES_DIR', BASE . 'Toolkit/Contacts/templates');
+
+               /**
+                * Where are the compiled flexy templates stored at for this class.
+                */
+               define('COMPILED_DIR', BASE . 'Toolkit/Contacts/templates/compiled');
+               $oldUmask = umask(0);
+               if (!is_dir(TEMPLATES_DIR)) {
+                       mkdir(TEMPLATES_DIR, 0770, true);
+               }
+               if (!is_dir(COMPILED_DIR)) {
+                       mkdir(COMPILED_DIR, 0770, true);
+               }
+               umask($oldUmask);
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+
+               $var = basename(__FILE__, '.php');
+
+               $callbackUrl = ($_SERVER['HTTPS'] == 'on') ?
+                                                         BASE_SECURE_URL : BASE_URL;
+
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+               $this->configureConstants();
+       }
+
+       //      }}}
+
+       //      {{{     configureConstats()
+
+    /**
+     * Constant variables for the form
+        *
+        * These values won't get overridden by POST or GET vars
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureConstants()
+       {
+               $constants = array(
+                       'user_agent' => $_SERVER['HTTP_USER_AGENT'],
+                       'remote_addr' => $_SERVER['REMOTE_ADDR'],
+               );
+               $this->setupConstants($constants);
+       }
+
+       //      }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureDefaults()
+       {
+               if ($contactData = $this->contactExists()) {
+                       $defaults = $contactData;
+               } else {
+                       $defaults = array(
+                               'state' => '',
+                'mail_ok' => 1,
+                       );
+               }
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureElements()
+       {
+               //      All Elements are created here.  This includes group element definitions.
+        $elements[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'user_agent'
+        );
+        $elements[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'remote_addr'
+        );
+        $elements[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'email',
+            'display' => 'Email'
+        );
+        $elements[] = array(
+            'type' => 'text',
+            'req' => true,
+            'name' => 'email_rmv',
+            'display' => 'Verify Email'
+        );
+        $elements[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'mail_ok',
+            'display' => 'Yes, please sign me up for your E-newsletter',
+            'opts' => 'Yes',
+            'val' => array(0, 1)
+        );
+
+        $elements[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit_rmv',
+            'display' => 'Submit Form'
+        );
+
+               $this->setupElements($elements);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     *
+        * Adds validation rules for the given fields
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureRules()
+       {
+               //      Form Rules
+        $rules[] = array(
+            'element' => 'email',
+            'message' => 'ERROR: Invalid Email Format!',
+            'type' => 'email',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+        $rules[] = array(
+            'element' => array('email', 'email_rmv'),
+            'message' => 'ERROR: Your Email Addresses Do Not Match!',
+            'type' => 'compare',
+            'format' => null,
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+        $rules[] = array(
+            'element' => 'zip',
+            'message' => 'ERROR: Invalid Zip!',
+            'type' => 'zip',
+            'format' => array('requireDBCheck' => false),
+            'validation' => $this->validationType,
+            'reset' => true,
+            'force' => false
+        );
+
+               $this->setupRules($rules);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     *
+        * Applies a data filter for the given fields when the form is submitted
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureFilters()
+       {
+               $filters[] = array('element' => '__ALL__', 'filter' => 'trim');
+       }
+
+       //      }}}
+       //      {{{     contactExists()
+
+    /**
+     * Checks a contact already exists
+     *
+     * @return mixed     database tuple of query, false on error
+     * @access protected
+     */
+       protected function contactExists()
+       {
+               try {
+                       if (!isset($_GET['id'])) {
+                               return false;
+                       }
+                       $sql = "
+                SELECT fname, lname, address, address2, city, state, zip,
+                                          email, email AS email_rmv, phone, fax, mail_ok
+                  FROM contacts
+                 WHERE id = :cid";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':cid', $_GET['id'], PDO::PARAM_INT);
+                       $stmt->execute();
+                       return $stmt->fetch(PDO::FETCH_ASSOC);
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     emailPDFLink()
+
+    /**
+     * Emails the owner the submitted data from the submitted form
+     *
+        * Uses a flexy template to render a nice looking html email.
+        * Emails the link for pdf to person filling out form.
+        *
+     * @return boolean   result of the mailing
+     * @access protected
+     */
+       protected function emailPDFLink()
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $page->email_from  = FROM_NEWS_EMAIL;
+               $page->subject     = $this->subject;
+               $page->client_info = $this->clientInfo;
+               $page->pdfName     = $this->pdfFileName;
+               $page->pdfLinkURL  = BASE_URL.'assets/'.$this->pdfFileName;
+        $page->pdfFileSize = GLM_TOOLBOX::get_size(
+            BASE.'assets/' . $this->pdfFileName
+        );
+
+               $template->compile('pdfDownloadEmail.html');
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               $crlf     = "\n";
+               $mimeMail = new Mail_mime($crlf);
+               $mimeMail->setFrom("{$this->siteName} <{$page->email_from}>");
+               $mimeMail->setSubject($this->subject);
+               $mimeMail->setHTMLBody($htmlMsg);
+
+               $mail    =& Mail::factory('mail');
+               $body    = $mimeMail->get();
+               $headers = $mimeMail->headers();
+
+               $res = $mail->send($this->getSubmitValue('email'), $headers, $body);
+               if (PEAR::isError($res)) {
+                       return Toolkit_Common::handleError($res);
+               } else {
+                       return $res;
+               }
+       }
+
+       //      }}}
+       //      {{{     error()
+
+    /**
+     * Display errors with the form to the user
+     *
+     * @param object $error PEAR Error Object
+        *
+     * @return void
+     * @access public
+     */
+       public function error($error)
+       {
+               //      make the variables static so that is only has to do the defining
+               //      on the first call.
+               static $errorMessages;
+               static $className;
+
+               //      define the various error messages
+               if (!isset($errorMessages)) {
+                       $className     = get_class($this);
+                       $errorMessages = array(
+                               FORM_OK                  => 'No error',
+                               FORM_ERROR               => 'Unknown error',
+                NO_RECORD               => 'Setting both properties (email and
+                hasContactDB) to false in the <i>' . $className . '</i>
+                class will result in no email record being sent and no
+                record being inserted into the database.  There will be
+                no record that this form was ever filled out.',
+                INVALID_DB              => 'Please set the property hasContactDB
+                to a boolean value in the class <i>' . $className . '</i>
+                before continuing',
+                MISSING_CONSTANT => 'You have failed to set a CONSTANT
+                for the class <i>' . $className . '</i> to function properly',
+                       );
+               }
+
+               if (!is_null($error->message)) {
+                       $message = $error->message;
+               } elseif (isset($errorMessages[$error->code])) {
+                       $message = $errorMessages[$error->code];
+               } else {
+                       $message = $errorMessages[$error->code];
+                       $message = $errorMessages[FORM_ERROR];
+               }
+
+               echo "<div id=\"form-warning-top\">{$message}</div>";
+       }
+
+       //      }}}
+
+       //      {{{     getInterestFields()
+
+    /**
+     * Returns the field definitions of the contact db interest fields
+     *
+     * @return array     Group definitions for the interest fields
+     * @access protected
+     */
+       protected function getInterestFields()
+       {
+               if (is_array($this->inquiries)) {
+                       foreach ($this->inquiries as $k => $v) {
+                               $interests[] = array('type' => 'checkbox',
+                                                                        'req' => false,
+                                                                        'name' => $k,
+                                                                        'opts' => $v);
+                       }
+               }
+
+               return $interests;
+       }
+
+       //      }}}
+
+       //      {{{     insertData()
+
+    /**
+     * Inserts contact data into the contact db
+     *
+     * @param array $values submitted values
+        *
+     * @return object    result of db insert query
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+            $values['interest'] = ':' . implode(
+                ':',
+                array_keys($values['interest'])
+            ) . ':';
+               }
+               try {
+                       $params     = implode(', ', array_keys($values));
+                       $bindParams = ':' . implode(', :', array_keys($values));
+
+                       $sql  = "
+                               INSERT INTO {$this->tableName} ($params)
+                               VALUES ($bindParams)";
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } elseif ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      For empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               if (empty($v) && $v !== 0) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     *
+     * @param array $values Form submitted values
+        *
+     * @return array     Result of Insert / Update function
+     * @access protected
+     */
+       protected function processData($values)
+       {
+               //      Form data used for the insert/update sql queries and
+               //      the form email.
+               $e = array(
+                       'mail_ok',
+                       'user_agent',
+                       'remote_addr'
+               );
+               $this->setFormData($e);
+
+
+               //      If no contact db, return true so we can send owner email.
+               if (!$this->hasContactDB) {
+                       return true;
+               }
+
+               //      Get rid of any defined un-needed elements.
+               //      un-needed elements after the form is submitted are defined
+               //      by the ending _rmv name.
+               foreach ($values as $k => &$v) {
+                       if (preg_match('/^.+_rmv$/', $k)) {
+                               unset($values[$k]);
+                       }
+               }
+
+               $this->tableMetaData = Toolkit_Common::getTableMetaData(
+            $this->dbh,
+            $this->tableName
+        );
+               //      Check if a contact w/ the submitted email already exists.
+               //      if so, then we need to update, if not then do a fresh insert.
+               try {
+                       $sql = "
+                               SELECT count(*)
+                                 FROM {$this->tableName}
+                                WHERE email   = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $values['email'], PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('count', $contactExists);
+                       $stmt->fetch();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               if ($contactExists) {
+                       return $this->updateData($values);
+               } else {
+                       return $this->insertData($values);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setInterestFields()
+
+    /**
+     * Contact DB interests
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setInterestFields()
+       {
+               try {
+                       $sql = "
+                SELECT *
+                  FROM contact_inq
+                 ORDER BY pos";
+
+                       foreach ($this->dbh->query($sql) as $row) {
+                               $inquiries[$row['id']] = $row['header'];
+                       }
+
+                       $this->inquiries = $inquiries;
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Custom rendering templates for special fields on the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+        $required = '<!-- BEGIN required -->
+        <span class="req">*</span>
+        <!-- END required -->';
+        $error    = '<!-- BEGIN error -->
+        <div class="form-warning-inside">{error}</div>
+        <!-- END error -->';
+
+        $renderer->setElementTemplate(
+            '<tr>
+            <td colspan="2">'.$required.'{label}'.$error.'{element}</td>
+        </tr>', 'comments'
+        );
+        $renderer->setElementTemplate(
+            '<tr align="center">
+            <td colspan="2">'.$required.'{label}'.$error.'{element}</td>
+        </tr>', 'submit_rmv'
+        );
+
+       }
+
+       //      }}}
+       //      {{{     toHTML()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHTML()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                               $ret = $this->emailPDFLink();
+                               $output = $this->successMsg;
+                       }
+            $this->sent = true;
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+
+       //      {{{     updateData()
+
+    /**
+     * Updates the contact in the contact db
+     *
+     * @param array $values Form submitted values
+        *
+     * @return object Result of the update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+            $values['interest'] = ':' . implode(
+                ':',
+                array_keys($values['interest'])
+            ) . ':';
+               }
+               try {
+                       $params = array_keys($values);
+                       $length = count($params);
+                       for ($i = 0; $i < $length; ++$i) {
+                               $bindParams .= "{$params[$i]} = :{$params[$i]}";
+                               if ($i < ($length - 1)) {
+                                       $bindParams .= ', ';
+                               }
+                       }
+                       $sql  = "
+                               UPDATE {$this->tableName}
+                                  SET $bindParams
+                                WHERE email = :email";
+                       $stmt = $this->dbh->prepare($sql);
+                       foreach ($values as $k => &$v) {
+                               $metaData = $this->tableMetaData[$k];
+                               if ($metaData == 'integer') {
+                                       $dataType = PDO::PARAM_INT;
+                               } elseif ($metaData == 'boolean') {
+                                       $dataType = PDO::PARAM_BOOL;
+                               } else {
+                                       $dataType = PDO::PARAM_STR;
+                               }
+                               //      For empty values that are not actually a zero (0), we
+                               //      want to insert null's.
+                               if (empty($v) && $v !== 0) {
+                                       $v        = null;
+                                       $dataType = PDO::PARAM_NULL;
+                               }
+                               $stmt->bindParam(":$k", $v, $dataType);
+                       }
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/SaveTripPlanner.php b/Toolkit/Contacts/SaveTripPlanner.php
new file mode 100755 (executable)
index 0000000..63d7849
--- /dev/null
@@ -0,0 +1,658 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Toolkit_Forms
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @link        <>
+ */
+
+/**
+ * Ask the concierge form
+ * 
+ * This form handles rendering and processing the contact form.
+ * 
+ * @category  CategoryName
+ * @package   Toolkit_Forms_AskTheConcierge
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id:
+ * @link      <>
+ * @see       Toolkit_FormBuilder
+ */
+class Toolkit_Contacts_SaveTripPlanner extends Toolkit_Contacts_ContactUs
+{
+       //      {{{     properties
+
+       /**
+        * Contact type to be inserted into the DB as when the form is submitted
+        *
+        * This property is only valid when the [hasContactDB] property is set
+        * to true.
+        *
+        * N.B.
+        * If you subclass this class out to other forms that are
+        * inserted into the contact db, be sure to make each one of their
+        * contactType properties unique.  We don't check for duplicates.
+        *
+        * @var string
+        * @access public
+        */
+       public $contactType = '4';
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * public $email = false;
+        * </code>
+        *
+     * @var    unknown  
+     * @access public
+     */
+       public $email = false;
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string   
+     * @access public
+     */
+       public $successMsg = '
+               <div id="form-success-top">
+            You have successfully created a new account.  You may receive a confirmation email. 
+               </div>';
+
+    /**
+        * Email subject and <h1> header in email
+        * 
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string   
+     * @access public
+     */
+       public $subject;
+
+    protected $plannerListPageId;
+    protected $plannerFormPageId;
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $pdo         PDO object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->subject           = 'Travel List from website ' . SITENAME;
+        $this->plannerListPageId = MEMBER_SESSION_PAGE;
+        $this->plannerFormPageId = MEMBER_SESSION_FORM;
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureElements()
+       {
+               $e = array();
+               $this->setInterestFields();
+               //      Grouped Elements are defined here.
+               $this->interestsGroups =& $this->getInterestFields();
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'user_agent'
+               );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'remote_addr'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fname',
+                       'display' => 'First Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'lname',
+                       'display' => 'Last Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address',
+                       'display' => 'Address 1'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address2',
+                       'display' => 'Address 2'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'city',
+                       'display' => 'City'
+               );
+        $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'state',
+                       'display' => 'State/Province',
+                       'opts'    => $GLOBALS['states']
+               );
+        $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'zip',
+                       'display' => 'ZIP/Postal Code'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email',
+                       'display' => 'Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email_rmv',
+                       'display' => 'Verify Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Phone'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'password',
+                       'display' => 'Password'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'verify_password',
+                       'display' => 'Verify Password'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fax',
+                       'display' => 'Fax'
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'mail_ok',
+                       'display' => 'Yes, I would like to receive Email Newsletters',
+                       'opts'    => 'Yes',
+                       'val'     => array(0, 1)
+               );
+        if (is_array($this->interestsGroups)) {
+            foreach ($this->interestsGroups as $group => $gData) {
+                $this->myGroups[] = $gData;
+                $e[] = array(
+                    'type'       => 'group',
+                    'req'        => false,
+                    'name'       => 'interest['.$group.']',
+                    'group'         => $gData,
+                    'label'      => $group,
+                    'seperator'  => ' ',
+                    'appendName' => true
+                );
+            }
+        }
+               $e[] = array(
+                       'type'    => 'CAPTCHA_Image',
+                       'req'     => false,
+                       'name'    => 'captcha_question',
+                       'display' => 'Verification code',
+                       'opts'    => $this->captchaOptions
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'captcha_rmv',
+                       'display' => 'Enter verification code'
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'submit_rmv',
+                       'display' => 'Submit Form'
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+        * Adds validation rules for the given fields
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+               //      Form Rules
+               $r[] = array(
+                       'element'    => array('email', 'email_rmv'),
+                       'message'    => 'ERROR: Your Email Addresses Do Not Match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => array('password', 'verify_password'),
+                       'message'    => 'ERROR: Your Passwords do not match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'email',
+                       'message'    => 'ERROR: Invalid Email Format!',
+                       'type'       => 'checkEmail',
+                       'format'     => array('use_rfc822' => true),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        /*
+               $r[] = array(
+                       'element'    => 'state',
+                       'message'    => 'ERROR: Invalid State!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        */
+               $r[] = array(
+                       'element'    => 'phone',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'fax',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'zip',
+                       'message'    => 'ERROR: Invalid Zip!',
+                       'type'       => 'zip',
+                       'format'     => array('requireDBCheck' => false),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'mail_ok',
+                       'message'    => 'ERROR: Invalid Value!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'captcha_rmv',
+                       'message'    => 'ERROR: Incorrect verification code!',
+                       'type'       => 'CAPTCHA',
+                       'format'     => $this->captchaQuestion,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+    //  {{{ contactExists()
+
+    /**
+     * Checks for a duplicate email address already in the DB.
+     *
+     * @param string $email The email address to check for in the DB
+     *
+     * @return boolean If the email address already exists
+     * @access protected
+     */
+    protected function contactExists($email)
+    {
+               //      Check if a contact w/ the submitted email already exists.
+               //      if so, then we need to update, if not then do a fresh insert.
+               try {
+                       $sql = "
+                               SELECT id,password
+                                 FROM contact 
+                                WHERE email = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $email, PDO::PARAM_STR);
+                       $stmt->execute();
+                       //$stmt->bindColumn('id', $contactExists);
+                       //$stmt->bindColumn('password', $password);
+                       $row = $stmt->fetch();
+            //die('<pre>'.print_r($row, true).'</pre>');
+            if (!empty($row)) {
+                return array(
+                        'contactId' => $row['id'], 
+                        'password' => $row['password']
+                    );
+            } else {
+                return false;
+            }
+
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+    }
+
+    //  }}}
+
+       //      {{{     insertData()
+
+    /**
+     * Inserts contact data into the contact db
+     * 
+     * @param array $values submitted values
+        *
+     * @return object result of db insert query
+     * @access protected
+     */
+       protected function insertData($values)
+       {
+        unset($values['comments']);
+               $values['contact_type'] = ":{$this->contactType}:";
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+                       $values['interest'] = ':' . implode(':', array_keys($values['interest'])) . ':';
+               }
+               try {
+            $sql = Toolkit_Common::createSQLInsert(
+                $this->tableName,
+                array_keys($values)
+            );
+
+            $sql .= " RETURNING id";
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return array     Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+               //      Form data used for the insert/update sql queries and 
+               //      the form email.
+               $e = array(
+                       'user_agent',
+                       'remote_addr',
+                       'contact_type',
+                       'catid',
+                       'cPage',
+               );
+               $this->setFormData($e);
+
+
+               //      If no contact db, return true so we can send owner email.
+               if (!$this->hasContactDB) {
+                       return true;
+               }
+
+        //  Get rid of any elements in the values array that
+        //  aren't going to be used when inserting/updating the db.
+        $values = Toolkit_Common::cleanArray($values);
+
+        //  Send data off to StreamSend
+        if (   defined('STREAMSEND_FORMS_API')
+            && STREAMSEND_FORMS_API
+            && $values['mail_ok']
+        ) {
+            // Insert the record into the streamsend server
+            $streamSend = new Toolkit_Contacts_StreamSend();
+            $streamSend->addContact($values);
+        }
+
+        //  Check if we are updating an existing contact or not
+        //  question: is this the best approach?  what if someone else
+        //  sends a form through w/ different data but the same emil addy
+        //  the old users data can be completely wiped out.
+        $existingContact = $this->contactExists($values['email']);
+
+        $values['password'] = md5($values['password']);
+        unset($values['catid']);
+        unset($values['cPage']);
+        $tripPlannerAuth =& new Toolkit_Members_TripPlanner_TripAuth('DB', array(), '', false);
+        $tripPlannerAuth->setIdle();
+        $tripPlannerAuth->start();
+        $sessionList = new Toolkit_Members_TripPlanner_Sessions(
+                       Toolkit_Database::getInstance(),
+            &$tripPlannerAuth
+               );
+               if (is_array($existingContact)) {
+            // if there already in the database then give a message that they're already in and need to login
+            // this is true only if they already have a password set
+            if (!$existingContact['password']) {
+                           $this->updateData($values);
+                $contactId = $existingContact['contactId'];
+                $tripPlannerAuth->setAuth($values['email']);
+                $tripPlannerAuth->setAuthData('id', $contactId);
+                $tripPlannerAuth->setAuthData('username', $values['email']);
+                $sessionList->saveList($contactId);
+                return true;
+            } else {
+                $toolbox = new GLM_TEMPLATE(HOME_ID);
+                $this->errorMsg = '<p>Your Email address already exist.  Please <a href="' .
+                    $toolbox->get_seo_url($this->plannerListPageId) .
+                    '">sign-in</a>.</p>';
+                return false;
+            }
+               } else {
+                       $contactId = $this->insertData($values);
+            $contactData = $this->contactExists($values['email']);
+            $contactId   = $contactData['contactId'];
+            $tripPlannerAuth->setAuth($values['email']);
+            $tripPlannerAuth->setAuthData('id', $contactId);
+            $tripPlannerAuth->setAuthData('username', $values['email']);
+            $sessionList->saveList($contactId);
+            return true;
+               }
+       }
+
+       //      }}}
+       //      {{{     toHTML()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     * 
+        * destroying and resetting the captcha value dis-allows someone from 
+        * re-sending a form on a previous captcha.
+        *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHTML()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->captchaQuestion->destroy();
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                               $output = $this->successMsg;
+                       } else {
+                $output  = $this->errorMsg;
+                //$output .= parent::toHTML();
+            }
+            $this->sent = true;
+               } elseif ($this->isSubmitted()) {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       //$output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output .= parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+       //      {{{     updateData()
+
+    /**
+     * Updates the contact in the contact db
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return object    Result of the update query
+     * @access protected
+     */
+       protected function updateData($values)
+       {
+        unset($values['comments']);
+               if (is_array($values['interest']) && !empty($values['interest'])) {
+                       $values['interest'] = ':' . implode(':', array_keys($values['interest'])) . ':';
+               }
+
+               try {
+                       //      Get all the existing contact type data
+                       $sql = "
+                               SELECT contact_type
+                                 FROM {$this->tableName}
+                                WHERE email = :email";
+
+                       $stmt = $this->dbh->prepare($sql);
+                       $stmt->bindParam(':email', $values['email'], PDO::PARAM_STR);
+                       $stmt->execute();
+                       $stmt->bindColumn('contact_type', $cType);
+                       $stmt->fetch();
+
+                       $existingTypes = explode(':', $cType);
+                       if (!in_array($this->contactType, $existingTypes)) {
+                               $values['contact_type'] = "$cType{$this->contactType}:";
+                       }
+
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('email = :email')
+            );
+
+            
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/SendTripPlanner.php b/Toolkit/Contacts/SendTripPlanner.php
new file mode 100755 (executable)
index 0000000..737df6c
--- /dev/null
@@ -0,0 +1,748 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Toolkit_Forms
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @link        <>
+ */
+
+/**
+ * Ask the concierge form
+ * 
+ * This form handles rendering and processing the contact form.
+ * 
+ * @category  CategoryName
+ * @package   Toolkit_Forms_AskTheConcierge
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id:
+ * @link      <>
+ * @see       Toolkit_FormBuilder
+ */
+class Toolkit_Contacts_SendTripPlanner extends Toolkit_Contacts_ContactUs
+{
+       //      {{{     properties
+
+       /**
+        * Contact type to be inserted into the DB as when the form is submitted
+        *
+        * This property is only valid when the [hasContactDB] property is set
+        * to true.
+        *
+        * N.B.
+        * If you subclass this class out to other forms that are
+        * inserted into the contact db, be sure to make each one of their
+        * contactType properties unique.  We don't check for duplicates.
+        *
+        * @var string
+        * @access public
+        */
+       public $contactType = '4';
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * public $email = false;
+        * </code>
+        *
+     * @var    unknown  
+     * @access public
+     */
+       public $email = false;
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string   
+     * @access public
+     */
+       public $successMsg = '
+               <div id="form-success-top">
+                       <p>Thank you for adding these businesses to your Trip Planner. Your 
+information is currently being sent to each business so they may contact you regarding your 
+visit to The Upper Peninsula of Michigan.</p>
+               </div>';
+
+    /**
+        * Email subject and <h1> header in email
+        * 
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string   
+     * @access public
+     */
+       public $subject;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $pdo         Passed in PDO object
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $pdo,
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->subject = 'Travel List from website ' . SITENAME;
+       }
+
+       //      }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        $defaults = array(
+            'state'   => '',
+            'mail_ok' => 1,
+            'catid'   => $_REQUEST['catid'],
+            'cPage'   => $_REQUEST['cPage']
+        );
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureElements()
+       {
+               $e = array();
+               $this->setInterestFields();
+               //      Grouped Elements are defined here.
+        $this->interestsGroups =& $this->getInterestFields();
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'catid'
+               );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'cPage'
+               );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'user_agent'
+               );
+               $e[] = array(
+                       'type' => 'hidden',
+                       'req'  => false,
+                       'name' => 'remote_addr'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fname',
+                       'display' => 'First Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'lname',
+                       'display' => 'Last Name'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address',
+                       'display' => 'Address 1'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'address2',
+                       'display' => 'Address 2'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'city',
+                       'display' => 'City'
+               );
+        $e[] = array(
+                       'type'    => 'select',
+                       'req'     => false,
+                       'name'    => 'state',
+                       'display' => 'State/Province',
+                       'opts'    => $GLOBALS['states']
+               );
+        $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'zip',
+                       'display' => 'ZIP/Postal Code'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email',
+                       'display' => 'Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'email_rmv',
+                       'display' => 'Verify Email'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'phone',
+                       'display' => 'Phone'
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => false,
+                       'name'    => 'fax',
+                       'display' => 'Fax'
+               );
+               $e[] = array(
+                       'type'    => 'textarea',
+                       'req'     => false,
+                       'name'    => 'comments',
+                       'display' => 'Comments'
+               );
+               $e[] = array(
+                       'type'    => 'advcheckbox',
+                       'req'     => false,
+                       'name'    => 'mail_ok',
+                       'display' => 'Yes, I would like to receive Email Newsletters',
+                       'opts'    => 'Yes',
+                       'val'     => array(0, 1)
+               );
+        if (is_array($this->interestsGroups)) {
+            foreach ($this->interestsGroups as $group => $gData) {
+                $this->myGroups[] = $gData;
+                $e[] = array(
+                    'type'       => 'group',
+                    'req'        => false,
+                    'name'       => 'interest['.$group.']',
+                    'group'         => $gData,
+                    'label'      => $group,
+                    'seperator'  => ' ',
+                    'appendName' => true
+                );
+            }
+        }
+               $e[] = array(
+                       'type'    => 'CAPTCHA_Image',
+                       'req'     => false,
+                       'name'    => 'captcha_question',
+                       'display' => 'Verification code',
+                       'opts'    => $this->captchaOptions
+               );
+               $e[] = array(
+                       'type'    => 'text',
+                       'req'     => true,
+                       'name'    => 'captcha_rmv',
+                       'display' => 'Enter verification code'
+               );
+               $e[] = array(
+                       'type'    => 'submit',
+                       'req'     => false,
+                       'name'    => 'submit_rmv',
+                       'display' => 'Submit Form'
+               );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+        * Adds validation rules for the given fields
+     * 
+     * @return void     
+     * @access public
+     */
+       public function configureRules()
+       {
+               $r = array();
+               //      Form Rules
+               $r[] = array(
+                       'element'    => array('email', 'email_rmv'),
+                       'message'    => 'ERROR: Your Email Addresses Do Not Match!',
+                       'type'       => 'compare',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'email',
+                       'message'    => 'ERROR: Invalid Email Format!',
+                       'type'       => 'checkEmail',
+                       'format'     => array('use_rfc822' => true),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        /*
+               $r[] = array(
+                       'element'    => 'state',
+                       'message'    => 'ERROR: Invalid State!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+        */
+               $r[] = array(
+                       'element'    => 'phone',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'fax',
+                       'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+                       'type'       => 'phone',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'zip',
+                       'message'    => 'ERROR: Invalid Zip!',
+                       'type'       => 'zip',
+                       'format'     => array('requireDBCheck' => false),
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'mail_ok',
+                       'message'    => 'ERROR: Invalid Value!',
+                       'type'       => 'numeric',
+                       'format'     => null,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+               $r[] = array(
+                       'element'    => 'captcha_rmv',
+                       'message'    => 'ERROR: Incorrect verification code!',
+                       'type'       => 'CAPTCHA',
+                       'format'     => $this->captchaQuestion,
+                       'validation' => $this->validationType,
+                       'reset'      => true,
+                       'force'      => false
+        );
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     * 
+     * @param array $values Form submitted values
+        *
+     * @return array     Result of Insert / Update function
+     * @access protected
+     */
+       public function processData($values)
+       {
+               //      Form data used for the insert/update sql queries and 
+               //      the form email.
+        unset($values['catid']);
+        unset($values['cPage']);
+               $e = array(
+                       'user_agent',
+                       'remote_addr',
+                       'contact_type',
+               );
+               $this->setFormData($e);
+
+
+               //      If no contact db, return true so we can send owner email.
+               if (!$this->hasContactDB) {
+                       return true;
+               }
+
+        //  Get rid of any elements in the values array that
+        //  aren't going to be used when inserting/updating the db.
+        $values = Toolkit_Common::cleanArray($values);
+
+        //  Send data off to StreamSend
+        if (   defined('STREAMSEND_FORMS_API')
+            && STREAMSEND_FORMS_API
+            && $values['mail_ok']
+        ) {
+            // Insert the record into the streamsend server
+            $streamSend = new Toolkit_Contacts_StreamSend();
+            $streamSend->addContact($values);
+        }
+
+        //  Check if we are updating an existing contact or not
+        //  question: is this the best approach?  what if someone else
+        //  sends a form through w/ different data but the same emil addy
+        //  the old users data can be completely wiped out.
+        $existingContact = $this->contactExists($values['email']);
+
+               if ($existingContact) {
+                       return $this->updateData($values);
+               } else {
+                       return $this->insertData($values);
+               }
+       }
+
+       //      }}}
+
+    // {{{ sendEmails()
+
+    /**
+     * sendEmails
+     * 
+     * From the list of emails contained in $_SESSIEN['wish_list']
+     * send out emails to each email address 
+     * only if we're on the production server
+     * if on the development server send to OWNER_EMAIL
+     * 
+     * @return void  
+     * @access public
+     */
+    function sendEmails()
+    {
+        $hasInterestField = $this->elementExists('interest');
+
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+        // for comments textarea need to replace newlines with br
+        $this->formData['comments']['element'] = nl2br($this->getSubmitValue('comments'));
+
+               $page->email_from  = OWNER_EMAIL;
+               $page->subject     = $this->subject;
+               $page->client_info = $this->clientInfo;
+               $page->fname       = $this->getSubmitValue('fname');
+               $page->lname       = $this->getSubmitValue('lname');
+               $page->formData    = $this->formData;
+
+        // unset some extra fields
+        unset(
+            $page->formData['catid'],
+            $page->formData['cPage']
+        );
+               
+               if ($hasInterestField) {
+                       //      Clean up the interests so they will look nice in the email
+                       $page->formData['interest']['nowrap']  = 'nowrap';
+                       $page->formData['interest']['element'] = null;
+                       $g  =& $this->getElement('interest');
+                       $ge =& $g->getElements();
+                       $interests = array();
+                       foreach ($ge as $e) {
+                               if ($e->getChecked()) {
+                                       $interests[] = $e->getText();
+                               }
+                       }
+                       $page->formData['interest']['element'] = implode('<br>', $interests);
+               }
+
+               if ($this->elementExists('mail_ok')) {
+                       //      Clean up the mail_ok flag so its human readable
+                       $page->formData['mail_ok']['element']
+                = ($page->formData['mail_ok']['element']) ? 'Yes' : 'No';
+               }
+
+               $template->compile('emailOwner.tpl');
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               if ($hasInterestField) {
+                       //      Text version can't have HTML in it
+                       //      so reset the interests to use commas
+                       $page->formData['interest']['element'] = implode(", ", $interests);
+               }
+               $msg  = "{$page->subject}\n\n";
+               $msg .= "From {$page->fname} {$page->lname}\n\n";
+               $msg .= "Information\n\n";
+               foreach ($page->formData as $i) {
+                       $msg .= "{$i['label']}: {$i['element']}\n";
+               }
+
+               $crlf     = "\n";
+               $mimeMail = new Mail_mime($crlf);
+               $mimeMail->setFrom("Online Form <{$page->email_from}>");
+               $mimeMail->setSubject($this->subject);
+               $mimeMail->setHTMLBody($htmlMsg);
+               $mimeMail->setTXTBody($msg);
+
+               $mail    =& Mail::factory('mail');
+               $body    = $mimeMail->get();
+        $setHeader['Reply-To'] = "{$this->getSubmitValue('fname')} {$this->getSubmitValue('lname')} <{$this->getSubmitValue('email')}>";
+               $headers = $mimeMail->headers($setHeader);
+        $sql = "
+        SELECT member_contact_email
+          FROM member
+         WHERE member_id = :member_id";
+        $getMemberEmail = $this->dbh->prepare($sql);
+
+        switch (GLM_HOST_ID) {
+        case "DEVELOPMENT":
+            // code for sending email
+            if (is_array($_SESSION['wish_list']) && !empty($_SESSION['wish_list'])) {
+                foreach ($_SESSION['wish_list'] as $member_id => $row) {
+                    try {
+                        $getMemberEmail->bindParam(":member_id", $member_id, PDO::PARAM_INT);
+                        $getMemberEmail->execute();
+                        $memberEmail = $getMemberEmail->fetchColumn();
+                    } catch(PDOException $e) {
+                        return Toolkit_Common::handleError($e);
+                    }
+                    if (GLM_TOOLBOX::valid_email($memberEmail)) {
+                        echo '<p>Send mail to: '.$memberEmail.'</p>';
+                    }
+                }
+            }
+            $res = $mail->send(OWNER_EMAIL, $headers, $body);
+            if (PEAR::isError($res)) {
+                return Toolkit_Common::handleError($res);
+            }
+            break;
+        case "PRODUCTION":
+            if (is_array($_SESSION['wish_list']) && !empty($_SESSION['wish_list'])) {
+                foreach ($_SESSION['wish_list'] as $member_id => $row) {
+                    try {
+                        $getMemberEmail->bindParam(":member_id", $member_id, PDO::PARAM_INT);
+                        $getMemberEmail->execute();
+                        $memberEmail = $getMemberEmail->fetchColumn();
+                    } catch(PDOException $e) {
+                        return Toolkit_Common::handleError($e);
+                    }
+                    // code for sending emails
+                    if (GLM_TOOLBOX::valid_email($memberEmail)) {
+                        $res = $mail->send($memberEmail, $headers, $body);
+                        if (PEAR::isError($res)) {
+                            return Toolkit_Common::handleError($res);
+                        }
+                    }
+                }
+            }
+            break;
+        }
+        $tripPlannerAuth =& new Toolkit_Members_TripPlanner_TripAuth('DB', array(), '', false);
+        $tripPlannerAuth->setIdle();
+        $tripPlannerAuth->start();
+        $sessionList = new Toolkit_Members_TripPlanner_Sessions($this->dbh, &$tripPlannerAuth);
+        $sessionList->dumpList();
+               return $res;
+    }
+    
+    // }}}
+    // {{{ showDirectList()
+
+    /**
+     * showDirectList
+     * 
+     * Display the list of members in $_SESSION['wish_list']
+     * 
+     * @return void  
+     * @access public
+     */
+    function showDirectList()
+    {
+        // Initiate HTML_Template_Flexy.
+        $template           = new HTML_Template_Flexy($this->flexyOptions);
+        $page               = new stdClass();
+        $page->memberDirect = $page->memberDirectNoEmail = array();
+        if (is_array($_SESSION['wish_list']) && !empty($_SESSION['wish_list'])) {
+            $sql   = "
+            SELECT member_name,member_contact_email,phone,toll_free
+              FROM member
+             WHERE member_id = :member_id";
+            $getMemberData = $this->dbh->prepare($sql);
+            $mACount = $mBCount = 0;
+            foreach ($_SESSION['wish_list'] as $member_id => $row) {
+                try {
+                    $getMemberData->bindParam(":member_id", $member_id, PDO::PARAM_INT);
+                    $getMemberData->execute();
+                    $memberData     = $getMemberData->fetch();
+                    $memberName     = $memberData['member_name'];
+                    $memberPhone    = $memberData['phone'];
+                    $memberTollFree = $memberData['toll_free'];
+                } catch(PDOException $e) {
+                    Toolkit_Common::handleError($e);
+                }
+                if ($memberData['member_contact_email']) {
+                    $page->memberDirect[] = array(
+                        'memberName'     => $memberName,
+                        'memberPhone'    => $memberPhone,
+                        'memberTollFree' => $memberTollFree,
+                        'memberLink'     => BASE_URL
+                            .'index.php?catid='.$row['catid'].'&member_id='.$member_id,
+                        'deleteLink'     => BASE_URL
+                            .'Toolkit/Members/TripPlanner/'
+                            .'wish-list.php?catid='
+                            .$_REQUEST['catid'].'&member_id=' . $member_id
+                            . '&cPage=' . urlencode($_REQUEST['cPage']),
+                        'trclass' => (($mACount % 2 == 0) ? 'tr1': 'tr2')
+                    );
+                    $mACount++;
+                } else {
+                    $page->memberDirectNoEmail[] = array(
+                        'memberName'     => $memberName,
+                        'memberPhone'    => $memberPhone,
+                        'memberTollFree' => $memberTollFree,
+                        'memberLink'     => BASE_URL
+                            .'index.php?catid='.$row['catid'].'&member_id='.$member_id,
+                        'deleteLink'     => BASE_URL
+                            .'Toolkit/Members/TripPlanner/'
+                            . 'wish-list.php?catid='
+                            . $_REQUEST['catid'].'&member_id=' . $member_id
+                            . '&cPage=' . urlencode($_REQUEST['cPage']),
+                        'trclass' => (($mBCount % 2 == 0) ? 'tr1': 'tr2')
+                    );
+                    $mBCount++;
+                }
+            }
+        }
+        $this->totalMembersEmails   = $mACount;
+        $this->totalMembersNoEmails = $mBCount;
+        // Compile the direct-list.html from the templates directory.
+        $template->compile('direct-list.html');
+
+        // Merge compiled template with the $page object.
+        $out = $template->bufferedOutputObject($page);
+        return $out;
+    }
+    // }}}
+    // {{{ showNoList()
+
+    /**
+     * showNoList
+     * 
+     * What to display If nothing is in $_SESSION['wish_list']
+     * 
+     * @return void  
+     * @access public
+     */
+    function showNoList()
+    {
+        // Initiate HTML_Template_Flexy.
+        $template      = new HTML_Template_Flexy($this->flexyOptions);
+        $page          = new stdClass();
+        $page->baseUrl = BASE_URL;
+        // Compile the direct-nolist.html from the templates directory.
+        $template->compile('direct-nolist.html');
+
+        // Merge compiled template with the $page object.
+        $out = $template->bufferedOutputObject($page);
+        return $out;
+    }
+    // }}}
+       //      {{{     toHTML()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     * 
+        * destroying and resetting the captcha value dis-allows someone from 
+        * re-sending a form on a previous captcha.
+        *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHTML()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->captchaQuestion->destroy();
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                $this->sendEmails();
+                               $output = $this->successMsg;
+                       }
+            $this->sent = true;
+               } elseif ($this->isSubmitted()) {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output .= parent::toHTML();
+               } else {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+            $output = $this->showDirectList();
+            if ($this->totalMembersEmails > 0) {
+                $output .= parent::toHTML();
+            }
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/StreamSend.php b/Toolkit/Contacts/StreamSend.php
new file mode 100755 (executable)
index 0000000..dd7658c
--- /dev/null
@@ -0,0 +1,201 @@
+<?php
+/**
+ * StreamSend.php
+ * 
+ * PHP version 5
+ * 
+ * All Right Reserved
+ * 
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: StreamSend.php,v 1.4 2009/09/16 11:31:23 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Default parameters for contact create operations.
+ * Note that these are strings for use in XML data not true/false values.
+ * If false, the person will be created with a status of pending
+ */
+define('STREAMSEND_DEFAULT_ACTIVATE', 'false');
+/**
+  * If activate is false, setting this to true will trigger the sending of the built-in 
+  * activation notification; if activate is true, this setting has no effect
+  */
+define('STREAMSEND_DEFAULT_DELIVER_ACTIVATION', 'true');
+/**
+  * If activate is true, setting this to true will trigger the sending of the built-in 
+  * welcome notification; if activate is false, this setting has no effect
+  */
+define('STREAMSEND_DEFAULT_DELIVER_WELCOME', 'false');
+/**
+  * URI for streamsend API
+  */
+define('STREAMSEND_BASE_URL', "https://app.streamsend.com");
+
+/**
+ * Toolkit_Contacts_StreamSend
+ * 
+ * Contact support class for inergration with StreamSend API
+ * 
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_Contacts_StreamSend
+{
+    // {{{ Class Properties
+
+
+    /**
+     * Description for public
+     * @var    boolean
+     * @access public 
+     */
+    public $debug = false;
+
+    /**
+     * streamSendFields
+     * 
+     * array with key values matching the gaslight contact tabel to the
+     * StreamSend field (normal fields)
+     * 
+     * @var    array    
+     * @access protected
+     */
+    protected $streamSendFields = array(
+        'email'    => 'email-address',
+        'fname'    => 'first-name',
+        'lname'    => 'last-name',
+        'address'  => 'address1',
+        'address2' => 'address2',
+        'city'     => 'city',
+        'state'    => 'stateprovince',
+        'zip'      => 'postal-code',
+        'phone'    => 'phone-number'
+    );
+
+    /**
+     * contactInqTypes
+     * 
+     * array with key values matching the gaslight contact_inq tabel to the
+     * StreamSend field (Radio fields)
+     * key   = id from contact_inq table
+     * value = name from contact_inq_table
+     * value is same name as the StreamSend fieldname
+     * 
+     * @var    array    
+     * @access protected
+     */
+    protected $contactInqTypes = array();
+
+    /**
+     * booleanTypes
+     * 
+     * StreamSend fields (boolean fields) an array of field names for the 
+     * boolean field types
+     * 
+     * @var    array    
+     * @access protected
+     */
+    protected $booleanTypes = array();
+    // }}}
+    // {{{ __construct()
+
+
+    /**
+     *  __construct(
+     * 
+     * @return void  
+     * @access public
+     */
+    public function __construct()
+    {
+    }
+
+
+    // }}}
+    // {{{ addContact()
+
+
+    /**
+     * addContact
+     * 
+     * Given $values from a Toolkit_Contacts Form add Contact
+     * 
+     * @param array $values Parameter description (if any) ...
+     *                         
+     * @return boolean Return true if successfull
+     * @access public 
+     */
+    public function addContact($values)
+    {
+        // check the array $values to make sure it is correct
+        if (is_array($values) && !empty($values)) {
+            include_once GLM_APP_BASE.'StreamSend/class_streamsend_api.inc';
+            // initialize the streamsend object
+            $ss = new streamSend (STREAMSEND_BASE_URL, STREAMSEND_LOGIN_ID, 
+                STREAMSEND_KEY);
+            $ss->debug = $this->debug;
+            $contactData = array();
+            $values[$type] = 1;
+            foreach ($this->streamSendFields as $glmName => $ssName) {
+                switch ($glmName) {
+                case "state":
+                    $contactData[$ssName] = ($values[$glmName]) ? $GLOBALS['states'][$values[$glmName]]: '';
+                    break;
+                default:
+                    $contactData[$ssName] = $values[$glmName];
+                    break;
+                }
+            }
+            foreach ($this->contactInqTypes as $contactInqId => $name) {
+                $slug = str_replace(" ", "-", strtolower($this->contactInqTypes[$contactInqId]));
+                if ($values['interest'][$contactInqId]) {
+                    $contactData[$slug] = 'Yes';
+                } else {
+                    $contactData[$slug] = 'No';
+                }
+            }
+            foreach ($this->booleanTypes as $name) {
+                if ($values[$name]) {
+                    $contactData[$name] = 'Yes';
+                } else {
+                    $contactData[$name] = 'No';
+                }
+            }
+            $contacts = $ss->contactCreate(
+                $contactData, 
+                STREAMSEND_DEFAULT_ACTIVATE, 
+                STREAMSEND_DEFAULT_DELIVER_ACTIVATION, 
+                STREAMSEND_DEFAULT_DELIVER_WELCOME
+            );
+            if (!$contacts) {
+
+                // show errors if on development server
+                switch (GLM_HOST_ID) {
+                case "DEVELOPMENT":
+                    echo "<p>A total and complete failure occured.";
+                    break;
+                case "PRODUCTION":
+                    break;
+                }
+            }
+            if ($ss->debug == true) {
+                echo '<p><h3>Debug Results</h3>'.$ss->debugBuffer.'</p>';
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    // }}}
+}
+?>
diff --git a/Toolkit/Contacts/TellAFriend.php b/Toolkit/Contacts/TellAFriend.php
new file mode 100755 (executable)
index 0000000..046f93d
--- /dev/null
@@ -0,0 +1,610 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Contacts
+ * @package  Toolkit_Contacts
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: TellAFriend.php,v 1.8 2010/01/28 16:33:53 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Error codes for Toolkit_Contacts_ContactUs
+ *
+ * Codes are mapped to textual messaged by errorMessage() method,
+ * if you add a new code be sure to add a new message for it to errorMessage()
+ *
+ * @see Toolkit_Contacts_TellAFriend::errorMessage()
+ */
+define('FORM_OK', 1);
+define('FORM_ERROR', -1);
+define('NO_RECORD', -2);
+define('INVALID_DB', -3);
+define('MISSING_CONSTANT', -4);
+
+/**
+ * GLM Tell a Friend form
+ *
+ * This form handles rendering and processing the contact us form.
+ * Controls the email functionality of the form, whether the client
+ * has a contact DB to store contact records and how to insert/update
+ * submitted form values.
+ *
+ * @category  Contacts
+ * @package   Toolkit_Contacts
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      <>
+ * @see       Toolkit_FormBuilder
+ */
+class Toolkit_Contacts_TellAFriend extends Toolkit_FormBuilder
+{
+       //      {{{     properties
+
+    /**
+     * Table in Database which holds the contact data
+        *
+     * @var    string
+     * @access public
+     */
+       public $tableName = 'contact';
+
+    /**
+     * Table meta data
+        *
+        * This is used when inserting/updating data for the records
+        * so the PDO's can use explicit data types for the parameters.
+        *
+     * @var    array
+     * @access public
+     */
+       public $tableMetaData;
+
+    /**
+     * Used in the email template for the client info string at the bottom
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $clientInfo = array(
+               'name'    => 'Gaslight Media',
+               'address' => '120 E. Lake St.',
+               'city'    => 'Petoskey',
+               'state'   => 'MI',
+               'zip'     => '49770',
+               'phone'   => '231.487.0697',
+       );
+
+    /**
+        * Who to send the email to when the contact form is submitted
+        *
+        * If you leave this blank, its value will get set to the OWNER_EMAIL
+        * in the constructor.
+        *
+        * If you ***DO NOT*** want any emails to go out when the form is submitted
+        * then set the value to false. Do not set it to 0 for false, because the
+        * check uses a strict type check to determine if the value is actually
+        * false. This is what allows for the empty value as an option, which sets
+        * the value to OWNER_EMAIL and won't override the $email property if
+        * this class gets subclassed and the value for this property gets set in
+        * the properties of the subclass and not in the constructor after this
+        * constructor function is called.
+        *
+        * tongue twister...I know.
+        * <code>
+        * protected $email = false;
+        * </code>
+        *
+     * @var    unknown
+     * @access protected
+     */
+       protected $email;
+
+    /**
+     * From header in the owner email
+        *
+        * This just sets the From header in the owner email
+        * SITENAME <from@email.com>
+        *
+        * It gets set to the constant SITENAME in the constructor if you leave
+        * empty here, but you can set it to something different here to override
+        * that if you desire.
+        *
+     * @var    unknown
+     * @access protected
+     */
+    protected $siteName = 'Demo Gaslight Media';
+
+    /**
+        * Email subject and <h1> header in email
+        *
+        * It gets set in the constructor if you leave empty here, but you
+        * can set it to something different here to override that if you desire.
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $subject = 'Tell a Friend';
+
+    /**
+     * Whether the site has a contact DB to store contact records
+        *
+        * If this value is set to false, an email will still be sent to the
+        * addressed specified in the email property.
+        *
+     * @var    boolean
+     * @access protected
+     */
+       protected $hasContactDB = false;
+
+    /**
+     * The interests from the contact db
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $inquiries = array();
+
+    /**
+     * Message to display if the form is successfully submitted
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $successMsg = '
+               <div id="form-success-top">
+            Thank You, your message is sent.
+               </div>';
+
+    /**
+     * Extra rules for processesing
+        *
+        * This registers the Zip validation rules (and any others listed) for
+        * QuickForm.
+        *
+        * Zip validation checks both US and Canadian Zip codes
+        *
+     * @var    array
+     * @access protected
+        * @see    app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rules/Zip.php
+     */
+       protected $registeredRules = array();
+
+    /**
+     * Options for flexy templating engine
+        *
+        * Pulls the preset options from the setup.phtml file
+        * overwrites the templateDir and compileDir to match this classes needs
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $flexyOptions;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        *
+        * @access public
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               //      Make sure these end cases are never met.
+               //      These are more for the development phase.
+               if ($this->email === false && $this->hasContactDB === false) {
+                       PEAR::raiseError(
+                null,
+                NO_RECORD,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               if (!is_bool($this->hasContactDB)) {
+                       PEAR::raiseError(
+                null,
+                INVALID_DB,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+               //      we haven't defined the FROM_NEWS_EMAIL constant and
+               //      the email will default to relying on it.
+               if (   !defined('FROM_NEWS_EMAIL')
+            && (empty($this->email) && $this->email !== false)
+        ) {
+                       PEAR::raiseError(
+                'You need to define the FROM_NEWS_EMAIL
+                                constant for this form to work correctly',
+                MISSING_CONSTANT,
+                PEAR_ERROR_CALLBACK,
+                array(&$this, 'error')
+            );
+               }
+
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               if ($this->email !== false && empty($this->email)) {
+                       //      Set to false to turn off email function.
+                       $this->email = OWNER_EMAIL;
+               }
+               if (empty($this->siteName)) {
+                       $this->siteName = SITENAME;
+               }
+               if (empty($this->subject)) {
+                       $this->subject = "Your Pdf request from website " . SITENAME;
+               }
+
+               /**
+                * Where are the flexy templates stored at for this class.
+                */
+               define('TEMPLATES_DIR', BASE . 'Toolkit/Contacts/templates');
+
+               /**
+                * Where are the compiled flexy templates stored at for this class.
+                */
+               define('COMPILED_DIR', BASE . 'Toolkit/Contacts/templates/compiled');
+               $oldUmask = umask(0);
+               if (!is_dir(TEMPLATES_DIR)) {
+                       mkdir(TEMPLATES_DIR, 0770, true);
+               }
+               if (!is_dir(COMPILED_DIR)) {
+                       mkdir(COMPILED_DIR, 0770, true);
+               }
+               umask($oldUmask);
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+        $this->flexyOptions['charset']     = 'utf-8';
+        $this->flexyOptions['nonHTML']     = true;
+
+               $var = basename(__FILE__, '.php');
+
+               $callbackUrl = ($_SERVER['HTTPS'] == 'on') ?
+                                                         BASE_SECURE_URL : BASE_URL;
+
+               $this->captchaOptions = array(
+                       'width' => 100,
+                       'height' => 50,
+                       'callback' => "{$callbackUrl}Toolkit/qfcaptcha.php?var=$var",
+                       'sessionVar' => $var,
+                       'imageOptions' => array(
+                               'font_size' => 16,
+                               'font_path' => GLM_APP_BASE . 'glmPEAR/Image/Canvas/Fonts/',
+                               'font_file' => 'times.ttf',
+                               'background_color' => '#cccccc',
+                               'obfuscation' => false,
+                               'angle' => true,
+                       ),
+               );
+
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+               $this->configureConstants();
+       }
+
+       //      }}}
+       //      {{{     configureConstats()
+
+    /**
+     * Constant variables for the form
+        *
+        * These values won't get overridden by POST or GET vars
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureConstants()
+       {
+               $constants = array(
+                       'user_agent' => $_SERVER['HTTP_USER_AGENT'],
+                       'remote_addr' => $_SERVER['REMOTE_ADDR'],
+               );
+               $this->setupConstants($constants);
+       }
+
+       //      }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureDefaults()
+       {
+        $defaults = array(
+        );
+
+               $this->setupDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureElements()
+       {
+               //      All Elements are created here.  This includes group element definitions.
+               $elements[] = array('type' => 'hidden',                 'req' => false, 'name' => 'user_agent');
+               $elements[] = array('type' => 'hidden',                 'req' => false, 'name' => 'remote_addr');
+        $elements[] = array('type' => 'text',                  'req' => true,  'name' => 'fname',                              'display' => 'Friends Name:');
+        $elements[] = array('type' => 'text',                  'req' => true,  'name' => 'femail',                             'display' => 'Friends Email:');
+
+        $elements[] = array('type' => 'text',                  'req' => true,  'name' => 'yname',                              'display' => 'Your Name:');
+               $elements[] = array('type' => 'text',                   'req' => true,  'name' => 'yemail',                             'display' => 'Your Email:');
+
+               $elements[] = array('type' => 'CAPTCHA_Image',  'req' => false, 'name' => 'captcha_question',   'display' => null, 'opts' => $this->captchaOptions);
+               $elements[] = array('type' => 'text',                   'req' => true,  'name' => 'captcha_rmv',                'display' => 'Enter the letters you see');
+        $elements[] = array('type' => 'submit',                        'req' => false, 'name' => 'submit_rmv',                 'display' => 'Send Email');
+
+               $this->setupElements($elements);
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     *
+        * Adds validation rules for the given fields
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureRules()
+       {
+               //      Form Rules
+               $rules[] = array('element' => 'email',                                          'message' => 'ERROR: Invalid Email Format!',                            'type' => 'email',              'format' => null,       'validation' => $this->validationType, 'reset' => true, 'force' => false);
+
+               $rules[] = array('element' => 'captcha_rmv',                            'message' => 'ERROR: What you entered didn\'t match!',          'type' => 'CAPTCHA',    'format' => $this->captchaQuestion, 'validation' => $this->validationType, 'reset' => true, 'force' => false);
+
+               $this->setupRules($rules);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     *
+        * Applies a data filter for the given fields when the form is submitted
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureFilters()
+       {
+               $filters[] = array('element' => '__ALL__', 'filter' => 'trim');
+       }
+
+       //      }}}
+       //      {{{     emailFriend()
+
+    /**
+     * Emails the owner the submitted data from the submitted form
+     *
+        * Uses a flexy template to render a nice looking html email.
+        * Emails the link for pdf to person filling out form.
+        *
+     * @return boolean   result of the mailing
+     * @access protected
+     */
+    protected function emailFriend()
+       {
+               $template = new HTML_Template_Flexy($this->flexyOptions);
+               $page     = new stdClass();
+
+               $page->email_from  = FROM_NEWS_EMAIL;
+               $page->fname       = $this->getSubmitValue('fname');
+               $page->yname       = $this->getSubmitValue('yname');
+               $page->subject     = $this->subject;
+
+               $template->compile('friendEmail.html');
+               $htmlMsg = $template->bufferedOutputObject($page);
+
+               $crlf     = "\n";
+               $mimeMail = new Mail_mime($crlf);
+               $mimeMail->setFrom("{$this->siteName} <{$page->email_from}>");
+               $mimeMail->setSubject($this->subject);
+               $mimeMail->setHTMLBody($htmlMsg);
+
+               $mail    =& Mail::factory('mail');
+        $setting = array(
+            'text_charset'=>'utf-8',
+            'html_charset'=>'utf-8',
+        );
+        $body    = $mimeMail->get($setting);
+        $headers = $mimeMail->headers(array('Reply-To'=>$this->getSubmitValue('femail')), true);
+
+               $res = $mail->send($this->getSubmitValue('femail'), $headers, $body);
+               if (PEAR::isError($res)) {
+                       return Toolkit_Common::handleError($res);
+               } else {
+                       return $res;
+               }
+       }
+
+       //      }}}
+       //      {{{     error()
+
+    /**
+     * Display errors with the form to the user
+     *
+     * @param object $error PEAR Error Object
+        *
+     * @return void
+     * @access public
+     */
+       public function error($error)
+       {
+               //      make the variables static so that is only has to do the defining
+               //      on the first call.
+               static $errorMessages;
+               static $className;
+
+               //      define the various error messages
+               if (!isset($errorMessages)) {
+                       $className     = get_class($this);
+                       $errorMessages = array(
+                               FORM_OK                  => 'No error',
+                               FORM_ERROR               => 'Unknown error',
+                               NO_RECORD                => 'Setting both properties (email and hasContactDB) to false in the <i>' . $className . '</i> class will result in no email record being sent and no record being inserted into the database.  There will be no record that this form was ever filled out.',
+                               INVALID_DB               => 'Please set the property hasContactDB to a boolean value in the class <i>' . $className . '</i> before continuing',
+                               MISSING_CONSTANT => 'You have failed to set a CONSTANT for the class <i>' . $className . '</i> to function properly',
+                       );
+               }
+
+               if (!is_null($error->message)) {
+                       $message = $error->message;
+               } elseif (isset($errorMessages[$error->code])) {
+                       $message = $errorMessages[$error->code];
+               } else {
+                       $message = $errorMessages[$error->code];
+                       $message = $errorMessages[FORM_ERROR];
+               }
+
+               echo "<div id=\"form-warning-top\">{$message}</div>";
+       }
+
+       //      }}}
+       //      {{{     processData()
+
+    /**
+     * Handles how to process the form when submitted
+     *
+     * @param array $values Form submitted values
+        *
+     * @return array Result of Insert / Update function
+     * @access protected
+     */
+       protected function processData($values)
+       {
+               //      Form data used for the insert/update sql queries and
+               //      the form email.
+               $e = array(
+                       'mail_ok',
+                       'user_agent',
+                       'remote_addr'
+               );
+               $this->setFormData($e);
+
+
+               //      If no contact db, return true so we can send owner email.
+               if (!$this->hasContactDB) {
+                       return true;
+               }
+
+               //      Get rid of any defined un-needed elements.
+               //      un-needed elements after the form is submitted are defined
+               //      by the ending _rmv name.
+               foreach ($values as $k => &$v) {
+                       if (preg_match('/^.+_rmv$/', $k)) {
+                               unset($values[$k]);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Custom rendering templates for special fields on the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req">*</span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside">{error}</div><!-- END error -->';
+
+               $renderer->setElementTemplate('<tr><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'comments');
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'submit_rmv');
+
+               $renderer->setElementTemplate('<tr><td class="labelcell captcha">{element}</td>', 'captcha_question');
+               $renderer->setElementTemplate('<td class="fieldcell">'.$required.'{label}<br>'.$error.'{element}</td></tr>', 'captcha_rmv');
+       }
+
+       //      }}}
+       //      {{{     toHTML()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     *
+        * destroying and resetting the captcha value dis-allows someone from
+        * re-sending a form on a previous captcha.
+        *
+     * @return string form HTML state
+     * @access public
+     */
+       public function toHTML()
+       {
+               $GLOBALS['styleSheets'][] = BASE_URL . 'contactform.css';
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->captchaQuestion->destroy();
+                       $this->cleanForm();
+
+                       if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) {
+                               $this->freeze();
+                               $ret = $this->emailFriend();
+                               $output = $this->successMsg;
+                       }
+            $this->sent = true;
+               } elseif ($this->isSubmitted()) {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $this->captchaQuestion->destroy();
+                       $this->captchaAnswer->setValue('');
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Contacts/assets/.keepme b/Toolkit/Contacts/assets/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Toolkit/Contacts/database-table-modifiers.sql b/Toolkit/Contacts/database-table-modifiers.sql
new file mode 100644 (file)
index 0000000..b539d26
--- /dev/null
@@ -0,0 +1,46 @@
+CREATE SEQUENCE contact_id_seq
+    INCREMENT BY 1
+    NO MAXVALUE
+    NO MINVALUE
+    CACHE 1;
+
+ALTER TABLE contact ALTER COLUMN id SET DEFAULT nextval('contact_id_seq'::regclass);
+
+ALTER TABLE ONLY contact
+    ADD CONSTRAINT contact_pkey PRIMARY KEY (id);
+
+CREATE INDEX contact_create_date_indx ON contact USING btree (create_date);
+
+CREATE INDEX contact_email_indx ON contact USING btree (email);
+
+CREATE INDEX contact_fname_indx ON contact USING btree (fname);
+
+CREATE UNIQUE INDEX contact_id_indx ON contact USING btree (id);
+
+CREATE INDEX contact_lname_indx ON contact USING btree (lname);
+
+CREATE UNIQUE INDEX news_response_id_indx ON contact USING btree (id);
+
+CREATE UNIQUE INDEX query_db_id_indx ON contact USING btree (id);
+
+CREATE SEQUENCE contact_inq_id_seq
+    INCREMENT BY 1
+    NO MAXVALUE
+    NO MINVALUE
+    CACHE 1;
+
+ALTER TABLE contact_inq ALTER COLUMN id SET DEFAULT nextval('contact_inq_id_seq'::regclass);
+
+ALTER TABLE ONLY inq_group
+    ADD CONSTRAINT inq_group_pkey PRIMARY KEY (id);
+
+CREATE SEQUENCE inq_group_id_seq
+    INCREMENT BY 1
+    NO MAXVALUE
+    NO MINVALUE
+    CACHE 1;
+
+ALTER TABLE inq_group ALTER COLUMN id SET DEFAULT nextval('inq_group_id_seq'::regclass);
+
+ALTER TABLE ONLY inq_group
+    ADD CONSTRAINT inq_group_pkey PRIMARY KEY (id);
diff --git a/Toolkit/Contacts/database-tables.sql b/Toolkit/Contacts/database-tables.sql
new file mode 100644 (file)
index 0000000..1b71879
--- /dev/null
@@ -0,0 +1,45 @@
+CREATE TABLE contact (
+    id integer NOT NULL,
+    create_date date DEFAULT CURRENT_DATE,
+    fname text,
+    lname text,
+    company text,
+    address text,
+    address2 text,
+    city text,
+    state text,
+    zip text,
+    country text,
+    phone text,
+    fax text,
+    email text,
+    user_agent text,
+    remote_addr text,
+    interest text,
+    mail_ok boolean DEFAULT false,
+    visitorguide boolean DEFAULT false,
+    uidpdf text,
+    visitorguide_download boolean DEFAULT false,
+    email_verified boolean DEFAULT true,
+    contact_type text,
+    discover text,
+    member_ok boolean DEFAULT false,
+    staff boolean DEFAULT false,
+    comments text,
+    password text,
+    verify_password text
+);
+
+CREATE TABLE inq_group (
+    id integer NOT NULL,
+    name text
+);
+
+CREATE TABLE contact_inq (
+    id integer NOT NULL,
+    header text,
+    pos integer,
+    description text,
+    image text,
+    groupid integer
+);
diff --git a/Toolkit/Contacts/templates/brochurePage.html b/Toolkit/Contacts/templates/brochurePage.html
new file mode 100755 (executable)
index 0000000..b90d3d5
--- /dev/null
@@ -0,0 +1,9 @@
+<link type="text/css" rel="stylesheet" href="<?php echo BASE_URL;?>contactform.css">
+<div flexy:if="pdfForm"><strong>DOWNLOAD:</strong> 
+  <p>We will email you a link to the PDF version of the {brochure}.</p> 
+</div>
+<div>
+  {pdfForm:h}
+</div>
+<p style="clear: both;" flexy:if="contactForm"><strong>ORDER BY MAIL:</strong></p>
+{contactForm:h}
diff --git a/Toolkit/Contacts/templates/compiled/.cvsignore b/Toolkit/Contacts/templates/compiled/.cvsignore
new file mode 100644 (file)
index 0000000..65fb5e5
--- /dev/null
@@ -0,0 +1 @@
+* *.*
diff --git a/Toolkit/Contacts/templates/compiled/.keepme b/Toolkit/Contacts/templates/compiled/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Toolkit/Contacts/templates/currentTables/Element.tpl b/Toolkit/Contacts/templates/currentTables/Element.tpl
new file mode 100755 (executable)
index 0000000..595457b
--- /dev/null
@@ -0,0 +1,14 @@
+<tr>
+       <td class="labelcell">
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               <label>{label}</label>
+       </td>
+       <td class="fieldcell">
+               <!-- BEGIN error -->
+               <div class="req"> {error} </div>
+               <!-- END error -->
+               {element}
+       </td>
+</tr>
diff --git a/Toolkit/Contacts/templates/currentTables/Form.tpl b/Toolkit/Contacts/templates/currentTables/Form.tpl
new file mode 100755 (executable)
index 0000000..f59286a
--- /dev/null
@@ -0,0 +1,7 @@
+<div id="contact">
+       <form{attributes}>
+               <table>
+                       {content}
+               </table>
+       </form>
+</div>
diff --git a/Toolkit/Contacts/templates/currentTables/Group.tpl b/Toolkit/Contacts/templates/currentTables/Group.tpl
new file mode 100755 (executable)
index 0000000..cdd24cf
--- /dev/null
@@ -0,0 +1,5 @@
+<table class="group">
+       <tbody>
+               {content}
+       </tbody>
+</table>
diff --git a/Toolkit/Contacts/templates/currentTables/GroupElement.tpl b/Toolkit/Contacts/templates/currentTables/GroupElement.tpl
new file mode 100755 (executable)
index 0000000..1a4ba27
--- /dev/null
@@ -0,0 +1,9 @@
+<tr>
+       <td>
+               {element}
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               {label}
+       </td>
+</tr>
diff --git a/Toolkit/Contacts/templates/currentTables/Header.tpl b/Toolkit/Contacts/templates/currentTables/Header.tpl
new file mode 100755 (executable)
index 0000000..64ac244
--- /dev/null
@@ -0,0 +1,5 @@
+<tr class="hdr">
+       <td colspan="2">
+               {header}
+       </td>
+</tr>
diff --git a/Toolkit/Contacts/templates/currentTables/RequiredNote.tpl b/Toolkit/Contacts/templates/currentTables/RequiredNote.tpl
new file mode 100755 (executable)
index 0000000..dad5d0b
--- /dev/null
@@ -0,0 +1 @@
+<span class="req">* = Required Fields</span>
diff --git a/Toolkit/Contacts/templates/direct-list.html b/Toolkit/Contacts/templates/direct-list.html
new file mode 100755 (executable)
index 0000000..eefc842
--- /dev/null
@@ -0,0 +1,29 @@
+<h1>Your Trip Planner List</h1>
+<p>Below is the list of businesses you have added to your Trip Planner. The form below will be sent to each individual business listing that has an email address listed with their business listing. For those businesses with no email address, we have included their phone numbers for you to call directly and request additional information.</p>
+<h2 flexy:if="memberDirectNoEmail">Request Information by Phone from:</h2>
+<p>These business listings have no current email address on file. To receive additional information please call the phone numbers listed next to each business name.</p>
+<table flexy:if="memberDirectNoEmail">
+    <tr>
+        <th>Name</td>
+        <th>Phone</td>
+        <th>&nbsp;</td>
+    </tr>
+    {foreach:memberDirectNoEmail,member}
+    <tr class="{member[trclass]}">
+        <td><a href="{member[memberLink]}">{member[memberName]}</a></td>
+        <td>{member[memberPhone]}</td>
+        <td class="rowDelete"><a href="{member[deleteLink]}" style="text-decoration: underline;">Remove</a></td>
+    </tr>
+    {end:}
+</table>
+<h2 flexy:if="memberDirect">Request Information by Email from:</h2>
+<p flexy:if="memberDirect">This list of businesses will receive the following information form directly to their email account.</p>
+<table flexy:if="memberDirect">
+    {foreach:memberDirect,member}
+    <tr class="{member[trclass]}">
+        <td><a href="{member[memberLink]}">{member[memberName]}</a></td>
+        <td class="rowDelete"><a href="{member[deleteLink]}" style="text-decoration: underline;">Remove</a></td>
+    </tr>
+    {end:}
+</table>
+<h2 flexy:if="memberDirect">Plan Your Trip Information Request Form</h2>
diff --git a/Toolkit/Contacts/templates/emailOwner.tpl b/Toolkit/Contacts/templates/emailOwner.tpl
new file mode 100755 (executable)
index 0000000..e574342
--- /dev/null
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>{title:h}</title>
+</head>
+<body>
+       <!-- {{{ body -->
+       <p>
+               <font size="4" face="arial, sans-serif">
+                       <b>{subject:h}</b>
+               </font>
+       </p>
+       <p>
+               <font size="3" face="arial, sans-serif">
+                       <b>From {fname:h} {lname:h}</b>
+               </font>
+       </p>
+       <table cellspacing="0" cellpadding="0" bgcolor="#c0c0c0" border="0">
+               <tr>
+                       <td>
+                               <table cellspacing="1" cellpadding="5" border="0" bgcolor="#c0c0c0" width="400">
+                                       {foreach:formData,v}
+                                               <tr flexy:if="v[element]" bgcolor="#c0c0c0">
+                                                       <td align="right" bgcolor="#ffffff">
+                                                               <font size="2" face="arial, sans-serif">
+                                                                       <b>{v[label]:h}</b>
+                                                               </font>
+                                                       </td>
+                                                       {if:v[nowrap]}
+                                                               <td nowrap bgcolor="#ffffff">
+                                                                       <font size="2" face="arial, sans-serif">{v[element]:h}</font>
+                                                               </td>
+                                                       {else:}
+                                                               <td bgcolor="#ffffff">
+                                                                       <font size="2" face="arial, sans-serif">{v[element]:h}</font>
+                                                               </td>
+                                                       {end:}
+                                               </tr>
+                                       {end:}
+                               </table>
+                       </td>
+               </tr>
+               <tr>
+                       <td>
+                               <table cellspacing="0" cellpadding="10" border="0" width="400">
+                                       <tr>
+                                               <td bgcolor="#eeeeee">
+                                                       <font size="1" face="arial, sans-serif">
+                                                               To ensure the delivery of these e-mails to your inbox, please add {email_from:h} to your e-mail Address Book or Safe List.
+                                                       </font>
+                                               </td>
+                                       </tr>
+                               </table>
+                       </td>
+               </tr>                           
+                                                       
+       </table>
+       <!-- }}} -->
+</body>
+</html>
diff --git a/Toolkit/Contacts/templates/friendEmail.html b/Toolkit/Contacts/templates/friendEmail.html
new file mode 100644 (file)
index 0000000..358ded6
--- /dev/null
@@ -0,0 +1,49 @@
+<html>
+               <style type="text/css">
+               <!--
+               body { background-color: #fff;
+                       color: black;
+                       font-family: verdana, arial, helvetica, sans-serif;
+                       }
+               h1, h2 {font-family: arial, helvetica, sans-serif;}     
+               h1 {font-size: 18px; }
+               h2 {font-size: 16px; margin-bottom: 5px;}
+               p {font-size: 12px;}
+               .label {
+                       font-weight: bold; 
+                       background-color: transparent;
+                       text-align: right;
+                       width: 200px;
+                       padding: 5px;
+                       }
+               .field {
+                       //background-color: #F2F7FB;
+                       background-color: #fff;
+                       padding: 3px;
+                       }
+               table.data { 
+                       //background-color: #F9FBFD; 
+                       background-color: #fff; 
+                       color: #000; 
+                       width: 500px;  
+                       //border: 1px solid #D7E5F2; 
+                       border: 1px solid #ccc; 
+                       border-collapse: collapse; 
+                       margin-left: 20px;
+                       }
+               table.data td { 
+                       //border: 1px solid #D7E5F2; 
+                       border: 1px solid #ccc; 
+                       padding-left: 4px; 
+                       font-size: 12px;
+                       }       
+               -->
+</style>
+<body>
+               
+    <p>Dear {fname}</p>
+    <p>Your friend {yname} has been to <a href="baseurl">demo.gaslightmedia.com</a>, and thought you might be interested in it. </p>
+    <p>Message here.</p>
+    <div>&nbsp;</div><br clear="all">
+</body>
+</html>
diff --git a/Toolkit/Contacts/templates/pdfDownloadEmail.html b/Toolkit/Contacts/templates/pdfDownloadEmail.html
new file mode 100755 (executable)
index 0000000..6f01198
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>{title:h}</title>
+</head>
+<body>
+               <!-- {{{ body -->
+        <b>{subject:h}</b>
+        <p>Thank you for requesting the {pdfName} Link.  Here is the link to the Adobe PDF version:
+            </p>
+        <p><a href="{pdfLinkURL}">Brochure</a> ({pdfFileSize})</p>
+        <p>Thank you for your interest in {client_info[name]:h}'!</p>
+        <p>Sincerely,</p>
+        <p>{client_info[name]:h}</p>
+        <p>{client_info[url]:h}</p>
+               <!-- }}} -->
+</body>
+</html>
diff --git a/Toolkit/Coupons/Category.php b/Toolkit/Coupons/Category.php
new file mode 100644 (file)
index 0000000..db77db9
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+class Toolkit_Coupons_Category
+{
+       private $_id;
+       private $_name;
+
+       public function __construct($name)
+       {
+               $this->_name = $name;
+       }
+
+       private function _getTableData()
+       {
+               $classData = get_object_vars($this);
+               $dataKeys = array_keys($classData);
+               $dataValues = array_values($classData);
+               $func = create_function('$v', 'return substr($v, 1);');
+               $newKeys = array_map($func, $dataKeys);
+
+               return array_combine($newKeys, $dataValues);
+       }
+
+       public function setName($name)
+       {
+               $this->_name = $name;
+       }
+
+       public function getName()
+       {
+               return $this->_name;
+       }
+
+       public function insert(PDO $dbh)
+       {
+               $classData = $this->_getTableData();
+               unset($classData['id']);
+
+               $sql = Toolkit_Common::createSQLInsert(
+                       'coupon_category',
+                       array_keys($classData)
+               );
+
+               try {
+                       $dbh->beginTransaction();
+                       Toolkit_Common::processQuery(
+                               $dbh,
+                               'coupon_category',
+                               $sql,
+                               $classData
+                       );
+
+                       $sql = "
+                SELECT id
+                  FROM coupon_category
+                 ORDER BY id DESC LIMIT 1";
+
+                       $row = $dbh->query($sql, PDO::FETCH_ASSOC)->fetch();
+
+                       $dbh->commit();
+
+                       $this->_id = $row['id'];
+                       return $this->_id;
+               } catch (PDOException $e) {
+                       $dbh->rollback();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       public function update(PDO $dbh)
+       {
+       date_default_timezone_set('America/New_York');
+$d = new Date();
+$d->setDate('10-17-2008');
+print_r($d);
+die;
+               $classData = $this->_getTableData();
+               $id = $classData['id'];
+               unset($classData['id']);
+
+               $sql = Toolkit_Common::createSQLUpdate(
+                       'coupon_category',
+                       array_keys($classData),
+                       array('id = :id')
+               );
+
+               try {
+                       $classData['id'] = $id;
+                       return Toolkit_Common::processQuery(
+                               $dbh,
+                               'coupon_category',
+                               $sql,
+                               $classData
+                       );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+}
+?>
diff --git a/Toolkit/Coupons/Coupon.php b/Toolkit/Coupons/Coupon.php
new file mode 100644 (file)
index 0000000..423dc1f
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+abstract class Toolkit_Coupons_Coupon
+{
+       protected $id;
+       protected $title;
+       protected $description;
+       protected $image;
+       protected $expiration;
+
+       public function setTitle($title)
+       {
+               $this->title = $title;
+       }
+
+       public function setDescription($description)
+       {
+               $this->description = $description;
+       }
+
+       public function setImage($image)
+       {
+               $this->image = $image;
+       }
+
+       public function setExpiration(Date $expiration)
+       {
+               $this->expiration = $expiration;
+       }
+
+       public function getTitle()
+       {
+               return $this->title;
+       }
+
+       public function getDescription()
+       {
+               return $this->description;
+       }
+
+       public function getImage()
+       {
+               return $this->image;
+       }
+
+       public function getExpiration()
+       {
+               return $this->expiration;
+       }
+}
+?>
diff --git a/Toolkit/Coupons/Database/application.sql b/Toolkit/Coupons/Database/application.sql
new file mode 100644 (file)
index 0000000..e09edc2
--- /dev/null
@@ -0,0 +1,13 @@
+--
+-- Tables
+--
+\i ./tables/coupon_category.sql
+\i ./tables/coupons.sql
+
+--
+-- Procedures
+--
+
+--
+-- Modules
+--
diff --git a/Toolkit/Coupons/Database/tables/coupon_category.sql b/Toolkit/Coupons/Database/tables/coupon_category.sql
new file mode 100644 (file)
index 0000000..3800073
--- /dev/null
@@ -0,0 +1,7 @@
+CREATE TABLE coupon_category
+(id INTEGER NOT NULL,
+ name TEXT NOT NULL,
+ PRIMARY KEY (id));
+
+GRANT ALL ON coupon_category_id_seq TO nobody;
+GRANT ALL ON coupon_category TO nobody;
diff --git a/Toolkit/Coupons/Database/tables/coupons.sql b/Toolkit/Coupons/Database/tables/coupons.sql
new file mode 100644 (file)
index 0000000..9d32c1f
--- /dev/null
@@ -0,0 +1,22 @@
+CREATE TABLE coupons
+(id INTEGER NOT NULL,
+ title TEXT,
+ description TEXT,
+ url TEXT,
+ sdate DATE NOT NULL,
+ edate DATE NOT NULL,
+ expiration DATE NOT NULL,
+ category INTEGER
+       REFERENCES coupon_category (id)
+       ON UPDATE CASCADE
+       ON DELETE CASCADE,
+ active BOOLEAN NOT NULL DEFAULT FALSE,
+ member INTEGER
+       REFERENCES member (member_id)
+       ON UPDATE CASCADE
+       ON DELETE CASCADE,
+ image TEXT,
+ PRIMARY KEY (id));
+
+GRANT ALL ON coupons_id_seq TO nobody;
+GRANT ALL ON coupons TO nobody;
diff --git a/Toolkit/Coupons/ICoupon.php b/Toolkit/Coupons/ICoupon.php
new file mode 100644 (file)
index 0000000..570e210
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+interface Toolkit_Coupons_ICoupon
+{
+       public function insert(PDO $dbh);
+       public function update(PDO $dbh);
+}
+?>
diff --git a/Toolkit/Coupons/IFactory.php b/Toolkit/Coupons/IFactory.php
new file mode 100644 (file)
index 0000000..def769d
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+interface Toolkit_Coupons_IFactory
+{
+       public function createCoupon();
+}
+?>
diff --git a/Toolkit/Coupons/MemberCoupon.php b/Toolkit/Coupons/MemberCoupon.php
new file mode 100644 (file)
index 0000000..8450017
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+class Toolkit_Coupons_MemberCoupon extends Toolkit_Coupons_Coupon
+       implements Toolkit_Coupons_ICoupon
+{
+       protected $category;
+
+       public function __construct(array $data)
+       {
+               if (!isset($data['title'])) {
+                       throw new BadMethodCallException('Missing title property');
+               }
+               if (!isset($data['description'])) {
+                       throw new BadMethodCallException('Missing description');
+               }
+
+               $this->title       = $data['title'];
+               $this->image       = $data['image'];
+               if (isset($data['description'])) {
+                       $this->description = $data['description'];
+               }
+               if (isset($data['expiration'])) {
+                       $this->expiration  = $data['expiration'];
+               }
+       }
+
+       public function setCategory ($category)
+       {
+               settype($category, 'integer');
+
+               $this->category = $category;
+       }
+
+       public function getCategory()
+       {
+               return $this->category;
+       }
+
+       public function insert(PDO $dbh)
+       {
+               $classData = get_object_vars($this);
+               $classData['expiration'] = $this->expiration->format('%m-%d-%Y');
+               unset($classData['id']);
+
+               $sql = Toolkit_Common::createSQLInsert(
+                       'coupons',
+                       array_keys($classData)
+               );
+
+               try {
+                       $dbh->beginTransaction();
+                       Toolkit_Common::processQuery(
+                               $dbh,
+                               'coupons',
+                               $sql,
+                               $classData
+                       );
+
+                       $sql = "
+                SELECT id
+                  FROM coupons
+                 ORDER BY id DESC LIMIT 1";
+
+                       $row = $dbh->query($sql, PDO::FETCH_ASSOC)->fetch();
+
+                       $dbh->commit();
+
+                       $this->id = $row['id'];
+                       return $this->id;
+               } catch (PDOException $e) {
+                       $dbh->rollback();
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       public function update(PDO $dbh)
+       {
+               $classData = get_object_vars($this);
+               $classData['expiration'] = $this->expiration->format('%m-%d-%Y');
+               $id = $classData['id'];
+               unset($classData['id']);
+
+               $sql = Toolkit_Common::createSQLUpdate(
+                       'coupons',
+                       array_keys($classData),
+                       array('id = :id')
+               );
+
+               try {
+                       $classData['id'] = $id;
+                       return Toolkit_Common::processQuery(
+                               $dbh,
+                               'coupons',
+                               $sql,
+                               $classData
+                       );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+}
+?>
diff --git a/Toolkit/Coupons/MemberFactory.php b/Toolkit/Coupons/MemberFactory.php
new file mode 100644 (file)
index 0000000..4bb9241
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+class Toolkit_Coupons_MemberFactory implements Toolkit_Coupons_IFactory
+{
+       public function createCoupon()
+       {
+               return new Toolkit_Coupons_MemberCoupon();
+       }
+}
+?>
diff --git a/Toolkit/DataGridBuilder.php b/Toolkit/DataGridBuilder.php
new file mode 100644 (file)
index 0000000..0666dcf
--- /dev/null
@@ -0,0 +1,285 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Create Datagrids for displaying data
+ *
+ * PHP version 5
+ *
+ * @category Structures
+ * @package  Toolkit_DataGridBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Create Datagrids for displaying data
+ *
+ * This abstract class handles all the base functionality of creating
+ * handeling all the details associated w/ a regular dataGrid.
+ * 1. Creation
+ * 2. Sorting (via column headers or sortform)
+ * 3. Pagenation
+ *
+ * @category  Structures
+ * @package      Toolkit_DataGridBuilder
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @Release      CVS: $Id: DataGridBuilder.php,v 1.13 2009/09/16 00:07:44 jamie Exp $
+ * @link         http://demo.gaslightmedia.com
+ * @see                  Toolkit_SortForm, Structures_DataGrid
+ */
+abstract class Toolkit_DataGridBuilder extends Structures_DataGrid
+{
+       //      {{{ properties
+
+    /**
+     * Options to pass to DataGrid
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $options;
+
+    /**
+     * Rendering options for DataGrid
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $rendererOptions = array(
+               'sortIconASC' => '&uArr;',
+               'sortIconDESC'  => '&dArr;',
+               'evenRowAttributes' => 'class="even"',
+               'oddRowAttributes' => 'class="odd"',
+               'sortingResetsPaging' => false,
+       );
+
+    /**
+     * Rendering options for DataGrid paging element
+        *
+     * @var    array    
+     * @access protected
+     */
+       protected $pagerOptions = array(
+               'nextImg' => 'Next',
+               'prevImg' => 'Previous',
+               'separator' => '',
+               'spacesBeforeSeparator' => 0,
+               'spacesAfterSeparator' => 0,
+               'containerClass' => 'paging',
+       );
+
+    /**
+     * SQL query used to obtain the DataGrid
+        *
+     * @var    unknown  
+     * @access protected
+     */
+       protected $sql;
+
+    /**
+     * How many records must exist in the Datagrid before the sort form shows up
+        *
+     * @var    integer  
+     * @access protected
+     */
+       protected $sortableAfter = 10;
+
+    /**
+     * The HTML table id of the DataGrid
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $tableId = 'dataGrid';
+
+    /**
+     * The HTML class name of the DataGrid
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $tableClass = 'dataGrid';
+
+    /**
+     * The HTML id of the DataGrid sorting form (when present)
+        *
+     * @var    string   
+     * @access protected
+     */
+       protected $sortFormId = 'gridSorter';
+
+       /**
+        * Message to display to users if no records were found
+        *
+        * @var         String
+        * @access      Protected
+        * @see         Toolkit_DataGridBuilder::setNoRecordMessage()
+        */
+       protected $noRecMessage = 'No Records';
+
+       //      }}}
+       //      {{{ __construct()
+
+    /**
+     * DataGrid constructor
+     * 
+     * Instantiates a DataGrid and sets up when to make the grid sortable
+     * 
+        * @param PDO     $pdo          PDO object used in the datagrid
+     * @param integer $limit        The number of records to display per page.
+     * @param integer $page         The current page view. In most cases,
+        *                                                              this is useless. Note: if you specify
+        *                                                              this, the "page"GET variable will be ignored.
+     * @param string  $rendererType The type of renderer to use. You may
+        *                                                              prefer to use the $type argument of
+        *                                                              render, fill or getOutput.
+        *
+     * @return void   
+     * @access public 
+     */
+       public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+               parent::__construct($limit, $page, $rendererType);
+
+               $this->options = array('dbc' => $pdo);
+               if (!is_null($limit)) {
+                       $this->sortableAfter = $limit;
+               }
+       }
+
+       //      }}}
+
+    //  {{{ configureColumns()
+
+    /**
+     * configure retrieved columns
+     *
+     * Tells the DataGrid how to render the retrieved columns
+     * 
+        * @return void
+     * @access protected
+     */
+    abstract protected function configureColumns();
+
+    //  }}}
+
+       //      {{{ setNoRecordMessage()
+
+    /**
+     * The message to display if no results were found from the sql query
+     * 
+     * @param string $msg No result message.
+        *
+     * @return void   
+     * @access public 
+     */
+       public function setNoRecordMessage($msg)
+       {
+               $this->noRecMessage = $msg;
+       }
+
+       //      }}}
+       //      {{{ setQuery()
+
+    /**
+     * Sets the sql query to use in the DataGrid to get the results
+     * 
+     * @param string $sql The SQL query
+        *
+     * @return void   
+     * @access public 
+     */
+       public function setQuery($sql)
+       {
+               $this->sql = $sql;
+       }
+
+       //      }}}
+       //      {{{ show()
+
+    /**
+     * Displays the DataGrid results
+     * 
+     * @return void  
+     * @access public
+     */
+       public function show()
+       {
+               echo $this->toHTML();
+       }
+       
+       //      }}}
+
+       //      {{{ toHTML()
+
+    /**
+     * returns a HTML table of the datagrid
+     * 
+     * @return string
+     * @access public 
+     */
+       public function toHTML()
+       {
+        $this->configureColumns();
+
+               try {
+                       $bind = $this->bind($this->sql, $this->options, 'PDO');
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               if (PEAR::isError($bind)) {
+            return Toolkit_Common::handleError($bind);
+               } elseif (($recCount = $this->getRecordCount()) > 0) {
+                       $this->setRendererOptions($this->rendererOptions);
+                       $renderer =& $this->getRenderer();
+                       //      Allows us to turn off the id name for the table,
+                       //      when we subclass this class out.
+                       if ($this->tableId) {
+                               $renderer->setTableAttribute('id', $this->tableId);
+                       }
+                       //      Allows us to turn off the class name for the table,
+                       //      when we subclass this class out.
+                       if ($this->tableClass) {
+                               $renderer->setTableAttribute('class', $this->tableClass);
+                       }
+                       $gridBody = $this->getOutput();
+
+                       if (PEAR::isError($gridBody)) {
+                return Toolkit_Common::handleError($gridBody);
+                       }
+
+                       $gridPager = $this->getOutput(
+                DATAGRID_RENDER_PAGER,
+                               array('pagerOptions' => $this->pagerOptions)
+            );
+                       if (PEAR::isError($gridPager)) {
+                return Toolkit_Common::handleError($gridPager);
+                       }
+
+                       if ($recCount > $this->sortableAfter) {
+                               $form    = new Toolkit_SortForm($this->sortFormId);
+                               $options = array('directionStyle' => 'radio');
+                               $this->fill($form, $options, DATAGRID_RENDER_SORTFORM);
+                               //      Datagrid never ads a submit button.
+                               $form->addElement('submit', null, 'Submit');
+                               $gridSorter = $form->toHTML();
+                       }
+
+                       return $gridPager . $gridSorter . $gridBody . $gridPager;
+               } else {
+                       return "<h2>{$this->noRecMessage}</h2>";
+               }
+       }
+               
+       //      }}}
+}
+?>
diff --git a/Toolkit/Database.php b/Toolkit/Database.php
new file mode 100644 (file)
index 0000000..1bab552
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Database Singleton
+ *
+ * PHP version 5
+ *
+ * @category Database
+ * @package  Toolkit_Database
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: Database.php,v 1.4 2009/11/15 19:06:21 jamie Exp $
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Database Singleton class
+ *
+ * @category  Database
+ * @package   Toolkit_Database
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Database
+{
+       //      {{{     properties
+
+    /**
+     * Database handler object
+        *
+     * @var PDO
+     * @access private
+     */
+       private $_dbh;
+
+    /**
+     * Class instance
+        *
+     * @var Toolkit_Database
+     * @access private
+     */
+       private static $_instance;
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+        * Make the database handler connection for the class
+        *
+        * @access private
+        */
+       private function __construct()
+       {
+               try {
+                       $dsn = 'pgsql:' . CONN_STR;
+                       //      Keep the fetch mode set to FETCH_BOTH, we use
+                       //      associative arrays throughout our apps, but some PEAR lib
+                       //      apps require numerical indicies to work correctly.
+                       //      i.e. (DataGrids working w/ PDO's)
+                       $driverOptions = array(
+                               PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_BOTH,
+                       );
+                       $this->_dbh = new PDO($dsn, null, null, $driverOptions);
+                       $this->_dbh->setAttribute(
+                               PDO::ATTR_ERRMODE,
+                               PDO::ERRMODE_EXCEPTION
+                       );
+                       $this->_dbh->query("SET DATESTYLE TO 'SQL,US'");
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     __clone()
+
+       /**
+        * Clone magic method
+        *
+        * Don't allow cloning of instances of this class
+        * which could potentially duplicate system resources
+        * and make extra DB connections
+        *
+        * @return void
+        * @access private
+        */
+       private function __clone()
+       {
+               //      Do nothing so we don't create duplicate resources
+       }
+
+       //      }}}
+
+       //      {{{     getInstance()
+
+       /**
+        * Get an instance of this class
+        *
+        * If this object hasn't been instantiated once already
+        * then create the object and return the dbh.
+        * Otherwise just return the already instantiated dbh.
+        *
+        * @return PDO $_instance database handler instance
+        * @access public
+        * @static
+        */
+       public static function getInstance()
+       {
+               if (!(self::$_instance instanceof self)) {
+                       self::$_instance = new self();
+               }
+
+               return self::$_instance->_dbh;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/FlexyDataGridBuilder.php b/Toolkit/FlexyDataGridBuilder.php
new file mode 100644 (file)
index 0000000..d41e241
--- /dev/null
@@ -0,0 +1,222 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Create Flexy templating Datagrids for displaying data
+ *
+ * PHP version 5
+ *
+ * @category Structures
+ * @package  Toolkit_FlexyDataGridBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version     CVS: $Id: FlexyDataGridBuilder.php,v 1.13 2009/12/29 14:27:55 jamie Exp $
+ * @link        <>
+ */
+
+/**
+ * Create Flexy templating Datagrids for displaying data
+ *
+ * This abstract class handles all the base functionality of creating
+ * handeling all the details associated w/ a Flexy template datagrid
+ * 1. Creation
+ * 2. Sorting (via column headers or sortform)
+ * 3. Pagenation
+ *
+ * @category  Structures
+ * @package      Toolkit_FlexyDataGridBuilder
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com/Gaslightmedia Gaslightmedia
+ * @link         http://pear.php.net/package/Structures_DataGrid/docs
+ * @see                  Structures_DataGrid_Renderer_Flexy, HTML_Template_Flexy
+ */
+abstract class Toolkit_FlexyDataGridBuilder extends Toolkit_DataGridBuilder
+{
+       //      {{{ properties
+
+       /**
+        * Name of the table which we will be dealing with
+        *
+        * @var string
+        * @access protected
+        */
+       protected $tableName;
+
+       /**
+        * The name of the template that renders this datagrid
+        *
+        * @var string
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * Output an object as $t to the template
+        *
+        * converts array keys to objects usable in a template form.
+        *
+        * <code>
+        *   $this->ctrlObj['url'] = BASE_URL;
+        * </code>
+        *
+        * <example>
+        *   <img alt="{row[img]} src="{url}images/member_thumb/{row[img]}">
+        * </example>
+        *
+        * @var array
+        * @access protected
+        */
+       protected $ctrlObj = array();
+
+    /**
+     * Rendering options for DataGrid
+        *
+     * @var    array
+     * @access protected
+     */
+       protected $rendererOptions = array(
+               'sortIconASC' => '&uArr;',
+               'sortIconDESC'  => '&dArr;',
+               'sortingResetsPaging' => false,
+       );
+
+    /**
+     * The HTML id of the DataGrid
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $gridId = 'dataGrid';
+
+    /**
+     * The HTML class of the DataGrid
+        *
+     * @var    string
+     * @access protected
+     */
+       protected $gridClass = 'dataGrid';
+
+       //      }}}
+       //      {{{ __construct()
+
+    /**
+     * Constructor
+     *
+     * Builds the DataGrid class.
+     *
+        * @param PDO     $pdo          PDO object used in the datagrid
+     * @param integer $limit        The number of records to display per page.
+     * @param integer $page         The current page view. In most cases,
+        *                                                              this is useless. Note: if you specify
+        *                                                              this, the "page"GET variable will be ignored.
+     * @param string  $rendererType The type of renderer to use. You may
+        *                                                              prefer to use the $type argument of
+        *                                                              render, fill or getOutput.
+        *
+     * @return void
+     * @access public
+     */
+       public function __construct(
+        PDO $pdo,
+        $limit = null,
+        $page = null,
+        $rendererType = null
+    ) {
+        $this->dbh = $pdo;
+               if (ctype_digit($_GET['setPerPage'])) {
+                       $limit = $_GET['setPerPage'];
+               }
+
+               parent::__construct($pdo, $limit, $page, $rendererType);
+
+               //      If all records show on one page, then hide sort form.
+               if (!is_null($limit)) {
+                       $this->sortableAfter = $limit;
+               }
+       }
+
+       //      }}}
+
+       //      {{{ show()
+
+    /**
+     * Displays the DataGrid results
+     *
+     * @param Structures_DataGrid_Renderer_Flexy $renderer Rendering engine used to render DG
+     *
+     * @return void
+     * @access public
+     */
+       public function show(Structures_DataGrid_Renderer_Flexy $renderer)
+       {
+               echo $this->toHtml($renderer);
+       }
+
+       //      }}}
+
+       //      {{{ toHtml()
+
+    /**
+     * Returns the DataGrid
+     *
+     * @param Structures_DataGrid_Renderer_Flexy $renderer Rendering engine used to render DG
+     *
+     * @return string html templated datagrid results
+     * @access public
+     */
+       public function toHtml(
+               Structures_DataGrid_Renderer_Flexy $renderer,
+               $template = null
+       ) {
+        $this->configureColumns();
+
+               try {
+                       $bind = $this->bind($this->sql, $this->options, 'PDO');
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               if (PEAR::isError($bind)) {
+            return Toolkit_Common::handleError($bind);
+               }
+
+               if (method_exists($this, 'setControlObject')) {
+                       $this->setControlObject();
+                       foreach ($this->ctrlObj as $k => $v) {
+                               $renderer->$k = $v;
+                       }
+               }
+
+               $renderer->setOptions($this->rendererOptions);
+               $renderer->setOptions(array('pagerOptions' => $this->pagerOptions));
+
+               $this->attachRenderer($renderer);
+               $tEngine = $renderer->getContainer();
+
+               $pathToTemplate = $tEngine->options['templateDir'][0];
+
+               if (   !is_null($template)
+                       && file_exists("$pathToTemplate/$template")
+               ) {
+                       $tEngine->compile($template);
+               } elseif (isset($this->template)
+                                 && file_exists($pathToTemplate . $this->template)
+               ) {
+                       $tEngine->compile($this->template);
+               } else {
+                       throw new RuntimeException('Template not available');
+               }
+
+               //      Get the entire datagrid body.
+               $gridBody = $this->getOutput();
+               if (PEAR::isError($gridBody)) {
+            return Tolkit_Common::handleError($gridBody);
+               }
+
+               return $gridSorter . $gridBody;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Form.php b/Toolkit/Form.php
new file mode 100644 (file)
index 0000000..c9e8d2e
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Define how form objects should be built
+ * 
+ * PHP version 5
+ * 
+ * @category  Form
+ * @package   Toolkit_Form
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @version   CVS: $Id: Form.php,v 1.6 2009/08/31 17:43:48 jamie Exp $
+ * @link      http://demo.gaslightmedia.com/
+ */
+
+/**
+ * Minimum form object method definitions
+ * 
+ * Each form must at least define some elements and setup the rules for
+ * that form.  They must also create a method which handless extracting
+ * the form object into an html string suitable to be displayed onto a
+ * page.
+ * 
+ * @category  Form
+ * @package   Toolkit_Form
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com/
+ */
+interface Toolkit_Form
+{
+    //  {{{ configureElements()
+
+    /**
+     * Defines all elements to be used in a form
+     *
+     * Creates an array of elements and passes them off to the setupElements
+     * function wich adds each element to the form object.
+     * 
+     * <code>
+     * public function configureElements()
+     * {
+     *   $e = array();
+     *
+     *   $e[] = array(
+     *     'type'    => 'text',
+     *     'req'     => false
+     *     'name'    => 'text_field',
+     *     'display' => 'Text Label',
+     *   );
+     *   $e[] = array(
+     *     'type'    => 'checkbox',
+     *     'req'     => false
+     *     'name'    => 'checkbox_field',
+     *     'display' => 'Checkbox Label',
+     *   );
+     *
+     *   // ... More Element Definitions
+     *
+     *   $this->setupElements($e);
+     * }
+     * </code>
+     * 
+     * @access public
+     * @return void
+     */
+    //public function configureElements();
+
+    //  }}}
+    //  {{{ configureForm()
+
+    /**
+     * Calls all the configuration methods to configure a form for use
+     * 
+     * @access public
+     * @return void
+     */
+    //public function configureForm();
+
+    //  }}}
+    //  {{{ configureRules()
+
+    /**
+     * Defines all element rules to be used for validation in the form
+     * 
+     * At the bare minimum, this function needs to be called to setup the
+     * form rules, even if no extra rules are defined.  Because it still
+     * creates all the required rules that are defined w/ each element.
+     *
+     * <code>
+     * public function configureRules()
+     * {
+     *   $r = array();
+     *
+        *   $r[] = array(
+     *     'element'    => 'text_field',
+        *     'message'    => 'ERROR: 10 characters max!',
+        *     'type'       => 'maxlength',
+        *     'format'     => 10,
+        *     'validation' => $this->validationType,
+        *     'reset'      => true,
+        *     'force'      => false,
+     *   );
+        *   $r[] = array(
+     *     'element'    => 'text_field',
+        *     'message'    => 'ERROR: Numric characters only!',
+        *     'type'       => 'numeric',
+        *     'format'     => null,
+        *     'validation' => $this->validationType,
+        *     'reset'      => true,
+        *     'force'      => false,
+     *   );
+     *
+     *   // ... More Rule Definitions
+     *
+     *   $this->setupRules($r);
+     * }
+     * </code>
+     * 
+     * @access public
+     * @return void
+     */
+    public function configureRules();
+
+    //  }}}
+    //  {{{ toHtml()
+
+    /**
+     * Get an html string that contains the form
+     * 
+     * Check if the form needs to be validated (ie. it was submitted)
+     * Check if submitted data needs to be processed
+     * 
+     * @access public
+     * @return string an html string that contains the entire form
+     */
+    public function toHtml();
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/FormBuilder.php b/Toolkit/FormBuilder.php
new file mode 100644 (file)
index 0000000..20bfbaf
--- /dev/null
@@ -0,0 +1,1197 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Forms
+ * @package  Toolkit_FormBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: FormBuilder.php,v 1.39 2010/01/30 17:05:35 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Allow the inclusion of the Element Grid plugin for QuickForms
+ */
+require_once 'HTML/QuickForm/ElementGrid.php';
+
+/**
+ * Handle QuickForm CAPTCHA's
+ */
+require_once 'HTML/QuickForm/CAPTCHA/Image.php';
+
+/**
+ * Require PEAR QuickForm class
+ */
+require_once 'HTML/QuickForm.php';
+
+require_once 'HTML/QuickForm/Rule/Zip.php';
+require_once 'HTML/QuickForm/Rule/Phone.php';
+require_once 'HTML/QuickForm/Rule/Banwords.php';
+require_once 'HTML/QuickForm/Rule/State.php';
+
+/**
+ * Base functionality for creating HTML_Quickforms
+ *
+ * @category  Forms
+ * @package      Toolkit_FormBuilder
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+abstract class Toolkit_FormBuilder extends HTML_QuickForm
+{
+       //      {{{     properties
+
+    /**
+     * Global form captcha question element
+        *
+     * @var object
+     * @access protected
+     */
+       protected $captchaQuestion;
+
+    /**
+     * Global form captcha answer from user
+        *
+     * @var object
+     * @access protected
+     */
+       protected $captchaAnswer;
+
+    /**
+     * Form submitted data used when emailing form results
+        *
+     * @var array
+     * @access protected
+     */
+       protected $formData = array();
+
+       /**
+        * Automatically create validation rules for any date elements
+        *
+        * This will only work if the date element is in m-d-Y format
+        *
+        * @var boolean
+        * @access protected
+        */
+       protected $autoValidateDateElements = true;
+
+       /**
+        * How do we want to validate the form
+        *
+        * Possible options are [server, client]
+        *
+        * @var string
+        * @access protected
+        */
+       protected $validationType = 'server';
+
+       /**
+        * What do you want the error msg to be if the form doesn't validate
+        *
+        * @var string
+        * @access protected
+        */
+       protected $errorMsg
+        = '<div id="form-warning-top">
+                Warning: The form was not sent, please review the errors below.
+           </div>';
+
+       /**
+        * What do you want the success msg to be if the form validates successfully
+        *
+        * @var string
+        * @access protected
+        */
+       protected $successMsg
+        = '<div id="form-success-top">
+                The information below has been successfully submitted.
+           </div>';
+
+       /**
+        * Whether uploaded files should be processed too (if present)
+        *
+        * @var string
+        * @access protected
+        */
+       protected $mergeFiles = true;
+
+    /**
+     * Include a captcha on the form or not
+        *
+     * @var    boolean
+     * @access protected
+     */
+       protected $useCaptcha;
+
+       /**
+        * The default templates to inject into the form renderer
+        *
+        * @var string
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * The default rules to register for validating
+        *
+        * We have to register these rules, or any others we want, before
+        * we are able to use them in our forms.
+        *
+        * These rules can be removed in subclasses before the rules are configured
+        * if you want to omit any of them from validating input - just remember
+        * to not call them in your configured rules!
+        *
+        * Phone: validates input against US and CA style phone #'s
+        * <code>
+        * $rules[] = array('element'    => 'phone',
+        *                  'message'    => 'ERROR: Invalid Phone Format!',
+        *                  'type'       => 'phone',
+        *                  'format'     => null,
+        *                  'validation' => $this->validationType,
+        *                  'reset'      => true,
+        *                  'force'      => false);
+        * </code>
+        *
+        * Zip: Validates input against US and CA zip codes, if DB check is
+        *      set to true, validate zip codes against all the zip codes in the
+        *      DB.
+        * <code>
+        * $rules[] = array('element'    => 'zip',
+        *                  'message'    => 'ERROR: Invalid Zip!',
+        *                  'type'       => 'zip',
+        *                  'format'     => array('requireDBCheck' => true),
+        *                  'validation' => $this->validationType,
+        *                  'reset'      => true,
+        *                  'force'      => false);
+        * </code>
+        *
+        * Banwords: Make sure each each doesn't contain a banned word. Checking
+        *           against a DB of banned words.
+        *
+        * State: Validate input against US and CA region / province codes.  If DB
+        *        check is set to true, validate region / province against all the
+        *        regions / provinces in the DB.
+        * <code>
+        * $rules[] = array('element'    => 'state_id',
+        *                  'message'    => 'ERROR: Invalid State / Province!',
+        *                  'type'       => 'state',
+        *                  'format'     => array('requireDBCheck' => true),
+        *                  'validation' => $this->validationType,
+        *                  'reset'      => true,
+        *                  'force'      => false);
+        * </code>
+        *
+        * @var array
+        * @access protected
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Zip.php
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Phone.php
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Banwords.php
+        * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/State.php
+        */
+       protected $registeredRules = array('phone', 'zip', 'state');
+
+       //      }}}
+       //      {{{     __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        *
+        * @access public
+        * @link http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html
+        * @see HTML_QuickForm
+     * @todo Remove assigning the dbh the global dbh and setup a PDO
+     *       to be passed in from a parameter - this will allow for easier
+     *       PHPUnit testing
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               //      T_VARIABLE error when passing this server
+               //      var in on the constructors params.
+        $action = empty($action) ? $_SERVER['REQUEST_URI'] : $action;
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+               $this->template = BASE . 'Toolkit/Forms/templates/tables/';
+               $this->dbh      = Toolkit_Database::getInstance();
+
+               $GLOBALS['styleSheets'][] = BASE_URL . 'contactform.css';
+
+               $GLOBALS['scripts'][]
+                       = GLM_APP_BASE_URL . 'libjs/contactform-1.1.js';
+       }
+
+       //      }}}
+
+       //      {{{     addCharLimit()
+
+       /**
+        * adds a maxlength character limitation to an element
+     *
+     * @param string  $element The name of the element to add
+     *                         the char limit to
+     * @param integer $limit   The number of characters allowed
+        *
+        * @return void
+        * @access public
+        */
+       public function addCharLimit($element, $limit)
+       {
+               $this->addRule(
+            $element,
+            "ERROR: $limit characters max!",
+            'maxlength',
+            $limit,
+            'server'
+        );
+               //      Add a maxlength attribute to the field on the form
+               //      which will help prevent users from sending over 100 chars
+               //      to the server in the first place.
+               if ($this->getElementType($element) == 'text') {
+                       $e =& $this->getElement($element);
+                       $e->setMaxLength($limit);
+               }
+       }
+
+       //      }}}
+       //      {{{     apiVersion()
+
+       /**
+        * Returns the current FormBuilder API version
+        *
+        * @since 1.10
+        * @access public
+        * @return float
+        */
+       public function version()
+       {
+               return 1.1;
+       }
+
+       //      }}}
+
+       //      {{{     checkDateInput()
+
+    /**
+     * Checks the validation of a m-d-Y date
+        *
+        * This function will only be called if the autoValidateDateElements
+        * property is set to true.
+     *
+     * @param array $value Date element from form.
+        *
+     * @return boolean
+     * @access public
+        * @see Toolkit_FormBuilder->autoValidateDateElements
+     */
+       public function checkDateInput($value)
+       {
+               if (   empty($value['m'])
+            || empty($value['d'])
+            || empty($value['Y'])
+        ) {
+                       return false;
+               }
+               return checkdate($value['m'], $value['d'], $value['Y']);
+       }
+
+       //      }}}
+       //      {{{     cleanElements()
+
+    /**
+     * Removes elements from form
+     *
+        * Loops through elements and if any names end in '_rmv' they are removed
+        * from the form object.
+     *
+        * Dynamically finds all elements on a form and removes any that
+        * end in '_rmv'.  This can be really usefull if you want to display
+        * from results after the form was successfully submitted and validated,
+        * but don't need to display any extra form elements initially displayed
+        * on the form (like email confirmation fields, or static instruction
+        * elements).
+        *
+     * @param array $elements Form elements.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function cleanElements($elements)
+       {
+               if (is_array($elements)) {
+                       foreach ($elements as $e) {
+                               if ($e['type'] == 'group') {
+                                       $this->cleanGroup($e['name']);
+                               } elseif (preg_match('/^.+_rmv$/', $e['name'])) {
+                                       $this->removeElement($e['name']);
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     cleanForm()
+
+    /**
+     * Removes elements from form
+        *
+        * Dynamically finds all elements on a form and removes any that
+        * end in '_rmv'.  This can be really usefull if you want to display
+        * from results after the form was successfully submitted and validated,
+        * but don't need to display any extra form elements initially displayed
+        * on the form (like email confirmation fields, or static instruction
+        * elements).
+     *
+     * @return void
+     * @access protected
+     */
+       protected function cleanForm()
+       {
+               $formArray = $this->toArray();
+               if (array_key_exists('sections', $formArray)) {
+                       foreach ($formArray['sections'] as $k) {
+                               if (preg_match('/^.+_rmv$/', $k['name'])) {
+                                       $this->removeElement($k['name']);
+                               }
+                               $this->cleanElements($k['elements']);
+                       }
+               } else {
+                       $this->cleanElements($formArray['elements']);
+               }
+       }
+
+       //      }}}
+       //      {{{     cleanGroup()
+
+    /**
+     * Removes any elements from a group that have names that end in '_rmv'
+     *
+     * @param string $name The name of the group element
+        *
+     * @return void
+     * @access protected
+     */
+       protected function cleanGroup($name)
+       {
+               $e =& $this->getElement($name);
+               $g =& $e->getElements();
+               $i = 0;
+               while ($name = $e->getElementName($i++)) {
+                       if (preg_match('/^.+_rmv/', $name)) {
+                               unset($g[($i - 1)]);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     createGridElement()
+
+    /**
+     * Creates a grid element for the form
+     *
+        * Written so this can be overridden easily in subclasses later if needed!
+     *
+     * @param string $elementType QuickForm ElementGrid element definition
+        *
+     * @return mixed ElementGrid element.
+     * @access protected
+     */
+       protected function &createGridElement($elementType)
+       {
+               $args = func_get_args();
+               return call_user_func_array(array($this, 'createElement'), $args);
+
+       }
+
+       //      }}}
+
+       //      {{{     prepElement()
+
+       /**
+        * Make sure all the element array indexes are set
+        *
+        * @param array &$e Element to prep
+        *
+        * @return void
+        * @access protected
+        */
+       protected function prepElement(&$e)
+       {
+               if (!isset($e['opts'])) {
+                       $e['opts'] = '';
+               }
+               if (!isset($e['att'])) {
+                       $e['att'] = '';
+               }
+               if (!isset($e['val'])) {
+                       $e['val'] = '';
+               }
+               if (!isset($e['display'])) {
+                       $e['display'] = '';
+               }
+               if (!isset($e['label'])) {
+                       $e['label'] = '';
+               }
+               if (!isset($e['noCharLimit'])) {
+                       $e['noCharLimit'] = false;
+               }
+       }
+
+       //      }}}
+
+       //      {{{     registerRules()
+
+    /**
+     * Registers custom form rules you can use when validating
+        *
+        * If the registeredRule token is an array, any QF rule can be
+        * registered. This is useful if you want to register rules
+        * from outside classes
+        * e.g. (Validate, Validate_US, Validate_CA, etc...).
+     *
+        * This will set up a rule called 'checkEmail' which uses the
+        * Validate::email() function.
+        * you can still pass in parameters to this rule if you pass them in
+        * via the 'format' option when you are defining your rules.
+        * <code>
+        * class exampleClass
+        * {
+        *     $registeredRules = array(
+        *             array(
+        *             'checkEmail',
+        *             'callback',
+        *             'email',
+        *             'Validate'
+        *         )
+        *     );
+        *
+        *     // ... Rest of your class code
+        *
+        *     public function configureRules()
+        *     {
+        *         $r = array();
+        *
+        *         $r[] = array(
+        *                      'element'    => 'process_email',
+        *                      'message'    => 'ERROR: Invalid email format!',
+        *                      'type'       => 'checkEmail',
+        *                      'format'     => array('use_rfc822' => true),
+        *                      'validation' => $this->validationType,
+        *                      'reset'      => false,
+        *                      'force'      => false
+        *         );
+        *
+        *         $this->setupRules($r);
+        *      }
+        *
+        *      // ... Rest of your class code
+        * }
+        * </code>
+        *
+        * If the registeredRule is a string, the corresponding rule in the
+        * glmPEAR/HTML/QuickForm/Rule/ directory will be registered with
+        * the form.
+        *
+        * This will set up the 'phone' rule already defined in the
+        * glmPEAR/HTML/QuickForm/Rule directory which validates both
+        * US and Canadian phone numbers
+        * <code>
+        * class exampleClass
+        * {
+        *     $registeredRules = array('phone');
+        *
+        *     // ... Rest of your class code
+        *
+        *     public function configureRules()
+        *     {
+        *         $r = array();
+        *
+        *         $r[] = array(
+        *                      'element'    => 'phone',
+        *                      'message'    => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+        *                      'type'       => 'phone',
+        *                      'format'     => null,
+        *                      'validation' => $this->validationType,
+        *                      'reset'      => false,
+        *                      'force'      => false
+        *         );
+        *
+        *         $this->setupRules($r);
+        *      }
+        *
+        *      // ... Rest of your class code
+        * }
+        * </code>
+     *
+     * @return void
+     * @access protected
+     */
+       protected function registerRules()
+       {
+               if (is_array($this->registeredRules)) {
+                       foreach ($this->registeredRules as $r) {
+                               if (is_array($r)) {
+                                       call_user_func_array(array(&$this, 'registerRule'), $r);
+                               } else {
+                                       //      Don't nedd to register rules more than once
+                                       if (!$this->isRuleRegistered($r)) {
+                                               $this->registerRule($r, null, "HTML_QuickForm_Rule_$r");
+                                       }
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+
+       //      {{{     setAutoValidateDateElements()
+
+    /**
+     * Set if we need to auto validate the Date Elements
+     *
+     * @param boolean $validate true/false to auto validate date elements
+     *
+     * @return void
+     * @access public
+     */
+       public function setAutoValidateDateElements($validate)
+       {
+        $this->autoValidateDateElements = $validate;
+       }
+
+       //      }}}
+       //      {{{     setFormData()
+
+    /**
+     * Sets the submitted values from the form
+     *
+        * Set these values into an internal variable so they will be accessible
+        * anywhere we need them in the form.
+     *
+     * @param array $exclude (optional) Any element names you don't want
+        *                                               included. Since this is primarily used in
+        *                                               emailing, this is helpful to exclude any data
+        *                                               we don't want before the array is generated.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setFormData(array $exclude = array())
+       {
+               $values = $this->getSubmitValues();
+               foreach ($values as $k => $v) {
+                       if ($this->elementExists($k)) {
+                               $e =& $this->getElement($k);
+                               if (!in_array($e->getName(), $exclude)) {
+                                       switch ($e->getType()) {
+                                       case 'date' :
+                                               list($m, $d, $y) = array_values($e->getValue());
+                                               //      If all the date fields are empty, then don't add
+                                               //      the output to the formData.
+                                               if (!(empty($m[0]) && empty($d[0]) && empty($y[0]))) {
+                                                       $this->formData[$e->getName()]['label']
+                                = $e->getLabel();
+
+                                                       $oldDate = $e->getValue();
+                                                       $newDate = Toolkit_Common::arrayFlatten(
+                                $oldDate,
+                                0,
+                                $newDate
+                            );
+
+                                                       $this->formData[$e->getName()]['element']
+                                = implode(' / ', $newDate);
+                                                       unset($oldDate, $newDate);
+                                               }
+                                               break;
+
+                                       case 'group':
+                                               $e->freeze();
+                                               $this->formData[$e->getName()]['label']   = $e->getLabel();
+                                               $this->formData[$e->getName()]['element'] = $e->toHtml();
+                                               break;
+
+                                       case 'select' :
+                                               $this->formData[$e->getName()]['label'] = $e->getLabel();
+
+                                               $values = $e->getValue();
+                                               foreach ($values as $v) {
+                                                       $this->formData[$e->getName()]['element'] .= $v;
+                                               }
+                                               break;
+
+                                       default :
+                                               $this->formData[$e->getName()]['label']   = $e->getLabel();
+                                               $this->formData[$e->getName()]['element'] = $e->getValue();
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     setupConstants()
+
+    /**
+     * Sets the form constant values
+     *
+     * @param array $constants Associative array of form constant values.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupConstants($constants)
+       {
+               $this->setConstants($constants);
+       }
+
+       //      }}}
+       //      {{{     setupDefaults()
+
+    /**
+     * Sets the form default values
+     *
+     * @param array $defaults Associative array of form default values.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupDefaults($defaults)
+       {
+               $this->setDefaults($defaults);
+       }
+
+       //      }}}
+       //      {{{ setupElements()
+
+    /**
+     * Sets up all the elements to the form
+     *
+        * Takes a multi-dimensional array of form elements and uses them
+        * to set up the form objects elements
+     *
+     * @param array $elements Multi-Dimensional array of form elements.
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupElements($elements)
+       {
+               if (!is_array($elements)) {
+                       return;
+               }
+               foreach ($elements as &$e) {
+                       $this->prepElement($e);
+                       switch ($e['type']) {
+                       case 'group' :
+                               if (is_array($e['group']) && !empty($e['group'])) {
+                                       //      Special rendering for grouped elements.
+                                       unset($field);
+                                       foreach ($e['group'] as $g) {
+                                               $this->prepElement($g);
+                                               $field[] =& HTML_QuickForm::createElement(
+                            $g['type'],
+                            $g['name'],
+                            $g['display'],
+                            $g['opts'],
+                            $g['att'],
+                            $g['val']
+                        );
+                                       }
+                                       $source =& $this->addGroup(
+                        $field,
+                        $e['name'],
+                        $e['label'],
+                        $e['seperator'],
+                        $e['appendName']
+                    );
+                               }
+                               break;
+
+                       case 'elementGrid' :
+                               $source =& $this->addElement(
+                    $e['type'],
+                    $e['name'],
+                    $e['display'],
+                    $e['opts'],
+                    $e['att'],
+                    $e['val']
+                );
+                               unset($columnNames);
+
+                               //      Loop through the rows (r) and columns (c)
+                               //      to add each of the elements to our grid.
+                               foreach ($e['group'] as $k => $r) {
+                                       unset($set, $rowTitle);
+                                       foreach ($r as $c) {
+                                               $columnNames[$c['display']] = $c['display'];
+
+                                               $set[] =& $this->createGridElement(
+                            $c['type'],
+                            $c['name'],
+                            null,
+                            $c['opts'],
+                            $c['att']
+                        );
+                                       }
+                                       $rowTitle = is_int($k) ? '&nbsp;' : $k;
+                                       $source->addRow(&$set, $rowTitle);
+                               }
+
+                               $source->setColumnNames($columnNames);
+                               break;
+
+                       default :
+                               //      Render all elements except groups
+                               try {
+                                       $source =& $this->addElement(
+                        $e['type'],
+                        $e['name'],
+                        $e['display'],
+                        $e['opts'],
+                        $e['att'],
+                        $e['val']
+                    );
+
+                                       if (PEAR::isError($source)) {
+                                               throw new Exception ('PEAR QuickForm Element Error');
+                                       }
+                               } catch (HTML_QuickForm_Error $e) {
+                                       Toolkit_Common::dieGracefully(null, $e);
+                               } catch (Exception $e) {
+                                       Toolkit_Common::handleError($e);
+                               }
+
+                               if ($e['type'] == 'advmultiselect') {
+                                       $source->setLabel($e['labels']);
+                               }
+                               if ($e['name'] == 'categories') {
+                                       $res = $source->loadArray($this->categories);
+                                       if (PEAR::isError($res)) {
+                                               Toolkit_Common::dieGracefully(null, $res);
+                                       }
+                               }
+                               if ($e['type'] == 'header') {
+                                       $this->formHeaders[$e['display']] = $e;
+                               }
+
+                               if ($e['name'] == 'captcha_rmv') {
+                                       $this->captchaAnswer =& $source;
+                               }
+
+                               if ($e['name'] == 'captcha_question') {
+                                       $this->captchaQuestion =& $source;
+                               }
+                               break;
+                       }
+               }
+               $this->formElements = $elements;
+       }
+
+       //      }}}
+       //      {{{     setupFilters()
+
+    /**
+     * Sets any filters needed for the form elements when submitting
+     *
+     * @param array $filters Element filters.
+        *
+        * @return void
+     * @access protected
+     */
+       protected function setupFilters($filters)
+       {
+               foreach ($filters as $f) {
+                       $res = $this->applyFilter($f['element'], $f['filter']);
+
+            if (PEAR::isError($res)) {
+                Toolkit_Common::handleError($res);
+            }
+               }
+       }
+
+       //      }}}
+       //      {{{ setupRules()
+
+       /**
+        * Apply rules to the form
+        *
+        * 100 & 1000 char length limitations are automatically assigned to
+        * text/textarea elements to help reduce load limitations on the server.
+        * -request per Chuck in a conference call on (5/22/2009 @ 12:15pm)
+        *
+        * Applies rules that are defined in child classes to the form elements
+        * group rules can be kind of tricky, since you can't apply a rule
+        * directly to an element inside of a rule you have to define
+        * the rule inside a nest of array's and then add a group rule.
+        * the array will contain all the elements inside the group you wish
+        * to apply rules to.
+        *
+        * You can assign as many rules as you would like to individual elements,
+        * and you aren't required to make the array associative, although it is
+        * easier to see whats going on.
+        *
+        * see: http://pear.activeventure.com/package/package.html.html-quickform.html-quickform.addgrouprule.html
+        * for another example.
+        * <code>
+        * //   Define the rules for each element in the group.
+        * $num_rule = array(
+     *   'ERROR: Must contain a valid decimal number!',
+     *   'numeric'
+     * );
+        * //   Collect together the rules for each element.
+        * $lat_rules = array('lat' => array($num_rule));
+        * $lon_rules = array('lon' => array($num_rule));
+        * $r[] = array(
+     *   'element'    => 'latitude',
+        *   'message'    => 'ERROR:',
+        *   'type'       => 'group',
+        *   'format'     => $lat_rules,
+        *   'validation' => $this->validationType,
+        *   'reset'      => false,
+        *   'force'      => false
+     * );
+        * </code>
+        *
+        * To make a group required but not require every element in the group
+        * you can use the addGroupRule function again
+        * for example:  say you have a group of checkboxes and you only only
+        * require 1 be checked.  a simple group rule such as the following
+        * will handle this.
+        * N.B. notice the extra "howMany" index.
+        * <code>
+        * $r[] = array(
+     *   'element'   => 'element_name',
+        *   'message'   => 'ERROR: Error to display!',
+        *   'type'      => 'required',
+        *   'format'    => null,
+        *   'howMany'   => 1,
+        *   'validation'=> $this->validationType,
+        *   'reset'     => true,
+        *   'force'     => false,
+     * );
+        * </code>
+        *
+        * @param array $rules Multi-Dimensional array of rules for form elements.
+        *
+        * @return void
+        * @access protected
+        */
+       protected function setupRules(array $rules = null)
+       {
+               $this->registerRules();
+               $preRegisteredRules = $this->getRegisteredRules();
+               if (is_array($this->formElements)) {
+                       foreach ($this->formElements as $e) {
+                               //      Put length limitations on text and textarea fields
+                               if ($e['type'] == 'text' && !$e['noCharLimit']) {
+                                       $this->addCharLimit($e['name'], 100);
+                               } elseif ($e['type'] == 'textarea' && !$e['noCharLimit']) {
+                                       $this->addCharLimit($e['name'], 1000);
+                               } elseif ($e['type'] == 'group') {
+                                       //      We need to apply these same limitations to the
+                                       //      text and textarea fields inside of groups
+                                       $r = array();
+                    if (is_array($e['group'])) {
+                        foreach ($e['group'] as $i) {
+                            // Loop through group elements and if they are
+                            // text/textarea fields then put the field into
+                            // a rule array that we will assign to the group
+                            if ($i['type'] == 'text') {
+                                $r[$i['name']][] = array(
+                                    'ERROR: 100 characters max!',
+                                    'maxlength'
+                                );
+                            } elseif ($i['type'] == 'textarea') {
+                                $r[$i['name']][] = array(
+                                    'ERROR: 1000 characters max!',
+                                    'maxlength'
+                                );
+                            }
+                        }
+                    }
+                                       if (!empty($r)) {
+                                               $this->addGroupRule($e['name'], $r);
+                                       }
+                               }
+                               if ($this->validationType == 'client') {
+                                       $label = $e['display'];
+                               }
+                               if ($e['req']) {
+                                       if ($e['type'] == 'group') {
+                                               foreach ($e['group'] as $ge) {
+                                                       if ($ge['req']) {
+                                                               $rule[$ge['name']][] = array(
+                                                                               'ERROR: You must complete this field!',
+                                                                               'required',
+                                                                               null,
+                                                                               $this->validationType);
+                                                       }
+                                               }
+                                               $this->addGroupRule($e['name'], $rule);
+                                               unset($rule);
+                                       } elseif ($e['type'] == 'date') {
+                        if (!empty($e['error'])) {
+                            //  Custom error message for the date element.
+                            $error = $e['error'];
+                        } else {
+                            //  Default error message for the date element.
+                            $error = 'ERROR: You must enter a date!';
+                        }
+                                               $this->addGroupRule(
+                            $e['name'],
+                            $error,
+                            'required',
+                            3,
+                            $this->validationType
+                        );
+                                               if ($this->autoValidateDateElements) {
+                                                       $this->addRule(
+                                $e['name'],
+                                'ERROR: Date is invalid!',
+                                'callback',
+                                array(&$this, 'checkDateInput')
+                            );
+                                               }
+                                       } else {
+                                               $this->addRule(
+                            $e['name'],
+                            "$label ERROR: You must complete this field!",
+                            'required',
+                            null,
+                            $this->validationType
+                        );
+                                       }
+                               }
+                       }
+               }
+               if (is_array($rules)) {
+                       foreach ($rules as $r) {
+                               if (!is_array($r['element'])) {
+                                       $group = ($this->getElementType($r['element']) == 'group');
+                               }
+                               if ($group) {
+                                       $this->addGroupRule(
+                        $r['element'],
+                        $r['message'],
+                        $r['type'],
+                        $r['format'],
+                        $r['howMany'],
+                        $r['validation'],
+                        $r['reset']
+                    );
+                               } elseif (in_array($r['type'], $preRegisteredRules)) {
+                                       $this->addRule(
+                        $r['element'],
+                        $r['message'],
+                        $r['type'],
+                        $r['format'],
+                        $r['validation'],
+                        $r['reset'],
+                        $r['force']
+                    );
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Sets up renderers for form objects
+     *
+        * Uses the default form renderer to allow templates to be injected
+        * into the form object before displaying on a page.  This allows
+        * changing the face of the form w/ out any backend adjustment.
+        *
+        * Files that can be created for templates are
+        *
+        * Examples:
+        * # Element.tpl
+        * <code>
+        * <tr>
+        *   <td class="labelcell">
+        *     <!-- BEGIN required -->
+        *     <span class="required">*</span>
+        *     <!-- END required -->
+        *     <label> {label} </label>
+        *   </td>
+        *   <td class="fieldcell">
+        *     <!-- BEGIN error -->
+        *     <div class="req"> {error} </div>
+        *     <!-- END error -->
+        *     {element}
+        *   </td>
+        *</tr>
+        * </code>
+        *
+        * # Form.tpl
+        * <code>
+        *   <div id="contact">
+        *     <form{attributes}>
+        *       <table>
+        *         {content}
+        *       </table>
+        *     </form>
+        *   </div>
+        * </code>
+        *
+        * # GroupElement.tpl
+        * <code>
+        *   <tr>
+        *     <td>
+        *       {element}
+        *       <!-- BEGIN required -->
+        *       <span class="req">*</span>
+        *       <!-- END required -->
+        *       {label}
+        *     </td>
+        *   </tr>
+        * </code>
+        *
+        * # Group.tpl
+        * <code>
+        *   <table class="group">
+        *     <tbody>
+        *       {content}
+        *     </tbody>
+        *   </table>
+        * </code>
+        *
+        * # Header.tpl
+        * <code>
+        * <tr class="hdr">
+        *   <td colspan="2">
+        *     {header}
+        *   </td>
+        * </tr>
+        * </code>
+        *
+        * # RequiredNote.tpl
+        * <code>
+        *   <span class="req">*</span> Denotes required field
+        * </code>
+     *
+     * @param array $groups any groups that need to be rendered
+     *                      via the groupElementTemplate and groupTemplate
+        *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers(array $groups = array())
+       {
+               if (is_dir($this->template)) {
+                       if ($dh = opendir($this->template)) {
+                               while (($file = readdir($dh)) !== false) {
+                                       //      Ignore current dir and parent dir.
+                                       if ($file != '..' && $file != '.' && $file != 'CVS') {
+                                               $baseName = reset(explode('.', $file));
+                                               //      Ignores swp files.
+                                               if (!empty($baseName)) {
+                                                       $method   = "set{$baseName}Template";
+                                                       $template = file_get_contents($this->template . $file);
+                                                       $renderer =& $this->defaultRenderer();
+                                                       if (   $method != 'setGroupTemplate'
+                                && $method != 'setGroupElementTemplate'
+                            ) {
+                                                               if (method_exists($renderer, $method)) {
+                                                                       $renderer->$method($template);
+                                                               }
+                                                       } else {
+                                                               //      apply the templates to any defined groups
+                                                               foreach ($groups as $k) {
+                                                                       $renderer->$method($template, $k);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               closedir($dh);
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{     useCaptcha()
+
+    /**
+     * Set if we need to use a captcha in this form or not
+     *
+     * @param boolean $useCaptcha true/false to use a captcha with the form
+     *
+     * @return void
+     * @access public
+     */
+       public function useCaptcha($useCaptcha)
+       {
+               $this->useClueTip();
+        $this->useCaptcha = $useCaptcha;
+       }
+
+       //      }}}
+       //      {{{     useClueTip()
+
+    /**
+     * Set if we need to use the JS cluetip
+     *
+     * @param boolean $useCaptcha include cluetip resources or not
+     *
+     * @return void
+     * @access public
+     */
+       public function useClueTip()
+       {
+               $GLOBALS['styleSheets'][]
+                       = GLM_APP_BASE_URL . 'libjs/cluetip/jquery.cluetip.css';
+               $GLOBALS['scripts'][]
+                       = GLM_APP_BASE_URL . 'libjs/cluetip/jquery.cluetip.js';
+               $GLOBALS['scripts'][]
+                       = GLM_APP_BASE_URL . 'libjs/cluetip/lib/jquery.hoverIntent.js';
+               $GLOBALS['scripts'][]
+                       = GLM_APP_BASE_URL . 'libjs/cluetip/lib/jquery.bgiframe.min.js';
+       }
+
+       //      }}}
+       //      {{{     show()
+
+    /**
+     * Shows the form
+     *
+        * @return void
+     * @access public
+     */
+       public function show()
+       {
+               Toolkit_Common::show();
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Forms/Rules/Date.php b/Toolkit/Forms/Rules/Date.php
new file mode 100644 (file)
index 0000000..8b899a3
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+require_once 'HTML/QuickForm/Rule.php';
+require_once 'Validate.php';
+
+class Toolkit_Forms_Rules_Date extends HTML_QuickForm_Rule
+{
+       /**
+        * Validate if a string is a valid date
+        *
+        * If element is part of a group, then you can pass in the group name
+        * under the options parameter, that way you can find the date values
+        *
+        * You must pass in at least the format of the date in an array.
+        * array('format' => '%m-%d-%Y') is the default
+        *
+        * @param string $value   the date array to validate
+        * @param array  $options options used to dictate validation of the date
+
+        * @return bool if the string could correctly be validated as a date.
+        * @access      public
+        * @see         Validate::date()
+        */
+       function validate($value, array $options)
+       {
+               $month  = !isset($options['group'])
+                       ? $value['m']
+                       : $value[$options['group']]['m'];
+               $day    = !isset($options['group'])
+                       ? $value['d']
+                       : $value[$options['group']]['d'];
+               $year   = !isset($options['group'])
+                       ? $value['Y']
+                       : $value[$options['group']]['Y'];
+
+               if (isset($options['allowEmpty'])
+                       && $options['allowEmpty']
+                       && empty($month)
+                       && empty($day)
+                       && empty($year)
+               ) {
+                       return true;
+               }
+
+               unset($options['group'], $options['allowEmpty']);
+
+               $day = str_pad($day, 2, '0', STR_PAD_LEFT);
+               $month = str_pad($month, 2, '0', STR_PAD_LEFT);
+
+               return Validate::date("$month-$day-$year", $options);
+       }
+
+       function getValidationScript($options = null)
+       {
+               return array('', true);
+       }
+}
+
+HTML_QuickForm::registerRule(
+       'Date',
+       'rule',
+       'Toolkit_Forms_Rules_Date',
+       BASE . 'Toolkit/Forms/Rules/Date.php'
+);
+?>
diff --git a/Toolkit/Forms/templates/tables/Element.tpl b/Toolkit/Forms/templates/tables/Element.tpl
new file mode 100644 (file)
index 0000000..595457b
--- /dev/null
@@ -0,0 +1,14 @@
+<tr>
+       <td class="labelcell">
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               <label>{label}</label>
+       </td>
+       <td class="fieldcell">
+               <!-- BEGIN error -->
+               <div class="req"> {error} </div>
+               <!-- END error -->
+               {element}
+       </td>
+</tr>
diff --git a/Toolkit/Forms/templates/tables/Form.tpl b/Toolkit/Forms/templates/tables/Form.tpl
new file mode 100644 (file)
index 0000000..09f344b
--- /dev/null
@@ -0,0 +1,7 @@
+<div class="webform">
+       <form{attributes}>
+               <table>
+                       {content}
+               </table>
+       </form>
+</div>
diff --git a/Toolkit/Forms/templates/tables/Group.tpl b/Toolkit/Forms/templates/tables/Group.tpl
new file mode 100644 (file)
index 0000000..cdd24cf
--- /dev/null
@@ -0,0 +1,5 @@
+<table class="group">
+       <tbody>
+               {content}
+       </tbody>
+</table>
diff --git a/Toolkit/Forms/templates/tables/GroupElement.tpl b/Toolkit/Forms/templates/tables/GroupElement.tpl
new file mode 100644 (file)
index 0000000..1a4ba27
--- /dev/null
@@ -0,0 +1,9 @@
+<tr>
+       <td>
+               {element}
+               <!-- BEGIN required -->
+               <span class="req">*</span>
+               <!-- END required -->
+               {label}
+       </td>
+</tr>
diff --git a/Toolkit/Forms/templates/tables/Header.tpl b/Toolkit/Forms/templates/tables/Header.tpl
new file mode 100644 (file)
index 0000000..64ac244
--- /dev/null
@@ -0,0 +1,5 @@
+<tr class="hdr">
+       <td colspan="2">
+               {header}
+       </td>
+</tr>
diff --git a/Toolkit/Forms/templates/tables/RequiredNote.tpl b/Toolkit/Forms/templates/tables/RequiredNote.tpl
new file mode 100644 (file)
index 0000000..525ef33
--- /dev/null
@@ -0,0 +1 @@
+<span class="req">*</span> Denotes required field
diff --git a/Toolkit/INavigation.php b/Toolkit/INavigation.php
new file mode 100644 (file)
index 0000000..9e8f4cf
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+
+interface Toolkit_INavigation
+{
+       public function __construct(
+               HTML_Menu $menu,
+               HTML_Menu_Renderer $rEngine
+       );
+
+       public function renderPageNav(array $navigation, $type);
+}
+?>
diff --git a/Toolkit/Image/Server.php b/Toolkit/Image/Server.php
new file mode 100755 (executable)
index 0000000..7056ef4
--- /dev/null
@@ -0,0 +1,370 @@
+<?php
+
+/**
+ * Server.php
+ * 
+ * PHP version 5
+ * 
+ * @category  Images
+ * @package   Toolkit_Image
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Steve Sutton
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Server.php,v 1.15 2009/09/29 18:37:48 matrix Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Description for define
+ */
+define('IS_VALIDATE_SECRET', 'Glm0IS1secreT');
+
+/**
+ * Description for define
+ */
+define('IS_SUBMIT_URL', 'is0.gaslightmedia.com/submit.phtml');
+
+/**
+ * Toolkit_Image_Server
+ * 
+ * Class for implementation of the image server process Chuck has 
+ * setup for is0.gaslightmedia.com
+ * Uses Curl PHP Library to upload images to the server
+ * 
+ * @category  Images
+ * @package   Toolkit_Image
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Steve Sutton
+ * @license   Gaslight Media
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Image_Server
+{
+    // {{{ properties
+
+    /**
+     * OwnerID for the Image Server User
+     * @var    string   
+     * @access protected
+     */
+    protected $OwnerID;
+
+    /**
+     * Owner Password 
+     * @var    string   
+     * @access protected
+     */
+    protected $OwnerPW;
+
+    /**
+     * DOMDocument Object
+     * @var    unknown  
+     * @access protected
+     */
+    protected $xml;
+    
+    // }}}
+
+    //  {{{ __construct()
+
+    /**
+     * __construct
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct()
+    {
+        $this->OwnerID = IS_OWNER_ID;
+        $this->OwnerPW = IS_OWNER_PW;
+    }
+    
+    // }}}
+
+    //  {{{ buildImageServerXML()
+
+    /**
+     * buildImageServerXML
+     * 
+     * Create the xml for the FileServerRequest
+     * 
+     * @param string  $fileName File to upload or delete
+     * @param unknown $type     Upload or Delete
+     * 
+     * @return string xml content
+     * @access public 
+     */
+    function buildImageServerXML($fileName, $type)
+    {
+        $xml               = new DOMDocument('1.0');
+        $xml->formatOutput = true;
+        $FileServerRequest = $xml->createElement('FileServerRequest');
+        $FileServerRequest->setAttribute('version', '1.0');
+        // AccessRequest part
+        $AccessRequest = $xml->createElement('AccessRequest');
+        $Owner         = $xml->createElement('Owner');
+        $OwnerID       = $xml->createElement('OwnerID', $this->OwnerID);
+        $OwnerPW       = $xml->createElement('OwnerPW', $this->OwnerPW);
+        $Owner->appendChild($OwnerID);
+        $Owner->appendChild($OwnerPW);
+        $AccessRequest->appendChild($Owner);
+        $FileServerRequest->appendChild($AccessRequest);
+        // file part
+        $File = $xml->createElement('File');
+        switch ($type) {
+        case "Upload":
+            $FileAction     = $xml->createElement('FileAction', 'Submit');
+            $DeliveryMethod = $xml->createElement('DeliveryMethod', 'Submit');
+            $FieldName      = $xml->createElement('FieldName', 'file_upload');
+            $File->appendChild($FileAction);
+            $File->appendChild($DeliveryMethod);
+            $File->appendChild($FieldName);
+            $FileServerRequest->appendChild($File);
+            $size     = filesize($_FILES[$fileName]['tmp_name']);
+            $validStr = md5($this->OwnerID.$this->OwnerPW.IS_VALIDATE_SECRET);
+            break;
+        case "URL":
+            $FileAction     = $xml->createElement('FileAction', 'Submit');
+            $DeliveryMethod = $xml->createElement('DeliveryMethod', 'URL');
+            $Src            = $xml->createElement('Src', $fileName);
+            $File->appendChild($FileAction);
+            $File->appendChild($DeliveryMethod);
+            $File->appendChild($Src);
+            $FileServerRequest->appendChild($File);
+            $size     = strlen($fileName);
+            $validStr = md5($this->OwnerID.$this->OwnerPW.IS_VALIDATE_SECRET);
+            break;
+        case "Delete":
+            $FileAction = $xml->createElement('FileAction', 'Delete');
+            $File->appendChild($FileAction);
+            $FileName = $xml->createElement('FileName', $fileName);
+            $File->appendChild($FileName);
+            $FileServerRequest->appendChild($File);
+            $validStr = md5($this->OwnerID.$this->OwnerPW.IS_VALIDATE_SECRET);
+            break;
+        }
+        // validation part
+        $Validation = $xml->createElement('Validation', $validStr);
+        $FileServerRequest->appendChild($Validation);
+        $xml->appendChild($FileServerRequest);
+        return $xml->saveXML($xml);
+    }
+    
+    // }}}
+
+    //  {{{ imageDelete()
+
+    /**
+     * imageDelete
+     * 
+     * Delete an image from the image server
+     * 
+     * @param unknown $name Image name
+     * 
+     * @return unknown image name
+     * @access public 
+     */
+    function imageDelete($name)
+    {
+        if ($name) {
+            $request     = $this->buildImageServerXML($name, 'Delete');
+            $ch          = curl_init();
+            $fileData    = array(
+                'request' => $request
+                );
+            $curlOptions = array(
+                    CURLOPT_URL            => IS_SUBMIT_URL,
+                    CURLOPT_HEADER         => 0,
+                    CURLOPT_RETURNTRANSFER => 1,
+                    CURLOPT_POSTFIELDS     => $fileData
+                    );
+            curl_setopt_array($ch, $curlOptions);
+
+            $response = curl_exec($ch);
+            curl_close($ch);
+            $xmlDoc   = new DOMDocument;
+            $response = str_replace("<?xml version=\"1.0\"?>", "", $response);
+            $xmlDoc->loadXML($response);
+            $SuccessCode = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/SuccessCode'
+            );
+            $Message     = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/Message'
+            );
+            $Owner       = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/Owner'
+            );
+            $StoredName  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredName'
+            );
+            $StoredSize  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredSize'
+            );
+            $MediaType   = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/MediaType'
+            );
+            return $Message;
+        }
+    }
+    
+    //  }}}
+    //  {{{ imageUpload()
+
+    /**
+     * imageUpload
+     * 
+     * Upload image to server
+     * 
+     * @param string $name Form field name of image
+     * 
+     * @return string Image name
+     * @access public 
+     */
+    function imageUpload($name)
+    {
+        $fileType = null;
+        if (preg_match("/^http/", $name)) {
+            $fileType = 'URL';
+        } elseif (is_array($_FILES[$name])) {
+            $fileType = 'Upload';
+        }
+        if ($fileType) {
+            $request = $this->buildImageServerXML($name, $fileType);
+            $ch      = curl_init();
+            if ($fileType == "URL") {
+                $fileData = array(
+                    'request' => $request
+                    );
+            } else {
+                $fileData = array(
+                    'request'          => $request,
+                    'file_upload'      => '@'.$_FILES[$name]['tmp_name'],
+                    'file_upload_name' => $_FILES[$name]['name']
+                    );
+            }
+            $curlOptions = array(
+                    CURLOPT_URL            => IS_SUBMIT_URL,
+                    CURLOPT_HEADER         => 0,
+                    CURLOPT_RETURNTRANSFER => 1,
+                    CURLOPT_POSTFIELDS     => $fileData
+                    );
+            curl_setopt_array($ch, $curlOptions);
+
+            $response = curl_exec($ch);
+            curl_close($ch);
+            $xmlDoc   = new DOMDocument;
+            $response = str_replace("<?xml version=\"1.0\"?>", "", $response);
+            $xmlDoc->loadXML($response);
+            $SuccessCode = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/SuccessCode'
+            );
+            $Message     = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/ReplyStatus/Message'
+            );
+            $Owner       = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/Owner'
+            );
+            $StoredName  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredName'
+            );
+            $StoredSize  = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/StoredSize'
+            );
+            $MediaType   = $this->xmlPathContent(
+                $xmlDoc, 
+                '/FileServerResponse/File/MediaType'
+            );
+            if ($SuccessCode != 0) {
+                //throw new Exception('Image Server Error said:'.$response);
+                throw new PEAR_Exception('Image Server Error said:'.$response);
+                exit;
+            }
+            return $StoredName;
+        }
+    }
+    
+    // }}}
+
+    //  {{{ getImageSize()
+
+    /**
+     * getImageSize
+     * 
+     * Return image data on an image from image server
+     * 
+     * @param string $image Full URI to image
+     *                      http://is0/userId/imageStyle/imageName
+     *                      Must be a full URI including an authority.
+     *                      No relative URIs, the // are mandatory
+     * 
+     * @return array Image data 0 => width, 1 => height, 2 => html
+     * @access public 
+     * @throws PEAR Error
+     */
+    function getImageSize($image)
+    {
+        $options = array('allowed_schemes' => array('http'));
+        if (!Validate::uri($image, $options)) {
+            throw new PEAR_Exception('Invalid URI for the image');
+            exit;
+        }
+
+        $ch          = curl_init();
+        $curlOptions = array(
+            CURLOPT_URL            => "{$image}/info",
+            CURLOPT_HEADER         => 0,
+            CURLOPT_RETURNTRANSFER => 1,
+            CURLOPT_POSTFIELDS     => $fileData
+        );
+        curl_setopt_array($ch, $curlOptions);
+
+        $response = curl_exec($ch);
+        curl_close($ch);
+        $wPattern = "/<width>(.*)<\/width>/";
+        preg_match($wPattern, $response, $matches);
+        $width    = $matches[1];
+        $hPattern = "/<height>(.*)<\/height>/";
+        preg_match($hPattern, $response, $matches);
+        $height = $matches[1];
+        $html   = "width=\"{$width}\" height=\"{$height}\"";
+        return array($width, $height, $html);
+    }
+
+    //  }}}
+
+    // {{{  xmlPathContent()
+
+    /**
+     * xmlPathContent
+     * 
+     * Grab the content given XPath Query
+     * 
+     * @param unknown $dom     DOMDocument nodelist
+     * @param unknown $content query for XPath
+     * 
+     * @return object string of node
+     * @access public 
+     */
+    function xmlPathContent($dom, $content)
+    {
+        $xPath    = new DOMXPath($dom);
+        $nodelist = $xPath->query($content);
+        foreach ($nodelist as $entry) {
+            return $entry->nodeValue;
+        }
+    }
+    
+    // }}}
+}
+?>
diff --git a/Toolkit/Logger.php b/Toolkit/Logger.php
new file mode 100644 (file)
index 0000000..8b4b26f
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+
+/**
+ * Error handling logger for system
+ *
+ * PHP version 5
+ *
+ * @category  Logger
+ * @package   Toolkit_Logger
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: Logger.php,v 1.3 2010/01/29 11:48:47 jamie Exp $
+ * @link      <>
+ * @see       Log
+ */
+
+/**
+ * Logging class used to handle system logs
+ */
+require_once 'Log.php';
+
+/**
+ * Error handling logger for system
+ *
+ * @category  Logger
+ * @package   Toolkit_Logger
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       Log
+ */
+class Toolkit_Logger
+{
+
+    /**
+     * Gets a concrete log subclass based on constant parameters set for server
+     *
+     * Define parameters in server setup block of bootstrap file
+     *
+     * @return Log concrete Log subclass
+     * @access public
+     * @static
+     */
+       public static function &getLogger()
+       {
+               $errorLogName = (ERROR_LOG_NAME != '') ? constant(ERROR_LOG_NAME) : '';
+
+               $logger =& Log::singleton(
+                       ERROR_LOG_TYPE,
+                       $errorLogName,
+                       ERROR_LOG_IDENT,
+                       $GLOBALS['ERROR_LOG_CONF'],
+                       constant(ERROR_LOG_LEVEL)
+               );
+
+               return $logger;
+       }
+
+    /**
+     * User-defined error handler function
+     *
+     * handles errors in script.  E_ERROR, E_WARNING, E_NOTICE are automatically
+        * logged when they occur.  Fatal errors (E_ERROR) have a 404 page shown to
+        * user so script doesn't halt.
+     *
+     * @param int    $errno   Level of the error rasied
+     * @param string $errstr  Error message
+     * @param string $errfile Filename that the error was raised in
+     * @param int    $errline Line number the error was raised at
+     * @param Log    $logger  Logger to user for error loggin
+        *
+     * @return boolean false, allows the normal error handler to continue
+     * @access public
+     * @static
+     */
+       public static function errorHandler(
+               $errno,
+               $errstr,
+               $errfile,
+               $errline,
+               $logger = null
+       ) {
+               if (!($logger instanceof Log)) {
+                       $logger =& self::getLogger();
+               }
+
+               switch ($errno) {
+               case E_ERROR :
+               case E_USER_ERROR :
+                       $logger->emerg($errstr. ' in ' . $errfile . ' at line ' . $errline, PEAR_LOG_EMERG);
+                       include BASE . '404.html';
+                       exit(1);
+                       break;
+
+               case E_WARNING :
+               CASE E_USER_WARNING :
+                       $logger->warning($errstr. ' in ' . $errfile . ' at line ' . $errline, PEAR_LOG_WARNING);
+                       break;
+
+               case E_NOTICE :
+               case E_USER_NOTICE :
+                       $logger->notice($errstr. ' in ' . $errfile . ' at line ' . $errline, PEAR_LOG_NOTICE);
+                       break;
+
+               default :
+                       $logger->info($errstr. ' in ' . $errfile . ' at line ' . $errline, PEAR_LOG_INFO);
+                       break;
+               }
+
+               //      return FALSE and let the normal error handler continue
+               return false;
+       }
+}
+?>
diff --git a/Toolkit/Navigation.php b/Toolkit/Navigation.php
new file mode 100644 (file)
index 0000000..0946b5e
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+abstract class Toolkit_Navigation
+{
+       //      {{{     properties
+
+       /**
+        * Default nav index
+        * @param integer
+        * @access protected
+        */
+       protected $currIndex;
+
+       /**
+        * page menu
+        * @param HTML_Menu
+        * @access protected
+        */
+       protected $menu;
+
+       /**
+        * menu rendering engine
+        * @param HTML_Menu_DirectRenderer
+        * @access protected
+        */
+       protected $rEngine;
+
+       //      }}}
+       //      {{{     renderPageNav()
+
+    /**
+     * Render the page navigation that is defined in the navStructure
+     *
+        * @param array  $navStructure Page navigation structure
+        * @param string $type         Type of menu to render
+        *
+     * @return string  Page navigation structure
+     * @access public
+     */
+       public function renderPageNav(array $navStructure, $type)
+       {
+               $this->menu->setMenu($navStructure);
+               $this->menu->setMenuType($type);
+
+               $this->setCurrentIndex();
+               $this->setNavTemplates();
+
+               $this->menu->render($this->rEngine);
+               return $this->rEngine->toHtml();
+       }
+
+       //      }}}
+       //      {{{     setNavTemplates()
+
+       abstract protected function setNavTemplates();
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Page.php b/Toolkit/Page.php
new file mode 100755 (executable)
index 0000000..49ebe14
--- /dev/null
@@ -0,0 +1,563 @@
+<?php
+//vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Page.php
+ *
+ * PHP version 5
+ *
+ * All rights reserved.
+ *
+ * @category  Toolkit
+ * @package   Toolkit_Page
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   http://demo.gaslightmedia.com Gaslight Media
+ * @version   CVS: $Id: Page.php,v 1.61 2010/02/02 17:15:32 jamie Exp $
+ * @link      http://demo.gaslightmedia.com
+ */
+
+/**
+ * Page for Error Doc
+ */
+define("ERROR_DOCUMENT", "404.html");
+
+/**
+ * The home page template
+ */
+define("HOME_TEMPLATE", "template.html");
+
+/**
+ * inside page template
+ */
+define("INSIDE_TEMPLATE", "template.html");
+
+/**
+ * Template for the error doc
+ */
+define("ERROR_DOCUMENT_TEMPLATE", "404-template.html");
+
+/**
+ * page title default
+ */
+define("PAGE_TITLE", "Gaslight Media Demo Site");
+
+
+/**
+ * Toolkit_Page
+ *
+ * A class Object for use with merging into the flexy template for output.
+ * Sets up the $page object used for merging with the flexy template
+ * to output the toolbox and members admin content
+ *
+ * @category  Toolkit
+ * @package   Toolkit_Page
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   http://demo.gaslightmedia.com Gaslight Media
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Page
+{
+    //  {{{ Properties
+
+    /**
+     * used on img src and style href tags
+     * @var    $baseURL
+     * @access public
+     */
+    public $baseURL;
+
+    /**
+     * meta tag description element
+     * @var    $metaTags
+     * @access public
+     */
+    public $metaTags;
+
+    /**
+     * Array of scripts with absolute paths
+     * @var    $scripts array
+     * @access public
+     */
+    public $scripts = array();
+
+    /**
+     * Array of style sheet with absolute paths
+     * @var    $styles array
+     * @access public
+     */
+    public $styles = array();
+
+    /**
+     * title tag node
+     * @var    $title
+     * @access public
+     */
+    public $title;
+
+    /**
+     * The main content of website
+     * @var    $toolboxContent
+     * @access public
+     */
+    public $toolboxContent;
+
+       //  }}}
+       //      {{{     __construct()
+
+    /**
+     * __construct
+     *
+     * @param object $toolbox An instance of a valid GLM_TOOLBOX Object
+     *
+     * @return void
+     * @access public
+     */
+    public function __construct(GLM_TEMPLATE $toolbox)
+    {
+        // determine the base url to use (for images and stylesheet urls)
+        $this->baseURL
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+            ? BASE_SECURE_URL
+            : BASE_URL;
+
+               if (isset($_GET['member_id']) && ctype_digit($_GET['member_id'])) {
+                       // Member profile pages can't have search page title tags
+                       $this->title = SITENAME;
+               } else { 
+                       // set the title of the page
+                       $this->title = $toolbox->title()
+                                                 ? $toolbox->title() . SITENAME
+                                                 : SITENAME;
+               }
+
+        // set the metaTags
+        $this->metaTags = $toolbox->meta_tags();
+
+        // determine the base url to use (for GLM_APP_BASE_URL)
+        $this->glmAppBaseURL
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+            ? BASE_SECURE_URL
+            : GLM_APP_BASE_URL;
+
+        // used in class
+        $this->toolbox    = $toolbox;
+        $this->sitemapURL = $this->baseURL . 'site-map';
+
+        // get top parent id if needed
+        $topParent = $toolbox->get_top_parent($toolbox->catid);
+
+        // true if on home page
+        $this->isHomePage = (HOME_ID == $toolbox->catid);
+
+        // pageTitle
+        $this->pageTitle = $toolbox->get_catheader($topParent, $toolbox->DB);
+
+               // Resources needed for every page.
+               $GLOBALS['styleSheets'][] = $this->baseURL . 'stylesNew.css';
+               $GLOBALS['scripts'][]
+                       = $this->glmAppBaseURL . 'libjs/jquery-1.3.2.min.js';
+               $GLOBALS['scripts'][] = $this->baseURL . 'libjs/newsletterSignup.js';
+
+        // bread crumb navigation
+        $this->breadCrumbs = $toolbox->get_bread_crumbs($toolbox->catid);
+
+        // main nav
+        $this->mainNav = $toolbox->get_main_nav();
+
+        // sideNav
+        if ($toolbox->catid != HOME_ID) {
+            $this->sideNav = $toolbox->get_side_nav($topParent);
+        } else {
+            $this->sideNav = '';
+        }
+
+        // urls used in the template set using get_seo_url
+        $this->glmAssociate     = $toolbox->get_seo_url(2);
+        $this->contactGLM       = $toolbox->get_seo_url(10);
+        $this->servicesOffered  = $toolbox->get_seo_url(81);
+        $this->aboutGLM         = $toolbox->get_seo_url(86);
+        $this->newsletterAction = $toolbox->get_seo_url(10);
+
+        $this->tripPlannerCount = count($_SESSION['wish_list']);
+        $this->tripPlannerUrl   = $toolbox->get_seo_url(MEMBER_SESSION_PAGE);
+        // check if define for HOME_EVENTS is set
+        if (defined("HOME_EVENTS") && HOME_EVENTS && $toolbox->catid == HOME_ID) {
+            $this->events($toolbox);
+        }
+
+        // check if define for HOME_HEADLINES is set
+        if (   defined("HOME_HEADLINES")
+                       && HOME_HEADLINES
+                       && $this->isHomePage
+               ) {
+            $this->headlines($toolbox);
+        }
+
+        // check if define for HOME_NEWS is set
+        if (defined("HOME_NEWS") && HOME_NEWS) {
+            $this->news($toolbox);
+        }
+
+        // check if define for WEATHER is set
+        if (defined("WEATHER") && WEATHER) {
+            $this->hasWeather = true;
+            $this->weather();
+        }
+
+        // check if define for GOOGLE_SEARCH is set
+        if (defined("GOOGLE_SEARCH") && GOOGLE_SEARCH) {
+            $this->googleSearch();
+        }
+
+        // check if define for BANNERS is set
+        if (defined("BANNERS") && BANNERS) {
+            $this->banners(&$toolbox);
+        }
+
+               if (   defined("ROTATING_IMAGES")
+                       && ROTATING_IMAGES
+                       && in_array($toolbox->catid, array(108))
+               ) {
+                       $this->_rotatingImages();
+               }
+    }
+
+    //  }}}
+
+       //      {{{     _rotatingImages()
+
+       private function _rotatingImages()
+       {
+               $nodesIterator = new Toolkit_RotatingImages_NodesIterator();
+               $nodesIterator->findAll(Toolkit_Database::getInstance());
+               $is = new Toolkit_Image_Server();
+               $decorator = new Toolkit_RotatingImages_LiveDecorator();
+               foreach ($nodesIterator as $v) {
+                       if ($v->getActive()) {
+                               if ($v instanceof Toolkit_RotatingImages_Anchor) {
+                                       $nodeDecorator
+                                               = new Toolkit_RotatingImages_AnchorDecorator($v);
+                                       $decorator->add($nodeDecorator);
+                               } elseif ($v instanceof Toolkit_RotatingImages_Image) {
+                                       $nodeDecorator
+                                               = new Toolkit_RotatingImages_ImageDecorator($v);
+                                       $decorator->add($nodeDecorator);
+                               }
+                       }
+               }
+
+               $this->rotatingImages = $decorator->getRotatingJavascript(
+                       Toolkit_Database::getInstance()
+               );
+               $this->rotatingImages .= $decorator->toHtml($is);
+       }
+
+       //      }}}
+
+       //  {{{ banners()
+
+    /**
+     * Add Banner module
+     *
+     * @param unknown &$toolbox Toolbox object
+     *
+     * @return void
+     * @access public
+     */
+    public function banners(&$toolbox)
+    {
+               $dbh = Toolkit_Database::getInstance();
+        $banners =& Toolkit_Banners_BannersIterator::create('Bottom');
+        if (defined('MEMBER_DB') && MEMBER_DB) {
+               $categoriesIterator = Toolkit_Members_CategoriesIterator::create();
+               $banners->fetchAllAvailable(
+                       $dbh,
+                       $categoriesIterator,
+                       $toolbox->catid
+               );
+        } else {
+               $banners->fetchAllAssignedToPage($dbh, $toolbox->catid);
+        }
+
+        $availableBanners = $banners->getAvailable();
+
+        //     Are there any banners even available
+        if (count($availableBanners)) {
+               $decorators = Toolkit_Banners_RotatingBannersDecorator::create();
+               foreach ($availableBanners as $i) {
+                       $decorator = Toolkit_Banners_HorizontalDecorator::create($i);
+                       $decorators->add($decorator);
+               }
+
+               $this->hasBanner = count($decorators->getIterator());
+               $this->bannerAds = $decorators->toHtml(
+                               $dbh,
+                               new Toolkit_Image_Server(),
+                               $toolbox->catid
+                       );
+        }
+    }
+
+       // }}}
+
+    //  {{{ createErrorDocument()
+
+    /**
+     * Create the error document page
+     *
+     * @return void
+     * @access public
+     */
+    function createErrorDocument()
+    {
+        $this->baseURL = BASE_URL;
+        $this->homeURL = $this->toolbox->get_seo_url(HOME_ID);;
+        // Initiate HTML_Template_Flexy.
+        $template = new HTML_Template_Flexy($GLOBALS['flexyOptions']);
+
+        // Create a template object for the 404 content part
+        $errorDocumentTemplate = new HTML_Template_Flexy($GLOBALS['flexyOptions']);
+        $errorDocumentTemplate->compile(ERROR_DOCUMENT_TEMPLATE);
+        $errorDocumentContents = $errorDocumentTemplate->bufferedOutputObject($this);
+
+        // set defaults
+        $this->toolboxContent = $errorDocumentContents;
+        $this->title          = '404 Not Found - '.PAGE_TITLE;
+        $this->hasHeadlines   = false;
+        $this->hasAreaEvents  = false;
+        $this->hasNews        = false;
+        $this->sideNav        = null;
+        $this->mainNav        = $this->toolbox->get_main_nav();
+        $this->hasWeather     = false;
+        $this->isHomePage     = false;
+        $this->sitemapURL     = false;
+
+        // compile the flexy template
+        $template->compile(INSIDE_TEMPLATE);
+
+        // Merge compiled template with the object.
+        $fileContents = $template->bufferedOutputObject($this);
+        file_put_contents(BASE.ERROR_DOCUMENT, $fileContents);
+    }
+
+    //  }}}
+
+    //  {{{ events()
+
+    /**
+     * Add Event module
+     *
+     * @param object $toolbox Toolbox object
+     *
+     * @return void
+     * @access public
+     */
+    public function events($toolbox)
+    {
+        $events          = new Toolkit_Events_Display(
+            Toolkit_Database::getInstance()
+        );
+        $this->events    = $events->getHomeEvents();
+        $this->hasEvents = !empty($this->events);
+        $this->eventsUrl = $toolbox->get_seo_url(EVENT_PAGE);
+        $GLOBALS['scripts'][]
+            = $this->glmAppBaseURL . 'libjs/plugins/cycle/2.73/jquery.cycle.all.min.js';
+        $GLOBALS['scripts'][] 
+            = $this->baseURL . 'Toolkit/Events/libjs/eventRotate.js';
+        $GLOBALS['styleSheets'][]
+            = $this->baseURL . 'event.css';
+    }
+
+    //  }}}
+
+    //  {{{ generateSiteMap()
+
+    /**
+     * Generate the site map page
+     *
+     * @return string HTML sitemap string
+     * @access public
+     */
+    function generateSiteMap()
+    {
+        $WHERE = '';
+        if (defined(MEMBERS_CATEGORY) && defined(MEMBERS_DB)) {
+            $WHERE = "AND id != ".MEMBERS_CATEGORY;
+        }
+        $sql = "
+            SELECT *
+              FROM bus_category
+             WHERE active = 't'
+             $WHERE
+             ORDER BY parent, pos";
+
+        $data = $this->toolbox->DB->db_auto_get_data($sql);
+        if (is_array($data)) {
+            foreach ($data as $key => $val) {
+                $threads[] = array(
+                    "id"       => $val['id'],
+                    'category' => strip_tags($val['category']),
+                    'type'     => $val['type'],
+                    'parent'   => $val['parent'],
+                    'closed'   => false);
+            }
+        }
+        if (is_array($threads)) {
+            $myThread = new Toolkit_SiteMap($this->toolbox);
+            //sort threads by parent
+            $converted = $myThread->sortChilds($threads);
+            //print the threads
+            $out .= $myThread->convertToThread($converted, $converted[0]);
+        }
+        return '<div id="sitemap">
+            '.$out.'
+            </div>';
+    }
+
+    //  }}}
+
+    // {{{ getToolboxName($id)
+
+    /**
+     * grab the navigation name for the id
+     *
+     * @param integer $id id for bus_category table
+     *
+     * @return string page nav name
+     * @access public
+     */
+    function getToolboxName($id)
+    {
+        return $this->toolbox->get_catheader($id, $this->toolbox->DB);
+    }
+
+    // }}}
+    // {{{ getToolboxUrl($id)
+
+    /**
+     * grab the navigation url for the id
+     *
+     * @param integer $id id for bus_category table
+     *
+     * @return string url
+     * @access public
+     */
+    function getToolboxUrl($id)
+    {
+        return $this->toolbox->get_seo_url($id);
+    }
+
+    // }}}
+
+    //  {{{ googleSearch()
+
+    /**
+     * Add Google Search module
+     *
+     * @return void
+     * @access public
+     */
+    public function googleSearch()
+    {
+        $this->gSearchOn  = false;
+        $this->isHomePage = false;
+        if (isset($_REQUEST['query']) && $_REQUEST['query']) {
+            $this->gSearchOn = true;
+            $query           = urlencode($_REQUEST['query']);
+                       $GLOBALS['styleSheets'][] = BASE_URL.'gsearch.css';
+                       $GLOBALS['scripts'][]
+                               = 'http://www.google.com/uds/api?file=uds.js&v=1.0&key='.GSEARCH_API;
+                       $GLOBALS['scripts'][] = BASE_URL . 'libjs/gsearch.php?query='.$query;
+        }
+    }
+
+    //  }}}
+
+    //  {{{ headlines()
+
+    /**
+     * grab the home page headlines
+     *
+     * @param object $toolbox Toolbox object
+     *
+     * @return void
+     * @access public
+     */
+    public function headlines($toolbox)
+    {
+        // get headlines aka 'Quick Links'
+        $this->headlines = $toolbox->get_headlines();
+        // boolean for if toolbox has headlines
+        $this->hasHeadlines = !empty($this->headlines);
+    }
+
+    //  }}}
+
+    //  {{{ isPhotoGalleryPage()
+
+    /**
+     * Check if this page has photo gallery in it
+     *
+     * @return boolean If this page has a photo gallery assigned to it
+     * @access public
+     */
+    function isPhotoGalleryPage()
+    {
+        $sql = "
+            SELECT photocat_id
+              FROM photo_category_bus
+             WHERE buscat_id = {$this->toolbox->catid}";
+        if ($pData = $this->toolbox->DB->select($sql)) {
+            return true;
+        }
+        return false;
+    }
+    //  }}}
+
+    //  {{{ news()
+
+    /**
+     * grab the home page newsletter/press info
+     *
+     * @param object $toolbox Toolbox object
+        *
+     * @return void
+     * @access public
+     */
+    public function news($toolbox)
+    {
+        if (HOME_ID == $toolbox->catid) {
+            $this->news    = $toolbox->get_news();
+            $this->hasNews = (!empty($this->news));
+        } else {
+            $this->hasNews = false;
+        }
+    }
+
+    //  }}}
+
+    //  {{{ weather()
+
+    /**
+     * Add Weather module
+     *
+     * @return void
+     * @access public
+     */
+    public function weather()
+    {
+        $weather           = new Toolkit_Weather();
+        if (PEAR::isError($weather->currentCond)) {
+            return false;
+        }
+        $this->weather     = $weather->currentCond['weather'];
+        $this->tempF       = $weather->currentCond['temp_f'];
+        $this->iconUrlName = $weather->currentCond['icon_url_name'];
+        $this->location    = $weather->currentCond['location'];
+    }
+
+       //  }}}
+}
+?>
diff --git a/Toolkit/ShortURL.php b/Toolkit/ShortURL.php
new file mode 100755 (executable)
index 0000000..7189021
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+
+/**
+ * ShortURL.php
+ * 
+ * Integration of Toolbox with creation of ShortURL
+ * 
+ * PHP version 5
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_ShortURL
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: ShortURL.php,v 1.3 2009/06/24 01:30:02 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_ShortURL
+ * 
+ * Integration of Toolbox with creation of ShortURL
+ * the url rewrite happens with one line of code in .htaccess
+ * RewriteRule ^([A-Za-z0-9_-]*)$ index.php?page=$1 [L]
+ * index page checks for $_GET['page'] and then calls 
+ * getShortUrlId to get the page's catid. If not found it 
+ * defaults to HOME_ID
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_ShortURL
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class Toolkit_ShortURL
+{
+    // {{{ Class Properties
+    /**
+     * PDO Global object 
+     * @var    string   
+     * @access protected
+     */
+    public $dbh;
+    // }}}
+
+    // {{{ __construct()
+
+    /**
+     * __construct()
+     * 
+     * @param object &$dbh from setup.phtml
+     * 
+     * @return void
+     * @access public
+     */
+    function __construct(&$dbh)
+    {
+        $this->dbh = $dbh;
+    }
+
+    // }}}
+    // {{{ getShortUrl()
+
+    /**
+     * getShortUrl()
+     * 
+     * grab the shorturl from bus_category table
+     * else return false 
+     * 
+     * @param string $id bus_category id
+     * 
+     * @return mixed  ShortURL from bus_category
+     * @access public
+     */
+    function getShortUrl($id)
+    {
+        $sql = "
+        SELECT short_url
+          FROM bus_category
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":id", $id, PDO::PARAM_INT);
+            $stmt->execute();
+            return $stmt->fetchColumn();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return false;
+    }
+
+    // }}}
+    // {{{ getShortUrlId()
+
+    /**
+     * getShortUrlId()
+     * 
+     * grab the id from bus_category table
+     * else return false 
+     * 
+     * @param string $short_url bus_category short_url
+     * 
+     * @return mixed  catid for page or HOME_ID if not found
+     * @access public
+     */
+    function getShortUrlId($short_url)
+    {
+        $sql = "
+        SELECT id
+          FROM bus_category
+         WHERE short_url = :short_url";
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(":short_url", $short_url, PDO::PARAM_STR);
+            $stmt->execute();
+            return $stmt->fetchColumn();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return HOME_ID;
+    }
+
+    // }}}
+}
+?>
diff --git a/Toolkit/SiteMap.php b/Toolkit/SiteMap.php
new file mode 100755 (executable)
index 0000000..1b84c68
--- /dev/null
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * SiteMap.php
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_SiteMap
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: SiteMap.php,v 1.6 2009/06/17 23:01:20 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_SiteMap
+ * 
+ * Generate a sitemap for the site
+ * need to remove members only pages and other pages you
+ * don't want viewed by public 
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_SiteMap
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_SiteMap
+{
+    // {{{ Properties
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $beginLevel = "<ul>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $endLevel = "</ul>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $beginItem = "<li>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $endItem = "</li>";
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $wholeThread;
+
+    /**
+     * Description for var
+     * @var    string
+     * @access public
+     */
+    var $search = "";
+
+    /**
+     * Description for var
+     * @var    unknown
+     * @access public 
+     */
+    var $DB;
+    // }}}
+    // {{{ __construct()
+    /**
+     * __construct
+     * 
+     * Must be given a GLM_TEMPLATE object
+     * 
+     * @param mixed $toolbox GLM_TEMPLATE Object
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct(GLM_TEMPLATE $toolbox)
+    {    
+        $this->toolbox =& $toolbox;
+        $this->DB      =& $toolbox->DB;
+    }
+    // }}}
+    // {{{ sortChilds()
+    /**
+     * sortChilds
+     * 
+     * Sort by Parent
+     * 
+     * @param unknown $threads Array
+     * 
+     * @return array   Return array
+     * @access public 
+     */
+    function sortChilds($threads)
+    {    
+        while (list($var, $value) = each($threads)) {
+            $childs[$value['parent']][$value['id']] = $value;
+        }
+        return $childs;
+    }
+    // }}}
+    // {{{ convertToThread()
+    /**
+    * convertToThread
+    * 
+    * outputs the array with the correct styles and code applied
+    * 
+    * @param unknown $threads Thread array
+    * @param unknown $thread  Start with thread[0] will work it way down
+    * 
+    * @return wholeThread
+    * @access public 
+    **/
+    function convertToThread($threads, $thread)
+    {    
+        static $p,$level_counter;
+        if (!$level_counter) {
+            $level_counter = 1;
+        }
+        $this->wholeThread .= $this->beginLevel;
+        while (list($parent, $value) = each($thread)) {    
+            $this->wholeThread .= $this->beginItem;
+            $page               = $value['url'];
+            $this->wholeThread .= '<a href="'.$page.'">'; 
+            $this->wholeThread .= $value["category"] 
+                . "</a>";
+            if ($threads[$parent]) {
+                ++$level_counter;
+                $this->convertToThread($threads, $threads[$parent]);
+                --$level_counter;
+            }
+            $this->wholeThread .= $this->endItem ."\n";
+        }
+        $this->wholeThread .= $this->endLevel;
+        return $this->wholeThread;
+    }
+    // }}}
+}
+?>
diff --git a/Toolkit/SortForm.php b/Toolkit/SortForm.php
new file mode 100644 (file)
index 0000000..c5a1fc8
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Creates a sortform to be used w/ datagrid DataGrids
+ *
+ * PHP version 5
+ *
+ * @category HTML
+ * @package  Toolkit_SortForm
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: SortForm.php,v 1.6 2010/01/18 02:09:05 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Creates a sortform to be used w/ datagrid DataGrids
+ *
+ * @category  HTML
+ * @package   Toolkit_SortForm
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_SortForm extends Toolkit_FormBuilder
+{
+    //  {{{ properties
+
+       /**
+        * The default rules to register for validating
+        *
+        * @var string
+        * @access protected
+        */
+    protected $registeredRules = array();
+
+    //  }}}
+       //      {{{     toHTML()
+
+       /**
+        * Render the form to a string
+        *
+        * Handle the rendering and validation of the form when displayed
+        * and submitted.
+        *
+     * @return string html form
+        * @access public
+        */
+       public function toHTML()
+       {
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $output = parent::toHTML();
+               } else if ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Toolbox/Admin/EditPage.php b/Toolkit/Toolbox/Admin/EditPage.php
new file mode 100644 (file)
index 0000000..f29a0f9
--- /dev/null
@@ -0,0 +1,1044 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * Toolbox page edit form
+ *
+ * PHP version 5
+ *
+ * @category Toolbox
+ * @package  Toolkit_Toolbox
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @release  CVS: $Id: EditPage.php,v 1.16 2010/01/09 18:59:45 jamie Exp $:
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Edit Toolbox page
+ *
+ * Handles form to insert/edit a toolbox page
+ *
+ * @category  Toolbox
+ * @package   Toolkit_Toolbox
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Toolbox_Admin_EditPage
+    extends Toolkit_FormBuilder implements Toolkit_Form
+{
+    //  {{{ properties
+
+    /**
+     * Primary database table we need to interact with
+     * @var    string
+     * @access protected
+     */
+    public $tableName = 'bus_category';
+
+    /**
+     * How many levels deep do you want to show in the parent select list
+     *
+     * 0 = Show All Levels
+     *
+     * @var    integer
+     * @access protected
+     */
+    protected $maxDepth = 0;
+
+    /**
+     * Don't need to register any rules for this form.
+     * @var    array
+     * @access protected
+     */
+       protected $registeredRules = array();
+
+    //  }}}
+    //  {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * Sets the database handler this class will use via the PDO passed in
+     * from the parameters.  Sets up the flexyOptions from the default options
+     * defined in the setup.phtml file, updates where the templates directory
+     * and compiled templates directory are located.
+     *
+     * @param PDO    $pdo         PHP Data Object used to set the database
+     *                            handler
+     * @param string $formName    Form's name.
+     * @param string $method      (optional) Form's method defaults to 'POST'
+     * @param string $action      (optional) Form's action
+     * @param string $target      (optional) Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional) Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional) Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+     *
+        * @access public
+        * @see    Toolkit_FormBuilder, HTML_QuickForm
+        */
+       public function __construct(
+        PDO $pdo,
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+        $this->dbh = $pdo;
+
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+    }
+
+    //  }}}
+
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     *
+     * @return void
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        if (is_numeric($_GET['id'])) {
+            try {
+                $sql = "
+                    SELECT *
+                      FROM {$this->tableName}
+                     WHERE id = :id";
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                $stmt->execute();
+                $d = $stmt->fetch();
+                $i = '<img src="%s">';
+
+                $d['current_image'] = sprintf($i, THUMB . $d['image']);
+
+            } catch (PDOException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+        } else {
+            $d = array(
+                'template' => 1,
+            );
+        }
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+       public function configureElements(Config_Container $c)
+       {
+        $e = array();
+
+        //  get reference to [listing type] section of config file
+               $pluralType = $c->getItem('section', 'listing type')
+                                   ->getItem('directive', 'plural')
+                                   ->getContent();
+
+               //      Grouped Elements are defined here.
+        $submitBtns = array();
+
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'update_rmv',
+            'display' => 'Update'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'cancel_rmv',
+            'display' => 'Cancel'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'delete_rmv',
+            'display' => 'Delete'
+        );
+
+        $templates = array();
+
+        $options = range(1, 6);
+        foreach ($options as $i) {
+            $img = "<img src=\"template$i.gif\">";
+
+            $templates[] = array(
+                'type'    => 'radio',
+                'req'     => false,
+                'name'    => 'template',
+                'display' => "Template $i<br>$img",
+                'att'     => $i,
+                'opts'    => $i,
+            );
+        }
+
+               //      All Elements are created here.
+        //  This includes group element definitions.
+        $res   = $this->getConstant('MEMBERS_DB');
+        $isErr = PEAR::isError($res);
+        if ($isErr) {
+            Toolkit_Common::handleError($e);
+        }
+        if ($res && !$isErr) {
+            $e[] = array(
+                'type'    => 'header',
+                'req'     => false,
+                'name'    => 'memberDbHdr',
+                'display' => $pluralType,
+            );
+            $e[] = array(
+                'type' => 'static',
+                'req'  => false,
+                'name' => 'pageCategories'
+            );
+            //  Note that we call to populate this select list at the
+            //  bottom of this function after the element is made
+            //  so we load attributes (classes) into each option as needed.
+            $e[] = array(
+                'type'    => 'select',
+                'req'     => false,
+                'name'    => 'memberCat',
+                'display' => 'Member Categories',
+                'opts'    => array('' => '-- None --'),
+                'att'     => array(
+                    'multiple' => 'multiple',
+                    'size'     => 7
+                )
+            );
+            $e[] = array(
+                'type'    => 'advcheckbox',
+                'req'     => false,
+                'name'    => 'no_search_form',
+                'display' => 'Search Box',
+                'val'     => array(0, 1)
+            );
+        }
+               $e[] = array(
+            'type'    => 'header',
+            'req'     => false,
+            'name'    => 'pageAttributesHdr',
+            'display' => 'Page Attributes'
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'category',
+            'display' => 'Navigation Name'
+        );
+               $e[] = array(
+            'type'    => 'select',
+            'req'     => false,
+            'name'    => 'parent',
+            'display' => 'Parent Page',
+            'opts'    => array('0' => '-- No Parent --'),
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'keyword',
+            'display' => 'Keyword'
+        );
+               $e[] = array(
+            'type'    => 'advcheckbox',
+            'req'     => false,
+            'name'    => 'section_links',
+            'display' => 'Search',
+            'opts'    => 'Create a list of links to the paragraph headlines',
+            'val'     => array(0, 1)
+        );
+        $res   = $this->getConstant('HOME_HEADLINES');
+        $isErr = PEAR::isError($res);
+        if ($isErr) {
+            Toolkit_Common::handleError($e);
+        }
+        if ($res && !$isErr) {
+            $e[] = array(
+                'type'    => 'header',
+                'req'     => false,
+                'name'    => 'homePageHeadlinesHdr',
+                'display' => 'Headlines'
+            );
+            $e[] = array(
+                'type'    => 'advcheckbox',
+                'req'     => false,
+                'name'    => 'featured',
+                'display' => 'Home Page Headlines',
+                'val'     => array(0, 1)
+            );
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'feature_intro',
+                'display' => 'Headline Intro'
+            );
+        }
+               $e[] = array(
+            'type'    => 'header',
+            'req'     => false,
+            'name'    => 'pageBodyHdr',
+            'display' => 'Page Body'
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'intro',
+            'display' => 'Page Title'
+        );
+               $e[] = array(
+            'type'    => 'textarea',
+            'req'     => false,
+            'name'    => 'description',
+            'display' => 'Description',
+            'opts'    => array(
+                'cols' => 70,
+                'rows' => 25
+            ),
+        );
+        if ($this->hasUploadedImage()) {
+            $e[] = array(
+                'type'    => 'static',
+                'req'     => false,
+                'name'    => 'current_image',
+                'display' => 'Current Image'
+            );
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'imagename',
+                'display' => 'Image Caption'
+            );
+            $e[] = array(
+                'type'    => 'checkbox',
+                'req'     => false,
+                'name'    => 'remove_image',
+                'display' => 'Delete Image'
+            );
+        }
+               $e[] = array(
+            'type'    => 'file',
+            'req'     => false,
+            'name'    => 'image',
+            'display' => 'New Image'
+        );
+               $e[] = array(
+            'type'       => 'group',
+            'req'        => false,
+            'name'       => 'page_layout',
+            'group'         => $templates,
+            'label'      => 'Template',
+            'seperator'  => '',
+            'appendName' => false
+        );
+
+        //  If we are editing a page, show three submit buttons
+        //  otherwise, just show one insert button.
+        if (is_numeric($_GET['id'])) {
+            $e[] = array(
+                'type'       => 'group',
+                'req'        => false,
+                'name'       => 'submit_buttons',
+                'group'             => $submitBtns,
+                'label'      => '',
+                'seperator'  => '',
+                'appendName' => false,
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'submit',
+                'req'     => false,
+                'name'    => 'insert_rmv',
+                'display' => 'Insert'
+            );
+        }
+
+               $this->setupElements($e);
+        //  Load the member categories after the elements have been created
+        //  so we can get more control how the options are rendered
+        //  ie (adding classes to them)
+        $res   = $this->getConstant('MEMBERS_DB');
+        $isErr = PEAR::isError($res);
+        if ($isErr) {
+            Toolkit_Common::handleError($e);
+        }
+        if ($res && !$isErr) {
+            $this->loadMemberCategories();
+        }
+        //  Do the same for the pages
+        $this->loadParentPages();
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     *
+        * Applies a data filter for the given fields when the form is submitted
+     *
+     * @return void
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter'  => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Bundle all form configuration calls into one function call
+     *
+     * @param Config_Container $c Configuration object
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm(Config_Container $c)
+    {
+               $this->configureElements($c);
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     *
+        * Adds validation rules for the given fields
+     *
+     * @return void
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+               //      Form Rules
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+    //  {{{ getCurrentParent()
+
+    /**
+     * Gets the parent id of a page
+     *
+     * @param integer $id page id
+     *
+     * @return integer parent id
+     * @access protected
+     */
+    protected function getCurrentParent($id)
+    {
+        try {
+            $sql = "
+                SELECT parent
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('parent', $parent);
+            $stmt->fetch();
+
+            return $parent;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ getNewParentPosition()
+
+    /**
+     * Gets the position to use for a page
+     *
+     * If we are inserting a new page we need to get the position to insert
+     * the new page at. Or if we are updating an existing page and reassigning
+     * it to a new parent, we need to get the new position to insert
+     * the page at.
+     *
+     * @param integer $parent page id of the new parent page
+     *
+     * @return integer new position to use
+     * @access protected
+     */
+    protected function getNewParentPosition($parent)
+    {
+        try {
+            $sql = "
+                SELECT count(*) + 1 AS newparent
+                  FROM {$this->tableName}
+                 WHERE parent = :parent
+                   AND id != :home_id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':parent', $parent, PDO::PARAM_INT);
+            $stmt->bindValue(':home_id', HOME_ID, PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('newparent', $newParent);
+            $stmt->fetch();
+
+            if ($parent == 0) {
+                ++$newParent;
+            }
+
+            return $newParent;
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ getTableName()
+
+    /**
+     * Gets the primary table name
+     *
+     * @return string table name
+     * @access public
+     */
+    public function getTableName()
+    {
+        return $this->tableName;
+    }
+
+    //  }}}
+    //  {{{ getConstant()
+
+    /**
+     * fetch a defined constant value
+     *
+     * @param string $constant constant name
+     *
+     * @return mixed constant value
+     * @acess protected
+     */
+    protected function getConstant($constant)
+    {
+        if (!defined($constant)) {
+            return PEAR::raiseError('calling undefined constant');
+        } else {
+            return constant($constant);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ hasUploadedImage()
+
+    /**
+     * Check to see if page we are editing has an uploaded image
+     *
+     * @return boolean If page has a previously uploaded image
+     * @access protected
+     */
+    protected function hasUploadedImage()
+    {
+        if (!is_numeric($_GET['id'])) {
+            return false;
+        }
+        try {
+            $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('image', $image);
+            $row = $stmt->fetch();
+            return !is_null($image);
+            //return !(is_null($image) || empty($image));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ loadMemberCategories()
+
+    /**
+     * Loads member categories into the select list
+     *
+     * Gets an array structure of the member categories in a linear tree order
+     * Then walk through the array and load each category into the select list
+     *
+     * @return void
+     * @access public
+     */
+    public function loadMemberCategories()
+    {
+        try {
+            //  Get a tree list of categories in linear order with
+            //  category keys in the values and their level in the tree
+            //  in the value
+               $c = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'category',
+                'category_id',
+                'parent_id'
+            );
+
+            //  Get all the data about each category
+            $sql = "
+                SELECT *
+                  FROM category
+                 WHERE category_id = ?";
+
+            $stmt = $this->dbh->prepare($sql);
+            //  Get the member categories select list element
+            $e =& $this->getElement('memberCat');
+            foreach ($c as $i => $j) {
+                $stmt->execute(array($i));
+                $row = $stmt->fetch();
+                //  the class level is always 1 less than what is reported
+                //  from our $c array
+                $x = $j - 1;
+                //  Add the option data to the select list.
+                $e->addOption($row['name'], $i, array('class' => "level-$x"));
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ loadParentPages()
+
+    /**
+     * Load option elements into the parent select list
+     *
+     * These options are loaded via this seperate function vs inline w/ the
+     * element definition b/c we need a little more control defining
+     * the class names for each option so they will render nice when a user
+     * is looking at the list.
+     *
+     * @return void
+     * @throws PDOException throws exception on sql error
+     * @access public
+     */
+    public function loadParentPages()
+    {
+        try {
+            //  Get a tree list of categories in linear order with
+            //  category keys in the values and their level in the tree
+            //  in the value
+               $c = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'bus_category',
+                'id',
+                'parent',
+                'pos',
+                0,
+                $this->maxDepth
+            );
+
+            //  unset the home page, this is never an option to have children
+            //  underneath it.
+            unset($c[HOME_ID]);
+
+            //  If we are editing a page, then we don't want that page
+            //  to show up as an option in the select list.
+            if (is_numeric($_GET['id'])) {
+                reset($c);
+                //  Get us to the point in the array were this page is located
+                while (key($c) != $_GET['id'] && current($c) !== false) {
+                    next($c);
+                }
+                //  Make sure we didn't traverse off the end of the array
+                if (current($c) !== false) {
+                    //  get the starting level we are currently at
+                    $sl = current($c);
+                    //  remove this page (the one we're editing) from the
+                    //  array and advance the internal array pointer
+                    unset($c[key($c)]);
+                    //  now we need to make sure all sub pages beneath this
+                    //  page are also not being shown
+
+                    //  while we don't traverse off the end of the array
+                    while (current($c) !== false) {
+                        //  get the current sub level we are at
+                        $csl = current($c);
+                        //  if the current sub-level is the same as the
+                        //  starting level, that means we have traversed through
+                        //  all the sub-pages and can break out of the loop
+                        if ($csl == $sl) {
+                            break;
+                        } else {
+                            //  we are still in a sub-level page, so unset
+                            //  this page so it doesn't show, and advance
+                            //  the internal array pointer
+                            unset($c[key($c)]);
+                        }
+                    }
+                }
+            }
+
+            //  Get all the data about each category
+            $sql = "
+                SELECT *
+                  FROM bus_category
+                 WHERE id = ?";
+
+            $stmt = $this->dbh->prepare($sql);
+            //  Get the member categories select list element
+            $e =& $this->getElement('parent');
+            foreach ($c as $i => $j) {
+                $stmt->execute(array($i));
+                $row = $stmt->fetch();
+                //  the class level is always 1 less than what is reported
+                //  from our $c array
+                $x = $j - 1;
+                //  Add the option data to the select list.
+                $e->addOption($row['category'], $i, array('class' => "level-$x"));
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ insertPage()
+
+    /**
+     * Create a new page in the site by inserting values into the DB
+     *
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function insertPage($values)
+    {
+        //  Get the member categories if they exists so we don't try and
+        //  insert them into the wrong table.
+        $memberCats = $values['memberCat'];
+        unset($values['memberCat']);
+
+        //  Get the value of the new position this page will be set to.
+        $values['pos'] = $this->getNewParentPosition($values['parent']);
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $this->uploadImage('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } else {
+            unset($values['image']);
+        }
+
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+
+        try {
+            $this->dbh->beginTransaction();
+            Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+
+            //  If we are trying to associate member categories
+            //  with the toolbox page then insert them here.
+            if (is_array($memberCats) && !empty($memberCats)) {
+                //  Need to get the last id inserted into the table.
+                $sql = "
+                    SELECT id
+                      FROM {$this->tableName}
+                     ORDER BY id DESC
+                     LIMIT 1";
+
+                $row = $this->dbh->query($sql)->fetch();
+                $sql = Toolkit_Common::createSQLInsert(
+                    'bus_cat_member',
+                    array('catid', 'memb_type')
+                );
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':catid', $row['id'], PDO::PARAM_INT);
+                //  zip through all the member categories selected
+                //  and insert them into the table.
+                foreach ($memberCats as $i) {
+                    if (is_numeric($i)) {
+                        $stmt->bindParam(':memb_type', $i, PDO::PARAM_INT);
+                        $stmt->execute();
+                    }
+                }
+            }
+
+            return $this->dbh->commit();
+        } catch (PDOException $e) {
+            $this->dbh->rollback();
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ processData()
+
+    /**
+     * Clean unneeded form elements out of the submitted values array
+     *
+     * @param array $values QuickForm submitted elements
+     *
+     * @return boolean Result of insert/update functions
+     * @access public
+     */
+    public function processData($values)
+    {
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'MAX_FILE_SIZE' :
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                               if (substr($k, -4) == '_rmv') {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+        $function = is_numeric($_GET['id']) ? 'updatePage' : 'insertPage';
+        return $this->$function($values);
+    }
+
+    //  }}}
+
+    //  {{{ removeImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Deletes an image from the file server
+     *
+     * @param string $fileName Name of the image to delete
+     *
+     * @return void
+     * @access protected
+     */
+    protected function removeImage($fileName)
+    {
+        $is = new Toolkit_Image_Server();
+        $is->imageDelete($fileName);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+
+    //  {{{ setMaxDepth()
+
+    /**
+     * Sets the max depth level that the parent page select list will show
+     *
+     * @param integer $md New max depth
+     *
+     * @return void
+     * @access public
+     */
+    public function setMaxDepth($md)
+    {
+        $this->maxDepth = $md;
+    }
+
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Custom rendering templates for special fields on the form
+     *
+     * @return void
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req"> * </span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside"> {error} </div><!-- END error -->';
+
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'submit_buttons');
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'insert_rmv');
+
+               $renderer->setGroupTemplate("\n\t<table id=\"templates\">\n\t\t<tbody>\n\t\t\t<tr>{content}</tr>\n\t\t</tbody>\n\t</table>", 'page_layout');
+               $renderer->setGroupElementTemplate("\n\t<td>\n\t\t<label>{label}<br>{element}</label>\n\t</td>", 'page_layout');
+       }
+
+       //      }}}
+
+       //      {{{     toHtml()
+
+    /**
+     * Handles how to display the current step the user is at in the form
+     *
+     * @return string rendered html form
+     * @access public
+     */
+       public function toHtml()
+       {
+               $validated = $this->validate();
+               $this->setupRenderers();
+               if ($validated) {
+                       $this->cleanForm();
+
+            $r = $this->process(
+                array(&$this, 'processData'),
+                $this->mergeFiles
+            );
+            if (PEAR::isError($r)) {
+                return Toolkit_Common::handleError($r);
+            } else {
+                               $this->freeze();
+                               $output = $this->successMsg;
+                       }
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+       //      }}}
+
+    //  {{{ updatePage()
+
+    /**
+     * Update an existing page in the site by updating values in the DB
+     *
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function updatePage($values)
+    {
+        //  Make sure we are dealing w/ a valid page
+        if (!is_numeric($_GET['id'])) {
+            return PEAR::raiseError('Invalid page id');
+        }
+
+        //  Handle user deleting the page image.
+        if (array_key_exists('remove_image', $values)) {
+            $this->removeImage($values['imagename']);
+
+            //  unset value so its not included in the update sql query
+            unset($values['remove_image']);
+            //  set image and imagename to null to overwrite value in db.
+            //  if we are not uploading a new image.
+            if (empty($values['image']['size'])) {
+                $values['image'] = $values['imagename'] = null;
+            }
+        }
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $is->imageUpload('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } elseif (!is_null($values['image'])) {
+            unset($values['image']);
+        }
+
+        //  Get the parent id this page is currently set to in the DB.
+        $curPar = $this->getCurrentParent($_GET['id']);
+        //  parents will be different if we are reassining to a new parent
+        if ($curPar != $values['parent']) {
+            //  Get an updated position for the new parent page.
+            $values['pos'] = $this->getNewParentPosition($values['parent']);
+        }
+
+               try {
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('id = :id')
+            );
+
+            $values['id'] = $_GET['id'];
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Uploads an image to the image server
+     *
+     * @param string $key name of the file upload key to find the image in the
+     *                    $_FILES array
+     *
+     * @return mixed file name on success, false on error
+     * @access protected
+     */
+    protected function uploadImage($key)
+    {
+        $is = new Toolkit_Image_Server();
+        return $is->imageUpload($key);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+}
+?>
diff --git a/Toolkit/Toolbox/Admin/EditParagraph.php b/Toolkit/Toolbox/Admin/EditParagraph.php
new file mode 100644 (file)
index 0000000..b6e3d79
--- /dev/null
@@ -0,0 +1,692 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category Forms
+ * @package  Toolkit_FormBuilder
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditParagraph.php,v 1.4 2009/10/27 14:46:32 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  CategoryName
+ * @package   Toolkit_Toolbox
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Toolbox_Admin_EditParagraph extends Toolkit_FormBuilder
+{
+    //  {{{ properties
+
+
+    /**
+     * Description for protected
+     * @var    string   
+     * @access protected
+     */
+    protected $tableName = 'bus';
+
+    //  }}}
+    //  {{{ __construct()
+
+       /**
+        * Class constructor
+        *
+     * @param string $formName    Form's name.
+     * @param PDO    $pdo         PHP Data Object used for DB calls
+     * @param string $method      (optional)Form's method defaults to 'POST'
+     * @param string $action      (optional)Form's action
+     * @param string $target      (optional)Form's target defaults to '_self'
+     * @param mixed  $attributes  (optional)Extra attributes for <form> tag
+     * @param bool   $trackSubmit (optional)Whether to track if the form was
+        *                                                        submitted by adding a special hidden field
+        * 
+        * @access public
+        * @link http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html
+        * @see HTML_QuickForm
+     * @todo Remove assigning the dbh the global dbh and setup a PDO
+     *       to be passed in from a parameter - this will allow for easier
+     *       PHPUnit testing
+        */
+       public function __construct(
+        $formName,
+        PDO $pdo,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+        $this->dbh = $pdo;
+               $this->flexyOptions                = $GLOBALS['flexyOptions'];
+               $this->flexyOptions['templateDir'] = TEMPLATES_DIR;
+               $this->flexyOptions['compileDir']  = COMPILED_DIR;
+    }
+
+    //  }}}
+
+    //  {{{ createTables()
+
+    /**
+     * Read file from parameter and use the PDO parameter to create process file
+     * 
+     * @param object $pdo  Database handler
+     * @param string $file full path of file to parse
+     *                      
+     * @return void  
+     * @access public
+     * @static
+     */
+    static public function createTables(PDO $pdo, $file)
+    {
+        $sql = file_get_contents($file);
+        $tok = strtok($sql, ';');
+        while ($tok !== false) {
+            $pdo->query($tok);
+            $tok = strtok(';');
+        }
+    }
+
+    //  }}}
+       //      {{{     configureDefaults()
+
+    /**
+     * Initializes default form values
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureDefaults()
+       {
+        if (is_numeric($_GET['id'])) {
+            try {
+                $sql = "
+                    SELECT *
+                      FROM {$this->tableName}
+                     WHERE id = :id";
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+                $stmt->execute();
+                $d = $stmt->fetch();
+                $i = '<img src="%s">';
+
+                $d['current_image'] = sprintf($i, THUMB . $d['image']);
+
+            } catch (PDOException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+        } else {
+            $d = array(
+                'template' => 1,
+            );
+        }
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+       //      {{{     configureElements()
+
+    /**
+     * Form element definitions
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureElements()
+       {
+        $e = array();
+               //      Grouped Elements are defined here.
+        $submitBtns = array();
+
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'update_rmv',
+            'display' => 'Update'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'cancel_rmv',
+            'display' => 'Cancel'
+        );
+        $submitBtns[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'delete_rmv',
+            'display' => 'Delete'
+        );
+
+               //      All Elements are created here.
+        //  This includes group element definitions.
+               $e[] = array(
+            'type'    => 'header',
+            'req'     => false,
+            'name'    => 'paragraphAttributesHdr',
+            'display' => 'Paragraph Attributes'
+        );
+               $e[] = array(
+            'type'    => 'select',
+            'req'     => false,
+            'name'    => 'page',
+            'display' => 'Page',
+            'opts'    => array(),
+        );
+               $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'intro',
+            'display' => 'Paragraph Title'
+        );
+               $e[] = array(
+            'type'    => 'textarea',
+            'req'     => false,
+            'name'    => 'description',
+            'display' => 'Description',
+            'opts'    => array(
+                'cols' => 70,
+                'rows' => 25
+            ),
+        );
+        if ($this->hasUploadedImage()) {
+            $e[] = array(
+                'type'    => 'static',
+                'req'     => false,
+                'name'    => 'current_image',
+                'display' => 'Current Image'
+            );
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'imagename',
+                'display' => 'Image Caption'
+            );
+            $e[] = array(
+                'type'    => 'checkbox',
+                'req'     => false,
+                'name'    => 'remove_image',
+                'display' => 'Delete Image'
+            );
+        }
+               $e[] = array(
+            'type'    => 'file',
+            'req'     => false,
+            'name'    => 'image',
+            'display' => 'New Image'
+        );
+
+        //  If we are editing a page, show three submit buttons
+        //  otherwise, just show one insert button.
+        if (is_numeric($_GET['id'])) {
+            $e[] = array(
+                'type'       => 'group',
+                'req'        => false,
+                'name'       => 'submit_buttons',
+                'group'             => $submitBtns,
+                'label'      => '',
+                'seperator'  => '',
+                'appendName' => false,
+            );
+        } else {
+            $e[] = array(
+                'type'    => 'submit',
+                'req'     => false,
+                'name'    => 'insert_rmv',
+                'display' => 'Insert'
+            );
+        }
+
+               $this->setupElements($e);
+        //  Do the same for the pages
+        $this->loadParagraphPages();
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+    /**
+     * Form filter definitions
+     * 
+        * Applies a data filter for the given fields when the form is submitted
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureFilters()
+       {
+        $f = array();
+
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter'  => 'trim'
+        );
+
+        $this->setupFilters($f);
+       }
+
+       //      }}}
+    //  {{{ configureForm()
+
+    /**
+     * Bundle all form configuration calls into one function call
+     * 
+     * @return void  
+     * @access public
+     */
+    public function configureForm()
+    {
+               $this->configureElements();
+               $this->configureRules();
+               $this->configureFilters();
+               $this->configureDefaults();
+    }
+
+    //  }}}
+       //      {{{     configureRules()
+
+    /**
+     * Form rule definitions
+     * 
+        * Adds validation rules for the given fields
+     * 
+     * @return void  
+     * @access public
+     */
+       public function configureRules()
+       {
+        $r = array();
+               //      Form Rules
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+    //  {{{ getTableName()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    public function getTableName()
+    {
+        return $this->tableName;
+    }
+
+    //  }}}
+
+    //  {{{ hasUploadedImage()
+
+    /**
+     * Check to see if page we are editing has an uploaded image
+     * 
+     * @return boolean   If page has a previously uploaded image
+     * @access protected
+     */
+    protected function hasUploadedImage()
+    {
+        if (!is_numeric($_GET['id'])) {
+            return false;
+        }
+        try {
+            $sql = "
+                SELECT *
+                  FROM {$this->tableName}
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
+            $stmt->execute();
+            $stmt->bindColumn('image', $image);
+            $row = $stmt->fetch();
+            return !is_null($image);
+            //return !(is_null($image) || empty($image));
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ loadParagraphPages()
+
+    /**
+     * Load option elements into the parent select list
+     * 
+     * These options are loaded via this seperate function vs inline w/ the
+     * element definition b/c we need a little more control defining
+     * the class names for each option so they will render nice when a user
+     * is looking at the list.
+     * 
+     * @return void        
+     * @throws PDOException throws exception on sql error
+     * @access public      
+     */
+    public function loadParagraphPages()
+    {
+        try {
+            //  Get a tree list of categories in linear order with
+            //  category keys in the values and their level in the tree
+            //  in the value
+               $c = Toolkit_Common::getHierarchicalTreeStructure(
+                $this->dbh,
+                'bus_category',
+                'id',
+                'parent',
+                'pos',
+                1,
+                $this->maxDepth
+            );
+
+            //  Get all the data about each category
+            $sql = "
+                SELECT *
+                  FROM bus_category
+                 WHERE id = ?";
+
+            $stmt = $this->dbh->prepare($sql);
+            //  Get the member categories select list element
+            $e =& $this->getElement('page');
+            foreach ($c as $i => $j) {
+                $stmt->execute(array($i));
+                $row = $stmt->fetch();
+                //  the class level is always 1 less than what is reported
+                //  from our $c array
+                $x = $j - 1;
+                //  Add the option data to the select list.
+                $e->addOption($row['category'], $i, array('class' => "level-$x"));
+            }
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ insertPage()
+
+    /**
+     * Create a new page in the site by inserting values into the DB
+     * 
+     * @param array $values Submitted form values
+     *                           
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function insertPage($values)
+    {
+        //  Get the member categories if they exists so we don't try and
+        //  insert them into the wrong table.
+        $memberCats = $values['memberCat'];
+        unset($values['memberCat']);
+
+        //  Get the value of the new position this page will be set to.
+        $values['pos'] = $this->getNewParentPosition($values['parent']);
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $this->uploadImage('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } else {
+            unset($values['image']);
+        }
+
+        $sql = Toolkit_Common::createSQLInsert(
+            $this->tableName,
+            array_keys($values)
+        );
+
+        try {
+            $this->dbh->beginTransaction();
+            Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+
+            //  If we are trying to associate member categories
+            //  with the toolbox page then insert them here.
+            if (is_array($memberCats) && !empty($memberCats)) {
+                //  Need to get the last id inserted into the table.
+                $sql = "
+                    SELECT id
+                      FROM {$this->tableName}
+                     ORDER BY id DESC
+                     LIMIT 1";
+                
+                $row = $this->dbh->query($sql)->fetch();
+                $sql = Toolkit_Common::createSQLInsert(
+                    'bus_cat_member',
+                    array('catid', 'memb_type')
+                );
+
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(':catid', $row['id'], PDO::PARAM_INT);
+                //  zip through all the member categories selected
+                //  and insert them into the table.
+                foreach ($memberCats as $i) {
+                    if (is_numeric($i)) {
+                        $stmt->bindParam(':memb_type', $i, PDO::PARAM_INT);
+                        $stmt->execute();
+                    }
+                }
+            }
+
+            return $this->dbh->commit();
+        } catch (PDOException $e) {
+            $this->dbh->rollback();
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+
+    //  {{{ processData()
+
+    /**
+     * Clean unneeded form elements out of the submitted values array
+     * 
+     * @param array $values QuickForm submitted elements
+     *                         
+     * @return boolean Result of insert/update functions
+     * @access public 
+     */
+    public function processData($values)
+    {
+               foreach ($values as $k => $v) {
+                       switch ($k) {
+                       case 'MAX_FILE_SIZE' : 
+                               unset($values[$k]);
+                               break;
+
+                       default :
+                               if (substr($k, -4) == '_rmv') {
+                                       unset($values[$k]);
+                               }
+                               break;
+                       }
+               }
+
+        $function = is_numeric($_GET['id']) ? 'updatePage' : 'insertPage';
+        return $this->$function($values);
+    }
+
+    //  }}}
+    //  {{{ removeImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Deletes an image from the file server
+     * 
+     * @param string $fileName Name of the image to delete
+     *                             
+     * @return void     
+     * @access protected
+     */
+    protected function removeImage($fileName)
+    {
+        $is = new Toolkit_Image_Server();
+        $is->imageDelete($fileName);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+
+    //  {{{ setMaxDepth()
+
+    /**
+     * Sets the max depth level that the parent page select list will show
+     *
+     * @param integer $md New max depth
+     *                     
+     * @return void   
+     * @access public 
+     */
+    public function setMaxDepth($md)
+    {
+        $this->maxDepth = $md;
+    }
+
+    //  }}}
+       //      {{{     setupRenderers()
+
+    /**
+     * Custom rendering templates for special fields on the form
+     * 
+     * @return void     
+     * @access protected
+     */
+       protected function setupRenderers()
+       {
+               parent::setupRenderers();
+               $renderer =& $this->defaultRenderer();
+               $required = '<!-- BEGIN required --><span class="req"> * </span><!-- END required -->';
+               $error    = '<!-- BEGIN error --><div class="form-warning-inside"> {error} </div><!-- END error -->';
+
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'submit_buttons');
+               $renderer->setElementTemplate("\n\t<tr align=\"center\">\n\t\t<td colspan=\"2\">$required{label}$error{element}</td>\n\t</tr>", 'insert_rmv');
+
+               $renderer->setGroupTemplate("\n\t<table id=\"templates\">\n\t\t<tbody>\n\t\t\t<tr>{content}</tr>\n\t\t</tbody>\n\t</table>", 'page_layout');
+               $renderer->setGroupElementTemplate("\n\t<td>\n\t\t<label>{label}<br>{element}</label>\n\t</td>", 'page_layout');
+       }
+
+       //      }}}
+
+    //  {{{ updatePage()
+
+    /**
+     * Update an existing page in the site by updating values in the DB
+     * 
+     * @param array $values Submitted form values
+     *                           
+     * @return boolean Result of insertion
+     * @access protected
+     */
+    protected function updatePage($values)
+    {
+        //  Make sure we are dealing w/ a valid page
+        if (!is_numeric($_GET['id'])) {
+            return PEAR::raiseError('Invalid page id');
+        }
+
+        //  Handle user deleting the page image.
+        if (array_key_exists('remove_image', $values)) {
+            $this->removeImage($values['imagename']);
+
+            //  unset value so its not included in the update sql query
+            unset($values['remove_image']);
+            //  set image and imagename to null to overwrite value in db.
+            //  if we are not uploading a new image.
+            if (empty($values['image']['size'])) {
+                $values['image'] = $values['imagename'] = null;
+            }
+        }
+
+        //  a non empty file size indicates to use an image has been uploaded.
+        if (!empty($values['image']['size'])) {
+            $values['image'] = $is->imageUpload('image');
+            if ($values['image'] === false) {
+                return PEAR::raiseError('Invalid image response');
+            }
+        } elseif (!is_null($values['image'])) {
+            unset($values['image']);
+        }
+
+        //  Get the parent id this page is currently set to in the DB.
+        $curPar = $this->getCurrentParent($_GET['id']);
+        //  parents will be different if we are reassining to a new parent
+        if ($curPar != $values['parent']) {
+            //  Get an updated position for the new parent page.
+            $values['pos'] = $this->getNewParentPosition($values['parent']);
+        }
+
+               try {
+            $sql = Toolkit_Common::createSQLUpdate(
+                $this->tableName,
+                array_keys($values),
+                array('id = :id')
+            );
+
+            $values['id'] = $_GET['id'];
+            return Toolkit_Common::processQuery(
+                $this->dbh,
+                $this->tableName,
+                $sql,
+                $values
+            );
+        } catch (PDOException $e) {
+            return Toolkit_Common::handleError($e);
+        }
+    }
+
+    //  }}}
+    //  {{{ uploadImage()
+    //  @codeCoverageIgnoreStart
+
+    /**
+     * Uploads an image to the image server
+     * 
+     * @param string $key name of the file upload key to find the image in the
+     *                    $_FILES array
+     *                        
+     * @return mixed file name on success, false on error 
+     * @access protected
+     */
+    protected function uploadImage($key)
+    {
+        $is = new Toolkit_Image_Server();
+        return $is->imageUpload($key);
+    }
+
+    //  @codeCoverageIgnoreEnd
+    //  }}}
+}
+?>
diff --git a/Toolkit/Toolbox/Admin/toolbox.sql b/Toolkit/Toolbox/Admin/toolbox.sql
new file mode 100644 (file)
index 0000000..5fc4cdb
--- /dev/null
@@ -0,0 +1,33 @@
+CREATE TABLE bus_category (
+id              SERIAL PRIMARY KEY,
+parent          INTEGER,
+category        TEXT,
+intro           TEXT,
+description     TEXT,
+image           TEXT,
+imagename       TEXT,
+active          BOOLEAN DEFAULT FALSE,
+pos             INTEGER,
+keyword         TEXT,
+template        INTEGER,
+featured        BOOLEAN DEFAULT FALSE,
+no_search_form  BOOLEAN DEFAULT FALSE,
+feature_intro   TEXT,
+section_links   BOOLEAN DEFAULT FALSE
+);
+
+CREATE TABLE bus (
+id              SERIAL PRIMARY KEY,
+name            TEXT,
+description     TEXT,
+image           TEXT,
+imagename       TEXT,
+back_to_top     BOOLEAN DEFAULT FALSE
+);
+
+CREATE TABLE bus_category_bus (
+id              SERIAL PRIMARY KEY,
+busid           INTEGER,
+catid           INTEGER,
+pos             INTEGER
+);
diff --git a/Toolkit/Toolbox/assets/.keepme b/Toolkit/Toolbox/assets/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Toolkit/Tree.php b/Toolkit/Tree.php
new file mode 100644 (file)
index 0000000..5af1553
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * DB tree structures
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Toolkit_Tree
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @release     CVS: $Id: Tree.php,v 1.4 2009/06/18 14:12:50 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Create tree structures of database entries
+ *
+ * Base class used to setup tree objects that will render
+ * database structures into iterable PHP objects.
+ *
+ * @category  Toolkit
+ * @package      Toolkit_Tree
+ * @author       Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+abstract class Toolkit_Tree
+{
+       //      {{{ properties
+
+       /**
+        * Database ID of tuple
+        *
+        * @var int
+        * @access public
+        */
+       public $catid = 0;
+
+       /**
+        * Name of object
+        *
+        * @var string
+        * @access public
+        */
+       public $category;
+
+       /**
+        * Children of object
+        *
+        * @var array
+        * @access public
+        */
+    public $children = array();
+
+       /**
+        * Parent of this category
+        *
+        * @var array
+        * @access public
+        */
+    public $parentId;
+
+       /**
+        * Database connection handle
+        *
+        * @var PDO Object
+        * @access protected
+        */
+       protected $dbh;
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * Setup the objects properties and call to setup children
+        *
+        * @param integer $catid    ID of the Database object
+        * @param string  $name     Name of the Database object
+        * @param PDO     $dbh      Database handler object
+        * @param integer $parentId Id of parent node
+        *
+        * @author      Jamie Kahgee <jamie.kahgee@gmail.com>
+        * @access      public
+        */
+    public function __construct($catid, $name, PDO $dbh, $parentId = 0)
+    {
+               $this->parentId = $parentId;
+        $this->catid    = $catid;
+        $this->category = $name;
+               $this->dbh      = $dbh;
+        $this->addChildren();
+    }
+
+       //      }}}
+       //      {{{ __get()
+
+    /**
+     * utilized for reading data from inaccessible members
+     * 
+     * @param string $name property name
+     *                      
+     * @return mixed  void
+     * @access public
+     */
+       public function __get($name)
+       {
+               return $this->$name;
+       }
+
+       //      }}}
+       //      {{{ __set()
+
+
+    /**
+     * Run when writing data to inaccessible members
+     * 
+     * @param string $name  property
+     * @param string $value new value
+     *                       
+     * @return void  
+     * @access public
+     */
+       public function __set($name, $value)
+       {
+               $this->$name = $value;
+       }
+
+       //      }}}
+       //      {{{ addChildren()
+
+       /**
+        * Attaches children to tree object
+        *
+        * @author Jamie Kahgee <jamie.kahgee@gmail.com>
+     * @return void
+        * @access protected
+        */
+    abstract protected function addChildren();
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/Weather.php b/Toolkit/Weather.php
new file mode 100755 (executable)
index 0000000..60a9d09
--- /dev/null
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Weather.php
+ * 
+ * PHP version 5
+ * 
+ * @category  Weather
+ * @package   Toolkit_Weather
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com/license.txt The Gaslight License
+ * @version   CVS: $Id: Weather.php,v 1.6 2009/09/16 11:20:51 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Weather class for Gaslight Media
+ * 
+ * You can get the stationId for weather at 
+ * http://www.weather.gov/xml/current_obs/seek.php?state=mi
+ * Uses NOAA for getting the rss feed for weather
+ * 
+ * @category  Toolkit
+ * @package   Toolkit_Weather
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license   http://www.gaslightmedia.com/license.txt The Gaslight License
+ * @link      <>
+ */
+class Toolkit_Weather
+{
+    //{{{ __Class Properties
+
+
+    /**
+     * The xml file used for caching the feed
+     * @var    $_weatherFile string
+     * @access private
+     */
+    private $_weatherFile;
+
+    /**
+     * Station identifier for the feed
+     * @link http://www.weather.gov/xml/current_obs/seek.php?state=mi
+     *
+     * @var    $_stationId string
+     * @access private
+     */
+    private $_stationId = 'KPLN';    
+
+
+    /**
+     * XMLReader object for parsing feed
+     * @var    $_xml object 
+     * @access private
+     */
+    private $_xml;
+
+    /**
+     * Description for private
+     * @var    $_assoc array  
+     * @access private
+     */
+    private $_assoc;
+
+    /**
+     * Storage array for the current conditions
+     * @var     $currendCond array 
+     * @access public
+     */
+    public $currentCond;
+
+    /**
+     * Boolean if the file exists or not
+     * @var    $_cacheFileExist boolean
+     * @access private
+     */
+    private $_cacheFileExist = false;
+     
+    //}}}
+    //{{{ __construct()
+
+    /**
+     * Class Constructer
+     * 
+     * @return void  
+     * @access public
+     */
+    function __construct()
+    {
+        $currentErrorMask = ini_get('error_reporting');
+        error_reporting(0);
+        $this->_weatherFile = BASE.'weather-feed.xml';
+        $this->interval     = 25; // interval in minutes for page cache
+        $this->fetchWeather();
+        $this->setCurrentCond();
+        error_reporting($currentErrorMask);
+    }
+    
+    //}}}
+    //{{{ fetchWeather()
+
+
+    /**
+     * fetchWeather
+     * 
+     * THis will use curl to grab the weather feed using
+     * the $_weatherFile as destination
+     * and the $_stationId for the xml file name
+     * 
+     * @return void  
+     * @access public
+     */
+    function fetchWeather()
+    {
+        if (is_file($this->_weatherFile)) {
+            $time2hoursago = mktime(
+                date('H'),
+                date('i') - $this->interval, 
+                date('s'),
+                date('m'),
+                date('d'),
+                date('Y')
+            );
+            $file_time     = filemtime($this->_weatherFile);
+            if ($file_time < $time2hoursago) {
+                $this->grabFeedUrl();
+            }
+            if (is_file($this->_weatherFile)) {
+                $this->_cacheFileExist = true;
+            }
+        } else {
+            $this->grabFeedUrl();
+            if (is_file($this->_weatherFile)) {
+                $this->_cacheFileExist = true;
+            }
+        }
+    }
+    
+    //}}}
+    // {{{ grabFeedUrl()
+
+
+    /**
+     * grabFeedUrl 
+     * 
+     * @return void
+     * @access public
+     */
+    function grabFeedUrl()
+    {
+        // the NOAA xml feed url to be used 
+        // from the _stationId
+        $feed_url = 'http://www.weather.gov/xml/current_obs/'
+            .$this->_stationId.'.xml';
+        // Curl Options used for connection
+        $curlOptions = array(
+            CURLOPT_URL            => $feed_url,
+            CURLOPT_HEADER         => 0,
+            CURLOPT_RETURNTRANSFER => 1,
+            CURLOPT_TIMEOUT        => 15,
+            CURLOPT_CONNECTTIMEOUT => 5,
+            CURLOPT_FAILONERROR    => 1,
+            );
+        // start curl object
+        $ch = curl_init();
+        // set options
+        curl_setopt_array($ch, $curlOptions);
+        // assign the response to a string variable
+        $response = curl_exec($ch);
+        // grab the connection info to check for http_code = 200
+        $info = curl_getinfo($ch);
+        curl_close($ch);
+        if ($info['http_code'] == '200') {
+            file_put_contents($this->_weatherFile, $response);
+        } else {
+            @touch($this->_weatherFile);
+        }
+    }
+    
+
+    // }}}
+    //{{{ setCurrentCond()
+
+    /**
+     * Set currentCond
+     * 
+     * Set the currentCond clas var up with variables from the xml file
+     * from the weather feed 
+     * 
+     * @return void  
+     * @access public
+     */
+    function setCurrentCond()
+    {
+        $xml = new XML_Unserializer();
+        $xml->unserialize($this->_weatherFile, true);
+        $this->currentCond = $xml->getUnserializedData();
+    }
+    
+    //}}}
+}
+?>
diff --git a/Toolkit/qfcaptcha.php b/Toolkit/qfcaptcha.php
new file mode 100755 (executable)
index 0000000..f4bf079
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * HTML_QuickForm_CAPTCHA example - Image generator
+ *
+ * PHP versions 4 and 5
+ *
+ * @category   HTML
+ * @package    HTML_QuickForm_CAPTCHA
+ * @subpackage Examples
+ * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
+ * @copyright  2006-2008 by Philippe Jausions / 11abacus
+ * @license    http://www.opensource.org/licenses/bsd-license.php New BSD
+ * @version    CVS: $Id: qfcaptcha.php,v 1.2 2009/10/01 16:00:02 jamie Exp $
+ * @filesource
+ * @link       http://pear.php.net/package/HTML_QuickForm_CAPTCHA
+ * @see        qfcaptcha_form_image.php
+ * @see        qfcaptcha_form_random.php
+ */
+
+// Require the class before opening the session
+// so the instance unserialize properly
+require_once '../setup.phtml';
+require_once 'Text/CAPTCHA.php';
+require_once 'Text/CAPTCHA/Driver/Image.php';
+
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+
+header('Content-Type: image/jpeg');
+
+$sessionVar = (empty($_REQUEST['var']))
+              ? '_HTML_QuickForm_CAPTCHA'
+              : $_REQUEST['var'];
+
+// Force a new CAPTCHA for each one displayed
+$_SESSION[$sessionVar]->setPhrase();
+
+echo $_SESSION[$sessionVar]->getCAPTCHAAsJPEG();
+?> 
diff --git a/admin/.htaccess b/admin/.htaccess
new file mode 100644 (file)
index 0000000..38dcd05
--- /dev/null
@@ -0,0 +1 @@
+RewriteEngine Off
diff --git a/admin/Photos/edit-default.php b/admin/Photos/edit-default.php
new file mode 100644 (file)
index 0000000..44d2417
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+require_once '../../setup.phtml';
+require_once 'photo-setup.inc';
+GLM_TOOLBOX::top('Photo Albums (Edit Default Text)', '');
+if ($_POST) {
+       $query = "update photo_default set header = '".$_POST['header']."', description = '".$_POST['description']."' where id = 1;";
+       if (!$res1 = $DB->db_exec($query)) {
+               die('error updating');
+       } else {
+               echo '<h2>Updated</h2>';
+       }
+}
+$query = "select * from photo_default where id = 1;";
+echo '
+<form action="edit-default.php" method="post">
+  <table id="admin-table-edit">
+';
+if ($res = $DB->db_exec($query)) {
+       $obj = pg_fetch_object($res, 0, PGSQL_ASSOC);
+       echo '<tr>
+               <td>Header:</td>
+               <td><input id="header" name="header" value="'.$obj->header.'"></td>
+               </tr>';
+       echo '<tr>
+               <td>Text:</td>
+               <td><textarea id="description" name="description" rows="15" cols="25">'.$obj->description.'</textarea></td>
+               </tr>';
+       echo '<tr>
+               <td><input type="submit" value="Update Default Text"></td>
+               </tr>';
+}
+?>
+  </table>
+</form>
+<?php GLM_TOOLBOX::footer();?>
diff --git a/admin/Photos/edit_display.phtml b/admin/Photos/edit_display.phtml
new file mode 100644 (file)
index 0000000..ee77926
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+require_once('../../setup.phtml');
+require_once('photo-setup.inc');
+top('','');
+$query = "select category from photo_config";
+$data = db_auto_get_data( $query );
+$catid = $data[0]['category'];
+echo '<form action="update_display.php" method="post">';
+echo '<table id="admin-edit-table">';
+echo '<tr>';
+echo '<td>Category:</td>';
+echo '<td>'.parent_select( $catid ).'</td>';
+echo '</tr>';
+echo '<tr>';
+echo '<td colspan="2"><input type="submit"></td>';
+echo '</tr>';
+echo '</table>';
+echo '</form>';
+footer();
+?>
diff --git a/admin/Photos/edit_photo.phtml b/admin/Photos/edit_photo.phtml
new file mode 100644 (file)
index 0000000..6f61e33
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+require_once "../../setup.phtml";
+require_once "photo-setup.inc";
+GLM_TOOLBOX::top("Photo Albums (Edit/Delete)", HELP_BASE."photo.phtml?key=edit");
+$lnav = array(
+               "Add A New Photo"       => "edit_photo.phtml?catid=$catid",
+               "List Photos"           => "list_photo.phtml?catid=$catid"
+               );
+GLM_TOOLBOX::html_nav_table($lnav, 2);
+if (isset($id)) {
+       $qs = "select   id,title,catid,description,image,pos from photo where id = $id";
+       if (!$res = $DB->db_exec($qs)) {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG, 1);
+       }
+       $row = $DB->db_fetch_array($res, $i, PGSQL_ASSOC);
+       if (!$row['id']) {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG, 0);
+       }
+} else {
+       $row = array(
+                       'title' => '',
+                       'catid' => $catid,
+                       'description' => '',
+                       'image' => '');
+}
+function catid_select($catid) 
+{
+    $DB =& $GLOBALS['DB'];
+       $qs = "
+        SELECT id, category
+          FROM photo_category";
+       if (!$res2 = $DB->db_exec($qs)) {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG, 0);
+       }
+       $select = '<select name="catid">';
+       for($x = 0; $x < $DB->db_numrows($res2); ++$x) {
+               $row = $DB->db_fetch_array($res2, $x, PGSQL_ASSOC); 
+               if (!$row['id']) {
+                       GLM_TOOLBOX::html_error(DB_ERROR_MSG, 0);
+               }
+               $select .= '<option value="'.$row['id'].'"';
+               if ($row['id'] == $catid) {
+                       $select .= " SELECTED";
+               }
+               $select .= ">{$row['category']}";
+       }
+       $select .= '</select>';
+       return $select;
+}
+?>
+<script src="../verify.js"></script>
+<form action="update_photo.phtml?SID" method="POST"
+       enctype="multipart/form-data" onSubmit="
+       if (this.description.value.length > 300) {alert('Please limit' +
+       ' your description to 300 characters or less.'); return false;}
+this.title.optional = true;
+this.title.r = 'Photo Name';
+this.image.optional = true;
+this.description.optional = true;
+return(verify(this));
+">
+       <?
+echo '<table id="admin-edit-table">';
+foreach($row as $key=>$value) {
+       switch($key) {
+       case "id":
+               echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+       case "pos":
+               echo "<input type=\"hidden\" name=\"oldpos\" value=\"$value\">";
+               break;
+
+       case "title":
+               echo "<tr><td class=\"navtd\" align=\"right\" nowrap=\"nowrap\">Photo Name:</td>";
+               GLM_TOOLBOX::text_box("title",$value);
+               echo "</tr>";
+               break;
+
+       case "catid":
+               echo "<tr><td class=\"navtd\" align=\"right\" nowrap=\"nowrap\">
+               <input type=\"hidden\" name=\"oldcatid\" value=\"$value\">
+               Album Name</td>";
+               $output = catid_select($value);
+               echo "<td class=\"navtd2\">".$output."</td>";
+               echo "</tr>";
+               break;
+
+       case "description":
+               echo "<tr><td class=\"navtd\" align=\"right\" nowrap=\"nowrap\">Description</td>
+                               <td><textarea id=\"description\" name=\"description\" cols=\"54\" rows=\"10\">$value</textarea>";
+//             text_area("description",$value);
+               echo "</tr>";
+               break;
+
+       case "image":
+               echo "<tr><td class=\"navtd\" align=\"right\" nowrap=\"nowrap\">Current Image:</td>";
+               echo "<td class=\"navtd2\">
+                       <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+               if ($value != "") 
+               {
+                       echo "<img src=\"".PHOTO_SMALL_URL."$value\">
+                               </td>
+                               <tr>
+                               <td class=\"navtd\" align=\"right\">Delete this image:</td>
+                               <td nowrap=\"nowrap\">
+                               <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                               <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                               </td>
+                               </tr>";
+               }
+               echo "<tr><td align=\"right\">
+                       New Image:</td><td nowrap=\"nowrap\"><input type=\"file\" name=\"image\"></td></tr>";
+               break;
+
+       default:
+               GLM_TOOLBOX::html_error("Incorrect Value -> ".$key,1);
+               break;
+       }
+}
+if (isset($id)) {
+       ?>
+               <tr><td colspan=2 align=center nowrap="nowrap">
+               <input type="submit" name="Command" value="Update">
+               <input type="submit" name="Command" value="Cancel">
+               <input type="submit" name="Command" value="Delete" onClick="
+               if (confirm('This will delete this Record!\n Are you sure?'))
+                       return(true);
+               else 
+                       return(false);
+       ">
+               </td></tr>
+               <?
+} else {
+       GLM_TOOLBOX::form_footer("Insert","",2);
+}
+echo '</table></form>';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Photos/edit_photo_category.phtml b/admin/Photos/edit_photo_category.phtml
new file mode 100755 (executable)
index 0000000..8092102
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+require_once("../../setup.phtml");
+require_once("photo-setup.inc");
+
+GLM_TOOLBOX::top("Photo Albums (Add Album)", HELP_BASE."photocat.phtml?key=edit");
+$lnav["List Albums"] = "list_photo_category.phtml";
+GLM_TOOLBOX::html_nav_table($lnav, 6);
+
+if(isset($id)) {
+       $qs = "SELECT   id,category,pos  
+               FROM    photo_category 
+               WHERE   id = $id";
+       if(!$res = $DB->db_exec($qs)) {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG,1);
+       }
+       $row = $DB->db_fetch_array($res,0, PGSQL_ASSOC);
+       $qs2 = "select * from photo_category_bus where photocat_id = $id;";
+       $res2 = $DB->db_exec($qs2); 
+       if( pg_numrows( $res2 ) > 0 ) {
+               for( $i =0; $i < pg_numrows( $res2 ); $i++ ) {
+                       $parent[] = pg_result( $res2, $i, 'buscat_id' );
+               }
+       }
+} else {
+       $row = array( "category" => "");
+}
+
+?>
+<script type="text/javascript">
+function mySubmit()
+{
+       var Sel = document.getElementById('parent' ).value;
+       if( Sel == '' )
+       {
+               alert('You must select a page!');
+               return( false );
+       }
+       var Category = document.getElementById('category').value;
+       if( Category == '' )
+       {
+               alert('You must supply a Album Name');
+               return( false );
+       }
+       return( true );
+}
+</script>
+<form action="update_photo_category.phtml" method="post" enctype="multipart/form-data" onSubmit="return(mySubmit());">
+       <?
+echo '<table id="admin-edit-table">';
+echo '<tr>
+  <td align="right" nowrap="nowrap">Page to display on:</td>
+  <td>'.parent_select($parent).'</td>
+  </tr>';
+foreach ($row as $key=>$value) {
+       switch ($key) {
+
+               case "id":
+                       echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+               break;
+
+               case "pos":
+                       echo "<input type=\"hidden\" name=\"oldpos\" value=\"$value\">";
+               break;
+
+               case "category":
+
+                       echo '<tr><td class="navtd" align="right" nowrap="nowrap">Album Name:</td>
+                       <td><input id="category" name="category" value="'.htmlspecialchars($value).'"></td>
+                       </tr>';
+               break;
+
+               case "intro":
+                       echo "<tr><td class=\"navtd\" align=\"right\" nowrap=\"nowrap\">Intro:</td>";
+               GLM_TOOLBOX::text_area("intro",$value);
+               echo "</tr>";
+               break;
+
+               case "description":
+                       echo "<tr><td class=\"navtd\" align=\"right\" nowrap=\"nowrap\">Description:</td>";
+               GLM_TOOLBOX::text_area("description",$value);
+               echo "</tr>";
+               break;
+
+               case "image":
+                       if($value != "") {
+                               echo "<tr><td class=\"navtd2\" align=\"right\">
+                                       <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+                               echo "Current Image:</td><td call=\"navtd2\"><img src=\"".PHOTO_SMALL_URL."$value\">
+                                       </td>
+                                       </tr>
+                                       <tr>
+                                       <td align=\"right\" nowrap=\"nowrap\">
+                                       Delete this image:
+                                       </td>
+                                       <td nowrap=\"nowrap\">
+                                       <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                                       <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                                       </td>
+                                       </tr>";
+                       }
+               echo "<tr><td align=\"right\" nowrap=\"nowrap\">New Image:</td>\n";
+               echo "<td nowrap=\"nowrap\"><input type=\"file\" name=\"image\"></td></tr>";
+               break;
+
+               default:
+               GLM_TOOLBOX::html_error("Incorrect Value -> ".$key,1);
+               break;
+       }
+}
+if(isset($id)) {
+       $qs = "SELECT   count(*) as count
+               FROM    photo
+               WHERE   catid = $id";
+
+       if(!$res = $DB->db_exec($qs)) {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+       }
+
+       $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+       ?>
+               <tr><td colspan=2 align=center>
+               <input type="submit" name="Command" value="Update">
+               <input type="submit" name="Command" value="Cancel">
+               <input type="submit" name="Command" value="Delete" onClick="
+               <?php
+               if( $row[count] == 0 ) {
+                       ?>
+                               if(confirm('This will delete this category!\n Are you sure?'))
+                                       return(true);
+                               else 
+                                       return(false);
+                       <?php
+               } else {
+                       ?>
+                               alert('You have to remove any records in\n this category first');
+                       return(false);
+                       <?php
+               }
+       ?>
+               ">
+               </td></tr>
+               <?php
+} else { 
+       GLM_TOOLBOX::form_footer("Insert", "", 2);
+}
+echo '</table>
+</form>';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Photos/export-images-is0.php b/admin/Photos/export-images-is0.php
new file mode 100755 (executable)
index 0000000..faa8623
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'Toolkit/Image/Server.php';
+$db = new PDO('pgsql:'.CONN_STR);
+define('OLDORG', 'http://www.migcsa.org/testphoto/');
+$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
+$sql = "
+  SELECT id,image
+    FROM photo
+   WHERE image != ''
+   AND image not like 'is%'
+   ORDER BY id";
+try {
+    $stmt = $db->query($sql);
+    $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
+    echo '<pre>';
+    print_r($data);
+    echo '</pre>';
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+//$db->beginTransaction();
+$IServer = new Toolkit_Image_Server();
+if (is_array($data)) {
+    $prep2 = "
+    UPDATE photo
+       SET image = :image
+     WHERE id = :id";
+    $stmt3 = $db->prepare($prep2);
+
+    foreach ($data as &$row) {
+        $row['image'] = trim($row['image']);
+            var_dump(OLDORG.$row['image']);
+        if (!ereg("^is", $row['image'])) {
+            $image_URL = OLDORG.$row['image'];
+            $image = $IServer->imageUpload($image_URL);
+            if ($image) {
+                try {
+                    $stmt3->bindParam(":image", $image, PDO::PARAM_STR);
+                    $stmt3->bindParam(":id", $row['id'], PDO::PARAM_INT);
+                    $stmt3->execute();
+                } catch(PDOException $e) {
+                    die($e->getMessage());
+                }
+            }
+            echo '<br>Image Name Returned: ';
+            var_dump($image);
+        }
+    }
+}
+//$db->commit();
+//$db->rollBack();
+?>
diff --git a/admin/Photos/index.php b/admin/Photos/index.php
new file mode 100644 (file)
index 0000000..d4380ca
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+header('Location: list_photo_category.phtml');
+?>
diff --git a/admin/Photos/list_photo.phtml b/admin/Photos/list_photo.phtml
new file mode 100755 (executable)
index 0000000..4b9d14a
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+require_once "../../setup.phtml";
+require_once "photo-setup.inc";
+GLM_TOOLBOX::top("Photo Albums (List Photos)", HELP_BASE."photo.phtml?key=list");
+$lnav = array(
+                       "Add A New Photo"       => "edit_photo.phtml?catid=$catid",
+                       "List Photos"           => "list_photo.phtml?catid=$catid",
+                       "List Albums"   => "list_photo_category.phtml"
+               );
+GLM_TOOLBOX::html_nav_table($lnav, 5);
+$query = "select * from photo_category_bus;";
+if ($res2 = $DB->db_exec($query)) {
+       while ($row2 = pg_fetch_array($res2)) {
+               $data2[$row2['photocat_id']] = $row2['buscat_id'];
+       }
+}
+$qs2 = "SELECT         id,title,pos 
+               FROM    photo
+               WHERE   catid = $catid
+               ORDER BY pos";
+$res = $DB->db_exec($qs2);
+if (!$res) {
+       GLM_TOOLBOX::html_error(DB_ERROR_MSG, 1);
+}
+echo '<div style="clear: left; margin: 10px; padding-top: 10px; font-family: arial, sans-serif; font-size: 12px; font-weight: bold; color: #666;">';
+echo get_cat_name($data2[$catid]);
+echo '</div>';
+echo ' <form action="update_photo.phtml" method="POST">
+<table id="admin-list-table">';
+?>
+<tr>
+  <th> Function </th>
+  <th> Title </th>
+</tr>
+<?
+for($i = 0; $i < $DB->db_numrows($res); $i++) 
+{
+       $row = $DB->db_fetch_array($res,$i, PGSQL_ASSOC); 
+       if(!$row[id])
+       {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG,1);
+       }
+       if(!$row[id])
+       {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG,1);
+       }
+       ?>
+<tr>
+       <td align="left" nowrap="nowrap">
+               <a href="edit_photo.phtml?id=<?echo $row[id]?>&catid=<?echo $catid?>">[Edit/Delete]</a>
+       <?
+       $qs = "SELECT   MAX(pos) as maxpos
+                  FROM         photo
+                  WHERE        catid = $catid";
+
+       if(!$maxresult = $DB->db_exec($qs)) 
+       {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+       }
+       $max_data = $DB->db_fetch_array($maxresult,0,PGSQL_ASSOC);
+       $maxpos = $max_data['maxpos'];
+       $pos = "<font size=-4><select name=pos 
+               onChange=location.href=this[this.selectedIndex].value;
+               size=1>";
+       for($newpos=1;$newpos<=$maxpos;$newpos++) 
+       {
+               $string = "Command=Move&id=$row[id]&catid=$catid&newpos=$newpos";
+               $pos .= "<option value=\"update_photo.phtml?$string\"";
+               if($newpos == $row[pos]) 
+               {
+                       $pos .= " selected";
+               }
+               $pos .= ">$newpos\n";
+       }
+       $pos .= "</select></font>";
+       echo $pos;
+       ?>
+       </td>
+       <td align=left> <b><?echo $row[title]?></b> </td>
+</tr>
+       <?
+}
+echo '</table>
+       </form>
+';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Photos/list_photo_category.phtml b/admin/Photos/list_photo_category.phtml
new file mode 100755 (executable)
index 0000000..a1e1cd6
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+require_once "../../setup.phtml";
+require_once "photo-setup.inc";
+$query = "select * from photo_category_bus order by buscat_id;";
+$sql = "
+  SELECT pcb.buscat_id,pcb.photocat_id
+    FROM photo_category pc 
+         LEFT OUTER JOIN photo_category_bus pcb ON (pcb.photocat_id = pc.id) 
+         LEFT OUTER JOIN bus_category bc ON (bc.id = pcb.buscat_id)
+ORDER BY bc.parent,bc.pos,pcb.pos";
+if ($res2 = $DB->db_exec($sql)) {
+       while ($row2 = pg_fetch_array($res2)) {
+               $data2[$row2['buscat_id']][] = $row2['photocat_id'];
+       }
+}
+GLM_TOOLBOX::top("Photo Albums (List Categories)", HELP_BASE."photocat.phtml?key=list");
+$lnav["Add A New Album"]       = "edit_photo_category.phtml";
+//$lnav["Default Text"]        = "edit-default.php";
+//$lnav["List Albums"] = "list_photo_category.phtml";
+GLM_TOOLBOX::html_nav_table($lnav, 7);
+echo ' <form action="update_photo_category.phtml" method="POST">
+<table id="admin-list-table" style="width:500px;">';
+?>
+<tr>
+  <th> Function </th>
+  <th> Gallery Name </th>
+</tr>
+<script type="text/javascript">
+function toggleRows(rowId)
+{
+    //$("." + rowId).toggle();
+    $("." + rowId).each(function(i, elem) {
+           $(elem).toggle($(elem).css('display') == 'none');
+    });
+    return false;
+}
+</script>
+<?php
+if (is_array($data2)) {
+    foreach ($data2 as $buscat => $row3) {
+        $qs =  "select pc.id,pc.category,pcb.pos 
+            from photo_category pc left outer join photo_category_bus pcb on (pcb.photocat_id = pc.id) 
+            where pcb.buscat_id = ".$buscat." order by pcb.pos;";
+        if (!$res = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+        }
+        echo '<tr>
+            <td colspan="2" style="background-color:#003366;color:#fff;text-align:left;">
+                <a href="#" onClick="toggleRows(\'buscat-'.$buscat.'\');" 
+                    style="color:white;float:left;padding:0 15px 0 5px;">Toggle Exp/Col</a>
+                '.get_cat_name($buscat).'
+            </td>
+            </tr>';
+        for ($i = 0; $i < $DB->db_numrows( $res ); $i++) {
+            $row = $DB->db_fetch_array($res, $i, PGSQL_ASSOC); 
+            if (!$row['id']) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG, 1);
+            }
+            ?>
+            <tr class="buscat-<?php echo $buscat;?>" style="display:none;">
+            <td class="navtd2" nowrap="nowrap">
+            <a href="edit_photo_category.phtml?id=<?php echo $row[id]?>">[Edit]</a>
+            <a href="list_photo.phtml?catid=<?php echo $row[id]?>">[List Photos]</a>
+            <?php
+            $qs = "SELECT      MAX(pos) as maxpos
+                   FROM        photo_category_bus 
+                   where       buscat_id = $buscat;";
+
+            if (!$maxresult = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+            }
+            $max_data = $DB->db_fetch_array($maxresult, 0, PGSQL_ASSOC);
+            $maxpos = $max_data['maxpos'];
+            $pos = '<select name=pos 
+                onChange=location.href=this[this.selectedIndex].value;
+                size=1 style="font-size:9pt;">';
+            for ($newpos = 1; $newpos <= $maxpos; $newpos++) {
+                $string = "Command=Move&id=$row[id]&newpos=$newpos&oldpos=".$row['pos']."&&buscat_id=$buscat";
+                $pos .= "<option value=\"update_photo_category.phtml?$string\"";
+                if ($newpos == $row['pos']) {
+                    $pos .= " selected";
+                }
+                $pos .= ">$newpos\n</option>";
+            }
+            $pos .= "</select>";
+            echo $pos;
+            ?>
+            </td>
+            <td class="navtd2" nowrap="nowrap"><b><?php echo $row['category'];?></b> </td>
+        </tr>
+            <?php
+        }
+    }
+}
+echo '</table>
+</form>
+';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Photos/photo-setup.inc b/admin/Photos/photo-setup.inc
new file mode 100644 (file)
index 0000000..d228853
--- /dev/null
@@ -0,0 +1,304 @@
+<?php
+
+/**
+ * photo-setup.inc
+ * 
+ * Setup file for including in all photo scripts
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  Toolkit
+ * @package   PackageName
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: photo-setup.inc,v 1.6 2009/10/16 15:09:11 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Description for define
+ */
+define("LEVELS_DEEP", 5);
+// create a global database object
+$DB = new GLM_DB();
+
+/**
+ * $GLOBALS['DB']
+ * @global mixed $GLOBALS['DB']
+ * @name   $DB
+ */
+$GLOBALS['DB'] = $DB;
+// {{{ get_cat_name()
+/**
+ * get_cat_name 
+ * get the name of the category and the parent up to 4 levels 
+ * 
+ * @param mixed $id id for table bus_category
+ * 
+ * @access public
+ * @return void  
+ */
+function get_cat_name($id)
+{
+    $DB =& $GLOBALS['DB'];
+    if (is_numeric($id) && $id != 0) {
+        $query = "
+        SELECT category,parent 
+          FROM bus_category 
+         WHERE id = $id;";
+        $res      = $DB->db_exec($query);
+        $category = pg_result($res, 0, 'category');
+        $parent   = pg_result($res, 0, 'parent');
+        $cats[]   = strip_tags($category);
+        if ($parent != '0') {
+            $query    = "
+            SELECT category,parent 
+             FROM bus_category 
+            WHERE id = $parent;";
+            $res      = $DB->db_exec( $query);
+            $category = pg_result($res, 0, 'category');
+            $parent   = pg_result($res, 0, 'parent');
+            $cats[]   = strip_tags($category);
+            if ($parent != '0') {
+                $query    = "
+                SELECT category,parent 
+                 FROM bus_category 
+                WHERE id = $parent;";
+                $res      = $DB->db_exec( $query);
+                $category = pg_result($res, 0, 'category');
+                $parent   = pg_result($res, 0, 'parent');
+                $cats[]   = strip_tags($category);
+                if ($parent != '0') {
+                    $query    = "
+                    SELECT category,parent 
+                     FROM bus_category 
+                    WHERE id = $parent;";
+                    $res      = $DB->db_exec( $query);
+                    $category = pg_result($res, 0, 'category');
+                    $parent   = pg_result($res, 0, 'parent');
+                    $cats[]   = strip_tags($category);
+                }
+            }
+        }
+        $cats = array_reverse($cats);
+        return implode(" &#62; ", $cats);
+    } else {
+        return false;
+    }
+}
+// }}}
+// {{{ photo_process_image()
+/**
+ * photo_process_image function for image processing
+ * 
+ * @param  mixed  $image      The variable of the image being post from the form
+ * @param  mixed  $image_name The variable_name of the image being post
+ * @access public
+ * @return void  
+ */
+function photo_process_image($image, $image_name) 
+{
+    $image_upload_array = GLM_TOOLBOX::img_upload($image, $image_name, PHOTO_LARGE_DIR);
+    GLM_TOOLBOX::img_resize(PHOTO_LARGE_DIR.$image_upload_array[0], 
+        PHOTO_LARGE_DIR.$image_upload_array[0], PHOTO_LARGE_SIZE);
+    GLM_TOOLBOX::img_resize(PHOTO_LARGE_DIR.$image_upload_array[0], 
+        PHOTO_SMALL_DIR.$image_upload_array[0], PHOTO_SMALL_SIZE);
+    $image_name         = $image_upload_array[0];
+    return $image_name;
+}
+// }}}
+// {{{ sort_by_parent()
+/**
+ * sort_by_parent 
+ * 
+ * @param  mixed  $data
+ * @access public
+ * @return void  
+ */
+function sort_by_parent($data)
+{
+    if (!is_array($data)) {
+        return false;
+    }
+    foreach($data as $key=>$value) {
+        $data_new[$value["parent"]][$value["id"]] = $value;
+    }
+    return $data_new;
+}
+// }}}
+// {{{ convertParent()
+/**
+ * convertParent 
+ * 
+ * @param  mixed  $threads
+ * @param  mixed  $thread 
+ * @access public
+ * @return void  
+ */
+function convertParent($threads,$thread)
+{
+    static $select,$count;
+    if (!$count) {
+        $count = 0;
+    }
+    $bgcolor[] = '#ccc';
+    $bgcolor[] = '#ddd';
+    if (is_array($thread)) {
+        foreach($thread as $parent=>$value) {            
+            $color = $bgcolor[$count];
+            $select[$value["id"]]["color"]    = $color;
+            $select[$value["id"]]["category"] = $value["category"];
+            $select[$value["id"]]["count"]    = $count;
+
+            if (isset($threads[$parent])) {    
+                $count++;
+                convertParent($threads, $threads[$parent]);
+            }
+        }
+    }
+    $count--;
+    return $select;
+}
+// }}}
+// {{{ parent_select()
+/**
+ * parent select
+ *
+ * This function does both the bus and bus category page parent select drop down 
+ * boxes. The backcount var is used to lock the list to a certain level set up
+ * with define of LEVELS_DEEP. Count varl starts at one and is generated in the 
+ * function convertParent so we'll need to subtract one for proper results.
+ * To unset backcount properly we'll need to check if count goes under or 
+ * equals that of backcount. Then unset($backcount) cause if backcount is not 
+ * empty then category won't get added to list.
+ *    
+ * @return string
+ */
+function parent_select($catid) 
+{
+    // select catid portion 
+    $qs  = "
+      SELECT id,category,parent 
+        FROM bus_category 
+    ORDER BY parent,pos";
+
+    $res = $GLOBALS['DB']->db_exec( $qs);
+    while ($row = pg_fetch_array($res)) {
+        $data[] = $row;
+    }
+    $data1  = sort_by_parent($data);
+    $select = '<select id="parent" name="parent[]" multiple size="10">';
+    //$select .= '<option value="">--No Page--</option>';
+    $parts  = convertParent($data1,$data1[0]);
+    if (is_array($parts)) {
+        foreach($parts as $key=>$value) {
+            if (isset($backcount) && $value['count'] <= $backcount) {
+                unset($backcount);
+            }
+            if ($key == $id && $sel_name = "parent") {
+                $backcount = $value['count'];
+            }
+
+            if ((!isset($backcount) && ($value['count'] < (LEVELS_DEEP - 1)) || $sel_name == "catid[]")) {
+                $bkg = $value["color"];
+                $indent  = (int)$value["count"] * 10;
+                $cc      = (int)$value["count"] * 2;
+                $paddman = str_repeat("&nbsp;",$cc);
+                $select .= '<option value="'.$key.'"';
+                if (is_array($catid) && in_array($key, $catid)) {
+                    $select .= ' selected';
+                }
+                $select .= ' style="background-color:'.$bkg.';"';
+                $select .= '>'.$paddman.$value["category"];
+            }
+        }
+    }
+    $select .= "</select>";
+    return $select;
+}// }}}
+// {{{ update_photo_bus()
+
+/**
+ * update_photo_bus
+ * 
+ * run update of the photo_category_bus table
+ * 
+ * @param  unknown $photo_id id from table photo
+ * @param  array   $bus_id   id from table bus_category
+ * 
+ * @return boolean Return description (if any) ...
+ */
+function update_photo_bus($photo_id, $bus_id)
+{
+    if (!is_array($bus_id)) {
+        return false;
+    } elseif (!is_numeric($photo_id)) { 
+        return false;
+    }
+    // starting transaction 
+    if (!$GLOBALS['DB']->db_exec("BEGIN WORK;")) {
+        die('end'.__LINE__);
+    }
+    $query = "
+    SELECT * 
+      FROM photo_category_bus 
+     WHERE photocat_id = $photo_id
+       AND buscat_id NOT IN (".implode(',',$bus_id).");";
+    if (!$res = $GLOBALS['DB']->db_exec( $query)) {
+        die('end'.$query.__LINE__);
+    }
+    while ($row = pg_fetch_object($res)) {
+        $query = "
+        DELETE FROM photo_category_bus 
+         WHERE id = ".$row->id.";
+        UPDATE photo_category_bus
+           SET pos = pos - 1 
+         WHERE pos > ".$row->pos." 
+           AND buscat_id = ".$row->buscat_id.";";
+        if (!$res = $GLOBALS['DB']->db_exec( $query)) {
+            die('end'.$query.__LINE__);
+        }
+    }
+    foreach($bus_id as $busId) {
+        unset($maxpos);
+        $query = "
+        SELECT max(pos) AS maxpos 
+          FROM photo_category_bus 
+         WHERE buscat_id = $busId";
+        if (!$res = $GLOBALS['DB']->db_exec( $query)) {
+            die('end'.$query.__LINE__);
+        }
+        $maxpos = pg_result($res, 0, 'maxpos');
+        if (!$maxpos) {
+            $maxpos = 1;
+        } else {
+            $maxpos++;
+        }
+        $query = "
+        SELECT count(id) AS count 
+          FROM photo_category_bus 
+         WHERE photocat_id = $photo_id 
+           AND buscat_id = $busId;";
+        if (!$res = $GLOBALS['DB']->db_exec( $query)) {
+            die('end'.$query.__LINE__);
+        }
+        $count = pg_result($res, 0 , 'count');
+        if ($count == 0) {
+            $query = "
+            INSERT INTO photo_category_bus 
+            (photocat_id,buscat_id,pos) 
+            VALUES 
+            ($photo_id,$busId,$maxpos);";
+            if (!$GLOBALS['DB']->db_exec( $query)) {
+                die('end'.$query.__LINE__);
+            }
+        }
+    }
+    // ending transaction 
+    if (!$GLOBALS['DB']->db_exec("COMMIT WORK;")) {
+        die('end'.__LINE__);
+    }
+    $query = "";
+}// }}}
+?>
diff --git a/admin/Photos/photo.sql b/admin/Photos/photo.sql
new file mode 100755 (executable)
index 0000000..f7742e3
--- /dev/null
@@ -0,0 +1,139 @@
+\connect - postgres
+SET client_encoding = 'SQL_ASCII';
+SET check_function_bodies = false;
+CREATE TABLE "photo_category" (
+       "id" SERIAL PRIMARY KEY, 
+       "category" text,
+       "image" text,
+       "pos" integer
+);
+
+REVOKE ALL on "photo_category" from PUBLIC;
+GRANT ALL on "photo_category" to "nobody";
+GRANT ALL on "photo_category" to "postgres";
+
+REVOKE ALL on "photo_category_id_seq" from PUBLIC;
+GRANT ALL on "photo_category_id_seq" to "nobody";
+GRANT ALL on "photo_category_id_seq" to "postgres";
+
+CREATE TABLE "photo" (
+       "id" SERIAL PRIMARY KEY, 
+       "title" text,
+       "description" text,
+       "image" text,
+       "catid" integer,
+       "pos" integer,
+       FOREIGN KEY (catid) REFERENCES photo_category(id) ON DELETE CASCADE
+);
+
+REVOKE ALL on "photo" from PUBLIC;
+GRANT ALL on "photo" to "nobody";
+GRANT ALL on "photo" to "postgres";
+
+REVOKE ALL on "photo_id_seq" from PUBLIC;
+GRANT ALL on "photo_id_seq" to "nobody";
+GRANT ALL on "photo_id_seq" to "postgres";
+
+CREATE TABLE photo_category_bus (
+       "id" SERIAL PRIMARY KEY,
+       "photocat_id" int,
+       "buscat_id" int,
+       "pos" integer,
+       FOREIGN KEY (photocat_id) REFERENCES photo_category(id) ON DELETE CASCADE,
+       FOREIGN KEY (buscat_id) REFERENCES bus_category(id) ON DELETE CASCADE
+)
+
+REVOKE ALL on "photo_category_bus" from PUBLIC;
+GRANT ALL on "photo_category_bus" to "nobody";
+GRANT ALL on "photo_category_bus" to "postgres";
+
+REVOKE ALL on "photo_category_bus_id_seq" from PUBLIC;
+GRANT ALL on "photo_category_bus_id_seq" to "nobody";
+GRANT ALL on "photo_category_bus_id_seq" to "postgres";
+--
+-- TOC entry 3 (OID 12966596)
+-- Name: photo_config; Type: TABLE; Schema: public; Owner: matrix
+--
+
+CREATE TABLE photo_default (
+    id serial NOT NULL,
+    header text,
+       description text
+);
+
+
+--
+-- TOC entry 4 (OID 12966596)
+-- Name: photo_config; Type: ACL; Schema: public; Owner: matrix
+--
+
+REVOKE ALL ON TABLE photo_default FROM PUBLIC;
+GRANT ALL ON TABLE photo_default TO nobody;
+
+
+--
+-- TOC entry 5 (OID 12966599)
+-- Name: photo_config_pkey; Type: CONSTRAINT; Schema: public; Owner: matrix
+--
+
+ALTER TABLE ONLY photo_default 
+    ADD CONSTRAINT photo_default_pkey PRIMARY KEY (id);
+
+insert into photo_default (header,description) values ('Photo Gallery','Instructions on how to use this gallery. This text will be managed from the administration area shortly.');
+--
+-- TOC entry 3 (OID 13410626)
+-- Name: photo_category_bus; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE photo_category_bus (
+    id serial NOT NULL,
+    photocat_id integer,
+    buscat_id integer,
+    pos integer
+);
+
+
+--
+-- TOC entry 4 (OID 13410626)
+-- Name: photo_category_bus; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE photo_category_bus FROM PUBLIC;
+GRANT ALL ON TABLE photo_category_bus TO nobody;
+
+
+--
+-- TOC entry 5 (OID 13410626)
+-- Name: photo_category_bus_id_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE photo_category_bus_id_seq FROM PUBLIC;
+GRANT ALL ON TABLE photo_category_bus_id_seq TO nobody;
+
+
+--
+-- TOC entry 6 (OID 13410629)
+-- Name: photo_category_bus_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY photo_category_bus
+    ADD CONSTRAINT photo_category_bus_pkey PRIMARY KEY (id);
+
+
+--
+-- TOC entry 7 (OID 13410631)
+-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY photo_category_bus
+    ADD CONSTRAINT "$1" FOREIGN KEY (photocat_id) REFERENCES photo_category(id) ON DELETE CASCADE;
+
+
+--
+-- TOC entry 8 (OID 13410635)
+-- Name: $2; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY photo_category_bus
+    ADD CONSTRAINT "$2" FOREIGN KEY (buscat_id) REFERENCES bus_category(id) ON DELETE CASCADE;
+
diff --git a/admin/Photos/photo_config.sql b/admin/Photos/photo_config.sql
new file mode 100755 (executable)
index 0000000..2ad98e8
--- /dev/null
@@ -0,0 +1,97 @@
+--
+-- PostgreSQL database dump
+--
+
+SET client_encoding = 'SQL_ASCII';
+SET check_function_bodies = false;
+
+SET SESSION AUTHORIZATION 'matrix';
+
+SET search_path = public, pg_catalog;
+
+--
+-- TOC entry 3 (OID 12966596)
+-- Name: photo_config; Type: TABLE; Schema: public; Owner: matrix
+--
+
+CREATE TABLE photo_config (
+    id serial NOT NULL,
+    category integer
+);
+
+
+--
+-- TOC entry 4 (OID 12966596)
+-- Name: photo_config; Type: ACL; Schema: public; Owner: matrix
+--
+
+REVOKE ALL ON TABLE photo_config FROM PUBLIC;
+GRANT ALL ON TABLE photo_config TO nobody;
+
+
+--
+-- TOC entry 5 (OID 12966599)
+-- Name: photo_config_pkey; Type: CONSTRAINT; Schema: public; Owner: matrix
+--
+
+ALTER TABLE ONLY photo_config
+    ADD CONSTRAINT photo_config_pkey PRIMARY KEY (id);
+
+--
+-- TOC entry 3 (OID 13410626)
+-- Name: photo_category_bus; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE photo_category_bus (
+    id serial NOT NULL,
+    photocat_id integer,
+    buscat_id integer
+);
+
+
+--
+-- TOC entry 4 (OID 13410626)
+-- Name: photo_category_bus; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE photo_category_bus FROM PUBLIC;
+GRANT ALL ON TABLE photo_category_bus TO nobody;
+
+
+--
+-- TOC entry 5 (OID 13410626)
+-- Name: photo_category_bus_id_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE photo_category_bus_id_seq FROM PUBLIC;
+GRANT ALL ON TABLE photo_category_bus_id_seq TO nobody;
+
+
+--
+-- TOC entry 6 (OID 13410629)
+-- Name: photo_category_bus_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY photo_category_bus
+    ADD CONSTRAINT photo_category_bus_pkey PRIMARY KEY (id);
+
+
+--
+-- TOC entry 7 (OID 13410631)
+-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY photo_category_bus
+    ADD CONSTRAINT "$1" FOREIGN KEY (photocat_id) REFERENCES photo_category(id) ON DELETE CASCADE;
+
+
+--
+-- TOC entry 8 (OID 13410635)
+-- Name: $2; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY photo_category_bus
+    ADD CONSTRAINT "$2" FOREIGN KEY (buscat_id) REFERENCES bus_category(id) ON DELETE CASCADE;
+
+
+
diff --git a/admin/Photos/update_display.php b/admin/Photos/update_display.php
new file mode 100644 (file)
index 0000000..71db4da
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+require_once('../../setup.phtml');
+require_once('photo-setup.inc');
+
+$query = "update photo_config set category = $parent;";
+db_auto_exec( $query );
+header('Location: list_photo_category.phtml');
+exit();
+echo $query;
+?>
diff --git a/admin/Photos/update_photo.phtml b/admin/Photos/update_photo.phtml
new file mode 100644 (file)
index 0000000..684033b
--- /dev/null
@@ -0,0 +1,276 @@
+<?php
+
+/**
+ * update_photo.phtml
+ * 
+ * PHP Script to update the photo table from edit_photo.phtml Form submittion
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  Toolkit
+ * @package   PackageName
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: update_photo.phtml,v 1.4 2009/05/13 16:50:53 matrix Exp $
+ * @link      <>
+ */
+
+/**
+ * Description for require_once
+ */
+require_once "../../setup.phtml";
+
+/**
+ * Description for require_once
+ */
+require_once 'photo-setup.inc';
+
+if ($_POST || $_REQUEST['Command'] == "Move") {
+    switch ($Command) {
+    case "Move":
+        $qs = "
+        SELECT pos,id
+          FROM photo
+         WHERE id = $id";
+
+        if (!$result = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+        }
+
+        $data = $DB->db_fetch_array($result, 0, PGSQL_ASSOC);
+        $pos  = $data['pos'];
+        
+        if ($newpos < $pos) {
+            $qs = "
+             SELECT id,pos
+               FROM photo
+              WHERE pos < $pos
+                AND pos >= $newpos
+                AND catid = $catid
+           ORDER BY pos";
+
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+            }
+            
+            $counter = ($newpos + 1);
+            for ($i = 0; $i < $DB->db_numrows($res); $i++) {
+                $res_data = $DB->db_fetch_array($res, $i, PGSQL_ASSOC);
+                $res_id   = $res_data['id'];
+                $res_pos  = $res_data['pos'];
+                $qs       = "
+                UPDATE photo
+                   SET pos = $counter
+                 WHERE id = $res_id";
+                
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+                }
+                $counter++;
+            }
+        } else {
+            $qs = "
+              SELECT pos,id
+                FROM photo
+               WHERE pos > $pos
+                 AND pos <= $newpos
+                 AND catid = $catid
+            ORDER BY pos";
+
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+            }
+            
+            $counter = ($pos);
+            for ($i = 0; $i < $DB->db_numrows($res); $i++) {
+                $res_data = $DB->db_fetch_array($res, $i, PGSQL_ASSOC);
+                $res_id   = $res_data['id'];
+                $res_pos  = $res_data['pos'];
+                $qs       = "
+                UPDATE photo
+                   SET pos = $counter
+                 WHERE id = $res_id";
+                
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+                }
+                $counter++;
+            }
+        }
+        $qs = "
+        UPDATE photo 
+           SET pos = $newpos
+         WHERE id = $id";
+
+        if (!$DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+        }
+    
+        $location = "list_photo.phtml?catid=$catid";
+        break;
+    
+    case "Update":
+        if ($image != "none" && $image != '') {
+
+            /**
+             * include the Toolkit_Image_Server class
+             */
+            include_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            if ($oldimage) {
+                $imServer->imageDelete($oldimage);
+            }
+            $image_name = GLM_TOOLBOX::process_image('image');
+        } else {
+            $image_name = $oldimage;
+        }
+        
+        if ($delete == "1") {
+            $image_name = "";
+
+            /**
+             * include the Toolkit_Image_Server class
+             */
+            include_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($_REQUEST['oldimage']);
+        }
+        
+        if ($catid != $oldcatid) {
+
+            $qs = "
+                SELECT MAX(pos) as maxpos
+                  FROM photo
+                 WHERE catid = $catid";
+
+            $res = $DB->db_exec($qs);
+            $row = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+            $pos = $row['maxpos'];
+            ++$pos;
+            
+            $qs = "
+                SELECT pos, id
+                  FROM photo
+                 WHERE catid = $oldcatid
+                   AND pos   > $oldpos
+                 ORDER BY pos";
+                   
+            $res2             = $DB->db_exec($qs);
+            $oldcatid_counter = $oldpos;
+            for ($i = 0; $i < $DB->db_numrows($res2); ++$i) {
+                $row2 = $DB->db_fetch_array($res2, $i, PGSQL_ASSOC);
+                $qs   = "
+                    UPDATE photo
+                       SET pos = $oldcatid_counter
+                     WHERE id  = {$row2['id']}";
+
+                $DB->db_exec($qs);
+                ++$oldcatid_counter;
+            }
+            
+        } else {
+            $pos = $oldpos;
+        }
+        
+        $qs = "
+        UPDATE photo
+           SET title = '$title',
+               catid = $catid,
+               image = '$image_name',
+               description = '$description',
+               pos = $pos
+         WHERE id    = $id";
+        
+        if (!$DB->db_auto_exec($qs)) {
+            html_error("failed ->".$qs, 1);
+        }
+        
+        $location = "list_photo.phtml?catid=$catid"; 
+        break;
+    
+    case "Insert":
+        if ($image != "none") {
+            $image_name = GLM_TOOLBOX::process_image('image');
+        } else { 
+            $image_name = "";
+        }
+        
+        $qs = "
+        SELECT MAX(pos) as maxpos
+          FROM photo
+         WHERE catid = $catid";
+
+        $res     = $DB->db_exec($qs);
+        $row     = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+        $nextpos = $row['maxpos'];
+        $nextpos++;
+        
+        $qs = "
+        INSERT INTO photo 
+        (description,title,catid,image,pos)
+        VALUES 
+        ('$description','$title',$catid,'$image_name',$nextpos)";
+                    
+        if (!$DB->db_auto_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs, 1);
+        }
+        
+        $location = "list_photo.phtml?catid=$catid"; 
+    
+        break;
+    
+    case "Delete":
+        $qs = "
+        DELETE FROM photo 
+         WHERE id = $id";
+        
+        if (!$DB->db_auto_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs, 1);
+        }
+        if ($oldimage) {
+
+            /**
+             * include the Toolkit_Image_Server class
+             */
+            include_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($oldimage);
+        }
+        
+        $qs = "
+          SELECT pos,id 
+            FROM photo
+           WHERE catid = $oldcatid
+             AND pos > $oldpos
+        ORDER BY pos";
+                   
+        $res2             = $DB->db_exec($qs);
+        $oldcatid_counter = $oldpos;
+        for ($i = 0; $i < $DB->db_numrows($res2); $i++) {
+            $row2 = $DB->db_fetch_array($res2, $i, PGSQL_ASSOC);
+            $qs   = "
+            UPDATE photo
+               SET pos = $oldcatid_counter
+             WHERE id = {$row2['id']}";
+
+            if (!$DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG, 0);
+            }
+            $oldcatid_counter++;
+        }
+        $location = "list_photo.phtml?catid=$catid"; 
+    
+        break;
+    
+    case "Cancel":
+        $location = "list_photo.phtml?catid=$catid"; 
+        break;
+    
+    default:
+        GLM_TOOLBOX::html_error("incorrect value for Command", 1);
+        break;
+    }
+    header("Location: $location");
+}
+?>
diff --git a/admin/Photos/update_photo_category.phtml b/admin/Photos/update_photo_category.phtml
new file mode 100644 (file)
index 0000000..3c6a454
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+include "../../setup.phtml";
+require_once 'photo-setup.inc';
+
+if ($REQUEST_METHOD == "POST" || $Command == "Move") {
+       switch ($Command) {
+               case "Move":
+                       $DB->db_exec('BEGIN WORK;');
+
+                       if( $newpos > $oldpos )
+                       {
+                               $query = "update photo_category_bus 
+                                       set pos = pos - 1 
+                                       where pos > $oldpos 
+                                       and buscat_id = ".$_GET['buscat_id']."
+                                       and pos <= $newpos";
+                               $DB->db_exec($query);
+                       }
+                       elseif( $newpos < $oldpos )
+                       {
+                               $query = "update photo_category_bus 
+                                       set pos = pos + 1 
+                                       where pos >= $newpos 
+                                       and buscat_id = ".$_GET['buscat_id']."
+                                       and pos < $oldpos";
+                               $DB->db_exec($query);
+                       }
+                       $query = "update photo_category_bus set pos = $newpos where photocat_id = ".$_GET['id']." 
+                               and buscat_id = ".$_GET['buscat_id'].";";
+                       //      echo '<p>'.$query.'</p>';
+                       $DB->db_exec($query);
+                       $DB->db_exec('COMMIT WORK;');
+                       //exit();
+                       $location = "list_photo_category.phtml?catid=$catid";
+               break;
+
+               case "Update":
+                       $DB->db_exec('BEGIN WORK;');
+            $qs = "UPDATE photo_category SET
+                category       = '$category'
+                WHERE id = $id";
+            if(!$DB->db_exec($qs)) {
+                html_error("failed ->".$qs,1);
+            }
+            update_photo_bus($id, $parent);
+            $location = "list_photo_category.phtml"; 
+            $DB->db_exec('COMMIT WORK'); 
+               break;
+
+               case "Insert":
+            $DB->db_exec('BEGIN WORK'); 
+            $qs = "INSERT INTO photo_category 
+                (category)
+                VALUES 
+                ('$category')";
+            if(!$res = $DB->db_exec($qs)) 
+            {
+                html_error("failed ->".$qs,1);
+            }
+            if( is_array( $parent ) )
+            {
+                $qs = "
+                    SELECT id
+                      FROM photo_category
+                     order by id DESC limit 1";
+                $res = $DB->db_exec($qs); 
+                $res = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+                update_photo_bus( $res['id'], $parent);
+            }
+            $DB->db_exec('COMMIT WORK'); 
+            $location = "list_photo_category.phtml"; 
+               break;
+
+               case "Delete":
+               $DB->db_exec('BEGIN WORK'); 
+               $qs = "SELECT   * 
+                       FROM    photo 
+                       WHERE   catid = $id";
+               $res = $DB->db_exec($qs);
+               if($DB->db_numrows($res) >0) 
+               {
+                       html_error("Sorry but you have items in there\n 
+                                       Delete these record before the Categories\n",1); 
+               }
+               $query = "select * from photo_category_bus where photocat_id = $id;";
+               if( !$res = $DB->db_exec($query ) )
+               {
+                       die('end'.$query.__LINE__);
+               }
+               while( $row = pg_fetch_object( $res ) )
+               {
+                       $query = "delete from photo_category_bus where id = ".$row->id.";
+                       update photo_category_bus set pos = pos - 1 where pos > ".$row->pos." and buscat_id = ".$row->buscat_id.";";
+                       if( !$res = $DB->db_exec($query ) )
+                       {
+                               die('end'.$query.__LINE__);
+                       }
+               }
+               $qs2 = "DELETE FROM photo_category 
+                       WHERE           id = $id";
+               if(!$DB->db_exec($qs2)) 
+               {
+                       html_error(DB_ERROR_MSG.$qs2,1);
+               }
+               $DB->db_exec('COMMIT WORK'); 
+               //exit();
+               $location = "list_photo_category.phtml"; 
+               break;
+
+               case "Cancel":
+                       $location = "list_photo_category.phtml"; 
+               break;
+
+               default:
+               html_error("incorrect value for Command",1);
+               break;
+       }
+
+       header("Location: $location");
+}
+?>
diff --git a/admin/Toolbox/business.sql b/admin/Toolbox/business.sql
new file mode 100644 (file)
index 0000000..b68fbc3
--- /dev/null
@@ -0,0 +1,86 @@
+CREATE TABLE bus (
+    id serial NOT NULL,
+    name text,
+    description text,
+    image text,
+    imagename text,
+    back_to_top bool
+);
+
+CREATE TABLE bus_category (
+    id serial NOT NULL,
+    parent integer,
+    category text,
+    intro text,
+    description text,
+    image text,
+    imagename text,
+    active boolean,
+    pos integer,
+    keyword text,
+       "template" integer,
+       no_search_form bool,
+       include_member_map boolean not null default false,
+       featured bool,
+       feature_intro text,
+    section_links bool,
+    title text,
+    meta_descr text,
+    short_url text,
+    region integer
+);
+
+CREATE TABLE bus_category_bus (
+    id serial NOT NULL,
+    busid integer,
+    catid integer,
+    pos integer
+);
+
+CREATE UNIQUE INDEX bus_id_indx ON bus USING btree (id);
+CREATE UNIQUE INDEX bus_category_id_indx ON bus_category USING btree (id);
+CREATE INDEX bus_category_parent_indx ON bus_category USING btree (parent);
+CREATE INDEX bus_category_pos_indx ON bus_category USING btree (pos);
+CREATE INDEX bus_category_keyword_indx ON bus_category USING btree (keyword);
+CREATE INDEX bus_category_template_indx ON bus_category USING btree ("template");
+CREATE UNIQUE INDEX bus_category_bus_id_indx ON bus_category_bus USING btree (id);
+CREATE INDEX bus_category_bus_busid_indx ON bus_category_bus USING btree (busid);
+CREATE INDEX bus_category_bus_catid_indx ON bus_category_bus USING btree (catid);
+ALTER TABLE ONLY bus_category
+    ADD CONSTRAINT bus_category_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY bus
+    ADD CONSTRAINT bus_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY bus_category_bus
+    ADD CONSTRAINT bus_category_bus_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY bus_category_bus ADD CONSTRAINT "$1" FOREIGN KEY (catid) REFERENCES bus_category(id) ON DELETE CASCADE;
+ALTER TABLE ONLY bus_category_bus ADD CONSTRAINT "$2" FOREIGN KEY (busid) REFERENCES bus(id) ON DELETE CASCADE;
+GRANT ALL on "bus" to "nobody";
+GRANT ALL on "bus" to "postgres";
+GRANT ALL on "bus_id_seq" to "nobody";
+GRANT ALL on "bus_id_seq" to "postgres";
+GRANT ALL on "bus_category" to "nobody";
+GRANT ALL on "bus_category" to "postgres";
+GRANT ALL on "bus_category_id_seq" to "nobody";
+GRANT ALL on "bus_category_id_seq" to "postgres";
+GRANT ALL on "bus_category_bus" to "nobody";
+GRANT ALL on "bus_category_bus" to "postgres";
+GRANT ALL on "bus_category_bus_id_seq" to "nobody";
+GRANT ALL on "bus_category_bus_id_seq" to "postgres";
+
+INSERT INTO bus_category (id,category,parent,pos,active) VALUES (nextval('bus_category_id_seq'),'Home',0,1,'t');
+
+CREATE TABLE files (
+    id serial NOT NULL,
+    filename text,
+    bytes integer,
+    "type" text,
+    urltext text,
+       bus_id integer,
+       pos integer default 1
+);
+GRANT ALL ON TABLE files TO nobody;
+GRANT ALL ON TABLE files_id_seq TO nobody;
+ALTER TABLE ONLY files
+    ADD CONSTRAINT files_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY files
+    ADD CONSTRAINT "$1" FOREIGN KEY (bus_id) REFERENCES bus(id) ON DELETE CASCADE;
diff --git a/admin/Toolbox/cktoolbox.js b/admin/Toolbox/cktoolbox.js
new file mode 100644 (file)
index 0000000..12cef85
--- /dev/null
@@ -0,0 +1,23 @@
+var CkToolbox =
+{
+    init: function()
+    {
+        if ($('#description').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('description',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+    }
+};
+$(document).ready(CkToolbox.init);
diff --git a/admin/Toolbox/collapse.png b/admin/Toolbox/collapse.png
new file mode 100755 (executable)
index 0000000..d10e051
Binary files /dev/null and b/admin/Toolbox/collapse.png differ
diff --git a/admin/Toolbox/convert_files.php b/admin/Toolbox/convert_files.php
new file mode 100644 (file)
index 0000000..26c751d
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+       //exit();
+include('../../setup.phtml');
+include(BASE.'classes/class_db.inc');
+$DB =& new GLM_DB();
+for( $i = 1; $i <= 3; $i++ )
+{
+       $query = "select id,file";
+       if( $i > 1 )
+       {
+               $query .= $i;
+       }
+       $query .= ",file";
+       if( $i > 1 )
+       {
+               $query .= $i;
+       }
+       $query .= "name from bus where file";
+       if( $i > 1 )
+       {
+               $query .= $i;
+       }
+       $query .= " != '' order by id;";
+       echo '<p>Query is :'.$query.'</p>';
+       $res = $DB->db_exec( $query );
+       while( $row = pg_fetch_array( $res ) )
+       {
+               $data[] = $row;
+       }
+}
+echo '<pre>';
+print_r( $data );
+echo '</pre>';
+//exit();
+$res = $DB->db_exec( "BEGIN WORK" );
+if( is_array( $data ) )
+{
+       foreach( $data as $row )
+       {
+               $id = $row['0'];
+               $filename = $row['1'];
+               $urltext = $row['2'];
+               $iFile = stat( UP_BASE.$filename );
+       //      echo '<p>File: '.UP_BASE.$filename.'</p>';
+               $query = "insert into files 
+               (filename,bytes,urltext,bus_id) 
+               values 
+               ('$filename','".$iFile['size']."','$urltext','$id');";
+               echo '<p>'.$query.'</p>';
+               if(! $res = $DB->db_exec( $query ) )
+               {
+                       die( pg_errormessage( $res ) );
+               }
+       }
+}
+$res = $DB->db_exec( "ABORT WORK" );
+/*
+echo '<pre>';
+print_r( $data );
+echo '</pre>';
+*/
+?>
diff --git a/admin/Toolbox/edit_bus.phtml b/admin/Toolbox/edit_bus.phtml
new file mode 100755 (executable)
index 0000000..5d1b06d
--- /dev/null
@@ -0,0 +1,318 @@
+<?php
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+if(isset($id)) {
+    $qs =  "SELECT    b.*
+    FROM    bus b,bus_category_bus bcb,bus_category bc
+    WHERE     b.id = $id
+    AND     bcb.busid = $id
+    AND     bcb.busid = b.id
+    AND     bcb.catid = bc.id";
+
+    if(!$res = $DB->db_exec($qs)) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+    }
+    $row = $DB->db_fetch_array($res,0, PGSQL_ASSOC);
+    if(!$row[id]) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+    }
+} else {
+    $row = array (
+        "name" => "",
+        "catid" => $catid,
+        "address" => "",
+        "city" => "",
+        "state" => "",
+        "zip" => "",
+        "phone" => "",
+        "fax" => "",
+        "email" => "",
+        "url" => "",
+        "description" => "",
+        "image" => "",
+    );
+}
+
+GLM_TOOLBOX::top2("Updatable Paragraphs (Add/Edit)", HELP_BASE."bus.phtml?key=edit","ToolboxUserGuide_2.0");
+
+$toolbox_nav["Add New Paragraph"] = "edit_bus.phtml?catid=$catid";
+unset($toolbox_nav["Add A New Page"]);
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+
+$qs = "SELECT     id,category
+FROM     bus_category
+ORDER BY parent,pos";
+
+if(!$altcats = $DB->db_exec($qs)) 
+GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+
+?>
+<script type="text/javascript" src="<?php echo GLM_APP_BASE_URL;?>ckeditor/current/ckeditor.js"></script>
+<script>
+function mySubmit() {
+    var check = 0;
+    for( i = 0; i < <?echo pg_numrows($altcats);?>;i++ )    {
+        if( document.myform.catid.options[i].selected ) {
+            check = 1;
+            document.myform.category.value += ':' + document.myform.catid.options[i].value;
+        }
+    }
+    if( check == 0 ) {
+            alert('Must select one Page from the list!');
+        return(false);
+    }
+}
+var MemberToolbox =
+{
+    init: function()
+    {
+        if ($('#description').is('textarea')) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                CKEDITOR.replace('description',
+                    {
+                        toolbar : 'Default',
+                        width : 570,
+                        height : 400,
+                        filebrowserImageBrowseUrl : '../../Toolkit/CKImages/browser.php?folder=1',
+                        filebrowserImageUploadUrl : '../../Toolkit/CKImages/connector.php?command=Upload',
+                                               filebrowserImageWindowWidth : '760',
+                                               filebrowserImageWindowHeight : '500'
+                    });
+            }
+        }
+    }
+};
+
+$(document).ready(MemberToolbox.init);
+</script>
+<?php
+if(defined("MULTIPLE_CAT") && MULTIPLE_CAT) {
+    echo     '<form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data" onSubmit="return(mySubmit(this));">';
+} else {
+    echo '
+    <script type="text/javascript">
+var mpos = 0;
+function getElementsByAttribute(attribute, attributeValue) {
+  var elementArray = new Array();
+  var matchedArray = new Array();
+
+  if (document.all) {
+    elementArray = document.all;
+  } else {
+    elementArray = document.getElementsByTagName("*");
+  }
+
+  for (var i = 0; i < elementArray.length; i++) {
+    if (attribute == "class") {
+      var pattern = new RegExp("(^| )" + attributeValue + "( |$)");
+
+      if (pattern.test(elementArray[i].className)) {
+        matchedArray[matchedArray.length] = elementArray[i];
+      }
+    } else if (attribute == "for") {
+      if (elementArray[i].getAttribute("htmlFor") || elementArray[i].getAttribute("for")) {
+        if (elementArray[i].htmlFor == attributeValue) {
+          matchedArray[matchedArray.length] = elementArray[i];
+        }
+      }
+    } else if (elementArray[i].getAttribute(attribute) == attributeValue) {
+      matchedArray[matchedArray.length] = elementArray[i];
+    }
+  }
+
+  return matchedArray;
+}
+function toSubmit() {
+    document.forms["myform"].submit();
+}
+</script>
+    <form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data">';
+}
+echo '<table id="admin-edit-table">';
+
+echo "<tr><th colspan=2>Pages:</th></tr>";
+if(isset($id) && $id != "") {
+        $qs = "SELECT     bc.id as catid, bcb.id as id,bc.category,bcb.pos
+        FROM     bus_category bc,bus_category_bus bcb,bus b
+        WHERE    bcb.busid = $id
+        AND         bcb.catid = bc.id
+        AND         b.id = bcb.busid
+        ORDER BY bc.category";
+
+        if(!$altres = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+        }
+
+        for($rel=0;$rel<$DB->db_numrows($altres);$rel++) {
+            $altrow = $DB->db_fetch_array($altres,$rel,PGSQL_ASSOC);
+            if( is_array( $oldalt ) ){
+                $oldalt[$rel] = array_merge_recursive($altrow,$oldalt);    
+            } else {
+                 $oldalt[$rel] = $altrow;    
+            }
+        }
+    }
+    ?>
+    <tr><td class="navtd" align="right">Page:</td>
+        <td>
+            <?php echo parent_select($catid,NULL,"catid[]");?>    
+            <?php $oldcatid = "";     
+            for($i=0;$i<$DB->db_numrows($altcats);$i++) {     
+                 $altrow = $DB->db_fetch_array($altcats,$i,PGSQL_ASSOC);     
+                 for($a=0;$a<count($oldalt);$a++) {     
+                    if(is_array($oldalt) && ($oldalt[$a]['catid'] == $altrow['id'])) {     
+                                 $oldcatid .= ":".$altrow['id'];     
+                    }     
+                 }     
+             }     
+
+     ?>
+        <?php if(defined("MULTIPLE_CAT") && MULTIPLE_CAT){?>
+        <input type="hidden" name="category" value="">
+        <?php }?>    
+        <input type="hidden" name="oldcatid" value="<?echo $catid?>">
+</td></tr>
+<?php 
+echo "<tr><td colspan=2><hr noshade></td></tr>";
+
+foreach($fields as $key=>$value) {
+    if($value['type'] == "text") {
+    ?>
+    <tr><td class="navtd" align="right"><?php echo $value['title']?></td>
+        <td><input name="<?php echo $value['name']?>" id="<?php echo $value['name']?>"
+            value="<?php echo htmlspecialchars($row[$value['name']])?>" size=40></td>
+    </tr>
+    <?php 
+    } elseif($value['type'] == "seperator") {
+        echo '<tr><td colspan="2"><hr noshade></td></tr>';
+        echo '<tr><td colspan="2" align="center"><b>'.$value["name"].'</b></td></tr>';
+    } elseif($value['type'] == "img") {
+        ?>
+        <tr></tr>
+        <?php 
+        echo "<input type=\"hidden\" name=\"old".$value['name']."\"
+        value=\"".$row[$value['name']]."\">";
+        if($row[$value['name']] != "") {
+            echo "<tr><td class=\"navtd2\" align=\"right\">Current Image:</td>";
+                echo "<td><img src=\"".MIDSIZED.$row[$value['name']]."\">
+                </td>
+            </tr>
+            <tr>
+                <td class=\"navtd2\" align=\"right\">Delete this image:</td>
+                <td>
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"1\">Yes
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"2\" CHECKED>No
+                </td>
+            </tr>";
+        }
+        echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+        echo "<td><input type=\"file\" name=\"".$value['name']."\"></td>";
+        echo "</tr>";
+    } elseif ($value['type'] == "file") {
+        ?>
+        <tr></tr>
+        <?
+        echo "<input type=\"hidden\" name=\"old".$value['name']."\"
+        value=\"".$row[$value['name']]."\">";
+        if($row[$value['name']] != "") {
+            echo "<tr><td class=\"navtd2\" align=\"right\">Current File:</td>";
+                echo "<td>".$row[$value['name']]."
+                </td>
+            </tr>
+            <tr>
+                <td class=\"navtd2\" align=\"right\">Delete this File:</td>
+                <td>
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"1\">Yes
+                    <input type=\"radio\" name=\"delete".$value['name']."\" value=\"2\" CHECKED>No
+                </td>
+            </tr>";
+        }
+        echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+            echo "<td><input type=\"file\" name=\"".$value['name']."\"></td>";
+            echo "</tr>";
+    }
+    if($value['type'] == "desc") {
+        echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td>";
+        echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$row[$value['name']].'</textarea></td>';
+        echo "</tr>";
+    } elseif($value['type'] == "hide") {
+        echo "<input type=\"hidden\" name=\"".$value['title']."\" 
+        value=\"".$row[$value['name']]."\">";
+    } elseif($value['type'] == "bool") {
+        echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td><td>";
+                echo '<label><input type="checkbox" name="'.$value['name'].'" value="t"'.($row[$value['name']]=='t'?' checked':'');
+                echo '>Yes</label>';
+                echo "</tr>";
+    }
+}
+echo '<tr>
+    <th colspan="2">File Uploads</th>
+    </tr>
+    ';
+if( is_numeric( $id ) ) {
+    echo '
+        <tr>
+            <td>Current Files:
+                <div style="width:100px;float:left;clear:both;background-color:#fff;border:solid 1px #000;">
+                To reposition the files use the drop down numbers to reposition them.
+                this updates the position of the files but any changes in filenames or updated files are not saved.
+                Make sure to reposition before making any other changes to files.            
+                </div>
+            </td>
+          <td>
+              <div id="file-uploads-data">
+                </div>
+              <div id="file-uploads">
+    ';
+echo '
+    </div>
+        </td>
+        </tr>
+    ';
+}
+echo '
+
+    <tr>
+       <td class="navtd" align="right">New File Upload:</td>
+      <td><input type="file" name="file"></td>
+    </tr>
+    <tr>
+       <td class="navtd" align="right">Name for link:</td>
+      <td><input name="filename"></td>
+    </tr>
+    ';
+echo '<input type="hidden" name="base_parent" value="'.$base_parent.'">';
+if(isset($id)) {
+    ?>
+    <tr><td colspan=2 align=center>
+        <input type="submit" name="Command" value="Update">
+        <input type="submit" name="Command" value="Cancel">
+        <input type="submit" name="Command" value="Delete" onClick="
+        if(confirm('This will delete this Listing!\n Are you sure?'))
+        return(true);
+        else 
+        return(false);
+        ">
+    </td>
+    <?php 
+} else {
+    GLM_TOOLBOX::form_footer("Insert","",2);
+}
+echo '</tr>
+</table>
+</form>
+
+';
+if( $id ) {
+    echo '<script type="text/javascript" src="jake-handler.js"></script>
+    <script type="text/javascript">
+    get_files('.$id.');
+    </script>
+    ';
+}
+
+GLM_TOOLBOX::footer();
+?>
+       
\ No newline at end of file
diff --git a/admin/Toolbox/edit_bus_category.phtml b/admin/Toolbox/edit_bus_category.phtml
new file mode 100755 (executable)
index 0000000..a1566af
--- /dev/null
@@ -0,0 +1,376 @@
+<?php
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+GLM_TOOLBOX::top2("Page (Add/Edit)", HELP_BASE."buscat.phtml?key=edit","ToolboxUserGuide_2.0");
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+// select parts used for putting fields together
+if (defined("TOOLBOX_REGIONS") && TOOLBOX_REGIONS) {
+    $select_part[] = "region";
+}
+if (defined("SHORT_URLS") && SHORT_URLS) {
+    // DO NOT use short_url for HOME_ID page
+    if (!$_REQUEST['id'] || ($_REQUEST['id'] && $_REQUEST['id'] != HOME_ID)) {
+        $select_part[] = "short_url";
+    }
+}
+if (defined("MEMBERS_DB") && MEMBERS_DB) {
+    $select_part[] = "include_member_map";
+    $select_part[] = "no_search_form";
+}
+if (defined("HOME_HEADLINES") && HOME_HEADLINES && $_REQUEST['id'] != HOME_ID) {
+    $select_part[] = "featured";
+    $select_part[] = "feature_intro";
+}
+$select_part[] = "category";
+$select_part[] = "intro";
+$select_part[] = "parent";
+$select_part[] = "description";
+$select_part[] = "image";
+$select_part[] = "imagename";
+$select_part[] = "keyword";
+$select_part[] = "template";
+$select_part[] = "pos";
+$select_part[] = "section_links";
+$select_part[] = "title";
+$select_part[] = "meta_descr";
+if (isset($id)) { 
+    if (is_array($select_part)) {
+        $selects = implode(",", $select_part);
+    }
+    $sql = "
+    SELECT id,$selects
+    FROM   bus_category
+    WHERE id = $id ";
+    if (!$res = $DB->db_exec($sql)) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG,1);
+    }
+    $row = $DB->db_fetch_array($res,0, PGSQL_ASSOC);
+    if (!$row[id]){
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG,1);
+    }
+} else {
+    if (is_array($select_part)) {
+        foreach ($select_part as $fieldrow) {
+            $row[$fieldrow] = ($fieldrow == 'template') ? "1": "";
+        }
+    }
+}
+if (defined("MEMBERS_DB") && MEMBERS_DB == 1) {
+    $memb_types_all = get_memb_all_types(&$DB);
+    if ($memb_data = get_memb_types(&$DB)) {
+        $member_sel = '<select id="memb_type" name="memb_type">';
+            $member_sel .= '<option value=""></option>';
+            foreach($memb_data as $memb_id => $memb_name) {
+                $member_sel .= '<option value="'.$memb_id.'">'.$memb_name.'</option>';
+            }
+            $member_sel .= '</select>';
+    }
+    if ($id) {
+        $query = "select * from bus_cat_member where catid = $id;";
+        if ($bcmData = $DB->db_auto_get_data($query)) {
+            foreach($bcmData as $bcmRow) {
+                $bus_cat_member_text .= '<div>';
+                $bus_cat_member_text .= '<a href="#" style="font-size:9pt;" onClick="$(this).parent().html(\'\');return false;">Delete</a>';
+                $bus_cat_member_text .= $memb_types_all[$bcmRow['memb_type']];
+                $bus_cat_member_text .= '<input type="hidden" name="member_cats[]" value="'.$bcmRow['memb_type'].'">';
+                $bus_cat_member_text .= '</div>';
+            }
+        }
+    }
+}
+echo '<script type="text/javascript" src="'.GLM_APP_BASE_URL.'ckeditor/current/ckeditor.js"></script>';
+echo '<form id="myForm" action="update_bus_category.phtml" method="POST" enctype="multipart/form-data">';
+echo '<table id="admin-edit-table">';
+if (defined("MEMBERS_DB") && MEMBERS_DB == 1) {
+    echo '<tr onclick="if ($(this).next().css(\'display\')==\'none\'){$(this).next().show();}else{$(this).next().hide();}return(false);">
+        <th colspan="2" style="background-color:#61614d;color:#ffffff;text-align:center;text-decoration:underline;cursor:pointer;">Link to Member Listing (click to show/hide)</th>
+    </tr>';
+    echo '<tr>';
+    echo '<td>Current Member-Links</td>';
+    echo '<td style="border:#61614d solid 1px;"><div id="list-members-info">'.$bus_cat_member_text.'</div></td>';
+    echo '</tr>';
+    echo '<tr>';
+    echo '<td>Link to Member Listing</td>';
+    echo '<td> <div id="add-member-area"><a style="float:right;" href="#" id="add-member">Add Member Link</a></div></td>';
+    echo '</tr>';
+}
+
+foreach ($row as $key => $value) {
+    switch ($key) {
+    // {{{ case "id":
+    case "id":
+        echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+        break;
+    // }}}
+    // {{{ case "pos":
+    case "pos":
+        echo "<input type=\"hidden\" name=\"oldpos\" value=\"$value\">";
+        break;
+    // }}}
+    // {{{ case "section_links":
+    case "section_links":
+    echo '<tr><td>Search</td>';
+        $output = '<label><input type="checkbox" name="section_links" value="t"';
+        if ($value == 't'){
+            $output .= ' checked';
+        }
+        $output .= '>Create a list of links to the paragraph headlines</label>';
+        echo '<td>'.$output.'</td>';
+        echo '</tr>';
+        break;
+    // }}}
+    // {{{ case "no_search_form":
+    case "no_search_form":
+    echo '<tr><td>Search</td>';
+        $output = '<label><input type="checkbox" name="no_search_form" value="t"';
+        if ($value == 't'){
+            $output .= ' checked';
+        }
+        $output .= '>No Search Required</label>';
+        echo '<td>'.$output.'</td>';
+        echo '</tr>';
+        break;
+    // }}}
+    // {{{ case "include_member_map":
+    case "include_member_map":
+    echo '<tr><td>Map</td>';
+        $output = '<label><input type="checkbox" name="include_member_map" value="t"';
+        if ($value == 't'){
+            $output .= ' checked';
+        }
+        $output .= '>Include Member Map On Page</label>';
+        echo '<td>'.$output.'</td>';
+        echo '</tr>';
+        break;
+    // }}}
+    // {{{ case "featured":
+    case "featured":
+        echo '<tr><td>Home Page Headlines</td>';
+        $output = '<label><input type="checkbox" name="featured" value="t"';
+        if ($value == 't'){
+            $output .= ' checked';
+        }
+        $output .= '> Home Page Headlines</label><br clear="all">';
+        $output .= '<table>
+            <tr><td>Headline&nbsp;Intro:</td>';
+        $output .= '<td><input size="35" id="feature_intro" 
+                name="feature_intro" value="'.htmlspecialchars($row['feature_intro']).'"></td>';
+        $output .= '</tr>
+            </table>';
+        echo '<td>'.$output.'</td>';
+        echo '</tr>';
+        break;
+    // }}}
+    // {{{ case "feature_intro":
+    case "feature_intro":
+        break;
+    // }}}
+    // {{{ case "parent":
+    case "parent":
+        echo "<tr><td>
+            <input type=\"hidden\" name=\"oldparent\" value=\"$value\">
+            Parent&nbsp;Page:</td>";
+        $output = parent_select($value,$id);
+        echo "<td>".$output."</td>";
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "category":
+    case "category":
+        echo "<tr><td>Navigation&nbsp;Name:</td>";
+        GLM_TOOLBOX::text_box("category",$value);
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "imagename":
+    case "imagename":
+        echo "<tr><td>Image&nbsp;Caption:</td>";
+        GLM_TOOLBOX::text_box("imagename",$value);
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "intro":
+    case "intro":
+        echo "<tr><td>Page&nbsp;Title:</td>";
+        GLM_TOOLBOX::text_box("intro",$value);
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "image":
+    case "image":
+        echo "<tr><td>Current&nbsp;Image:</td>";
+        echo "<td>
+            <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+        if ($value != "") {
+            echo "<img src=\"".MIDSIZED."$value\">
+            </td>
+            <tr>
+                <td >Delete this image:</td>
+                <td>
+                    <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+                    <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+                </td>
+            </tr>";
+        }
+        echo "<tr><td>
+                New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+        break;
+    // }}}
+    // {{{ case "description":
+    case "description":
+        echo "<tr><td>Description:</td>";    
+        echo '<td><textarea name="description" id="description" cols="60" rows="60">'.$value.'</textarea></td>';
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "keyword":
+    case "keyword":
+        echo "<tr><td><font color=red>Keyword:</font></td>";    
+        GLM_TOOLBOX::text_box("keyword",$value);        
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ case "short_url":
+    case "short_url":
+        echo '<tr>
+        <td>Short URL:</td>
+        <td>'.BASE_URL.'<input name="short_url" value="'.$row['short_url'].'">/<br>
+            NOTE:  Short URL\'s Must not contain any spaces or non alpha characters.<br>
+            Only a-z 0-9 _(underscore) -(dash) allowed.
+        </td>
+        </tr>';
+        break;
+    // }}}
+    // {{{ case "template":
+    case "template":
+        echo "<tr><td>Templates:</td>";    
+        echo '<td>
+            <table style="padding:5px;margin:0;border:none;">
+                ';
+        echo '<tr>';
+        for($i = 1; $i <= 6; ++$i):
+            echo '
+            <th>Template'.$i.'</th>
+            ';
+        endfor;
+        echo '</tr>
+        ';
+        echo '<tr>';
+        for($i = 1; $i <= 6; ++$i):
+            echo '
+            <td><label for="temp'.$i.'"><img src="../template'.$i.'.gif"></label></td>
+            ';
+        endfor;
+        echo '</tr>
+        ';
+        echo '<tr>';
+        for($i = 1; $i <= 6; ++$i):
+            echo '
+            <td>'.$i.'<input type="radio" id="temp'.$i.'" name="template" value="'.$i.'"'.(($value == $i) ? 'checked':'').'></td>
+            ';
+        endfor;
+        echo '</tr>
+                </table>
+            </td>
+        </tr>';
+        break;
+    // }}}
+    // {{{ case "title":
+    case "title":
+        if ((GLM_HOST_ID == 'PRODUCTION' && $_SERVER['PHP_AUTH_USER'] == 'MediaAdmin')
+               || GLM_HOST != 'PRODUCTION') {
+            echo "<tr><td>Title Tag:</td>";
+            GLM_TOOLBOX::text_box("title", $value);
+            echo "</tr>";
+        } else {
+            echo '<input type="hidden" name="meta_descr" value="'.htmlspecialchars($value).'">';
+        }
+        break;
+    // }}}
+    // {{{ case "meta_descr":
+    case "meta_descr":
+       if ((GLM_HOST_ID == 'PRODUCTION' && $_SERVER['PHP_AUTH_USER'] == 'MediaAdmin')
+               || GLM_HOST != 'PRODUCTION') {
+            echo '<tr>
+                <td valign="top">Meta&nbsp;Description:</td>
+                <td>
+                    <textarea name="meta_descr" cols="40" rows="5">'.htmlspecialchars($value).'</textarea>
+                </td>
+              </tr>';
+        } else {
+            echo '<input type="hidden" name="meta_descr" value="'.htmlspecialchars($value).'">';
+        }
+        break;
+    // }}}
+    // {{{ case "region":
+    case "region":
+        $regionsArray[''] = '-- Counties --';
+        $sql = "
+        SELECT *
+          FROM region
+      ORDER BY region_name";
+        try {
+            $stmt = $dbh->query($sql);
+            while ($regionRow = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                if (!is_numeric($regionRow['region_name'])) {
+                    $regionsArray[$regionRow['region_id']] = $regionRow['region_name'];
+                }
+            }
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        echo "<tr><td>Counties:</td>";    
+        echo '<td>'.GLM_TOOLBOX::build_picklist('region', $regionsArray, $value).'</td>';
+        echo "</tr>";
+        break;
+    // }}}
+    // {{{ default:
+    default:
+        GLM_TOOLBOX::html_error("Incorrect Value -> ".$key,1);
+        break;
+    // }}}
+    }
+}
+echo '<script type="text/javascript" src="./cktoolbox.js"></script>';
+if (defined("MEMBERS_DB") && MEMBERS_DB == 1) {
+    echo '<script type="text/javascript" src="./member-toolbox.js"></script>';
+}
+if (isset($id)) {
+    $qs = "SELECT     count(*) as count
+    FROM     bus_category_bus
+    WHERE    catid = $id";
+
+    if (!$res = $DB->db_exec($qs)) {
+        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+    }
+
+    $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+    echo '<tr><td colspan=2>
+            <input type="submit" name="Command" value="Update">
+            <input type="submit" name="Command" value="Cancel">
+            ';
+    if (defined("CAT_LOCK") && !CAT_LOCK && !check_lock($id)) {        
+        echo '
+        <input type="submit" name="Command" value="Delete" onClick="';
+        if ($row[count] == 0) {
+            echo '
+            if (confirm(\'This will delete this category!\n Are you sure?\'))
+            return(true);
+            else 
+            return(false);
+            ';
+        } else {
+            echo 'alert(\'You have to remove any records in\n this category first\');
+            return(false);
+            ';
+        }
+        echo '">
+        ';
+    }
+    echo '</td></tr>';
+} else {
+    GLM_TOOLBOX::form_footer("Insert", "", 2);
+}
+echo "</table></form>";
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Toolbox/expand.png b/admin/Toolbox/expand.png
new file mode 100755 (executable)
index 0000000..38dcfc0
Binary files /dev/null and b/admin/Toolbox/expand.png differ
diff --git a/admin/Toolbox/export-images-is0.php b/admin/Toolbox/export-images-is0.php
new file mode 100755 (executable)
index 0000000..9c795ee
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'Toolkit/Image/Server.php';
+$db = new PDO('pgsql:'.CONN_STR);
+define('OLDORG', 'http://www.brewbakers.com/images/uploads/original/');
+$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
+$sql = "
+SELECT id,image
+FROM bus_category
+WHERE image != ''
+ORDER BY id";
+//$sql .= " LIMIT 1 OFFSET 0";
+$pre1 = "
+SELECT id,image
+FROM bus
+WHERE image != ''";
+//$pre1 .= " LIMIT 1 OFFSET 0";
+try {
+    $stmt  = $db->query($sql);
+    $data  = $stmt->fetchAll(PDO::FETCH_ASSOC);
+    $stmt2 = $db->query($pre1);
+    $data2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
+    echo '<pre>';
+    print_r($data);
+    print_r($data2);
+    echo '</pre>';
+} catch(PDOException $e) {
+    die($e->getMessage());
+}
+$db->beginTransaction();
+$IServer = new Toolkit_Image_Server();
+if (is_array($data)) {
+    $prep2 = "
+    UPDATE bus_category
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt3 = $db->prepare($prep2);
+
+    foreach ($data as &$row) {
+        $image_URL = OLDORG.$row['image'];
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt3->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt3->bindParam(":id", $row['id'], PDO::PARAM_INT);
+                $stmt3->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+if (is_array($data2)) {
+    $prep3 = "
+    UPDATE bus
+    SET    image = :image
+    WHERE  id = :id";
+    $stmt4 = $db->prepare($prep3);
+    foreach ($data2 as &$row2) {
+        echo '<pre>'.print_r($row2, true).'</pre>';
+        if (preg_match("/^is/",$row2['image'])) {
+            continue;
+        }
+        $image_URL = OLDORG.$row2['image'];
+        echo '<pre>'.print_r($image_URL, true).'</pre>';
+        $image = $IServer->imageUpload($image_URL);
+        if ($image) {
+            try {
+                $stmt4->bindParam(":image", $image, PDO::PARAM_STR);
+                $stmt4->bindParam(":id", $row2['id'], PDO::PARAM_INT);
+                $stmt4->execute();
+            } catch(PDOException $e) {
+                die($e->getMessage());
+            }
+        }
+        echo '<br>Image Name Returned: ';
+        var_dump($image);
+    }
+}
+$db->commit();
+//$db->rollBack();
+?>
diff --git a/admin/Toolbox/file-repos-xml.php b/admin/Toolbox/file-repos-xml.php
new file mode 100644 (file)
index 0000000..1d947bf
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+header("Content-Type: text/plain\n");
+Header('Cache-Control: no-cache');
+Header('Pragma: no-cache');
+include_once("../../setup.phtml");
+include_once("toolbox_setup.inc");
+$DB->db_exec( "BEGIN WORK;" );
+if( $_GET['oldpos'] < $_GET['newpos'] )
+{
+       $query = "update files 
+               set pos = pos - 1 
+               where bus_id = ".$_GET['busid']." 
+               and pos > ".$_GET['oldpos']."
+               and pos <= ".$_GET['newpos']." ";
+       $DB->db_exec( $query );
+       $DB->db_exec( "update files set pos = ".$_GET['newpos']." where id = ".$_GET['id'] );
+}
+else
+{
+       $query = "update files 
+               set pos = pos + 1 
+               where bus_id = ".$_GET['busid']." 
+               and pos >= ".$_GET['newpos']."
+               and pos < ".$_GET['oldpos']." ";
+       $DB->db_exec( $query );
+       $DB->db_exec( "update files set pos = ".$_GET['newpos']." where id = ".$_GET['id'] );
+}
+$DB->db_exec( "COMMIT WORK;" );
+?>
diff --git a/admin/Toolbox/file-xml.php b/admin/Toolbox/file-xml.php
new file mode 100644 (file)
index 0000000..f54c5f8
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+header("Content-Type: text/plain\n");
+header('Cache-Control: no-cache');
+header('Pragma: no-cache');
+include_once("../../setup.phtml");
+include_once("toolbox_setup.inc");
+$out = '';
+$query = "select * from files where bus_id = ".$_GET['id']." order by pos;";
+if( $file_data = $DB->db_auto_get_data( $query ) )
+{
+       $total = count( $file_data );
+       for( $i = 1; $i <= $total; $i++ )
+       {
+               $poses[$i] = $i;
+       }
+       foreach( $file_data as $file_row )
+       {
+               $filename = ($file_row['urltext']) ? $file_row['urltext']: $file_row['filename'];
+               $out .= '<div class="fileupload">
+                       <p><strong>File '.$file_row["pos"].':</strong>
+                       <!--<button class="file-edit-button" id="edit-file-'.$file_row['id'].'">Edit</button>-->
+                       <input type="hidden" name="oldfile['.$file_row['id'].']" value="'.$file_row['filename'].'">
+                       <a target="_blank" href="'.BASE_URL.'uploads/'.$file_row['filename'].'">'.$filename.'</a></p>';
+               $out .= '<div id="file-edit-div-'.$file_row['id'].'" class="file_div" ><br clear="all">';
+               if( is_array( $poses ) )
+               {
+                       $out .= '<input type="hidden" name="filename_poshide'.$file_row["id"].'" value="'.$file_row["pos"].'">
+                       <select onChange="update_file_pos( '.$_GET["id"].', '.$file_row["id"].', '.$file_row["pos"].', this.options[this.selectedIndex].value );" name="filename_pos['.$file_row["id"].']" class="filepos">';
+                       foreach( $poses as $posval )
+                       {
+                               $out .= '<option value="'.$posval.'"'.(($posval == $file_row["pos"])?"selected":"").'>'.$posval.'</option>';
+                       }
+                       $out .= '</selected>';
+               }
+               $out .= '
+                               <br clear="all"><strong>File: </strong>
+               '.$file_row['filename'].' ('.$file_row['bytes'].' bytes)<br>
+               <strong>Update File: </strong>
+               <input type="file" name="file_new['.$file_row['id'].']"><br>
+               <strong>File URL text: </strong>
+               <input name="filename_urltext['.$file_row['id'].']" value="'.$file_row['urltext'].'" size="50">
+               <br>
+               <label>
+                 <strong>Delete: </strong>
+                 <input type="checkbox" id="'.$file_row['filename'].'" name="delete[]" value="'.$file_row['id'].'"> Yes
+               </label>
+               </div>
+       </div><br clear="all">
+       <script type="text/javascript">
+               var button_'.$file_row['id'].' = document.getElementById(\'edit-file-'.$file_row['id'].'\');
+               button_'.$file_row['id'].'.onclick = function()
+               {
+                       document.getElementById(\'file-edit-div-'.$file_row['id'].'\').style.display = \'block\';
+                       return( false );
+               }
+       </script>';
+       }
+}
+echo $out;
+?>
diff --git a/admin/Toolbox/file_load.js b/admin/Toolbox/file_load.js
new file mode 100644 (file)
index 0000000..6192717
--- /dev/null
@@ -0,0 +1,5 @@
+function add_file()
+{
+       var myForm = document.getElementById('myForm');
+       var newFile = document.createElement('fileUpload');
+}
diff --git a/admin/Toolbox/files.sql b/admin/Toolbox/files.sql
new file mode 100644 (file)
index 0000000..b148ca5
--- /dev/null
@@ -0,0 +1,63 @@
+--
+-- PostgreSQL database dump
+--
+
+SET client_encoding = 'SQL_ASCII';
+SET check_function_bodies = false;
+
+SET SESSION AUTHORIZATION 'postgres';
+
+SET search_path = public, pg_catalog;
+
+--
+-- TOC entry 3 (OID 15572607)
+-- Name: files; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE files (
+    id serial NOT NULL,
+    filename text,
+    bytes integer,
+    "type" text,
+    urltext text,
+    bus_id integer,
+       pos integer DEFAULT >= 1
+);
+
+
+--
+-- TOC entry 4 (OID 15572607)
+-- Name: files; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE files FROM PUBLIC;
+GRANT ALL ON TABLE files TO nobody;
+
+
+--
+-- TOC entry 5 (OID 15572607)
+-- Name: files_id_seq; Type: ACL; Schema: public; Owner: postgres
+--
+
+REVOKE ALL ON TABLE files_id_seq FROM PUBLIC;
+GRANT ALL ON TABLE files_id_seq TO nobody;
+
+
+--
+-- TOC entry 6 (OID 15572613)
+-- Name: files_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY files
+    ADD CONSTRAINT files_pkey PRIMARY KEY (id);
+
+
+--
+-- TOC entry 7 (OID 15572619)
+-- Name: $1; Type: FK CONSTRAINT; Schema: public; Owner: postgres
+--
+
+ALTER TABLE ONLY files
+    ADD CONSTRAINT "$1" FOREIGN KEY (bus_id) REFERENCES bus(id) ON DELETE CASCADE;
+
+
diff --git a/admin/Toolbox/htmlarea.css b/admin/Toolbox/htmlarea.css
new file mode 100644 (file)
index 0000000..23bdf7d
--- /dev/null
@@ -0,0 +1,180 @@
+.htmlarea { background: #fff; }
+
+.htmlarea .toolbar {
+  cursor: default;
+  background: ButtonFace;
+  padding: 1px 1px 2px 1px;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar table { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+.htmlarea .toolbar img { border: none; }
+.htmlarea .toolbar .label { padding: 0px 3px; }
+
+.htmlarea .toolbar .button {
+  background: ButtonFace;
+  color: ButtonText;
+  border: 1px solid ButtonFace;
+  padding: 1px;
+  margin: 0px;
+}
+.htmlarea .toolbar .buttonHover {
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar .buttonActive, .htmlarea .toolbar .buttonPressed {
+  padding: 2px 0px 0px 2px;
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+.htmlarea .toolbar .buttonPressed {
+  background: ButtonHighlight;
+}
+.htmlarea .toolbar .indicator {
+  padding: 0px 3px;
+  overflow: hidden;
+  width: 20px;
+  text-align: center;
+  cursor: default;
+  border: 1px solid ButtonShadow;
+}
+
+.htmlarea .toolbar .buttonDisabled { background-color: #aaa; }
+
+.htmlarea .toolbar .buttonDisabled img {
+  filter: alpha(opacity = 25);
+  -moz-opacity: 25%;
+}
+
+.htmlarea .toolbar .separator {
+  position: relative;
+  margin: 3px;
+  border-left: 1px solid ButtonShadow;
+  border-right: 1px solid ButtonHighlight;
+  width: 0px;
+  height: 16px;
+  padding: 0px;
+}
+
+.htmlarea .toolbar .space { width: 5px; }
+
+.htmlarea .toolbar select { font: 11px Tahoma,Verdana,sans-serif; }
+
+.htmlarea .toolbar select,
+.htmlarea .toolbar select:hover,
+.htmlarea .toolbar select:active { background: FieldFace; color: ButtonText; }
+
+.htmlarea .statusBar {
+  border: 1px solid;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+  padding: 2px 4px;
+  background-color: ButtonFace;
+  color: ButtonText;
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.htmlarea .statusBar .statusBarTree a {
+  padding: 2px 5px;
+  color: #00f;
+}
+
+.htmlarea .statusBar .statusBarTree a:visited { color: #00f; }
+.htmlarea .statusBar .statusBarTree a:hover {
+  background-color: Highlight;
+  color: HighlightText;
+  padding: 1px 4px;
+  border: 1px solid HighlightText;
+}
+
+
+/* Hidden DIV popup dialogs (PopupDiv) */
+
+.dialog {
+  color: ButtonText;
+  background: ButtonFace;
+}
+
+.dialog .content { padding: 2px; }
+
+.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table {
+  font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.dialog table { border-collapse: collapse; }
+
+.dialog .title {
+  background: #008;
+  color: #ff8;
+  border-bottom: 1px solid #000;
+  padding: 1px 0px 2px 5px;
+  font-size: 12px;
+  font-weight: bold;
+  cursor: default;
+}
+
+.dialog .title .button {
+  float: right;
+  border: 1px solid #66a;
+  padding: 0px 1px 0px 2px;
+  margin-right: 1px;
+  color: #fff;
+  text-align: center;
+}
+
+.dialog .title .button-hilite { border-color: #88f; background: #44c; }
+
+.dialog button {
+  width: 5em;
+  padding: 0px;
+}
+
+.dialog .buttonColor {
+  padding: 1px;
+  cursor: default;
+  border: 1px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.dialog .buttonColor-hilite {
+  border-color: #000;
+}
+
+.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor {
+  height: 0.6em;
+  border: 1px solid;
+  padding: 0px 1em;
+  border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.dialog .buttonColor .nocolor { padding: 0px; }
+.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }
+
+.dialog .label { text-align: right; width: 6em; }
+.dialog .value input { width: 100%; }
+.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; }
+
+.dialog legend { font-weight: bold; }
+.dialog fieldset table { margin: 2px 0px; }
+
+.popupdiv {
+  border: 2px solid;
+  border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.popupwin {
+  padding: 0px;
+  margin: 0px;
+}
+
+.popupwin .title {
+  background: #fff;
+  color: #000;
+  font-weight: bold;
+  font-size: 120%;
+  padding: 3px 10px;
+  margin-bottom: 10px;
+  border-bottom: 1px solid black;
+  letter-spacing: 2px;
+}
+
+form { margin: 0px; border: none; }
diff --git a/admin/Toolbox/images/collapse.png b/admin/Toolbox/images/collapse.png
new file mode 100755 (executable)
index 0000000..d10e051
Binary files /dev/null and b/admin/Toolbox/images/collapse.png differ
diff --git a/admin/Toolbox/images/expand.png b/admin/Toolbox/images/expand.png
new file mode 100755 (executable)
index 0000000..38dcfc0
Binary files /dev/null and b/admin/Toolbox/images/expand.png differ
diff --git a/admin/Toolbox/index.phtml b/admin/Toolbox/index.phtml
new file mode 100755 (executable)
index 0000000..550afb8
--- /dev/null
@@ -0,0 +1,3 @@
+<?
+header("Location: list_bus_category.phtml");
+?>
diff --git a/admin/Toolbox/jake-handler.js b/admin/Toolbox/jake-handler.js
new file mode 100644 (file)
index 0000000..efd60c1
--- /dev/null
@@ -0,0 +1,49 @@
+function getHTTPObject()
+{
+   var http = false;
+
+   if (window.XMLHttpRequest) { // Mozilla, Safari,...
+       http = new XMLHttpRequest();
+       if (http.overrideMimeType) {
+           http.overrideMimeType('text/html');
+       }
+   } else if (window.ActiveXObject) { // IE
+       try {
+           http = new ActiveXObject("Msxml2.XMLHTTP");
+       } catch (e) {
+           try {
+               http = new ActiveXObject("Microsoft.XMLHTTP");
+           } catch (e) {}
+       }
+   } 
+       return http; 
+} 
+function get_files( id )
+{
+       var http = getHTTPObject(); // We create the HTTP Object
+       var url = "file-xml.php?id=" + id + "&ms=";
+       http.open("GET", url + "&ms=" + new Date().getTime(),true);
+       http.onreadystatechange = function()
+       {
+               if(http.readyState == 4)
+               {
+                       document.getElementById('file-uploads').innerHTML = http.responseText;
+               }
+       }
+       http.send(null);
+}
+function update_file_pos( busid, id, oldpos, newpos )
+{
+       var http = getHTTPObject(); // We create the HTTP Object
+       var url = "file-repos-xml.php?busid=" + busid + "&id=" + id + "&oldpos=" + oldpos + "&newpos=" + newpos;
+       http.open("GET", url + "&ms=" + new Date().getTime(),true);
+       http.onreadystatechange = function()
+       {
+               if(http.readyState == 4)
+               {
+                       document.getElementById('file-uploads-data').innerHTML = http.responseText;
+                       get_files( busid );
+               }
+       }
+       http.send(null);
+}
diff --git a/admin/Toolbox/list_bus.phtml b/admin/Toolbox/list_bus.phtml
new file mode 100755 (executable)
index 0000000..d3f3974
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+include_once "../../setup.phtml";
+include_once 'toolbox_setup.inc';
+$qs = "SELECT  category
+               FROM    bus_category
+               WHERE   id = $catid";
+if(!$catres = $DB->db_exec($qs)) 
+{
+       GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+}
+$catrow = $DB->db_fetch_array($catres,0,PGSQL_ASSOC);
+$qs =  "SELECT         b.id,b.name,bcb.pos
+               FROM    bus b,bus_category_bus bcb
+           WHERE       bcb.catid = $catid
+               AND             b.id = bcb.busid
+               AND             bcb.catid = $catid
+               ORDER BY bcb.pos";
+if(!$res = $DB->db_exec($qs)) 
+{
+       GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+}
+GLM_TOOLBOX::top("$catrow[category] Paragraphs", HELP_BASE."bus.phtml?key=list","ToolboxUserGuide_2.0");
+$toolbox_nav["Add New Paragraph"] = "edit_bus.phtml?catid=$catid";
+unset($toolbox_nav["Add A New Page"]);
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+echo '<form action="update_bus.phtml" method="POST">
+<table id="admin-list-table">
+<tr>
+<th> Function </th>
+<th> Records </th>
+</tr>';
+for($i = 0; $i < $DB->db_numrows($res); $i++) 
+{
+       $row = $DB->db_fetch_array($res,$i, PGSQL_ASSOC); 
+       echo '<tr>
+       <td class="navtd2" nowrap="nowrap">
+       <a href="edit_bus.phtml?id='.$row["id"].'&catid='.$catid.'">[Edit]</a>';
+       $qs = "SELECT   MAX(bus_category_bus.pos) as maxpos 
+                  FROM         bus LEFT OUTER JOIN bus_category_bus ON (bus.id = bus_category_bus.busid) 
+                  WHERE        bus_category_bus.catid = $catid;";
+       if(!$maxresult = $DB->db_exec($qs)) 
+       {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+       }
+       $max_data = $DB->db_fetch_array($maxresult,0,PGSQL_ASSOC);
+       $maxpos = $max_data[maxpos];
+       $qs = "SELECT   bcb.id
+                  FROM         bus_category_bus bcb,bus b 
+                  WHERE        bcb.catid = $catid
+                  AND          b.id = bcb.busid
+                  AND          b.id = $row[id]
+                  AND          bcb.busid = b.id
+                  ";
+
+       if(!$idres = $DB->db_exec($qs)) 
+       {
+               GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+       }
+       $idrow = $DB->db_fetch_array($idres,0,PGSQL_ASSOC);
+       $pos = '<select name="pos" style="font-size:12px;" onChange="location.href=this[this.selectedIndex].value;" size="1">';
+       for($newpos=1;$newpos<=$maxpos;$newpos++) 
+       {
+               $string = "Command=Move&id=$idrow[id]&newpos=$newpos&catid=$catid";
+               $pos .= "<option value=\"update_bus.phtml?$string\"";
+               if($newpos == $row[pos]) 
+               {
+                       $pos .= " selected";
+               }
+               $pos .= ">$newpos\n";
+       }
+       $pos .= "</select>";
+       echo $pos;
+       echo '</td>
+       <td class="navtd2" width="80%">'.$row["name"].'</td>
+       </tr>';
+}
+echo '</table>
+</form>';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Toolbox/list_bus_category.phtml b/admin/Toolbox/list_bus_category.phtml
new file mode 100755 (executable)
index 0000000..e0f927e
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+session_start();
+session_register("expanded");
+if( is_numeric( $_GET['expand'] ) ) {
+       // code for adding expanded 
+       $expanded[$_GET['expand']] = $_GET['expand'];
+}
+if( is_numeric( $fold ) ) {
+       // code for folding 
+       $oldexp = $expanded;
+       session_unregister("expanded");
+       unset($oldexp[$fold]);
+       $expanded = $oldexp; 
+       session_register("expanded");
+}
+require_once "../../setup.phtml";
+require_once BASE."classes/class_toolbox.inc";
+require_once "toolbox_setup.inc";
+GLM_TOOLBOX::top("Pages (List)",HELP_BASE."buscat.phtml?key=list","ToolboxUserGuide_2.0");
+echo '<div id="toolbox-list-cat">';
+if(isset($active)) {
+       if($active=="t") {
+               $nd = "f";
+       } else {
+               $nd = "y";
+       }
+       $query = "UPDATE bus_category SET active = '$nd' WHERE id = $id";
+       $DB->db_exec($query);
+       GLM_TOOLBOX::create_sitemap();
+    $toolbox->cache->clean('Nav');
+}
+$toolbox_nav["Edit Positions"] = "list_bus_category.phtml?show_pos=1";
+$toolbox_nav["Expand All"] = "list_bus_category.phtml?expand_all=1";
+$toolbox_nav["Collapse All"] = "list_bus_category.phtml?collaspe_all=1";
+GLM_TOOLBOX::html_nav_table($toolbox_nav, 6);
+echo '<table id="admin-list-table" style="width:700px;">
+       <tr>
+               <td>
+                       <form name="search_form" action="'.$PHP_SELF.'">
+                               <input name="cat_search" value="'.stripslashes($cat_search).'">
+                               <input type="submit" name="Command" value="Search Pages">
+                       </form>
+               </td>
+       </tr>
+       <tr><td>
+<form action="update_bus_category.phtml" method="POST">
+';
+include_once("threads.phtml");
+if( !isset( $cat_search ) || $cat_search == '' ) {
+       $qs = "SELECT   id,parent,pos,category,active,keyword
+       FROM    bus_category
+       WHERE   parent is not null
+       ORDER BY pos;";
+
+       if(!$res = $DB->db_exec($qs)) {
+               echo "Failure".$qs;
+       }
+       for($i=0;$i<pg_numrows($res);$i++) {
+               $data = pg_fetch_array($res,$i,PGSQL_ASSOC);
+               $id = $data[id];
+               $category = $data["category"];
+               if( $data['keyword'] != '' ){ 
+                       $category .= " {".$data['keyword']."}";
+               }
+               $parent = $data['parent'];
+               $position = $data['pos'];
+               if(TOOLBOX_FLAGS == 1 && $data['id']!=HOME_ID) {
+                       if($data['active'] == 't') {
+                               $alt = "Don't display";
+                       } else {
+                               $alt = "Display";
+                       }
+                       $active = '<a title="'.$alt.'" href="'.$PHP_SELF."?active=$data[active]&id=$data[id]".'">';
+                       if($data['active'] == "t") {
+                               $active .= "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0></a>";
+                       } else {
+                               $active .= "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0></a>";
+               }
+       } elseif($data['id']==HOME_ID) {
+               $active = "&nbsp;";
+       }
+       if($show_pos && !in_array($id,$category_locks)) {
+               $qs = "SELECT   MAX(pos) as maxpos
+               FROM    bus_category
+               WHERE   parent = $parent";
+
+               if(!$maxresult = $DB->db_exec($qs)) {
+                       GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+               }
+               $max_data = $DB->db_fetch_array($maxresult,0,PGSQL_ASSOC);
+               $maxpos = $max_data['maxpos'];
+               $pos = '<select style="font-size:12px;" name="pos" onChange="location.href=this[this.selectedIndex].value;" size="1">';
+               $starting = 1;//( $parent == 0 ) ? 14: 1;
+               for($newpos=$starting;$newpos<=$maxpos;$newpos++) {
+                       $string = "Command=Move&id=$id&parent=$parent&newpos=$newpos";
+                       $pos .= "<option value=\"update_bus_category.phtml?$string\"";
+                       if($newpos == $position) {
+                               $pos .= " selected";
+                       }
+                       $pos .= ">$newpos\n";
+               }
+               $pos .= "</select>";
+       }elseif($show_pos){
+               $pos = '';
+       }
+       if( $expand_all == true ) {
+               $close = false;
+               $expanded[$id] = 1;
+       }
+       if( $collaspe_all == true ) {
+               $close = true;
+               unset($expanded[$id]);
+       }
+       if( $expanded[$id] ) {
+               $close = false;
+       } else {
+               $close = true;
+       }
+       $url = $toolbox->get_seo_url( $id );
+       $threads[] = array("ID" => $id,"content" => $category,"pos" => $pos,"parent" =>
+       $parent,"active" => $active,"closed" => $close,'seo_url'=>$url);
+}
+//$links = array( "beginLevel" => "<ul>", "beginLevel2" => "<ul id=\"toolbox\">", "endLevel" => "</ul>", "beginItem" => "<li>", "beginItem2" => "<li class=\"toolboxArrow\">", "endItem" => "</li>");
+               if($DB->db_numrows($res) != 0) {
+                       $myThread = new toolbox_thread(); 
+                       $converted = $myThread->sortChilds($threads); //sort threads by parent
+                       print $myThread->convertToThread($converted, $converted[0]); //print the threads
+               }
+       } else {
+               $toolbox =& new GLM_TEMPLATE( NULL );
+               $query = "select * from bus_category where category ilike '%$cat_search%';";
+               //echo $query;
+               $res = $DB->db_exec( $query );
+               if( pg_numrows( $res ) > 0 ) {
+                       echo '<ul id="toolbox">';
+                       while( $row = pg_fetch_object( $res ) ) {
+                               if(TOOLBOX_FLAGS == 1) {
+                                       if($row->active == 't') {
+                                               $alt = "Don't display";
+                                       } else {
+                                               $alt = "Display";
+                                       }
+                                       $active = '<a title="'.$alt.'" href="'.$PHP_SELF.'?cat_search='.urlencode(stripslashes($cat_search)).'&amp;active='.$row->active.'&id='.$row->id.'">';
+                                       if( $row->id == HOME_ID ) {
+                                               $active = '';
+                                       } elseif($row->active == "t") {
+                                               $active .= "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0></a>";
+                                       } else {
+                                                       $active .= "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0></a>";
+                                       }
+                               }
+                               $url = $toolbox->get_seo_url( $row->id );
+                               $params = "&amp;cat_search=".urlencode(stripslashes($cat_search));
+                               echo '<li>
+                               <a href="edit_bus_category.phtml?id='.$row->id.$params.'">[Edit]</a>
+                               <a href="list_bus.phtml?catid='.$row->id.$params.'">[Paragraphs]</a>
+                               <a href="'.$url.'" target="_BLANK">[Preview]</a>
+                               '.$active.'
+                               <strong>'.strip_tags($row->category);
+                               if( $row->keyword != '' ){
+                                       echo ' {'.$row->keyword.'}';
+                               }
+                               echo '</strong>
+                               </li>';
+                       }
+                       echo '</ul>';
+       } else {
+               echo 'Nothing found!';
+       }
+}
+echo '
+       </form>
+               </td></tr>
+       </table>
+</div>';
+GLM_TOOLBOX::footer();
+?>
diff --git a/admin/Toolbox/member-code-line.php b/admin/Toolbox/member-code-line.php
new file mode 100644 (file)
index 0000000..6d4a5f2
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'classes/class_db.inc';
+$DB = new GLM_DB();
+if( $_REQUEST['category_id'] ){
+       $query = "select * from category where category_id = ".$_REQUEST['category_id'];
+       if( $data = $DB->pgsql_select( $query ) ){
+               $out = '<div>';
+               $out .= '<a href="3" onclick="$(this).parent().html(\'\');return false;">Delete</a>&nbsp;';
+               $out .= $data[0]['class_code'].' '.$data[0]['name'];
+               $out .= '<input type="hidden" name="member_cats[]" value="'.$data[0]['category_id'].'">';
+               $out .= '</div>';
+       }
+}
+echo $out;
+?>
diff --git a/admin/Toolbox/member-code-query.php b/admin/Toolbox/member-code-query.php
new file mode 100644 (file)
index 0000000..744b82a
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+require_once '../../setup.phtml';
+require_once BASE.'classes/class_db.inc';
+$DB = new GLM_DB();
+$query = "select * 
+from category 
+where parent_id = 0
+order by name";
+if( $data = $DB->pgsql_select( $query ) ){
+       $out = '<div class="buttons">';
+       $out .= '<select name="newCategory" id="newCategory" style="width:360px">';
+       foreach( $data as $row ){
+               $out .= '<option value="'.$row['category_id'].'" class="level-0">'.$row['name'].'</option>';
+               $query = "select * 
+                       from category 
+                       where parent_id = ".$row['category_id']." 
+                       order by name";
+               if( $data2 = $DB->pgsql_select( $query ) ){
+                       foreach( $data2 as $row2 ){
+                               $out .= '<option value="'.$row2['category_id'].'" class="level-1">'.$row2['name'].'</option>';
+                               $query = "select * 
+                                       from category 
+                                       where parent_id = ".$row2['category_id']." 
+                                       order by name";
+                               if( $data3 = $DB->pgsql_select( $query ) ){
+                                       foreach( $data3 as $row3 ){
+                                               $out .= '<option value="'.$row3['category_id'].'" class="level-2">'.$row3['name'].'</option>';
+                                       }
+                               }
+                       }
+               }
+       }
+       $out .= '</select><button id="add-code" class="positive">Add</button></div>';
+}
+echo $out;
+?>
diff --git a/admin/Toolbox/member-toolbox.js b/admin/Toolbox/member-toolbox.js
new file mode 100644 (file)
index 0000000..e090c19
--- /dev/null
@@ -0,0 +1,37 @@
+var MemberToolbox =
+{
+    init: function()
+    {
+        if ($("#add-member-area")) {
+            $.ajax({
+                url: "member-code-query.php",
+                data: "Option=category",
+                cache: false,
+                success: function(html, textStatus) {
+                    $("#add-member-area").html(html);
+                    $("#add-code").click(function() {
+                        MemberToolbox.addCodes();
+                        return false;
+                    });
+                }
+            });
+        }
+    },
+
+    addCodes: function()
+    {
+        var category_id = $("#newCategory").val();
+        $.ajax({
+            url: "member-code-line.php",
+            cache: false,
+            data: "category_id=" + category_id,
+            success: function(html, textStatus) {
+                $("#list-members-info").append(html);
+            }
+        });
+
+        return false;
+    }
+};
+
+$(document).ready(MemberToolbox.init);
diff --git a/admin/Toolbox/member-toolbox.php b/admin/Toolbox/member-toolbox.php
new file mode 100644 (file)
index 0000000..6ef4db9
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+include_once("../../setup.phtml");
+include_once("toolbox_setup.inc");
+if( MEMBERS_DB )
+{
+       if( $memb_data = get_memb_types( &$DB ) )
+       {
+               $member_sel = '<select id="memb_type" name="memb_type">';
+               $member_sel .= '<option value=""></option>';
+               foreach( $memb_data as $memb_id => $memb_name )
+               {
+                       $member_sel .= '<option value="'.$memb_id.'">'.$memb_name.'</option>';
+               }
+               $member_sel .= '</select><span id="sub-part">&nbsp;</span>';
+       }
+       if( $memb_sub_types = get_memb_sub_types( &$DB ) )
+       {
+               foreach( $memb_sub_types as $parent => $memb_sub_value )
+               {
+                       $member_sub_sel[$parent] = '<select id="memb_sub" name="memb_sub">';
+                       $member_sub_sel[$parent] .= '<option value=""></option>';
+                       foreach( $memb_sub_value as $id => $name )
+                       {
+                               $member_sub_sel[$parent] .= '<option value="'.$id.'">'.$name.'</option>';
+                       }
+                       $member_sub_sel[$parent] .= '</select>';
+               }
+       }
+}
+?>
+var addMemberLink = document.getElementById('add-member');
+var addMemberDiv = document.getElementById('add-member-area');
+var addMemberList = document.getElementById('list-members-info');
+function removeElement( elem )
+{
+               var rem = document.getElementById( elem );
+       rem.innerHTML = '';
+}
+function attachEventListener(target, eventType, functionRef, capture)
+{
+       if (typeof target.addEventListener != "undefined")
+       {
+               target.addEventListener(eventType, functionRef, capture);
+       }
+       else if (typeof target.attachEvent != "undefined")
+       {
+               target.attachEvent("on" + eventType, functionRef);
+       }
+       else
+       {
+               eventType = "on" + eventType;
+
+               if (typeof target[eventType] == "function")
+               {
+                       var oldListener = target[eventType];
+
+                       target[eventType] = function()
+                       {
+                               oldListener();
+
+                               return functionRef();
+                       }
+               }
+               else
+               {
+                       target[eventType] = functionRef;
+               }
+       }
+
+       return true; 
+}
+function addLoadListener(fn)
+{
+       if (typeof window.addEventListener != 'undefined')
+       {
+               window.addEventListener('load', fn, false);
+       }
+       else if (typeof document.addEventListener != 'undefined')
+       {
+               document.addEventListener('load', fn, false);
+       }
+       else if (typeof window.attachEvent != 'undefined')
+       {
+               window.attachEvent('onload', fn);
+       }
+       else
+       {
+               var oldfn = window.onload;
+               if (typeof window.onload != 'function')
+               {
+                       window.onload = fn;
+               }
+               else
+               {
+                       window.onload = function()
+                       {
+                               oldfn();
+                               fn();
+                       };
+               }
+       }
+}
+function myLink()
+{
+       attachEventListener(addMemberLink,"click",addMyMember,false); 
+}
+function addMyMember() 
+{
+       addMemberDiv.innerHTML = '<?php echo $member_sel;?>';
+       addMemberDiv.innerHTML += '<a href="#" id="add-member-type" href="#">Add</a>';
+       var addType = document.getElementById('add-member-type');
+       attachEventListener(addType,"click",myAddType,false);   
+       var addMemberType = document.getElementById('memb_type');
+       attachEventListener(addMemberType,"change",myAddSubType,false); 
+}
+function myAddSubType(){
+       var sub_sel_hmtl = new Array();
+       <?php
+       foreach( $member_sub_sel as $parent => $html )
+       {
+       ?>
+       sub_sel_hmtl[<?php echo $parent;?>] = '<?php echo $html;?>';
+       <?php
+       }
+       ?>
+       var memb_type = document.getElementById('memb_type');
+       var memType = memb_type.options[memb_type.selectedIndex].value
+       if( !isNaN( memType ) )
+       {
+               var subPart = document.getElementById('sub-part');
+               subPart.innerHTML = sub_sel_hmtl[memType];
+       }
+}
+function myAddType()
+{
+       try{
+               var membTypes = document.getElementById('memb_sub');
+               if( membTypes.value ){
+                       var hideMemIdName = 'hideMember_' + membTypes.value;
+                       var hideMemName = 'hideMember_' + membTypes.value;
+                       addMemberList.innerHTML += '<div id="' + hideMemIdName + '" style="display:block;">'
+                               +  membTypes.options[membTypes.selectedIndex].text
+                               + '<input type="hidden" name="member_link[]" value="' + membTypes.value +'">'
+                               + '<a href="#" style="font-size:9pt;" onClick="removeElement(\'' + hideMemName + '\')">Delete</a></div>';
+               }
+               else{
+                       var membTypes = document.getElementById('memb_type');
+                       if( membTypes.value ){
+                               var hideMemIdName = 'hideMember_' + membTypes.value;
+                               var hideMemName = 'hideMember_' + membTypes.value;
+                               addMemberList.innerHTML += '<div id="' + hideMemIdName + '" style="display:block;">'
+                                       +  membTypes.options[membTypes.selectedIndex].text
+                                       + '<input type="hidden" name="member_link[]" value="' + membTypes.value +'">'
+                                       + '<a href="#" style="font-size:9pt;" onClick="removeElement(\'' + hideMemName + '\')">Delete</a></div>';
+                       }
+               }
+       }
+       catch(err){
+               var membTypes = document.getElementById('memb_type');
+               if( membTypes.value ){
+                       var hideMemIdName = 'hideMember_' + membTypes.value;
+                       var hideMemName = 'hideMember_' + membTypes.value;
+                       addMemberList.innerHTML += '<div id="' + hideMemIdName + '" style="display:block;">'
+                               +  membTypes.options[membTypes.selectedIndex].text
+                               + '<input type="hidden" name="member_link[]" value="' + membTypes.value +'">'
+                               + '<a href="#" style="font-size:9pt;" onClick="removeElement(\'' + hideMemName + '\')">Delete</a></div>';
+               }
+       }
+       addMemberDiv.innerHTML = '<a href="#" id="add-member">Add Member Link</a>';
+       var addMemberLink = document.getElementById('add-member');
+       attachEventListener(addMemberLink,"click",addMyMember,false); 
+}
+addLoadListener(myLink);
diff --git a/admin/Toolbox/threads.phtml b/admin/Toolbox/threads.phtml
new file mode 100755 (executable)
index 0000000..762cce9
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+class toolbox_thread {    
+       var $beginLevel = '<ul>';
+       var $beginLevel2 = '<ul id="toolbox">';
+    var $endLevel = '</ul>';
+    var $beginItem = '<li>';
+    var $beginItem2 = '<li class="toolboxArrow">';
+    var $endItem = '</li>';
+    var $wholeThread;
+       
+    function __construct($code="") {    
+               if(!empty($code)) {    
+                       $this->beginLevel = $code['beginLevel'];
+                       $this->beginLevel2 = $code['beginLevel2'];
+            $this->endLevel = $code['endLevel'];
+            $this->beginItem = $code['beginItem'];
+            $this->beginItem2 = $code['beginItem2'];
+            $this->endItem = $code['endItem'];
+        }
+    }
+
+    function sortChilds($threads) {    
+               while(list($var, $value) = each($threads))
+            $childs[$value[parent]][$value[ID]] = $value;
+        return $childs;
+    }
+
+    function convertToThread($threads, $thread) {    
+               static $count;
+               if( !$count ) {
+                       $this->wholeThread .= $this->beginLevel2;
+               } else {
+                       $this->wholeThread .= $this->beginLevel;
+               }
+        while(list($parent, $value) = each($thread)) {    
+                       if( $threads[$parent] && $value['closed'] ) {
+                               $this->wholeThread .= $this->beginItem2;
+                               $this->wholeThread .= '<a href="list_bus_category.phtml?expand='.$value['ID'].'"
+                                       title="Expand"><img border="0" src="expand.png"></a>';
+                       } elseif( $threads[$parent] && !$value['closed'] ) {
+                               $this->wholeThread .= $this->beginItem2;
+                               $this->wholeThread .= '<a href="list_bus_category.phtml?fold='.$value['ID'].'"
+                                       title="Fold"><img border="0"src="collapse.png"></a>';
+                       } else {
+                               $this->wholeThread .= $this->beginItem;
+                       }
+                       $count++;
+                       $this->wholeThread .= " <a href=\"edit_bus_category.phtml?id=".$value['ID']."\">[Edit]</a>&nbsp;&nbsp;"
+                       ."<a href=\"list_bus.phtml?catid=".$value['ID']."\">[Paragraphs]</a>&nbsp;&nbsp;" 
+                       ."<a target=\"_blank\" href=\"".$value['seo_url']."\">[Preview]</a>" 
+                       .$value[pos] 
+                       ."<b>".$value[active];
+                  $this->wholeThread .= $value['content'] . "</b>" . $this->endItem ."\n";
+                       if( $threads[$parent] && !$value['closed'] ) {
+                $this->convertToThread($threads, $threads[$parent]);
+                       }
+        }
+        $this->wholeThread .= $this->endLevel;
+        return $this->wholeThread;
+    }
+}
+?>
diff --git a/admin/Toolbox/toolbox_setup.inc b/admin/Toolbox/toolbox_setup.inc
new file mode 100755 (executable)
index 0000000..3d019a4
--- /dev/null
@@ -0,0 +1,435 @@
+<?php
+
+/**
+ * toolbox_setup.inc
+ * 
+ * Setup for the toolbox admin application
+ * 
+ * PHP versions 4 and 5
+ * 
+ * @category  Toolbox
+ * @package   Toolbox
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: toolbox_setup.inc,v 1.5 2009/09/09 13:44:33 matrix Exp $
+ * @link      <>
+ */
+// {{{ INCLUDES
+/**
+ * Main site config file
+ */
+include_once '../../setup.phtml';
+
+/**
+ * GLM_DB class
+ */
+include_once BASE.'classes/class_db.inc';
+
+/**
+ * GLM_TOOLBOX class
+ */
+include_once BASE.'classes/class_toolbox.inc';
+
+/**
+ * GLM_TEMPLATE class
+ */
+include_once BASE.'classes/class_template.inc';
+// }}}
+$DB =& new GLM_DB();
+$toolbox =& new GLM_TEMPLATE(1);
+// {{{ DEFINES
+if (!defined("DELUXE_TOOLBOX"))  {
+
+    /**
+     * Description for define
+     */
+       define("DELUXE_TOOLBOX",0);
+}
+if (!defined("TOOLBOX_FLAGS"))  {
+
+    /**
+     * Description for define
+     */
+       define("TOOLBOX_FLAGS",1);
+}
+if (!defined("LEVELS_DEEP")) 
+{
+
+    /**
+     * Description for define
+     */
+       define("LEVELS_DEEP",5);
+}
+if (!defined("MEMBERS_DB"))  {
+
+    /**
+     * Description for define
+     */
+       define("MEMBERS_DB",false);
+}
+if (!defined("HOME_ID"))  {
+
+    /**
+     * Description for define
+     */
+       define("HOME_ID",1);
+}
+if (!defined("CAT_LOCK"))  {
+
+    /**
+     * Description for define
+     */
+       define("CAT_LOCK",0);
+}
+if (!defined("MULTIPLE_CAT"))  {
+
+    /**
+     * Description for define
+     */
+       define("MULTIPLE_CAT",0);
+}
+// }}}
+$category_locks = array();//range(1,13);
+// {{{ $fields = array();
+// $fields array used for the bus table edit page
+$fields[] = array(
+    "name" => "id",
+    "title" => "id",
+    "type" => "hide"
+);
+$fields[] = array(
+    "name" => "name",
+    "title" => "Paragraph Title",
+    "type" => "text"
+);
+$fields[] = array(
+    "name" => "description", 
+    "title" => "Description", 
+    "type" => "desc"
+);
+$fields[] = array(
+    "name" => "imagename",
+    "title"=> "Image Caption",
+    "type" => "text"
+);
+$fields[] = array(
+    "name" => "image",
+    "title" => "Image",
+    "type" => "img"
+);
+$fields[] = array(
+    "name" => "back_to_top", 
+    "title" => "Insert 'Back to Top' link", 
+    "type" => "bool"
+);
+// }}}
+// {{{ update_member_bus_cat()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object  &$DB Parameter description (if any) ...
+ * @return boolean Return description (if any) ...
+ */
+function update_member_bus_cat(&$DB)
+{
+       if (!is_numeric($_REQUEST['id'])) {
+        return false;
+    }  
+       $query = "select * from bus_cat_member where catid = ".$_REQUEST['id'];
+       if ($bcm_data = $DB->pgsql_select($query)) {
+               foreach ($bcm_data as $bcm_row) {
+                       if (is_array($_REQUEST['member_cats']) && !in_array($bcm_row['memb_type'], $_REQUEST['member_cats'])) {
+                               // delete this one by the bus_cat_member id 
+                               $DB->pgsql_delete('bus_cat_member', array('id'=>$bcm_row['id']));
+                       } elseif (is_array($_REQUEST['member_cats'])) {
+                               $key = array_search($bcm_row['memb_type'], $_REQUEST['member_cats']);
+                               unset($_REQUEST['member_cats'][$key]);
+               }
+               }
+       }
+       if (is_array($_REQUEST['member_cats']))  {
+               foreach ($_REQUEST['member_cats'] as $row) {
+                       $data = array('catid'=>$_REQUEST['id'],'memb_type'=>$row);
+                       $DB->pgsql_insert('bus_cat_member', $data, 'id', 'bus_cat_member_id_seq') ;
+               }
+       }else{
+               // if there's no member_cats array then delete any that are in bus_cat_member table
+               $DB->pgsql_delete('bus_cat_member', array('catid'=>$_REQUEST['id'])) ;
+       }
+}
+// }}}
+// {{{ get_sub()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  unknown $catid Parameter description (if any) ...
+ * @param  object  $DB    Parameter description (if any) ...
+ * @return array   Return description (if any) ...
+ */
+function get_sub($catid, $DB) {
+       static $string,$count;
+       if (!isset($count))  {
+               $count = 0;
+       }
+       $string[$count] = $catid;
+       $count++;
+       $query = "SELECT        id
+               FROM            bus_category
+               WHERE   parent = $catid
+               ORDER BY        pos";
+       if ($data = $DB->db_auto_get_data($query)){
+               foreach($data as $key=>$value){
+                       $id = $value['id'];
+                       $string = get_sub($id, $DB) ;
+               }
+               return $string;
+       }else{
+               return $string;
+       }
+}
+// }}}
+// {{{ get_prop_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_prop_types(&$DB) {
+       static $prop_types;
+       if (!is_array($prop_types))  {
+               $query = "select * from prop_type order by name;";
+               if ($data = $DB->db_auto_get_data($query))  {
+                       foreach ($data as $row) {
+                               $prop_types[$row['id']] = $row['name'];
+                       }
+               }
+       }
+       return $prop_types;
+}
+// }}}
+// {{{ get_memb_sub_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_memb_sub_types(&$DB) {
+       static $memb_sub_types;
+       if (!is_array($memb_sub_types))  {
+               $query = "select category_id,name,parent_id from category where parent_id != 0 order by parent_id,pos";
+               if ($data = $DB->pgsql_select($query))  {
+                       foreach ($data as $row) {
+                               $memb_sub_types[$row['parent_id']][$row['category_id']] = $row['name'];
+                       }
+               }
+       }
+       return $memb_sub_types;
+}
+// }}}
+// {{{ get_memb_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_memb_types(&$DB) {
+       static $memb_types;
+       if (!is_array($memb_types))  {
+               $query = "select * from category where parent_id = 0 order by pos;";
+               if ($data = $DB->db_auto_get_data($query))  {
+                       foreach ($data as $row) {
+                               $memb_types[$row['category_id']] = $row['name'];
+                       }
+               }
+       }
+       return $memb_types;
+}
+// }}}
+// {{{ get_memb_all_types()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  object &$DB Parameter description (if any) ...
+ * @return array  Return description (if any) ...
+ */
+function get_memb_all_types(&$DB) {
+       static $memb_types;
+       if (!is_array($memb_types))  {
+               $query = "select * from category order by parent_id,pos;";
+               if ($data = $DB->db_auto_get_data($query))  {
+                       foreach ($data as $row) {
+                               $memb_types[$row['category_id']] = $row['class_code'].' '.$row['name'];
+                       }
+               }
+       }
+       return $memb_types;
+}
+// }}}
+// {{{ check_lock()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  mixed   $id Parameter description (if any) ...
+ * @return boolean Return description (if any) ...
+ */
+function check_lock($id){
+       if (isset($id)  && $id != '' && is_numeric($id))  {
+               if (file_exists(BASE.'static/'.$id.'.phtml')  || $id == HOME_ID) {
+                       return true;
+               }else{
+               return false;
+       }       
+       }else{
+               return false;
+       }       
+
+}
+// }}}
+// {{{ sort_by_parent()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  array $data Parameter description (if any) ...
+ * @return mixed Return description (if any) ...
+ */
+function sort_by_parent($data) {
+       if (!is_array($data))
+               return false;
+       foreach($data as $key=>$value) {
+               $data_new[$value["parent"]][$value["id"]] = $value;
+       }
+       return $data_new;
+}
+// }}}
+// {{{ convertParent()
+/**
+ * Short description for function
+ * 
+ * Long description (if any) ...
+ * 
+ * @param  array $threads Parameter description (if any) ...
+ * @param  array $thread  Parameter description (if any) ...
+ * @return array Return description (if any) ...
+ */
+function convertParent($threads,$thread) {
+       static $select,$count;
+       $count = (!isset($count))   ? 0: $count;
+       $bgcolor[] = '#6d6d6d';
+       $bgcolor[] = '#7a7a7a';
+       $bgcolor[] = '#8a8a8a';
+       $bgcolor[] = '#979797';
+       $bgcolor[] = '#adadad';
+       $bgcolor[] = '#c1c1c1';
+       if (is_array($thread)) {
+               foreach($thread as $parent=>$value) {                   
+                       $color = $bgcolor[$count];
+                       $select[$value['id']]['color'] = $color;
+                       $select[$value['id']]['category'] = $value['category'];
+                       $select[$value['id']]['count'] = $count;
+
+                       if (isset($threads[$parent])) { 
+                               $count++;
+                               convertParent($threads, $threads[$parent]);
+                       }
+               }
+       }
+       $count--;
+       return $select;
+}
+// }}}
+// {{{ parent_select()
+/**
+  parent select
+
+  <p>This function does both the bus and bus category page parent select drop down boxes.
+  the backcount var is used to lock the list to a certain level set up with define of LEVELS_DEEP.
+  count varl starts at one and is generated in the function convertParent so we'll need to subtract one for proper results.
+  to unset backcount properly we'll need to check if count goes under or equals that of backcount.
+  then unset($backcount) cause if backcount is not empty then category won't get added to list.
+  </p>
+ */
+function parent_select($catid,$id,$sel_name = "parent"){
+       global $DB;
+       // select catid portion 
+       $qs = "SELECT   id,category,parent 
+               FROM    bus_category 
+               ORDER BY parent,pos";
+
+       $data = $DB->db_auto_get_data($qs,CONN_STR); 
+       $data1 = sort_by_parent($data);
+       $select = "<select name=\"".$sel_name."\" style=\"width:500px;\">";
+       if ($sel_name == "parent") {
+               $select .= "<option value=\"0\">--No Parent--";
+       }
+       $parts = convertParent($data1,$data1[0]);
+       if (is_array($parts)){
+               foreach($parts as $key=>$value){
+                       if (isset($backcount)  && $value['count'] <= $backcount) {
+                               unset($backcount);
+                       }
+                       if ($key == $id && $sel_name = "parent") {
+                               $backcount = $value['count'];
+                       }
+                       if ($key == HOME_ID && $sel_name == "parent") {
+                               continue;
+                       }
+                       if ((!isset($backcount) && ($value['count'] < (LEVELS_DEEP - 1))   || $sel_name == "catid[]"))  {
+                               $bkg = $value["color"];
+                               $indent = (int)$value["count"] * 10;
+                               $cc = (int)$value["count"] * 2;
+                               $paddman = str_repeat("&nbsp;",$cc);
+                               $select .= '<option value="'.$key.'"';
+                               if ($key == $catid){
+                                       $select .= ' selected';
+                               }
+                               $select .= ' class="level-'.$value['count'].'"';
+                               $select .= '>'.$value["category"];
+                       }
+               }
+       }
+       $select .= "</select>";
+       if (CAT_LOCK == true && $sel_name == "parent"){
+               if ($catid!=0){         
+                       $qs = "SELECT   category 
+                               FROM    bus_category
+                               WHERE   id = $catid";
+
+                       $res2 = $DB->db_auto_get_data($qs,CONN_STR);
+                       $category = $res2['category'];
+               }else{
+                       $category = "No Parent";                
+               }
+
+               $select = $category."<input type=\"hidden\" name=\"$sel_name\" value=\"$catid\">";              
+       }
+       if ((($id==HOME_ID || in_array($id,$GLOBALS['category_locks']))  && $catid == 0)&& strstr($_SERVER['PHP_SELF'],"edit_bus_category") && ($catid!='' && $id!='')){
+               $select = 'No Parent <input type="hidden" name="parent" value="0">';
+       }
+       return $select;
+}
+// }}}
+$toolbox_nav['Toolbox Home'] = 'list_bus_category.phtml';
+if (!CAT_LOCK) {
+       $toolbox_nav["Add A New Page"]  = "edit_bus_category.phtml";
+}
+?>
diff --git a/admin/Toolbox/update_bus.phtml b/admin/Toolbox/update_bus.phtml
new file mode 100755 (executable)
index 0000000..d7cf243
--- /dev/null
@@ -0,0 +1,604 @@
+<?php
+/*
+ * Includes
+ */
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+/*
+ * Defines
+ */
+define("TABLE", "bus");
+define("ID", "id");
+define("SEQUENCE", "bus_id_seq");
+// last field count
+$LAST     = count($fields)-1;
+// location for redirect
+$location = "../list_bus.phtml?catid={$_REQUEST['catid']}";
+GLM_TOOLBOX::http_strip($url);
+/*
+ * Command are only done on POST or when Moving an item
+ */
+if ($_POST || $_REQUEST['Command'] == "Move") {
+    switch($Command) {
+    /*
+     * Move a paragraph position 
+     */
+    case "Move":// {{{
+        $qs = "
+        SELECT  pos,id
+        FROM    bus_category_bus
+        WHERE   id = $id";
+        if (!$result = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+        }
+        $data = $DB->db_fetch_array($result, 0, PGSQL_ASSOC);
+        $pos  = $data['pos'];
+        if ($newpos < $pos) {
+            $qs = "
+            SELECT  id,pos
+            FROM    bus_category_bus 
+            WHERE   pos < $pos
+            AND     pos >= $newpos
+            AND     catid = $catid
+            ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+            }
+            $counter = ($newpos + 1);
+            for ($i = 0; $i < $DB->db_numrows($res); $i++) {
+                $res_data = $DB->db_fetch_array($res, $i, PGSQL_ASSOC);
+                $res_id   = $res_data['id'];
+                $res_pos  = $res_data['pos'];
+                $qs       = "
+                UPDATE  bus_category_bus
+                SET     pos = $counter
+                WHERE   id = $res_id";
+            
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+                }
+                $counter++;
+            }
+        } else {
+            $qs = "
+            SELECT  pos,id
+            FROM    bus_category_bus
+            WHERE   pos > $pos
+            AND     pos <= $newpos
+            AND     catid = $catid
+            ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+            }
+            $counter = ($pos);
+            for ($i = 0; $i < $DB->db_numrows($res); $i++) {
+                $res_data = $DB->db_fetch_array($res, $i, PGSQL_ASSOC);
+                $res_id   = $res_data['id'];
+                $res_pos  = $res_data['pos'];
+                $qs       = "
+                UPDATE  bus_category_bus
+                SET     pos = $counter
+                WHERE   id = $res_id";
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+                }
+                $counter++;
+            }
+        }
+        $qs = "
+        UPDATE  bus_category_bus
+        SET     pos = $newpos
+        WHERE   id = $id";
+        if (!$DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 0);
+        }
+        $location = "list_bus.phtml?catid=$catid";
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $catid, 'Toolbox');
+        break;// }}}
+    
+    /*
+     * Update the Paragraph
+     */
+    case "Update":// {{{
+        $DB->db_exec("BEGIN WORK");
+        if (is_array($_POST['delete'])) {
+            foreach ($_POST['delete'] as $d_row_id) {
+                $query    = "
+                SELECT filename 
+                FROM files 
+                WHERE id = ".$d_row_id;
+                $file_res = $DB->db_exec($query); 
+                $filename = pg_result($file_res, 0, 'filename');
+                $query    = "
+                DELETE FROM files 
+                WHERE id = ".$d_row_id;
+                $DB->db_exec($query); 
+                @unlink(UP_BASE.$filename);
+                unset($_FILES['file_new']['name']);
+                // remember files have to be repositioned when there are deleted
+                // get the position number of file then reposition all the ones with a greater pos
+                $query = "
+                UPDATE files SET 
+                pos = pos - 1 
+                WHERE pos > ".$_POST['filename_poshide'.$d_row_id]." 
+                AND bus_id = ".$_POST['id'];
+                $DB->db_exec($query); 
+            }
+        }
+        if (is_array($_FILES['file_new']['name'])) {
+            foreach ($_FILES['file_new']['name'] as $fileId => $fileName) {
+                if ($_FILES['file_new']['name'][$fileId]) {
+                    @unlink(UP_BASE.$_POST['oldfile'][$fileId]);
+                    $update_file_name = GLM_TOOLBOX::file_upload($_FILES['file_new']['tmp_name'][$fileId], $_FILES['file_new']['name'][$fileId], UP_BASE);    
+                    $query = "
+                    UPDATE files SET 
+                    filename = '$update_file_name' 
+                    WHERE id = $fileId;";
+                    $DB->db_exec($query); 
+                }
+            }
+        }
+        if ($_POST['filename_urltext']) {
+            foreach ($_POST['filename_urltext'] as $fileId => $fileUrlText) {
+                $query = "
+                UPDATE files SET 
+                urltext = '$fileUrlText' 
+                WHERE id = $fileId;";
+                $DB->db_exec($query); 
+            }
+        }
+        if (is_array($_FILES['file']) && $_FILES['file']['name'] != '') {
+            $res = $DB->db_exec("select max(pos) as maxpos from files where bus_id = ".$_POST['id']); 
+            $maxpos = pg_result($res, 0, 'maxpos');
+            $maxpos = ($maxpos) ? ++$maxpos : 1;
+            $new_file_name = GLM_TOOLBOX::file_upload($_FILES['file']['tmp_name'], $_FILES['file']['name'], UP_BASE);    
+            $query = "
+            INSERT INTO files 
+            (filename,bytes,type,urltext,bus_id,pos) 
+            VALUES 
+            ('$new_file_name',".$_FILES['file']['size'].",'".$_FILES['file']['type']."',
+            '".$_POST['filename']."',".$_POST['id'].",$maxpos);";
+            $DB->db_exec($query); 
+        }
+        $oldcatid = ereg_replace("^:","",$oldcatid);
+        $oldcatid = split(":",$oldcatid);
+        if ($category) {
+            $category = ereg_replace("^:","",$category);
+            $catid = split(":",$category);
+        }
+        $array_counter = 0;
+        if (is_array($catid)) {
+            $query = "
+            SELECT catid,pos 
+            FROM bus_category_bus 
+            WHERE busid = $id";
+            $res = $DB->db_exec($query);
+            $oldpos = pg_result($res,0,'pos');
+            while ($row = pg_fetch_array($res)) {
+                // do this only if ald catid is being removed
+                if (!in_array($row['catid'],$catid)) {
+                    $query = "
+                    UPDATE bus_category_bus SET 
+                    pos = pos - 1 
+                    WHERE catid = ".$row['catid']." 
+                    AND pos >= $oldpos";
+                    $DB->db_exec($query);
+                    $query = "
+                    DELETE FROM bus_category_bus 
+                    WHERE catid = ".$row['catid']." 
+                    aNd busid = $id";
+                    $DB->db_exec($query);                
+                }
+            }
+            foreach ($catid as $key=>$value) {
+                // do this only if ald catid is being removed
+                if (!in_array($value,$oldcatid)) {
+                    $qs = "SELECT   count(*) as maxpos
+                           FROM     bus_category_bus
+                           WHERE    catid = $value";
+                    if (!$res = $DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+                    }
+                    $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+                    $pos = ($row['maxpos'] == 0) ? (int)0 : (int)$row['maxpos'] ;
+                    $pos++;
+                    $qs = "
+                    INSERT     
+                    INTO bus_category_bus
+                    (busid,catid,pos)
+                    VALUES
+                    ($id,$value,$pos)";
+                    if (!$DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+                    }
+                }
+            }
+        }
+        $fields = array_reverse($fields);
+        $qs = "UPDATE ".TABLE." SET ";
+        for ($i=0;$i<count($fields);$i++) {
+            if ($fields[$i][type]=="date") {
+                $month =  $_POST[$fields[$i][name]."_month"];
+                $day = $_POST[$fields[$i][name]."_day"];
+                $year = $_POST[$fields[$i][name]."_year"];
+                if (is_numeric($month) && is_numeric($day) && is_numeric($year)) {
+                    $date = "'".date("Y-m-d H:i:s T",mktime(0,0,0,$month,$day,$year))."'";
+                } else {
+                    $date = 'NULL';
+                }
+                $qs .= $fields[$i][name]." = $date";
+                if ($i != $LAST) {
+                    $qs .= ",";
+                }
+            } elseif ($fields[$i][type]=="datetime") {
+                $month =  $fields[$i][name]."_month";
+                $day = $fields[$i][name]."_day";
+                $year = $fields[$i][name]."_year";
+                $H = $fields[$i][name]."_hour";
+                $mm = $fields[$i][name]."_mm";
+                if ($$mm == "PM") {
+                    $$H = $$H + 12;
+                }
+                $m = $fields[$i][name]."_min"; 
+                $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+                $qs .= $fields[$i][name]." = '$date'";
+                if ($i != $LAST) {
+                    $qs .= ",";
+                }
+            } elseif ($fields[$i][name]!=ID) {
+                if ($fields[$i][type]=="img") {
+                    $tmpimg = $fields[$i]['name'];
+                    $image_tmp = $$tmpimg;
+                    $oldy = ${"old".$tmpimg};
+                    $image_tmp_name = ${$tmpimg."_name"};
+                    if ($image_tmp == "none" || $image_tmp == "") {
+                        $image_tmp_name = $oldy;
+                    } else { 
+                        $image_tmp_name = GLM_TOOLBOX::process_image($tmpimg);
+                        if ($oldy) {
+                            require_once BASE.'Toolkit/Image/Server.php';
+                            $imServer = new Toolkit_Image_Server();
+                            $imServer->imageDelete($oldy);
+                        }
+                    }
+                    $delete = ${"delete".$tmpimg};
+                    if ($delete==1) {
+                        $image_tmp_name = "";
+                        if ($oldy) {
+                            require_once BASE.'Toolkit/Image/Server.php';
+                            $imServer = new Toolkit_Image_Server();
+                            $imServer->imageDelete($oldy);
+                        }
+                    }
+                    $qs .= $fields[$i][name]." = '".$image_tmp_name."'";
+                    if ($i != $LAST) {
+                        $qs .= ",";
+                    }
+                } elseif ($fields[$i][type]=="seperator") {
+                        //empty
+                } elseif ($fields[$i][type]=="file") {
+                    $tmpfile = $fields[$i]['name'];
+                    $file_tmp = $$tmpfile;
+                    $oldy = ${"old".$tmpfile};
+                    $file_tmp_name = ${$tmpfile."_name"};
+                    if ($file_tmp == "none" || $file_tmp == "") {
+                        $file_tmp_name = $oldy;
+                    } else { 
+                        $file_tmp_name = GLM_TOOLBOX::file_upload($file_tmp,$file_tmp_name,UP_BASE);
+                    }
+
+                    $delete = ${"delete".$tmpfile};
+                    if ($delete==1) {
+                        $file_tmp_name = "";
+                        @unlink(UP_BASE.$oldy);
+                    }
+                    $qs .= $fields[$i][name]." = '".$file_tmp_name."'";
+                    if ($i != $LAST) {
+                        $qs .= ",";
+                    }
+                } elseif ($fields[$i]['type']=="bool") {
+                        $value = ($_REQUEST[$fields[$i]['name']]) ? 't' : 'f';
+                        $qs .= $fields[$i]['name']." = '$value'";
+                        if ($i != $LAST) {
+                            $qs .= ",";
+                        }
+                } elseif ($fields[$i][type]=="static") {
+                    // do nothing
+                } elseif ($fields[$i][type]=="password") {
+                    if (($password && $password2) && ($password == $password2)) {
+                        $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+                        if ($i != $LAST) {
+                            $qs .= ",";
+                        }
+                    }        
+                } else {
+                    $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+                    if ($i != $LAST) {
+                        $qs .= ",";
+                    }
+                }
+            } else {
+                $qs = substr($qs,0,strlen($qs)-1);
+                $qs .= " WHERE ".$fields[$i][name]." = ".$$fields[$i][name];
+            }    
+        }
+        $fields = array_reverse($fields);
+        if (!$DB->db_exec($qs)) {
+            $ERRORS .= pg_errormessage($dbd).$qs;
+        }
+        $location = "list_bus.phtml?catid=".$catid[0]."&".SID;
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $oldcatid[0], 'Toolbox');
+               $toolbox->cache->remove('paragraphs-' . $catid[0], 'Toolbox');
+        $DB->db_exec("COMMIT WORK");
+        break;// }}}
+    
+    /*
+     * Insert a new paragraph at last position + 1
+     */
+    case "Insert":// {{{
+        if (is_array($_FILES['file']) && $_FILES['file']['name'] != '') {
+            $new_file_name = GLM_TOOLBOX::file_upload($_FILES['file']['tmp_name'], $_FILES['file']['name'], UP_BASE);    
+        }
+        if ($category) {
+            $category = ereg_replace("^:", "", $category);
+            $catid = split(":", $category);
+        }
+        $tmp = "";
+        $tmp_value = "";
+        for ($i = 0; $i < count($fields); $i++) {
+            if ($fields[$i]['name'] != ID) {
+                if ($fields[$i]['type']!="static" && $fields[$i]['type']!="seperator") {
+                    $tmp .= $fields[$i]['name'];
+                    $tmp .= ",";    
+                }
+            }
+        }
+        for ($i=0;$i<count($fields);$i++) {
+            if ($fields[$i]['type']=="date") {
+                $month = $_POST[$fields[$i]['name']."_month"];
+                $day   = $_POST[$fields[$i]['name']."_day"];
+                $year  = $_POST[$fields[$i]['name']."_year"];
+                if (is_numeric($month) && is_numeric($day) && is_numeric($year)) {
+                    $date = "'".date("Y-m-d H:i:s T",mktime(0, 0, 0, $month, $day, $year))."'";
+                } else {
+                    $date = 'NULL';
+                }
+                $tmp_value .= "$date";
+                $tmp_value .= ",";    
+                } elseif ($fields[$i]['type']=="bool") {
+                    $value = ($_REQUEST[$fields[$i]['name']]) ? 't' : 'f';
+                    $tmp_value .= "'$value'";
+                    $tmp_value .= ",";    
+            } elseif ($fields[$i]['type'] == "static") {
+            } elseif ($fields[$i]['type'] == "seperator") {
+            } elseif ($fields[$i]['type'] == "datetime") {
+                $month =  $fields[$i]['name']."_month";
+                $day   = $fields[$i]['name']."_day";
+                $year  = $fields[$i]['name']."_year";
+                $H     = $fields[$i]['name']."_hour";
+                $mm    = $fields[$i]['name']."_mm";
+                if ($$mm == "PM") {
+                    $$H = $$H + 12;
+                }
+                $m          = $fields[$i]['name']."_min"; 
+                $date       = date("Y-m-d H:i:s T", mktime($$H, $$m,0, $$month, $$day, $$year));
+                $tmp_value .= "'$date'";
+                $tmp_value .= ",";    
+            } elseif ($fields[$i]['type'] == "img") {
+                $tmpimg     = $fields[$i]['name'];
+                $image      = $$tmpimg;
+                $image_name = ${$tmpimg."_name"};
+                if ($image == "none" || $image == "") {
+                    $image_name = '';
+                } else { 
+                    $image_name = GLM_TOOLBOX::process_image($tmpimg);
+                }
+                $tmp_value .= "'".$image_name."'";
+                $tmp_value .= ",";    
+            } elseif ($fields[$i]['type'] == "file") {
+                $tmpfile   = $fields[$i]['name'];
+                $file      = $$tmpfile;
+                $file_name = ${$tmpfile."_name"};
+                if ($file == "none" || $file == "") {
+                    $file_name = '';
+                } else { 
+                    $file_name = GLM_TOOLBOX::file_upload($file, $file_name, UP_BASE);
+                }
+                $tmp_value .= "'".$file_name."'";
+                $tmp_value .= ",";    
+            } elseif ($fields[$i]['name'] != ID) {
+                $tmp_value .= "'".$$fields[$i]['name']."'";
+                $tmp_value .= ",";    
+            }
+        }
+        // get the lat and lon for bus
+        // check for all blanks
+        $tmp_blank = str_replace("'", "", $tmp_value);
+        $tmp_blank = str_replace(",", "", $tmp_blank);
+        $tmp       = substr($tmp, 0, strlen($tmp)-1);
+        $tmp_value = substr($tmp_value, 0, strlen($tmp_value)-1);
+        if (!$res = $DB->db_exec("BEGIN WORK")) {
+            die(pg_errormessage($dbd).$qs);
+        }
+        if ($tmp_blank || $_FILES['file']['name']) {
+            $qs = "
+            INSERT INTO ".TABLE." 
+            (".ID.", $tmp)
+            VALUES
+            (nextval('".SEQUENCE."'), $tmp_value)";
+            if (!$res = $DB->db_exec($qs)) {
+                die(pg_errormessage($dbd).$qs);
+            }
+            if ($new_file_name) {
+                $query = "
+                INSERT INTO files 
+                (filename,bytes,type,urltext,bus_id) 
+                VALUES 
+                ('$new_file_name',".$_FILES['file']['size'].",'".$_FILES['file']['type']."',
+                '".$_POST['filename']."',currval('bus_id_seq'));";
+                $DB->db_exec($query); 
+            }
+            if (is_array($catid)) {
+                foreach ($catid as $key => $value) {
+                    $qs = "
+                    SELECT  count(*) as maxpos
+                    FROM    bus_category_bus
+                    WHERE   catid = $value";
+                    if (!$res = $DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                    }
+                    $row2 = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+                    if (!$pos = $row2[maxpos]) {
+                        $pos = 1;
+                    } else {
+                        $pos++;
+                    }
+                    $qs = "
+                    INSERT     
+                    INTO bus_category_bus
+                    (busid,catid,pos)
+                    VALUES
+                    (currval('bus_id_seq'),$value,$pos)";
+                    if (!$DB->db_exec($qs)) {
+                        GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                    }
+                }
+                if (!$res = $DB->db_exec("COMMIT WORK")) {
+                    die(pg_errormessage($dbd).$qs);
+                }
+            } else {
+                $qs = "
+                SELECT  count(*) as maxpos
+                FROM    bus_category_bus
+                WHERE    catid = $catid";
+                if (!$res = $DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                }
+                $row2 = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+                if (!$pos = $row2[maxpos]) {
+                    $pos = 1;
+                } else {
+                    $pos++;
+                }
+                $qs = "
+                INSERT     
+                INTO bus_category_bus
+                (busid,catid,pos)
+                VALUES
+                ($row[id],$catid,$pos)";
+    
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                }
+                if (!$res = $DB->db_exec("COMMIT WORK")) {
+                    die(pg_errormessage($dbd).$qs);
+                }
+            }
+        }
+        $location = "list_bus.phtml?catid=".$catid[0]."&".SID; 
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $catid[0], 'Toolbox');
+        break;// }}}
+    
+    /*
+     * Delete a paragraph
+     * reposition all other paragraphs
+     * delete images and files for this
+     * paragraph
+     */
+    case "Delete":// {{{
+        $oldcatid = ereg_replace("^:", "", $oldcatid);
+        $oldcatid = split(":", $oldcatid);
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        if ($oldimage) {
+            $imServer->imageDelete($oldimage);
+        }
+        if ($oldimage2) {
+            $imServer->imageDelete($oldimage2);
+        }
+        if ($oldimage3) {
+            $imServer->imageDelete($oldimage3);
+        }
+        $query = "
+        SELECT * 
+        FROM files 
+        WHERE bus_id = $id;";
+        if ($fRes = $DB->db_exec($query)) {
+            while ($fRow = pg_fetch_array($fRes)) {
+                if (is_file(UP_BASE.$fRow['filename'])) {
+                    unlink(UP_BASE.$fRow['filename']);
+                }
+            }
+        }
+        foreach ($oldcatid as $key=>$value) {
+            if ($value) {
+                $qs = "
+                SELECT id,pos
+                FROM   bus_category_bus
+                WHERE  busid = $id
+                AND    catid = $value";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+            }
+            $row = $DB->db_fetch_array($res, 0, PGSQL_ASSOC);
+            $qs = "
+            SELECT  id
+            FROM    bus_category_bus
+            WHERE   pos > $row[pos]
+            AND     catid = $value
+            ORDER BY pos";
+            if (!$res2 = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+            }
+            $counter = $row[pos];
+            for ($i = 0; $i < $DB->db_numrows($res2); $i++) {
+                $row2 = $DB->db_fetch_array($res2, $i, PGSQL_ASSOC);
+            
+                $qs = "
+                UPDATE  bus_category_bus
+                SET     pos = $counter
+                WHERE   id = $row2[id]";
+                       
+                if (!$DB->db_exec($qs)) {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs, 1);
+                }
+                $counter++;
+                }
+            }
+        }
+        $qs = "
+        DELETE FROM bus
+        WHERE id = $id";
+        if (!$DB->db_auto_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs, 1);
+        }
+        $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID; 
+               // cach_Toolbox_paragraphs-$ID
+               $toolbox->cache->remove('paragraphs-' . $oldcatid[0], 'Toolbox');
+        break;// }}}
+    
+    /*
+     * Cancel Paragraph edit
+     */
+    case "Cancel":// {{{
+        $oldcatid = ereg_replace("^:","",$oldcatid);
+        $oldcatid = split(":",$oldcatid);
+        $catid = ereg_replace("^:","",$oldcatid);
+        $catid = split(":",$oldcatid);
+        $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID; 
+        break;// }}}
+    
+    default:// {{{
+        GLM_TOOLBOX::html_error("incorrect value for Command",1);
+        break;// }}}
+            
+    }
+}
+/*
+ * Redirect to the list paragraph page
+ */
+header("Location: $location");
+?>
diff --git a/admin/Toolbox/update_bus_category.phtml b/admin/Toolbox/update_bus_category.phtml
new file mode 100755 (executable)
index 0000000..be87eb5
--- /dev/null
@@ -0,0 +1,315 @@
+<?php
+/*
+ * Includes
+ */
+include_once "../../setup.phtml";
+include_once "toolbox_setup.inc";
+// clean short_url
+if ($_REQUEST['short_url']) {
+    $_REQUEST['short_url'] = ereg_replace("[^A-Za-z0-9_-]", "", trim($_REQUEST['short_url']));
+}
+if ($REQUEST_METHOD == "POST" || $Command == "Move") {
+    switch($Command) {
+    // {{{ case "Move":
+
+    /*
+     * Move a Page position 
+     */
+    case "Move":
+        $qs = "
+        SELECT  pos,id
+        FROM    bus_category
+        WHERE   id = $id";
+        if (!$result = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+        }
+        $data = $DB->db_fetch_array($result,0,PGSQL_ASSOC);
+        $pos = $data['pos'];
+        if ($newpos < $pos) {
+            $qs = "
+                SELECT  id,pos
+                FROM    bus_category
+                WHERE   pos < $pos
+                AND     pos >= $newpos
+                AND     parent = $parent
+                ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+            }
+            $counter = ($newpos + 1);
+            for ($i=0;$i<$DB->db_numrows($res);$i++) {
+                $res_data = $DB->db_fetch_array($res,$i,PGSQL_ASSOC);
+                $res_id = $res_data['id'];
+                $res_pos = $res_data['pos'];
+                $qs = "
+                    UPDATE  bus_category
+                    SET     pos = $counter
+                    WHERE   id = $res_id";
+                if (!$DB->db_exec($qs)) 
+                {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+                }
+                $counter++;
+            }
+        } else {
+            $qs = "
+                SELECT  pos,id
+                FROM    bus_category
+                WHERE   pos > $pos
+                AND     pos <= $newpos
+                AND     parent = $parent
+                ORDER BY pos";
+            if (!$res = $DB->db_exec($qs)) {
+                GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+            }
+            $counter = ($pos);
+            for ($i=0;$i<$DB->db_numrows($res);$i++) {
+                $res_data = $DB->db_fetch_array($res,$i,PGSQL_ASSOC);
+                $res_id = $res_data['id'];
+                $res_pos = $res_data['pos'];
+                $qs = "
+                    UPDATE  bus_category
+                    SET     pos = $counter
+                    WHERE   id = $res_id";
+                if (!$DB->db_exec($qs)) 
+                {
+                    GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+                }
+                $counter++;
+            }
+        }
+        $qs = "
+            UPDATE  bus_category 
+            SET     pos = $newpos
+            WHERE   id = $id";
+        if (!$DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,0);
+        }
+        $toolbox->cache->clean('Nav');
+        break;// }}}
+    // {{{ case "Update":
+
+    /*
+     * Update the Page
+     */
+    case "Update":
+        if ($image != "none" && $image != "") {
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            if ($oldimage) {
+                $imServer->imageDelete($oldimage);
+            }
+            $image_name = GLM_TOOLBOX::process_image('image');
+        } else {
+            $image_name = $oldimage;
+        }
+        if ($delete == "1") {
+            $image_name = "";
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($_REQUEST['oldimage']);
+        }
+        if ($parent != $oldparent) {
+            $qs = "
+                SELECT  MAX(pos) as maxpos
+                FROM    bus_category
+                WHERE   parent = $parent";
+            $res = $DB->db_exec($qs);
+            $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+            $pos = $row[maxpos];
+            $pos++;
+            $qs = "
+                SELECT  pos,id 
+                FROM    bus_category
+                WHERE   parent = $oldparent
+                AND     pos > $oldpos
+                ORDER BY pos";
+            $res2 = $DB->db_exec($qs);
+            $oldparent_counter = $oldpos;
+            for ($i=0;$i<$DB->db_numrows($res2);$i++) {
+                $row2 = $DB->db_fetch_array($res2,$i,PGSQL_ASSOC);
+                $qs = "
+                    UPDATE  bus_category
+                    SET     pos = $oldparent_counter
+                    WHERE   id = $row2[id]";
+                $DB->db_exec($qs);
+                $oldparent_counter++;
+            }
+        } else {
+            $pos = $oldpos;
+        }
+        $template           = ($template) ? $template : 1;
+        $featured           = ($featured == 't') ? $featured : 'f';
+        $include_member_map = ($include_member_map == 't') ? $include_member_map : 'f';
+        $no_search_form     = ($no_search_form == 't') ? $no_search_form : 'f';
+        $section_links      = ($section_links == 't') ? $section_links : 'f';
+        $region             = (is_numeric($region)) ? $region : 'NULL';
+        
+        //$res2 = $DB->db_exec("BEGIN WORK;"); 
+        $qs = "
+            UPDATE bus_category SET     
+            category = '$category', 
+            featured = '$featured',
+            include_member_map = '$include_member_map',
+            no_search_form = '$no_search_form',
+            meta_descr = '$meta_descr',
+            title = '$title',
+            section_links = '$section_links',
+            parent = $parent,
+            pos = $pos,
+            intro = '$intro',
+            feature_intro = '$feature_intro',
+            description = '$description',
+            image = '$image_name',
+            imagename = '$imagename',
+            keyword = '$keyword',
+            template = $template,
+            short_url = '$short_url',
+            region = $region
+            WHERE id = $id";
+        if (!$DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs,1);
+        }
+        if (defined("MEMBERS_DB") && MEMBERS_DB) {
+            update_member_bus_cat(&$DB);
+        }
+        //$DB->db_exec("COMMIT WORK;"); 
+        break;// }}}
+    // {{{ case "Insert":
+    
+    /*
+     * Insert a new Page at last position + 1
+     */
+    case "Insert":
+        $parent = ($parent) ? $parent : 0;
+        if ($image != "none" && $image != "") {
+            $image_name = GLM_TOOLBOX::process_image('image');
+        } else { 
+            $image_name = $oldimage;
+        }
+        $qs = "
+            SELECT  MAX(pos) as maxpos
+            FROM    bus_category
+            WHERE   parent = $parent";
+        $res = $DB->db_exec($qs);
+        $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+        $nextpos = $row[maxpos];
+        $nextpos++;
+        $template           = ($template) ? $template : 1;
+        $parent             = ($parent) ? $parent : 0;
+        $featured           = ($featured == 't') ? $featured : 'f';
+        $no_search_form     = ($no_search_form == 't') ? $no_search_form : 'f';
+        $include_member_map = ($include_member_map == 't') ? $include_member_map : 'f';
+        $section_links      = ($section_links == 't') ? $section_links : 'f';
+        $region             = (is_numeric($region)) ? $region : 'NULL';
+
+        $res2 = $DB->db_exec("BEGIN WORK;"); 
+        $qs = "
+            INSERT INTO bus_category 
+            (section_links,include_member_map, no_search_form,featured,feature_intro,template,keyword,
+             category,parent,intro,description,image,imagename,pos,meta_descr,
+             short_url,title,region)
+            VALUES 
+            ('$section_links','$include_member_map','$no_search_form','$featured','$feature_intro',$template,'$keyword',
+             '$category',$parent,'$intro','$description','$image_name','$imagename',$nextpos,'$meta_descr',
+             '$short_url','$title',$region)";
+        if (!$res1 = $DB->db_exec($qs)) {
+            GLM_TOOLBOX::html_error("failed ->".$qs,1);
+        }
+        if (defined("MEMBERS_DB") && MEMBERS_DB && is_array($_REQUEST['member_cats'])) {
+            foreach ($_REQUEST['member_cats'] as $memb_catid) {
+                $query = "
+                    INSERT INTO bus_cat_member 
+                    (catid, memb_type) 
+                    VALUES 
+                    (currval('bus_category_id_seq'), $memb_catid);";
+                if (!$DB->db_exec($query)) {
+                    die($query.__LINE__);
+                }
+            }
+        }
+        $DB->db_exec("COMMIT WORK;"); 
+        $toolbox->cache->clean('Nav');
+        break;// }}}
+    // {{{ case "Delete"
+    /*
+     * Delete a Page
+     * reposition all other Pages
+     * delete images
+     * Page
+     */
+    case "Delete":
+        $DB->db_exec("BEGIN WORK");
+        $qs = "
+        SELECT   count(*) as count 
+        FROM     bus_category_bus
+        WHERE    catid = $id";
+        $res = $DB->db_exec($qs);
+        $row = $DB->db_fetch_array($res,0,PGSQL_ASSOC);
+        if ($row['count'] >0) {
+            GLM_TOOLBOX::html_error("Sorry but you have items in there\n 
+                        Delete these records first\n",1); 
+        }
+        $qs = "
+            SELECT  parent 
+            FROM    bus_category 
+            WHERE   parent = $id";
+        $res = $DB->db_exec($qs);
+        if ($DB->db_numrows($res) >0) {
+            GLM_TOOLBOX::html_error("Sorry but you have Categories in there\n 
+                        Delete these Categories first\n",1); 
+        }
+        $qs = "
+            SELECT  pos,id 
+            FROM    bus_category
+            WHERE   parent = $oldparent
+            AND     pos > $oldpos
+            ORDER BY pos";
+        $res2 = $DB->db_exec($qs);
+        $oldparent_counter = $oldpos;
+        for ($i=0;$i<$DB->db_numrows($res2);$i++) {
+            $row2 = $DB->db_fetch_array($res2,$i,PGSQL_ASSOC);
+            $qs = "
+                UPDATE  bus_category
+                SET     pos = $oldparent_counter
+                WHERE   id = $row2[id]";
+            $DB->db_exec($qs);
+            $oldparent_counter++;
+        }
+        $qs2 = "
+            DELETE 
+            FROM    bus_category 
+            WHERE   id = $id";
+        $DB->db_exec($qs2);
+        if (!$DB->db_auto_exec($qs2)) html_error(DB_ERROR_MSG.$qs2,1);
+        if ($oldimage) {
+            require_once BASE.'Toolkit/Image/Server.php';
+            $imServer = new Toolkit_Image_Server();
+            $imServer->imageDelete($oldimage);
+        }
+        $DB->db_exec("COMMIT WORK");
+        // remove the cache for this paragraphs
+        // cach_Toolbox_paragraphs-$ID
+        $toolbox->cache->remove('paragraphs-' . $id, 'Toolbox');
+        $toolbox->cache->clean('Nav');
+        break;// }}}
+    // {{{ case "Cancel":
+    
+    /*
+     * Cancel Page edit
+     */
+    case "Cancel":
+        break;// }}}
+    // {{{ default
+    default:
+        GLM_TOOLBOX::html_error("incorrect value for Command",1);
+        break;// }}}
+    }
+}
+// remove the cache for this paragraphs
+// cach_Toolbox_page-$ID
+$toolbox->cache->remove('page-' . $id, 'Toolbox');
+$toolbox->cache->remove('paragraphs-' . $id, 'Toolbox');
+//GLM_TOOLBOX::create_sitemap();
+header("Location: ".BASE_URL."admin/Toolbox/list_bus_category.phtml?".SID);
+?>
diff --git a/admin/Toolbox/updatetoolset.php b/admin/Toolbox/updatetoolset.php
new file mode 100755 (executable)
index 0000000..7863b18
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+       /* If you don't have a newsletter installed then comment oeut the part where it updates
+         the news and news_block tables
+        or else this will rollback (since it is in a transaction)
+       :) 
+        */
+       require_once '../../setup.phtml';
+       require_once BASE.'classes/class_db.inc';
+       require_once BASE.'classes/class_template.inc';
+
+       $DB =& new GLM_DB();
+       $DB->db_connect();
+       $DB->db_exec( "BEGIN WORK" );
+
+       echo 'replacing newlines with &lt;br&gt; in bus_category<br>';
+       $DB->db_exec( "update bus_category set description = replace(description,'\\n','<br>')" );
+       echo 'replacing newlines with &lt;br&gt; in bus<br>';
+       $DB->db_exec( "update bus set description = replace(description,'\\n','<br>')" );
+       $DB->db_exec( "update bus set description2 = replace(description2,'\\n','<br>')" );
+       $DB->db_exec( "update bus set description3 = replace(description3,'\\n','<br>')" );
+       
+       echo 'replacing newlines with &lt;br&gt; in news<br>';
+       $DB->db_exec( "update news set description = replace(description,'\\n','<br>')" );
+       echo 'replacing newlines with &lt;br&gt; in news_block<br>';
+       $DB->db_exec( "update news_block set description2 = replace(description2,'\\n','<br>')" );
+
+       $DB->db_exec( "COMMIT WORK" );
+       /**
+         update media_category set description = replace(description,'http://devsys.gaslightmedia.com/www.upnorth.net/','http://www.upnorth.net/');
+         update bus_category set description = replace(description,'http://devsys.gaslightmedia.com/www.upnorth.net/','http://www.upnorth.net/');
+         */
+?>
diff --git a/admin/Toolbox/upgradefiles2.php b/admin/Toolbox/upgradefiles2.php
new file mode 100644 (file)
index 0000000..c2cd054
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+include('../../setup.phtml');
+include(BASE.'classes/class_db.inc');
+$DB =& new GLM_DB();
+$DB->db_exec( "BEGIN WORK;" );
+echo '<p>BEGIN WORK</p>';
+$query = "select id,bus_id from files order by bus_id,filename;";
+echo '<p>'.$query.'</p>';
+if( $data = $DB->db_auto_get_data( $query ) )
+{
+       $bus_id = null;
+       $pos = 1;
+       foreach( $data as $row )
+       {
+               if( $row['bus_id'] == $bus_id )
+               {
+                       $pos++;
+               }
+               else
+               {
+                       $pos = 1;
+                       $bus_id = $row['bus_id'];
+               }
+               $query2 = "update files set pos = $pos where id = ".$row['id'].";";
+               echo '<p>'.$query2.'</p>';
+               $DB->db_exec( $query2 );
+       }
+}
+$DB->db_exec( "COMMIT WORK;" );
+echo '<p>COMMIT WORK</p>';
+?>
diff --git a/admin/form.js b/admin/form.js
new file mode 100644 (file)
index 0000000..0bbabf0
--- /dev/null
@@ -0,0 +1,42 @@
+function reshow(object) {
+    artist = object.options[object.selectedIndex].text;
+        for (var i = document.track.names.length;i > 0;i--)
+            document.track.names.options[0] = null;
+        reloading = true;
+        showlinks();
+        document.track.names.options[0].selected = true;
+    return false;
+}
+
+function load(object) {
+    alert('Just testing: ' + object.options[object.selectedIndex].value);
+    //window.location.href = object.options[object.selectedIndex].value;
+    return false;
+}
+
+function showlinks() {
+    if (artist == 'Chris Rea') {
+        opt('cr/one.zip','The Road To Hell');
+        opt('cr/two.zip','Let\'s Dance');
+    }
+
+    if (artist == 'Annie Lennox') {
+        opt('al/why.zip','Why');
+        opt('al/wobg.zip','Walking on Broken Glass');
+    }
+
+    if (artist == 'Dina Carrol') {
+        opt('dc/track1.zip','Escaping');
+        opt('dc/track2.zip','Only Human');
+    }
+}
+
+function opt(href,text) {
+    if (reloading)  {
+        var optionName = new Option(text, href, false, false)
+        var length = document.track.names.length;
+        document.track.names.options[length] = optionName;
+    }
+    else
+        document.write('<OPTION VALUE="',href,'">',text,'<\/OPTION>');
+}
diff --git a/admin/index.phtml b/admin/index.phtml
new file mode 100644 (file)
index 0000000..c398566
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+include '../setup.phtml';
+$page = isset($_GET['page']) ? $_GET['page'] : 'splash.phtml';
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+ "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+<head>
+<title><?php echo SITENAME;?> Administration</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<frameset cols="160,*">
+<frame name="Nav" src="nav.phtml" frameborder="0">
+<frame name="Main" src="<?php echo $page;?>" frameborder="0">
+<noframes><p>Admin Requires Frames Capable Browser</p>
+You can get a Standard Compliant browser from:
+<ul>
+<li>Microsoft <a href="http://www.microsoft.com/windows/ie/">Internet Explorer</a></li>
+<li>Mozilla's <a href="http://www.mozilla.org/products/firefox/">Firefox</a></li>
+</ul>
+</noframes>
+</frameset>
+</html>
diff --git a/admin/main.css b/admin/main.css
new file mode 100644 (file)
index 0000000..de72596
--- /dev/null
@@ -0,0 +1,204 @@
+body {
+       padding-left: 50px;
+       font-family: arial, helvetica, sans-serif;
+       font-size: 12px;
+       }
+.clearer {
+ height:1px;
+ overflow:hidden;
+ margin-top:-1px;
+ clear:left;
+}
+h1 {font-size: 18px; color: #777;}
+form {margin: 0; padding: 0;}
+/* TOOLBOX NAV */
+ul#toolbox {list-style-position:inside;list-style-type:circle;}
+ul#toolbox li {list-style-type:circle}
+ul#toolbox li.toolboxArrow {list-style-type:none;padding-left:0;margin-left:-7px;}
+* html ul#toolbox li.toolboxArrow {margin-left:-20px;} /*style for IE*/
+/* APP  Nav*/
+ul.admin_nav 
+{
+margin: 0;
+list-style-type: none;
+padding: 5px 0;
+}
+ul.admin_nav li { display: inline; }
+ul.admin_nav li a
+{
+border-top: 1px solid #eee;
+border-right: 1px solid #ccc;
+border-bottom: 1px solid #ccc;
+border-left: 1px solid #eee;
+text-decoration: none;
+background-color: #ddd;
+color: #000;
+padding: 2px 6px;
+margin: 0 1px;
+font-weight: bold;
+font-size: 12px;
+}
+#admin-list-table {clear:left;width:500px;}
+#admin-list-table td {
+       border: 2px solid #ccc;
+       border-collapse: collapse;
+       background: #eee;
+       padding: 4px;}  
+/*#admin-list-table img {border: 0; text-align: center; margin: 0 auto; display: block;}*/
+#admin-list-table a:link {color: #666;}
+#admin-list-table a:visited {color: #666;}
+#admin-list-table a:active {color: #666;}
+#admin-list-table a:hover {color: #000;}
+
+/*event-edit-table */
+#admin-edit-table {
+       clear:left;
+       font-family: arial, helvetica, sans-serif;
+       border: 2px solid #ccc;
+       border-collapse: collapse;
+       font-size: 12px;
+       }
+#admin-edit-table td {
+       border: 2px solid #ccc;
+       border-collapse: collapse;
+       background: #eee;       padding: 4px;}          
+#admin-list-table table td {border:none;padding:0;margin:0;}
+#admin-edit-table table td {border:none;padding:0;margin:0;}
+#admin-edit-table select,
+#admin-edit-table input,
+#admin-edit-table option {font-size: 12px;}
+#glm-manual {position:absolute;right:200px;top:10px;width:300px;}
+#glm-manual a {padding:5px 2px;width:149px;background-color:#DDDDDD;color:#000;}
+div.fileupload { border:1px solid black;float:left;margin:5px; padding:5px;background-color:white; color:black; }
+div.fileupload p { margin:0; padding:0;float:left; }
+div.fileupload span { background-color:#c0c0c0;  }
+.level-0 {
+        font-weight: bold;
+        padding-left: 0;
+        background-color: #ccc;
+}
+.level-1 {
+        padding-left: 20px;
+        background-color: #ddd;
+        }
+.level-2 {padding-left: 40px;}
+.level-3 {padding-left: 60px;}
+.level-4 {padding-left: 80px;}
+.level-5 {padding-left: 100px;}
+.level-6 {padding-left: 120px;}
+table.banners,
+table.banners tr {
+       border: 1px solid #17186A;
+       border-collapse: collapse;
+}
+table.banners {
+       border: none;
+       border: 1px solid #17186A;
+       width: 100%;
+       margin: 5px 2px;
+}
+table.banners td.status {
+       text-align: center;
+}
+table.banners a img {
+       border: none;
+}
+table.banners thead th {
+       text-align: center;
+       background: #1D58A5;
+       border: 1px solid #17186A;
+       color: #FFF;
+       padding: 2px 6px;
+}
+table.banners thead a {
+       color: #FFF;
+}
+table.banners tbody tr td {
+       padding: 5px 5px;
+}
+table.banners tbody tr:hover {
+       background: #E3E3E3;
+}
+table.banners a:hover {
+       text-decoration: none;
+}
+.pager {
+       text-align: center;
+       background: #F6F6F6;
+       border-color: #DDD;
+       border-style: solid;
+       border-width: 1px 0;
+       margin: 1.0em 0;
+       padding: 8px 0;
+       text-align: center;
+       width: 100%;
+       font-size: 12px;
+
+}
+.pager b {
+       border: 1px solid #CCC;
+       border: 1px solid #17186A;
+       background: #FFF;
+       padding: 5px 7px;
+}
+.pager a {
+       background: #FFF;
+       border: 1px solid #CCC;
+       padding: 5px 7px;
+       text-decoration: none;
+       color: #000;
+}
+.pager a:hover {
+       border: 1px solid #999;
+       border: 1px solid #17186A;
+}
+#form-wrap legend {
+       color: #fff;
+       background: #1D58A5;
+       border: 1px solid #17186A;
+       padding: 2px 6px;
+}
+#form-wrap p {margin:1px;}
+#form-wrap label {
+       float: none;
+       margin-right: 0;
+       display: inline;
+       clear: left;
+}
+
+
+/* Banner Reporting */
+
+#bannerInfo, #reportResult {
+       margin: 10px;
+       border: 1px solid #bbb;
+       border-right: 1px solid #444;
+       border-bottom: 1px solid #444;
+       padding: 20px;
+       width: 400px;
+       background: #efefef;
+       font-size: 12px;
+}
+#bannerInfo h3, #reportResult h3 {
+       margin: 0;
+}
+#bannerInfo p {
+       margin-bottom: 0;
+}
+
+#bannerInfo table, #reportResult table, 
+#bannerInfo th, #reportResult th,
+#bannerInfo tr, #reportResult tr,
+#bannerInfo td, #reportResult td {
+       margin: 5px;
+       padding: 5px;
+       border-collapse: collapse;
+       font-size: 12px;
+}
+#bannerInfo td {
+       padding: 5px;
+}
+
+/* Report Result */
+
diff --git a/admin/msg.js b/admin/msg.js
new file mode 100644 (file)
index 0000000..8ed837d
--- /dev/null
@@ -0,0 +1,29 @@
+function glm_confirm(o) {
+       var p = o.msg.split("\n");
+       var k = 0;
+       for(i = 0;i < p.length;i++) {
+               if(k > p[i].length)
+                       continue;
+               else 
+                       k = p[i].length;
+       }       
+       
+       var bound = "";
+       for(i = 0; i < k; i++) {
+               bound = bound+'_';
+       }
+       var str = bound+"\n\n"+o.msg+"\n\n"+bound+"\n\nAre You Sure?";
+       if(confirm(str)) {
+               if(o.popup == '1') {
+                       var nw = new Object();
+                       nw.url = o.url;
+                       nw.name = o.popup.name;
+                       nw.width = o.width;
+                       nw.height = o.height;
+                       glm_open(nw);
+               }
+               else {
+                       location.replace(o.url);
+               }
+       }
+}
diff --git a/admin/nav.phtml b/admin/nav.phtml
new file mode 100644 (file)
index 0000000..5c40dff
--- /dev/null
@@ -0,0 +1,87 @@
+<?php include_once '../setup.phtml'; ?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Admin Navigation</title>
+<style type="text/css">
+body {margin: 2px; font-family: arial, sans-serif; font-size: 12px; background-color: #fff;}
+a:link {color: #004C64;}
+a:visited {color: #004C64;}
+a:hover {color: #2C788F;}
+a:active {color: #004C64;}
+
+h1 {
+    font-weight: bold;
+    text-align: center;
+    font-size: 14px;
+    background: url(../images/logoAdminSmall.gif) no-repeat;
+    text-indent: -3000px;
+    width: 130px;
+    height: 53px;
+    margin-left: 10px;
+    }
+ul { margin: 0; padding: 0; list-style-type: none; }
+li { margin: 0; padding: 0; display: block;    }
+li a {
+    text-decoration: none; 
+    display: block; 
+    margin: 0;
+    padding: 4px 8px; 
+    background-color: #004C64; 
+    border-bottom: 1px solid #eee;
+    width: 136px;
+    }
+li a:link, li a:visited, li a:active { color: #EEE; }
+li a:hover { background-color: #2C788F; color: #fff; }
+</style>
+</head>
+<body>
+    <h1><a href="<?php echo BASE_URL.$url;?>" target="_top"><?php echo SITENAME;?></a></h1>
+<ul>
+<?php
+$conf = new Config;
+$memberRoot =& $conf->parseConfig(
+       BASE . 'Toolkit/Members/config.ini',
+       'IniFile'
+);
+$pluralType
+       = $memberRoot->getItem('section', 'listing type')
+       ->getItem('directive', 'plural')
+       ->getContent();
+
+$rotatingImagesRoot =& $conf->parseConfig(
+       BASE . 'Toolkit/RotatingImages/config.ini',
+       'IniFile'
+);
+
+//  get reference to [conf] section of config file
+$rotatingImagesName
+       = $rotatingImagesRoot->getItem('section', 'conf')
+       ->getItem('directive', 'applicationName')
+       ->getContent();
+
+$nav['Home']              = 'admin/splash.phtml';
+$nav['Toolbox']           = 'admin/Toolbox/';
+$nav['Events']            = 'admin/Events/';
+$nav['Contact']           = 'admin/Contact/';
+$nav['Banners']           = 'admin/banners.php';
+$nav[$rotatingImagesName] = 'admin/rotatingImages.php';
+$nav['Coupons']           = 'admin/Coupons/';
+$nav[$pluralType]         = 'admin/members.php';
+$nav['Postcards']         = 'admin/Postcards/list_card_gallery.phtml';
+$nav['Photos']            = 'admin/Photos/';
+$nav['Server Statistics'] = 'admin/logs/';
+
+foreach ($nav as $name => $url) {
+    echo '
+    <li><a href="'.BASE_URL.$url.'" target="Main">'.$name.'</a></li>
+        ';
+}
+?>
+<li><a href="http://travel.gaslightmedia.com/members/" target="Main">Travel Reservation System</a></li>
+</ul>
+
+<a style="display: block; margin: 10px auto; text-align: center;" href="http://www.gaslightmedia.com/" target="_blank"><img alt="" src="http://www.gaslightmedia.com/assets/poweredby.gif" border="0" title="Gaslight Media Website"></a>
+</body>
+</html>
diff --git a/admin/splash.phtml b/admin/splash.phtml
new file mode 100644 (file)
index 0000000..3034a7d
--- /dev/null
@@ -0,0 +1,21 @@
+<?
+include("../setup.phtml");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<link type="text/css" rel=stylesheet href="<?echo URL_BASE."admin/main.css"?>">
+<title>Welcome to GLM Toolbox</TITLE>
+</head>
+<body>
+
+<div style="text-align: center;">
+<p><strong>Welcome To The <?=SITENAME?> Administration Area</strong></p>
+<p>Please Choose The Area You Wish To Update.</p>
+<img src="<?=URL_BASE."images/logo.gif"?>">
+</div>
+
+</body>
+</html>
+
diff --git a/admin/template1.gif b/admin/template1.gif
new file mode 100644 (file)
index 0000000..327d943
Binary files /dev/null and b/admin/template1.gif differ
diff --git a/admin/template2.gif b/admin/template2.gif
new file mode 100644 (file)
index 0000000..edf3d8b
Binary files /dev/null and b/admin/template2.gif differ
diff --git a/admin/template3.gif b/admin/template3.gif
new file mode 100644 (file)
index 0000000..16e2107
Binary files /dev/null and b/admin/template3.gif differ
diff --git a/admin/template4.gif b/admin/template4.gif
new file mode 100644 (file)
index 0000000..32174dd
Binary files /dev/null and b/admin/template4.gif differ
diff --git a/admin/template5.gif b/admin/template5.gif
new file mode 100644 (file)
index 0000000..6c36b50
Binary files /dev/null and b/admin/template5.gif differ
diff --git a/admin/template6.gif b/admin/template6.gif
new file mode 100644 (file)
index 0000000..28d140e
Binary files /dev/null and b/admin/template6.gif differ
diff --git a/admin/verify.js b/admin/verify.js
new file mode 100644 (file)
index 0000000..54ebd72
--- /dev/null
@@ -0,0 +1,107 @@
+function isblank(s) {
+       for(var i = 0; i < s.length; i++) {
+               var c = s.charAt(i);
+               if((c != ' ') && (c != '\n') && (c != '\t'))
+                       return(false);
+       }
+       return(true);
+}
+
+function verify(f) {
+       var msg;
+       var empty_fields = "";
+       var errors = "";
+
+       for(var i = 0; i < f.length; i++) {
+               var e = f.elements[i];
+               if(((e.type == "text") || (e.type == "password") ||(e.type == "textarea")) && !e.optional) {
+                       if((e.value == null) || (e.value == "") || isblank(e.value)) {
+                               empty_fields += "\n             " + e.r;
+                               continue;
+                       }
+
+                       if(e.d) {
+                               if(isNaN(Date.parse(e.value)))
+                                       errors += "- The field " +e.r+" must be formated like 01/17/2001\n";
+                       }
+                       if(e.numeric || (e.min != null) || (e.max != null)) {
+                               if(e.i) {
+                                       var v = parseInt(e.value);
+                                       if(v != e.value) {
+                                               errors += "- The field " +e.r + " must be a ";
+                                               errors += "number with no decimal\n";
+                                               continue;
+                                       }
+                               }
+                               else
+                                       var v = parseFloat(e.value);
+                               if(isNaN(v) ||
+                                       ((e.min != null) && (v < e.min)) ||
+                                       ((e.max != null) && (v > e.max))) {
+
+                                       errors += "- The field " + e.r + " must be a number";
+                                       if(e.min != null)
+                                               errors += " that is greater than " + e.min;
+                                       if(e.max != null && e.min != null)
+                                               errors += " and less than " + e.max;
+                                       else if (e.max != null)
+                                               errors += " that is less than " + e.max;
+                                       errors += ".\n";
+                               }
+                       }
+               }
+               if (e.options && !e.optional)
+               {
+                       if((e.value == null) || (e.value == "") || isblank(e.value)) 
+                       {
+                               empty_fields += "\n             " + e.r;
+                               continue;
+                       }
+               }
+       }
+
+       if(!empty_fields && !errors)
+               return(true);
+
+       msg = "_____________________________________________________\n\n";
+       msg +="The form was not submitted because of the following error(s).\n";
+       msg +="Please correct these error(s) and re-submit.\n";
+       msg +="_____________________________________________________\n\n";
+
+       if(empty_fields) {
+               msg += "- The following required field(s) are empty:"
+                               + empty_fields + "\n";
+               if(errors)
+                       msg += "\n";
+       }
+       msg += errors;
+       alert(msg);
+       return(false);
+}
+var chkDot = true;
+var usEmail = true;
+function validEmail(eAddr) 
+{ 
+   var lenSuffix = (usEmail) ? 4: 3;
+   var goodAddr = false;
+   var ndxAt = ndxDot = 0;
+   ndxAt  = eAddr.indexOf("@");
+   ndxDot = eAddr.indexOf(".");
+   ndxDot2 = eAddr.lastIndexOf(".");
+
+   if ( (ndxDot < 0) || (ndxAt < 0) )
+      return(goodAddr);//alert("Your email address lacks '.' or '@'.\n\nThe format is 'you@dom.suf'");  
+   else if (chkDot  && (ndxDot < ndxAt) )
+        chkDot =!( confirm("You entered a 'dot' before the '@'\n Are you sure that is right?"));
+   else if ( (ndxDot2 - 3) <= ndxAt)
+        return(goodAddr);//alert("You may be missing your domain name.\n\nThe format is 'you@dom.suf'");
+   else if ( eAddr.length < (ndxDot2 + lenSuffix) )
+      usEmail =!( confirm("You have fewer than 3 characters as a domain suffix.\nAre you sure that is right?"));
+   else
+      goodAddr = true;
+
+
+   return (goodAddr);                       
+} 
+
+
diff --git a/admin/wm.js b/admin/wm.js
new file mode 100644 (file)
index 0000000..7a7323e
--- /dev/null
@@ -0,0 +1,13 @@
+function glm_open(o) {
+       var x = (screen.width/2) - (o.width/2);
+       var y = (screen.height/2) - (o.height/2);
+       var args = "width="+o.width+",height="+o.height+",screenX="+x+",screenY="+y+",top="+y+",left="+x;
+       if(o.scroll == true)
+               args += ",scrollbars=1";
+       //args += "\'";
+       //alert(args);
+       pow=window.open(o.url,o.name,args);
+       //confirm(args);
+       if (pow.opener == null)
+               pow.opener = self;
+}
diff --git a/cache/.cvsignore b/cache/.cvsignore
new file mode 100644 (file)
index 0000000..65fb5e5
--- /dev/null
@@ -0,0 +1 @@
+* *.*
diff --git a/cache/.keepme b/cache/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/classes/class_db.inc b/classes/class_db.inc
new file mode 100755 (executable)
index 0000000..babc4a6
--- /dev/null
@@ -0,0 +1,755 @@
+<?php
+
+/**
+ * class_db.inc
+ * 
+ * Class build for providing postgres function to facilitate
+ * database abstraction.
+ * We're moving on to using PHP Data Objects (PDO) now
+ * 
+ * PHP version 5
+ * 
+ * @category  Classes
+ * @package   GLM_DB
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: class_db.inc,v 1.6 2009/11/10 20:13:30 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Short description for class
+ * 
+ * Long description (if any) ...
+ * 
+ * @category  Classes
+ * @package   GLM_DB
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   Release: @package_version@
+ * @link      <>
+ */
+class GLM_DB
+{
+    // {{{ Properties
+
+    /**
+     * host 
+     * string host database host server name
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $host;
+    /**
+     * dbname 
+     * string dbname name of the database 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $dbname;
+    /**
+     * user 
+     * string user The user to connect as
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $user;
+    /**
+     * password 
+     * string password The users password if any 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $password;
+    /**
+     * dbd 
+     * string dbd Database connection result ID#
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $dbd;
+    /**
+     * conn 
+     * string conn string postgres connection string default = CONN_STR
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $conn;
+    /**
+     * trans 
+     * boolean trans bool if true a transaction is in process 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $trans;
+    /**
+     * Result 
+     * 
+     * @var    mixed 
+     * @access public
+     */
+    protected $Result;
+
+    /**
+     * Description for public
+     * @var    unknown
+     * @access public 
+     */
+    public $dbh;
+    // }}}
+    // {{{ GLM_DB()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param unknown $conn Parameter description (if any) ...
+     * 
+     * @return void   
+     * @access public 
+     */
+    function GLM_DB($conn = CONN_STR)
+    {
+        $this->dbh      = Toolkit_Database::getInstance();
+        $this->host     = "";
+        $this->dbname   = "";
+        $this->user     = "nobody";
+        $this->password = "";    
+        $this->conn     = $conn;
+        $this->trans    = 0;    
+        $this->dbd      = "";
+    }
+
+    // }}}
+    // {{{ db_auto_array()
+
+    /** db_auto_get_array
+    *
+    *  The auto function for retrieving an array based soley on a query
+    *  string. This function makes the connection, does the exec, fetches
+    *  the array, closes the connection, frees memory used by the result,
+    *  and then returns the array
+    *
+    * {@source } 
+    * @param  $qs    SQL           query       string
+    * @param  $i     row           number
+    * @param  $type  PGSQL_ASSOC or PGSQL_BOTH or PSQL_NUM
+    *
+    * @returns array - Returns an associative array of key-value pairs
+    * @access  public
+    */
+
+    function db_auto_array($qs, $i, $type)
+    {
+        if (!$this->dbd) {
+            $this->dbd =& $this->db_connect();
+        }
+        $res = $this->db_exec($qs);
+        if (!$res) {
+            return 0;
+        }
+        if ($this->db_numrows($res) == 0) {
+            return 0;
+        }
+
+        $row = $this->db_fetch_array($res, $i, $type);
+
+        if(!$this->db_freeresult($res)) {
+            return 0;
+        }
+
+        return $row;
+    }
+
+    // }}}
+    // {{{ db_auto_exec()
+
+    /** db_auto_exec
+    *
+    *  The auto function for executing a query.
+    *  This function makes the connection, does the exec, fetches
+    *  the array, closes the connection, frees memory used by the result,
+    *  and then returns success (not a valid result index)
+    *
+    * {@source }
+    * @param   $qs    SQL query string
+    * @returns int - Returns 1 for success 0 for failure
+    * @access  public
+    */
+
+    function db_auto_exec($qs)
+    {
+        $this->db_connect();
+        if (!$this->dbd) {
+            return 0;
+        }
+        if (!$this->db_exec( $qs)) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+
+    // }}}
+    // {{{ db_auto_get_data()
+
+    /** db_auto_get_data
+    *
+    *  <p>The auto function for retrieving an array based soley on a query
+    *  string. This function makes the connection, does the exec, fetches
+    *  the array, closes the connection, frees memory used by the result,
+    *  and then returns the array.</p>
+    *
+    * {@source } 
+    * @param string $qs    SQL query string
+    *
+    * @returns mixed
+    * @access  public
+    */
+    function db_auto_get_data($qs)
+    {
+        if ($this->dbh) {
+            return $this->dbh->query($qs)->fetchAll(PDO::FETCH_ASSOC);
+        }
+        if (!$this->dbd) {
+            $this->db_connect();
+        }
+        if (!( $res = $this->db_exec( $qs))) {
+            return false;
+        }
+        $totalrows = pg_NumRows( $res);
+        for ($i = 0 ; $i < $totalrows ; $i++) {
+            $data[$i] = $this->db_fetch_array ($res, $i, PGSQL_ASSOC);
+        }
+        if (isset( $data) && $data != "")    {
+            return $data;
+        } else {
+            return 0;
+        }
+    }
+
+    // }}}
+    // {{{ db_close()
+
+    /** db_close 
+      *
+      * Closes the connection to database specified by the handle dbd    
+      * returns a boolean for success                     
+      *
+      * {@source } 
+      * @returns bool - Returns 1 on success 0 if dbd is not a valid connection    
+    * @access  public
+     */
+
+    function db_close()
+    {
+        switch (DB_TYPE) {
+            case "postgres":
+                pg_close($this->dbd);
+            break;
+            default:
+            return false;
+        }
+    }
+
+    // }}}
+    // {{{ db_connect()
+
+   /** 
+    * db_connect
+    *
+    * Creates a connection to database specified $conn_str, 
+    * and returns a boolean for success.            
+    *
+    * @uses    GLM_DB::$dbd
+    * @uses    GLM_DB::$conn
+    * @uses    GLM_DB::$dbname
+    * @uses    GLM_DB::$host
+    * @uses    GLM_DB::$user
+    * @uses    GLM_DB::$password
+    *          {@source } 
+    * @returns int
+    * @access  public
+    */
+
+    function db_connect()
+    {
+        if (isset( $this->dbd) && $this->dbd != "") {
+            return $this->dbd;    
+        }
+        switch (DB_TYPE) {
+        case "postgres":
+            if ($this->host == '' && $this->dbname == '') {
+                $conn = $this->conn;// CONN_STR;
+            } else {    
+                $conn .= ($this->host != '') ? 'host='.$this->host.' ' : '';
+                $conn .= ($this->dbname != '') ? 'dbname='.$this->dbname.' ' : '';
+                $conn .= ($this->user != '') ? 'user='.$this->user." " : '';
+                $conn .= ($this->password != '') ? "password=".$this->password : '';
+            }
+            if (!$this->dbd = pg_connect($conn)) {
+                echo pg_errormessage($conn);
+            }
+            break;
+
+        default:
+            return 0;
+            break;
+        }
+        return $this->dbd;        
+    }
+
+    // }}}
+    // {{{ db_exec()
+
+    /** db_exec
+    *
+    *  Execute an SQL query, * returning a valid result index or zero(0) on    
+    *  failure.                                
+    *
+    * {@source } 
+    * @param   $qs    -- SQL query string                
+    * @returns int Returns a valid result index on success 0 on failure    
+    * @access  public
+    */
+    function db_exec($qs)
+    {
+        if (!$this->dbd) {
+            $this->dbd = $this->db_connect();    
+        }
+        switch (DB_TYPE) {
+            case "postgres":
+                if(!$ret = pg_exec($this->dbd, $qs)) {
+                    echo "<font color=red>".$qs."</font>";
+                }
+            break;
+            default:
+            return false;
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ db_fetch_array()
+
+    /** db_fetch_array
+    *
+    *  Stores the data in associative indices, using the field names as    
+    *  keys.                                 
+    *
+    * {@source } 
+    * @param   $res   -- valid database result index            
+    * @param   $i     -- row number                    
+    * @param   $type  -- PGSQL_ASSOC,PGSQL_BOTH,PGSQL_NUM                    
+    * @returns array Returns an associative array of key-value pairs        
+    * @access  public
+    */
+
+    function db_fetch_array($res, $i, $type)
+    {
+        switch (DB_TYPE) {
+        case "postgres":
+            $row = pg_fetch_array($res, $i, $type);
+            break;
+
+        default:
+            return false;
+        }
+        return $row;
+    }
+
+    // }}}
+    // {{{ db_freeresult()
+
+    /** db_freeresult
+    *
+    *  Free result memory.                            
+    *
+    * {@source } 
+    * @param   $res   -- valid database result index            
+    * @returns bool - Returns 1 for success 0 for failure            
+    * @access  public
+    */
+
+    function db_freeresult($res)
+    {
+        switch (DB_TYPE) {
+        case "postgres":
+            $ret = pg_freeresult($res);
+            break;
+
+        default:
+            return false;
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ db_numrows()
+
+    /** db_numrows
+    *
+    *  Determine number of rows in a result index                
+    *
+    * {@source } 
+    * @param   $res   -- valid database result index            
+    * @returns int - Returns number of rows                    
+    * @access  public
+    */
+
+    function db_numrows($res)
+    {
+        switch (DB_TYPE) {
+        case "postgres":
+            $ret = pg_numrows($res);
+            break;
+
+        default:
+            return -1;
+        }
+        return $ret;
+    }
+
+    // }}}
+    // {{{ delete()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $table     Parameter description (if any) ...
+     * @param  unknown $condition Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function delete($table, $condition)
+    {
+        return $this->pgsql_delete($table, $condition);
+    }
+
+    // }}}
+    // {{{ insert()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $table       Parameter description (if any) ...
+     * @param  unknown $data        Parameter description (if any) ...
+     * @param  unknown $primary_key Parameter description (if any) ...
+     * @param  unknown $sequence    Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function insert($table, $data, $primary_key, $sequence)
+    {
+        return $this->pgsql_insert($table, $data, $primary_key, $sequence);
+    }
+
+    // }}}
+    // {{{ pgsql_convert()
+
+    /**
+     * pgsql_convert 
+     * 
+     * converts an array (like _POST) and verifies field types to use in insert or update of postgres table
+     * 
+     * @param  mixed  $table
+     * @param  mixed  $data 
+     * @access public
+     * @return string
+     */
+    function pgsql_convert($table, $data)
+    {
+        $query = "select a.attname, format_type(a.atttypid, a.atttypmod)
+                from pg_class c, pg_attribute a
+                where c.relname = '$table'
+                and a.attnum > 0 and a.attrelid = c.oid
+                order by a.attnum";
+        if ($mData = $this->db_auto_get_data($query)) {
+            foreach ($mData as $mRow) {
+                $meta_data[$mRow['attname']] = $mRow['format_type'];
+            }
+        }
+        if (is_array($data)) {
+            foreach ($data as $field => $val) {
+                if ($meta_data[$field]) {
+                    switch ($meta_data[$field]) {
+                    case "integer":
+                    case "double precision":
+                        if ($val == '') {
+                            $proc_data[$field] = 'NULL';
+                        } elseif (is_numeric( $val)) {
+                            $proc_data[$field] = $val;
+                        } else{
+                            die('value for field (int)'.$field.' is not a number');
+                        }
+                        break;
+                    case "boolean":
+                        if ($val == '') {
+                            $proc_data[$field] = 'NULL';
+                        } elseif ($val == 'f' || $val == 't') {
+                            $proc_data[$field] = "'".$val."'";
+                        } else{
+                            die('value for field (boolean)'.$field.' is not a boolean');
+                        }
+                        break;
+                    case "text":
+                        // maybe check to see that the text is being slashed if not then prepare it for postgres
+                        $text = addslashes( stripslashes( trim( $val)));
+                        $proc_data[$field] = "'$text'";
+                        break;
+                    case "date":
+                    if (preg_match( "/([0-9]{1,2})[\/-]?([0-9]{1,2})[\/-]?([0-9]{2,4})|/", $val)) {
+                            $proc_data[$field] = "'".$val."'";
+                    } else{
+                            die('value for field (date)'.$field.' is not a date');
+                    }
+                        break;
+                    default:
+                        die('need case for this name:'.$field.' type: '.$meta_data[$field]);
+                        break;
+                    }
+                } else{
+                    die('Error no field named '.$field.' exist in '.$table);
+                }
+            }
+        } else{
+            return false;
+        }
+        return $proc_data;
+    }
+
+    // }}}
+    // {{{ pgsql_delete()
+
+    /**
+     * pgsql_delete 
+     * 
+     * @param  mixed  $table    
+     * @param  mixed  $condition
+     * @access public
+     * @return string
+     */
+    function pgsql_delete($table, $condition)
+    {
+        reset($condition);
+        $cKey   = key($condition);
+        $query  = "delete from $table where ";
+        $query .= $cKey;
+        $query .= " = ".$condition[$cKey];
+        return $this->db_exec( $query);
+    }
+
+    // }}}
+    // {{{ pgsql_insert()
+
+    /**
+     * pgsql_insert 
+     * 
+     * @param  mixed  $table      
+     * @param  mixed  $data       
+     * @param  mixed  $primary_key
+     * @param  mixed  $sequence   
+     * @access public
+     * @return string
+     */
+    function pgsql_insert($table, $data, $primary_key, $sequence)
+    {
+        $converted = $this->pgsql_convert($table, $data);
+        if ($res = $this->db_exec("select nextval('$sequence') as $primary_key")) {
+            $insert_data = $this->db_fetch_array( $res, 0, PGSQL_ASSOC);
+            $insert_id = $insert_data[$primary_key];
+        } else {
+            die('returned no insert_id');
+        }
+        $query = "INSERT INTO $table ($primary_key,".implode(",",array_keys( $converted)).") values ($insert_id,".implode(",",array_values( $converted)).")";
+        if ($res = $this->db_exec($query)) {
+            $this->insert_id = $insert_id;
+            return $insert_id;
+        } else {
+            echo $query;
+            die('error');
+        }
+    }
+
+    // }}}
+    // {{{ pgsql_select()
+
+    /**
+     * pgsql_select 
+     * 
+     * @param  mixed  $query
+     * @access public
+     * @return string
+     */
+    function pgsql_select($query)
+    {
+        return $this->db_auto_get_data( $query);
+    }
+
+    // }}}
+    // {{{ pgsql_update()
+
+    /**
+     * pgsql_update 
+     * 
+     * @param  mixed  $table    
+     * @param  mixed  $data     
+     * @param  mixed  $condition
+     * @access public
+     * @return string
+     */
+    function pgsql_update($table, $data, $condition)
+    {
+        $converted = $this->pgsql_convert($table, $data);
+        foreach ($converted as $key => $value) {
+            $q_parts[] = "$key = $value";
+        }
+        reset($condition);
+        $cKey = key($condition);
+        if (is_array($converted)) {
+            $query = "update $table set ";
+            if (is_array($q_parts)) {
+                $query .= implode(",",$q_parts);
+            }
+            $query .= " where ";
+            $query .= $cKey;
+            $query .= " = ".$condition[$cKey];
+        }
+        $this->db_exec($query);
+    }
+
+    // }}}
+    // {{{ select()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $query Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function select($query)
+    {
+        return $this->db_auto_get_data($query);
+    }
+
+    // }}}
+    // {{{ trans_end()
+
+    /** trans_end
+     *
+     * Commit the postgres transaction  
+     *
+     * {@source } 
+     * @returns bool true if successful
+    * @access  public
+     */
+    function trans_end() 
+    {
+        if (!$this->trans) {
+            if(!$this->db_exec("COMMIT WORK;")) {
+                return false;
+            } else{
+                return true;
+            }
+        } else{
+            return false;
+        }
+    }
+
+    // }}}
+    // {{{ trans_exec()
+
+    /** trans_exec
+    *
+    *  exec a postgres query in a 
+    *  postgres transaction
+    *
+    * {@source } 
+    * @param  string query
+    * @access public
+    */
+    function trans_exec($query)
+    {
+        if ($query != "") {
+            if(!$ret = $this->db_exec($query)) {
+                $this->db_exec("ABORT WORK;");
+                return false;
+            } else {
+                return $ret;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    // }}}
+    // {{{ trans_start()
+
+    /** trans_start
+    *
+    * Start a postgres transaction 
+    *
+    * {@source } 
+    * @returns bool true if sucessful
+    * @access  public
+    */
+    function trans_start()
+    {
+        if (!$this->trans) {
+            if (!$this->dbd = $this->db_connect()) {
+                $this->trans = false;
+                return false;
+            } else {
+                $this->db_exec("BEGIN WORK;");
+                $this->trans = true;
+                return true;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    // }}}
+    // {{{ update()
+
+
+    /**
+     * Short description for function
+     * 
+     * Long description (if any) ...
+     * 
+     * @param  unknown $table     Parameter description (if any) ...
+     * @param  unknown $data      Parameter description (if any) ...
+     * @param  unknown $condition Parameter description (if any) ...
+     * @return unknown Return description (if any) ...
+     * @access public 
+     */
+    function update($table, $data, $condition)
+    {
+        return $this->pgsql_update($table, $data, $condition);
+    }
+
+    // }}}
+}
+?>
diff --git a/classes/class_template.inc b/classes/class_template.inc
new file mode 100644 (file)
index 0000000..4458341
--- /dev/null
@@ -0,0 +1,2903 @@
+<?php
+/**
+ * Toolbox Classes :)
+ *
+ * @package Toolbox Library
+ * @subpackage Template Library
+ * @filesource
+ */
+
+require_once BASE."classes/class_db.inc";
+require_once BASE."classes/class_toolbox.inc";
+
+/**
+ *     Template Class :)
+ *
+ * <p>
+ * $Id: class_template.inc,v 1.41 2010/01/29 15:27:58 jamie Exp $
+ * NOTE: for the search engine freindly url's use .htaccess file.
+ * need to make sure .htaccess is enabled or this work work
+ * to turn off seo url's set define SEO_URL to 0 in setup file
+ * NOTE: make sure you redo the www.domain.com lines in the .htaccess file
+ * need to set it up before testing with it.
+ * </p>
+ * <p>
+ * For the page title and meta tags make a $title and $meta vars depending on
+ * weather or not it is the home page.
+ * </p>
+ *
+ * @package Toolbox Library
+ * @subpackage Template Library
+ * @category Template
+ * @author Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2007
+ * @version $Revision: 1.41 $
+ * @since $Date: 2010/01/29 15:27:58 $
+ * @todo update the phpdocs for all classes
+ * @todo add title for all the navigation links if and only if they have page title
+ * @todo some tutorial in the docs for how to set things up.
+ */
+class GLM_TEMPLATE
+{
+       //      {{{ properties
+
+       /**
+        * The category id for the page
+        * @var integer
+        * @access public
+        */
+       public $catid;
+
+       /**
+        * The postgres database handler
+        * @var object
+        * @access public
+        */
+       public $DB;
+
+       /**
+        * The starting style for the header
+        *
+        * class="content" should not be used anymore
+        *
+        * @var string
+        * @access protected
+        */
+       protected $header_begin = '<h1>';
+
+       /**
+        * The ending style for the header
+        * @var string header_end
+        * @access protected
+        */
+       protected $header_end = '</h1>';
+
+       /**
+        * The starting style for the sub header
+        * @var string
+        * @access protected
+        */
+       protected $subheader_begin = '<h2>';
+
+       /**
+        * The ending style for the sub header
+        * @var string
+        * @access protected
+        */
+       protected $subheader_end = '</h2>';
+
+       /**
+        * The starting position for images
+        *
+        * @var string
+        * @access protected
+        */
+       protected $img_align = 'left';
+
+       /**
+        * Whether to alternate the images or not
+        *
+        * for alternating images set to 1 else leave alone
+        *
+        * @var string
+        * @access protected
+        */
+       protected $img_alternate = 1;
+
+       /**
+        * The path to the image directory
+        * @var string
+        * @access protected
+        */
+       protected $img_size;
+
+       /**
+        * The category array
+        * @var array
+        * @access protected
+        */
+       protected $data;
+
+       /**
+        * The items array
+        * @var array
+        * @access protected
+        */
+       protected $items;
+
+       /**
+        * @var string type The type
+        */
+       protected $type;
+
+       /**
+        * Used for menu generation
+        * @var string whole_thread The thread string
+        */
+       protected $whole_thread = null;
+
+       /**
+        * Used for menu generation
+        * @var integer thread_count The thread count
+        */
+       protected $thread_count = 1;
+
+       /**
+        * @var array $pages
+        * @access protected
+        */
+       protected $pages;
+
+       /**
+        * adds active = 't' to queries only if ACTIVE_FLAG is set to true
+        * @var string
+        * @access protected
+        */
+       protected $active_query;
+
+       /**
+        * determines page layout
+        * @var integer
+        * @access protected
+        */
+       protected $template;
+
+       /**
+        * Page extension for php pages .php or .phtml
+        * @var string
+        * @access protected
+        */
+       protected $php_ext = '.php';
+
+       //      }}}
+       //      {{{ __construct()
+
+       /**
+        * GLM_TEMPLATE
+        *
+        * @param mixed $catid current page category id
+        * @param mixed $DB Object passed from GLM_DB if done
+        * @access public
+        * @return string
+        */
+       function __construct($catid, $DB = NULL)
+       {
+        // set the cache option from $GLOBALS
+        $this->cacheOptions = $GLOBALS['cacheOptions'];
+        // redo the cachDir
+        $this->cacheOptions['cacheDir'] = BASE . 'cache/';
+        // create a new instance of Cache_Lite
+        $this->cache =& new Cache_Lite($this->cacheOptions);
+               $this->catid = $this->get_catid($catid);
+               // using a reference to $DB (should be started on setup.phtml
+               $this->set_DB(&$DB);
+        // switching to $GLOBALS['dbh']
+        $this->dbh = Toolkit_Database::getInstance();
+               // used for cvb's
+               $this->Member = $this->set_member();
+               // img_size are RESIZED, MIDSIZED, THUMB do not use ORIGINAL
+               $this->img_size = RESIZED;
+
+               $this->set_body_tag();
+               // Uses the PAGE array set in setup.phtml
+               $this->set_pages(&$GLOBALS['PAGES']);
+               // tell if page is active, deleted or inactive
+               $this->page_status($catid);
+               // set active query string
+               $this->set_active_query();
+       }
+
+       //      }}}
+
+       //      {{{ build_picklist()
+
+       /**
+        * build_picklist:
+        * @param string $fieldname:
+        * @param array $data:
+        * @param mixed $selected:
+        * @param string $type = "standard":
+        * @param boolean $auto = 0:
+        * @param integer $width = NULL :
+        *
+        * @uses GLM_TOOLBOX::build_picklist()
+        *
+        * @return string
+        * @access  public
+        */
+       function build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL )
+       {
+               return GLM_TOOLBOX::build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL );
+       }
+
+       //      }}}
+
+       //      {{{ clean_text()
+
+       /**
+       * clean_text:get rid of single br or p br tags left from htmlarea when textarea is empty.
+       * @param string $output:
+       *
+       * @return string text cleaned
+       * @access  public
+       **/
+       function clean_text($output)
+       {
+               $output = str_replace("<br />","<br>",$output);
+               $output = str_replace("<p><br></p>","",$output);
+               return $output;
+       }
+
+       //      }}}
+       //      {{{     convert_to_thread()
+
+       /**
+        * convert_to_thread:
+        *
+        * @param array $threads:
+        * @param array $thread:
+        * @uses GLM_TEMPLATE::$thread_count
+        * @uses GLM_TEMPLATE::$whole_thread
+        * @uses GLM_TEMPLATE::get_seo_url()
+        * @uses GLM_TEMPLATE::convert_to_thread()
+        *
+        * @return string
+        * @access public
+        */
+       function convert_to_thread($threads, $thread)
+       {
+               foreach($thread as $parent=>$value) {
+                       $this->whole_thread .= str_repeat(".",$this->thread_count);
+                       $this->whole_thread .= "|".htmlentities($value['category'],ENT_QUOTES,'UTF-8');
+                       $url = $this->get_seo_url( $value['id'] );
+                       $this->whole_thread .= "|$url";
+                       $this->whole_thread .= "\n";
+                       if ($threads[$parent]) {
+                               $this->thread_count++;
+                               GLM_TEMPLATE::convert_to_thread($threads, $threads[$parent]);
+                       }
+               }
+               $this->thread_count--;
+               return $this->whole_thread;
+       }
+
+       //      }}}
+
+       //      {{{     has_children()
+
+       /**
+        * has_children: return true or false if this category has sub categories under it.
+        *
+        * @param integer $catid:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function has_children($catid)
+       {
+               // returns number of children that $catid has
+               $qs = "
+            SELECT count(*)
+              FROM bus_category
+             WHERE parent = $catid {$this-> active_query}";
+               $row=$this->DB->db_auto_get_data($qs);
+               return $row[0]['count'];
+       }
+
+       //      }}}
+       //      {{{ has_subs()
+
+       /**
+        * has_subs:
+        * @param integer $catid:
+        * @param object $DB:
+        *
+        * @uses GLM_TEMPLATE::$active_query
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function has_subs($catid, &$DB)
+       {
+               $sql = "
+            SELECT id
+              FROM bus_category
+             WHERE parent = $catid {$this->active_query}
+             ORDER BY pos";
+               $data = $DB->db_auto_get_data($sql);
+               return is_array($data);
+       }
+
+       //      }}}
+
+       //      {{{ get_all()
+
+       /**
+       * get_all:Does the query and set_data calls boths arrays
+       *
+       * @uses GLM_TEMPLATE::set_data()
+       * @uses GLM_TEMPLATE::$data
+       * @uses GLM_TEMPLATE::$items
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return void
+       * @access public
+       **/
+       function get_all($type = NULL)
+       {
+               $catid = $this->catid;
+               if ($type == 1 || !$type) {
+            $cat_query = "
+            SELECT *
+             FROM bus_category
+            WHERE id = $catid
+         ORDER BY pos";
+            try {
+                $res = $this->set_data($this->dbh->query($cat_query)->fetchAll());
+                $this->data = $res[0];
+            } catch(PDOException $e) {
+                echo '<pre>'.print_r($e, true).'</pre>';
+                die($e->getMessage());
+            }
+               }
+               //$this->img_size = MIDSIZED;
+               //$this->img_size = RESIZED;
+               if ($type == 2 || !$type) {
+            $item_query = "
+            SELECT b.*
+              FROM bus b
+                LEFT OUTER JOIN bus_category_bus bcb ON (bcb.busid = b.id)
+             WHERE bcb.catid = $catid
+          ORDER BY bcb.pos";
+            try {
+                $this->items = $this->set_data($this->dbh->query($item_query)->fetchAll());
+            } catch(PDOException $e) {
+                echo '<pre>'.print_r($e, true).'</pre>';
+                die($e->getMessage());
+            }
+            $file_query = "
+            SELECT *
+             FROM files
+            WHERE bus_id IN ( SELECT bus_id FROM bus_category_bus
+            WHERE catid = ".$this->catid." )
+         ORDER BY bus_id,pos;";
+            try {
+                $file_data = $this->DB->db_auto_get_data($file_query);
+            } catch(PDOException $e) {
+                echo '<pre>'.print_r($e, true).'</pre>';
+                die($e->getMessage());
+            }
+                       if (is_array($file_data)) {
+                               foreach ($file_data as $file_row) {
+                                       $this->item_files[$file_row['bus_id']][] = GLM_TEMPLATE::set_file( $file_row['filename'],$file_row['urltext'] );
+                               }
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ get_ancestors()
+
+       /**
+        * get_ancestors:get the ancestors for this category
+        *
+        * @param integer $catid: catid
+        * @param integer $count: starting counter
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return array
+        * @access  public
+        */
+       function get_ancestors($catid, $count)
+       {
+               if ($count == 0 ) {
+                       unset ($this->ancestors);
+               }
+
+               if ($catid) {
+                       $query = "
+                               SELECT id,category,parent
+                             FROM bus_category
+                            WHERE id = ".$catid."
+                            ".$this->active_query;
+
+                       $res = $this->DB->db_auto_get_data($query);
+                       $id = $res[0]['id'];
+                       $parent = $res[0]['parent'];
+                       $category = $res[0]['category'];
+                       $this->ancestors[$count]['id'] = $id;
+                       $this->ancestors[$count]['label'] = $category;
+
+                       $url = $this->get_seo_url( $id );
+                       $this->ancestors[$count]['link'] = $url;
+                       GLM_TEMPLATE::get_ancestors($parent,$count+1);
+
+                       return array_reverse($this->ancestors);
+               }
+       }
+
+       //      }}}
+       //      {{{ get_base_url()
+
+       /**
+        * get_base_url: generate the base of the url for the given category id
+        * @param integer $id :
+        *
+        * @return string
+        * @access public
+        */
+       function get_base_url($id)
+       {
+               if ($this->pages[$id]) {
+                       $page = $this->pages[$id];
+               } else {
+                       $page = $this->pages['default'];
+               }
+               if ($GLOBALS['GLM_SERVER_ID'] == 'ws1.gaslightmedia.com' &&
+                       $this->catid == 1) {
+                       $page = '';
+               }
+               return $page;
+       }
+
+       //      }}}
+       //      {{{ get_bottom_banner()
+
+       function get_bottom_banner(){
+               $banner = new BANNER_ADS();
+               $banner->get_banners();
+               $out = $banner->show_banners();
+               return $out;
+       }
+
+       //      }}}
+       //      {{{     get_bottom_nav()
+
+       /**
+        * get_bottom_nav: generate a top level only bottom navigation for the pages.
+        *
+        * @param integer $parent=0:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access public
+        */
+       function get_bottom_nav($parent=0)
+       {
+               $out = '';
+               $query = "select id,category,intro from bus_category where id != 1 and parent = $parent ".$this->active_query." order by pos asc";
+               $row = $this->DB->db_auto_get_data( $query );
+               $url = $this->get_seo_url( HOME_ID );
+               $links[] = '<a href="'.$url.'">Home</a>';
+               if (!is_array( $row ) ) {
+                       return false;
+               } else {
+                       $out .= '<div id="nav-bottom">';
+                       for ($i = 0; $i < sizeof($row); $i++) {
+                               $category = htmlentities(strip_tags($row[$i]['category']),ENT_QUOTES,'UTF-8');
+                               $url = $this->get_seo_url( $row[$i]['id'] );
+                               $links[] = '<a href="'.$url.'">'.$category."</a>\n";
+                       }
+                       if (is_array($links)) {
+                               $out .= implode(" | ",$links);
+                       }
+                       $out .= '</div>';
+                       return $out;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_bread_crumbs()
+
+       /**
+        * get_bread_crumbs
+        *
+        * @param mixed $catid
+        * @access public
+        * @return string
+        */
+       function get_bread_crumbs($catid)
+       {
+               $string = $this->get_ancestors($catid, 0);
+               $isMemberProfilePage = (   isset($_GET['member_id'])
+                                                               && ctype_digit($_GET['member_id']));
+               if (is_array($string)) {
+                       //      adjust end if we have a profile page so we can last search
+                       //      page as link.
+                       $end = $isMemberProfilePage ? count($string) : count($string) - 1;
+                       if ($this->catid != HOME_ID) {
+                               $outarray[] = '<a href="'.BASE_URL.'">Home</a>';
+                       }
+                       for($i = 0; $i < $end; ++$i) {
+                               $outarray[] = '<a href="'.$string[$i]["link"].'">'.$string[$i]["label"].'</a>';
+                       }
+                       if (  isset($_GET['photo_catid'])
+                               && defined('PHOTO_GALLERY')
+                               && PHOTO_GALLERY
+                               && ctype_digit($_GET['photo_catid'])
+                       ) {
+                               //      user is now in a photo gallery albumn.
+                               //      need to update the breadcrumbs for this.
+                               $currPageUri = $this->get_seo_url($catid);
+                               $currPageLabel = $this->get_catheader($catid, &$this->DB);
+
+                               $outarray[] = '<a href="'.$currPageUri.'">'.$currPageLabel.'</a>';
+
+                               $sql = "
+                                       SELECT category
+                                         FROM photo_category
+                                        WHERE id = :id";
+
+                               $stmt = $this->dbh->prepare($sql);
+                               $stmt->bindParam(':id', $_GET['photo_catid'], PDO::PARAM_INT);
+                               $stmt->execute();
+                               $stmt->bindColumn('category', $photoCategory);
+                               $stmt->fetch();
+
+                               $outarray[] = $photoCategory;
+                       } else {
+                               if (!$isMemberProfilePage) {
+                                       $outarray[] = $this->get_catheader($catid, &$this->DB);
+                               } else {
+                                       //      Is a member profile page, attach member name to end
+                                       //      of breadcrumbs
+                                       $sql = "
+                                               SELECT member_name
+                                                 FROM member
+                                                WHERE member_id = :mid";
+
+                                       $stmt = $this->dbh->prepare($sql);
+                                       $stmt->bindParam(':mid', $_GET['member_id'], PDO::PARAM_INT);
+                                       $stmt->execute();
+                                       $stmt->bindColumn('member_name', $memberName);
+                                       $stmt->fetch();
+
+                                       $outarray[] = $memberName;
+                               }
+                       }
+                       $out = '';
+                       if (is_array($outarray) && count($outarray) > 1) {
+                               $out .= implode(" &gt; ", $outarray);
+                       }
+                       if ($out) {
+                               $return = '<div id="breadcrumbs">'.$out.'</div>';
+                       }
+               }
+               return $return;
+       }
+
+       //      }}}
+       //      {{{ get_category()
+
+       /**
+       * get_category: grab just category contents
+       * @param integer $catid: id of bus_category
+       * @param object $DB:
+       * @param boolean $showimg=1: weather or not to show category image
+       * @uses DELUXE_TOOLBOX
+       * @uses HOME_PAGE_EVENTS
+       * @uses GLM_TEMPLATE::clean_text()
+       * @uses GLM_TEMPLATE::get_home_events()
+       *
+       * @return string $output
+       * @access public
+       **/
+       function get_category($showimg = 1, $showdiv = 1)
+       {
+        if ($pageContent = $this->cache->get('page-'.$this->catid, 'Toolbox')) {
+            $sql = "
+            SELECT intro
+              FROM bus_category
+             WHERE id = :id";
+            try {
+                $stmt = $this->dbh->prepare($sql);
+                $stmt->bindParam(":id", $this->catid, PDO::PARAM_INT);
+                $stmt->execute();
+                $this->data['intro'] = $this->set_header($stmt->fetchColumn());
+            } catch(PDOException $e) {
+                Toolkit_Common::handleError($e);
+            }
+            return $pageContent;
+        } else {
+            if (DELUXE_TOOLBOX) {
+                $this->get_template("cat");
+            }
+            if (!$this->data) {
+                $this->get_all(1);
+            }
+            $data = $this->data;
+            // Setup the section_links boolean var so section links only
+            // show up on correct pages.
+            $this->section_links = ($data['section_links'] == 't');
+            if (   !$data["image"]
+               && !$data["description"]
+               && !$data["intro"] &&
+                ($this->catid != 1 && HOME_PAGE_EVENTS != true)
+            ) {
+                return false;
+            }
+
+            $output = '';
+            if ($showdiv == 1) {
+                $output .= '<div id="category">';
+            }
+
+            if ($this->catid == 1 && HOME_PAGE_EVENTS ) {
+                $output .= $this->get_home_events();
+            }
+
+            if ($data["image"] || $data["description"] || $data["intro"]) {
+            // $output .= $data["intro"] . ' ';
+                if ($showimg == 1) {
+                    $output .= $data["image"] . ' ';
+                }
+                $output .= $data["description"] . ' ';
+            }
+
+            if ($showdiv == 1) {
+                $output .= '</div>';
+            }
+            $output = GLM_TEMPLATE::clean_text($output);
+            $this->cache->save($output, 'page-'.$this->catid, 'Toolbox');
+            return $output;
+        }
+
+       }
+
+       //      }}}
+       //      {{{ get_category_name()
+
+       /**
+        * getCategoryName:
+        * used mostly for getting category name for search engine friendly url's
+        *
+        * @param integer $id:
+        * @param string $table:
+        * @param object &$DB :
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access public
+        */
+       function get_category_name( $id, $table,&$DB )
+       {
+               if (!is_numeric($id)) {
+                       return false;
+               }
+               if ($table == "class_category") {
+                       $category = "name";
+               } else {
+                       $category = "category";
+               }
+        $query = "
+        SELECT {$category}
+          FROM {$table}
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $id, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetchAll();;
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+               if (is_array($data)) {
+
+                       $add = '-'.$id;
+                       if ($data[0]['category']) {
+                               $category = $data[0]['category'].$add;
+                       } elseif ($data[0]['name']) {
+                               $category = $data[0]['name'].$add;
+                       } else {
+                               $category = $add;
+                       }
+                       return htmlspecialchars($category);
+               }
+       }
+
+       //      }}}
+       //      {{{ get_catheader()
+
+       /**
+        * get_catheader:output the category name.
+        *
+        * @param integer $catid: The catid for the page
+        * @param object $DB: db obj
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access  public
+        */
+       function get_catheader($catid,$DB)
+       {
+               $query = "SELECT category FROM bus_category WHERE id = $catid";
+               $data = $DB->db_auto_get_data($query);
+               if ($data[0]['category']!="") {
+                       $header = strip_tags($data[0]['category']);
+               } else {
+                       $header = '';
+               }
+               return $header;
+       }
+
+       //      }}}
+       //      {{{ get_catid()
+
+       /**
+        * get_catid: setting catid for class
+     *
+        * We should be using the $_POST or $_GET globals here
+        *
+        * @return int catid
+        * @access public
+        **/
+       function get_catid($catid)
+       {
+               if (is_numeric($_GET['catid'])) {
+                       return $_GET['catid'];
+               } elseif (is_numeric($_POST['catid'])) {
+                       return $_POST['catid'];
+               } else {
+                       return $this->catid = $catid;
+               }
+       }
+
+       //      }}}
+       //      {{{     get_catintro()
+
+       /**
+        * get_catintro: return the category page name.
+        *
+        * @param integer $catid: The catid for the page
+        * @param object $DB: db obj
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access  public
+        */
+       function get_catintro($catid)
+       {
+               $query = "SELECT intro FROM bus_category WHERE id = $catid";
+               $data = $this->DB->db_auto_get_data($query);
+               if ($data[0]['intro']!="") {
+                       $header = strip_tags($data[0]['intro']);
+               } else {
+                       $header = '';
+               }
+               return $header;
+       }
+
+       //      }}}
+       //      {{{ get_distance_from_traverse()
+
+       function get_distance_from_traverse( $zipcode ){
+               if (is_numeric( $zipcode ) ){
+                       // zipcode for search is 49684
+                       $tlat = (float)44.77329;
+                       $tlon = (float)-85.70123;
+                       $zipDB =& new GLM_DB();
+                       $zipDB->host = 'ds1';
+                       $zipDB->dbname = 'zip';
+                       $zipDB->pgsql_select( "BEGIN WORK;" );
+                       $query = "
+                SELECT lat, lon, city, state_name
+                  FROM zip
+                 WHERE zipcode = '$zipcode'
+                 order by city_type desc limit 1 offset 0;";
+                       if ($data = $zipDB->pgsql_select( $query ) ){
+                               $lat = (float)$data[0]['lat'];
+                               $lon = (float)$data[0]['lon'];
+                               $city = $data[0]['city'];
+                               $state = $data[0]['state_name'];
+                       }
+
+                       $temp = "(pow(sin( ( ( $tlat * pi()/180.0 ) - ( $lat * pi()/180.0 )) /2.0),2) + cos( ( $lat * pi()/180.0 )) * cos( ( $tlat * pi()/180.0 ) ) * pow(sin( ( ( $tlon * pi()/180.0 ) - ( $lon * pi()/180.0 )) /2.0),2))";
+                       $query = "select ceil(3956 * 2 * atan2(sqrt($temp ),sqrt(1- ($temp) ))) as distance";
+                       if ($zip_data = $zipDB->pgsql_select( $query ) ){
+                               $zipDB->pgsql_select( "ABORT WORK;" );
+                               $zdata['remote_addr'] = $_SERVER['REMOTE_ADDR'];
+                               $zdata['zipcode'] = $zipcode;
+                               $zdata['city'] = $city;
+                               $zdata['state'] = $state;
+                               $this->DB->pgsql_insert( 'zip_dist_form', $zdata, 'zip_dist_form_id', 'zip_dist_form_zip_dist_form_id_seq', true );
+                               return $zip_data[0]['distance'];
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ get_event_date()
+
+       /**
+        * get_event_date: make the event date human readable
+        * @param string $sdate: start date
+        * @param string $edate: end date
+        * @param string $dateType: dateType Postgres,etc
+        *
+        * @return string
+        * @access public
+        */
+       function get_event_date($sdate,$edate,$dateType)
+       {
+               switch($dateType) {
+                       case "Postgres":
+                               if (preg_match("/([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})/",$sdate,$spt)) {
+                                       $mon = $spt[1];
+                                       $day = $spt[2];
+                                       $yr = $spt[3];
+                               }
+
+                               if (preg_match("/([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})/",$edate,$ept)) {
+                                       $mon2 = $ept[1];
+                                       $day2 = $ept[2];
+                                       $yr2 = $ept[3];
+                               }
+                               break;
+
+                       case "timestamp":
+                               $mon = date("m",$sdate);
+                               $day = date("d",$sdate);
+                               $yr = date("Y",$sdate);
+                               $mon2 = date("m",$edate);
+                               $day2 = date("d",$edate);
+                               $yr2 = date("Y",$edate);
+                               break;
+
+               }
+
+               $start = mktime(0,0,0,$mon,$day,$yr);
+               $end = mktime(0,0,0,$mon2,$day2,$yr2);
+               if ($day == $day2 && $mon == $mon2 && $yr == $yr2) {
+                       $dateparam = "M j, Y";
+                       $date_begin = date($dateparam, $start) ;
+                       $date_end = "";
+               } elseif ($day == $day2 AND $mon == $mon2 AND $yr != $yr2) {
+                       $dateparam1 = "M j, Y -";
+                       $dateparam2 = "Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } elseif ($day != $day2 AND $mon == $mon2 AND $yr == $yr2) {
+                       $dateparam1 = "M j -";
+                       $dateparam2 = "j, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } elseif ($day != $day2 AND $mon == $mon2 AND $yr != $yr2) {
+                       $dateparam1 = "M j, Y -";
+                       $dateparam2 = "M j, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } elseif ($yr == $yr2) {
+                       $dateparam1 = "M j -";
+                       $dateparam2 = "M j, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               } else {
+                       $dateparam1 = "M j, Y -";
+                       $dateparam2 = "M j, Y";
+                       $date_begin = date($dateparam1, $start);
+                       $date_end = date($dateparam2, $end);
+               }
+
+               return $date_begin." ".$date_end;
+       }
+
+       //      }}}
+       // {{{ get_headlines()
+       function get_headlines(){
+               $headlines = array();
+               $query = "
+          SELECT id,intro,feature_intro,description,image
+            FROM bus_category
+           WHERE featured = 't'
+             AND active = 't'
+        ORDER BY parent,pos;";
+               if( $data = $this->DB->pgsql_select( $query ) ){
+                       foreach( $data as $row ){
+                               $headlines[] = array(
+                    'href'   => $this->get_seo_url($row['id']),
+                    'img'    => ($row['image']) ? THUMB . $row['image']: '',
+                    'header' => $row['feature_intro'],
+                    'descr'  => GLM_TOOLBOX::make_teaser($row['description'], 150, true));
+                       }
+               }
+               return $headlines;
+       }// }}}
+       // {{{ get_home_events()
+       /**
+       * get_home_events: get events flaged as home events
+       * @param object $DB: DB reference to DB obj
+       *
+       * @uses GLM_TEMPLATE::get_event_date()
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return void
+       * @access public
+       **/
+       public function get_home_events($limit = 3)
+       {
+               $query = "
+                 SELECT id, header, descr, bdate, edate, img,
+                                to_char(bdate, 'Mon - DDth') AS sdate
+                   FROM event
+                  WHERE visable='t'
+                    AND edate >= current_date
+             AND home='t'
+        ORDER BY bdate asc, edate asc";
+               $data = $this->DB->db_auto_get_data($query);
+               if(is_array($data)) {
+                       foreach($data as $key => $value) {
+                               $id = $value['id'];
+                               $header = $value['header'];
+                               $title = strip_tags(addslashes($header));
+                               $descr = GLM_TOOLBOX::make_teaser($value['descr'], 250, true);
+                               $sdate = strtotime($value['bdate']);
+                               $edate = strtotime($value['edate']);
+                               $month = date('n',$sdate);
+                               $year = date('Y',$sdate);
+                               $dates = GLM_TEMPLATE::get_event_date($sdate,$edate,"timestamp");
+                               $href = BASE_URL.'index.php?catid='.EVENT_PAGE."&amp;month={$month}&amp;year={$year}&amp;eventid={$id}";
+                               $area_events[] = array(
+                                       'href'   => $href,
+                                       'bdate'  => $value['sdate'],
+                                       'dates'  => $dates,
+                                       'header' => $header,
+                                       'descr'  => $descr,
+                               );
+                       }
+                       return $area_events;
+               } else {
+                       return null;
+               }
+       }// }}}
+       //      {{{ get_hotspecials()
+
+       function get_hotspecials(){
+               $query = "
+            SELECT id, intro, feature_intro
+              FROM bus_category
+             WHERE featured = 't'
+             order by parent, pos;";
+               if ($data = $this->DB->pgsql_select( $query ) ){
+                       $out = '<div id="h-hotspecials">
+                               <span class="h-all">Hot specials</span>';
+                       foreach ($data as $row) {
+                               $intro = htmlspecialchars(strip_tags($row['intro']));
+                               $intro_text = '<p>'.htmlspecialchars(strip_tags($row['feature_intro'] ) ).'</p>';
+                               $out .= '<div class="h-hotspecial">
+                                       <a href="'.$this->get_seo_url( $row['id'] ).'">'.$intro.'</a>
+                                       '.$intro_text.'
+                                       </div>';
+                       }
+                       $out .= '</div>';
+               }
+               return $out;
+       }
+
+       //      }}}
+       //      {{{ get_main_nav()
+
+       function get_main_nav()
+       {
+               $query = "select id,category
+                       from bus_category
+                       where parent = 0
+                       and id not in (".HOME_ID.",".MEMBERS_CATEGORY.",7,8,9)
+                       and active = 't'
+                       order by pos";
+               if ($data = $this->DB->pgsql_select( $query ) ){
+                       $out = '<ul id="nav">';
+                       foreach( $data as $row ){
+                               $out .= '<li><a href="'.$this->get_seo_url( $row['id'] ).'">'.$row['category'].'</a></li>';
+                       }
+                       $out .= '</ul>';
+               }
+               return $out;
+       }
+
+       //      }}}
+       //      {{{     get_menu_array()
+
+
+       /**
+        * get_menu_array: like get_menu_string but returns an array
+        *
+        * @uses GLM_TEMPLATE::sort_childs()
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function get_menu_array()
+       {
+               $query = "
+            SELECT id, parent, category
+              FROM bus_category
+             WHERE id != 0 {$this->active_query}
+             order by parent, pos";
+               $data = $this->DB->db_auto_get_data($query);
+               $newdata = GLM_TEMPLATE::sort_childs($data);
+               return $newdata;
+       }
+
+       //      }}}
+       //      {{{ get_main_cats()
+
+       /**
+        * get_main_cats
+        *
+        * @access public
+        * @return string
+        */
+       function get_main_cats()
+       {
+               static $main_cats_array;
+               if (!is_array($main_cats_array)) {
+                       $query = "
+                SELECT id, category
+                  FROM bus_category
+                 WHERE parent = 0
+                 order by pos;";
+                       if ($data = $this->DB->db_auto_get_data( $query ) ) {
+                               foreach ($data as $row) {
+                                       $main_cats_array[$row['id']] = htmlentities(strip_tags($row['category']),ENT_QUOTES,'UTF-8');
+                               }
+                       }
+               }
+               return $main_cats_array;
+       }
+
+       //      }}}
+       //      {{{ get_menu_string()
+
+       /**
+        * get_menu_string:get categories for the phplayermenu
+        *
+        * @uses GLM_TEMPLATE::sort_childs()
+        * @uses GLM_TEMPLATE::convert_to_thread()
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return string
+        * @access  public
+        **/
+       function get_menu_string()
+       {
+               $query = "
+            SELECT id, parent, category
+              FROM bus_category
+             WHERE id != 0 {$this->active_query}
+             ORDER BY parent, pos";
+               $data = $this->DB->db_auto_get_data($query);
+               $newdata = GLM_TEMPLATE::sort_childs($data);
+               $string = GLM_TEMPLATE::convert_to_thread($newdata,$newdata[0]);
+               return $string;
+       }
+
+       //      }}}
+       //      {{{ get_id_from_name()
+
+       /**
+        * getIdFromName:
+        *
+        * @param string $name:
+        * @param string $table:
+        * @param object $DB:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @deprecated Don't use this!  THIS IS A WARNING (this funcion will be gone next time)
+        * @return string
+        * @access  public
+        */
+       function get_id_from_name( $name, $table, &$DB)
+       {
+               if ($name == "") {
+                       return 0;
+               }
+               if (is_numeric($name)) {
+                       return $name;
+               }
+        $pattern = "/(.*)/$/";
+               if (preg_match($pattern, $name, $tmp)) {
+                       $name = $tmp[1];
+               }
+               $category = "category";
+        $pattern = "/-([0-9]*)$/";
+               if (preg_match($pattern, $name, $tmp)) {
+                       $id = $tmp[1];
+                       return $id;
+               }
+               // should already be returning id at this point
+               // putting the _id on the end of all url's as
+               // the other way is very inifiecent for the database.
+               $name = str_replace( "-"," ",$name );
+               $query = "select id from $table where trim(lower(replace(replace(replace(replace(replace(replace($category,'\'',''),'/',''),'-',' '),'#',''),'&',''),'?',''))) = '".trim(strtolower($name))."'";
+               $data = $DB->db_auto_get_data($query);
+               if (is_array($data)) {
+                       foreach ($data as $key => $val) {
+                               $catid = $val['id'];
+                       }
+                       return $catid;
+               } else {
+                       return 0;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_id_from_path_info()
+
+       /**
+        * get_id_from_path_info: takes the path_info and gets a catid from bus_category table
+        * NOTE: not used.
+        *
+        * @deprecated using .htaccess file for this when using seo url's
+        * @return int catid
+        * @access public
+        **/
+       function get_id_from_path_info()
+       {
+               return false;
+       }
+
+       //      }}}
+       //      {{{ get_image_path()
+
+       /**
+        * get_image_path: get image path from the size used
+        *
+        * @uses MIDSIZED_PATH
+        * @uses RESIZED_PATH
+        * @uses THUMB_PATH
+        *
+        * @return path for images
+        * @access public
+        **/
+       function get_image_path()
+       {
+               if (strstr($this->img_size, 'midsized/')) {
+                       return MIDSIZED_PATH;
+               }
+               if (strstr($this->img_size,'resized/')) {
+                       return RESIZED_PATH;
+               }
+               if (strstr($this->img_size,'thumb/')) {
+                       return THUMB_PATH;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_listings()
+
+       /**
+        * template_parser:This function creates data
+        * and items arrays and does the output for the page.
+        *
+        * @uses DELUXE_TOOLBOX
+        * @uses GLM_TEMPLATE::$items
+        * @uses GLM_TEMPLATE::get_template()
+        * @uses GLM_TEMPLATE::get_all()
+        * @uses GLM_TEMPLATE::load_static_page()
+        * @uses GLM_TEMPLATE::clean_text()
+        * @uses GLM_TEMPLATE::$item_files
+        *
+        * @return void
+        * @access public
+        */
+       function get_listings()
+       {
+        if ($paragraphContent = $this->cache->get('paragraphs-'.$this->catid, 'Toolbox')) {
+            return $paragraphContent;
+        } else {
+            // grab category and items into data and items respectfully
+            if (DELUXE_TOOLBOX ) {
+                $this->get_template( "list" );
+            }
+
+            if (!is_array($this->items)) {
+                $this->get_all(2);
+            }
+
+            $output = '';
+            // load any static category page from the static directory
+            // hard codded content would have $catid.phtml page for it
+            //$output .= $this->load_static_page();
+            if (is_array($this->items)) {
+               $anchors = array();
+                foreach($this->items as $key=>$val) {
+                    // building array with links to each paragraph
+                    $name = trim(strip_tags($val["name"]));
+                    if ($name && $this->section_links) {
+                        $anchors[] = '<a href="#sect-'.$val['id'].'">'.strip_tags($val["name"]).'</a>';
+                    }
+                    // items can be moved around as needed
+                    $output .= '<div class="listing" id="sect-'.$val['id'].'">'."\n";
+                    $output .= $val["name"];
+                    $output .= $val["image"];
+                    $output .= $val["address"];
+                    $output .= $val["description"];
+                    $output .= $val["contactname"];
+                    $output .= $val["email"];
+                    $output .= $val["phone"];
+                    $output .= $val["fax"];
+                    $output .= $val["url"];
+                    if (   isset($this->item_files[$val['id']])
+                       && is_array($this->item_files[$val['id']])
+                    ) {
+                        $output .= implode('', $this->item_files[$val['id']]);
+                    }
+                    if ($val['back_to_top'] == 't') {
+                        $output .= '<a href="#toolbox">Back to Top</a>';
+                    }
+                    $output .= "</div>"."\n";
+                }
+                // assign array of links to $this->sectionAnchors
+                $this->sectionAnchors = $anchors;
+            }
+            $output = GLM_TEMPLATE::clean_text($output);
+            $this->cache->save($output, 'paragraphs-'.$this->catid, 'Toolbox');
+            return $output;
+        }
+       }
+
+       //      }}}
+       //      {{{ get_page()
+
+       /**
+        * get_page: replacing template_parser with get_page function
+        *
+        * @uses GLM_TEMPLATE::get_category() For building the main page section
+        * @uses GLM_TEMPLATE::get_listings() For building out the paragraph sections
+        *
+        * @return  string $out NEED to echo results of this function
+        * @access  public
+        */
+       function get_page($showimg = 1, $showdiv = 1)
+       {
+               if (isset($_REQUEST['sitemap']) && $_REQUEST['sitemap'] == 1) {
+                       return $this->get_sitemap();
+               } elseif (   isset($_REQUEST['zipcode'])
+                                 && is_numeric($_REQUEST['zipcode'])
+               ) {
+                       $this->distance = '<div>'.$this->get_distance_from_traverse($_REQUEST['zipcode']).' miles from '.$_REQUEST['zipcode'].'</div>';
+               }
+
+               if ($this->page_status != 'Good') {
+                       return '<h1>Sorry this page is Down!</h1>';
+               }
+
+               if (   defined('GOOGLE_SEARCH')
+                   && GOOGLE_SEARCH
+                   && isset($_REQUEST['query'])
+                   && $_REQUEST['query']
+               ) {
+                       $out = '<div id="searchcontrol"></div>';
+               } elseif (   isset($_REQUEST['member_id'])
+                                 && is_numeric($_REQUEST['member_id'])
+                                 && !$this->Member->memberSections[$this->catid]
+               ) {
+                       $out = $this->load_static_page();
+               } elseif (   defined('MEMBERS_DB')
+                                 && MEMBERS_DB
+                                 && isset($this->Member->memberSections)
+                                 && $this->Member->memberSections[$this->catid]
+               ) {
+            $GLOBALS['scripts'][]
+                = BASE_URL . 'Toolkit/Members/libjs/travel-list.js';
+            $out = $this->get_bread_crumbs($this->catid);
+                       if (   !isset($_REQUEST['member_id'])
+                && !isset($_REQUEST['search'])
+                && !isset($_REQUEST['start'])
+               ) {
+                               $out .= $this->get_category($showimg,0);
+                $pageHeader  = $this->data['intro'];
+                $out .= '<div id="category">';
+                $out .= $pageHeader;
+              //  $out .= $category;
+                $out .= '</div>';
+                       }
+
+            //  application configuration
+            $conf = new Config;
+            $root =& $conf->parseConfig(
+                               BASE . 'Toolkit/Members/config.ini',
+                               'IniFile'
+                       );
+
+            if (isset($_GET['member_id']) && is_numeric($_GET['member_id'])) {
+                try {
+                    $profile = new Toolkit_Members_ProfilePage(
+                                               Toolkit_Database::getInstance(),
+                        new Toolkit_Image_Server(),
+                        $_GET['member_id']
+                    );
+                    $profile->setCatId($this->catid);
+                    $profile->setConfig($root);
+                    $flexy = new HTML_Template_Flexy(
+                                               Toolkit_Members::getFlexyOptions()
+                                       );
+                    $cache = new Cache_Lite(Toolkit_Members::getCacheOptions());
+                    $out .= $profile->toHtml($flexy, $cache, MEMBER_RESIZED);
+                } catch (PEAR_Exception $e) {
+                    return Toolkit_Common::handleError($e);
+                }
+            } elseif (   isset($_GET['search'])
+                                         || $this->Member->hideUserSearchForm()
+                       ) {
+                               if ($this->Member->includeMemberMap()) {
+                                       $googleMap = new Toolkit_Members_Map();
+                                       $out .= $googleMap->toHtml();
+                               }
+
+                               $searchQuery = new Toolkit_Members_SearchQueryGenerator(
+                                       true,
+                                       $root
+                               );
+                               $sql = $searchQuery->getQuery($this->dbh);
+                $searchList = new Toolkit_Members_SearchList(
+                                       $this->dbh,
+                    50,
+                    null,
+                    null,
+                    true
+                );
+
+                $searchList->setConfig($root);
+                $searchList->setQuery($sql);
+                $searchList->setDefaultSort(array('member_name' => 'ASC'));
+                //  rendering engine to use
+                $rEngine = new Structures_DataGrid_Renderer_Flexy();
+                //  template options to use for template engine
+                $tplOpts  = Toolkit_Members::getFlexyOptions();
+                //  templating  engine to use
+                $tEngine = new HTML_Template_Flexy($tplOpts);
+                $rEngine->setContainer($tEngine);
+
+                $out .= $searchList->toHtml($rEngine);
+            } else {
+                               if ($this->Member->includeMemberMap()) {
+                                       $googleMap = new Toolkit_Members_Map();
+                                       $out .= $googleMap->toHtml();
+                               }
+
+                $action = BASE_URL . "index.php?catid={$this->catid}";
+                $form = new Toolkit_Members_UserSearchForm(
+                    'SearchForm',
+                    'get',
+                    $action,
+                    null,
+                    null,
+                    true
+                );
+                $res = $form->setCatId($this->catid);
+                if (!PEAR::isError($res)) {
+                    $form->setPageMemberCategories($this->dbh);
+                    $form->configureForm($this->dbh, $root);
+                    $out .= $form->toHtml(Toolkit_Members::getFlexyOptions());
+                } else {
+                    return Toolkit_Common::handleError($res);
+                }
+            }
+
+                       if (   !isset($_REQUEST['member_id'])
+                && !isset($_REQUEST['search'])
+                && !isset($_REQUEST['start'])
+            ) {
+                $out .= $this->load_static_page();
+                               $out .= $this->get_listings();
+                       }
+
+                       if (PHOTO_GALLERY) {
+                               $out .= $this->photo_module();
+                       }
+               } else {
+            $breadCrumbs = $this->get_bread_crumbs($this->catid);
+                       $category    = $this->get_category($showimg, 0);
+            $pageHeader  = $this->data['intro'];
+            $static      = $this->load_static_page();
+                       $listings    = $this->get_listings();
+            // generation of the section links to each paragraph
+            if (is_array($this->sectionAnchors)) {
+                $links = '<ul id="paragraphLinks">
+                    ';
+                foreach ($this->sectionAnchors as $anchors) {
+                    $links .= '<li>'.$anchors.'</li>
+                    ';
+                }
+                $links .= '
+            </ul>';
+            }
+            $out  = $breadCrumbs;
+            $out .= '<div id="category">';
+            $out .= $pageHeader;
+            $out .= $links;
+            $out .= $category;
+            $out .= '</div>';
+            $out .= $static;
+            $out .= $listings;
+                       if (PHOTO_GALLERY) {
+                               $out .= $this->photo_module();
+                       }
+               }
+               return $out;
+       }
+
+       //      }}}
+       //      {{{ get_page_header_image()
+
+       function get_page_header_image(){
+               $headers[5] = 'accommodations';
+               $headers[21] = 'arts';
+               $headers[22] = 'beaches';
+               $headers[16] = 'golf';
+               $headers[20] = 'guest';
+               $headers[4] = 'outdoor';
+               $headers[43] = 'reservations';
+               $headers[3] = 'things';
+               $headers[18] = 'winaries';
+               $headers[7] = 'meeting';
+               $headers[8] = 'tour';
+               $headers[9] = 'media';
+               $headers[33] = 'events';
+               $this->header_images = $headers;
+               $top_parent = $this->get_top_parent($this->catid);
+               if ($top_parent && $this->catid != HOME_ID) {
+                       if ($_SERVER['HTTPS'] == "on") {
+                               $base_url = BASE_SECURE_URL;
+                       } else {
+                               $base_url = BASE_URL;
+                       }
+
+                       if ($_SERVER['HTTPS'] != "on") {
+                       return( '
+<div id="topimg">
+       <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="565" height="95" id="accommodations" align="middle">
+               <param name="allowScriptAccess" value="sameDomain">
+               <param value="transparent" name="wmode">
+               <param name="movie" value="'.$base_url.'assets/headers/headers.swf?XMLfile='.$base_url.'assets/headers/'.$headers[$top_parent].'.xml">
+               <param name="quality" value="high">
+               <param name="bgcolor" value="#3D8D3A">
+               <embed wmode="transparent" src="'.$base_url.'assets/headers/headers.swf?XMLfile='.$base_url.'assets/headers/'.$headers[$top_parent].'.xml" quality="high" bgcolor="#ffffff" width="565" height="95" name="accommodations" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">
+       </object>
+</div>
+' );
+                       } else {
+                               return false;
+                       }
+               } else {
+                       return false;
+               }
+       }
+
+       //      }}}
+       //      {{{ get_parent()
+
+       /**
+       * get_parent: get parent for this category
+       *
+       * @param integer $catid: id
+       * @param object $DB: database obj
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return int $parent
+       * @access public
+       **/
+       function get_parent($catid,&$DB)
+       {
+               $query = "
+            SELECT parent
+              FROM bus_category
+             WHERE id = $catid
+             ORDER BY pos";
+               $data = $DB->db_auto_get_data($query);
+               return $data[0]["parent"];
+       }
+
+       //      }}}
+       //      {{{ get_parent_id ()
+
+       function get_parent_id($id)
+       {
+               if (is_numeric($id)) {
+                       $query = "select parent from bus_category where id = $id";
+                       if ($data = $this->DB->pgsql_select($query)) {
+                               return $data[0]['parent'];
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ get_seo_url()
+
+       /**
+        * get_seo_url:
+        * grab category part of the search engine friendly url
+        * looks at define for seo_url to see weather to use the seach engine friendly url's or not
+        *
+        * @param integer $id:
+        * @param boolean $slash = 1 : to put a slash on end or not
+        * @uses BASE_URL
+        * @uses SEO_URL
+        * @uses HOME_ID
+        * @uses GLM_TEMPLATE::$php_ext
+        * @uses GLM_TEMPLATE::set_name_url()
+        * @uses GLM_TEMPLATE::get_category_name()
+        * @uses GLM_TEMPLATE::get_base_url()
+        *
+        * @return string $url for page.
+        * @access public
+        **/
+       function get_seo_url($id, $slash = 1)
+       {
+               if ($id == HOME_ID &&
+                               $GLOBALS['GLM_SERVER_ID'] != 'devsys.gaslightmedia.com') {
+                       return BASE_URL;
+               } elseif ($id == HOME_ID &&
+                               $GLOBALS['GLM_SERVER_ID'] == 'devsys.gaslightmedia.com') {
+                       return BASE_URL.'index.php';
+               }
+               if (   isset($this->category_toolbox)
+                       && is_array($this->category_toolbox)
+                       && in_array($id, $this->category_toolbox)
+               ) {
+                       $category_id = array_search($id, $this->category_toolbox);
+                       $url = BASE_URL.'member.php?category_id='.$category_id;
+                       return $url;
+               }
+        if (in_array($id, array(
+            MEMBERS_PROFILE_FORM_PAGE,
+            MEMBERS_COUPONS_PAGE,
+            MEMBERS_EVENTS_PAGE,
+            MEMBERS_REPORTS_PAGE
+        ))) {
+            switch ($id) {
+            case MEMBERS_PROFILE_FORM_PAGE :
+                return $baseurl . 'memberdb/index.php?Option=Member&amp;Action=Edit';
+            break;
+            case MEMBERS_COUPONS_PAGE :
+                return $baseurl . 'memberdb/index.php?Option=Coupons&amp;Action=List';
+            break;
+            case MEMBERS_EVENTS_PAGE :
+                return $baseurl . 'memberdb/index.php?Option=Events&amp;Action=List';
+            break;
+            case MEMBERS_REPORTS_PAGE :
+                return $baseurl . 'memberdb/index.php?Option=Reports&amp;Action=List';
+            break;
+            }
+        }
+               if (SEO_URL) {
+                       if ($id == 142) {
+                               $base_url = BASE_SECURE_URL;
+                       } else {
+                               $base_url = BASE_URL;
+                       }
+            $url = $base_url;
+                       if (defined("SHORT_URLS") && SHORT_URLS) {
+                static $ShortURL;
+                if (!$ShortURL) {
+                    $ShortURL   = new Toolkit_ShortURL($this->dbh);
+                }
+                $short_url = $ShortURL->getShortUrl($id);
+                if ($short_url) {
+                    return $base_url.$short_url . '/';
+                }
+                       }
+                       $url .= GLM_TEMPLATE::set_name_url(GLM_TEMPLATE::get_category_name($id, "bus_category", $this->DB));
+                       $url = htmlspecialchars(strip_tags($url));
+                       if ($slash) {
+                               $url .= '/';
+                       }
+               } else {
+                       $url = $this->get_base_url($id);
+                       if ($url) {
+                               if ($id == 142) {
+                                       $url = BASE_SECURE_URL.$url;
+                               }else{
+                                       $url = BASE_URL.$url;
+                               }
+                               $url .= $this->php_ext.'?catid='.$id;
+                       } else {
+                               $url = BASE_URL;
+                       }
+               }
+
+               return $url;
+       }
+
+       //      }}}
+       // {{{ get_side_nav()
+
+       function get_side_nav($parent = 0)
+       {
+        if ($navContent = $this->cache->get($this->catid, 'Nav')) {
+            return $navContent;
+        } else {
+            $qs = "
+                SELECT id, category, intro
+                  FROM bus_category
+                 WHERE parent = :parent {$this->active_query}
+                 ORDER BY pos";
+            try {
+                $stmt = $this->dbh->prepare($qs);
+                $stmt->bindParam(":parent", $parent, PDO::PARAM_INT);
+                $stmt->execute();
+                $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
+            } catch(PDOException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+            if (!is_array($data)) {
+                return false;
+            } else {
+               $return = '';
+                foreach ($data as $key => $row) {
+                    $url = $this->get_seo_url($row['id']);
+                    $title = strip_tags(addslashes($row['intro']));
+                    $return .= '<li><a title="' .
+                            htmlentities($title,ENT_QUOTES,'UTF-8') .
+                            '" href="'.$url.'"';
+                    if ($this->catid == $row['id']) {
+                        $return .= ' id="current"';
+                    }
+                    $return .= '>' .
+                        htmlentities($row['category'],ENT_QUOTES,'UTF-8')."</a>";
+                    $hasSubs = $this->has_subs($row['id'], $this->DB);
+                    $isSubId = $this->is_sub_id($this->catid, $row['id'], $this->DB);
+                    $isPage  = $this->catid == $row['id'];
+
+                    if ($hasSubs && ($isSubId || $isPage)) {
+                        $ret2 = $this->make_ul_menu($row['id']);
+                        $return .= $ret2;
+                    }
+                    $return .= '</li>';
+                }
+                $main_cats = $this->get_main_cats();
+                if ($main_cats[$parent]) {
+                    $return = '<h2>'.$this->get_catheader($parent, &$this->DB).'</h2>
+                    <ul>'.$return.'</ul>';
+                    $this->cache->save($return, $this->catid, 'Nav');
+                    return $return;
+                } else {
+                    $return = "\n<ul>$return</ul>\n";
+                    return $return;
+                }
+            }
+        }
+       }
+
+       // }}}
+       //      {{{ get_sitemap()
+
+       function get_sitemap(){
+               // sitemap.inc goes here
+               // maybe make a sitemap class
+       }
+
+       //      }}}
+       //      {{{ get_sub_nav()
+
+       /**
+       * get_sub_nav:
+       * @param integer $catid:
+       * @param object $DB:
+       *
+       * @uses GLM_TEMPLATE::get_parent()
+       * @uses GLM_TEMPLATE::get_seo_url()
+       * @uses GLM_TEMPLATE::is_sub_id()
+       * @uses GLM_TEMPLATE::get_sub_nav()
+       * @uses GLM_TEMPLATE::has_subs()
+       * @uses GLM_DB::db_auto_get_data()
+       *
+       * @return  string
+       * @access  public
+       **/
+       function get_sub_nav($catid,&$DB)
+       {
+               $parentid = GLM_TEMPLATE::get_parent($catid,&$DB);
+               //echo $parentid.'<br>';
+               $query = "SELECT id,category,intro FROM bus_category WHERE parent = $parentid ".$this->active_query." ORDER BY pos";
+               $data = $DB->db_auto_get_data($query);
+               if (is_array($data)) {
+                       $output = '<div id="subnav">';
+                               $counter = 1;
+                               foreach($data as $key=>$val) {
+                                       $url = $this->get_seo_url( $val['id'] );
+                                       $title = strip_tags(addslashes($val['intro']));
+                                       if (GLM_TEMPLATE::is_sub_id($catid,$parentid,&$DB) && (GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) || $val['id'] == $catid) ) {
+                                               $output .=  '<a title="'.$title.'" class="current" href="'.$url.'">';
+                                       } else {
+                                               $output .=  '<a title="'.$title.'" href="'.$url.'">';
+                                       }
+                                       $output .=  $val["category"];
+                                       $output .=  '</a>';
+                                       if (GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) && GLM_TEMPLATE::has_subs($val['id'],&$DB)) {
+                                               $output .= GLM_TEMPLATE::get_sub_nav($val["id"],&$DB,$catid);
+                                       }
+                               }
+                               $output .= '</div>';
+                       $output = GLM_TEMPLATE::clean_text($output);
+                       echo $output;
+               }
+               return false;
+       }
+
+       //      }}}
+       //      {{{ get_template()
+
+       /**
+        * get_template: get the template type of the bus_category
+        * @param mixed $type : 'cat' or 'list'
+        *
+        * @uses GLM_DB::db_auto_get_data()
+        * @uses GLM_TEMLATE::img_align()
+        * @uses GLM_TEMLATE::img_alternate()
+        * @uses GLM_TEMLATE::$template
+        *
+        * @return void
+        * @access public
+        */
+       function get_template($type)
+       {
+               $query = "select template from bus_category where id = ".$this->catid;
+               $data = $this->DB->db_auto_get_data($query);
+               switch ($type) {
+               case "cat" :
+                       switch ($data[0]['template']) {
+                       case "5" :
+                       case "4" :
+                       case "2" :
+                               $this->img_align = "left";
+                               break;
+
+                       default:
+                               $this->img_align = "right";
+                               break;
+                       }
+                       break;
+
+               case "list" :
+                       switch( $data[0]['template'] ) {
+                               case "6" :
+                               case "2" :
+                                       $this->img_align = "left";
+                                       $this->img_alternate = 0;
+                                       break;
+
+                               case "5" :
+                               case "1" :
+                                       $this->img_align = "right";
+                                       $this->img_alternate = 0;
+                                       break;
+
+                               case "4" :
+                                       $this->img_align = "right";
+                                       $this->img_alternate = 1;
+                                       break;
+
+                               case "3":
+                                       $this->img_align = "left";
+                                       $this->img_alternate = 1;
+                                       break;
+
+                               default:
+                                       break;
+                       }
+                       break;
+               }
+               return $this->template = $data[0]['template'];
+       }
+
+       //      }}}
+       //      {{{ get_top_parent()
+
+       /**
+        * get_top_parent:Get the highest level parent id (not 0 )for the category.
+        *
+        *      <p><b>NOTICE:</b> This is ment to get the top level parent not the parent of the id given.</p>
+        *
+        * @param integer $id: The catid for the page.
+        * @param object $DB: obj
+        * @uses GLM_TEMPLATE::get_top_parent()
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return int $parent
+        * @access public
+        */
+       function get_top_parent($id)
+       {
+               if ($id == 0 ){
+                       return 0;
+               }
+               $qs = "select parent from bus_category where id = $id";
+               $parentrow = $this->DB->db_auto_get_data( $qs );
+               if ($parentrow[0]['parent'] == 0 ){
+                       return $id;
+               } else {
+                       return $this->get_top_parent( $parentrow[0]['parent'] );
+               }
+       }
+
+       //      }}}
+
+       //      {{{ is_sub_id()
+
+       /**
+        * is_sub_id:Check to see if catid is sub of category
+        *
+        * @param integer $catid: the catid looking at
+        * @param integer $category: to see if it is in category
+        * @param object $DB: Db object reference
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return bool
+        * @access public
+        */
+       function is_sub_id($catid,$category,&$DB)
+       {
+               if (!is_numeric($catid)) {
+                       return false;
+               }
+
+               if ($category == $catid)
+               {
+                       return true;
+               }
+
+               $query = "select id,parent from bus_category where id = $catid";
+               $data = $DB->db_auto_get_data($query);
+               $parent = $data[0]['parent'];
+               if ($parent == 0) {
+                       return false;
+               } else {
+                       return GLM_TEMPLATE::is_sub_id($parent,$category,&$DB);
+               }
+       }
+
+       //      }}}
+
+       //      {{{ keyword_replace()
+
+       /**
+        * keyword_replace:
+        *
+        * @param string $string:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return string
+        * @access public
+        */
+       function keyword_replace($string)
+       {
+               //return $string;
+               if ($search = strstr($string,"{")) {
+                       if (preg_match("/\{([A-Z0-9\&\-\,\'\" ]*)\}/i",$string,$needle)) {
+                               if ($needle[0] != "") {
+                                       $qs = "
+                        SELECT id, category
+                          FROM bus_category
+                         WHERE trim(keyword) = '".trim($needle[1])."'";
+
+                                       $keyres = $this->DB->db_auto_get_data($qs);
+                                       $parent = $this->get_top_parent($keyres[0]['id'],&$this->DB);
+                                       $url = $this->get_seo_url( $keyres[0]['id'] );
+                                       $replacement = "<a href=\"".$url."\">".htmlspecialchars($keyres[0]['category'])."</a>";
+                                       $string = str_replace($needle[0],$replacement,$string);
+                               }
+                       } else {
+                               return $string;
+                       }
+                       if ($search = strstr($string,"{")) {
+                               return $this->keyword_replace($string);
+                       }
+               }
+               return $string;
+       }
+
+       //      }}}
+
+       //      {{{ load_static_page()
+
+       /**
+       * load_static_page:using object buffer include the page $catid.phtml from static dir
+       and return it as string
+       *
+       * @return string $text
+       * @access  public
+       **/
+       function load_static_page()
+       {
+               if (file_exists(BASE."static/".$this->catid.".phtml")) {
+                       ob_start();
+                       include BASE . "static/".$this->catid.".phtml";
+                       $text = ob_get_contents();
+                       ob_end_clean();
+                       return $text;
+               }
+       }
+
+       //      }}}
+
+       //      {{{ make_ul_menu()
+
+       /**
+        * make_ul_menu: create url list of categories
+        *
+        * @param integer $parent parent to start from
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return string
+        * @access public
+        */
+       function make_ul_menu($parent = 0)
+       {
+               $qs = "
+            SELECT id, category, intro
+              FROM bus_category
+             WHERE parent =  $parent
+               AND id <> ".MEMBERS_ONLY_CATEGORY."
+                        {$this->active_query}
+             order by pos";
+               $data = $this->DB->db_auto_get_data($qs);
+
+               if (!is_array($data)) {
+                       return false;
+               } else {
+                       $return = '';
+                       foreach ( $data as $key => $row ) {
+                               $url = $this->get_seo_url( $row['id'] );
+                               $title = strip_tags(addslashes($row['intro']));
+                               $return .= "\t<li><a title=\"".htmlentities($title, ENT_QUOTES, 'UTF-8').'" href="'.$url.'"';
+                               if ($this->catid == $row['id']) {
+                                       $return .= ' id="current"';
+                               }
+                               $return .= '>' . htmlentities($row['category'], ENT_QUOTES, 'UTF-8') . '</a>';
+                $hasSubs = $this->has_subs($row['id'], $this->DB);
+                $isSubId = $this->is_sub_id($this->catid, $row['id'], $this->DB);
+                $isPage  = $this->catid == $row['id'];
+                               if ($hasSubs && ($isSubId || $isPage)) {
+                    $ret2 = $this->make_ul_menu($row['id']);
+                    $return .= $ret2;
+                               }
+                               $return .= "</li>\n";
+                       }
+                       $main_cats = $this->get_main_cats();
+                       if (   (isset($parent) && $parent != 0)
+                               || (   isset($main_cats)
+                                       && isset($main_cats[$parent])
+                                       && $main_cats[$parent]
+                                  )
+                       ) {
+                               return "<ul>\n\t$return</ul>\n";
+                       } else {
+                               return "<ul id=\"nav\">\n\t" . $return . "</ul>\n";
+                       }
+               }
+       }
+
+       //      }}}
+       //      {{{ meta_tags()
+
+       /**
+        * meta_tags: create the meta description content for this page.
+        * this is taken from the category description.
+        * this should be only done for all but the home page.
+        * $meta = ( $catid != 1 ) ? $toolbox->meta_tags() : '';
+        *
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        */
+       function meta_tags()
+       {
+        $query = "
+        SELECT meta_descr,description
+          FROM bus_category
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $this->catid, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetch();;
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+        if ($data['meta_descr']) {
+            $description = htmlentities(trim(strip_tags($data['meta_descr'])), ENT_QUOTES, 'UTF-8');
+        } else {
+                   $description = htmlentities(substr(trim(strip_tags($data['description'])), 0, 250),ENT_QUOTES,'UTF-8');
+        }
+               return $description;
+       }
+
+       //      }}}
+
+       //      {{{ page_status()
+
+       /**
+        * page_status
+        *
+        * tell if page is active, deleted or inactive
+        * this will redirect to the index.php page if the
+        * id has been deleted or not active
+        * it will display message about page not found.
+        *
+        * @param mixed $id
+        * @access public
+        * @return string
+        */
+       function page_status($id) {
+               if ($id == 9999) {
+                       $this->page_status = 'Good';
+                       return true;
+               }
+
+               if (empty($id)) {
+                       return false;
+               }
+               if ($id == HOME_ID) {
+                       $this->page_status = 'Good';
+               }
+               $query = "
+            SELECT id, active
+              FROM bus_category
+             WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $id, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetch();
+            //echo '<pre>'.print_r($data, true).'</pre>';
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+
+               if (is_array($data)) {
+                       if (!$data['active'] &&
+                                       !strstr($_SERVER['HTTP_REFERER'], 'admin/')) {
+                // page was deleted and no longer avail.
+                // give 404 redirect and go back to index page
+                header('HTTP/1.1 404 Not Found');
+                               $this->page_status = 'Bad';
+                       } else {
+                               $this->page_status = 'Good';
+                       }
+               } else {
+                       // page was deleted and no longer avail.
+                       // give 301 redirect and go back to index page
+                       header('HTTP/1.1 301 Moved Permanently');
+                       header('Location: '.BASE_URL);
+                       exit();
+               }
+       }
+
+       //      }}}
+       //      {{{ photo_module()
+
+       /**
+        * photo_module
+        * Load the photo gallery into page
+        *
+        * @access public
+        * @return string
+        */
+       function photo_module()
+       {
+        $query = "
+            SELECT photocat_id
+            FROM photo_category_bus
+            WHERE buscat_id = $this->catid;";
+        $out = '';
+               if ($pData = $this->DB->db_auto_get_data($query)) {
+                       if (count($pData) > 1) {
+                               foreach ($pData as $pKey => $pVal) {
+                                       $photocatid[] = $pVal['photocat_id'];
+                               }
+                               $SINGLE_GALLERY = false;
+                       } else {
+                               $SINGLE_GALLERY = true;
+                               $photocatid = $pData[0]['photocat_id'];
+                       }
+                       if (is_numeric($photocatid) || is_array($photocatid)) {
+                               if (!$_REQUEST['photo_catid']) {
+                                       $_REQUEST['photo_catid'] = $photocatid;
+                               }
+                $photoApp = new Toolkit_Photos_Display();
+                $out = $photoApp->toHTML();
+                       }
+               }
+               return $out;
+       }
+
+       //      }}}
+       //      {{{ print_ancestors()
+
+       /**
+        * print_ancestors:print out the ancestors
+        * @param integer $catid: the id to start at.
+        *
+        * @return string
+        * @access public
+        */
+       function print_ancestors($catid)
+       {
+               return $this->get_bread_crumbs($catid);
+       }
+
+       //      }}}
+
+       //      {{{ set_active_query()
+
+       /**
+        * set_active_query: some toolboxes have an active flag some do not
+        * so this is to allow both with and without a flag.
+        *
+        * @uses ACTIVE_FLAG
+        *
+        * @return void
+        * @access public
+        **/
+       function set_active_query()
+       {
+               if (ACTIVE_FLAG) {
+                       $this->active_query = " and active = 't'";
+               }
+               return $this->active_query;
+       }
+
+       //      }}}
+       //      {{{ set_address()
+
+       /**
+       * set_address:set_address
+       * <code><p>{$address}<br>{$city},{$state} {$zip}</p></code>
+       * @param array $data: data contain the address info for display.
+       *
+       * @return string $address
+       * @access public
+       **/
+       function set_address($data)
+       {
+               $address = "";
+               if ($data["address"]) {
+                       $address .= $data["address"];
+               }
+               if ($data["city"] && $data["state"] && $data["zip"]) {
+                       $address .= '<br>'.$data["city"].', '.$data["state"].' '.$data["zip"];
+               } elseif ($data["city"] && $data["state"]) {
+                       $address .= '<br>'.$data["city"].', '.$data["state"];
+               } elseif ($data["city"]) {
+                       $address .= '<br>'.$data["city"];
+               }
+
+               if ($address != "") {
+                       return '<p>'.$address.'<br></p>';
+               }
+       }
+
+       //      }}}
+       //      {{{ set_body_tag()
+
+       function set_body_tag()
+       {
+               if ($this->catid != HOME_ID) {
+                       $this->body_tag = ' id="inside"';
+               }
+               if (isset($_REQUEST['query']) && $_REQUEST['query']) {
+                       switch (GLM_HOST_ID) {
+                       case "devsy.gaslightmedia.com":
+                       case "DEVELOPMENT":
+                               $apikey = "ABQIAAAA4LuqJozzD0jiTLPhI0tT7xQUAAYHl_Rab4aEI5hGyHxlqR-rKxQMGKAdHLOEIFLI9wcDJjjSkJ7qng";
+                               break;
+
+                       case "ws1.gaslightmedia.com":
+                       case "PRODUCTION":
+                               $apikey = "ABQIAAAAWqyv9sBAgUBdsdOdgo7LsRQRzeqzQXKdvmJb4FZzpdF0AtrabhSiNxG27kD8OcNt7Ae6sNRUH1VXCA";
+                               break;
+
+                       default :
+                               break;
+                       }
+                       $this->body_tag .= ' onload="OnLoad();"';
+                       $this->scripts .= '
+                               <script type="text/javascript" src="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key='.$apikey.'"></script>';
+                       $this->scripts .= '<link rel="stylesheet" type="text/css" href="'.BASE_URL.'gsearch.css">';
+                       $this->scripts .= '<script type="text/javascript" src="'.BASE_URL.'libjs/gsearch.php?query='.urlencode($_REQUEST['query']).'"></script>';
+               }
+       }
+
+       //      }}}
+       //      {{{ set_catid()
+
+       /**
+       * set_catid:Set the class catid var
+       * @param integer $catid: $catid
+       *
+       * @deprecated using get_catid
+       * @return void
+       * @access public
+       **/
+       function set_catid($catid)
+       {
+               if (is_numeric($catid)) {
+                       $this->catid = $catid;
+               } else {
+                       $this->catid = 1;
+               }
+       }
+
+       //      }}}
+       //      {{{     set_contact()
+
+       /**
+       * set_contact:Set the contact string
+       * <code><p><strong>Contact Name:</strong>&nbsp;{$text}</p></code>
+       *
+       * @param string $text: The text as string
+       * @param string $email: email if givin
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_contact($text, $email)
+       {
+               if ($email != "") {
+                       $text = "";
+               } else {
+                       $text = '<p><strong>Contact Name:</strong>&nbsp;'.$text.'</p>';
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_DB()
+
+       /**
+        * set_DB: set the DB up to be that of the global one if it exists
+        *
+        * @param object $DB : the DB object
+        * @uses GLM_DB
+        *
+        * @return void
+        * @access public
+        **/
+       function set_DB($DB) {
+               if (isset($DB)) {
+                       $this->DB =& $DB;
+               } else {
+                       $this->DB =& new GLM_DB();
+               }
+       }
+
+       //      }}}
+       //      {{{ set_data()
+
+       /**
+       * call all class methods to set tho data elements
+       *
+       * <p>This is hightly dependant on the three tables of bus bus_category and bus_category_bus
+       * set_data:Calls each function of the class
+       * based on the key af the array $data[0][$key]</p>
+       * @todo Really need to look at enhancing this function for different datasetups.
+       * @param array $data: The input array from db query
+       * @uses GLM_TEMPLATE::$img_size
+       * @uses GLM_TEMPLATE::$img_align
+       * @uses GLM_TEMPLATE::$img_alternate
+       * @uses GLM_TEMPLATE::set_text()
+       * @uses GLM_TEMPLATE::set_header()
+       * @uses GLM_TEMPLATE::set_subheader()
+       * @uses GLM_TEMPLATE::set_url()
+       * @uses GLM_TEMPLATE::set_address()
+       * @uses GLM_TEMPLATE::set_img()
+       * @uses GLM_TEMPLATE::set_email()
+       * @uses GLM_TEMPLATE::set_phone()
+       *
+       * @return array data The finished array
+       * @access  public
+       **/
+       function set_data($data)
+       {
+               if (is_array($data)) {
+                       foreach ($data as $k => $val) {
+                               foreach ($val as $key => $value) {
+                                       if (   strstr($key, "image")
+                                               && !strstr($key, "name")
+                                               && $value != ""
+                                       ) {
+                                               $titletag = $data[$k]['category'] ?
+                                                       $data[$k]['category'] :
+                                                       $data[$k]['name'];
+
+                                               //$data[$k][$key."_name"] = $value;
+                                               $data[$k][$key] = $this->set_img(
+                                                       $value,
+                                                       $this->img_size,
+                                                       $this->img_align,
+                                                       $titletag,
+                                                       $data[$k][$key."name"]
+                                               );
+
+                                               if (!strstr($key, "name")) {
+                                                       if (   $this->img_align == "right"
+                                                               && $this->img_alternate
+                                                       ) {
+                                                               $this->img_align = "left";
+                                                       } elseif ($this->img_alternate) {
+                                                               $this->img_align = "right";
+                                                       }
+                                               }
+                                       } elseif (   strstr($key, "file")
+                                                         && strstr($key, "name")
+                                                         && $value != ""
+                                       ) {
+                                       } elseif (   strstr($key,"url")
+                                                         && strstr($key,"name")
+                                                         && $value != ""
+                                       ) {
+                                       } elseif (strstr($key,"descr") && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_text($value);
+                                       } elseif (isset($data[$k]['email'])
+                                                         && $key == "contactname"
+                                                         && $value != ""
+                                       ) {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_contact(
+                                                       $value,
+                                                       $data[$k]['email']
+                                               );
+                                       } elseif ($key == "name" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_subheader($value);
+                                       } elseif (strstr( $key, "header" ) && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_subheader($value);
+                                       } elseif ($key == "intro" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_header($value);
+                                       } elseif ($key == "category" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_header($value);
+                                       } elseif ($key == "url" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_url($value,
+                                                       $data[$k]["urlname"]);
+                                       } elseif ($key == "email" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_email($value,
+                                                       $data[$k]["contactname"]);
+                                       } elseif ($key == "phone" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_phone($value);
+                                       } elseif ($key == "fax" && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_fax($value);
+                                       } elseif (strstr($key, "file") && $value != "") {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_file(
+                                                       $value,
+                                                       $data[$k][$key.'name']
+                                               );
+                                       } elseif ($key == "address") {
+                                               $data[$k][$key] =  GLM_TEMPLATE::set_address($data[$k]);
+                                       } elseif ($key == "id") {
+                                               $data[$k][$key] = $value;
+                                       } else {
+                                               $data[$k][$key] = GLM_TEMPLATE::set_text($value);
+                                       }
+                               }
+                       }
+                       return $data;
+               }
+               return false;
+       }
+
+       //      }}}
+       //      {{{     set_email()
+
+       /**
+       * set_email:Set the email string
+       * <code><p><strong>Contact:</strong>&nbsp;&nbsp;<a href="mailto:{$email}" target="_blank">{$text}</a></p></code>
+       * @param string $email: The email as string
+       * @param string $contact: The contactname this is used as the link text
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_email($email, $contact)
+       {
+               if ($email != "") {
+                       if ($contact != "") {
+                               $email = '<p><strong>Contact:</strong>&nbsp;&nbsp;<a href="mailto:'.$email.'" target="_blank">'.htmlspecialchars($contact).'</a></p>';
+                       } else {
+                               $email = '<p><strong>Email:</strong>&nbsp;&nbsp;<a href="mailto:'.$email.'" target="_blank">'.htmlspecialchars($email).'</a></p>';
+                       }
+               }
+               return $email;
+       }
+
+       //      }}}
+       //      {{{ set_fax()
+
+       /**
+       * set_fax:Set the fax string
+       * <code><p><strong>Fax:</strong>&nbsp;&nbsp;{$text}</p></code>
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_fax($text)
+       {
+               if ($text != "") {
+                       $text = '<p><strong>Fax:</strong>&nbsp;&nbsp;'.htmlspecialchars($text).'</p>';
+               }
+               return $text;
+       }
+
+       //      }}}
+    // {{{ set_file()
+
+       /**
+       * set_file:Set the file string
+       * <code><p><strong>Contact Name:</strong>&nbsp;{$text}</p></code>
+       * @param string $text: The text as string
+       * @param string $name: The file name displayed
+       * @uses URL_BASE
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_file($text, $name)
+       {
+               if ($text != "") {
+                       $outtext = '<p><a';
+                       if (preg_match("/[.]([A-Z0-9]{3}$)/i", $text, $tmp)) {
+                               $outtext .= ' class="file-download '.strtolower($tmp[1]).'"';
+                       }
+                       $outtext .= ' href="'.URL_BASE.'uploads/'.$text.'" target="_blank">';
+                       if ($name) {
+                               $outtext .= htmlspecialchars($name);
+                       } else {
+                               $outtext .= htmlspecialchars($text);
+                       }
+                       $outtext .= '</a>';
+                       if (preg_match("/[.]([A-Z0-9]{3}$)/i", $text, $tmp)) {
+                // don't output second link
+                               //$outtext .= '<a href="'.BASE_URL.'download.php?file='.$text.'" class="download">Click here to Download&nbsp;</a>';
+                       }
+                       $outtext .= '</p>';
+               }
+               return $outtext;
+       }
+
+       //      }}}
+       //      {{{ set_header()
+
+       /**
+       * set_header:Set the header string
+       * @param string $text: The text as string
+       * @uses GLM_TEMPLATE::header_begin()
+       * @uses GLM_TEMPLATE::header_end()
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_header($text)
+       {
+               if ($text != "") {
+                       $text = $this->header_begin.htmlspecialchars($text).$this->header_end;
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_img()
+
+       /**
+       * set_img:Set the image string
+       * <p><code>
+       * <div class="image{$align}" style="width: {$width}px" src="{$size}{$image}" {$titletag}>
+       * <div class="imagecaption">{$caption}</div>
+       * </div>
+       * </code>
+       * </p>
+       *
+       * @param string $image: The image
+       * @param string $size: The path
+       * @param string $align: The alignment
+       * @param string $name: The image_name (displayed under image)
+       * @param string $alt_title text for use in alt and title tags
+       * @param string $caption Text for image caption if given
+       * @uses GLM_TEMPLATE::get_image_path()
+       *
+       * @return void
+       * @access public
+       **/
+       function set_img($image, $size, $align, $alt_title = NULL, $caption = NULL)
+       {
+               if ($image != "") {
+                       if ($caption != '') {
+                               $caption = str_replace('&amp;','&',$caption);
+                               $titletag = 'title="'.htmlspecialchars(strip_tags($caption)).'"';
+                               $titletag .= ' alt="'.htmlspecialchars(strip_tags($image)).'"';
+                       } elseif ($alt_title != '') {
+                               $alt_title = str_replace('&amp;','&',$alt_title);
+                               $titletag = 'title="'.htmlspecialchars(strip_tags($alt_title)).'"';
+                               $titletag .= ' alt="'.htmlspecialchars(strip_tags($image)).'"';
+                       } else {
+                               $titletag = 'title="'.htmlspecialchars(strip_tags($image)).'"';
+                               $titletag .= ' alt="'.htmlspecialchars(strip_tags($image)).'"';
+                       }
+
+                       if ($align != "") {
+                               $img_align = 'class="image'.$align.'"';
+                       }
+                       $path = $this->get_image_path();
+                       if (is_file($path.$image)) {
+                               $image_size = getimagesize($path.$image);
+                               $img_attr = $image_size[3];
+                       } else {
+                $imServer = new Toolkit_Image_Server();
+                $image_size = $imServer->getImageSize($size.$image);
+                //$image_size[0] = $ret['width'];
+                //$image_size[1] = $ret['height'];
+            }
+                       $img = '<div '.$img_align.' style="width: '.$image_size[0].'px">';
+                       $img .= '<img ';
+                       if (isset($img_attr)) {
+                               $img .= $img_attr;
+                       }
+                       $img .= ' src="'.$size.$image.'" '.$titletag.'>';
+                       if ($caption) {
+                               $img .= '<div class="imagecaption">'.$caption.'</div>';
+                       }
+                       $img .= '</div>';
+                       return $img;
+               }
+       }
+
+       //      }}}
+       //      {{{ set_member()
+
+       /**
+        * set_member
+        *
+        * @access public
+        * @return string
+        */
+       function set_member()
+       {
+               if (MEMBERS_DB && $this->catid) {
+                       $member =& new Toolkit_Members_Display($this->dbh);
+            try {
+                $res = $member->setCatId($this->catid);
+            } catch (InvalidArgumentException $e) {
+                return Toolkit_Common::handleError($e);
+            }
+            $member->setMemberSections();
+            return $member;
+               }
+       }
+
+       //      }}}
+       //      {{{ set_name_url()
+
+       /**
+        * setNameUrl:
+        * @param string $name :
+        *
+        * @return string
+        * @access public
+        */
+       function set_name_url( $name )
+       {
+               $name = str_replace(" ","-",$name);
+               $name = preg_replace("/[\/#&?'\"]|amp;/","",strip_tags( strtolower( trim( $name ) ) ) );
+               return htmlspecialchars( $name );
+       }
+
+       //      }}}
+       //      {{{ set_pages()
+
+       /**
+        * set_pages: grab the globals for the pages an use this for
+        *      the pages array for the class
+        *
+        * @return void
+        * @access public
+        **/
+       function set_pages($pages)
+       {
+        $this->pages[1] = 'index';
+       }
+
+       //      }}}
+       //      {{{ set_phone()
+
+       /**
+       * set_phone:Set the phone string
+       * <code><p><strong>Phone:</strong>&nbsp;&nbsp;{$text}</p></code>
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_phone($text)
+       {
+               if ($text != "") {
+                       $text = '<p><strong>Phone:</strong>&nbsp;&nbsp;'.$text.'</p>';
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_subheader()
+
+       /**
+       * set_subheader:Set the subheader string
+       * @param string $text: The text as string
+       * @uses GLM_TEMPLATE::subheader_begin()
+       * @uses GLM_TEMPLATE::subheader_end()
+       *
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_subheader($text)
+       {
+               if ($text != "") {
+                       $text = $this->subheader_begin.htmlspecialchars($text).$this->subheader_end;
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_text()
+
+       /**
+       * set_text:Set the contact string
+       * <code><p>{$text}</code>
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_text($text)
+       {
+               if ("" == str_replace("<br />", "", trim($text))) {
+                       return false;
+               }
+               if ($text != "") {
+                       $text = $this->keyword_replace($text);
+                       $text = $text;
+               }
+               return $text;
+       }
+
+       //      }}}
+       //      {{{ set_toolbox_to_category_array()
+
+       function set_toolbox_to_category_array(){
+               $category_toolbox[1] = 70;// Places to Stay
+               $category_toolbox[20] = 71;// Things to Do
+               $category_toolbox[19] = 72;// Food & Spirits
+               $category_toolbox[24] = 73;// Camping
+               $category_toolbox[40] = 74;// Travel Services
+               $category_toolbox[25] = 75;// Attractions
+               $category_toolbox[41] = 76;// Golf
+               $category_toolbox[42] = 77;// Real Estate
+               $category_toolbox[43] = 78;// Shopping
+               $category_toolbox[44] = 79;// Recreation
+               $this->category_toolbox = $category_toolbox;
+       }
+
+       //      }}}
+       //      {{{     set_url()
+
+       /**
+       * set_url:Set the url string
+       * <p>
+       * <code><p><a href="http://{$url}" target="_blank">{$text}</a></code>
+       * </p>
+       *
+       * @param string $url: The url
+       * @param string $text: The text as string
+       *
+       * @return string $text
+       * @access public
+       **/
+       function set_url($url, $text)
+       {
+               if ($url != "") {
+                       if (!$text) {
+                               $text = $url;
+                       }
+                       if (strtolower(substr($url, 0, 7) ) == "https://") {
+                               $url = '<p><a href="'.$url.'" target="_blank">'.htmlspecialchars($text).'</a></p>';
+                       } else {
+                               $url = '<p><a href="http://'.$url.'" target="_blank">'.htmlspecialchars($text).'</a></p>';
+                       }
+               }
+               return $url;
+       }
+
+       //      }}}
+       //      {{{ show_catheader()
+
+       /**
+        * show_catheader:
+        *
+        * @param integer $catid:
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access  public
+        **/
+       function show_catheader($catid)
+       {
+               $query = "SELECT category FROM bus_category WHERE id = $catid";
+               $data = $this->DB->db_auto_get_data($query);
+               if ($data[0][category]!="") {
+                       $header = $data[0][category];
+               } else {
+                       $header = '&nbsp;';
+               }
+               echo $header;
+       }
+
+       //      }}}
+       //      {{{ show_catimg()
+
+       /**
+        * show_catimg:output the category image.
+        *
+        * @param integer $catid: The catid for the page.
+        * @uses GLM_TEMPLATE::MIDSIZED
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access  public
+        */
+       function show_catimg($catid)
+       {
+               $query = "SELECT image FROM bus_category WHERE id = $catid";
+               $data = $this->DB->db_auto_get_data($query);
+               if ($data[0]["image"]!="") {
+                       $img = '<img src="'.MIDSIZED.$data[0]["image"].'" border="0" vspace="30" hspace="0">';
+               } else {
+                       $img = '<img src="assets/logo_small.gif" width="150" height="85" vspace="0" hspace="0" border="0" alt="Birchwood Construction"><BR>';
+               }
+               echo $img;
+               echo '<BR><img src="assets/clear.gif" height="30" width="1">';
+       }
+
+       //      }}}
+       //      {{{ sort_childs()
+
+       /**
+        * sort_childs:
+        * @param array $threads:
+        *
+        * @return  string
+        * @access  public
+        */
+       function sort_childs($threads)
+       {
+               foreach($threads as $var=>$value) {
+                       $childs[$value["parent"]][$value["id"]] = $value;
+               }
+               return $childs;
+       }
+
+       //      }}}
+       //      {{{ sub_nav()
+
+       /**
+        * sub_nav:Create a sub navigation 4 across
+        *
+        * @param integer $catid: The catid for the page
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return void
+        * @access public
+        */
+       function sub_nav($catid)
+       {
+               $newcatid = $this->get_parent_id($catid);
+               if ($newcatid != 0) {
+                       $catid = $newcatid;
+               }
+               $query1 = "SELECT category FROM bus_category WHERE id = $catid";
+               $data1 = $this->DB->db_auto_get_data( $query1 );
+               $out = '<div id="subnav"> ';
+
+               $query = "SELECT id,category,intro FROM bus_category WHERE parent = $catid ".$this->active_query." ORDER BY pos";
+               $data = $this->DB->db_auto_get_data($query);
+               if (is_array($data)) {
+                       $counter = 1;
+                       foreach ($data as $key => $val) {
+                               $url = $this->get_seo_url($val['id']);
+                               $title = strip_tags(addslashes($val['intro']));
+                               //GLM_TEMPLATE::set_name_url( GLM_TEMPLATE::get_category_Name( $val['id'],"bus_category",$this->DB ) );
+                               $out .=  '<a title="'.$title.'" href="'.$url.'">';
+                               $out .= $val["category"];
+                               $out .= '</a>';
+                       }
+               }
+               $out .= '</div>';
+               return $out;
+       }
+
+       //      }}}
+
+       //      {{{ title()
+
+       /**
+        * title: create the title for the page.
+        * this should be only done for all but the home page.
+        * $title = ( $catid != 1 ) ? $toolbox->title() : '';
+        *
+        * @uses GLM_DB::db_auto_get_data()
+        *
+        * @return  string
+        * @access public
+        */
+       function title()
+       {
+        $query = "
+        SELECT category,intro,title
+          FROM bus_category
+         WHERE id = :id";
+        try {
+            $stmt = $this->dbh->prepare($query);
+            $stmt->bindParam(":id", $this->catid, PDO::PARAM_INT);
+            $stmt->execute();
+            $data = $stmt->fetchAll();;
+        } catch(PDOException $e) {
+            echo '<pre>'.print_r($e, true).'</pre>';
+            die($e->getMessage());
+        }
+
+               if ($data[0]['title']) {
+                       $title = strip_tags($data[0]['title']);
+        } else if ($data[0]['intro']) {
+                       $title = strip_tags($data[0]['intro']);
+               }       else {
+                       $title = strip_tags($data[0]['category']);
+               }
+               return htmlentities($title.' - ',ENT_QUOTES,'UTF-8');
+       }
+
+       //      }}}
+
+       //      {{{ valid_email()
+
+       /**  valid email
+        *
+        * <p>Checks for a valid format and good (mx check)
+        * email address.</p>
+        * @deprecated using GLM_TOOLBOX::valid_email()
+        * @uses GLM_TOOLBOX::valid_email()
+        *
+        * @param string email the email address as string.
+        * @return boolean
+        */
+       function valid_email( $email )
+       {
+               return GLM_TOOLBOX::valid_email( $email );
+       }
+
+       //      }}}
+}
+?>
diff --git a/classes/class_threads.inc b/classes/class_threads.inc
new file mode 100644 (file)
index 0000000..9e7f2c0
--- /dev/null
@@ -0,0 +1,86 @@
+<?php\r
+class Thread {    \r
+       var $beginLevel = "<ul>";\r
+       var $beginLevel2 = "<ul>";\r
+    var $endLevel = "</ul>";\r
+    var $beginItem = "<li>";\r
+    var $beginItem2 = "<li>";\r
+    var $endItem = "</li>";\r
+    var $wholeThread;\r
+       var $select_value;\r
+       var $bg_style = array();\r
+    function Thread( $code = "", $select_value = "" ) {\r
+               if( !empty( $code ) ) {    \r
+                       $this->beginLevel = $code['beginLevel'];\r
+                       $this->beginLevel2 = $code['beginLevel2'];\r
+            $this->endLevel = $code['endLevel'];\r
+            $this->beginItem = $code['beginItem'];\r
+            $this->beginItem2 = $code['beginItem2'];\r
+            $this->endItem = $code['endItem'];\r
+        }\r
+               if( $select_value ){\r
+                       $this->select_value = $select_value;\r
+               }\r
+               $this->bg_style[0] = 'background-color:#77A94C;color:#000;';\r
+               $this->bg_style[1] = 'background-color:#9FCF74;color:#000;';\r
+               $this->bg_style[2] = 'background-color:#C8EFA4;color:#000;';\r
+               $this->bg_style[3] = 'background-color:#E6FFCF;color:#000;';\r
+               $this->bg_style[4] = 'background-color:#ffffff;color:#000;';\r
+    }\r
+    function sortChilds( $threads ) {    \r
+               while( list( $var, $value ) = each( $threads ) ){\r
+            $childs[$value['parent']][$value['ID']] = $value;\r
+               }\r
+        return $childs;\r
+    }\r
+       function convertToThread( $threads, $thread ){    \r
+               static $count;\r
+               if( !$count ){\r
+                       $this->wholeThread .= $this->beginLevel2;\r
+               }\r
+               else{\r
+                       $this->wholeThread .= $this->beginLevel;\r
+               }\r
+        while( list( $parent, $value ) = each( $thread ) ){\r
+                       if( $threads[$parent] ){\r
+                               $this->wholeThread .= $this->beginItem2;\r
+                       }\r
+                       else{\r
+                               $this->wholeThread .= $this->beginItem;\r
+                       }\r
+                       $count++;\r
+                       $this->wholeThread .= $value['content'].$this->endItem."\n";\r
+                       if( $threads[$parent] && !$value['closed'] ){\r
+                $this->convertToThread($threads, $threads[$parent]);\r
+                       }\r
+                       $count--;\r
+        }\r
+        $this->wholeThread .= $this->endLevel;\r
+        return $this->wholeThread;\r
+    }\r
+    function convertToSelect( $threads, $thread ){    \r
+               static $count;\r
+               $count = ( $count <= 0 ) ? 0 : $count;\r
+        while( list( $parent, $value ) = each( $thread ) ){\r
+                       $count++;\r
+                       $this->wholeThread .= '<option value="'.$value['value'].'"';\r
+                       if( $this->select_value == $value['value'] ){\r
+                               $this->wholeThread .= ' selected';\r
+                       }\r
+                       $this->wholeThread .= ' style="'.$this->bg_style[$count].'"';\r
+                       $this->wholeThread .= '>';\r
+                       if( $count != 0 ){\r
+                               $this->wholeThread .= str_repeat( "&nbsp;&nbsp;", $count );\r
+                       }\r
+                       $this->wholeThread .= htmlspecialchars( $value['text'] );\r
+                       $this->wholeThread .= '</option>'."\n";\r
+                       if( $threads[$parent] && !$value['closed'] ){\r
+                $this->convertToSelect( $threads, $threads[$parent] );\r
+                       }\r
+                       $count--;\r
+        }\r
+        $this->wholeThread .= $this->endLevel;\r
+        return $this->wholeThread;\r
+    }\r
+}\r
+?>\r
diff --git a/classes/class_toolbox.inc b/classes/class_toolbox.inc
new file mode 100755 (executable)
index 0000000..5ab6f1c
--- /dev/null
@@ -0,0 +1,1665 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ *  Toolbox Classes :)
+ *
+ *  PHP version 5
+ *
+ *  <p>
+ *  These classes and any code is not licensed for anyone but gaslight to use
+ *  </p>
+ *
+ * @category  Toolbox
+ * @package   GLM_TOOLBOX
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2005-2008 Gaslight Media
+ * @license   http://app.gaslightmedia.com/license.php Gaslight Media  
+ * @link      http://www.gaslightmedia.com www.gaslightmedia.com           
+ * @since     $Date: 2010/01/15 19:50:07 $
+ */
+/**
+ *    Toolbox Class :)
+ *
+ * <p><b>NOTICE</b>
+ *  Im going to be moving all functions from the setup.phtml
+ *  file and putting it into this</p>
+ *  <p>class.  This is so we can eventially move
+ *  everything to one siteinfo.inc file.</p>
+ *  <kbd>matrix@devsys Does this work?</kbd>
+ *
+ * @todo move all functions from setup.phtml into here
+ */
+define('GLM_TOOLBOX', true);
+
+/**
+ * Short description for class
+ *
+ * Long description (if any) ...
+ *
+ * @category  Toolbox
+ * @package   GLM_TOOLBOX
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2005-2008 Gaslight Media
+ * @license   http://app.gaslightmedia.com/license.php Gaslight Media
+ * @link      http://www.gaslightmedia.com www.gaslightmedia.com
+ * @see       References to other sections (if any)...
+ */
+class GLM_TOOLBOX
+{
+    /** @var array php_version */
+    var $php_version;
+    /** @var boolean true if php is version < 4.2 */
+    var $php_old_pg;
+    // {{{ __construct()
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function __construct()
+    {
+        $this->php_version = $this->php_version_check();
+        $this->php_old_pg  = $this->php_old_pg();
+    }// }}}
+    // {{{ CC_date_entry($month, $year, $month_name, $year_name)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string $month      Parameter description (if any) ...
+     * @param string $year       Parameter description (if any) ...
+     * @param string $month_name Parameter description (if any) ...
+     * @param string $year_name  Parameter description (if any) ...
+     *
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function CC_date_entry($month, $year, $month_name, $year_name)
+    {
+        $cur_date = getdate();
+        if ($month == "") {
+            $month = $cur_date['mon'];
+        }
+        if ($year == "") {
+            $year = $cur_date['year'];
+        }
+        $date = '<select name="'.$month_name.'">';
+        for ($i = 1; $i < 13; $i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $month) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        $date .= '<select name="'.$year_name.'">';
+        for ($i = $year; $i < $year + 15; $i++) {
+            $date .= '<option value="'.$i.'"';
+            if ($i == $year) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        return $date;
+    }    // }}}
+    // {{{ CreditVal($Num, $Name = '', $Accepted='')
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $Num      Parameter description (if any) ...
+     * @param string  $Name     Parameter description (if any) ...
+     * @param string  $Accepted Parameter description (if any) ...
+     *
+     * @return boolean Return description (if any) ...
+     * @access public
+     */
+    function CreditVal($Num, $Name = '', $Accepted='')
+    {
+        $Name     = strtolower($Name);
+        $Accepted = strtolower($Accepted);
+        $GoodCard = 1;
+        $Num      = ereg_replace("[^[:digit:]]", "", $Num);
+        switch ($Name) {
+
+        case "mastercard" :
+            $GoodCard = ereg("^5[1-5].{14}$", $Num);
+            break;
+
+        case "visa" :
+            $GoodCard = ereg("^4.{15}$|^4.{12}$", $Num);
+            break;
+
+        case "americanexpress" :
+            $GoodCard = ereg("^3[47].{13}$", $Num);
+            break;
+
+        case "discover" :
+            $GoodCard = ereg("^6011.{12}$", $Num);
+            break;
+
+        case "dinerscard" :
+            $GoodCard = ereg("^30[0-5].{11}$|^3[68].{12}$", $Num);
+            break;
+
+        default:
+            if (ereg("^5[1-5].{14}$", $Num)) {
+                $Name = "mastercard";
+            }
+            if (ereg("^4.{15}$|^4.{12}$", $Num)) {
+                $Name = "visa";
+            }
+            if (ereg("^3[47].{13}$", $Num)) {
+                $Name = "americanexpress";
+            }
+            if (ereg("^6011.{12}$", $Num)) {
+                $Name = "discover";
+            }
+            if (ereg("^30[0-5].{11}$|^3[68].{12}$", $Num)) {
+                $Name ="dinerscard";
+            }
+            break;
+        }
+
+        // If there's a limit on card types we accept, check for it here.
+        if ($Accepted) {
+            $type_verified = false;
+            $brands        = explode(",", $Accepted);
+            foreach ($brands as $brand) {
+                if ($Name == $brand) {
+                    $type_verified = true;
+                }
+            }
+            if (!$type_verified) {
+                return false;
+            }
+        }
+        $Num   = strrev($Num);
+        $Total = 0;
+        for ($x=0; $x<strlen($Num); $x++) {
+            $digit = substr($Num, $x, 1);
+            if ($x/2 != floor($x/2)) {
+                $digit *= 2;
+                if (strlen($digit) == 2) {
+                    $digit = substr($digit, 0, 1) + substr($digit, 1, 1);
+                }
+            }
+            $Total += $digit;
+        }
+        if ($GoodCard && $Total % 10 == 0) {
+            return true;
+        } else {
+            return false;
+        }
+    }// }}}
+    // {{{ build_checklist($name, $data)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string $name Parameter description (if any) ...
+     * @param array  $data Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function build_checklist($name, $data)
+    {
+        if (!is_array($selected)) {
+            $sel[0] = $selected;
+        } else {
+            $sel = $selected;
+        }
+        if (!is_array($data)) {
+            return false;
+        }
+        foreach ($data as $field => $title) {
+            $out .= '<label for="'.$name.'['.$field.']">
+                <input type="checkbox" id="'.$name.'['.$field.']"
+                name="'.$name.'['.$field.']" value="t"';
+            if ($_POST[$field] == 't') {
+                $out .= ' checked';
+            }
+            $out .= '>'.$title.'</label>';
+        }
+        return $out;
+    }// }}}
+    // {{{ build_picklist($fieldname, $data, $selected, $type = "standard",$auto = 0,$width = null)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string  $fieldname Parameter description (if any) ...
+     * @param array   $data      Parameter description (if any) ...
+     * @param unknown $selected  Parameter description (if any) ...
+     * @param string  $type      Parameter description (if any) ...
+     * @param integer $auto      Parameter description (if any) ...
+     * @param string  $width     Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access public
+     */
+    function build_picklist($fieldname, $data, $selected, $type = "standard",$auto = 0,$width = null)
+    {
+        if (!is_array($selected)) {
+            $sel[0] = $selected;
+        } else {
+            $sel = $selected;
+        }
+        if ($auto == 1) {
+            $autosubmit = "onChange=\"form.submit()\"";
+        }
+        if ($width) {
+            $autosubmit .= "style=\"width:".$width."px;\"";
+        }
+        switch($type) {
+        case "multiple":
+            $str = "<select name=\"".$fieldname."\" multiple size=\"10\" ".$autosubmit.">\n";
+            while (list($key, $val) = each($data)) {
+                if (in_array($key, $sel)) {
+                    $select = " selected ";
+                } else {
+                    $select = "";
+                }
+                $str .= "    <option value=\"$key\"".$select.">$val\n";
+            }
+            break;
+        case "simple":
+            $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+            for ($i = 0; $i < count($data); $i++) {
+                $select = (in_array($data[$i], $sel)) ? " selected ":"";
+                $str   .= "    <option value=\"".$data[$i]."\"".$select.">".$data[$i]."\n";
+            }
+            break;
+
+        case "standard":
+        default:
+            $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+            while (list($key, $val) = each($data)) {
+                $select = (in_array($key, $sel)) ? " selected ":"";
+                $str   .= "    <option value=\"$key\"".$select.">$val\n";
+            }
+            break;
+        }
+        $str .= "</select>\n";
+        return $str;
+    }// }}}
+    // {{{ build_radios($name, $data)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string $name Parameter description (if any) ...
+     * @param array  $data Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function build_radios($name, $data)
+    {
+        if (!is_array($selected)) {
+            $sel[0] = $selected;
+        } else {
+            $sel = $selected;
+        }
+        if (!is_array($data)) {
+            return false;
+        }
+        $count = 1;
+        foreach ($data as $field => $title) {
+            $out .= '<label for="'.$name.'-'.$count.'">
+                <input type="radio" id="'.$name.'-'.$count.'"
+                name="'.$name.'" value="'.$field.'"';
+            if ($_POST[$name] == $field) {
+                $out .= ' checked';
+            }
+            $out .= '>'.$title.'</label><br>';
+            $count++;
+        }
+        return $out;
+    }// }}}
+    // {{{ calendar_entry_input($name, $value, $icon_path)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string  $name      Parameter description (if any) ...
+     * @param unknown $value     Parameter description (if any) ...
+     * @param string  $icon_path Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access public
+     */
+    function calendar_entry_input($name, $value, $icon_path)
+    {
+        $out = '
+        <input value="'.(($value)?$value:'Enter Date').'"
+        style="width:100px;float:left;" type="text" name="'.$name.'"
+        id="'.$name.'" readonly="1">
+        <img src="'.$icon_path.'img.gif" id="'.$name.'_trigger"
+        style="cursor: pointer; border: 1px solid red;" title="Date selector"
+        onmouseover="this.style.background=\'red\';"
+        onmouseout="this.style.background=\'\'">
+            ';
+        return $out;
+    }// }}}
+    // {{{ calendar_entry_javascript($name, $value)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string $name  Parameter description (if any) ...
+     * @param string $value Parameter description (if any) ...
+     *
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function calendar_entry_javascript($name, $value)
+    {
+        $out .= '
+            <script type="text/javascript">
+    Calendar.setup({
+        inputField     :    "'.$name.'",        // id of the input field
+        ifFormat       :    "%m/%e/%Y",         // format of the input field
+        button         :    "'.$name.'_trigger",// trigger for the calendar (button ID)
+        align          :    "Bl",               // alignment (defaults to "Bl")
+        singleClick    :    true,
+        step           :    1
+
+        ';
+        if ($value && $value != 'Enter Date') {
+            $out .= ',date : "'.$value.'"';
+        }
+        $out .= '
+    });
+</script>';
+        return $out;
+    }// }}}
+    // {{{ contact_date_entry($month,$day,$year,$month_name,$day_name,$year_name)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string $month      Month
+     * @param string $day        Day
+     * @param string $year       Year
+     * @param string $month_name id and name value of month
+     * @param string $day_name   id and name value of day
+     * @param string $year_name  id and name value of year
+     * @param string $onChange   must be onChange="javzascript;"
+     *
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function contact_date_entry($month,$day,$year,$month_name,$day_name,$year_name,$onChange = null)
+    {
+        $cur_date = getdate();
+
+        if ($month == "") {
+            $month = $cur_date['mon'];
+        }
+        if ($day == "") {
+            $day = $cur_date['mday'];
+        }
+        if ($year == "") {
+            $year = $cur_date['year'];
+        }
+        $date = '<select id="'.$month_name.'" name="'.$month_name.'" '.$onChange.'>';
+        for ($i=1;$i<13;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $month) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        $date .= '<select id="'.$day_name.'" name="'.$day_name.'" '.$onChange.'>';
+        for ($i=1;$i<32;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $day) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date  .= '</select>';
+        $date  .= '<select id="'.$year_name.'" name="'.$year_name.'" '.$onChange.'>';
+        $ystart = $cur_date['year'] - 10;
+        for ($i=$ystart;$i<=$year;$i++) {
+            $date .= '<option value="'.$i.'"';
+            if ($i == $year) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        return $date;
+    }// }}}
+    // {{{ cp1252_to_utf8($str)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $str Parameter description (if any) ...
+     *
+     * @return array   Return description (if any) ...
+     * @access public
+     */
+    function cp1252_to_utf8($str)
+    {
+        $cp1252_map = array(
+            "\xc2\x80" => "\xe2\x82\xac", /* EURO SIGN */
+            "\xc2\x82" => "\xe2\x80\x9a", /* SINGLE LOW-9 QUOTATION MARK */
+            "\xc2\x83" => "\xc6\x92",    /* LATIN SMALL LETTER F WITH HOOK */
+            "\xc2\x84" => "\xe2\x80\x9e", /* DOUBLE LOW-9 QUOTATION MARK */
+            "\xc2\x85" => "\xe2\x80\xa6", /* HORIZONTAL ELLIPSIS */
+            "\xc2\x86" => "\xe2\x80\xa0", /* DAGGER */
+            "\xc2\x87" => "\xe2\x80\xa1", /* DOUBLE DAGGER */
+            "\xc2\x88" => "\xcb\x86",    /* MODIFIER LETTER CIRCUMFLEX ACCENT */
+            "\xc2\x89" => "\xe2\x80\xb0", /* PER MILLE SIGN */
+            "\xc2\x8a" => "\xc5\xa0",    /* LATIN CAPITAL LETTER S WITH CARON */
+            "\xc2\x8b" => "\xe2\x80\xb9", /* SINGLE LEFT-POINTING ANGLE QUOTATION */
+            "\xc2\x8c" => "\xc5\x92",    /* LATIN CAPITAL LIGATURE OE */
+            "\xc2\x8e" => "\xc5\xbd",    /* LATIN CAPITAL LETTER Z WITH CARON */
+            "\xc2\x91" => "\xe2\x80\x98", /* LEFT SINGLE QUOTATION MARK */
+            "\xc2\x92" => "\xe2\x80\x99", /* RIGHT SINGLE QUOTATION MARK */
+            "\xc2\x93" => "\xe2\x80\x9c", /* LEFT DOUBLE QUOTATION MARK */
+            "\xc2\x94" => "\xe2\x80\x9d", /* RIGHT DOUBLE QUOTATION MARK */
+            "\xc2\x95" => "\xe2\x80\xa2", /* BULLET */
+            "\xc2\x96" => "\xe2\x80\x93", /* EN DASH */
+            "\xc2\x97" => "\xe2\x80\x94", /* EM DASH */
+
+            "\xc2\x98" => "\xcb\x9c",    /* SMALL TILDE */
+            "\xc2\x99" => "\xe2\x84\xa2", /* TRADE MARK SIGN */
+            "\xc2\x9a" => "\xc5\xa1",    /* LATIN SMALL LETTER S WITH CARON */
+            "\xc2\x9b" => "\xe2\x80\xba", /* SINGLE RIGHT-POINTING ANGLE QUOTATION*/
+            "\xc2\x9c" => "\xc5\x93",    /* LATIN SMALL LIGATURE OE */
+            "\xc2\x9e" => "\xc5\xbe",    /* LATIN SMALL LETTER Z WITH CARON */
+            "\xc2\x9f" => "\xc5\xb8"      /* LATIN CAPITAL LETTER Y WITH DIAERESIS*/
+               );
+        return  strtr(utf8_encode($str), $cp1252_map);
+    }// }}}
+    // {{{ create_href($options)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param array $options Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function create_href($options)
+    {
+        if (!is_array($options)) {
+            return false;
+        } else {
+            $id          = ($options['id'] && $options['id'] != '')
+                ? ' id="'.$options["id"].'"': '';
+            $title       = ($options['title'] && $options['title'] != '')
+                ? ' title="'.$options["title"].'"': '';
+            $class       = ($options['class'] && $options['class'] != '')
+                ? ' class="'.$options["class"].'"': '';
+            $text        = ($options['text'] && $options['text'] != '')
+                ? strip_tags($options["text"]) : '';
+            $onClick     = ($options['onClick'] && $options['onClick'] != '')
+                ? ' onClick="'.$options["onClick"].'"': '';
+            $onMouseover = ($options['onMouseover'] && $options['onMouseover'] != '')
+                ? ' onMouseover="'.$options["onMouseover"].'"': '';
+            $onMouseout  = ($options['onMouseout'] && $options['onMouseout'] != '')
+                ? ' onMouseout="'.$options["onMouseout"].'"': '';
+            $out         = '<a'.$class.$title.$onClick.$onMouseout.$id.'
+                href="'.$options["href"].'">'.$text.'</a>';
+            return $out;
+        }
+    }// }}}
+    // {{{ create_page_links($totalnum,$num,$start=0,$params,$page_length=ENTRIES_PER_PAGE)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param mixed   $totalnum    Parameter description (if any) ...
+     * @param unknown $num         Parameter description (if any) ...
+     * @param number  $start       Parameter description (if any) ...
+     * @param unknown $params      Parameter description (if any) ...
+     * @param number  $page_length Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access public
+     */
+    function create_page_links($totalnum,$num,$start=0,$params=null,
+            $page_length=ENTRIES_PER_PAGE)
+    {
+        // FIND out which page we're on.
+        if ($totalnum!=0) {
+            $total_pages = floor($totalnum / $page_length);        // total pages = the total result divided by page length rounded down
+            $total_pages++;                                        // then add one
+            if ($start == 0) {                                     // if start is 0 then page is one {
+                $page = 1;
+            } else {
+                $page = ($start / $page_length) + 1;
+            }
+        }
+
+        if ($totalnum > $page_length && ($page != $totalpages)) {
+            $end = $page_length + $start;
+        } else {
+            $end = $totalnum;
+        }
+        $last = $start - $page_length;
+        if (($start - $page_length) < 0) {
+            $prev = "";
+        } else {
+            $prev = "[<a href=\"$GLOBALS[PHP_SELF]?start=".$last
+                ."&$params\">PREVIOUS PAGE</a>]";
+        }
+        if ($end < $totalnum) {
+            $next = "[<a href=\"$GLOBALS[PHP_SELF]?start=".$end
+                ."&$params\">NEXT PAGE</a>]";
+        } else {
+            $next = "";
+        }
+        $starting = $start + 1;
+        $last_c   = $start + $num;
+        $links    = '<div class="page-links">Showing: '.$starting.' to '
+            .$last_c.' of '.$totalnum.'<div> '.$prev. ' &nbsp;  '
+            .$next.'</div></div>';
+        return $links;
+    }// }}}
+    // {{{ create_sitemap()
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function create_sitemap()
+    {
+        $page = new Toolkit_Page(new GLM_TEMPLATE(9999));
+        // 404 pages must not contain any links (including css)
+        //$page->createErrorDocument();
+    }// }}}
+    // {{{ date_entry($month,$day,$year,$month_name,$day_name,$year_name)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string $month      Month
+     * @param string $day        Day
+     * @param string $year       Year
+     * @param string $month_name id and name value of month
+     * @param string $day_name   id and name value of day
+     * @param string $year_name  id and name value of year
+     * @param string $onChange   must be onChange="javzascript;"
+     *
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function date_entry($month,$day,$year,$month_name,$day_name,$year_name,$onChange = null)
+    {
+        $cur_date = getdate();
+        if ($month == "") {
+            $month = $cur_date['mon'];
+        }
+        if ($day == "") {
+            $day = $cur_date['mday'];
+        }
+        if ($year == "") {
+            $year = $cur_date['year'];
+        }
+        $date = '<select id="'.$month_name.'" name="'.$month_name.'" '.$onChange.'>';
+        for ($i=1;$i<13;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $month) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        $date .= '<select id="'.$day_name.'" name="'.$day_name.'" '.$onChange.'>';
+        for ($i=1;$i<32;$i++) {
+            $date .= '<option value="';
+            if ($i < 10) {
+                $date .= "0";
+            }
+            $date .= $i.'"';
+            if ($i == $day) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        $date .= '<select id="'.$year_name.'" name="'.$year_name.'" '.$onChange.'>';
+        for ($i=2000;$i<2023;$i++) {
+            $date .= '<option value="'.$i.'"';
+            if ($i == $year) {
+                $date .= ' selected';
+            }
+            $date .= '>'.$i.'</option>';
+        }
+        $date .= '</select>';
+        return $date;
+    }    // }}}
+    // {{{ explode_template($template,$data)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param boolean $template Parameter description (if any) ...
+     * @param unknown $data     Parameter description (if any) ...
+     *
+     * @return boolean Return description (if any) ...
+     * @access public
+     */
+    function explode_template($template,$data)
+    {
+        $template = GLM_TOOLBOX::template_read($template);
+        $output   = GLM_TOOLBOX::template_replacement($template, $data);
+        return $output;
+
+    }// }}}
+    // {{{ file_upload($form_field, $file_name, $destination_path, $restricted = false)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $form_field       Parameter description (if any) ...
+     * @param string  $file_name        Parameter description (if any) ...
+     * @param string  $destination_path Parameter description (if any) ...
+     * @param boolean $restricted       Parameter description (if any) ...
+     *
+     * @return array   Return description (if any) ...
+     * @access public
+     */
+    function file_upload($form_field, $file_name, $destination_path, $restricted = false)
+    {
+        $file_name_in_use = false;
+        $file_name        = ereg_replace("[!@#$%^&()+={};:\'\"\/ ]", "-", $file_name);
+        if ($restricted) {
+            $size = getImageSize($form_field);
+            if (!in_array($size[2], array(1, 2, 3))) {
+                echo '<p style="background-color:red;color:white;">'
+                .'The file you uploaded was of an incorect type, please only upload .gif,.png or .jpg files'
+                .'<BR CLEAR=ALL>'
+                .'</p>'
+                ."Hit your browser's back button to continue"
+                .'<P>';
+                $error[0] = "ERROR";
+                return $error;
+            }
+        }
+        if (file_exists($destination_path.$file_name)) {
+            $file_name_in_use = true;
+        }
+        if ($file_name_in_use == true) {
+            $new_file_name     = mktime().$file_name;
+            $new_file_location = $destination_path.$new_file_name;
+            copy($form_field, $new_file_location);
+            $file_upload       = $new_file_name;
+            $file_upload_array = array($new_file_name, $new_file_location);
+        } else {
+            $new_file_name     = $file_name;
+            $new_file_location = $destination_path.$new_file_name;
+            copy($form_field, $new_file_location);
+            $file_upload       = $new_file_name;
+            $file_upload_array = array($new_file_name, $new_file_location);
+        }
+        if (is_file($new_file_location)) {
+            chmod($new_file_location, 0666);
+        }
+        if ($restricted) {
+            return $file_upload_array;
+        } else {
+            return $file_upload;
+        }
+    }// }}}
+    // {{{ footer()
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function footer()
+    {
+        $out = '
+            </body>
+            </html>
+            ';
+        echo $out;
+    }// }}}
+    // {{{ form_footer($name, $suppress = 0, $cs)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $name     Parameter description (if any) ...
+     * @param integer $suppress Parameter description (if any) ...
+     * @param unknown $cs       Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function form_footer($name, $suppress = 0, $cs = 2)
+    {
+        echo "<tr><td colspan=\"$cs\" align=center>
+            <input type=\"SUBMIT\" name=\"Command\" value=\"$name\">";
+        if ($suppress == 1) {
+            echo '<input type="SUBMIT" name="Command" value="Delete" onclick="return confirm(\'This will be Deleted! Are you sure?\');">';
+        }
+        /*        echo "<input type=\"SUBMIT\" name=\"Command\" value=\"Cancel\">";*/
+        echo "</td>";
+    }// }}}
+    // {{{ form_header($action, $method, $hidden = "")
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $action Parameter description (if any) ...
+     * @param unknown $method Parameter description (if any) ...
+     * @param mixed   $hidden Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function form_header($action, $method, $hidden = "")
+    {
+        echo "<form action=\"$action\" method=\"$method\"
+            enctype=\"multipart/form-data\">";
+        if ($hidden != "" && is_array($hidden)) {
+            foreach ($hidden as $key=>$value) {
+                echo "<input type=\"hidden\" name=\"$key\" value=\"$value\">";
+            }
+        }
+    }// }}}
+    // {{{ get_parentid($id)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param integer $id Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public
+     */
+    function get_parentid($id)
+    {
+        static $parentshow;
+        if ($id == 0) {
+            return 0;
+        }
+        if (!is_array($parentshow)) {
+            $qs        = "select parent from bus_category where id = $id";
+            $parentrow = GLM_TOOLBOX::db_auto_get_data($qs);
+        }
+        if ($parentrow[0]['parent'] == 0) {
+            return $id;
+        } else {
+            return GLM_TOOLBOX::get_parentid($parentrow[0]['parent']);
+        }
+    }// }}}
+    // {{{ get_season()
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @return string Return description (if any) ...
+     * @access public
+     */
+    function get_season()
+    {
+        /*
+           The seasons
+           Spring     March 21st     to     June 20
+           Summer     June 21     to     Sept 20
+           Fall        Sept 21        to  Dec 20
+           Winter        Dec  21        to    March 20
+         */
+        $Spring = mktime(0, 0, 0, 3, 21, date("Y"));
+        $Summer = mktime(0, 0, 0, 6, 21, date("Y"));
+        $Fall   = mktime(0, 0, 0, 9, 21, date("Y"));
+        $Winter = mktime(0, 0, 0, 12, 21, date("Y"));
+        $time   = mktime();
+        if ($time >= $Spring && $time < $Summer) {
+            $season = "spring";
+        } elseif ($time >= $Summer && $time < $Fall) {
+            $season = "summer";
+        } elseif ($time >= $Fall && $time < $Winter) {
+            $season = "fall";
+        } else {
+            $season = "winter";
+        }
+        return $season;
+    }// }}}
+    // {{{ get_size($file)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $file Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public
+     */
+    function get_size($file)
+    {
+        $size = filesize($file) / 1024;
+        if ($size >= 1000) {
+            $size  = (float) number_format($size / 1000, 2);
+            $size .= 'MB';
+        } elseif ($size < 1000) {
+            $size  = ceil($size);
+            $size .= 'KB';
+        }
+        return $size;
+    }// }}}
+    // {{{ html_error($msg, $bail)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string  $msg  Parameter description (if any) ...
+     * @param unknown $bail Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function html_error($msg, $bail)
+    {
+        echo '<div style="color:red;"><pre>'.$msg.'</pre></div>';
+        if ($bail) {
+            GLM_TOOLBOX::footer();
+        }
+    }// }}}
+    // {{{ html_header($title, $msg, $img)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $title Parameter description (if any) ...
+     * @param unknown $msg   Parameter description (if any) ...
+     * @param unknown $img   Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function html_header($title, $msg, $img)
+    {
+        $header_table_width = "400";
+        $header_table_align = "center";
+        echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+            "http://www.w3.org/TR/html4/loose.dtd">
+            <html>
+            <head>
+            <title><?echo $title?></title>
+            <link type="text/css" rel=stylesheet href="<?echo STYLE?>">
+            </head>
+            <body>
+            <table width="<?echo $header_table_width?>" align="<?echo $header_table_align?>" summary="Header Information" class="headertable" cellspacing="0" cellpadding="3">
+            <tr class="headertr">
+            <td class="headertd">';
+        if ($img) {
+            echo '<img src="<?echo IMG_BASE.$img?>" alt="<?echo HEAD?>" border="0">';
+        }
+        echo '</td>
+            </tr>
+            <tr>
+            <td class="headertd2" align="center">
+            <div class="headerh2" align="center"><?echo "$msg"?></div>
+            </td>
+            </tr>
+            </table>';
+    }// }}}
+    // {{{ html_nav_table($nav, $w)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param array   $nav Parameter description (if any) ...
+     * @param unknown $w   Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function html_nav_table($nav, $w)
+    {
+        if (is_array($nav)) {
+            $out = '<ul class="admin_nav">';
+            foreach ($nav as $link => $url) {
+                if (is_array($url)) {
+                    $out .= '<li><a href="'.$urli[0].'" '.$url[1].'>'.$link.'</a></li>';
+                } else {
+                    $out .= '<li><a href="'.$url.'">'.$link.'</a></li>';
+                }
+            }
+            $out .= '</ul>';
+        }
+        echo $out;
+    }// }}}
+    // {{{ http_strip(&$string)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown &$string Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function http_strip(&$string)
+    {
+        $test_string = strtolower($string);
+        if (substr($test_string, 0, 7) == "http://") {
+            $string = substr($string, 7);
+        }
+    }// }}}
+    // {{{ img_resize($path2image, $path2thumb, $size)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $path2image Parameter description (if any) ...
+     * @param unknown $path2thumb Parameter description (if any) ...
+     * @param unknown $size       Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public
+     */
+    function img_resize($path2image, $path2thumb, $size)
+    {
+        exec("which convert", $output, $return);
+        if ($return == 0) {
+            $CONVERT = $output[0];
+        } else {
+            return $error = array('convert path uknown');
+        }
+        $imageName = basename($path2image);
+        $thumbName = basename($path2thumb);
+
+        exec("$CONVERT -quality 100 -scale $size $path2image $path2thumb");
+        //chmod($path2thumb,660);
+
+        $img_resize_array = array("$imageName","$path2image","$thumbName","$path2thumb");
+        return $img_resize_array;
+    }// }}}
+    // {{{ img_upload($form_field, $img_name, $destination_path)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $form_field       Parameter description (if any) ...
+     * @param unknown $img_name         Parameter description (if any) ...
+     * @param unknown $destination_path Parameter description (if any) ...
+     *
+     * @return boolean Return description (if any) ...
+     * @access public
+     */
+    function img_upload($form_field, $img_name, $destination_path)
+    {
+        return GLM_TOOLBOX::file_upload($form_field, $img_name, $destination_path, true);
+    }// }}}
+    // {{{ is_utf8($string)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $string Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public
+     */
+    function is_utf8($string)
+    {
+        return preg_match('/^([\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xec][\x80-\xbf]{2}|\xed[\x80-\x9f][\x80-\xbf]|[\xee-\xef][\x80-\xbf]{2}|f0[\x90-\xbf][\x80-\xbf]{2}|[\xf1-\xf3][\x80-\xbf]{3}|\xf4[\x80-\x8f][\x80-\xbf]{2})*$/', $string) === 1;
+    }// }}}
+    // {{{ make_data_table($data, $tableId = null)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param array  $data    Parameter description (if any) ...
+     * @param string $tableId Parameter description (if any) ...
+     *
+     * @return mixed  Return description (if any) ...
+     * @access public
+     */
+    function make_data_table($data, $tableId = null)
+    {
+        if (is_array($data)) {
+            $count = 0;
+            foreach ($data as $row) {
+                if (!is_array($row)) {
+                    return false;
+                }
+                $table_body .= '<tr>
+                    ';
+                $col         = 1;
+                foreach ($row as $field_name => $field) {
+                    if ($count == 0) {
+                        $table_head .= '<th>'.$field_name.'</th>';
+                    }
+                    $table_body .= '<td class="c'.$col.'">'.$field.'</td>';
+                    $col++;
+                }
+                $count++;
+                $table_body .= '</tr>
+                    ';
+            }
+            $table = '<table'.(($tableId)?' id="'.$tableId.'"':'').'>
+                <tr>'.$table_head.'</tr>
+                '.$table_body.'
+                </table>';
+        }
+        return $table;
+    }// }}}
+    // {{{ make_teaser($text, $maxlength, $strip_tags=false)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $text       Parameter description (if any) ...
+     * @param unknown $maxlength  Parameter description (if any) ...
+     * @param boolean $strip_tags Parameter description (if any) ...
+     *
+     * @return unknown Return description (if any) ...
+     * @access public
+     */
+    function make_teaser($text, $maxlength, $strip_tags=false)
+    {
+        if ($strip_tags) {
+            $text = strip_tags($text);
+        }
+        if (strlen($text) > $maxlength) {
+            if (!($pos = strpos($text, ' ', $maxlength))) {
+                return $text;
+            }
+            $text = substr($text, 0, $pos);
+        }
+        return $text;
+    }// }}}
+    // {{{ myEncode($string)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $string Parameter description (if any) ...
+     *
+     * @return boolean Return description (if any) ...
+     * @access public
+     */
+    function myEncode($string)
+    {
+        if (GLM_TOOLBOX::is_utf8($string)) {
+            return $string;
+        } else {
+            return GLM_TOOLBOX::cp1252_to_utf8($string);
+        }
+    }// }}}
+    // {{{ php_old_pg()
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @return boolean Return description (if any) ...
+     * @access public
+     */
+    function php_old_pg()
+    {
+        switch($this->php_version[0]) {
+        case 5:
+            return false;
+            break;
+
+        case 4:
+            switch($php_version[1]) {
+            case 2:
+                return false;
+                break;
+            case 1:
+                return true;
+                break;
+            }
+            break;
+        }
+    }// }}}
+    // {{{ php_version_check()
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @return array  Return description (if any) ...
+     * @access public
+     */
+    function php_version_check()
+    {
+        $this->php_version = explode(".", phpversion());
+        return $this->php_version;
+    }// }}}
+    // {{{ process_image($image, $image_name)
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $image      Parameter description (if any) ...
+     * @param unknown $image_name Parameter description (if any) ...
+     *
+     * @return unknown Return description (if any) ...
+     * @access public
+     */
+    function process_image($image)
+    {
+        require_once BASE.'Toolkit/Image/Server.php';
+        $imServer = new Toolkit_Image_Server();
+        $image_name = $imServer->imageUpload($image);
+        return $image_name;
+    }// }}}
+    // {{{ send_html_email($to, $subject, $body, $headers, $charset = 'utf-8')
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $to      Parameter description (if any) ...
+     * @param unknown $subject Parameter description (if any) ...
+     * @param unknown $body    Parameter description (if any) ...
+     * @param string  $headers Parameter description (if any) ...
+     * @param string  $charset Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function send_html_email($to, $subject, $body, $headers, $charset = 'utf-8')
+    {
+        if ($headers) {
+            $headers .= "\n";
+        }
+        $headers .= "MIME-Version: 1.0\n"
+                 .  "Content-type: text/html; charset=".$charset;
+        mail($to, $subject, $body, $headers);
+    }// }}}
+    // {{{ template_read($template)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param nknown $template Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access public
+     */
+    function template_read($template)
+    {
+        $fp       = fopen($template, "r");
+        $contents = fread($fp, filesize($template));
+        fclose($fp);
+        if ($contents) {
+            return $contents;
+        } else {
+            return "";
+        }
+    }// }}}
+    // {{{ template_replacement($template, $fieldarr)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $template Parameter description (if any) ...
+     * @param array   $fieldarr Parameter description (if any) ...
+     *
+     * @return unknown Return description (if any) ...
+     * @access public
+     */
+    function template_replacement($template, $fieldarr)
+    {
+        if (is_array($fieldarr)) {
+            $fieldarr['BASE_URL'] = BASE_URL;
+            foreach ($fieldarr as $key => $value) {
+                $p = "/<!-- loop:$key -->(.*?)<!-- endloop:$key -->/s";
+                if (preg_match($p, $template, $match) && is_array($value)) {
+                    // ok we have found a loop for this array
+                    // now lets add into this template the correct
+                    // number we'll need to do the replacement
+                    // replace template loop section with {loop:$key}
+                    $p        = "/<!-- loop:$key -->(.*?)<!-- endloop:$key -->/s";
+                    $template = preg_replace($p, "{loop:$key}", $template);
+                    // saving the actual template with match run through
+                    // the array to build a tempory section
+                    // then switch it out for {loop:$key}
+                    $template_temp = '';
+                    foreach ($value as $srow) {
+                        $tpl = $match[1];
+                        foreach ($srow as $field => $val) {
+                            $p = "/<!-- if:$key:$field -->(.*?)<!-- endif:$key:$field -->/s";
+                            if (preg_match($p, $template) && $val == '') {
+                                $p   = "/<!-- if:$key:$field -->(.*?)<!-- endif:$key:$field -->/s";
+                                $tpl = preg_replace($p, '', $tpl);
+                            } else {
+                                $tpl = str_replace("<!-- $key:$field -->", $val, $tpl);
+                            }
+                        }
+                        $template_temp .= $tpl;
+                    }
+                    $template = str_replace("{loop:$key}", $template_temp, $template);
+
+                } else {
+                    $p = "/<!-- if:$key -->(.*?)<!-- endif:$key -->/s";
+                    if (preg_match($p, $template) && $value == '') {
+                        $p        = "/<!-- if:$key -->(.*?)<!-- endif:$key -->/s";
+                        $template = preg_replace($p, '', $template);
+                    } else {
+                        $template = str_replace("<!-- $key -->", $value, $template);
+                    }
+                }
+            }
+        }
+
+        return $template;
+    }// }}}
+    // {{{ text_area($name, $value, $rows = 15, $cols = 50, $wrap = "virtual")
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @deprecated
+     *
+     * @param unknown $name  Parameter description (if any) ...
+     * @param unknown $value Parameter description (if any) ...
+     * @param integer $rows  Parameter description (if any) ...
+     * @param integer $cols  Parameter description (if any) ...
+     * @param string  $wrap  Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function text_area($name, $value, $rows = 15, $cols = 50, $wrap = "virtual")
+    {
+        include_once BASE . 'fckeditor/fckeditor.php';
+        $oFCKeditor           = new FCKeditor($name);
+        $oFCKeditor->BasePath = BASE_URL . 'fckeditor/';
+        $oFCKeditor->Width    = '570';
+        $oFCKeditor->Height   = '400';
+        $oFCKeditor->Value    = $value;
+        echo '<td>';
+        $oFCKeditor->Create();
+        echo '</td>';
+
+    }// }}}
+    // {{{ text_box($name, $value, $size = 35)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $name  Parameter description (if any) ...
+     * @param unknown $value Parameter description (if any) ...
+     * @param integer $size  Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function text_box($name, $value, $size = 35)
+    {
+        echo "<td class=\"navtd2\"><input type=\"text\" name=\"$name\"
+            value=\"".htmlspecialchars($value)."\" size=\"$size\"></td>";
+    }// }}}
+    // {{{ time_entry($H, $m, $F, $H_name, $m_name, $F_name)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param mixed   $H      Parameter description (if any) ...
+     * @param string  $m      Parameter description (if any) ...
+     * @param string  $F      Parameter description (if any) ...
+     * @param unknown $H_name Parameter description (if any) ...
+     * @param unknown $m_name Parameter description (if any) ...
+     * @param unknown $F_name Parameter description (if any) ...
+     *
+     * @return string  Return description (if any) ...
+     * @access public
+     */
+    function time_entry($H, $m, $F, $H_name, $m_name, $F_name)
+    {
+        $cur_date = getdate();
+        if ($H == "") {
+            $H = $cur_date['hours'];
+        }
+        if ($m == "") {
+            $m = $cur_date['minutes'];
+        }
+        if ($H>12) {
+            $F = "PM";
+            $H = $H - 12;
+        }
+        $time = "Hr:<select name=\"$H_name\" size=\"1\">";
+        for ($i=1;$i<=12;$i++) {
+            $time .= "<option value=\"";
+            if ($i < 10) {
+                $time .= "0";
+            }
+            $time .= "$i\"";
+            if ($i == $H) {
+                $time .= " selected";
+            }
+            $time .= ">$i\n";
+        }
+        $time .= "</select>\n";
+        $time .= "Min:<select name=\"$m_name\" size=\"1\">";
+        for ($i=0;$i<60;$i=$i+15) {
+            $time .= "<Option value=\"";
+            if ($i < 10) {
+                $time .= "0";
+            }
+            $time .= "$i\"";
+            if ($i == $m) {
+                $time .= " selected";
+            }
+            $time .= ">";
+            if ($i < 10) {
+                $time .= "0";
+            }
+            $time .= "$i\n";
+        }
+        $time .= "</select>";
+        $time .= "<select name=\"$F_name\" size=\"1\">";
+        $time .= "<option value=\"AM\"";
+        if ($F == "AM") {
+            $time .= " selected";
+        }
+        $time .= ">AM\n";
+        $time .= "<option value=\"PM\"";
+        if ($F == "PM") {
+            $time .= " selected";
+        }
+        $time .= ">PM\n";
+        $time .= "</select>\n";
+        return $time;
+    }// }}}
+    // {{{ top($message, $hp,$hp2 = null)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param string  $message Parameter description (if any) ...
+     * @param unknown $hp      Parameter description (if any) ...
+     * @param string  $hp2     Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function top($message, $hp,$hp2 = null)
+    {
+        if ($hp2 != "") {
+            $help_guide = '<div id="glm-manual">';
+            /*
+               $help_guide = '<div id="glm-manual"><a id="manual-html"
+               href="http://www.gaslightmedia.com/manuals/html/'.$hp2.'.html"
+               target="_blank">Online Help Guide</a>&nbsp;';
+             */
+            $help_guide .= '<a id="manual-pdf"
+                href="http://www.gaslightmedia.com/manuals/pdf/'.$hp2.'.pdf"
+                target="_blank">Printable Help Guide</a></div>';
+        }
+               //      Default resources for admin pages.
+               $GLOBALS['scripts'][] = GLM_APP_BASE_URL . 'libjs/jquery-1.3.2.min.js';
+               $GLOBALS['styleSheets'][] = BASE_URL . 'admin/main.css';
+
+               $scripts = Toolkit_Common::getScripts();
+               $styles  = Toolkit_Common::getStyleSheets();
+
+        $out = '
+            <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+            "http://www.w3.org/TR/html4/strict.dtd">
+            <html>
+            <head>
+            <title>Untitled</title>
+            <meta http-equiv="content-type" content="text/html;charset=utf-8">
+                       ' .  $styles .  $scripts .'
+            </head>
+            <body>
+            <h1>'.$message.'</h1>
+            '.$help_guide.'
+            ';
+        echo $out;
+    }// }}}
+    // {{{ top2($message, $hp,$hp2 = null)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $message Parameter description (if any) ...
+     * @param unknown $hp      Parameter description (if any) ...
+     * @param unknown $hp2     Parameter description (if any) ...
+     *
+     * @return void
+     * @access public
+     */
+    function top2($message, $hp, $hp2 = null)
+    {
+        // make this an alias to top()
+        // by calling top instead of adding extra code
+        GLM_TOOLBOX::top($message, $hp, $hp2);
+    }// }}}
+    // {{{ valid_email($email)
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $email Parameter description (if any) ...
+     *
+     * @return boolean Return description (if any) ...
+     * @access public
+     */
+    function valid_email($email)
+    {
+        // First, we check that there's one @ symbol, and lengths are right
+        if (!ereg("^[^@]{1,64}@[^@]{1,255}$", $email)) {
+            // Email invalid because wrong number of characters in one section,
+            // or wrong number of @ symbols.
+            return false;
+        }
+        // Split it into sections to make life easier
+        $email_array = explode("@", $email);
+        $local_array = explode(".", $email_array[0]);
+        for ($i = 0; $i < sizeof($local_array); $i++) {
+            $p = "^(([A-Za-z0-9!#$%&'*+/=?^_`{"
+                ."|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})"
+                . "|(\"[^(\\|\")]{0,62}\"))$";
+            if (!ereg($p, $local_array[$i])) {
+                return false;
+            }
+        }
+        if (!ereg("^\[?[0-9\.]+\]?$", $email_array[1])) {
+            // Check if domain is IP. If not, it should be valid domain name
+            $domain_array = explode(".", $email_array[1]);
+            if (sizeof($domain_array) < 2) {
+                return false; // Not enough parts to domain
+            }
+            for ($i = 0; $i < sizeof($domain_array); $i++) {
+                $p = "^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])"
+                    ."|([A-Za-z0-9]+))$";
+                if (!ereg($p, $domain_array[$i])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }// }}}
+    // {{{ word_limiter($str, $limit = 100, $end_char = '&#8230;')
+
+
+    /**
+     * Short description for function
+     *
+     * Long description (if any) ...
+     *
+     * @param unknown $str      Parameter description (if any) ...
+     * @param mixed   $limit    Parameter description (if any) ...
+     * @param string  $end_char Parameter description (if any) ...
+     *
+     * @return mixed   Return description (if any) ...
+     * @access public
+     */
+    function word_limiter($str, $limit = 100, $end_char = '&#8230;')
+    {
+        if (trim($str) == '') {
+            return $str;
+        }
+
+        preg_match('/\s*(?:\S*\s*) {'. (int) $limit .'}/', $str, $matches);
+
+        if (strlen($matches[0]) == strlen($str)) {
+            $end_char = '';
+        }
+        return rtrim($matches[0]) . $end_char;
+    }// }}}
+}
+?>
diff --git a/contactform.css b/contactform.css
new file mode 100644 (file)
index 0000000..3a382ae
--- /dev/null
@@ -0,0 +1,100 @@
+#contact,
+.webform {margin: 10px;}
+
+.req {color: #f00;}
+
+/* Main table */
+#contact table,
+.webform table { 
+       background-color: #fff;
+       border: 1px solid #eee;
+       border-collapse: collapse;
+       }
+/* Any Table inside the form */        
+#contact table table,
+.webform table table {
+       width: 100%;
+       margin-left: 0;
+       border: 0px solid #ddd;
+       }
+#contact table table td        {       border: 0px solid #ddd;}
+       
+/* TD's */     
+#contact td,
+.webform td { 
+       padding: 3px;
+       font-family: arial, helvetica, sans-serif;
+       color: #000;
+       border: 1px solid #eee;
+       border-collapse: collapse;
+       }
+/* Left Cells */
+.labelcell { 
+       background-color: transparent; 
+       text-align: right;
+       padding-right: 10px;
+       padding-top: 3px;
+       white-space:nowrap;
+       width: 140px;
+       } 
+/*Right Cells */
+.fieldcell {
+       padding-left: 4px;
+       width: 250px;
+       } 
+
+/* Misc */
+textarea {width: 95%; height: 100px; display:block;}
+
+/* WARNINGS */
+#form-warning-top {
+       margin-top: 1em;
+       margin-bottom: 0.5em;
+       color: #f00;
+       font-size: 14px;
+       font-weight: bold;
+       }
+/* SHow hide instruction div */
+#contact table tr td .form-warning-inside, 
+.webform table tr td .form-warning-inside {
+       display: none;
+       }
+#contact table tr.req td .form-warning-inside,
+.webform table tr.req td .form-warning-inside {
+       display: block;
+       background-image: url('images/error.gif');
+       background-repeat:no-repeat;
+       background-position: top left;
+       padding: 2px 2px 2px 22px;
+}
+
+/* Showing/hiding rows */
+/*invisible*/
+#contact table tr td.instructioncell,
+.webform table tr td.instructioncell {
+       width: 200px;
+       white-space: nowrap;
+       color: #fff;
+       }
+       
+/*visible*/
+table tr.req {
+       border: 2px solid #f00;
+       background-color:#FCD6D4;
+       border-collapse: separate;
+       border-collapse: collapse;
+}
+/*color*/
+table tr.req td                        { background-color: #fcd6d4;}
+table tr.req td.labelcell      { background-color: #FCD6D4; }
+table tr.req td.fieldcell      { background-color: #FCD6D4; }
+table tr.req td.instructioncell        { background-color: #FCD6D4; }  
+table tr.req td.instructioncell {
+       padding: 4px;
+       padding-left: 20px;
+       background-image: url('images/error.gif');
+       background-repeat:no-repeat;
+       background-position: center left;
+       border-width: 0;
+       color: #000;
+       }
diff --git a/coupons.css b/coupons.css
new file mode 100644 (file)
index 0000000..11d6589
--- /dev/null
@@ -0,0 +1,81 @@
+#coupons {margin-left: 12px;}
+
+.couponheader {
+       border-bottom: 2px solid #B5B292;
+       font-size: 16px;
+       color: #369;
+       font-weight: bold;
+  margin-top: 1em;
+       }
+.couponitem {
+       background-color: #fff;
+       border: 1px dashed #B5B292;
+       font-weight:normal;
+       color: #369;
+       margin: 5px;
+       font-size: 12px;
+       text-align: center;
+       height: 1%;
+       overflow: hidden;
+       float: left;
+       position: relative;
+       width: 256px;
+       }
+.couponitem strong {
+       display: block;
+       font-size: 16px;
+       display: block;
+       margin: 12px auto;
+       }       
+.couponitem a {display: block; font-size: 12px;}       
+.couponitem img {
+
+       margin: 0 auto;
+       display: block;
+       }
+.couponcontainer {
+       text-align: left;
+       height: 1%;
+       overflow: hidden;
+       }
+.couponitem .couponlogo {
+       margin-top: 10px;
+       }       
+.couponcontainer h2 {
+       font-size: 16px; color: black;
+       clear: left;
+       }
+.couponcatheader {font-size: 16px; color: #369; font-weight: bold;}
+.couponcontainer p {
+       margin: 0.5em 22px !important;
+       text-align: left;
+       }
+.expire_date {
+       float: right;
+       margin: 12px;
+       }
+.coupon-url {
+       float: left;
+       margin: 12px;
+       }
+       
+.newBackground {
+background-color: #B5B292; color: #fff; font-weight: bold; padding: 5px; font-size: 13px; text-align: left;
+}
+.oldBackground {
+background-color: #E7E7D5; color: #3D1006; font-weight: bold; padding: 5px; font-size: 13px; text-align: left;
+}
+.changeParent {display: block;}
+
+.coupon-buttons {
+       text-align: center;
+       padding: 6px;
+       position: relative;
+       clear: left;
+       margin-top: 12px;
+       }
+.coupon-buttons input { padding: auto 12px;}   
+.couponDivider {
+       clear: left;
+}
+.couponRow {clear:both;}
diff --git a/download.php b/download.php
new file mode 100644 (file)
index 0000000..8ec3fcf
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+include('setup.phtml');
+$output = BASE.'uploads/'.$file;
+if(ini_get('zlib.output_compression'))
+{
+       ini_set('zlib.output_compression', 'Off');
+}
+header("Content-Type: application/force-download\n");
+/* Correction for the stupid MSIE thing */
+if(strstr(getenv('HTTP_USER_AGENT'), 'MSIE'))
+{
+       header("Content-Disposition: inline; filename=\"$file\"");
+}
+else 
+{
+       header("Content-Disposition: attachment; filename=\"$file\"");
+}
+$fn=fopen($output , "r");
+fpassthru($fn);
+@fclose($fn);
+exit();
+?>
diff --git a/email.css b/email.css
new file mode 100644 (file)
index 0000000..70d0ad3
--- /dev/null
+++ b/email.css
@@ -0,0 +1,42 @@
+body {
+       background-color: #ff;
+       color: black;
+       font-family: verdana, arial, helvetica, sans-serif;
+}
+h1, h2 {
+       font-family: arial, helvetica, sans-serif;
+}
+h1 {
+       font-size: 18px;
+}
+h2 {
+       font-size: 16px;
+       margin-bottom: 5px;
+}
+p {
+       font-size: 12px;
+}
+.label {
+       font-weight: bold;
+       background-color: transparent;
+       text-align: right;
+       width: 200px;
+       padding: 5px;
+}
+.field {
+       background-color: #fff;
+       padding: 3px;
+}
+table.data {
+       background-color: #fff;
+       color: #000;
+       width: 500px;
+       border: 1px solid #ccc;
+       border-collapse: collapse;
+       margin-left: 20px;
+}
+table.data td {
+       border: 1px solid #ccc;
+       padding-left: 4px;
+       font-size: 12px;
+}
diff --git a/event.css b/event.css
new file mode 100644 (file)
index 0000000..55343d9
--- /dev/null
+++ b/event.css
@@ -0,0 +1,266 @@
+/* Side bar */
+#events {
+       margin: 10px 8px;
+       clear: both;
+       margin-top: 12px;
+       border: 1px solid #006BB4;
+       background: white;
+}
+#eventtitle {
+       font-weight: 14px;
+       text-transform: uppercase;
+       text-align: center;
+       font-weight: bold;
+       border-bottom: 1px solid #ccc;
+       padding: 5px;
+}
+#prev-event {
+       text-indent: -9000px;
+       display: block;
+       height: 30px;
+       width: 150px;
+       background: url(Toolkit/Events/assets/arrowUp.png) no-repeat center center #E66B23;
+       cursor: hand;
+        cursor: pointer;
+       }
+#next-event  {
+        text-indent: -9000px;
+        display: block;
+        height: 30px;
+        width: 150px;
+        background: url(Toolkit/Events/assets/arrowDown.png) no-repeat center center #E66B23;
+       cursor: hand;
+        cursor: pointer;
+        }
+#next-event:hover,
+#prev-event:hover {
+       background-color: #006BB5;
+}
+#events .date {
+       font-size: 11px;
+       margin: 0;
+
+       }
+#events ul, #events li {
+       list-style-type: none;
+       margin: 0;
+       padding: 0;
+       display: block;
+}
+#events li {
+       padding: 5px 10px;
+}
+#events ul a {
+       font-weight: bold;
+       font-size: 14px;
+
+}
+/* event calendar styles*/
+table.caltable {
+       font-family: Arial, Helvetica, sans-serif;
+       color: #003266;
+       font-size: 10px;
+       border:solid #67A5CF 1px;
+       border-collapse: collapse;
+       margin-top: 10px;
+       clear: both;
+       }
+table.caltablesmall {
+       float: left;
+       font-family: tahoma, arial, sans-serif;
+       color: #888;
+       border:solid #67A5CF 1px;
+       margin:0 0 0 5px;
+       border-collapse: collapse;
+       width: 120px;
+       }
+table.caltable td {border:solid #67A5CF 1px;}  
+table.caltablesmall td {border:solid #67A5CF 1px;border-collapse: collapse;}   
+td.caltitle {
+       text-align:center;
+       font-weight:bold;
+       background-color: #67A5CF;
+       color: white;
+       }
+td.caltitle a {color:white;margin:0;padding:0; text-transform: uppercase;}
+td.calmonth {
+       text-align:center;
+       font-weight:bold;
+       background-color: #67A5CF;
+       color: white;
+       font-size: 14px;
+       text-transform: uppercase;}     
+td.calmonthsmall {
+       text-align:center;
+       font-weight:bold;
+       background-color: #67A5CF;
+       color: white;
+       font-size: 9px;
+       text-transform: uppercase;}     
+td.calspacer { background-color:#eee;
+       font-size: 4px;}
+td.calspacersmall {
+       background-color:#eee;
+       font-size: 4px;
+}
+td.caldayheader{
+       text-align:center;
+       height:auto;
+       background-color: #e8dcc2;
+       color:#000;
+       width: 68px;
+       width: auto;
+       }
+td.caldayheadersmall{
+       text-align:center;
+       height:auto;
+       background-color: #e8dcc2;
+       color:#000;
+       width: 5px;
+       width: auto;
+       font-size: 10px;
+       }
+
+td.calday {
+       text-align:left;
+       width: 14%;
+       font-size: 11px;
+       font-family: tahoma, arial, sans-serif;}
+td.caldaysmall {
+       font-family: tahoma, arial, sans-serif;
+       font-size: 9px;
+       text-align:center;
+       padding: 2px;
+       }
+/* td.calday a { display: block; margin-top: 0.5em; }*/
+td.calday a:link { color: #000; }
+td.calday a:visited { color: #333; }
+td.calday a:active { color: #000; }
+td.calday a:hover { color: #555;  }
+
+td.caldaysmall a { }
+td.caldaysmall a:link { color: #000; }
+td.caldaysmall a:visited { color: #222; }
+td.caldaysmall a:active { color: #000; }
+td.caldaysmall a:hover { color: #000; }
+
+td.calmonthsmall a { font-weight:bold; margin:0;padding:0; color:white;}
+
+img.calleftarrow { float:left;}
+img.calrightarrow { float: right;}
+
+/* FLAT VIEW */
+.eventcontainer {
+       clear: both;
+       margin-top: 1em;
+       font-size: 12px;
+       padding-bottom: 1em;
+       margin-bottom: 1em;
+       }
+.event-list {
+       margin-top: 2em;
+       }
+.event-list h2 {
+       font-size: 18px;
+       margin-bottom: 0.5em;
+}      
+.eventimg1 {
+       float: right;
+       border: 0px solid #8094C0;
+       margin: 0 10px 10px 10px;
+       }
+.eventimg2 {
+       float: left;
+       border: 0px solid #8094C0;
+       margin: 0 10px 10px 10px;
+       }
+.eventimg3 {
+       float: right;
+       border: 0px solid #8094C0;
+       margin: 0 10px 10px 10px;
+       }               
+.eventheader {
+       font-size: 18px;
+       font-weight: bold;
+       color: #219BAF;
+       padding-top: 1em;
+       }
+.eventdate {font-weight: bold;  color: #000;}
+
+.eventvalue a:link, .eventvalue a:visited, .eventvalue a:hover, .eventvalue a:active { font-weight: bold; text-decoration: underline;}
+.eventvalue a:link {color: #13246C;}
+.eventvalue a:visited {color: #13246C;}
+.eventvalue a:active {color: #13246C;}
+.eventvalue a:hover {color: #000;}
+
+.eventdescr {margin: 0.5em 0;}
+#smallcals {border: 0px solid red; float: right;}
+
+
+/* customized */
+.topic a {display: block; padding: 3px;}
+.topic div {border-top: 1px solid #aaa;} 
+
+
+/* SELECT TOPICS */
+#topicsearch {margin: 0 0 10px 0; display:block;float:left; background: #eee; padding: 1px; border: 1px dotted #ddd;}
+#topicsearch .topicsearchrow {clear: left;}
+#topicsearch .topicsearchheader {width:12px;height:12px; float:left; position: relative;  border: 1px solid #666; margin-bottom: 1px; margin-right: 4px; font-size: 1px;}
+#topicsearch a  {display: block;  position: relative; font-size: 10px;}
+#topicsearch a:link  {color: #000;}
+#topicsearch a:visited  {color: #333;}
+#topicsearch a:active  {color: #000;}
+#topicsearch a:hover  {color: #666;}
+
+
+/* --- */
+
+#monthsearch { display:block;  padding-bottom: 1em; clear: both;}
+#monthsearch form {display:block;float:left;font-size: 12px;clear: both;}
+#monthsearch select, #monthsearch input   {font-size: 12px; margin-right: 5px;}
+#monthsearch a {margin-left: 18px;}
+#monthsearch a:link {color: #000;}
+#monthsearch a:visited {color: #000;}
+#monthsearch a:hover {color: #00387B;}
+#monthsearch a:active {color: #000;}
+
+
+
+.color1 {background-color: #FFCCCC;}
+.color2 {background-color: #CC9999;}
+.color3 {background-color: #FF9999;}
+.color4 {background-color: #FFCCFF;}
+.color5 {background-color: #CC99CC;}
+
+.color6 {background-color: #FF99FF;}
+.color7 {background-color: #CCCCFF;}
+.color8 {background-color: #9999CC;}
+.color9 {background-color: #9999FF;}
+.color10 {background-color: #CCFFFF;}
+
+.color11 {background-color: #99CCCC;}
+.color12 {background-color: #99FFFF;}
+.color13 {background-color: #CCFFCC;}
+.color14 {background-color: #99CC99;}
+.color15 {background-color: #99FF99;}
+
+.color16 {background-color: #FFFFCC;}
+.color17 {background-color: #CCCC99;}
+.color18 {background-color: #FFFF99;}
+.color19 {background-color: #FFCC99;}
+.color20 {background-color: #FF99CC;}
+
+.color21 {background-color: #CC99FF;}
+.color22 {background-color: #99CCFF;}
+.color23 {background-color: #99FFCC;}
+.color24 {background-color: #CCFF99;}
+.color25 {background-color: #CCCCCC;}
+
+
+/* advacned search result*/
+#searching {padding: 3px; border: 1px dotted grey; background: #eee;}
+/* advacned search result*/
+#searching h4 {margin: 0;}
+
+
+       
diff --git a/gsearch.css b/gsearch.css
new file mode 100644 (file)
index 0000000..f3bb5f4
--- /dev/null
@@ -0,0 +1,851 @@
+/** Copyright 2005 Google Inc. All rights reserved. */
+
+/* the GSearchControl CSS Classes
+ * .gsc-control : the primary class of the control
+ */
+#searchcontrol {background-color:white; padding: 20px; clear: both;}
+.gsc-control {
+  width: auto;
+}
+
+.gsc-control div {
+  position: static;
+}
+
+/* control inputs
+ * .gsc-search-box : the container that hosts the text input area
+ * .gsc-input : the text input area
+ * .gsc-keeper : the save link below savable results
+ */
+form.gsc-search-box {
+  font-size: 13px;
+  margin-top : 0px;
+  margin-right : 0px;
+  margin-bottom : 4px;
+  margin-left : 0px;
+  width: 100%;
+}
+
+/*
+ * This table contains the input element as well as the search button
+ * Note that the search button column is fixed width, designed to hold the
+ * button div's background image
+ */
+table.gsc-search-box {
+  border-style : none;
+  border-width : 0px;
+  border-spacing : 0px 0px;
+  width : 100%;
+  margin-bottom : 2px;
+}
+
+table.gsc-search-box td {
+  vertical-align : middle;
+}
+
+td.gsc-search-button {
+  width : 1%;
+}
+
+td.gsc-clear-button {
+  width : 14px;
+       display: none;
+}
+
+table.gsc-branding {
+  border-style : none;
+  border-width : 0px;
+  border-spacing : 0px 0px;
+  width : 100%;
+       display: none;
+       }
+
+td.gsc-branding-text {
+  vertical-align : top;
+}
+
+td.gsc-branding-text div.gsc-branding-text {
+  padding-bottom : 2px;
+  text-align : right;
+  color : #676767;
+  font-size : 11px;
+  margin-right : 2px;
+}
+
+td.gsc-branding-img-noclear {
+  width : 51px;
+  vertical-align : bottom;
+}
+
+td.gsc-branding-img {
+  width : 65px;
+  vertical-align : bottom;
+}
+
+table.gsc-branding-vertical td.gsc-branding-text div.gsc-branding-text {
+  margin-right : 0px;
+  text-align : center;
+}
+
+table.gsc-branding-vertical td.gsc-branding-img-noclear {
+  text-align : center;
+}
+
+div.gsc-branding-img,
+div.gsc-branding-img-noclear,
+img.gsc-branding-img,
+img.gsc-branding-img-noclear {
+  padding-top : 1px;
+}
+
+img.gsc-branding-img,
+img.gsc-branding-img-noclear {
+  margin : 0 0 0 0;
+  padding-right : 0;
+  padding-left : 0;
+  padding-bottom : 0;
+  border : none;
+}
+
+input.gsc-search-button {
+  margin-left : 4px;
+}
+
+div.gsc-clear-button {
+  display : inline;
+  text-align : right;
+  margin-left : 4px;
+  margin-right : 4px;
+  padding-left : 10px;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-image: url('http://www.google.com/uds/css/clear.gif');
+  cursor : pointer;
+}
+
+/*
+ * Given that this is sitting in a variable width tabel cell, the idea is
+ * for it to consume the entire cell. The adjacent cell contains the search
+ * button and that is a fixed width cell.
+ */
+input.gsc-input {
+  padding-left : 2px;
+  border-style : solid;
+  border-width : 1px;
+  border-color : #BCCDF0;
+  width : 99%;
+}
+
+.gsc-keeper {
+  color: #3366cc;
+  text-decoration: underline;
+  font-size: 13px;
+  cursor: pointer;
+  font-weight: normal;
+
+  padding-left: 16px;
+  background-repeat: no-repeat;
+  background-position: 1px 3px;
+  background-image: url('http://www.google.com/uds/css/blue_check.gif');
+}
+.gsc-imageResult .gsc-keeper {
+  text-decoration: none;
+}
+
+/* each section of results has a results header table
+ * .gsc-resultsHeader : the header itseld
+ * td.twiddleRegionCell : the section that controls twiddleing of the section to expand/collapse
+ * td.configLabelCell : the twiddler that controls active configuration of a searcher (used in GlocalSearch)
+ * .gsc-twiddle : the twiddle image, note, this is a div that wraps gsc-title so that standard image replacement is feasible
+ * .gsc-twiddle-closed : class added to gsc-twiddle when the twiddler is in the closed state
+ * .gsc-twiddle-opened : class added to gsc-twiddle when the twiddler is in the opened state
+ * .gsc-title : the section's title (e.g., Web Results, etc.)
+ * .gsc-stats : contains the result counts
+ * .gsc-stats
+ */
+.gsc-resultsHeader {
+  clear: both;
+  width: 100%;
+  border-bottom: 1px solid #e9e9e9;
+  margin-bottom : 4px;
+}
+
+.gsc-resultsHeader td.gsc-twiddleRegionCell{
+  width: 75%;
+}
+
+.gsc-resultsHeader td.gsc-configLabelCell{
+  text-align: right;
+  width: 75%;
+}
+
+/*
+ * note that the next three classes are all joined together
+ * to implement the twiddle image. apps can substitute in their
+ * own images but will need to account for the image size here
+ * as well as in the left padding of the title element
+ *
+ * Note: uds provides the following images that work with the geometry/padding defined below
+ *  to use these images simply over-ride the.gsc-twiddle-opened/-closed class and specify an alternate image
+ *  or use an image of your own design
+ */
+.gsc-resultsHeader .gsc-twiddle{
+  margin-top: 4px;
+  display: inline;
+  cursor: pointer;
+  background-repeat: no-repeat;
+  background-position: 0px 2px;
+}
+.gsc-resultsHeader td.gsc-twiddle-closed div.gsc-twiddle{
+  background-image: url('http://www.google.com/uds/css/arrow_close.gif');
+}
+.gsc-resultsHeader td.gsc-twiddle-opened div.gsc-twiddle{
+  background-image: url('http://www.google.com/uds/css/arrow_open.gif');
+}
+
+.gsc-resultsHeader .gsc-title{
+  color: #676767;
+  margin-right: 10px;
+  padding-left: 14px;
+  display: inline;
+}
+
+.gsc-resultsHeader .gsc-stats {
+  color: #676767;
+  font-size: 11px;
+  font-weight: normal;
+  display : inline;
+}
+
+.gsc-resultsHeader td.gsc-twiddle-opened .gsc-stats {
+  display : none;
+}
+
+/*
+ * .gsc-results-selector : box surrounding individual selectors for 1, more, or all results
+ * .gsc-result-selector : an individual selector
+ * .gsc-one-result : single result selector
+ * .gsc-more-results : more (4) results selector
+ * .gsc-all-results : all results (8) selector
+ */
+.gsc-results-selector {
+  display : inline;
+}
+
+.gsc-resultsHeader td.gsc-twiddle-closed .gsc-results-selector {
+  display : none;
+}
+
+.gsc-result-selector {
+  cursor : pointer;
+  display : inline;
+  font-size : 13px;
+  padding-left : 13px;
+  background-repeat: no-repeat;
+  background-position: center left;
+}
+
+/* default mode is dark */
+.gsc-one-result {
+  background-image: url('http://www.google.com/uds/css/one-complex-dark.gif');
+}
+
+.gsc-more-results {
+  background-image: url('http://www.google.com/uds/css/more-complex-dark.gif');
+}
+
+.gsc-all-results {
+  background-image: url('http://www.google.com/uds/css/all-complex-dark.gif');
+  padding-right : 1px;
+}
+
+/* active mode is light */
+.gsc-one-result-active .gsc-one-result {
+  background-image: url('http://www.google.com/uds/css/one-complex-light-blue.gif');
+}
+
+.gsc-more-results-active .gsc-more-results {
+  background-image: url('http://www.google.com/uds/css/more-complex-light-blue.gif');
+}
+
+.gsc-all-results-active .gsc-all-results {
+  background-image: url('http://www.google.com/uds/css/all-complex-light-blue.gif');
+}
+
+.gsc-resultsHeader .gsc-configLabel{
+  color: #676767;
+  display: inline;
+  font-size: 11px;
+  cursor: pointer;
+}
+
+.gsc-resultsHeader td.gsc-configLabelCell span.gsc-twiddle-closed {
+  padding-right: 12px;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-image: url('http://www.google.com/uds/css/settings.gif');
+}
+
+
+/* tabbed mode of search control
+ * .gsc-tabsArea : the box containing all of the tabs
+ * .gsc-tabsAreaInvisible : same as above, but this is the state when search has been cleared
+ * .gsc-tabHeader : an individual tab
+ * .gsc-tabHeader.gsc-tabhActive : the active tab
+ * .gsc-tabHeader.gsc-tabhInactive : an inactive tab
+ * .gsc-tabData : the data area/box containg results and header data for each tab
+ * .gsc-tabData.gsc-tabdActive : the data area for the active tab
+ * .gsc-tabData.gsc-tabdInactive : the data area for inactive tabs
+ */
+.gsc-tabsArea {
+  clear: both;
+  margin-top: 6px;
+       display: none;
+  }
+
+.gsc-tabsAreaInvisible {
+  display : none;
+  }
+
+.gsc-tabHeader {
+  display: inline;
+  cursor: pointer;
+  padding-left: 6px;
+  padding-right: 6px;
+  margin-right: 2px;
+  }
+
+.gsc-tabHeader.gsc-tabhActive {
+  border-left: 1px solid #e9e9e9;
+  border-right: 1px solid #e9e9e9;
+  border-top: 2px solid #ff9900;
+  color: black;
+  }
+
+.gsc-tabHeader.gsc-tabhInactive {
+  border-left: 1px solid #e9e9e9;
+  border-right: 1px solid #e9e9e9;
+  border-top: 2px solid #e9e9e9;
+  background: #e9e9e9;
+  color: #676767;
+  }
+
+.gsc-tabData.gsc-tabdActive {
+  display: block;
+  }
+
+.gsc-tabData.gsc-tabdInactive {
+  display: none;
+  }
+
+/* tab specific results header supression
+ * - no twiddle, tabbed mode runs in full expand mode
+ * - no title
+ * - no stats
+ */
+.gsc-tabData .gsc-resultsHeader .gsc-title {
+  display: none;
+  }
+
+.gsc-tabData .gsc-resultsHeader .gsc-stats {
+  display: none;
+  }
+
+.gsc-tabData .gsc-resultsHeader .gsc-results-selector {
+  display : none;
+}
+
+
+
+/* the results for each section
+ * .gsc-resultsbox-{visible,invisible} : a complete-collection of results including headers
+ * .gsc-results : the collection of results for a given searcher
+ * .gsc-result : a generic result within the control. each result has this class, as well as .gsc-xxxResult where xxx is web, image, local, blog, etc.
+ */
+.gsc-resultsbox-visible {
+  display : block;
+}
+
+.gsc-resultsbox-invisible {
+  display : none;
+}
+
+.gsc-results {
+  clear: both;
+  padding-bottom: 2px;
+}
+
+.gsc-result {
+  margin-bottom: 10px;
+}
+
+.gsc-result .gs-title {
+  height: 1.4em;
+  overflow: hidden;
+  }
+
+/* specialized, result type specific, fine grained controls */
+.gsc-result div.gs-watermark {
+  display: none;
+}
+
+/* Ads
+ * inline the title div so that we can have an adjecent ad marker
+ * in the control, the ad-marker is supressed since ads are already positioned
+ * underneath a results divider
+ */
+.gsc-webResult a div.gs-title {
+  display: inline;
+}
+.gsc-results .gsc-result img.gs-ad-marker {
+  display: none;
+}
+
+/* Standard configuration div/form */
+div.gsc-config {
+  border: 1px solid #e9e9e9;
+  margin-top: 0px;
+  margin-bottom: 10px;
+  padding-top : 2px;
+  padding-left : 6px;
+  padding-right : 6px;
+  padding-bottom : 6px;
+}
+
+form.gsc-config {
+  margin-bottom : 0px;
+}
+
+.gsc-configSetting {
+  margin-top : 6px;
+  }
+
+.gsc-configSetting_Label {
+  color: #676767;
+  }
+
+.gsc-configSettingInput {
+  color: #676767;
+  border: 1px solid #e9e9e9;
+  width: 75%;
+  }
+
+.gsc-configSettingCheckbox {
+  color: #676767;
+  margin-right: 6px;
+  }
+
+.gsc-configSettingCheckboxLabel {
+  display : inline;
+  color: #676767;
+  }
+
+div.gsc-configSettingSubmit {
+  margin-top : 8px;
+  text-align : right;
+}
+
+input.gsc-configSettingSubmit {
+  display: inline;
+  font-size: 11px;
+  cursor: pointer;
+}
+
+
+/* Image Search
+ * - support for horizontal and vertical orientation
+ * - title, url, and size supression
+ */
+.gsc-results.gsc-imageResult .gsc-imageResult.horizontal{
+  float: left;
+  width: 65px;
+  margin-bottom: 4px;
+  margin-right: 8px;
+  text-align: center;
+}
+
+.gsc-results.gsc-imageResult .gsc-imageResult.horizontal .gs-imageResult {
+  height: 41px;
+}
+
+.gsc-results.gsc-imageResult .gsc-imageResult.vertical{
+  float: none;
+  margin-bottom: 4px;
+  margin-right: 8px;
+  text-align: left;
+}
+
+.gsc-results.gsc-imageResult .gsc-imageResult.horizontal .gsc-keeper {
+  background-position: center;
+}
+
+.gsc-imageResult .gs-title {
+  display: none;
+}
+.gsc-imageResult .gs-visibleUrl {
+  display: none;
+}
+.gsc-imageResult .gs-size {
+  display: none;
+}
+
+/* Video Search
+ * - metadata, publisher small font
+ * - single line title
+ */
+
+.gsc-videoResult .gs-videoResult .gs-metadata {
+  font-size: 11px;
+}
+
+.gsc-videoResult .gs-videoResult .gs-title {
+  line-height: 1.3em;
+  height: 1.3em;
+  overflow: hidden;
+  }
+
+.gsc-videoResult .gs-videoResult .gs-snippet {
+  line-height: 1.3em;
+  max-height: 2.6em;
+  overflow: hidden;
+  }
+
+/*** End of Control, Begin Results ***/
+
+/* generic, cross cutting result style
+ * - in the form of .gs-result .gs-xxx where xxx is the generic style
+ * .gs-title : typically the first line of a result, typically a link, image results over ride this, since for image results, the image is the link
+ * .gs-divider : typically seperates results from ads
+ * .gs-visibleUrl : typically the last line of a result, displayed in green. sometimes a link (like in blog search)
+ * .gs-clusterUrl : for news, and other similar services, this is a cluster of additional results
+ * img.gs-image : an actial image in a result
+ * .gs-phone : a phone number
+ * .gs-address : an address (includes street, city, region, country)
+ * .gs-streetAddress : a street (including #)
+ * .gs-city : a city
+ * .gs-region : a region (zip code, area, etc.)
+ * .gs-country : a country
+ * .gs-snippet : snippetized content
+ * .gs-watermark : indicator that user selected this result
+ * .gs-metadata : generic metadata, e.g.,
+ * .gs-image-box : generic container for a result's image (within a table)
+ * .gs-text-box : generic container for a result's text content (within a table). Note that this class, and image-box are only used in video
+ */
+.gs-result .gs-title,
+.gs-result .gs-title * {
+  color: #0000cc;
+  text-decoration: underline;
+}
+
+.gs-divider {
+  padding-bottom: 8px;
+  text-align: center;
+  color: #676767;
+}
+
+.gs-result a.gs-visibleUrl,
+.gs-result .gs-visibleUrl {
+  color: #008000;
+  text-decoration: none;
+}
+
+/* relative and absolute dates, not, news inlines these */
+.gs-relativePublishedDate,
+.gs-publishedDate {
+  color: #6f6f6f;
+  text-decoration: none;
+}
+.gs-result a.gs-clusterUrl,
+.gs-result .gs-clusterUrl {
+  color: #008000;
+  text-decoration: none;
+  cursor: pointer;
+}
+
+.gs-newsResult .gs-publisher {
+  color: #6f6f6f;
+  display : inline;
+  text-decoration: none;
+}
+
+.gs-bookResult .gs-author {
+  color: #6f6f6f;
+}
+
+/*
+ * For news results there are two dates...
+ * The relative date is visible while in the
+ * search control and the published date
+ * is visible when clipped. Why? It doesn't
+ * make sense to say 4 hours ago for a clipped
+ * result...
+ */
+
+/* establish the base style */
+.gs-newsResult .gs-relativePublishedDate,
+.gs-newsResult .gs-publishedDate {
+  display : inline;
+  margin-left : 4px;
+}
+
+/* base styling for relative date is none */
+.gs-blogResult .gs-relativePublishedDate,
+.gs-newsResult .gs-relativePublishedDate {
+  display : none;
+}
+
+/* suppress publishedDate while in the control */
+.gsc-blogResult .gs-blogResult .gs-publishedDate,
+.gsc-newsResult .gs-newsResult .gs-publishedDate {
+  display : none;
+}
+
+/* enable relativePublishedDate while in the control */
+.gsc-blogResult .gs-blogResult .gs-relativePublishedDate,
+.gsc-newsResult .gs-newsResult .gs-relativePublishedDate {
+  display : inline;
+}
+
+.gs-newsResult .gs-location {
+  color: #6f6f6f;
+  display : inline;
+  text-decoration: none;
+}
+
+.gs-result img.gs-image {
+  vertical-align : middle;
+  border : 1px solid #0000cc;
+}
+
+.gs-result div.gs-phone {}
+
+.gs-result .gs-directions,
+.gs-result .gs-directions * {
+  color: #3366cc;
+  font-weight: normal;
+  text-decoration : underline;
+}
+
+.gs-videoResult a.gs-publisher,
+.gs-videoResult .gs-publisher {
+  color: #008000;
+  text-decoration: none;
+}
+
+.gs-result a {
+  cursor: pointer;
+}
+
+.gs-result .gs-address {
+}
+
+.gs-result .gs-snippet {
+}
+
+.gs-result .gs-watermark{
+  font-size: 10px;
+  color: #7777cc;
+}
+
+div.gs-results-attribution {
+  text-align : center;
+  margin-bottom : 4px;
+}
+
+div.gs-results-attribution,
+div.gs-results-attribution * {
+  font-size : 10px;
+  color : #676767;
+  text-decoration : none;
+}
+
+div.gs-results-attribution a {
+  color: #0000cc;
+  cursor : pointer;
+}
+
+div.gs-results-attribution a:hover {
+  text-decoration : underline;
+}
+
+.gs-result .gs-metadata{
+  color: #676767;
+}
+
+/* searcher specific styling for
+ * - web ad
+ * - web
+ * - local
+ * - image (none)
+ * - blog (none)
+ * - video (none)
+ */
+
+/* webAd search specific over rides
+ * .gs-ad-marker : disabled in control, but on in green to indicate clipped result is an ad
+ */
+.gs-localAd img.gs-ad-marker,
+.gs-webAd img.gs-ad-marker {
+  padding-left: 4px;
+}
+
+.gs-localAd a.gs-visibleUrl div.gs-visibleUrl,
+.gs-webAd a.gs-visibleUrl div.gs-visibleUrl {
+  display : none;
+}
+
+/* default is to not show long mode visible urls
+ * apps should selectively enable this while disabling
+ * div.gs-visibleUrl-short
+ */
+.gs-webResult div.gs-visibleUrl-long {
+  width : 100%;
+  overflow : hidden;
+  display : block;
+}
+
+.gs-webResult div.gs-visibleUrl-short {
+       display: none;
+}
+
+/* local search specific over rides
+ * - city, region displayed inline
+ * - country supressed
+ * - small font size for info window's
+ */
+
+.gs-localAd div.gs-address * {
+  color : #676767;
+}
+
+.gs-localAd div.gs-street {
+  display: inline;
+}
+
+div.gs-city {
+  display: inline;
+}
+
+div.gs-region {
+  display: inline;
+}
+
+div.gs-country {
+  display: none;
+}
+
+div.gs-infoWindow * {
+  font-size: 11px;
+  }
+
+/* video search specific over rides
+ * - align the table data
+ * - default image width garuntee
+ * - appropriate cell seperation
+ */
+
+/* todo(markl): workaround until gre in gmail fixes his styles */
+.gs-videoResult * {
+  font-size: 13px;
+  }
+
+/*
+.gs-videoResult td .gs-image {
+  vertical-align : middle;
+}
+
+.gs-videoResult td.gs-image-box {
+  background-color : #000000;
+}*/
+
+.gs-videoResult td div.gs-image-box {
+  width : 110px;
+  height : 78px;
+}
+
+.gs-videoResult td div.gs-text-box {
+  vertical-align: top;
+  margin-left: 4px;
+  }
+
+
+/* book search specific over rides
+ * - default image width garuntee
+ * - appropriate cell seperation
+ */
+.gs-bookResult td div.gs-image-box {
+  width : 75px;
+  height : 90px;
+}
+
+.gs-bookResult td div.gs-text-box {
+  vertical-align: top;
+  margin-left: 4px;
+  }
+
+.gs-bookResult img.gs-image,
+.gs-bookResult img {
+  border-spacing : 0px 0px;
+  border : none;
+}
+
+.gs-bookResult table.gs-image-box {
+  border-style : none;
+  border-width : 0px;
+  border-spacing : 0px 0px;
+}
+
+.gs-bookResult td.gs-pages img {
+  height : 7px;
+  width : 45px;
+}
+
+.gs-bookResult td.gs-page-edge img {
+  height : 7px;
+  width : 11px;
+}
+
+.gs-bookResult td.gs-shadow {
+  vertical-align : bottom;
+}
+
+.gs-bookResult td.gs-image img {
+  height : 80px;
+}
+.gsc-ad-box { display:none;}
+
+
+/* trailing cursor section
+ */
+.gsc-imageResult .gsc-cursor-box {
+  clear : both;
+}
+
+.gsc-results .gsc-cursor-box .gsc-trailing-more-results {
+  margin-bottom : 0px;
+  display : inline;
+}
+
+.gsc-results .gsc-cursor {
+  display : inline;
+}
+
+.gsc-results .gsc-cursor-box {
+  margin-bottom : 10px;
+}
+
+.gsc-results .gsc-cursor-box .gsc-cursor-page {
+  cursor : pointer;
+  color : #000000;
+  text-decoration: underline;
+  margin-right : 8px;
+  display : inline;
+}
+
+.gsc-results .gsc-cursor-box .gsc-cursor-current-page {
+  color : #A90A08;
+  font-weight : bold;
+  text-decoration: none;
+}
+
+.gsc-resultsHeader *{display:none;}
diff --git a/images/add.png b/images/add.png
new file mode 100755 (executable)
index 0000000..6332fef
Binary files /dev/null and b/images/add.png differ
diff --git a/images/application_edit.png b/images/application_edit.png
new file mode 100644 (file)
index 0000000..fb2efb8
Binary files /dev/null and b/images/application_edit.png differ
diff --git a/images/cross.png b/images/cross.png
new file mode 100644 (file)
index 0000000..1514d51
Binary files /dev/null and b/images/cross.png differ
diff --git a/images/delete.png b/images/delete.png
new file mode 100644 (file)
index 0000000..08f2493
Binary files /dev/null and b/images/delete.png differ
diff --git a/images/error.gif b/images/error.gif
new file mode 100644 (file)
index 0000000..48543cd
Binary files /dev/null and b/images/error.gif differ
diff --git a/images/file-ext/avi.gif b/images/file-ext/avi.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/avi.gif differ
diff --git a/images/file-ext/cad.gif b/images/file-ext/cad.gif
new file mode 100644 (file)
index 0000000..3947208
Binary files /dev/null and b/images/file-ext/cad.gif differ
diff --git a/images/file-ext/doc.gif b/images/file-ext/doc.gif
new file mode 100644 (file)
index 0000000..7e053f5
Binary files /dev/null and b/images/file-ext/doc.gif differ
diff --git a/images/file-ext/download.gif b/images/file-ext/download.gif
new file mode 100644 (file)
index 0000000..d27f89e
Binary files /dev/null and b/images/file-ext/download.gif differ
diff --git a/images/file-ext/gif.gif b/images/file-ext/gif.gif
new file mode 100644 (file)
index 0000000..2f1cd83
Binary files /dev/null and b/images/file-ext/gif.gif differ
diff --git a/images/file-ext/html.gif b/images/file-ext/html.gif
new file mode 100644 (file)
index 0000000..e92ab0c
Binary files /dev/null and b/images/file-ext/html.gif differ
diff --git a/images/file-ext/jpg.gif b/images/file-ext/jpg.gif
new file mode 100644 (file)
index 0000000..2f1cd83
Binary files /dev/null and b/images/file-ext/jpg.gif differ
diff --git a/images/file-ext/mov.gif b/images/file-ext/mov.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/mov.gif differ
diff --git a/images/file-ext/mp3.gif b/images/file-ext/mp3.gif
new file mode 100644 (file)
index 0000000..6a41246
Binary files /dev/null and b/images/file-ext/mp3.gif differ
diff --git a/images/file-ext/pdf.png b/images/file-ext/pdf.png
new file mode 100644 (file)
index 0000000..e64037e
Binary files /dev/null and b/images/file-ext/pdf.png differ
diff --git a/images/file-ext/ppt.gif b/images/file-ext/ppt.gif
new file mode 100644 (file)
index 0000000..4f0c034
Binary files /dev/null and b/images/file-ext/ppt.gif differ
diff --git a/images/file-ext/rm.gif b/images/file-ext/rm.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/rm.gif differ
diff --git a/images/file-ext/txt.png b/images/file-ext/txt.png
new file mode 100644 (file)
index 0000000..22e37ee
Binary files /dev/null and b/images/file-ext/txt.png differ
diff --git a/images/file-ext/wmv.gif b/images/file-ext/wmv.gif
new file mode 100644 (file)
index 0000000..9754248
Binary files /dev/null and b/images/file-ext/wmv.gif differ
diff --git a/images/file-ext/xls.gif b/images/file-ext/xls.gif
new file mode 100644 (file)
index 0000000..9f5d57b
Binary files /dev/null and b/images/file-ext/xls.gif differ
diff --git a/images/file-ext/zip.png b/images/file-ext/zip.png
new file mode 100644 (file)
index 0000000..6b75d4d
Binary files /dev/null and b/images/file-ext/zip.png differ
diff --git a/images/find.png b/images/find.png
new file mode 100644 (file)
index 0000000..1547479
Binary files /dev/null and b/images/find.png differ
diff --git a/images/flag_green.png b/images/flag_green.png
new file mode 100644 (file)
index 0000000..e4bc611
Binary files /dev/null and b/images/flag_green.png differ
diff --git a/images/folder.png b/images/folder.png
new file mode 100755 (executable)
index 0000000..784e8fa
Binary files /dev/null and b/images/folder.png differ
diff --git a/images/folder_add.png b/images/folder_add.png
new file mode 100755 (executable)
index 0000000..529fe8f
Binary files /dev/null and b/images/folder_add.png differ
diff --git a/images/folder_delete.png b/images/folder_delete.png
new file mode 100755 (executable)
index 0000000..112b016
Binary files /dev/null and b/images/folder_delete.png differ
diff --git a/images/grnball.gif b/images/grnball.gif
new file mode 100755 (executable)
index 0000000..5f7740b
Binary files /dev/null and b/images/grnball.gif differ
diff --git a/images/help.gif b/images/help.gif
new file mode 100755 (executable)
index 0000000..4915678
Binary files /dev/null and b/images/help.gif differ
diff --git a/images/html.gif b/images/html.gif
new file mode 100755 (executable)
index 0000000..21e8e85
Binary files /dev/null and b/images/html.gif differ
diff --git a/images/img.gif b/images/img.gif
new file mode 100755 (executable)
index 0000000..cd2c4a5
Binary files /dev/null and b/images/img.gif differ
diff --git a/images/left.gif b/images/left.gif
new file mode 100644 (file)
index 0000000..29d0ba1
Binary files /dev/null and b/images/left.gif differ
diff --git a/images/loadingAnimation.gif b/images/loadingAnimation.gif
new file mode 100644 (file)
index 0000000..92c5c30
Binary files /dev/null and b/images/loadingAnimation.gif differ
diff --git a/images/logo.gif b/images/logo.gif
new file mode 100755 (executable)
index 0000000..cb56683
Binary files /dev/null and b/images/logo.gif differ
diff --git a/images/magnifier.png b/images/magnifier.png
new file mode 100755 (executable)
index 0000000..cf3d97f
Binary files /dev/null and b/images/magnifier.png differ
diff --git a/images/note_edit.png b/images/note_edit.png
new file mode 100644 (file)
index 0000000..291bfc7
Binary files /dev/null and b/images/note_edit.png differ
diff --git a/images/page_edit.png b/images/page_edit.png
new file mode 100644 (file)
index 0000000..046811e
Binary files /dev/null and b/images/page_edit.png differ
diff --git a/images/redball.gif b/images/redball.gif
new file mode 100755 (executable)
index 0000000..7005133
Binary files /dev/null and b/images/redball.gif differ
diff --git a/images/right.gif b/images/right.gif
new file mode 100644 (file)
index 0000000..d66a1ca
Binary files /dev/null and b/images/right.gif differ
diff --git a/images/shadowb.gif b/images/shadowb.gif
new file mode 100644 (file)
index 0000000..72c4706
Binary files /dev/null and b/images/shadowb.gif differ
diff --git a/images/shadowr.gif b/images/shadowr.gif
new file mode 100644 (file)
index 0000000..f7e19d1
Binary files /dev/null and b/images/shadowr.gif differ
diff --git a/images/size.sh b/images/size.sh
new file mode 100755 (executable)
index 0000000..2471ec3
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/bash
+convert='/usr/bin/convert'
+composite='/usr/bin/composite'
+
+for file in original/*
+do 
+       temp=`basename $file` 
+       $convert -scale '287>' $file resized/$temp
+       $convert -scale '210>' $file midsized/$temp
+       $convert -scale '120>' $file thumb/$temp
+
+       echo $temp 
+done
diff --git a/images/tick.png b/images/tick.png
new file mode 100644 (file)
index 0000000..a9925a0
Binary files /dev/null and b/images/tick.png differ
diff --git a/images/top2.jpg b/images/top2.jpg
new file mode 100755 (executable)
index 0000000..350fbe1
Binary files /dev/null and b/images/top2.jpg differ
diff --git a/images/user_add.png b/images/user_add.png
new file mode 100644 (file)
index 0000000..deae99b
Binary files /dev/null and b/images/user_add.png differ
diff --git a/images/user_edit.png b/images/user_edit.png
new file mode 100644 (file)
index 0000000..c1974cd
Binary files /dev/null and b/images/user_edit.png differ
diff --git a/index.php b/index.php
new file mode 100644 (file)
index 0000000..2befbfc
--- /dev/null
+++ b/index.php
@@ -0,0 +1,82 @@
+<?php
+$dont_include_functions = true;
+require_once 'setup.phtml';
+if (   defined("SHORT_URLS")
+       && SHORT_URLS
+       && isset($_GET['glmPage'])
+       && $_GET['glmPage']
+) {
+    $shortURL = new Toolkit_ShortURL(
+               Toolkit_Database::getInstance()
+       );
+    if (!$catid = $shortURL->getShortUrlId($_GET['glmPage'])) {
+        $catid = HOME_ID;
+    }
+    $_REQUEST['catid'] = $_GET['catid'] = $catid;
+} else {
+    $catid = ctype_digit((string)$_GET['catid']) ? $_GET['catid'] : HOME_ID;
+}
+if ($catid != HOME_ID) {
+    require_once 'Text/CAPTCHA.php';
+    require_once 'Text/CAPTCHA/Driver/Image.php';
+} else {
+    $_REQUEST['catid'] = $_GET['catid'] = $catid;
+}
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+require_once 'setup_functions.phtml';
+
+// check that the setup file has been set for new customer
+if (!strpos(BASE_URL, 'demo.gaslightmedia.com') && !CUSTOMER_SETUP_COMPLETE) {
+    die('Site is not setup.  Please set all defines in setup.phtml');
+}
+$toolbox = new GLM_TEMPLATE($catid);
+
+//     Initiate HTML_Template_Flexy.
+$template = new HTML_Template_Flexy($flexyOptions);
+//     Page object used for merging with the flexy template object.
+//     now using the page class from toolkit
+$gPage = new Toolkit_Page($toolbox);
+
+if (isset($_GET['forgot']) && $_GET['forgot'] == 1) {
+       require_once BASE . 'classes/class_auth.inc';
+       $auth =& new authuser();
+       $gPage->toolboxContent = $auth->show_forgot_login_form();
+} elseif (isset($_GET['sitemap']) && $_GET['sitemap'] == 1) {
+       $gPage->toolboxContent = $gPage->generateSiteMap();
+} else {
+       $gPage->toolboxContent = $toolbox->get_page();
+}
+if (isset($_GET['member_id']) && is_numeric($_GET['member_id'])) {
+    // get member name and put in title
+    $sql = "
+    SELECT member_name
+    FROM   member
+    WHERE  member_id = {$_GET['member_id']}";
+    if ($memData = $toolbox->DB->db_auto_get_data($sql)) {
+        $member_name = htmlentities(strip_tags($memData[0]['member_name']));
+        $gPage->title = $member_name.' - '.$gPage->title;
+    }
+}
+
+if ($catid == HOME_ID && !$_POST) {
+       $sql = "
+               SELECT *
+                 FROM bus_category
+                WHERE featured = true";
+       $dbh = Toolkit_Database::getInstance();
+       foreach ($dbh->query($sql) as $row) {
+               $row['link']      = $toolbox->get_seo_url($row['id']);
+               $gPage->features[] = $row;
+       }
+}
+$gPage->hasHeadlines = !empty($gPage->features);
+
+$gPage->scripts = Toolkit_Common::getScripts();
+$gPage->styles  = Toolkit_Common::getStyleSheets();
+
+//     Compile the template.html from the templates directory.
+$template->compile('template.html');
+//     Merge compiled template with the $gPage object.
+$template->outputObject($gPage);
+?>
diff --git a/libjs/.keepme b/libjs/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/libjs/external.js b/libjs/external.js
new file mode 100644 (file)
index 0000000..a080c66
--- /dev/null
@@ -0,0 +1,27 @@
+function externalLinks() 
+{
+       if(!document.getElementsByTagName)
+       {
+               return;
+       }
+       var anchors = document.getElementsByTagName("a");
+       var msg = '';
+       var tHref = '';
+       var baseurl = document.baseURI;
+       msg +=  baseurl + '\n';
+       for(var i=0; i<anchors.length; i++)
+       {
+               var anchor = anchors[i];
+               var pattern = /\/www.travelbrochure.com|www.travelbrochure.com\//
+               var pattern2 = /^https?:/
+               tHref = anchor.getAttribute("href");
+               if( tHref != '' && pattern2.test(tHref) )
+               {
+                       if( !pattern.test(tHref) )
+                       {
+                       anchor.target = "_blank";
+                       }
+               }
+       }
+}
+window.onload = externalLinks;
diff --git a/libjs/gsearch.php b/libjs/gsearch.php
new file mode 100755 (executable)
index 0000000..0070850
--- /dev/null
@@ -0,0 +1,33 @@
+<?php require_once '../setup.phtml';?>
+//google.load("search", "1");
+google.load("search", "1", {"nocss" : true});
+
+function initGoogleSearch()
+{
+    // create WebSearch with restriction to website
+    var siteSearch = new google.search.WebSearch();
+    siteSearch.setUserDefinedLabel("<?php echo SITE_URL;?>");
+    siteSearch.setUserDefinedClassSuffix("siteSearch");
+    siteSearch.setSiteRestriction("<?php echo SITE_URL;?>");
+
+    // create options for searchControl
+    var options = new google.search.SearcherOptions();
+    options.setExpandMode(google.search.SearchControl.EXPAND_MODE_OPEN);
+
+    // create the searchControl
+    var searchControl = new google.search.SearchControl();
+    searchControl.addSearcher(siteSearch, options);
+    searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
+
+    // create draw options for searchControl
+    var drawOptions = new google.search.DrawOptions();
+    drawOptions.setDrawMode(google.search.SearchControl.DRAW_MODE_LINEAR);
+
+    // tell the searcher to draw itself and tell it where to attach
+    searchControl.draw(document.getElementById("searchcontrol", drawOptions));
+
+    // execute the search
+    searchControl.execute("<?php echo $_GET['query'];?>");
+}
+
+google.setOnLoadCallback(initGoogleSearch);
diff --git a/setup.phtml b/setup.phtml
new file mode 100644 (file)
index 0000000..5a35ae6
--- /dev/null
@@ -0,0 +1,1088 @@
+<?php
+/**
+ * Media Toolbox(R)
+ *
+ * Setup.phtml file includes the functions that were in the functions.inc
+ * and siteinfo.inc file into one file.
+ * All set up stuff is on the top of the page.
+ *
+ * @version $Id: setup.phtml,v 1.67 2010/01/30 16:08:52 jamie Exp $
+ * @header  Gaslight Media Toolbox
+ */
+
+if (!isset($SITEINFO)) {
+       if (!isset($DEBUG)) {
+               $DEBUG = (isset($mysecretcode) && $mysecretcode == 1234);
+       }
+       /**
+        * Home page id of site
+        * Change this if the home page is other than id = 1
+        */
+       define('HOME_ID', 1);
+       /**
+        * Members login page catid
+        */
+       define('MEMBERS_CATEGORY', '45');
+       /**
+        * Members only category catid
+        * This is usually a sub-category of the MEMBERS_CATEGORY page
+        */
+       define('MEMBERS_ONLY_CATEGORY', '48');
+       /**
+        * Toolbox catid that corresponds to the
+        * edit profile page in the members only area
+        */
+       define('MEMBERS_PROFILE_FORM_PAGE', 101);
+       /**
+        * Toolbox catid that corresponds to the
+        * coupons page in the members only area
+        */
+       define('MEMBERS_COUPONS_PAGE', 102);
+       /**
+        * Toolbox catid that corresponds to the
+        * events page in the members only area
+        */
+       define('MEMBERS_EVENTS_PAGE', 502);
+       /**
+        * Toolbox catid that corresponds to the
+        * reports page in the members only area
+        */
+       define('MEMBERS_REPORTS_PAGE', 103);
+    /**
+     * Trip Planner / Itinerary Builder
+     * Boolean true or false to setup a wish list in session
+     * for  the businesses/members
+     */
+    define('MEMBER_SESSION_LIST', true);
+    /**
+     * The id of the page for the planner output
+     */
+    define('MEMBER_SESSION_PAGE', 105);
+    /**
+     * The id of the page for the create account form
+     */
+    define('MEMBER_SESSION_FORM', 106);
+       define('MEMBERS_LIST_RAND', false);
+       $PAGES[1] = 'index';
+       //$DEBUG = TRUE;
+       /*
+        *      Customer Setup
+        */
+    define("SITE_URL","http://demo.gaslightmedia.com");
+    define("SITENAME","Trout Creek Condominium Resort");
+       define('SITENAME_SHORT', SITENAME);
+       /**
+        * Same as the SITENAME constant
+        */
+       define('SITE_NAME', SITENAME);
+       /**
+        * DB library type
+        */
+       define('DB_TYPE', 'postgres');
+       /**
+        * Default error message
+        */
+       define('DB_ERROR_MSG', 'An error has occured with the database!');
+       /**
+        * Whether or not to use many to many relations
+        */
+       define('MULTIPLE_CAT', 0);
+       /**
+        * If set to 1 or true, will lock the categories
+        */
+       define('CAT_LOCK', 0);
+       /**
+        * Default per page number
+        */
+       define('ENTRIES_PER_PAGE', 10);
+       /**
+        * @depreciated
+        */
+       define('HTML_HELP_CODE', 1);
+       /**
+        * Used in the email out for contact DB
+        */
+       define('PRODUCTION_MODE', 'ON');
+       /**
+        * Turn ON for html emails
+        */
+       define('HTML_EMAIL', 'ON');
+       /**
+        * Turn on if the bus_category table has active boolean field
+        */
+       define('ACTIVE_FLAG', 1);
+       /**
+        * Used for the toolbox deluxe vs.
+        */
+       define('DELUXE_TOOLBOX', 1);
+       /**
+        * Whether to use SEO optimized URI's
+        *
+        * requires .htacces enabled
+        */
+       define('SEO_URL', 1);
+       /**
+        * Turn on/off short url
+        *
+        * requires .htacces enabled
+        */
+    define('SHORT_URLS', 1);
+       /**
+    * Weather to generate sitemap
+        */
+       define('SITEMAP_GENERATOR', false);
+       /**
+     * Page for the event calendar
+        */
+       define('EVENT_PAGE', 12);
+       /**
+     * Site has home page Events?
+        */
+       define('HOME_EVENTS', 0);
+       /**
+     * Site has home page Headlines?
+        */
+       define('HOME_HEADLINES', 1);
+       /**
+     * Site has home page news Press/newsletter?
+        */
+       define('HOME_NEWS', 0);
+       /**
+     * Site has banner ad application?
+        */
+       define('BANNERS', 0);
+       /*
+        * Site has rotating images application?
+        */
+       define('ROTATING_IMAGES', 0);
+       /**
+     * Site has photo gallery?
+        */
+       define('PHOTO_GALLERY', 1);
+       /**
+     * Site has google search api key?
+        */
+       define('GOOGLE_SEARCH', 0);
+       /**
+     * Grab weather feed for site?
+        */
+       define('WEATHER', 0);
+       /**
+     * Member Database Installed?
+        */
+       define('MEMBERS_DB', 0);
+       /**
+        * Sets the first year available in the year select lists in
+        * the Admin > Contacts > Report Builder
+        */
+       define('CONTACTS_FIRST_YEAR', 2008);
+       /**
+     * To display events on home page or not
+        */
+       define('HOME_PAGE_EVENTS', 0);
+
+    /**
+      * Login Id for StreamSend account
+      */
+    define ('STREAMSEND_LOGIN_ID', 'Needsetup');
+    /**
+      * key for StreamSend account
+      */
+    define ('STREAMSEND_KEY', 'Needsetup');
+    /**
+      * StreamSend Account Name
+      */
+    define ('STREAMSEND_ACCOUNT_NAME', 'Needsetup');
+    /**
+      * StreamSend Audience Number
+      */
+    define ('STREAMSEND_AUDIENCE', '1');
+
+       /**
+        *      DO NOT EDIT THIS SECTION
+        */
+       // Find where this file is located
+       $BASE_PATH   = dirname( __FILE__ );
+       $php_version = phpversion();
+       // If php5 or above
+       if (version_compare($php_version, '5.0.0', '>')) {
+               $CALLED_FROM_DIR = substr(dirname($_SERVER['SCRIPT_FILENAME']), strlen($BASE_PATH));
+               define('GLM_HOST_ID', $_ENV['GLM_HOST_ID']);
+               define('PHP5', true);
+       } else {
+               $CALLED_FROM_DIR = substr(dirname($HTTP_SERVER_VARS['PATH_TRANSLATED']), strlen($BASE_PATH));
+               define('GLM_HOST_ID', $_SERVER['GLM_HOST_ID']);
+               define('PHP5', false);
+       }
+
+       if (($x = strlen($CALLED_FROM_DIR)) > 0) {
+               $base_url = $_SERVER['HTTP_HOST'] . substr(dirname($_SERVER['SCRIPT_NAME']), 0, -strlen($CALLED_FROM_DIR));
+       } else {
+               $script_name_dir = dirname($_SERVER['SCRIPT_NAME']);
+               if ($script_name_dir == '/') {
+                       $script_name_dir = '';
+               }
+               $base_url = $_SERVER['HTTP_HOST'] . $script_name_dir;
+       }
+       $BASE_URL = "http://$base_url";
+       // Indicate that this file has been referenced
+       $SITEINFO = true;
+
+       $pathParts = pathinfo($BASE_PATH);
+       define('SERVER_DIRECTORY', $pathParts['basename']);
+
+       //      Dynamic Configuration:
+       //      Parameters that DO change based on location
+       switch ($_ENV['GLM_HOST_ID']) {
+       case 'DEVELOPMENT' : // {{{
+        /**
+          * For our forms using Toolkit_Contacts_ContactUs as base
+          * The form will send it's data to StreamSend
+          * The defines for StreamSend must be set for client
+          */
+        define('STREAMSEND_FORMS_API', false);
+        /**
+         * API key for google search AJAX
+         */
+        define('GSEARCH_API', 'ABQIAAAANX0yQZ2OteLu_zqbwdfUuRTeX7yNUukyMrmY8FsCXcCA9axlYBTyhehgzuXOUfNI0E5UYHCLponA0A');
+               /**
+                * API key for google maps
+                */
+               define('GMAPS_API', 'ABQIAAAANX0yQZ2OteLu_zqbwdfUuRQsHGkczIjpqPY1-dTKNoaiGtfPJBTloI-YH7fzUV-bsMLwcy2Yjyti7A');
+               /**
+                * Path to the common GLM application repository
+                */
+               define('GLM_APP_BASE', '/var/www/server/app.gaslightmedia.com/');
+               /**
+                * URI to the common GLM application repository
+                */
+               define('GLM_APP_BASE_URL','http://devsys2.gaslightmedia.com/app.gaslightmedia.com/');
+               /**
+                * Show all errors and notices
+                */
+               error_reporting(E_ALL ^ E_NOTICE);
+               /**
+                * Print all errors to the page so we can see what went wrong
+                */
+               ini_set('display_errors', '1');
+
+               /**
+                * Type of Log subclass to use
+                */
+               define('ERROR_LOG_TYPE', 'error_log');
+               /**
+                * Constant of log store to use
+                */
+               define('ERROR_LOG_NAME', PEAR_LOG_TYPE_FILE);
+               /**
+                * Identity reported to the log system
+                */
+               define('ERROR_LOG_IDENT', '');
+               /**
+                * Log messages up to and including this level
+                *
+                * HIGHEST PRIORITY
+                * +-------------------------------------------+
+                * |PEAR_LOG_EMERG   |System is unusable       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ALERT   |Immediate action required|
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_CRIT    |Critical conditions      |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ERR     |Error conditions         |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_WARNING |Warning conditions       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_NOTICE  |Normal but significant   |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_INFO    |Informational            |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_DEBUG   |Debug-level messages     |
+                * +-------------------------------------------+
+                * LOWEST PRIORITY
+                */
+               define('ERROR_LOG_LEVEL', PEAR_LOG_WARNING);
+               /**
+                * additional configuration for ERROR_LOG_TYPE subclass
+                */
+               $ERROR_LOG_CONF = array(
+                       'destination'   => "{$BASE_PATH}/php.error",
+                       'error_prepend' => '<font color="#ff0000"><tt>',
+                       'error_append'  => '</tt></font>',
+                       'lineFormat'    => "%{timestamp}: " .
+                                                          "PRIORITY: %{priority} " .
+                                                          "MESSAGE: %{message}\n"
+               );
+
+               // Use the $BASE_URL for secure URL on Devsys
+               $BASE_SECURE_URL = $BASE_URL;
+               /**
+                * URI used for the secure site
+                */
+               define('BASE_SECURE_URL', "$BASE_SECURE_URL/");
+               /**
+                * Database Connection String
+                */
+               define('CONN_STR', 'host=devsys2 user=nobody dbname=troutcreek');
+               /**
+                * DSN Connection String
+                */
+               define('DSN', 'pgsql://nobody@devsys2/troutcreek');
+               /**
+                * Used for error reporting
+                *
+                * When in development mode, more info is displayed if errors occur.
+                */
+               define('DEVELOPMENT', true);
+               /**
+                * Site owners email address
+                */
+               define('OWNER_EMAIL', 'jamie.kahgee@gmail.com');
+               /**
+                * From header for admin/Contact mailout.
+                */
+               define('FROM_NEWS_EMAIL', 'jamie.kahgee@gmail.com');
+               /**
+                * From headers for admin/MContact
+                */
+               define('FROM_MEMBER_NEWS_EMAIL', 'jamie.kahgee@gmail.com');
+               /**
+                * Reply header for admin/MContact
+                */
+               define('REPLY_MEMBER_NEWS_EMAIL', 'jamie.kahgee@gmail.com');
+               /**
+                * which email address should the notifications go to when a member
+                * listing updates thier record?
+                *
+                * If you set this to false, no emails will be sent when updates occur.
+                */
+               define('MEMBER_RECORD_UPDATES_ADVISOR', 'jamie.kahgee@gmail.com');
+               /**
+                * in admin/Contact mailout.phtml file
+                * Reply-To: header
+                */
+               define('REPLY_TO', 'jamie.kahgee@gmail.com');
+               break;
+       //      }}}
+
+       case "PRODUCTION": // {{{
+        /**
+          * For our forms using Toolkit_Contacts_ContactUs as base
+          * The form will send it's data to StreamSend
+          * The defines for StreamSend must be set for client
+          */
+        define('STREAMSEND_FORMS_API', true);
+        /**
+         * API key for google search AJAX
+         */
+        define('GSEARCH_API', 'ABQIAAAANX0yQZ2OteLu_zqbwdfUuRT9PY8-4c5xPr71Q7CZ_E9OOktIvhS7e6r_9XaLW5jy3O84t-dz7SK21Q');
+               /**
+                * API key for google maps
+                */
+               define('GMAPS_API', 'ABQIAAAANX0yQZ2OteLu_zqbwdfUuRT9PY8-4c5xPr71Q7CZ_E9OOktIvhS7e6r_9XaLW5jy3O84t-dz7SK21Q');
+               /**
+                * Path to the common GLM application repository
+                */
+               define('GLM_APP_BASE', '/var/www/server/app.gaslightmedia.com/');
+               /**
+                * URI to the common GLM application repository
+                */
+               define('GLM_APP_BASE_URL', 'http://app.gaslightmedia.com/');
+               /**
+                * Turn off all error reporting
+                */
+               error_reporting(0);
+               /**
+                * Don't print errors to the screen as part of output
+                */
+               ini_set('display_errors', '0');
+
+               /**
+                * Type of Log subclass to use
+                */
+               define('ERROR_LOG_TYPE', 'error_log');
+               /**
+                * Constant of log store to use
+                */
+               define('ERROR_LOG_NAME', PEAR_LOG_TYPE_FILE);
+               /**
+                * Identity reported to the log system
+                */
+               define('ERROR_LOG_IDENT', 'Production');
+               /**
+                * Log messages up to and including this level
+                *
+                * HIGHEST PRIORITY
+                * +-------------------------------------------+
+                * |PEAR_LOG_EMERG   |System is unusable       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ALERT   |Immediate action required|
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_CRIT    |Critical conditions      |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_ERR     |Error conditions         |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_WARNING |Warning conditions       |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_NOTICE  |Normal but significant   |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_INFO    |Informational            |
+                * +-----------------+-------------------------+
+                * |PEAR_LOG_DEBUG   |Debug-level messages     |
+                * +-------------------------------------------+
+                * LOWEST PRIORITY
+                */
+               define('ERROR_LOG_LEVEL', PEAR_LOG_WARNING);
+               /**
+                * additional configuration for ERROR_LOG_TYPE subclass
+                */
+               $ERROR_LOG_CONF = array(
+                       'destination' => '/var/www/log/' . SERVER_DIRECTORY . '/php.error',
+                       'lineFormat'  => "%{timestamp}: " .
+                                                        "PRIORITY: %{priority} " .
+                                                        "MESSAGE: %{message}\n"
+               );
+
+
+               $BASE_SECURE_URL = "https://$base_url";
+               /**
+                * Url used for the secure site
+                *
+                * For some sites it is necessary to change BASE_URL when in secure mode
+                */
+               define('BASE_SECURE_URL', "$BASE_SECURE_URL/");
+               // This needs to be set to the real url ie. http://www.upnorth.net
+               if ($_SERVER['HTTPS'] == 'on' ) {
+                       $BASE_URL = "http://$base_url";
+               }
+               /**
+                * Database Connection String
+                */
+               define('CONN_STR', 'host=ds3 user=nobody dbname=troutcreek');
+               /**
+                * DSN Connection String
+                */
+               define('DSN', "pgsql://nobody@ds3/troutcreek");
+               /**
+                * Whether the site is in Test Mode or not
+                */
+               define('TEST_MODE',     false);
+               /**
+                * Used for error reporting
+                *
+                * When in development mode, more info is displayed if errors occur.
+                */
+               define('DEVELOPMENT', false);
+               /**
+                * Site owners email address
+                */
+               define('OWNER_EMAIL', 'info@gaslightmedia.com');
+               /**
+                * From header for admin/Contact mailout.
+                *
+                * The networking department assigns an alias for the
+                * "From:"newsletter@xxx.com address that forwards to a
+                * "xxx_bounce@harbor.gaslightmedia.com" address.
+                *
+                * xxx being domain of website.
+                */
+               define('FROM_NEWS_EMAIL', 'newsletter@demo.gaslightmedia.com');
+               /**
+                * From headers for admin/MContact
+                *
+                * The networking department assigns an alias for the
+                * "From:"newsletter@xxx.com address that forwards to a
+                * "xxx_bounce@harbor.gaslightmedia.com" address.
+                *
+                * xxx being domain of website.
+                */
+               define('FROM_MEMBER_NEWS_EMAIL', 'newsletter@demo.gaslightmedia.com');
+               /**
+                * Reply header for admin/MContact
+                */
+               define('REPLY_MEMBER_NEWS_EMAIL', OWNER_EMAIL);
+               /**
+                * which email address should the notifications go to when a member
+                * listing updates thier record?
+                *
+                * If you set this to false, no emails will be sent when updates occur.
+                */
+               define('MEMBER_RECORD_UPDATES_ADVISOR', OWNER_EMAIL);
+               /**
+                * in admin/Contact mailout.phtml file
+                * Reply-To: header
+                */
+               define('REPLY_TO', 'info@gaslightmedia.com');
+               break;
+       //      }}}
+
+       //      Jamie's Machine.
+       case 'KANGA' : // {{{
+        /**
+          * For our forms using Toolkit_Contacts_ContactUs as base
+          * The form will send it's data to StreamSend
+          * The defines for StreamSend must be set for client
+          */
+        define('STREAMSEND_FORMS_API', false);
+        /**
+         * API key for google maps
+         */
+        define('GMAPS_API', 'ABQIAAAAFEik3hTZkksVQYtPm0OFmRT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQhDw8ITgl-K4LjnHuSww6VQQFDnA');
+               define("GLM_APP_BASE","/home/veilig/public_html/app.gaslightmedia.com/");
+               define("GLM_APP_BASE_URL","http://kanga.acrewoods.com/~veilig/app.gaslightmedia.com/");
+
+               error_reporting(E_ALL ^ E_NOTICE);
+               ini_set('display_errors', '1');
+
+               define('ERROR_LOG_TYPE', 'error_log');
+               define('ERROR_LOG_NAME', PEAR_LOG_TYPE_FILE);
+               define('ERROR_LOG_IDENT', '');
+               define('ERROR_LOG_LEVEL', PEAR_LOG_WARNING);
+               $ERROR_LOG_CONF = array(
+                       'destination'   => "{$BASE_PATH}/php.error",
+                       'error_prepend' => '<font color="#ff0000"><tt>',
+                       'error_append'  => '</tt></font>',
+                       'lineFormat'    => '%{timestamp}: ' .
+                                                          'PRIORITY: %{priority} ' .
+                                                          "MESSAGE: %{message}\n"
+               );
+
+               // Use the $BASE_URL for secure URL on Devsys
+               $BASE_SECURE_URL = $BASE_URL;
+               // url used for the secur site
+               define('BASE_SECURE_URL', "$BASE_SECURE_URL/");
+               // DB connection string
+               define('CONN_STR', 'user=nobody dbname=demo');
+               define('DSN', "pgsql://nobody@/demo");
+               //      Used for error reporting. When in development mode, more
+               //      info is displayed if errors occur.
+               define('DEVELOPMENT',   true);
+               // site owner's email address
+               define('OWNER_EMAIL',                                   'jamie.kahgee@gmail.com');
+               define('FROM_NEWS_EMAIL',                               'jamie.kahgee@gmail.com');
+               define('FROM_MEMBER_NEWS_EMAIL',                'jamie.kahgee@gmail.com');
+               define('REPLY_MEMBER_NEWS_EMAIL',               'jamie.kahgee@gmail.com');
+               define('TEST_MEMBER_NEWS_EMAIL',                'jamie.kahgee@gmail.com');
+               define('NOTIFY_MEMBER_NEWS_EMAIL',              'jamie.kahgee@gmail.com');
+               //      called in memberdb/classes/class_user.inc
+               define('MEMBERDB_EMAIL',                                'jamie.kahgee@gmail.com');
+               //      Which email address should the notifications go to
+               //      when a business listing updates thier record?
+               //      If you set this to false, no emails will be sent for updates.
+               define('MEMBER_RECORD_UPDATES_ADVISOR', 'jamie.kahgee@gmail.com');
+               // the reply-to field for email's
+               define('REPLY_TO',                                              'jamie.kahgee@gmail.com');
+               break;
+       //      }}}
+
+    case "STEVE": // {{{
+        /**
+          * For our forms using Toolkit_Contacts_ContactUs as base
+          * The form will send it's data to StreamSend
+          * The defines for StreamSend must be set for client
+          */
+        define('STREAMSEND_FORMS_API', false);
+               define("GLM_APP_BASE","/home/steve/public_html/app.gaslightmedia.com/");
+               define("GLM_APP_BASE_URL","http://localhost/~steve/app.gaslightmedia.com/");
+               error_reporting(E_ALL ^ E_NOTICE);
+               ini_set('display_errors', '1');
+
+               define('ERROR_LOG_TYPE', 'error_log');
+               define('ERROR_LOG_NAME', PEAR_LOG_TYPE_FILE);
+               define('ERROR_LOG_IDENT', '');
+               define('ERROR_LOG_LEVEL', PEAR_LOG_DEBUG);
+               $ERROR_LOG_CONF = array(
+                       'destination'   => "{$BASE_PATH}/php.error",
+                       'error_prepend' => '<font color="#ff0000"><tt>',
+                       'error_append'  => '</tt></font>',
+                       'lineFormat'    => "%{timestamp}: " .
+                                                          "PRIORITY: %{priority} " .
+                                                          "FILE: %{file} " . 
+                                                          "LINE: %{line} " . 
+                                                          "MESSAGE: %{message}\n"
+               );
+
+               // Use the $BASE_URL for secure URL on Devsys
+               $BASE_SECURE_URL = $BASE_URL;
+               // url used for the secur site
+               define('BASE_SECURE_URL', "$BASE_SECURE_URL/");
+               // DB connection string
+               define('CONN_STR', 'user=postgres dbname=troutcreek');
+               define('DSN', "pgsql://postgres@/troutcreek");
+               //      Used for error reporting. When in development mode, more
+               //      info is displayed if errors occur.
+               define('DEVELOPMENT',   true);
+               // site owner's email address
+               define('OWNER_EMAIL',                                   'jamie.kahgee@gmail.com');
+               define('FROM_NEWS_EMAIL',                               'jamie.kahgee@gmail.com');
+               define('FROM_MEMBER_NEWS_EMAIL',                'jamie.kahgee@gmail.com');
+               define('REPLY_MEMBER_NEWS_EMAIL',               'jamie.kahgee@gmail.com');
+               define('TEST_MEMBER_NEWS_EMAIL',                'jamie.kahgee@gmail.com');
+               define('NOTIFY_MEMBER_NEWS_EMAIL',              'jamie.kahgee@gmail.com');
+               //      called in memberdb/classes/class_user.inc
+               define('MEMBERDB_EMAIL',                                'jamie.kahgee@gmail.com');
+               //      Which email address should the notifications go to
+               //      when a business listing updates thier record?
+               //      If you set this to false, no emails will be sent for updates.
+               define('MEMBER_RECORD_UPDATES_ADVISOR', 'jamie.kahgee@gmail.com');
+               // the reply-to field for email's
+               define('REPLY_TO',                                              'jamie.kahgee@gmail.com');
+        break;
+       //      }}}
+
+       default:        // There should be no need for any settings here
+               $error = 'Your request could not be completed at this time, please try again later!';
+               die("<p>$error</p>");
+               break;
+       }
+
+       /**
+        * URI used for the root of the site
+        */
+       define('BASE_URL', "$BASE_URL/");
+       /**
+        * Another way of calling the BASE_URL constant
+        */
+       define('URL_BASE', "$BASE_URL/");
+       /**
+        * root directory path of site in filesystem
+        */
+       define('BASE_PATH', "$BASE_PATH/");
+       /**
+        * Another way of calling the BASE_PATH constant
+        */
+       define('BASE', "$BASE_PATH/");
+
+    /**
+     * Chuck and John H. have setup site monitoring script that will hit a file
+     * every so often and make a db connection to test if that database connection is good.
+     * The aim here it to monitor the sites to see if they go down and page Chuck/John and Dave 
+     * We'll check for the setup script in the root of the site if it is not there and the database
+     * has been setup in this file it will create the file.
+     */ 
+    $SiteCheckFile = BASE . 'GLM_site_check.phtml';
+    if (!file_exists($SiteCheckFile)) {
+        // get the dbname for the connection
+        $siteCheckArray = explode(" ", CONN_STR);
+        foreach ($siteCheckArray as $scaVar) {
+            parse_str($scaVar, $parsedSettings);
+            if ($parsedSettings['dbname']) {
+                $dbname = $parsedSettings['dbname'];
+            }
+        }
+        if ($dbname) {
+            // we're going to assume that the connection 
+            // will be for ds3.gaslightmedia.com
+            $fileContent = "<?php \n"
+                . "/**\n"
+                . " * GLM Standard Site Monitoring Target\n"
+                . " */\n\n"
+                . "define('HOST',   'ds3.gaslightmedia.com');\n"
+                . "define('USER',   'nobody');\n" 
+                . "define('DBNAME', '$dbname');\n"
+                . "\n"
+                . "// End of parameters to set for each site\n"
+                . "include '/var/www/templates/Global_site_check.phtml';\n"
+                . "?>";
+            file_put_contents($SiteCheckFile, $fileContent);
+        }
+    }
+
+       //      explode the current include_path by forward slashes (/),
+       //      colons (:),     or periods (.)
+       $path = preg_split('(\/|:|\.)', get_include_path());
+       if (!in_array(GLM_APP_BASE . 'glmPEAR', $path)) {
+               set_include_path(GLM_APP_BASE . 'glmPEAR' .
+                       PATH_SEPARATOR . get_include_path());
+       }
+
+       //      Include path to geocode API
+       if (!in_array(GLM_APP_BASE . 'geocode', $path)) {
+               set_include_path(GLM_APP_BASE . 'geocode' .
+                       PATH_SEPARATOR . get_include_path());
+       }
+
+       //      Include the path to the Toolkit directory.
+       //      This is an Xdebug fix - first classes don't load properly w/ __autoload
+       if (!in_array(BASE . 'Toolkit', $path)) {
+               set_include_path(get_include_path() . PATH_SEPARATOR .
+                               BASE . 'Toolkit');
+       }
+
+       $secureUrl
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+               ? BASE_SECURE_URL
+               : BASE_URL;
+
+       $forceCompile = (DEVELOPMENT || $_SERVER['HTTPS'] == 'on');
+
+       $flexyOptions    = array(
+               'templateDir'  => BASE . 'templates',
+               'compileDir'   => BASE . 'templates/compiled',
+               'forceCompile' => 'true',
+               'url_rewrite'  => "baseurl/::".BASE_URL.",basesecureurl/::$secureUrl,glmappbaseurl/::" . GLM_APP_BASE_URL,
+               'allowPHP'     => true,
+       );
+
+       $cacheOptions = array(
+               'cacheDir'                       => BASE . 'cache',
+               'writeControl'           => true,
+        'lifeTime'           => (DEVELOPMENT) ? 0 : null,
+               'readControl'            => true,
+               'fileNameProtection' => false,
+               'readControlType'        => 'md5',
+       );
+
+       //      Global arrays to store resources for apps.
+       $scripts = array();
+       $styleSheets = array();
+
+    // {{{ __autoload()
+
+    /**
+     * autoload function that aids in calling class files only when needed
+     * 
+     * @param string $className Name of class
+     * 
+     * @return void  
+     */
+       function __autoload($className)
+       {
+               if (    (preg_match('/Flexy.+/', $className) === 0)
+                        || $className == 'Toolkit_FlexyDataGridBuilder'
+               ) {
+                       switch ($className) {
+                       case 'GLM_DB' :
+                               require_once BASE . 'classes/class_db.inc';
+                               break;
+
+                       case 'GLM_TOOLBOX' :
+                               require_once BASE . 'classes/class_toolbox.inc';
+                               break;
+
+                       case 'GLM_TEMPLATE' :
+                               require_once BASE . 'classes/class_template.inc';
+                               break;
+
+                       case 'GLM_DB' :
+                               require_once BASE . 'classes/class_db.inc';
+                               break;
+
+                       case 'BANNER_ADS' :
+                               require_once BASE . 'classes/class_banners.inc';
+                               break;
+
+                       case 'GLM_EVENTS' :
+                               require_once BASE . 'classes/class_events.inc';
+                               break;
+
+                       case 'GLM_COUPON' :
+                               require_once BASE . 'classes/class_coupon.inc';
+                               break;
+
+                       case 'contact_form' :
+                               require_once BASE . 'classes/class_contact_form.inc';
+                               break;
+
+                       case 'guide' :
+                               require_once BASE . 'classes/class_visitor_guide_form.inc';
+                               break;
+
+                       case 'event_form' :
+                               require_once BASE . 'classes/class_event_form.inc';
+                               break;
+
+                       case 'html_quickform_rule_phone' :
+                       case 'html_quickform_rule_email' :
+                       case 'html_quickform_rule_zip' :
+                       case 'html_quickform_rule_state' :
+                       case 'html_quickform_rule_banwords' :
+                       case 'html_quickform_rule_date' :
+                       case 'html_quickform_rule_image' :
+                       case 'html_quickform_rule_image2' :
+                       case 'html_quickform_rule_memberimage' :
+                       case 'html_quickform_rule_memberpackage' :
+                       case 'html_quickform_rule_memberlogo' :
+                       case 'html_quickform_rule_memberfile' :
+                       case 'html_quickform_rule_amenity' :
+                       case 'html_quickform_rule_banner' :
+                               $path = explode('_', $className);
+                               $className = ucfirst(end($path));
+                               require_once GLM_APP_BASE . "glmPEAR/HTML/QuickForm/Rule/$className.php";
+                               break;
+
+                       default :
+                               //      Since our old naming conventions conflict w/ the pear
+                               //      naming conventions.
+                               //      Check to see what we're trying to call by checking if the
+                               //      file/class exits in the PEAR sturcture.
+                               $class = implode('/', explode('_', $className));
+                               if (file_exists(GLM_APP_BASE . "glmPEAR/$class.php")) {
+                                       require_once "$class.php";
+                               } elseif (file_exists(GLM_APP_BASE . "geocode/$class.php")) {
+                                       require_once "$class.php";
+                               } elseif (file_exists(GLM_APP_BASE . "$class.php")) {
+                                       require_once GLM_APP_BASE . "$class.php";
+                               } elseif (file_exists(BASE . "$class.php")) {
+                                       require_once BASE . "$class.php";
+                               } else {
+                                       require_once BASE."classes/$className.php";
+                               }
+                               break;
+                       }
+               }
+       }
+
+    // }}}
+
+       set_error_handler(array('Toolkit_Logger', 'errorHandler'));
+       
+       // help guide base (depreciated)
+       define('HELP_BASE',                             'help/');
+       // uploads directory path
+       define('UP_BASE',                               BASE.'uploads/');
+       // the images url path
+       define('IMG_BASE',                              URL_BASE.'images/');
+       // postcard url (used for postcard app)
+       define('POSTCARD_URL',                  BASE_URL.'postcard.phtml');
+       // used in admin area as the path to image logo
+       define('LOGO_IMG',                              URL_BASE.'images/logoicon.gif');
+       // help image url (depriated)
+       define('HELP_IMG',                              URL_BASE.'images/help.gif');
+
+       // Toolbox image paths
+       define('ORIGINAL_PATH',                 BASE.'images/original/');
+       define('RESIZED_PATH',                  BASE.'images/resized/');
+       define('MIDSIZED_PATH',                 BASE.'images/midsized/');
+       define('THUMB_PATH',                    BASE.'images/thumb/');
+
+       //      Amenity icon path
+       define('AMENITY_PATH',                  BASE.'images/amenities/');
+
+       $imageURLBase
+               = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
+               ? BASE_SECURE_URL
+               : BASE_URL;
+
+       // Toolbox image URLS
+    // Now using new Image Server
+    /**
+     * Now using new Image Server
+     * http://is0.gaslightmedia.com/admin
+     * setup new owner with owner_id and owner_pw
+     * MUST BE DONE BEFORE uploading any images
+     */
+    /**
+    * IS_OWNER_ID owner_id from image server config
+     */
+    define('IS_OWNER_ID', 'demo');
+    /**
+     * IS_OWNER_PW owner_pw from image server config
+     */
+    define('IS_OWNER_PW', 'demo4us');
+    /**
+     * Toolbox image URLS
+     * NOTE: these don't change
+     * There are 4 global "image styles"
+     * original = used for original images no processing
+     * tbs1     = used to be resized
+     * tbs2     = used to be midsized
+     * tbs3     = used to be thumb
+     * check on http://is0.gaslightmedia.com/admin under owner _SYSTEM_
+     * for their sizes
+     * if you need a different size you'll need to create image style for
+     * your owner with new sizes just use one of set style names
+     * tbs1,tbs2,tbs3 (do this before uploading the image will help)
+     */
+    define('ORIGINAL', "http://is0.gaslightmedia.com/".IS_OWNER_ID."/original/");
+       define('RESIZED',  "http://is0.gaslightmedia.com/".IS_OWNER_ID."/tbs1/");
+       define('MIDSIZED', "http://is0.gaslightmedia.com/".IS_OWNER_ID."/tbs2/");
+    define('THUMB',    "http://is0.gaslightmedia.com/".IS_OWNER_ID."/tbs3/");
+
+    define('IMAGE_MANAGER',    "http://is0.gaslightmedia.com/".IS_OWNER_ID."/imgMgr/");
+
+       /**
+        * These are defines for the photo gallery images
+     * NOTICE these are now on image server
+     * There are 2 global "image styles"
+     * pgs1 = used to be photo-large
+     * pgs2 = used to be photo-small
+     * check on http://is0.gaslightmedia.com/admin under owner _SYSTEM_
+     * for their sizes
+        */
+       define('PHOTO_LARGE_URL',       "http://is0.gaslightmedia.com/".IS_OWNER_ID."/pgs1/");
+       define('PHOTO_SMALL_URL',       "http://is0.gaslightmedia.com/".IS_OWNER_ID."/pgs2/");
+
+       //      Rotating Image URLS
+       define('ROTATING_IMAGE_THUMB', 'http://is0.gaslightmedia.com/'.IS_OWNER_ID.'/rotatingImagesThumb/');
+       define('ROTATING_IMAGE_RESIZED', 'http://is0.gaslightmedia.com/'.IS_OWNER_ID.'/rotatingImagesResized/');
+
+       //      Member image URLS
+       define('MEMBER_ORIGINAL',          "http://is0.gaslightmedia.com/".IS_OWNER_ID."/original/");
+       define('MEMBER_RESIZED',           "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberResized/");
+       define('MEMBER_MIDSIZED',          "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberMidsized/");
+       define('MEMBER_THUMB',             "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberThumb/");
+       define('MEMBER_PHOTOS',            "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberPhotos/");
+       define('MEMBER_PACKAGES',          "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberResized/");
+       define('MEMBER_GOOGLE_MAP',    "http://is0.gaslightmedia.com/".IS_OWNER_ID."/memberGoogleMap/");
+       define('TRIP_PLANNER_MAP_IMG', "http://is0.gaslightmedia.com/".IS_OWNER_ID."/tripPlannerMapImg/");
+
+       define('BANNER_ORIGINAL',                       'http://is0.gaslightmedia.com/'.IS_OWNER_ID.'/original/');
+       define('HORIZONTAL_BANNER',             'http://is0.gaslightmedia.com/'.IS_OWNER_ID.'/horizontalBanner/');
+       define('HORIZONTAL_BANNER_THUMB',       'http://is0.gaslightmedia.com/'.IS_OWNER_ID.'/horizontalBannerThumb/');
+       define('VERTICAL_BANNER',                   'http://is0.gaslightmedia.com/'.IS_OWNER_ID.'/verticalBanner/');
+       define('VERTICAL_BANNER_THUMB',         'http://is0.gaslightmedia.com/'.IS_OWNER_ID.'/verticalBannerThumb/');
+
+       //      Amenity image URLS
+       define('AMENITY_THUMB',         "{$imageURLBase}images/amenities/");
+       //      Icon image URLS
+       define('ICONS_URL',                     "{$imageURLBase}images/");
+
+
+    /**
+      * CUSTOMER_SETUP_COMPLETE
+      *
+      * The Developer when setting up the initial site must walk through all defines above and
+      * set them accordingly.  When complete set this define to true.
+      */
+    define('CUSTOMER_SETUP_COMPLETE', false);
+
+       // [status_US] array of states and their abbr.
+       $states_US['']   = '-- Select --';// {{{
+       $states_US['AL'] = 'Alabama';
+       $states_US['AK'] = 'Alaska';
+       $states_US['AZ'] = 'Arizona';
+       $states_US['AR'] = 'Arkansas';
+       $states_US['CA'] = 'California';
+       $states_US['CO'] = 'Colorado';
+       $states_US['CT'] = 'Connecticut';
+       $states_US['DE'] = 'Delaware';
+       $states_US['DC'] = 'District of Columbia';
+       $states_US['FL'] = 'Florida';
+       $states_US['GA'] = 'Georgia';
+       $states_US['HI'] = 'Hawaii';
+       $states_US['ID'] = 'Idaho';
+       $states_US['IL'] = 'Illinois';
+       $states_US['IN'] = 'Indiana';
+       $states_US['IA'] = 'Iowa';
+       $states_US['KS'] = 'Kansas';
+       $states_US['KY'] = 'Kentucky';
+       $states_US['LA'] = 'Louisiana';
+       $states_US['ME'] = 'Maine';
+       $states_US['MD'] = 'Maryland';
+       $states_US['MA'] = 'Massachusetts';
+       $states_US['MI'] = 'Michigan';
+       $states_US['MN'] = 'Minnesota';
+       $states_US['MS'] = 'Mississppi';
+       $states_US['MO'] = 'Missouri';
+       $states_US['MT'] = 'Montana';
+       $states_US['NE'] = 'Nebraska';
+       $states_US['NV'] = 'Nevada';
+       $states_US['NH'] = 'New Hampshire';
+       $states_US['NJ'] = 'New Jersey';
+       $states_US['NM'] = 'New Mexico';
+       $states_US['NY'] = 'New York';
+       $states_US['NC'] = 'North Carolina';
+       $states_US['ND'] = 'North Dakota';
+       $states_US['OH'] = 'Ohio';
+       $states_US['OK'] = 'Oklahoma';
+       $states_US['OR'] = 'Oregon';
+       $states_US['PA'] = 'Pennsylvania';
+       $states_US['RI'] = 'Rhode Island';
+       $states_US['SC'] = 'South Carolina';
+       $states_US['SD'] = 'South Dakota';
+       $states_US['TN'] = 'Tennessee';
+       $states_US['TX'] = 'Texas';
+       $states_US['UT'] = 'Utah';
+       $states_US['VT'] = 'Vermont';
+       $states_US['VA'] = 'Virginia';
+       $states_US['WA'] = 'Washington';
+       $states_US['WV'] = 'West Virginia';
+       $states_US['WI'] = 'Wisconsin';
+       $states_US['WY'] = 'Wyoming';// }}}
+
+       // [states] extended states array
+       $states['AB'] = 'Alberta';// {{{
+       $states['AS'] = 'American Samoa';
+       $states['BC'] = 'British Columbia';
+       $states['DC'] = 'District of Columbia';
+       $states['FM'] = 'Federated States of Micronesia';
+       $states['GU'] = 'Guam';
+       $states['MB'] = 'Manitoba';
+       $states['MH'] = 'Marshall Islands';
+       $states['NB'] = 'New Brunswick';
+       $states['NF'] = 'Newfoundland';
+       $states['MP'] = 'Northern Mariana Islands';
+       $states['NT'] = 'Northwest Territories';
+       $states['NS'] = 'Nova Scotia';
+       $states['ON'] = 'Ontario';
+       $states['PW'] = 'Palau';
+       $states['PE'] = 'Prince Edward Island';
+       $states['PR'] = 'Puerto Rico';
+       $states['QC'] = 'Quebec';
+       $states['SK'] = 'Saskatchewan';
+       $states['VI'] = 'Virgin Islands';
+       $states['YT'] = 'Yukon';// }}}
+
+       //      Merge the 50 US states together with some of the extended
+       //      provinces / territories and then sort them on their keys
+       //      Then add the remaining countries and areas at the end
+       //      of the array.
+       $states = $states_US + $states;
+       ksort($states);
+       $states = $states + array(// {{{
+               'Asia'                  => 'Asia',
+               'Australia'             => 'Australia',
+               'Bahamas'               => 'Bahamas',
+               'Caribbean'             => 'Caribbean',
+               'Costa Rica'    => 'Costa Rica',
+               'South America' => 'South America',
+               'South Africa'  => 'South Africa',
+               'Europe'                => 'Europe',
+               'Mexico'                => 'Mexico',
+       );// }}}
+
+       // Libraries
+       // Replaced with the actual functions instead of includes (2001-12-14)
+
+       $cp1252_map = array(
+               "\xc2\x80" => "\xe2\x82\xac",   //      EURO SIGN
+               "\xc2\x82" => "\xe2\x80\x9a",   //      SINGLE LOW-9 QUOTATION MARK
+               "\xc2\x83" => "\xc6\x92",               //      LATIN SMALL LETTER F WITH HOOK
+               "\xc2\x84" => "\xe2\x80\x9e",   //      DOUBLE LOW-9 QUOTATION MARK
+               "\xc2\x85" => "\xe2\x80\xa6",   //      HORIZONTAL ELLIPSIS
+               "\xc2\x86" => "\xe2\x80\xa0",   //      DAGGER
+               "\xc2\x87" => "\xe2\x80\xa1",   //      DOUBLE DAGGER
+               "\xc2\x88" => "\xcb\x86",               //      MODIFIER LETTER CIRCUMFLEX ACCENT
+               "\xc2\x89" => "\xe2\x80\xb0",   //      PER MILLE SIGN
+               "\xc2\x8a" => "\xc5\xa0",               //      LATIN CAPITAL LETTER S WITH CARON
+               "\xc2\x8b" => "\xe2\x80\xb9",   //      SINGLE LEFT-POINTING ANGLE QUOTATION
+               "\xc2\x8c" => "\xc5\x92",               //      LATIN CAPITAL LIGATURE OE
+               "\xc2\x8e" => "\xc5\xbd",               //      LATIN CAPITAL LETTER Z WITH CARON
+               "\xc2\x91" => "\xe2\x80\x98",   //      LEFT SINGLE QUOTATION MARK
+               "\xc2\x92" => "\xe2\x80\x99",   //      RIGHT SINGLE QUOTATION MARK
+               "\xc2\x93" => "\xe2\x80\x9c",   //      LEFT DOUBLE QUOTATION MARK
+               "\xc2\x94" => "\xe2\x80\x9d",   //      RIGHT DOUBLE QUOTATION MARK
+               "\xc2\x95" => "\xe2\x80\xa2",   //      BULLET
+               "\xc2\x96" => "\xe2\x80\x93",   //      EN DASH
+               "\xc2\x97" => "\xe2\x80\x94",   //      EM DASH
+
+               "\xc2\x98" => "\xcb\x9c",               //      SMALL TILDE
+               "\xc2\x99" => "\xe2\x84\xa2",   //      TRADE MARK SIGN
+               "\xc2\x9a" => "\xc5\xa1",               //      LATIN SMALL LETTER S WITH CARON
+               "\xc2\x9b" => "\xe2\x80\xba",   //      SINGLE RIGHT-POINTING ANGLE QUOTATION
+               "\xc2\x9c" => "\xc5\x93",               //      LATIN SMALL LIGATURE OE
+               "\xc2\x9e" => "\xc5\xbe",               //      LATIN SMALL LETTER Z WITH CARON
+               "\xc2\x9f" => "\xc5\xb8",               //      LATIN CAPITAL LETTER Y WITH DIAERESIS
+       );
+
+    if (!$dont_include_functions) {
+
+    /**
+     * all setup function in setup_functions.phtml
+     */
+        require_once BASE_PATH . "setup_functions.phtml";
+    }
+
+}
+?>
diff --git a/setup_functions.phtml b/setup_functions.phtml
new file mode 100644 (file)
index 0000000..5b62a88
--- /dev/null
@@ -0,0 +1,1145 @@
+<?php
+/** @header Gaslight Media Toolbox
+  functions that were in the functions.inc
+ */
+
+       /**
+        * is_utf8
+        *
+        * @param mixed $string
+        * @access public
+        * @return void
+        */
+       function is_utf8($string)
+       {
+               return preg_match('/^([\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xec][\x80-\xbf]{2}|\xed[\x80-\x9f][\x80-\xbf]|[\xee-\xef][\x80-\xbf]{2}|f0[\x90-\xbf][\x80-\xbf]{2}|[\xf1-\xf3][\x80-\xbf]{3}|\xf4[\x80-\x8f][\x80-\xbf]{2})*$/', $string) === 1;
+       }
+
+       /**
+        * cp1252_to_utf8
+        *
+        * @param mixed $str
+        * @access public
+        * @return void
+        */
+       function cp1252_to_utf8($str)
+       {
+               global $cp1252_map;
+               return  strtr(utf8_encode($str), $cp1252_map);
+       }
+
+       /**
+        * myEncode
+        *
+        * @param mixed $string
+        * @access public
+        * @return void
+        */
+       function myEncode($string)
+       {
+               if (is_utf8($string)) {
+                       return $string;
+               } else {
+                       return cp1252_to_utf8($string);
+               }
+       }
+
+       /**
+        * CreditVal : CreditVal Checks for a valid credit card number doing Luhn check, if no
+        card type is given, attempts to guess. Then, if a list of
+        accepted types is given, determines whether or not we'll
+        accept it
+        * @param $Num: Credit Card Number
+        * @param $Name = '': Type of Card
+        * @param $Accepted='' : Accepted array
+        *
+        * @return bool
+        * @access
+        **/
+       function CreditVal($Num, $Name = '', $Accepted = '')
+       {
+               $Name = strtolower($Name);
+               $Accepted = strtolower($Accepted);
+               $GoodCard = 1;
+               $Num = ereg_replace('[^[:digit:]]', '', $Num);
+               switch ($Name) {
+               case 'mastercard' :
+                       $GoodCard = ereg('^5[1-5].{14}$', $Num);
+                       break;
+
+               case 'visa' :
+                       $GoodCard = ereg('^4.{15}$|^4.{12}$', $Num);
+                       break;
+
+               case 'americanexpress' :
+                       $GoodCard = ereg('^3[47].{13}$', $Num);
+                       break;
+
+               case 'discover' :
+                       $GoodCard = ereg('^6011.{12}$', $Num);
+                       break;
+
+               case 'dinerscard' :
+                       $GoodCard = ereg('^30[0-5].{11}$|^3[68].{12}$', $Num);
+                       break;
+
+               default:
+                       if (ereg('^5[1-5].{14}$', $Num)) {
+                               $Name = 'mastercard';
+                       }
+                       if (ereg('^4.{15}$|^4.{12}$', $Num)){
+                               $Name = 'visa';
+                       }
+                       if (ereg('^3[47].{13}$', $Num)) {
+                               $Name = 'americanexpress';
+                       }
+                       if (ereg('^6011.{12}$', $Num)) {
+                               $Name = 'discover';
+                       }
+                       if (ereg('^30[0-5].{11}$|^3[68].{12}$', $Num)) {
+                               $Name = 'dinerscard';
+                       }
+                       break;
+               }
+
+               // If there's a limit on card types we accept, check for it here.
+               if ($Accepted) {
+                       $type_verified = false;
+                       $brands = explode_trim(',', $Accepted);
+                       foreach ($brands as $brand) {
+                               if ($Name == $brand)
+                                       $type_verified = true;
+                       }
+
+                       if (!$type_verified) {
+                               return false;
+                       }
+               }
+
+               $Num = strrev($Num);
+
+               $Total = 0;
+
+               for ($x = 0; $x < strlen($Num); ++$x) {
+                       $digit = substr($Num, $x, 1);
+                       if ($x / 2 != floor($x / 2)) {
+                               $digit *= 2;
+                               if (strlen($digit) == 2)
+                                       $digit = substr($digit, 0, 1) + substr($digit, 1, 1);
+                       }
+                       $Total += $digit;
+               }
+               return ($GoodCard && (($Total % 10) == 0)) ? true : false;
+       }
+       // DataBase Library
+
+       /**
+        * db_connect :Creates a connection to database specified $conn_str
+        * @param $conn="" : connection string
+        *
+        * @return index or bool
+        * @access
+        **/
+       function db_connect($conn = '')
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       if ($conn == '')
+                       $conn = CONN_STR;
+                       $ret = pg_connect($conn);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_close :Closes the connection to database specified by the handle dbd
+        * @param $$dbd : database handle
+        *
+        * @return bool
+        * @access
+        **/
+       function db_close($dbd)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_close($dbd);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+         NOTICE DON'T USE THIS
+        * db_pconnect :Creates a persistant connection to database specified in $conn_str
+        * @param $$conn="" : connection string
+        *
+        * @return
+        * @access
+        **/
+       function db_pconnect($conn = '')
+       {
+               return false;
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       if($conn == '')
+                               $conn == CONN_STR;
+                       $ret = pg_pconnect($conn);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_exec : Execute an SQL query
+        * @param $dbd: database handle
+        * @param $$qs : Query
+        *
+        * @return int Returns a valid result index on success 0 on failure
+        * @access
+        **/
+       function db_exec($dbd, $qs)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_exec($dbd, $qs);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_fetch_array :Stores the data in associative indices, using the field names as
+        * keys.
+        * @param $res: valid database result index
+        * @param $i: row number
+        * @param $$type : database type
+        *
+        * @return array Returns an associative array of key-value pairs
+        * @access
+        **/
+       function db_fetch_array($res, $i, $type)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $row = pg_fetch_array($res, $i, $type);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $row;
+       }
+
+       /**
+        * db_freeresult :Free result memory.
+        * @param $$res : valid database result index
+        *
+        * @return bool - Returns 1 for success 0 for failure
+        * @access
+        **/
+       function db_freeresult($res)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_freeresult($res);
+                       break;
+
+               default:
+                       return 0;
+                       break;
+               }
+               return $ret;
+       }
+
+       /**
+        * db_numrows :Determine number of rows in a result index
+        * @param $$res : valid database result index
+        *
+        * @return int - Returns number of rows
+        * @access
+        **/
+       function db_numrows($res)
+       {
+               switch (DB_TYPE) {
+               case 'postgres' :
+                       $ret = pg_numrows($res);
+                       break;
+
+               default:
+                       return -1;
+                       break;
+               }
+               return $ret;
+       }
+
+       /************************************************************************
+        *                                                                                                                                              *
+        * BEGIN Auto functions                                                                                                 *
+        *                                                                                                                                              *
+        ***********************************************************************/
+
+       /**
+        * db_auto_array :The auto function for retrieving an array based soley on a query
+        * string. This function makes the connection, does the exec, fetches
+        * the array, closes the connection, frees memory used by the result,
+        * and then returns the array
+        * @param $qs: SQL query string
+        * @param $i: row number
+        * @param $$type : PGSQL_ASSOC or PGSQL_BOTH or PSQL_NUM
+        *
+        * @return array - Returns an associative array of key-value pairs
+        * @access
+        **/
+       function db_auto_array($qs, $i, $type)
+       {
+               $dbd = db_connect();
+               if (!$dbd) {
+                       return 0;
+               }
+               $res = db_exec($dbd, $qs);
+               if (!$res) {
+                       return 0;
+               }
+               $row = db_fetch_array($res, $i, $type);
+               if (!db_freeresult($res)) {
+                       return 0;
+               }
+               db_close($dbd);
+               return $row;
+       }
+
+       /**
+        * db_auto_exec :The auto function for executing a query.
+        * This function makes the connection, does the exec, fetches
+        * the array, closes the connection, frees memory used by the result,
+        * and then returns success (not a valid result index)
+        * @param $qs: SQL query string
+        * @param $$conn="" : Connect String
+        *
+        * @return int - Returns 1 (or oid, if available) for success 0 for failure
+        * @access
+        **/
+       function db_auto_exec($qs, $conn = '')
+       {
+               if ($conn == ''){
+                       $conn = CONN_STR;
+               }
+               $dbd = db_connect($conn);
+               if (!$dbd) {
+                       return 0;
+               }
+               if (!db_exec($dbd, $qs)) {
+                       db_close($dbd);
+                       return 0;
+               } else {
+                       db_close($dbd);
+                       return 1;
+               }
+       }
+
+       /**
+        * db_auto_get_data :The auto function for retrieving an array based soley on a query
+        string. This function makes the connection, does the exec, fetches
+        the array, closes the connection, frees memory used by the result,
+        and then returns the array
+        * @param $qs:  SQL query string
+        * @param $CONN_STR: Connect String
+        * @param $$fail_mode=0 : Failure Mode
+        *
+        * @return array Returns an associative array of key-value pairs
+        * @access
+        **/
+       function db_auto_get_data($qs, $conn = CONN_STR, $fail_mode = 0) {
+
+               if (!($dbd = db_connect($conn))) {
+                       return false;
+               }
+
+               if (!($res = db_exec($dbd, $qs))) {
+                       return false;
+               }
+
+               $totalrows = pg_NumRows($res);
+
+               for ($i = 0 ; $i < $totalrows; ++$i) {
+                       $data[$i] = db_fetch_array($res, $i, PGSQL_ASSOC);
+               }
+
+               db_close($dbd);
+               return (isset($data) && $data != '') ? $data : 0;
+       }
+
+       //      HTML Libraries
+
+       /**
+        * html_footer :Generates a footer table on the bottom of the page it's called on.
+        and closes out the body and html tags.
+        *
+        * @return void
+        * @access
+        **/
+       function html_footer()
+       {
+               $footer_table_width = '400';
+               $footer_table_align = 'center';
+               ?>
+                       <hr>
+                       <table width="<?php echo $footer_table_width?>"
+                               align="<?php echo $footer_table_align?>"
+                               summary="Footer Information" class="footertable" cellspacing="0">
+                               <tr>
+                                       <td align="left" class="footertd">
+                                               <a href="mailto:<?php echo MASTER_EMAIL;?>"><?php echo MASTER;?></a>
+                                       </td>
+                                       <td align="right" class="footertd">
+                                               <a href="<?php echo FOOTER_URL;?>" target="new">
+                                               <img src="<?php echo FOOTER_IMG;?>" border=0 alt="FOOTER_IMG"></a>
+                                       </td>
+                               </tr>
+                       </table>
+                       </body>
+                       </html>
+                       <?php
+                       //      We've got to terminate any more output
+                       exit;
+       }
+
+       /**
+        * html_error :Generates a footer table on the bottom of the page it's called on.
+        and closes out the body and html tags.
+        * @param $msg: string error message to be displayed
+        * @param $$bail : bool whether or not to exit() after $msg
+        *
+        * @return void
+        * @access
+        **/
+       function html_error($msg, $bail)
+       {
+               ?>
+                       <table summary="Error Information" class="errortable" cellspacing="0">
+                               <tr class="errortr">
+                                       <td class="errortd">
+                                               <div class="errormsg"><?echo "<pre>$msg</pre>"?></div>
+                                       </td>
+                               </tr>
+                       </table>
+
+                       <?php
+                       if ($bail) {
+                               html_footer();
+                       }
+       }
+
+       /**
+        * html_nav_table :Generates a navigation table on the page it's called on.
+        * @param $nav: associative array with entries like:$nav[text][url]
+        * @param $$w : max width of table
+        *
+        * @return void
+        * @access
+        **/
+       function html_nav_table($nav, $w)
+       {
+               if (is_array($nav)) {
+                       $out = '<ul class="admin_nav">';
+                       foreach ($nav as $link => $url) {
+                               if (is_array($url)) {
+                                       $out .= '<li><a href="'.$url[0].'" '.$url[1].'>'.$link.'</a></li>';
+                               } else {
+                                       $out .= '<li><a href="'.$url.'">'.$link.'</a></li>';
+                               }
+                       }
+                       $out .= '</ul>';
+               }
+               echo $out;
+       }
+
+       /**
+        * html_header :Opens up the html tags, and includes the style sheet link
+        generates a header table on the top of the page it's called on.
+        * @param $title: Page Title
+        * @param $msg: message to display
+        * @param $$img : image to display
+        *
+        * @return void
+        * @access
+        **/
+       function html_header($title, $msg, $img)
+       {
+               $header_table_width = '400';
+               $header_table_align = 'center';
+               ?>
+                       <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+                       "http://www.w3.org/TR/html4/loose.dtd">
+                       <html>
+                       <head>
+                               <title><?php echo $title?></title>
+                               <link type="text/css" rel=stylesheet href="<?php echo STYLE;?>">
+                       </head>
+                       <body>
+                               <table width="<?php echo $header_table_width?>"
+                                       align="<?echo $header_table_align?>"
+                                       summary="Header Information" class="headertable"
+                                       cellspacing="0" cellpadding="3">
+                                       <tr class="headertr">
+                                               <td class="headertd">
+                                                       <?php if($img) : ?>
+                                                       <img src="<?php echo IMG_BASE.$img;?>"
+                                                               alt="<?php echo HEAD;?>" border="0">
+                                                       <?php endif; ?>
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td class="headertd2" align="center">
+                                                       <div class="headerh2" align="center">
+                                                               <?php echo $msg;?>
+                                                       </div>
+                                               </td>
+                                       </tr>
+                               </table>
+                       <?php
+       }
+
+       /**
+        * form_header :Opens up the form tag, and includes the hidden assoc array as hidden
+        fields.
+        * @param $action: string form action string
+        * @param $method: string Method of form
+        * @param $$hidden = "" : assoc array with $hidden($name => $value)
+        *
+        * @return void
+        * @access
+        **/
+       function form_header($action, $method, $hidden = '')
+       {
+               echo '<form action="'.$action.'" method="'.$method.'"
+                       enctype="multipart/form-data">';
+               if ($hidden != '' && is_array($hidden)) {
+                       foreach ($hidden as $k => $v) {
+                               echo '<input type="hidden" name="'.$k.'" value="'.$v.'">';
+                       }
+               }
+       }
+
+       /**
+        * text_box :Creates a input box for text with 35 as default size
+        * @param $name: string name of text box
+        * @param $value: string value of text box
+        * @param $$size = 35 : string size of text box
+        *
+        * @return void
+        * @access
+        **/
+       function text_box($name, $value, $size = 35) {
+               echo '<td class="navtd2"><input type="text" name="'.$name.'"
+                       value="'.htmlspecialchars($value).'" size="'.$size.'"></td>';
+       }
+
+       /**
+        * form_footer :Closes up the form tag, and includes the submit button
+        * @param $name: string form action string
+        * @param $$suppress = 0: string Method of form
+        * @param $$cs : int colspan for td
+        *
+        * @return void
+        * @access
+        **/
+       function form_footer($name, $suppress = 0, $cs)
+       {
+               echo '<tr><td colspan="'.$cs.'" align=center>
+                       <input type="SUBMIT" name="Command" value="'.$name.'">';
+               if ($suppress == 1) {
+                       echo '<input type="SUBMIT" name="Command" value="Delete">';
+               }
+               echo '</td>';
+       }
+
+       /**
+        * file_upload
+        * this will replace the older version and that of img_upload which calls this with extra
+        * restricted of true
+        *
+        * @param mixed $form_field
+        * @param mixed $file_name
+        * @param mixed $destination_path
+        * @access public
+        * @return string
+        */
+       function file_upload($form_field, $file_name, $destination_path, $restricted = false)
+       {
+               $file_name_in_use = false;
+               $file_name = ereg_replace('[!@#$%^&()+={};:\'\"\/ ]', '-', $file_name);
+               if ($restricted) {
+                       $size = getImageSize($form_field);
+                       if (!in_array($size[2], array(1, 2, 3))) {
+                               echo '<p style="background-color:red;color:white;">' .
+                               'The file you uploaded was of an incorect type,
+                                please only upload .gif,.png or .jpg files' .
+                               '<BR CLEAR=ALL>' .
+                               '</p>' .
+                               "Hit your browser's back button to continue" .
+                               '<p>';
+                               $error[0] = 'ERROR';
+                               return $error;
+                       }
+               }
+               if (file_exists($destination_path . $file_name)) {
+                       $file_name_in_use = true;
+               }
+               if ($file_name_in_use == true) {
+                       $new_file_name = mktime() . $file_name;
+                       $new_file_location = $destination_path . $new_file_name;
+                       copy($form_field, $new_file_location);
+                       $file_upload = $new_file_name;
+                       $file_upload_array = array( $new_file_name, $new_file_location);
+               } else {
+                       $new_file_name = $file_name;
+                       $new_file_location = $destination_path.$new_file_name;
+                       copy($form_field, $new_file_location);
+                       $file_upload = $new_file_name;
+                       $file_upload_array = array($new_file_name, $new_file_location);
+               }
+               if (is_file($new_file_location)) {
+                       chmod($new_file_location, 0666);
+               }
+               return ($restricted) ? $file_upload_array : $file_upload;
+       }
+
+       //      Misc. Functions
+
+       /**
+        * http_strip :Strips the http:// part from start of string
+        * @param $&$string : $string
+        *
+        * @return string $stirng minus http:// in front
+        * @access
+        **/
+       function http_strip(&$string)
+       {
+               $test_string = strtolower($string);
+               if(substr($test_string, 0, 7) == 'http://') {
+                       $string = substr($string, 7);
+               }
+       }
+
+       /**
+        * footer : used for admin page footer to close out the top function
+        *
+        * @return void
+        * @access
+        **/
+       function footer()
+       {
+               echo "\n\t</body>\n</html>";
+       }
+
+       /**
+        * top :Output the starting html and admin table tags
+        * @param $message: The title
+        * @param $hp: The help file to use
+        * @param $$hp2 = NULL : The help file to use (links to gaslightmedia.com)
+        *
+        * @return void
+        * @access
+        **/
+       function top($message, $hp, $hp2 = NULL)
+       {
+               if ($hp2 != '') {
+                       $help_guide = '<div id="glm-manual">';
+                       /*
+                          $help_guide = '<div id="glm-manual"><a id="manual-html"
+                          href="http://www.gaslightmedia.com/manuals/html/'.$hp2.'.html"
+                          target="_blank">Online Help Guide</a>&nbsp;';
+                        */
+                       $help_guide .= '<a id="manual-pdf"
+                               href="http://www.gaslightmedia.com/manuals/pdf/'.$hp2.'.pdf"
+                               target="_blank">Printable Help Guide</a></div>';
+               }
+               $out = '
+                       <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                       "http://www.w3.org/TR/html4/strict.dtd">
+                       <html>
+                       <head>
+                               <title>Untitled</title>
+                               <meta http-equiv="content-type" content="text/html;charset=utf-8">
+                               <link rel="stylesheet" type="text/css" href="../main.css">
+                       <script type="text/javascript" src="'.BASE_URL.'libjs/jquery-1.3.2.min.js"></script>
+                       </head>
+                       <body>
+                               <h1>'.$message.'</h1>
+                               ' . $help_guide;
+               echo $out;
+       }
+
+       /**
+        * top2 : alias to top()
+        * @param $message: message title
+        * @param $hp: help file
+        * @param $$hp2 = NULL : gaslight help file
+        *
+        * @return
+        * @access
+        **/
+       function top2($message, $hp,$hp2 = NULL) {
+               // make this an alias to top()
+               // by calling top instead of adding extra code
+               top($message, $hp, $hp2);
+
+       }
+
+       /********************************************************************************
+        *
+        *      DO NOT EDIT THIS SECTION
+        *
+        ********************************************************************************/
+
+       if ($DEBUG) {
+               echo '<CENTER>
+                       <TABLE BORDER=0 CELLPADDING=3 CELLSPACING=1 WIDTH=600 BGCOLOR="#000000" ALIGN="CENTER">
+                       <TR VALIGN="middle" BGCOLOR="#9999CC">
+                       <TD COLSPAN="2" ALIGN="center"><H1>Portable Site Data - setup.phtml </H1></TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>CVS Version Id:</B></TD>
+                       <TD ALIGN="left">$Id: setup_functions.phtml,v 1.5 2010/01/20 19:50:13 jamie Exp $</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>SITENAME</B></TD>
+                       <TD ALIGN="left">'.SITENAME.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>BASE</B></TD>
+                       <TD ALIGN="left">'.BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>UP_BASE</B></TD>
+                       <TD ALIGN="left">'.UP_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>HELP_BASE</B></TD>
+                       <TD ALIGN="left">'.HELP_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>IMG_BASE</B></TD>
+                       <TD ALIGN="left">'.IMG_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>URL_BASE</B></TD>
+                       <TD ALIGN="left">'.URL_BASE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>CONN_STR</B></TD>
+                       <TD ALIGN="left">'.CONN_STR.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>STYLE</B></TD>
+                       <TD ALIGN="left">'.STYLE.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>ORIGINAL_PATH</B></TD>
+                       <TD ALIGN="left">'.ORIGINAL_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>RESIZED_PATH</B></TD>
+                       <TD ALIGN="left">'.RESIZED_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>MIDSIZED_PATH</B></TD>
+                       <TD ALIGN="left">'.MIDSIZED_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>THUMB_PATH</B></TD>
+                       <TD ALIGN="left">'.THUMB_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>ORIGINAL</B></TD>
+                       <TD ALIGN="left">'.ORIGINAL.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>RESIZED</B></TD>
+                       <TD ALIGN="left">'.RESIZED.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>MIDSIZED</B></TD>
+                       <TD ALIGN="left">'.MIDSIZED.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>THUMB</B></TD>
+                       <TD ALIGN="left">'.THUMB.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$CALLED_FROM_DIR</B></TD>
+                       <TD ALIGN="left">'.$CALLED_FROM_DIR.'&nbsp;</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$BASE_PATH</B></TD>
+                       <TD ALIGN="left">'.$BASE_PATH.'</TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$BASE_URL</B></TD>
+                       <TD ALIGN="left"><A HREF="'.$BASE_URL.'">'.$BASE_URL.'</A></TD>
+                       </TR>
+                       <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+                       <TD BGCOLOR="#CCCCFF" ><B>$BASE_SECURE_URL</B></TD>
+                       <TD ALIGN="left">'.$BASE_SECURE_URL.'</TD>
+                       </TR>
+                       </TABLE>
+                       &nbsp;
+               <P>
+                       <HR WIDTH="600">
+                       <P>
+                       </CENTER>
+                       ';
+       }
+
+       /**
+        * date_entry : Generate the select boxes for date entry
+        * month-day-year as drop down select
+        * @param $month:
+        * @param $day:
+        * @param $year:
+        * @param $month_name: name of select month
+        * @param $day_name: name of select day
+        * @param $$year_name : name of select year
+        *
+        * @return
+        * @access
+        **/
+       function date_entry($month, $day, $year, $month_name, $day_name, $year_name, $onChange = NULL)
+       {
+               $cur_date = getdate();
+
+               if ($month == '') {
+                       $month = $cur_date['mon'];
+               }
+               if($day == '') {
+                       $day = $cur_date['mday'];
+               }
+               if($year == '') {
+                       $year = $cur_date['year'];
+               }
+               $date = '<select id="'.$month_name.'" name="'.$month_name.'" '.$onChange.'>';
+               for ($i = 1; $i < 13; ++$i) {
+                       $date .= '<option value="';
+                       if ($i < 10) {
+                               $date .= '0';
+                       }
+                       $date .= $i.'"';
+                       if ($i == $month) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               $date .= '<select id="'.$day_name.'" name="'.$day_name.'" '.$onChange.'>';
+               for ($i = 1; $i < 32; ++$i) {
+                       $date .= '<option value="';
+                       if ($i < 10) {
+                               $date .= "0";
+                       }
+                       $date .= $i.'"';
+                       if($i == $day) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               $date .= '<select id="'.$year_name.'" name="'.$year_name.'" '.$onChange.'>';
+               for ($i = 2000; $i < 2023; ++$i) {
+                       $date .= '<option value="'.$i.'"';
+                       if ($i == $year) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               return $date;
+       }
+
+       /**
+        * contact_date_entry : build select boxes for date entry going backwords in years
+        * @param $month:
+        * @param $day:
+        * @param $year:
+        * @param $month_name: name of select month
+        * @param $day_name: name of select day
+        * @param $$year_name : name of select year
+        *
+        * @return void
+        * @access
+        **/
+       function contact_date_entry($month, $day, $year, $month_name, $day_name, $year_name)
+       {
+               $cur_date = getdate();
+
+               if ($month == '') {
+                       $month = $cur_date['mon'];
+               }
+               if ($day == '') {
+                       $day = $cur_date['mday'];
+               }
+               if ($year == '') {
+                       $year = $cur_date['year'];
+               }
+               $date = '<select name="'.$month_name.'">';
+               for ($i = 1; $i < 13; ++$i) {
+                       $date .= '<option value="';
+                       if ($i < 10) {
+                               $date .= '0';
+                       }
+                       $date .= $i.'"';
+                       if ($i == $month) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               $date .= '<select name="'.$day_name.'">';
+               for ($i = 1; $i < 32; ++$i) {
+                       $date .= '<option value="';
+                       if($i < 10) {
+                               $date .= '0';
+                       }
+                       $date .= $i.'"';
+                       if ($i == $day) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               $date .= '<select name="'.$year_name.'">';
+               $ystart = $cur_date['year'] - 10;
+               for ($i = $ystart; $i <= $year; ++$i) {
+                       $date .= '<option value="'.$i.'"';
+                       if ($i == $year) {
+                               $date .= ' selected';
+                       }
+                       $date .= ">$i";
+               }
+               $date .= '</select>';
+               return $date;
+       }
+
+       /**
+        * time_entry : build select boxes for time entry
+        * @param $H:
+        * @param $m:
+        * @param $F:
+        * @param $H_name: name of select hour
+        * @param $m_name: name of select min
+        * @param $$F_name : name of select sec
+        *
+        * @return
+        * @access
+        **/
+       function time_entry($H, $m, $F, $H_name, $m_name, $F_name)
+       {
+               $cur_date = getdate();
+               if ($H == '') {
+                       $H = $cur_date['hours'];
+               }
+               if ($m == '') {
+                       $m = $cur_date['minutes'];
+               }
+               if ($H > 12) {
+                       $F = 'PM';
+                       $H = $H - 12;
+               }
+               $time = "Hr:<select name=\"$H_name\" size=\"1\">";
+               for ($i = 1; $i <= 12; ++$i) {
+                       $time .= "<option value=\"";
+                       if ($i < 10) {
+                               $time .= "0";
+                       }
+                       $time .= "$i\"";
+                       if ($i == $H) {
+                               $time .= " selected";
+                       }
+                       $time .= ">$i\n";
+               }
+               $time .= "</select>\n";
+               $time .= "Min:<select name=\"$m_name\" size=\"1\">";
+               for ($i = 0; $i < 60; $i = $i + 15) {
+                       $time .= "<Option value=\"";
+                       if ($i < 10) {
+                               $time .= "0";
+                       }
+                       $time .= "$i\"";
+                       if ($i == $m) {
+                               $time .= " selected";
+                       }
+                       $time .= ">";
+                       if ($i < 10) {
+                               $time .= "0";
+                       }
+                       $time .= "$i\n";
+               }
+               $time .= "</select>";
+               $time .= "<select name=\"$F_name\" size=\"1\">";
+               $time .= "<option value=\"AM\"";
+               if ($F == "AM") {
+                       $time .= " selected";
+               }
+               $time .= ">AM\n";
+               $time .= "<option value=\"PM\"";
+               if ($F == "PM") {
+                       $time .= " selected";
+               }
+               $time .= ">PM\n";
+               $time .= "</select>\n";
+               return $time;
+       }
+
+       /**
+        * get_parentid: get the (highest level) parent category for this id
+        * @param $id: id from bus_category table
+        *
+        * @return int parent
+        * @access
+        **/
+       function get_parentid($id)
+       {
+               static $parentshow;
+               if ($id == 0) {
+                       return 0;
+               }
+               if (!is_array($parentshow)) {
+                       $sql = "
+                               SELECT parent
+                                 FROM bus_category
+                                WHERE id = $id";
+                       $parentrow = db_auto_get_data($qs);
+               }
+               if ($parentrow[0]['parent'] == 0) {
+                       return $id;
+               } else {
+                       return get_parentid($parentrow[0]['parent']);
+               }
+       }
+
+       /**
+        * build_picklist:Builds a pick list from an array
+        * @param $fieldname: fieldname field name for select
+        * @param $data: data array of data
+        * @param $selected: selected witch element is selected
+        * @param $$type = "standard": type Standard,multi
+        * @param $$auto = 0: auto
+        * @param $$width = NULL : width width controlled by css
+        *
+        * @return void
+        * @access
+        **/
+       function build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL ) {
+               if(!is_array($selected)) {
+                       $sel[0] = $selected;
+               } else {
+                       $sel = $selected;
+               }
+               if($auto == 1)
+                       $autosubmit = "onChange=\"form.submit()\"";
+               if($width)
+                       $autosubmit .= "style=\"width:".$width."px;\"";
+               switch( $type ) {
+                       case "multiple":
+                               $str = "<select name=\"".$fieldname."\" multiple size=\"10\" ".$autosubmit.">\n";
+                       while( list($key, $val) = each($data) ) {
+                               if( in_array($key,$sel) ) {
+                                       $select = " selected ";
+                               }
+                               else
+                                       $select = "";
+                               $str .= "       <option value=\"$key\"".$select.">$val\n";
+                       }
+                       break;
+                       case "simple":
+                               $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+                       for( $i=0 ; $i<count($data) ; $i++ ) {
+                               $select = (in_array($data[$i],$sel)) ? " selected ":"";
+                               $str .= "       <option value=\"".$data[$i]."\"".$select.">".$data[$i]."\n";
+                       }
+                       break;
+
+                       case "standard":
+                       default:
+                               $str = "<select name=\"$fieldname\" ".$autosubmit.">\n";
+                               while( list($key, $val) = each($data) ) {
+                                       $select = (in_array($key,$sel)) ? " selected ":"";
+                                       $str .= "       <option value=\"$key\"".$select.">$val\n";
+                               }
+                               break;
+               }
+               $str .= "</select>\n";
+
+               return $str;
+
+       }
+
+       /**
+        * create_page_links:Create prev and next links
+        * to page through the results.
+        * @param $totalnum: The total result of the query
+        * @param $num: The total result for the page
+        * @param $$start=0: The starting num defaults to 0
+        * @param $params: variables to add to the url
+        * @param $ENTRIES_PER_PAGE: number of items on page defaults to the ENTRIES_PER_PAGE
+        *
+        * @return string of links
+        * @access
+        **/
+       function create_page_links($totalnum,$num,$start=0,$params,$page_length=ENTRIES_PER_PAGE) {
+               // find out which page we're on.
+               if($totalnum!=0) {
+                       $total_pages = floor($totalnum / $page_length);         // total pages = the total result divided by page length rounded down
+                       $total_pages++;                                                                         // then add one
+                       if($start == 0) {                                                                       // if start is 0 then page is one {
+                               $page = 1;
+                       } else  {
+                               $page = ($start / $page_length) + 1;
+                       }
+               }
+
+               if($totalnum > $page_length && ( $page != $totalpages ) ) {
+                       $end = $page_length + $start;
+               } else {
+                       $end = $totalnum;
+               }
+               $last = $start - $page_length;
+               if(($start - $page_length) < 0)
+                       $prev = "";
+               else
+                       $prev = "<span class=\"accenttext\">[</span><a class=\"small\"
+                               href=\"$GLOBALS[PHP_SELF]?start=".$last."&$params\">PREVIOUS PAGE</a><span
+                               class=\"accenttext\"> ]</span>";
+               if($end < $totalnum)
+                       $next = "<span class=\"accenttext\">[</span><a class=\"small\"
+                               href=\"$GLOBALS[PHP_SELF]?start=".$end."&$params\">NEXT PAGE</a><span
+                               class=\"accenttext\"> ]</span>";
+               else
+                       $next = "";
+               $starting = $start + 1;
+               $last_c = $start + $num;
+               $links = '<center><span class="pagetitle">Listings Displayed: </span><span
+                       class="accenttext">'.$starting.' to '.$last_c.'</span>
+                       <span class="pagetitle"> of '.$totalnum.'<br></span> '.$prev. ' &nbsp; <span
+                       class="pagetitle"></span> '.$next.'<BR></span></center>';
+               return $links;
+       }
+?>
diff --git a/static/.keepme b/static/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/templates/404-template.html b/templates/404-template.html
new file mode 100755 (executable)
index 0000000..e6a96a1
--- /dev/null
@@ -0,0 +1,15 @@
+<div id="404">
+       <h1>Ooops.. </h1>
+       <h2>We can't find the page you were looking for</h2>
+  <p>There can be a couple of reasons for this:
+       <ul>
+       <li>If you typed the website address yourself, please make sure that the spelling is correct</li>
+      <li>The page does not exist anymore</li>
+               </ul>
+
+       To help you find what you're looking for, you can use the navigation on this page, or just follow one of the links below.
+  <ul>
+      <li><a href="{homeURL}">Go to the Homepage</a></li>
+      <li flexy:if="sitemapURL"><a href="{sitemapURL}">Look at a sitemap of this website</a></li>
+       </ul>
+</div>
diff --git a/templates/template.html b/templates/template.html
new file mode 100755 (executable)
index 0000000..da8548e
--- /dev/null
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>{title:h}</title>
+<meta http-equiv="content-type" content="text/html;charset=utf-8">
+<meta name="description" content="{metaTags:h}">
+<meta http-equiv="imagetoolbar" content="no">
+<meta http-equiv="imagetoolbar" content="false">
+{styles:h}
+{scripts:h}
+<!--[if lte IE 7]>
+<link rel="stylesheet" type="text/css" href="http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/ie7.css">
+<![endif]-->
+<link rel="stylesheet" type="text/css" href="http://devsys2.gaslightmedia.com/demo.gaslightmedia.com/toolbox.css">
+</head>
+<body>
+<div id="wrapper">
+       <div id="wrapperInner">
+               <div id="top">
+                       <a href="baseurl/index.php">
+                               <img id="logo" src="baseurl/assets/logo.gif">
+                       </a>
+               </div><!-- /#top -->
+               <div id="nav">
+      <ul>
+        <li><a href="baseurl/index.php">Home</a></li>
+        <li><a href="{glmAssociate}">The GLM Associate</a></li>
+        <li><a href="{contactGLM}">Contact Gaslight Media</a></li>
+        <li><a href="{servicesOffered}">Services Offered</a></li>
+        <li><a href="{aboutGLM}">About Gaslight Media</a></li>
+      </ul>
+               </div><!-- /#nav -->
+               <div id="main">
+                       <div id="toolbox">
+                               {toolboxContent:h}
+                               {if:rotatingImages}
+                                       {rotatingImages:h}
+                               {end:}
+                       </div><!-- /#toolbox -->
+
+                       <div flexy:if="hasHeadlines" id="headlines">
+                               <h2>Headlines</h2>
+                               {foreach:features,v}
+                                       <div class="headlinesItem">
+                                               <h3>{v[intro]:h}</h3>
+                                               <img>
+                                               <p>
+                                                       {v[feature_intro]:h}
+                                                       <a href="{v[link]:h}">Read More...</a>
+                                               </p>
+                                       </div><!-- /.headlinesItem -->
+                       {end:}
+                       </div><!-- /#headlines -->
+                       <div flexy:if="hasBanner" id="banner">
+                               {bannerAds:h}
+                       </div><!-- /#banner -->
+               </div><!-- /#main -->
+               <div id="column">
+                       <div id="subnav">
+                               {sideNav:h}
+                       </div>
+            <div id="planyourtrip">
+                <p><a href="{tripPlannerUrl}"><span class="trip-list-count">{tripPlannerCount:h}</span> items in your trip</a></p>
+            </div><!-- /#planyourtrip -->
+
+<div id="events" flexy:if="hasEvents">
+       <div id="eventtitle">
+               <a href="{eventsUrl}" title="Events">EVENTS</a>
+       </div><!-- /#eventtitle -->
+       <div id="prev-event">Previous Event</div>
+       <ul class="events-rotator">
+               <li flexy:foreach="events,event">
+                       <p><a href="{event[href]:h}">{event[header]:h}</a></p>
+                       <p class="date">{event[dates]:h}</p>
+                       <p>{event[descr]:h}</p>
+               </li>
+       </ul>
+       <div id="next-event">Next Event</div>
+
+</div><!-- /#events -->
+                       <div id="guide">
+                               <a href="baseurl/request-our-brochure-42/">View Brochure</a>
+                       </div><!-- /#guide -->
+                       <div id="cReservations">
+                               <a href="baseurl/online-reservations-50/">
+                                       Book a Room Now
+                               </a>
+                       </div><!-- /#cReservations -->
+                       <div flexy:if="hasEvents" id="cEvents">
+                               <a flexy:foreach="events,v" href="{v[href]:h}" class="cEventItem">
+                                       <span class="cEventDate">{v[bdate]:h}</span>
+                                       <span class="cEventTitle">{v[header]:h}</span>
+                               </a><!-- /.cEventItem -->
+                       </div><!-- /#cEvents -->
+                       <form id="cNewsletter" action="{newsletterAction}" method="post">
+                               <input id="email-f" name="email" type="text" class="text" value="Your Email Address">
+                               <input type="hidden" name="verify_email" id="email-h">
+                               <input type="hidden" name="mail_ok" value="t">
+                               <input type="hidden" name="contact_type" value="6">
+                               <input type="image" src="baseurl/assets/go.gif" alt="" class="submit">
+                       </form><!-- /#cNewsletter -->
+            <div id="weather" flexy:if="hasWeather">
+            <img src="http://app.gaslightmedia.com/weather/{iconUrlName}" alt="" width="48" height="48">
+            <p class="top">{weather} <span class="temp">{tempF}&#176;</span></p>
+            <p>{location}</p>
+          </div><!-- /#weather -->
+               </div><!-- /#column -->
+               <div id="bottom">
+                       <img src="baseurl/assets/logoGlm.gif" id="logoGlm">
+                       <div id="address">
+                               <span>120 E. Lake Street</span>
+                               <span>Petoskey, MI 49770</span>
+                               <span>231.487.0692 - Phone</span>
+                               <span>231.487.0313 - Fax</span>
+                       </div><!-- /#address -->
+               </div><!-- /#bottom -->
+<div id="glmLoad" style="display:none;position:fixed;top:50%;width:208px;margin:-6px 0 0 -104px;left: 50%;height:13px;z-index: 103;"><img src="http://app.gaslightmedia.com/gallery/loadingAnimation.gif" /></div>
+               <div id="copyright">
+                       Copyright&copy;<?php echo date('Y');?> Gaslight Media, All Rights Reserved.
+               </div><!-- /#copyright -->
+       </div><!-- /#wrapperInner" -->
+</div><!-- /#wrapper -->
+</body>
+</html>
diff --git a/toolbox.css b/toolbox.css
new file mode 100644 (file)
index 0000000..4d620f3
--- /dev/null
@@ -0,0 +1,27 @@
+/* Image Upload Icons */
+.file-download, .download {
+       background-repeat: no-repeat;
+       background-position: left;
+       padding: 1px 2px;       
+       padding-left: 18px;
+       position: relative;
+       margin-right: 10px;
+       margin-bottom: 5px;
+       display: block;
+       float: left;
+       clear: left;
+       }
+.avi   { background-image: url(images/file-ext/avi.gif);}
+.doc   { background-image: url(images/file-ext/doc.gif);}
+.gif   { background-image: url(images/file-ext/gif.gif);}
+.html  { background-image: url(images/file-ext/html.gif);}
+.jpg   { background-image: url(images/file-ext/jpg.gif);}
+.mov   { background-image: url(images/file-ext/mov.gif);}
+.mp3   { background-image: url(images/file-ext/mp3.gif);}
+.pdf   { background-image: url(images/file-ext/pdf.png);}
+.ppt   { background-image: url(images/file-ext/ppt.gif);}
+.txt   { background-image: url(images/file-ext/txt.png);}
+.wmv   { background-image: url(images/file-ext/wmv.gif);}
+.xls   { background-image: url(images/file-ext/xls.gif);}
+.zip   { background-image: url(images/file-ext/zip.png);}
+.download {  background-image: url(images/file-ext/download.gif); clear: none; background-repeat: no-repeat;}  
\ No newline at end of file
diff --git a/uploads/.cvsignore b/uploads/.cvsignore
new file mode 100644 (file)
index 0000000..65fb5e5
--- /dev/null
@@ -0,0 +1 @@
+* *.*
diff --git a/uploads/.keepme b/uploads/.keepme
new file mode 100644 (file)
index 0000000..e69de29