Adding slideshow
authorSteve Sutton <steve@gaslightmedia.com>
Mon, 23 Feb 2015 17:35:13 +0000 (12:35 -0500)
committerSteve Sutton <steve@gaslightmedia.com>
Mon, 23 Feb 2015 17:35:13 +0000 (12:35 -0500)
Install the slideshow application

45 files changed:
Toolkit/RotatingImages/ActiveImagesDataGrid.php [new file with mode: 0644]
Toolkit/RotatingImages/Database/application.sql [new file with mode: 0644]
Toolkit/RotatingImages/Database/removeApplication.sql [new file with mode: 0644]
Toolkit/RotatingImages/Database/tables/application.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/Database/upgradeApp.sql [new file with mode: 0644]
Toolkit/RotatingImages/Decorator/Admin.php [new file with mode: 0644]
Toolkit/RotatingImages/Decorator/Anchor.php [new file with mode: 0644]
Toolkit/RotatingImages/Decorator/DecoratorAbstract.php [new file with mode: 0644]
Toolkit/RotatingImages/Decorator/IDecoratorsIterator.php [new file with mode: 0644]
Toolkit/RotatingImages/Decorator/Image.php [new file with mode: 0644]
Toolkit/RotatingImages/Decorator/Thumbnail.php [new file with mode: 0644]
Toolkit/RotatingImages/Decorator/User.php [new file with mode: 0644]
Toolkit/RotatingImages/EditImageController.php [new file with mode: 0644]
Toolkit/RotatingImages/Forms/EditImage.php [new file with mode: 0644]
Toolkit/RotatingImages/Forms/TransitionSettings.php [new file with mode: 0644]
Toolkit/RotatingImages/Gateway.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/ImagesDataGridAbstract.php [new file with mode: 0644]
Toolkit/RotatingImages/InactiveImagesDataGrid.php [new file with mode: 0644]
Toolkit/RotatingImages/IndexController.php [new file with mode: 0644]
Toolkit/RotatingImages/Navigation.php [new file with mode: 0644]
Toolkit/RotatingImages/NodesIterator.php [new file with mode: 0644]
Toolkit/RotatingImages/PreviewIframe.php [new file with mode: 0644]
Toolkit/RotatingImages/PreviewJavascript.php [new file with mode: 0644]
Toolkit/RotatingImages/TransitionGateway.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/sortable.js [new file with mode: 0644]
Toolkit/RotatingImages/libjs/user.php [new file with mode: 0644]
Toolkit/RotatingImages/styles.css [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]
Toolkit/RotatingImages/templates/rotatingImages.html [new file with mode: 0644]
admin/rotatingImages.php [new file with mode: 0644]
config/application.ini

diff --git a/Toolkit/RotatingImages/ActiveImagesDataGrid.php b/Toolkit/RotatingImages/ActiveImagesDataGrid.php
new file mode 100644 (file)
index 0000000..e90ed12
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * ActiveImagesDataGrid.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_ActiveImagesDataGrid
+ *
+ * Description of newPHPClass
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_ActiveImagesDataGrid
+    extends Toolkit_RotatingImages_ImagesDataGridAbstract
+    implements Toolkit_RotatingImages_IImagesDataGrid
+{
+    //  {{{ setControlObject()
+
+    /**
+     * Description of setControlObject
+     *
+     * @return void
+     */
+    protected function setControlObject()
+    {
+        $this->ctrlObj['tableId']  = 'active';
+        $this->ctrlObj['gridName'] = 'Active Images';
+    }
+
+    //  }}}
+    //  {{{ setQuery()
+
+    /**
+     * Sets query to all active rotating images
+     *
+     * @return void
+     */
+    public function setQuery()
+    {
+        $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE active = true
+               AND application = " . SLIDESHOW_APP_ID;
+
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/Database/application.sql b/Toolkit/RotatingImages/Database/application.sql
new file mode 100644 (file)
index 0000000..d3c3b6f
--- /dev/null
@@ -0,0 +1,16 @@
+CREATE SCHEMA rotatingImages;
+GRANT ALL ON SCHEMA rotatingImages TO nobody;
+--
+-- Tables
+--
+\i ./tables/application.sql
+\i ./tables/rotating_images.sql
+\i ./tables/rotating_images_transitions.sql
+
+--
+-- Procedures
+--
+
+--
+-- Modules
+--
diff --git a/Toolkit/RotatingImages/Database/removeApplication.sql b/Toolkit/RotatingImages/Database/removeApplication.sql
new file mode 100644 (file)
index 0000000..ed04c5c
--- /dev/null
@@ -0,0 +1,8 @@
+--
+--     This will drop everything in the rotatingImages schema.
+--     Nothing better be in here except rotatingImages related objects
+--     or it will be dropped
+--
+--     the forece is strong w/ this one, use it wisely.
+--
+DROP SCHEMA IF EXISTS rotatingImages CASCADE;
diff --git a/Toolkit/RotatingImages/Database/tables/application.sql b/Toolkit/RotatingImages/Database/tables/application.sql
new file mode 100644 (file)
index 0000000..fee76f2
--- /dev/null
@@ -0,0 +1,14 @@
+DROP TABLE IF EXISTS rotatingImages.application CASCADE;
+
+CREATE TABLE rotatingImages.application
+(
+    id SERIAL,
+    name TEXT,
+    page INTEGER,
+    PRIMARY KEY (id)
+);
+
+GRANT ALL ON rotatingImages.application_id_seq TO nobody;
+GRANT ALL ON rotatingImages.application TO nobody;
+
+INSERT INTO rotatingImages.application VALUES (1, 'Home Page Slideshow', 1);
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..af27688
--- /dev/null
@@ -0,0 +1,22 @@
+DROP TABLE IF EXISTS rotatingImages.rotating_images CASCADE;
+
+CREATE TABLE rotatingImages.rotating_images (
+    id SERIAL,
+    application INT NOT NULL,
+ image TEXT NOT NULL UNIQUE,
+ title TEXT,
+ descr TEXT,
+ url TEXT,
+ external BOOLEAN NOT NULL DEFAULT FALSE,
+ active BOOLEAN NOT NULL DEFAULT FALSE,
+ pos INTEGER,
+ thumb_width INTEGER NOT NULL,
+ thumb_height INTEGER NOT NULL,
+ width INTEGER NOT NULL,
+ height INTEGER NOT NULL,
+    UNIQUE (application, active, pos),
+    PRIMARY KEY (id)
+);
+
+GRANT ALL ON rotatingImages.rotating_images_id_seq TO nobody;
+GRANT ALL ON rotatingImages.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..0871dcb
--- /dev/null
@@ -0,0 +1,11 @@
+DROP TABLE IF EXISTS rotatingImages.rotating_images_transitions CASCADE;
+
+CREATE TABLE rotatingImages.rotating_images_transitions
+(
+    application INT NOT NULL,
+    timeout INTEGER NOT NULL DEFAULT 10,
+ transition TEXT NOT NULL DEFAULT 'fade');
+
+INSERT INTO rotatingImages.rotating_images_transitions VALUES (1, 10, 'fade');
+
+GRANT ALL ON rotatingImages.rotating_images_transitions TO nobody;
diff --git a/Toolkit/RotatingImages/Database/upgradeApp.sql b/Toolkit/RotatingImages/Database/upgradeApp.sql
new file mode 100644 (file)
index 0000000..8a3f75c
--- /dev/null
@@ -0,0 +1,25 @@
+--
+-- Upgrade from old version
+--
+ALTER TABLE rotatingImages.rotating_images ADD title TEXT;
+ALTER TABLE rotatingImages.rotating_images ADD descr TEXT;
+
+ALTER TABLE rotating_images DROP CONSTRAINT rotatingimages.rotating_images_active_key;
+
+--
+-- Add new table for application
+--
+\i ./tables/application.sql
+
+--
+-- Update old tables for the application
+--
+ALTER TABLE rotatingimages.rotating_images ADD application INTEGER;
+ALTER TABLE rotatingimages.rotating_images ALTER application SET NOT NULL;
+UPDATE rotatingimages.rotating_images SET application = 1;
+
+ALTER TABLE rotatingimages.rotating_images_transitions ADD application INTEGER;
+ALTER TABLE rotatingimages.rotating_images_transitions ALTER application SET NOT NULL;
+UPDATE rotatingimages.rotating_images_transitions SET application = 1;
+
+CREATE UNIQUE INDEX rotating_images_active_key ON rotatingimages.rotating_images (application, active, pos);
\ No newline at end of file
diff --git a/Toolkit/RotatingImages/Decorator/Admin.php b/Toolkit/RotatingImages/Decorator/Admin.php
new file mode 100644 (file)
index 0000000..a98b7d7
--- /dev/null
@@ -0,0 +1,136 @@
+<?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: Admin.php,v 1.1 2010/07/25 17:05:58 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_Decorator_Admin
+    implements IteratorAggregate,
+    Toolkit_RotatingImages_Decorator_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_DecoratorAbstract $d Decorator object
+     *
+     * @return void
+     * @access public
+     */
+    public function add(Toolkit_RotatingImages_Decorator_DecoratorAbstract $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
+     *
+     * @return string HTML version of the static banners available
+     * @access public
+     */
+    public function toHtml()
+    {
+        $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/plugins/nivoslider/2.0/' . LIBJS_ENV . '/jquery.nivo.slider.js';
+        $GLOBALS['styleSheets'][]   = MEDIA_APP_BASE_URL . 'libjs/plugins/nivoslider/2.0/' . LIBJS_ENV . '/nivo-slider.css';
+        $GLOBALS['styleSheets'][]   = MEDIA_BASE_URL . 'Toolkit/RotatingImages/styles.css';
+
+        foreach ($this->_decorators as $i) {
+            switch (get_class($i)) {
+                case 'Toolkit_RotatingImages_Decorator_Thumbnail' :
+                case 'Toolkit_RotatingImages_Decorator_Image' :
+                    $images .= $i->toHtml();
+                    break;
+
+                case 'Toolkit_RotatingImages_Decorator_Anchor' :
+                    $images .= $i->toHtml();
+                    break;
+
+                default :
+                    break;
+            }
+        }
+
+        return "<div id=\"rotatingImagesPreview\">$images</div>";
+    }
+
+    // }}}
+}
diff --git a/Toolkit/RotatingImages/Decorator/Anchor.php b/Toolkit/RotatingImages/Decorator/Anchor.php
new file mode 100644 (file)
index 0000000..e83266e
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * Decorator for links
+ *
+ * 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: Anchor.php,v 1.3 2010/08/15 16:02:21 jamie Exp $
+ * @link      <>
+ */
+
+
+/**
+ * Decorator for links
+ *
+ * @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_Decorator_Anchor
+       extends Toolkit_RotatingImages_Decorator_DecoratorAbstract
+{
+       //      {{{     properties
+
+    /**
+     * The image decorator object
+     * @var    Toolkit_RotatingImages_Decorator_Image
+     * @access private
+     */
+       private $_imageDecorator;
+
+       //      }}}
+       //  {{{ __construct()
+
+    /**
+     * constructor
+     *
+     * create a shallow copy of the image passed in so we can manipulate
+        * it all we want and not worry about affecting the original object
+     *
+     * @param Toolkit_RotatingImages_Decorator_Image $imageDecorator Object to decorate image markup
+     * @param Toolkit_RotatingImages_Image           $image          Node to be decorated
+        *
+     * @return void
+     * @access protected
+     */
+       public function __construct(
+               Toolkit_RotatingImages_Decorator_Image $imageDecorator,
+               Toolkit_RotatingImages_Image $image
+       ) {
+               $this->_imageDecorator = $imageDecorator;
+               //      Clone the node object so we keep original properties the same
+               $this->image = clone $image;
+       }
+
+       //  }}}
+    //  {{{ toHtml()
+
+    /**
+     * Convert the anchor to a HTML string
+     *
+     * @return string HTML output of the anchor
+     * @access public
+     */
+       public function toHtml()
+       {
+               $anchorFormat = '<a href="%s" %s>%s</a>';
+               return sprintf(
+                       $anchorFormat,
+                       $this->image->getUrl(),
+            $this->image->getExternal() ? 'class="external"' : '',
+                       $this->_imageDecorator->toHtml()
+               );
+       }
+
+    //  }}}
+    public function getTitle()
+    {
+        return $this->image->getTitle();
+    }
+
+    public function getDescr()
+    {
+        return $this->image->getDescr();
+    }
+
+    public function getId()
+    {
+        return $this->image->getId();
+    }
+}
+?>
diff --git a/Toolkit/RotatingImages/Decorator/DecoratorAbstract.php b/Toolkit/RotatingImages/Decorator/DecoratorAbstract.php
new file mode 100644 (file)
index 0000000..81509fc
--- /dev/null
@@ -0,0 +1,55 @@
+<?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: DecoratorAbstract.php,v 1.1 2010/07/25 17:05:58 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_DecoratorAbstract
+{
+    //  {{{ properties
+
+    /**
+     * Image object that will be decorated
+     * @var Toolkit_RotatingImages_Image
+     * @access protected
+     */
+    protected $image;
+
+    //  }}}
+    // {{{     getImage()
+
+    /**
+     * Get the image we are decorating
+     *
+     * @return Toolkit_RotatingImages_Image object
+     * @access public
+     */
+    public function getImage()
+    {
+        return $this->image;
+    }
+
+    // }}}
+}
+
+?>
diff --git a/Toolkit/RotatingImages/Decorator/IDecoratorsIterator.php b/Toolkit/RotatingImages/Decorator/IDecoratorsIterator.php
new file mode 100644 (file)
index 0000000..f7be31f
--- /dev/null
@@ -0,0 +1,49 @@
+<?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 2010/07/25 17:05:58 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_Decorator_IDecoratorsIterator
+{
+
+    /**
+     * Add a new decorator to the collection
+     *
+     * @param Toolkit_RotatingImages_Decorator_DecoratorAbstract $d decorator
+     *
+     * @return void
+     * @access public
+     */
+    public function add(Toolkit_RotatingImages_Decorator_DecoratorAbstract $d);
+
+    /**
+     * Return an HTML version of the decorator
+     *
+     * @return html version of banners
+     * @access public
+     */
+    public function toHtml();
+}
+
+?>
diff --git a/Toolkit/RotatingImages/Decorator/Image.php b/Toolkit/RotatingImages/Decorator/Image.php
new file mode 100644 (file)
index 0000000..5f872ab
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * Decorator for images
+ *
+ * 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: Image.php,v 1.2 2010/08/15 15:57:30 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Decorator for images
+ *
+ * @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_Decorator_Image
+    extends Toolkit_RotatingImages_Decorator_DecoratorAbstract
+{
+    //  {{{ __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_Image $image node to be decorated
+     *
+     * @return void
+     * @access protected
+     */
+    public function __construct(Toolkit_RotatingImages_Image $image)
+    {
+        //     Clone the node object so we keep original properties the same
+        $this->image = clone $image;
+    }
+
+    //  }}}
+    //  {{{ toHtml()
+
+    /**
+     * Convert the image to a HTML string
+     *
+     * @return string HTML output of the image
+     * @access public
+     */
+    public function toHtml()
+    {
+        $format = '<img '
+            . 'width="%s" '
+            . 'height="%s" '
+            . 'src="%s" '
+            . 'alt="" '
+            . 'title="#event-%d">';
+        return sprintf(
+            $format,
+            $this->image->getWidth(),
+            $this->image->getHeight(),
+            ROTATING_IMAGE_RESIZED . $this->image->getImage(),
+            $this->image->getId()
+        );
+    }
+
+    //  }}}
+
+    public function getTitle()
+    {
+        return $this->image->getTitle();
+    }
+
+    public function getDescr()
+    {
+        return $this->image->getDescr();
+    }
+
+    public function getId()
+    {
+        return $this->image->getId();
+    }
+
+}
diff --git a/Toolkit/RotatingImages/Decorator/Thumbnail.php b/Toolkit/RotatingImages/Decorator/Thumbnail.php
new file mode 100644 (file)
index 0000000..831f373
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * Decorator for thumbnail images
+ *
+ * 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: Thumbnail.php,v 1.1 2010/07/25 17:05:58 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * Decorator for thumbnail images
+ *
+ * @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_Decorator_Thumbnail
+    extends Toolkit_RotatingImages_Decorator_DecoratorAbstract
+{
+    //  {{{ __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_Image $image image to be decorated
+     *
+     * @return void
+     * @access protected
+     */
+    public function __construct(Toolkit_RotatingImages_Image $image)
+    {
+        //     Clone the image object so we keep original properties the same
+        $this->image = clone $image;
+    }
+
+    //  }}}
+    //  {{{ toHtml()
+
+    /**
+     * Convert the image to a HTML string
+     *
+     * @return string HTML output of the image
+     * @access public
+     */
+    public function toHtml()
+    {
+        $format = '<img width="%s" height="%s" src="%s">';
+        return sprintf(
+            $format, $this->image->getThumbWidth(),
+            $this->image->getThumbHeight(),
+            ROTATING_IMAGE_THUMB . $this->image->getImage()
+        );
+    }
+
+    //  }}}
+}
+
+?>
diff --git a/Toolkit/RotatingImages/Decorator/User.php b/Toolkit/RotatingImages/Decorator/User.php
new file mode 100644 (file)
index 0000000..7797a37
--- /dev/null
@@ -0,0 +1,125 @@
+<?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: User.php,v 1.2 2010/08/15 15:59:26 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_Decorator_User
+    implements IteratorAggregate,
+    Toolkit_RotatingImages_Decorator_IDecoratorsIterator
+{
+    /**
+     * Banner decorators
+     * @var    array
+     * @access private
+     */
+    private $_decorators;
+
+    /**
+     * constructor
+     *
+     * @return void
+     * @access protected
+     */
+    public function __construct()
+    {
+        $this->_decorators = array();
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * Adds a decorator to the collection
+     *
+     * @param Toolkit_RotatingImages_Decorator_DecoratorAbstract $d Decorator object
+     *
+     * @return void
+     * @access public
+     */
+    public function add(Toolkit_RotatingImages_Decorator_DecoratorAbstract $d)
+    {
+        $this->_decorators[] = $d;
+    }
+
+    /**
+     * 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
+     *
+     * @return string HTML version of the static banners available
+     * @access public
+     */
+    public function toHtml()
+    {
+        $glmAppBaseUrl = MEDIA_APP_BASE_URL;
+        $baseUrl       = MEDIA_BASE_URL;
+
+        $GLOBALS['styleSheets'][]
+            = $glmAppBaseUrl . 'libjs/plugins/nivoslider/3.2/prod/nivo-slider.css';
+        $GLOBALS['styleSheets'][]
+            = $glmAppBaseUrl . 'libjs/plugins/nivoslider/themes/default/default.css';
+        $GLOBALS['bottomScripts'][]
+            = $glmAppBaseUrl . 'libjs/plugins/nivoslider/3.2/prod/jquery.nivo.slider.js';
+        $GLOBALS['bottomScripts'][]
+            = $baseUrl . 'Toolkit/RotatingImages/libjs/user.php?appId=' . SLIDESHOW_APP_ID;
+
+        $options = $GLOBALS['flexyOptions'];
+        $options['templateDir'] = BASE . 'Toolkit/RotatingImages/templates';
+        $options['compileDir'] = BASE . 'Toolkit/RotatingImages/templates/compiled';
+        $tpl = new HTML_Template_Flexy($options);
+        $tpl->compile('rotatingImages.html');
+        $page = new stdClass();
+        $page->images = array();
+        $images = '';
+        foreach ($this->_decorators as $i) {
+            $images .= $i->toHtml();
+            $page->images[] = $i;
+        }
+
+        return !empty($images)
+            ? $tpl->bufferedOutputObject($page)
+            : '';
+    }
+
+}
diff --git a/Toolkit/RotatingImages/EditImageController.php b/Toolkit/RotatingImages/EditImageController.php
new file mode 100644 (file)
index 0000000..2701aa5
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * EditImageController.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_EditImageController
+ *
+ * Description of Toolkit_RotatingImages_EditImageController
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_EditImageController
+    extends Toolkit_BaseControllerAbstract
+    implements Toolkit_IController
+{
+    //  {{{ indexAction()
+
+    /**
+     * indexAction
+     *
+     * @return string
+     */
+    public function indexAction()
+    {
+        $imageAdapter = new Toolkit_FileServer_ImageAdapter();
+        $form         = new Toolkit_RotatingImages_Forms_EditImage(
+            'GLM_RotatingImages'
+        );
+        $form->setConfig($this->registry->config);
+        $form->configureForm($this->registry->dbh, $imageAdapter);
+        $html         = $form->toHtml($this->registry->dbh);
+
+        if ($form->isSubmitted() && $form->validate()) {
+            if ($form->getSubmitValue('delete')) {
+                $this->deleteAction();
+            }
+            $ia      = new Toolkit_FileServer_ImageAdapter();
+            $values  = $form->getSubmitValues();
+            list($values['thumb_width'], $values['thumb_height'], )
+                = $ia->getImageSize(ROTATING_IMAGE_THUMB . $values['image']);
+            list($values['width'], $values['height'], )
+                = $ia->getImageSize(ROTATING_IMAGE_RESIZED . $values['image']);
+            $gateway = new Toolkit_RotatingImages_Gateway($this->registry->dbh);
+            if ($imageId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) {
+                $image = new Toolkit_RotatingImages_Image($values, $imageId);
+                $gateway->update($image);
+            } else {
+                $image = new Toolkit_RotatingImages_Image($values);
+                $gateway->insert($image);
+            }
+            $append = '?app=' . SLIDESHOW_APP_ID;
+            header('Location: ' . MEDIA_BASE_URL . 'admin/rotatingImages.php' . $append);
+            exit();
+        }
+
+        return $html;
+    }
+
+    //  }}}
+    //  {{{ deleteAction()
+
+    /**
+     * deleteAction
+     *
+     * @return void
+     */
+    public function deleteAction()
+    {
+        if ($imageId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) {
+            $gateway = new Toolkit_RotatingImages_Gateway($this->registry->dbh);
+            $image   = $gateway->find($imageId);
+            $gateway->delete($image, new Toolkit_FileServer_ImageAdapter());
+        }
+        $append = '?app=' . SLIDESHOW_APP_ID;
+        header('Location: ' . MEDIA_BASE_URL . 'admin/rotatingImages.php' . $append);
+        exit();
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/Forms/EditImage.php b/Toolkit/RotatingImages/Forms/EditImage.php
new file mode 100644 (file)
index 0000000..3cdfdc8
--- /dev/null
@@ -0,0 +1,404 @@
+<?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 <steve@gaslightmedia.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: EditImage.php,v 1.2 2010/08/15 18:40:57 jamie Exp $
+ * @link        http://demo.gaslightmedia.com
+ */
+require_once BASE . 'Toolkit/Forms/Rules/Image.php';
+require_once BASE . 'Toolkit/Forms/Rules/Url.php';
+
+/**
+ * Rotating Images Application
+ *
+ * Manages the creation and editing form for manipulating images in the db.
+ *
+ * @category  RotatingImages
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_RotatingImages_Forms_EditImage
+    extends Toolkit_FormBuilder
+{
+    //  {{{ properties
+
+    private $_config;
+
+    /**
+     * 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'
+        )
+    );
+
+    //  }}}
+    public function setConfig(Config_Container $config)
+    {
+        $this->_config = $config;
+    }
+    //  {{{ configureConstants()
+
+    /**
+     * Configure form constants
+     *
+     * @return void
+     * @access public
+     */
+    public function configureConstants()
+    {
+        $c = array(
+            'application' => SLIDESHOW_APP_ID
+        );
+
+        //     If we are adding a new banner
+        if (!filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) {
+            $c['current_image_thumb'] = '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_thumb'] = 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 public
+     */
+    public function configureDefaults(PDO $dbh)
+    {
+        if ($imageId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) {
+            $gateway = new Toolkit_RotatingImages_Gateway($dbh);
+            if ($node    = $gateway->find($imageId)) {
+                $img = '<img src="%s%s" alt="Rotating Image" width="%s" height="%s">';
+                $d   = array(
+                    'active'              => (int) $node->getActive(),
+                    'image'               => $node->getImage(),
+                    'current_image_thumb' => sprintf(
+                        $img, ROTATING_IMAGE_THUMB, $node->getImage(),
+                        $node->getThumbWidth(), $node->getThumbHeight()
+                    ),
+                    'external'            => (int) $node->getExternal(),
+                    'url'                 => $node->getUrl(),
+                    'title'               => $node->getTitle(),
+                    'descr'               => $node->getDescr()
+                );
+            }
+        } 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();
+
+        $useTitles = $this->_config
+            ->getItem('section','conf')
+            ->getItem('directive', 'useTitles')
+            ->getContent();
+
+        //     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' => 'hidden',
+            'req'  => false,
+            'name' => 'application'
+        );
+        if ($useTitles) {
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'title',
+                'display' => 'Title',
+                'opts'    => array('class' => 'text')
+            );
+            $e[] = array(
+                'type'    => 'text',
+                'req'     => false,
+                'name'    => 'descr',
+                'display' => 'Description',
+                'opts'    => array('class' => 'text')
+            );
+        }
+        $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',
+            'display' => 'Image'
+        );
+        $e[] = array(
+            'type'    => 'static',
+            'req'     => false,
+            'name'    => 'current_image_thumb',
+            'display' => 'Current Image'
+        );
+        $e[] = array(
+            'type'    => 'submit',
+            'req'     => false,
+            'name'    => 'submit',
+            'display' => 'Submit Image',
+        );
+        if (filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) {
+            $e[] = array(
+                'type'    => 'submit',
+                'req'     => false,
+                'name'    => 'delete',
+                'display' => 'Delete Image',
+            );
+        }
+
+        $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
+     *
+     * @param PDO                             $dbh PDO
+     * @param Toolkit_FileServer_ImageAdapter $ia  File server image adapter
+     *
+     * @return void
+     * @access public
+     */
+    public function configureForm(PDO $dbh, Toolkit_FileServer_ImageAdapter $ia)
+    {
+        $this->configureElements();
+        $this->configureFilters();
+        $this->configureRules($ia);
+        $this->configureDefaults($dbh);
+        $this->configureConstants();
+    }
+
+    // }}}
+    // {{{     configureRules()
+
+    /**
+     * Configure how the form elements should act
+     *
+     * @param Toolkit_FileServer_ImageAdapter $ia File server image adapter
+     *
+     * @return void
+     * @access public
+     */
+    public function configureRules(Toolkit_FileServer_ImageAdapter $ia)
+    {
+        $r = array();
+
+        $r[]           = array(
+            'element'    => 'url',
+            'message'    => 'ERROR: Invalid URL',
+            'type'       => 'Url',
+            'format'     => null,
+            'validation' => $this->validationType,
+            'reset'      => false,
+            'force'      => false
+        );
+        $uploadedImage = $this->getSubmitValue('image');
+        if (empty($uploadedImage)) {
+            $r[] = array(
+                'element'    => 'file',
+                'message'    => 'ERROR: Must upload an image!',
+                'type'       => 'uploadedfile',
+                'format'     => null,
+                'validation' => $this->validationType,
+                'reset'      => false,
+                'force'      => false
+            );
+        }
+        if (is_uploaded_file($_FILES['file']['tmp_name'])) {
+            $r[] = array(
+                'element'    => 'file',
+                'message'    => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!',
+                'type'       => 'mimetype',
+                'format'     => $ia->getAllowedMimeTypes(),
+                'validation' => $this->validationType,
+                'reset'      => false,
+                'force'      => false
+            );
+        }
+        $r[] = array(
+            'element'    => 'file',
+            'message'    => 'ERROR: Error uploading image!',
+            'type'       => 'Image',
+            'format'     => array(
+                'form'                => $this,
+                'fieldName'           => 'file',
+                'imageField'          => 'image',
+                'is'                  => $ia,
+                'deleteExistingImage' => true,
+                'injectImage'         => array('tgtElement' => 'current_image_thumb'),
+            ),
+            'validation' => 'server',
+            'reset'      => false,
+            'force'      => false
+        );
+
+        $this->setupRules($r);
+    }
+
+    // }}}
+    // {{{     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="req"> {error} </div><!-- END error -->';
+        $renderer->setElementTemplate(
+            '<tr align="center">
+                               <td colspan="2">' . $required . '{label}' . $error . '{element}</td>
+                       </tr>', 'submit'
+        );
+        $renderer->setElementTemplate(
+            '<tr align="center">
+                               <td colspan="2">' . $required . '{label}' . $error . '{element}</td>
+                       </tr>', 'delete'
+        );
+    }
+
+    // }}}
+    //  {{{ toHtml()
+
+    /**
+     * Call the rendering function to get the form in a string
+     *
+     * @param PDO $dbh Database handler
+     *
+     * @return string $output The Form to be rendered or success msg.
+     * @access protected
+     */
+    public function toHtml(PDO $dbh)
+    {
+        $this->setupRenderers();
+        if ($this->isSubmitted()) {
+            if ($this->validate()) {
+                $output = $this->successMsg;
+            } else {
+                $output = $this->errorMsg;
+                $output .= parent::toHTML();
+            }
+        } else {
+            $output = parent::toHTML();
+        }
+        return $output;
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/Forms/TransitionSettings.php b/Toolkit/RotatingImages/Forms/TransitionSettings.php
new file mode 100644 (file)
index 0000000..1963556
--- /dev/null
@@ -0,0 +1,313 @@
+<?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 <steve@gaslightmedia.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @version  CVS: $Id: TransitionSettings.php,v 1.2 2010/08/15 18:41:14 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 <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight Media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link         http://demo.gaslightmedia.com
+ */
+class Toolkit_RotatingImages_Forms_TransitionSettings
+       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();
+
+    //  }}}
+
+    //  {{{ configureConstants()
+
+       /**
+        * Configure the constant values for the form
+        *
+     * @return void
+        * @access protected
+        */
+       public function configureConstants()
+       {
+               $c = array(
+            'ac'          => 'preview',
+            'application' => SLIDESHOW_APP_ID,
+            'app'         => SLIDESHOW_APP_ID,
+               );
+               $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)
+       {
+               $sql = "
+                       SELECT *
+              FROM rotating_images_transitions
+             WHERE application = " . SLIDESHOW_APP_ID;
+
+               $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)
+               );
+
+               //      All Grouped Elements are created here.
+               $submitButtons = array();
+               $submitButtons[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'apply',
+            'display' => 'Apply Transition',
+        );
+               $submitButtons[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'preview',
+            'display' => 'Preview Transition',
+        );
+
+               //      All Elements are created here.  This includes group element definitions.
+               $e[] = array(
+            'type' => 'hidden',
+            'req' => false,
+            'name' => 'ac',
+        );
+        $e[] = array(
+            'type' => 'hidden',
+            'req'  => false,
+            'name' => 'app',
+        );
+        $e[] = array(
+            'type' => 'hidden',
+            'req'  => false,
+            'name' => 'application',
+        );
+               $e[] = array(
+            'type' => 'select',
+            'req' => false,
+            'name' => 'timeout',
+            'display' => 'Seconds between transition',
+            'opts' => array('' => '-- Select --') + $timeout,
+        );
+        $e[] = array(
+               'type' => 'select',
+               'req' => false,
+               'name' => 'transition',
+               'display' => 'Transition effect',
+                       'opts' => array('' => '-- Select --') + $transition,
+                       'att' => array('id' => 'transition')
+        );
+               $e[] = array(
+            'type' => 'group',
+                       'group' => $submitButtons,
+            'req' => false,
+            'name' => 'submitButtons',
+                       'appendName' => false,
+                       'seperator' => ' - '
+        );
+
+               $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->configureConstants();
+               $this->configureDefaults($pdo);
+               $this->configureElements($pdo, $c);
+       }
+
+       //      }}}
+
+       //      {{{     processData()
+
+       /**
+        * Update transition values
+        *
+     * @param PDO $dbh Database handler
+     *
+     * @return boolean Result of update
+        * @access protected
+        */
+       private function _processData(PDO $dbh)
+       {
+        if (!$this->_submitValues['timeout']) {
+            return;
+        }
+               try {
+                       $sql = "
+                UPDATE rotating_images_transitions
+                                  SET timeout = :timeout,
+                       transition = :transition
+                 WHERE application = " . SLIDESHOW_APP_ID;
+
+                       $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}>
+                                       <div class="hiddenElements">
+                                               {hidden}
+                                       </div>
+                                       {requiredNote}
+                                       <table id="transition-settings">{content}</table>
+                               </form>
+                       </div>'
+               );
+               $renderer->setElementTemplate(
+                       '<tr align="center">
+                               <td colspan="2">'.$required.'{label}'.$error.'{element}</td>
+                       </tr>',
+                       'submitButtons'
+               );
+       }
+
+    //  @codeCoverageIgnoreEnd
+       //      }}}
+
+    //  {{{ toHtml()
+
+       /**
+        * Call the rendering function to get the form in a string
+     * 
+     * @param PDO $pdo PDO
+        *
+        * @return string $output The Form to be rendered or success msg.
+        * @access protected
+        */
+       public function toHtml(PDO $pdo)
+       {
+               $GLOBALS['styleSheets'][] = MEDIA_BASE_URL . 'css/contactform.css';
+
+               $this->setupRenderers();
+               $output = '';
+               if ($this->validate()) {
+                       if ($this->_processData($pdo)) {
+                               $output = $this->successMsg;
+                       }
+               }
+               $output .= parent::toHTML();
+
+               return $output;
+       }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/Gateway.php b/Toolkit/RotatingImages/Gateway.php
new file mode 100644 (file)
index 0000000..13591e2
--- /dev/null
@@ -0,0 +1,319 @@
+<?php
+
+/**
+ * Gateway.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_Gateway
+ *
+ * Description of Toolkit_RotatingImages_Gateway
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_Gateway
+{
+
+    //  {{{ properties
+    /**
+     * PDO
+     *
+     * @var PDO
+     * @access protected
+     */
+    protected $dbh;
+
+    //  }}}
+    //  {{{ __construct()
+    /**
+     * Class construct
+     *
+     * @param PDO $dbh PDO
+     *
+     * @return void
+     */
+    public function __construct(PDO $dbh)
+    {
+        $this->dbh = $dbh;
+    }
+
+    //  }}}
+    //  {{{ delete()
+    /**
+     * Deleting the image
+     *
+     * @param Toolkit_RotatingImages_Image    $image Image
+     * @param Toolkit_FileServer_ImageAdapter $ia    ImageAdapter
+     *
+     * @return \Toolkit_RotatingImages_Image|boolean
+     * @throws InvalidArgumentException
+     */
+    public function delete(
+        Toolkit_RotatingImages_Image $image,
+        Toolkit_FileServer_ImageAdapter $ia
+    ) {
+        $id = $image->getId();
+        if (!filter_var($id, FILTER_VALIDATE_INT)) {
+            throw new InvalidArgumentException("Invalid image id `$id`");
+        }
+
+        try {
+            $ia->delete($image->getImage());
+            $sql = "
+                DELETE FROM rotating_images
+                 WHERE id = :id";
+
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+            $stmt->execute();
+
+            return $image;
+        } catch (RangeException $e) {
+            Toolkit_Logger::logException('File Server Error', $e);
+        } catch (Toolkit_FileServer_Exception $e) {
+            Toolkit_Logger::logException('File Server Error', $e);
+        } catch (PDOException $e) {
+            Toolkit_Logger::logException('DB Error', $e);
+        }
+
+        return false;
+    }
+
+    //  }}}
+    //  {{{ find()
+    /**
+     * Finding the image by id
+     *
+     * @param int $id Description for id
+     *
+     * @return \Toolkit_RotatingImages_Image|boolean
+     * @throws InvalidArgumentException
+     */
+    public function find($id)
+    {
+        if (!filter_var($id, FILTER_VALIDATE_INT)) {
+            throw new InvalidArgumentException("Invalid image id `$id`");
+        }
+
+        $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE id = :id";
+
+        try {
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+            $stmt->execute();
+
+            if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                return new Toolkit_RotatingImages_Image($row, $row['id']);
+            } else {
+                return false;
+            }
+        } catch (PDOException $e) {
+            Toolkit_Logger::logException('DB Error', $e);
+        }
+
+        return false;
+    }
+
+    //  }}}
+    //  {{{ insert()
+    /**
+     * Inserting the image
+     *
+     * @param Toolkit_RotatingImages_Image $image Description for $image
+     *
+     * @return boolean
+     */
+    public function insert(Toolkit_RotatingImages_Image $image)
+    {
+        try {
+            $this->dbh->beginTransaction();
+            $maxPosSql = "
+                SELECT COALESCE(MAX(pos) + 1, 1) AS pos
+                  FROM rotating_images
+                 WHERE active = cast(1 AS BOOLEAN)
+                   AND application = " . SLIDESHOW_APP_ID;
+            $row       = $this->dbh->query($maxPosSql)->fetch(PDO::FETCH_ASSOC);
+
+            $insertSql = "
+                INSERT INTO rotating_images
+                (image, active, url, external, pos, thumb_width, thumb_height,
+                width, height, title, descr, application)
+                VALUES
+                (:image, :active, :url, :external, :pos, :thumb_width, :thumb_height,
+                :width, :height, :title, :descr, :application)";
+            $stmt      = $this->dbh->prepare($insertSql);
+            $stmt->bindParam(':image', $image->getImage(), PDO::PARAM_STR);
+            $stmt->bindParam(':active', $image->getActive(), PDO::PARAM_BOOL);
+            $stmt->bindParam(':external', $image->getExternal(), PDO::PARAM_BOOL);
+            $stmt->bindParam(':application', $image->getApplication(), PDO::PARAM_INT);
+            $stmt->bindParam(
+                ':thumb_width', $image->getThumbWidth(), PDO::PARAM_INT
+            );
+            $stmt->bindParam(
+                ':thumb_height', $image->getThumbHeight(), PDO::PARAM_INT
+            );
+            $stmt->bindParam(
+                ':width', $image->getWidth(), PDO::PARAM_INT
+            );
+            $stmt->bindParam(
+                ':height', $image->getHeight(), PDO::PARAM_INT
+            );
+            if ($image->getActive()) {
+                $stmt->bindParam(':pos', $row['pos'], PDO::PARAM_INT);
+            } else {
+                $stmt->bindValue(':pos', null, PDO::PARAM_NULL);
+            }
+            if ($image->getUrl()) {
+                $stmt->bindParam(':url', $image->getUrl(), PDO::PARAM_STR);
+            } else {
+                $stmt->bindValue(':url', null, PDO::PARAM_NULL);
+            }
+            if ($image->getTitle()) {
+                $stmt->bindParam(':title', $image->getTitle(), PDO::PARAM_STR);
+            } else {
+                $stmt->bindValue(':title', null, PDO::PARAM_NULL);
+            }
+
+            if ($image->getDescr()) {
+                $stmt->bindParam(':descr', $image->getDescr(), PDO::PARAM_STR);
+            } else {
+                $stmt->bindValue(':descr', null, PDO::PARAM_NULL);
+            }
+            $stmt->execute();
+
+            return $this->dbh->commit();
+        } catch (PDOException $e) {
+            $this->dbh->rollback();
+            Toolkit_Logger::logException('DB Error', $e);
+        }
+
+        return false;
+    }
+
+    //  }}}
+    //  {{{ update()
+    /**
+     * Updating the image
+     *
+     * @param Toolkit_RotatingImages_Image $image Image
+     *
+     * @return boolean
+     * @throws RuntimeException
+     */
+    public function update(Toolkit_RotatingImages_Image $image)
+    {
+        if (!filter_var($image->getId(), FILTER_VALIDATE_INT)) {
+            throw new RuntimeException(
+            'Image has not been inserted into the database yet'
+            );
+        }
+
+        try {
+            $updateSql = "
+                UPDATE rotating_images
+                   SET image = :image,
+                       active = :active,
+                       external = :external,
+                       thumb_width = :thumb_width,
+                       thumb_height = :thumb_height,
+                       width = :width,
+                       height = :height,
+                       url = :url,
+                       title = :title,
+                       descr = :descr,
+                       application = " . SLIDESHOW_APP_ID . "
+                 WHERE id    = :id";
+            $stmt      = $this->dbh->prepare($updateSql);
+            $stmt->bindParam(':image', $image->getImage(), PDO::PARAM_STR);
+            $stmt->bindParam(':active', $image->getActive(), PDO::PARAM_BOOL);
+            $stmt->bindParam(':external', $image->getExternal(), PDO::PARAM_BOOL);
+            $stmt->bindParam(':id', $image->getId(), PDO::PARAM_INT);
+            $stmt->bindParam(
+                ':thumb_width', $image->getThumbWidth(), PDO::PARAM_INT
+            );
+            $stmt->bindParam(
+                ':thumb_height', $image->getThumbHeight(), PDO::PARAM_INT
+            );
+            $stmt->bindParam(
+                ':width', $image->getWidth(), PDO::PARAM_INT
+            );
+            $stmt->bindParam(
+                ':height', $image->getHeight(), PDO::PARAM_INT
+            );
+
+            if ($image->getUrl()) {
+                $stmt->bindParam(':url', $image->getUrl(), PDO::PARAM_STR);
+            } else {
+                $stmt->bindValue(':url', null, PDO::PARAM_NULL);
+            }
+
+            if ($image->getTitle()) {
+                $stmt->bindParam(':title', $image->getTitle(), PDO::PARAM_STR);
+            } else {
+                $stmt->bindValue(':title', null, PDO::PARAM_NULL);
+            }
+
+            if ($image->getDescr()) {
+                $stmt->bindParam(':descr', $image->getDescr(), PDO::PARAM_STR);
+            } else {
+                $stmt->bindValue(':descr', null, PDO::PARAM_NULL);
+            }
+
+            return $stmt->execute();
+        } catch (PDOException $e) {
+            Toolkit_Logger::logException('DB Error', $e);
+        }
+
+        return false;
+    }
+
+    //  }}}
+    //  {{{ find()
+    /**
+     * Find all images
+     *
+     * @return \Toolkit_RotatingImages_Image
+     */
+    public function findAll()
+    {
+        $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE application = " . SLIDESHOW_APP_ID . "
+             ORDER BY active DESC, pos, id";
+
+        try {
+            $images = array();
+            foreach ($this->dbh->query($sql) as $row) {
+                $images[] = new Toolkit_RotatingImages_Image($row, $row['id']);
+            }
+        } catch (PDOException $e) {
+            Toolkit_Logger::logException('DB Error', $e);
+        }
+
+        return $images;
+    }
+
+    //  }}}
+}
+
+?>
diff --git a/Toolkit/RotatingImages/IImagesDataGrid.php b/Toolkit/RotatingImages/IImagesDataGrid.php
new file mode 100644 (file)
index 0000000..be7685c
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * IImagesDataGrid.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_IImagesDataGrid
+ *
+ * Images Datagrid Interface
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+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..2771b2f
--- /dev/null
@@ -0,0 +1,486 @@
+<?php
+
+/**
+ * Image.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_Image
+ *
+ * Class representation of the image database
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_Image
+{
+    //  {{{ properties
+
+    /**
+     * Database id of node tuple
+     * @var    integer
+     * @access protected
+     */
+    protected $id;
+
+    /**
+     * The Application Id for this slideshow
+     * @var    integer
+     * @access protected
+     */
+    protected $application;
+
+    /**
+     * If the node is active or not
+     * @var    boolean
+     * @access protected
+     */
+    protected $active;
+
+    /**
+     * Image
+     * @var string
+     * @access protected
+     */
+    protected $image;
+
+    /**
+     * url
+     * @var string
+     * @access protected
+     */
+    protected $url;
+
+    /**
+     * external
+     * @var string
+     * @access protected
+     */
+    protected $external;
+
+    /**
+     * width of thumbnail
+     * @var integer
+     * @access protected
+     */
+    protected $thumbWidth;
+
+    /**
+     * height of thumb
+     * @var integer
+     * @access protected
+     */
+    protected $thumbHeight;
+
+    /**
+     * width of image
+     * @var integer
+     * @access protected
+     */
+    protected $width;
+
+    /**
+     * height of image
+     * @var integer
+     * @access protected
+     */
+    protected $height;
+
+    /**
+     * Title of the Image
+     * @var string
+     * @access protected
+     */
+    protected $title;
+
+    /**
+     * Description of Image
+     * @var type
+     * @access protected
+     */
+    protected $descr;
+
+    //  }}}
+    //  {{{ __construct()
+    /**
+     * Class constructor
+     *
+     * @param array   $attributes Description of attributes
+     * @param integer $id         Database ID of node tuple
+     *
+     * @throws InvalidArgumentException
+     * @return void
+     */
+    public function __construct(array $attributes, $id = null)
+    {
+        if (!array_key_exists('active', $attributes)) {
+            throw new InvalidArgumentException(
+            'Missing `active` key for attributes'
+            );
+        } elseif (!array_key_exists('image', $attributes)) {
+            throw new InvalidArgumentException(
+            'Missing `image` key for attributes'
+            );
+        }
+
+        if (filter_var($attributes['url'], FILTER_VALIDATE_URL)) {
+            $this->url = $attributes['url'];
+        }
+
+        $this->application = $attributes['application'];
+        $this->active      = (bool) $attributes['active'];
+        $this->external    = (bool) $attributes['external'];
+        $this->image       = $attributes['image'];
+        $this->thumbWidth  = $attributes['thumb_width'];
+        $this->thumbHeight = $attributes['thumb_height'];
+        $this->width       = $attributes['width'];
+        $this->height      = $attributes['height'];
+        $this->id          = $id;
+        $this->title       = $attributes['title'];
+        $this->descr       = $attributes['descr'];
+    }
+
+    //  }}}
+    //  {{{ getActive()
+
+    /**
+     * Gets the active flag
+     *
+     * @return boolean node active flag
+     * @access public
+     */
+    public function getActive()
+    {
+        return $this->active;
+    }
+
+    //  }}}
+    //  {{{ getExternal()
+
+    /**
+     * Checks whether it is external url
+     *
+     * @return boolean
+     * @access public
+     */
+    public function getExternal()
+    {
+        return $this->external;
+    }
+
+    //  }}}
+    //  {{{ getHeight()
+
+    /**
+     * Get image height
+     *
+     * @return integer image height
+     * @access public
+     */
+    public function getHeight()
+    {
+        return $this->height;
+    }
+
+    //  }}}
+    //  {{{ getId()
+
+    /**
+     * Gets the node id in the database
+     *
+     * @return integer database id
+     * @access public
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    //  }}}
+    /**
+     * Returns the Application Id
+     *
+     * @access public
+     * @return void
+     */
+    public function getApplication()
+    {
+        return $this->application;
+    }
+    //  {{{ getImage()
+
+    /**
+     * Get image
+     *
+     * @return string image
+     * @access public
+     */
+    public function getImage()
+    {
+        return $this->image;
+    }
+
+    //  }}}
+    //  {{{ getThumbHeight()
+
+    /**
+     * Get Thumbnail height
+     *
+     * @return integer thumbnail height
+     * @access public
+     */
+    public function getThumbHeight()
+    {
+        return $this->thumbHeight;
+    }
+
+    //  }}}
+    //  {{{ getThumbWidth()
+
+    /**
+     * Get thumbnail width
+     *
+     * @return integer thumbnail width
+     * @access public
+     */
+    public function getThumbWidth()
+    {
+        return $this->thumbWidth;
+    }
+
+    //  }}}
+    //  {{{ getWidth()
+
+    /**
+     * Get image width
+     *
+     * @return integer image width
+     * @access public
+     */
+    public function getWidth()
+    {
+        return $this->width;
+    }
+
+    //  }}}
+    //  {{{ getUrl()
+
+    /**
+     * Get image url
+     *
+     * @return string image url
+     * @access public
+     */
+    public function getUrl()
+    {
+        return $this->url;
+    }
+
+    //  }}}
+    //  {{{ isAnchor()
+
+    /**
+     * Checks whether the image is an anchor
+     *
+     * @return boolean
+     * @access public
+     */
+    public function isAnchor()
+    {
+        return !empty($this->url);
+    }
+
+    //  }}}
+    //  {{{ setActive()
+
+    /**
+     * set the active flag to true for the node
+     *
+     * @param boolean $active new active flag to set
+     *
+     * @return void
+     * @access public
+     */
+    public function setActive($active)
+    {
+        if (!is_bool($active)) {
+            throw InvalidArgumentException(
+                '$active must be a boolean.'
+            );
+        }
+
+        $this->active = $active;
+    }
+
+    //  }}}
+    public function setApplication($application)
+    {
+        if (!filter_var($application, FILTER_VALIDATE_INT)) {
+            throw InvalidArgumentException(
+                '$application must be a boolean.'
+            );
+        }
+
+        $this->application = $application;
+    }
+    //  {{{ setExternal()
+
+    /**
+     * Sets external
+     *
+     * @param boolean $external External
+     *
+     * @return void
+     * @access public
+     */
+    public function setExternal($external)
+    {
+        $this->external = (bool) $external;
+    }
+
+    //  }}}
+    //  {{{ setImage()
+    /**
+     * Sets image
+     *
+     * @param string $image Image
+     *
+     * @return void
+     * @access public
+     *
+     */
+    public function setImage($image)
+    {
+        $this->image = $image;
+    }
+
+    //  }}}
+    //  {{{ setUrl()
+
+    /**
+     * Sets url
+     *
+     * @param string $url url
+     *
+     * @throws InvalidArgumentException
+     * @return void
+     * @access public
+     */
+    public function setUrl($url)
+    {
+        if (!filter_var($url, FILTER_VALIDATE_URL)) {
+            throw new InvalidArgumentException(
+            '$url parameter must be a valid url'
+            );
+        }
+        $this->url = $url;
+    }
+
+    //  }}}
+    //  {{{ setThumbHeight()
+
+    /**
+     * Set the thumbnail image height value
+     *
+     * @param integer $thumbHeight thumbnail image height
+     *
+     * @return void
+     * @access public
+     */
+    public function setThumbHeight($thumbHeight)
+    {
+        if (!filter_var($thumbHeight, FILTER_VALIDATE_INT)) {
+            throw new InvalidArgumentException(
+            "`$thumbHeight` is not an integer"
+            );
+        }
+        $this->thumbHeight = $thumbHeight;
+    }
+
+    //  }}}
+    //  {{{ setThumbWidth()
+
+    /**
+     * Set the thumbnail image width value
+     *
+     * @param integer $thumbWidth thumbnail image width
+     *
+     * @return void
+     * @access public
+     */
+    public function setThumbWidth($thumbWidth)
+    {
+        if (!filter_var($thumbWidth, FILTER_VALIDATE_INT)) {
+            throw new InvalidArgumentException(
+            "`$thumbWidth` is not an integer"
+            );
+        }
+        $this->thumbWidth = $thumbWidth;
+    }
+
+    //  }}}
+
+    /**
+     * Returns the Title
+     *
+     * @access public
+     * @return void
+     */
+    public function getTitle()
+    {
+        return $this->title;
+    }
+
+    /**
+     * Returns the Description
+     *
+     * @access public
+     * @return void
+     */
+    public function getDescr()
+    {
+        return $this->descr;
+    }
+
+    /**
+     * Sets the Title
+     *
+     * @param mixed $title
+     * @access public
+     * @return void
+     */
+    public function setTitle($title)
+    {
+        $this->title = $title;
+        return $this;
+    }
+
+    /**
+     * Sets the Description
+     *
+     * @param mixed $descr
+     * @access public
+     * @return void
+     */
+    public function setDescr($descr)
+    {
+        $this->descr = $descr;
+        return $this;
+    }
+
+}
diff --git a/Toolkit/RotatingImages/ImagesDataGridAbstract.php b/Toolkit/RotatingImages/ImagesDataGridAbstract.php
new file mode 100644 (file)
index 0000000..b20df13
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+
+/**
+ * ImagesDataGridAbstract.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_ImagesDataGridAbstract
+ *
+ * Description of Toolkit_RotatingImages_ImagesDataGridAbstract
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+abstract class Toolkit_RotatingImages_ImagesDataGridAbstract
+    extends Toolkit_FlexyDataGridBuilder
+{
+    //  {{{ properties
+
+    /**
+     * Description of $noRecMessage
+     * @var    string
+     * @access protected
+     */
+    protected $noRecMessage = 'No Images';
+
+    //  }}}
+    //  {{{ configureColumns()
+
+    /**
+     * Description for configureColumns
+     *
+     * @return void
+     */
+    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, MEDIA_APP_BASE_URL . 'assets/icons/image_edit.png'
+        );
+
+        $linkFormat = '<a href="%s?%s">%s</a>';
+        return sprintf(
+            $linkFormat, MEDIA_BASE_URL . 'admin/rotatingImages.php',
+            "app=".SLIDESHOW_APP_ID."&rt=EditImage&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, MEDIA_APP_BASE_URL . 'assets/icons/image_delete.png'
+        );
+
+        $linkFormat = '<a href="%s?%s">%s</a>';
+        return sprintf(
+            $linkFormat, MEDIA_BASE_URL . 'admin/rotatingImages.php',
+            "app=".SLIDESHOW_APP_ID."&rt=EditImage&amp;ac=delete&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" witdh="%s" height="%s" src="%s" alt="Image thumbnail">';
+        return sprintf(
+            $imgFormat, $thumb_width, $thumb_height,
+            ROTATING_IMAGE_THUMB . $image
+        );
+    }
+
+    //  }}}
+    //  {{{ toHtml()
+
+    /**
+     * Returns the DataGrid
+     *
+     * @param Structures_DataGrid_Renderer_Flexy $renderer Rendering engine used to render DG
+     * @param string                             $template Template to use
+     *
+     * @return string html templated datagrid results
+     * @access public
+     */
+    public function toHtml(
+    Structures_DataGrid_Renderer_Flexy $renderer, $template = null
+    )
+    {
+        $GLOBALS['styleSheets'][] = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8/development-bundle/themes/smoothness/jquery.ui.core.css';
+        $GLOBALS['styleSheets'][] = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8/development-bundle/themes/smoothness/jquery.ui.theme.css';
+
+        $GLOBALS['bottomScripts'][] = JQUERY_UI_CDN_JS;
+        $GLOBALS['bottomScripts'][] = MEDIA_BASE_URL . 'Toolkit/RotatingImages/libjs/sortable.js';
+
+        return parent::toHtml($renderer, $template);
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/InactiveImagesDataGrid.php b/Toolkit/RotatingImages/InactiveImagesDataGrid.php
new file mode 100644 (file)
index 0000000..bdaeb09
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * InactiveImagesDataGrid.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_InactiveImagesDataGrid
+ *
+ * Description of Toolkit_RotatingImages_InactiveImagesDataGrid
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_InactiveImagesDataGrid
+    extends Toolkit_RotatingImages_ImagesDataGridAbstract
+    implements Toolkit_RotatingImages_IImagesDataGrid
+{
+    //  {{{ setControlObject()
+
+    /**
+     * setControlObject
+     *
+     * @return void
+     */
+    protected function setControlObject()
+    {
+        $this->ctrlObj['tableId']  = 'disabled';
+        //$this->ctrlObj['noRecMessage'] = 'No Disabled Images';
+        $this->ctrlObj['gridName'] = 'Disabled Images';
+    }
+
+    //  }}}
+    //  {{{ setQuery()
+
+    /**
+     * Sets query to get inactive rotating images
+     *
+     * @return void
+     */
+    public function setQuery()
+    {
+        $sql = "
+            SELECT *
+              FROM rotating_images
+             WHERE active = false
+               AND application = " . SLIDESHOW_APP_ID;
+
+        parent::setQuery($sql);
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/IndexController.php b/Toolkit/RotatingImages/IndexController.php
new file mode 100644 (file)
index 0000000..730da74
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+
+/**
+ * IndexController.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_IndexController
+ *
+ * Description of Toolkit_RotatingImages_IndexController
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_IndexController
+    extends Toolkit_BaseControllerAbstract
+    implements Toolkit_IController
+{
+    //  {{{ indexAction()
+
+    /**
+     * Description of indexAction()
+     *
+     * @return string
+     */
+    public function indexAction()
+    {
+        $GLOBALS['styleSheets'][] = MEDIA_BASE_URL . 'Toolkit/RotatingImages/styles.css';
+
+        $flexyOptions                = $GLOBALS['flexyOptions'];
+        $flexyOptions['templateDir'] = BASE . 'Toolkit/RotatingImages/templates/';
+        $flexyOptions['compileDir']  = $flexyOptions['templateDir'] . 'compiled/';
+        $tEngine                     = new HTML_Template_Flexy($flexyOptions);
+
+        $controllerObject = new stdClass();
+
+        $controllerObject->width  = $this->registry->config->getItem('section',
+                                                                     'conf')
+            ->getItem('directive', 'width')
+            ->getContent();
+        $controllerObject->height = $this->registry->config->getItem('section',
+                                                                     'conf')
+            ->getItem('directive', 'height')
+            ->getContent();
+        $controllerObject->appId = SLIDESHOW_APP_ID;
+
+
+        $tEngine->compile('instructions.html');
+        $ret = $tEngine->bufferedOutputObject($controllerObject);
+
+        //
+        //  Settings Form
+        //
+        $settings = new Toolkit_RotatingImages_Forms_TransitionSettings(
+            'settings', 'get', 'rotatingImages.php?app=' . SLIDESHOW_APP_ID . '&ac=preview', 'preview'
+        );
+        $settings->configureForm($this->registry->dbh, $this->registry->config);
+        $ret .= $settings->toHtml($this->registry->dbh);
+
+        $previewIframe = new Toolkit_RotatingImages_PreviewIframe(
+            'rotatingImages.php?app=' . SLIDESHOW_APP_ID . '&ac=preview', 'preview'
+        );
+        $ret .= $previewIframe->toHtml();
+
+        $activeREngine = new Structures_DataGrid_Renderer_Flexy();
+        $activeREngine->setContainer($tEngine);
+        //
+        //  Active images datagrid
+        //
+        $activeDG      = new Toolkit_RotatingImages_ActiveImagesDataGrid(
+            $this->registry->dbh
+        );
+        $activeDG->setQuery();
+        $activeDG->setDefaultSort(array('pos' => 'ASC'));
+        $ret .= $activeDG->toHtml($activeREngine, 'imagesDataGrid.html');
+
+        $inactiveREngine = new Structures_DataGrid_Renderer_Flexy();
+        $inactiveREngine->setContainer($tEngine);
+        //
+        //  In-active images datagrid
+        //
+        $disabledDG      = new Toolkit_RotatingImages_InactiveImagesDataGrid(
+            $this->registry->dbh
+        );
+        $disabledDG->setQuery();
+        $disabledDG->setDefaultSort(array('pos' => 'ASC'));
+        $ret .=$disabledDG->toHtml($inactiveREngine, 'imagesDataGrid.html');
+
+        return $ret;
+    }
+
+    //  }}}
+    //  {{{ previewAction()
+
+    /**
+     * Description of previewAction
+     *
+     * @return string
+     */
+    public function previewAction()
+    {
+        try {
+            $sql = "
+                SELECT *
+                  FROM rotating_images
+                 WHERE active = true
+                   AND application = " . SLIDESHOW_APP_ID;
+
+            $images = $this->registry->dbh->query($sql, PDO::FETCH_ASSOC)->fetchAll();
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+
+        $gateway           = new Toolkit_RotatingImages_TransitionGateway($this->registry->dbh);
+        $previewJavascript = new Toolkit_RotatingImages_PreviewJavascript($gateway);
+        $javascript        = $previewJavascript->toHtml();
+        $fadingDecorator   = new Toolkit_RotatingImages_Decorator_Admin();
+        foreach ($images as $v) {
+            $image              = new Toolkit_RotatingImages_Image($v);
+            $thumbnailDecorator = new Toolkit_RotatingImages_Decorator_Thumbnail($image);
+
+            $fadingDecorator->add($thumbnailDecorator);
+        }
+
+        return $fadingDecorator->toHtml() . $javascript;
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/Navigation.php b/Toolkit/RotatingImages/Navigation.php
new file mode 100644 (file)
index 0000000..dc6eb5f
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+
+/**
+ * Navigation.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_Navigation
+ *
+ * Sets up navigation bars
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_Navigation
+    extends Toolkit_NavigationAbstract
+    implements Toolkit_INavigation
+{
+    //  {{{ __construct()
+
+    /**
+     * Class constructor
+     *
+     * @param HTML_Menu $menu
+     * @param HTML_Menu_Renderer $rEngine
+     */
+    public function __construct(
+    HTML_Menu $menu, HTML_Menu_Renderer $rEngine
+    )
+    {
+        $this->menu      = $menu;
+        $this->rEngine   = $rEngine;
+        $this->currIndex = 'listToolbox';
+    }
+
+    //  }}}
+    //  {{{ setNavTemplates()
+
+    /**
+     * Set navigation templates
+     *
+     * @return void
+     */
+    protected function setNavTemplates()
+    {
+        $tpl = '<li><a href="%s" title="%s">{Title}</a></li>';
+        $this->rEngine->setEntryTemplate(
+            HTML_MENU_ENTRY_INACTIVE,
+            sprintf($tpl, '{url}', '{desc}', '{Title}')
+        );
+        $this->rEngine->setEntryTemplate(
+            HTML_MENU_ENTRY_ACTIVE, sprintf($tpl, '{url}', '{desc}', '{Title}')
+        );
+        $this->rEngine->setEntryTemplate(
+            HTML_MENU_ENTRY_ACTIVEPATH,
+            sprintf($tpl, '{url}', '{desc}', '{Title}')
+        );
+        $this->rEngine->setMenuTemplate('', '');
+        $this->rEngine->setRowTemplate('<ul class="admin_nav">', '</ul>');
+    }
+
+    //  }}}
+    //  {{{ setCurrentIndex()
+
+    /**
+     * Sets current menu index
+     *
+     * @return void
+     */
+    protected function setCurrentIndex()
+    {
+        $this->menu->forceCurrentIndex($_GET['rt']);
+    }
+
+    //  }}}
+    //  {{{ getNavSructure()
+
+    /**
+     * Sets up a multi dimensional array used for the nav structure
+     *
+     * @param Config_Container $c Application configuration
+     *
+     * @return array navigational array hash
+     * @access public
+     */
+    public function getNavStructure(Config_Container $c)
+    {
+        //  get reference to [listing type] section of config file
+        $appName = $c->getItem('section', 'conf')
+            ->getItem('directive', 'applicationName')
+            ->getContent();
+
+        $nav = array(
+            'listImages' => array(
+                'Title' => "List Images",
+                'url'   => MEDIA_BASE_URL . 'admin/rotatingImages.php?app=' . SLIDESHOW_APP_ID,
+                'desc'  => "Display all the Images",
+            ),
+            'addImage'   => array(
+                'Title' => 'Add Image',
+                'url'   => MEDIA_BASE_URL . 'admin/rotatingImages.php?app=' . SLIDESHOW_APP_ID . '&rt=EditImage',
+                'desc'  => 'Display all the page drafts'
+            ),
+        );
+
+        return $nav;
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/NodesIterator.php b/Toolkit/RotatingImages/NodesIterator.php
new file mode 100644 (file)
index 0000000..3230eb2
--- /dev/null
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * class to iterator over available rotating image nodes
+ *
+ * PHP version 5
+ *
+ * The license text...
+ *
+ * @category  Toolkit
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: NodesIterator.php,v 1.2 2010/07/25 17:07:24 jamie Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * class to iterator over available rotating image nodes
+ *
+ * @category  Toolkit
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_RotatingImages_NodesIterator
+    implements IteratorAggregate
+{
+    //  {{{ properties
+
+    /**
+     * Node objects to iterator over
+     * @var    array
+     * @access private
+     */
+    private $_nodes;
+
+    //  }}}
+    //  {{{ __construct()
+
+    /**
+     * Constructor
+     *
+     * @return void
+     * @access public
+     */
+    public function __construct()
+    {
+        $this->_nodes = array();
+    }
+
+    //  }}}
+    //  {{{ getIterator()
+
+    /**
+     * Get the iterator
+     *
+     * @return ArrayIterator iterator for arrays
+     * @access public
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator($this->_nodes);
+    }
+
+    //  }}}
+    //  {{{ addImage()
+
+    /**
+     * Add image node object to iterator
+     *
+     * @param Toolkit_RotatingImages_Image $node node object to add to iterator
+     *
+     * @return void
+     * @access public
+     */
+    public function addImage(Toolkit_RotatingImages_Image $node)
+    {
+        $this->_nodes[] = $node;
+    }
+
+    //  }}}
+    //  {{{ getNode()
+
+    /**
+     * Get a node from the iterator
+     *
+     * @param integer $key offset to get node at
+     *
+     * @return mixed false if no nodes available, else Toolkit_RotatingImages_Image object
+     * @access public
+     * @throws InvalidArgumentException if $key is not an integer
+     */
+    public function getNode($key)
+    {
+        if (!count($this->_nodes)) {
+            return false;
+        }
+
+        if (!filter_var($key, FILTER_VALIDATE_INT)) {
+            throw new InvalidArgumentException(
+            "\$key must be an integer, `$key` given"
+            );
+        }
+
+        return $this->_nodes[$key];
+    }
+
+    //  }}}
+    //  {{{ getTotal()
+
+    /**
+     * Gets the total number of nodes in the iterator
+     *
+     * @return integer number of nodes in interator
+     *
+     * @access public
+     */
+    public function getTotal()
+    {
+        return count($this->_nodes);
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/PreviewIframe.php b/Toolkit/RotatingImages/PreviewIframe.php
new file mode 100644 (file)
index 0000000..be6d71c
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * Short description for file
+ *
+ * Long description (if any) ...
+ *
+ * PHP version 5
+ *
+ * The license text...
+ *
+ * @category  Toolkit
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   CVS: $Id: PreviewIframe.php,v 1.1 2010/07/25 17:07:24 jamie Exp $
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Short description for class
+ *
+ * Long description (if any) ...
+ *
+ * @category  Toolkit
+ * @package   Toolkit_RotatingImages
+ * @author    Jamie Kahgee <jamie@gaslightmedia.com>
+ * @copyright 2010 Jamie Kahgee
+ * @license   http://www.gaslightmedia.com/ Gaslightmedia
+ * @version   Release: @package_version@
+ * @link      <>
+ * @see       References to other sections (if any)...
+ */
+class Toolkit_RotatingImages_PreviewIframe
+{
+    //  {{{ properties
+
+    /**
+     * url of the document to show in iframe
+     * @var    string
+     * @access private
+     */
+    private $_src;
+
+    /**
+     * name of the iframe
+     * @var    string
+     * @access private
+     */
+    private $_name;
+
+    //  }}}
+    //  {{{ __construct()
+
+    /**
+     * Constructor
+     *
+     * @param string $src  URL of the document to show in ifram
+     * @param string $name name of the iframe
+     *
+     * @return void
+     * @access public
+     */
+    public function __construct($src, $name)
+    {
+        $this->_src  = $src;
+        $this->_name = $name;
+    }
+
+    //  }}}
+    //  {{{ toHtml()
+
+    /**
+     * Creates an iframe
+     *
+     * @return string html iframe tag
+     * @access public
+     */
+    public function toHtml()
+    {
+        $nonSupport = 'Your browser does not support iframes.';
+        $format     = '<iframe src="%s" name="%s" frameborder="0" marginheight="0" marginwidth="0"><p>%s</p></iframe>';
+        return sprintf($format, $this->_src, $this->_name, $nonSupport);
+    }
+
+    //  }}}
+}
diff --git a/Toolkit/RotatingImages/PreviewJavascript.php b/Toolkit/RotatingImages/PreviewJavascript.php
new file mode 100644 (file)
index 0000000..7650091
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * PreviewJavascript.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_PreviewJavascript
+ *
+ * Description of Toolkit_RotatingImages_PreviewJavascript
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_PreviewJavascript
+{
+
+    /**
+     * Transition gateway
+     *
+     * @var    Toolkit_RotatingImages_TransitionGateway
+     * @access private
+     */
+    private $_gateway;
+
+    /**
+     * Class construct
+     *
+     * @param Toolkit_RotatingImages_TransitionGateway $gateway Construct gateway
+     */
+    public function __construct(
+    Toolkit_RotatingImages_TransitionGateway $gateway
+    )
+    {
+        $this->_gateway = $gateway;
+    }
+
+    /**
+     * Description for toHtml
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        if (filter_input(INPUT_GET, 'preview')) {
+            $transitionEffect = filter_input(INPUT_GET, 'transition',
+                                             FILTER_SANITIZE_STRING);
+            $pauseTime        = filter_input(INPUT_GET, 'timeout',
+                                             FILTER_SANITIZE_NUMBER_INT);
+        } elseif (filter_input(INPUT_GET, 'apply')) {
+            $transitionEffect = filter_input(INPUT_GET, 'transition',
+                                             FILTER_SANITIZE_STRING);
+            $pauseTime        = filter_input(INPUT_GET, 'timeout',
+                                             FILTER_SANITIZE_NUMBER_INT);
+            $this->_gateway->set($transitionEffect, $pauseTime);
+        } else {
+            $effect           = $this->_gateway->get();
+            $transitionEffect = $effect['transition'];
+            $pauseTime        = $effect['timeout'];
+        }
+
+        $js = "$(window).load(function() {\n";
+        $js .= "    $('#rotatingImagesPreview').nivoSlider({\n";
+        $js .= "        effect: '$transitionEffect',\n";
+        $js .= "        pauseTime: $pauseTime * 1000,\n";
+        $js .= "        directionNav: false,\n";
+        $js .= "        controlNav: false\n";
+        $js .= "    });\n";
+        $js .= "});\n";
+
+        return "<script type=\"text/javascript\">$js</script>";
+    }
+
+}
diff --git a/Toolkit/RotatingImages/TransitionGateway.php b/Toolkit/RotatingImages/TransitionGateway.php
new file mode 100644 (file)
index 0000000..591c1cc
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * TransitionGateway.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+/**
+ * Toolkit_RotatingImages_TransitionGateway
+ *
+ * Gateway for transition of rotating images
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_RotatingImages_TransitionGateway
+{
+
+    /**
+     * PDO
+     *
+     * @var    PDO
+     * @access private
+     */
+    private $_dbh;
+
+    /**
+     * Class construct
+     *
+     * @param PDO $dbh PDO
+     */
+    public function __construcT(PDO $dbh)
+    {
+        $this->_dbh = $dbh;
+    }
+
+    /**
+     * Getting the transitions for the slideshow
+     *
+     * @return array|null
+     */
+    public function get()
+    {
+        try {
+            $sql = "
+                SELECT *
+                  FROM rotating_images_transitions
+                 WHERE application = " . SLIDESHOW_APP_ID;
+
+            return $this->_dbh->query($sql)->fetch(PDO::FETCH_ASSOC);
+        } catch (PDOException $e) {
+            Toolkit_Logger::logException('DB Error', $e);
+        }
+    }
+
+    /**
+     * Set transition type and time
+     *
+     * @param string $transition Description for transition
+     * @param int    $timeout    Description for timeout
+     *
+     * @throws RuntimeException
+     * @return void
+     */
+    public function set($transition, $timeout)
+    {
+        if (!filter_var($transition)) {
+            throw new RuntimeException("Invalid transition type `$transition`");
+        } elseif (!filter_var($timeout, FILTER_VALIDATE_INT)) {
+            throw new RuntimeException("Invalid transition timeout `$transition`");
+        }
+
+        try {
+            $sql = "
+                UPDATE rotating_images_transitions
+                   SET timeout = :timeout, transition = :transition
+                 WHERE application = " . SLIDESHOW_APP_ID;
+
+            $stmt = $this->_dbh->prepare($sql);
+            $stmt->bindParam(':transition', $transition, PDO::PARAM_STR);
+            $stmt->bindParam(':timeout', $timeout, PDO::PARAM_INT);
+
+            $stmt->execute();
+        } catch (PDOException $e) {
+            Toolkit_Logger::logException('DB Error', $e);
+        }
+    }
+
+}
diff --git a/Toolkit/RotatingImages/ajax.php b/Toolkit/RotatingImages/ajax.php
new file mode 100644 (file)
index 0000000..881e218
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * ajax.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages
+ * @author    Jamie Kahgee <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+if (!isset($_POST['action']) || $_POST['action'] != 'updateOrder'
+) {
+    return false;
+}
+
+require_once '../../setup.phtml';
+$appId = filter_var($_REQUEST['appId'], FILTER_VALIDATE_INT);
+$dbh = Toolkit_Database::getInstance();
+
+try {
+    $dbh->beginTransaction();
+    $sql = "
+        UPDATE rotating_images
+           SET active = false, pos = null
+         WHERE application = {$appId}";
+
+    $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..6eb99bc
--- /dev/null
@@ -0,0 +1,35 @@
+[conf]
+; Application Name
+applicationName = "Homepage Slideshow"
+useTitles = On
+hasPrevNextLinks = Off
+width = 720 
+height = 480
+
+; time between the fades in milliseconds
+[rotation time]
+timeout[] = 2
+timeout[] = 3
+timeout[] = 4
+timeout[] = 5
+timeout[] = 7
+timeout[] = 10
+
+; type of animation 'fade' or 'slide'
+[animation type]
+transition[] = "sliceDown"
+transition[] = "sliceDownLeft"
+transition[] = "sliceUp"
+transition[] = "sliceUpLeft"
+transition[] = "sliceUpDown"
+transition[] = "sliceUpDownLeft"
+transition[] = "fold"
+transition[] = "fade"
+transition[] = "random"
+transition[] = "slideInRight"
+transition[] = "slideInLeft"
+transition[] = "boxRandom"
+transition[] = "boxRain"
+transition[] = "boxRainReverse"
+transition[] = "boxRainGrow"
+transition[] = "boxRainGrowReverse"
\ No newline at end of file
diff --git a/Toolkit/RotatingImages/libjs/sortable.js b/Toolkit/RotatingImages/libjs/sortable.js
new file mode 100644 (file)
index 0000000..1dd1a0f
--- /dev/null
@@ -0,0 +1,45 @@
+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)
+       {
+               var $disabled = $(this).children('.ui-state-disabled');
+               if ($disabled.is('li')) {
+                       $disabled.remove();
+               }
+       },
+
+       remove: function(event, ui)
+       {
+               var $myself = $(this);
+               if ($myself.children().length == 0) {
+                       $myself.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?appId=' + appId, order+'&action=updateOrder');
+       }
+};
+
+$(document).ready(RISortable.init);
diff --git a/Toolkit/RotatingImages/libjs/user.php b/Toolkit/RotatingImages/libjs/user.php
new file mode 100644 (file)
index 0000000..7e2ce84
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+/**
+ * user.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   RotatingImages_libjs
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: $id$
+ * @link      <>
+ */
+
+require_once '../../../setup.phtml';
+$dbh = Toolkit_Database::getInstance();
+$appId = filter_var($_REQUEST['appId'], FILTER_VALIDATE_INT);
+$sql = "
+SELECT *
+  FROM rotating_images_transitions
+ WHERE application = $appId";
+$row = $dbh->query($sql)->fetch(PDO::FETCH_ASSOC);
+?>
+$(window).load(function() {
+    $('#slider').nivoSlider({
+        effect: '<?php echo $row['transition'];?>',
+        animSpeed: 1000,
+        pauseTime: <?php echo $row['timeout'] * 1000;?>
+    });
+    if ($('#slider').children('a').size() <= 1 ) {
+        $('.nivo-prevNav').css('display', 'none');
+        $('.nivo-nextNav').css('display', 'none');
+    }
+
+    $('#slideshow a.external').each(function() {
+        $(this).click(function() {
+            var $newWindow = window.open($(this).attr('href'));
+            $newWindow.focus();
+            return false;
+        });
+    });
+});
diff --git a/Toolkit/RotatingImages/styles.css b/Toolkit/RotatingImages/styles.css
new file mode 100644 (file)
index 0000000..14abe30
--- /dev/null
@@ -0,0 +1,119 @@
+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;
+}
+.dataGrid .delete {
+       line-height: 16px;
+       vertical-align: center;
+       float: right;
+       margin-top: 10px;
+}
+.dataGrid .edit {
+       line-height: 16px;
+       vertical-align: center;
+       clear: left;
+       margin-top: 10px;
+}
+.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 {
+       height: 100px;
+       width: 200px;
+       float: left;
+       overflow: hidden;
+}
+#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/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..6f91d70
--- /dev/null
@@ -0,0 +1,22 @@
+<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 class="delete">{row[Delete]:h}</div>
+                               <div class="edit">{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..a9ef25d
--- /dev/null
@@ -0,0 +1,11 @@
+<flexy:toJavascript appId="appId">
+<div id="instructions">
+<b>Instructions</b>
+<p>All images will be resized to correct size.</p>
+<p>If you want to resize the images yourself before uploading, use these dimensions:</p>
+<ul>
+<li>Width:  {width} pixels</li>
+<li>Height: {height} pixels</li>
+</ul>
+</div>
+<h2>Slideshow Settings</h2>
diff --git a/Toolkit/RotatingImages/templates/rotatingImages.html b/Toolkit/RotatingImages/templates/rotatingImages.html
new file mode 100644 (file)
index 0000000..7a63826
--- /dev/null
@@ -0,0 +1,35 @@
+<style>
+.nivo-caption {
+    background: #369 !important;
+    background: rgba(51,102,153,0.8) !important;
+    }
+.nivo-caption span {
+    float: right;
+    }
+.nivo-controlNav {
+    display: block;
+    position: absolute;
+    z-index: 999;
+    top: -10px;
+    right: 10px;
+    }
+#slider-wrapper {
+    width: 100%;
+    height: auto;
+    position: relative;
+    }
+</style>
+{if:images}
+<div id="slider-wrapper" class="slider-wrapper theme-default">
+    <div class="ribbon"></div>
+    <div id="slider" class="nivoSlider">
+    {foreach:images,image}
+        {image.toHtml():h}
+    {end:}
+    </div>
+</div>
+<div flexy:foreach="images,image" id="event-{image.getId():h}" class="nivo-html-caption">
+    {if:image.getTitle()}<strong>{image.getTitle()}</strong>{end:}
+    {if:image.getDescr()}<span>{image.getDescr()}</span>{end:}
+</div>
+{end:}
diff --git a/admin/rotatingImages.php b/admin/rotatingImages.php
new file mode 100644 (file)
index 0000000..227dae9
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+require_once '../setup.phtml';
+$application = filter_var($_REQUEST['app'], FILTER_VALIDATE_INT);
+define('SLIDESHOW_APP_ID', $application);
+$rotatingImagesConf = new Config;
+$rotatingImagesRoot =& $rotatingImagesConf->parseConfig(
+    BASE . 'Toolkit/RotatingImages/config.ini',
+    'IniFile'
+);
+
+$registry         = new Toolkit_Registry;
+$registry->dbh    = Toolkit_Database::getInstance();
+$registry->logger = Toolkit_Logger::getLogger();
+$registry->config = $rotatingImagesRoot;
+$registry->router = new Toolkit_Router($registry);
+$registry->router->setPath(BASE . 'Toolkit/RotatingImages');
+$registry->router->setApplication('RotatingImages');
+
+$navigation = new Toolkit_RotatingImages_Navigation(
+    new HTML_Menu(),
+    new HTML_Menu_DirectRenderer()
+);
+
+$navArray = $navigation->getNavStructure($rotatingImagesRoot);
+$navHtml  = $navigation->renderPageNav($navArray, 'rows');
+
+$html = $registry->router->loader();
+
+$appName
+    = $rotatingImagesRoot->getItem('section', 'conf')
+    ->getItem('directive', 'applicationName')
+    ->getContent();
+$sql = "
+SELECT name
+  FROM rotatingimages.application
+ WHERE id = :id";
+$stmt = $registry->dbh->prepare($sql);
+$stmt->bindParam(':id', $application, PDO::PARAM_INT);
+$stmt->execute();
+$appName = $stmt->fetchColumn();
+
+if (filter_input(INPUT_GET, 'ac') == 'preview') {
+    GLM_TOOLBOX::top('', '', null, false);
+    echo $html;
+    GLM_TOOLBOX::footer();
+} else {
+    GLM_TOOLBOX::top($appName, '');
+    echo $navHtml;
+    echo $html;
+    GLM_TOOLBOX::footer();
+}
+?>
index 6f27624..033cd92 100644 (file)
@@ -112,7 +112,7 @@ news.page = Off
 photo_gallery.application = On
 
 ; Turn the rotating image application On or Off
-rotating_images.application = Off
+rotating_images.application = On
 
 ; Turn the weather application On or Off
 weather.application = Off