From: Laury GvR Date: Thu, 24 Jul 2014 13:18:02 +0000 (-0400) Subject: UserArea files, Contact page X-Git-Tag: VV1^2~76 X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/?a=commitdiff_plain;h=c5291a12fa4649bbde4d4abff2b0f469541d77e1;p=web%2FCityofMI.git UserArea files, Contact page Added UserArea files from Cheboygancounty, though only functional under some circumstances. Added 10.phtml from Demo, static contacts. --- diff --git a/Toolkit/Contacts/config.ini b/Toolkit/Contacts/config.ini index c77d0d2..aaecfc3 100644 --- a/Toolkit/Contacts/config.ini +++ b/Toolkit/Contacts/config.ini @@ -9,6 +9,6 @@ sequence = "contact_id_seq" [contact_types] 1 = "Web Contact" -2 = "E-News" -3 = "Travel Planner" -4 = "Visitor Guide" +;2 = "E-News" +;3 = "Travel Planner" +;4 = "Visitor Guide" diff --git a/Toolkit/UserArea/Admin/EditUser.php b/Toolkit/UserArea/Admin/EditUser.php new file mode 100644 index 0000000..8d230be --- /dev/null +++ b/Toolkit/UserArea/Admin/EditUser.php @@ -0,0 +1,675 @@ + + * @copyright 2010 Gaslight Media + * @license Gaslight Media + * @version CVS: $Id: EditContact.php,v 1.3 2010/05/13 20:18:38 matrix Exp $ + * @link http://pear.php.net/package/Contacts + * @see References to other sections (if any)... + */ + +/** + * Toolkit_UserArea_Admin_EditUser + * + * Edit Process class to insert or update a user + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2010 Steve Sutton + * @license Gaslight Media + * @version Release: @package_version@ + * @link http://pear.php.net/package/Contacts + * @see References to other sections (if any)... + */ +class Toolkit_UserArea_Admin_EditUser + extends Toolkit_FormBuilder +{ + + /** + * Table meta data + * + * This is used when inserting/updating data for the records + * so the PDO's can use explicit data types for the parameters. + * + * @var array + * @access public + */ + public $tableMetaData = array(); + + /** + * What do you want the error msg to be if the form doesn't validate + * + * @var string + * @access protected + */ + protected $errorMsg + = '
+ Warning: The form was not sent, please review the errors below. +
'; + + /** + * What do you want the success msg to be if the form validates successfully + * + * @var string + * @access protected + */ + protected $successMsg + = '
+ The information below has been successfully submitted. +
'; + + /** + * The default templates to inject into the form renderer + * + * @var string + * @access protected + */ + protected $template; + + /** + * The default rules to register for validating + * + * We have to register these rules, or any others we want, before + * we are able to use them in our forms. + * + * These rules can be removed in subclasses before the rules are configured + * if you want to omit any of them from validating input - just remember + * to not call them in your configured rules! + * + * Phone: validates input against US and CA style phone #'s + * + * $rules[] = array('element' => 'phone', + * 'message' => 'ERROR: Invalid Phone Format!', + * 'type' => 'phone', + * 'format' => null, + * 'validation' => $this->validationType, + * 'reset' => true, + * 'force' => false); + * + * + * Zip: Validates input against US and CA zip codes, if DB check is + * set to true, validate zip codes against all the zip codes in the + * DB. + * + * $rules[] = array('element' => 'zip', + * 'message' => 'ERROR: Invalid Zip!', + * 'type' => 'zip', + * 'format' => array('requireDBCheck' => true), + * 'validation' => $this->validationType, + * 'reset' => true, + * 'force' => false); + * + * + * Banwords: Make sure each each doesn't contain a banned word. Checking + * against a DB of banned words. + * + * State: Validate input against US and CA region / province codes. If DB + * check is set to true, validate region / province against all the + * regions / provinces in the DB. + * + * $rules[] = array('element' => 'state_id', + * 'message' => 'ERROR: Invalid State / Province!', + * 'type' => 'state', + * 'format' => array('requireDBCheck' => true), + * 'validation' => $this->validationType, + * 'reset' => true, + * 'force' => false); + * + * + * @var array + * @access protected + * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Zip.php + * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Phone.php + * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/Banwords.php + * @see app.gaslightmedia.com/glmPEAR/HTML/QuickForm/Rule/State.php + */ + protected $registeredRules = array(); + + /** + * Class constructor + * + * @param object $pdo PHP Data Object + * @param string $formName Form's name. + * @param string $method (optional)Form's method defaults to 'POST' + * @param string $action (optional)Form's action + * @param string $target (optional)Form's target defaults to '_self' + * @param mixed $attributes (optional)Extra attributes for
tag + * @param bool $trackSubmit (optional)Whether to track if the form was + * submitted by adding a special hidden field + * + * @author Jamie Kahgee + * @access public + * @link http://pear.php.net/package/HTML_QuickForm/docs/latest/HTML_QuickForm/HTML_QuickForm.html + * @see HTML_QuickForm + */ + public function __construct( + PDO $pdo, + $formName, + $method = 'post', + $action = '', + $target = '', + $attributes = null, + $trackSubmit = false + ) { + parent::__construct( + $formName, + $method, + $action, + $target, + $attributes, + $trackSubmit + ); + + $this->dbh = $pdo; + + /** + * Where are the flexy templates stored at for this class. + */ + define('TEMPLATES_DIR', BASE . 'Toolkit/Contacts/templates'); + + /** + * Where are the compiled flexy templates stored at for this class. + */ + define('COMPILED_DIR', BASE . 'Toolkit/Contacts/templates/compiled'); + $oldUmask = umask(0); + if (!is_dir(TEMPLATES_DIR)) { + mkdir(TEMPLATES_DIR, 0770, true); + } + if (!is_dir(COMPILED_DIR)) { + mkdir(COMPILED_DIR, 0770, true); + } + umask($oldUmask); + + $this->flexyOptions = $GLOBALS['flexyOptions']; + $this->flexyOptions['templateDir'] = TEMPLATES_DIR; + $this->flexyOptions['compileDir'] = COMPILED_DIR; + + } + + /** + * Constant variables for the form + * + * These values won't get overridden by POST or GET vars + * + * @return void + * @access public + */ + public function configureConstants() + { + $c = array( + 'toolbox' => true + ); + if ($id = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT)) { + $c['id'] = $id; + } + $this->setupConstants($c); + } + + /** + * Initializes default form values + * + * @return void + * @access public + */ + public function configureDefaults() + { + $id = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + if ($id) { + $mapper + = new Toolkit_UserArea_Models_Mapper(); + $user + = $mapper->fetchUserById($this->dbh, $id); + $defaults = array( + 'id' => $user->getId(), + 'username' => $user->getUsername(), + 'password' => $user->getPassword(), + 'name' => $user->getName(), + 'active' => $user->getActive() + ); + } else { + $defaults = array(); + } + + $this->setupDefaults($defaults); + } + + /** + * Form element definitions + * + * @return void + * @access public + */ + public function configureElements() + { + $e = array(); + $id = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + // All Elements are created here. This includes group element definitions. + + $e[] = array( + 'type' => 'header', + 'display' => 'User Information' + ); + if ($id) { + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'id', + 'opts' => array('id' => 'userId') + ); + } + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'toolbox' + ); + $e[] = array( + 'type' => 'advcheckbox', + 'req' => false, + 'name' => 'active', + 'display' => '', + 'opts' => 'Active?', + 'val' => array(0, 1) + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'name', + 'display' => 'Name' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'username', + 'display' => 'User Name' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'password', + 'display' => 'Password' + ); + $e[] = array( + 'type' => 'header', + 'display' => 'Applications +
' + ); + + $e[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'submit_rmv', + 'display' => 'Save' + ); + + $this->setupElements($e); + } + + /** + * Form rule definitions + * + * Adds validation rules for the given fields + * + * @return void + * @access public + */ + public function configureRules() + { + $r = array(); + // Form Rules + + $r[] = array( + 'element' => 'username', + 'message' => 'ERROR: Sorry, but this username has already been taken!', + 'type' => 'callback', + 'format' => array($this, 'checkUName'), + 'validation' => $this->validationType, + 'reset' => false, + 'force' => false + ); + + $this->setupRules($r); + } + + /** + * Checks if the login name already exists in the database + * + * @param array $data The name of the member to check for. + * + * @return boolean False on SQL Query error, otherwise true. + * @access protected + */ + public function checkUName($data) + { + try { + // If we're editing a member, they + // can save that member as its + // own name. so don't include that + // member in the check. + if (is_numeric($_REQUEST['id'])) { + $and = "AND id <> :id"; + } + $sql = " + SELECT count(*) AS total + FROM auth.users + WHERE username = :name + $and"; + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':name', $data, PDO::PARAM_STR); + if (is_numeric($_REQUEST['id'])) { + $stmt->bindParam(':id', $_REQUEST['id'], PDO::PARAM_STR); + } + $stmt->execute(); + $stmt->bindColumn('total', $valid); + $stmt->fetch(); + + return !(bool) $valid; + } catch (PDOException $e) { + return Toolkit_Common::handleError($e); + } + } + + /** + * 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); + } + + /** + * Helper function, configures the entire form + * + * @return void + * @access public + */ + public function configureForm() + { + $this->configureElements(); + $this->configureFilters(); + $this->configureRules(); + $this->configureDefaults(); + $this->configureConstants(); + } + + /** + * Handles how to process the form when submitted + * + * @param array $values Form submitted values + * + * @return array Result of Insert / Update function + * @access protected + */ + public function processData($values) + { + // Form data used for the insert/update sql queries and + // the form email. + $e = array( + 'user_agent', + 'remote_addr', + 'contact_type', + ); + $this->setFormData($e); + + // Get rid of any elements in the values array that + // aren't going to be used when inserting/updating the db. + $values = Toolkit_Common::cleanArray($values); + $id = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + $user = Toolkit_UserArea_Models_User::createUserFromValues($values); + if ($id) { + $this->Action = 'Updated'; + } else { + $this->Action = 'Added'; + } + $user->save($this->dbh); + $mapper = new Toolkit_UserArea_Models_Mapper(); + $mapper->saveUserAppData( + $this->dbh, + $user, + $values['app'], + $values['pages'], + $values['eventCategories'] + ); + return true; + } + + /** + * setConfig + * + * @param Config_Container $c instance of Config Container + * + * @access public + * @return string + */ + function setConfig(Config_Container $c) + { + $this->config = $c; + } + + /** + * Custom rendering templates for special fields on the form + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + parent::setupRenderers(); + $renderer =& $this->defaultRenderer(); + $required = ' + * + '; + $error = ' +
{error}
+ '; + $renderer->setElementTemplate( + ' + + '.$required.'{label}'.$error.'{element} + + ', + 'interest' + ); + + $renderer->setElementTemplate( + ''.$required.'{label}'.$error.'{element}', + 'comments' + ); + $renderer->setElementTemplate( + ' + '.$required.'{label}'.$error.'{element} + + ', + 'submit' + ); + + $renderer->setElementTemplate( + ' + + + + + {element} + + ', + 'captcha_question'); + $renderer->setElementTemplate( + ' + + '.$required.' + + + '.$error.'{element} + What is this? + + ', + 'captcha_rmv' + ); + } + + /** + * 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() + { + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/development-bundle/themes/base/jquery.ui.all.css'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL . 'libjs/plugins/asmselect/1.0.4a/jquery.asmselect.css'; + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/js/jquery-ui-1.8.13.custom.min.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_BASE_URL . 'Toolkit/UserArea/libjs/jquery.columnview.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/plugins/asmselect/1.0.4a/jquery.asmselect.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_BASE_URL . 'Toolkit/UserArea/libjs/editUser.js'; + + $this->setupRenderers(); + if ($this->validate()) { + $this->cleanForm(); + if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) { + $this->freeze(); + $output = $this->successMsg; + header("Location: userArea.php"); + exit; + } + } elseif ($this->isSubmitted()) { + $output = $this->errorMsg; + $output .= parent::toHTML(); + } else { + $output = parent::toHTML(); + } + return $output; + } + + /** + * Load option elements into the parent select list + * + * These options are loaded via this seperate function vs inline w/ the + * element definition b/c we need a little more control defining + * the class names for each option so they will render nice when a user + * is looking at the list. + * + * @param PDO $dbh Database handler + * + * @return void + * @throws PDOException throws exception on sql error + * @access public + */ + public function loadParentPages(PDO $dbh) + { + try { + // Get a tree list of categories in linear order with + // category keys in the values and their level in the tree + // in the value + $c = Toolkit_Common::getHierarchicalTreeStructure( + $dbh, + 'pages', + 'id', + 'parent', + 'pos', + 0, + 0 + ); + + // unset the home page, this is never an option to have children + // underneath it. + unset($c[HOME_ID]); + + // If we are editing a page, then we don't want that page + // to show up as an option in the select list. + if (is_numeric($_GET['id'])) { + reset($c); + // Get us to the point in the array were this page is located + while (key($c) != $_GET['id'] && current($c) !== false) { + next($c); + } + // Make sure we didn't traverse off the end of the array + if (current($c) !== false) { + // get the starting level we are currently at + $sl = current($c); + // remove this page (the one we're editing) from the + // array and advance the internal array pointer + unset($c[key($c)]); + // now we need to make sure all sub pages beneath this + // page are also not being shown + + // while we don't traverse off the end of the array + while (current($c) !== false) { + // get the current sub level we are at + $csl = current($c); + // if the current sub-level is the same as the + // starting level, that means we have traversed through + // all the sub-pages and can break out of the loop + if ($csl <= $sl) { + break; + } else { + // we are still in a sub-level page, so unset + // this page so it doesn't show, and advance + // the internal array pointer + unset($c[key($c)]); + } + } + } + } + + // Get all the data about each category + $sql = " + SELECT * + FROM pages + WHERE id = ?"; + + $stmt = $dbh->prepare($sql); + // Get the member categories select list element + $e =& $this->getElement('page'); + foreach ($c as $i => $j) { + $stmt->execute(array($i)); + $row = $stmt->fetch(); + // the class level is always 1 less than what is reported + // from our $c array + $x = $j - 1; + // Add the option data to the select list. + $e->addOption( + $row['navigation_name'], + $i, + array('class' => "level-$x") + ); + } + } catch (PDOException $e) { + Toolkit_Logger::logException('DB error', $e); + throw new Toolkit_Toolbox_Exception( + "Error loading parent pages" + ); + } + } + +} diff --git a/Toolkit/UserArea/Admin/IndexController.php b/Toolkit/UserArea/Admin/IndexController.php new file mode 100644 index 0000000..d790db9 --- /dev/null +++ b/Toolkit/UserArea/Admin/IndexController.php @@ -0,0 +1,170 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ +if (!defined('COMMON_APP_BASE')) { + define('COMMON_APP_BASE', '/var/www/server/CommonApps/'); +} +require_once COMMON_APP_BASE . 'EventCalendar/V1/models/EventMapper.php'; +define('COMMON_EVENTS_SCHEMA', 'events'); +/** + * Toolkit_UserArea_Admin_User + * + * Description of User + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Admin_IndexController + extends Toolkit_BaseControllerAbstract + implements Toolkit_IController +{ + + const TOOLBOX_APP_ID = 1; + const EVENT_APP_ID = 2; + const HAS_TOOLBOX = true; + const HAS_EVENTS = true; + + public function indexAction() + { + $users = new Toolkit_UserArea_Admin_ListUsers( + Toolkit_Database::getInstance() + ); + $users->setQuery(); + $html = $users->toHtml(); + + return $html; + } + + public function showPagesAction() + { + $pageTree = new Toolkit_UserArea_Admin_PageTree($this->registry->dbh); + echo $pageTree->toHtml(); + exit; + } + + private function _getPageName($pageId) + { + try { + $sql = " + SELECT navigation_name + FROM toolbox.pages + WHERE id = :id"; + $stmt = $this->registry->dbh->prepare($sql); + $stmt->bindParam(':id', $pageId, PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchColumn(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + private function _getEventCategories() + { + static $categories = array(); + if (empty($categories)) { + $eventMapper = new EventMapper(Toolkit_Database::getInstance()); + $categories = $eventMapper->fetchAllCategories(); + } + return $categories; + } + + public function GetUserAppsAction() + { + $userEventCategories = array(); + $options = $GLOBALS['flexyOptions']; + $options['templateDir'] = BASE . 'Toolkit/UserArea/views'; + $options['compileDir'] = BASE . 'Toolkit/UserArea/views/compiled'; + $options['flexyIgnore'] = true; + $tpl = new HTML_Template_Flexy($options); + $userId = filter_var($_REQUEST['userId'], FILTER_VALIDATE_INT); + $mapper = new Toolkit_UserArea_Models_Mapper(); + $userApps = array(); + $toolboxPages = array(); + if ($userId) { + $user + = $mapper->fetchUserById($this->registry->dbh, $userId); + $userAppsData + = $mapper->fetchAllUserApps($this->registry->dbh, $user); + if ($userAppsData) { + foreach ($userAppsData as $apps) { + $userApps[] = $apps->getAppId(); + if ($apps->getAppId() == self::TOOLBOX_APP_ID) { + $hasToolbox = true; + if ($appId = filter_var($apps->getConfig(), FILTER_VALIDATE_INT)) { + $toolboxPages[] = array( + 'id' => $apps->getConfig(), + 'name' => $this->_getPageName($appId) + ); + } + } else if ($apps->getAppId() == self::EVENT_APP_ID) { + $config = $apps->getConfig(); + if ($config) { + $userEventCategories = unserialize($config); + } + } + } + } + } + $tpl->compile('EditUserApps.html'); + $page = new stdClass(); + $page->stuff = null; + $page->apps = $mapper->fetchAllApps($this->registry->dbh); + $page->userApps = ($userApps) ? $userApps : null; + $page->pages = $toolboxPages; + $page->hasToolbox = self::HAS_TOOLBOX; + $page->hasEvents = self::HAS_EVENTS; + $page->categories = $this->_getEventCategories(); + $page->userEventCategories + = $userEventCategories; + $html + = $tpl->bufferedOutputObject($page); + echo $html; + exit; + } + + public function EditAction() + { + $editUser = new Toolkit_UserArea_Admin_EditUser( + $this->registry->dbh, + 'edit-user-form', + 'post' + ); + $editUser->configureForm(); + $html = $editUser->toHtml(); + $id = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + return $html; + } + + public function DeleteAction() + { + $userId = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT); + if ($userId) { + $dbh = Toolkit_Database::getInstance(); + $user = Toolkit_UserArea_Models_User::fetchUserById( + $dbh, + $userId + ); + $user->delete($dbh); + } + return $this->indexAction(); + } + +} diff --git a/Toolkit/UserArea/Admin/ListLogs.php b/Toolkit/UserArea/Admin/ListLogs.php new file mode 100644 index 0000000..5213ae1 --- /dev/null +++ b/Toolkit/UserArea/Admin/ListLogs.php @@ -0,0 +1,156 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_UserArea_Admin_ListLogs + * + * Create the list of logs for a user + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Admin_ListLogs + extends Toolkit_DataGridBuilder +{ + private $_userId; + /** + * How many records must exist in the Datagrid before the sort form shows up + * + * @var integer + * @access protected + */ + protected $sortableAfter = null; + + /** + * Message to display to users if no records were found + * + * @var String + * @access Protected + * @see Toolkit_DataGridBuilder::setNoRecordMessage() + */ + protected $noRecMessage = 'No Logs'; + + public function __construct( + PDO $pdo, + $limit = null, + $page = null, + $rendererType = null + ) { + parent::__construct($pdo, $limit, $page, $rendererType); + $this->options = array('dbc' => $pdo); + if (!is_null($limit)) { + $this->sortableAfter = $limit; + } + } + + protected function configureColumns() + { + $this->addColumn(new Structures_DataGrid_Column( + 'Alter Time', + 'alter_time', + null + )); + $this->addColumn(new Structures_DataGrid_Column( + 'Type', + 'alter_type', + null + )); + $this->addColumn(new Structures_DataGrid_Column( + 'Comment', + 'comment', + null + )); + } + + public function setUserId($id) + { + if ( !is_int($id) + && !ctype_digit($id) + && $id <= 0 + ) { + throw new InvalidArgumentException('Id must be an integer'); + } + $this->_userId = $id; + } + + public function setQuery() + { + + $sql = " + SELECT * + FROM auth.logs + WHERE user_id = {$this->_userId}"; + + parent::setQuery($sql); + } + + /** + * returns a HTML table of the datagrid + * + * @return string + * @access public + */ + public function toHTML() + { + $this->configureColumns(); + + try { + $bind = $this->bind($this->sql, $this->options, 'PDO'); + } catch (PDOException $e) { + return Toolkit_Common::handleError($e); + } + + if (PEAR::isError($bind)) { + return Toolkit_Common::handleError($bind); + } elseif (($recCount = $this->getRecordCount()) > 0) { + $this->setRendererOptions($this->rendererOptions); + $renderer =& $this->getRenderer(); + // Allows us to turn off the id name for the table, + // when we subclass this class out. + if ($this->tableId) { + $renderer->setTableAttribute('id', $this->tableId); + } + // Allows us to turn off the class name for the table, + // when we subclass this class out. + if ($this->tableClass) { + $renderer->setTableAttribute('class', $this->tableClass); + } + $gridBody = $this->getOutput(); + + if (PEAR::isError($gridBody)) { + return Toolkit_Common::handleError($gridBody); + } + + $gridPager = $this->getOutput( + DATAGRID_RENDER_PAGER, + array('pagerOptions' => $this->pagerOptions) + ); + if (PEAR::isError($gridPager)) { + return Toolkit_Common::handleError($gridPager); + } + + return $gridPager . $gridBody . $gridPager; + } else { + return "

{$this->noRecMessage}

"; + } + } +} + diff --git a/Toolkit/UserArea/Admin/ListUsers.php b/Toolkit/UserArea/Admin/ListUsers.php new file mode 100644 index 0000000..f5c281e --- /dev/null +++ b/Toolkit/UserArea/Admin/ListUsers.php @@ -0,0 +1,104 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_ListUsers + * + * List the User in the User Area + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Admin_ListUsers + extends Toolkit_DataGridBuilder +{ + + public function __construct( + PDO $pdo, + $limit = null, + $page = null, + $rendererType = null + ) { + parent::__construct($pdo, $limit, $page, $rendererType); + $this->options = array('dbc' => $pdo); + if (!is_null($limit)) { + $this->sortableAfter = $limit; + } + } + + protected function configureColumns() + { + $this->addColumn(new Structures_DataGrid_Column( + 'Edit', + null, + null, + array('class' => 'editLink'), + null, + array(&$this, 'renderEditLink') + )); + $this->addColumn(new Structures_DataGrid_Column( + 'Name', + 'name', + 'name' + )); + $this->addColumn(new Structures_DataGrid_Column( + 'Delete', + null, + null, + array('class' => 'editLink'), + null, + array(&$this, 'renderDeleteLink') + )); + } + + public function renderEditLink($data) + { + extract($data['record']); + $link = 'Edit'; + return sprintf($link, MEDIA_BASE_URL, $id); + } + + public function renderDeleteLink($data) + { + extract($data['record']); + $link = 'Delete'; + return sprintf( + $link, + MEDIA_BASE_URL . "admin/userArea.php?ac=Delete&id={$id}" + ); + } + + public function setQuery() + { + + $sql = " + SELECT * + FROM auth.users"; + + $params = array(); + if (isset($_GET['_qf__search_form']) && !empty($params)) { + $params = implode(' AND ', $params); + $sql = "{$sql} WHERE $params"; + } + + parent::setQuery($sql); + } +} diff --git a/Toolkit/UserArea/Admin/Log.php b/Toolkit/UserArea/Admin/Log.php new file mode 100644 index 0000000..84122e7 --- /dev/null +++ b/Toolkit/UserArea/Admin/Log.php @@ -0,0 +1,366 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_Log + * + * Object representation of the auth.logs table record + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Admin_Log +{ + private $_id; + private $_userId; + private $_alterTime; + private $_dbTable; + private $_alterType; + private $_foreignKey; + private $_comment; + + /** + * Creates an object of type Log + * + * @param array $values Log values + * + * @return Toolkit_UserArea_Admin_Log + */ + private function __construct(array $values) + { + extract($values); + $this->setUserId($user_id) + ->setAlterTime($alter_time) + ->setAlterType($alter_type) + ->setDbTable($db_table) + ->setForeignKey($foreign_key) + ->setComment($comment); + if ($id) { + $this->setId($id); + } + return $this; + } + + /** + * Static method for creating Log objects + * + * @param array $values Log values + * + * @return Toolkit_UserArea_Admin_Log + */ + public static function createLogWithValues(array $values) + { + return new Toolkit_UserArea_Admin_Log($values); + } + + /** + * Returns an array of logs for a user + * + * @param PDO $dbh Database Connection + * @param int $userId User's id + * + * @return array + */ + public static function fetchLogsByUserId(PDO $dbh, $userId) + { + $logs = array(); + try { + $sql = " + SELECT * + FROM logs + WHERE user_id = :user_id + ORDER BY alter_time DESC"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':user_id', $userId, PDO::PARAM_INT); + $stmt->execute(); + while ($values = $stmt->fetch(PDO::FETCH_ASSOC)) { + $logs[] = new Toolkit_UserArea_Admin_Log($values); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $logs; + } + + /** + * Return the Log id + * + * @return int + */ + public function getId() + { + return (int)$this->_id; + } + + /** + * Sets the Log id + * + * @param int $id Log id + * + * @return Toolkit_UserArea_Admin_Log + * @throws InvalidArgumentException + */ + public function setId($id) + { + if ( !is_int($id) + && !ctype_digit($id) + && $id <= 0 + ) { + throw new InvalidArgumentException('Id must be an integer'); + } + if (!$this->id) { + $this->_id = (int)$id; + } + return $this; + } + + /** + * Returns Log user_id + * + * @return int + */ + public function getUserId() + { + return $this->_userId; + } + + /** + * Sets the Log user_id + * + * @param int $userId Log user_id + * + * @return Toolkit_UserArea_Admin_Log + * @throws InvalidArgumentException + */ + public function setUserId($userId) + { + if ( !is_int($userId) + && !ctype_digit($userId) + && $userId <= 0 + ) { + throw new InvalidArgumentException('userId must be an integer'); + } + $this->_userId = (int)$userId; + return $this; + } + + /** + * Returns the Logs alter_time + * + * @return string + */ + public function getAlterTime() + { + return $this->_alterTime; + } + + /** + * Sets the Logs alter_time + * + * @param string $alterTime Logs alter_time + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setAlterTime($alterTime) + { + $this->_alterTime = $alterTime; + return $this; + } + + /** + * Returns the Logs db_table + * + * @return string + */ + public function getDbTable() + { + return $this->_dbTable; + } + + /** + * Sets the Logs db_table + * + * @param string $dbTable Logs db_table + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setDbTable($dbTable) + { + $this->_dbTable = $dbTable; + return $this; + } + + /** + * Returns Logs alter_type + * + * @return string + */ + public function getAlterType() + { + return $this->_alterType; + } + + /** + * Sets the Logs alter_type + * + * @param string $alterType Logs alter_type + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setAlterType($alterType) + { + $this->_alterType = $alterType; + return $this; + } + + /** + * Returns the Logs foreign_key + * + * @return int + */ + public function getForeignKey() + { + return (int)$this->_foreignKey; + } + + /** + * Sets the Logs foreign_key + * + * @param int $foreignKey Logs foreign_key + * + * @return Toolkit_UserArea_Admin_Log + * @throws InvalidArgumentException + */ + public function setForeignKey($foreignKey) + { + if (!is_int($foreignKey) && !ctype_digit($foreignKey)) { + throw new InvalidArgumentException('foreignKey must be an integer'); + } + $this->_foreignKey = (int)$foreignKey; + return $this; + } + + /** + * Returns the Logs comments + * + * @return string + */ + public function getComment() + { + return $this->_comment; + } + + /** + * Sets the Logs comment + * + * @param string $comment Comment for the log + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setComment($comment) + { + $this->_comment = $comment; + return $this; + } + + + /** + * if $this->_id is set then it will run update. + * if $this->_id is not set then it will run insert. + * + * @param PDO $dbh Database Connection + * + * @return Toolkit_UserArea_Admin_Log + */ + public function save(PDO $dbh) + { + if ($this->_id) { + $this->_update($dbh); + } else { + $this->_insert($dbh); + } + return $this; + } + + /** + * Insert the record into the database + * + * @param PDO $dbh Database connection + * + * @return void + */ + private function _insert(PDO $dbh) + { + try { + $sql = " + INSERT INTO + auth.logs + (user_id,alter_time,db_table,alter_type,foreign_key,comment) + VALUES + (:user_id,:alter_time,:db_table,:alter_type,:foreign_key,:comment) + RETURNING id"; + $insert = $dbh->prepare($sql); + $insert->bindParam(':user_id', $this->_userId, PDO::PARAM_INT); + $insert->bindParam(':foreign_key', $this->_foreignKey, PDO::PARAM_INT); + $insert->bindParam(':alter_time', $this->_alterTime); + $insert->bindParam(':db_table', $this->_dbTable); + $insert->bindParam(':alter_type', $this->_alterType); + $insert->bindParam(':comment', $this->_comment); + $insert->execute(); + $this->setId($insert->fetchColumn()); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Update the Log in the database + * + * @param PDO $dbh Database connection + * + * @return void + */ + private function _update(PDO $dbh) + { + try { + $sql = " + UPDATE log + SET user_id = :user_id, + alter_time = :alter_time, + db_table = :db_table, + alter_type = :alter_type, + foreign_key = :foreign_key, + comment = :comment + WHERE id = :id"; + $update = $dbh->prepare($sql); + $update->bindParam(':user_id', $this->_userId, PDO::PARAM_INT); + $update->bindParam(':foreign_key', $this->_foreignKey, PDO::PARAM_INT); + $update->bindParam(':id', $this->_id, PDO::PARAM_INT); + $update->bindParam(':alter_time', $this->_alterTime); + $update->bindParam(':db_table', $this->_dbTable); + $update->bindParam(':alter_type', $this->_alterType); + $update->bindParam(':comment', $this->_comment); + $update->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } +} diff --git a/Toolkit/UserArea/Admin/PageTree.php b/Toolkit/UserArea/Admin/PageTree.php new file mode 100644 index 0000000..9e88b3a --- /dev/null +++ b/Toolkit/UserArea/Admin/PageTree.php @@ -0,0 +1,150 @@ + + * @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_UserArea_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 { + if (defined('MEMBERS_CATEGORY') + && MEMBERS_CATEGORY + ) { + $sql = " + SELECT id,parent,navigation_name + FROM pages + WHERE id NOT IN (".MEMBERS_CATEGORY.") + AND parent NOT IN (".MEMBERS_CATEGORY.") + ORDER by parent, pos"; + } else { + $sql = " + SELECT id,parent,navigation_name + FROM pages + 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/UserArea/Auth.php b/Toolkit/UserArea/Auth.php new file mode 100644 index 0000000..ce21ae0 --- /dev/null +++ b/Toolkit/UserArea/Auth.php @@ -0,0 +1,225 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_UserArea_Auth + * + * Description of Auth + * + * @category Toolkit + * @package UserArea_Auth + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Auth + extends Auth +{ + + /** + * 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; + + /** + * 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( + Toolkit_UserArea_Auth_Container $storageDriver, + $loginFunction = '', + $showLogin = true + ) { + $loginFunction = array($this, 'loginForm'); + parent::Auth($storageDriver, '', $loginFunction, $showLogin); + $this->setSessionName('UserArea'); + } + + /** + * Function to set up the regular login form + * + * @param unknown $uname Last attempted username + * @param unknown $status The authorization status + * @param unknown &$auth The authentication object + * + * @return void + * @access public + */ + protected function loginForm($uname = null, $status = null, &$auth = null) + { + $login = new Toolkit_UserArea_Auth_LoginForm( + 'userarea_login', + 'post', + MEDIA_BASE_URL . 'userArea/login.php' + ); + + $login->setDbh(Toolkit_Database::getInstance()); + $login->configureForm(); + echo $login->toHtml(); + } + + /** + * Function to set up the forgot password form + * + * @return void + * @access public + */ + protected function passwordForm() + { + $pword = new Toolkit_UserArea_Auth_PasswordForm('userarea_password'); + $pword->setDbh(Toolkit_Database::getInstance()); + $pword->configureForm(); + echo $pword->toHtml(); + } + + /** + * 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); + } + + /** + * Returns the current page assigned to the User + * + * @param PDO $dbh Database Connection + * + * @return int + */ + public function getUserPageId(PDO $dbh) + { + if ($pageId = filter_var($_SESSION['pageId'], FILTER_VALIDATE_INT)) { + return $pageId; + } + + try { + $sql = " + SELECT page + FROM auth.users + WHERE id = :id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $this->getAuthData('id'), PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchColumn(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + public function getUserEventCategories(PDO $dbh) + { + try { + $sql = " + SELECT config + FROM auth.userapps + WHERE app_id = :app_id + AND user_id = :user_id"; + $stmt = $dbh->prepare($sql); + $stmt->bindValue( + ':app_id', + Toolkit_UserArea_Admin_IndexController::EVENT_APP_ID, + PDO::PARAM_INT + ); + $stmt->bindParam( + ':user_id', + $this->getAuthData('id'), + PDO::PARAM_INT + ); + $stmt->execute(); + $config = $stmt->fetchColumn(); + return ($config) ? unserialize($config) : array(); + } catch(PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Returns Active state of User + * + * @param PDO $dbh Database Connection + * + * @return bool + */ + public function isUserActive(PDO $dbh) + { + try { + $sql = " + SELECT active + FROM auth.users + WHERE id = :id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $this->getAuthData('id'), PDO::PARAM_INT); + $stmt->execute(); + return (bool)$stmt->fetchColumn(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Returns Active state of User + * + * @param PDO $dbh Database Connection + * + * @return bool + */ + public function hasToolbox(PDO $dbh) + { + try { + $sql = " + SELECT toolbox + FROM auth.users + WHERE id = :id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $this->getAuthData('id'), PDO::PARAM_INT); + $stmt->execute(); + return (bool)$stmt->fetchColumn(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + +} diff --git a/Toolkit/UserArea/Auth/Container.php b/Toolkit/UserArea/Auth/Container.php new file mode 100644 index 0000000..508af08 --- /dev/null +++ b/Toolkit/UserArea/Auth/Container.php @@ -0,0 +1,185 @@ + + * @copyright 2010 Jamie Kahgee + * @license http://www.gaslightmedia.com/ Gaslightmedia + * @version CVS: $Id: AuthContainer.php,v 1.3 2010/06/22 11:45:34 jamie Exp $ + * @link <> + * @see References to other sections (if any)... + */ + +/** + * Authentication container for UsarArea + * + * Custom container which allows us to utilize our PDO Singleton which + * takes advantage of schema based partitioning of our tables + * + * @category Toolkit + * @package UserArea_Auth + * @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_UserArea_Auth_Container + extends Auth_Container +{ + + /** + * Database handler + * @var PDO + * @access private + */ + private $_dbh; + + /** + * Addition options for the storage container + * @var array + * @access private + */ + private $_options = array(); + + /** + * Constructor + * + * @param PDO $dbh Database handler + * @param array $options Addition options for the storage container + * + * @return void + * @access public + */ + public function __construct(PDO $dbh, array $options = null) + { + $this->_dbh = $dbh; + $this->_setDefaults(); + if (is_array($options)) { + $this->_parseOptions($options); + } + } + + /** + * Set some default options + * + * @access private + * @return void + */ + private function _setDefaults() + { + $this->_options['table'] = 'auth.users'; + $this->_options['usernamecol'] = 'username'; + $this->_options['passwordcol'] = 'password'; + $this->_options['db_fields'] = array('id', 'name', 'active'); + $this->_options['cryptType'] = 'none'; + $this->_options['db_where'] = 'active'; + } + + /** + * Parse options passed to the container class + * + * @param array $array options for class + * + * @access private + * @return void + */ + private function _parseOptions(array $array) + { + foreach ($array as $key => $value) { + if (isset($this->_options[$key])) { + $this->_options[$key] = $value; + } + } + } + + /** + * 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"; + + + // check if there is an optional parameter db_where + if ($this->_options['db_where'] != '') { + // There is one, so add it to the query + $sql .= " AND {$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`" + ); + } + } + + /** + * 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/UserArea/Auth/LoginForm.php b/Toolkit/UserArea/Auth/LoginForm.php new file mode 100644 index 0000000..fe08c63 --- /dev/null +++ b/Toolkit/UserArea/Auth/LoginForm.php @@ -0,0 +1,213 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_UserArea_Auth_LoginForm + * + * Handles rendering and validating the UserArea login form + * + * @category Toolkit + * @package UserArea_Auth + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Auth_LoginForm + extends Toolkit_FormBuilder +{ + + /** + * Custom rules to check for when validating the form + * + * @var array + * @access protected + */ + protected $registeredRules = array(); + + /** + * Where to perform validation + * + * @var string + * @access protected + */ + protected $validationType = 'client'; + protected $tpl; + + /** + * Sets up the elements to be configured for use with the form + * + * @param Config_Container $c Configuration object + * + * @return void + * @access protected + */ + protected function configureElements() + { + $e = array(); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'username', + 'display' => 'Username' + ); + $e[] = array( + 'type' => 'password', + 'req' => true, + 'name' => 'password', + 'display' => 'Password' + ); + $e[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'doLogin', + 'display' => 'Login now', + 'opts' => array('id' => 'doLogin') + ); + + $this->setupElements($e); + } + + /** + * Sets up the filters to be used with the form when submitted + * + * @return void + * @access protected + */ + protected function configureFilters() + { + $f = array(); + + $f[] = array( + 'element' => '__ALL__', + 'filter' => 'trim' + ); + $this->setupFilters($f); + } + + /** + * Helper method to setup form + * + * @param Config_Container $c Configuration object + * + * @return void + * @access public + */ + public function configureForm() + { + $this->configureElements(); + $this->configureFilters(); + $this->configureRules(); + } + + /** + * Sets up required rules and extra defined rules for the form + * + * @return void + * @access protected + */ + protected function configureRules() + { + $this->setupRules($r); + } + + /** + * set the pdo to use for db calls + * + * @param PDO $pdo PHP Data Object to use + * + * @return void + * @access public + */ + public function setDbh(PDO $pdo) + { + $this->dbh = $pdo; + } + + /** + * Inject custom renderers into the forms elements for custom display + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + $options = $GLOBALS['flexyOptions']; + $options['templateDir'] = BASE . 'userArea/templates'; + $options['compiledDir'] = BASE . 'userArea/templates/compiled'; + $this->tpl = new HTML_Template_Flexy($options); + + $renderer = new HTML_QuickForm_Renderer_ObjectFlexy($this->tpl); + + $this->accept($renderer); + $this->view = new StdClass(); + $this->view->form = $renderer->toObject(); + $this->tpl->compile('loginPage.html'); + } + + /** + * Returns an HTML version of the form + * + * @return string HTML version of the form + * @access public + */ + public function toHtml() + { + $this->setupRenderers(); + if ($this->validate()) { + header('Location: ' .MEDIA_BASE_URL . 'userArea/index.php'); + } elseif ($this->isSubmitted()) { + $errors = $this->errorMsg; + $this->view->errors = $errors; + $output .= $this->tpl->bufferedOutputObject($this->view); + } else { + if ($_GET['status']) { + switch ($_GET['status']) { + case -1 : + $error = 'Your session has exceeded the maximum idle time'; + break; + + case -2 : + $error = 'Your session has expired.'; + break; + + case -3 : + $error = 'Invalid username or password.'; + break; + + case -4 : + // This is primarily used for Development. + // Users should never be presented with this error. + $error = 'Invalid Container'; + break; + + case -5 : + // This is only thrown if the advanced security system + // has detected a breach into the system. + $error = 'The system has encountered an error. Reference code: -5'; + break; + } + $errors = "
    $error
    "; + $this->view->errors = $errors; + } + $output .= $this->tpl->bufferedOutputObject($this->view); + } + + return $output; + } + +} diff --git a/Toolkit/UserArea/Auth/PasswordForm.php b/Toolkit/UserArea/Auth/PasswordForm.php new file mode 100644 index 0000000..d0c4ec3 --- /dev/null +++ b/Toolkit/UserArea/Auth/PasswordForm.php @@ -0,0 +1,335 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_UserArea_Auth_PasswordForm + * + * Handles rendering and validating the UserArea password form + * + * @category Toolkit + * @package UserArea_Auth + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Auth_PasswordForm +{ + + /** + * Table to query when gathering information + * + * @var string + * @access public + */ + public $tableName = 'member'; + + /** + * Custom defined rules to validate against when the form is submitted + * + * @var array + * @access protected + */ + protected $registeredRules = array(); + + /** + * Where to perform validation + * + * @var string + * @access protected + */ + protected $validationType = 'client'; + + /** + * Constructor + * + * @param string $formName Form's name + * @param string $method (optional)Form's method defaults to 'POST' + * @param string $action (optional)Form's action + * @param string $target (optional)Form's target + * @param mixed $attributes (optional)Extra attributes for the tag + * @param boolean $trackSubmit (optional)Whether to track if the form + * was submitted by adding a special hidden field + * + * @return void + * @access public + */ + public function __construct( + $formName, + $method = 'post', + $action = '', + $target = '', + $attributes = null, + $trackSubmit = false + ) { + parent::__construct( + $formName, + $method, + $action, + $target, + $attributes, + $trackSubmit + ); + + $this->template = dirname(__FILE__) . '/templates/currentTables/'; + } + + /** + * Checks to see if the email address exists before allowing an email to go out + * + * @param string $value submitted email address + * + * @return boolean If the email address exists or not + * @access public + */ + public function checkAddressExists($value) + { + try { + $sql = " + SELECT count(*) AS total + FROM {$this->tableName} + WHERE member_contact_email = :mce"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':mce', $value, PDO::PARAM_STR); + $stmt->execute(); + $stmt->bindColumn('total', $exists); + $stmt->fetch(); + + return (bool) $exists; + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Sets up the elements to be configured for use with the form + * + * @return void + * @access protected + */ + protected function configureElements() + { + $e = array(); + + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'formHdr', + 'display' => 'Email Reminder' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'email', + 'display' => 'Your Member Contact Email Address' + ); + $e[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'submit', + 'display' => 'Send' + ); + + $this->setupElements($e); + } + + /** + * Sets up the filters to be used with the form when submitted + * + * @return void + * @access protected + */ + protected function configureFilters() + { + $f = array(); + + $f[] = array( + 'element' => '__ALL__', + 'filter' => 'trim' + ); + $this->setupFilters($f); + } + + /** + * Helper method to setup form + * + * @return void + * @access public + */ + public function configureForm() + { + $this->configureElements(); + $this->configureFilters(); + $this->configureRules(); + } + + /** + * Sets up required rules and extra defined rules for the form + * + * @return void + * @access protected + */ + protected function configureRules() + { + $r = array(); + + $r[] = array( + 'element' => 'email', + 'message' => 'ERROR: Invalid Email Format!', + 'type' => 'email', + 'format' => null, + 'validation' => $this->validationType, + 'reset' => true, + 'force' => false + ); + $r[] = array( + 'element' => 'email', + 'message' => 'ERROR: Cannot locate email address!', + 'type' => 'callback', + 'format' => array(&$this, + 'checkAddressExists'), + 'validation' => $this->validationType, + 'reset' => true, + 'force' => false + ); + + $this->setupRules($r); + } + + /** + * set the pdo to use for db calls + * + * @param PDO $pdo PHP Data Object to use + * + * @return void + * @access public + */ + public function setDbh(PDO $pdo) + { + $this->dbh = $pdo; + } + + /** + * Inject custom renderers into the forms elements for custom display + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + parent::setupRenderers(); + + $renderer =& $this->defaultRenderer(); + $required = '*'; + $error = '
    {error}
    '; + + $renderer->setElementTemplate('{element}', 'submit'); + } + + /** + * Processes the data submitted by the form + * + * Gets the login credentials for the matching email address and mails + * them to that email address + * + * @param array $values submitted form values + * + * @return boolean Result of mail + * @access protected + */ + protected function processData($values) + { + try { + $sql = " + SELECT member_login, member_passwd + FROM {$this->tableName} + WHERE member_contact_email = :mce"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':mce', $values['email'], PDO::PARAM_STR); + $stmt->execute(); + $row = $stmt->fetch(); + } catch (PDOException $e) { + Toolkit_Common::handlError($e); + } + + $htmlMsg + = "Here is your " . SITENAME . " password:

    " . + "Login: {$row['member_login']}
    " . + "Email: {$values['email']}
    " . + "Password: {$row['member_passwd']}

    "; + + $msg + = "Here is your " . SITENAME . " password:\n\n" . + "Login: {$row['member_login']}\n" . + "Email: {$values['email']}\n" . + "Password: {$row['member_passwd']}"; + + $mimeMail = new Mail_mime("\n"); + $mimeMail->setHTMLBody($htmlMsg); + $mimeMail->setTXTBody($msg); + + $body = $mimeMail->get(); + $hdrs = $mimeMail->headers( + array( + 'From' => DO_NOT_REPLY_EMAIL, + 'Subject' => 'Your ' . htmlspecialchars_decode(SITENAME) . ' Password', + 'Reply-To' => SITENAME . '<' . MEMBER_FORGOT_PASSWORD_EMAIL_REPLY_TO . '>' + ) + ); + + $mail =& Mail::factory('mail'); + + $res = $mail->send($values['email'], $hdrs, $body); + + return PEAR::isError($res) ? + Toolkit_Common::handleError($res) : + $res; + } + + /** + * Returns an HTML version of the form + * + * @return string HTML version of the form + * @access public + */ + public function toHtml() + { + $this->setupRenderers(); + if ($this->validate()) { + if ($this->process(array(&$this, 'processData'))) { + $url = MEDIA_BASE_URL . 'userArea/index.php'; + $e =& $this->getElement('email'); + $email = $e->getValue(); + $output + = "

    Your Login Information has been sent to $email

    " . + "

    Continue to User Login

    "; + } else { + $output = '

    Email address not found.

    '; + } + } elseif ($this->isSubmitted()) { + $output = $this->errorMsg; + $output .= parent::toHtml(); + } else { + $output .= parent::toHtml(); + } + + return $output; + } + +} diff --git a/Toolkit/UserArea/BreadCrumbsAbstract.php b/Toolkit/UserArea/BreadCrumbsAbstract.php new file mode 100644 index 0000000..026670a --- /dev/null +++ b/Toolkit/UserArea/BreadCrumbsAbstract.php @@ -0,0 +1,143 @@ +dbh = $dbh; + + if (!ctype_digit((string)$id)) { + throw new InvalidArgumentException( + "\$id must be an integer `$id` given" + ); + } + + $this->id = $id; + } + + // }}} + // {{{ getPage() + + protected function getPage($id) + { + try { + $sql = " + SELECT * + FROM pages + WHERE id = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + + return $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Could not fetch parent for page `$id`" + ); + } + } + + // }}} + // {{{ __toString() + + public function __toString() + { + return ''; + } + + // }}} + // {{{ getId() + + /** + * @return the $id + */ + public function getId() + { + return $this->id; + } + + // }}} + // {{{ getPageUri() + + abstract protected function getPageUri(array $page); + + // }}} + public function getAuthData() + { + static $authData; + if ($authData) { + return $authData; + } + $authContainer = new Toolkit_UserArea_Auth_Container( + Toolkit_Database::getInstance() + ); + $userAuth = new Toolkit_UserArea_Auth( + $authContainer, + '', + false + ); + $userAuth->setIdle(); + $userAuth->start(); + $authData = $userAuth->getAuthData(); + return $authData; + } + // {{{ getPath() + + /** + * @return the $path + */ + public function getPath() + { + if ($this->id == HOME_ID) { + return; + } + $authData = $this->getAuthData(); + $id = $this->id; + $stack = array(); + do { + $page = $this->getPage($id); + $navigationName + = ($this->id == $id || $id == AUTH_USER_PAGE_ID) + ? $page['navigation_name'] + : $this->getPageUri($page); + + $stack[] = $navigationName; + + if (AUTH_USER_PAGE_ID && $id == AUTH_USER_PAGE_ID) { + $id = 0; + } else { + $id = $page['parent']; + } + } while ($id != 0); + + $reverse = array_reverse($stack); + $this->path = implode(' > ', $reverse); + + return $this->path; + } + + // }}} + // {{{ setId() + + /** + * @param $id the $id to set + */ + public function setId($id) + { + $this->id = $id; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/Database/application.sql b/Toolkit/UserArea/Database/application.sql new file mode 100644 index 0000000..1edc2f1 --- /dev/null +++ b/Toolkit/UserArea/Database/application.sql @@ -0,0 +1,13 @@ +-- +-- Set up schema +-- + +CREATE SCHEMA auth; +GRANT ALL ON SCHEMA auth TO nobody; + +\i ./tables/users.sql +-- \i ./tables/logs.sql +\i ./tables/apps.sql +\i ./tables/userapps.sql + +INSERT INTO auth.users (name,username,password) VALUES ('Steve Sutton', 'steve', 'admin'); \ No newline at end of file diff --git a/Toolkit/UserArea/Database/apps.sql b/Toolkit/UserArea/Database/apps.sql new file mode 100644 index 0000000..8f1ec39 --- /dev/null +++ b/Toolkit/UserArea/Database/apps.sql @@ -0,0 +1,33 @@ +-- +-- PostgreSQL database dump +-- + +SET statement_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = off; +SET check_function_bodies = false; +SET client_min_messages = warning; +SET escape_string_warning = off; + +SET search_path = auth, pg_catalog; + +-- +-- Name: apps_id_seq; Type: SEQUENCE SET; Schema: auth; Owner: postgres +-- + +SELECT pg_catalog.setval('apps_id_seq', 3, true); + + +-- +-- Data for Name: apps; Type: TABLE DATA; Schema: auth; Owner: postgres +-- + +INSERT INTO apps (id, name, page, config) VALUES (1, 'Toolbox', 'toolbox.php', true); +INSERT INTO apps (id, name, page, config) VALUES (2, 'Events', 'CommonEvents/', false); +INSERT INTO apps (id, name, page, config) VALUES (3, 'Photo Gallery', 'photos.php', false); + + +-- +-- PostgreSQL database dump complete +-- + diff --git a/Toolkit/UserArea/Database/removeApplication.sql b/Toolkit/UserArea/Database/removeApplication.sql new file mode 100644 index 0000000..d238733 --- /dev/null +++ b/Toolkit/UserArea/Database/removeApplication.sql @@ -0,0 +1,8 @@ +-- +-- This will drop everything in the toolbox schema. +-- Nothing better be in here except toolbox related objects +-- or it will be dropped +-- +-- The force is strong w/ this one, use it wisely. +-- +DROP SCHEMA IF EXISTS auth CASCADE; diff --git a/Toolkit/UserArea/Database/tables/apps.sql b/Toolkit/UserArea/Database/tables/apps.sql new file mode 100644 index 0000000..124ffc2 --- /dev/null +++ b/Toolkit/UserArea/Database/tables/apps.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS auth.apps CASCADE; + +CREATE TABLE auth.apps +( +id SERIAL, +name TEXT, +page TEXT, +config BOOLEAN DEFAULT false, +PRIMARY KEY (id) +); + +GRANT ALL ON auth.apps TO nobody; +GRANT ALL ON auth.apps_id_seq TO nobody; \ No newline at end of file diff --git a/Toolkit/UserArea/Database/tables/logs.sql b/Toolkit/UserArea/Database/tables/logs.sql new file mode 100644 index 0000000..2ce9096 --- /dev/null +++ b/Toolkit/UserArea/Database/tables/logs.sql @@ -0,0 +1,16 @@ +DROP TABLE IF EXISTS auth.logs CASCADE; + +CREATE TABLE auth.logs +( +id SERIAL, +user_id INT NOT NULL, +alter_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, +db_table TEXT NOT NULL, +alter_type TEXT, +foreign_key INTEGER, +comment TEXT, +PRIMARY KEY (id) +); + +GRANT ALL ON auth.logs TO nobody; +GRANT ALL ON auth.logs_id_seq TO nobody; \ No newline at end of file diff --git a/Toolkit/UserArea/Database/tables/userapps.sql b/Toolkit/UserArea/Database/tables/userapps.sql new file mode 100644 index 0000000..f5467db --- /dev/null +++ b/Toolkit/UserArea/Database/tables/userapps.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS auth.userapps CASCADE; + +CREATE TABLE auth.userapps +( +id SERIAL, +user_id INTEGER, +app_id INTEGER, +config TEXT, +PRIMARY KEY (id) +); + +GRANT ALL ON auth.userapps TO nobody; +GRANT ALL ON auth.userapps_id_seq TO nobody; \ No newline at end of file diff --git a/Toolkit/UserArea/Database/tables/users.sql b/Toolkit/UserArea/Database/tables/users.sql new file mode 100644 index 0000000..b0a75fa --- /dev/null +++ b/Toolkit/UserArea/Database/tables/users.sql @@ -0,0 +1,14 @@ +DROP TABLE IF EXISTS auth.users CASCADE; + +CREATE TABLE auth.users +( +id SERIAL, +active BOOLEAN DEFAULT TRUE, +name TEXT, +username TEXT, +password TEXT, +PRIMARY KEY (id) +); + +GRANT ALL ON auth.users TO nobody; +GRANT ALL ON auth.users_id_seq TO nobody; \ No newline at end of file diff --git a/Toolkit/UserArea/DraftPagesTree.php b/Toolkit/UserArea/DraftPagesTree.php new file mode 100644 index 0000000..46cb43f --- /dev/null +++ b/Toolkit/UserArea/DraftPagesTree.php @@ -0,0 +1,42 @@ +rootNodeStart : $this->subTreeStart; + + if (is_array($leaf) && !empty($leaf)) { + foreach ($tree as $parent => $children) { + foreach ($children as $branch) { + $html .= sprintf($this->leafStart, $branch['id'], null); + $previewUrl = BASE_URL . "index.php?rt=Draft&catid={$branch['id']}"; + + $html .= "{$branch['navigation_name']}"; + + $html .= '
    '; + + $html .= '[Edit] '; + $html .= '[Paragraphs] '; + $html .= '[Preview] '; + $html .= $this->getActiveBall($branch); + + $html .= '
    '; + + $html .= $this->leafEnd; + } + } + } + + $html .= $this->treeEnd; + if ($level) { + $html .= $this->leafEnd; + } + + return $html; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/EditDraftController.php b/Toolkit/UserArea/EditDraftController.php new file mode 100644 index 0000000..4b036a2 --- /dev/null +++ b/Toolkit/UserArea/EditDraftController.php @@ -0,0 +1,218 @@ +registry->dbh); + $gateway->delete($id); + } + + // }}} + + // {{{ indexAction() + + public function indexAction() + { + if (ctype_digit($_GET['id'])) { + $breadCrumbs = new Toolkit_UserArea_PageDraftBreadCrumbs( + $this->registry->dbh, + $_GET['id'] + ); + $html = (string) $breadCrumbs; + } + + $form = $this->getForm( + 'EditDraft', + new Toolkit_UserArea_PageGatewayDraftFactory($this->registry->dbh) + ); + $html .= $form->toHtml($this->registry->dbh); + + return $html; + } + + // }}} + + protected function preview($form) + { + die('preview'); + } + + // {{{ processAction() + + public function processAction() + { + return $this->processForm( + 'EditDraft', + new Toolkit_UserArea_PageGatewayDraftFactory($this->registry->dbh), + new Cache_Lite($GLOBALS['cacheOptions']) + ); + } + + // }}} + // {{{ publishPage() + + protected function publishPage(HTML_QuickForm $form, Cache_Lite $cache) + { + $pageGatewayDraft = new Toolkit_UserArea_PageGatewayDraft( + $this->registry->dbh + ); + $pageGatewayPublish = new Toolkit_UserArea_PageGatewayPublish( + $this->registry->dbh + ); + $paragraphGatewayDraft = new Toolkit_UserArea_ParagraphGatewayDraft( + $this->registry->dbh + ); + $paragraphGatewayPublish = new Toolkit_UserArea_ParagraphGatewayPublish( + $this->registry->dbh + ); + + if ($form->validate()) { + $draftPageId = $form->getSubmitValue('id'); + $existingDraft = $pageGatewayDraft->find($draftPageId); + if (is_null($existingDraft['published_page'])) { + $publishId = $pageGatewayPublish->insert( + $form->getSubmitValues() + ); + + $paragraphs = $paragraphGatewayDraft->findAll( + $form->getSubmitValue('id') + ); + + $this->_convertOldFilesToUploadedFiles( + $paragraphGatewayPublish, + $paragraphs, + $publishId + ); + } else { + $oldPageId = $existingDraft['published_page']; + // delete from staff + $deleteSql = " + DELETE + FROM staff.staff + WHERE page = :page"; + $delete = $this->registry->dbh->prepare($deleteSql); + $delete->bindParam(':page', $oldPageId, PDO::PARAM_INT); + $delete->execute(); + // delete from staff contacts + $deleteSql = " + DELETE + FROM staff.contacts + WHERE page = :page"; + $delete = $this->registry->dbh->prepare($deleteSql); + $delete->bindParam(':page', $oldPageId, PDO::PARAM_INT); + $delete->execute(); + + $pageGatewayPublish->update( + $form->getSubmitValues(), + $existingDraft['published_page'] + ); + + $existingParagraphs = $paragraphGatewayPublish->findAll( + $existingDraft['published_page'] + ); + + foreach ($existingParagraphs as $paragraph) { + $paragraphGatewayPublish->delete($paragraph['id']); + } + + $updatedParagraphs = $paragraphGatewayDraft->findAll( + $form->getSubmitValue('id') + ); + + $this->_convertOldFilesToUploadedFiles( + $paragraphGatewayPublish, + $updatedParagraphs, + $existingDraft['published_page'] + ); + } + + $pageGatewayDraft->delete($draftPageId); + $cache->clean('Nav'); + if ($existingDraft['published_page']) { + $cache->remove("page-{$existingDraft['published_page']}", 'Toolbox'); + $cache->remove("paragraphs-{$existingDraft['published_page']}", 'Toolbox'); + $cache->remove("sectionLinks-{$existingDraft['published_page']}", 'Toolbox'); + } + + header('Location: ' .MEDIA_BASE_URL . 'userArea/toolbox.php'); + exit(); + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml(); + + return $return; + } + } + + // }}} + + // {{{ _convertOldFilesToUploadedFiles() + + private function _convertOldFilesToUploadedFiles( + Toolkit_UserArea_ParagraphGatewayAbstract $paragraphGateway, + &$paragraphs, + $newPageId + ) { + if (is_array($paragraphs)) { + foreach ($paragraphs as &$paragraph) { + if (is_array($paragraph['files'])) { + $paragraph['uploaded_files'] = array( + 'urltext' => array(), + 'filename' => array(), + 'bytes' => array(), + 'type' => array() + ); + foreach ($paragraph['files'] as $file) { + $paragraph['uploaded_files']['urltext'][] = $file['urltext']; + $paragraph['uploaded_files']['filename'][] = $file['filename']; + $paragraph['uploaded_files']['bytes'][] = $file['bytes']; + $paragraph['uploaded_files']['type'][] = $file['type']; + } + } + $paragraph['page'] = $newPageId; + $paragraphGateway->insert($paragraph); + } + } + } + + // }}} + + // {{{ saveDraft() + + protected function saveDraft(HTML_QuickForm $form) + { + $gateway = new Toolkit_UserArea_PageGatewayDraft($this->registry->dbh); + if ($form->validate()) { + $pageId = $form->getSubmitValue('id'); + if ($pageId) { + $gateway->update($form->getSubmitValues(), $pageId); + } else { + $gateway->insert($form->getSubmitValues()); + } + header('Location: ' .MEDIA_BASE_URL . 'userArea/toolbox.php'); + exit(); + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml(); + + return $return; + } + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/EditPageController.php b/Toolkit/UserArea/EditPageController.php new file mode 100644 index 0000000..83ad7fb --- /dev/null +++ b/Toolkit/UserArea/EditPageController.php @@ -0,0 +1,265 @@ + + * @copyright 2010 Gaslight Media + * @license Gaslight Media + * @version CVS: $Id: EditContact.php,v 1.3 2010/05/13 20:18:38 matrix Exp $ + * @link http://pear.php.net/package/Contacts + * @see References to other sections (if any)... + */ + +/** + * Toolkit_UserArea_EditPageController + * + * Edit Process class to insert or update a user + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2010 Steve Sutton + * @license Gaslight Media + * @version Release: @package_version@ + * @link http://pear.php.net/package/Contacts + * @see References to other sections (if any)... + */ +class Toolkit_UserArea_EditPageController + extends Toolkit_UserArea_FormControllerAbstract +{ + // {{{ cancel() + + protected function cancel() + { + header('Location: ' .MEDIA_BASE_URL . 'userArea/toolbox.php'); + exit(); + } + + // }}} + + // {{{ delete () + + protected function delete($id) + { + // try to get AuthUser from registry + $authUser = Registry::get('Toolkit_UserArea_Auth'); + $userId = $authUser->getAuthData('id'); + $gateway = new Toolkit_UserArea_PageGatewayPublish($this->registry->dbh); + $page = $gateway->findNavItem($id); + + $logData = array( + 'user_id' => $userId, + 'alter_time' => date('m/d/Y H:i:s'), + 'db_table' => 'pages', + 'alter_type' => 'delete', + 'foreign_key' => $id, + 'comment' => $page['navigation_name'] + ); + + try { + $log = Toolkit_UserArea_Admin_Log::createLogWithValues($logData); + $log->save($this->registry->dbh); + } catch(InvalidArgumentException $e) { + echo $e->getTraceAsString(); + echo $e->getMessage(); + exit; + } + + $gateway = new Toolkit_UserArea_PageGatewayPublish($this->registry->dbh); + $gateway->delete($id); + } + + // }}} + + // {{{ indexAction() + + public function indexAction() + { + if ($pageId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) { + $breadCrumbs = new Toolkit_UserArea_PageBreadCrumbs( + $this->registry->dbh, + $pageId + ); + $html = (string) $breadCrumbs; + } + + $form = $this->getForm( + 'EditPage', + new Toolkit_UserArea_PageGatewayPublishFactory($this->registry->dbh) + ); + $html .= $form->toHtml($this->registry->dbh); + + return $html; + } + + // }}} + + // {{{ processAction() + + public function processAction() + { + return $this->processForm( + 'EditPage', + new Toolkit_UserArea_PageGatewayPublishFactory($this->registry->dbh), + new Cache_Lite($GLOBALS['cacheOptions']) + ); + } + + // }}} + // {{{ publishPage() + + protected function publishPage(HTML_QuickForm $form, Cache_Lite $cache) + { + // try to get AuthUser from registry + $authUser = Registry::get('Toolkit_UserArea_Auth'); + $userId = $authUser->getAuthData('id'); + $gateway = new Toolkit_UserArea_PageGatewayPublish($this->registry->dbh); + if ($form->validate()) { + + $pageId = $form->getSubmitValue('id'); + if ($pageId) { + $gateway->update($form->getSubmitValues(), $pageId); + + $logData = array( + 'user_id' => $userId, + 'alter_time' => date('m/d/Y H:i:s'), + 'db_table' => 'pages', + 'alter_type' => 'update', + 'foreign_key' => $pageId, + 'comment' => $form->getSubmitValue('navigation_name') + ); + } else { + $pageId = $gateway->insert($form->getSubmitValues()); + $logData = array( + 'user_id' => $userId, + 'alter_time' => date('m/d/Y H:i:s'), + 'db_table' => 'pages', + 'alter_type' => 'insert', + 'foreign_key' => $pageId, + 'comment' => $form->getSubmitValue('navigation_name') + ); + } + + try { + $log = Toolkit_UserArea_Admin_Log::createLogWithValues($logData); + $log->save($this->registry->dbh); + } catch(InvalidArgumentException $e) { + echo $e->getTraceAsString(); + echo $e->getMessage(); + exit; + } + $cache->clean('Nav'); + $cache->remove("page-$pageId", 'Toolbox'); + $cache->remove("paragraphs-$pageId", 'Toolbox'); + $cache->remove("sectionLinks-$pageId", 'Toolbox'); + + header('Location: ' .MEDIA_BASE_URL . 'userArea/toolbox.php'); + exit(); + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml(); + + return $return; + } + } + + // }}} + + // {{{ saveDraft() + + protected function saveDraft(HTML_QuickForm $form) + { + $pageGatewayDraft = new Toolkit_UserArea_PageGatewayDraft( + $this->registry->dbh + ); + $paragraphGatewayPublish = new Toolkit_UserArea_ParagraphGatewayPublish( + $this->registry->dbh + ); + $paragraphGatewayDraft = new Toolkit_UserArea_ParagraphGatewayDraft( + $this->registry->dbh + ); + + if ($form->validate()) { + $draftId = $pageGatewayDraft->insert($form->getSubmitValues()); + + // drafting an already published page, + // need to bring over the paragraphs + if (ctype_digit($form->getSubmitValue('id'))) { + $paragraphs = $paragraphGatewayPublish->findAll( + $form->getSubmitValue('id') + ); + + if (is_array($paragraphs)) { + foreach ($paragraphs as &$paragraph) { + if (is_array($paragraph['files'])) { + $paragraph['uploaded_files'] = array( + 'urltext' => array(), + 'filename' => array(), + 'bytes' => array(), + 'type' => array() + ); + foreach ($paragraph['files'] as $file) { + $paragraph['uploaded_files']['urltext'][] = $file['urltext']; + $paragraph['uploaded_files']['filename'][] = $file['filename']; + $paragraph['uploaded_files']['bytes'][] = $file['bytes']; + $paragraph['uploaded_files']['type'][] = $file['type']; + } + } + $paragraph['page'] = $draftId; + $paragraphGatewayDraft->insert($paragraph); + } + } + // Need to copy over the Staff + try { + $staffSql = " + SELECT * + FROM staff.staff + WHERE page = :page"; + $staffStmt = $this->registry->dbh->prepare($staffSql); + $staffStmt->bindParam(':page', $oldPageId, PDO::PARAM_INT); + $staffStmt->execute(); + $staffData = $staffStmt->fetch(PDO::FETCH_ASSOC); + unset($staffData['id']); + $staffData['page'] = $draftId; + $staffModel = new Toolkit_Staff_Models_Staff(); + $staff = $staffModel->createByValues($staffData); + $staff->save($this->registry->dbh); + $contactSql = " + SELECT * + FROM staff.contacts + WHERE page = :page"; + $contactStmt = $this->registry->dbh->prepare($contactSql); + $contactStmt->bindParam(':page', $oldPageId, PDO::PARAM_INT); + $contactStmt->execute(); + $pos = 1; + while ($row = $contactStmt->fetch(PDO::FETCH_ASSOC)) { + unset($row['id']); + $row['page'] = $draftId; + $row['pos'] = $pos; + $contactModel = new Toolkit_Staff_Models_Contact(); + $contact = $contactModel->createByValues($row); + $contact->save($this->registry->dbh); + ++$pos; + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + header('Location: ' .MEDIA_BASE_URL . 'userArea/toolbox.php?rt=ListDrafts'); + exit(); + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml(); + + return $return; + } + } + + // }}} +} diff --git a/Toolkit/UserArea/Exception.php b/Toolkit/UserArea/Exception.php new file mode 100644 index 0000000..dc96907 --- /dev/null +++ b/Toolkit/UserArea/Exception.php @@ -0,0 +1,3 @@ + diff --git a/Toolkit/UserArea/FileExtension.php b/Toolkit/UserArea/FileExtension.php new file mode 100644 index 0000000..9862c4d --- /dev/null +++ b/Toolkit/UserArea/FileExtension.php @@ -0,0 +1,133 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @link <> + */ + +/** + * Toolkit_UserArea_FileExtension + * + * Description for Toolkit_UserArea_FileExtension + * + * @category Toolkit + * @package Toolbox + * @author Jamie Kahgee + * @license http://www.gaslightmedia.com Gaslightmedia + * @link <> + */ +class Toolkit_UserArea_FileExtension +{ + // {{{ getImage() + + /** + * Description for getImage() + * + * @param string $filename File name + * + * @return string + * @access public + */ + public function getImage($filename) + { + switch (pathinfo($filename, PATHINFO_EXTENSION)) { + case 'avi' : + $img = 'avi.gif'; + break; + + case 'mp3' : + $img = 'mp3.gif'; + break; + + case 'pdf' : + $img = 'pdf.png'; + break; + + case 'xls' : + case 'xlsx' : + $img = 'xls.gif'; + break; + + case 'ppt' : + $img = 'ppt.gif'; + break; + + case 'mov' : + $img = 'mov.gif'; + break; + + case 'cad' : + $img = 'cad.gif'; + break; + + case 'html' : + $img = 'html.gif'; + break; + + case 'doc' : + case 'docx' : + case 'msword' : + $img = 'doc.gif'; + break; + + case 'txt' : + $img = 'txt.png'; + break; + + case 'zip' : + $img = 'zip.png'; + break; + + case 'rar' : + $img = 'rar.gif'; + break; + + case 'png' : // image does not exist yet. + case 'jpeg' : + case 'jpg' : + $img = 'jpg.gif'; + break; + + case 'gif' : + $img = 'gif.gif'; + break; + + case 'wmv' : + $img = 'wmv.gif'; + break; + + default : + $img = 'download.gif'; + break; + } + + return $img; + } + + // }}} + // {{{ getClassForType() + + /** + * Description for getClassForType() + * + * @param string $filename File name + * + * @return string + * @access public + */ + public function getClassForType($filename) + { + $image = $this->getImage($filename); + $pieces = explode('.', $image); + reset($pieces); + return current($pieces); + } + + // }}} +} diff --git a/Toolkit/UserArea/FormControllerAbstract.php b/Toolkit/UserArea/FormControllerAbstract.php new file mode 100644 index 0000000..c345a4d --- /dev/null +++ b/Toolkit/UserArea/FormControllerAbstract.php @@ -0,0 +1,118 @@ +parseConfig( + BASE . 'Toolkit/Members/config.ini', + 'IniFile' + ); + } + + if (defined('COUPONS') && COUPONS) { + $cpnConf = new Config; + $cpnRoot =& $cpnConf->parseConfig( + BASE . 'Toolkit/Coupons/config.ini', + 'IniFile' + ); + } + $tlbConf = new Config; + $tbxRoot =& $tlbConf->parseConfig( + BASE . 'Toolkit/UserArea/config.ini', + 'IniFile' + ); + + $form = new Toolkit_UserArea_Forms_EditPage( + 'edit_page', + 'post', + MEDIA_BASE_URL . "userArea/toolbox.php?rt=$controller&ac=process" + ); + + $form->configureForm( + $this->registry->dbh, + $factory, + new Toolkit_FileServer_ImageAdapter(), + $memRoot, + $cpnRoot + ); + + return $form; + } + + // }}} + + // {{{ savePage() + + protected function savePage( + Toolkit_UserArea_PageGatewayAbstract $gateway, + HTML_QuickForm $form + ) { + if ($form->validate()) { + $pageId = $form->getSubmitValue('id'); + if ($pageId) { + $gateway->update($form->getSubmitValues(), $pageId); + } else { + $gateway->insert($form->getSubmitValues()); + } + header('Location: ' .MEDIA_BASE_URL . 'userArea/toolbox.php'); + exit(); + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml(); + + return $return; + } + } + + // }}} + + // {{{ processForm() + + protected function processForm( + $controller, + Toolkit_UserArea_GatewayFactoryAbstract $factory, + Cache_Lite $cache + ) { + $form = $this->getForm($controller, $factory); + + if ($form->isSubmitted()) { + if ($form->getSubmitValue('cancel')) { + // do nothing + $this->cancel(); + } elseif ($form->getSubmitValue('previewPage')) { + $this->preview(); + } elseif ($form->getSubmitValue('saveDraft')) { + // save draft + $return = $this->saveDraft($form); + } elseif ($form->getSubmitValue('publishPage')) { + // publish page + $return = $this->publishPage($form, $cache); + } elseif ($form->getSubmitValue('deletePage')) { + // delete page + $this->delete($form->getSubmitValue('id')); + $navTitle = $form->getSubmitValue('navigation_name'); + $return = "[$navTitle] successfully deleted."; + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml(); + } + } else { + $return = $form->toHtml(); + } + + return $return; + } + + // }}} +} diff --git a/Toolkit/UserArea/Forms/EditPage.php b/Toolkit/UserArea/Forms/EditPage.php new file mode 100644 index 0000000..6540dd2 --- /dev/null +++ b/Toolkit/UserArea/Forms/EditPage.php @@ -0,0 +1,1208 @@ + + * @release CVS: $Id: EditPage.php,v 1.10 2010/08/15 19:29:57 jamie Exp $: + * @license http://www.gaslightmedia.com Gaslightmedia + * @link http://demo.gaslightmedia.com + */ + +require_once BASE . 'Toolkit/Forms/Rules/Image.php'; +require_once BASE . 'Toolkit/Forms/Rules/ShortUrl.php'; + +/** + * Edit Toolbox page + * + * Handles form to insert/edit a toolbox page + * + * @category Toolbox + * @package Toolkit_UserArea + * @author Jamie Kahgee + * @copyright 2009 Jamie Kahgee + * @license http://www.gaslightmedia.com Gaslightmedia + * @link http://demo.gaslightmedia.com + */ +class Toolkit_UserArea_Forms_EditPage + extends Toolkit_FormBuilder +{ + // {{{ properties + + /** + * How many levels deep do you want to show in the parent select list + * + * 0 = Show All Levels + * + * @var integer + * @access protected + */ + protected $maxDepth = 0; + + /** + * Don't need to register any rules for this form. + * @var array + * @access protected + */ + protected $registeredRules = array(); + + // }}} + + // {{{ configureConstants() + + /** + * Configure form constants + * + * @param PDO $dbh Database handler + * + * @return void + * @access public + */ + public function configureConstants(PDO $dbh) + { + $c = array( + 'id' => $_GET['id'] + ); + + $this->setupConstants($c); + } + + // }}} + // {{{ configureDefaults() + + /** + * Initializes default form values + * + * @param Toolkit_UserArea_GatewayFactoryAbstract $factory Gateway factory + * @param integer $id page id (optional) + * + * @return void + * @access public + */ + public function configureDefaults( + Toolkit_UserArea_GatewayFactoryAbstract $factory, + $id = null + ) { + if (!is_null($id)) { + $gateway = $factory->createGateway(); + $page = $gateway->find($id); + } else { + $page = array( + 'template' => 1, + 'current_image_thumb' => 'Image not yet uploaded', + 'search_form' => 1 + ); + } + $this->setupDefaults($page); + } + + // }}} + // {{{ configureElements() + + /** + * Form element definitions + * + * @param PDO $dbh Database handler + * @param Config_Container $memRoot Configuration object + * @param Config_Container $cpnRoot Configuration object + * + * @return void + * @access public + */ + public function configureElements( + PDO $dbh, + Config_Container $memRoot = null, + Config_Container $cpnRoot = null, + $id = null + ) { + $e = array(); + + if (!is_null($memRoot)) { + $pluralMem = $memRoot->getItem('section', 'listing type') + ->getItem('directive', 'plural') + ->getContent(); + $singularMem = $memRoot->getItem('section', 'listing type') + ->getItem('directive', 'singular') + ->getContent(); + $hasRegions = $memRoot->getItem('section', 'conf') + ->getItem('directive', 'regions') + ->getContent(); + } + + if (!is_null($cpnRoot)) { + $pluralCpn = $cpnRoot->getItem('section', 'listing type') + ->getItem('directive', 'plural') + ->getContent(); + $singularCpn = $cpnRoot->getItem('section', 'listing type') + ->getItem('directive', 'singular') + ->getContent(); + } + + $hideDelete = (!is_null($id) && $id == HOME_ID); + $dir = dir(BASE . 'static'); + $staticPages = array(); + while (false !== ($page = $dir->read())) { + $pieces = explode('.', $page); + if ($pageId = filter_var($pieces[0], FILTER_VALIDATE_INT)) { + $staticPages[] = $pageId; + } + } + $hideDelete = ($hideDelete || in_array($id, $staticPages) || is_null($id)); + + $showParentPage = ($id != HOME_ID); + $auth = Registry::get('Toolkit_UserArea_Auth'); + $authData = $auth->getAuthData(); + if (AUTH_USER_PAGE_ID == $id) { + $showParentPage = false; + $hideDelete = true; + } + + // Grouped Elements are defined here. + $submitBtns = array(); + + $submitBtns[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'publishPage', + 'display' => 'Publish Page' + ); + $submitBtns[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'saveDraft', + 'display' => 'Save as draft' + ); + $submitBtns[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'cancel', + 'display' => 'Cancel' + ); + if (!$hideDelete) { + $submitBtns[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'deletePage', + 'display' => 'Delete Page' + ); + } + + $templates = array(); + + $options = range(1, 6); + foreach ($options as $i) { + $img = 'page template '.$i.''; + + $templates[] = array( + 'type' => 'radio', + 'req' => false, + 'name' => 'template', + 'att' => $i, + 'opts' => "Template $i
    $img", + ); + } + + // All Elements are created here. + // This includes group element definitions. + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'pageContentHdr', + 'display' => 'Page Content' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'id' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'published_page' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'navigation_name', + 'display' => 'Navigation Name', + 'opts' => array('size' => 35) + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'title', + 'display' => 'Page Title', + 'opts' => array('size' => 35) + ); + if ($_GET['rt'] == 'EditPage' && $showParentPage) { + $e[] = array( + 'type' => 'select', + 'req' => false, + 'name' => 'parent', + 'display' => 'Parent Page', + 'opts' => array(), + ); + } else { + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'parent' + ); + } + $e[] = array( + 'type' => 'textarea', + 'req' => false, + 'name' => 'description', + 'opts' => array( + 'cols' => 60, + 'rows' => 60, + 'id' => 'description' + ), + 'noCharLimit' => true + ); + $e[] = array( + 'type' => 'file', + 'req' => false, + 'name' => 'file', + 'display' => 'New Image' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'caption', + 'display' => 'Image Caption', + 'opts' => array('size' => 35) + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'current_image_thumb', + 'display' => 'Current Image' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'image', + ); + if (!empty($this->_defaultValues['image']) + || ($this->isSubmitted() && $this->getSubmitValue('remove_image')) + ) { + $e[] = array( + 'type' => 'checkbox', + 'req' => false, + 'name' => 'remove_image', + 'display' => 'Remove Current Image' + ); + } + + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'pageAttributesHdr', + 'display' => 'Page Attributes' + ); + if (defined('SHORT_URLS') && SHORT_URLS) { + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'short_url_instructions', + 'display' => '', + 'opts' => "Short URL's Must not contain any spaces or non alpha characters.
    Only A-Z, a-z, 0-9, _(underscore), -(dash) allowed" + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'short_url', + 'display' => 'Short URL', + ); + } + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'keyword', + 'display' => 'Keyword', + 'opts' => array('size' => 35) + ); + $e[] = array( + 'type' => 'advcheckbox', + 'req' => false, + 'name' => 'paragraph_links', + 'display' => 'Paragraph Links', + 'opts' => 'Show links to the paragraph headlines at the top of the page', + 'val' => array(0, 1) + ); + + if (!is_null($memRoot)) { + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'memberDbHdr', + 'display' => $pluralMem, + ); + $e[] = array( + 'type' => 'advcheckbox', + 'req' => false, + 'name' => 'include_members', + 'display' => "Members", + 'opts' => "Include Members On Page", + 'val' => array(0, 1) + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => ' + + + To include all members, turn this feature on and + don\'t select categories or regions below.
    + To restrict to specific categories, select desired + categories under Category Filter.
    + To restrict to specific regions, select desired + regions under Region Filter. + + ' + ); + // Note that we call to populate this select list at the + // bottom of this function after the element is made + // so we load attributes (classes) into each option as needed. + $e[] = array( + 'type' => 'select', + 'req' => false, + 'name' => 'member_categories', + 'display' => 'Category Filter
    (none = all)', + 'opts' => array(), + 'att' => array( + 'multiple' => 'multiple', + 'size' => 7, + 'title' => '-- Select to Add --', + 'id' => 'MemberCategories' + ) + ); + if ($hasRegions) { + $e[] = array( + 'type' => 'select', + 'req' => false, + 'name' => 'member_regions', + 'display' => 'Region Filter
    (none = all)', + 'opts' => array(), + 'att' => array( + 'multiple' => 'multiple', + 'size' => 7, + 'title' => '-- Select to Add --', + 'id' => 'MemberRegions' + ) + ); + } + $e[] = array( + 'type' => 'advcheckbox', + 'req' => false, + 'name' => 'include_member_map', + 'display' => "Google Map", + 'opts' => "Include Map On Page", + 'val' => array(0, 1) + ); + $e[] = array( + 'type' => 'advcheckbox', + 'req' => false, + 'name' => 'search_form', + 'display' => "Search Box", + 'opts' => 'Include Search Box', + 'val' => array(0, 1) + ); + } + + if (!is_null($cpnRoot)) { + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'couponsHdr', + 'display' => $pluralCpn + ); + $e[] = array( + 'type' => 'advcheckbox', + 'req' => false, + 'name' => 'include_coupons', + 'display' => "Coupons", + 'opts' => "Include Coupons On Page", + 'val' => array(0, 1) + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => ' + + + To include all coupons, turn this feature on and + don\'t select categories below.
    + To restrict to specific categories, select desired + categories under Categories Filter. + + ' + ); + // Note that we call to populate this select list at the + // bottom of this function after the element is made + // so we load attributes (classes) into each option as needed. + $e[] = array( + 'type' => 'select', + 'req' => false, + 'name' => 'coupon_categories', + 'display' => 'Category Filter
    (none = all)', + 'opts' => $this->_getCouponCategories($dbh), + 'att' => array( + 'multiple' => 'multiple', + 'size' => 4, + 'title' => '-- Select to Add --', + 'id' => 'CouponCategories' + ) + ); + } + + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'staffHdr', + 'display' => 'Staff' + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'staff_pick', + 'display' => '
    Here is staff stuff
    ' + ); + + if (defined('HOME_HEADLINES') && HOME_HEADLINES) { + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'headline', + 'display' => 'Headline', + 'opts' => 'Include this page in the Home Page Headlines', + 'val' => array(0, 1) + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'headline_intro', + 'display' => 'Intro', + 'opts' => array('size' => 55), + 'noCharLimit' => true + ); + } + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + if ($_SERVER['PHP_AUTH_USER'] == 'MediaAdmin' || DEVELOPMENT) { + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'metaHdr', + 'display' => 'Metadata Information' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'meta_title', + 'display' => 'Title Tag', + 'opts' => array('size' => 35) + ); + $e[] = array( + 'type' => 'textarea', + 'req' => false, + 'name' => 'meta_description', + 'display' => 'Description', + 'opts' => array( + 'cols' => 40, + 'rows' => 5 + ), + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + } else { + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'meta_title' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'meta_description' + ); + } + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'templatesHdr', + 'display' => 'Page Layout' + ); + $e[] = array( + 'type' => 'group', + 'req' => false, + 'name' => 'page_layout', + 'group' => $templates, + 'seperator' => '', + 'appendName' => false + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + if (isset($_GET['id']) && ctype_digit($_GET['id'])) { + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'templatesHdr', + 'display' => 'Page Information' + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'page_id', + 'display' => 'Page ID', + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'active_alt', + 'display' => 'State', + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'revised', + 'display' => 'Revised', + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'created', + 'display' => 'Created Date', + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'last_modified', + 'display' => 'Last Modified Date', + ); + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + } + $e[] = array( + 'type' => 'html', + 'req' => false, + 'name' => '', + ); + + // If we are editing a page, show three submit buttons + // otherwise, just show one insert button. + $e[] = array( + 'type' => 'group', + 'req' => false, + 'name' => 'submit_buttons', + 'group' => $submitBtns, + 'label' => '', + 'seperator' => '', + 'appendName' => false, + ); + + $this->setupElements($e); + + // Do the same for the pages + if ($_GET['rt'] == 'EditPage' && $showParentPage) { + $this->loadParentPages($dbh); + } + + // Load the member categories after the elements have been created + // so we can get more control how the options are rendered + // ie (adding classes to them) + if (defined('MEMBERS_DB') && MEMBERS_DB) { + $this->loadMemberCategories($dbh); + if ($hasRegions) { + $this->loadMemberRegions($dbh); + } + } + } + + // }}} + // {{{ 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() + + /** + * Bundle all form configuration calls into one function call + * + * @param PDO $dbh Database handler + * @param Toolkit_UserArea_GatewayFactoryAbstract $factory Gateway factory + * @param Toolkit_FileServer_ImageApater $is Image Server + * @param Config_Container $memRoot (optional) Configuration object + * @param Config_Container $cpnRoot (optional) Configuration object + * + * @return void + * @access public + */ + public function configureForm( + PDO $dbh, + Toolkit_UserArea_GatewayFactoryAbstract $factory, + Toolkit_FileServer_ImageAdapter $is, + Config_Container $memRoot = null, + Config_Container $cpnRoot = null + ) { + $this->configureDefaults($factory, $_GET['id']); + $this->configureElements($dbh, $memRoot, $cpnRoot, $_GET['id']); + $this->configureRules($is); + $this->configureFilters(); + $this->configureConstants($dbh); + } + + // }}} + // {{{ configureRules() + + /** + * Form rule definitions + * + * Adds validation rules for the given fields + * + * @param Toolkit_FileServer_ImageAdapter $is Image Server + * + * @return void + * @access public + */ + public function configureRules(Toolkit_FileServer_ImageAdapter $is) + { + $r = array(); + + // Form Rules + $r[] = array( + 'element' => 'short_url', + 'message' => 'ERROR: Short URLs may only contain alpha numeric characters plus - (dash) or _ (underscore)!', + 'type' => 'ShortUrl', + 'format' => null, + 'validation' => $this->validationType, + 'reset' => false, + 'force' => false + ); + if (!empty($_FILES['file']['tmp_name'])) { + $r[] = array( + 'element' => 'file', + 'message' => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!', + 'type' => 'mimetype', + 'format' => $is->getAllowedMimeTypes(), + 'validation' => 'server', + 'reset' => false, + 'force' => false + ); + } + $r[] = array( + 'element' => 'file', + 'message' => 'ERROR: Error uploading image!', + 'type' => 'Image', + 'format' => array( + 'form' => $this, + 'fieldName' => 'file', + 'imageField' => 'image', + 'is' => $is, + 'deleteExistingImage' => false, + 'injectImage' => array('tgtElement' => 'current_image_thumb') + ), + 'validation' => 'server', + 'reset' => false, + 'force' => false + ); + + $this->setupRules($r); + } + + // }}} + + // {{{ getCouponCategories() + + /** + * Fetches all coupon categories + * + * @param PDO $dbh Database handler + * + * @return array coupon categories + */ + private function _getCouponCategories(PDO $dbh) + { + $sql = " + SELECT * + FROM coupon_category + ORDER BY name"; + $couponCats = array(); + foreach ($dbh->query($sql) as $row) { + $couponCats[$row['id']] = $row['name']; + } + return $couponCats; + } + + // }}} + + // {{{ loadParentPages() + + /** + * Load option elements into the parent select list + * + * These options are loaded via this seperate function vs inline w/ the + * element definition b/c we need a little more control defining + * the class names for each option so they will render nice when a user + * is looking at the list. + * + * @param PDO $dbh Database handler + * + * @return void + * @throws PDOException throws exception on sql error + * @access public + */ + public function loadParentPages(PDO $dbh) + { + try { + $authContainer = new Toolkit_UserArea_Auth_Container( + Toolkit_Database::getInstance() + ); + + $userAuth = new Toolkit_UserArea_Auth( + $authContainer, + '', + false + ); + $userAuth->setIdle(); + $userAuth->start(); + $authData = $userAuth->getAuthData(); + $page = $userAuth->getUserPageId($this->dbh); + // Get a tree list of categories in linear order with + // category keys in the values and their level in the tree + // in the value + $c = Toolkit_Common::getHierarchicalTreeStructure( + $dbh, + 'pages', + 'id', + 'parent', + 'pos', + $page, + $this->maxDepth + ); + + // unset the home page, this is never an option to have children + // underneath it. + unset($c[HOME_ID]); + + // If we are editing a page, then we don't want that page + // to show up as an option in the select list. + if (is_numeric($_GET['id'])) { + reset($c); + // Get us to the point in the array were this page is located + while (key($c) != $_GET['id'] && current($c) !== false) { + next($c); + } + // Make sure we didn't traverse off the end of the array + if (current($c) !== false) { + // get the starting level we are currently at + $sl = current($c); + // remove this page (the one we're editing) from the + // array and advance the internal array pointer + unset($c[key($c)]); + // now we need to make sure all sub pages beneath this + // page are also not being shown + + // while we don't traverse off the end of the array + while (current($c) !== false) { + // get the current sub level we are at + $csl = current($c); + // if the current sub-level is the same as the + // starting level, that means we have traversed through + // all the sub-pages and can break out of the loop + if ($csl <= $sl) { + break; + } else { + // we are still in a sub-level page, so unset + // this page so it doesn't show, and advance + // the internal array pointer + unset($c[key($c)]); + } + } + } + } + + // Get all the data about each category + $sql = " + SELECT id,navigation_name,parent + FROM pages + WHERE id = ?"; + + $stmt = $dbh->prepare($sql); + // Get the member categories select list element + $e =& $this->getElement('parent'); + // need to add the main page level to the array for parent pages + $stmt->execute(array($page)); + $mainPage = $stmt->fetch(); + if ($mainPage['parent'] == 0 && $_REQUEST['id'] == $mainPage['id']) { + $e->addOption( + '-- No Parent --', + 0, + array('class' => 'level-0') + ); + return false; + } + if ($_REQUEST['id'] != $mainPage['id']) { + $e->addOption( + $mainPage['navigation_name'], + $mainPage['id'], + array('class' => 'level-0') + ); + } + foreach ($c as $i => $j) { + $stmt->execute(array($i)); + $row = $stmt->fetch(); + // the class level is always 1 less than what is reported + // from our $c array + $x = $j; + // Add the option data to the select list. + $e->addOption( + $row['navigation_name'], + $i, + array('class' => "level-$x") + ); + } + } catch (PDOException $e) { + Toolkit_Logger::logException('DB error', $e); + throw new Toolkit_UserArea_Exception( + "Error loading parent pages" + ); + } + } + + // }}} + // {{{ loadMemberCategories() + + /** + * Loads member categories into the select list + * + * Gets an array structure of the member categories in a linear tree order + * Then walk through the array and load each category into the select list + * + * @param PDO $dbh Database handler + * + * @return void + * @access public + */ + public function loadMemberCategories(PDO $dbh) + { + try { + // Get a tree list of categories in linear order with + // category keys in the values and their level in the tree + // in the value + $c = Toolkit_Common::getHierarchicalTreeStructure( + $dbh, + 'category', + 'category_id', + 'parent_id', + 'name' + ); + + // Get all the data about each category + $sql = " + SELECT * + FROM category + WHERE category_id = ?"; + + $stmt = $dbh->prepare($sql); + // Get the member categories select list element + $e =& $this->getElement('member_categories'); + if (is_array($c)) { + foreach ($c as $i => $j) { + $stmt->execute(array($i)); + $row = $stmt->fetch(); + // the class level is always 1 less than what is reported + // from our $c array + $x = $j - 1; + // Add the option data to the select list. + $e->addOption($row['name'], $i, array('class' => "level-$x")); + } + } + } catch (PDOException $e) { + Toolkit_Logger::logException('DB error', $e); + throw new Toolkit_UserArea_Exception( + "Error loading member categories" + ); + } + } + + // }}} + // {{{ loadMemberRegions() + + /** + * Loads member Cities into the select list + * + * Gets an array structure of the member Cities in a sorted order by name + * Then walk through the array and load each category into the select list + * + * @param PDO $dbh Database handler + * + * @return void + * @access public + */ + public function loadMemberRegions(PDO $dbh) + { + try { + // Get all the data about each category + $sql = " + SELECT * + FROM region + ORDER BY region_name"; + + $stmt = $dbh->query($sql); + // Get the member categories select list element + $e =& $this->getElement('member_regions'); + while ($row = $stmt->fetch()) { + // Add the option data to the select list. + $e->addOption($row['region_name'], $row['region_id']); + } + } catch (PDOException $e) { + Toolkit_Logger::logException('DB error', $e); + throw new Toolkit_UserArea_Exception( + "Error loading member regions" + ); + } + } + + // }}} + + // {{{ setMaxDepth() + + /** + * Sets the max depth level that the parent page select list will show + * + * @param integer $md New max depth + * + * @return void + * @access public + */ + public function setMaxDepth($md) + { + $this->maxDepth = $md; + } + + // }}} + // {{{ setupRenderers() + + /** + * Custom rendering templates for special fields on the form + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + parent::setupRenderers(); + $renderer =& $this->defaultRenderer(); + + $required = ''; + $required .= ' * '; + $required .= ''; + + $error = ''; + $error .= '
    {error}
    '; + $error .= ''; + + $baseUrl =MEDIA_BASE_URL; + + $renderer->setFormTemplate( + "
    \n + \n +
    + {hidden} +
    + {requiredNote} + \n + {content} \n +
    \n + \n +
    " + ); + + $renderer->setElementTemplate( + "\n + $required{label}\n + {$error}{$baseUrl}{element}/\n + \n", + 'short_url' + ); + $renderer->setElementTemplate( + "\n + $required{label}$error{element} + ", + 'description' + ); + $renderer->setElementTemplate( + "\n + $required{label}$error{element} + ", + 'submit_buttons' + ); + $renderer->setElementTemplate( + "\n + $required{label}$error{element}\n + ", + 'edit' + ); + $renderer->setElementTemplate( + "\n + $required{label}$error{element} + ", + 'staff_pick' + ); + + $renderer->setElementTemplate( + "\n + $required{label}$error{element}\n + \n", + 'page_layout' + ); + $renderer->setGroupTemplate( + "\n + {content}\n +
    \n", + 'page_layout' + ); + $renderer->setGroupElementTemplate( + "\n + {element}
    {label}\n + \n", + 'page_layout' + ); + } + + // }}} + + // {{{ toHtml() + + /** + * Handles how to display the current step the user is at in the form + * + * @return string rendered html form + * @access public + */ + public function toHtml() + { + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jquery/jquery-1.4.2.min.js'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/' . + 'development-bundle/themes/start/jquery.ui.all.css'; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/' . + 'development-bundle/ui/jquery-ui-1.8.13.custom.js'; + $GLOBALS['bottomScripts'][] + = CKEDITOR_JS . ''; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/plugins/asmselect/1.0.4a/jquery.asmselect.js'; + $GLOBALS['bottomScripts'][] + =MEDIA_BASE_URL . 'Toolkit/UserArea/libjs/edit-page.js?v=1'; + + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL . 'libjs/plugins/asmselect/1.0.4a/jquery.asmselect.css'; + $GLOBALS['styleSheets'][] + =MEDIA_BASE_URL . 'css/contactform.css'; + $GLOBALS['styleSheets'][] + =MEDIA_BASE_URL . 'Toolkit/UserArea/styles.css'; + + $this->setupRenderers(); + + return parent::toHtml(); + } + + // }}} +} diff --git a/Toolkit/UserArea/Forms/EditParagraph.php b/Toolkit/UserArea/Forms/EditParagraph.php new file mode 100644 index 0000000..b530137 --- /dev/null +++ b/Toolkit/UserArea/Forms/EditParagraph.php @@ -0,0 +1,516 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @version CVS: $Id: EditParagraph.php,v 1.4 2010/07/20 18:39:40 jamie Exp $ + * @link http://demo.gaslightmedia.com + */ + +require_once BASE . 'Toolkit/Forms/Rules/Image.php'; + +/** + * Edit a page paragraph form + * + * @category Toolbox + * @package Toolkit_UserArea + * @author Jamie Kahgee + * @copyright 2009 Jamie Kahgee + * @license http://www.gaslightmedia.com Gaslightmedia + * @link http://demo.gaslightmedia.com + */ +class Toolkit_UserArea_Forms_EditParagraph extends Toolkit_FormBuilder +{ + // {{{ configureDefaults() + + /** + * Initializes default form values + * + * @param Toolkit_UserArea_GatewayFactoryAbstract $factory Gateway factory + * @param integer $id pargraph id (optional) + * @return void + * @access public + */ + public function configureDefaults( + Toolkit_UserArea_GatewayFactoryAbstract $factory, + Toolkit_UserArea_FileExtension $fileExtension, + $id = null + ) { + if (!is_null($id)) { + $gateway = $factory->createGateway(); + $paragraph = $gateway->find($id); + if ( isset($paragraph['files']) + && is_array($paragraph['files']) + ) { + $files = array(); + foreach ($paragraph['files'] as $file) { + $linkRenderer + = Toolkit_Template_Page_FileLink_Factory::createLinkRenderer( + $file + ); + $fileLink = $linkRenderer->getLink(); + $extImg = $fileExtension->getImage($file['filename']); + $id = preg_replace('/[^A-Za-z0-9]/', '', $file['urltext']); + $files[] = ' +
  • + + '.$fileLink.' + File Name: +
    + + + + +
  • '; + } + $paragraph['uploaded_files'] = '
      ' . implode('', $files) . '
    '; + } + } else { + $paragraph = array( + 'current_image_thumb' => 'Image not yet uploaded', + 'page' => $_GET['pageid'], + 'active' => true, + ); + } + + $this->setupDefaults($paragraph); + } + + // }}} + // {{{ configureElements() + + /** + * Form element definitions + * + * @param PDO $dbh Database handler + * + * @return void + * @access public + */ + public function configureElements(PDO $dbh) + { + $e = array(); + // Grouped Elements are defined here. + $submitBtns = array(); + + $submitBtns[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'saveParagraph', + 'display' => 'Save Paragraph' + ); + $submitBtns[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'cancel', + 'display' => 'Cancel' + ); + $submitBtns[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'deleteParagraph', + 'display' => 'Delete Paragraph' + ); + + // All Elements are created here. + // This includes group element definitions. + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'id' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'active' + ); + if ($_GET['rt'] == 'Paragraphs') { + $e[] = array( + 'type' => 'select', + 'req' => false, + 'name' => 'page', + 'display' => 'Page', + 'opts' => array(), + ); + } else { + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'page' + ); + } + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'title', + 'display' => 'Title', + 'opts' => array('size' => 40) + ); + $e[] = array( + 'type' => 'textarea', + 'req' => false, + 'name' => 'description', + 'opts' => array( + 'cols' => 60, + 'rows' => 60, + 'id' => 'description' + ), + 'noCharLimit' => true + ); + $e[] = array( + 'type' => 'file', + 'req' => false, + 'name' => 'file', + 'display' => 'New Image' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'caption', + 'display' => 'Image Caption', + 'opts' => array('size' => 35) + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'current_image_thumb', + 'display' => 'Current Image' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'image', + ); + if (!empty($this->_defaultValues['image'])) { + $e[] = array( + 'type' => 'checkbox', + 'req' => false, + 'name' => 'remove_image', + 'display' => 'Remove Current Image' + ); + } + $e[] = array( + 'type' => 'advcheckbox', + 'req' => false, + 'name' => 'back_to_top', + 'display' => "Insert 'Back to Top' link", + 'opts' => 'Yes', + 'val' => array(0, 1) + ); + + $e[] = array( + 'type' => 'header', + 'req' => false, + 'name' => 'templatesHdr', + 'display' => 'Files' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'fileurltext', + 'display' => 'New File Name', + 'opts' => array('size' => 35) + ); + $e[] = array( + 'type' => 'file', + 'req' => false, + 'name' => 'filename', + 'display' => 'New File', + 'opts' => array('id' => 'filename') + ); + $e[] = array( + 'type' => 'static', + 'req' => false, + 'name' => 'uploaded_files', + 'display' => 'Uploaded Files', + 'opts' => '
      ' + ); + + // If we are editing a page, show three submit buttons + // otherwise, just show one insert button. + $e[] = array( + 'type' => 'group', + 'req' => false, + 'name' => 'submit_buttons', + 'group' => $submitBtns, + 'label' => '', + 'seperator' => '', + 'appendName' => false, + ); + + $this->setupElements($e); + // Do the same for the pages + if ($_GET['rt'] == 'Paragraphs') { + $this->loadParagraphPages($dbh); + } + } + + // }}} + // {{{ 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() + + /** + * Bundle all form configuration calls into one function call + * + * @param PDO $dbh Database handler $dbh Database handler + * @param Toolkit_UserArea_GatewayFactoryAbstract $factory Gateway factory + * @param Toolkit_FileServer_ImageAdapter $is Image adapter for file server + * @param Toolkit_FileServer_FileAdapter $fs File adapter for file server + * + * @return void + * @access public + */ + public function configureForm( + PDO $dbh, + Toolkit_UserArea_GatewayFactoryAbstract $factory, + Toolkit_FileServer_ImageAdapter $is, + Toolkit_FileServer_FileAdapter $fs, + Toolkit_UserArea_FileExtension $fileExtension + ) { + $this->configureDefaults($factory, $fileExtension, $_GET['id']); + $this->configureElements($dbh); + $this->configureRules($is, $fs); + $this->configureFilters(); + } + + // }}} + // {{{ configureRules() + + /** + * Form rule definitions + * + * Adds validation rules for the given fields + * + * @param Toolkit_FileServer_ImageAdapter $is Image adapter for file server + * @param Toolkit_FileServer_FileAdapter $fs File adapter for file server + * + * @return void + * @access public + */ + public function configureRules( + Toolkit_FileServer_ImageAdapter $is, + Toolkit_FileServer_FileAdapter $fs + ) { + $r = array(); + // Form Rules + if (!empty($_FILES['file']['tmp_name'])) { + $r[] = array( + 'element' => 'file', + 'message' => 'ERROR: Incorrect File Type (.gif, .png, .jpg) only!', + 'type' => 'mimetype', + 'format' => $is->getAllowedMimeTypes(), + 'validation' => 'server', + 'reset' => false, + 'force' => false + ); + } + $r[] = array( + 'element' => 'file', + 'message' => 'ERROR: Error uploading image!', + 'type' => 'Image', + 'format' => array( + 'form' => $this, + 'fieldName' => 'file', + 'imageField' => 'image', + 'is' => $is, + 'deleteExistingImage' => false, + 'injectImage' => array('tgtElement' => 'current_image_thumb') + ), + 'validation' => 'server', + 'reset' => false, + 'force' => false + ); + + $this->setupRules($r); + } + + // }}} + + // {{{ loadParagraphPages() + + /** + * Load option elements into the parent select list + * + * These options are loaded via this seperate function vs inline w/ the + * element definition b/c we need a little more control defining + * the class names for each option so they will render nice when a user + * is looking at the list. + * + * @param PDO $dbh Database handler + * + * @return void + * @throws PDOException throws exception on sql error + * @access public + */ + public function loadParagraphPages(PDO $dbh) + { + try { + $auth = Registry::get('Toolkit_UserArea_Auth'); + $authData = $auth->getAuthData(); + // Get a tree list of categories in linear order with + // category keys in the values and their level in the tree + // in the value + $cSub = Toolkit_Common::getHierarchicalTreeStructure( + $dbh, + 'pages', + 'id', + 'parent', + 'pos', + AUTH_USER_PAGE_ID, + 3 + ); + // need to add the main level to the $c array for its page + $c = array(AUTH_USER_PAGE_ID => 1); + function addOne(&$input, &$key) { + $input++; + } + if ($cSub) { + array_walk_recursive($cSub, 'addOne'); + } + $c = $c + $cSub; + + // Get all the data about each category + $sql = " + SELECT * + FROM pages + WHERE id = ?"; + + $stmt = $dbh->prepare($sql); + // Get the member categories select list element + $e =& $this->getElement('page'); + foreach ($c as $i => $j) { + $stmt->execute(array($i)); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + // the class level is always 1 less than what is reported + // from our $c array + $x = $j - 1; + // Add the option data to the select list. + $e->addOption($row['navigation_name'], $i, array('class' => "level-$x")); + } + } catch (PDOException $e) { + Toolkit_Logger::logException('DB error', $e); + throw new Toolkit_UserArea_Exception( + "Error loading parent pages for paragraph" + ); + } + } + + // }}} + + // {{{ setupRenderers() + + /** + * Custom rendering templates for special fields on the form + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + parent::setupRenderers(); + $renderer =& $this->defaultRenderer(); + + $required = ''; + $required .= ' * '; + $required .= ''; + + $error = ''; + $error .= '
      {error}
      '; + $error .= ''; + + $renderer->setElementTemplate( + "\n + $required{label}$error{element} + ", + 'submit_buttons' + ); + $renderer->setElementTemplate( + "\n + $required{label}$error{element}\n + ", + 'insert' + ); + + $renderer->setElementTemplate( + "\n + $required{label}$error{element} + ", + 'description' + ); + } + + // }}} + + // {{{ toHtml() + + /** + * Handles how to display the current step the user is at in the form + * + * @param PDO $dbh Database handler + * + * @return string rendered html form + * @access public + */ + public function toHtml(PDO $dbh) + { + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jquery/jquery-1.4.2.min.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'ckeditor/current/ckeditor.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/plugins/ajaxUpload/3.9/ajaxupload.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/js/jquery-ui-1.8.13.custom.min.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/development-bundle/ui/minified/jquery.ui.sortable.min.js'; + $GLOBALS['bottomScripts'][] + =MEDIA_BASE_URL . 'Toolkit/UserArea/libjs/edit-paragraph.js?v=1'; + + $GLOBALS['styleSheets'][] =MEDIA_BASE_URL . 'css/contactform.css'; + $GLOBALS['styleSheets'][] =MEDIA_BASE_URL . 'Toolkit/UserArea/styles.css'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL . 'libjs/jqueryui/1.8.13/css/smoothness/jquery-ui-1.8.13.custom.css'; + + $this->setupRenderers(); + $out + = ($_REQUEST['g'] == '1') + ? '
      Form Submit Successfull!
      ' + : ''; + + return $out . parent::toHtml(); + } + + // }}} +} diff --git a/Toolkit/UserArea/Forms/SearchForm.php b/Toolkit/UserArea/Forms/SearchForm.php new file mode 100644 index 0000000..92f694a --- /dev/null +++ b/Toolkit/UserArea/Forms/SearchForm.php @@ -0,0 +1,174 @@ + 'Search'); + + $this->setupConstants($c); + } + + // }}} + // {{{ configureElements() + + /** + * Form element definitions + * + * @return void + * @access public + */ + public function configureElements() + { + $e = array(); + + // All Elements are created here. + // This includes group element definitions. + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'rt' + ); + + $elements = array(); + + $elements[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'q', + 'opts' => array( + 'size' => 75, + 'id' => 'q' + ) + ); + $elements[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'submit', + 'display' => 'Search Page Titles' + ); + + $e[] = array( + 'type' => 'group', + 'req' => false, + 'name' => 'fields', + 'group' => $elements, + 'seperator' => '', + 'appendName' => false + ); + $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() + + /** + * Bundle all form configuration calls into one function call + * + * @return void + * @access public + */ + public function configureForm() + { + $this->configureConstants(); + $this->configureElements(); + $this->configureFilters(); + } + + // }}} + + // {{{ setupRenderers() + + /** + * Custom rendering templates for special fields on the form + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + parent::setupRenderers(); + $renderer =& $this->defaultRenderer(); + + $required = ''; + $required .= ' * '; + $required .= ''; + + $error = ''; + $error .= '
      {error}
      '; + $error .= ''; + + $renderer->setElementTemplate( + "\n + $required{label}$error{element}\n + \n", + 'fields' + ); + } + + // }}} + + // {{{ toHtml() + + /** + * Handles how to display the current step the user is at in the form + * + * @return string rendered html form + * @access public + */ + public function toHtml() + { + $GLOBALS['styleSheets'][] + = MEDIA_BASE_URL . 'css/contactform.css'; + $GLOBALS['styleSheets'][] + = MEDIA_BASE_URL . 'Toolkit/UserArea/styles.css'; + + $this->setupRenderers(); + + return parent::toHtml(); + } + + // }}} +} diff --git a/Toolkit/UserArea/GatewayAbstract.php b/Toolkit/UserArea/GatewayAbstract.php new file mode 100644 index 0000000..0a7ccc0 --- /dev/null +++ b/Toolkit/UserArea/GatewayAbstract.php @@ -0,0 +1,32 @@ +dbh = $dbh; + } + + // }}} + // {{{ find() + + abstract public function find($id); + + // }}} + // {{{ update() + + abstract public function update(array $data, $id); + + // }}} + // {{{ insert() + + abstract public function insert(array $data); + + // }}} +} diff --git a/Toolkit/UserArea/GatewayFactoryAbstract.php b/Toolkit/UserArea/GatewayFactoryAbstract.php new file mode 100644 index 0000000..3752254 --- /dev/null +++ b/Toolkit/UserArea/GatewayFactoryAbstract.php @@ -0,0 +1,12 @@ +dbh = $dbh; + } + + abstract public function createGateway(); +} diff --git a/Toolkit/UserArea/IndexController.php b/Toolkit/UserArea/IndexController.php new file mode 100644 index 0000000..6a5bb2f --- /dev/null +++ b/Toolkit/UserArea/IndexController.php @@ -0,0 +1,35 @@ +configureForm(); + + $html = $searchForm->toHtml(); + + $toolboxConfig = new Config; + $toolboxConfigRoot =& $toolboxConfig->parseConfig( + BASE . 'Toolkit/UserArea/config.ini', + 'IniFile' + ); + $tree = new Toolkit_UserArea_PagesTree($toolboxConfigRoot); + $html .= $tree->toHtml( + new Toolkit_UserArea_PageGatewayPublish($this->registry->dbh) + ); + return $html; + } + + // }}} +} diff --git a/Toolkit/UserArea/ListDraftsController.php b/Toolkit/UserArea/ListDraftsController.php new file mode 100644 index 0000000..cddea0e --- /dev/null +++ b/Toolkit/UserArea/ListDraftsController.php @@ -0,0 +1,26 @@ +parseConfig( + BASE . 'Toolkit/UserArea/config.ini', + 'IniFile' + ); + $tree = new Toolkit_UserArea_DraftPagesTree($toolboxConfigRoot); + $html .= $tree->toHtml( + new Toolkit_UserArea_PageGatewayDraft($this->registry->dbh) + ); + + return $html; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/Models/App.php b/Toolkit/UserArea/Models/App.php new file mode 100644 index 0000000..dc8302b --- /dev/null +++ b/Toolkit/UserArea/Models/App.php @@ -0,0 +1,162 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_UserArea_Admin_User + * + * Description of User + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Models_App +{ + private $_id; + private $_name; + private $_page; + private $_config; + + const TABLE_NAME = 'auth.apps'; + const PRIMARY_KEY = 'id'; + const SORT_FIELD = 'name'; + + /** + * Creates object of type User + * + * @param array $values array values for the user fields + */ + private function __construct(array $values) + { + extract($values); + $this->setName($name) + ->setPage($page) + ->setConfig($config); + if ($id) { + $this->setId($id); + } + } + + /** + * Create a User from an array of values + * + * @param array $values Array values for the user fields + * + * @return Toolkit_UserArea_Admin_User + */ + public static function createByValues(array $values) + { + return new Toolkit_UserArea_Models_App($values); + } + + + /** + * Returns the User's id + * + * @return int + */ + public function getId() + { + return (int)$this->_id; + } + + /** + * Sets the User's id + * + * @param int $id User's id + * + * @return Toolkit_UserArea_Admin_User + * @throws InvalidArgumentException + */ + public function setId($id) + { + if ( !is_int($id) + && !ctype_digit($id) + && $id <= 0 + ) { + throw new InvalidArgumentException( + 'Id must be a numeric value greater than 0' + ); + } + if (!$this->_id) { + $this->_id = (int)$id; + } + return $this; + } + + /** + * Returns User's Name + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the User's name + * + * @param string $name User's name + * + * @return Toolkit_UserArea_Admin_User + */ + public function setName($name) + { + $this->_name = $name; + return $this; + } + + /** + * Returns the User's password + * + * @return string + */ + public function getPage() + { + return $this->_page; + } + + /** + * Sets the User's password + * + * @param string $page User's password + * + * @return Toolkit_UserArea_Admin_User + */ + public function setPage($page) + { + $this->_page = $page; + return $this; + } + + public function getConfig() + { + return (bool)$this->_config; + } + + public function setConfig($config) + { + $this->_config = (bool)$config; + return $this; + } + + +} diff --git a/Toolkit/UserArea/Models/Log.php b/Toolkit/UserArea/Models/Log.php new file mode 100644 index 0000000..f5038bf --- /dev/null +++ b/Toolkit/UserArea/Models/Log.php @@ -0,0 +1,370 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_Log + * + * Object representation of the auth.logs table record + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Models_Log +{ + private $_id; + private $_userId; + private $_alterTime; + private $_dbTable; + private $_alterType; + private $_foreignKey; + private $_comment; + + const TABLE_NAME = 'auth.logs'; + const PRIMARY_KEY = 'id'; + const SORT_FIELD = 'alter_time'; + + /** + * Creates an object of type Log + * + * @param array $values Log values + * + * @return Toolkit_UserArea_Admin_Log + */ + private function __construct(array $values) + { + extract($values); + $this->setUserId($user_id) + ->setAlterTime($alter_time) + ->setAlterType($alter_type) + ->setDbTable($db_table) + ->setForeignKey($foreign_key) + ->setComment($comment); + if ($id) { + $this->setId($id); + } + return $this; + } + + /** + * Static method for creating Log objects + * + * @param array $values Log values + * + * @return Toolkit_UserArea_Admin_Log + */ + public static function createLogWithValues(array $values) + { + return new Toolkit_UserArea_Admin_Log($values); + } + + /** + * Returns an array of logs for a user + * + * @param PDO $dbh Database Connection + * @param int $userId User's id + * + * @return array + */ + public static function fetchLogsByUserId(PDO $dbh, $userId) + { + $logs = array(); + try { + $sql = " + SELECT * + FROM auth.logs + WHERE user_id = :user_id + ORDER BY alter_time DESC"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':user_id', $userId, PDO::PARAM_INT); + $stmt->execute(); + while ($values = $stmt->fetch(PDO::FETCH_ASSOC)) { + $logs[] = new Toolkit_UserArea_Admin_Log($values); + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $logs; + } + + /** + * Return the Log id + * + * @return int + */ + public function getId() + { + return (int)$this->_id; + } + + /** + * Sets the Log id + * + * @param int $id Log id + * + * @return Toolkit_UserArea_Admin_Log + * @throws InvalidArgumentException + */ + public function setId($id) + { + if ( !is_int($id) + && !ctype_digit($id) + && $id <= 0 + ) { + throw new InvalidArgumentException('Id must be an integer'); + } + if (!$this->id) { + $this->_id = (int)$id; + } + return $this; + } + + /** + * Returns Log user_id + * + * @return int + */ + public function getUserId() + { + return $this->_userId; + } + + /** + * Sets the Log user_id + * + * @param int $userId Log user_id + * + * @return Toolkit_UserArea_Admin_Log + * @throws InvalidArgumentException + */ + public function setUserId($userId) + { + if ( !is_int($userId) + && !ctype_digit($userId) + && $userId <= 0 + ) { + throw new InvalidArgumentException('userId must be an integer'); + } + $this->_userId = (int)$userId; + return $this; + } + + /** + * Returns the Logs alter_time + * + * @return string + */ + public function getAlterTime() + { + return $this->_alterTime; + } + + /** + * Sets the Logs alter_time + * + * @param string $alterTime Logs alter_time + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setAlterTime($alterTime) + { + $this->_alterTime = $alterTime; + return $this; + } + + /** + * Returns the Logs db_table + * + * @return string + */ + public function getDbTable() + { + return $this->_dbTable; + } + + /** + * Sets the Logs db_table + * + * @param string $dbTable Logs db_table + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setDbTable($dbTable) + { + $this->_dbTable = $dbTable; + return $this; + } + + /** + * Returns Logs alter_type + * + * @return string + */ + public function getAlterType() + { + return $this->_alterType; + } + + /** + * Sets the Logs alter_type + * + * @param string $alterType Logs alter_type + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setAlterType($alterType) + { + $this->_alterType = $alterType; + return $this; + } + + /** + * Returns the Logs foreign_key + * + * @return int + */ + public function getForeignKey() + { + return (int)$this->_foreignKey; + } + + /** + * Sets the Logs foreign_key + * + * @param int $foreignKey Logs foreign_key + * + * @return Toolkit_UserArea_Admin_Log + * @throws InvalidArgumentException + */ + public function setForeignKey($foreignKey) + { + if (!is_int($foreignKey) && !ctype_digit($foreignKey)) { + throw new InvalidArgumentException('foreignKey must be an integer'); + } + $this->_foreignKey = (int)$foreignKey; + return $this; + } + + /** + * Returns the Logs comments + * + * @return string + */ + public function getComment() + { + return $this->_comment; + } + + /** + * Sets the Logs comment + * + * @param string $comment Comment for the log + * + * @return Toolkit_UserArea_Admin_Log + */ + public function setComment($comment) + { + $this->_comment = $comment; + return $this; + } + + + /** + * if $this->_id is set then it will run update. + * if $this->_id is not set then it will run insert. + * + * @param PDO $dbh Database Connection + * + * @return Toolkit_UserArea_Admin_Log + */ + public function save(PDO $dbh) + { + if ($this->_id) { + $this->_update($dbh); + } else { + $this->_insert($dbh); + } + return $this; + } + + /** + * Insert the record into the database + * + * @param PDO $dbh Database connection + * + * @return void + */ + private function _insert(PDO $dbh) + { + try { + $sql = " + INSERT INTO + auth.logs + (user_id,alter_time,db_table,alter_type,foreign_key,comment) + VALUES + (:user_id,:alter_time,:db_table,:alter_type,:foreign_key,:comment) + RETURNING id"; + $insert = $dbh->prepare($sql); + $insert->bindParam(':user_id', $this->_userId, PDO::PARAM_INT); + $insert->bindParam(':foreign_key', $this->_foreignKey, PDO::PARAM_INT); + $insert->bindParam(':alter_time', $this->_alterTime); + $insert->bindParam(':db_table', $this->_dbTable); + $insert->bindParam(':alter_type', $this->_alterType); + $insert->bindParam(':comment', $this->_comment); + $insert->execute(); + $this->setId($insert->fetchColumn()); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Update the Log in the database + * + * @param PDO $dbh Database connection + * + * @return void + */ + private function _update(PDO $dbh) + { + try { + $sql = " + UPDATE auth.log + SET user_id = :user_id, + alter_time = :alter_time, + db_table = :db_table, + alter_type = :alter_type, + foreign_key = :foreign_key, + comment = :comment + WHERE id = :id"; + $update = $dbh->prepare($sql); + $update->bindParam(':user_id', $this->_userId, PDO::PARAM_INT); + $update->bindParam(':foreign_key', $this->_foreignKey, PDO::PARAM_INT); + $update->bindParam(':id', $this->_id, PDO::PARAM_INT); + $update->bindParam(':alter_time', $this->_alterTime); + $update->bindParam(':db_table', $this->_dbTable); + $update->bindParam(':alter_type', $this->_alterType); + $update->bindParam(':comment', $this->_comment); + $update->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } +} diff --git a/Toolkit/UserArea/Models/Mapper.php b/Toolkit/UserArea/Models/Mapper.php new file mode 100644 index 0000000..d5e4721 --- /dev/null +++ b/Toolkit/UserArea/Models/Mapper.php @@ -0,0 +1,310 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_Mapper + * + * Description of Mapper + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Models_Mapper +{ + public function saveUserAppData( + PDO $dbh, + Toolkit_UserArea_Models_User $user, + $data, + $pages = null, + $categories = null + ) { + $sql = " + DELETE + FROM " . Toolkit_UserArea_Models_UserApp::TABLE_NAME . " + WHERE user_id = :user_id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':user_id', $user->getId(), PDO::PARAM_INT); + $stmt->execute(); + $sql = " + INSERT + INTO " . Toolkit_UserArea_Models_UserApp::TABLE_NAME . " + (user_id, app_id, config) + VALUES + (:user_id, :app_id, :config)"; + $addUserApp = $dbh->prepare($sql); + if (is_array($data) && !empty($data)) { + foreach ($data as $appId => $approved) { + if (filter_var($approved, FILTER_VALIDATE_BOOLEAN)) { + $config = ''; + $addUserApp->bindParam(':user_id', $user->getId(), PDO::PARAM_INT); + $addUserApp->bindParam(':app_id', $appId, PDO::PARAM_INT); + $addUserApp->bindParam(':config', $config); + $addUserApp->execute(); + } + } + } + if (isset($pages) && !empty($pages)) { + $appId = Toolkit_UserArea_Admin_IndexController::TOOLBOX_APP_ID; + foreach ($pages as $config) { + $addUserApp->bindParam(':user_id', $user->getId(), PDO::PARAM_INT); + $addUserApp->bindParam(':app_id', $appId, PDO::PARAM_INT); + $addUserApp->bindParam(':config', $config); + $addUserApp->execute(); + } + } + if (isset($categories) && !empty($categories)) { + $appId = Toolkit_UserArea_Admin_IndexController::EVENT_APP_ID; + $config = serialize($categories); + $addUserApp->bindParam(':user_id', $user->getId(), PDO::PARAM_INT); + $addUserApp->bindParam(':app_id', $appId, PDO::PARAM_INT); + $addUserApp->bindParam(':config', $config); + $addUserApp->execute(); + } + } + + public function fetchAllApps(PDO $dbh) + { + $apps = new ArrayObject(); + try { + $sql = " + SELECT " . Toolkit_UserArea_Models_App::PRIMARY_KEY . " + FROM " . Toolkit_UserArea_Models_App::TABLE_NAME . " + ORDER BY " . Toolkit_UserArea_Models_App::SORT_FIELD . " ASC"; + $stmt = $dbh->query($sql); + $stmt->execute(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $app = $this->fetchAppById($dbh, $row['id']); + if ($app) { + $apps->offsetSet($app->getId(), $app); + } + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $apps; + } + + public static function fetchAppById(PDO $dbh, $id) + { + if ( !filter_var($id, FILTER_VALIDATE_INT) + && $id <= 0 + ) { + throw new InvalidArgumentException( + 'Id must be a numeric value greater than 0' + ); + } + try { + $sql = " + SELECT * + FROM " . Toolkit_UserArea_Models_App::TABLE_NAME . " + WHERE " . Toolkit_UserArea_Models_App::PRIMARY_KEY . " = :id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + $values = $stmt->fetch(PDO::FETCH_ASSOC); + if ($values) { + return Toolkit_UserArea_Models_App::createByValues( + $values + ); + } else { + return null; + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + public function fetchAllUserApps( + PDO $dbh, + Toolkit_UserArea_Models_User $user + ) { + $userApps = new ArrayObject(); + try { + $sql = " + SELECT " . Toolkit_UserArea_Models_UserApp::PRIMARY_KEY . " + FROM " . Toolkit_UserArea_Models_UserApp::TABLE_NAME . " + WHERE user_id = :user_id + ORDER BY " . Toolkit_UserArea_Models_UserApp::SORT_FIELD . " ASC"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':user_id', $user->getId(), PDO::PARAM_INT); + $stmt->execute(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $userApp = $this->fetchUserAppById($dbh, $row['id']); + if ($userApp) { + $userApps->offsetSet($userApp->getId(), $userApp); + } + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $userApps; + } + + public static function fetchUserAppById(PDO $dbh, $id) + { + if ( !filter_var($id, FILTER_VALIDATE_INT) + && $id <= 0 + ) { + throw new InvalidArgumentException( + 'Id must be a numeric value greater than 0' + ); + } + try { + $sql = " + SELECT * + FROM " . Toolkit_UserArea_Models_UserApp::TABLE_NAME . " + WHERE " . Toolkit_UserArea_Models_UserApp::PRIMARY_KEY . " = :id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + $values = $stmt->fetch(PDO::FETCH_ASSOC); + if ($values) { + return Toolkit_UserArea_Models_UserApp::createUserFromValues( + $values + ); + } else { + return null; + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + public function fetchAllUsers(PDO $dbh) + { + $users = new ArrayObject(); + try { + $sql = " + SELECT " . Toolkit_UserArea_Models_User::PRIMARY_KEY . " + FROM " . Toolkit_UserArea_Models_User::TABLE_NAME . " + ORDER BY " . Toolkit_UserArea_Models_User::SORT_FIELD . " ASC"; + $stmt = $dbh->query($sql); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $user = $this->fetchUserById($dbh, $row['id']); + if ($user) { + $users->offsetSet($user->getId(), $user); + } + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $users; + } + + public static function fetchUserById(PDO $dbh, $id) + { + if ( !filter_var($id, FILTER_VALIDATE_INT) + && $id <= 0 + ) { + throw new InvalidArgumentException( + 'Id must be a numeric value greater than 0' + ); + } + try { + $sql = " + SELECT * + FROM " . Toolkit_UserArea_Models_User::TABLE_NAME . " + WHERE " . Toolkit_UserArea_Models_User::PRIMARY_KEY . " = :id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + $values = $stmt->fetch(PDO::FETCH_ASSOC); + if ($values) { + return Toolkit_UserArea_Models_User::createUserFromValues( + $values + ); + } else { + return null; + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + public function saveUser( + PDO $dbh, + Toolkit_UserArea_Models_User $user + ) { + if ($user->getId()) { + $sql = " + UPDATE " . Toolkit_UserArea_Models_User::TABLE_NAME . " + SET name = :name, + page = :page, + password = :password, + username = :username, + active = :active, + toolbox = :toolbox + WHERE " . Toolkit_UserArea_Models_User::PRIMARY_KEY . " = :id"; + } else { + $sql = " + INSERT INTO " . Toolkit_UserArea_Models_User::TABLE_NAME . " + (name, page, username, password, active, toolbox) + VALUES + (:name, :page, :username, :password, :active, :toolbox) + RETURNING " . Toolkit_UserArea_Models_User::PRIMARY_KEY; + } + try { + $stmt = $dbh->prepare($sql); + + $stmt->bindParam(':page', $this->getPage(), PDO::PARAM_INT); + $stmt->bindParam(':name', $this->getName()); + $stmt->bindParam(':username', $this->getUsername()); + $stmt->bindParam(':password', $this->getPassword()); + $stmt->bindParam(':active', $this->getActive(), PDO::PARAM_BOOL); + $stmt->bindParam(':toolbox', $this->getToolbox(), PDO::PARAM_BOOL); + if ($user->getId()) { + $stmt->bindParam(':id', $this->getId(), PDO::PARAM_INT); + } + $stmt->execute(); + if (!$user->getId()) { + $user->setId($stmt->fetchColumn()); + } + return $user; + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + + } + + public function deleteUser( + PDO $dbh, + Toolkit_UserArea_Models_User $user + ) { + try { + $sql = " + DELETE + FROM " . Toolkit_UserArea_Models_User::TABLE_NAME . " + WHERE " . Toolkit_UserArea_Models_User::PRIMARY_KEY . " = :id"; + $delete = $dbh->prepare($sql); + $delete->bindParam(':id', $user->getId(), PDO::PARAM_INT); + $delete->execute(); + $sql = " + DELETE + FROM " . Toolkit_UserArea_Models_User::TABLE_NAME . " + WHERE user_id = :id"; + $delete = $dbh->prepare($sql); + $delete->bindParam(':id', $user->getId(), PDO::PARAM_INT); + $delete->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } +} diff --git a/Toolkit/UserArea/Models/User.php b/Toolkit/UserArea/Models/User.php new file mode 100644 index 0000000..994064a --- /dev/null +++ b/Toolkit/UserArea/Models/User.php @@ -0,0 +1,340 @@ + + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_UserArea_Admin_User + * + * Description of User + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Models_User +{ + private $_id; + private $_name; + private $_username; + private $_password; + private $_active; + + const TABLE_NAME = 'auth.users'; + const PRIMARY_KEY = 'id'; + const SORT_FIELD = 'name'; + + /** + * Creates object of type User + * + * @param array $values array values for the user fields + */ + private function __construct(array $values) + { + extract($values); + $this->setName($name) + ->setPassword($password) + ->setUsername($username) + ->setActive($active); + if ($id) { + $this->setId($id); + } + } + + /** + * Create a User from an array of values + * + * @param array $values Array values for the user fields + * + * @return Toolkit_UserArea_Admin_User + */ + public static function createUserFromValues(array $values) + { + return new Toolkit_UserArea_Models_User($values); + } + + /** + * Fetches the database record for an id and returns an User Object + * + * @param PDO $dbh Databes Connection + * @param int $id Id for record + * + * @return Toolkit_UserArea_Admin_User|null + * @throws InvalidArgumentException + */ + public static function fetchUserById(PDO $dbh, $id) + { + if ( !is_int($id) + && !ctype_digit($id) + && $id <= 0 + ) { + throw new InvalidArgumentException( + 'Id must be a numeric value greater than 0' + ); + } + try { + $sql = " + SELECT * + FROM auth.users + WHERE id = :id"; + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + $values = $stmt->fetch(PDO::FETCH_ASSOC); + if ($values) { + return new Toolkit_UserArea_Models_User($values); + } else { + return null; + } + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Returns the User's id + * + * @return int + */ + public function getId() + { + return (int)$this->_id; + } + + /** + * Sets the User's id + * + * @param int $id User's id + * + * @return Toolkit_UserArea_Admin_User + * @throws InvalidArgumentException + */ + public function setId($id) + { + if ( !is_int($id) + && !ctype_digit($id) + && $id <= 0 + ) { + throw new InvalidArgumentException( + 'Id must be a numeric value greater than 0' + ); + } + if (!$this->_id) { + $this->_id = (int)$id; + } + return $this; + } + + /** + * Returns User's Name + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the User's name + * + * @param string $name User's name + * + * @return Toolkit_UserArea_Admin_User + */ + public function setName($name) + { + $this->_name = $name; + return $this; + } + + /** + * Returns the User's username + * + * @return string + */ + public function getUsername() + { + return $this->_username; + } + + /** + * Sets the User's username + * + * @param string $username User's username + * + * @return Toolkit_UserArea_Admin_User + */ + public function setUsername($username) + { + $this->_username = $username; + return $this; + } + + /** + * Returns the User's password + * + * @return string + */ + public function getPassword() + { + return $this->_password; + } + + /** + * Sets the User's password + * + * @param string $password User's password + * + * @return Toolkit_UserArea_Admin_User + */ + public function setPassword($password) + { + $this->_password = $password; + return $this; + } + + /** + * Returns the active state of the User + * + * @return bool + */ + public function getActive() + { + return (bool)$this->_active; + } + + /** + * Sets the User's Active state + * + * @param bool $active User's active state + * + * @return Toolkit_UserArea_Admin_User + */ + public function setActive($active) + { + $this->_active = (bool)$active; + return $this; + } + + /** + * If the id is set then it will update else it inserts record into database + * + * @param PDO $dbh Database Connection + * + * @return Toolkit_UserArea_Admin_User + */ + public function save(PDO $dbh) + { + if ($this->_id) { + $this->_update($dbh); + } else { + $this->_insert($dbh); + } + return $this; + } + + /** + * Updates the record in the databas + * + * @param PDO $dbh Database Connection + * + * @return Toolkit_UserArea_Admin_User + */ + private function _update(PDO $dbh) + { + try { + $sql = " + UPDATE auth.users + SET name = :name, + password = :password, + username = :username, + active = :active + WHERE id = :id"; + $update = $dbh->prepare($sql); + $update->bindParam(':id', $this->getId(), PDO::PARAM_INT); + $update->bindParam(':name', $this->getName()); + $update->bindParam(':username', $this->getUsername()); + $update->bindParam(':password', $this->getPassword()); + $update->bindParam(':active', $this->getActive(), PDO::PARAM_BOOL); + $update->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $this; + } + + /** + * Insert the record into the database + * + * @param PDO $dbh Database Connection + * + * @return Toolkit_UserArea_Admin_User + */ + private function _insert(PDO $dbh) + { + try { + $sql = " + INSERT INTO auth.users + (name, username, password, active) + VALUES + (:name, :username, :password, :active) + RETURNING id"; + $insert = $dbh->prepare($sql); + $insert->bindParam(':name', $this->getName()); + $insert->bindParam(':username', $this->getUsername()); + $insert->bindParam(':password', $this->getPassword()); + $insert->bindParam(':active', $this->getActive(), PDO::PARAM_BOOL); + $insert->execute(); + $this->setId($insert->fetchColumn()); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + return $this; + } + + /** + * Delete the record from the databas + * + * @param PDO $dbh Database Connection + * + * @return void + */ + public function delete(PDO $dbh) + { + try { + $sql = " + DELETE + FROM auth.users + WHERE id = :id"; + $delete = $dbh->prepare($sql); + $delete->bindParam(':id', $this->getId(), PDO::PARAM_INT); + $delete->execute(); +// $sql = " +// DELETE +// FROM auth.logs +// WHERE user_id = :id"; +// $delete = $dbh->prepare($sql); +// $delete->bindParam(':id', $this->getId(), PDO::PARAM_INT); +// $delete->execute(); + } catch (PDOException $e) { + Toolkit_Common::handleError($e); + } + } + +} diff --git a/Toolkit/UserArea/Models/UserApp.php b/Toolkit/UserArea/Models/UserApp.php new file mode 100644 index 0000000..faa2070 --- /dev/null +++ b/Toolkit/UserArea/Models/UserApp.php @@ -0,0 +1,129 @@ + + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @version SVN: (0.1) + * @link <> + */ + +/** + * Toolkit_Package_UserApp + * + * Description of UserApp + * + * @category Toolkit + * @package UserArea + * @author Steve Sutton + * @copyright 2013 Gaslight Media + * @license Gaslight Media + * @release Release: (0.1) + * @link <> + */ +class Toolkit_UserArea_Models_UserApp +{ + private $id; + private $userId; + private $appId; + private $config; + + const TABLE_NAME = 'auth.userapps'; + const PRIMARY_KEY = 'id'; + const SORT_FIELD = 'id'; + + /** + * Creates object of type User + * + * @param array $values array values for the user fields + */ + private function __construct(array $values) + { + extract($values); + $this->setAppId($app_id) + ->setConfig($config) + ->setUserId($user_id); + if ($id) { + $this->setId($id); + } + } + + /** + * Create a User from an array of values + * + * @param array $values Array values for the user fields + * + * @return Toolkit_UserArea_Admin_User + */ + public static function createUserFromValues(array $values) + { + return new Toolkit_UserArea_Models_UserApp($values); + } + + public function getId() + { + return (int)$this->id; + } + + public function setId($id) + { + if (!filter_var($id, FILTER_VALIDATE_INT)) { + throw new InvalidArgumentException( + 'Id must be a numeric value' + ); + } + $this->id = (int)$id; + return $this; + } + + public function getUserId() + { + return (int)$this->userId; + } + + public function setUserId($userId) + { + if (!filter_var($userId, FILTER_VALIDATE_INT)) { + throw new InvalidArgumentException( + 'userId must be a numeric value' + ); + } + $this->userId = (int)$userId; + return $this; + } + + public function getAppId() + { + return (int)$this->appId; + } + + public function setAppId($appId) + { + if (!filter_var($appId, FILTER_VALIDATE_INT)) { + throw new InvalidArgumentException( + 'appId must be a numeric value' + ); + } + $this->appId = (int)$appId; + return $this; + } + + public function getConfig() + { + return $this->config; + } + + public function setConfig($config) + { + $this->config = $config; + return $this; + } + + +} diff --git a/Toolkit/UserArea/Navigation.php b/Toolkit/UserArea/Navigation.php new file mode 100644 index 0000000..68ef6e5 --- /dev/null +++ b/Toolkit/UserArea/Navigation.php @@ -0,0 +1,105 @@ +menu = $menu; + $this->rEngine = $rEngine; + $this->currIndex = 'listToolbox'; + } + + // }}} + // {{{ setNavTemplates() + + protected function setNavTemplates() + { + $tpl = '
    • {Title}
    • '; + $this->rEngine->setEntryTemplate( + HTML_MENU_ENTRY_INACTIVE, + sprintf($tpl, '{url}', '{desc}', '{Title}') + ); + $this->rEngine->setEntryTemplate( + HTML_MENU_ENTRY_ACTIVE, + sprintf($tpl, '{url}', '{desc}', '{Title}') + ); + $this->rEngine->setEntryTemplate( + HTML_MENU_ENTRY_ACTIVEPATH, + sprintf($tpl, '{url}', '{desc}', '{Title}') + ); + $this->rEngine->setMenuTemplate('', ''); + $this->rEngine->setRowTemplate('
        ', '
      '); + } + + // }}} + // {{{ setCurrentIndex() + + protected function setCurrentIndex() + { + $this->menu->forceCurrentIndex($_GET['rt']); + } + + // }}} + // {{{ getNavSructure() + // @codeCoverageIgnoreStart + + /** + * Sets up a multi dimensional array used for the nav structure + * + * @param Config_Container $c Application configuration + * + * @return array navigational array hash + * @access public + */ + public function getNavStructure(Config_Container $c) + { + // get reference to [listing type] section of config file + $appName = $c->getItem('section', 'conf') + ->getItem('directive', 'applicationName') + ->getContent(); + + $nav = array( + 'publishedPages' => array( + 'Title' => "Published Pages", + 'url' =>MEDIA_BASE_URL . 'userArea/toolbox.php', + 'desc' => "Display all the published pages", + ), + 'draftPages' => array( + 'Title' => 'Page Drafts', + 'url' =>MEDIA_BASE_URL . 'userArea/toolbox.php?rt=ListDrafts', + 'desc' => 'Display all the page drafts' + + ), + 'editPage' => array( + 'Title' => "Create New Page", + 'url' =>MEDIA_BASE_URL . 'userArea/toolbox.php?rt=EditPage', + 'desc' => "Create a new {$appName} Page" + ), + ); + + if (isset($_GET['rt']) && $_GET['rt'] == 'Paragraphs') { + $nav['editParagraph'] = array( + 'Title' => "Create Page Paragraph", + 'url' =>MEDIA_BASE_URL . "userArea/toolbox.php?rt=Paragraphs&ac=edit&pageid={$_GET['pageid']}", + 'desc' => "Edit a Page Paragraph" + ); + } elseif (isset($_GET['rt']) && $_GET['rt'] == 'ParagraphsDraft') { + $nav['editParagraph'] = array( + 'Title' => "Create Page Paragraph", + 'url' =>MEDIA_BASE_URL . "userArea/toolbox.php?rt=ParagraphsDraft&ac=edit&pageid={$_GET['pageid']}", + 'desc' => "Edit a Page Paragraph" + ); + } + + return $nav; + } + + // @codeCoverageIgnoreEnd + // }}} +} +?> diff --git a/Toolkit/UserArea/Page.php b/Toolkit/UserArea/Page.php new file mode 100644 index 0000000..485e285 --- /dev/null +++ b/Toolkit/UserArea/Page.php @@ -0,0 +1,322 @@ +_id = (int) $id; + } else { + throw new Toolkit_UserArea_Exception("Invalid page id `$id`"); + } + } + + $this->content = $cf->getComponent('content', $data); + $this->members = $cf->getComponent('members', $data); + $this->coupons = $cf->getComponent('coupons', $data); + $this->attributes = $cf->getComponent('attributes', $data); + $this->headlines = $cf->getComponent('headlines', $data); + $this->metaData = $cf->getComponent('metadata', $data); + $this->_createDate = $data['createDate']; + $this->_lastModifiedDate = $data['lastModifiedDate']; + $this->_revisions = $data['revisions']; + } + + // }}} + + // {{{ delete() + + /** + * Delete a toolbox page + * + * @param PDO $dbh Database handler + * @param integer $id Toolbox page id to delete + * + * @return boolean Result of delete query + * @access public + * @throws Toolkit_UserArea_Exception + */ + public static function delete(PDO $dbh, $id) + { + try { + $sql = " + DELETE FROM bus_category + WHERE id = :id"; + + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + return $stmt->execute(); + } catch(PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Error deleting the toolbox page `$id`" + ); + } + } + + // }}} + + // {{{ fetch() + + public static function fetch(PDO $dbh, $id) + { + if (!ctype_digit((string)$id)) { + throw new Toolkit_UserArea_Exception("Invalid page id `$id`"); + } + try { + $sql = " + SELECT * + FROM bus_category + WHERE id = :id"; + + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + $d = $stmt->fetch(); + + $sql = " + SELECT * + FROM bus_cat_member + WHERE catid = :id"; + + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + + $d['memberCat'] = array(); + while ($row = $stmt->fetch()) { + $d['memberCat'][] = $row['memb_type']; + } + + $sql = " + SELECT * + FROM coupon_categories2toolbox_pages + WHERE toolbox_catid = :id"; + + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + + $d['couponCat'] = array(); + while ($row = $stmt->fetch()) { + $d['couponCat'][] = $row['category_id']; + } + + $sql = " + SELECT CASE + WHEN active THEN 'Active' + ELSE 'In-Active' + END AS active + FROM bus_category + WHERE id = :id"; + + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + $row = $stmt->fetch(); + $d['active'] = $row['active']; + + $sql = " + SELECT to_char(min(revision_timestamp), 'FMDay, DD Month FMHH12:MIpm') AS created, + to_char(max(revision_timestamp), 'FMDay, DD Month FMHH12:MIpm') AS last_modified, + count(*) AS total + FROM bus_category_history + WHERE id = :id"; + + $stmt = $dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + $row = $stmt->fetch(); + $d['revisions'] = $row['total']; + $d['createDate'] = $row['created']; + $d['lastModifiedDate'] = $row['last_modified']; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Error retrieving defaults for page `$id`" + ); + } + + return new self(new Toolkit_UserArea_ComponentFactory(), $d, $id); + } + + // }}} + // {{{ getBusCategoryData() + public function getBusCategoryData() + { + if ($this->content->getRemoveImage()) { + $this->content->setImage(Toolkit_UserArea_ImageFactory::getImage()); + $this->content->setImageName(null); + } + return array( + 'intro' => $this->content->getIntro(), + 'description' => $this->content->getDescription(), + 'image' => $this->content->getImage()->getSrc(), + 'imagename' => $this->content->getImageName(), + 'parent' => $this->attributes->getParent(), + 'category' => $this->attributes->getCategory(), + 'keyword' => $this->attributes->getKeyword(), + 'template' => $this->attributes->getTemplate(), + 'section_links' => $this->attributes->getSectionLinks(), + 'short_url' => $this->attributes->getShortUrl(), + 'featured' => $this->headlines->getFeatured(), + 'feature_intro' => $this->headlines->getFeatureIntro(), + 'no_search_form' => $this->members->getSearch(), + 'include_member_map' => $this->members->getMap(), + 'meta_descr' => $this->metaData->getDescription(), + 'title' => $this->metaData->getTitle(), + ); + } + + // }}} + + // {{{ save() + public function save(PDO $dbh) + { + try { + $dbh->beginTransaction(); + + $busCategoryData = $this->getBusCategoryData(); + + $busCategorySql = Toolkit_Common::createSQLInsert( + 'bus_category', + array_keys($busCategoryData) + ); + + $stmt = Toolkit_Common::prepareQuery( + $dbh, + 'bus_category', + $busCategorySql, + $busCategoryData + ); + + $stmt->execute(); + $catidSql = " + SELECT * + FROM bus_category + ORDER BY id DESC LIMIT 1"; + + $row = $dbh->query($catidSql)->fetch(PDO::FETCH_ASSOC); + $this->_id = (int) $row['id']; + + $this->coupons->saveCategories($dbh, $this->_id); + $this->members->saveCategories($dbh, $this->_id); + + return $dbh->commit(); + } catch (PDOException $e) { + $dbh->rollback(); + Toolkit_Logger::logException('db error', $e); + throw new Toolkit_UserArea_Exception('Error saving page in Database'); + } + } + + // }}} + + // {{{ update() + public function update(PDO $dbh) + { + try { + if (!isset($this->_id)) { + throw new RuntimeException('Page does not exist yet'); + } + $dbh->beginTransaction(); + + $busCategoryData = $this->getBusCategoryData(); + + $busCategorySql = Toolkit_Common::createSQLUpdate( + 'bus_category', + array_keys($busCategoryData), + array("id = {$this->_id}") + ); + + $stmt = Toolkit_Common::prepareQuery( + $dbh, + 'bus_category', + $busCategorySql, + $busCategoryData + ); + + $stmt->execute(); + + $this->coupons->updateCategories($dbh, $this->_id); + $this->members->updateCategories($dbh, $this->_id); + + return $dbh->commit(); + + } catch (PDOException $e) { + Toolkit_Logger::logException('db error', $e); + throw new Toolkit_UserArea_Exception('Error updating page in Database'); + } catch (RuntimeException $e) { + Toolkit_Logger::logException('Runtime Error', $e); + throw new Toolkit_UserArea_Exception($e->getMessage()); + } + } + + // }}} + + // {{{ getCreateDate() + + public function getCreateDate() + { + return $this->_createDate; + } + + // }}} + // {{{ getLastModificationDate() + + public function getLastModificationDate() + { + return $this->_lastModifiedDate; + } + + // }}} + // {{{ getNumberOfRevisions() + + public function getNumberOfRevisions() + { + return $this->_revisions; + } + + // }}} + // {{{ getActive() + + public function getActive() + { + return $this->_active; + } + + // }}} + // {{{ getActiveText() + + public function getActiveText() + { + return $this->_active ? 'Active' : 'In-Active'; + } + + // }}} + + public function getId() + { + return $this->_id; + } +} +?> diff --git a/Toolkit/UserArea/PageBreadCrumbs.php b/Toolkit/UserArea/PageBreadCrumbs.php new file mode 100644 index 0000000..5cb3942 --- /dev/null +++ b/Toolkit/UserArea/PageBreadCrumbs.php @@ -0,0 +1,12 @@ +{$page['navigation_name']}"; + } +} +?> diff --git a/Toolkit/UserArea/PageDraftBreadCrumbs.php b/Toolkit/UserArea/PageDraftBreadCrumbs.php new file mode 100644 index 0000000..914ddaa --- /dev/null +++ b/Toolkit/UserArea/PageDraftBreadCrumbs.php @@ -0,0 +1,72 @@ +{$page['navigation_name']}"; + } + + // }}} + // {{{ getDraft() + + protected function getDraft($id) + { + try { + $sql = " + SELECT * + FROM pages_draft + WHERE id = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + + return $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Could not fetch parent for page `$id`" + ); + } + } + + // }}} + // {{{ getPath() + + /** + * @return the $path + */ + public function getPath() + { + if ($this->id == HOME_ID) { + return; + } + + $draft = $this->getDraft($this->id); + $stack = array($draft['navigation_name']); + + $publishedPage = $this->getPage($draft['published_page']); + $id = $publishedPage['parent']; + while ($id != 0) { + $page = $this->getPage($id); + + $navigationName = $this->getPageUri($page); + + $stack[] = $navigationName; + $id = $page['parent']; + } + + $reverse = array_reverse($stack); + $this->path = implode(' > ', $reverse); + + return $this->path; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/PageGatewayAbstract.php b/Toolkit/UserArea/PageGatewayAbstract.php new file mode 100644 index 0000000..defb275 --- /dev/null +++ b/Toolkit/UserArea/PageGatewayAbstract.php @@ -0,0 +1,280 @@ +dbh->prepare($sql); + $stmt->bindParam(':parent', $parent, PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Error fetching all pages by parent `$parent`" + ); + } + } + + // }}} + // {{{ findByKeyword() + + abstract public function findByKeyword($keyword); + + // }}} + // {{{ findTopParent() + + abstract public function findTopParent($pageId); + + // }}} + // {{{ findPage() + + protected function findPage($id, $pageSql) + { + // if the page has already been fetched, just return it. + if (is_array($this->page) && $this->page['id'] == $id) { + return $this->page; + } + + $pageStatsSql = " + SELECT count(*) AS revised, + MIN(revision_timestamp) AS created, + MAX(revision_timestamp) AS last_modified + FROM pages_history + WHERE id = :id"; + + $pageStmt = $this->dbh->prepare($pageSql); + $pageStmt->bindParam(':id', $id, PDO::PARAM_INT); + $pageStmt->execute(); + + $page = $pageStmt->fetch(PDO::FETCH_ASSOC); + + if ($page === false) { // Page doesn't exist + return false; + } + + if ($this->hasMemberDb()) { + $page['member_categories'] + = $this->getMemberCategoriesForPage($id); + $page['member_regions'] + = $this->getMemberRegionsForPage($id); + } + + if ($this->hasCouponDb()) { + $page['coupon_categories'] + = $this->getCouponCategoriesForPage($id); + } + + if ($this->hasPhotoGallery()) { + $page['photo_galleries'] + = $this->getPhotoGalleriesForPage($id); + } + + $pageStatsStmt = $this->dbh->prepare($pageStatsSql); + $pageStatsStmt->bindParam(':id', $id, PDO::PARAM_INT); + $pageStatsStmt->execute(); + + $pageStats = $pageStatsStmt->fetch(PDO::FETCH_ASSOC); + + $date = new Date(); + $date->setDate(strtotime($pageStats['created']), DATE_FORMAT_UNIXTIME); + $pageStats['created'] = $date->format('%D %r'); + $date->setDate(strtotime($pageStats['last_modified']), DATE_FORMAT_UNIXTIME); + $pageStats['last_modified'] = $date->format('%D %r'); + $page = array_merge($page, $pageStats); + + if (!empty($page['image'])) { + $imgFormat = "\"%s\""; + $page['current_image_original'] = sprintf( + $imgFormat, + $page['image'], + TOOLBOX_ORIGINAL . $page['image'] + ); + $page['current_image_resized'] = sprintf( + $imgFormat, + $page['image'], + TOOLBOX_RESIZED . $page['image'] + ); + $page['current_image_midsized'] = sprintf( + $imgFormat, + $page['image'], + TOOLBOX_MIDSIZED . $page['image'] + ); + $page['current_image_thumb'] = sprintf( + $imgFormat, + $page['image'], + TOOLBOX_THUMB . $page['image'] + ); + } else { + $page['current_image_original'] = 'Image not yet uploaded'; + $page['current_image_resized'] = 'Image not yet uploaded'; + $page['current_image_midsized'] = 'Image not yet uploaded'; + $page['current_image_thumb'] = 'Image not yet uploaded'; + } + + $this->page = $page; + return $this->page; + } + + // }}} + + // {{{ getCurrentPage() + + /** + * Gets the current page for the template if it exists + * + * @return mixed array of current page or false if no current page is set + * @access public + */ + public function getCurrentPage() + { + return is_array($this->page) ? $this->page : false; + } + + // }}} + // {{{ getHomePageHeadlines() + + public function getHomePageHeadlines() + { + $wordCounter = array( + 1 => 'one', + 2 => 'two', + 3 => 'three', + 4 => 'four' + ); + $headlines = array(); + $sql = " + SELECT p1.id, p1.navigation_name, p1.headline_intro, p2.image + FROM pages p1 join paragraphs p2 on (p1.id = p2.page) + WHERE p1.headline = true + AND p1.active = true + AND p2.pos = 1 + ORDER BY p1.parent, p1.pos"; + + $count = 1; + foreach ($this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC) as $row) { + $headlines[] = array( + 'count' => $wordCounter[$count], + 'href' => Toolkit_Template_Page::getSeoUrl($this, $row['id']), + 'img' => ($row['image']) + ? HOMEPAGE_HEADLINE_THUMB . $row['image'] + : '', + 'header' => $row['navigation_name'], + 'descr' => $row['headline_intro'], + ); + if (++$count > 4) { + $count = 1; + } + } + + return $headlines; + } + + // }}} + + // {{{ setPageVars() + + protected function setPageVars(PDOStatement &$stmt, $data) + { + if ($this->hasHeadlines()) { + $data['headline'] = (bool)$data['headline']; + $stmt->bindParam( + ':headline', + $data['headline'], + PDO::PARAM_BOOL + ); + $stmt->bindParam(':headline_intro', $data['headline_intro']); + } + + if ($this->hasMemberDb()) { + $data['include_member_map'] = (bool)$data['include_member_map']; + $data['search_form'] = (bool)$data['search_form']; + $stmt->bindParam( + ':include_member_map', + $data['include_member_map'], + PDO::PARAM_BOOL + ); + $stmt->bindParam( + ':search_form', + $data['search_form'], + PDO::PARAM_BOOL + ); + } + + $stmt->bindParam(':keyword', $data['keyword']); + $stmt->bindParam(':meta_title', $data['meta_title']); + $stmt->bindParam(':meta_description', $data['meta_description']); + $stmt->bindParam(':navigation_name', $data['navigation_name']); + $stmt->bindParam(':parent', $data['parent']); + $stmt->bindParam(':paragraph_links', $data['paragraph_links']); + $stmt->bindParam(':short_url', $data['short_url']); + $stmt->bindParam(':template', $data['template']); + $stmt->bindParam(':include_members', $data['include_members']); + $stmt->bindParam(':include_coupons', $data['include_coupons']); + } + + // }}} + // {{{ setParagraphVars() + + protected function setParagraphVars(PDOStatement &$stmt, $data) + { + if ($data['remove_image']) { + $data['image'] = ''; + } + $stmt->bindParam(':title', $data['title']); + $stmt->bindParam(':description', $data['description']); + $stmt->bindParam(':image', $data['image']); + $stmt->bindParam(':caption', $data['caption']); + } + + // }}} +} diff --git a/Toolkit/UserArea/PageGatewayDraft.php b/Toolkit/UserArea/PageGatewayDraft.php new file mode 100644 index 0000000..3fe3af4 --- /dev/null +++ b/Toolkit/UserArea/PageGatewayDraft.php @@ -0,0 +1,562 @@ +dbh->prepare($pageSql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + // delete from staff + $deleteSql = " + DELETE + FROM staff.staff + WHERE page = :page"; + $delete = $this->dbh->prepare($deleteSql); + $delete->bindParam(':page', $id, PDO::PARAM_INT); + $delete->execute(); + return true; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to delete page draft `$id`" + ); + } + } + + // }}} + public function findNavItem($id) + { + $sql = " + SELECT id,navigation_name,parent,short_url + FROM pages + WHERE id = :id"; + + try { + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam( + ':id', + $id, + PDO::PARAM_INT + ); + $stmt->execute(); + return $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception("Unable to find page `$id`"); + } + } + // {{{ find() + + public function find($id) + { + $pageSql = " + SELECT p1.*, p1.id AS page_id, + CASE p1.active + WHEN true THEN 'active' + ELSE 'In-Active' + END AS active, p2.title, p2.description, p2.image, p2.caption + FROM pages_draft p1 + LEFT JOIN paragraphs_draft p2 + ON p1.id = p2.page + WHERE p1.id = :id + AND (p2.pos = 1 OR p2.pos IS NULL)"; + + try { + return $this->findPage($id, $pageSql); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to find page draft `$id`" + ); + } + } + + // }}} + // {{{ findAll() + + public function findAll() + { + try { + $sql = " + SELECT * + FROM pages_draft + ORDER by parent, pos"; + + return $this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + 'Error fetching all draft pages' + ); + } + } + + // }}} + // {{{ findByKeyword() + + public function findByKeyword($keyword) + { + try { + $pageSql = " + SELECT id + FROM pages_draft + WHERE keyword = :keyword"; + + $stmt = $this->dbh->prepare($pageSql); + $stmt->bindParam(':keyword', $keyword); + $stmt->execute(); + + // Bind by column number + $stmt->bindColumn(1, $id); + + $stmt->fetch(PDO::FETCH_ASSOC); + + return $this->find($id); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to find page draft `$id`" + ); + } + } + + // }}} + // {{{ findTopParent() + + public function findTopParent($pageId, $useDraftTable = true) + { + if (!ctype_digit((string)$pageId)) { + throw new runtimeException("Invalid pageId `$pageId` to fetch"); + } + + try { + if ($useDraftTable) { + $sql = " + SELECT * + FROM pages_draft + WHERE id = :id"; + } else { + $sql = " + SELECT * + FROM pages + WHERE id = :id"; + } + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $pageId, PDO::PARAM_INT); + $stmt->execute(); + + $row = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($row['parent'] == '0') { + return $row['id']; + } else { + return $this->findTopParent($row['parent'], false); + } + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to find parent for page `$pageId`" + ); + } + } + + // }}} + + // {{{ insert() + + public function insert(array $data) + { + if (empty($data['published_page'])) { + settype($data['published_page'], 'null'); + } + + if ($this->hasHeadlines()) { + $headlineColumns = 'headline, headline_intro,'; + $headlineParams = ':headline, :headline_intro,'; + } + + if ($this->hasMemberDb()) { + $memberColumns = 'include_member_map, search_form, '; + $memberParams = ':include_member_map, :search_form, '; + } + + $pageSql = " + INSERT INTO pages_draft ( + $headlineColumns $memberColumns keyword, meta_title, + meta_description, navigation_name, parent, paragraph_links, + short_url, template, published_page, include_members, include_coupons) + VALUES ( + $headlineParams $memberParams :keyword, :meta_title, + :meta_description, :navigation_name, :parent, + :paragraph_links, :short_url, :template, :published_page, :include_members, :include_coupons)"; + + $paragraphSql = " + INSERT INTO paragraphs_draft ( + active, title, description, image, caption, page) + VALUES ( + true, :title, :description, :image, :caption, :page)"; + + try { + $this->dbh->beginTransaction(); + + $pageStmt = $this->dbh->prepare($pageSql); + $this->setPageVars($pageStmt, $data); + $pageStmt->bindParam(':published_page', $data['published_page']); + $pageStmt->execute(); + + $row = $this->dbh + ->query('select id from pages_draft order by id desc limit 1') + ->fetch(PDO::FETCH_ASSOC); + + if (defined('MEMBERS_DB') && MEMBERS_DB) { + $this->_updateMemberCategories( + $data['member_categories'], + $row['id'] + ); + } + + if (defined('COUPONS') && COUPONS) { + $this->_updateCouponCategories( + $data['coupon_categories'], + $row['id'] + ); + $this->_updateMemberCities( + $data['member_regions'], + $row['id'] + ); + } + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->bindParam(':page', $row['id']); + $paragraphStmt->execute(); + + $this->dbh->commit(); + + return $row['id']; + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to insert page draft [$content]" + ); + } + } + + // }}} + + // {{{ update() + + public function update(array $data, $id) + { + if ($this->hasHeadlines()) { + $headlineColumns = ' + headline = :headline, + headline_intro = :headline_intro, '; + } + + if ($this->hasMemberDb()) { + $memberColumns = ' + include_member_map = :include_member_map, + search_form = :search_form, '; + } + + $pageSql = " + UPDATE pages_draft + SET $headlineColumns + $memberColumns + keyword = :keyword, + meta_title = :meta_title, + meta_description = :meta_description, + navigation_name = :navigation_name, + parent = :parent, + paragraph_links = :paragraph_links, + short_url = :short_url, + template = :template, + include_members = :include_members, + include_coupons = :include_coupons + WHERE id = :id"; + + $paragraphSql = " + UPDATE paragraphs_draft + SET title = :title, + description = :description, + image = :image, + caption = :caption + WHERE page = :page + AND pos = 1"; + + try { + $this->dbh->beginTransaction(); + + $pageStmt = $this->dbh->prepare($pageSql); + $this->setPageVars($pageStmt, $data); + $pageStmt->bindParam(':id', $id, PDO::PARAM_INT); + $pageStmt->execute(); + + if (defined('MEMBERS_DB') && MEMBERS_DB) { + $this->_updateMemberCategories($data['member_categories'], $id); + $this->_updateMemberCities($data['member_regions'], $id); + } + if (defined('COUPONS') && COUPONS) { + $this->_updateCouponCategories($data['coupon_categories'], $id); + } + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->bindParam(':page', $id); + $paragraphStmt->execute(); + + return $this->dbh->commit(); + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to update page draft [$content]" + ); + } + } + + // }}} + + // {{{ _updateMemberCategories() + + private function _updateMemberCategories(array $data = null, $id) + { + $deleteCatsSql = " + DELETE FROM member_categories2toolbox_pages_draft + WHERE page = :id"; + $delStmt = $this->dbh->prepare($deleteCatsSql); + $delStmt->bindParam(':id', $id, PDO::PARAM_INT); + $delStmt->execute(); + + if (is_array($data)) { + $insertCatsSql = " + INSERT INTO member_categories2toolbox_pages_draft (page, category) + VALUES (:page, :category)"; + $insStmt = $this->dbh->prepare($insertCatsSql); + $insStmt->bindParam(':page', $id, PDO::PARAM_INT); + foreach ($data as $category) { + $insStmt->bindParam(':category', $category, PDO::PARAM_INT); + $insStmt->execute(); + } + } + } + + // }}} + // {{{ getMemberCategoriesForPage() + + protected function getMemberCategoriesForPage($id) + { + try { + $sql = " + SELECT * + FROM member_categories2toolbox_pages_draft + WHERE page = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $categories = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $categories[] = $row['category']; + } + + return $categories; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch member categories for page draft `$id`" + ); + } + } + + // }}} + + // {{{ _updateMemberCities() + + private function _updateMemberCities(array $data = null, $id) + { + $deleteCitiesSql = " + DELETE FROM member_regions2toolbox_pages_draft + WHERE page = :id"; + $delStmt = $this->dbh->prepare($deleteCitiesSql); + $delStmt->bindParam(':id', $id, PDO::PARAM_INT); + $delStmt->execute(); + + if (is_array($data)) { + $insertCitiesSql = " + INSERT INTO member_regions2toolbox_pages_draft (page, region) + VALUES (:page, :region)"; + $insStmt = $this->dbh->prepare($insertCitiesSql); + $insStmt->bindParam(':page', $id, PDO::PARAM_INT); + foreach ($data as $region) { + $insStmt->bindParam(':region', $region, PDO::PARAM_INT); + $insStmt->execute(); + } + } + } + + // }}} + // // {{{ getMemberRegionsForPage() + + protected function getMemberRegionsForPage($id) + { + try { + $sql = " + SELECT * + FROM member_regions2toolbox_pages_draft + WHERE page = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $regions = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $regions[] = $row['region']; + } + + return $regions; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch member regions for page `$id`" + ); + } + } + + // }}} + // {{{ getMemberCitiesForPage() + + protected function getMemberCitiesForPage($id) + { + try { + $sql = " + SELECT * + FROM member_regions2toolbox_pages_draft + WHERE page = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $regions = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $regions[] = $row['region']; + } + + return $regions; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch member regions for page `$id`" + ); + } + } + + // }}} + + // {{{ _updateCouponCategories() + + private function _updateCouponCategories(array $data = null, $id) + { + $deleteCatsSql = " + DELETE FROM coupon_categories2toolbox_pages_draft + WHERE page = :id"; + $delStmt = $this->dbh->prepare($deleteCatsSql); + $delStmt->bindParam(':id', $id, PDO::PARAM_INT); + $delStmt->execute(); + + if (is_array($data)) { + $insertCatsSql = " + INSERT INTO coupon_categories2toolbox_pages_draft (page, category) + VALUES (:page, :category)"; + $insStmt = $this->dbh->prepare($insertCatsSql); + $insStmt->bindParam(':page', $id, PDO::PARAM_INT); + foreach ($data as $category) { + $insStmt->bindParam(':category', $category, PDO::PARAM_INT); + $insStmt->execute(); + } + } + } + + // }}} + // {{{ getCouponCategoriesForPage() + + protected function getCouponCategoriesForPage($id) + { + try { + $sql = " + SELECT * + FROM coupon_categories2toolbox_pages_draft + WHERE page = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $categories = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $categories[] = $row['category']; + } + + return $categories; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch coupon categories for page draft `$id`" + ); + } + } + + // }}} + + // {{{ getPhotoGalleriesForPage() + + protected function getPhotoGalleriesForPage($id) + { + try { + $sql = " + SELECT pc.* + FROM photo_category pc + JOIN photo_category_bus pcb + ON (pc.id = pcb.photocat_id) + JOIN pages_draft pd + ON (pd.published_page = pcb.buscat_id) + WHERE pcb.buscat_id = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $photoGalleries = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photoGalleries[$row['id']] = $row['category']; + } + + return $photoGalleries; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch member categories for page `$id`" + ); + } + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/PageGatewayDraftFactory.php b/Toolkit/UserArea/PageGatewayDraftFactory.php new file mode 100644 index 0000000..68237e6 --- /dev/null +++ b/Toolkit/UserArea/PageGatewayDraftFactory.php @@ -0,0 +1,10 @@ +dbh); + } +} +?> diff --git a/Toolkit/UserArea/PageGatewayPublish.php b/Toolkit/UserArea/PageGatewayPublish.php new file mode 100644 index 0000000..643f8e1 --- /dev/null +++ b/Toolkit/UserArea/PageGatewayPublish.php @@ -0,0 +1,758 @@ +dbh->beginTransaction(); + + $this->dbh->query($createTableSql); + + $stmt = $this->dbh->prepare($pageSql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + + // delete from staff + $deleteSql = " + DELETE + FROM staff.staff + WHERE page = :page"; + $delete = $this->dbh->prepare($deleteSql); + $delete->bindParam(':page', $id, PDO::PARAM_INT); + $delete->execute(); + // delete from staff contacts + $deleteSql = " + DELETE + FROM staff.contacts + WHERE page = :page"; + $delete = $this->dbh->prepare($deleteSql); + $delete->bindParam(':page', $id, PDO::PARAM_INT); + $delete->execute(); + + return $this->dbh->commit(); + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to delete subtree `$id`" + ); + } + } + + // }}} + + // {{{ find() + + public function find($id) + { + $pageSql = " + SELECT p1.*, p1.id AS page_id, p1.id AS published_page, + CASE p1.active + WHEN CAST(1 AS BOOLEAN) THEN 'active' + ELSE 'In-Active' + END AS active_alt, p2.title, p2.description, p2.image, p2.caption + FROM pages p1 + LEFT JOIN paragraphs p2 + ON p1.id = p2.page + WHERE p1.id = :id + AND (p2.pos = 1 OR p2.pos IS NULL)"; + + try { + return $this->findPage($id, $pageSql); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception("Unable to find page `$id`"); + } + } + + // }}} + public function findNavItem($id) + { + $sql = " + SELECT id,navigation_name,parent,short_url + FROM pages + WHERE id = :id"; + + try { + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam( + ':id', + $id, + PDO::PARAM_INT + ); + $stmt->execute(); + return $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception("Unable to find page `$id`"); + } + } + // {{{ findAll() + + public function findAll() + { + $authContainer = new Toolkit_UserArea_Auth_Container( + Toolkit_Database::getInstance() + ); + + $userAuth = new Toolkit_UserArea_Auth( + $authContainer, + '', + false + ); + $userAuth->setIdle(); + $userAuth->start(); + if ($userAuth->checkAuth()) { + $page = $userAuth->getUserPageId($this->dbh); + $categories = Toolkit_Common::getHierarchicalTreeStructure( + $this->dbh, + 'pages', + 'id', + 'parent', + 'pos', + $page + ); + $categories[$page] = 1; + } else { + return array(); + } + try { + $sql = " + SELECT * + FROM pages + WHERE id IN (".implode(',', array_keys($categories)).") + ORDER by parent, pos"; + return $this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + 'Error fetching all published pages' + ); + } + } + + // }}} + // {{{ findByKeyword() + + public function findByKeyword($keyword) + { + try { + $pageSql = " + SELECT id + FROM pages + WHERE keyword = :keyword"; + + $stmt = $this->dbh->prepare($pageSql); + $stmt->bindParam(':keyword', $keyword); + $stmt->execute(); + + // Bind by column number + $stmt->bindColumn(1, $id); + + $stmt->fetch(PDO::FETCH_ASSOC); + + return $this->findNavItem($id); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to find keyword `$keyword`" + ); + } + } + + // }}} + // {{{ findTopParent() + + public function findTopParent($pageId) + { + if (!filter_var($pageId, FILTER_VALIDATE_INT)) { + throw new runtimeException("Invalid pageId `$pageId` to fetch"); + } + + try { + $sql = " + SELECT parent,id + FROM pages + WHERE id = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $pageId, PDO::PARAM_INT); + $stmt->execute(); + + $row = $stmt->fetch(PDO::FETCH_ASSOC); + if (!$stmt->rowCount()) { + return false; + } + + if ($row['parent'] == '0') { + return $row['id']; + } else { + return $this->findTopParent($row['parent']); + } + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to find parent for page `$pageId`" + ); + } + } + + // }}} + + // {{{ insert() + + public function insert(array $data) + { + if ($this->hasHeadlines()) { + $headlineColumns = 'headline, headline_intro,'; + $headlineParams = ':headline, :headline_intro,'; + } + + if ($this->hasMemberDb()) { + $memberColumns = 'include_member_map, search_form, '; + $memberParams = ':include_member_map, :search_form, '; + } + + $pageSql = " + INSERT INTO pages ( + $headlineColumns $memberColumns keyword, meta_title, + meta_description, navigation_name, parent, paragraph_links, + short_url, template, include_members, include_coupons) + VALUES ( + $headlineParams $memberParams :keyword, :meta_title, + :meta_description, :navigation_name, :parent, + :paragraph_links, :short_url, :template, :include_members, :include_coupons) + RETURNING id"; + + $paragraphSql = " + INSERT INTO paragraphs ( + active, title, description, image, caption, page) + VALUES ( + true, :title, :description, :image, :caption, :page)"; + + try { + $this->dbh->beginTransaction(); + + $pageStmt = $this->dbh->prepare($pageSql); + $this->setPageVars($pageStmt, $data); + $pageStmt->execute(); + + $pageId = $pageStmt->fetchColumn(); + + if (defined('MEMBERS_DB') && MEMBERS_DB) { + $this->_updateMemberCategories( + $data['member_categories'], + $pageId + ); + $this->_updateMemberRegions( + $data['member_regions'], + $pageId + ); + } + + if (defined('COUPONS') && COUPONS) { + $this->_updateCouponCategories( + $data['coupon_categories'], + $pageId + ); + } + $this->_updateStaff($data, $pageId); + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->bindParam(':page', $pageId); + $paragraphStmt->execute(); + + // for some reason when Jodie is adding new pages the page position + // get messed up maybe more than one person it adding or updating + // pages I don't know either way when adding in new pages + // we'll have to go through all pages that have the same + // parent and redo the page positions so they don't get off order + $sql = " + SELECT id,pos + FROM pages + WHERE parent = :parent + ORDER BY pos"; + $stmt = $this->dbh->prepare($sql); + $sql = " + UPDATE pages + SET pos = :pos + WHERE id = :id"; + $updatePositionOfPage = $this->dbh->prepare($sql); + $stmt->bindParam(':parent', $data['parent'], PDO::PARAM_INT); + $stmt->execute(); + $pos = 1; + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $updatePositionOfPage->bindParam( + ':id', + $row['id'], + PDO::PARAM_INT + ); + $updatePositionOfPage->bindParam( + ':pos', + $pos, + PDO::PARAM_INT + ); + $updatePositionOfPage->execute(); + ++$pos; + } + + $this->dbh->commit(); + + return $pageId; + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to insert page [$content]" + ); + } + } + + // }}} + + // {{{ update() + + public function update(array $data, $id) + { + $deleteContacts = array(); + foreach ($data as $key => $value) { + if (preg_match('%deleteStaff-([0-9]*)%', $key, $matches)) { + $deleteContacts[] = $matches[1]; + } + } + if ($this->hasHeadlines()) { + $headlineColumns = ' + headline = :headline, + headline_intro = :headline_intro, '; + } + + if ($this->hasMemberDb()) { + $memberColumns = ' + include_member_map = :include_member_map, + search_form = :search_form, '; + } + + try { + $this->dbh->beginTransaction(); + // need to know if we're moving this to another parent + $sql = " + SELECT parent, pos + FROM pages + WHERE id = :id"; + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam( + ":id", + $id, + PDO::PARAM_INT + ); + $stmt->execute(); + + // the old parent of the page + $oldData = $stmt->fetch(PDO::FETCH_ASSOC); + $oldParent = $oldData['parent']; + $oldPos = $oldData['pos']; + if ($data['parent'] != $oldParent) { + // adjust the old level to normal + $sql = " + UPDATE pages + SET pos = pos - 1 + WHERE pos > :pos + AND parent = :parent + "; + $preStmt = $this->dbh->prepare($sql); + $preStmt->bindParam( + ":parent", + $oldParent, + PDO::PARAM_INT + ); + $preStmt->bindParam( + ":pos", + $oldPos, + PDO::PARAM_INT + ); + $preStmt->execute(); + // if it is then get next position number for new parent + $sql = " + SELECT max(pos) + 1 + FROM pages + WHERE parent = :parent"; + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam( + ":parent", + $data['parent'], + PDO::PARAM_INT + ); + $stmt->execute(); + $pos = $stmt->fetchColumn(); + } + + $pageSql = " + UPDATE pages + SET $headlineColumns + $memberColumns + keyword = :keyword, + meta_title = :meta_title, + meta_description = :meta_description, + navigation_name = :navigation_name, + parent = :parent, + paragraph_links = :paragraph_links, + short_url = :short_url, + template = :template , + include_members = :include_members, + include_coupons = :include_coupons"; + if ($pos) { + $pageSql .= ", pos = $pos "; + } + + $pageSql .= " + WHERE id = :id"; + + $paragraphSql = " + UPDATE paragraphs + SET title = :title, + description = :description, + image = :image, + caption = :caption + WHERE page = :page + AND pos = 1"; + + $pageStmt = $this->dbh->prepare($pageSql); + $this->setPageVars($pageStmt, $data); + $pageStmt->bindParam(':id', $id, PDO::PARAM_INT); + $pageStmt->execute(); + + if (defined('MEMBERS_DB') && MEMBERS_DB) { + $this->_updateMemberCategories($data['member_categories'], $id); + $this->_updateMemberRegions($data['member_regions'], $id); + } + if (defined('COUPONS') && COUPONS) { + $this->_updateCouponCategories($data['coupon_categories'], $id); + } + $this->_updateStaff($data, $id, $deleteContacts); + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->bindParam(':page', $id); + $paragraphStmt->execute(); + + return $this->dbh->commit(); + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to update page [$content]" + ); + } + } + + // }}} + + // {{{ _updateMemberCategories() + + private function _updateMemberCategories(array $data = null, $id) + { + $deleteCatsSql = " + DELETE FROM member_categories2toolbox_pages + WHERE page = :id"; + $delStmt = $this->dbh->prepare($deleteCatsSql); + $delStmt->bindParam(':id', $id, PDO::PARAM_INT); + $delStmt->execute(); + + if (is_array($data)) { + $insertCatsSql = " + INSERT INTO member_categories2toolbox_pages (page, category) + VALUES (:page, :category)"; + $insStmt = $this->dbh->prepare($insertCatsSql); + $insStmt->bindParam(':page', $id, PDO::PARAM_INT); + foreach ($data as $category) { + $insStmt->bindParam(':category', $category, PDO::PARAM_INT); + $insStmt->execute(); + } + } + } + + // }}} + // {{{ getMemberCategoriesForPage() + + protected function getMemberCategoriesForPage($id) + { + try { + $sql = " + SELECT * + FROM member_categories2toolbox_pages + WHERE page = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $categories = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $categories[] = $row['category']; + } + + return $categories; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch member categories for page `$id`" + ); + } + } + + // }}} + + // {{{ _updateMemberRegions() + + private function _updateMemberRegions(array $data = null, $id) + { + $deleteRegionsSql = " + DELETE FROM member_regions2toolbox_pages + WHERE page = :id"; + $delStmt = $this->dbh->prepare($deleteRegionsSql); + $delStmt->bindParam(':id', $id, PDO::PARAM_INT); + $delStmt->execute(); + + if (is_array($data)) { + $insertRegionsSql = " + INSERT INTO member_regions2toolbox_pages (page, region) + VALUES (:page, :region)"; + $insStmt = $this->dbh->prepare($insertRegionsSql); + $insStmt->bindParam(':page', $id, PDO::PARAM_INT); + foreach ($data as $region) { + $insStmt->bindParam(':region', $region, PDO::PARAM_INT); + $insStmt->execute(); + } + } + } + + // }}} + // {{{ getMemberRegionsForPage() + + protected function getMemberRegionsForPage($id) + { + try { + $sql = " + SELECT * + FROM member_regions2toolbox_pages + WHERE page = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $regions = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $regions[] = $row['region']; + } + + return $regions; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch member regions for page `$id`" + ); + } + } + + // }}} + + // {{{ _updateCouponCategories() + + private function _updateCouponCategories(array $data = null, $id) + { + $deleteCatsSql = " + DELETE FROM coupon_categories2toolbox_pages + WHERE page = :id"; + $delStmt = $this->dbh->prepare($deleteCatsSql); + $delStmt->bindParam(':id', $id, PDO::PARAM_INT); + $delStmt->execute(); + + if (is_array($data)) { + $insertCatsSql = " + INSERT INTO coupon_categories2toolbox_pages (page, category) + VALUES (:page, :category)"; + $insStmt = $this->dbh->prepare($insertCatsSql); + $insStmt->bindParam(':page', $id, PDO::PARAM_INT); + foreach ($data as $category) { + $insStmt->bindParam(':category', $category, PDO::PARAM_INT); + $insStmt->execute(); + } + } + } + + // }}} + // {{{ getCouponCategoriesForPage() + + protected function getCouponCategoriesForPage($id) + { + try { + $sql = " + SELECT * + FROM coupon_categories2toolbox_pages + WHERE page = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $categories = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $categories[] = $row['category']; + } + + return $categories; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch coupon categories for page `$id`" + ); + } + } + + // }}} + + // {{{ getPhotoGalleriesForPage() + + protected function getPhotoGalleriesForPage($id) + { + try { + $sql = " + SELECT pc.* + FROM photo_category pc + JOIN photo_category_bus pcb + ON (pc.id = pcb.photocat_id) + WHERE pcb.buscat_id = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id); + $stmt->execute(); + + $photoGalleries = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $photoGalleries[$row['id']] = $row['category']; + } + + return $photoGalleries; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to fetch member categories for page `$id`" + ); + } + } + + // }}} + + protected function _updateStaff( + $data = null, + $pageId = null, + $deletedContacts = null + ) { + // does this page have a staff already + $staffModel = new Toolkit_Staff_Models_Staff(); + if ($pageId) { + $sql = " + SELECT id + FROM staff.staff + WHERE page = :page"; + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':page', $pageId, PDO::FETCH_ASSOC); + $stmt->execute(); + $staffId = $stmt->fetchColumn(); + } + $staffData = $data['staff']; + $staff = $staffModel->createByValues( + array( + 'id' => (($staffId) ? $staffId : null), + 'page' => $pageId, + 'department' => $staffData['department'], + 'name' => $staffData['name'], + 'email' => $staffData['email'], + 'phone' => $staffData['phone'], + 'office_address' => $staffData['office_address'], + 'office_address2' => $staffData['office_address2'], + 'office_city' => $staffData['office_city'], + 'office_state' => $staffData['office_state'], + 'office_zip' => $staffData['office_zip'], + 'office_email' => $staffData['office_email'], + 'office_phone' => $staffData['office_phone'], + 'office_fax' => $staffData['office_fax'], + 'office_hours' => $staffData['office_hours'] + ) + ); + $staff->save($this->dbh); + + $contacts = $data['staff_contacts']; + $newContacts = $data['staff_contacts']['new']; + $pos = 1; + if (!empty($contacts)) { + unset($contacts['new']); + foreach ($contacts as $contactId => $contactData) { + if (filter_var($contactId, FILTER_VALIDATE_INT)) { + $contactModel = new Toolkit_Staff_Models_Contact(); + $contact = $contactModel->createByValues( + $contactData + ); + $contact->setId($contactId); + $contact->setPage($pageId); + $contact->setPos($pos); + $contact->save($this->dbh); + ++$pos; + } + } + } + if (!empty($newContacts)) { + foreach ($newContacts as $contactData) { + if ( !$contactData['title'] + && !$contactData['name'] + && !$contactData['email'] + && !$contactData['phone'] + ) { + continue; + } + $contactModel = new Toolkit_Staff_Models_Contact(); + $contact = $contactModel->createByValues( + array( + 'page' => $pageId, + 'title' => $contactData['title'], + 'name' => $contactData['name'], + 'email' => $contactData['email'], + 'phone' => $contactData['phone'], + 'pos' => $pos + ) + ); + $contact->save($this->dbh); + ++$pos; + } + } + if ( is_array($deletedContacts) + && !empty($deletedContacts) + ) { + foreach ($deletedContacts as $deleteId) { + if (filter_var($deleteId, FILTER_VALIDATE_INT)) { + $contactModel = new Toolkit_Staff_Models_Contact(); + $contact = $contactModel->fetchById( + $this->dbh, + $deleteId + ); + $contact->delete($this->dbh); + } + } + } + } +} diff --git a/Toolkit/UserArea/PageGatewayPublishFactory.php b/Toolkit/UserArea/PageGatewayPublishFactory.php new file mode 100644 index 0000000..118218d --- /dev/null +++ b/Toolkit/UserArea/PageGatewayPublishFactory.php @@ -0,0 +1,9 @@ +dbh); + } +} diff --git a/Toolkit/UserArea/PagesTree.php b/Toolkit/UserArea/PagesTree.php new file mode 100644 index 0000000..9244f10 --- /dev/null +++ b/Toolkit/UserArea/PagesTree.php @@ -0,0 +1,292 @@ +\n"; + protected $leafStart = "\n\t
    • \n"; + + protected $toolbox; + + // }}} + // {{{ getActiveBall() + + protected function getActiveBall(array $branch) + { + $key = array_key_exists('published_page', $branch) + ? 'published_page' + : 'id'; + $homePage = ($branch[$key] == HOME_ID); + $memberDbHomePage = (defined('MEMBERS_DB') + && MEMBERS_DB + && $branch[$key] == MEMBERS_ONLY_HOME_PAGE); + + if ($homePage || $memberDbHomePage) { + return 'Active Ball'; + } + + $activeFormat = ''; + $activeFormat .= $this->getActiveBallImage($branch); + $activeFormat .= ''; + + return sprintf( + $activeFormat, + $branch['id'], + MEDIA_BASE_URL . "userArea/toolbox.php?id={$branch['id']}", + $branch['active_alt'] + ); + } + + // }}} + // {{{ getActiveMobileBall() + + protected function getActiveMobileBall(array $branch) + { + $key = array_key_exists('published_page', $branch) + ? 'published_page' + : 'id'; + $nonMobilePages + = (defined('NON_MOBILE_PAGES')) + ? unserialize(NON_MOBILE_PAGES) + : array(); + $nonMobilePages[] = HOME_ID; + if (defined('MEMBERS_DB') && MEMBERS_DB) { + $nonMobilePages[] = MEMBERS_ONLY_HOME_PAGE; + $nonMobilePages[] = MEMBERS_CATEGORY; + } + + if (in_array($branch[$key], $nonMobilePages)) { + return 'Active Ball'; + } + + $activeFormat = ''; + $activeFormat .= $this->getActiveMobileBallImage($branch); + $activeFormat .= ''; + + return sprintf( + $activeFormat, + $branch['id'], + MEDIA_BASE_URL . "userArea/toolbox.php?id={$branch['id']}", + $branch['active_alt'] + ); + } + + // }}} + // {{{ _getMoveArrows() + + private function _getMoveArrows($branch) + { + $homePage = ($branch['id'] == HOME_ID); + $memberDbHomePage = (defined('MEMBERS_DB') + && MEMBERS_DB + && $branch['id'] == MEMBERS_ONLY_HOME_PAGE); + + if ($homePage || $memberDbHomePage) { + $format = '%s'; + + $up = sprintf( + $format, + MEDIA_APP_BASE_URL . "assets/icons/arrow_up.png", + 'Move Up Arrow' + ); + + $down = sprintf( + $format, + MEDIA_APP_BASE_URL . "assets/icons/arrow_down.png", + 'Move Down Arrow' + ); + } else { + $format = 'Move %s Arrow'; + + $up = sprintf( + $format, + MEDIA_APP_BASE_URL . "assets/icons/arrow_up.png", + 'Up', + 'Up' + ); + + $down = sprintf( + $format, + MEDIA_APP_BASE_URL . "assets/icons/arrow_down.png", + 'Down', + 'Down' + ); + } + + + return $up . $down; + } + + // }}} + + private function _getPositionSelect($branch)/*{{{*/ + { + $homePage = ($branch['id'] == HOME_ID); + $memberDbHomePage = (defined('MEMBERS_DB') + && MEMBERS_DB + && $branch['id'] == MEMBERS_ONLY_HOME_PAGE); + $authUser = Registry::get('Toolkit_UserArea_Auth'); + $mainPageId = $authUser->getAuthData('page'); + $isMainPage = ($mainPageId == $branch['id']); + if ($homePage || $memberDbHomePage || $isMainPage) { + return ''; + } else { + $addClass + = ($branch['parent'] == 0 || $branch['parent'] == MEMBERS_CATEGORY) + ? 'pos-select parent-level-sel' + : 'pos-select'; + $showOn + = ($_GET['showpos']) + ? 'display:' + : 'display:none;'; + return ''; + } + }/*}}}*/ + + // {{{ createTree() + + protected function createTree(array $tree, $leaf, $level = 0) + { + $html = !$level ? $this->rootNodeStart : $this->subTreeStart; + + if ($level == 0) { + $lockMainNavPages = $this->config + ->getItem('section', 'conf') + ->getItem('directive', 'lockMainNavPages') + ->getContent(); + } else { + $lockMainNavPages = false; + } + + if (is_array($leaf) && !empty($leaf)) { + while (list($parent, $branch) = each($leaf)) { + if ($branch['id'] == HOME_ID) { + $html .= sprintf($this->leafStart, $branch['id'], 'rel="root"'); + } else { + $html .= sprintf($this->leafStart, $branch['id'], null); + } + if ( defined('MEMBERS_CATEGORY') + && MEMBERS_CATEGORY + && $branch['parent'] == MEMBERS_CATEGORY + ) { + $memberOnlyBase =MEDIA_BASE_URL . "members-only-area/"; + switch ($branch['id']) { + case MEMBERS_PROFILE_FORM_PAGE : + $previewUrl = $memberOnlyBase + . "?rt=EditProfile&tab=info"; + break; + case MEMBERS_COUPONS_PAGE : + $previewUrl = $memberOnlyBase + . "?rt=Coupons&page_id={$branch['id']}"; + break; + case MEMBERS_EVENTS_PAGE : + $previewUrl = $memberOnlyBase + . "?rt=Events&page_id={$branch['id']}"; + break; + case MEMBERS_LEADS_PAGE : + $previewUrl = $memberOnlyBase + . "?rt=Leads&page_id={$branch['id']}"; + break; + case MEMBERS_REPORTS_PAGE : + $previewUrl = $memberOnlyBase + . "?rt=Reports&page_id={$branch['id']}"; + break; + case MEMBERS_ADD_JOB_PAGE : + $previewUrl = $memberOnlyBase + . "?rt=Jobs&ac=addJob&page_id={$branch['id']}"; + break; + case MEMBERS_SHOW_JOBS_PAGE : + $previewUrl = $memberOnlyBase + . "?rt=Jobs&page_id={$branch['id']}"; + break; + default: + $previewUrl = $memberOnlyBase + . "?page_id={$branch['id']}"; + break; + } + + } else { + $previewUrl = BASE_URL . "index.php?catid={$branch['id']}&preview=1"; + } + + $html .= '
      '; + + $html .= 'Top +Section '; + $html .= 'Paragraphs '; + $html .= '[Preview] '; + if (!$lockMainNavPages) { + $html .= $this->getActiveBall($branch); + if (defined("MOBILE_SITE") && MOBILE_SITE) { + $html .= $this->getActiveMobileBall($branch); + } + $html .= $this->_getPositionSelect($branch); + } + + $html .= '
      '; + $html .= "{$branch['navigation_name']}"; + + if ($tree[$parent]) { + $html .= $this->createTree($tree, $tree[$parent], $level + 1); + } else { + $html .= $this->leafEnd; + } + } + } + + $html .= $this->treeEnd; + if ($level) { + $html .= $this->leafEnd; + } + return $html; + } + + // }}} + + // {{{ fetchContent() + + protected function fetchContent(Toolkit_UserArea_GatewayAbstract $gateway) + { + $pages = $gateway->findAll(); + if (is_array($pages)) { + $threads = array(); + foreach ($pages as $page) { + if (!empty($page['keyword'])) { + $page['navigation_name'] .= ' {' . $page['keyword'] . '}'; + } + $page['active_alt'] = $page['active'] ? 'On' : 'Off'; + $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(); + } + } + + // }}} + + // {{{ toHtml() + + public function toHtml(Toolkit_UserArea_GatewayAbstract $gateway) + { + $GLOBALS['bottomScripts'][] = MEDIA_BASE_URL . 'Toolkit/UserArea/libjs/pagesTree.js'; + $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/plugins/jsTree/0.9.9a2/jquery.tree.js'; + $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/plugins/jsTree/0.9.9a2/lib/jquery.cookie.js'; + $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/plugins/jsTree/0.9.9a2/plugins/jquery.tree.cookie.js'; + + $this->fetchContent($gateway); + $html = parent::toHtml(); + + return "
      $html
      "; + } + + // }}} +} diff --git a/Toolkit/UserArea/ParagraphBreadCrumbs.php b/Toolkit/UserArea/ParagraphBreadCrumbs.php new file mode 100644 index 0000000..e3d1609 --- /dev/null +++ b/Toolkit/UserArea/ParagraphBreadCrumbs.php @@ -0,0 +1,51 @@ +{$page['navigation_name']}"; + } + + // }}} + // {{{ getPath() + + /** + * @return the $path + */ + public function getPath() + { + $id = $this->id; + $authData = $this->getAuthData(); + $stack = array(); + do { + $page = $this->getPage($id); + + $stack[] = $this->getPageUri($page); + if (AUTH_USER_PAGE_ID && $id == AUTH_USER_PAGE_ID) { + $id = 0; + } else { + $id = $page['parent']; + } + } while ($id != 0); + + $reverse = array_reverse($stack); + + if (filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) { + $uri = MEDIA_BASE_URL . "userArea/toolbox.php?rt=Paragraphs&pageid={$this->id}"; + $reverse[] = "Paragraphs"; + } + + $this->path = implode(' > ', $reverse); + + return $this->path; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphDraftBreadCrumbs.php b/Toolkit/UserArea/ParagraphDraftBreadCrumbs.php new file mode 100644 index 0000000..fc7092b --- /dev/null +++ b/Toolkit/UserArea/ParagraphDraftBreadCrumbs.php @@ -0,0 +1,80 @@ +{$page['navigation_name']}"; + } + + // }}} + // {{{ getDraft() + + protected function getDraft($id) + { + try { + $sql = " + SELECT * + FROM pages_draft + WHERE id = :id"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + + return $stmt->fetch(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Could not fetch parent for page `$id`" + ); + } + } + + // }}} + // {{{ getPath() + + /** + * @return the $path + */ + public function getPath() + { + $draft = $this->getDraft($this->id); + + if (filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)) { + $uri = MEDIA_BASE_URL . "userArea/toolbox.php?rt=ParagraphsDraft&pageid={$this->id}"; + $stack = array("Paragraphs"); + } + + if (is_array($stack)) { + $stack[] = $this->getPageUri($draft); + } else { + $stack = array($draft['navigation_name']); + } + + $publishedPage = $this->getPage($draft['published_page']); + $id = $publishedPage['parent']; + while ($id != 0) { + $page = $this->getPage($id); + + $stack[] = $this->getPageUri($page); + $id = $page['parent']; + } + + $reverse = array_reverse($stack); + + $this->path = implode(' > ', $reverse); + + return $this->path; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphGatewayAbstract.php b/Toolkit/UserArea/ParagraphGatewayAbstract.php new file mode 100644 index 0000000..c0b5d18 --- /dev/null +++ b/Toolkit/UserArea/ParagraphGatewayAbstract.php @@ -0,0 +1,49 @@ +bindParam(':active', $data['active'], PDO::PARAM_BOOL); + $stmt->bindParam(':title', $data['title']); + $stmt->bindParam(':description', $data['description']); + $stmt->bindParam(':image', $data['image']); + $stmt->bindParam(':caption', $data['caption']); + $stmt->bindParam(':page', $data['page']); + $stmt->bindParam(':back_to_top', $data['back_to_top'], PDO::PARAM_BOOL); + } + + // }}} + // {{{ setFileVars() + + protected function setFileVars(PDOStatement &$stmt, $data, $key) + { + $stmt->bindParam(':filename', $data['filename'][$key]); + $stmt->bindParam(':bytes', $data['bytes'][$key]); + $stmt->bindParam(':urltext', $data['urltext'][$key]); + if ($data['type'][$key] != DIRECTORY_SEPARATOR) { + $stmt->bindParam(':type', $data['type'][$key]); + } else { + $pieces = explode('.', $data['filename'][$key]); + $extension = end($pieces); + $stmt->bindParam(':type', $extension); + } + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphGatewayDraft.php b/Toolkit/UserArea/ParagraphGatewayDraft.php new file mode 100644 index 0000000..baa08c5 --- /dev/null +++ b/Toolkit/UserArea/ParagraphGatewayDraft.php @@ -0,0 +1,225 @@ +dbh->prepare($pageSql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + return $stmt->execute(); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to delete paragraph draft `$id`" + ); + } + } + + // }}} + + // {{{ find() + + public function find($id) + { + $paragraphSql = " + SELECT * + FROM paragraphs_draft + WHERE id = :id "; + + $fileSql = " + SELECT * + FROM files_draft + WHERE paragraph = :paragraph + ORDER BY pos"; + + try { + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $paragraphStmt->bindParam(':id', $id, PDO::PARAM_INT); + $paragraphStmt->execute(); + + $paragraph = $paragraphStmt->fetch(PDO::FETCH_ASSOC); + + if (!empty($paragraph['image'])) { + $imgFormat = ""; + $paragraph['current_image_original'] + = sprintf($imgFormat, TOOLBOX_ORIGINAL); + $paragraph['current_image_resized'] + = sprintf($imgFormat, TOOLBOX_RESIZED); + $paragraph['current_image_midsized'] + = sprintf($imgFormat, TOOLBOX_MIDSIZED); + $paragraph['current_image_thumb'] + = sprintf($imgFormat, TOOLBOX_THUMB); + } else { + $paragraph['current_image_original'] = 'Image not yet uploaded'; + $paragraph['current_image_resized'] = 'Image not yet uploaded'; + $paragraph['current_image_midsized'] = 'Image not yet uploaded'; + $paragraph['current_image_thumb'] = 'Image not yet uploaded'; + } + + $fileStmt = $this->dbh->prepare($fileSql); + $fileStmt->bindParam(':paragraph', $id, PDO::PARAM_INT); + $fileStmt->execute(); + + $paragraph['files'] = $fileStmt->fetchAll(PDO::FETCH_ASSOC); + + return $paragraph; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to find paragraph draft `$id`" + ); + } + } + + // }}} + // {{{ findAll() + + public function findAll($page) + { + try { + $sql = " + SELECT * + FROM paragraphs_draft + WHERE page = :page + AND pos > 1 + ORDER BY pos"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':page', $page); + $stmt->execute(); + + $paragraphs = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $paragraphs[] = $this->find($row['id']); + } + + return $paragraphs; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Error fetching all paragraph drafts for page `$page`" + ); + } + } + + // }}} + + // {{{ insert() + + public function insert(array $data) + { + $paragraphSql = " + INSERT INTO paragraphs_draft (active, back_to_top, title, + description, image, caption, page) + VALUES (:active, :back_to_top, :title, :description, :image, + :caption, :page)"; + + $filesInsertSql = " + INSERT INTO files_draft (filename, bytes, type, urltext, paragraph) + VALUES (:filename, :bytes, :type, :urltext, :paragraph)"; + + try { + $this->dbh->beginTransaction(); + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->execute(); + + $row = $this->dbh + ->query('select id from paragraphs_draft order by id desc limit 1') + ->fetch(PDO::FETCH_ASSOC); + + if ( isset($data['uploaded_files']) + && is_array($data['uploaded_files']) + ) { + $fileInsertStmt = $this->dbh->prepare($filesInsertSql); + $fileInsertStmt->bindParam(':paragraph', $row['id']); + $length = count($data['uploaded_files']['type']); + for ($i = 0; $i < $length; ++$i) { + $this->setFileVars($fileInsertStmt, $data['uploaded_files'], $i); + $fileInsertStmt->execute(); + } + } + + return $this->dbh->commit(); + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to insert paragraph draft [$content]" + ); + } + } + + // }}} + + // {{{ update() + + public function update(array $data, $id) + { + $paragraphSql = " + UPDATE paragraphs_draft + SET back_to_top = :back_to_top, + active = :active, + title = :title, + description = :description, + image = :image, + caption = :caption, + page = :page + WHERE id = :id"; + + $filesDeleteSql = " + DELETE FROM files_draft + WHERE paragraph = :id"; + + $filesInsertSql = " + INSERT INTO files_draft (filename, bytes, type, urltext, paragraph) + VALUES (:filename, :bytes, :type, :urltext, :paragraph)"; + + try { + $this->dbh->beginTransaction(); + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->bindParam(':id', $id); + $paragraphStmt->execute(); + + $filesDeleteStmt = $this->dbh->prepare($filesDeleteSql); + $filesDeleteStmt->bindParam(':id', $id); + $filesDeleteStmt->execute(); + + if ( isset($data['uploaded_files']) + && is_array($data['uploaded_files']) + ) { + $fileInsertStmt = $this->dbh->prepare($filesInsertSql); + $fileInsertStmt->bindParam(':paragraph', $id); + $length = count($data['uploaded_files']['type']); + for ($i = 0; $i < $length; ++$i) { + $this->setFileVars($fileInsertStmt, $data['uploaded_files'], $i); + $fileInsertStmt->execute(); + } + } + + return $this->dbh->commit(); + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to update paragraph draft [$content]" + ); + } + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphGatewayDraftFactory.php b/Toolkit/UserArea/ParagraphGatewayDraftFactory.php new file mode 100644 index 0000000..b8fbe4e --- /dev/null +++ b/Toolkit/UserArea/ParagraphGatewayDraftFactory.php @@ -0,0 +1,10 @@ +dbh); + } +} +?> diff --git a/Toolkit/UserArea/ParagraphGatewayPublish.php b/Toolkit/UserArea/ParagraphGatewayPublish.php new file mode 100644 index 0000000..14ab5d4 --- /dev/null +++ b/Toolkit/UserArea/ParagraphGatewayPublish.php @@ -0,0 +1,293 @@ +dbh->prepare($pageSql); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + return $stmt->execute(); + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to delete paragraph `$id`" + ); + } + } + + // }}} + + // {{{ find() + + public function find($id) + { + $paragraphSql = " + SELECT * + FROM paragraphs + WHERE id = :id "; + + $fileSql = " + SELECT id,filename,bytes,type, + coalesce(urltext,filename,'empty') as urltext, + paragraph,pos + FROM files + WHERE paragraph = :paragraph + ORDER BY pos"; + + try { + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $paragraphStmt->bindParam(':id', $id, PDO::PARAM_INT); + $paragraphStmt->execute(); + + $paragraph = $paragraphStmt->fetch(PDO::FETCH_ASSOC); + + if (!empty($paragraph['image'])) { + $imgFormat = ""; + $paragraph['current_image_original'] + = sprintf($imgFormat, TOOLBOX_ORIGINAL); + $paragraph['current_image_resized'] + = sprintf($imgFormat, TOOLBOX_RESIZED); + $paragraph['current_image_midsized'] + = sprintf($imgFormat, TOOLBOX_MIDSIZED); + $paragraph['current_image_thumb'] + = sprintf($imgFormat, TOOLBOX_THUMB); + } else { + $paragraph['current_image_original'] = 'Image not yet uploaded'; + $paragraph['current_image_resized'] = 'Image not yet uploaded'; + $paragraph['current_image_midsized'] = 'Image not yet uploaded'; + $paragraph['current_image_thumb'] = 'Image not yet uploaded'; + } + + $fileStmt = $this->dbh->prepare($fileSql); + $fileStmt->bindParam(':paragraph', $id, PDO::PARAM_INT); + $fileStmt->execute(); + + $paragraph['files'] = $fileStmt->fetchAll(PDO::FETCH_ASSOC); + + return $paragraph; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Unable to find paragraph `$id`" + ); + } + } + + // }}} + // {{{ findAll() + + public function findAll($page) + { + try { + $sql = " + SELECT * + FROM paragraphs + WHERE page = :page + AND pos > 1 + ORDER BY pos"; + + $stmt = $this->dbh->prepare($sql); + $stmt->bindParam(':page', $page); + $stmt->execute(); + + $paragraphs = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $paragraphs[] = $this->find($row['id']); + } + + return $paragraphs; + } catch (PDOException $e) { + Toolkit_Logger::logException('DB Error', $e); + throw new Toolkit_UserArea_Exception( + "Error fetching all paragraphs for page `$page`" + ); + } + } + + // }}} + + // {{{ insert() + + public function insert(array $data) + { + // add the part where it throw the file to the server + // and returns the data for it + if (is_array($_FILES['filename']) && $_FILES['filename']['error'] == 0) { + $fs = new Toolkit_FileServer_FileAdapter(); + try { + if ($res = $fs->upload('filename')) { + $data['uploaded_files']['filename'][] = $res['name']; + $data['uploaded_files']['urltext'][] + = ($data['fileurltext']) + ? $data['fileurltext'] + : $_FILES['filename']['name']; + $data['uploaded_files']['bytes'][] = $res['size']; + $data['uploaded_files']['type'][] = $res['type']; + } + + } catch (Toolkit_FileServer_Exception $e) { + Toolkit_Logger::logException('File Server', $e); + echo -1; // Don't return "false", it will mess up the JS plugin. + return; + } + } + $paragraphSql = " + INSERT INTO paragraphs (active, back_to_top, title, description, + image, caption, page) + VALUES (:active, :back_to_top, :title, :description, :image, + :caption, :page)"; + + $filesInsertSql = " + INSERT INTO files (filename, bytes, type, urltext, paragraph) + VALUES (:filename, :bytes, :type, :urltext, :paragraph)"; + + try { + $this->dbh->beginTransaction(); + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->execute(); + + $row = $this->dbh + ->query('select id from paragraphs order by id desc limit 1') + ->fetch(PDO::FETCH_ASSOC); + + if ( isset($data['uploaded_files']) + && is_array($data['uploaded_files']) + ) { + $fileInsertStmt = $this->dbh->prepare($filesInsertSql); + $fileInsertStmt->bindParam(':paragraph', $row['id']); + $length = count($data['uploaded_files']['type']); + for ($i = 0; $i < $length; ++$i) { + $this->setFileVars($fileInsertStmt, $data['uploaded_files'], $i); + $fileInsertStmt->execute(); + } + } + + $this->dbh->commit(); + return $row['id']; + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to insert paragraph [$content]" + ); + } + } + + // }}} + + // {{{ update() + + public function update(array $data, $id) + { + if (is_array($data['deleteFile'])) { + foreach ($data['deleteFile'] as $fileNameToDelete) { + $delKey = array_search( + $fileNameToDelete, + $data['uploaded_files']['filename'] + ); + unset( + $data['uploaded_files']['urltext'][$delKey], + $data['uploaded_files']['filename'][$delKey], + $data['uploaded_files']['bytes'][$delKey], + $data['uploaded_files']['type'][$delKey] + ); + } + } + + // add the part where it throw the file to the server + // and returns the data for it + if (is_array($_FILES['filename']) && $_FILES['filename']['error'] == 0) { + $fs = new Toolkit_FileServer_FileAdapter(); + try { + if ($res = $fs->upload('filename')) { + $data['uploaded_files']['filename'][] = $res['name']; + $data['uploaded_files']['urltext'][] + = ($data['fileurltext']) + ? $data['fileurltext'] + : $_FILES['filename']['name']; + $data['uploaded_files']['bytes'][] = $res['size']; + $data['uploaded_files']['type'][] = $res['type']; + } + + } catch (Toolkit_FileServer_Exception $e) { + Toolkit_Logger::logException('File Server', $e); + echo -1; // Don't return "false", it will mess up the JS plugin. + return; + } + } + //echo '
      '.print_r($data, true).'
      '; + //exit; + unset( + $data['deleteFile'], + $data['fileurltext'] + ); + + $paragraphSql = " + UPDATE paragraphs + SET back_to_top = :back_to_top, + active = :active, + title = :title, + description = :description, + image = :image, + caption = :caption, + page = :page + WHERE id = :id"; + + $filesDeleteSql = " + DELETE FROM files + WHERE paragraph = :id"; + + $filesInsertSql = " + INSERT INTO files (filename, bytes, type, urltext, paragraph) + VALUES (:filename, :bytes, :type, :urltext, :paragraph)"; + + try { + $this->dbh->beginTransaction(); + + $paragraphStmt = $this->dbh->prepare($paragraphSql); + $this->setParagraphVars($paragraphStmt, $data); + $paragraphStmt->bindParam(':id', $id); + $paragraphStmt->execute(); + + $filesDeleteStmt = $this->dbh->prepare($filesDeleteSql); + $filesDeleteStmt->bindParam(':id', $id); + $filesDeleteStmt->execute(); + + if ( isset($data['uploaded_files']) + && is_array($data['uploaded_files']) + ) { + $fileInsertStmt = $this->dbh->prepare($filesInsertSql); + $fileInsertStmt->bindParam(':paragraph', $id); + $length = count($data['uploaded_files']['type']); + $fileArrayKeys = array_keys($data['uploaded_files']['type']); + foreach ($fileArrayKeys as $i) { + $this->setFileVars($fileInsertStmt, $data['uploaded_files'], $i); + $fileInsertStmt->execute(); + } + } + + return $this->dbh->commit(); + } catch (PDOException $e) { + $this->dbh->rollback(); + Toolkit_Logger::logException('DB Error', $e); + $content = serialize($data); + throw new Toolkit_UserArea_Exception( + "Unable to update paragraph [$content]" + ); + } + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphGatewayPublishFactory.php b/Toolkit/UserArea/ParagraphGatewayPublishFactory.php new file mode 100644 index 0000000..71a90b3 --- /dev/null +++ b/Toolkit/UserArea/ParagraphGatewayPublishFactory.php @@ -0,0 +1,10 @@ +dbh); + } +} +?> diff --git a/Toolkit/UserArea/ParagraphsController.php b/Toolkit/UserArea/ParagraphsController.php new file mode 100644 index 0000000..57b9df4 --- /dev/null +++ b/Toolkit/UserArea/ParagraphsController.php @@ -0,0 +1,348 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @link <> + */ + +/** + * Toolkit_UserArea_ParagraphsController + * + * Description for Toolkit_UserArea_ParagraphsController + * + * @category Toolkit + * @package Toolbox + * @author Jamie Kahgee + * @license http://www.gaslightmedia.com Gaslightmedia + * @link <> + */ +class Toolkit_UserArea_ParagraphsController + extends Toolkit_BaseControllerAbstract implements Toolkit_IController +{ + // {{{ _getForm() + + /** + * Description for _getForm() + * + * @return \Toolkit_UserArea_Forms_EditParagraph + * @access private + */ + private function _getForm() + { + // Need three separate objects otherwise, new parses overwrite existing + // root variable data. + $tlbConf = new Config; + $memConf = new Config; + $cpnConf = new Config; + + $memRoot =& $memConf->parseConfig( + BASE . 'Toolkit/Members/config.ini', + 'IniFile' + ); + $cpnRoot =& $cpnConf->parseConfig( + BASE . 'Toolkit/Coupons/config.ini', + 'IniFile' + ); + $tbxRoot =& $tlbConf->parseConfig( + BASE . 'Toolkit/UserArea/config.ini', + 'IniFile' + ); + + $form = new Toolkit_UserArea_Forms_EditParagraph( + 'edit_paragraph', + 'post', + MEDIA_BASE_URL . 'userArea/toolbox.php?rt=Paragraphs&ac=process' + ); + $form->configureForm( + $this->registry->dbh, + new Toolkit_UserArea_ParagraphGatewayPublishFactory($this->registry->dbh), + new Toolkit_FileServer_ImageAdapter(), + new Toolkit_FileServer_FileAdapter(), + new Toolkit_UserArea_FileExtension + ); + + return $form; + } + + // }}} + + // {{{ editAction() + + /** + * Description for editAction() + * + * @return string + * @access public + */ + public function editAction() + { + if (ctype_digit($_GET['pageid'])) { + $breadCrumbs = new Toolkit_UserArea_ParagraphBreadCrumbs( + $this->registry->dbh, + $_GET['pageid'] + ); + $html = (string) $breadCrumbs; + } + + $form = $this->_getForm(); + $html .= $form->toHtml($this->registry->dbh); + + return $html; + } + + // }}} + + // {{{ indexAction() + + /** + * Description for indexAction() + * + * @return string + * @throws Toolkit_UserArea_Exception + * @throws RuntimeException + * @access public + */ + public function indexAction() + { + if (ctype_digit($_GET['pageid'])) { + $breadCrumbs = new Toolkit_UserArea_ParagraphBreadCrumbs( + $this->registry->dbh, + $_GET['pageid'] + ); + $html = (string) $breadCrumbs; + } + + try { + if (!ctype_digit($_GET['pageid'])) { + throw new RuntimeException( + "Category id `{$_GET['pageid']}` is not an integer" + ); + } + + $toolboxConfig = new Config; + $toolboxConfigRoot =& $toolboxConfig->parseConfig( + BASE . 'Toolkit/UserArea/config.ini', + 'IniFile' + ); + $tree = new Toolkit_UserArea_ParagraphsTree($toolboxConfigRoot); + $html .= $tree->toHtml( + new Toolkit_UserArea_ParagraphGatewayPublish($this->registry->dbh) + ); + + return $html; + } catch (RuntimeException $e) { + Toolkit_Logger::logException('Runtime Error', $e); + throw new Toolkit_UserArea_Exception( + 'Category id must be an integer' + ); + } + } + + // }}} + + // {{{ processAction() + + /** + * Description for processAction() + * + * @return string + * @access public + */ + public function processAction() + { + $form = $this->_getForm(); + + if ($form->isSubmitted()) { + if ($form->getSubmitValue('cancel')) { + // do nothing + $pageid = $form->getSubmitValue('page'); + header('Location: ' .MEDIA_BASE_URL . "userArea/toolbox.php?rt=Paragraphs&pageid=$pageid"); + exit(); + } elseif ($form->getSubmitValue('previewParagraph')) { + } elseif ($form->getSubmitValue('saveParagraph')) { + // save paragraph + $gateway = new Toolkit_UserArea_ParagraphGatewayPublish($this->registry->dbh); + + if ($form->validate()) { + $paragraphId = $form->getSubmitValue('id'); + if ($paragraphId) { + $gateway->update($form->getSubmitValues(), $paragraphId); + } else { + $paragraphId = $gateway->insert($form->getSubmitValues()); + } + $pageid = $form->getSubmitValue('page'); + // try to get AuthUser from registry + $authUser = Registry::get('Toolkit_UserArea_Auth'); + $userId = $authUser->getAuthData('id'); + $sql = " + SELECT id,navigation_name + FROM pages + WHERE id = {$form->getSubmitValue('page')}"; + $page + = $this->registry->dbh + ->query($sql)->fetch(PDO::FETCH_ASSOC); + $logData = array( + 'user_id' => $userId, + 'alter_time' => date('m/d/Y H:i:s'), + 'db_table' => 'paragraph', + 'alter_type' => 'update', + 'foreign_key' => $paragraphId, + 'comment' => 'Paragraph From ' . $page['navigation_name'] + ); + + try { + $log = Toolkit_UserArea_Admin_Log::createLogWithValues($logData); + $log->save($this->registry->dbh); + } catch(InvalidArgumentException $e) { + echo $e->getTraceAsString(); + echo $e->getMessage(); + exit; + } + try { + $deleteFile = $form->getSubmitValue('deleteFile'); + if (is_array($deleteFile) && !empty($deleteFile)) { + $fs = new Toolkit_FileServer_FileAdapter(); + foreach ($deleteFile as $delFile) { + $fs->delete($delFile); + } + } + $image = $form->getSubmitValue('image'); + if ($form->getSubmitValue('remove_image') == '1' + && $image + ) { + $is = new Toolkit_FileServer_ImageAdapter(); + $is->delete($image); + } + } catch(Toolkit_FileServer_Exception $fileError) { + Toolkit_Common::handleError($fileError); + } + + $cache = new Cache_Lite($GLOBALS['cacheOptions']); + $cache->remove("page-$pageid", 'Toolbox'); + $cache->remove("paragraphs-$pageid", 'Toolbox'); + $cache->remove("sectionLinks-$pageid", 'Toolbox'); + + header( + 'Location: ' + .MEDIA_BASE_URL + . "userArea/toolbox.php?rt=Paragraphs" + . "&ac=edit&id={$paragraphId}&pageid={$pageid}&g=1" + ); + exit(); + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml($this->registry->dbh); + } + } elseif ($form->getSubmitValue('deleteParagraph')) { + try { + $files = $form->getSubmitValue('uploaded_files'); + $deleteFile = $files['filename']; + if (is_array($deleteFile) && !empty($deleteFile)) { + $fs = new Toolkit_FileServer_FileAdapter(); + foreach ($deleteFile as $delFile) { + $fs->delete($delFile); + } + } + $image = $form->getSubmitValue('image'); + if ($image) { + $is = new Toolkit_FileServer_ImageAdapter(); + $is->delete($image); + } + } catch(Toolkit_FileServer_Exception $fileError) { + Toolkit_Common::handleError($fileError); + } + // delete paragraph + $gateway = new Toolkit_UserArea_ParagraphGatewayPublish($this->registry->dbh); + $gateway->delete($form->getSubmitValue('id')); + + // try to get AuthUser from registry + $authUser = Registry::get('Toolkit_UserArea_Auth'); + $userId = $authUser->getAuthData('id'); + $sql = " + SELECT id,navigation_name + FROM pages + WHERE id = {$form->getSubmitValue('page')}"; + $page + = $this->registry->dbh + ->query($sql)->fetch(PDO::FETCH_ASSOC); + $logData = array( + 'user_id' => $userId, + 'alter_time' => date('m/d/Y H:i:s'), + 'db_table' => 'paragraph', + 'alter_type' => 'delete', + 'foreign_key' => $form->getSubmitValue('id'), + 'comment' => 'Paragraph From ' . $page['navigation_name'] + ); + + try { + $log = Toolkit_UserArea_Admin_Log::createLogWithValues($logData); + $log->save($this->registry->dbh); + } catch(InvalidArgumentException $e) { + echo $e->getTraceAsString(); + echo $e->getMessage(); + exit; + } + + $pageid = $form->getSubmitValue('page'); + + $cache = new Cache_Lite($GLOBALS['cacheOptions']); + $cache->remove("page-$pageid", 'Toolbox'); + $cache->remove("paragraphs-$pageid", 'Toolbox'); + $cache->remove("sectionLinks-$pageid", 'Toolbox'); + + $paragraphTitle = $form->getSubmitValue('title'); + $return = "[$paragraphTitle] successfully deleted."; + try { + $dbh = Toolkit_Database::getInstance(); + $sql = " + UPDATE paragraphs + SET pos = :pos + WHERE id = :id"; + $updateParagraphPos = $dbh->prepare($sql); + $sql = " + SELECT id,page,pos + FROM paragraphs + WHERE page = :page + ORDER BY page,pos"; + $res = $dbh->prepare($sql); + $res->bindParam(':page', $pageid, PDO::PARAM_INT); + $res->execute(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $paragraphData[$row['page']][] = $row['id']; + } + if (is_array($paragraphData)) { + $curPage = 0; + $pos = 1; + foreach ($paragraphData as $page => $paragraphs) { + if ($curPage != $page) { + $curPage = $page; + $pos = 1; + } + foreach ($paragraphs as $paragraphId) { + $updateParagraphPos->bindParam(":pos", $pos, PDO::PARAM_INT); + $updateParagraphPos->bindParam(":id", $paragraphId, PDO::PARAM_INT); + $updateParagraphPos->execute(); + ++$pos; + } + } + } + } catch(PDOException $e) { + die($e->getMessage()); + } + } + } else { + $return = $form->toHtml($this->registry->dbh); + } + + return $return; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphsDraftController.php b/Toolkit/UserArea/ParagraphsDraftController.php new file mode 100644 index 0000000..07695b3 --- /dev/null +++ b/Toolkit/UserArea/ParagraphsDraftController.php @@ -0,0 +1,154 @@ +parseConfig( + BASE . 'Toolkit/Members/config.ini', + 'IniFile' + ); + $cpnRoot =& $cpnConf->parseConfig( + BASE . 'Toolkit/Coupons/config.ini', + 'IniFile' + ); + $tbxRoot =& $tlbConf->parseConfig( + BASE . 'Toolkit/UserArea/config.ini', + 'IniFile' + ); + + $form = new Toolkit_UserArea_Forms_EditParagraph( + 'edit_paragraph', + 'post', + MEDIA_BASE_URL . 'userArea/toolbox.php?rt=ParagraphsDraft&ac=process' + ); + $form->configureForm( + $this->registry->dbh, + new Toolkit_UserArea_ParagraphGatewayDraftFactory($this->registry->dbh), + new Toolkit_FileServer_ImageAdapter(), + new Toolkit_FileServer_FileAdapter(), + new Toolkit_UserArea_FileExtension + ); + + return $form; + } + + // }}} + + // {{{ editAction() + + public function editAction() + { + if (ctype_digit($_GET['pageid'])) { + $breadCrumbs = new Toolkit_UserArea_ParagraphDraftBreadCrumbs( + $this->registry->dbh, + $_GET['pageid'] + ); + $html = (string) $breadCrumbs; + } + + $form = $this->_getForm(); + $html .= $form->toHtml($this->registry->dbh); + + return $html; + } + + // }}} + + // {{{ indexAction() + + public function indexAction() + { + if (ctype_digit($_GET['pageid'])) { + $breadCrumbs = new Toolkit_UserArea_ParagraphDraftBreadCrumbs( + $this->registry->dbh, + $_GET['pageid'] + ); + $html = (string) $breadCrumbs; + } + + try { + if (!ctype_digit($_GET['pageid'])) { + throw new RuntimeException( + "Category id `{$_GET['pageid']}` is not an integer" + ); + } + + $toolboxConfig = new Config; + $toolboxConfigRoot =& $toolboxConfig->parseConfig( + BASE . 'Toolkit/UserArea/config.ini', + 'IniFile' + ); + $tree = new Toolkit_UserArea_ParagraphsDraftTree($toolboxConfigRoot); + $html .= $tree->toHtml( + new Toolkit_UserArea_ParagraphGatewayDraft($this->registry->dbh) + ); + + return $html; + } catch (RuntimeException $e) { + Toolkit_Logger::logException('Runtime Error', $e); + throw new Toolkit_UserArea_Exception( + 'Category id must be an integer' + ); + } + } + + // }}} + + // {{{ processAction() + + public function processAction() + { + $form = $this->_getForm(); + + if ($form->isSubmitted()) { + if ($form->getSubmitValue('cancel')) { + // do nothing + $pageid = $form->getSubmitValue('page'); + header('Location: ' .MEDIA_BASE_URL . "userArea/toolbox.php?rt=ParagraphsDraft&pageid=$pageid"); + exit(); + } elseif ($form->getSubmitValue('previewParagraph')) { + } elseif ($form->getSubmitValue('saveParagraph')) { + // save paragraph + $gateway = new Toolkit_UserArea_ParagraphGatewayDraft($this->registry->dbh); + if ($form->validate()) { + $paragraphId = $form->getSubmitValue('id'); + if ($paragraphId) { + $gateway->update($form->getSubmitValues(), $paragraphId); + } else { + $gateway->insert($form->getSubmitValues()); + } + $pageid = $form->getSubmitValue('page'); + header('Location: ' .MEDIA_BASE_URL . "userArea/toolbox.php?rt=ParagraphsDraft&pageid=$pageid"); + exit(); + } else { + $return = $form->getErrorMessage(); + $return .= $form->toHtml(); + } + } elseif ($form->getSubmitValue('deleteParagraph')) { + // delete paragraph + $gateway = new Toolkit_UserArea_ParagraphGatewayDraft($this->registry->dbh); + $gateway->delete($form->getSubmitValue('id')); + + $paragraphTitle = $form->getSubmitValue('title'); + $return = "[$paragraphTitle] successfully deleted."; + } + } else { + $return = $form->toHtml(); + } + + return $return; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphsDraftTree.php b/Toolkit/UserArea/ParagraphsDraftTree.php new file mode 100644 index 0000000..78c8c7e --- /dev/null +++ b/Toolkit/UserArea/ParagraphsDraftTree.php @@ -0,0 +1,86 @@ +'; + $activeFormat .= $this->getActiveBallImage($branch); + $activeFormat .= ''; + + return sprintf( + $activeFormat, + MEDIA_BASE_URL . "userArea/toolbox.php?rt=ParagraphsDraft&id={$_GET['id']}", + $branch['active_alt'] + ); + } + + // }}} + + // {{{ createTree() + + protected function createTree(array $tree, $leaf, $level = 0) + { + if (empty($leaf)) { + return '

      No paragraph drafts created for this page yet

      '; // page has no paragraphs + } + + $html = $this->rootNodeStart; + + while (list($parent, $branch) = each($leaf)) { + $html .= sprintf($this->leafStart, $branch['id'], null); + + $html .= "{$branch['title']}"; + $html .= '
      '; + $html .= '[Edit] '; + $html .= $this->getActiveBall($branch); + $html .= '
      '; + $html .= $this->leafEnd; + } + + $html .= $this->treeEnd; + return $html; + } + + // }}} + + // {{{ fetchContent() + + protected function fetchContent(Toolkit_UserArea_GatewayAbstract $gateway) + { + $paragraphs = $gateway->findAll($_GET['pageid']); + if (is_array($paragraphs)) { + $threads = array(); + foreach ($paragraphs as $paragraph) { + $threads[] = $paragraph; + } + + $children = array(); + while (list($key, $value) = each ($threads)) { + $children[0][$value['id']] = $value; + } + + $this->tree = $children; + } else { + $this->tree = array(); + } + } + + // }}} + // {{{ toHtml() + + public function toHtml(Toolkit_UserArea_GatewayAbstract $gateway) + { + $GLOBALS['bottomScripts'][] = MEDIA_BASE_URL . 'Toolkit/UserArea/libjs/paragraph-tree.js'; + $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/plugins/jsTree/0.9.9a2/jquery.tree.js'; + + $this->fetchContent($gateway); + $html = parent::toHtml(); + + return "
      $html
      "; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/ParagraphsTree.php b/Toolkit/UserArea/ParagraphsTree.php new file mode 100644 index 0000000..df5901b --- /dev/null +++ b/Toolkit/UserArea/ParagraphsTree.php @@ -0,0 +1,120 @@ +\n"; + // {{{ getActiveBall() + + protected function getActiveBall(array $branch) + { + $activeFormat = ''; + $activeFormat .= $this->getActiveBallImage($branch); + $activeFormat .= ''; + + return sprintf( + $activeFormat, + $branch['id'], + MEDIA_BASE_URL . "userArea/toolbox.php?rt=Paragraphs&id={$branch['id']}", + $branch['active_alt'] + ); + } + + // }}} + // {{{ _getMoveArrows() + + private function _getMoveArrows() + { + $format = 'Move %s Arrow'; + + $up = sprintf( + $format, + MEDIA_APP_BASE_URL . "assets/icons/arrow_up.png", + 'Up', + 'Up' + ); + + $down = sprintf( + $format, + MEDIA_APP_BASE_URL . "assets/icons/arrow_down.png", + 'Down', + 'Down' + ); + + return $up . $down; + } + + // }}} + + private function _getPositionSelect($branch)/*{{{*/ + { + return ''; + }/*}}}*/ + // {{{ createTree() + + protected function createTree(array $tree, $leaf, $level = 0) + { + if (empty($leaf)) { + return '

      No paragraphs created for this page yet

      '; // page has no paragraphs + } + + $html = $this->rootNodeStart; + + while (list($parent, $branch) = each($leaf)) { + $html .= sprintf($this->leafStart, $branch['id'], null); + + $html .= '
      '; + $html .= '[Edit] '; + $html .= $this->getActiveBall($branch); + if (count($leaf) > 1) { + $html .= $this->_getPositionSelect($branch); + } + $html .= "{$branch['title']}"; + $html .= '
      '; + + $html .= $this->leafEnd; + } + + $html .= $this->treeEnd; + return $html; + } + + // }}} + + // {{{ fetchContent() + + protected function fetchContent(Toolkit_UserArea_GatewayAbstract $gateway) + { + $paragraphs = $gateway->findAll($_GET['pageid']); + if (is_array($paragraphs)) { + $threads = array(); + foreach ($paragraphs as $paragraph) { + $threads[] = $paragraph; + } + + $children = array(); + while (list($key, $value) = each ($threads)) { + $children[0][$value['id']] = $value; + } + + $this->tree = $children; + } else { + $this->tree = array(); + } + } + + // }}} + // {{{ toHtml() + + public function toHtml(Toolkit_UserArea_GatewayAbstract $gateway) + { + $GLOBALS['bottomScripts'][] = MEDIA_BASE_URL . 'Toolkit/UserArea/libjs/paragraph-tree.js'; + $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/plugins/jsTree/0.9.9a2/jquery.tree.js'; + + $this->fetchContent($gateway); + $html = parent::toHtml(); + + return "
      $html
      "; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/SearchController.php b/Toolkit/UserArea/SearchController.php new file mode 100644 index 0000000..ab35b4c --- /dev/null +++ b/Toolkit/UserArea/SearchController.php @@ -0,0 +1,50 @@ +configureForm(); + + $html = $searchForm->toHtml(); + + $toolbox = new GLM_TEMPLATE( NULL ); + $sql = " + SELECT id, parent, pos, active, + CASE WHEN keyword IS NOT NULL AND keyword <> '' + THEN category || ' {' || keyword || '}' + ELSE category + END AS category, + CASE WHEN active THEN 'Display' + ELSE 'Don\'t Display' + END AS active_alt + FROM bus_category + WHERE lower(category) LIKE :search"; + + $stmt = $this->registry->dbh->prepare($sql); + $stmt->bindParam(':search', strtolower("%{$_GET['q']}%"), PDO::PARAM_STR); + $stmt->execute(); + + $threads = $stmt->fetchAll(PDO::FETCH_ASSOC); + + $tree = new Toolkit_UserArea_SearchTree(new GLM_TEMPLATE(null)); + $sortedLeafs = $tree->sortChildren($threads, true); + $html .= $tree->toHtml($sortedLeafs, $sortedLeafs[0]); + + return $html; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/SearchTree.php b/Toolkit/UserArea/SearchTree.php new file mode 100644 index 0000000..12b6dd5 --- /dev/null +++ b/Toolkit/UserArea/SearchTree.php @@ -0,0 +1,35 @@ +%s'; + $img = $branch['active'] ? 'grnball.gif' : 'redball.gif'; + $q = urlencode(stripslashes($_GET['q'])); + return sprintf( + $activeFormat, + MEDIA_BASE_URL . "userArea/toolbox.php?id={$branch['id']}&_qf__search_form=&rt=Search&q=$q", + $branch['active_alt'], + MEDIA_BASE_URL . "Toolkit/UserArea/assets/$img", + $branch['active_alt'] + ); + } + + // }}} + // {{{ sortChildren() + + public function sortChildren(array $threads) + { + $children = array(); + while (list($key, $value) = each ($threads)) { + $children[0][$value['id']] = $value; + } + + return $children; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/TreeAbstract.php b/Toolkit/UserArea/TreeAbstract.php new file mode 100644 index 0000000..da78d74 --- /dev/null +++ b/Toolkit/UserArea/TreeAbstract.php @@ -0,0 +1,230 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @link <> + */ + +/** + * Toolkit_UserArea_TreeAbstract + * + * Description for Toolkit_UserArea_TreeAbstract + * + * @category Toolkit + * @package Toolbox + * @author Jamie Kahgee + * @license http://www.gaslightmedia.com Gaslightmedia + * @link <> + */ +abstract class Toolkit_UserArea_TreeAbstract +{ + // {{{ properties + + + /** + * Description for $rootNodeStart + * @var string + * @access protected + */ + protected $rootNodeStart = "
        \n"; + + /** + * Description for $subTreeStart + * @var string + * @access protected + */ + protected $subTreeStart = "\n
          \n"; + + /** + * Description for $treeEnd + * @var string + * @access protected + */ + protected $treeEnd = "\n
        \n"; + + /** + * Description for $leafStart + * @var string + * @access protected + */ + protected $leafStart = "\n\t
      • \n"; + + /** + * Description for $leafEnd + * @var string + * @access protected + */ + protected $leafEnd = "\n\t
      • \n"; + + /** + * Description for $config + * @var Config_Container + * @access protected + */ + protected $config; + + /** + * Description for $tree + * @var array + * @access protected + */ + protected $tree; + + // }}} + // {{{ __construct() + + /** + * Class constructor + * + * @param Config_Container $config Config container + * + * @return void + * @access public + */ + public function __construct(Config_Container $config) + { + $this->config = $config; + } + + // }}} + + // {{{ getActiveBallImage() + + /** + * Description for getActiveBallImage() + * + * @param array $branch Branch array + * + * @return string + * @access protected + */ + protected function getActiveBallImage(array $branch) + { + $imgFormat = '%s'; + + $show = sprintf( + $imgFormat, + ($branch['active']) ? '' : 'style="display: none;"', + MEDIA_BASE_URL . "Toolkit/UserArea/assets/grnball.gif", + 'Active Ball' + ); + + $hide = sprintf( + $imgFormat, + ($branch['active']) ? 'style="display: none;"' : '', + MEDIA_BASE_URL . "Toolkit/UserArea/assets/redball.gif", + "In-active Ball" + ); + + return $show . $hide; + } + + // }}} + // {{{ getActiveMobileBallImage() + + /** + * Description for getActiveMobileBallImage() + * + * @param array $branch Branch array + * + * @return string + * @access protected + */ + protected function getActiveMobileBallImage(array $branch) + { + $imgFormat = '%s'; + + $show = sprintf( + $imgFormat, + ($branch['mobile_active']) ? '' : 'style="display: none;"', + MEDIA_BASE_URL . "Toolkit/UserArea/assets/mobilemgreen.jpg", + 'Active Ball' + ); + + $hide = sprintf( + $imgFormat, + ($branch['mobile_active']) ? 'style="display: none;"' : '', + MEDIA_BASE_URL . "Toolkit/UserArea/assets/mobilemred.jpg", + "In-active Ball" + ); + + return $show . $hide; + } + + // }}} + // {{{ getActiveBall() + + /** + * Description for getActiveBall() + * + * @param array $branch Branch array + * + * @access protected + * @return void + */ + abstract protected function getActiveBall(array $branch); + + // }}} + + // {{{ createTree() + + /** + * Description for createTree + * + * @param array $tree Description for $tree ... + * @param unknown $leaf Description for $leaf ... + * @param int $level Description for $level ... + * + * @return void + * @access protected + */ + abstract protected function createTree(array $tree, $leaf, $level = 0); + + // }}} + // {{{ fetchContent() + + /** + * Description for fetchContent + * + * @param Toolkit_UserArea_GatewayAbstract $gateway Toolbox Gateway + * + * @return void + * @access protected + */ + abstract protected function fetchContent( + Toolkit_UserArea_GatewayAbstract $gateway + ); + + // }}} + + // {{{ toHtml() + + /** + * Description of toHtml() + * + * @return string + * @access public + */ + public function toHtml() + { +// $GLOBALS['styleSheets'][] =MEDIA_BASE_URL . 'admin/main.css'; + $GLOBALS['styleSheets'][] = MEDIA_BASE_URL . 'Toolkit/UserArea/styles.css'; + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL . 'libjs/jquery/jquery-1.4.2.min.js'; + + if (is_array($this->tree)) { + $html = $this->createTree($this->tree, reset($this->tree)); + } + + return $html; + } + + // }}} +} +?> diff --git a/Toolkit/UserArea/assets/.keepme b/Toolkit/UserArea/assets/.keepme new file mode 100644 index 0000000..e69de29 diff --git a/Toolkit/UserArea/assets/arrow.png b/Toolkit/UserArea/assets/arrow.png new file mode 100755 index 0000000..ee11ab4 Binary files /dev/null and b/Toolkit/UserArea/assets/arrow.png differ diff --git a/Toolkit/UserArea/assets/arrowClosed.png b/Toolkit/UserArea/assets/arrowClosed.png new file mode 100755 index 0000000..3b34262 Binary files /dev/null and b/Toolkit/UserArea/assets/arrowClosed.png differ diff --git a/Toolkit/UserArea/assets/arrowOpen.png b/Toolkit/UserArea/assets/arrowOpen.png new file mode 100755 index 0000000..6967dea Binary files /dev/null and b/Toolkit/UserArea/assets/arrowOpen.png differ diff --git a/Toolkit/UserArea/assets/collapse.png b/Toolkit/UserArea/assets/collapse.png new file mode 100755 index 0000000..d10e051 Binary files /dev/null and b/Toolkit/UserArea/assets/collapse.png differ diff --git a/Toolkit/UserArea/assets/expand.png b/Toolkit/UserArea/assets/expand.png new file mode 100755 index 0000000..38dcfc0 Binary files /dev/null and b/Toolkit/UserArea/assets/expand.png differ diff --git a/Toolkit/UserArea/assets/grnball.gif b/Toolkit/UserArea/assets/grnball.gif new file mode 100755 index 0000000..5f7740b Binary files /dev/null and b/Toolkit/UserArea/assets/grnball.gif differ diff --git a/Toolkit/UserArea/assets/mobilemgreen.jpg b/Toolkit/UserArea/assets/mobilemgreen.jpg new file mode 100644 index 0000000..a5fc6ce Binary files /dev/null and b/Toolkit/UserArea/assets/mobilemgreen.jpg differ diff --git a/Toolkit/UserArea/assets/mobilemred.jpg b/Toolkit/UserArea/assets/mobilemred.jpg new file mode 100644 index 0000000..217826d Binary files /dev/null and b/Toolkit/UserArea/assets/mobilemred.jpg differ diff --git a/Toolkit/UserArea/assets/redball.gif b/Toolkit/UserArea/assets/redball.gif new file mode 100755 index 0000000..7005133 Binary files /dev/null and b/Toolkit/UserArea/assets/redball.gif differ diff --git a/Toolkit/UserArea/assets/template1.gif b/Toolkit/UserArea/assets/template1.gif new file mode 100755 index 0000000..327d943 Binary files /dev/null and b/Toolkit/UserArea/assets/template1.gif differ diff --git a/Toolkit/UserArea/assets/template2.gif b/Toolkit/UserArea/assets/template2.gif new file mode 100755 index 0000000..edf3d8b Binary files /dev/null and b/Toolkit/UserArea/assets/template2.gif differ diff --git a/Toolkit/UserArea/assets/template3.gif b/Toolkit/UserArea/assets/template3.gif new file mode 100755 index 0000000..16e2107 Binary files /dev/null and b/Toolkit/UserArea/assets/template3.gif differ diff --git a/Toolkit/UserArea/assets/template4.gif b/Toolkit/UserArea/assets/template4.gif new file mode 100755 index 0000000..32174dd Binary files /dev/null and b/Toolkit/UserArea/assets/template4.gif differ diff --git a/Toolkit/UserArea/assets/template5.gif b/Toolkit/UserArea/assets/template5.gif new file mode 100755 index 0000000..6c36b50 Binary files /dev/null and b/Toolkit/UserArea/assets/template5.gif differ diff --git a/Toolkit/UserArea/assets/template6.gif b/Toolkit/UserArea/assets/template6.gif new file mode 100644 index 0000000..28d140e Binary files /dev/null and b/Toolkit/UserArea/assets/template6.gif differ diff --git a/Toolkit/UserArea/config.ini b/Toolkit/UserArea/config.ini new file mode 100644 index 0000000..3d81908 --- /dev/null +++ b/Toolkit/UserArea/config.ini @@ -0,0 +1,3 @@ +[conf] +applicationName = "Toolbox" +lockMainNavPages = Off diff --git a/Toolkit/UserArea/css/styles.css b/Toolkit/UserArea/css/styles.css new file mode 100644 index 0000000..744466b --- /dev/null +++ b/Toolkit/UserArea/css/styles.css @@ -0,0 +1,202 @@ +#form-warning-top { + color: #FF0000; + font-size: 14px; + font-weight: bold; + margin-bottom: 0.5em; + margin-top: 1em; +} +.required, .req { + color: #FF0000; +} +.group { + display: -moz-inline-box; + width: 100%; +} +.group td { + width: 324px; +} +.requiredNote { + text-align: center; +} +#contact { + margin: 10px; +} +#contact table { + background-color: #FFFFFF; + border: 1px solid #EEEEEE; + border-collapse: collapse; +} +#contact td { + border: 1px solid #EEEEEE; + border-collapse: collapse; + color: #000000; + font-family: arial, helvetica, sans-serif; + padding: 3px; + font-size: 12px; +} +.labelcell { + background-color: transparent; + padding-right: 10px; + padding-top: 3px; + text-align: right; + white-space: nowrap; + width: 140px; +} +.fieldcell { + padding-left: 4px; + width: 320px; +} +.fieldcell .text { + width: 90%; +} +#contact table.group { + font-size: 10px; + border: none; + padding-top: 4px; +} +#contact table.group td { + border: none; +} +#contact .hdr { + background-color: #999999; + border: 1px solid #666666; + font-weight: bold; +} +.paging { + text-align: center; + background-color: #F6F6F6; + border-color: #E86a10; + border-color: #296DC0; + border-style: solid; + border-width: 1px 0; + margin: 1.0em 0; + padding: 8px 0; + text-align: center; + width: 100%; + font-size: 12px; + +} +.paging b { + border: 1px solid #b22c2c; + border: 1px solid #E86A10; + background: #FFF; + padding: 5px 7px; + margin: 0 5px; +} +.paging a { + background: #FFF; + border: 1px solid #CCC; + padding: 5px 7px; + text-decoration: none; + font-family: helvetica, times; + color: #000; + margin: 0 5px; +} +.paging a:hover { + border: 1px solid #999; + border: 1px solid #b22c2c; + border: 1px solid #E86A10; +} +#dataGrid { + margin: 10px auto; + border: 1px solid #296DC0; + width: 100%; + border-collapse: collapse; +} +#dataGrid thead th { + background: #296DC0; + border: 1px solid #1b4880; + color: #000; + font-weight: normal; +} +#dataGrid th a { + font-weight: bolder; + color: #000; + text-decoration: none; +} +#dataGrid th a:hover { + color: #E86A10; + text-decoration: underline; +} +#dataGrid tr { + border: 1px solid #296DC0; + border-collapse: collapse; +} +#dataGrid tbody tr td { + padding: 5px; +} +#dataGrid .editLink, #dataGrid .delLink, +#dataGrid .mailLink, #dataGrid .dateLink, +#dataGrid .posLink { + text-align: center; +} +img.status { + border: none; +} +.even { + background-color: #D9D9D9; +} +#gridSorter { + margin: 0 auto; + padding: 10px; + text-align: center; + border: 1px solid #296DC0; +} +#gridSorter table { + border: none; +} +#gridSorter td { + border: none; +} +.fieldcell textarea { + width: 90%; + height: 70px; +} + +/* + * Banner Reporting + */ +#bannerInfo, #reportResult { + margin: 10px; + border: 1px solid #bbb; + border-right: 1px solid #444; + border-bottom: 1px solid #444; + padding: 20px; + width: 400px; + background: #efefef; + font-size: 12px; +} +#bannerInfo h3, #reportResult h3 { + margin: 0; +} +#bannerInfo p { + margin-bottom: 0; +} + +#bannerInfo table, #reportResult table, +#bannerInfo th, #reportResult th, +#bannerInfo tr, #reportResult tr, +#bannerInfo td, #reportResult td { + margin: 5px; + padding: 5px; + border-collapse: collapse; + font-size: 12px; +} +#bannerInfo td { + padding: 5px; +} +label.tooltip { + background-image: url(http://app.gaslightmedia.com/assets/icons/information.png); + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-position: left; + padding-left: 17px; +} + +/** + * Prevent the slider from showing through the datepicker + */ +.ui-datepicker { + z-index: 100 !important; +} diff --git a/Toolkit/UserArea/fixPageNoContent.php b/Toolkit/UserArea/fixPageNoContent.php new file mode 100644 index 0000000..8b59bad --- /dev/null +++ b/Toolkit/UserArea/fixPageNoContent.php @@ -0,0 +1,48 @@ +beginTransaction(); +try { + $checkSql = + "SELECT id + FROM paragraphs + WHERE page = :page + AND pos = 1"; + $checkStmt = $dbh->prepare($checkSql); + $addSql = " + INSERT INTO paragraphs + (active,page,pos) + VALUES + (true,:page,1)"; + $addStmt = $dbh->prepare($addSql); + $sql = " + SELECT id + FROM pages + ORDER BY parent,pos"; + $stmt = $dbh->query($sql); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $checkStmt->bindParam( + ':page', + $row['id'], + PDO::PARAM_INT + ); + $checkStmt->execute(); + if ($checkStmt->rowCount() == 0) { + // nothing set yet need to add one + $addStmt->bindParam( + ':page', + $row['id'], + PDO::PARAM_INT + ); + $addStmt->execute(); + echo '

        + Adding paragraph! PageId:'.$row['id'].'

        '; + } else { + echo '

        + Good Page PageId:'.$row['id'].'

        '; + } + } + $dbh->commit(); +} catch(PDOException $e) { + die($e->getMessage()); +} diff --git a/Toolkit/UserArea/fixPagePos.php b/Toolkit/UserArea/fixPagePos.php new file mode 100644 index 0000000..c414a6d --- /dev/null +++ b/Toolkit/UserArea/fixPagePos.php @@ -0,0 +1,70 @@ +beginTransaction(); +$pageData = array(); +try { + $sql = " + UPDATE pages + SET pos = :pos + WHERE id = :id"; + $updatePagePos = $dbh->prepare($sql); + $sql = " + SELECT id,parent,pos + FROM pages + ORDER BY parent,pos"; + $res = $dbh->query($sql); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $pageData[$row['parent']][] = $row['id']; + } + echo '

        fixing page positions

        '; + if (is_array($pageData)) { + $curParent = 0; + $pos = 1; + foreach ($pageData as $parent => $pages) { + if ($curParent != $parent) { + $curParent = $parent; + $pos = 1; + } + foreach ($pages as $pageId) { + $updatePagePos->bindParam(":pos", $pos, PDO::PARAM_INT); + $updatePagePos->bindParam(":id", $pageId, PDO::PARAM_INT); + $updatePagePos->execute(); + ++$pos; + } + } + } + $sql = " + UPDATE paragraphs + SET pos = :pos + WHERE id = :id"; + $updateParagraphPos = $dbh->prepare($sql); + $sql = " + SELECT id,page,pos + FROM paragraphs + ORDER BY page,pos"; + $res = $dbh->query($sql); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $paragraphData[$row['page']][] = $row['id']; + } + echo '

        fixing paragraphs positions

        '; + if (is_array($paragraphData)) { + $curPage = 0; + $pos = 1; + foreach ($paragraphData as $page => $paragraphs) { + if ($curPage != $page) { + $curPage = $page; + $pos = 1; + } + foreach ($paragraphs as $paragraphId) { + $updateParagraphPos->bindParam(":pos", $pos, PDO::PARAM_INT); + $updateParagraphPos->bindParam(":id", $paragraphId, PDO::PARAM_INT); + $updateParagraphPos->execute(); + ++$pos; + } + } + } +} catch(PDOException $e) { + die($e->getMessage()); +} +$dbh->commit(); diff --git a/Toolkit/UserArea/libjs/edit-page.js b/Toolkit/UserArea/libjs/edit-page.js new file mode 100644 index 0000000..a63bc1f --- /dev/null +++ b/Toolkit/UserArea/libjs/edit-page.js @@ -0,0 +1,256 @@ +var EditPage = +{ + openSection: '#pageContent', + sectionHeaders: null, + sectionAttributes: null, + + init: function()// {{{ + { + $('input[name=deletePage]:submit').click(EditPage.confirmPageDelete); + $('#MemberCategories').change(function() { + $('input[name=include_members]').attr('checked', 'checked'); + }); + $('#MemberRegions').change(function() { + $('input[name=include_members]').attr('checked', 'checked'); + }); + $('#CouponCategories').change(function() { + $('input[name=include_coupons]').attr('checked', 'checked'); + }); + EditPage.pageAttributes(); + EditPage.memberAttributes(); + EditPage.couponAttributes(); + EditPage.headlineAttributes(); + + EditPage.sectionHeaders = $('tbody tr.hdr td'); + EditPage.sectionAttributes = $('span.attributes'); + + + // If there was an error with validation, then + // find the first error and open that section. + var $firstFormValidationError = $('div.req:first'); + if ($firstFormValidationError.length > 0) { + // Hide all sections first + $("tbody.section > tr:not(.hdr)").toggle(); + + // Then open the target section + $firstFormValidationError + .parents("tbody.section") + .children("tr:not(.hdr)") + .toggle(); + $firstFormValidationError + .parents("tbody.section") + .children('tr.hdr') + .children() + .toggleClass('open'); + } else { + // Initially hide all sections EXCEPT the first section + // which has an id #pageContent + $("tbody.section > tr:not(.hdr)") + .not("tbody#pageContent > tr") + .toggle(); + } + + $("tbody.section tr.hdr").click(function() { + var $currId = $(this).parents('tbody').attr('id'); + if ($currId == EditPage.openSection) { + return false; + } + + // Set this section to the current section open + EditPage.openSection = $currId + + // Remove the class open from all the section headers. + // This will reset the arrow in the header back to closed (>) + EditPage.sectionHeaders.each(function() { + $(this).removeClass('open'); + }); + + // default shows all the section "quick at a glance" attributes + EditPage.sectionAttributes.show(); + // hide current sections "quick at a glance" attributes + $(this).find('.attributes').hide(); + + // hide all the sections + $('tbody.section > tr:not(.hdr)').hide(); + // unhide the section that was clicked + $(this).siblings().toggle(); + // make this section open, w/ a down arrow (v) + $(this).children().toggleClass('open'); + }); + + $("select[multiple]").asmSelect({ + animate: true + }); + + if ($("#description").is("textarea")) { + // Only try to replace the textarea if the + // CKEditor is compatible w/ the browser. + if (CKEDITOR.env.isCompatible) { + CKEDITOR.replace('description', + { + toolbar : [ + ['Format', 'Font','FontSize','Bold','Italic'], + ['Cut','Copy','PasteText','-','Undo','Redo'], + '/', + ['NumberedList','BulletedList','-','Outdent','Indent'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['TextColor'], + ['Link','Unlink', 'Anchor'], + ['Find','Replace','-','RemoveFormat','Source'] + ], + filebrowserImageBrowseUrl : '../Toolkit/CKImages/browser.php?folder=1', + filebrowserImageUploadUrl : '../Toolkit/CKImages/controller.php?command=Upload', + filebrowserImageWindowWidth : '760', + filebrowserImageWindowHeight : '500' + }); + } + } + var pageId = $("input[name='id']").val(); + console.log(pageId); + if (pageId == '') { + $.get("Staff-Page/", function(data){ + $("#staffPick").html(data); + }); + } else { + $.get("Staff-Page/" + pageId + "/", function(data){ + $("#staffPick").html(data); + }); + } + + },// }}} + + confirmPageDelete: function(event)// {{{ + { + if (!confirm("Are you sure you wish to delete this page and its paragraphs?\n\n" + + "All sub pages along with existing page drafts will also be deleted!")) { + event.preventDefault(); + } + },// }}} + createCategoryShortcutView: function(element, section, container)// {{{ + { + var target = section.find('select[name="'+element+'[]"]'); + if (target.length) { + container.append(''); + var $holder = container.find('.'+element), + $numSelected = target.find(':selected').length; + if ($numSelected) { + EditPage.updateText($holder, '['+$numSelected+']Categories'); + } + target.change(function() { + var $numSelected = target.find(':selected').length; + EditPage.updateText($holder, '['+$numSelected+']Categories'); + }); + } + },// }}} + createRegionShortcutView: function(element, section, container)// {{{ + { + var target = section.find('select[name="'+element+'[]"]'); + if (target.length) { + container.append(''); + var $holder = container.find('.'+element), + $numSelected = target.find(':selected').length; + if ($numSelected) { + EditPage.updateText($holder, '['+$numSelected+']Regions'); + } + target.change(function() { + var $numSelected = target.find(':selected').length; + EditPage.updateText($holder, '['+$numSelected+']Regions'); + }); + } + },// }}} + createCheckboxShortcutView: function(element, section, container, text)// {{{ + { + var target = section.find('input[name='+element+']:checkbox'); + if (target.length) { + container.append(''); + var $holder = container.find('.'+element), + $checked = target.is(':checked') + ? '[X]' + : '[ ]'; + EditPage.updateText($holder, $checked + text); + + target.change(function() { + var $checked = target.is(':checked') + ? '[X]' + : '[ ]'; + EditPage.updateText($holder, $checked + text); + }); + } + },// }}} + createTextShortcutView: function(element, section, container)// {{{ + { + var target = section.find('input[name='+element+']'); + if (target.length) { + container.append(''); + var $holder = container.find('.'+element); + if (target.val() != '') { + EditPage.updateText($holder, '{' + target.val() + '}'); + } + target.change(function() { + if ($(this).val() != '') { + EditPage.updateText($holder, '{' + $(this).val() + '}'); + } else { + EditPage.updateText($holder, ''); + } + }); + } + },// }}} + + couponAttributes: function()// {{{ + { + var $section = $('#coupons'); + $section.find('tr.hdr td') + .append(''); + + $attributes = $section.find('tr.hdr .attributes'); + + EditPage.createCheckboxShortcutView('include_coupons', $section, $attributes, 'Display Coupons'); + EditPage.createCategoryShortcutView('coupon_categories', $section, $attributes); + },// }}} + + headlineAttributes: function()// {{{ + { + var $section = $('#headlines'); + $section.find('tr.hdr td') + .append(''); + + $attributes = $section.find('tr.hdr .attributes'); + + EditPage.createCheckboxShortcutView('headline', $section, $attributes, 'Headline'); + },// }}} + + pageAttributes: function()// {{{ + { + var $section = $('#attributes'); + $section.find('tr.hdr td') + .append(''); + + $attributes = $section.find('tr.hdr .attributes'); + + EditPage.createTextShortcutView('keyword', $section, $attributes); + EditPage.createTextShortcutView('short_url', $section, $attributes); + EditPage.createCheckboxShortcutView('paragraph_links', $section, $attributes, 'Links'); + },// }}} + + memberAttributes: function()// {{{ + { + var $section = $('#members'); + $section.find('tr.hdr td') + .append(''); + + $attributes = $section.find('tr.hdr .attributes'); + + EditPage.createCheckboxShortcutView('include_members', $section, $attributes, 'Display Members'); + EditPage.createCategoryShortcutView('member_categories', $section, $attributes); + EditPage.createRegionShortcutView('member_regions', $section, $attributes); + EditPage.createCheckboxShortcutView('include_member_map', $section, $attributes, 'Map'); + EditPage.createCheckboxShortcutView('search_form', $section, $attributes, 'Search'); + },// }}} + + updateText: function(holder, content)// {{{ + { + holder.html(content); + }// }}} +}; + +$(document).ready(EditPage.init); diff --git a/Toolkit/UserArea/libjs/edit-paragraph.js b/Toolkit/UserArea/libjs/edit-paragraph.js new file mode 100644 index 0000000..f80a4ff --- /dev/null +++ b/Toolkit/UserArea/libjs/edit-paragraph.js @@ -0,0 +1,152 @@ +var EditParagraph = +{ + init: function()// {{{ + { + $('.files').sortable({ + placeholder: 'ui-state-highlight' + }); + + $('input[name="deleteParagraph"]').click(EditParagraph.confirmParagraphDelete); + + // Bind click events to the remove buttons for uploaded files + // everytime a button is clicked, an entire li element is removed + // so we can get rid of all the info stored in hidden fields + // about the file (bytes, filename, etc...). + $('.remove').live('click', function(event) { + event.preventDefault(); + $(this).parent('li').remove(); + }); + + $('#filename').after(''); + $('#filename').after(''); + var $uploadNotification = $('#upload_notification'); + + $("tbody.section tr:not(.hdr)").toggle(); + var $hdr = $('tbody.section tr.hdr'); + + $hdr.click(function() { + $(this).siblings() + .toggle(); + $(this).children() + .toggleClass('open'); + }); + + $("div.req").each(function() { + $(this).parents("tbody.section") + .children("tr:not(.hdr)") + .toggle(); + $(this).parents("tbody.section") + .children("tr.hdr") + .children() + .toggleClass('open'); + }); + + if ($("#description").is("textarea")) { + // Only try to replace the textarea if the + // CKEditor is compatible w/ the browser. + if (CKEDITOR.env.isCompatible) { + CKEDITOR.replace('description', + { + toolbar : [ + ['Format', 'Font','FontSize','Bold','Italic'], + ['Cut','Copy','PasteText','-','Undo','Redo'], + '/', + ['NumberedList','BulletedList','-','Outdent','Indent'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['TextColor'], + ['Link','Unlink', 'Anchor'], + ['Find','Replace','-','RemoveFormat','Source'] + ] + }); + } + } + },// }}} + + cleanName: function(filename)// {{{ + { + var $alphaNumeric = filename.replace(/[^A-Za-z0-9]/g, ''); + + return $alphaNumeric; + },// }}} + confirmParagraphDelete: function(event)// {{{ + { + if (!confirm("Are you sure you wish to delete this paragraph and its files?")) { + event.preventDefault(); + } + },// }}} + + getExtensionImage: function(ext)// {{{ + { + var img; + switch (ext) { + case 'mp3' : + img = 'mp3.gif'; + break; + + case 'avi' : + img = 'avi.gif'; + break; + + case 'html' : + img = 'html.gif'; + break; + + case 'mov' : + img = 'mov.gif' + break; + + case 'wmv' : + img = 'wmv.gif'; + break; + + case 'ppt' : + img = 'ppt.gif'; + break; + + case 'zip' : + img = 'zip.png'; + break; + + case 'rar' : + case 'tar' : + img = 'rar.gif'; + break; + + case 'txt' : + img = 'txt.png'; + break; + + case 'xlsx' : + case 'xls' : + img = 'xls.gif'; + break; + + case 'pdf' : + img = 'pdf.png'; + break; + + case 'doc' : + case 'docx' : + img = 'doc.gif'; + break; + + case 'png' : // image does not exist yet. + case 'jpeg' : + case 'jpg' : + img = 'jpg.gif'; + break; + + case 'gif' : + img = 'gif.gif'; + break; + + default : + img = 'download.gif'; + break; + } + + return img; + }// }}} +}; + +$(document).ready(EditParagraph.init); diff --git a/Toolkit/UserArea/libjs/editUser.js b/Toolkit/UserArea/libjs/editUser.js new file mode 100644 index 0000000..45b606c --- /dev/null +++ b/Toolkit/UserArea/libjs/editUser.js @@ -0,0 +1,6 @@ +$(function (){ + // get userId + var userId = $("#userId").val(); + $("#appData").load("userArea.php?ac=getUserApps", {'userId':userId}, function() { + }); +}); diff --git a/Toolkit/UserArea/libjs/jquery.columnview.js b/Toolkit/UserArea/libjs/jquery.columnview.js new file mode 100755 index 0000000..53a3834 --- /dev/null +++ b/Toolkit/UserArea/libjs/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/UserArea/libjs/pagesTree.js b/Toolkit/UserArea/libjs/pagesTree.js new file mode 100644 index 0000000..318f14e --- /dev/null +++ b/Toolkit/UserArea/libjs/pagesTree.js @@ -0,0 +1,242 @@ +var PagesTree = +{ + init: function() + { + PagesTree.updateMoveArrowVisibility(); + $('.admin_nav') + .append('
      • Expand All
      • ') + .append('
      • Collapse All
      • ') + .append('
      • Show Positions
      • ') + .append('
      • Hide Positions
      • ') + ; + + var $myTree = $('#tree'); + + if ($myTree.children('ul').size() > 0) { + $myTree.tree({ + callback : { + onsearch : function (NODES, TREE_OBJ) { + TREE_OBJ.container.find('strong.search').removeClass('search'); + NODES.addClass('search'); + + if (NODES.length == 0) { + alert('No matches found - Please refine your search.'); + } + } + }, + plugins : { + cookie : { + prefix : "jstree_toolbox_", + types : { + selected : false + } + } + } + }); + $('#show_pos').click(function(event) { + event.preventDefault(); + $('select').show(); + }); + $('#hide_pos').click(function(event) { + event.preventDefault(); + $('select').hide(); + }); + $('#expand_all').click(function(event) { + event.preventDefault(); + $.tree.focused().open_all(); + }); + $('#collapse_all').click(function(event) { + event.preventDefault(); + $.tree.focused().close_all(); + }); + + $("#search_form").submit(function(event) { + var $search = $("#q").val().toUpperCase(); + event.preventDefault(); + jQuery.expr[':'].Contains = function(a, i, m) { + return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0; + }; + $.tree.focused().search($search, "contains('"+$search+"'),strong:Contains"); + }); + + $('a.pagePreview').click(function(event) { + var newWindow = window.open($(this).attr('href')); + newWindow.focus(); + return false; + }); + + $('img.moveDown').click(function() { + var $li = $(this).closest('li'), + $sibling = $li.next(); + if ($sibling.length == 1) { + var $id = $li.attr('id'); + $li.detach(); + $li.insertAfter($sibling); + PagesTree.updateMoveArrowVisibility(); + $.ajax({ + url : '../user-page-move/'+$id+'/down/', + cache: false, + async: false, + success: function(html) { + if (html == 0) { + PagesTree.moveBack($li, $sibling); + } else if ($sibling.hasClass('last')) { + $sibling.removeClass('last'); + $li.addClass('last'); + } + }, + error: function() { + PagesTree.moveBack($li, $sibling); + } + }); + } + }); + + $('img.moveUp').click(function() { + var $li = $(this).closest('li'), + $sibling = $li.prev(); + if ($sibling.length == 1) { + var $id = $li.attr('id'); + $li.detach(); + $li.insertBefore($sibling); + PagesTree.updateMoveArrowVisibility(); + $.ajax({ + url : '../user-page-move/'+$id+'/up/', + cache: false, + async: false, + success: function(html) { + if (html == 0) { + PagesTree.moveBack($li, $sibling); + } else if ($li.hasClass('last')) { + $li.removeClass('last'); + $sibling.addClass('last'); + } + }, + error: function() { + PagesTree.moveBack($li, $sibling); + } + }); + } + }); + + $('.active-ball').click(function(event) { + event.preventDefault(); + var id = $(this).attr('rel'), + _this = $(this); + $.get('../user-change-state/'+id+'/?t=' + event.timeStamp, function(data) { + if (data) { + _this.children().toggle(); + var newTitle = _this.attr('title') == 'Display' + ? "Don't Display" + : 'Display'; + _this.attr('title', newTitle); + } + }); + }); + $('.mobile-active-ball').click(function(event) { + event.preventDefault(); + var id = $(this).attr('rel'), + _this = $(this); + $.get('../user-change-state-mobile/'+id+'/?t=' + event.timeStamp, function(data) { + if (data) { + _this.children().toggle(); + var newTitle = _this.attr('title') == 'Display' + ? "Don't Display" + : 'Display'; + _this.attr('title', newTitle); + } + }); + }); + } + $('.closed').hover(function(){ + $(this).css('background', 'lightgrey'); + //$(this).children('.right-element').show(); + },function(){ + $(this).css('background', 'none'); + //$(this).children('.right-element').hide(); + }); + $('.leaf').hover(function(){ + $(this).css('background', 'lightgrey'); + //$(this).children('.right-element').show(); + },function(){ + $(this).css('background', 'none'); + //$(this).children('.right-element').hide(); + }); + $('li.open').each(function(){ + var count = $(this).children('ul').children('li').size(); + PagesTree.loadSelectOptions( + $(this).children('ul').children('li').children('div.right-element'), + count + ); + }); + $('li.closed').each(function(){ + var count = $(this).children('ul').children('li').size(); + PagesTree.loadSelectOptions( + $(this).children('ul').children('li').children('div.right-element'), + count + ); + }); + $('select.pos-select').each(function(){ + $(this).change(function(){ + var id = $(this).attr('name'); + var oldpos = $(this).attr('rel'); + var newpos = $(this).attr('value'); + window.location.href = '../user-page-move-sel/' + id + '/' + oldpos + '/' + newpos + '/'; + }); + }); + $('ul.ltr').each(function(){ + var count = $(this).children('li').size(); + PagesTree.loadSelectOptions( + $(this).children('li').children('div.right-element'), + count + ); + }); + }, + + loadSelectOptions: function(ul, count) + { + ul.each(function(){ + var selCount = $(this).children('select').attr('rel'); + if ($(this).children('select').hasClass('parent-level-sel')) { + var begin = 2; + } else { + var begin = 1; + } + for (i = begin; i <= count; ++i) { + var html = '