adding RotatingImages
authorSteve Sutton <steve@gaslightmedia.com>
Fri, 5 Feb 2010 19:57:59 +0000 (19:57 +0000)
committerSteve Sutton <steve@gaslightmedia.com>
Fri, 5 Feb 2010 19:57:59 +0000 (19:57 +0000)
39 files changed:
Toolkit/RotatingImages/ActiveImagesDataGrid.php [new file with mode: 0644]
Toolkit/RotatingImages/Anchor.php [new file with mode: 0644]
Toolkit/RotatingImages/AnchorDecorator.php [new file with mode: 0644]
Toolkit/RotatingImages/Database/application.sql [new file with mode: 0644]
Toolkit/RotatingImages/Database/procedures/insertAnchor.sql [new file with mode: 0644]
Toolkit/RotatingImages/Database/procedures/insertImage.sql [new file with mode: 0644]
Toolkit/RotatingImages/Database/tables/rotating_images.sql [new file with mode: 0644]
Toolkit/RotatingImages/Database/tables/rotating_images_transitions.sql [new file with mode: 0644]
Toolkit/RotatingImages/Decorator.php [new file with mode: 0644]
Toolkit/RotatingImages/EditImageForm.php [new file with mode: 0644]
Toolkit/RotatingImages/IDecoratorsIterator.php [new file with mode: 0644]
Toolkit/RotatingImages/IImagesDataGrid.php [new file with mode: 0644]
Toolkit/RotatingImages/Image.php [new file with mode: 0644]
Toolkit/RotatingImages/ImageDecorator.php [new file with mode: 0644]
Toolkit/RotatingImages/ImageThumbnailDecorator.php [new file with mode: 0644]
Toolkit/RotatingImages/ImagesDataGrid.php [new file with mode: 0644]
Toolkit/RotatingImages/InactiveImagesDataGrid.php [new file with mode: 0644]
Toolkit/RotatingImages/LiveDecorator.php [new file with mode: 0644]
Toolkit/RotatingImages/Node.php [new file with mode: 0644]
Toolkit/RotatingImages/NodesIterator.php [new file with mode: 0644]
Toolkit/RotatingImages/PreviewDecorator.php [new file with mode: 0644]
Toolkit/RotatingImages/TransitionPreview.php [new file with mode: 0644]
Toolkit/RotatingImages/TransitionSettingsForm.php [new file with mode: 0644]
Toolkit/RotatingImages/ajax.php [new file with mode: 0644]
Toolkit/RotatingImages/assets/.keepme [new file with mode: 0644]
Toolkit/RotatingImages/config.ini [new file with mode: 0644]
Toolkit/RotatingImages/libjs/fade.js [new file with mode: 0644]
Toolkit/RotatingImages/libjs/sortable.js [new file with mode: 0644]
Toolkit/RotatingImages/styles.css [new file with mode: 0644]
Toolkit/RotatingImages/templates/compiled/.cvsignore [new file with mode: 0644]
Toolkit/RotatingImages/templates/compiled/.keepme [new file with mode: 0644]
Toolkit/RotatingImages/templates/currentTables/Element.tpl [new file with mode: 0755]
Toolkit/RotatingImages/templates/currentTables/Form.tpl [new file with mode: 0755]
Toolkit/RotatingImages/templates/currentTables/Group.tpl [new file with mode: 0755]
Toolkit/RotatingImages/templates/currentTables/GroupElement.tpl [new file with mode: 0755]
Toolkit/RotatingImages/templates/currentTables/Header.tpl [new file with mode: 0755]
Toolkit/RotatingImages/templates/currentTables/RequiredNote.tpl [new file with mode: 0755]
Toolkit/RotatingImages/templates/imagesDataGrid.html [new file with mode: 0644]
Toolkit/RotatingImages/templates/instructions.html [new file with mode: 0644]

diff --git a/Toolkit/RotatingImages/ActiveImagesDataGrid.php b/Toolkit/RotatingImages/ActiveImagesDataGrid.php
new file mode 100644 (file)
index 0000000..aaddf57
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+class Toolkit_RotatingImages_ActiveImagesDataGrid
+       extends Toolkit_RotatingImages_ImagesDataGrid
+       implements Toolkit_RotatingImages_IImagesDataGrid
+{
+       //      {{{     setControlObject()
+
+       protected function setControlObject()
+       {
+               $this->ctrlObj['tableId'] = 'active';
+//             $this->ctrlObj['noRecMessage'] = 'No Active Images';
+               $this->ctrlObj['gridName'] = 'Active Images';
+       }
+
+       //      }}}
+       //      {{{     setQuery()
+
+       public function setQuery()
+       {
+               $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE active = true";
+
+               parent::setQuery($sql);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/Anchor.php b/Toolkit/RotatingImages/Anchor.php
new file mode 100644 (file)
index 0000000..11353d6
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+require_once 'Image.php';
+
+class Toolkit_RotatingImages_Anchor extends Toolkit_RotatingImages_Image
+{
+       //      {{{     properties
+
+       protected $href;
+       protected $external;
+
+       //      }}}
+       //      {{{     __construct()
+
+       public function __construct(
+               $active,
+               $href,
+               $external,
+               $src,
+               $alt = null,
+               $title = null,
+               $id = null
+       ) {
+               $this->active   = $active;
+               //      anchor attributes
+               $this->href     = $href;
+               $this->external = $external;
+
+               //      image attributes
+               $this->src   = $src;
+               $this->alt   = $alt;
+               $this->title = $title;
+
+               $this->id     = $id;
+       }
+
+       //      }}}
+       //      {{{     find()
+
+       public static function find(PDO $dbh, $id)
+       {
+               if (!ctype_digit((string) $id)) {
+                       throw new Exception(
+                               '$id must be an integer.'
+                       );
+               }
+
+               $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE id = :id";
+
+               try {
+                       $stmt = $dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                       return new self(
+                               $row['active'],
+                               $row['url'],
+                               $row['external'],
+                               $row['image'],
+                               null,
+                               null,
+                               $id
+                       );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{     getHref()
+
+       public function getHref()
+       {
+               return $this->href;
+       }
+
+       //      }}}
+       //      {{{     setHref()
+
+       public function setHref($href)
+       {
+               $this->href = $href;
+       }
+
+       //      }}}
+       //      {{{     getTarget()
+
+       public function getTarget()
+       {
+               return $this->external ? '_blank' : '_self';
+       }
+
+       //      }}}
+       //      {{{     getExternal()
+
+       public function getExternal()
+       {
+               return $this->external;
+       }
+
+       //      }}}
+       //      {{{     setExternal()
+
+       public function setExternal($external)
+       {
+               $this->external = $external;
+       }
+
+       //      }}}
+
+       //      {{{     insert()
+       public function insert(PDO $dbh)
+       {
+               $sql = "SELECT InsertAnchor(:image, :active, :url, :external)";
+               $stmt = $dbh->prepare($sql);
+               $stmt->bindParam(':image', $this->src, PDO::PARAM_STR);
+               $stmt->bindParam(':active', $this->active, PDO::PARAM_BOOL);
+               $stmt->bindParam(':url', $this->href, PDO::PARAM_BOOL);
+               $stmt->bindParam(':external', $this->external, PDO::PARAM_BOOL);
+               return $stmt->execute();
+       }
+
+       //      }}}
+       //      {{{     update()
+       public function update(PDO $dbh)
+       {
+               $sql = "
+            UPDATE rotating_images
+                          SET image = :image,
+                              active = :active,
+                              url = :href,
+                              external = :external
+                        WHERE id = :id";
+
+               $stmt = $dbh->prepare($sql);
+               $stmt->bindParam(':image', $this->src, PDO::PARAM_STR);
+               $stmt->bindParam(':active', $this->active, PDO::PARAM_BOOL);
+               $stmt->bindParam(':href', $this->href, PDO::PARAM_BOOL);
+               $stmt->bindParam(':external', $this->external, PDO::PARAM_BOOL);
+               $stmt->bindParam(':id', $this->id, PDO::PARAM_INT);
+               return $stmt->execute();
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/AnchorDecorator.php b/Toolkit/RotatingImages/AnchorDecorator.php
new file mode 100644 (file)
index 0000000..64a5cc6
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * Decorator for horizontal banners
+ *
+ * PHP version 5
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages_
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: AnchorDecorator.php,v 1.1.1.1 2010/01/08 14:36:10 jamie Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Decorator for horizontal banners
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @link      <>
+ */
+class Toolkit_RotatingImages_AnchorDecorator
+       extends Toolkit_RotatingImages_Decorator
+{
+       //  {{{ __construct()
+
+
+    /**
+     * constructor
+     *
+     * create a shallow copy of the node passed in so we can manipulate
+        * it all we want and not worry about affecting the original object
+     *
+     * @param Toolkit_RotatingImages_Anchor $node node to be decorated
+        *
+     * @return void
+     * @access protected
+     */
+       public function __construct(Toolkit_RotatingImages_Anchor $node)
+       {
+               //      Clone the node object so we keep original properties the same
+               $copiedNode = clone $node;
+
+               $this->node = $copiedNode;
+       }
+
+       //  }}}
+    //  {{{ toHtml()
+
+
+    /**
+     * Convert the anchor to a HTML string
+     *
+     * @param Toolkit_Image_Server $is Image server
+     *
+     * @return string HTML output of the anchor
+     * @access public
+     */
+       public function toHtml(Toolkit_Image_Server $is)
+       {
+               $properties
+                       = $is->getImageSize(ROTATING_IMAGE_RESIZED . $this->node->getSrc());
+
+               $imgFormat = '<img alt="%s" title="%s" width="%s" height="%s" src="%s">';
+               $anchorSource = sprintf(
+                       $imgFormat,
+                       $this->node->getAlt(),
+                       $this->node->getTitle(),
+                       $properties[0],
+                       $properties[1],
+                       ROTATING_IMAGE_RESIZED . $this->node->getSrc()
+               );
+
+               $anchorFormat = '<a href="%s" target="%s">%s</a>';
+               return sprintf(
+                       $anchorFormat,
+                       $this->node->getHref(),
+            $this->node->getTarget(),
+                       $anchorSource
+               );
+       }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/Database/application.sql b/Toolkit/RotatingImages/Database/application.sql
new file mode 100644 (file)
index 0000000..202b0fa
--- /dev/null
@@ -0,0 +1,15 @@
+--
+-- Tables
+--
+\i ./tables/rotating_images.sql
+\i ./tables/rotating_images_transitions.sql
+
+--
+-- Procedures
+--
+\i ./procedures/insertImage.sql
+\i ./procedures/insertAnchor.sql
+
+--
+-- Modules
+--
diff --git a/Toolkit/RotatingImages/Database/procedures/insertAnchor.sql b/Toolkit/RotatingImages/Database/procedures/insertAnchor.sql
new file mode 100644 (file)
index 0000000..7bd59db
--- /dev/null
@@ -0,0 +1,32 @@
+--DROP LANGUALGE plpgsql;
+CREATE LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION InsertAnchor(IN new_image TEXT, IN new_active BOOLEAN, IN new_url TEXT, IN new_external BOOLEAN) RETURNS TEXT AS $$
+       DECLARE
+               new_pos INTEGER;
+       BEGIN
+               SELECT (max(pos) + 1) INTO new_pos
+                 FROM rotating_images
+                WHERE active = true;
+                
+               -- make sure we have a pos to set
+               IF new_pos > 0 THEN
+                       -- do nothing
+               ELSE
+                       new_pos := 1;
+               END IF;
+
+               IF new_active THEN
+                       INSERT INTO rotating_images (image, active, url, external, pos)
+                       VALUES (new_image, new_active, new_url, new_external, new_pos);
+
+                       RETURN 'created active anchor ' || $1::TEXT;
+               ELSE
+                       INSERT INTO rotating_images (image, active, url, external, pos)
+                       VALUES (new_image, new_active, new_url, new_external, NULL);
+
+                       RETURN 'created disabled anchor ' || $1::TEXT;
+               END IF;
+       END;
+$$
+LANGUAGE plpgsql;
diff --git a/Toolkit/RotatingImages/Database/procedures/insertImage.sql b/Toolkit/RotatingImages/Database/procedures/insertImage.sql
new file mode 100644 (file)
index 0000000..d8aff46
--- /dev/null
@@ -0,0 +1,32 @@
+--DROP LANGUALGE plpgsql;
+CREATE LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION InsertImage (IN new_image TEXT, IN new_active BOOLEAN) RETURNS TEXT AS $$
+       DECLARE
+               new_pos INTEGER;
+       BEGIN
+               SELECT (max(pos) + 1) INTO new_pos
+                 FROM rotating_images
+                WHERE active = true;
+                
+               -- make sure we have a pos to set
+               IF new_pos > 0 THEN
+                       -- do nothing
+               ELSE
+                       new_pos := 1;
+               END IF;
+
+               IF new_active THEN
+                       INSERT INTO rotating_images (image, active, pos)
+                       VALUES (new_image, new_active, new_pos);
+
+                       RETURN 'created active image ' || $1::TEXT;
+               ELSE
+                       INSERT INTO rotating_images (image, active, pos)
+                       VALUES (new_image, new_active, NULL);
+
+                       RETURN 'created disabled image ' || $1::TEXT;
+               END IF;
+       END;
+$$
+LANGUAGE plpgsql;
diff --git a/Toolkit/RotatingImages/Database/tables/rotating_images.sql b/Toolkit/RotatingImages/Database/tables/rotating_images.sql
new file mode 100644 (file)
index 0000000..f1d6766
--- /dev/null
@@ -0,0 +1,11 @@
+CREATE TABLE rotating_images
+(id SERIAL,
+ image TEXT NOT NULL UNIQUE,
+ url TEXT,
+ external BOOLEAN NOT NULL DEFAULT FALSE,
+ active BOOLEAN NOT NULL DEFAULT FALSE,
+ pos INTEGER UNIQUE,
+ PRIMARY KEY (id));
+
+GRANT ALL ON rotating_images_id_seq TO nobody;
+GRANT ALL ON rotating_images TO nobody;
diff --git a/Toolkit/RotatingImages/Database/tables/rotating_images_transitions.sql b/Toolkit/RotatingImages/Database/tables/rotating_images_transitions.sql
new file mode 100644 (file)
index 0000000..3813a26
--- /dev/null
@@ -0,0 +1,7 @@
+CREATE TABLE rotating_images_transitions
+(timeout INTEGER NOT NULL DEFAULT 10,
+ transition TEXT NOT NULL DEFAULT 'fade');
+
+INSERT INTO rotating_images_transitions VALUES (10, 'fade');
+
+GRANT ALL ON rotating_images_transitions TO nobody;
diff --git a/Toolkit/RotatingImages/Decorator.php b/Toolkit/RotatingImages/Decorator.php
new file mode 100644 (file)
index 0000000..29ebdad
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * Base class for decorators
+ *
+ * PHP version 5
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: Decorator.php,v 1.1.1.1 2010/01/08 14:36:10 jamie Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Base class for decorators
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @link      <>
+ */
+abstract class Toolkit_RotatingImages_Decorator
+{
+       //  {{{ properties
+
+
+    /**
+     * Image object that will be decorated
+     * @var Toolkit_RotatingImages_Image
+     * @access protected
+     */
+       protected $node;
+
+       //  }}}
+       //      {{{     getNode()
+
+    /**
+     * Get the node we are decorating
+     *
+     * @return Toolkit_RotatingImages_Node object
+     * @access public
+     */
+       public function getNode()
+       {
+               return $this->node;
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/EditImageForm.php b/Toolkit/RotatingImages/EditImageForm.php
new file mode 100644 (file)
index 0000000..16925b2
--- /dev/null
@@ -0,0 +1,509 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category RotatingImages
+ * @package  Toolkit_RotatingImages
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditImageForm.php,v 1.1.1.1 2010/01/08 14:36:10 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Rotating Images Application
+ *
+ * Manages the creation and editing form for manipulating images in the db.
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_RotatingImages_EditImageForm extends Toolkit_FormBuilder
+{
+    //  {{{ properties
+
+       /**
+        * 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">Image successfully updated.</div>';
+
+       /**
+        * 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.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $registeredRules = array(
+               array(
+                       'checkURI',
+                       'callback',
+                       'uri',
+                       'Validate'
+               )
+       );
+
+    //  }}}
+    //  {{{ __construct()
+
+       /**
+        * Constructor
+        *
+        * @param PDO    $pdo         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
+        */
+       public function __construct(
+        $formName,
+        $method = 'post',
+        $action = '',
+        $target = '',
+        $attributes = null,
+        $trackSubmit = false
+    ) {
+               parent::__construct(
+            $formName,
+            $method,
+            $action,
+            $target,
+            $attributes,
+            $trackSubmit
+        );
+
+               $this->template = BASE . 'Toolkit/RotatingImages/templates/currentTables/';
+       }
+
+    //  }}}
+
+    //  {{{ configureConstants()
+
+       /**
+        * Configure form constants
+        *
+        * @return void
+        * @access public
+        */
+    public function configureConstants()
+       {
+        $c = array();
+
+        //     If we are adding a new banner
+        if (!ctype_digit($_GET['id'])) {
+               $c['current_image_rmv'] = 'Image not yet uploaded';
+        }
+
+        //     If the form has been submitted and a new image was uploaded
+        $currImg = $this->getSubmitValue('image');
+        if ($this->isSubmitted() && !empty($currImg)) {
+               $img = '<img src="%s%s">';
+               $c['current_image_rmv'] = sprintf(
+                               $img,
+                               ROTATING_IMAGE_THUMB,
+                               $currImg
+                       );
+        }
+
+        $this->setupConstants($c);
+    }
+
+    //  }}}
+    //  {{{ configureDefaults()
+
+       /**
+        * Configure the initial default values for the form
+        *
+        * @param PDO $dbh Database handler
+        *
+     * @return void
+        * @access protected
+        */
+       public function configureDefaults(PDO $dbh)
+       {
+               if (ctype_digit($_GET['id'])) {
+            $node = Toolkit_RotatingImages_Anchor::find($dbh, $_GET['id']);
+            if ($node) {
+                $img = '<img src="%s%s">';
+                $d = array(
+                    'active' => (int) $node->getActive(),
+                    'image'=> $node->getSrc(),
+                    'current_image_rmv' => sprintf(
+                                               $img,
+                                               ROTATING_IMAGE_THUMB,
+                                               $node->getSrc()
+                                       ),
+                    'external' => (int) $node->getExternal(),
+                    'url' => $node->getHref(),
+                );
+            }
+               } else {
+                       $d = array(
+                               'external' => false,
+                       );
+               }
+
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+    //  {{{ configureElements()
+
+       /**
+        * Configure how the form elements should look
+        *
+     * @return void
+        * @access public
+        */
+       public function configureElements()
+       {
+        $e = array();
+
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'active',
+            'display' => 'Active',
+            'val' => array(0, 1)
+        );
+               $e[] = array(
+                'type' => 'hidden',
+                'req' => false,
+                'name' => 'image'
+        );
+               $e[] = array(
+            'type' => 'text',
+            'req' => false,
+            'name' => 'url',
+            'display' => 'URL',
+                       'opts' => array('class' => 'text')
+        );
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'external',
+            'display' => 'External Link',
+            'val' => array(0, 1)
+        );
+               $e[] = array(
+            'type' => 'file',
+            'req' => false,
+            'name' => 'file_rmv',
+            'display' => 'Image'
+        );
+               $e[] = array(
+                'type' => 'static',
+                'req' => false,
+                'name' => 'current_image_rmv',
+                'display' => 'Current Image'
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit_rmv',
+            'display' => 'Submit Image',
+            'opts' => array('id' => 'submit')
+        );
+        if (ctype_digit($_GET['id'])) {
+            $e[] = array(
+                'type' => 'submit',
+                'req' => false,
+                'name' => 'delete_rmv',
+                'display' => 'Delete Image',
+                'opts' => array('id' => 'delete')
+            );
+        }
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureFilters()
+
+       /**
+        * Configure how the form elements should act when being submitted
+        *
+     * @return void
+        * @access protected
+        */
+       public function configureFilters()
+       {
+        $f   = array();
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+        $f[] = array(
+            'element' => 'url',
+                       'filter' => array('Toolkit_Common', 'filterURI')
+        );
+
+               $this->setupFilters($f);
+       }
+
+       //      }}}
+       //      {{{     configureForm()
+
+       /**
+        * Configure a form so we can use it
+        *
+        * @return void
+        * @access public
+        */
+       public function configureForm(PDO $dbh)
+       {
+               $this->configureElements();
+               $this->configureFilters();
+               $this->configureRules();
+               $this->configureDefaults($dbh);
+               $this->configureConstants();
+       }
+
+       //      }}}
+       //      {{{     configureRules()
+
+       /**
+        * Configure how the form elements should act
+        *
+     * @return void
+        * @access public
+        */
+       public function configureRules()
+       {
+        $r = array();
+
+               $mimeTypes = array(
+                       'image/jpe',
+                       'image/jpeg',
+                       'image/jpg',
+                       'image/jfif',
+                       'image/pjpeg',
+                       'image/pjp',
+                       'image/gif',
+                       'image/png',
+               );
+
+               $r[] = array(
+                       'element'    => 'url',
+                       'message'    => 'ERROR: Invalid URL format (http, https only)',
+                       'type'       => 'checkURI',
+                       'format'     => array(
+                               'allowed_schemes' => array('http', 'https'),
+                               'strict' => true
+                       ),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+        $uploadedImage = $this->getSubmitValue('image');
+        if (empty($uploadedImage)) {
+                       $r[] = array(
+                'element' => 'file_rmv',
+                'message' => 'ERROR: Must upload an image!',
+                'type' => 'uploadedfile',
+                'format' => null,
+                'validation' => $this->validationType,
+                'reset' => false,
+                'force' => false
+            );
+               }
+               if (is_uploaded_file($_FILES['file_rmv']['tmp_name'])) {
+                       $r[] = array(
+                'element' => 'file_rmv',
+                'message' => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                'type' => 'mimetype',
+                'format' => $mimeTypes,
+                'validation' => $this->validationType,
+                'reset' => false,
+                'force' => false
+            );
+               }
+
+               $this->setupRules($r);
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+       /**
+        * Determine how the form should be handled (insert new data or update old)
+        *
+     * @param PDO   $dbh    Database handler
+     * @param array $values Submitted form values
+     *
+     * @return boolean Result of insert or update function
+        * @access protected
+        */
+       private function _processData(PDO $dbh, $values)
+       {
+               if (ctype_digit($_GET['id'])) {
+                       //      Editing a banner
+                       $node = Toolkit_RotatingImages_Anchor::find($dbh, $_GET['id']);
+                       $node->setActive((bool) $values['active']);
+                       $node->setSrc($values['image']);
+                       $node->setHref($values['url']);
+                       $node->setExternal($values['external']);
+
+                       return $node->update($dbh);
+               } else {
+                       //      Creating a new image
+                       $node = new Toolkit_RotatingImages_Anchor(
+                               $values['active'],
+                               $values['url'],
+                               $values['external'],
+                               $values['image']
+                       );
+
+                       return $node->insert($dbh);
+               }
+       }
+
+    //  }}}
+
+    //  {{{ sendImageToImageServer()
+
+    /**
+     * Send an image to the image server
+     *
+     * Sets the image name in the submit values, so when saving
+     * the image, we keep the image that was uploaded.
+     *
+     * Injects the thumbnail image of this uploaded image into
+     * the form, this way if validation fails, the thumbnail will
+     * be shown on the form so the user knows they don't have to
+     * re-upload the image.
+     *
+     * @param Toolkit_Image_Server $is          Image server
+     * @param string                      $file key of upload in $_FILES superarray
+     *
+     * @return void
+     * @access protected
+     */
+       protected function sendImageToImageServer(
+        Toolkit_Image_Server $is,
+        $file
+    ) {
+               $oldImage =& $this->getSubmitValue('image');
+               if (!empty($oldImage)) {
+                       $is->imageDelete($oldImage);
+               }
+
+               $imgTag = '<img src="%s%s">';
+               $name = $is->imageUpload($file);
+
+               $htmlImg = sprintf($imgTag, ROTATING_IMAGE_THUMB, $name);
+
+               $currImg =& $this->getElement('current_image_rmv');
+               $currImg->setValue($htmlImg);
+
+               $fileName =& $this->getElement('image');
+               $fileName->setValue($name);
+               $this->_submitValues['image'] = $name;
+       }
+
+    //  }}}
+       //      {{{     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 align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'submit_rmv');
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'delete_rmv');
+
+       }
+
+    //  @codeCoverageIgnoreEnd
+       //      }}}
+
+    //  {{{ toHtml()
+
+       /**
+        * Call the rendering function to get the form in a string
+        *
+        * @param PDO                              $dbh Database handler
+        * @param Toolkit_Image_Server $is  Image Server
+        *
+        * @return string $output The Form to be rendered or success msg.
+        * @access protected
+        */
+       public function toHtml(PDO $dbh, Toolkit_Image_Server $is)
+       {
+        //  Handle Deleting banner.
+        if (   $this->isSubmitted()
+            && ctype_digit($_GET['id'])
+        ) {
+            if ($this->getSubmitValue('delete_rmv')) {
+                $node = Toolkit_RotatingImages_Image::find(
+                    $dbh,
+                    $_GET['id']
+                );
+                if ($banner) {
+                    if ($banner->delete($dbh, $is, $_GET['id'])) {
+                        return 'Banner successfully deleted.';
+                    }
+                } else {
+                    //  the banner has already been deleted or doesn't exist.
+                    return "The banner has already been deleted or doesn't exists.";
+                }
+            }
+        }
+
+               $this->setupRenderers();
+               $uploadedNewImg = (   $this->isSubmitted()
+                                                  && is_uploaded_file($_FILES['file_rmv']['tmp_name'])
+               );
+               if ($uploadedNewImg) {
+                       $this->sendImageToImageServer($is, 'file_rmv');
+               }
+               if ($this->validate()) {
+                       $this->cleanForm();
+
+                       if ($this->_processData($dbh, $this->getSubmitValues())) {
+                               $this->freeze();
+                               $output = $this->successMsg;
+                       }
+               } else if ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/IDecoratorsIterator.php b/Toolkit/RotatingImages/IDecoratorsIterator.php
new file mode 100644 (file)
index 0000000..cdd5a48
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Decorators collection
+ *
+ * PHP version 5
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: IDecoratorsIterator.php,v 1.1.1.1 2010/01/08 14:36:10 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Decorators collection
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @link      <>
+ */
+interface Toolkit_RotatingImages_IDecoratorsIterator
+{
+
+    /**
+     * Add a new decorator to the collection
+     *
+     * @param Toolkit_RotatingImages_Decorator $d decorator
+        *
+        * @return void
+     * @access public
+     */
+       public function add(Toolkit_RotatingImages_Decorator $d);
+
+    /**
+     * Return an HTML version of the decorator
+     *
+     * @param Toolkit_Image_Server $is Image server
+        *
+        * @return html version of banners
+     * @access public
+     */
+       public function toHtml(Toolkit_Image_Server $is);
+}
+?>
diff --git a/Toolkit/RotatingImages/IImagesDataGrid.php b/Toolkit/RotatingImages/IImagesDataGrid.php
new file mode 100644 (file)
index 0000000..cddc09f
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+interface Toolkit_RotatingImages_IImagesDataGrid
+{
+    /**
+     * Set the query the datagrid will use.
+        *
+        * @return string HTML output
+     * @access public
+     */
+       public function setQuery();
+}
+?>
diff --git a/Toolkit/RotatingImages/Image.php b/Toolkit/RotatingImages/Image.php
new file mode 100644 (file)
index 0000000..a8eb874
--- /dev/null
@@ -0,0 +1,141 @@
+<?php
+require_once 'Node.php';
+
+class Toolkit_RotatingImages_Image extends Toolkit_RotatingImages_Node
+{
+       //      {{{ properties
+       protected $src;
+       protected $alt;
+       protected $title;
+
+       //      }}}
+       //      {{{ __construct()
+       public function __construct(
+               $active,
+               $src,
+               $alt = null,
+               $title = null,
+               $id = null
+       ) {
+               $this->active = (bool) $active;
+               $this->src    = $src;
+               $this->alt    = $alt;
+               $this->title  = $title;
+               $this->id     = $id;
+       }
+
+       //      }}}
+       //      {{{ getSrc()
+       public function getSrc()
+       {
+               return $this->src;
+       }
+
+       //      }}}
+       //      {{{ setSrc()
+       public function setSrc($src)
+       {
+               $this->src = $src;
+       }
+
+       //      }}}
+       //      {{{ getAlt()
+       public function getAlt()
+       {
+               return $this->alt;
+       }
+
+       //      }}}
+       //      {{{ getTitle()
+       public function getTitle()
+       {
+               return $this->title;
+       }
+
+       //      }}}
+       //      {{{ insert()
+       public function insert(PDO $dbh)
+       {
+               $sql = "SELECT InsertImage(:image, :active)";
+               $stmt = $dbh->prepare($sql);
+               $stmt->bindParam(':image', $this->src, PDO::PARAM_STR);
+               $stmt->bindParam(':active', $this->active, PDO::PARAM_BOOL);
+               return $stmt->execute();
+       }
+
+       //      }}}
+       //      {{{ update()
+       public function update(PDO $dbh)
+       {
+               $sql = "
+            UPDATE rotating_images
+               SET image = :image, active = :active
+                        WHERE id = :id";
+
+               try {
+                       $stmt = $dbh->prepare($sql);
+                       $stmt->bindParam(':image', $this->src, PDO::PARAM_STR);
+                       $stmt->bindParam(':active', $this->active, PDO::PARAM_BOOL);
+                       $stmt->bindParam(':id', $this->id, PDO::PARAM_INT);
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ find()
+       public static function find(PDO $dbh, $id)
+       {
+               if (!ctype_digit((string) $id)) {
+                       throw new Exception(
+                               '$id must be an integer.'
+                       );
+               }
+
+               $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE id = :id";
+
+               try {
+                       $stmt = $dbh->prepare($sql);
+                       $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+                       $stmt->execute();
+                       $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+                       return new self(
+                               $row['active'],
+                               $row['image'],
+                               null,
+                               null,
+                               $id
+                       );
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+       //      {{{ delete()
+       public function delete(PDO $dbh, Toolkit_Image_Server $is)
+       {
+               try {
+                       $is->imageDelete($this->src);
+
+                       $sql = "
+                               DELETE FROM rotating_images
+                                WHERE id = :id";
+
+                       $stmt = $dbh->prepare($sql);
+                       $stmt->bindParam(':id', $this->id, PDO::PARAM_INT);
+
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/ImageDecorator.php b/Toolkit/RotatingImages/ImageDecorator.php
new file mode 100644 (file)
index 0000000..d694477
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * Decorator for horizontal banners
+ *
+ * PHP version 5
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages_
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: ImageDecorator.php,v 1.1.1.1 2010/01/08 14:36:09 jamie Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Decorator for horizontal banners
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @link      <>
+ */
+class Toolkit_RotatingImages_ImageDecorator
+       extends Toolkit_RotatingImages_Decorator
+{
+       //  {{{ __construct()
+
+
+    /**
+     * constructor
+     *
+     * create a shallow copy of the node passed in so we can manipulate
+        * it all we want and not worry about affecting the original object
+     *
+     * @param Toolkit_RotatingImages_Node $node node to be decorated
+        *
+     * @return void
+     * @access protected
+     */
+       public function __construct(Toolkit_RotatingImages_Image $node)
+       {
+               //      Clone the node object so we keep original properties the same
+               $copiedNode = clone $node;
+
+               $this->node = $copiedNode;
+       }
+
+       //  }}}
+    //  {{{ toHtml()
+
+
+    /**
+     * Convert the image to a HTML string
+     *
+     * @param Toolkit_Image_Server $is Image server
+     *
+     * @return string HTML output of the image
+     * @access public
+     */
+       public function toHtml(Toolkit_Image_Server $is)
+       {
+               $properties
+                       = $is->getImageSize(ROTATING_IMAGE_RESIZED . $this->node->getSrc());
+
+               $format = '<img alt="%s" title="%s" width="%s" height="%s" src="%s">';
+               return sprintf(
+                       $format,
+                       $this->node->getAlt(),
+                       $this->node->getTitle(),
+                       $properties[0],
+                       $properties[1],
+                       ROTATING_IMAGE_RESIZED . $this->node->getSrc()
+               );
+       }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/ImageThumbnailDecorator.php b/Toolkit/RotatingImages/ImageThumbnailDecorator.php
new file mode 100644 (file)
index 0000000..5f2fd0b
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Decorator for horizontal banners
+ *
+ * PHP version 5
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages_
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: ImageThumbnailDecorator.php,v 1.1.1.1 2010/01/08 14:36:10 jamie Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Decorator for horizontal banners
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @link      <>
+ */
+class Toolkit_RotatingImages_ImageThumbnailDecorator
+       extends Toolkit_RotatingImages_Decorator
+{
+       //  {{{ __construct()
+
+
+    /**
+     * constructor
+     *
+     * create a shallow copy of the node passed in so we can manipulate
+        * it all we want and not worry about affecting the original object
+     *
+     * @param Toolkit_RotatingImages_Node $node node to be decorated
+        *
+     * @return void
+     * @access protected
+     */
+       public function __construct(Toolkit_RotatingImages_Image $node)
+       {
+               //      Clone the node object so we keep original properties the same
+               $copiedNode = clone $node;
+
+               $this->node = $copiedNode;
+       }
+
+       //  }}}
+    //  {{{ toHtml()
+
+
+    /**
+     * Convert the image to a HTML string
+     *
+     * @param Toolkit_Image_Server $is Image server
+     *
+     * @return string HTML output of the image
+     * @access public
+     */
+       public function toHtml(Toolkit_Image_Server $is)
+       {
+               $properties
+                       = $is->getImageSize(ROTATING_IMAGE_THUMB . $this->node->getSrc());
+
+               $format = '<img width="%s" height="%s" src="%s">';
+               return sprintf(
+                       $format,
+                       $properties[0],
+                       $properties[1],
+                       ROTATING_IMAGE_THUMB . $this->node->getSrc()
+               );
+       }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/ImagesDataGrid.php b/Toolkit/RotatingImages/ImagesDataGrid.php
new file mode 100644 (file)
index 0000000..78959d4
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+abstract class Toolkit_RotatingImages_ImagesDataGrid
+       extends Toolkit_FlexyDataGridBuilder
+{
+       //      {{{     properties
+
+       protected $noRecMessage = 'No Images';
+
+       //      }}}
+       //      {{{ configureColumns()
+
+       protected function configureColumns()
+       {
+               $id =& new Structures_DataGrid_Column(
+                       'ID',
+                       'id',
+                       'id'
+               );
+               $this->addColumn($id);
+
+               $delete =& new Structures_DataGrid_Column(
+                       'Delete',
+                       null,
+                       null,
+                       array('class' => 'delLink'),
+                       null,
+                       array(&$this, 'renderDeleteLink')
+               );
+               $this->addColumn($delete);
+
+               $edit =& new Structures_DataGrid_Column(
+                       'Edit',
+                       null,
+                       null,
+                       array('class' => 'editLink'),
+                       null,
+                       array(&$this, 'renderEditLink')
+               );
+               $this->addColumn($edit);
+
+               $url =& new Structures_DataGrid_Column(
+                       'URL',
+                       'url',
+                       'url'
+               );
+               $this->addColumn($url);
+
+               $image =& new Structures_DataGrid_Column(
+                       'Image',
+                       null,
+                       null,
+                       array('class' => 'image'),
+                       null,
+                       array(&$this, 'renderImage')
+               );
+               $this->addColumn($image);
+       }
+
+       //      }}}
+       //  {{{ renderEditLink()
+
+       /**
+        * Render the edit link for an image
+        *
+        * @param array $data DB record
+        *
+        * @return mixed  Link to edit a banner
+        * @access public
+        */
+       public function renderEditLink($data)
+       {
+               extract($data['record']);
+               $imgFormat = '<img src="%s" alt="Edit Image Icon" style="float: left; margin-right: 5px;"> Edit Image';
+               $img = sprintf(
+                       $imgFormat,
+                       GLM_APP_BASE_URL . 'assets/icons/image_edit.png'
+               );
+
+               $linkFormat = '<a href="%s?%s">%s</a>';
+               return sprintf(
+                       $linkFormat,
+                       BASE_URL . 'admin/rotatingImages.php',
+                       "action=edit&amp;id=$id",
+                       $img
+               );
+       }
+
+       //  }}}
+       //  {{{ renderDeleteLink()
+
+       /**
+        * Render the delete link for an image
+        *
+        * @param array $data DB record
+        *
+        * @return mixed  Link to edit a banner
+        * @access public
+        */
+       public function renderDeleteLink($data)
+       {
+               extract($data['record']);
+               $imgFormat = '<img src="%s" alt="Delete Image Icon" style="float: left; margin-right: 5px;"> Delete Image';
+               $img = sprintf(
+                       $imgFormat,
+                       GLM_APP_BASE_URL . 'assets/icons/image_delete.png'
+               );
+
+               $linkFormat = '<a href="%s?%s">%s</a>';
+               return sprintf(
+                       $linkFormat,
+                       BASE_URL . 'admin/rotatingImages.php',
+                       "action=del&amp;id=$id",
+                       $img);
+       }
+
+       //  }}}
+       //  {{{ renderImage()
+
+       /**
+        * Render the delete link for an image
+        *
+        * @param array $data DB record
+        *
+        * @return mixed  Link to edit a banner
+        * @access public
+        */
+       public function renderImage($data)
+       {
+               extract($data['record']);
+               $imgFormat = '<img class="thumbnail" src="%s" alt="Image thumbnail">';
+               return sprintf(
+                       $imgFormat,
+                       ROTATING_IMAGE_THUMB . $image
+               );
+       }
+
+       //  }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/InactiveImagesDataGrid.php b/Toolkit/RotatingImages/InactiveImagesDataGrid.php
new file mode 100644 (file)
index 0000000..a035cbe
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+class Toolkit_RotatingImages_InactiveImagesDataGrid
+       extends Toolkit_RotatingImages_ImagesDataGrid
+       implements Toolkit_RotatingImages_IImagesDataGrid
+{
+       //      {{{     setControlObject()
+
+       protected function setControlObject()
+       {
+               $this->ctrlObj['tableId'] = 'disabled';
+//             $this->ctrlObj['noRecMessage'] = 'No Disabled Images';
+               $this->ctrlObj['gridName'] = 'Disabled Images';
+       }
+
+       //      }}}
+       //      {{{     setQuery()
+
+       public function setQuery()
+       {
+               $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE active = false";
+
+               parent::setQuery($sql);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/LiveDecorator.php b/Toolkit/RotatingImages/LiveDecorator.php
new file mode 100644 (file)
index 0000000..f13956c
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * Collection of banner decorators to rotate
+ *
+ * PHP version 5
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: LiveDecorator.php,v 1.4 2010/01/25 20:22:04 jamie Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Collection of banner decorators to rotate
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @link      <>
+ */
+class Toolkit_RotatingImages_LiveDecorator
+       implements IteratorAggregate, Toolkit_RotatingImages_IDecoratorsIterator
+{
+       //      {{{     properties
+
+
+    /**
+     * Banner decorators
+     * @var    array
+     * @access private
+     */
+       private $_decorators;
+
+       private $_loaded = false;
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * constructor
+     *
+     * @return void
+     * @access protected
+     */
+       public function __construct()
+       {
+               $this->_decorators = array();
+       }
+
+       //      }}}
+    // {{{     getIterator()
+
+
+    /**
+     * Set the external iterator
+     *
+     * @return object An instance of an object implementing Iterator or Traversable
+     * @access public
+     */
+       public function getIterator()
+       {
+               return new ArrayIterator($this->_decorators);
+       }
+
+       //      }}}
+       //      {{{     getTotal()
+
+
+    /**
+     * Gets the total number of decorators we have added
+     *
+     * @return array  number of decorators in collection
+     * @access public
+     */
+       public function getTotal()
+       {
+               return count($this->_decorators);
+       }
+
+       //      }}}
+       //      {{{     add()
+
+
+       /**
+     * Adds a decorator to the collection
+     *
+     * @param Toolkit_RotatingImages_Decorator $d Decorator object
+     *
+     * @return void
+     * @access public
+     */
+       public function add(Toolkit_RotatingImages_Decorator $d)
+       {
+               $this->_decorators[] = $d;
+       }
+
+       //      }}}
+       //      {{{     toHtml()
+
+
+    /**
+     * Converts all decorator objects collection into an HTML string
+     *
+     * Adds the appropriate scripts to the page so we can use JS to
+     * rotate through the banners
+     *
+     * @param Toolkit_Image_Server $is Image Server
+     *
+     * @return string HTML version of the static banners available
+     * @access public
+     */
+       public function toHtml(Toolkit_Image_Server $is)
+       {
+               if (!$this->_loaded) {
+                       throw new LogicException(
+                               'call getRotatingJavascript() before accessing'
+                       );
+               }
+
+               $GLOBALS['scripts'][] = GLM_APP_BASE_URL . 'libjs/plugins/cycle/2.73/jquery.cycle.all.min.js';
+               $GLOBALS['scripts'][] = BASE_URL . 'Toolkit/RotatingImages/libjs/fade.js';
+               $GLOBALS['styleSheets'][] = BASE_URL . 'Toolkit/RotatingImages/styles.css';
+
+               $images = '';
+               foreach ($this->_decorators as $i) {
+                       switch (get_class($i)) {
+                       case 'Toolkit_RotatingImages_ImageThumbnailDecorator' :
+                       case 'Toolkit_RotatingImages_ImageDecorator' :
+                               $images .= $i->toHtml($is);
+                               break;
+
+                       case 'Toolkit_RotatingImages_AnchorDecorator' :
+                               $images .= $i->toHtml($is);
+                               break;
+
+                       default :
+                               break;
+                       }
+               }
+
+               if (!empty($images)) {
+                       $ret  = '<div id="rotatingImagesLive">';
+                       $ret .= "    <div id=\"images\">$images</div>";
+                       $ret .= '    <span id="if-prev">&lt; Prev</span> &#124; ';
+                       $ret .= '    <span id="if-next">Next &gt;</span>';
+                       $ret .= '</div>';
+
+                       return $ret;
+               } else {
+                       return '';
+               }
+       }
+
+       //      }}}
+
+       //      {{{     getRotatingJavascript()
+
+       public function getRotatingJavascript($dbh)
+       {
+               $this->_loaded = true;
+
+               try {
+                       $sql = "
+                SELECT *, timeout * 1000 AS jstimeout
+                  FROM rotating_images_transitions";
+                       $row = $dbh->query($sql, PDO::FETCH_ASSOC)->fetch();
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+
+               $js  = "<script type=\"text/javascript\">\n";
+               $js .= "$(document).ready(function() {\n";
+               $js .= "        $('#rotatingImagesLive #images').cycle({\n";
+               $js .= "                timeout: {$row['jstimeout']},\n";
+               $js .= "                height: '300px',\n";
+               $js .= "                fx: '{$row['transition']}',\n";
+               $js .= "                prev: '#if-prev',\n";
+               $js .= "                next: '#if-next'\n";
+               $js .= "        });\n";
+               $js .= "});\n";
+               $js .= "</script>";
+
+               return $js;
+       }
+
+       //      }}}
+}
diff --git a/Toolkit/RotatingImages/Node.php b/Toolkit/RotatingImages/Node.php
new file mode 100644 (file)
index 0000000..4b9f1e6
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+abstract class Toolkit_RotatingImages_Node
+{
+       //      {{{     properties
+
+       protected $id;
+       protected $active;
+
+       //      }}}
+       //      {{{ setActive()
+       public function setActive($active)
+       {
+               if (!is_bool($active)) {
+                       throw InvalidArgumentException(
+                               '$active must be a boolean.'
+                       );
+               }
+
+               $this->active = $active;
+       }
+
+       //      }}}
+       //      {{{ getActive()
+
+       public function getActive()
+       {
+               return $this->active;
+       }
+
+       //      }}}
+       //      {{{ getId()
+
+       public function getId()
+       {
+               return $this->id;
+       }
+
+       //      }}}
+       //      {{{ insert()
+       abstract public function insert(PDO $dbh);
+       //      }}}
+       //      {{{ update()
+       abstract public function update(PDO $dbh);
+       //      }}}
+       //      {{{ find()
+       abstract public static function find(PDO $dbh, $id);
+       //      }}}
+       //      {{{ delete()
+       abstract public function delete(PDO $dbh, Toolkit_Image_Server $is);
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/NodesIterator.php b/Toolkit/RotatingImages/NodesIterator.php
new file mode 100644 (file)
index 0000000..291542c
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+class Toolkit_RotatingImages_NodesIterator implements IteratorAggregate
+{
+       private $_nodes;
+
+       public function __construct()
+       {
+               $this->_nodes = array();
+       }
+
+       public function getIterator()
+       {
+               return new ArrayIterator($this->_nodes);
+       }
+
+       public function addImage(Toolkit_RotatingImages_Node $node)
+       {
+               $this->_nodes[] = $node;
+       }
+
+       public function getNode($key)
+       {
+               if (!count($this->_nodes)) {
+                       return false;
+               }
+
+               if (!ctype_digit((string)$key)) {
+                       throw new InvalidArgumentException(
+                               '$key must be an integer.'
+                       );
+               }
+
+               return $this->_nodes[$key];
+       }
+
+       public function getTotal()
+       {
+               return count($this->_nodes);
+       }
+
+       public function findAll(PDO $dbh)
+       {
+               $this->_nodes = array();
+
+               try {
+                       $sql = "
+                SELECT *
+                  FROM rotating_images
+                 ORDER BY active DESC, pos, id";
+
+                       foreach ($dbh->query($sql) as $row) {
+                               if (!empty($row['url'])) {
+                                       $this->_nodes[]
+                                               = Toolkit_RotatingImages_Anchor::find($dbh, $row['id']);
+                               } else {
+                                       $this->_nodes[]
+                                               = Toolkit_RotatingImages_Image::find($dbh, $row['id']);
+                               }
+                       }
+               } catch (PDOException $e) {
+                       return Toolkit_Common::handleError($e);
+               }
+       }
+}
+?>
diff --git a/Toolkit/RotatingImages/PreviewDecorator.php b/Toolkit/RotatingImages/PreviewDecorator.php
new file mode 100644 (file)
index 0000000..e8d0e38
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * Collection of banner decorators to rotate
+ *
+ * PHP version 5
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: PreviewDecorator.php,v 1.3 2010/01/25 20:22:04 jamie Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Collection of banner decorators to rotate
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2009 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @link      <>
+ */
+class Toolkit_RotatingImages_PreviewDecorator
+       implements IteratorAggregate, Toolkit_RotatingImages_IDecoratorsIterator
+{
+       //      {{{     properties
+
+
+    /**
+     * Banner decorators
+     * @var    array
+     * @access private
+     */
+       private $_decorators;
+
+       //      }}}
+       //      {{{     __construct()
+
+    /**
+     * constructor
+     *
+     * @return void
+     * @access protected
+     */
+       public function __construct()
+       {
+               $this->_decorators = array();
+       }
+
+       //      }}}
+    // {{{     getIterator()
+
+
+    /**
+     * Set the external iterator
+     *
+     * @return object An instance of an object implementing Iterator or Traversable
+     * @access public
+     */
+       public function getIterator()
+       {
+               return new ArrayIterator($this->_decorators);
+       }
+
+       //      }}}
+       //      {{{     getTotal()
+
+
+    /**
+     * Gets the total number of decorators we have added
+     *
+     * @return array  number of decorators in collection
+     * @access public
+     */
+       public function getTotal()
+       {
+               return count($this->_decorators);
+       }
+
+       //      }}}
+       //      {{{     add()
+
+
+       /**
+     * Adds a decorator to the collection
+     *
+     * @param Toolkit_RotatingImages_Decorator $d Decorator object
+     *
+     * @return void
+     * @access public
+     */
+       public function add(Toolkit_RotatingImages_Decorator $d)
+       {
+               $this->_decorators[] = $d;
+       }
+
+       //      }}}
+       //      {{{     toHtml()
+
+
+    /**
+     * Converts all decorator objects collection into an HTML string
+     *
+     * Adds the appropriate scripts to the page so we can use JS to
+     * rotate through the banners
+     *
+     * @param Toolkit_Image_Server $is Image Server
+     *
+     * @return string HTML version of the static banners available
+     * @access public
+     */
+       public function toHtml(Toolkit_Image_Server $is)
+       {
+               $GLOBALS['scripts'][] = GLM_APP_BASE_URL . 'libjs/plugins/cycle/2.73/jquery.cycle.all.min.js';
+               $GLOBALS['scripts'][] = BASE_URL . 'Toolkit/RotatingImages/libjs/fade.js';
+
+               foreach ($this->_decorators as $i) {
+                       switch (get_class($i)) {
+                       case 'Toolkit_RotatingImages_ImageThumbnailDecorator' :
+                       case 'Toolkit_RotatingImages_ImageDecorator' :
+                               $images .= $i->toHtml($is);
+                               break;
+
+                       case 'Toolkit_RotatingImages_AnchorDecorator' :
+                               $images .= $i->toHtml($is);
+                               break;
+
+                       default :
+                               break;
+                       }
+               }
+
+               return "<div id=\"rotatingImagesPreview\">$images</div>\n";
+       }
+
+       //      }}}
+}
diff --git a/Toolkit/RotatingImages/TransitionPreview.php b/Toolkit/RotatingImages/TransitionPreview.php
new file mode 100644 (file)
index 0000000..3df93a6
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+class Toolkit_RotatingImages_TransitionPreview
+{
+       public function __construct()
+       {
+       }
+
+       //      {{{     getPreview()
+
+       public function getPreview(PDO $dbh)
+       {
+               try {
+                       $sql = "
+                               SELECT *
+                                 FROM rotating_images
+                                WHERE active = true";
+
+                       $images = $dbh->query($sql, PDO::FETCH_ASSOC)->fetchAll();
+               } catch (PDOException $e) {
+                       Toolkit_Common::handleError($e);
+               }
+
+               $is = new Toolkit_Image_Server();
+               $fadingDecorator = new Toolkit_RotatingImages_PreviewDecorator();
+               foreach ($images as $v) {
+                       $image = new Toolkit_RotatingImages_Image(
+                               $v['active'],
+                               $v['image']
+                       );
+                       $thumbnailDecorator
+                               = new Toolkit_RotatingImages_ImageThumbnailDecorator($image);
+
+                       $fadingDecorator->add($thumbnailDecorator);
+               }
+
+               return $fadingDecorator->toHtml($is);
+       }
+
+       //      }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/TransitionSettingsForm.php b/Toolkit/RotatingImages/TransitionSettingsForm.php
new file mode 100644 (file)
index 0000000..0cd49c8
--- /dev/null
@@ -0,0 +1,245 @@
+<?php
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * File Doc Comment
+ *
+ * PHP version 5
+ *
+ * @category RotatingImages
+ * @package  Toolkit_RotatingImages
+ * @author   Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: TransitionSettingsForm.php,v 1.3 2010/01/25 20:22:04 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Rotating Images Application
+ *
+ * Manages the creation and editing form for manipulating banners in the db.
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie.kahgee@gmail.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_RotatingImages_TransitionSettingsForm
+       extends Toolkit_FormBuilder
+{
+    //  {{{ properties
+
+       /**
+        * 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">Settings successfully updated.</div>';
+
+       /**
+        * 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.
+        *
+        * @var string
+        * @access protected
+        */
+       protected $registeredRules = array();
+
+    //  }}}
+
+    //  {{{ configureDefaults()
+
+       /**
+        * Configure the initial default values for the form
+        *
+        * @param PDO $dbh Database handler
+        *
+     * @return void
+        * @access protected
+        */
+       public function configureDefaults(PDO $dbh)
+       {
+               $sql = "
+                       SELECT *
+                         FROM rotating_images_transitions";
+
+               $d = $dbh->query($sql, PDO::FETCH_ASSOC)->fetch();
+
+               $this->setupDefaults($d);
+       }
+
+       //      }}}
+    //  {{{ configureElements()
+
+       /**
+        * Configure how the form elements should look
+        *
+     * @param PDO              $dbh Database handler
+     * @param Config_Container $c   Configuration object
+     *
+     * @return void
+        * @access public
+        */
+       public function configureElements(PDO $dbh, Config_Container $c)
+       {
+        $e = array();
+
+        $rotationTime =& $c->getItem('section', 'rotation time')
+                       ->getItem('directive', 'timeout')
+                       ->getContent();
+               $timeout = array_combine(
+                       array_values($rotationTime),
+                       array_values($rotationTime)
+               );
+               $timeout = array_change_key_case($timeout);
+
+        $animationType =& $c->getItem('section', 'animation type')
+                       ->getItem('directive', 'transition')
+                       ->getContent();
+               $transition = array_combine(
+                       array_values($animationType),
+                       array_values($animationType)
+               );
+//             $transition = array_change_key_case($transition);
+
+               //      All Grouped Elements are created here.
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'select',
+            'req' => false,
+            'name' => 'timeout',
+            'display' => 'Seconds between transition',
+            'opts' => array('' => '-- Select --') + $timeout,
+                       'att' => array('id' => 'timeout')
+        );
+        $e[] = array(
+               'type' => 'select',
+               'req' => false,
+               'name' => 'transition',
+               'display' => 'Transition effect',
+                       'opts' => array('' => '-- Select --') + $transition,
+                       'att' => array('id' => 'transition')
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit',
+            'display' => 'Apply Transition',
+            'opts' => array('id' => 'submit')
+        );
+
+               $this->setupElements($e);
+       }
+
+       //      }}}
+       //      {{{     configureForm()
+
+       /**
+        * Configure a form so we can use it
+        *
+        * @param PDO              $pdo Database handler
+        * @param Config_Container $c   Application configuration settings
+        *
+        * @return void
+        * @access public
+        */
+       public function configureForm(PDO $pdo, Config_Container $c)
+       {
+               $this->configureElements($pdo, $c);
+               $this->configureDefaults($pdo);
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+       /**
+        * Update transition values
+        *
+     * @param PDO $dbh Database handler
+     *
+     * @return boolean Result of update
+        * @access protected
+        */
+       private function _processData(PDO $dbh)
+       {
+               try {
+                       $sql = "
+                UPDATE rotating_images_transitions
+                                  SET timeout = :timeout,
+                                      transition = :transition";
+
+                       $stmt = $dbh->prepare($sql);
+                       $stmt->bindParam(
+                               ':timeout',
+                               $this->_submitValues['timeout'],
+                               PDO::PARAM_INT
+                       );
+                       $stmt->bindParam(
+                               ':transition',
+                               $this->_submitValues['transition'],
+                               PDO::PARAM_INT
+                       );
+
+                       return $stmt->execute();
+               } catch (PDOException $e) {
+                       return 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();
+               $renderer->setFormTemplate('<div class="webform"><form{attributes}><table id="transition-settings">{content}</table></form></div>');
+               $renderer->setElementTemplate('<tr align="center"><td colspan="2">'.$required.'{label}'.$error.'{element}</td></tr>', 'submit');
+       }
+
+    //  @codeCoverageIgnoreEnd
+       //      }}}
+
+    //  {{{ toHtml()
+
+       /**
+        * Call the rendering function to get the form in a string
+        *
+        * @return string $output The Form to be rendered or success msg.
+        * @access protected
+        */
+       public function toHtml(PDO $pdo)
+       {
+               $GLOBALS['styleSheets'][] = BASE_URL . 'form.css';
+
+               $this->setupRenderers();
+               $output = '';
+               if ($this->validate()) {
+                       if ($this->_processData($pdo)) {
+                               $output = $this->successMsg;
+                       }
+               }
+               $output .= parent::toHTML();
+
+               return $output;
+       }
+
+    //  }}}
+}
+?>
diff --git a/Toolkit/RotatingImages/ajax.php b/Toolkit/RotatingImages/ajax.php
new file mode 100644 (file)
index 0000000..9164e62
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+if (   !isset($_POST['action'])
+       || $_POST['action'] != 'updateOrder'
+) {
+       return false;
+}
+
+require_once '../../setup.phtml';
+
+$dbh = Toolkit_Database::getInstance();
+
+try {
+       $dbh->beginTransaction();
+       $sql = "
+               UPDATE rotating_images
+                  SET active = false, pos = null";
+
+       $dbh->query($sql);
+
+       $sql = "
+               UPDATE rotating_images
+                  SET active = true, pos = :pos
+                WHERE id = :id";
+       $stmt = $dbh->prepare($sql);
+       $i = 1;
+       foreach ($_POST['image'] as $v) {
+               $stmt->bindParam(':pos', $i, PDO::PARAM_INT);
+               $stmt->bindParam(':id', $v, PDO::PARAM_INT);
+               $stmt->execute();
+               ++$i;
+       }
+       return $dbh->commit();
+} catch (PDOException $e) {
+       $dbh->rollback();
+       return Toolkit_Common::handleError($e);
+}
+?>
diff --git a/Toolkit/RotatingImages/assets/.keepme b/Toolkit/RotatingImages/assets/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Toolkit/RotatingImages/config.ini b/Toolkit/RotatingImages/config.ini
new file mode 100644 (file)
index 0000000..b267c90
--- /dev/null
@@ -0,0 +1,44 @@
+[conf]
+; Application Name
+applicationName = "Rotating Images"
+
+; time between the fades in milliseconds
+[rotation time]
+timeout[] = 1
+timeout[] = 2
+timeout[] = 3
+timeout[] = 4
+timeout[] = 5
+timeout[] = 10
+timeout[] = 15
+timeout[] = 20
+timeout[] = 25
+timeout[] = 30
+
+; type of animation 'fade' or 'slide'
+[animation type]
+transition[] = "blindX"
+transition[] = "blindY"
+transition[] = "blindZ"
+transition[] = "cover"
+transition[] = "curtainX"
+transition[] = "curtainY"
+transition[] = "fade"
+transition[] = "fadeZoom"
+transition[] = "growX"
+transition[] = "growY"
+transition[] = "scrollUp"
+transition[] = "scrollDown"
+transition[] = "scrollLeft"
+transition[] = "scrollRight"
+transition[] = "scrollHorz"
+transition[] = "scrollVert"
+transition[] = "slideX"
+transition[] = "slideY"
+transition[] = "turnUp"
+transition[] = "turnDown"
+transition[] = "turnLeft"
+transition[] = "turnRight"
+transition[] = "uncover"
+transition[] = "wipe"
+transition[] = "zoom"
diff --git a/Toolkit/RotatingImages/libjs/fade.js b/Toolkit/RotatingImages/libjs/fade.js
new file mode 100644 (file)
index 0000000..7e06993
--- /dev/null
@@ -0,0 +1,53 @@
+var fade =
+{
+       timeout: null,
+       animationtype: null,
+       container: '#rotatingImagesPreview',
+       height: '75px',
+
+       init: function()
+       {
+               setTimeout(function() {
+                       $('#form-success-top').fadeOut('slow');
+               }, 4000);
+
+               //      Get the dom nodes
+               fade.timeout = $('#timeout');
+               fade.animationtype = $('#transition');
+
+               $('#submit').attr("disabled", "disabled");
+
+               //      Bind events
+               fade.timeout
+                       .change(fade.update)
+                       .change(fade.activateSubmit);
+               fade.animationtype
+                       .change(fade.update)
+                       .change(fade.activateSubmit);
+
+               //      Start the innerfade
+               $(fade.container).cycle({
+                       timeout: fade.timeout.val() * 1000,
+                       fx: fade.animationtype.val(),
+                       height: fade.height
+               });
+       },
+
+       activateSubmit: function()
+       {
+               $('#submit').removeAttr('disabled');
+       },
+
+       update: function()
+       {
+               $(fade.container).cycle('stop');
+               //      reassign the cycle with new settings.
+               $(fade.container).cycle({
+                       timeout: fade.timeout.val() * 1000,
+                       fx: fade.animationtype.val(),
+                       height: fade.height
+               });
+       }
+};
+
+$(document).ready(fade.init);
diff --git a/Toolkit/RotatingImages/libjs/sortable.js b/Toolkit/RotatingImages/libjs/sortable.js
new file mode 100644 (file)
index 0000000..9adfd46
--- /dev/null
@@ -0,0 +1,52 @@
+var RISortable =
+{
+       init: function()
+       {
+               $('#active, #disabled').sortable({
+                       connectWith: 'ul',
+                       revert: true,
+                       cancel: '.ui-state-disabled',
+                       distance: 15,
+                       forcePlaceholderSize: true,
+                       placeholder: 'ui-state-highlight',
+                       cursor: 'move',
+                       receive: RISortable.receive,
+                       remove: RISortable.remove,
+                       stop: RISortable.stop,
+                       opacity: 0.6
+               });
+               $('.dataGrid').disableSelection();
+       },
+
+       receive: function(event, ui)
+       {
+               if ($(this).children('.ui-state-disabled').is('li')) {
+                       $(this).children('.ui-state-disabled').remove();
+               }
+       },
+
+       remove: function(event, ui)
+       {
+               if ($(this).children().length == 0) {
+                       $(this).html('<li class="ui-state-disabled ui-state-default">Drag image here to add</li>');
+               }
+       },
+
+       stop: function(event, ui)
+       {
+               var order = $('#active').sortable('serialize');
+
+               $.post('../Toolkit/RotatingImages/ajax.php', order+'&action=updateOrder');
+
+               $(fade.container).empty();
+               $('#active img.thumbnail').each(function() {
+                       var copy = $(this).clone();
+                       copy.removeAttr('class')
+                               .removeAttr('alt');
+                       copy.appendTo(fade.container);
+               });
+               fade.update();
+       }
+};
+
+$(document).ready(RISortable.init);
diff --git a/Toolkit/RotatingImages/styles.css b/Toolkit/RotatingImages/styles.css
new file mode 100644 (file)
index 0000000..fa468ea
--- /dev/null
@@ -0,0 +1,106 @@
+ul.dataGrid {
+       list-style-type: none;
+       margin: 0;
+       padding: 0;
+}
+ul.dataGrid li {
+       margin: 0 5px 5px 5px;
+       padding: 5px;
+}
+.ui-state-default {
+       width: 500px;
+       height: 120px;
+       clear: left;
+       -moz-border-radius: 10px;
+       -webkit-border-radius: 10px;
+       border-radius: 10px;
+       padding: 10px !important;
+       border: 1px solid #999 !important       }
+h2 {
+       clear: left;
+}
+.thumbnail {
+       float: left;
+       -webkit-box-shadow: 2px 2px 5px #ccc;
+       -moz-box-shadow: 2px 2px 5px #ccc;
+}
+.ui-state-default {
+       }
+.info {
+       border: 1px solid #ccc;
+       -moz-border-radius: 10px;
+       -webkit-border-radius: 10px;
+       border-radius: 10px;
+       -moz-box-shadow: 2px 2px 5px #ccc;
+       -webkit-box-shadow: 2px 2px 5px #ccc;
+       background: #eee;
+
+       margin: 0 10px;
+       float: right;
+       width: 250px;
+       padding: 10px;
+       height: 80px;
+}
+.info img {
+       border: 0;
+}
+.info a {
+       text-decoration: underline !important;
+}
+.info a:hover {
+       color: black;
+       font-weight: bold;
+       text-decoration: none !important;
+}
+.webform {
+       width: 250px;
+}
+h2 {
+       margin-top: 0;
+       padding-top: 1em;
+}
+#instructions {
+       width: 500px;
+       clear: left;
+       -moz-border-radius: 10px;
+       -webkit-border-radius: 10px;
+       border-radius: 10px;
+       padding: 10px !important;
+       border: 1px solid #D5DFC3;
+       background: #F3FFDF;
+       margin-top: 6px;
+}
+
+/* Slideshow */
+#transition-settings {
+       float: left;
+       margin: 0 10px 0 0;
+       display: block;
+       width: 300px;
+}
+#rotatingImagesPreview {
+       float: left;
+}
+#rotatingImagesLive {
+       color: orange;
+       font-weight: bold;
+       height: 1%;
+       overflow: hidden;
+}
+#rotatingImagesLive #images {
+       overflow: hidden;
+}
+#rotatingImagesLive #images img {
+       border-bottom: 5px solid #f7941d;
+}
+#if-prev,
+#if-next {
+       text-decoration: underline;
+       cursor: hand;
+       cursor: pointer;
+       color: orange;
+}
+#if-prev:hover,
+#if-next:hover {
+       color: black;
+}
diff --git a/Toolkit/RotatingImages/templates/compiled/.cvsignore b/Toolkit/RotatingImages/templates/compiled/.cvsignore
new file mode 100644 (file)
index 0000000..7f1398d
--- /dev/null
@@ -0,0 +1 @@
+* */*
diff --git a/Toolkit/RotatingImages/templates/compiled/.keepme b/Toolkit/RotatingImages/templates/compiled/.keepme
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Toolkit/RotatingImages/templates/currentTables/Element.tpl b/Toolkit/RotatingImages/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/RotatingImages/templates/currentTables/Form.tpl b/Toolkit/RotatingImages/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/RotatingImages/templates/currentTables/Group.tpl b/Toolkit/RotatingImages/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/RotatingImages/templates/currentTables/GroupElement.tpl b/Toolkit/RotatingImages/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/RotatingImages/templates/currentTables/Header.tpl b/Toolkit/RotatingImages/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/RotatingImages/templates/currentTables/RequiredNote.tpl b/Toolkit/RotatingImages/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/RotatingImages/templates/imagesDataGrid.html b/Toolkit/RotatingImages/templates/imagesDataGrid.html
new file mode 100644 (file)
index 0000000..eddba01
--- /dev/null
@@ -0,0 +1,32 @@
+<h2>{gridName:h}</h2>
+<ul id="{tableId:h}" class="dataGrid">
+       {if:numberedSet}
+               {foreach:recordSet,row}
+               <li id="image_{row[id]}" class="ui-state-default">
+                       <span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
+                       {row[Image]:h}
+                       <div class="info">
+                               <div style="line-height: 16px;
+                                                       vertical-align: center;
+                                                       float: right;
+                                                       margin-top: 10px;">
+                                       {row[Delete]:h}
+                               </div>
+                               <div style="line-height: 16px;
+                                                       vertical-align: center;
+                                                       clear: left;
+                                                       margin-top: 10px;">
+                                       {row[Edit]:h}
+                               </div>
+                               {if:row[url]}
+                               <br>Link: <a href="{row[url]:h}">{row[url]:h}</a>
+                               {end:}
+                       </div>
+               </li>
+               {end:}
+       {else:}
+               <li class="ui-state-disabled ui-state-default">
+               Drag image here to add
+               </li>
+       {end:}
+</ul>
diff --git a/Toolkit/RotatingImages/templates/instructions.html b/Toolkit/RotatingImages/templates/instructions.html
new file mode 100644 (file)
index 0000000..ec576c2
--- /dev/null
@@ -0,0 +1,7 @@
+<div id="instructions">
+<b>Instructions</b><br>
+Recommended image size is<br>
+Width:  580 pixels<br>
+Height: 303 pixels
+</div>
+<h2>Slideshow Settings</h2>