From 08d5ea42bbb782dad887c4fd5d61338da31dd9b4 Mon Sep 17 00:00:00 2001 From: Steve Sutton Date: Mon, 23 Jun 2014 19:35:51 +0000 Subject: [PATCH] Add Videos Application Set featured on for application --- Toolkit/Videos/AdminEditVideoForm.php | 309 ++++++++++++++++ Toolkit/Videos/Controller.php | 58 +++ Toolkit/Videos/Database/application.sql | 12 + Toolkit/Videos/Database/removeApplication.sql | 6 + Toolkit/Videos/Database/table/videos.sql | 12 + Toolkit/Videos/IDecorator.php | 56 +++ Toolkit/Videos/Navigation.php | 123 +++++++ Toolkit/Videos/Video.php | 346 ++++++++++++++++++ Toolkit/Videos/VideoMapper.php | 111 ++++++ Toolkit/Videos/VideosDataGrid.php | 300 +++++++++++++++ Toolkit/Videos/WebDecorator.php | 102 ++++++ Toolkit/Videos/WebPageDecorator.php | 100 +++++ Toolkit/Videos/config.ini | 7 + Toolkit/Videos/libjs/videos.js | 14 + Toolkit/Videos/moveVideo.php | 81 ++++ Toolkit/Videos/styles.css | 154 ++++++++ Toolkit/Videos/templates/webDecorator.html | 11 + .../Videos/templates/webPageDecorator.html | 14 + Toolkit/Videos/toggleActive.php | 65 ++++ Toolkit/Videos/toggleFeatured.php | 65 ++++ admin/videos.php | 33 ++ config/application.ini | 2 +- 22 files changed, 1980 insertions(+), 1 deletion(-) create mode 100644 Toolkit/Videos/AdminEditVideoForm.php create mode 100644 Toolkit/Videos/Controller.php create mode 100644 Toolkit/Videos/Database/application.sql create mode 100644 Toolkit/Videos/Database/removeApplication.sql create mode 100644 Toolkit/Videos/Database/table/videos.sql create mode 100644 Toolkit/Videos/IDecorator.php create mode 100644 Toolkit/Videos/Navigation.php create mode 100644 Toolkit/Videos/Video.php create mode 100644 Toolkit/Videos/VideoMapper.php create mode 100644 Toolkit/Videos/VideosDataGrid.php create mode 100644 Toolkit/Videos/WebDecorator.php create mode 100644 Toolkit/Videos/WebPageDecorator.php create mode 100644 Toolkit/Videos/config.ini create mode 100644 Toolkit/Videos/libjs/videos.js create mode 100644 Toolkit/Videos/moveVideo.php create mode 100644 Toolkit/Videos/styles.css create mode 100644 Toolkit/Videos/templates/webDecorator.html create mode 100644 Toolkit/Videos/templates/webPageDecorator.html create mode 100644 Toolkit/Videos/toggleActive.php create mode 100644 Toolkit/Videos/toggleFeatured.php create mode 100644 admin/videos.php diff --git a/Toolkit/Videos/AdminEditVideoForm.php b/Toolkit/Videos/AdminEditVideoForm.php new file mode 100644 index 0000000..0977087 --- /dev/null +++ b/Toolkit/Videos/AdminEditVideoForm.php @@ -0,0 +1,309 @@ + + * @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 + * @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 + = '
Coupon successfully updated.
'; + + /** + * 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 = ' +
There was a Problem with your form!
'; + + /** + * 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
+ + Click on the \'Share\' function on the YouTube video +
to get your link. If you\'re having problems click on "show options" + and select "long link"
', + '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 index 0000000..d33be54 --- /dev/null +++ b/Toolkit/Videos/Controller.php @@ -0,0 +1,58 @@ +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 index 0000000..178e2fd --- /dev/null +++ b/Toolkit/Videos/Database/application.sql @@ -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 index 0000000..6c60d9c --- /dev/null +++ b/Toolkit/Videos/Database/removeApplication.sql @@ -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 index 0000000..0411150 --- /dev/null +++ b/Toolkit/Videos/Database/table/videos.sql @@ -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 index 0000000..1095b2d --- /dev/null +++ b/Toolkit/Videos/IDecorator.php @@ -0,0 +1,56 @@ + + * @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 + * @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 index 0000000..0428d7a --- /dev/null +++ b/Toolkit/Videos/Navigation.php @@ -0,0 +1,123 @@ + + * @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 + * @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 = '
  • {Title}
  • '; + $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('
      ', '
    '); + } + + /** + * 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&module=listVideos', + 'desc' => "Display all the {$pluralType}", + ), + 'editVideo' => array( + 'Title' => "Add {$singularType}", + 'url' => MEDIA_BASE_URL . 'admin/videos.php?page=editVideo&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 index 0000000..8e5f6e3 --- /dev/null +++ b/Toolkit/Videos/Video.php @@ -0,0 +1,346 @@ + + * @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 + * @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 index 0000000..2a00c87 --- /dev/null +++ b/Toolkit/Videos/VideoMapper.php @@ -0,0 +1,111 @@ + + * @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 + * @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 index 0000000..f2403e8 --- /dev/null +++ b/Toolkit/Videos/VideosDataGrid.php @@ -0,0 +1,300 @@ + + * @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 + * @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 = 'Edit'; + 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 = ''; + 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) + ? '' + : ''; + 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( + '', + $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( + '', + $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 index 0000000..50c2092 --- /dev/null +++ b/Toolkit/Videos/WebDecorator.php @@ -0,0 +1,102 @@ + + * @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 + * @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 index 0000000..689f220 --- /dev/null +++ b/Toolkit/Videos/WebPageDecorator.php @@ -0,0 +1,100 @@ + + * @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 + * @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 index 0000000..af80382 --- /dev/null +++ b/Toolkit/Videos/config.ini @@ -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 index 0000000..6080caf --- /dev/null +++ b/Toolkit/Videos/libjs/videos.js @@ -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 index 0000000..74e4f49 --- /dev/null +++ b/Toolkit/Videos/moveVideo.php @@ -0,0 +1,81 @@ + + * @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 index 0000000..cc82e07 --- /dev/null +++ b/Toolkit/Videos/styles.css @@ -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 index 0000000..d7114d0 --- /dev/null +++ b/Toolkit/Videos/templates/webDecorator.html @@ -0,0 +1,11 @@ +
    +

    Check out our Video Spotlight

    +

    {title:h}

    + + + + +

    + See All Our Videos +

    +
    diff --git a/Toolkit/Videos/templates/webPageDecorator.html b/Toolkit/Videos/templates/webPageDecorator.html new file mode 100644 index 0000000..71622ca --- /dev/null +++ b/Toolkit/Videos/templates/webPageDecorator.html @@ -0,0 +1,14 @@ +
    + {foreach:videos,v} + {if:v[firstInRow]}
    {end:} +
    + + + +
    + {v[title]:h} +
    +
    + {if:v[lastInRow]}
    {end:} + {end:} +
    diff --git a/Toolkit/Videos/toggleActive.php b/Toolkit/Videos/toggleActive.php new file mode 100644 index 0000000..1b2eec6 --- /dev/null +++ b/Toolkit/Videos/toggleActive.php @@ -0,0 +1,65 @@ + + * @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 index 0000000..53b6294 --- /dev/null +++ b/Toolkit/Videos/toggleFeatured.php @@ -0,0 +1,65 @@ + + * @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 index 0000000..1fd8de6 --- /dev/null +++ b/admin/videos.php @@ -0,0 +1,33 @@ +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 diff --git a/config/application.ini b/config/application.ini index 46fa110..9c82125 100644 --- a/config/application.ini +++ b/config/application.ini @@ -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 -- 2.17.1