Add Videos Application
authorSteve Sutton <steve@gaslightmedia.com>
Mon, 23 Jun 2014 19:35:51 +0000 (19:35 +0000)
committerSteve Sutton <steve@gaslightmedia.com>
Mon, 23 Jun 2014 19:35:51 +0000 (19:35 +0000)
Set featured on for application

22 files changed:
Toolkit/Videos/AdminEditVideoForm.php [new file with mode: 0644]
Toolkit/Videos/Controller.php [new file with mode: 0644]
Toolkit/Videos/Database/application.sql [new file with mode: 0644]
Toolkit/Videos/Database/removeApplication.sql [new file with mode: 0644]
Toolkit/Videos/Database/table/videos.sql [new file with mode: 0644]
Toolkit/Videos/IDecorator.php [new file with mode: 0644]
Toolkit/Videos/Navigation.php [new file with mode: 0644]
Toolkit/Videos/Video.php [new file with mode: 0644]
Toolkit/Videos/VideoMapper.php [new file with mode: 0644]
Toolkit/Videos/VideosDataGrid.php [new file with mode: 0644]
Toolkit/Videos/WebDecorator.php [new file with mode: 0644]
Toolkit/Videos/WebPageDecorator.php [new file with mode: 0644]
Toolkit/Videos/config.ini [new file with mode: 0644]
Toolkit/Videos/libjs/videos.js [new file with mode: 0644]
Toolkit/Videos/moveVideo.php [new file with mode: 0644]
Toolkit/Videos/styles.css [new file with mode: 0644]
Toolkit/Videos/templates/webDecorator.html [new file with mode: 0644]
Toolkit/Videos/templates/webPageDecorator.html [new file with mode: 0644]
Toolkit/Videos/toggleActive.php [new file with mode: 0644]
Toolkit/Videos/toggleFeatured.php [new file with mode: 0644]
admin/videos.php [new file with mode: 0644]
config/application.ini

diff --git a/Toolkit/Videos/AdminEditVideoForm.php b/Toolkit/Videos/AdminEditVideoForm.php
new file mode 100644 (file)
index 0000000..0977087
--- /dev/null
@@ -0,0 +1,309 @@
+<?php
+
+/**
+ * AdminEditVideoForm.php
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Toolkit_Videos_AdminEditVideoForm
+ *
+ * Handles the form generation and processing of the Video Edit Page
+ *
+ * @category  Toolkit
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Videos_AdminEditVideoForm
+    extends Toolkit_FormBuilder
+{
+       /**
+        * 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">Coupon 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 $errorMsg = '
+        <div id="form-warning-top">There was a Problem with your form!</div>';
+
+    /**
+     * Setup Form Constants
+     *
+     * Constants are form values (hidden) fields most likely that cannot be
+     * changed by user input
+     *
+     * @return void
+     */
+    public function configureConstants()
+    {
+        $c = array();
+        $this->setConstants($c);
+    }
+
+    /**
+     * Setup Form Defaults
+     *
+     * if $_GET['id'] is numeric then it creates a Toolkit_Videos_Video
+     * class object and gets set as form element defaults
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return void
+     */
+    public function configureDefaults(PDO $dbh)
+    {
+        $d = array();
+        if (is_numeric($_GET['id'])) {
+            $video = new Toolkit_Videos_VideoMapper($dbh);
+            $d = $video->getVideoById($_GET['id']);
+        }
+        $this->setDefaults($d);
+    }
+
+    /**
+     * Setup the Form elements
+     *
+     * @param PDO              $dbh Database Connection
+     * @param Config_Container $c   PEAR::Config_Container object
+     *
+     * @return void
+     */
+    public function configureElements(PDO $dbh, Config_Container $c)
+       {
+        $e = array();
+
+        //  get reference to [conf] section of config file
+        $appHasFeaturedVideos
+            = $c->getItem('section', 'conf')
+            ->getItem('directive', 'featuredVideos')
+            ->getContent();
+        // All Elements are created here.
+        // This includes group element definitions.
+               $e[] = array(
+            'type' => 'advcheckbox',
+            'req' => false,
+            'name' => 'active',
+                       'display' => 'Active',
+                       'val' => array(0, 1)
+        );
+        if ($appHasFeaturedVideos) {
+            $e[] = array(
+                'type' => 'advcheckbox',
+                'req' => false,
+                'name' => 'featured',
+                'display' => 'Featured',
+                'val' => array(0, 1)
+            );
+        } else {
+            $e[] = array(
+                'type' => 'hidden',
+                'req' => false,
+                'name' => 'featured'
+            );
+        }
+        $e[] = array(
+               'type' => 'text',
+               'req' => true,
+               'name' => 'video_url',
+               'display' => 'Video Link<br>
+                <span style="color:blue">
+                Click on the \'Share\' function on the YouTube video
+                <br>to get your link. If you\'re having problems click on "show options"
+                and select "long link"</span>',
+               'opts' => array('class' => 'text','size'=>50)
+        );
+               $e[] = array(
+            'type' => 'submit',
+            'req' => false,
+            'name' => 'submit_rmv',
+            'display' => 'Submit Video',
+            'opts' => array('id' => 'submit')
+        );
+        if (ctype_digit($_GET['id'])) {
+            $e[] = array(
+                'type' => 'submit',
+                'req' => false,
+                'name' => 'delete_rmv',
+                'display' => 'Delete Video',
+                'opts' => array('id' => 'delete')
+            );
+        }
+
+               $this->setupElements($e);
+       }
+
+    /**
+     * Setup Form filters
+     *
+     * @return void
+     */
+    public function configureFilters()
+       {
+        $f   = array();
+               $f[] = array(
+            'element' => '__ALL__',
+            'filter' => 'trim'
+        );
+        $f[] = array(
+            'element' => 'url',
+                       'filter' => array('Toolkit_Common', 'filterURI')
+        );
+
+               $this->setupFilters($f);
+       }
+
+    /**
+     * Runs all function to setup the Form
+     *
+     * @param PDO              $dbh Database Connection
+     * @param Config_Container $c   PEAR::Config_Container object
+     *
+     * @return void
+     */
+    public function configureForm(
+               PDO $dbh,
+               Config_Container $c
+       ) {
+               $this->configureElements($dbh, $c);
+               $this->configureFilters();
+               $this->configureRules();
+               $this->configureDefaults($dbh);
+               $this->configureConstants();
+       }
+
+    /**
+     * Setup the Form's rules
+     *
+     * @return void
+     */
+    public function configureRules()
+       {
+        $r = array();
+
+               $r[] = array(
+                       'element'    => 'video_url',
+                       'message'    => 'ERROR: Invalid URL format (http)',
+                       'type'       => 'checkURI',
+                       'format'     => array(
+                               'allowed_schemes' => array('http'),
+                               'strict' => false
+                       ),
+                       'validation' => $this->validationType,
+                       'reset'      => false,
+                       'force'      => false
+               );
+
+
+               $this->setupRules($r);
+       }
+
+    /**
+     * _processData function creates an video object Toolkit_Videos_Video
+     * if id exists it creates the object by id
+     * else it creates a new object
+     * saved is called and the object is either created or updated
+     *
+     * If the $values['id'] is given it creates a Toolkit_Videos_VideoMapper
+     * object and get the video object using the getVideoById method
+     * If not it then just creates an empty video object
+     * The object is then updated using it's accessor method and saved
+     *
+     * @param type $dbh    Database Connection
+     * @param type $values Form $values
+     *
+     * @return void
+     */
+    private function _processData($dbh, $values)
+    {
+        $videoMapper = new Toolkit_Videos_VideoMapper($dbh);
+        if ($_GET['id']) {
+            $video = $videoMapper->getVideoById($_GET['id'], false);
+        } else {
+            $video = new Toolkit_Videos_Video();
+        }
+        $video->setVideo_url($values['video_url'])
+            ->setFeatured($values['featured'])
+            ->setActive($values['active']);
+
+        $video->save($dbh);
+    }
+
+    /**
+     * Output HTML for the form
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return string|boolean
+     */
+    public function toHtml(PDO $dbh)
+    {
+       //  Handle Deleting banner.
+        if (   $this->isSubmitted()
+            && ctype_digit($_GET['id'])
+        ) {
+            if ($this->getSubmitValue('delete_rmv')) {
+                $videoMapper = new Toolkit_Videos_VideoMapper($dbh);
+                $video = $videoMapper->getVideoById($_GET['id'], false);
+                if ($video instanceof Toolkit_Videos_Video) {
+                    if ($video->delete($dbh, $is)) {
+                        return 'Video successfully deleted.';
+                    }
+                } else {
+                    //  the coupon has already been deleted or doesn't exist.
+                    return "The video has already been deleted or doesn't exists.";
+                }
+                header ('Location: videos.php');
+                return false;
+            }
+        }
+
+               $this->setupRenderers();
+               if ($this->validate()) {
+                       $this->cleanForm();
+
+                       $submitValues = $this->getSubmitValues();
+                       if ($this->_processData($dbh, $submitValues)) {
+                               $this->freeze();
+                               $output = $this->successMsg;
+                       }
+            header('Location: videos.php');
+               } elseif ($this->isSubmitted()) {
+                       $output  = $this->errorMsg;
+                       $output .= parent::toHTML();
+               } else {
+                       $output = parent::toHTML();
+               }
+               return $output;
+       }
+
+}
diff --git a/Toolkit/Videos/Controller.php b/Toolkit/Videos/Controller.php
new file mode 100644 (file)
index 0000000..d33be54
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/**
+ * Description of Controller
+ *
+ * @author steve
+ */
+class Toolkit_Videos_Controller {
+
+    protected $flexyOptions;
+
+    public function getFlexyOptions()
+    {
+        return $this->flexyOptions;
+    }
+
+    public function setFlexyOptions($flexyOptions)
+    {
+        $this->flexyOptions = $flexyOptions;
+    }
+
+    function __construct()
+    {
+        $options = $GLOBALS['flexyOptions'];
+               $options['templateDir']
+                       = dirname(__FILE__) . '/templates';
+               $options['compileDir']
+                       = dirname(__FILE__) . '/templates/compiled';
+        $this->flexyOptions = $options;
+    }
+
+    public function toHtml(PDO $dbh, Config_Container $appConf)
+    {
+        switch ($_GET['module']) {
+        case 'editVideo':
+            $form = new Toolkit_Videos_AdminEditVideoForm(
+                'edit-video'
+            );
+            $form->configureForm($dbh, $appConf);
+            $ret = $form->toHtml($dbh);
+            break;
+        case 'listVideo':
+        default:
+            $videos = new Toolkit_Videos_VideosDataGrid($dbh);
+            $videos->setConfig($appConf);
+                       $videos->setQuery();
+            $videos->setDefaultSort(array('pos' => 'ASC'));
+                       $ret .= $videos->toHtml($appConf);
+            break;
+        }
+        return $ret;
+    }
+}
+?>
diff --git a/Toolkit/Videos/Database/application.sql b/Toolkit/Videos/Database/application.sql
new file mode 100644 (file)
index 0000000..178e2fd
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- setup schema
+--
+
+CREATE SCHEMA videos;
+GRANT ALL ON SCHEMA videos TO nobody;
+
+--
+-- Tables
+--
+
+\i ./table/videos.sql
diff --git a/Toolkit/Videos/Database/removeApplication.sql b/Toolkit/Videos/Database/removeApplication.sql
new file mode 100644 (file)
index 0000000..6c60d9c
--- /dev/null
@@ -0,0 +1,6 @@
+--
+-- Drops schema
+-- WARNING: CANNOT BE UNDONE
+--
+
+DROP SCHEMA IF EXISTS videos CASCADE;
\ No newline at end of file
diff --git a/Toolkit/Videos/Database/table/videos.sql b/Toolkit/Videos/Database/table/videos.sql
new file mode 100644 (file)
index 0000000..0411150
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE videos.videos (
+    id SERIAL,
+    create_date DATE DEFAULT current_date,
+    video_url TEXT,
+    active BOOLEAN,
+    featured BOOLEAN,
+    pos INT DEFAULT 1,
+    PRIMARY KEY (id)
+);
+
+GRANT ALL ON videos.videos TO nobody;
+GRANT ALL ON videos.videos_id_seq TO nobody;
\ No newline at end of file
diff --git a/Toolkit/Videos/IDecorator.php b/Toolkit/Videos/IDecorator.php
new file mode 100644 (file)
index 0000000..1095b2d
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * IDecorator.php
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Toolkit_Videos_IDecorator
+ *
+ * Inteface class for the Toolkit_Videos_Decorators
+ * In future there may be more decorators here we're insurring that they have
+ * simular API's
+ *
+ * @category  Toolkit
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+interface Toolkit_Videos_IDecorator
+{
+     /**
+     * Class Constructor
+     *
+     * @return void
+     */
+    public function __construct();
+
+    /**
+     * Handles setting up the PEAR::HTML_Template_Flexy options
+     *
+     * @return void
+     */
+    public function setFlexyOptions();
+    /**
+     * Handles creating HTML output
+     *
+     * @param PDO    $dbh     Database Connection
+     * @param object $gateway Gateway Object
+     *
+     * @return string
+     */
+    public function toHtml(
+        PDO $dbh,
+        $gateway = null
+    );
+}
diff --git a/Toolkit/Videos/Navigation.php b/Toolkit/Videos/Navigation.php
new file mode 100644 (file)
index 0000000..0428d7a
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * Navigation.php
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Toolkit_Videos_Navigation
+ *
+ * Handles the navigation for the Video admin side
+ *
+ * @category  Toolkit
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Videos_Navigation
+    extends Toolkit_NavigationAbstract
+       implements Toolkit_INavigation
+{
+       //      {{{     __construct()
+
+    /**
+     * Class Constructor
+     *
+     * @param HTML_Menu          $menu    Menu to use
+     * @param HTML_Menu_Renderer $rEngine Render to use
+     *
+     * @return void
+     */
+       public function __construct(
+               HTML_Menu $menu,
+               HTML_Menu_Renderer $rEngine
+       ) {
+               $this->menu      = $menu;
+               $this->rEngine   = $rEngine;
+               $this->currIndex = 'listCoupons';
+       }
+
+    /**
+     * Create templates for the navigation
+     *
+     * @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>');
+       }
+
+    /**
+     * force the current index to $_GET['page']
+     *
+     * @return void
+     */
+       protected function setCurrentIndex()
+       {
+               $this->menu->forceCurrentIndex($_GET['page']);
+       }
+
+       //      }}}
+       //      {{{     getNavSructure()
+       //      @codeCoverageIgnoreStart
+
+    /**
+     * 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
+        $singularType = $c->getItem('section', 'listing type')
+                         ->getItem('directive', 'singular')
+                         ->getContent();
+        $pluralType = $c->getItem('section', 'listing type')
+                         ->getItem('directive', 'plural')
+                         ->getContent();
+
+               $nav = array(
+                       'listVideos' => array(
+                               'Title' => "List {$pluralType}",
+                               'url' => MEDIA_BASE_URL . 'admin/videos.php?page=listVideos&amp;module=listVideos',
+                               'desc' => "Display all the {$pluralType}",
+                       ),
+                       'editVideo' => array(
+                               'Title' => "Add {$singularType}",
+                               'url' => MEDIA_BASE_URL . 'admin/videos.php?page=editVideo&amp;module=editVideo',
+                               'desc' => "Edit a {$singularType}"
+                       ),
+               );
+
+               return $nav;
+       }
+
+       //      @codeCoverageIgnoreEnd
+}
diff --git a/Toolkit/Videos/Video.php b/Toolkit/Videos/Video.php
new file mode 100644 (file)
index 0000000..8e5f6e3
--- /dev/null
@@ -0,0 +1,346 @@
+<?php
+
+/**
+ * Video.php
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Toolkit_Videos_Video
+ *
+ * Object Data pattern class for the Video PDO Table
+ *
+ * @category  Toolkit
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Videos_Video
+{
+
+    protected $id;
+    protected $video_url;
+    protected $pos;
+    protected $featured;
+    protected $active;
+
+    /**
+     * Handles the work of Inserting a video record into the database
+     * returns the id for the new record
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return int
+     */
+    private function _insert(PDO $dbh)
+    {
+        $classData = $this->getClassAsArray();
+        unset($classData['id']);
+        $pos = $this->getMaxPos();
+        $classData['pos'] = ++$pos;
+        $sql = Toolkit_Common::createSQLInsert(
+            'videos',
+            array_keys($classData)
+        );
+        $sql .= " RETURNING id";
+        $stmt = Toolkit_Common::prepareQuery(
+            $dbh,
+            'videos',
+            $sql,
+            $classData
+        );
+        $stmt->execute();
+        return $stmt->fetchColumn();
+    }
+
+    /**
+     * Handles the update of the record on the database record
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return int
+     */
+    private function _update(PDO $dbh)
+    {
+        $classData = $this->getClassAsArray();
+        $sql = Toolkit_Common::createSQLUpdate(
+            'videos',
+            array_keys($classData),
+            array('id = :id')
+        );
+        return Toolkit_Common::processQuery(
+            $dbh,
+            'videos',
+            $sql,
+            $classData
+        );
+    }
+
+    /**
+     * Handles the deletion of the record in the database and reordering
+     * any other videos in the table
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return void
+     */
+    public function delete(PDO $dbh)
+    {
+        try {
+            $dbh->beginTransaction();
+            $sql = "
+            DELETE
+              FROM videos
+             WHERE id = :id";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(
+                ':id',
+                $this->getId(),
+                PDO::PARAM_INT
+            );
+            $stmt->execute();
+            // we have to reorder the positions for the rest of the videos
+            $sql = "
+            UPDATE videos
+               SET pos = pos - 1
+             WHERE pos >= :oldpos";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':oldpos', $this->getPos(), PDO::PARAM_INT);
+            $stmt->execute();
+            $dbh->commit();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    /**
+     * active getter
+     *
+     * @return boolean
+     */
+    public function getActive()
+    {
+        return $this->active;
+    }
+
+    /**
+     * active setter the given values is cast to a boolean value
+     * so if you send in a string 'true' or 'false' both will be cast to true
+     *
+     * @param boolean $active Active flag
+     *
+     * @return Toolkit_Videos_Video
+     */
+    public function setActive($active)
+    {
+        $this->active = (bool)$active;
+        return $this;
+    }
+
+    /**
+     * id getter
+     *
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * id setter
+     *
+     * @param int $id integer for the record id
+     *
+     * @return Toolkit_Videos_Video
+     */
+    public function setId($id)
+    {
+        if (!$this->id) {
+            $this->id = $id;
+        }
+        return $this;
+    }
+
+    /**
+     * video_url getter
+     *
+     * @return string
+     */
+    public function getVideo_url()
+    {
+        return $this->video_url;
+    }
+
+    /**
+     * video_url settur
+     *
+     * @param string $video_url the youtube video url
+     *
+     * @return Toolkit_Videos_Video
+     */
+    public function setVideo_url($video_url)
+    {
+        $this->video_url = $video_url;
+        return $this;
+    }
+
+    /**
+     * pos getter
+     *
+     * @return int
+     */
+    public function getPos()
+    {
+        return $this->pos;
+    }
+
+    /**
+     * pos setter
+     *
+     * @param type $pos Position number for the video
+     *
+     * @return Toolkit_Videos_Video
+     */
+    public function setPos($pos)
+    {
+        $this->pos = $pos;
+        return $this;
+    }
+
+    /**
+     * featured getter
+     *
+     * @return boolean
+     */
+    public function getFeatured()
+    {
+        return $this->featured;
+    }
+
+    /**
+     * featured setter needs to be boolean not a string
+     *
+     * @param boolean $featured Featured flag
+     *
+     * @return Toolkit_Videos_Video
+     */
+    public function setFeatured($featured)
+    {
+        $this->featured = (bool)$featured;
+        return $this;
+    }
+
+    /**
+     * Handles the saving of the object to the database
+     *
+     * If the object has an id field set then update the record or else
+     * create a new one
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return void
+     */
+    public function save(PDO $dbh)
+    {
+        if ($this->getId()) {
+            $this->_update($dbh);
+        } else {
+            $this->_insert($dbh);
+        }
+    }
+
+    /**
+     * Create an array of the class fields
+     *
+     * @return array
+     */
+    public function getClassAsArray()
+    {
+        $data = array();
+        $classData = get_class_vars(get_class($this));
+        foreach ($classData as $fieldName => $element) {
+            $getFunc = 'get' . ucfirst($fieldName);
+            $data[$fieldName] = $this->$getFunc();
+        }
+        return $data;
+    }
+
+    /**
+     * Get the max position for the videos
+     *
+     * @staticvar int $maxPos position of the video
+     * @return int
+     */
+    public function getMaxPos()
+    {
+        static $maxPos;
+        if (!$maxPos) {
+            $dbh = Toolkit_Database::getInstance();
+            $sql = "
+            SELECT count(id) as maxpos
+              FROM videos";
+            $ret = $dbh->query($sql);
+            $maxPos = $ret->fetchColumn();
+        }
+        return (int)$maxPos;
+    }
+
+    /**
+     * Create the youtube url
+     *
+     * Using preg_match on two pattern to return the video url portion
+     * first is /v=(.*)$/ older style
+     * second is /youtu.be\/(.*)/
+     * These may need to be updated if youtube creates newer embed codes
+     *
+     * @return boolean
+     */
+    public function getVideoCode()
+    {
+        $pattern  = '/v=(.*)$/';
+        $pattern2 = '/youtu.be\/(.*)/';
+        $vidUrl = $this->getVideo_url();
+        if (preg_match($pattern, $vidUrl, $match)) {
+            return $match[1];
+        } else if (preg_match($pattern2, $vidUrl, $match)) {
+            return $match[1];
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Using the youtube API get the video title for the embed url
+     *
+     * @return string
+     */
+    public function getVideoTitle()
+    {
+        $url = "http://gdata.youtube.com/feeds/api/videos/". $this->getVideoCode();
+        $ch          = curl_init();
+        $curlOptions = array(
+                CURLOPT_URL            => $url,
+                CURLOPT_HEADER         => 0,
+                CURLOPT_RETURNTRANSFER => 1
+                );
+        curl_setopt_array($ch, $curlOptions);
+
+        $response = curl_exec($ch);
+        curl_close($ch);
+        $doc   = new DOMDocument;
+        $doc->loadXML($response);
+        $title = $doc->getElementsByTagName("title")->item(0)->nodeValue;
+        return $title;
+    }
+
+}
diff --git a/Toolkit/Videos/VideoMapper.php b/Toolkit/Videos/VideoMapper.php
new file mode 100644 (file)
index 0000000..2a00c87
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * Video.php
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Toolkit_Videos_Video
+ *
+ * Object Mapper pattern class for the Video PDO Table. Creates
+ * Toolkit_Video_Video objects by values or by id
+ *
+ * @category  Toolkit
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Videos_VideoMapper
+{
+
+    /**
+     * Class Constructor
+     *
+     * @param PDO $pdo Database Connection
+     */
+    function __construct(PDO $pdo)
+    {
+        $this->dbh = $pdo;
+    }
+
+    /**
+     * Creates Video object by a given array of values
+     * values must be set with the Videos fields as keys
+     *
+     * @param array $values array of values
+     *
+     * @return Toolkit_Videos_Video
+     */
+    public function createByValues($values)
+    {
+        $video = new Toolkit_Videos_Video();
+        $video->setId($values['id'])
+            ->setVideo_url($values['video_url'])
+            ->setActive($values['active'])
+            ->setfeatured($values['featured'])
+            ->setPos($this->getMaxPos());
+        return $video;
+    }
+
+    public function getMaxPos()
+    {
+        $dbh = Toolkit_Database::getInstance();
+        $sql = "
+        SELECT count(id) as maxpos
+            FROM videos";
+        $ret = $dbh->query($sql);
+        $maxPos = $ret->fetchColumn();
+        if ((int) $maxPos == 0) {
+            $maxPos = 1;
+        }
+        return $maxPos;
+    }
+    /**
+     * Create Video object by a given id
+     * if the id is not found then it does not return
+     *
+     * @param int   $id          id for the video record
+     * @param array $returnArray Can return the array instead of object
+     *
+     * @return mixed
+     */
+    public function getVideoById($id, $returnArray = true)
+    {
+        try {
+            $sql = "
+            SELECT *
+              FROM videos
+             WHERE id = :id";
+            $stmt = $this->dbh->prepare($sql);
+            $stmt->bindParam(
+                ':id', $id, PDO::PARAM_INT
+            );
+            $stmt->execute();
+            $res = $stmt->fetch(PDO::FETCH_ASSOC);
+            if ($res) {
+                $video = new Toolkit_Videos_Video();
+                $video->setId($res['id'])
+                    ->setVideo_url($res['video_url'])
+                    ->setActive($res['active'])
+                    ->setfeatured($res['featured'])
+                    ->setPos($res['pos']);
+                return ($returnArray)
+                    ? $video->getClassAsArray()
+                    : $video;
+            }
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+    
+}
diff --git a/Toolkit/Videos/VideosDataGrid.php b/Toolkit/Videos/VideosDataGrid.php
new file mode 100644 (file)
index 0000000..f2403e8
--- /dev/null
@@ -0,0 +1,300 @@
+<?php
+
+/**
+ * VideosDataGrid.php
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license     http://www.gaslightmedia.com Gaslightmedia
+ * @link        http://demo.gaslightmedia.com
+ */
+
+/**
+ * Toolkit_Videos_VideosDataGrid
+ *
+ * Handles the listing of the videos using the PEAR::Structures_DataGrid
+ * extended from our class Toolkit_DataGridBuilder
+ *
+ * @category  Toolkit
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight media
+ * @license      http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Videos_VideosDataGrid
+    extends Toolkit_DataGridBuilder
+{
+
+    /**
+     * Description for protected
+     * @var    string
+     * @access protected
+     */
+       protected $noRecMessage = 'No Videos Found.';
+
+    protected $config;
+
+    /**
+     * Set the config
+     *
+     * @param Config_Container $config
+     */
+    public function setConfig(Config_Container $config)
+    {
+        $this->config = $config;
+    }
+
+    /**
+     * Configure the columns for the datagrid
+     *
+     * @param Config_Container $c PEAR::Config_Container object
+     *
+     * @return void
+     * @access protected
+     */
+       protected function configureColumns()
+       {
+        //  get reference to [conf] section of config file
+        $appHasFeaturedVideos
+            = $this->config->getItem('section', 'conf')
+            ->getItem('directive', 'featuredVideos')
+            ->getContent();
+
+        $this->addColumn(
+            new Structures_DataGrid_Column(
+                       'Function',
+            null,
+            null,
+            array('class' => 'editLink'),
+            null,
+            array(&$this, 'renderEditLink')
+            )
+        );
+
+        $this->addColumn(
+            new Structures_DataGrid_Column(
+            'Active',
+            null,
+            null,
+            null,
+            null,
+            array($this, 'renderActive')
+            )
+        );
+
+        if ($appHasFeaturedVideos) {
+            $this->addColumn(
+                new Structures_DataGrid_Column(
+                'Featured',
+                null,
+                null,
+                null,
+                null,
+                array($this, 'renderFeatured')
+                )
+            );
+        }
+
+        $this->addColumn(
+            new Structures_DataGrid_Column(
+            'Position',
+            null,
+            null,
+            null,
+            null,
+            array($this, 'renderPos')
+            )
+        );
+
+        $this->addColumn(
+            new Structures_DataGrid_Column(
+            'Video Url',
+            'video_url',
+            null
+            )
+        );
+
+        $this->addColumn(
+            new Structures_DataGrid_Column(
+            'Thumbnail',
+            null,
+            null,
+            null,
+            null,
+            array($this, 'renderThumbNail')
+            )
+        );
+       }
+
+    /**
+     * Get the max position for the videos for generating a drop down for
+     * reordering them in the datagrid
+     *
+     * @staticvar type $maxPos
+     * @return int
+     */
+    public function getMaxPos()
+    {
+        static $maxPos;
+        if (!$maxPos) {
+            $dbh = Toolkit_Database::getInstance();
+            $sql = "
+            SELECT count(id) as maxpos
+              FROM videos";
+            $ret = $dbh->query($sql);
+            $row = $ret->fetch(PDO::FETCH_ASSOC);
+            if ((int)$row['maxpos'] == 0) {
+                $maxPos = 1;
+            } else {
+                $maxPos = $row['maxpos'];
+            }
+        }
+        return (int)$maxPos;
+    }
+
+    /**
+     * Render the edit link for a category
+     *
+     * @param array $data DB record
+     *
+     * @return mixed Link to edit a category
+     * @access public
+     */
+       public function renderEditLink($data)
+       {
+               extract($data['record']);
+               $link = '<a href="%sadmin/videos.php?page=editVideo&amp;module=editVideo&amp;id=%s">Edit</a>';
+               return sprintf($link, MEDIA_BASE_URL, $id);
+       }
+
+    /**
+     * Handles rendering the pos column
+     *
+     * @param type $data Data array
+     *
+     * @return string
+     */
+    public function renderPos($data)
+    {
+        extract($data['record']);
+        $html = '<select name="position" rel="'.$id.'" class="posSelect">';
+        $maxPos = $this->getMaxPos();
+        for ($i = 1; $i <= $maxPos; ++$i) {
+            $html .= '<option value="'.$i.'"';
+            if ($pos == $i) {
+                $html .= ' selected="selected"';
+            }
+            $html .= '>'.$i.'</option>';
+        }
+        $html .= '</select>';
+        return $html;
+    }
+
+    /**
+     * Handles rendering the thumbnail column
+     *
+     * @param type $data Data array
+     *
+     * @return string
+     */
+    public function renderThumbNail($data)
+    {
+        extract($data['record']);
+        $pattern = '/v=(.*)/';
+        $pattern2 = '/youtu.be\/(.*)/';
+        if (preg_match($pattern, $video_url, $match)) {
+            $vidCode = $match[1];
+        } else if (preg_match($pattern2, $video_url, $match)) {
+            $vidCode = $match[1];
+        }
+        $thumb = ($vidCode)
+            ? '<a href="http://www.youtube.com/embed/'.$vidCode.'?rel=0" class="colorbox"><img src="http://img.youtube.com/vi/'.$vidCode.'/default.jpg"></a>'
+            : '';
+        return $thumb;
+    }
+
+    /**
+     * Handles rendering the active column
+     *
+     * @param type $data Data array
+     *
+     * @return string
+     */
+    public function renderActive($data)
+    {
+        $active = $data['record']['active'];
+        $link   = MEDIA_BASE_URL . 'video-active-toggle/'.$data['record']['id'].'/';
+        $ball
+            = ($active)
+            ? 'grnball.gif'
+            : 'redball.gif';
+        $html = sprintf(
+            '<a href="%s"><img border="0" src="%sToolkit/Toolbox/assets/%s"></a>',
+            $link,
+            MEDIA_BASE_URL,
+            $ball
+        );
+        return $html;
+    }
+
+    /**
+     * Handles rendering the featured column
+     *
+     * @param type $data Data array
+     *
+     * @return type
+     */
+    public function renderFeatured($data)
+    {
+        $featured = $data['record']['featured'];
+        $link   = MEDIA_BASE_URL . 'video-featured-toggle/'.$data['record']['id'].'/';
+        $ball
+            = ($featured)
+            ? 'grnball.gif'
+            : 'redball.gif';
+        $html = sprintf(
+            '<a href="%s"><img border="0" src="%sToolkit/Toolbox/assets/%s"></a>',
+            $link,
+            MEDIA_BASE_URL,
+            $ball
+        );
+        return $html;
+    }
+
+    /**
+     * Handles setting the query for the datagrid
+     *
+     * @return void
+     */
+       public function setQuery()
+       {
+               $sql = "
+                       SELECT *
+              FROM videos";
+
+               parent::setQuery($sql);
+       }
+
+    /**
+     * Handles creation of the HTML for the datagrid
+     *
+     * @return string
+     */
+       public function toHtml()
+       {
+               $GLOBALS['styleSheets'][]
+            = MEDIA_BASE_URL . 'Toolkit/Videos/styles.css';
+        $GLOBALS['styleSheets'][]
+            = MEDIA_APP_BASE_URL . 'gallery/colorbox/colorbox.css';
+        $GLOBALS['bottomScripts'][]
+            = MEDIA_APP_BASE_URL . 'libjs/plugins/colorbox/1.3.15/jquery.colorbox-min.js';
+        $GLOBALS['bottomScripts'][]
+            = MEDIA_BASE_URL . 'Toolkit/Videos/libjs/videos.js';
+               return parent::toHTML();
+       }
+
+}
diff --git a/Toolkit/Videos/WebDecorator.php b/Toolkit/Videos/WebDecorator.php
new file mode 100644 (file)
index 0000000..50c2092
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * WebDecorator.php
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+
+/**
+ * Toolkit_Videos_WebDecorator
+ *
+ * Handles the listing of the videos using the PEAR::Structures_DataGrid
+ * extended from our class Toolkit_DataGridBuilder
+ *
+ * @category  Toolkit
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2008 Gaslight media
+ * @license   http://www.gaslightmedia.com Gaslightmedia
+ * @link      http://demo.gaslightmedia.com
+ */
+class Toolkit_Videos_WebDecorator
+    implements Toolkit_Videos_IDecorator
+{
+
+    private $_flexyOptions = array();
+    private $_template = 'webDecorator.html';
+    
+    /**
+     * Class Constructor
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        $this->setFlexyOptions();
+    }
+
+    /**
+     * Handles setting the flexyOptions
+     *
+     * @return void
+     */
+    public function setFlexyOptions()
+    {
+        $this->_flexyOptions = $GLOBALS['flexyOptions'];
+        $this->_flexyOptions['templateDir']
+            = BASE . 'Toolkit/Videos/templates';
+        $this->_flexyOptions['compileDir']
+            = BASE . 'Toolkit/Videos/templates/compiled';
+    }
+
+    /**
+     * Handles HTML output
+     *
+     * @param PDO  $dbh     Database Connection
+     * @param type $gateway Gateway object
+     *
+     * @return boolean
+     */
+    public function toHtml(
+        PDO $dbh,
+        $gateway = null
+    ) {
+        try {
+            $sql = "
+              SELECT id
+                FROM videos
+               WHERE featured = true
+            ORDER BY pos
+               LIMIT 1
+              OFFSET 0";
+            $row = $dbh->query($sql)->fetch(PDO::FETCH_ASSOC);
+            if ($row) {
+                $tpl  = new HTML_Template_Flexy($this->_flexyOptions);
+                $page = new stdClass;
+                $page->videoUrl = Toolkit_Template_Page::getSeoUrl($gateway, 189);
+                $videoMapper
+                    = new Toolkit_Videos_VideoMapper($dbh);
+                $video = $videoMapper->getVideoById($row['id'], false);
+                if ($video) {
+                    $page->vCode = $video->getVideoCode();
+                    $page->title = $video->getVideoTitle();
+                }
+
+                $tpl->compile($this->_template);
+                return $tpl->bufferedOutputObject($page);
+            } else {
+                return false;
+            }
+        } catch(PDOException $e) {
+            Toolkit_Common::handle_error($e);
+        }
+    }
+
+}
diff --git a/Toolkit/Videos/WebPageDecorator.php b/Toolkit/Videos/WebPageDecorator.php
new file mode 100644 (file)
index 0000000..689f220
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+/**
+ * WebPageDecorator
+ *
+ * PHP version 5
+ *
+ * @category  Category
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: Display.php,v 1.10 2010/07/04 23:55:12 jamie Exp $
+ * @link      <>
+ */
+
+/**
+ * WebPageDecorator
+ *
+ * Description of class
+ *
+ * @category  Category
+ * @package   Videos
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2009 Gaslight Media
+ * @license   Gaslight Media
+ * @link      <>
+ */
+class Toolkit_Videos_WebPageDecorator implements Toolkit_Videos_IDecorator
+{
+    private $_flexyOptions = array();
+    private $_template = 'webPageDecorator.html';
+    private $_perRow   = 5;
+
+    public function __construct()
+    {
+        $this->setFlexyOptions();
+    }
+
+    public function setFlexyOptions()
+    {
+        $this->_flexyOptions = $GLOBALS['flexyOptions'];
+        $this->_flexyOptions['templateDir']
+            = BASE . 'Toolkit/Videos/templates';
+        $this->_flexyOptions['compileDir']
+            = BASE . 'Toolkit/Videos/templates/compiled';
+    }
+
+    public function toHtml(
+        PDO $dbh,
+        $gateway = null
+    ) {
+        $GLOBALS['styleSheets'][]
+            = MEDIA_APP_BASE_URL . 'gallery/colorbox/colorbox.css';
+        $GLOBALS['bottomScripts'][]
+            = MEDIA_APP_BASE_URL . 'libjs/plugins/colorbox/1.3.15/jquery.colorbox-min.js';
+        $GLOBALS['bottomScripts'][]
+            = MEDIA_BASE_URL . 'Toolkit/Videos/libjs/videos.js';
+        $dbh = Toolkit_Database::getInstance();
+        $sql = "
+          SELECT id
+            FROM videos
+           WHERE active = true
+        ORDER BY pos";
+        $stmt = $dbh->query($sql);
+        $page = new stdClass;
+        $page->videos = array();
+        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+            $videoMapper
+                = new Toolkit_Videos_VideoMapper($dbh);
+            $video = $videoMapper->getVideoById($row['id'], false);
+            if ($video) {
+                $page->videos[] = array(
+                    'title' => $video->getVideoTitle(),
+                    'code'  => $video->getVideoCode()
+                );
+            }
+        }
+        $count = 1;
+        $trueCount = 1;
+        $num = count($page->videos);
+        foreach ($page->videos as &$row) {
+            $row['firstInRow'] = ($count == 1);
+            if ($count == $this->_perRow || $trueCount == $num) {
+                $row['lastInRow'] = true;
+                $count = 0;
+            } else {
+                $row['lastInRow'] = false;
+            }
+            ++$count;
+            ++$trueCount;
+        }
+        $tpl  = new HTML_Template_Flexy($this->_flexyOptions);
+        $tpl->compile($this->_template);
+        return $out  . $tpl->bufferedOutputObject($page);
+    }
+}
diff --git a/Toolkit/Videos/config.ini b/Toolkit/Videos/config.ini
new file mode 100644 (file)
index 0000000..af80382
--- /dev/null
@@ -0,0 +1,7 @@
+[conf]
+applicationName = "Videos"
+featuredVideos = On
+
+[listing type]
+singular = "Video"
+plural = "Videos"
diff --git a/Toolkit/Videos/libjs/videos.js b/Toolkit/Videos/libjs/videos.js
new file mode 100644 (file)
index 0000000..6080caf
--- /dev/null
@@ -0,0 +1,14 @@
+var GLMColorBox = {
+    init: function() {
+        $('a.colorbox').colorbox({iframe: true, innerWidth:425, innerHeight:344});
+        $('select.posSelect').each(function () {
+            $(this).change(function(){
+                var id = $(this).attr('rel');
+                var newpos = $(this).attr('value');
+                window.location.href = '../video-move/' + id + '/' + newpos + '/';
+            });
+        });
+    }
+};
+
+$(document).ready(GLMColorBox.init);
diff --git a/Toolkit/Videos/moveVideo.php b/Toolkit/Videos/moveVideo.php
new file mode 100644 (file)
index 0000000..74e4f49
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * VideosDataGrid.php
+ *
+ * Handles moving the video positions
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+if (!isset($_GET['kpass'])) {
+       die();
+}
+require_once '../../setup.phtml';
+
+$dbh    = Toolkit_Database::getInstance();
+$newpos = $_REQUEST['newpos'];
+$id     = $_REQUEST['id'];
+$error  = false;
+try {
+    $dbh->beginTransaction();
+    $sql = "
+    SELECT pos
+      FROM videos
+     WHERE id = :id";
+    $stmt = $dbh->prepare($sql);
+    $stmt->bindParam(
+        ":id", $_REQUEST['id'], PDO::PARAM_INT
+    );
+    $stmt->execute();
+    $oldpos = $stmt->fetchColumn();
+    if ($oldpos < $newpos) {
+       $sql = "
+        UPDATE videos
+           SET pos = pos - 1
+         WHERE pos BETWEEN :oldpos AND :newpos";
+        $updateStmt = $dbh->prepare($sql);
+    } else if ($oldpos > $newpos) {
+        $sql = "
+        UPDATE videos
+           SET pos = pos + 1
+         WHERE pos BETWEEN :newpos AND :oldpos";
+        $updateStmt = $dbh->prepare($sql);
+    } else {
+        $error = true;
+    }
+
+    if (!$error) {
+        $updateStmt->bindParam(
+            ':newpos', $newpos, PDO::PARAM_INT
+        );
+        $updateStmt->bindParam(
+            ':oldpos', $oldpos, PDO::PARAM_INT
+        );
+        $updateStmt->execute();
+        // now change the real video to its position
+        $sql = "
+        UPDATE videos
+           SET pos = :pos
+         WHERE id = :id";
+        $stmt = $dbh->prepare($sql);
+        $stmt->bindParam(
+            ':pos', $newpos, PDO::PARAM_INT
+        );
+        $stmt->bindParam(
+            ':id', $id, PDO::PARAM_INT
+        );
+        $stmt->execute();
+    }
+    $dbh->commit();
+} catch (PDOException $e) {
+       $dbh->rollback();
+    Toolkit_Logger::logException('DB Error', $e);
+}
+
+header('Location: '.MEDIA_BASE_URL.'admin/videos.php');
diff --git a/Toolkit/Videos/styles.css b/Toolkit/Videos/styles.css
new file mode 100644 (file)
index 0000000..cc82e07
--- /dev/null
@@ -0,0 +1,154 @@
+#form-warning-top {
+       color: #FF0000;
+       font-size: 14px;
+       font-weight: bold;
+       margin-bottom: 0.5em;
+       margin-top: 1em;
+}
+.required, .req {
+       color: #FF0000;
+}
+.group {
+       display: -moz-inline-box;
+       width: 100%;
+}
+.group td {
+       width: 324px;
+}
+.requiredNote {
+       text-align: center;
+}
+#contact {
+       margin: 10px;
+}
+#contact table {
+       background-color: #FFFFFF;
+       border: 1px solid #EEEEEE;
+       border-collapse: collapse;
+}
+#contact td {
+       border: 1px solid #EEEEEE;
+       border-collapse: collapse;
+       color: #000000;
+       font-family: arial, helvetica, sans-serif;
+       padding: 3px;
+       font-size: 12px;
+}
+.labelcell {
+       background-color: transparent;
+       padding-right: 10px;
+       padding-top: 3px;
+       text-align: right;
+       white-space: nowrap;
+       width: 140px;
+}
+.fieldcell {
+       padding-left: 4px;
+       width: 320px;
+}
+.fieldcell .text {
+       width: 90%;
+}
+#contact table.group {
+       font-size: 10px;
+       border: none;
+       padding-top: 4px;
+}
+#contact table.group td {
+       border: none;
+}
+#contact .hdr {
+       background-color: #999999;
+       border: 1px solid #666666;
+       font-weight: bold;
+}
+.paging {
+       text-align: center;
+       background-color: #F6F6F6;
+       border-color: #E86a10;
+       border-color: #296DC0;
+       border-style: solid;
+       border-width: 1px 0;
+       margin: 1.0em 0;
+       padding: 8px 0;
+       text-align: center;
+       width: 100%;
+       font-size: 12px;
+       
+}
+.paging b {
+       border: 1px solid #b22c2c;
+       border: 1px solid #E86A10;
+       background: #FFF;
+       padding: 5px 7px;
+       margin: 0 5px;
+}
+.paging a {
+       background: #FFF;
+       border: 1px solid #CCC;
+       padding: 5px 7px;
+       text-decoration: none;
+       font-family: helvetica, times;
+       color: #000;
+       margin: 0 5px;
+}
+.paging a:hover {
+       border: 1px solid #999;
+       border: 1px solid #b22c2c;
+       border: 1px solid #E86A10;
+}
+#dataGrid {
+       margin: 10px auto;
+       border: 1px solid #296DC0;
+       width: 100%;
+       border-collapse: collapse;
+}
+#dataGrid thead th {
+       background: #296DC0;
+       border: 1px solid #1b4880;
+       color: #000;
+       font-weight: normal;
+}
+#dataGrid th a {
+       font-weight: bolder;
+       color: #000;
+       text-decoration: none;
+}
+#dataGrid th a:hover {
+       color: #E86A10;
+       text-decoration: underline;
+}
+#dataGrid tr {
+       border: 1px solid #296DC0;
+       border-collapse: collapse;
+}
+#dataGrid tbody tr td {
+       padding: 5px;
+}
+#dataGrid .editLink, #dataGrid .delLink,
+#dataGrid .mailLink, #dataGrid .dateLink,
+#dataGrid .posLink {
+       text-align: center;
+}
+img.status {
+       border: none;
+}
+.even {
+       background-color: #D9D9D9;
+}
+#gridSorter {
+       margin: 0 auto;
+       padding: 10px;
+       text-align: center;
+       border: 1px solid #296DC0;
+}
+#gridSorter table {
+       border: none;
+}
+#gridSorter td {
+       border: none;
+}
+.fieldcell textarea {
+       width: 90%;
+       height: 70px;
+}
diff --git a/Toolkit/Videos/templates/webDecorator.html b/Toolkit/Videos/templates/webDecorator.html
new file mode 100644 (file)
index 0000000..d7114d0
--- /dev/null
@@ -0,0 +1,11 @@
+<div id="v" class="hBox">
+       <h2>Check out our Video Spotlight</h2>
+       <h3>{title:h}</h3>
+       <a href="http://www.youtube.com/embed/{vCode}?rel=0&hd=1" class="colorbox">
+               <img src="http://img.youtube.com/vi/{vCode}/0.jpg" width="400">
+               <img src="assets/videoOverlay.png" width="400" id="videoOverlay">
+       </a>
+               <p>
+               <a href="{videoUrl}">See All Our Videos</a>
+       </p>
+</div>
diff --git a/Toolkit/Videos/templates/webPageDecorator.html b/Toolkit/Videos/templates/webPageDecorator.html
new file mode 100644 (file)
index 0000000..71622ca
--- /dev/null
@@ -0,0 +1,14 @@
+<div id="videoGallery">
+  {foreach:videos,v}
+  {if:v[firstInRow]}<div class="vRow">{end:}
+  <div class="vThumb">
+    <a href="http://www.youtube.com/embed/{v[code]}?rel=0&hd=1" class="colorbox">
+      <img src="http://img.youtube.com/vi/{v[code]}/default.jpg">
+    </a>
+    <div class="vTitle">
+      {v[title]:h}
+    </div>
+  </div>
+  {if:v[lastInRow]}</div><!-- /.galleryRow --> {end:}
+  {end:}
+</div>
diff --git a/Toolkit/Videos/toggleActive.php b/Toolkit/Videos/toggleActive.php
new file mode 100644 (file)
index 0000000..1b2eec6
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * VideosDataGrid.php
+ *
+ * Handles switching the active flag for the video
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+if (!isset($_GET['kpass'])) {
+       die();
+}
+require_once '../../setup.phtml';
+
+$dbh    = Toolkit_Database::getInstance();
+$id     = $_REQUEST['id'];
+
+try {
+    $dbh->beginTransaction();
+    $sql = "
+    SELECT active
+      FROM videos
+     WHERE id = :id";
+    $stmt = $dbh->prepare($sql);
+    $stmt->bindParam(
+        ":id",
+        $_REQUEST['id'],
+        PDO::PARAM_INT
+    );
+    $stmt->execute();
+    $activeState = $stmt->fetchColumn();
+    
+    if ($activeState) {
+       $sql = "
+        UPDATE videos
+           SET active = false
+         WHERE id = :id";
+        $updateStmt = $dbh->prepare($sql);
+    } else {
+        $sql = "
+        UPDATE videos
+           SET active = true
+         WHERE id = :id";
+        $updateStmt = $dbh->prepare($sql);
+    }
+
+    $updateStmt->bindParam(
+        ':id',
+        $id,
+        PDO::PARAM_INT
+    );
+    $updateStmt->execute();
+    $dbh->commit();
+} catch (PDOException $e) {
+       $dbh->rollback();
+    Toolkit_Logger::logException('DB Error', $e);
+}
+
+header('Location: '.MEDIA_BASE_URL.'admin/videos.php');
diff --git a/Toolkit/Videos/toggleFeatured.php b/Toolkit/Videos/toggleFeatured.php
new file mode 100644 (file)
index 0000000..53b6294
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * VideosDataGrid.php
+ *
+ * Handles switching the featured flag for the video
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Videos
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @link     http://demo.gaslightmedia.com
+ */
+if (!isset($_GET['kpass'])) {
+       die();
+}
+require_once '../../setup.phtml';
+
+$dbh    = Toolkit_Database::getInstance();
+$id     = $_REQUEST['id'];
+
+try {
+    $dbh->beginTransaction();
+    $sql = "
+    SELECT featured
+      FROM videos
+     WHERE id = :id";
+    $stmt = $dbh->prepare($sql);
+    $stmt->bindParam(
+        ":id",
+        $_REQUEST['id'],
+        PDO::PARAM_INT
+    );
+    $stmt->execute();
+    $featuredState = $stmt->fetchColumn();
+    
+    if ($featuredState) {
+       $sql = "
+        UPDATE videos
+           SET featured = false
+         WHERE id = :id";
+        $updateStmt = $dbh->prepare($sql);
+    } else {
+        $sql = "
+        UPDATE videos
+           SET featured = true
+         WHERE id = :id";
+        $updateStmt = $dbh->prepare($sql);
+    }
+
+    $updateStmt->bindParam(
+        ':id',
+        $id,
+        PDO::PARAM_INT
+    );
+    $updateStmt->execute();
+    $dbh->commit();
+} catch (PDOException $e) {
+       $dbh->rollback();
+    Toolkit_Logger::logException('DB Error', $e);
+}
+
+header('Location: '.MEDIA_BASE_URL.'admin/videos.php');
diff --git a/admin/videos.php b/admin/videos.php
new file mode 100644 (file)
index 0000000..1fd8de6
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+require_once '../setup.phtml';
+
+//  application configuration
+$conf = new Config;
+$confRoot=& $conf->parseConfig(
+       BASE . 'Toolkit/Videos/config.ini',
+       'IniFile'
+);
+
+//  get reference to [conf] section of config file
+$appName
+       = $confRoot->getItem('section', 'conf')
+       ->getItem('directive', 'applicationName')
+       ->getContent();
+
+$navigation = new Toolkit_Videos_Navigation(
+       new HTML_Menu(),
+       new HTML_Menu_DirectRenderer()
+);
+
+$navArray = $navigation->getNavStructure($confRoot);
+$navHtml = $navigation->renderPageNav($navArray, 'rows');
+$c = new Toolkit_Videos_Controller();
+$videos = $c->toHtml(
+       Toolkit_Database::getInstance(),
+       $confRoot
+);
+
+GLM_TOOLBOX::top($appName, '');
+echo $navHtml;
+echo $videos;
+GLM_TOOLBOX::footer();
\ No newline at end of file
index 46fa110..9c82125 100644 (file)
@@ -124,7 +124,7 @@ ticketing.catid = Off
 ticketing.cat_seo = Off
 
 employment.application = Off
-videos.application = Off
+videos.application = On
 seasons.application = Off
 blocks.application = On
 ; development server configuration data inherits from production and