From ded9af7f3a78caf05ea28e3daaaab477798c113e Mon Sep 17 00:00:00 2001 From: Steve Sutton Date: Thu, 10 Jul 2014 15:33:42 -0400 Subject: [PATCH] Add Image Library Adding the Image Library Application --- Toolkit/Photos/Admin/FileUploader.php | 458 ++++++++ Toolkit/Photos/Admin/PageTree.php | 145 +++ Toolkit/Photos/Auth.php | 98 ++ Toolkit/Photos/AuthContainer.php | 193 ++++ .../Photos/Controllers/IndexController.php | 514 +++++++++ Toolkit/Photos/Database/addSlideShow.sql | 7 + Toolkit/Photos/Database/application.sql | 10 + Toolkit/Photos/Database/removeApplication.sql | 8 + Toolkit/Photos/Database/resetSequences.sql | 7 + Toolkit/Photos/Database/tables/photo.sql | 18 + .../Photos/Database/tables/photo2category.sql | 13 + .../Photos/Database/tables/photo_category.sql | 13 + .../Database/tables/photo_category_bus.sql | 20 + .../Photos/Database/tables/photo_default.sql | 10 + Toolkit/Photos/Database/updatePhotos.sql | 20 + Toolkit/Photos/Database/upgradeApp.sql | 15 + Toolkit/Photos/Display.php | 384 +++++++ Toolkit/Photos/Exception.php | 3 + Toolkit/Photos/Factory.php | 21 + Toolkit/Photos/Gallery.php | 169 +++ Toolkit/Photos/GalleryCategoryFilter.php | 46 + Toolkit/Photos/Models/Category.php | 156 +++ Toolkit/Photos/Models/MediaMapper.php | 1003 +++++++++++++++++ Toolkit/Photos/Models/Page2Category.php | 92 ++ Toolkit/Photos/Models/Photo.php | 157 +++ Toolkit/Photos/Models/Photo2Category.php | 105 ++ Toolkit/Photos/Models/User.php | 279 +++++ Toolkit/Photos/Photo.php | 23 + Toolkit/Photos/SlideShowCategoryFilter.php | 46 + Toolkit/Photos/application.ini | 45 + Toolkit/Photos/assets/.keepme | 0 Toolkit/Photos/css/gallery.css | 28 + Toolkit/Photos/css/style.css | 344 ++++++ Toolkit/Photos/css/thickbox.css | 168 +++ Toolkit/Photos/js/jquery.columnview.js | 267 +++++ Toolkit/Photos/js/photoGallery.js | 173 +++ Toolkit/Photos/login.php | 59 + Toolkit/Photos/photoProxy.php | 97 ++ Toolkit/Photos/photoSearch.php | 27 + Toolkit/Photos/setupNewPhotos.php | 9 + .../Photos/templates/Admin/editCategory.html | 187 +++ Toolkit/Photos/templates/Admin/editPhoto.html | 264 +++++ Toolkit/Photos/templates/Admin/editUser.html | 233 ++++ Toolkit/Photos/templates/Admin/emailUser.tpl | 68 ++ Toolkit/Photos/templates/Admin/index.html | 29 + .../templates/Admin/listCategories.html | 93 ++ .../Photos/templates/Admin/listPhotos.html | 63 ++ Toolkit/Photos/templates/Admin/listUsers.html | 26 + Toolkit/Photos/templates/Admin/nav.html | 17 + .../Photos/templates/Admin/searchForm.html | 76 ++ Toolkit/Photos/templates/Admin/userNav.html | 14 + Toolkit/Photos/templates/photoCats.html | 17 + .../Photos/templates/photoGalleryWrapper.html | 336 ++++++ Toolkit/Photos/templates/photos.html | 31 + admin/photos.php | 21 + config/application.ini | 2 +- static/9.phtml | 782 +++++++++++++ 57 files changed, 7508 insertions(+), 1 deletion(-) create mode 100644 Toolkit/Photos/Admin/FileUploader.php create mode 100644 Toolkit/Photos/Admin/PageTree.php create mode 100644 Toolkit/Photos/Auth.php create mode 100644 Toolkit/Photos/AuthContainer.php create mode 100644 Toolkit/Photos/Controllers/IndexController.php create mode 100644 Toolkit/Photos/Database/addSlideShow.sql create mode 100644 Toolkit/Photos/Database/application.sql create mode 100644 Toolkit/Photos/Database/removeApplication.sql create mode 100644 Toolkit/Photos/Database/resetSequences.sql create mode 100755 Toolkit/Photos/Database/tables/photo.sql create mode 100644 Toolkit/Photos/Database/tables/photo2category.sql create mode 100755 Toolkit/Photos/Database/tables/photo_category.sql create mode 100755 Toolkit/Photos/Database/tables/photo_category_bus.sql create mode 100755 Toolkit/Photos/Database/tables/photo_default.sql create mode 100644 Toolkit/Photos/Database/updatePhotos.sql create mode 100644 Toolkit/Photos/Database/upgradeApp.sql create mode 100644 Toolkit/Photos/Display.php create mode 100644 Toolkit/Photos/Exception.php create mode 100644 Toolkit/Photos/Factory.php create mode 100644 Toolkit/Photos/Gallery.php create mode 100644 Toolkit/Photos/GalleryCategoryFilter.php create mode 100644 Toolkit/Photos/Models/Category.php create mode 100644 Toolkit/Photos/Models/MediaMapper.php create mode 100644 Toolkit/Photos/Models/Page2Category.php create mode 100644 Toolkit/Photos/Models/Photo.php create mode 100644 Toolkit/Photos/Models/Photo2Category.php create mode 100644 Toolkit/Photos/Models/User.php create mode 100644 Toolkit/Photos/Photo.php create mode 100644 Toolkit/Photos/SlideShowCategoryFilter.php create mode 100644 Toolkit/Photos/application.ini create mode 100644 Toolkit/Photos/assets/.keepme create mode 100755 Toolkit/Photos/css/gallery.css create mode 100644 Toolkit/Photos/css/style.css create mode 100755 Toolkit/Photos/css/thickbox.css create mode 100755 Toolkit/Photos/js/jquery.columnview.js create mode 100644 Toolkit/Photos/js/photoGallery.js create mode 100644 Toolkit/Photos/login.php create mode 100644 Toolkit/Photos/photoProxy.php create mode 100644 Toolkit/Photos/photoSearch.php create mode 100644 Toolkit/Photos/setupNewPhotos.php create mode 100644 Toolkit/Photos/templates/Admin/editCategory.html create mode 100644 Toolkit/Photos/templates/Admin/editPhoto.html create mode 100644 Toolkit/Photos/templates/Admin/editUser.html create mode 100644 Toolkit/Photos/templates/Admin/emailUser.tpl create mode 100644 Toolkit/Photos/templates/Admin/index.html create mode 100644 Toolkit/Photos/templates/Admin/listCategories.html create mode 100644 Toolkit/Photos/templates/Admin/listPhotos.html create mode 100644 Toolkit/Photos/templates/Admin/listUsers.html create mode 100644 Toolkit/Photos/templates/Admin/nav.html create mode 100644 Toolkit/Photos/templates/Admin/searchForm.html create mode 100644 Toolkit/Photos/templates/Admin/userNav.html create mode 100755 Toolkit/Photos/templates/photoCats.html create mode 100644 Toolkit/Photos/templates/photoGalleryWrapper.html create mode 100755 Toolkit/Photos/templates/photos.html create mode 100644 admin/photos.php create mode 100644 static/9.phtml diff --git a/Toolkit/Photos/Admin/FileUploader.php b/Toolkit/Photos/Admin/FileUploader.php new file mode 100644 index 0000000..b81c390 --- /dev/null +++ b/Toolkit/Photos/Admin/FileUploader.php @@ -0,0 +1,458 @@ + + * @copyright 2009 Gaslight Media + * @license Gaslight Media + * @version CVS: $Id: ShortURL.php,v 1.5 2010/05/25 14:07:22 jamie Exp $ + * @link <> + */ + +define('YAHOO_YUI_BASE', MEDIA_APP_BASE_URL . 'yui/build/'); +define('PHOTOS_UPLOAD_PATH', BASE . 'admin/Photos/uploads/'); + +/** + * Toolkit_Photos_Admin_FileUploader + * + * Description of Toolkit_Photos_Admin_FileUploader + * + * @category Toolkit + * @package Photos/Admin + * @author Steve Sutton + * @copyright 2014 Gaslight Media + * @license Gaslight Media + * @release Release: $id$ + * @link <> + */ +class Toolkit_Photos_Admin_FileUploader + extends Toolkit_FormBuilder +{ + // {{{ Class Properties + /** + * Description of $debug + * @var boolean + */ + public $debug = false; + + /** + * Message for successful upload + * @var string + */ + protected $successMsg + = '
+ You have successfully uploaded the files to your photo album. +
'; + // }}} + + // {{{ configureDefaults() + + /** + * Initializes default form values + * + * @return void + * @access public + */ + public function configureDefaults() + { + $defaults = array('catid' => $_REQUEST['catid']); + + $this->setupDefaults($defaults); + } + + // }}} + // {{{ configureElements() + + /** + * Form element definitions + * + * @return void + * @access public + */ + public function configureElements() + { + $e = array(); + $categories = $this->getPhotoCategories(); + + // All Elements are created here. This includes group element definitions. + $e[] = array( + 'type' => 'header', + 'name' => 'albumHdr_rmv', + 'display' => ' +

+ USE: + Hold down the Ctrl key to select or unselect more than one photo + at a time. Hold down the Shift key to select a range.

+
+ This feature (Multiple Uploads) is only supported in certain modern browsers: +
    +
  • Internet Explorer 10
  • +
  • FireFox 8 and up
  • +
  • Safari 5 and up
  • +
  • Google Chrome 17 and up
  • +
+
' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'catid' + ); + $e[] = array( + 'type' => 'file', + 'name' => 'files[]', + 'display' => 'Files to Upload', + 'opts' => array( + 'id' => 'myuploader', + 'multiple' => 'multiple', + 'accept' => 'image/*' + ) + ); + + $e[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'submit_rmv', + 'display' => 'Submit Form' + ); + + $this->setupElements($e); + } + + // }}} + // {{{ configureFilters() + + /** + * Form filter definitions + * + * Applies a data filter for the given fields when the form is submitted + * + * @return void + * @access public + */ + public function configureFilters() + { + $f = array(); + + $f[] = array( + 'element' => '__ALL__', + 'filter' => 'trim' + ); + + $this->setupFilters($f); + } + + // }}} + // {{{ configureForm() + + /** + * Helper function, configures the entire form + * + * @return void + * @access public + */ + public function configureForm() + { + $this->configureElements(); + $this->configureFilters(); + $this->configureRules(); + $this->configureDefaults(); + } + + // }}} + // {{{ configureRules() + + /** + * Form rule definitions + * + * Adds validation rules for the given fields + * + * @return void + * @access public + */ + public function configureRules() + { + $r = array(); + $this->setupRules($r); + } + + // }}} + + // {{{ getFileData() + /** + * Get file data + * + * @param string $fileName Filename + * @param string $path File path + * + * @return array|boolean + * @access public + */ + function getFileData($fileName, $path) + { + $filename = $path . '/' . $fileName; + if (is_file($filename) && is_readable($filename)) { + return array( + 'name' => $fileName, + 'tmp_name' => $filename, + 'size' => filesize($filename), + 'type' => mime_content_type($filename) + ); + } else { + return false; + } + } + // }}} + // {{{ getPhotoCategorieso() + + /** + * Get photo categories + * + * @return array + * @access public + */ + function getPhotoCategories() + { + try { + $sql = " + SELECT id, category + FROM photo_category + ORDER BY category"; + $stmt = $this->dbh->query($sql); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $categories[$row['id']] = $row['category']; + } + return $categories; + } catch(PDOExecption $e) { + Toolkit_Common::handleError($e); + } + }// }}} + // {{{ getCategoryMaxPos() + /** + * get max pos plus one + * + * @param mixed $id photo category id + * + * @access public + * @return string + */ + function getCategoryMaxPos($id) + { + try { + $sql = " + SELECT COALESCE(max(pos) + 1, 1) + FROM photo2category + WHERE category = :catid"; + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(":catid", $id, PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchColumn(); + } catch(PDOException $e) { + Toolkit_Common::handleError($e); + } + }// }}} + + // {{{ processData() + + /** + * Handles how to process the form when submitted + * + * @param array $values Form submitted values + * + * @return array Result of Insert / Update function + * @access public + */ + public function processData($values) + { + if ( is_array($values['files']) + && !empty($values['files'])) { + $this->processFilesArray($values); + } else { + $this->processFolder($values); + } + return true; + } + + // }}} + + /** + * Process files array + * + * @param array $values Values array + * + * @return void + * @access public + */ + public function processFilesArray($values) + { + $images = array(); + $photos = array(); + $acceptedFiles = array( + 'image/jpeg', + 'image/gif', + 'image/png' + ); + $is = new Toolkit_FileServer_ImageAdapter(IS_OWNER_ID, IS_OWNER_PW); + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + Toolkit_Database::getInstance() + ); + $pos = $this->getCategoryMaxPos($values['catid']); + if (is_array($values['files']['name'])) { + for ($i = 0; $i < count($values['files']['name']); ++$i) { + // check that it's an image + // jpg jpeg gif or png + if ( !$values['files']['error'][$i] + && in_array($values['files']['type'][$i], $acceptedFiles) + ) { + $images[] = array( + 'name' => $values['files']['name'][$i], + 'tmp_name' => $values['files']['tmp_name'][$i], + 'size' => $values['files']['size'][$i] + ); + } + } + } + if (!empty($images)) { + foreach ($images as $img) { + $imgData = $is->uploadImageFile($img['tmp_name']); + $photo = Toolkit_Photos_Models_Photo::createByValues( + array( + 'image' => $imgData['name'], + 'catid' => $values['catid'] + ) + ); + $photoId = $mediaMapper->savePhoto($photo); + $photo2Category + = Toolkit_Photos_Models_Photo2Category::createByValues( + array( + 'photo' => $photoId, + 'category' => $values['catid'], + 'pos' => $pos + ) + ); + $mediaMapper->savePhoto2Category($photo2Category); + ++$pos; + } + } + } + + /** + * Process folder + * + * @param array $values Values array + * + * @throws Exception + * @return void + * @access public + */ + public function processFolder($values) + { + $is = new Toolkit_Image_Server(); + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + Toolkit_Database::getInstance() + ); + try { + if (!is_dir($_SESSION['uploadFolder'])) { + throw new Exception('No Folder exists'); + } + } catch (Exception $e) { + Toolkit_Common::handleError($e); + } + + $d = dir($_SESSION['uploadFolder']); + $pos = $this->getCategoryMaxPos($_REQUEST['catid']); + $i = 0; + while (false !== ($entry = $d->read())) { + if (!in_array($entry, array('.','..','.svn','CVS'))) { + // before we can send the image to the image class we need + // to inject the data for the images into the $_FILES array + $_FILES['img' . $i] = $this->getFileData($entry, $_SESSION['uploadFolder']); + // send to image server and insert values + $image_name = $is->imageUpload('img' . $i, $_SESSION['uploadFolder']); + $photo = Toolkit_Photos_Models_Photo::createByValues( + array( + 'image' => $image_name, + 'catid' => $_REQUEST['catid'] + ) + ); + $photoId = $mediaMapper->savePhoto($photo); + $photo2Category + = Toolkit_Photos_Models_Photo2Category::createByValues( + array( + 'photo' => $photoId, + 'category' => $_REQUEST['catid'], + 'pos' => $pos + ) + ); + $mediaMapper->savePhoto2Category($photo2Category); + ++$pos; + unlink($_SESSION['uploadFolder'] . '/'. $entry); + ++$i; + } + } + $d->close(); + if (is_dir($_SESSION['uploadFolder'])) { + rmdir($_SESSION['uploadFolder']); + } + } + + // {{{ setupRenderers() + // @codeCoverageIgnoreStart + + /** + * Custom rendering templates for special fields on the form + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + parent::setupRenderers(); + $renderer =& $this->defaultRenderer(); + $required = ' * '; + $error = '
{error}
'; + } + + // @codeCoverageIgnoreEnd + // }}} + + // {{{ toHtml() + + /** + * Handles how to display the current step the user is at in the form + * + * destroying and resetting the captcha value dis-allows someone from + * re-sending a form on a previous captcha. + * + * @return string form HTML state + * @access public + */ + public function toHtml() + { + $this->setupRenderers(); + if ($this->validate()) { + $this->cleanForm(); + if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) { + $this->freeze(); + HTTP_Session2::unregister('uploadFolder'); + header("Location: photos.php?ac=editCategory&id=" . $_REQUEST['catid']); + exit; + } + + } elseif ($this->isSubmitted()) { + $output = $this->errorMsg; + $output .= parent::toHTML(); + $output = '
'.print_r($this, true).'
'; + } else { + $output = parent::toHTML(); + } + return $output; + } + + // }}} +} +?> diff --git a/Toolkit/Photos/Admin/PageTree.php b/Toolkit/Photos/Admin/PageTree.php new file mode 100644 index 0000000..9e52bfa --- /dev/null +++ b/Toolkit/Photos/Admin/PageTree.php @@ -0,0 +1,145 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_PageTree + * + * Display the toolbox page as ul lil list for jQuery-Column viewer + * + * @category Toolkit + * @package Blocks + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Admin_PageTree +{ + private $_dbh; + private $_rootNodeStart = "
    \n"; + private $_leafStartExpanded = "\n\t
  • \n"; + private $_leafStartLeaf = "\n\t
  • \n"; + private $_subTreeStart = "\n
      \n"; + private $_treeEnd = "\n
    \n"; + private $_leafEnd = "\n\t
  • \n"; + private $_tree; + + public function __construct(PDO $dbh) + { + $this->_dbh = $dbh; + } + + /** + * creates and executes the sql query for getting the pages + * + * @return array | null + */ + private function _findAll() + { + try { + $members + = (filter_var(MEMBERS_CATEGORY, FILTER_VALIDATE_INT)) + ? "WHERE id NOT IN (" . MEMBERS_CATEGORY . ") + AND parent NOT IN (" . MEMBERS_CATEGORY . ")" + : ''; + $sql = " + SELECT id,parent,navigation_name + FROM pages + $members + ORDER by parent, pos"; + + return $this->_dbh + ->query($sql) + ->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Get all pages for the tree + * + * @return array + */ + private function _fetchPages() + { + $pages = $this->_findAll(); + if (is_array($pages)) { + $threads = array(); + foreach ($pages as $page) { + $page['children'] = array(); + $threads[] = $page; + } + + $children = array(); + while (list($key, $value) = each ($threads)) { + $children[$value['parent']][$value['id']] = $value; + } + + $this->_tree = $children; + } else { + $this->_tree = array(); + } + } + + /** + * Create html of the pages tree for jqueyr.columnview + * + * @return string + */ + public function toHtml() + { + $this->_fetchPages(); + if (is_array($this->_tree)) { + $html = $this->createTree($this->_tree, reset($this->_tree)); + } + return $html; + } + + /** + * Creates the tree structure for the pages jquery column view + * + * @param array $tree Array for tree + * @param type $leaf Array for leaf + * @param type $level tree level + * + * @return string + */ + protected function createTree(array $tree, $leaf, $level = 0) + { + $html = !$level ? $this->_rootNodeStart : $this->_subTreeStart; + if (is_array($leaf) && !empty($leaf)) { + while (list($parent, $branch) = each($leaf)) { + $pageName = htmlspecialchars($branch['navigation_name']); + if ($tree[$parent]) { + $html .= sprintf($this->_leafStartExpanded, null); + $html .= "{$branch['navigation_name']} "; + $html .= $this->createTree($tree, $tree[$parent], $level + 1); + } else { + $html .= sprintf($this->_leafStartLeaf, null); + $html .= "{$branch['navigation_name']} "; + $html .= $this->_leafEnd; + } + } + } + $html .= $this->_treeEnd; + if ($level) { + $html .= $this->_leafEnd; + } + return $html; + } +} diff --git a/Toolkit/Photos/Auth.php b/Toolkit/Photos/Auth.php new file mode 100644 index 0000000..8b5e31e --- /dev/null +++ b/Toolkit/Photos/Auth.php @@ -0,0 +1,98 @@ + + * @copyright 2009 Jamie Kahgee + * @license http://www.gaslightmedia.com Gaslightmedia + * @version CVS: $Id: Auth.php,v 1.22 2010/08/10 18:08:44 jamie Exp $ + * @link http://demo.gaslightmedia.com + * @see Toolkit_Members_Auth-LoginForm, Toolkit_Members_Auth-PasswordForm + */ + +require_once 'Auth.php'; + +/** + * Methods for the memberdb authentication system + * + * Handles Cookie and session generation, id challenges and security for + * the memberdb application + * + * @category MembersDB + * @package Toolkit_Members + * @author Jamie Kahgee + * @copyright 2009 Jamie Kahgee + * @license http://www.gaslightmedia.com Gaslightmedia + * @link http://demo.gaslightmedia.com + * @see Toolkit_Members_Auth-LoginForm, Toolkit_Members_Auth-PasswordForm + */ +class Toolkit_Photos_Auth extends Auth +{ + // {{{ properties + + /** + * Maximum idle time + * + * If more seconds pass before a new page request, then the user + * will have to re-authenticate back into the application. + * 1800 = 30 min + * 3600 = 1 hr + * + * @var integer + * @access protected + */ + protected $idleTime = 3600; + + // }}} + // {{{ __construct() + + /** + * Constructor + * + * Sets up the storage driver + * + * @param Config_Container $c Configuration object + * @param Toolkit_Members_AuthContainer $storageDriver storage driver + * @param string $loginFunction (optional)Name of the function + * that creates the login form + * @param boolean $showLogin (optional)Should the login form + * be displayed if neccessary? + * + * @return void + * @access public + */ + public function __construct( + Auth_Container $storageDriver, + $loginFunction = '', + $showLogin = false + ) { + parent::Auth($storageDriver, '', $loginFunction, $showLogin); + } + + // }}} + + // {{{ setIdle() + + /** + * Set the maximum idle time + * + * @param integer $time time in seconds + * @param boolean $add (optional)add time to current maximum idle time or not + * + * @return void + * @access public + */ + public function setIdle($time = null, $add = false) + { + $time = is_null($time) ? $this->idleTime : $time; + parent::setIdle($time, $add); + } + + // }}} +} diff --git a/Toolkit/Photos/AuthContainer.php b/Toolkit/Photos/AuthContainer.php new file mode 100644 index 0000000..a3eed86 --- /dev/null +++ b/Toolkit/Photos/AuthContainer.php @@ -0,0 +1,193 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_AuthContainer + * + * Description of AuthContainer + * + * @category Toolkit + * @package Photos + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_AuthContainer + extends Auth_Container +{ + // {{{ properties + + /** + * Database handler + * @var PDO + * @access private + */ + private $_dbh; + + /** + * Addition options for the storage container + * @var array + * @access private + */ + private $_options = array(); + + // }}} + // {{{ __construct() + + /** + * Constructor + * + * @param PDO $dbh Database handler + * + * @return void + * @access public + */ + public function __construct(PDO $dbh, array $options = null) + { + $this->_dbh = $dbh; + $this->_setDefaults(); + if (is_array($options)) { + $this->_parseOptions($options); + } + } + + // }}} + // {{{ _setDefaults() + + /** + * Set some default options + * + * @access private + * @return void + */ + private function _setDefaults() + { + $this->_options['sessionName'] = 'glmMedia'; + $this->_options['table'] = 'contact'; + $this->_options['usernamecol'] = 'email'; + $this->_options['passwordcol'] = 'media_pass'; + $this->_options['db_fields'] = array('id', 'fname', 'lname'); + $this->_options['cryptType'] = 'none'; + $this->_options['db_where'] = ' AND media = true AND approved = true' + . ' AND (expire IS NULL OR expire > current_date)'; + } + + // }}} + // {{{ _parseOptions() + + /** + * Parse options passed to the container class + * + * @param array $array options for class + * + * @access private + * @return void + */ + private function _parseOptions($array) + { + foreach ($array as $key => $value) { + if (isset($this->_options[$key])) { + $this->_options[$key] = $value; + } + } + } + + // }}} + // {{{ fetchData() + + /** + * Get the user information from the database + * + * @param string $username username to authenticate + * @param string $password password to authenticate against username + * + * @return boolean If the user was authenticated or not + * @access public + * @throws Toolkit_Members_Exception upon error querying DB for user + */ + public function fetchData($username, $password) + { + if ( is_string($this->_options['db_fields']) + && strstr($this->_options['db_fields'], '*') + ) { + $sqlFrom = '*'; + } else { + $sqlFrom = $this->_options['usernamecol']; + + if (strlen($fields = $this->_getDBFields()) > 0) { + $sqlFrom .= ", $fields"; + } + + } + + $pword = ($this->_options['cryptType'] == 'md5') ? 'MD5(:pword)' : ':pword'; + + $sql = " + SELECT $sqlFrom + FROM {$this->_options['table']} + WHERE {$this->_options['usernamecol']} = :uname + AND {$this->_options['passwordcol']} = $pword"; + + if ($this->_options['db_where']) { + $sql .= $this->_options['db_where']; + } + + try { + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':uname', $username, PDO::PARAM_STR); + $stmt->bindParam(':pword', $password, PDO::PARAM_STR); + $stmt->execute(); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($row !== FALSE) { + foreach ($row as $key => $value) { + $this->_auth_obj->setAuthData($key, $value); + } + return true; + } + + return false; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_Members_Exception( + "Error validating user `$username` - `$password`" + ); + } + } + + // }}} + // {{{ _getDBFields() + + /** + * Get extra db fields to fetch and set in the auth data + * + * @return array comma separated string of extra db fields for a SQL query + * @access private + */ + private function _getDBFields() + { + if (isset($this->_options['db_fields'])) { + if (is_array($this->_options['db_fields'])) { + return implode(', ', $this->_options['db_fields']); + } + } + } + + // }}} +} + diff --git a/Toolkit/Photos/Controllers/IndexController.php b/Toolkit/Photos/Controllers/IndexController.php new file mode 100644 index 0000000..1a6f3e8 --- /dev/null +++ b/Toolkit/Photos/Controllers/IndexController.php @@ -0,0 +1,514 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_IndexController + * + * Description of IndexController + * + * @category Toolkit + * @package Media + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Controllers_IndexController + extends Toolkit_BaseControllerAbstract + implements Toolkit_IController +{ + + const LIST_CATEGORY_TPL = 'Admin/listCategories.html'; + const LIST_PHOTOS_TPL = 'Admin/listPhotos.html'; + const LIST_USERS_TPL = 'Admin/listUsers.html'; + const EDIT_CATEGORY_TPL = 'Admin/editCategory.html'; + const EDIT_PHOTO_TPL = 'Admin/editPhoto.html'; + const EDIT_USER_TPL = 'Admin/editUser.html'; + const ADMIN_PAGE_TPL = 'Admin/index.html'; + + public function indexAction() + { + $pageUrl = $this->registry->page; + $flexyOptions = $this->registry->config->flexyOptions->toArray(); + $tpl = new HTML_Template_Flexy($flexyOptions); + $tpl->compile(self::LIST_CATEGORY_TPL); + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $page = new stdClass(); + $page->imgPath = PHOTO_SMALL_URL; + + // list template + $page->editUrl = $pageUrl . '?ac=editCategory&id='; + $page->deleteUrl = $pageUrl . '?ac=deleteCategory&id='; + $page->categories = $mediaMapper->fetchAllCategories(); + return $this->_createPage($tpl->bufferedOutputObject($page)); + } + + public function ajaxPhotoSearchAction() + { + $jsonData = array(); + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $photoSearch = filter_var($_REQUEST['photoName'], FILTER_SANITIZE_STRING); + $photos = $mediaMapper->fetchPhotosByName(true); + if ($photos) { + foreach ($photos as $photo) { + $jsonData[] = $photo->getTitle(); + } + } + return json_encode($jsonData); + } + + public function multipleUploadAction() + { + define('PHOTOS_UPLOAD_PATH', BASE . 'uploads/photos/'); + + HTTP_Session2::useCookies(false); + HTTP_Session2::start('photoUploader'); + $form = new Toolkit_Photos_Admin_FileUploader('file_upload_form'); + $form->debug = YUI_UPLOADER_DEBUG; + $form->configureForm(); + $formOut = $form->toHtml(); + return $this->_createPage($formOut); + } + + private function _createPage($html) + { + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jquery/jquery-1.7.2.min.js'; + $GLOBALS['topScripts'][] + = MEDIA_BASE_URL . 'admin/Photos/checkBrowserSupport.js'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/development-bundle/themes/base/jquery.ui.all.css'; + $GLOBALS['styleSheets'][] + = MEDIA_BASE_URL . 'Toolkit/Photos/css/style.css'; + $GLOBALS['styleSheets'][] + = MEDIA_BASE_URL . 'css/contactform.css'; + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/js/jquery-ui-1.8.13.custom.min.js'; + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $tpl = new HTML_Template_Flexy( + $this->registry->config->flexyOptions->toArray() + ); + $page = new stdClass(); + $ac = filter_var($_REQUEST['ac'], FILTER_SANITIZE_STRING); + $catId = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + if ($ac && ($ac == 'editCategory') && $catId) { + $page->categoryId = $catId; + } + + $page->categorySearchUrl + = MEDIA_BASE_URL . 'admin/photos.php'; + $this->_setNav($page); + $page->topScripts = $this->_getTopScripts(); + $page->bottomScripts = $this->_getBottomScripts(); + $page->styles = $this->_getCss(); + $page->categories = $mediaMapper->fetchAllCategories(); + $page->AppName = $this->registry->config->application->name; + $page->content = $html; + $tpl->compile(self::ADMIN_PAGE_TPL); + return $tpl->bufferedOutputObject($page); + } + + private function _setNav(&$page) + { + $page->userAdminUrl = MEDIA_BASE_URL . 'admin/photos.php'; + $pageUrl = $this->registry->page; + $ac = filter_var($_REQUEST['ac'], FILTER_SANITIZE_STRING); + + // navigation urls + if ($ac == 'editCategory') { + $catId = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + if ($catId) { + $page->addPhotoUrl + = $pageUrl . '?ac=editPhoto&catid=' . $catId; + $page->addMultipleUrl + = $pageUrl . '?ac=multipleUpload&catid=' . $catId; + } + } + if ($ac == 'multipleUpload') { + $catId = filter_var($_REQUEST['catid'], FILTER_VALIDATE_INT); + if ($catId) { + $page->addPhotoUrl + = $pageUrl . '?ac=editPhoto&catid=' . $catId; + $page->addMultipleUrl + = $pageUrl . '?ac=multipleUpload&catid=' . $catId; + } + } + $page->addCategoryUrl = $pageUrl . '?ac=editCategory'; + $page->listCategoryUrl = $pageUrl; + if ($this->registry->config->settings->mediaExclusive) { + $page->listUsersUrl = $pageUrl . '?ac=listUsers'; + } + } + + public function searchPhotosAction() + { + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $flexyOptions + = $this->registry->config->flexyOptions->toArray(); + $tpl + = new HTML_Template_Flexy($flexyOptions); + $page + = new stdClass(); + $page->imgPath = PHOTO_SMALL_URL; + $page->photos = $mediaMapper->fetchPhotosByName(); + $page->editUrl = $this->registry->page + . '?ac=editPhoto'; + $this->_setNav($page); + $tpl->compile(self::LIST_PHOTOS_TPL); + return $this->_createPage($tpl->bufferedOutputObject($page)); + } + + public function listUsersAction() + { + $flexyOptions = $this->registry->config->flexyOptions->toArray(); + $tpl = new HTML_Template_Flexy($flexyOptions); + $tpl->compile(self::LIST_USERS_TPL); + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $page = new stdClass(); + $this->_setNav($page); + $page->editUrl = $this->registry->page + . '?ac=editUser&catid=' . $catId + . '&id='; + $status = filter_var($_REQUEST['userStatus'], FILTER_SANITIZE_STRING); + $filters = array(); + switch ($status) { + case 'approved': + $page->statusText = 'Approved'; + $filters[] = "approved = true"; + $filters[] = "(expire > current_date OR expire IS NULL)"; + break; + case 'denied': + $page->statusText = 'Denied'; + $filters[] = "denied = true"; + break; + case 'expired': + $page->statusText = 'Expired'; + $filters[] = "expire is not null"; + $filters[] = "expire < current_date"; + break; + default: + $page->statusText = 'Pending'; + $filters[] = "((approved is null + AND denied IS NULL) + OR (denied = false AND approved = false))"; + break; + } + $page->users = $mediaMapper->fetchUsers($filters); + return $this->_createPage($tpl->bufferedOutputObject($page)); + } + + public function showPagesAction() + { + $pageTree = new Toolkit_Photos_Admin_PageTree($this->registry->dbh); + return $pageTree->toHtml(); + } + + public function editCategoryAction() + { + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + if ($_POST) { + $saved = $mediaMapper->saveCategoryWithPost(); + if ($saved) { + header('Location: ' . $this->registry->page); + exit; + } + } + $categoryId = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + + $GLOBALS['styleSheets'][] + = MEDIA_BASE_URL . 'css/contactform.css'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL + . 'libjs/jqueryui/1.8.13/development-bundle/themes/base/jquery.ui.all.css'; + $GLOBALS['bottomScripts'][] + = MEDIA_BASE_URL . 'Toolkit/Photos/js/jquery.columnview.js'; + $flexyOptions + = $this->registry->config->flexyOptions->toArray(); + $tpl + = new HTML_Template_Flexy($flexyOptions); + $page + = new stdClass(); + $page->mediaExclusive + = $this->registry->config->settings->mediaExclusive; + $page->slideShow + = $this->registry->config->settings->slideShowOption; + $page->pages2Categories + = ($categoryId) + ? $mediaMapper->fetchCategoryPages($categoryId) + : null; + $page->imgPath = PHOTO_SMALL_URL; + $page->photos + = ($categoryId) + ? $mediaMapper->fetchAllPhotosByCatid($categoryId) + : null; + $page->categoryId = $categoryId; + $page->editUrl = $this->registry->page + . '?ac=editPhoto&catid=' . $categoryId + . '&id='; + $this->_setNav($page); + if ($categoryId) { + $page->category = $mediaMapper->fetchCategoryById($categoryId); + } + $page->formAction = $this->registry->page . '?ac=editCategory'; + $tpl->compile(self::EDIT_CATEGORY_TPL); + return $this->_createPage($tpl->bufferedOutputObject($page)); + } + + public function editPhotoAction() + { + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $catId = filter_var($_REQUEST['catid'], FILTER_VALIDATE_INT); + // grab the category + if ($catId) { + $photoCategory = $mediaMapper->fetchCategoryById($catId); + } + $pageUrl = $this->registry->page; + + if ($_POST) { + $saved = $mediaMapper->savePhotoWithPost(); + if ($saved) { + header('Location: ' + . $this->registry->page.'?ac=editCategory&id=' + . $catId); + exit; + } + exit; + } + $photoId = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + + $GLOBALS['styleSheets'][] + = MEDIA_BASE_URL . 'css/contactform.css'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL . 'libjs/plugins/asmselect/1.0.4a/jquery.asmselect.css'; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/plugins/asmselect/1.0.4a/jquery.asmselect.js'; + $flexyOptions = $this->registry->config->flexyOptions->toArray(); + $tpl = new HTML_Template_Flexy($flexyOptions); + $page = new stdClass(); + $page->mediaExclusive + = $this->registry->config->settings->mediaExclusive; + $page->catid = $catId; + $page->photo2Categories + = ($photoId) + ? $mediaMapper->fetchPhoto2CategoryByPhotoId($photoId) + : new ArrayObject(); + $page->imgPath = PHOTO_SMALL_URL; + $page->categoryName= $photoCategory->getCategory(); + $this->_setNav($page); + if ($photoId) { + $page->photo = $mediaMapper->fetchPhotoById($photoId); + } + $page->categories = $mediaMapper->fetchAllCategories(); + $page->formAction = $this->registry->page + . '?ac=editPhoto&catid=' . $catId; + $tpl->compile(self::EDIT_PHOTO_TPL); + return $this->_createPage($tpl->bufferedOutputObject($page)); + } + + public function editUserAction() + { + $GLOBALS['styleSheets'][] = MEDIA_BASE_URL . 'css/contactform.css'; + $pageUrl = $this->registry->page; + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + if ($_POST) { + // if the user is beign approved + if ($_REQUEST['status'] == 'approved') { + // expire date needs to be greater or equal to current date + $expire = filter_var( + $_REQUEST['expire'], + FILTER_VALIDATE_REGEXP, + array( + 'options' => array( + 'regexp' => '%[0-9]{2}/[0-9]{2}/[0-9]{4}%' + ) + ) + ); + $isActiveDate + = (!$expire || strtotime($expire) >= mktime()); + if ($isActiveDate) { + $this->emailUser('approved'); + } + } + // if the user is being denied + if ($_REQUEST['status'] == 'denied') { + $this->emailUser('denied'); + } + + $saved = $mediaMapper->saveUserWithPost(); + if ($saved) { + $status = filter_var( + $_REQUEST['userStatus'], FILTER_SANITIZE_STRING + ); + header( + 'Location: ' . $this->registry->page.'?ac=listUsers' + . '&userStatus=' . $status + ); + exit; + } + exit; + } + $userId + = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + $flexyOptions + = $this->registry->config->flexyOptions->toArray(); + $tpl = new HTML_Template_Flexy($flexyOptions); + $page = new stdClass(); + $this->_setNav($page); + if ($userId) { + $page->user = $mediaMapper->fetchUserById($userId); + } + $page->formAction = $this->registry->page . '?ac=editUser'; + $tpl->compile(self::EDIT_USER_TPL); + return $this->_createPage($tpl->bufferedOutputObject($page)); + } + + public function emailUser($status) + { + $userId + = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $page = new stdClass(); + $page->user = $mediaMapper->fetchUserById($userId); + if (!$page->user instanceof Toolkit_Photos_Models_User) { + return false; + } + if (!$page->user->getEmail()) { + return false; + } + $page->title = SITENAME . ' Media Gallery'; + $page->subject = 'Your Media Request for Photos - Traverse City'; + $page->email_from = MEDIA_REQUEST_FORM_EMAIL; + switch ($status) { + case 'approved' : + $page->approved = true; + break; + case 'denied' : + $page->denied = true; + break; + default : + return false; + } + $flexyOptions = $GLOBALS['flexyOptions']; + $flexyOptions['templateDir'] = BASE . 'Toolkit/Photos/templates/Admin'; + $flexyOptions['compileDir'] = BASE . 'Toolkit/Photos/templates/compiled'; + $tpl = new HTML_Template_Flexy($flexyOptions); + $tpl->compile('emailUser.tpl'); + $htmlMsg = $tpl->bufferedOutputObject($page); + $msg = strip_tags($htmlMsg); + $mimeMail = new Mail_mime("\n"); + $mimeMail->setFrom("Traverse City Media Gallery <".MEDIA_REQUEST_FORM_EMAIL.">"); + $mimeMail->setSubject($page->subject); + $mimeMail->setHTMLBody($htmlMsg); + $mimeMail->setTXTBody($msg); + + $mail =& Mail::factory('mail'); + $body = $mimeMail->get(); + $setHeader['Reply-To'] = "Traverse City Media Gallery <".MEDIA_REQUEST_FORM_EMAIL.">"; + + $headers = $mimeMail->headers($setHeader); + + $res = $mail->send($page->user->getEmail(), $headers, $body); + if (PEAR::isError($res)) { + return Toolkit_Common::handleError($res); + } else { + return $res; + } + exit; + } + + public function moveCategoriesAction() + { + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $values = filter_var_array( + $_REQUEST, + array( + 'catPhotos' => array( + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FORCE_ARRAY + ) + ) + ); + if ($values['catPhotos']) { + $mediaMapper->saveCategoryPositionsByArray($values['catPhotos']); + } + return true; + } + + public function movePhotosAction() + { + $categoryId = filter_var($_REQUEST['categoryId'], FILTER_VALIDATE_INT); + if (!$categoryId) { + return false; + } + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->registry->dbh + ); + $values = filter_var_array( + $_REQUEST, + array( + 'categoryId' => FILTER_VALIDATE_INT, + 'photos' => array( + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FORCE_ARRAY + ) + ) + ); + if ($values['photos']) { + $mediaMapper->savePhotoPositionsByCategory( + $values['photos'], + $values['categoryId'] + ); + } + return '
    '.print_r($photo2categories, true).'
    '; + } + + private function _getCss() + { + return Toolkit_Common::getStyleSheets(); + } + + private function _getTopScripts() + { + return Toolkit_Common::getScripts($GLOBALS['topScripts']); + } + + private function _getBottomScripts() + { + return Toolkit_Common::getScripts($GLOBALS['bottomScripts']); + } + +} diff --git a/Toolkit/Photos/Database/addSlideShow.sql b/Toolkit/Photos/Database/addSlideShow.sql new file mode 100644 index 0000000..3dc1a96 --- /dev/null +++ b/Toolkit/Photos/Database/addSlideShow.sql @@ -0,0 +1,7 @@ +-- +-- adding slideshow +-- + +ALTER TABLE photos.photo_category ADD slideshow BOOLEAN; +ALTER TABLE photos.photo_category ALTER slideshow SET DEFAULT false; +UPDATE photos.photo_category SET slideshow = false; diff --git a/Toolkit/Photos/Database/application.sql b/Toolkit/Photos/Database/application.sql new file mode 100644 index 0000000..eb1c72c --- /dev/null +++ b/Toolkit/Photos/Database/application.sql @@ -0,0 +1,10 @@ +CREATE SCHEMA photos; +GRANT ALL ON SCHEMA photos TO nobody; +-- +-- Tables +-- +\i ./tables/photo_category.sql +\i ./tables/photo.sql +\i ./tables/photo_category_bus.sql +\i ./tables/photo_default.sql +\i ./tables/photo2category.sql diff --git a/Toolkit/Photos/Database/removeApplication.sql b/Toolkit/Photos/Database/removeApplication.sql new file mode 100644 index 0000000..7428041 --- /dev/null +++ b/Toolkit/Photos/Database/removeApplication.sql @@ -0,0 +1,8 @@ +-- +-- This will drop everything in the photos schema. +-- Nothing better be in here except photos related objects +-- or it will be dropped +-- +-- The force is strong w/ this one, use it wisely. +-- +DROP SCHEMA IF EXISTS photos CASCADE; diff --git a/Toolkit/Photos/Database/resetSequences.sql b/Toolkit/Photos/Database/resetSequences.sql new file mode 100644 index 0000000..4cd9be2 --- /dev/null +++ b/Toolkit/Photos/Database/resetSequences.sql @@ -0,0 +1,7 @@ +-- +-- Need to reset sequences for photos tables +-- try running this file +-- +SET search_path TO photos; +SELECT setval('photo_id_seq', (SELECT max(id) FROM photos.photo)); +SELECT setval('photo_category_id_seq', (SELECT max(id) FROM photos.photo_category)); \ No newline at end of file diff --git a/Toolkit/Photos/Database/tables/photo.sql b/Toolkit/Photos/Database/tables/photo.sql new file mode 100755 index 0000000..7ca56ad --- /dev/null +++ b/Toolkit/Photos/Database/tables/photo.sql @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS photos.photo CASCADE; + +CREATE TABLE photos.photo +(id SERIAL, + title TEXT, + description TEXT, + image TEXT, + catid INTEGER NOT NULL + REFERENCES photos.photo_category (id) + ON UPDATE CASCADE + ON DELETE CASCADE, + pos INTEGER, + exclusive BOOLEAN DEFAULT false, + download BOOLEAN DEFAULT false, + PRIMARY KEY (id)); + +GRANT ALL on photos.photo_id_seq to nobody; +GRANT ALL on photos.photo to nobody; diff --git a/Toolkit/Photos/Database/tables/photo2category.sql b/Toolkit/Photos/Database/tables/photo2category.sql new file mode 100644 index 0000000..654915e --- /dev/null +++ b/Toolkit/Photos/Database/tables/photo2category.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS photos.photo2category CASCADE; + +CREATE TABLE photos.photo2category +( + id SERIAL, + photo INTEGER, + category INTEGER, + pos INTEGER, + PRIMARY KEY (id) +); + +GRANT ALL ON photos.photo2category TO nobody; +GRANT ALL ON photos.photo2category_id_seq TO nobody; \ No newline at end of file diff --git a/Toolkit/Photos/Database/tables/photo_category.sql b/Toolkit/Photos/Database/tables/photo_category.sql new file mode 100755 index 0000000..bd22f55 --- /dev/null +++ b/Toolkit/Photos/Database/tables/photo_category.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS photos.photo_category CASCADE; + +CREATE TABLE photos.photo_category +(id SERIAL, + category TEXT, + image TEXT, + pos INTEGER, + exclusive BOOLEAN DEFAULT false, + slideshow BOOLEAN DEFAULT false, + PRIMARY KEY (id)); + +GRANT ALL ON photos.photo_category_id_seq TO nobody; +GRANT ALL ON photos.photo_category TO nobody; diff --git a/Toolkit/Photos/Database/tables/photo_category_bus.sql b/Toolkit/Photos/Database/tables/photo_category_bus.sql new file mode 100755 index 0000000..41592ec --- /dev/null +++ b/Toolkit/Photos/Database/tables/photo_category_bus.sql @@ -0,0 +1,20 @@ +DROP TABLE IF EXISTS photos.photo_category_bus CASCADE; + +CREATE TABLE photos.photo_category_bus +(id SERIAL, + photocat_id INTEGER + REFERENCES photos.photo_category (id) + ON UPDATE CASCADE + ON DELETE CASCADE, + buscat_id INTEGER + REFERENCES toolbox.pages (id) + ON UPDATE CASCADE + ON DELETE CASCADE, + pos INTEGER, + PRIMARY KEY (id) +); + +GRANT ALL ON photos.photo_category_bus_id_seq TO nobody; +GRANT ALL ON photos.photo_category_bus TO nobody; + +CREATE UNIQUE INDEX photo_category_bus_bus_phot_indx on photos.photo_category_bus (buscat_id ,photocat_id); diff --git a/Toolkit/Photos/Database/tables/photo_default.sql b/Toolkit/Photos/Database/tables/photo_default.sql new file mode 100755 index 0000000..8dc9467 --- /dev/null +++ b/Toolkit/Photos/Database/tables/photo_default.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS photos.photo_default CASCADE; + +CREATE TABLE photos.photo_default +(id SERIAL, + header TEXT, + description TEXT, + PRIMARY KEY (id)); + +GRANT ALL ON photos.photo_default_id_seq TO nobody; +GRANT ALL ON photos.photo_default TO nobody; diff --git a/Toolkit/Photos/Database/updatePhotos.sql b/Toolkit/Photos/Database/updatePhotos.sql new file mode 100644 index 0000000..b3ee1dc --- /dev/null +++ b/Toolkit/Photos/Database/updatePhotos.sql @@ -0,0 +1,20 @@ +-- +-- Update photo tables +-- + +\i ./tables/photo2category.sql + +ALTER TABLE photos.photo_category ALTER pos SET DEFAULT 1; +ALTER TABLE photos.photo_category ADD exclusive bool; +ALTER TABLE photos.photo_category ALTER exclusive set default false; +UPDATE photos.photo_category SET exclusive = false; + +ALTER TABLE photos.photo add exclusive bool; +ALTER TABLE photos.photo ALTER exclusive set default false; +UPDATE photos.photo SET exclusive = false; + +ALTER TABLE photos.photo add download bool; +ALTER TABLE photos.photo ALTER download set default false; +UPDATE photos.photo SET download = false; + +ALTER TABLE contacts.contact ADD title TEXT; \ No newline at end of file diff --git a/Toolkit/Photos/Database/upgradeApp.sql b/Toolkit/Photos/Database/upgradeApp.sql new file mode 100644 index 0000000..d8e285b --- /dev/null +++ b/Toolkit/Photos/Database/upgradeApp.sql @@ -0,0 +1,15 @@ +-- +-- Upgrade (movie schemas) +-- + +CREATE SCHEMA oldphotos; +GRANT ALL ON oldphotos TO nobody; + +ALTER TABLE public.photo SET SCHEMA oldphotos; +ALTER TABLE public.photo_category SET SCHEMA oldphotos; +ALTER TABLE public.photo_category_bus SET SCHEMA oldphotos; +ALTER TABLE public.photo_default SET SCHEMA oldphotos; + +INSERT INTO photos.photo_category (SELECT * FROM oldphotos.photo_category); +INSERT INTO photos.photo (SELECT * FROM oldphotos.photo); +INSERT INTO photos.photo_category_bus (SELECT * FROM oldphotos.photo_category_bus); \ No newline at end of file diff --git a/Toolkit/Photos/Display.php b/Toolkit/Photos/Display.php new file mode 100644 index 0000000..5f88ba4 --- /dev/null +++ b/Toolkit/Photos/Display.php @@ -0,0 +1,384 @@ + + * @copyright 2009 Gaslight Media + * @license Gaslight Media + * @version CVS: $Id: Display.php,v 1.10 2010/07/04 23:55:12 jamie Exp $ + * @link <> + */ + +/** + * Toolkit_Photos_Display + * + * Display the Photo Gallery assoc to a toolbox page + * + * @category Photos + * @package Toolkit_Photos + * @author Steve Sutton + * @copyright 2009 Gaslight Media + * @license Gaslight Media + * @link <> + */ +class Toolkit_Photos_Display +{ + // {{{ Properties + + private $_dbh; + + /** + * Options for Flexy Templates + * @var array + * @access protected + */ + protected $flexyOptions; + + /** + * page name for form action and links + * @var unknown + * @access protected + */ + protected $pageName; + + /** + * Photo Table Name + * @var string + * @access protected + */ + protected $photoTable = 'photo'; + + /** + * Photo Category Table Name + * @var string + * @access protected + */ + protected $categoryTable = 'photo_category'; + + /** + * rowCount + * + * @var float + * @access protected + */ + protected $rowCount = 4; + protected $baseURL; + protected $glmAppBaseURL; + protected $pageId; + protected $config; + + const PHOTO_GALLERY_WRAPPER_TPL = 'photoGalleryWrapper.html'; + const PHOTO_SLIDER = 'photoSlider.html'; + // }}} + // {{{ __construct() + + /** + * __construct() + * + * @return void + * @access public + */ + function __construct(PDO $dbh) + { + $this->pageId = filter_var($_REQUEST['catid'], FILTER_VALIDATE_INT); + $this->_dbh = $dbh; + // create a Zend Config Object and store into Registry + $config = new Zend_Config_Ini( + BASE . 'Toolkit/Photos/application.ini', + strtolower($_ENV['GLM_HOST_ID']) + ); + $this->config = $config; + $this->flexyOptions = $config->flexyOptions->toArray(); + + // the main display page for events to link to + $this->pageName = BASE_URL . 'index.php?catid=' . $_REQUEST['catid']; + $this->baseURL = ($_SERVER['HTTPS'] == 'on') + ? BASE_SECURE_URL + : BASE_URL; + $this->glmAppBaseURL = ($_SERVER['HTTPS'] == 'on') + ? GLM_APP_BASE_SECURE_URL + : GLM_APP_BASE_URL; + } + + // }}} + public function getSlideShow(array $photoCatIds, $galleries) + { + $GLOBALS['styleSheets'][] = $this->glmAppBaseURL + . 'libjs/plugins/nivoslider/3.2/prod/nivo-slider.css'; + $GLOBALS['styleSheets'][] = $this->glmAppBaseURL + . 'libjs/plugins/nivoslider/themes/default/default.css'; + $GLOBALS['bottomScripts'][] = $this->glmAppBaseURL + . 'libjs/plugins/nivoslider/3.2/prod/jquery.nivo.slider.js'; + $tpl = new HTML_Template_Flexy($this->flexyOptions); + $tpl->compile(self::PHOTO_SLIDER); + + $page = new stdClass(); + + // Filter the categories so only slideshow ones are in $categories + $categories = $this->getCategories($photoCatIds); + $iterator = new Toolkit_Photos_SlideShowCategoryFilter( + $categories->getIterator() + ); + $slideShowCategories = new ArrayObject(); + $photoCatIds = array(); + foreach ($iterator as $index) { + $slideShowCategories->append($index); + $photoCatIds[] = $index['id']; + } + if (empty($photoCatIds)) { + return false; + } + + $page->categories = $slideShowCategories; + $page->searchFormUrl = $this->pageName; + $page->pageId = $this->pageId; + $page->base_url = BASE_URL; + $page->webUrl = BASE_URL . 'download-photo-web/'; + $page->printUrl = BASE_URL . 'download-photo-print/'; + $page->photoUrlLarge = FILE_SERVER_URL . IS_OWNER_ID + . '/rotatingImagesResized/'; + $page->photoUrlSmall = FILE_SERVER_URL . IS_OWNER_ID + . '/mediaGallery/'; + $catid = filter_var($_REQUEST['photoCategoryId']); + + if (count($page->categories) == 1) { + $catid = $photoCatIds[0]; + } + $photoCatSelected = ($catid) + ? $catid + : $photoCatIds[0]; + $page->photos = $this->getPhotosByCatid( + $photoCatSelected, + $this->getLoginStatus() + ); + + + return $tpl->bufferedOutputObject($page); + } + // {{{ toHTML() + + /** + * toHTML() + * + * call to listPhotos function for display of Photos + * + * @return void + * @access public + */ + public function toHTML(array $photoCatIds, $galleries) + { + $GLOBALS['styleSheets'][] + = $this->baseURL . 'photoswipe/photoswipe.css'; + $GLOBALS['styleSheets'][] + = $this->baseURL . 'Toolkit/Photos/css/gallery.css'; + $GLOBALS['bottomScripts'][] + = $this->baseURL . 'photoswipe/lib/klass.min.js'; + $GLOBALS['bottomScripts'][] + = $this->baseURL . 'photoswipe/code.photoswipe.jquery-3.0.5.js'; + $GLOBALS['bottomScripts'][] + = $this->baseURL . 'Toolkit/Photos/js/photoGallery.js'; + + $GLOBALS['styleSheets'][] = $this->glmAppBaseURL + . 'libjs/jqueryui/1.8.13/development-bundle/themes/base/jquery.ui.all.css'; + $GLOBALS['styleSheets'][] = $this->baseURL + . 'Toolkit/Photos/css/style.css'; + $GLOBALS['styleSheets'][] = $this->baseURL + . 'css/contactform.css'; + $GLOBALS['topScripts'][] = $this->glmAppBaseURL + . 'libjs/jqueryui/1.8.13/js/jquery-ui-1.8.13.custom.min.js'; + + $tpl = new HTML_Template_Flexy($this->flexyOptions); + $tpl->compile(self::PHOTO_GALLERY_WRAPPER_TPL); + + $page = new stdClass(); + $page->mediaExclusive = $this->config->settings->mediaExclusive; + $page->photoNameSearch = $this->config->settings->photoNameSearch; + $page->galleries = $galleries; + $page->pageId = $this->pageId; + $page->base_url = BASE_URL; + $page->mediaGalleryRequestFormUrl = BASE_URL . 'media-gallery-request-form-' + . MEDIA_GALLERY_REQUEST_FORM . '/'; + $page->isLoggedIn = $this->getLoginStatus(); + $page->loginUrl = BASE_URL . 'Toolkit/Photos/login.php'; + $page->logoutUrl = BASE_URL . 'Toolkit/Photos/login.php?catid=' + . $_REQUEST['catid'] . '&logout=1'; + $page->photoSearchFormUrl = $this->pageName; + $page->photoUrlLarge = PHOTO_LARGE_URL; + $page->photoUrlSmall = FILE_SERVER_URL . IS_OWNER_ID . '/mediaGallery/'; + $page->photoDownWeb = BASE_URL . "download-photo-web/"; + $page->photoDownPrint = BASE_URL . "download-photo-print/"; + + // Filter out the slideshow categories + $categories = $this->getCategories($photoCatIds); + $iterator = new Toolkit_Photos_GalleryCategoryFilter( + $categories->getIterator() + ); + $galleryCategories = new ArrayObject(); + $photoCatIds = array(); + foreach ($iterator as $index) { + $galleryCategories->append($index); + $photoCatIds[] = $index['id']; + } + if (empty($photoCatIds)) { + return false; + } + $page->categories = $galleryCategories; + + $failedStatus = $this->_getFailedLoginStatus(); + $page->expired = false; + if ($failedStatus == -4) { + $page->failedStatus = ''; + $page->expired = true; + } else { + $page->failedStatus = $failedStatus; + } + + $catid = filter_var($_REQUEST['photoCategoryId'], FILTER_VALIDATE_INT); + $photoName = filter_var($_REQUEST['photo_name'], FILTER_SANITIZE_STRING); + + if (count($page->categories) == 1) { + $catid = $photoCatIds[0]; + } + if ($photoName) { + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->_dbh + ); + $gallery = new Toolkit_Photos_Gallery( + Toolkit_Database::getInstance(), + new Toolkit_Photos_Display( + Toolkit_Database::getInstance() + ) + ); + $page->photos = $mediaMapper->fetchPhotosByNameAndCats( + $photoName, $gallery->getPageGalleries($this->pageId) + ); + } else if ($catid) { + $photoCatSelected = ($catid) + ? $catid + : $photoCatIds[0]; + $photoCategory = $this->getPhotoCategory($photoCatSelected); + $page->photoCategoryName = $photoCategory['category']; + $page->photos = $this->getPhotosByCatid( + $photoCatSelected, $page->isLoggedIn + ); + } else { + $page->photoUrl = $this->pageName . '&photoCategoryId='; + $page->catPhotos = $this->getCategoriesForPage($photoCatIds); + } + + return $tpl->bufferedOutputObject($page); + } + + // }}} + + public function getLoginStatus() + { + $authContainer = new Toolkit_Photos_AuthContainer( + Toolkit_Database::getInstance() + ); + + $photoAuth = new Toolkit_Photos_Auth( + $authContainer, '', false + ); + $photoAuth->start(); + return $photoAuth->checkAuth(); + } + + private function _getFailedLoginStatus() + { + $failStatus = filter_var($_REQUEST['status'], FILTER_VALIDATE_INT); + switch ($failStatus) { + case -1: + $status = 'Idled'; + break; + case -2: + $status = 'Expired'; + break; + case -3: + $status = 'Incorrect Username/Password supplied'; + break; + case -4: + return -4; + $url = BASE_URL . 'media-gallery-request-form-' + . MEDIA_GALLERY_REQUEST_FORM . '/'; + $status = 'Your login has expired'; + $status .= ' Ask for more time'; + break; + default: + $status = ''; + break; + } + return $status; + } + + public function getPhotosByCatid($catid, $isLogedIn) + { + $filter = (!$isLogedIn) + ? array("exclusive <> true") + : ''; + + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->_dbh + ); + $photos = $mediaMapper->fetchAllPhotosByCatid( + $catid, $filter + ); + return $photos; + } + + public function getCategoriesForPage($photoCats) + { + $categories = new ArrayObject(); + $mediaMapper = new Toolkit_Photos_Models_MediaMapper( + $this->_dbh + ); + if (is_array($photoCats) && !empty($photoCats)) { + $index = 0; + foreach ($photoCats as $cat) { + $categories->offsetSet( + $index, $mediaMapper->fetchCategoryById($cat) + ); + ++$index; + } + } + return $categories; + } + + public function getCategories($photoCats) + { + $categories = new ArrayObject(); + if (is_array($photoCats) && !empty($photoCats)) { + $index = 0; + foreach ($photoCats as $cat) { + $categories->offsetSet( + $index, $this->getPhotoCategory($cat) + ); + ++$index; + } + } + return $categories; + } + + public function getPhotoCategory($categoryId) + { + try { + $sql = " + SELECT * + FROM photos.photo_category + WHERE id = :id + ORDER BY pos"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $categoryId, PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + +} diff --git a/Toolkit/Photos/Exception.php b/Toolkit/Photos/Exception.php new file mode 100644 index 0000000..82dfa3c --- /dev/null +++ b/Toolkit/Photos/Exception.php @@ -0,0 +1,3 @@ + diff --git a/Toolkit/Photos/Factory.php b/Toolkit/Photos/Factory.php new file mode 100644 index 0000000..048c5f5 --- /dev/null +++ b/Toolkit/Photos/Factory.php @@ -0,0 +1,21 @@ +createByValues($values); + return $photo; + } +} +?> diff --git a/Toolkit/Photos/Gallery.php b/Toolkit/Photos/Gallery.php new file mode 100644 index 0000000..e658738 --- /dev/null +++ b/Toolkit/Photos/Gallery.php @@ -0,0 +1,169 @@ + + * @copyright 2010 Jamie Kahgee + * @license http://www.gaslightmedia.com/ Gaslightmedia + * @version CVS: $Id: Gallery.php,v 1.1 2010/06/09 19:52:24 jamie Exp $ + * @link <> + * @see References to other sections (if any)... + */ + +/** + * Fetches photo galleries assigned to pages + * + * @category Toolkit_Photos + * @package Photos + * @author Jamie Kahgee + * @copyright 2010 Jamie Kahgee + * @license http://www.gaslightmedia.com/ Gaslightmedia + * @version Release: @package_version@ + * @link <> + * @see References to other sections (if any)... + */ +class Toolkit_Photos_Gallery +{ + // {{{ properties + + /** + * Database handler + * @var object + * @access private + */ + private $_dbh; + + /** + * Toolkit_Photos_Display object + * @var object + * @access private + */ + private $_photoApp; + + // }}} + // {{{ __construct() + + /** + * Constructor + * + * @param PDO $dbh Database handler + * @param Toolkit_Photos_Display $photoApp Photo Gallery Display object + * @return void + * @access public + */ + public function __construct(PDO $dbh, Toolkit_Photos_Display $photoApp) + { + $this->_dbh = $dbh; + $this->_photoApp = $photoApp; + } + + // }}} + // {{{ _getGalleriesAssignedToPage() + + /** + * Gets an array of photo galleries assigned to page + * + * If we were on a page that contained multiple galleries + * and we move into a single gallery page - this function + * returns that single gallery, so we can view all its photos + * + * @param integer $pageId Id of page we're on + * + * @return array multi-dimensional array of photo galleries assigned to page + * @access private + * @throws Toolkit_Photos_Exception If can't query for galleries on page + */ + private function _getGalleriesAssignedToPage($pageId) + { + if (isset($_GET['photo_catid']) && ctype_digit($_GET['photo_catid'])) { + return array( + array('photocat_id' => $_GET['photo_catid']) + ); + } + + try { + $where + = (!$this->_photoApp->getLoginStatus()) + ? " AND exclusive <> true" + : ''; + $sql = " + SELECT pcb.photocat_id + FROM photo_category_bus pcb, photo_category pc + WHERE buscat_id = :pageId + AND pc.id = pcb.photocat_id + AND pc.id IN ( + SELECT distinct category + FROM photo2category + ) + $where + ORDER BY pc.pos"; + + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':pageId', $pageId, PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_Photos_Exception( + "Unable to check if page has a gallery `$pageId`" + ); + } + } + + // }}} + public function getPageGalleries($pageId) + { + $cats = array(); + $galleries = $this->_getGalleriesAssignedToPage($pageId); + foreach ($galleries as $galley) { + $cats[] = $galley['photocat_id']; + } + return $cats; + } + // {{{ getPageGallery() + + /** + * Gets the page galleries / gallery + * + * @param integer $pageId Id of page we're on + * + * @return string photo gallery output + * @access public + */ + public function getPageGallery($pageId) + { + $galleries = $this->_getGalleriesAssignedToPage($pageId); + + $photoCatIds = array(); + foreach ($galleries as $gallery) { + $photoCatIds[] = $gallery['photocat_id']; + } + + return !empty($photoCatIds) + ? $this->_photoApp->toHTML($photoCatIds, $galleries) + : ''; + } + + // }}} + + public function getPageSlideShow($pageId) + { + $galleries = $this->_getGalleriesAssignedToPage($pageId); + + $photoCatIds = array(); + foreach ($galleries as $gallery) { + $photoCatIds[] = $gallery['photocat_id']; + } + + return !empty($photoCatIds) + ? $this->_photoApp->getSlideShow($photoCatIds, $galleries) + : ''; + } +} diff --git a/Toolkit/Photos/GalleryCategoryFilter.php b/Toolkit/Photos/GalleryCategoryFilter.php new file mode 100644 index 0000000..d90e91e --- /dev/null +++ b/Toolkit/Photos/GalleryCategoryFilter.php @@ -0,0 +1,46 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Photos_GalleryCategoryFilter + * + * Description of SlideShowFilter + * + * @category Toolkit + * @package Photos + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_GalleryCategoryFilter + extends FilterIterator +{ + public function __construct(Iterator $iterator) + { + parent::__construct($iterator); + } + + public function accept() + { + $category = $this->getInnerIterator()->current(); + if (!$category['slideshow']) { + return true; + } + return false; + } +} diff --git a/Toolkit/Photos/Models/Category.php b/Toolkit/Photos/Models/Category.php new file mode 100644 index 0000000..eccd7c8 --- /dev/null +++ b/Toolkit/Photos/Models/Category.php @@ -0,0 +1,156 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Photos_Models_Category + * + * Represents the Category for Media Gallery + * + * @category Toolkit + * @package Media + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Models_Category +{ + private $_id; + private $_category; + private $_exclusive; + private $_slideshow; + private $_pos; + + const TABLE_NAME = 'photos.photo_category'; + const PRI_KEY = 'id'; + const SORT = 'pos'; + + private function __construct($values) + { + extract($values); + $this->setCategory($category) + ->setExclusive($exclusive) + ->setSlideShow($slideshow) + ->setPos($pos); + if ($id) { + $this->setId($id); + } + } + + static public function createByValues($values) + { + return new Toolkit_Photos_Models_Category($values); + } + + public function getFirstPhoto() + { + $dbh = Toolkit_Database::getInstance(); + try { + $sql = " + SELECT p.image + FROM photos.photo p, photos.photo2category p2c + WHERE p2c.pos = 1 + AND p2c.photo = p.id + AND p2c.category = :catid"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':catid', $this->getId(), PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchColumn(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + public function getTotalNumberOfPhotos() + { + $dbh = Toolkit_Database::getInstance(); + try { + $sql = " + SELECT count(p.id) + FROM photos.photo p, photos.photo2category p2c + WHERE p2c.photo = p.id + AND p2c.category = :catid"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':catid', $this->getId(), PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchColumn(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + public function getId() + { + return (int)$this->_id; + } + + public function setId($id) + { + $this->_id + = (filter_var($id, FILTER_VALIDATE_INT)) + ? $id + : null; + return $this; + } + + public function getPos() + { + return (int)$this->_pos; + } + + public function setPos($pos) + { + $this->_pos = (int)$pos; + return $this; + } + + + public function getCategory() + { + return $this->_category; + } + + public function setCategory($category) + { + $this->_category = $category; + return $this; + } + + public function getExclusive() + { + return (bool)$this->_exclusive; + } + + public function setExclusive($exclusive) + { + $this->_exclusive = (bool)$exclusive; + return $this; + } + + public function getSlideShow() + { + return (bool)$this->_slideshow; + } + + public function setSlideShow($slideshow) + { + $this->_slideshow = (bool)$slideshow; + return $this; + } + + +} diff --git a/Toolkit/Photos/Models/MediaMapper.php b/Toolkit/Photos/Models/MediaMapper.php new file mode 100644 index 0000000..53226e7 --- /dev/null +++ b/Toolkit/Photos/Models/MediaMapper.php @@ -0,0 +1,1003 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Photos_Models_MediaMapper + * + * Maps the Media Objects to methods to create and generate list of + * categories and photos. + * + * @category Toolkit + * @package Media + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Models_MediaMapper +{ + private $_dbh; + + public function __construct(PDO $dbh) + { + $this->_dbh = $dbh; + } + + public function fetchAllCategories() + { + $categories = new ArrayObject(); + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_Category::TABLE_NAME . " + ORDER BY " . Toolkit_Photos_Models_Category::SORT; + $stmt = $this->_dbh->query($sql); + while ($category = $stmt->fetch(PDO::FETCH_ASSOC)) { + $categories->append( + Toolkit_Photos_Models_Category::createByValues($category) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $categories; + } + + public function fetchAllPhotos($catId) + { + $photos = new ArrayObject(); + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_Photo::TABLE_NAME . " + WHERE catid = :catid + ORDER BY " . Toolkit_Photos_Models_Photo::SORT; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':catid', $catId, PDO::PARAM_INT); + $stmt->execute(); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photos->append( + Toolkit_Photos_Models_Photo::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $photos; + } + + public function fetchPhotosByName($distinct = false) + { + $nameSearch = filter_var($_REQUEST['photoName'], FILTER_SANITIZE_STRING); + if (!$nameSearch) { + return false; + } + $photos = new ArrayObject(); + try { + $nameSearch = $this->_dbh->quote('%' . $nameSearch . '%'); + $select + = (!$distinct) + ? '*' + : 'DISTINCT ON (title) title'; + $orderBy + = (!$distinct) + ? Toolkit_Photos_Models_Photo::SORT + : 'title'; + $sql = " + SELECT $select + FROM " . Toolkit_Photos_Models_Photo::TABLE_NAME . " + WHERE title ilike $nameSearch + ORDER BY $orderBy"; + $stmt = $this->_dbh->query($sql); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photos->append( + Toolkit_Photos_Models_Photo::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $photos; + } + + public function fetchPhotosByNameAndCats( + $nameSearch, + $galleries, + $distinct = false + ) { + if (!$nameSearch) { + die('here'); + return false; + } + $photos = new ArrayObject(); + try { + $nameSearch = $this->_dbh->quote('%' . $nameSearch . '%'); + $select + = (!$distinct) + ? '*' + : 'DISTINCT ON (title) title'; + $where + = (!empty($galleries)) + ? " AND id IN (SELECT photo FROM photo2category WHERE category IN (" + . implode(",", $galleries) . "))" + : ''; + $orderBy + = (!$distinct) + ? Toolkit_Photos_Models_Photo::SORT + : 'title'; + $sql = " + SELECT $select + FROM " . Toolkit_Photos_Models_Photo::TABLE_NAME . " + WHERE title ilike $nameSearch + $where + ORDER BY $orderBy"; + $stmt = $this->_dbh->query($sql); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photos->append( + Toolkit_Photos_Models_Photo::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $photos; + } + + public function fetchAllPhotosByCatid($catId, $filter = null) + { + $photos = new ArrayObject(); + try { + $where + = ($filter) + ? "AND " . implode(" AND ", $filter) + : ''; + $sql = " + SELECT p.* + FROM " . Toolkit_Photos_Models_Photo::TABLE_NAME . " p, + " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " p2c + WHERE p2c.category = :catid + AND p2c.photo = p.id + $where + ORDER BY p2c.pos"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':catid', $catId, PDO::PARAM_INT); + $stmt->execute(); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photos->append( + Toolkit_Photos_Models_Photo::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $photos; + } + + public function fetchPhoto2CategoryByPhotoId($photoId) + { + $photo2Categories = new ArrayObject(); + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " + WHERE photo = :photo + ORDER BY " . Toolkit_Photos_Models_Photo2Category::SORT; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':photo', $photoId, PDO::PARAM_INT); + $stmt->execute(); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photo2Categories->offsetSet( + $photo['category'], + Toolkit_Photos_Models_Photo2Category::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $photo2Categories; + } + + public function fetchPhoto2Category($catId) + { + $photo2Categories = new ArrayObject(); + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " + WHERE category = :catid + ORDER BY " . Toolkit_Photos_Models_Photo2Category::SORT; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':catid', $catId, PDO::PARAM_INT); + $stmt->execute(); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photo2Categories->append( + Toolkit_Photos_Models_Photo2Category::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $photo2Categories; + } + + public function fetchCategoryPages($catId) + { + $pages2Categories = new ArrayObject(); + try { + $sql = " + SELECT pcb.buscat_id as page, p.navigation_name as page_name, pcb.pos as pos + FROM photo_category_bus pcb, photo_category pc, pages p + WHERE pc.id IN ( + SELECT photocat_id + FROM photo_category_bus + WHERE photocat_id = :catid) + AND pcb.photocat_id = pc.id + AND p.id = pcb.buscat_id + ORDER BY pcb.pos"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':catid', $catId, PDO::PARAM_INT); + $stmt->execute(); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $pages2Categories->append( + $photo + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $pages2Categories; + } + + public function fixAllPhoto2Cats() + { + $sql = " + DELETE FROM photos.photo2category"; + $this->_dbh->query($sql); + // first grab all categories + $categories = $this->fetchAllCategories(); + foreach ($categories as $category) { + var_dump($category); + $photos = $this->fetchAllPhotos($category->getId()); + var_dump($photos); + if ($photos) { + foreach ($photos as $photo) { + $photo2Category + = Toolkit_Photos_Models_Photo2Category::createByValues( + array( + 'category' => $category->getId(), + 'photo' => $photo->getId(), + 'pos' => $photo->getPos() + ) + ); + $this->savePhoto2Category($photo2Category); + } + } + } + exit; + } + + public function fetchPhotoById($photoId) + { + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_Photo::TABLE_NAME . " + WHERE " . Toolkit_Photos_Models_Photo::PRI_KEY . " = :id"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $photoId, PDO::PARAM_INT); + $stmt->execute(); + return Toolkit_Photos_Models_Photo::createByValues( + $stmt->fetch(PDO::FETCH_ASSOC) + ); + + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function saveCategoryWithPost() + { + if ($_REQUEST['Cancel']) { + return true; + } + if ($_REQUEST['Delete']) { + // delete the category + $category = $this->fetchCategoryById($_REQUEST['id']); + $this->removeCategory($category); + return true; + } + $postedData = filter_var_array( + $_POST, + array( + 'id' => FILTER_VALIDATE_INT, + 'pos' => FILTER_VALIDATE_INT, + 'pages' => array( + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FORCE_ARRAY + ), + 'category' => array( + 'filter' => FILTER_SANITIZE_STRIPPED, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'exclusive' => FILTER_VALIDATE_BOOLEAN, + 'slideshow' => FILTER_VALIDATE_BOOLEAN + ) + ); + if (get_magic_quotes_gpc()) { + $postedData['category'] = stripslashes($postedData['category']); + } + + $category = Toolkit_Photos_Models_Category::createByValues( + $postedData + ); + //var_dump($category);exit; + $id = $this->saveCategory($category); + + try { + $this->_dbh->beginTransaction(); + if ($postedData['id']) { + $sql = " + DELETE + FROM " . Toolkit_Photos_Models_Page2Category::TABLE_NAME . " + WHERE photocat_id = :category"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':category', $postedData['id'], PDO::PARAM_INT); + $stmt->execute(); + } + if ( is_array($postedData['pages']) + && !empty($postedData['pages']) + ) { + foreach ($postedData['pages'] as $pageId) { + $page2Category + = Toolkit_Photos_Models_Page2Category::createByValues( + array( + 'buscat_id' => $pageId, + 'photocat_id' => $category->getId() + ) + ); + $this->savePage2Category($page2Category); + } + } + + $this->_dbh->commit(); + } catch (PDOException $e) { + $this->_dbh->rollBack(); + Toolkit_Common::handleError($e); + } + + return true; + } + + public function saveCategory( + Toolkit_Photos_Models_Category $category + ) { + if ($category->getId()) { + $sql = " + UPDATE " . Toolkit_Photos_Models_Category::TABLE_NAME . " + SET category = :category, + exclusive = :exclusive, + slideshow = :slideshow, + pos = :pos + WHERE " . Toolkit_Photos_Models_Category::PRI_KEY . " = :id"; + + } else { + $sql = " + INSERT INTO " . Toolkit_Photos_Models_Category::TABLE_NAME . " + (category, exclusive, slideshow, pos) + VALUES + (:category, :exclusive, :slideshow, :pos) + RETURNING " . Toolkit_Photos_Models_Category::PRI_KEY; + } + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':category', $category->getCategory()); + $stmt->bindParam(':pos', $category->getPos(), PDO::PARAM_INT); + $stmt->bindParam(':exclusive', $category->getExclusive(), PDO::PARAM_BOOL); + $stmt->bindParam(':slideshow', $category->getSlideShow(), PDO::PARAM_BOOL); + if ($category->getId()) { + $stmt->bindParam(':id', $category->getId(), PDO::PARAM_INT); + } + $stmt->execute(); + if (!$category->getId()) { + $category->setId($stmt->fetchColumn()); + } + return $category->getId(); + } + + public function savePage2Category( + Toolkit_Photos_Models_Page2Category $page2Category + ) { + if ($page2Category->getId()) { + $sql = " + UPDATE " . Toolkit_Photos_Models_Page2Category::TABLE_NAME . " + SET photocat_id = :category, + buscat_id = :page + WHERE " . Toolkit_Photos_Models_Page2Category::PRI_KEY . " = :id"; + + } else { + $sql = " + INSERT INTO " . Toolkit_Photos_Models_Page2Category::TABLE_NAME . " + (photocat_id, buscat_id) + VALUES + (:category, :page) + RETURNING " . Toolkit_Photos_Models_Page2Category::PRI_KEY; + } + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':page', $page2Category->getBuscatId(), PDO::PARAM_INT); + $stmt->bindParam(':category', $page2Category->getPhotocatId(), PDO::PARAM_INT); + if ($page2Category->getId()) { + $stmt->bindParam(':id', $page2Category->getId(), PDO::PARAM_INT); + } + $stmt->execute(); + return ($page2Category->getId()) + ? $page2Category->getId() + : $stmt->fetchColumn(); + } + + public function savePhoto2Category( + Toolkit_Photos_Models_Photo2Category $photo2Category + ) { + if ($photo2Category->getId()) { + $sql = " + UPDATE " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " + SET photo = :photo, + category = :category, + pos = :pos + WHERE " . Toolkit_Photos_Models_Photo2Category::PRI_KEY . " = :id"; + + } else { + $sql = " + INSERT INTO " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " + (photo, category, pos) + VALUES + (:photo, :category, :pos) + RETURNING " . Toolkit_Photos_Models_Photo2Category::PRI_KEY; + } + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':photo', $photo2Category->getPhoto(), PDO::PARAM_INT); + $stmt->bindParam(':category', $photo2Category->getCategory(), PDO::PARAM_INT); + $stmt->bindParam(':pos', $photo2Category->getPos(), PDO::PARAM_INT); + if ($photo2Category->getId()) { + $stmt->bindParam(':id', $photo2Category->getId(), PDO::PARAM_INT); + } + $stmt->execute(); + return ($photo2Category->getId()) + ? $photo2Category->getId() + : $stmt->fetchColumn(); + } + + public function fetchCategoryById($categoryId) + { + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_Category::TABLE_NAME . " + WHERE " . Toolkit_Photos_Models_Category::PRI_KEY . " = :id"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $categoryId, PDO::PARAM_INT); + $stmt->execute(); + return Toolkit_Photos_Models_Category::createByValues( + $stmt->fetch(PDO::FETCH_ASSOC) + ); + + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function savePhotoPositionsByCategory($photos, $categoryId) + { + if (!is_array($photos) || empty($photos)) { + return false; + } + var_dump($photos); + var_dump($categoryId); + try { + $this->_dbh->beginTransaction(); + $sql = " + DELETE + FROM " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " + WHERE category = :category"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':category', $categoryId, PDO::PARAM_INT); + $stmt->execute(); + + foreach ($photos as $position => $photoId) { + $photo2Category + = Toolkit_Photos_Models_Photo2Category::createByValues( + array( + 'photo' => $photoId, + 'category' => $categoryId, + 'pos' => $position + 1 + ) + ); + $this->savePhoto2Category($photo2Category); + var_dump($photo2Category); + } + + $this->_dbh->commit(); + } catch (PDOException $e) { + $this->_dbh->rollBack(); + Toolkit_Common::handleError($e); + } + + } + + public function saveCategoryPositionsByArray($cats) + { + if (!is_array($cats) || empty($cats)) { + return false; + } +// var_dump($cats);exit; + foreach ($cats as $position => $catId) { + $category = $this->fetchCategoryById($catId); + $category->setPos((int)$position + 1); + $this->saveCategory($category); + } + } + + public function savePhotoWithPost() + { + if ($_REQUEST['Cancel']) { + return true; + } + if ($_REQUEST['Delete']) { + // delete the photo + $photo = $this->fetchPhotoById($_REQUEST['id']); + $this->removePhoto($photo); + return true; + } + + if ( $_FILES['image']['name'] + && !$_FILES['image']['error'] + ) { + $fs = new Toolkit_FileServer_ImageAdapter(); + $image = $fs->upload('image'); + } + $postedData = filter_var_array( + $_POST, + array( + 'id' => FILTER_VALIDATE_INT, + 'catid' => FILTER_VALIDATE_INT, + 'title' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'image' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'description' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'photo2Categories' => array( + 'filter' => FILTER_VALIDATE_INT, + 'flags' => FILTER_FORCE_ARRAY + ), + 'pos' => FILTER_VALIDATE_INT, + 'del_img' => FILTER_VALIDATE_BOOLEAN, + 'download' => FILTER_VALIDATE_BOOLEAN, + 'exclusive' => FILTER_VALIDATE_BOOLEAN, + ) + ); + + if (!$image && $postedData['del_img']) { + $postedData['image'] = ''; + } else if ($image) { + $postedData['image'] = $image['name']; + } + $photo = Toolkit_Photos_Models_Photo::createByValues( + $postedData + ); + $photoId = $this->savePhoto($photo); + $postedData['id'] = $photoId; + $this->savePhoto2CategoryData($postedData); + return $photoId; + } + + public function savePhoto2CategoryData($data) + { + if (!is_array($data) || empty($data)) { + return false; + } +// var_dump($data); + // need to get the current photo2category records for this photo + $currentCategories = $this->fetchPhoto2CategoryByPhotoId($data['id']); +// var_dump($currentCategories); + foreach ($data['photo2Categories'] as $catId) { + // if the offest does not exists then the photo need to be + // added to the category + if (!$currentCategories->offsetExists($catId)) { + $photoCatsNew = $this->fetchPhoto2Category($catId); + $newPosition = $photoCatsNew->count() + 1; + // need to add photo to the photo2category record as last pos + $newPhoto2Cat + = Toolkit_Photos_Models_Photo2Category::createByValues( + array( + 'photo' => $data['id'], + 'category' => $catId, + 'pos' => $newPosition + ) + ); +// var_dump($newPhoto2Cat); + $this->savePhoto2Category($newPhoto2Cat); +// var_dump('adding record for category ' . $catId); + } + // for each step through remove the iteration in the ArrayObject + // that way we know if we have to remove any records and reorder + $currentCategories->offsetUnset($catId); + } + foreach ($currentCategories as $photo2Category) { +// var_dump($photo2Category); + $this->removePhoto2Category($photo2Category); + } + } + + public function removeCategory( + Toolkit_Photos_Models_Category $category + ) { + // if there's any photos in the category that are only in that + // category then it will need to delete them. + try { + // 1. delete this category + $sql = " + DELETE + FROM photos.photo_category + WHERE id = :id"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $category->getId(), PDO::PARAM_INT); + $stmt->execute(); + // 2. delete all references in photo2category table for this category + $sql = " + DELETE + FROM photos.photo2category + WHERE category = :id"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $category->getId(), PDO::PARAM_INT); + $stmt->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function removePhoto( + Toolkit_Photos_Models_Photo $photo + ) { + $photo2Categories = $this->fetchPhoto2CategoryByPhotoId( + $photo->getId() + ); + + foreach ($photo2Categories as $photoCat) { + $this->removePhoto2Category($photoCat); + } + try { + $sql = " + DELETE + FROM photos.photo + WHERE id = :id"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $photo->getId(), PDO::PARAM_INT); + $stmt->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function removePhoto2Category( + Toolkit_Photos_Models_Photo2Category $photo2Category + ) { + try { + $sql = " + DELETE + FROM " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " + WHERE id = :id"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $photo2Category->getId(), PDO::PARAM_INT); + $stmt->execute(); + $sql = " + UPDATE " . Toolkit_Photos_Models_Photo2Category::TABLE_NAME . " + SET pos = pos - 1 + WHERE pos >= :pos + AND category = :category"; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':pos', $photo2Category->getPos(), PDO::PARAM_INT); + $stmt->bindParam(':category', $photo2Category->getCategory(), PDO::PARAM_INT); + $stmt->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function savePhoto( + Toolkit_Photos_Models_Photo $photo + ) { + try { + if ($photo->getId()) { + $sql = " + UPDATE " . Toolkit_Photos_Models_Photo::TABLE_NAME . " + SET title = :title, + catid = :catid, + description = :description, + image = :image, + pos = :pos, + download = :download, + exclusive = :exclusive + WHERE " . Toolkit_Photos_Models_Photo::PRI_KEY . " = :id"; + + } else { + $sql = " + INSERT INTO " . Toolkit_Photos_Models_Photo::TABLE_NAME . " + (title, catid, description, image, pos, download, exclusive) + VALUES + (:title, :catid, :description, :image, :pos, :download, :exclusive) + RETURNING " . Toolkit_Photos_Models_Photo::PRI_KEY; + } + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':title', $photo->getTitle()); + $stmt->bindParam(':catid', $photo->getCatid(), PDO::PARAM_INT); + $stmt->bindParam(':description', $photo->getDescription()); + $stmt->bindParam(':image', $photo->getImage()); + $stmt->bindParam(':pos', $photo->getPos(), PDO::PARAM_INT); + $stmt->bindParam(':download', $photo->getDownload(), PDO::PARAM_BOOL); + $stmt->bindParam(':exclusive', $photo->getExclusive(), PDO::PARAM_BOOL); + if ($photo->getId()) { + $stmt->bindParam(':id', $photo->getId(), PDO::PARAM_INT); + } + $stmt->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + return ($photo->getId()) + ? $photo->getId() + : $stmt->fetchColumn(); + } + + public function saveUserWithPost() + { + $postedData = filter_var_array( + $_POST, + array( + 'id' => FILTER_VALIDATE_INT, + 'status' => FILTER_SANITIZE_STRING, + 'expire' => array( + 'filter' => FILTER_VALIDATE_REGEXP, + 'options' => array( + 'regexp' => '%[0-9]{2}/[0-9]{2}/[0-9]{4}%' + ) + ), + 'phone' => FILTER_SANITIZE_STRING, + 'email' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'media_pass' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'company' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'title' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'fname' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'lname' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'address' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'address2' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'city' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'state' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ), + 'zip' => array( + 'filter' => FILTER_SANITIZE_STRING, + 'flags' => FILTER_FLAG_NO_ENCODE_QUOTES + ) + ) + ); + if ($postedData['status'] == 'approved') { + $postedData['approved'] = true; + $postedData['denied'] = false; + } else { + $postedData['approved'] = false; + $postedData['denied'] = true; + } + if (!$postedData['expire']) { + $postedData['expire'] = null; + } + + $user = Toolkit_Photos_Models_User::createByValues( + $postedData + ); + return $this->saveUser($user); + } + + public function saveUser( + Toolkit_Photos_Models_User $user + ) { + if ($user->getId()) { + $sql = " + UPDATE " . Toolkit_Photos_Models_User::TABLE_NAME . " + SET company = :company, + title = :title, + fname = :fname, + lname = :lname, + email = :email, + phone = :phone, + address = :address, + address2 = :address2, + city = :city, + state = :state, + zip = :zip, + media = true, + approved = :approved, + denied = :denied, + expire = :expire + WHERE " . Toolkit_Photos_Models_User::PRI_KEY . " = :id"; + + } else { + $sql = " + INSERT INTO " . Toolkit_Photos_Models_User::TABLE_NAME . " + (fname, lname, email, phone, + address, address2, city, state, zip, + approved, denied, expire, media) + VALUES + (:fname, :lname, :email, :phone, + :address, :address2, :city, :state, :zip, + :approved, :denied, :expire, true) + RETURNING " . Toolkit_Photos_Models_User::PRI_KEY; + } + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':expire', $user->getExpire()); + $stmt->bindParam(':company', $user->getCompany()); + $stmt->bindParam(':title', $user->getTitle()); + $stmt->bindParam(':fname', $user->getFname()); + $stmt->bindParam(':lname', $user->getLname()); + $stmt->bindParam(':email', $user->getEmail()); + $stmt->bindParam(':phone', $user->getPhone()); + $stmt->bindParam(':address', $user->getAddress()); + $stmt->bindParam(':address2', $user->getAddress2()); + $stmt->bindParam(':city', $user->getCity()); + $stmt->bindParam(':state', $user->getState()); + $stmt->bindParam(':zip', $user->getZip()); + $stmt->bindParam(':approved', $user->getApproved(), PDO::PARAM_BOOL); + $stmt->bindParam(':denied', $user->getDenied(), PDO::PARAM_BOOL); + if ($user->getId()) { + $stmt->bindParam(':id', $user->getId(), PDO::PARAM_INT); + } + $stmt->execute(); + return ($user->getId()) + ? $user->getId() + : $stmt->fetchColumn(); + } + + public function fetchUserById($userId) + { + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_User::TABLE_NAME . " + WHERE " . Toolkit_Photos_Models_User::PRI_KEY . " = :id + AND " . Toolkit_Photos_Models_User::WHERE; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':id', $userId, PDO::PARAM_INT); + $stmt->execute(); + return Toolkit_Photos_Models_User::createByValues( + $stmt->fetch(PDO::FETCH_ASSOC) + ); + + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function fetchUserByEmail($email) + { + try { + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_User::TABLE_NAME . " + WHERE " . Toolkit_Photos_Models_User::EMAIL . " = :email + AND " . Toolkit_Photos_Models_User::WHERE; + $stmt = $this->_dbh->prepare($sql); + $stmt->bindParam(':email', $email, PDO::PARAM_INT); + $stmt->execute(); + return Toolkit_Photos_Models_User::createByValues( + $stmt->fetch(PDO::FETCH_ASSOC) + ); + + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function fetchAllUsers() + { + $users = new ArrayObject(); + try { + $sql = " + SELECT * + FROM " . Toolkit_Media_Models_User::TABLE_NAME . " + WHERE media = true + ORDER BY " . Toolkit_Media_Models_User::SORT; + $sql .= " LIMIT 10 OFFSET 0"; + $stmt = $this->_dbh->prepare($sql); + $stmt->execute(); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $users->append( + Toolkit_Media_Models_User::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $users; + } + + public function fetchUsers(array $filters = null) + { + $users = new ArrayObject(); + try{ + $where = (is_array($filters) && !empty($filters)) + ? "AND " . implode(" AND ", $filters) + : ''; + $sql = " + SELECT * + FROM " . Toolkit_Photos_Models_User::TABLE_NAME . " + WHERE media = true + $where + ORDER BY " . Toolkit_Photos_Models_User::SORT; + $sql .= " LIMIT 10 OFFSET 0"; + $stmt = $this->_dbh->prepare($sql); + $stmt->execute(); + while ($photo = $stmt->fetch(PDO::FETCH_ASSOC)) { + $users->append( + Toolkit_Photos_Models_User::createByValues($photo) + ); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $users; + } + +} diff --git a/Toolkit/Photos/Models/Page2Category.php b/Toolkit/Photos/Models/Page2Category.php new file mode 100644 index 0000000..f79ec4d --- /dev/null +++ b/Toolkit/Photos/Models/Page2Category.php @@ -0,0 +1,92 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_Photo2Category + * + * Description of Photo2Category + * + * @category Toolkit + * @package Photos + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Models_Page2Category +{ + private $_id; + private $_photocatId; + private $_buscatId; + + const TABLE_NAME = 'photos.photo_category_bus'; + const PRI_KEY = 'id'; + const SORT = 'pos'; + + private function __construct($values) + { + extract($values); + $this->setBuscatId($buscat_id) + ->setPhotocatId($photocat_id); + if ($id) { + $this->setId($id); + } + } + + static public function createByValues($values) + { + return new Toolkit_Photos_Models_Page2Category($values); + } + + public function getId() + { + return (int)$this->_id; + } + + public function setId($id) + { + $this->_id + = (filter_var($id, FILTER_VALIDATE_INT)) + ? $id + : null; + return $this; + } + + public function getPhotocatId() + { + return $this->_photocatId; + } + + public function setPhotocatId($photocatId) + { + $this->_photocatId = $photocatId; + return $this; + } + + public function getBuscatId() + { + return $this->_buscatId; + } + + public function setBuscatId($buscatId) + { + $this->_buscatId = $buscatId; + return $this; + } + + +} diff --git a/Toolkit/Photos/Models/Photo.php b/Toolkit/Photos/Models/Photo.php new file mode 100644 index 0000000..0d3d8be --- /dev/null +++ b/Toolkit/Photos/Models/Photo.php @@ -0,0 +1,157 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Photos_Models_Photo + * + * Represents the Photo for Media Gallery + * + * @category Toolkit + * @package Media + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Models_Photo +{ + private $_id; + private $_title; + private $_description; + private $_image; + private $_catid; + private $_pos; + private $_download; + private $_exclusive; + + const TABLE_NAME = 'photos.photo'; + const PRI_KEY = 'id'; + const SORT = 'pos'; + + private function __construct($values) + { + extract($values); + $this->setTitle($title) + ->setDescription($description) + ->setImage($image) + ->setCatid($catid) + ->setPos($pos) + ->setDownload($download) + ->setExclusive($exclusive); + if ($id) { + $this->setId($id); + } + } + + static public function createByValues($values) + { + return new Toolkit_Photos_Models_Photo($values); + } + + public function getId() + { + return (int)$this->_id; + } + + public function setId($id) + { + $this->_id + = (filter_var($id, FILTER_VALIDATE_INT)) + ? $id + : null; + return $this; + } + + public function getTitle() + { + return $this->_title; + } + + public function setTitle($title) + { + $this->_title = $title; + return $this; + } + + public function getDescription() + { + return $this->_description; + } + + public function setDescription($description) + { + $this->_description = $description; + return $this; + } + + public function getImage() + { + return $this->_image; + } + + public function setImage($image) + { + $this->_image = $image; + return $this; + } + + public function getCatid() + { + return (int)$this->_catid; + } + + public function setCatid($catid) + { + $this->_catid = (int)$catid; + return $this; + } + + public function getPos() + { + return (int)$this->_pos; + } + + public function setPos($pos) + { + $this->_pos = (int)$pos; + return $this; + } + + public function getDownload() + { + return (bool)$this->_download; + } + + public function setDownload($download) + { + $this->_download = (bool)$download; + return $this; + } + + public function getExclusive() + { + return (bool)$this->_exclusive; + } + + public function setExclusive($exclusive) + { + $this->_exclusive = (bool)$exclusive; + return $this; + } + + +} diff --git a/Toolkit/Photos/Models/Photo2Category.php b/Toolkit/Photos/Models/Photo2Category.php new file mode 100644 index 0000000..76b5249 --- /dev/null +++ b/Toolkit/Photos/Models/Photo2Category.php @@ -0,0 +1,105 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_Photo2Category + * + * Description of Photo2Category + * + * @category Toolkit + * @package Photos + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Models_Photo2Category +{ + private $_id; + private $_photo; + private $_category; + private $_pos; + + const TABLE_NAME = 'photos.photo2category'; + const PRI_KEY = 'id'; + const SORT = 'pos'; + + private function __construct($values) + { + extract($values); + $this->setCategory($category) + ->setPhoto($photo) + ->setPos($pos); + if ($id) { + $this->setId($id); + } + } + + static public function createByValues($values) + { + return new Toolkit_Photos_Models_Photo2Category($values); + } + + public function getId() + { + return (int)$this->_id; + } + + public function setId($id) + { + $this->_id + = (filter_var($id, FILTER_VALIDATE_INT)) + ? $id + : null; + return $this; + } + + public function getPhoto() + { + return (int)$this->_photo; + } + + public function setPhoto($photo) + { + $this->_photo = (int)$photo; + return $this; + } + + public function getCategory() + { + return (int)$this->_category; + } + + public function setCategory($category) + { + $this->_category = (int)$category; + return $this; + } + + public function getPos() + { + return (int)$this->_pos; + } + + public function setPos($pos) + { + $this->_pos = (int)$pos; + return $this; + } + + +} diff --git a/Toolkit/Photos/Models/User.php b/Toolkit/Photos/Models/User.php new file mode 100644 index 0000000..9345b34 --- /dev/null +++ b/Toolkit/Photos/Models/User.php @@ -0,0 +1,279 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Photos_Model_User + * + * Class representation of the User + * + * @category Toolkit + * @package Media + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_Models_User +{ + private $_id; + private $_company; + private $_title; + private $_fname; + private $_lname; + private $_email; + private $_address; + private $_address2; + private $_city; + private $_state; + private $_zip; + private $_phone; + private $_media; + private $_expire; + private $_mediaPass; + private $_approved; + private $_denied; + + const TABLE_NAME = 'contacts.contact'; + const PRI_KEY = 'id'; + const SORT = 'lname,fname'; + const EMAIL = 'email'; + const WHERE = 'media = true'; + + private function __construct($values) + { + extract($values); + $this->setCompany($company) + ->setTitle($title) + ->setAddress($address) + ->setAddress2($address2) + ->setApproved($approved) + ->setMediaPass($media_pass) + ->setCity($city) + ->setDenied($denied) + ->setEmail($email) + ->setExpire($expire) + ->setFname($fname) + ->setLname($lname) + ->setMedia($media) + ->setPhone($phone) + ->setState($state) + ->setZip($zip); + if ($id) { + $this->setId($id); + } + } + + public function createByValues($values) + { + if (is_array($values) && !empty($values)) { + return new Toolkit_Photos_Models_User($values); + } else { + return false; + } + } + + public function getMediaPass() + { + return $this->_mediaPass; + } + + public function setMediaPass($mediaPass) + { + $this->_mediaPass = $mediaPass; + return $this; + } + + + public function getId() + { + return (int)$this->_id; + } + + public function setId($id) + { + $this->_id = (int)$id; + return $this; + } + + public function getCompany() + { + return $this->_company; + } + + public function setCompany($company) + { + $this->_company = $company; + return $this; + } + + public function getTitle() + { + return $this->_title; + } + + public function setTitle($title) + { + $this->_title = $title; + return $this; + } + + + public function getFname() + { + return $this->_fname; + } + + public function setFname($fname) + { + $this->_fname = $fname; + return $this; + } + + public function getLname() + { + return $this->_lname; + } + + public function setLname($lname) + { + $this->_lname = $lname; + return $this; + } + + public function getEmail() + { + return $this->_email; + } + + public function setEmail($email) + { + $this->_email = $email; + return $this; + } + + public function getAddress() + { + return $this->_address; + } + + public function setAddress($address) + { + $this->_address = $address; + return $this; + } + + public function getAddress2() + { + return $this->_address2; + } + + public function setAddress2($address2) + { + $this->_address2 = $address2; + return $this; + } + + public function getCity() + { + return $this->_city; + } + + public function setCity($city) + { + $this->_city = $city; + return $this; + } + + public function getState() + { + return $this->_state; + } + + public function setState($state) + { + $this->_state = $state; + return $this; + } + + public function getZip() + { + return $this->_zip; + } + + public function setZip($zip) + { + $this->_zip = $zip; + return $this; + } + + public function getPhone() + { + return $this->_phone; + } + + public function setPhone($phone) + { + $this->_phone = $phone; + return $this; + } + + public function getMedia() + { + return $this->_media; + } + + public function setMedia($media) + { + $this->_media = (bool)$media; + return $this; + } + + public function getExpire() + { + return $this->_expire; + } + + public function setExpire($expire) + { + $this->_expire = $expire; + return $this; + } + + public function getApproved() + { + return (bool)$this->_approved; + } + + public function setApproved($approved) + { + $this->_approved = (bool)$approved; + return $this; + } + + public function getDenied() + { + return (bool)$this->_denied; + } + + public function setDenied($denied) + { + $this->_denied = (bool)$denied; + return $this; + } + + +} diff --git a/Toolkit/Photos/Photo.php b/Toolkit/Photos/Photo.php new file mode 100644 index 0000000..12c9b08 --- /dev/null +++ b/Toolkit/Photos/Photo.php @@ -0,0 +1,23 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Photos_SlideShowCategoryFilter + * + * Description of SlideShowFilter + * + * @category Toolkit + * @package Photos + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_Photos_SlideShowCategoryFilter + extends FilterIterator +{ + public function __construct(Iterator $iterator) + { + parent::__construct($iterator); + } + + public function accept() + { + $category = $this->getInnerIterator()->current(); + if ($category['slideshow']) { + return true; + } + return false; + } +} diff --git a/Toolkit/Photos/application.ini b/Toolkit/Photos/application.ini new file mode 100644 index 0000000..d576e1c --- /dev/null +++ b/Toolkit/Photos/application.ini @@ -0,0 +1,45 @@ +; Production server configuration data +[production] +; Application settings +application.name = "Image Library" +application.path = BASE "Toolkit/Photos/Controllers" +application.application = "Photos/Controllers" + +; turn on media exclusive flag for categories and photos +; This option also may need other new fields not added yet to the contact table +settings.mediaExclusive = Off +settings.photoNameSearch = Off +settings.slideShowOption = Off + +; default Flexy Options for this application +flexyOptions.templateDir = BASE "Toolkit/Photos/templates" +flexyOptions.compileDir = BASE "Toolkit/Photos/templates/compiled" +flexyOptions.url_rewrite = "baseurl/::" BASE_URL ",basesecureurl/::" BASE_SECURE_URL ",glmappbaseurl/::" GLM_APP_BASE_URL +flexyOptions.forceCompile = Off +flexyOptions.locale = "en" +flexyOptions.debug = Off +flexyOptions.allowPHP = On +flexyOptions.flexyIgnore = On +flexyOptions.globals = On +flexyOptions.globalfunctions = On +flexyOptions.privates = On +flexyOptions.compiler = "Flexy" + +; development server configuration data inherits from production and +; overrides values as necessary +[development : production] + +; chuck's server configuration data inherits from development +; and overrides values as necessary +[chuck : development] + +; john's server configuration data inherits from development +; and overrides values as necessary +[john : development] + +; steve's server configuration data inherits from development +; and overrides values as necessary +[steve : development] +; Vagrant server configuration inherits from development and +; overrides values as needed +[vagrant : development] diff --git a/Toolkit/Photos/assets/.keepme b/Toolkit/Photos/assets/.keepme new file mode 100644 index 0000000..e69de29 diff --git a/Toolkit/Photos/css/gallery.css b/Toolkit/Photos/css/gallery.css new file mode 100755 index 0000000..545a01c --- /dev/null +++ b/Toolkit/Photos/css/gallery.css @@ -0,0 +1,28 @@ +.header { + margin: 10px 20px; + } +#photo-gallery { + margin: 10px 20px; +} +#glmMediaGallery { + background: #F5F3E5; + border-width: 0 1px 1px; + border: 1px solid #A6C9E2; + padding: 15px; +} +div.thumb { + margin: 3px 9px; + border: 0px solid #A0ACC0; + height: auto; + float: left; + text-align: center; +} +.thumb img{ + display: inline; + margin: 3px; + border: 1px solid #A0ACC0; + } +.thumb a:hover img {border: 1px solid black;} +.photocattitle {text-align: center; font-weight: bold;} +.phototitle {text-align: center; font-weight: normal; width: 110px;} +.galleryRow {clear: left;} diff --git a/Toolkit/Photos/css/style.css b/Toolkit/Photos/css/style.css new file mode 100644 index 0000000..f26d4c0 --- /dev/null +++ b/Toolkit/Photos/css/style.css @@ -0,0 +1,344 @@ +.containerobj .widget { + background-color: white; +} +.containerobj .active .widget { + color: white; + background-color: #3671cf; +} +.containerobj .inpath .widget { + background-color: #d0d0d0; +} +#demo1 { + height: 200px; +} +#demo1 a { + padding: 0 3px; +} +.ui-dialog-buttonpane { + padding: 0 10px 0 20px !important; +} +#dialog-modal { + height: auto !important; +} + +#addPageTo { + /*display: inline; + width: 82px; + height: 28px; + border: none; + text-align: left; + padding: 0 0 0 24px;*/ + margin: 6px 0 0 0; + float: right; +} +#deleteBtn2 { + display: block; + position:absolute; + bottom: 36px; + right: 5px; + width: 55px; + height: 28px; + background: url(../assets/btn_delete.gif) no-repeat; + border: none; + padding: 0 0 0 27px; + font-size: 14px; + font-size: 1.4rem; + line-height: 28px; + text-decoration: none; + margin: 0px; +} +.ui-state-highlight { + color: #09F; + border-color: #09F; + background: #09F; +} +.ui-widget-content { + margin: 0; + padding: 0; +} +#photoGalleryFooter { + display: none; + padding: 10px; + text-align: center; + width: 100%; + float: bottom; +} + +/* Search Form styles */ +#photoAdminSearch input[type="search"], + #categoryAdminSearch select { + height: 26px; + font-size: 18px; + width: 300px; + border: 1px solid #CCCCCC; + background-color: #EFEFEF !important; + } + #mediaGallerySearchForm { + padding: 0; + margin: 20px 0 20px; + } + #categorySearchWrapper { + width: 800px; + height: 34px; + position: relative; + border-bottom: 1px solid #CCC; + } + #categoryAdminSearch select { + display: block; + position: relative; + float: left; + z-index: 99; + left: 0; + top: 0; + width: 37.75%; + margin: 0 .5% 0 0; + font-size: 14px; + font-weight: normal; + color: #666; + height: 27px; + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + padding:.2em;/.3em; + } + #categoryAdminSearch input[type="submit"], #photoAdminSearch input[type="submit"] { + display: block; + position: relative; + float: left; + z-index: 99; + right: 0; + top: 0; + width: 10%; + margin: 0; + font-size: 14px; + font-weight: normal; + color: #666; + margin: 0; + height: 28px; + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + } + #photoAdminSearch input[type="search"] { + display: block; + position: relative; + float: left; + z-index: 99; + left: 0; + top: 0; + width: 37.75%; + margin: 0 .5% 0 3%; + font-size: 14px; + font-weight: normal; + color: #333; + height: 27px; + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + padding:.2em;/.3em; + padding-left: 6px; + } + div.photo-category-list { + background: #EFEFEF; + border-radius: 5px; + display: block; + float: left; + height: 148px; + margin: 0 20px 20px 0; + padding: 10px; + position: relative; + width: 120px; + border: 1px solid #CCC; + -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + } + div.pCount { + background-color: #333; + border-radius: 30px 30px 30px 30px; + -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + color: white; + display: inline; + float: right; + font-weight: bold; + padding: 1px 5px; + position: absolute; + right: -8px; + text-shadow: 1px 1px grey; + top: 0; + } + div.photo-category-list h1 { + bottom: 10px; + left: 10px; + margin: 0; + overflow: hidden; + padding: 0; + position: absolute; + width: 123px; + } + div.photo-category-list img { + border: medium none; + border-radius: 5px; + -webkit-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2); + -moz-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2); + box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2); + border: 1px solid #CCC; + } + +/* edit category form styles */ +#editCategoryForm .webform { + margin: 10px 0; + width: 400px; + border: 1px solid #CCC; + border-radius: 5px; + padding: 10px 2%; + } + #editCategoryForm .webform td { + width: 100%; + float: left; + border: 0; + text-align: left; + } + #editCategoryForm .webform td input[type="text"] { + display: block; + position: relative; + z-index: 99; + left: 0; + top: 0; + width: 100%; + margin: 0; + font-size: 14px; + font-weight: normal; + color: #333; + height: 27px; + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + padding:.2em;/.3em; + padding-left: 6px; + background: #EFEFEF !important; + border: 1px solid #CCC; + } + .category-category-list { + position: relative; + box-shadow: 1px 2px 2px grey; + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + display:block; + width: 120px; + float: left; + background: #D6DFC3; + margin: 5px; + padding: 10px; + height: 130px; + } + .category-category-list h1 { + position: absolute; + bottom: 0; + left: 5px; + margin: 0; + padding: 0; + overflow: hidden; + width: 123px;; + } + .category-category-list h1 a { + color: #006BB4; + font-size: 12px; + text-decoration: none; + padding: 0; + margin: 0; + overflow: hidden; + white-space: nowrap; + } + .category-category-list img { + box-shadow: 1px 2px 2px grey; + border-radius: 10px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border: none; + } + #addPageTo, form#editCategoryForm input[type="submit"] { + /*box-shadow: 1px 2px 2px grey; + background-color: #D6DFC3; + font-size: 16px; + font-weight: normal; + text-align: center; + margin: 0; + padding: 1px 5px 1px 5px; + width: auto;*/ + } + .pageLink { + /*border-radius: 10px;*/ + /*box-shadow: 1px 2px 2px grey; + width: 280px; + background-color: #D6DFC3; + padding: 5px; + margin: 5px 0; + float: left;*/ + width: 96%; + padding: 5px 2%; + border-bottom: 1px solid #CCC; + } + .btnDelete { + float: right; + } + #displayWrapper { + margin: 3px 0; + border-left: 1px solid #CCC; + border-right: 1px solid #CCC; + border-top: 1px solid #CCC; + background: #EFEFEF; + } + #categorySave { + width: 31.333333%; + margin: 0 2% 0 0; + } + #categoryCancel { + width: 31.333333%; + margin: 0 2% 0 0; + } + #categoryDelete { + width: 31.333333%; + margin: 0; + } + #pagesLabel { + padding-top: 5px; + } + div.category-category-list { + background: #EFEFEF; + border-radius: 5px; + display: block; + float: left; + height: 148px; + margin: 0 20px 20px 0; + padding: 10px; + position: relative; + width: 120px; + border: 1px solid #CCC; + -webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + } + div.category-category-list h1 { + bottom: 10px; + left: 10px; + margin: 0; + overflow: hidden; + padding: 0; + position: absolute; + width: 123px; + } + div.category-category-list img { + border: medium none; + border-radius: 5px; + -webkit-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2); + -moz-box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2); + box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.2); + border: 1px solid #CCC; + } + div#categoryPhotos { + margin-top: 20px; + } diff --git a/Toolkit/Photos/css/thickbox.css b/Toolkit/Photos/css/thickbox.css new file mode 100755 index 0000000..f69f4e4 --- /dev/null +++ b/Toolkit/Photos/css/thickbox.css @@ -0,0 +1,168 @@ +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> global settings needed for thickbox <<<-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +/* *{padding: 0; margin: 0;} */ + +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> thickbox specific link and font settings <<<------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +#TB_window { + font: 12px Arial, Helvetica, sans-serif; + color: #333333; +} + +#TB_secondLine { + font: 10px Arial, Helvetica, sans-serif; + color:#666666; +} + +#TB_window a:link {color: #666666;} +#TB_window a:visited {color: #666666;} +#TB_window a:hover {color: #000;} +#TB_window a:active {color: #666666;} +#TB_window a:focus{color: #666666;} + +/* ----------------------------------------------------------------------------------------------------------------*/ +/* ---------->>> thickbox settings <<<-----------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------------------------------------*/ +#TB_overlay { + position: fixed; + z-index:100; + top: 0px; + left: 0px; + height:100%; + width:100%; +} + +.TB_overlayMacFFBGHack {background: url(macFFBgHack.png) repeat;} +.TB_overlayBG { + background-color:#000; + filter:alpha(opacity=75); + -moz-opacity: 0.75; + opacity: 0.75; +} + +* html #TB_overlay { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_window { + position: fixed; + background: #ffffff; + z-index: 102; + color:#000000; + display:none; + border: 4px solid #525252; + text-align:left; + top:50%; + left:50%; +} + +* html #TB_window { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_window img#TB_Image { + display:block; + margin: 15px 0 0 15px; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + border-top: 1px solid #666; + border-left: 1px solid #666; +} + +#TB_caption{ +/* height:25px; */ + padding:7px 30px 10px 25px; + float:left; +} + +#TB_DownloadLinks { + padding:7px 30px 10px 25px; + float:left; +} + +#TB_closeWindow{ + height:25px; + padding:11px 25px 10px 0; + float:right; +} + +#TB_closeAjaxWindow{ + padding:7px 10px 5px 0; + margin-bottom:1px; + text-align:right; + float:right; +} + +#TB_ajaxWindowTitle{ + float:left; + padding:7px 0 5px 10px; + margin-bottom:1px; +} + +#TB_title{ + background-color:#e8e8e8; + height:27px; +} + +#TB_ajaxContent{ + clear:both; + padding:2px 15px 15px 15px; + overflow:auto; + text-align:left; + line-height:1.4em; +} + +#TB_ajaxContent.TB_modal{ + padding:15px; +} + +#TB_ajaxContent p{ + padding:5px 0px 5px 0px; +} + +#TB_load{ + position: fixed; + display:none; + height:13px; + width:208px; + z-index:103; + top: 50%; + left: 50%; + margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */ +} + +* html #TB_load { /* ie6 hack */ +position: absolute; +margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); +} + +#TB_HideSelect{ + z-index:99; + position:fixed; + top: 0; + left: 0; + background-color:#fff; + border:none; + filter:alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + height:100%; + width:100%; +} + +* html #TB_HideSelect { /* ie6 hack */ + position: absolute; + height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); +} + +#TB_iframeContent{ + clear:both; + border:none; + margin-bottom:-1px; + margin-top:1px; + _margin-bottom:1px; +} diff --git a/Toolkit/Photos/js/jquery.columnview.js b/Toolkit/Photos/js/jquery.columnview.js new file mode 100755 index 0000000..53a3834 --- /dev/null +++ b/Toolkit/Photos/js/jquery.columnview.js @@ -0,0 +1,267 @@ +/** + * jquery.columnview-1.2.js + * + * Created by Chris Yates on 2009-02-26. + * http://christianyates.com + * Copyright 2009 Christian Yates and ASU Mars Space Flight Facility. All rights reserved. + * + * Supported under jQuery 1.2.x or later + * Keyboard navigation supported under 1.3.x or later + * + * Dual licensed under MIT and GPL. + */ + +(function($){ + $.fn.columnview = function(options){ + + var settings = $.extend({}, $.fn.columnview.defaults, options); + + // Add stylesheet, but only once + if(!$('.containerobj').get(0)){ + $('head').prepend('\ + '); + } + + // Hide original list + $(this).hide(); + // Reset the original list's id + var origid = $(this).attr('id'); + if (origid) { + $(this).attr('id', origid + "-processed"); + } + + // Create new top container from top-level LI tags + var top = $(this).children('li'); + var container = $('
    ').addClass('containerobj').attr('id', origid).insertAfter(this); + var topdiv = $('
    ').appendTo(container); + // Set column width + if (settings.fixedwidth || $.browser.msie) { // MSIE doesn't support auto-width + var width = typeof settings.fixedwidth == "string" ? settings.fixedwidth : '200px'; + $('.top').width(width); + } + $.each(top,function(i,item){ + var topitem = $(':eq(0)',item).clone(true).wrapInner("").data('sub',$(item).children('ul')).appendTo(topdiv); + if (settings.fixedwidth || $.browser.msie) + $(topitem).css({'text-overflow':'ellipsis', '-o-text-overflow':'ellipsis','-ms-text-overflow':'ellipsis'}); + if($(topitem).data('sub').length) { + $(topitem).addClass('hasChildMenu'); + addWidget(container, topitem); + } + }); + + // Firefox doesn't repeat keydown events when the key is held, so we use + // keypress with FF/Gecko/Mozilla to enable continuous keyboard scrolling. + var key_event = $.browser.mozilla ? 'keypress' : 'keydown'; + + // Event handling functions + $(container).bind("click " + key_event, function(event){ + if ($(event.target).is("a,span")) { + if ($(event.target).is("span")){ + var self = $(event.target).parent(); + } + else { + var self = event.target; + } + if (!settings.multi) { + delete event.shiftKey; + delete event.metaKey; + } + self.focus(); + var container = $(self).parents('.containerobj'); + // Handle clicks + if (event.type == "click"){ + var level = $('div',container).index($(self).parents('div')); + var isleafnode = false; + // Remove blocks to the right in the tree, and 'deactivate' other + // links within the same level, if metakey is not being used + $('div:gt('+level+')',container).remove(); + if (!event.metaKey && !event.shiftKey) { + $('div:eq('+level+') a',container).removeClass('active').removeClass('inpath'); + $('.active',container).addClass('inpath'); + $('div:lt('+level+') a',container).removeClass('active'); + } + // Select intermediate items when shift clicking + // Sorry, only works with jQuery 1.4 due to changes in the .index() function + if (event.shiftKey) { + var first = $('a.active:first', $(self).parent()).index(); + var cur = $(self).index(); + var range = [first,cur].sort(function(a,b){return a - b;}); + $('div:eq('+level+') a', container).slice(range[0], range[1]).addClass('active'); + } + $(self).addClass('active'); + if ($(self).data('sub').children('li').length && !event.metaKey) { + // Menu has children, so add another submenu + var w = false; + if (settings.fixedwidth || $.browser.msie) + w = typeof settings.fixedwidth == "string" ? settings.fixedwidth : '200px'; + submenu(container,self,w); + } + else if (!event.metaKey && !event.shiftKey) { + // No children, show title instead (if it exists, or a link) + isleafnode = true; + var previewcontainer = $('
    ').addClass('feature').appendTo(container); + // Fire preview handler function + if ($.isFunction(settings.preview)) { + // We're passing the element back to the callback + var preview = settings.preview($(self)); + } + // If preview is specifically disabled, do nothing with the previewbox + else if (!settings.preview) { + } + // If no preview function is specificied, use a default behavior + else { + var title = $('').attr({href:$(self).attr('href')}).text($(self).attr('title') ? $(self).attr('title') : $(self).text()); + $(previewcontainer).html(title); + } + // Set the width + var remainingspace = 0; + $.each($(container).children('div').slice(0,-1),function(i,item){ + remainingspace += $(item).width(); + }); + var fillwidth = $(container).width() - remainingspace; + $(previewcontainer).css({'top':0,'left':remainingspace}).width(fillwidth).show(); + } + // Fire onchange handler function, but only if multi-select is off. + // FIXME Need to deal multiple selections. + if ($.isFunction(settings.onchange) && !settings.multi) { + // We're passing the element back to the callback + var onchange = settings.onchange($(self), isleafnode); + } + } + // Handle Keyboard navigation + if(event.type == key_event){ + switch(event.keyCode){ + case(37): //left + $(self).parent().prev().children('.inpath').focus().trigger("click"); + break; + case(38): //up + $(self).prev().focus().trigger("click"); + break; + case(39): //right + if($(self).hasClass('hasChildMenu')){ + $(self).parent().next().children('a:first').focus().trigger("click"); + } + break; + case(40): //down + $(self).next().focus().trigger("click"); + break; + case(13): //enter + $(self).trigger("dblclick"); + break; + } + } + event.preventDefault(); + } + }); + + }; + + $.fn.columnview.defaults = { + multi: false, // Allow multiple selections + preview: true, // Handler for preview pane + fixedwidth: false,// Use fixed width columns + onchange: false // Handler for selection change + }; + + // Generate deeper level menus + function submenu(container,item,width){ + var leftPos = 0; + $.each($(container).children('div'),function(i,mydiv){ + leftPos += $(mydiv).width(); + }); + var submenu = $('
    ').css({'top':0,'left':leftPos}).appendTo(container); + // Set column width + if (width) + $(submenu).width(width); + var subitems = $(item).data('sub').children('li'); + $.each(subitems,function(i,subitem){ + var subsubitem = $(':eq(0)',subitem).clone(true).wrapInner("").data('sub',$(subitem).children('ul')).appendTo(submenu); + if (width) + $(subsubitem).css({'text-overflow':'ellipsis', '-o-text-overflow':'ellipsis','-ms-text-overflow':'ellipsis'}); + if($(subsubitem).data('sub').length) { + $(subsubitem).addClass('hasChildMenu'); + addWidget(container, subsubitem); + } + }); + } + + // Uses canvas, if available, to draw a triangle to denote that item is a parent + function addWidget(container, item, color){ + var triheight = $(item).height(); + var canvas = $("").attr({height:triheight,width:10}).addClass('widget').appendTo(item); if(!color){ color = $(canvas).css('color'); } + canvas = $(canvas).get(0); + if(canvas.getContext){ + var context = canvas.getContext('2d'); + context.fillStyle = color; + context.beginPath(); + context.moveTo(3,(triheight/2 - 3)); + context.lineTo(10,(triheight/2)); + context.lineTo(3,(triheight/2 + 3)); + context.fill(); + } else { + /** + * Canvas not supported - put something in there anyway that can be + * suppressed later if desired. We're using a decimal character here + * representing a "black right-pointing pointer" in Windows since IE + * is the likely case that doesn't support canvas. + */ + $("").addClass('widget').css({'height':triheight,'width':10}).prependTo(item); + } + $(container).find('.widget').bind('click', function(event){ + event.preventDefault(); + }); + + } +})(jQuery); \ No newline at end of file diff --git a/Toolkit/Photos/js/photoGallery.js b/Toolkit/Photos/js/photoGallery.js new file mode 100644 index 0000000..d05c97f --- /dev/null +++ b/Toolkit/Photos/js/photoGallery.js @@ -0,0 +1,173 @@ +$(function(){ + $("#photoCategoryId").change(function(){ + $(this).parent().submit(); + }); +}); + +(function(window, PhotoSwipe){ + //if ($(".photoimg").length > 0) { + if(document.addEventListener) { + document.addEventListener('DOMContentLoaded', function(){ + var + options = { + getImageCaption: function(el){ + var captionText, captionDesc, captionId, captionEl; + + if (el.nodeName === "A") { + captionText = el.getAttribute('title'); + captionDesc = el.getAttribute('rel'); + captionId = el.getAttribute('data-photoid'); + captionDownload = el.getAttribute('data-download'); + } + + // Return a DOM element with custom styling + if((captionText != null && captionText != "") || (captionDesc != null && captionDesc != "")) { + captionEl = document.createElement('div'); + captionEl.className = 'captionWrapper'; + // Add Caption Title. + if(captionText != null && captionText != "") { + captionTitleOutput = document.createElement('h2'); + captionTitleOutput.className = "captionTitleWrapper"; + captionTitleOutput.appendChild(document.createTextNode(captionText)); + captionEl.appendChild(captionTitleOutput); + } + // Add Caption Description. + if(captionDesc != null && captionDesc != "") { + captionDescOutput = document.createElement('p'); + captionDescOutput.className = "captionDescWrapper"; + captionDescOutput.appendChild(document.createTextNode(captionDesc)); + captionEl.appendChild(captionDescOutput); + } + } else { + //captionEl = document.createElement('div'); + //captionEl.style.cssText = 'display:none; width:0; height:0;'; + captionEl = ""; + } + // Add Download links. + if(captionId != null && captionId != "" && captionDownload == "1") { + captionIdOutput = document.createElement('div'); + captionIdOutput.className = 'download_wrapper'; + captionEl.appendChild(captionIdOutput); + // Add Link Text. + captionLinkText = document.createElement('span'); + captionText = document.createTextNode("Download for "); + captionLinkText.appendChild(captionText); + captionIdOutput.appendChild(captionLinkText); + // Add Web Link. + captionWebLink = base_url + "download-photo-web/" + captionId + "/"; + downloadWebLink = document.createElement('a'); + linkText = document.createTextNode("Web"); + downloadWebLink.appendChild(linkText); + downloadWebLink.title = "Download for Web"; + downloadWebLink.href = captionWebLink; + captionIdOutput.appendChild(downloadWebLink); + // Add Spacer Text. + captionSpacerText = document.createElement('span'); + captionText = document.createTextNode(" - "); + captionSpacerText.appendChild(captionText); + captionIdOutput.appendChild(captionSpacerText); + // Add Print Link. + captionPrintLink = base_url + "download-photo-print/" + captionId + "/"; + downloadPrintLink = document.createElement('a'); + linkPrintText = document.createTextNode("Print"); + downloadPrintLink.appendChild(linkPrintText); + downloadPrintLink.title = "Download for Print"; + downloadPrintLink.href = captionPrintLink; + captionIdOutput.appendChild(downloadPrintLink); + } + + return captionEl; + + // Alternatively you can just pass back a string. However, any HTML + // markup will be escaped + + }, captionAndToolbarAutoHideDelay:0, imageScaleMethod: "fitNoUpscale", captionAndToolbarFlipPosition: true, backButtonHideEnabled: true + }, + instance = PhotoSwipe.attach( window.document.querySelectorAll('a.photoimg'), options ); + }, false); + } else { // You are using IE8- and you should feel bad. + document.attachEvent('onreadystatechange', function(){ + var + options = { + getImageCaption: function(el){ + var captionText, captionDesc, captionId, captionEl; + + if (el.nodeName === "A") { + captionText = el.getAttribute('title'); + captionDesc = el.getAttribute('rel'); + captionId = el.getAttribute('data-photoid'); + captionDownload = el.getAttribute('data-download'); + } + + // Return a DOM element with custom styling + if((captionText != null && captionText != "") || (captionDesc != null && captionDesc != "")) { + //captionEl = document.createElement('div'); + captionEl = $('
    '); + captionEl.addClass = 'captionWrapper'; + // Add Caption Title. + if(captionText != null && captionText != "") { + //captionTitleOutput = document.createElement('h2'); + captionTitleOutput = $('

    '); + captionTitleOutput.addClass = "captionTitleWrapper"; + captionTitleOutput.append(captionText); + captionEl.append(captionTitleOutput); + } + // Add Caption Description. + if(captionDesc != null && captionDesc != "") { + //captionDescOutput = document.createElement('p'); + captionDescOutput = $('

    '); + captionDescOutput.addClass = "captionDescWrapper"; + captionDescOutput.append(document.createTextNode(captionDesc)); + captionEl.append(captionDescOutput); + } + } else { + //captionEl = document.createElement('div'); + //captionEl.style.cssText = 'display:none; width:0; height:0;'; + captionEl = ""; + } + // Add Download links. + if(captionId != null && captionId != "" && captionDownload == "1") { + captionIdOutput = $('
    '); + captionIdOutput.addClass = 'download_wrapper'; + captionEl.append(captionIdOutput); + // Add Link Text. + captionLinkText = $(''); + captionText = document.createTextNode("Download for "); + captionLinkText.append(captionText); + captionIdOutput.append(captionLinkText); + // Add Web Link. + captionWebLink = base_url + "download-photo-web/" + captionId + "/"; + downloadWebLink = $('
    '); + linkText = document.createTextNode("Web"); + downloadWebLink.append(linkText); + downloadWebLink.title = "Download for Web"; + downloadWebLink.attr('href', captionWebLink); + captionIdOutput.append(downloadWebLink); + // Add Spacer Text. + captionSpacerText = $(''); + captionText = document.createTextNode(" - "); + captionSpacerText.append(captionText); + captionIdOutput.append(captionSpacerText); + // Add Print Link. + captionPrintLink = base_url + "download-photo-print/" + captionId + "/"; + downloadPrintLink = $(''); + linkPrintText = document.createTextNode("Print"); + downloadPrintLink.append(linkPrintText); + downloadPrintLink.title = "Download for Print"; + downloadPrintLink.attr('href', captionPrintLink); + captionIdOutput.append(downloadPrintLink); + } + + return captionEl; + + // Alternatively you can just pass back a string. However, any HTML + // markup will be escaped + + }, captionAndToolbarAutoHideDelay:0, imageScaleMethod: "fitNoUpscale", captionAndToolbarFlipPosition: true, backButtonHideEnabled: true + }, + instance = PhotoSwipe.attach( window.document.querySelectorAll('a.photoimg'), options ); + }, false); + } + //} +}(window, window.Code.PhotoSwipe)); + diff --git a/Toolkit/Photos/login.php b/Toolkit/Photos/login.php new file mode 100644 index 0000000..b30a681 --- /dev/null +++ b/Toolkit/Photos/login.php @@ -0,0 +1,59 @@ +start(); + +if (isset($_REQUEST['logout'])) { + $photoAuth->logout(); + header('Location: ' . BASE_URL . 'index.php?catid=' . $catid); + exit; +} + +if (!$photoAuth->checkAuth()) { + // see if the user exists but has expired + $userName = filter_var($_REQUEST['username'], FILTER_SANITIZE_STRING); + $passWord = filter_var($_REQUEST['password'], FILTER_SANITIZE_STRING); + $status = $photoAuth->getStatus(); + if ($passWord && $userName) { + try { + $sql = " + SELECT id + FROM contacts.contact + WHERE email = :uname + AND media_pass = :pword + AND media = true + AND approved = true + AND expire < current_date"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':uname', $userName, PDO::PARAM_STR); + $stmt->bindParam(':pword', $passWord, PDO::PARAM_STR); + $stmt->execute(); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + if ($row !== FALSE) { + $status = -4; + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + // Manually adjust the authentication status for empty credentials + if (empty($_POST['username']) || empty($_POST['password'])) { + $status = -3; + } + header('Location: ' + . BASE_URL . 'index.php?catid=' . $catid . '&status=' . $status); + exit; +} else { + header('Location: ' . BASE_URL . 'index.php?catid=' . $catid); +} diff --git a/Toolkit/Photos/photoProxy.php b/Toolkit/Photos/photoProxy.php new file mode 100644 index 0000000..560bf58 --- /dev/null +++ b/Toolkit/Photos/photoProxy.php @@ -0,0 +1,97 @@ + 'glmMedia', + 'allowLogin' => true, + 'dbFields' => array('id', 'fname', 'lname') + ), + '', + false +); +$photoAuth->setIdle(86400, true); +$photoAuth->start(); +//var_dump($_REQUEST); + +// get image name from db +$photoId = filter_var($_REQUEST['photo_id'], FILTER_VALIDATE_INT); +if (!$photoId) { + die('Sorry no image found'); +} +$isAuthorized = $photoAuth->checkAuth(); +try { + // here we'll need to also check to make sure that if they're not + // logged in they cannot get the exclusive photos. + $where + = (!$isAuthorized) + ? "AND exclusive <> true" + : ''; + $sql = " + SELECT image + FROM photo + WHERE id = :id + $where"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $photoId, PDO::PARAM_INT); + $stmt->execute(); + $imageName = $stmt->fetchColumn(); + if (!$imageName) { + return false; + } +} catch (PDOException $e) { + Toolkit_Common::handleError($e); +} +//var_dump($imageName); +//exit; +if (!$isAuthorized) { + // use watermarked image style + $style = ($_REQUEST['type'] == 'print') ? 'downPrint': 'downWeb'; + $fileUrlPath = FILE_SERVER_URL . IS_OWNER_ID . "/{$style}/{$imageName}"; + + $ch = curl_init($fileUrlPath); + curl_setopt($ch, CURLOPT_TIMEOUT, 50); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + $imageResponse = curl_exec($ch); + if (!curl_errno($ch)) { + $bytes = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Content-Type: application/force-download"); + header("Content-Type: application/octet-stream"); + header("Content-Type: application/download"); + header("Content-Disposition: attachment;filename=photo-" . $photoId.".jpeg"); + header("Content-Transfer-Encoding: binary "); + curl_close($ch); + echo $imageResponse; + } + + exit; +} else { + // use style without watermarks + $style = ($_REQUEST['type'] == 'print') ? 'downPrintMedia': 'downWebMedia'; + $fileUrlPath = FILE_SERVER_URL . IS_OWNER_ID . "/{$style}/{$imageName}"; + $ch = curl_init($fileUrlPath); + curl_setopt($ch, CURLOPT_TIMEOUT, 50); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + $imageResponse = curl_exec($ch); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Content-Type: application/force-download"); + header("Content-Type: application/octet-stream"); + header("Content-Type: application/download"); + header("Content-Disposition: attachment;filename=photo-" . $photoId.".jpeg"); + header("Content-Transfer-Encoding: binary "); + curl_close($ch); + echo $imageResponse; + exit; +} diff --git a/Toolkit/Photos/photoSearch.php b/Toolkit/Photos/photoSearch.php new file mode 100644 index 0000000..8d51338 --- /dev/null +++ b/Toolkit/Photos/photoSearch.php @@ -0,0 +1,27 @@ +getPageGalleries($pageId); + +$photos = $mediaMapper->fetchPhotosByNameAndCats( + $photoSearch, + $galleries, + true +); +if ($photos) { + foreach ($photos as $photo) { + $jsonData[] = $photo->getTitle(); + } +} +echo json_encode($jsonData); diff --git a/Toolkit/Photos/setupNewPhotos.php b/Toolkit/Photos/setupNewPhotos.php new file mode 100644 index 0000000..7e492a1 --- /dev/null +++ b/Toolkit/Photos/setupNewPhotos.php @@ -0,0 +1,9 @@ +fixAllPhoto2Cats(); diff --git a/Toolkit/Photos/templates/Admin/editCategory.html b/Toolkit/Photos/templates/Admin/editCategory.html new file mode 100644 index 0000000..47219b2 --- /dev/null +++ b/Toolkit/Photos/templates/Admin/editCategory.html @@ -0,0 +1,187 @@ +
    +
    +
    +

    + Edit Category +

    +
    +
    +
    + {if:category} + + + {if:!mediaExclusive} + + {end:} + {end:} + + + + + + + + + + + + + + + + + + + + +
    + Name + + {if:category} + + {else:} + + {end:} +
    + Pages for Display + +
    +
    + {if:pages2Categories} + + {end:} +
    + + +
    +
    + SlideShow Option? + + +
    + Media Exclusive? + + +
    + + {if:category} + + + {end:} +
    +
    +
    +
    +
    + + +
    + + {if:photo.getImage()} + + + + {end:} +
    +
    +

    + + {photo.getTitle()} + +

    +
    +
    +
    +
    +
    + diff --git a/Toolkit/Photos/templates/Admin/editPhoto.html b/Toolkit/Photos/templates/Admin/editPhoto.html new file mode 100644 index 0000000..77d6c69 --- /dev/null +++ b/Toolkit/Photos/templates/Admin/editPhoto.html @@ -0,0 +1,264 @@ + +
    +
    +
    +

    + Edit Photo in {categoryName} +

    +
    +
    +
    + {if:photo} + + {if:!mediaExclusive} + + {end:} + {end:} + + + + + + + + + + + + + + + + + + + + + + + {if:photo} + + + + + {end:} + + + + + + + +
    + Name + + {if:photo} + + {else:} + + {end:} +
    + Media Exclusive? + + +
    + Download? + + +
    + Category + + +
    + Description + + {if:photo} + + {else:} + + {end:} +
    + Current Photo + + + +
    + New Photo + + {if:photo} + + {else:} + + {end:} +
    + + {if:photo} + + + {end:} +
    +
    +
    + diff --git a/Toolkit/Photos/templates/Admin/editUser.html b/Toolkit/Photos/templates/Admin/editUser.html new file mode 100644 index 0000000..128b30e --- /dev/null +++ b/Toolkit/Photos/templates/Admin/editUser.html @@ -0,0 +1,233 @@ + +
    +
    + + {if:user} + + {end:} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Status + + + {if:user} + + + {else:} + + + + {end:} + +
    + Company Name + + {if:user} + + {else:} + + {end:} +
    + Title + + {if:user} + + {else:} + + {end:} +
    + Expire Date + + {if:user} + + {else:} + + {end:} +
    + Email Address + + {if:user} + + {else:} + + {end:} +
    + Password + + {if:user} + + {else:} + + {end:} +
    + First Name + + {if:user} + + {else:} + + {end:} +
    + Last Name + + {if:user} + + {else:} + + {end:} +
    + Phone + + {if:user} + + {else:} + + {end:} +
    + Address 1 + + {if:user} + + {else:} + + {end:} +
    + Address2 + + {if:user} + + {else:} + + {end:} +
    + City + + {if:user} + + {else:} + + {end:} +
    + State + + {if:user} + + {else:} + + {end:} +
    + Zip + + {if:user} + + {else:} + + {end:} +
    + +
    +
    +
    + diff --git a/Toolkit/Photos/templates/Admin/emailUser.tpl b/Toolkit/Photos/templates/Admin/emailUser.tpl new file mode 100644 index 0000000..ac8da03 --- /dev/null +++ b/Toolkit/Photos/templates/Admin/emailUser.tpl @@ -0,0 +1,68 @@ + + + + + {title:h} + + +

    + + {subject:h} + +

    + + + + + + + + +
    + {if:approved} +

    Thank you for submitting your request for photos to the Traverse + City Convention & Visitors Bureau. Your request has been approved + and your login information is below. Please note that your access + to this site will be active for 2 weeks, beginning today. Should + you require additional time once your access period has expired, we + ask that you fill out a new request form.

    +
    +

    Login: {user.getEmail()}

    +

    Password: {user.getMediaPass()}

    +
    +

    Sincerely,

    +
    +

    The Traverse City Tourism Marketing Team

    + {end:} + {if:denied} +

    We're sorry, but your request for media-quality photos did not meet + our criteria. However, we encourage you to choose from the wide range + of photos available on our general photo library. You do not require + a special login to view and download those photos.

    +
    +

    Thanks for your interest in Traverse City!

    +

    The Traverse City Tourism Marketing Team

    + {end:} +
    + + + + +
    + + To ensure the delivery of these e-mails to your inbox, please + add {email_from:h} to your e-mail Address Book or Safe List. + +
    +
    + + diff --git a/Toolkit/Photos/templates/Admin/index.html b/Toolkit/Photos/templates/Admin/index.html new file mode 100644 index 0000000..4ce6dfe --- /dev/null +++ b/Toolkit/Photos/templates/Admin/index.html @@ -0,0 +1,29 @@ + + + + {AppName} + + + {styles:h} + + {topScripts:h} + + +
    +
    +

    {AppName}

    +
    + + +
    + {content:h} + {bottomScripts:h} + + diff --git a/Toolkit/Photos/templates/Admin/listCategories.html b/Toolkit/Photos/templates/Admin/listCategories.html new file mode 100644 index 0000000..d0e9508 --- /dev/null +++ b/Toolkit/Photos/templates/Admin/listCategories.html @@ -0,0 +1,93 @@ + +
    +
    + +
    + + {if:category.getFirstPhoto()} + + + + {end:} +
    + {category.getTotalNumberOfPhotos():h} +
    +
    +
    +

    + + {category.getCategory()} + +

    +
    +
    +
    +
    +
    + diff --git a/Toolkit/Photos/templates/Admin/listPhotos.html b/Toolkit/Photos/templates/Admin/listPhotos.html new file mode 100644 index 0000000..7711ee8 --- /dev/null +++ b/Toolkit/Photos/templates/Admin/listPhotos.html @@ -0,0 +1,63 @@ + +
    +
    + {if:photo.getImage()} + + + + {end:} +
    +
    +

    + + {photo.getTitle()} + +

    +
    +
    +
    +
    diff --git a/Toolkit/Photos/templates/Admin/listUsers.html b/Toolkit/Photos/templates/Admin/listUsers.html new file mode 100644 index 0000000..1d0d90c --- /dev/null +++ b/Toolkit/Photos/templates/Admin/listUsers.html @@ -0,0 +1,26 @@ + +
    +

    {statusText}

    + + + + + + + + + + + + + +
    FunctionNameExpiresApproved
    + [Edit] + {user.getFname()} {user.getLname()}{user.getExpire()} + {if:user.getApproved()} + Yes + {else:} + No + {end:} +
    +
    diff --git a/Toolkit/Photos/templates/Admin/nav.html b/Toolkit/Photos/templates/Admin/nav.html new file mode 100644 index 0000000..953174b --- /dev/null +++ b/Toolkit/Photos/templates/Admin/nav.html @@ -0,0 +1,17 @@ + diff --git a/Toolkit/Photos/templates/Admin/searchForm.html b/Toolkit/Photos/templates/Admin/searchForm.html new file mode 100644 index 0000000..6b5ac51 --- /dev/null +++ b/Toolkit/Photos/templates/Admin/searchForm.html @@ -0,0 +1,76 @@ + +
    +
    +
    + + + +
    +
    + + {if:_REQUEST[photoName]} + + {else:} + + {end:} + +
    +
    +
    diff --git a/Toolkit/Photos/templates/Admin/userNav.html b/Toolkit/Photos/templates/Admin/userNav.html new file mode 100644 index 0000000..721ba30 --- /dev/null +++ b/Toolkit/Photos/templates/Admin/userNav.html @@ -0,0 +1,14 @@ + diff --git a/Toolkit/Photos/templates/photoCats.html b/Toolkit/Photos/templates/photoCats.html new file mode 100755 index 0000000..a01d715 --- /dev/null +++ b/Toolkit/Photos/templates/photoCats.html @@ -0,0 +1,17 @@ +catPhotos) { + foreach ($t->catPhotos as $category) { + ?> +
  • + + + + getCategory();?> +
  • + \ No newline at end of file diff --git a/Toolkit/Photos/templates/photoGalleryWrapper.html b/Toolkit/Photos/templates/photoGalleryWrapper.html new file mode 100644 index 0000000..e48bb57 --- /dev/null +++ b/Toolkit/Photos/templates/photoGalleryWrapper.html @@ -0,0 +1,336 @@ + + + + +{if:photoNameSearch} + +{end:} \ No newline at end of file diff --git a/Toolkit/Photos/templates/photos.html b/Toolkit/Photos/templates/photos.html new file mode 100755 index 0000000..90e3171 --- /dev/null +++ b/Toolkit/Photos/templates/photos.html @@ -0,0 +1,31 @@ +photos) { + foreach ($t->photos as $photo) { + ?> +
  • + + <?php echo htmlspecialchars($photo->getDescription())?> + getTitle()) {?> + + getTitle(); + if(strlen($tempTitle) > 50) { + $tempTitle = substr($tempTitle, 0, 47); + $tempTitle .= "..."; + } + echo $tempTitle; + //echo $photo->getTitle(); + ?> + + + + getDownload()) {?> + + Download for + Web - Print + + +
  • + diff --git a/admin/photos.php b/admin/photos.php new file mode 100644 index 0000000..9ee553f --- /dev/null +++ b/admin/photos.php @@ -0,0 +1,21 @@ +config = $config; +$registry->page = MEDIA_BASE_URL . 'admin/photos.php'; +$appConfig = $config->application->toArray(); +$registry->dbh = Toolkit_Database::getInstance(); +$registry->logger = Toolkit_Logger::getLogger(); +$registry->router = new Toolkit_Router($registry); +$registry->router->setPath($appConfig['path']); +$registry->router->setApplication($appConfig['application']); + +$html = $registry->router->loader(); + +echo $html; \ No newline at end of file diff --git a/config/application.ini b/config/application.ini index 6778b14..08d83f8 100644 --- a/config/application.ini +++ b/config/application.ini @@ -108,7 +108,7 @@ news.home = Off news.page = Off ; Turn the photo gallery application On or Off -photo_gallery.application = Off +photo_gallery.application = On ; Turn the rotating image application On or Off rotating_images.application = On diff --git a/static/9.phtml b/static/9.phtml new file mode 100644 index 0000000..2326739 --- /dev/null +++ b/static/9.phtml @@ -0,0 +1,782 @@ +_validationType = 'server'; + $this->_partySize = array('' => '-- Select Size --') + range(0, 10); + } + + protected function _setupElements($elements) + { + $this->formElements = $elements; + foreach ($elements as $e) { + switch ($e['type']) { + case 'group' : + if (is_array($e['group'])) { + unset($field); + foreach ($e['group'] as $g) { + $field[] =& HTML_QuickForm::createElement($g['type'], $g['name'], $g['display'], $g['opts'], $g['att'], $g['val']); + } + $source =& $this->addGroup($field, $e['name'], $e['label'], $e['separator'], $e['appendName']); + } + break; + + case 'html' : + if (isset($e['name'], $e['display'])) { + $source =& $this->addElement($e['type'], $e['name'], $e['display']); + } else { + $this->addElement($e['type'], $e['display']); + } + break; + + default : + $source =& $this->addElement($e['type'], $e['name'], $e['display'], $e['opts'], $e['att'], $e['val']); + if ($e['type'] == 'advmultiselect') { + $source->setLabel($e['labels']); + } + break; + } + } + } + + protected function _setupRules(array $rules = null) + { + if (is_array($rules)) { + foreach ($rules as $r) { + $this->addRule($r['element'], $r['message'], $r['type'], $r['format'], $r['validation'], $r['reset'], $r['force']); + } + } + + foreach ($this->formElements as $e) { + if ($e['req']) { + $this->addRule($e['name'], + 'ERROR: You must complete this field!', + 'required', null, $this->_validationType + ); + } + } + } + + protected function _setupFilters($filters) + { + foreach ($filters as $f) { + $this->applyFilter($f['element'], $f['filter']); + } + } +} + +class PageFirst extends PageBase +{ + function buildForm() + { + $this->_formBuilt = true; + + $nextWeek = mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')); + $defaults = array( + 'arrival' => array('m' => date('m'), 'd' => date('d'), 'Y' => date('Y')), + 'departure' => array('m' => date('m', $nextWeek), 'd' => date('d', $nextWeek), 'Y' => date('Y', $nextWeek)), + ); + $golfers = array('' => '-- Select --') + range(0, 20); + + $elements[] = array('type' => 'header', 'req' => false, 'name' => 'header_rmv', 'display' => 'Package Price Quote Request page 1 of 4'); + $elements[] = array('type' => 'date', 'req' => true, 'name' => 'arrival', 'display' => 'Arrival:', 'opts' => array('format' => 'm / d / Y', 'minYear' => date('Y'), 'maxYear' => date('Y')+1)); + $elements[] = array('type' => 'date', 'req' => true, 'name' => 'departure', 'display' => 'Departure:', 'opts' => array('format' => 'm / d / Y', 'minYear' => date('Y'), 'maxYear' => date('Y')+1)); + $elements[] = array('type' => 'select', 'req' => true, 'name' => 'golfers', 'display' => 'Number of golfers:', 'opts' => $golfers); + $elements[] = array('type' => 'select', 'req' => true, 'name' => 'nongolfers', 'display' => 'Number of non-golfers:', 'opts' => $golfers); + $elements[] = array('type' => 'submit', 'req' => false, 'name' => $this->getButtonName('next'), 'display' => 'Next step >>'); + + $rules[] = array('element' => array('arrival', 'departure'), 'message' => 'ERROR: Arrival date must preceed your Departure!', 'type' => 'callback', 'format' => 'check_dates', 'validation' => $this->_validationType, 'reset' => true, 'force' => false); + $rules[] = array('element' => 'arrival', 'message' => 'ERROR: Invalid Date!', 'type' => 'callback', 'format' => 'check_date', 'validation' => $this->_validationType, 'reset' => true, 'force' => false); + $rules[] = array('element' => 'departure', 'message' => 'ERROR: Invalid Date!', 'type' => 'callback', 'format' => 'check_date', 'validation' => $this->_validationType, 'reset' => true, 'force' => false); + + $filters[] = array('element' => '__ALL__', 'filter' => 'trim'); + + $this->_setupElements($elements); + $this->_setupRules($rules); + $this->_setupFilters($filters); + $this->setDefaults($defaults); + $this->setDefaultAction('next'); + } +} + +class PageSecond extends PageBase +{ + function buildForm() + { + $this->_formBuilt = true; + + $golfers= $this->controller->exportValue('page1', 'golfers'); + $nongolfers = $this->controller->exportValue('page1', 'nongolfers'); + + $attendees = $golfers + $nongolfers; + + $couples = ($attendees % 2) ? (($attendees - 1) / 2) : ($attendees / 2); + $couples = array('' => '-- Select --') + range(0, $couples); + $singles = array('' => '-- Select --') + range(0, $attendees); + $accomodations = array('' => '-- Select --') + range(0, $attendees); + $bathrooms = range(1, $attendees); + foreach ($bathrooms as $k => $v) + { + $temp[++$k] = $v; + } + unset($bathrooms); + $bathrooms = $temp; + unset($temp); + + $lodging[] = array('type' => 'radio', 'req' => true, 'name' => 'lodging', 'display' => null, 'opts' => 'Hamlet Village', 'att' => 'Hamlet Village Condominiums'); + $lodging[] = array('type' => 'radio', 'req' => true, 'name' => 'lodging', 'display' => null, 'opts' => 'Trout Creek', 'att' => 'Trout Creek Condominiums'); + + $bedOptions[] = array('type' => 'checkbox', 'req' => false, 'name' => 'twin', 'display' => null, 'opts' => 'Twin Bed is OK'); + $bedOptions[] = array('type' => 'checkbox', 'req' => false, 'name' => 'sleeper', 'display' => null, 'opts' => 'Sleeper Sofa is OK'); + + $elements[] = array('type' => 'header', 'req' => false, 'name' => 'header_rmv', 'display' => 'Package Price Quote Request page 2 of 4'); + $elements[] = array('type' => 'group', 'req' => true, 'name' => 'accommodation', 'group' => $lodging, 'label' => 'Lodging:', 'appendName' => false); + $elements[] = array('type' => 'select', 'req' => true, 'name' => 'couples', 'display' => 'Number of Couples:', 'opts' => $couples); + $elements[] = array('type' => 'select', 'req' => true, 'name' => 'singles', 'display' => 'Number of Singles:', 'opts' => $singles); + $elements[] = array('type' => 'select', 'req' => false, 'name' => 'bathrooms', 'display' => 'Number of Bathrooms:','opts' => $bathrooms); + $elements[] = array('type' => 'header', 'req' => false, 'name' => 'accomodation_rmv', 'display' => 'Accommodation Type Preference'); + $elements[] = array('type' => 'select', 'req' => true, 'name' => 'rooms', 'display' => 'Number of Rooms:', 'opts' => $accomodations); + $elements[] = array('type' => 'select', 'req' => true, 'name' => 'beds', 'display' => 'Number of Beds:', 'opts' => $accomodations); + $elements[] = array('type' => 'group', 'req' => false, 'name' => 'bedOptions', 'group' => $bedOptions, 'label' => 'Bed Options:', 'separator' => '
    ', 'appendName' => false); + + $prevnext[] =& $this->createElement('submit', $this->getButtonName('next'), 'Next step >>'); + + $filters[] = array('element' => '__ALL__', 'filter' => 'trim'); + + $this->_setupElements($elements); + $this->_setupRules(); + $this->addGroup($prevnext, 'control_buttons', '', ' ', false); + $this->_setupFilters($filters); + $this->setDefaultAction('next'); + $defaults = array( + 'couples' => '', + 'singles' => '', + 'rooms' => '', + 'beds' =>'', + ); + $this->setDefaults($defaults); + } +} + +class PageThird extends PageBase +{ + function buildForm() + { + $this->_formBuilt = true; + + $arrival = $this->controller->exportValue('page1', 'arrival'); + $departure = $this->controller->exportValue('page1', 'departure'); + list($arrivalMonth, $arrivalDay, $arrivalYear) = array_values($arrival); + list($departureMonth, $departureDay, $departureYear) = array_values($departure); + + $vacationLength = date_difference( + $arrivalMonth, + $arrivalDay, + $arrivalYear, + $departureMonth, + $departureDay, + $departureYear + ); + + $morning = array( + 'Any Time' => '-- Anytime --', + '07:00 am' => '07:00 am', + '07:30 am' => '07:30 am', + '08:00 am' => '08:00 am', + '08:30 am' => '08:30 am', + '09:00 am' => '09:00 am', + '09:30 am' => '09:30 am', + '10:00 am' => '10:00 am', + '10:30 am' => '10:30 am', + '11:00 am' => '11:00 am', + '11:30 am' => '11:30 am', + ); + + $evening = array( + 'Any Time' => '-- Anytime --', + '12:00 noon' => '12:00 noon', + '12:30 pm' => '12:30 pm', + '01:00 pm' => '01:00 pm', + '01:30 pm' => '01:30 pm', + '02:00 pm' => '02:00 pm', + '02:30 pm' => '02:30 pm', + '03:00 pm' => '03:00 pm', + '03:30 pm' => '03:30 pm', + '04:00 pm' => '04:00 pm', + ); + + $golfers = array('0' => '-- None --') + range(0, $this->controller->exportValue('page1', 'golfers')); + + $courses = array( + '' => '-- Select --', + 'Belvedere Golf Club' => 'Belvedere Golf Club', + 'Dunmaglas' => 'Dunmaglas', + 'Little Traverse Bay' => 'Little Traverse Bay', + 'Black Lake' => 'Black Lake' + ); + + $tos = 'Tee Times are requests only and subject to change based on course availability and travel time between courses.'; + + $elements[] = array('type' => 'header', 'req' => false, 'name' => 'header_rmv', 'display' => 'Package Price Quote Request page 3 of 4'); + $elements[] = array('type' => 'static', 'req' => false, 'name' => 'tos_rmv', 'display' => 'Terms of Service:', 'opts' => $tos); + $elements[] = array('type' => 'static', 'req' => false, 'name' => 'view_courses_rmv', 'display' => 'Click here to view course
    desriptions and locations:', 'opts' => 'View Courses'); + $elements[] = array('type' => 'elementGrid', 'req' => false, 'name' => 'golfing', 'display' => 'Golfing Preference:', 'opts' => array('actAsGroup' => false)); + + $prevnext[] =& $this->createElement('submit', $this->getButtonName('next'), 'Next step >>'); + + $filters[] = array('element' => '__ALL__', 'filter' => 'trim'); + + foreach ($elements as $e) { + $source =& $this->addElement($e['type'], $e['name'], $e['display'], $e['opts'], $e['att'], $e['val']); + + if ($e['name'] == 'golfing') { + $columnNames = array( + 'No. Golfers', + 'Tee Time', + 'Golf Course', + ); + $source->setColumnNames($columnNames); + + $date = gregoriantojd($arrivalMonth, $arrivalDay, $arrivalYear); + for ($i = 0; $i <= $vacationLength; ++$i) { + unset($amgolf); + unset($pmgolf); + + $calDate = cal_from_jd($date++, CAL_GREGORIAN); + + $amgolf[] =& $this->createElement('select', "amGolfers$i", null, $golfers); + $amgolf[] =& $this->createElement('select', "amTeeTime$i", null, $morning); + $amgolf[] =& $this->createElement('select', "amCourse$i", null, $courses); + + $pmgolf[] =& $this->createElement('select', "pmGolfers$i", null, $golfers); + $pmgolf[] =& $this->createElement('select', "pmTeeTime$i", null, $evening); + $pmgolf[] =& $this->createElement('select', "pmCourse$i", null, $courses); + + $source->addRow(&$amgolf, $calDate['date']); + $source->addRow(&$pmgolf, ' '); + } + } + } + $this->addGroup($prevnext, 'control_buttons', '', ' ', false); + $this->_setupFilters($filters); + $this->setDefaultAction('next'); + } +} + +class PageFourth extends PageBase +{ + function buildForm() + { + $this->_formBuilt = true; + + $arrival = $this->controller->exportValue('page1', 'arrival'); + $departure = $this->controller->exportValue('page1', 'departure'); + list($arrivalMonth, $arrivalDay, $arrivalYear) = array_values($arrival); + list($departureMonth, $departureDay, $departureYear) = array_values($departure); + + $vacationLength = date_difference( + $arrivalMonth, + $arrivalDay, + $arrivalYear, + $departureMonth, + $departureDay, + $departureYear + ); + + $reservationTime = array( + '' => '-- Select --', + '5:00 pm' => '5:00 pm', + '5:30 pm' => '5:30 pm', + '6:00 pm' => '6:00 pm', + '6:30 pm' => '6:30 pm', + '7:00 pm' => '7:00 pm', + '7:30 pm' => '7:30 pm', + '8:00 pm' => '8:00 pm', + '8:30 pm' => '8:30 pm', + '9:00 pm' => '9:00 pm', + ); + + $locations = array( + '' => '-- Select --', + 'Black Lake Golf Club' => 'Black Lake Golf Club', + 'Little Traverse Bay' => 'Little Traverse Bay' + ); + + $states = array('' => '-- Select --') + $GLOBALS['states']; + unset( + $states['Asia'], + $states['Australia'], + $states['Bahamas'], + $states['Caribbean'], + $states['Costa Rica'], + $states['South America'], + $states['South Africa'], + $states['Europe'], + $states['Mexico'] + ); + + try { + $dns = 'pgsql:' . CONN_STR; + $dbh = new PDO($dns); + $dbh->setAttribute(PDO::ATTR_ERRMODE, ERRMODE); + + $sql = " + SELECT * + FROM contact_inq + ORDER BY pos ASC"; + + $stmt = $dbh->prepare($sql); + $stmt->execute(); + + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $discovery[$row['header']] = $row['header']; + } + + $discovery = array('' => '-- Select --') + $discovery; + unset($dbh); + unset($stmt); + } catch (PDOException $e) { + unset($dbh); + unset($stmt); + echo 'PDO Exception Caught. '; + echo 'Error with the database:
    '; + echo 'Error: ' . $e->getMessage() . '
    '; + echo 'File: ' . $e->getFile() . '
    '; + echo 'Line: ' . $e->getLine() . '
    '; + } + +// $elements[] = array('type' => 'header', 'req' => false, 'name' => 'header_rmv', 'display' => 'Package Price Quote Request page 4 of 4'); +// $elements[] = array('type' => 'elementGrid', 'req' => false, 'name' => 'dining', 'display' => 'Dining Preference:', 'opts' => array('actAsGroup' => false)); + $elements[] = array('type' => 'header', 'req' => false, 'name' => 'cust_info_rmv', 'display' => 'Customer Information'); + $elements[] = array('type' => 'text', 'req' => true, 'name' => 'fname', 'display' => 'First Name:'); + $elements[] = array('type' => 'text', 'req' => true, 'name' => 'lname', 'display' => 'Last Name:'); + $elements[] = array('type' => 'text', 'req' => false, 'name' => 'address', 'display' => 'Address:'); + $elements[] = array('type' => 'text', 'req' => false, 'name' => 'city', 'display' => 'City:'); + $elements[] = array('type' => 'select', 'req' => false, 'name' => 'state', 'display' => 'State / Province:', 'opts' => $states); + $elements[] = array('type' => 'select', 'req' => false, 'name' => 'country', 'display' => 'Country:', 'opts' => array('' => '-- Select --', 'USA' => 'USA', 'Canada' => 'Canada')); + $elements[] = array('type' => 'text', 'req' => false, 'name' => 'zip', 'display' => 'Zip Code / Postal Code:'); + $elements[] = array('type' => 'text', 'req' => false, 'name' => 'phone', 'display' => 'Primary Phone:'); + $elements[] = array('type' => 'text', 'req' => false, 'name' => 'alt_phone', 'display' => 'Secondary Phone:'); + $elements[] = array('type' => 'text', 'req' => true, 'name' => 'email', 'display' => 'Email:'); + $elements[] = array('type' => 'text', 'req' => true, 'name' => 'email_rmv', 'display' => 'Confirm Email Address:'); + $elements[] = array('type' => 'textarea', 'req' => false, 'name' => 'comments', 'display' => 'Special Requests/Comments:', 'opts' => array('rows' => 10, 'cols' => 37)); + $elements[] = array('type' => 'select', 'req' => true, 'name' => 'discovery', 'display' => 'How did you hear of Big Fore:', 'opts' => $discovery); + + $prevnext[] =& $this->createElement('submit', $this->getButtonName('next'), 'Finish'); + + $rules[] = array('element' => 'email', 'message' => 'Error: Invalid email address!', 'type' => 'email', 'format' => null, 'validation' => $this->_validationType, 'reset' => false, 'force' => false); + $rules[] = array('element' => array('email', 'email_rmv'), 'message' => 'Error: Your email addresses do not match!', 'type' => 'compare', 'format' => null, 'validation' => $this->_validationType, 'reset' => true, 'force' => false); + $rules[] = array('element' => array('state', 'country'), 'message' => 'Error: Your state / province does not match your country!', 'type' => 'callback', 'format' => 'checkCountryState', 'validation' => $this->_validationType, 'reset' => true, 'force' => false); + + $filters[] = array('element' => '__ALL__', 'filter' => 'trim'); + + foreach ($elements as $e) { + $source =& $this->addElement($e['type'], $e['name'], $e['display'], $e['opts'], $e['att'], $e['val']); + + if ($e['name'] == 'dining') { + $source->addColumnName('No. in Party'); + $source->addColumnName('Reservation Time'); + $source->addColumnName('Restaurant'); + + $date = gregoriantojd( + $arrivalMonth, + $arrivalDay, + $arrivalYear + ); + + $golfers = array('' => '-- Select --') + range(1, 20); + for ($i = 0; $i <= $vacationLength; ++$i) { + unset($dining); + + $calDate = cal_from_jd($date++, CAL_GREGORIAN); + + $dining[] =& $this->createElement('select', "size$i", null, $golfers); + $dining[] =& $this->createElement('select', "time$i", null, $reservationTime); + $dining[] =& $this->createElement('select', "location$i", null, $locations); + + $source->addRow($dining, $calDate['date']); + } + } + } + $this->addGroup($prevnext, 'control_buttons', '', ' ', false); + $this->formElements = $elements; + $this->_setupRules($rules); + $this->_setupFilters($filters); + $this->setDefaultAction('next'); + } +} + +class ActionDisplay extends HTML_QuickForm_Action_Display +{ + function _renderForm(&$page) + { + $renderer =& $page->defaultRenderer(); + +// $renderer->setFormTemplate('{content}
    '); +// $renderer->setHeaderTemplate('{header}'); +// $renderer->setGroupTemplate('{content}
    ', 'name'); +// $renderer->setGroupElementTemplate('{element}
    *{label}', 'name'); + $renderer->setHeaderTemplate('{header}'); + $renderer->setElementTemplate('
    *{label}{element}', 'golfing'); + $renderer->setElementTemplate('
    *{label}{element}', 'dining'); + $renderer->setGroupElementTemplate('{element}
    *{label}', 'golfing'); + + $page->accept($renderer); + return $renderer->toHtml(); + } +} + +class ActionProcess extends HTML_QuickForm_Action +{ + function perform(&$page, $actionName) + { + $return = $this->_getEntireForm(&$page); + if ($this->_process(&$page, $return)) { + $return = "

    The information below was successfully submitted

    \n
    \n{$return}\n
    \n"; + $return = "

    Thank you for requesting a custom package price quote from Big Fore Golf. + The lodging partner that you requested will receive your request and personally + follow up with you to finalize any details of your selections, and return your + package pricing and details.

    \n{$return}\n"; + } else { + $return = '

    There was an error processing your request, if this problem persists please contact BigFore

    '; + } + return $return; + } + + private function _getEntireForm(&$page) + { + $values = $page->controller->exportValues(); +// $return .= print_r($values, true); + unset($temp); + unset($renderer); + $rmvElements = array( + 'control_buttons', + 'tos_rmv', + 'view_courses_rmv', + 'header_rmv', + 'cust_info_rmv', + 'accomodation_rmv', + ); + for ($i = 1; $i < 4; ++$i) { + $temp =& $page->controller->getPage("page$i"); + $back = $temp->getButtonName('back'); + $next = $temp->getButtonName('next'); + $temp->buildForm(); +// $return .= print_r($temp, true); + if ($temp->elementExists($back)) { + $temp->removeElement($back); + } + if ($temp->elementExists($next)) { + $temp->removeElement($next); + } + foreach ($rmvElements as $e) { + if ($temp->elementExists($e)) { + $temp->removeElement($e); + } + } + $temp->loadValues($values); + $temp->freeze(); + $renderer =& $temp->defaultRenderer(); + $style = "border: 1px solid #eee; border-collapse: collapse; color: #000; font-family: arial, helvetica, sans-serif; padding: 3px;"; + + $renderer->setHeaderTemplate('{header}'); +// $renderer->setElementTemplate('
    *{label}{element}'); +// $renderer->setElementTemplate("\n\t\n\t\t*{label}\n\t\t{error}
    \t{element}\n\t"); + $renderer->setElementTemplate('
    *{label}{element}', 'golfing'); + $renderer->setElementTemplate('
    *{label}{element}', 'dining'); + $renderer->setGroupElementTemplate('{element}
    *{label}', 'golfing'); + + $temp->accept($renderer); + $return .= $temp->toHtml(); + } + foreach ($rmvElements as $e) { + if ($page->elementExists($e)) { + $page->removeElement($e); + } + } + $renderer =& $page->defaultRenderer(); + + $renderer->setHeaderTemplate('{header}'); + $renderer->setElementTemplate('
    *{label}{element}', 'golfing'); + $renderer->setElementTemplate('
    *{label}{element}', 'dining'); + $renderer->setGroupElementTemplate('{element}
    *{label}', 'golfing'); + + $page->accept($renderer); + $page->freeze(); + $return .= $page->toHtml(); + + return $return; + } + + private function _process(&$page, $email) + { + $values = $page->controller->exportValues(); + try { + $dns = 'pgsql:' . CONN_STR; + $dbh = new PDO($dns); + $dbh->setAttribute(PDO::ATTR_ERRMODE, ERRMODE); + $dbh->beginTransaction(); + $sql = " + SELECT * + FROM contact + WHERE email = :email"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':email', $values['email'], PDO::PARAM_STR); + $stmt->execute(); + $contact = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($contact === false) { + $sql = " + INSERT INTO contact(pquote_create_date, fname, lname, address, city, state, zip, phone, alt_phone, email, mail_ok, arrival, departure, golfers, nongolfers, + lodging, couples, singles, bathrooms, rooms, beds, twinok, sleepersofaok, comments, discover, partysize, pquote) + VALUES (now(), :fname, :lname, :addy, :city, :state, :zip, :phone, :altphone, :email, true, :arrival, :departure, :golfers, :nongolfers, :lodging, + :couples, :singles, :brooms, :rooms, :beds, :twinok, :sofaok, :comments, :discover, :partysize, true)"; + } else { + $sql = " + UPDATE contact + SET pquote_create_date = now(), + fname = :fname, + lname = :lname, + address = :addy, + city = :city, + state = :state, + zip = :zip, + phone = :phone, + alt_phone = :altphone, + email = :email, + mail_ok = true, + arrival = :arrival, + departure = :departure, + golfers = :golfers, + nongolfers = :nongolfers, + lodging = :lodging, + couples = :couples, + singles = :singles, + bathrooms = :brooms, + rooms = :rooms, + beds = :beds, + twinok = :twinok, + sleepersofaok = :sofaok, + comments = :comments, + discover = :discover, + partysize = :partysize, + pquote= true + WHERE email = :email"; + } + + $arrival = "{$values['arrival']['Y']}-{$values['arrival']['m']}-{$values['arrival']['d']}"; + $departure = "{$values['departure']['Y']}-{$values['departure']['m']}-{$values['departure']['d']}"; + $twin = ($values['twin'] == 'No') ? false : true; + $sofa = ($values['sleeper'] == 'No') ? false : true; + $partySize = ($values['golfers'] + $values['nongolfers']); + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':fname', $values['fname'], PDO::PARAM_STR); + $stmt->bindParam(':lname', $values['lname'], PDO::PARAM_STR); + $stmt->bindParam(':addy', $values['address'], PDO::PARAM_STR); + $stmt->bindParam(':city', $values['city'], PDO::PARAM_STR); + $stmt->bindParam(':state', $values['state'], PDO::PARAM_STR); + $stmt->bindParam(':zip', $values['zip'], PDO::PARAM_STR); + $stmt->bindParam(':phone', $values['phone'], PDO::PARAM_STR); + $stmt->bindParam(':altphone', $values['alt_phone'], PDO::PARAM_STR); + $stmt->bindParam(':email', $values['email'], PDO::PARAM_STR); + $stmt->bindParam(':arrival', $arrival, PDO::PARAM_STR); + $stmt->bindParam(':departure', $departure, PDO::PARAM_STR); + $stmt->bindParam(':golfers', $values['golfers'], PDO::PARAM_INT); + $stmt->bindParam(':nongolfers', $values['nongolfers'], PDO::PARAM_INT); + $stmt->bindParam(':lodging', $values['lodging'], PDO::PARAM_STR); + $stmt->bindParam(':couples', $values['couples'], PDO::PARAM_INT); + $stmt->bindParam(':singles', $values['singles'], PDO::PARAM_INT); + $stmt->bindParam(':brooms', $values['bathrooms'], PDO::PARAM_INT); + $stmt->bindParam(':rooms', $values['rooms'], PDO::PARAM_INT); + $stmt->bindParam(':beds', $values['beds'], PDO::PARAM_INT); + $stmt->bindParam(':twinok', $twin, PDO::PARAM_BOOL); + $stmt->bindParam(':sofaok', $sofa, PDO::PARAM_BOOL); + $stmt->bindParam(':comments', $values['comments'], PDO::PARAM_STR); + $stmt->bindParam(':discover', $values['discovery'], PDO::PARAM_STR); + $stmt->bindParam(':partysize', $partySize, PDO::PARAM_INT); + $stmt->execute(); + + if ($contact === false) { + $sql = " + SELECT id + FROM contact + ORDER BY id DESC LIMIT 1"; + $stmt = $dbh->prepare($sql); + $stmt->execute(); + $contact = $stmt->fetch(PDO::FETCH_ASSOC); + } + + $vacationLength = date_difference( + $values['arrival']['m'], + $values['arrival']['d'], + $values['arrival']['Y'], + $values['departure']['m'], + $values['departure']['d'], + $values['departure']['Y'] + ); + + $golfingDate = $diningDate = gregoriantojd( + $values['arrival']['m'], + $values['arrival']['d'], + $values['arrival']['Y'] + ); + $sql = " + INSERT INTO golfing_preference (contact_id, date, golfers, teetime, course) + VALUES (:cid, :date, :golfers, :teetime, :course)"; + + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':cid', $contact['id'], PDO::PARAM_INT); + // Add all the golfing trips the user scheduled + for ($i = 0; $i <= $vacationLength; ++$i) { + $calDate = cal_from_jd($golfingDate++, CAL_GREGORIAN); + // Only add the trip into the DB if the user has selected a course. + if (!empty($values["amCourse$i"]) && !empty($values["amGolfers$i"])) { + $stmt->bindParam(':date', $calDate['date'], PDO::PARAM_STR); + $stmt->bindParam(':golfers', $values["amGolfers$i"], PDO::PARAM_INT); + $stmt->bindParam(':teetime', $values["amTeeTime$i"], PDO::PARAM_STR); + $stmt->bindParam(':course', $values["amCourse$i"], PDO::PARAM_STR); + $stmt->execute(); + } + if (!empty($values["pmCourse$i"]) && !empty($values["pmGolfers$i"])) { + $stmt->bindParam(':date', $calDate['date'], PDO::PARAM_STR); + $stmt->bindParam(':golfers', $values["pmGolfers$i"], PDO::PARAM_INT); + $stmt->bindParam(':teetime', $values["pmTeeTime$i"], PDO::PARAM_STR); + $stmt->bindParam(':course', $values["pmCourse$i"], PDO::PARAM_STR); + $stmt->execute(); + } + } + +// $sql = " +// insert into dining_preference(contact_id, size, time, restaurant, date) +// values (:cid, :size, :time, :res, :date)"; +// $stmt = $dbh->prepare($sql); +// $stmt->bindParam(':cid', $contact['id'], PDO::PARAM_INT); +// // Add all the dining reservations the user scheduled +// for ($i = 0; $i <= $vacationLength; ++$i) { +// $calDate = cal_from_jd($diningDate++, CAL_GREGORIAN); +// // Only add the reservation if the user changed the party size. +// if (!empty($values["size$i"])) { +// $stmt->bindParam(':size', $values["size$i"], PDO::PARAM_INT); +// $stmt->bindParam(':time', $values["time$i"], PDO::PARAM_INT); +// $stmt->bindParam(':res', $values["location$i"], PDO::PARAM_INT); +// $stmt->bindParam(':date', $calDate['date'], PDO::PARAM_INT); +// $stmt->execute(); +// } +// } + + $dbh->commit(); + + if ($values['lodging'] === 'Trout Creek Condominiums') { + $toEmail = TROUT_CREEK_EMAILS; + } else { + $toEmail = HAMLET_VILLAGE_EMAILS; + } + require_once 'Mail.php'; + require_once 'Mail/mime.php'; + + $msg = "{$email}"; + $crlf = "\n"; + $mimeMail = new Mail_mime($crlf); + $mimeMail->setFrom(SITENAME . '<' . OWNER_EMAIL . '>'); + $mimeMail->addBcc('jodie@gaslightmedia.com'); + //$mimeMail->addBcc('veilig2000@gmail.com'); + $mimeMail->setSubject(SITENAME . ' Price Quote Request Form'); + $mimeMail->setHTMLBody($msg); + + $mail =& Mail::factory('mail'); + $body = $mimeMail->get(); + $headers = $mimeMail->headers(); + + $mail->send($toEmail, $headers, $body); + unset($dbh); + unset($stmt); + unset($mimeMail); + unset($mail); + return true; + } catch (PDOException $e) { + $dbh->rollBack(); + unset($dbh); + unset($stmt); + echo 'PDO Exception Caught. '; + echo 'Error with the database:
    '; + echo 'Error: ' . $e->getMessage() . '
    '; + echo 'File: ' . $e->getFile() . '
    '; + echo 'Line: ' . $e->getLine() . '
    '; +// echo 'PDO::errorInfo():
    ' . print_r($dbh->errorInfo(), true) . '

    '; +// echo 'TraceAsString:
    ' . print_r($e->getTrace(), true) . '

    '; + return false; + } + return false; + } +} + +$wizard =& new HTML_QuickForm_Controller('Wizard'); +$wizard->addPage(new PageFirst('page1')); +$wizard->addPage(new PageSecond('page2')); +$wizard->addPage(new PageThird('page3')); +$wizard->addPage(new PageFourth('page4')); + +$wizard->addAction('display', new ActionDisplay()); +$wizard->addAction('process', new ActionProcess()); + +$pqForm = $wizard->run(); -- 2.17.1