From 11e6535fc57ad85127e8c7eb9ca9f109db4a0a6a Mon Sep 17 00:00:00 2001
From: Laury GvR The system has encountered an un-recoverable error! ' . self::getErrorInfo($e) . '";
+ }
+
+ // }}}
+ // {{{ createLink()
+
+
+ /**
+ * Creates a folder link so we can browse to each folder
+ *
+ * @param array $row Folder information
+ *
+ * @return string anchor link for folder
+ * @access protected
+ */
+ protected function createLink(array $row)
+ {
+ $format = '%s';
+
+ $link = sprintf(
+ $format,
+ ($_GET['folder'] == $row['id']) ? 'clicked' : null,
+ $_GET['CKEditor'],
+ $_GET['CKEditorFuncNum'],
+ $_GET['langCode'],
+ $row['id'],
+ $row['name']
+ );
+
+ return $link;
+ }
+
+ // }}}
+
+ // {{{ fetchFoldersArray()
+
+
+ /**
+ * Fetches a tree hierarchy of the folder structure into a linear array
+ *
+ * @param integer $start node to start at
+ *
+ * @return array folder structure with levels
+ * @access protected
+ */
+ protected function fetchFoldersArray($start)
+ {
+ return Toolkit_Common::getHierarchicalTreeStructure(
+ $this->dbh,
+ 'ckeditor_folders',
+ 'id',
+ 'parent',
+ 'id',
+ $start
+ );
+ }
+
+ // }}}
+
+ // {{{ getFolders()
+
+
+ /**
+ * Gets the folders ul list
+ *
+ * @param integer $parent start at a certain level
+ *
+ * @return string list of folders
+ * @access public
+ */
+ public function getFolders($parent = 0)
+ {
+ $folders = $this->fetchFoldersArray($parent);
+ try {
+ $sql = "
+ SELECT *
+ FROM ckeditor_folders
+ WHERE id = :id";
+
+ $stmt = $this->dbh->prepare($sql);
+ foreach ($folders as $i => $j) {
+ $stmt->bindParam(':id', $i, PDO::PARAM_INT);
+ $stmt->execute();
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ if ($j == $this->_prevLvl) {
+ $tree .= $this->openNode($row);
+ $tree .= $this->createLink($row);
+ $this->_prevLvl = $j;
+ } elseif ($j > $this->_prevLvl) {
+ ++$this->_lvlsOpen;
+ $tree .= $this->createFolder();
+ $tree .= $this->openNode($row);
+ $tree .= $this->createLink($row);
+ $this->_prevLvl = $j;
+ } elseif ($j < $this->_prevLvl) {
+ do {
+ $tree .= $this->closeNode();
+ $tree .= $this->closeFolder();
+ } while (--$this->_lvlsOpen > $j);
+ $tree .= $this->closeNode();
+ $tree .= $this->openNode($row);
+ $tree .= $this->createLink($row);
+ $this->_prevLvl = $this->_lvlsOpen;
+ }
+ }
+ $tree .= $this->closeFolder();
+ return $tree;
+ } catch (PDOException $e) {
+ return Toolkit_Common::handleError($e);
+ }
+ }
+
+ // }}}
+
+ // {{{ openNode()
+
+
+ /**
+ * Opens a branch or leaf node
+ *
+ * @param array $row Folder information
+ *
+ * @return string opening li tag
+ * @access protected
+ */
+ protected function openNode(array $row)
+ {
+ return "\n\t
GLM Image Browser
+
+
+
+
+
+
+
+ * public function &emailRenderElement($e)
+ * {
+ * switch ($e) {
+ * case 'element_one' :
+ * case 'element_two' :
+ * case 'element_three' :
+ * $renderer =& $this->defaultRenderer();
+ * $renderer->clearAllTemplates();
+ * $renderer->setGroupTemplate('{content}', $e);
+ * $renderer->setGroupElementTemplate('{element}
+ *
+ * @param array $newLabels Assoc array of element names and new
+ * labels to be used in the email form.
+ * eg [$newLabels['element'] => 'Label']
+ * @param array $excludeList Any element that needs to be removed
+ * from the form when creating the table
+ * eg [$list = array(e1, e2, e3, etc..)]
+ *
+ * @return mixed The table body for the email.
+ */
+ public function createEmailBody(
+ array $newLabels = array(),
+ array $excludeList = array()
+ ) {
+ $this->freeze();
+ // Get the values corresponding to the elements present in the form.
+ $formData = $this->exportValues();
+ // The array keys holds all the names of the elements.
+ $elements = array_keys($formData);
+ // Remove any unwanted elements from our elements array.
+ foreach ($excludeList as $trgt) {
+ unset($elements[array_search($trgt, $elements)]);
+ }
+
+ // Which row we are at.
+ $i = 0;
+ $table = new HTML_Table(array('class' => 'data'));
+ // Auto grow the table, since the forms will by dynamic in size.
+ $table->setAutoGrow(true);
+ // Get the labels and values of the elements.
+ foreach ($elements as $name) {
+ $e =& $this->getElement($name);
+ // Get the default HTML for each element.
+ $html = $e->toHtml();
+ // If any elements need to have their html
+ // changed for an email, this function in the
+ // class should exist and will return a renderer
+ // object of how the element should be rendered.
+ if (method_exists($this, 'emailRenderElement')) {
+ $renderer =& $this->emailRenderElement($name);
+ // make sure we have an actual rendering object
+ // if the element doesn't need to be altered it should
+ // just return null.
+ if (is_object($renderer)) {
+ $e->accept($renderer);
+ $html = $renderer->toHtml($name);
+ // We have to reset the entire forms html
+ // otherwise we'll just keep adding to it everytime
+ // we render a new element.
+ // This is a bit of a hack to make this work (because
+ // the _html element is supposed to be a private
+ // property)
+ $renderer->_html = null;
+ }
+ }
+ // Get the label for the element.
+ $label = array_key_exists($name, $newLabels) ?
+ $newLabels[$name] :
+ $e->getLabel();
+
+ // Make the row and increment the row counter.
+ $table->setCellContents($i, 0, $label);
+ $table->setCellAttributes($i, 0, array('class' => 'label'));
+ $table->setCellAttributes($i, 1, array('class' => 'field'));
+ $table->setCellContents($i++, 1, $html);
+ }
+ return $table->toHtml();;
+ }
+
+ // }}}
+ // {{{ createSQLInsert()
+
+ /**
+ * Generates a properly formatted sql query to insert data into a table
+ *
+ * @param string $table Name of the table to insert into
+ * @param array $columns Array of column names you want to set in the
+ * insert statement and bind names
+ *
+ *
', $e);
+ * break;
+ *
+ * default :
+ * $renderer = null;
+ * break;
+ * }
+ *
+ * return $renderer;
+ * }
+ *
+ * Toolkit_Common::createSQLInsert('member', array('name', 'pos'));
+ * will create the sql statement
+ * INSERT INTO member (name, pos) VALUES(:name, :pos)
+ *
+ *
+ * @return string Formatted SQL string
+ * @access public
+ * @static
+ */
+ public static function createSQLInsert($table, array $columns)
+ {
+ $params = implode(', ', $columns);
+ $bindParams = ':' . implode(', :', $columns);
+
+ return "INSERT INTO $table ($params) VALUES ($bindParams)";
+ }
+
+ // }}}
+ // {{{ createSQLUpdate()
+
+ /**
+ * Generates a properly formatted sql query to update data in a table
+ *
+ *
+ * Toolkit_Common::createSQLUpdate('member',
+ * array('name', 'pos'),
+ * array('id = :id');
+ * will create the sql statement
+ * UPDATE member SET name = :name, pos = :pos WHERE id = :id
+ *
+ *
+ * @param string $table Name of the table to update
+ * @param array $columns Array of columns names you want to update
+ * @param array $constraints Constraints to apply to the table to prevent
+ * running the update on every row in the db
+ *
+ * @return string formatted query string
+ * @access public
+ * @static
+ */
+ public static function createSQLUpdate(
+ $table,
+ array $columns,
+ array $constraints = null
+ ) {
+ $length = count($columns);
+ for ($i = 0; $i < $length; ++$i) {
+ $bindParams .= "{$columns[$i]} = :{$columns[$i]}";
+ if ($i < ($length - 1)) {
+ $bindParams .= ', ';
+ }
+ }
+ $sql = "UPDATE $table SET $bindParams";
+
+ if (!empty($constraints)) {
+ $sql .= ' WHERE ' . implode(' AND ', $constraints);
+ }
+
+ return $sql;
+ }
+
+ // }}}
+ // {{{ createTables()
+
+ /**
+ * Read file from parameter and use the PDO parameter to create process file
+ *
+ * @param PDO $pdo PHP Data Object to use for DB calls
+ * @param string $file full path of file to parse
+ *
+ * @return void
+ * @access public
+ * @static
+ */
+ public static function createTables(PDO $pdo, $file)
+ {
+ $sql = file_get_contents($file);
+ // break multiple queries apart by ';'
+ $tok = strtok($sql, ';');
+ try {
+ // while we have valid tokens, execute the query
+ // and grab the next token
+ while ($tok !== false) {
+ $pdo->query($tok);
+ $tok = strtok(';');
+ }
+ } catch (PDOException $e) {
+ Toolkit_Common::handleError($e);
+ }
+ }
+
+ // }}}
+
+ // {{{ dieGracefully()
+
+ /**
+ * Gracefully exit from the script when an unrecoverable error is created
+ *
+ * @param string $msg Message to display to user
+ * @param mixed $e Error object
+ * @param boolean $moreInfo More debugging info when in development
+ *
+ * @return void
+ * @access public
+ */
+ public function dieGracefully($msg = null, $e = null, $moreInfo = false)
+ {
+ if (is_null($e)) {
+ if (is_null($msg)) {
+ die('There was an error, please try again later!');
+ } else {
+ die($msg);
+ }
+ } else {
+ echo $msg . '
';
+ echo 'Error Caught.
';
+ echo 'Error: ' . $e->getMessage() . '
';
+ if ($moreInfo) {
+ echo 'Code: ' . $e->getCode() . '
';
+ echo 'Debug Info: ' . $e->getDebugInfo() . '
';
+ }
+ }
+ }
+
+ // }}}
+
+ // {{{ errorException()
+
+ /**
+ * Stops script on Exception error
+ *
+ * Stops the script when an Exception is raised inside a
+ * try/catch block.
+ *
+ * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+ * We don't show any error info, but let the user know an unexpected
+ * error has occured and then mail the error info the the admin.
+ *
+ * Example usage:
+ *
+ * try {
+ if ($foo != $bar) {
+ throw new Exception ("Foo Doesn't equal Bar");
+ }
+ * } catch (Exception $e) {
+ * return Toolkit_Common::handleError($e);
+ * }
+ *
+ *
+ * @param Exception $e Exception Object
+ * @param Mail $mail What to use to send mail to admin
+ *
+ * @return false
+ * @access public
+ * @static
+ */
+ public static function errorException(Exception $e, Mail $mail = null)
+ {
+ if (!is_null($mail)) {
+ $subject = 'Exception Error for ' . SITENAME;
+ self::mailError($mail, $subject, $e);
+ } else {
+ echo self::getErrorInfo($e);
+ }
+
+ return false;
+ }
+
+ // }}}
+ // {{{ errorHTMLQuickFormError()
+
+ /**
+ * Handles PEAR Errors for our developers
+ *
+ * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+ * We don't show any error info, but let the user know an unexpected
+ * error has occured and then mail the error info the the admin.
+ *
+ * HTML_QuickForm Example usage:
+ *
+ * $e =& $this->getElement('elementName');
+ * if (PEAR::isError($e)) {
+ * return Toolkit_Common::handleError($e);
+ * }
+ *
+ *
+ * @param HTML_QuickForm_Error $e QuickFormError Object
+ * @param Mail $mail What to use to send mail to admin
+ *
+ * @return false
+ * @access public
+ * @since Method available since Release 1.0.1
+ * @static
+ */
+ public static function errorHTMLQuickFormError(
+ HTML_QuickForm_Error $e,
+ Mail $mail = null
+ ) {
+ if (!is_null($mail)) {
+ $subject = 'PEAR Error for ' . SITENAME;
+ self::mailError($mail, $subject);
+ } else {
+ echo self::getErrorInfo($e);
+ }
+
+ return false;
+ }
+
+ // }}}
+ // {{{ errorPDOException()
+
+ /**
+ * Stops script on database error
+ *
+ * Stops the script when a PDOException is raised inside a
+ * try/catch block.
+ *
+ * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+ * We don't show any error info, but let the user know an unexpected
+ * error has occured and then mail the error info the the admin.
+ *
+ * Example usage:
+ *
+ * try {
+ * $sql = "
+ * SELECT *
+ * FROM table_name
+ * WHERE id = :id";
+ *
+ * $stmt = $this->dbh->prepare($sql);
+ * $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+ * return $stmt->execute();
+ * } catch (PDOException $e) {
+ * return Toolkit_Common::handleError($e);
+ * }
+ *
+ *
+ * @param PDOException $e PDO Error Object.
+ * @param Mail $mail Mail object used to send admin email
+ *
+ * @return false
+ * @access public
+ * @since Method available since Release 1.0.1
+ */
+ public function errorPDOException(PDOException $e, Mail $mail = null)
+ {
+ if (!is_null($mail)) {
+ $subject = 'SQL Error for ' . SITENAME;
+ self::mailError($mail, $subject, $e);
+ } else {
+ echo self::getErrorInfo($e);
+ }
+
+ return false;
+ }
+
+ // }}}
+ // {{{ errorPEARError()
+
+ /**
+ * Handles PEAR Errors for our developers
+ *
+ * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+ * We don't show any error info, but let the user know an unexpected
+ * error has occured and then mail the error info the the admin.
+ *
+ * @param PEAR_Error $e PEARError Object
+ * @param Mail $mail Mail object used to send admin email
+ *
+ * @return false
+ * @access public
+ * @since Method available since Release 1.0.1
+ */
+ public function errorPEARError(PEAR_Error $e, Mail $mail = null)
+ {
+ if (!is_null($mail)) {
+ $subject = 'PEAR Error for ' . SITENAME;
+ self::mailError($mail, $subject);
+ } else {
+ echo self::getErrorInfo($e);
+ }
+
+ return false;
+ }
+
+ // }}}
+ // {{{ errorPEARException()
+
+ /**
+ * Handles PEAR Exception for our developers
+ *
+ * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+ * We don't show any error info, but let the user know an unexpected
+ * error has occured and then mail the error info the the admin.
+ *
+ * @param PEAR_Exception $e PEARException Object
+ * @param Mail $mail Mail object used to send admin email
+ *
+ * @return false
+ * @access public
+ * @since Method available since Release 1.0.1
+ */
+ public function errorPEARException(PEAR_Exception $e, Mail $mail = null)
+ {
+ if (!is_null($mail)) {
+ $subject = 'SQL Error for ' . SITENAME;
+ self::mailError($mail, $subject, $e);
+ } else {
+ echo self::getErrorInfo($e);
+ }
+
+ return false;
+ }
+
+ // }}}
+ // {{{ errorRuntimeException()
+
+ /**
+ * Stops script on runtime error
+ *
+ * Stops the script when a runtimeException is raised inside a
+ * try/catch block.
+ *
+ * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+ * We don't show any error info, but let the user know an unexpected
+ * error has occured and then mail the error info the the admin.
+ *
+ * @param RuntimeException $e PDO Error Object.
+ * @param Mail $mail Mail object used to send admin email
+ *
+ * @return false
+ * @access public
+ * @since Method available since Release 1.0.2
+ */
+ public function errorRuntimeException(
+ RuntimeException $e,
+ Mail $mail = null
+ ) {
+ if (!is_null($mail)) {
+ $subject = 'Runtime Exception for ' . SITENAME;
+ self::mailError($mail, $subject, $e);
+ } else {
+ echo self::getErrorInfo($e);
+ }
+
+ return false;
+ }
+
+ // }}}
+ // {{{ errorBadMethodCallException()
+
+ /**
+ * Stops script on bad method call error
+ *
+ * Stops the script when a badMethodCallException is raised inside a
+ * try/catch block.
+ *
+ * When a site is no longer in DEVELOPMENT, ie: its live on ws3.
+ * We don't show any error info, but let the user know an unexpected
+ * error has occured and then mail the error info the the admin.
+ *
+ * @param BadMethodCallException $e PDO Error Object.
+ * @param Mail $mail Mail object used to send admin email
+ *
+ * @return false
+ * @access public
+ * @since Method available since Release 1.0.3
+ */
+ public function errorBadMethodCallException(
+ BadMethodCallException $e,
+ Mail $mail = null
+ ) {
+ if (!is_null($mail)) {
+ $subject = 'Bad Method Call Exception for ' . SITENAME;
+ self::mailError($mail, $subject, $e);
+ } else {
+ echo self::getErrorInfo($e);
+ }
+
+ return false;
+ }
+
+ // }}}
+
+ // {{{ filterURI()
+
+ /**
+ * Filters uri's before they are validated
+ *
+ * @param string $uri URI to filter
+ *
+ * @return mixed new uri if missing scheme
+ * @access public
+ * @static
+ */
+ public static function filterURI($uri)
+ {
+ $validProtocol = '/^https?\:\/\/.*/';
+ $invalidProtocol = '/^.*?\:\/\/.*/';
+ if (empty($uri)) {
+ // Empty field, just return
+ return $uri;
+ } elseif (preg_match($validProtocol, $uri)) {
+ // has valid protocol, return unchanged
+ // should pass validation.
+ return $uri;
+ } elseif (!preg_match($invalidProtocol, $uri)) {
+ // missing protocol, prepend default
+ // http:// protocol and return.
+ return "http://$uri";
+ } else {
+ // has invalid protocol, return unchanged
+ // validation should catch this and throw error.
+ return $uri;
+ }
+ }
+
+ // }}}
+ // {{{ filterPhone()
+
+ /**
+ * Filters phone numbers before they are validated
+ *
+ * @param string $phone number to filter
+ *
+ * @return mixed newly formatted phone number
+ * @access public
+ * @static
+ */
+ public static function filterPhone($phone)
+ {
+ // Ditch anything that is not a number
+ $number = preg_replace('/[^0-9]/', '', $phone);
+
+ // Invalid Number, validation will catch error
+ $len = strlen($number);
+ if (($len < 10) || ($len > 11)) {
+ return $phone;
+ }
+
+ // subscriber number
+ $sn = substr($number, -4);
+ // city code
+ $cc = substr($number, -7, 3);
+ // area code
+ $ac = substr($number, -10, 3);
+ if ($len == 11) {
+ // country prefix
+ $cp = $number[0];
+ }
+
+ $filteredNumber = "($ac) $cc-$sn";
+ if (!is_null($cp)) {
+ $filteredNumber = "$cp $filteredNumber";
+ }
+
+ return $filteredNumber;
+ }
+
+ // }}}
+
+ // {{{ getCities()
+
+ /**
+ * Get an array of cities from the database
+ *
+ * @param PDO $dbh Database handler
+ * @param integer $state State id the city is in
+ * @param integer $county County id the city is in
+ * @param integer $region Region id the city is in
+ *
+ * @return array states
+ * @access public
+ * @static
+ */
+ public static function getCities(
+ PDO $dbh,
+ $state = null,
+ $county = null,
+ $region = null
+ ) {
+ $param = array();
+ if (ctype_digit((string)$state)) {
+ $param[] = 'state_id = ' . $dbh->quote($state);
+ }
+ if (ctype_digit((string)$county)) {
+ $param[] = 'county_id = ' . $dbh->quote($county);
+ }
+ if (ctype_digit((string)$region)) {
+ $param[] = 'region_id = ' . $dbh->quote($region);
+ }
+
+ try {
+ $sql = "
+ SELECT *
+ FROM city";
+
+ if (!empty($param)) {
+ $sql .= ' WHERE ' . implode(' AND ', $param);
+ }
+ $sql .= ' ORDER BY city_name';
+
+ $stmt = $dbh->prepare($sql);
+ $stmt->execute();
+
+ $cities = array();
+ while ($row = $stmt->fetch()) {
+ $cities[$row['city_id']] = $row['city_name'];
+ }
+
+ return $cities;
+ } catch (PDOException $e) {
+ return Toolkit_Common::handleError($e);
+ }
+ }
+
+ // }}}
+ // {{{ getErrorInfo()
+
+ /**
+ * extract error info from error object
+ *
+ * @param mixed $obj Error object to get info for
+ *
+ * @return string formatted error information
+ * @access public
+ */
+ public function getErrorInfo($obj)
+ {
+ $state = '' . get_class($obj) . ' error: ';
+
+ $state .= '
$_SERVER[\'QUERY_STRING\']: ' . $_SERVER['QUERY_STRING']
+ . "\n";
+ $state .= '
$_SERVER[\'HTTP_REFERER\']: ' . $_SERVER['HTTP_REFERER']
+ . "\n";
+ $state .= '
$_SERVER[\'REDIRECT_QUERY_STRING\']: '
+ . $_SERVER['REDIRECT_QUERY_STRING'] . "\n";
+ $state .= '
$_SERVER[\'REQUEST_URI\']: ' . $_SERVER['REQUEST_URI']
+ . "\n";
+
+ $state .= '
$_GET: ' . print_r($_GET, true) . '
';
+ $state .= '
$_POST: ' . print_r($_POST, true) . '
';
+ $state .= '
$_SESSION: ' . print_r($_SESSION, true) . '
';
+
+ if (method_exists($obj, 'getMessage')) {
+ $state .= $obj->getMessage();
+ if (method_exists($obj, 'getDebugInfo')) {
+ $state .= '; ' . $obj->getDebugInfo();
+ }
+ }
+ if (method_exists($obj, 'getFile')) {
+ $state .= ' in ' . $obj->getFile() . '';
+ }
+ if (method_exists($obj, 'getLine')) {
+ $state .= ' on line ' . $obj->getLine() . '';
+ }
+ if (method_exists($obj, 'getBacktrace')) {
+ $backtrace = print_r($obj->getBacktrace(), true);
+
+ $state .= "$backtrace
";
+ }
+
+ return $state;
+ }
+
+ // }}}
+ // {{{ getHierarchicalTreeStructure()
+
+ /**
+ * Create a hierarchical tree stored in an linear array
+ *
+ * Produces a representation of a hierarchical tree structure into a
+ * linear array so you can iterate straight through to get the tree
+ * structure.
+ *
+ * @param PDO $pdo Database handler
+ * @param string $table Name of the source relation
+ * @param string $key Name of the key field
+ * @param string $parent Name of the parent-key field
+ * @param string $order Name of the field to order siblings by
+ * @param integer $start Key value of the row to start at
+ * @param integer $maxDepth Maximum depth to descend to, or zero
+ * for unlimited depth
+ * @param boolean $validParent exclude branches that have null
+ * parent values
+ *
+ * @return array Linear array of tree structure
+ * @access public
+ * @see http://www.postgresql.org/doc/8.3/interactive/tablefunc.html#AEN104085
+ */
+ public function getHierarchicalTreeStructure(
+ PDO $pdo,
+ $table = 'pages',
+ $key = 'id',
+ $parent = 'parent',
+ $order = 'pos',
+ $start = 0,
+ $maxDepth = 0,
+ $validParent = true
+ ) {
+ try {
+ $tree = array();
+
+ $sql = "
+ SELECT *
+ FROM connectby('{$table}', '{$key}', '{$parent}',
+ '{$order}', '{$start}', {$maxDepth})
+ as t(id text, parent text, level int, pos int)";
+ if ($validParent) {
+ $sql .= " WHERE parent is not null";
+ }
+ foreach ($pdo->query($sql) as $row) {
+ $tree[$row['id']] = $row['level'];
+ }
+
+ return $tree;
+ } catch (PDOException $e) {
+ return self::handleError($e);
+ }
+ }
+
+ // }}}
+ // {{{ getScripts()
+
+ /**
+ * Gets all scripts for the page
+ *
+ * adds version number to url for all local (non-app.glm) urls
+ * so we can use .htaccess cachebusting
+ *
+ * combines script by server id, so we can decrease http requests to fetch
+ * the needed scripts
+ *
+ * @param array $scripts The array of js scripts for the page
+ *
+ * @return string HTML markup for scripts
+ * @access public
+ * @static
+ */
+ public static function getScripts(array $scripts)
+ {
+ if (!is_array($scripts) || empty($scripts)) {
+ return false;
+ }
+
+ $uniqueScripts = array_unique($scripts);
+ // Get the main jquery file
+ $jquery = JQUERY_CDN_JS;
+ $key = array_search($jquery, $uniqueScripts);
+ // If it exists, remove it from its current location
+ // and put at front of array.
+ if ($key !== false) {
+ unset($uniqueScripts[$key]);
+ array_unshift($uniqueScripts, $jquery);
+ }
+ $format = '';
+
+ $ret = '';
+ $baseUrlStrLen = strlen(MEDIA_BASE_URL);
+ $appUrlStrLen = strlen(MEDIA_APP_BASE_URL);
+
+ // Use versioning with local scripts for cachebusting
+ $localPath = MEDIA_BASE_URL . 'v/' . VERSION . '/javascript/';
+ $appPath = MEDIA_APP_BASE_URL . 'javascript/';
+
+ $localScripts = array();
+ $appScripts = array();
+ foreach ($uniqueScripts as $origScript) {
+ $ret .= sprintf($format, $origScript) . "\n";
+ }
+
+ if (!empty($appScripts)) {
+ $appPath = $appPath . implode(',', $appScripts);
+ $ret .= sprintf($format, $appPath) . "\n";
+ }
+
+ if (!empty($localScripts)) {
+ $localPath = $localPath . implode(',', $localScripts);
+ $ret .= sprintf($format, $localPath) . "\n";
+ }
+
+ return $ret;
+ }
+
+ // }}}
+ // {{{ getStates()
+
+
+ /**
+ * Get an array of states from the database
+ *
+ * @param PDO $dbh Database handler
+ * @param boolean $unionStatesOnly If we want to only retrieve
+ * the 50 US states
+ *
+ * @return array states
+ * @access public
+ * @static
+ */
+ public static function getStates(PDO $dbh, $unionStatesOnly = false)
+ {
+ if ($unionStatesOnly) {
+ // Just grab the 50 states of the union
+ $where = "WHERE us_state = :bool";
+ }
+
+ try {
+ $sql = "
+ SELECT *
+ FROM state
+ $where
+ ORDER BY state_name";
+
+ $stmt = $dbh->prepare($sql);
+ if ($unionStatesOnly) {
+ $stmt->bindValue(':bool', 1, PDO::PARAM_BOOL);
+ }
+ $stmt->execute();
+
+ $states = array();
+ while ($row = $stmt->fetch()) {
+ $states[$row['state_id']] = $row['state_name'];
+ }
+
+ return $states;
+ } catch (PDOException $e) {
+ return Toolkit_Common::handleError($e);
+ }
+ }
+
+ // }}}
+ // {{{ getStyleSheets()
+
+ /**
+ * Gets all style sheets for the page
+ *
+ * adds version number to url for all local (non-app.glm) urls
+ * so we can use .htaccess cachebusting
+ *
+ * combines style sheets by server id, so we can decrease http
+ * requests to fetch the needed style sheets
+ *
+ * @return string HTML markup for stylesheets
+ * @access public
+ * @static
+ */
+ public static function getStyleSheets()
+ {
+ if ( !isset($GLOBALS['styleSheets'])
+ || !is_array($GLOBALS['styleSheets'])
+ || empty($GLOBALS['styleSheets'])
+ ) {
+ return false;
+ }
+
+ $uniqueStyleSheets = array_unique($GLOBALS['styleSheets']);
+ $format = '';
+
+ $baseUrlStrLen = strlen(MEDIA_BASE_URL);
+ $appUrlStrLen = strlen(MEDIA_APP_BASE_URL);
+ $ret = '';
+
+ $localPath = MEDIA_BASE_URL . 'v/' . VERSION . '/css/';
+ $appPath = MEDIA_APP_BASE_URL . 'css/';
+
+ $localStyleSheets = array();
+ $appStyleSheets = array();
+ foreach ($uniqueStyleSheets as $origStyleSheet) {
+ $ret .= sprintf($format, $origStyleSheet) . "\n";
+ }
+
+ if (!empty($appStyleSheets)) {
+ $appPath = $appPath . implode(',', $appStyleSheets);
+ $ret .= sprintf($format, $appPath) . "\n";
+ }
+ if (!empty($localStyleSheets)) {
+ $localPath = $localPath . implode(',', $localStyleSheets);
+ $ret .= sprintf($format, $localPath) . "\n";
+ }
+
+ return $ret;
+ }
+
+ // }}}
+ // {{{ getTableMetaData()
+
+ /**
+ * Gets the meta data of the calling classes table columns
+ *
+ * The table used when retrieving the meta data is defined
+ * in the class property $tableName. The class or parent class
+ * must also have a $tableMetaData property
+ *
+ * @param PDO $pdo Database Handler
+ * @param string $tableName The name of the table to get the meta data for.
+ * @param array $clauses Only retrieve meta data for certain column types
+ *
+ * @return array metadata for table
+ * @access protected
+ */
+ public function getTableMetaData(
+ PDO $pdo,
+ $tableName,
+ array $clauses = null
+ ) {
+ if (is_array($clauses)) {
+ while ($c = current($clauses)) {
+ $ands .= " data_type = '{$c}'";
+ if (false !== next($clauses)) {
+ $ands .= " OR ";
+ }
+ }
+ $ands = " AND ($ands)";
+ }
+ try {
+ $sql = "
+ SELECT column_name, data_type
+ FROM information_schema.columns
+ WHERE table_name = :tname
+ $ands";
+ $stmt = $pdo->prepare($sql);
+ $stmt->bindParam(':tname', $tableName, PDO::PARAM_STR);
+
+ $stmt->execute();
+
+ $metaData = array();
+ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ $metaData[$row['column_name']] = $row['data_type'];
+ }
+
+ return $metaData;
+ } catch (PDOException $e) {
+ return self::handleError($e);
+ }
+ }
+
+ // }}}
+
+ // {{{ handleError()
+
+ /**
+ * Handles various script error
+ *
+ * @param Object $e Error Object
+ * @param boolean $developmentServer If we are on a development server
+ *
+ * @return mixed String, false, void
+ * @access public
+ * @static
+ */
+ public static function handleError($e, $developmentServer = DEVELOPMENT)
+ {
+ $errorType = str_replace('_', '', get_class($e));
+ $errorType = "error$errorType";
+
+ if (method_exists(__CLASS__, $errorType)) {
+ if (!$developmentServer) {
+ // Tell the user we encountered an Error.
+ if (file_exists(BASE . '404.html')) {
+ include_once BASE . "404.html";
+ }
+
+ $mail = Mail::factory('mail');
+ self::$errorType($e, $mail);
+ exit();
+ } else {
+ return self::$errorType($e, $mail);
+ }
+ } else {
+ echo '
+ * $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('phone', 'zip', 'state');
+
+ // }}}
+ // {{{ __construct()
+
+ /**
+ * 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
We will email you a link to the PDF version of the {brochure}.
+ORDER BY MAIL:
+{contactForm:h} diff --git a/Toolkit/Contacts/templates/contactForm.html b/Toolkit/Contacts/templates/contactForm.html new file mode 100644 index 0000000..2f2f84a --- /dev/null +++ b/Toolkit/Contacts/templates/contactForm.html @@ -0,0 +1,92 @@ ++ {sec.header:h} | +||||||||
+ | {elem.html:h} | +|||||||
+ {if:elem.required}*{end:}
+ {if:elem.error} {end:}
+ {elem.label:h} {end:}
+ {else:}
+ {if:elem.isType(#CAPTCHA_Image#)}
+ + {if:elem.error} |
+ {if:elem.required}*{end:}
+ {if:elem.error} {end:}
+ {elem.label:h}
+ {if:elem.error} {end:}
+ |
+ + {else:} + {if:elem.isType(#group#)} + |
+ {if:elem.required}*{end:}
+ {if:elem.error} {end:}
+ {elem.label:h} {end:}
+ {else:}
+ + {if:elem.error} |
+ {if:elem.required}*{end:}
+ {if:elem.error} {end:}
+ {elem.label:h}
+ {if:elem.error} {end:}
+ |
+ {if:elem.isName(#interest#)}
+ + {else:} + |
+ {end:}
+ {end:}
+ {end:}
+ {end:}
+ {if:elem.error} {elem.error} {end:}
+ {if:elem.isType(#group#)}
+ {foreach:elem.elements,gitem}
+ {gitem.label:h}
+ {gitem.html:h}{if:gitem.required}* {end:}
+ {if:elem.separator}{elem.separator:h}{end:}
+ {end:}
+ {else:}
+ {elem.html:h}
+ {if:elem.isName(#captcha_rmv#)}
+ What is this?
+
+ {end:}
+ {end:}
+ |
+
Below is the list of businesses you have added to your Trip Planner. The form below will be sent to each individual business listing that has an email address listed with their business listing. For those businesses with no email address, we have included their phone numbers for you to call directly and request additional information.
+These business listings have no current email address on file. To receive additional information please call the phone numbers listed next to each business name.
+Name + | Phone + | + |
---|---|---|
{member[memberName]} | +{member[memberPhone]} | +Remove | +
This list of businesses will receive the following information form directly to their email account.
+{member[memberName]} | +Remove | +
+ + {subject:h} + +
++ + From {fname:h} {lname:h} + +
+
+
|
+ |||
+
|
+
Dear {fname}
+Your friend {yname} has been to demo.gaslightmedia.com, and thought you might be interested in it.
+Message here.
+Thank you for requesting the {pdfName} Link. Here is the link to the Adobe PDF version: +
+Brochure ({pdfFileSize})
+Thank you for your interest in {client_info[name]:h}'!
+Sincerely,
+{client_info[name]:h}
+{client_info[url]:h}
+ + + diff --git a/Toolkit/DataGridBuilder.php b/Toolkit/DataGridBuilder.php new file mode 100644 index 0000000..ced09b6 --- /dev/null +++ b/Toolkit/DataGridBuilder.php @@ -0,0 +1,288 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @link http://demo.gaslightmedia.com + */ + +/** + * Create Datagrids for displaying data + * + * This abstract class handles all the base functionality of creating + * handeling all the details associated w/ a regular dataGrid. + * 1. Creation + * 2. Sorting (via column headers or sortform) + * 3. Pagenation + * + * @category Structures + * @package Toolkit_DataGridBuilder + * @author Jamie Kahgee
+ * protected $email = false;
+ *
+ *
+ * @var unknown
+ * @access protected
+ */
+ protected $email;
+
+ /**
+ * From header in the owner email
+ *
+ * This just sets the From header in the owner email
+ * SITENAME
+ * protected $email = false;
+ *
+ *
+ * @var unknown
+ * @access protected
+ */
+ protected $email;
+
+ /**
+ * From header in the owner email
+ *
+ * This just sets the From header in the owner email
+ * SITENAME ' . $calendar . ' ' + . (($size == 2) + ? $year + : '') . ' | +||||||
' . $prev_month . ' | +' . $calendar . ' ' + . (($size == 2) + ? $year + : '') . ' | +' . $next_month . ' | +||||
' . $week_titles[$x] . ' | + '; + } + $out .= ' +||||||
", $offset + ); + } + $offset = ($offset == 7) + ? 0 + : $offset; + // start entering in the information + for ($day = 1; $day <= $totaldays; $day++) { + $out .= ' + | '; + $datelink = $this->getEventData($month, $day, $year, $eventObj); + if ($size == 1 && $datelink) { + $out .= '' + . $day . ''; + } elseif ($datelink) { + $out .= $day . ''; + $out .= $datelink; + } else { + $out .= $day . ''; + } + $out .= ' | + '; + $offset++; + // if we're on the last day of the week, wrap to the other side + if ($offset > 6) { + $offset = 0; + $out .= ' +|||||
", $offset + ); + } + // end the table + $out .= ' + |
Goes back to color array and grabs the class for that peticular color.
+ * + * @param string $color Color to use + * + * @return string class to use for style. + */ + + function disColor($color) + { + // get style class for this color + return $this->_colorArray[$color]; + } + + // }}} + // {{{ lastDayOfMonth() + /** + * lastDayOfMonth + * + *given timestamp get the last day of the month it + * fall in
+ * + * @param string $time Timestamp + * + * @return string timestamp + */ + function lastDayOfMonth($time = '') + { + $timestamp = ($time == '') + ? time() + : $time; + $timePart = date("Y-m", $timestamp); + return strtotime($timePart . ' last day'); + } + + // }}} + // {{{ myGetTimeStamp() + + /** + * gets time stamp + * + * Long description (if any)... + * + * @param unknown $time Parameter description (if any)... + * @param boolean $all_day Parameter description (if any)... + * + * @return integer Return description (if any)... + * @access public + */ + function myGetTimeStamp($time, $all_day = false) + { + static $count, $count2; + $count = ($count) + ? $count + : 1; + $count2 = ($count2) + ? $count2 + : 1; + $pattern = "/^([0-9]{1,2}):?([0-9]{1,2})? ?([AP]M)/i"; + if (!$all_day && preg_match($pattern, trim($time), $tar1)) { + if (($tar1[3] == 'PM' || $tar1[3] == 'pm') && (int) $tar1[1] < 12) { + $a1 = (int) $tar1[1] + 12; + } else { + $a1 = (int) $tar1[1]; + } + $a2 = $tar1[2]; + $time1 = mktime($a1, $a2, $count++, 1, 1, 2000); + return $time1; + } else { + if ($all_day) { + $time1 = $count2++; + } else { + $time1 = 999999999 + $count++; + } + return $time1; + } + } + + // }}} + // {{{ ordinalDay() + /** + * ordinalDay + * get ordinal (th)day for given timestamp + * + * @param int $ord ordinal number + * @param int $day number of day + * @param int $month number of month + * @param int $year number of year + * + * @access public + * @return int + */ + + function ordinalDay($ord, $day, $month, $year) + { + $firstOfMonth = strtotime("{$month}/01/{$year}"); + $lastOfMonth = $firstOfMonth + date("t", $firstOfMonth) * 86400; + $dayOccurs = 0; + for ($i = $firstOfMonth; $i < $lastOfMonth; $i += 86400) { + if (date("w", $i) == $day) { + $dayOccurs++; + if ($dayOccurs == $ord) { + $ordDay = $i; + } + } + } + return $ordDay; + } + + // }}} + // {{{ showEventHeaders() + /** + * showEventHeaders + * + * @param string $date date string + * @param mixed $eventObj Pass the EventCalendar Obj + * + * @access public + * @return string + */ + + function showEventHeaders($date, $eventObj) + { + $pattern = "/([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{4})/"; + if (preg_match($pattern, $date, $dpart)) { + $month = (int) $dpart[1]; + $year = (int) $dpart[3]; + } + if (is_array($this->_eventsData[$date])) { + foreach ($this->_eventsData[$date] as $num => $data) { + $btime = $this->calTime($data['btime']); + $etime = $this->calTime($data['etime']); + $all_day = ($data['all_day'] == 't') + ? 1 + : 0; + $stime = (int) $this->myGetTimeStamp($btime, $all_day); + $data2[(int) $stime] = 'Show an advanced search form
+ * + * @return string + */ + function advancedSearch() + { + $out = ''; + $out .= $this->getEventSearch(1); + $out .= ' +Search For: | ++ + | +
Search By Category: | +
+ ';
+ $sql = "
+ SELECT id,descr
+ FROM topic";
+ try {
+ $data = $this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
+ } catch (PDOException $e) {
+ Toolkit_Common::handleError($e);
+ }
+ if ($data) {
+ foreach ($data as $key => $val) {
+ $out .= '
+
+ '; + } + } + $out .= ' + |
+
From: | ++ (MM/DD/YYYY) + | +
To: | ++ (MM/DD/YYYY) + | +
+ | +
+ * protected $email = false;
+ *
+ *
+ * @var unknown
+ * @access protected
+ */
+ protected $email;
+
+ /**
+ * From header in the owner email
+ *
+ * This just sets the From header in the owner email
+ * SITENAME ' . $prevLink . ' | +' + . $monthText->thisMonthName() + . ' ' + . $Month->thisYear() + . ' | +' . $nextLink . ' | +||||
---|---|---|---|---|---|---|
\n"; + } else { + $out .= ' | '; + // if the day isSelected then create a link + if ($Day->isSelected()) { + // Calendar_Decorator_Uri for links + $dayUri = new Calendar_Decorator_Uri($Day); + $dayUri->setFragments('year', 'month', 'day'); + $out .= '' . $Day->thisDay(). ''; + } else { + $out .= $Day->thisDay(); + } + $out .= " | \n"; + } + + if ($Day->isLast()) { + $out .= "
Add New Category: | ++ | + |
+ | + | + | + |
{v[label]:h} | + {if:v[nowrap]} +{v[element]:h} | + {else:} +{v[element]:h} | + {end:} +
A new Event has been added to your Website from your "Add Your Event" page.
+To approve it, please go to the Pending Events page in your admin.
+ + diff --git a/Toolkit/Events/templates/eventDetail.html b/Toolkit/Events/templates/eventDetail.html new file mode 100755 index 0000000..667dd91 --- /dev/null +++ b/Toolkit/Events/templates/eventDetail.html @@ -0,0 +1,58 @@ + +{event[header]:h}
+ {else:} +No events found
+ {end:} +{event[bdate]}
+ {event[header]} +Showing {search}
+{if:events} + {foreach:events,event} + {if:event[spans]}{event[dates]}
+Ongoing Event
{end:} + {if:event[reacur]}Repeating Event
{end:} +No events were found for your search.
+{end:} +
+ * $this->ctrlObj['url'] = MEDIA_BASE_URL;
+ *
+ *
+ *
+ * public function configureElements()
+ * {
+ * $e = array();
+ *
+ * $e[] = array(
+ * 'type' => 'text',
+ * 'req' => false
+ * 'name' => 'text_field',
+ * 'display' => 'Text Label',
+ * );
+ * $e[] = array(
+ * 'type' => 'checkbox',
+ * 'req' => false
+ * 'name' => 'checkbox_field',
+ * 'display' => 'Checkbox Label',
+ * );
+ *
+ * // ... More Element Definitions
+ *
+ * $this->setupElements($e);
+ * }
+ *
+ *
+ * @access public
+ * @return void
+ */
+ //public function configureElements();
+
+ // }}}
+ // {{{ configureForm()
+
+ /**
+ * Calls all the configuration methods to configure a form for use
+ *
+ * @access public
+ * @return void
+ */
+ //public function configureForm();
+
+ // }}}
+ // {{{ configureRules()
+
+ /**
+ * Defines all element rules to be used for validation in the form
+ *
+ * At the bare minimum, this function needs to be called to setup the
+ * form rules, even if no extra rules are defined. Because it still
+ * creates all the required rules that are defined w/ each element.
+ *
+ *
+ * public function configureRules()
+ * {
+ * $r = array();
+ *
+ * $r[] = array(
+ * 'element' => 'text_field',
+ * 'message' => 'ERROR: 10 characters max!',
+ * 'type' => 'maxlength',
+ * 'format' => 10,
+ * 'validation' => $this->validationType,
+ * 'reset' => true,
+ * 'force' => false,
+ * );
+ * $r[] = array(
+ * 'element' => 'text_field',
+ * 'message' => 'ERROR: Numric characters only!',
+ * 'type' => 'numeric',
+ * 'format' => null,
+ * 'validation' => $this->validationType,
+ * 'reset' => true,
+ * 'force' => false,
+ * );
+ *
+ * // ... More Rule Definitions
+ *
+ * $this->setupRules($r);
+ * }
+ *
+ *
+ * @access public
+ * @return void
+ */
+ public function configureRules();
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Get an html string that contains the form
+ *
+ * Check if the form needs to be validated (ie. it was submitted)
+ * Check if submitted data needs to be processed
+ *
+ * @access public
+ * @return string an html string that contains the entire form
+ */
+ public function toHtml();
+
+ // }}}
+}
diff --git a/Toolkit/FormBuilder.php b/Toolkit/FormBuilder.php
new file mode 100644
index 0000000..4eb5592
--- /dev/null
+++ b/Toolkit/FormBuilder.php
@@ -0,0 +1,1264 @@
+
+ * @license http://www.gaslightmedia.com Gaslightmedia
+ * @version CVS: $Id: FormBuilder.php,v 1.48 2010/08/05 14:19:47 jamie Exp $
+ * @link http://demo.gaslightmedia.com
+ */
+
+/**
+ * Allow the inclusion of the Element Grid plugin for QuickForms
+ */
+require_once 'HTML/QuickForm/ElementGrid.php';
+
+/**
+ * Handle QuickForm CAPTCHA's
+ */
+require_once 'HTML/QuickForm/CAPTCHA/Image.php';
+
+/**
+ * Require PEAR QuickForm class
+ */
+require_once 'HTML/QuickForm.php';
+
+require_once 'HTML/QuickForm/Rule/Zip.php';
+require_once 'HTML/QuickForm/Rule/Phone.php';
+require_once 'HTML/QuickForm/Rule/Banwords.php';
+require_once 'HTML/QuickForm/Rule/State.php';
+
+/**
+ * Base functionality for creating HTML_Quickforms
+ *
+ * @category Toolkit
+ * @package FormBuilder
+ * @author Jamie Kahgee
+ * $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('phone', 'zip', 'state');
+
+ // }}}
+ // {{{ __construct()
+
+ /**
+ * Class 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 defaults to '_self'
+ * @param mixed $attributes (optional)Extra attributes for
+ * class exampleClass
+ * {
+ * $registeredRules = array(
+ * array(
+ * 'checkEmail',
+ * 'callback',
+ * 'email',
+ * 'Validate'
+ * )
+ * );
+ *
+ * // ... Rest of your class code
+ *
+ * public function configureRules()
+ * {
+ * $r = array();
+ *
+ * $r[] = array(
+ * 'element' => 'process_email',
+ * 'message' => 'ERROR: Invalid email format!',
+ * 'type' => 'checkEmail',
+ * 'format' => array('use_rfc822' => true),
+ * 'validation' => $this->validationType,
+ * 'reset' => false,
+ * 'force' => false
+ * );
+ *
+ * $this->setupRules($r);
+ * }
+ *
+ * // ... Rest of your class code
+ * }
+ *
+ *
+ * If the registeredRule is a string, the corresponding rule in the
+ * glmPEAR/HTML/QuickForm/Rule/ directory will be registered with
+ * the form.
+ *
+ * This will set up the 'phone' rule already defined in the
+ * glmPEAR/HTML/QuickForm/Rule directory which validates both
+ * US and Canadian phone numbers
+ *
+ * class exampleClass
+ * {
+ * $registeredRules = array('phone');
+ *
+ * // ... Rest of your class code
+ *
+ * public function configureRules()
+ * {
+ * $r = array();
+ *
+ * $r[] = array(
+ * 'element' => 'phone',
+ * 'message' => 'ERROR: Invalid number (xxx) xxx-xxxx!',
+ * 'type' => 'phone',
+ * 'format' => null,
+ * 'validation' => $this->validationType,
+ * 'reset' => false,
+ * 'force' => false
+ * );
+ *
+ * $this->setupRules($r);
+ * }
+ *
+ * // ... Rest of your class code
+ * }
+ *
+ *
+ * @return void
+ * @access protected
+ */
+ protected function registerRules()
+ {
+ if (is_array($this->registeredRules)) {
+ foreach ($this->registeredRules as $r) {
+ if (is_array($r)) {
+ call_user_func_array(array(&$this, 'registerRule'), $r);
+ } else {
+ // Don't nedd to register rules more than once
+ if (!$this->isRuleRegistered($r)) {
+ $this->registerRule($r, null, "HTML_QuickForm_Rule_$r");
+ }
+ }
+ }
+ }
+ }
+
+ // }}}
+
+ // {{{ setAutoValidateDateElements()
+
+ /**
+ * Set if we need to auto validate the Date Elements
+ *
+ * @param boolean $validate true/false to auto validate date elements
+ *
+ * @return void
+ * @access public
+ */
+ public function setAutoValidateDateElements($validate)
+ {
+ $this->autoValidateDateElements = $validate;
+ }
+
+ // }}}
+ // {{{ setFormData()
+
+ /**
+ * Sets the submitted values from the form
+ *
+ * Set these values into an internal variable so they will be accessible
+ * anywhere we need them in the form.
+ *
+ * @param array $exclude (optional) Any element names you don't want
+ * included. Since this is primarily used in
+ * emailing, this is helpful to exclude any data
+ * we don't want before the array is generated.
+ *
+ * @return void
+ * @access protected
+ */
+ protected function setFormData(array $exclude = array())
+ {
+ $values = $this->getSubmitValues();
+ foreach ($values as $k => $v) {
+ if ($this->elementExists($k)) {
+ $e =& $this->getElement($k);
+ if (!in_array($e->getName(), $exclude)) {
+ switch ($e->getType()) {
+ case 'date' :
+ list($m, $d, $y) = array_values($e->getValue());
+ // If all the date fields are empty, then don't add
+ // the output to the formData.
+ if (!(empty($m[0]) && empty($d[0]) && empty($y[0]))) {
+ $this->formData[$e->getName()]['label']
+ = $e->getLabel();
+
+ $oldDate = $e->getValue();
+ $newDate = Toolkit_Common::arrayFlatten(
+ $oldDate,
+ 0,
+ $newDate
+ );
+
+ $this->formData[$e->getName()]['element']
+ = implode(' / ', $newDate);
+ unset($oldDate, $newDate);
+ }
+ break;
+
+ case 'group':
+ $e->freeze();
+ $this->formData[$e->getName()]['label'] = $e->getLabel();
+ $this->formData[$e->getName()]['element'] = $e->toHtml();
+ break;
+
+ case 'select' :
+ $this->formData[$e->getName()]['label'] = $e->getLabel();
+
+ $values = $e->getValue();
+ foreach ($values as $v) {
+ $this->formData[$e->getName()]['element'] .= $v;
+ }
+ break;
+
+ default :
+ $this->formData[$e->getName()]['label'] = $e->getLabel();
+ $this->formData[$e->getName()]['element'] = $e->getValue();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // }}}
+ // {{{ setupConstants()
+
+ /**
+ * Sets the form constant values
+ *
+ * @param array $constants Associative array of form constant values.
+ *
+ * @return void
+ * @access protected
+ */
+ protected function setupConstants($constants)
+ {
+ $this->setConstants($constants);
+ }
+
+ // }}}
+ // {{{ setupDefaults()
+
+ /**
+ * Sets the form default values
+ *
+ * @param array $defaults Associative array of form default values.
+ *
+ * @return void
+ * @access protected
+ */
+ protected function setupDefaults($defaults)
+ {
+ $this->setDefaults($defaults);
+ }
+
+ // }}}
+ // {{{ setupElements()
+
+ /**
+ * Sets up all the elements to the form
+ *
+ * Takes a multi-dimensional array of form elements and uses them
+ * to set up the form objects elements
+ *
+ * @param array $elements Multi-Dimensional array of form elements.
+ *
+ * @return void
+ * @access protected
+ */
+ protected function setupElements($elements)
+ {
+ if (!is_array($elements)) {
+ return;
+ }
+ foreach ($elements as &$e) {
+ $this->prepElement($e);
+ switch ($e['type']) {
+ case 'group' :
+ if (is_array($e['group']) && !empty($e['group'])) {
+ // Special rendering for grouped elements.
+ unset($field);
+ foreach ($e['group'] as $g) {
+ $this->prepElement($g);
+ $field[] =& HTML_QuickForm::createElement(
+ $g['type'],
+ $g['name'],
+ $g['display'],
+ $g['opts'],
+ $g['att'],
+ $g['val']
+ );
+ }
+ $source =& $this->addGroup(
+ $field,
+ $e['name'],
+ $e['label'],
+ $e['seperator'],
+ $e['appendName']
+ );
+ }
+ break;
+
+ case 'elementGrid' :
+ $source =& $this->addElement(
+ $e['type'],
+ $e['name'],
+ $e['display'],
+ $e['opts'],
+ $e['att'],
+ $e['val']
+ );
+ unset($columnNames);
+
+ // Loop through the rows (r) and columns (c)
+ // to add each of the elements to our grid.
+ foreach ($e['group'] as $k => $r) {
+ unset($set, $rowTitle);
+ foreach ($r as $c) {
+ $columnNames[$c['display']] = $c['display'];
+
+ $set[] =& $this->createGridElement(
+ $c['type'],
+ $c['name'],
+ null,
+ $c['opts'],
+ $c['att']
+ );
+ }
+ $rowTitle = is_int($k) ? ' ' : $k;
+ $source->addRow($set, $rowTitle);
+ }
+
+ $source->setColumnNames($columnNames);
+ break;
+
+ default :
+ // Render all elements except groups
+ try {
+ $source =& $this->addElement(
+ $e['type'],
+ $e['name'],
+ $e['display'],
+ $e['opts'],
+ $e['att'],
+ $e['val']
+ );
+
+ if (PEAR::isError($source)) {
+ var_dump($source);
+ throw new Exception ('PEAR QuickForm Element Error');
+ }
+ } catch (HTML_QuickForm_Error $e) {
+ Toolkit_Common::dieGracefully(null, $e);
+ } catch (Exception $e) {
+ Toolkit_Common::handleError($e);
+ }
+
+ if ($e['type'] == 'advmultiselect') {
+ $source->setLabel($e['labels']);
+ }
+ if ($e['name'] == 'categories') {
+ $res = $source->loadArray($this->categories);
+ if (PEAR::isError($res)) {
+ Toolkit_Common::dieGracefully(null, $res);
+ }
+ }
+ if ($e['type'] == 'header') {
+ $this->formHeaders[$e['display']] = $e;
+ }
+
+ if ($e['name'] == 'captcha_rmv') {
+ $this->captchaAnswer =& $source;
+ }
+
+ if ($e['name'] == 'captcha_question') {
+ $this->captchaQuestion =& $source;
+ }
+ break;
+ }
+ }
+ $this->formElements = $elements;
+ }
+
+ // }}}
+ // {{{ setupFilters()
+
+ /**
+ * Sets any filters needed for the form elements when submitting
+ *
+ * @param array $filters Element filters.
+ *
+ * @return void
+ * @access protected
+ */
+ protected function setupFilters($filters)
+ {
+ foreach ($filters as $f) {
+ $res = $this->applyFilter($f['element'], $f['filter']);
+
+ if (PEAR::isError($res)) {
+ Toolkit_Common::handleError($res);
+ }
+ }
+ }
+
+ // }}}
+ // {{{ setupRules()
+
+ /**
+ * Apply rules to the form
+ *
+ * 100 & 1000 char length limitations are automatically assigned to
+ * text/textarea elements to help reduce load limitations on the server.
+ * -request per Chuck in a conference call on (5/22/2009 @ 12:15pm)
+ *
+ * Applies rules that are defined in child classes to the form elements
+ * group rules can be kind of tricky, since you can't apply a rule
+ * directly to an element inside of a rule you have to define
+ * the rule inside a nest of array's and then add a group rule.
+ * the array will contain all the elements inside the group you wish
+ * to apply rules to.
+ *
+ * You can assign as many rules as you would like to individual elements,
+ * and you aren't required to make the array associative, although it is
+ * easier to see whats going on.
+ *
+ * see: http://pear.activeventure.com/package/package.html.html-quickform.html-quickform.addgrouprule.html
+ * for another example.
+ *
+ * // Define the rules for each element in the group.
+ * $num_rule = array(
+ * 'ERROR: Must contain a valid decimal number!',
+ * 'numeric'
+ * );
+ * // Collect together the rules for each element.
+ * $lat_rules = array('lat' => array($num_rule));
+ * $lon_rules = array('lon' => array($num_rule));
+ * $r[] = array(
+ * 'element' => 'latitude',
+ * 'message' => 'ERROR:',
+ * 'type' => 'group',
+ * 'format' => $lat_rules,
+ * 'validation' => $this->validationType,
+ * 'reset' => false,
+ * 'force' => false
+ * );
+ *
+ *
+ * To make a group required but not require every element in the group
+ * you can use the addGroupRule function again
+ * for example: say you have a group of checkboxes and you only only
+ * require 1 be checked. a simple group rule such as the following
+ * will handle this.
+ * N.B. notice the extra "howMany" index.
+ *
+ * $r[] = array(
+ * 'element' => 'element_name',
+ * 'message' => 'ERROR: Error to display!',
+ * 'type' => 'required',
+ * 'format' => null,
+ * 'howMany' => 1,
+ * 'validation'=> $this->validationType,
+ * 'reset' => true,
+ * 'force' => false,
+ * );
+ *
+ *
+ * @param array $rules Multi-Dimensional array of rules for form elements.
+ *
+ * @return void
+ * @access protected
+ */
+ protected function setupRules(array $rules = null)
+ {
+ $this->registerRules();
+ $preRegisteredRules = $this->getRegisteredRules();
+ if (is_array($this->formElements)) {
+ foreach ($this->formElements as $e) {
+ // Put length limitations on text and textarea fields
+ if ($e['type'] == 'text' && !$e['noCharLimit']) {
+ $this->addCharLimit($e['name'], 100);
+ } elseif ($e['type'] == 'textarea' && !$e['noCharLimit']) {
+ $this->addCharLimit($e['name'], 1000);
+ } elseif ($e['type'] == 'group') {
+ // We need to apply these same limitations to the
+ // text and textarea fields inside of groups
+ $r = array();
+ if (is_array($e['group'])) {
+ foreach ($e['group'] as $i) {
+ // Loop through group elements and if they are
+ // text/textarea fields then put the field into
+ // a rule array that we will assign to the group
+ if ($i['type'] == 'text' && !$i['noCharLimit']) {
+ $r[$i['name']][] = array(
+ 'ERROR: 100 characters max!',
+ 'maxlength'
+ );
+ } elseif ($i['type'] == 'textarea' && !$i['noCharLimit']) {
+ $r[$i['name']][] = array(
+ 'ERROR: 1000 characters max!',
+ 'maxlength'
+ );
+ }
+ }
+ }
+ if (!empty($r)) {
+ $this->addGroupRule($e['name'], $r);
+ }
+ }
+ if ($this->validationType == 'client') {
+ $label = $e['display'];
+ }
+ if ($e['req']) {
+ if ($e['type'] == 'group') {
+ foreach ($e['group'] as $ge) {
+ if ($ge['req']) {
+ $rule[$ge['name']][] = array(
+ 'ERROR: You must complete this field!',
+ 'required',
+ null,
+ $this->validationType);
+ }
+ }
+ $this->addGroupRule($e['name'], $rule);
+ unset($rule);
+ } elseif ($e['type'] == 'date') {
+ if (!empty($e['error'])) {
+ // Custom error message for the date element.
+ $error = $e['error'];
+ } else {
+ // Default error message for the date element.
+ $error = 'ERROR: You must enter a date!';
+ }
+ $this->addGroupRule(
+ $e['name'],
+ $error,
+ 'required',
+ 3,
+ $this->validationType
+ );
+ if ($this->autoValidateDateElements) {
+ $this->addRule(
+ $e['name'],
+ 'ERROR: Date is invalid!',
+ 'callback',
+ array(&$this, 'checkDateInput')
+ );
+ }
+ } else {
+ $this->addRule(
+ $e['name'],
+ "$label ERROR: You must complete this field!",
+ 'required',
+ null,
+ $this->validationType
+ );
+ }
+ }
+ }
+ }
+ if (is_array($rules)) {
+ foreach ($rules as $r) {
+ if (!is_array($r['element'])) {
+ $group = ($this->getElementType($r['element']) == 'group');
+ }
+ if ($group) {
+ $this->addGroupRule(
+ $r['element'],
+ $r['message'],
+ $r['type'],
+ $r['format'],
+ $r['howMany'],
+ $r['validation'],
+ $r['reset']
+ );
+ } elseif (in_array($r['type'], $preRegisteredRules)) {
+ $this->addRule(
+ $r['element'],
+ $r['message'],
+ $r['type'],
+ $r['format'],
+ $r['validation'],
+ $r['reset'],
+ $r['force']
+ );
+ }
+ }
+ }
+ }
+
+ // }}}
+ // {{{ setupRenderers()
+
+ /**
+ * Sets up renderers for form objects
+ *
+ * Uses the default form renderer to allow templates to be injected
+ * into the form object before displaying on a page. This allows
+ * changing the face of the form w/ out any backend adjustment.
+ *
+ * Files that can be created for templates are
+ *
+ * Examples:
+ * # Element.tpl
+ *
+ *
+ *
+ *
+ * *
+ *
+ *
+ *
+ *
+ *
+ * {error}
+ *
+ * {element}
+ *
+ *
+ *
+ *
+ * # Form.tpl
+ *
+ *
+ *
+ *
+ * {content}
+ *
+ *
+ *
+ *
+ *
+ * # GroupElement.tpl
+ *
+ *
+ *
+ * {element}
+ *
+ * *
+ *
+ * {label}
+ *
+ *
+ *
+ *
+ * # Group.tpl
+ *
+ *
+ *
+ * {content}
+ *
+ *
+ *
+ *
+ * # Header.tpl
+ *
+ *
+ *
+ * {header}
+ *
+ *
+ *
+ *
+ * # RequiredNote.tpl
+ *
+ * * Denotes required field
+ *
+ *
+ * @param array $groups any groups that need to be rendered
+ * via the groupElementTemplate and groupTemplate
+ *
+ * @return void
+ * @access protected
+ */
+ protected function setupRenderers(array $groups = array())
+ {
+ $renderer =& $this->defaultRenderer();
+ if (is_dir($this->template)) {
+ if ($dh = opendir($this->template)) {
+ while (($file = readdir($dh)) !== false) {
+ // Ignore current dir and parent dir.
+ if ($file != '..' && $file != '.' && $file != 'CVS') {
+ $baseName = reset(explode('.', $file));
+ // Ignores swp files.
+ if (!empty($baseName)) {
+ $method = "set{$baseName}Template";
+ $template = file_get_contents($this->template . $file);
+ if ( $method != 'setGroupTemplate'
+ && $method != 'setGroupElementTemplate'
+ ) {
+ if (method_exists($renderer, $method)) {
+ $renderer->$method($template);
+ }
+ } else {
+ // apply the templates to any defined groups
+ foreach ($groups as $k) {
+ $renderer->$method($template, $k);
+ }
+ }
+ }
+ }
+ }
+ closedir($dh);
+ }
+ }
+
+ // Set the default how the captcha's should look
+ // can be overridden in subclasses
+ if ($this->useCaptcha) {
+ $required = '*';
+ $error = ''.print_r($values, true).''; + $sql = " + UPDATE {$values['table_name']} + SET {$values['img_field_name']} = :new_img + WHERE {$values['primary_key']} = :id"; + $updateImg = $this->dbh->prepare($sql); + try { + $sql = " + SELECT * + FROM {$values['table_name']} + WHERE {$values['img_field_name']} != '' + AND {$values['img_field_name']} IS NOT NULL + AND {$values['img_field_name']} != 'ERROR' + AND {$values['img_field_name']} !~ '^is' + AND {$values['img_field_name']} !~ '^fs' + "; + $stmt = $this->dbh->prepare($sql); + $stmt->execute(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + if ($row[$values['primary_key']]) { + echo '
' + . print_r( + $values['original_url'] + . '/' . $row[$values['img_field_name']], + true + ) . ''; + $newImage = $this->is->imageUpload($values['original_url']. '/' . $row[$values['img_field_name']]); + $updateImg->bindParam(":new_img", $newImage, PDO::PARAM_STR); + $updateImg->bindParam(":id", $row[$values['primary_key']], PDO::PARAM_STR); + $updateImg->execute(); + } + } + } catch(PDOException $e) { + Toolkit_Common::handleError($e); + } + } + + /** + * Short description for function + * + * Long description (if any) ... + * + * @return void + * @access public + */ + function setupElements() + { + $e[] = array( + 'type' => 'header', + 'name' => 'header_rmv', + 'display' => 'Converter' + ); + $e[] = array( + 'type' => 'text', + 'name' => 'original_url', + 'display' => 'Original Path URL without ending /' + ); + $e[] = array( + 'type' => 'text', + 'name' => 'table_name', + 'display' => 'Table Name' + ); + $e[] = array( + 'type' => 'text', + 'name' => 'img_field_name', + 'display' => 'Image Field Name' + ); + $e[] = array( + 'type' => 'text', + 'name' => 'primary_key', + 'display' => 'Primary Key' + ); + $e[] = array( + 'type' => 'submit', + 'name' => 'submit', + 'display' => 'Submit' + ); + parent::setupElements($e); + } + + /** + * Short description for function + * + * Long description (if any) ... + * + * @return void + * @access public + */ + function setupConstants() + { + } + + /** + * Short description for function + * + * Long description (if any) ... + * + * @return void + * @access public + */ + function setupDefaults() + { + } + + /** + * Short description for function + * + * Long description (if any) ... + * + * @return void + * @access public + */ + function setupRules() + { + } + + /** + * Short description for function + * + * Long description (if any) ... + * + * @return string Return description (if any) ... + * @access public + */ + function toHtml() + { + if ($this->validate()) { + if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) { + $this->freeze(); + //$output = $this->successMsg; + //$output .= parent::toHTML(); + } + } else if ($this->isSubmitted()) { + $output = $this->errorMsg; + $output .= parent::toHtml(); + } else { + $output = parent::toHtml(); + } + return $output; + } +} +?> diff --git a/Toolkit/Image/Server.php b/Toolkit/Image/Server.php new file mode 100755 index 0000000..c56daca --- /dev/null +++ b/Toolkit/Image/Server.php @@ -0,0 +1,385 @@ + + * @copyright 2008 Steve Sutton + * @license Gaslight Media + * @version CVS: $Id: Server.php,v 1.19 2010/05/25 14:02:45 jamie Exp $ + * @link http://demo.gaslightmedia.com + */ + +/** + * Description for define + */ +define('IS_VALIDATE_SECRET', 'Glm0IS1secreT'); + +/** + * Description for define + */ +define('IS_SUBMIT_URL', FILE_SERVER_URL . 'submit.phtml'); + +/** + * Toolkit_Image_Server + * + * Class for implementation of the image server process Chuck has + * setup for is0.gaslightmedia.com + * Uses Curl PHP Library to upload images to the server + * + * @category Toolkit + * @package Image + * @author Steve Sutton
We sent the following XML:
$entryA total and complete failure occured."; + break; + case "PRODUCTION": + break; + } + } + if ($ss->debug == true) { + echo '
5ic7XC*2PRyZs2nd
zFr20p1+lU)V@d&oIV;d=u;g)IXjMd`r#xT)16@A=B@r;Aym
z%7C$)-M5ycAbh@|o@)JZJh4xCEK|96hAZ~bVtKUXMg%Adw_ni^i`nl6iU7rdvIE?5
zBba-DO^wn>2Vl)aYVIN6%I+*5JgTRyKX(85J9w=KZ0rDAWoRwVJ!ftO+36w+0===P
zKO?UVG$HIOE`jdju0GFlbHGWiZtM^#V-*nnT+dfBWfMM8o3l
z
+
+
+
+
+
+
+
+
+
+
+
All images will be resized to correct size.
+If you want to resize the images yourself before uploading, use these dimensions:
+Dictumst quis adipiscing etiam odio et augue, ut, cum cras adipiscing dolor cursus eros in integer in enim, aliquet in, amet tempor porta scelerisque, a eros sociis nec, porta in, lacus lacus, integer phasellus vut sit? Massa turpis porttitor. In, enim pulvinar? Ac et, ac nascetur porttitor magnis natoque duis! Nisi, ac et, aliquet? Cras tempor dignissim! Adipiscing cursus vel, integer dis penatibus vut! Et? Nec lundium lacus nunc nunc tempor a pid cum turpis magnis urna est eu rhoncus porttitor mauris ridiculus eu! Dolor pid porta ac dis lorem phasellus, tincidunt eros montes auctor adipiscing? Sed adipiscing risus scelerisque scelerisque ridiculus tortor, ut aliquam. Aenean enim et. Lectus enim dapibus scelerisque eros elementum nec, sagittis arcu. Purus augue ac.
+Enim tincidunt pid, augue est magna velit lacus in tincidunt cras sed tempor! Sed. Dis adipiscing odio, urna mus! Natoque arcu elit. Dapibus natoque a ridiculus scelerisque nisi cras. Phasellus ultricies natoque augue sagittis mauris adipiscing porta pulvinar integer! Lacus adipiscing sit porta ultricies mus natoque amet porta etiam, mauris. Egestas! Et urna! Platea risus magnis porta magnis in! Integer turpis cursus enim ac, ac? Phasellus enim. Cras enim! Lectus pulvinar, ac porta elementum nec, vut elementum pulvinar dignissim elementum porta placerat porttitor a lundium, turpis velit et mattis augue hac tempor adipiscing, magnis, lectus, pulvinar diam. Scelerisque scelerisque. Nunc sagittis ut proin, tincidunt ultrices velit parturient, sit vel enim. Porta? Ac non! Magna tincidunt arcu augue aenean eros.
+Placerat et placerat massa aliquam aliquet scelerisque, urna lorem! Adipiscing rhoncus, pid natoque turpis, auctor. Placerat sit, non sed, mattis augue dis placerat amet elementum vel habitasse, placerat. Etiam cum magnis arcu nisi a proin mus sit tortor montes! Integer aliquam, pellentesque sed sit. Dis mattis magnis! Enim non tincidunt cursus urna urna magna etiam? Facilisis ultricies dapibus porttitor, turpis ac et placerat urna, urna turpis vel, porta purus ac non! Nunc lorem? Tincidunt quis sagittis ridiculus sit, turpis? A ut ac rhoncus. Aenean tristique a tincidunt. Ac in odio dis et nascetur, est proin. Nisi, aliquam elementum, sed. Nunc sociis. Ut enim, ultricies nascetur a magna porta duis ut tincidunt! Aenean, augue cursus tristique ridiculus, integer eros dolor.
', '', '', 1, 1); +INSERT INTO toolbox.paragraphs(active, title, description, image, caption, back_to_top, page, pos) VALUES(TRUE, 'Paragraph A', 'Sit, et odio, risus proin adipiscing mattis! Est! Non lorem, et scelerisque sociis! Ac? Porttitor in, pid auctor, etiam hac sagittis dignissim scelerisque elementum? Nisi. Auctor in, lacus, enim vut, ac eros magna cursus nisi et! Vut tortor natoque rhoncus augue est tincidunt tortor in sed elementum, tristique purus. Nec nascetur porta adipiscing cum. Diam porttitor lorem hac parturient cras, pulvinar integer! Vel ac, rhoncus ridiculus ac magna est integer, ut ultrices! Pulvinar hac lundium pid pulvinar dapibus et rhoncus! Montes et pulvinar vut. Sit porta arcu turpis! Dictumst, proin pulvinar et turpis tristique odio aliquam, est odio hac dis? Elit elementum integer adipiscing turpis tincidunt massa? Habitasse dignissim lectus porta, nunc, aliquam est? Integer enim? Lectus, dignissim natoque, turpis.
', '', '', TRUE, 1, 1); +INSERT INTO toolbox.paragraphs(active, title, description, image, caption, back_to_top, page, pos) VALUES(TRUE, 'Paragraph B', 'Tortor adipiscing ut magna cras elit elit elit, dis! Eros pid scelerisque, aenean sagittis odio tristique elementum sed sit, porta ridiculus! Eros lundium integer? Integer, pulvinar sociis mid! Enim, magna velit mattis et ultrices egestas sed egestas non pulvinar etiam! Urna porta et pulvinar lorem sed aliquam, ridiculus. Dolor aenean integer enim, amet porta enim penatibus, proin a ut tincidunt, turpis magnis lectus quis enim aliquet, mauris in vel quis! Facilisis dolor. Urna eu, amet quis, mattis sed! Phasellus lorem! Non platea. Sit elit sed proin mus, mauris mauris dignissim, tincidunt et augue placerat tristique elementum purus lundium a cursus platea pid, ultricies platea? Elit sed eu diam, elementum sit rhoncus massa, lorem hac, urna natoque sit a tincidunt vel.
', '', '', TRUE, 1, 1); +INSERT INTO toolbox.paragraphs(active, title, description, image, caption, back_to_top, page, pos) VALUES(TRUE, 'Paragraph C', 'Porta, augue facilisis, arcu massa enim massa phasellus nisi elementum, aliquet sit phasellus sed nunc turpis, augue cum, cum lundium, ridiculus, vut sociis auctor! Tincidunt pulvinar, tempor eu mid amet? Odio, lacus ultrices, nunc purus, cursus in diam mattis et penatibus. Dolor. Elementum pid tincidunt magna penatibus risus, odio aliquet. Dapibus amet eros enim diam? Elit, urna elit porttitor platea. Nascetur proin odio habitasse aenean magnis? Facilisis nascetur? A elementum, lorem diam, phasellus phasellus montes magna proin? Habitasse risus, vel porta mauris tortor velit, egestas tortor augue. Vut sed placerat aliquet enim diam porttitor dignissim, montes, mattis enim! Egestas ultrices? Nec porta lundium dapibus! Dictumst turpis augue integer, proin nec lectus dictumst! Platea urna, rhoncus hac ac adipiscing a augue.
', '', '', TRUE, 1, 1); +INSERT INTO toolbox.paragraphs(active, title, description, image, caption, page, pos) VALUES(TRUE, 'Parent Title', 'Dictumst quis adipiscing etiam odio et augue, ut, cum cras adipiscing dolor cursus eros in integer in enim, aliquet in, amet tempor porta scelerisque, a eros sociis nec, porta in, lacus lacus, integer phasellus vut sit? Massa turpis porttitor. In, enim pulvinar? Ac et, ac nascetur porttitor magnis natoque duis! Nisi, ac et, aliquet? Cras tempor dignissim! Adipiscing cursus vel, integer dis penatibus vut! Et? Nec lundium lacus nunc nunc tempor a pid cum turpis magnis urna est eu rhoncus porttitor mauris ridiculus eu! Dolor pid porta ac dis lorem phasellus, tincidunt eros montes auctor adipiscing? Sed adipiscing risus scelerisque scelerisque ridiculus tortor, ut aliquam. Aenean enim et. Lectus enim dapibus scelerisque eros elementum nec, sagittis arcu. Purus augue ac.
', '', '', 2, 1); +INSERT INTO toolbox.paragraphs(active, title, description, image, caption, back_to_top, page, pos) VALUES(TRUE, 'Parent Paragraph A', 'Sit, et odio, risus proin adipiscing mattis! Est! Non lorem, et scelerisque sociis! Ac? Porttitor in, pid auctor, etiam hac sagittis dignissim scelerisque elementum? Nisi. Auctor in, lacus, enim vut, ac eros magna cursus nisi et! Vut tortor natoque rhoncus augue est tincidunt tortor in sed elementum, tristique purus. Nec nascetur porta adipiscing cum. Diam porttitor lorem hac parturient cras, pulvinar integer! Vel ac, rhoncus ridiculus ac magna est integer, ut ultrices! Pulvinar hac lundium pid pulvinar dapibus et rhoncus! Montes et pulvinar vut. Sit porta arcu turpis! Dictumst, proin pulvinar et turpis tristique odio aliquam, est odio hac dis? Elit elementum integer adipiscing turpis tincidunt massa? Habitasse dignissim lectus porta, nunc, aliquam est? Integer enim? Lectus, dignissim natoque, turpis.
', '', '', TRUE, 2, 1); +INSERT INTO toolbox.paragraphs(active, title, description, image, caption, back_to_top, page, pos) VALUES(TRUE, 'Parent Paragraph B', 'Tortor adipiscing ut magna cras elit elit elit, dis! Eros pid scelerisque, aenean sagittis odio tristique elementum sed sit, porta ridiculus! Eros lundium integer? Integer, pulvinar sociis mid! Enim, magna velit mattis et ultrices egestas sed egestas non pulvinar etiam! Urna porta et pulvinar lorem sed aliquam, ridiculus. Dolor aenean integer enim, amet porta enim penatibus, proin a ut tincidunt, turpis magnis lectus quis enim aliquet, mauris in vel quis! Facilisis dolor. Urna eu, amet quis, mattis sed! Phasellus lorem! Non platea. Sit elit sed proin mus, mauris mauris dignissim, tincidunt et augue placerat tristique elementum purus lundium a cursus platea pid, ultricies platea? Elit sed eu diam, elementum sit rhoncus massa, lorem hac, urna natoque sit a tincidunt vel.
', '', '', TRUE, 2, 1); +INSERT INTO toolbox.paragraphs(active, title, description, page, pos) VALUES(TRUE, 'Child Title', 'Child Description', 3, 1); +INSERT INTO toolbox.paragraphs(active, title, description, page, pos) VALUES(TRUE, 'Sibling Title', 'Sibling Description', 7, 1); +INSERT INTO toolbox.paragraphs(active, title, page, pos) VALUES(TRUE, 'Sibling Paragraph A', 7, 1); +INSERT INTO toolbox.paragraphs(active, title, page, pos) VALUES(TRUE, 'Sibling Paragraph B', 7, 1); +INSERT INTO toolbox.paragraphs(active, title, page, pos) VALUES(TRUE, 'p Paragraph', 4, 1); +INSERT INTO toolbox.paragraphs(active, title, page, pos) VALUES(TRUE, 'p Paragraph', 5, 1); +INSERT INTO toolbox.paragraphs(active, title, page, pos) VALUES(TRUE, 'p Paragraph', 6, 1); + + +INSERT INTO members.city(state_id, city_name) VALUES (34, 'Cary'); +INSERT INTO members.city(state_id, city_name) VALUES (23, 'Petoskey'); + +INSERT INTO members.member(member_name, member_login, member_passwd, street, lat, lon, phone, process_email, url, city_id, state_id, zip, member_contact_email, mailing_address, primary_contact_fname, primary_contact_lname, active, mailing_city, mailing_state_id, mailing_zip, new_member) values('1111 AAA Test', 'uname', 'pword', '120 E. Lake St.', 45.374893, -84.958404, '(231) 487-0692', 'jamie@gaslightmedia.com', 'http://www.gaslightmedia.com', 3, 23, 49770, 'jamie@gaslightmedia.com', '139 Dove Cottage Ln.', 'Jamie', 'Kahgee', true, 'Cary', 34, 27519, false); + +INSERT INTO coupons.coupons(title, url, sdate, edate, expiration, category, active, member) VALUES ('Coupon Test', 'http://www.google.com', '2010-04-22', '2010-10-22', '2010-10-22', 'Accommodations', true, 1); diff --git a/Toolkit/Toolbox/Database/procedures/check_pages_pos_consistency.sql b/Toolkit/Toolbox/Database/procedures/check_pages_pos_consistency.sql new file mode 100644 index 0000000..085ff72 --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/check_pages_pos_consistency.sql @@ -0,0 +1,38 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS check_pages_pos_consistency ON toolbox.pages; + +-- +-- Function and trigger checking for duplicate positions when a paragraph +-- has been inserted or updated. +-- +-- This trigger only happens after an insert or update and is initially +-- deferred which allows us to wrap our movements in a transaction and +-- examine the results when we are done +-- +-- This is a final check to help ensure data integrity +-- +CREATE OR REPLACE FUNCTION toolbox.check_pages_pos_consistency() RETURNS TRIGGER AS $check_pages_pos_consistency$ + DECLARE + duplicates INTEGER; + BEGIN + + SELECT + INTO duplicates count(*) + FROM toolbox.pages + WHERE parent = NEW.parent + AND pos = NEW.pos; + + IF (duplicates > 1) THEN + RAISE EXCEPTION 'Duplicate page positions!'; + END IF; + + RETURN NULL; + END; +$check_pages_pos_consistency$ LANGUAGE plpgsql; + +CREATE CONSTRAINT TRIGGER trigger_pages_pos_check_consistency +AFTER INSERT OR UPDATE ON toolbox.pages + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW EXECUTE PROCEDURE toolbox.check_pages_pos_consistency(); diff --git a/Toolkit/Toolbox/Database/procedures/check_paragraph_pos_consistency.sql b/Toolkit/Toolbox/Database/procedures/check_paragraph_pos_consistency.sql new file mode 100644 index 0000000..a6b46ae --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/check_paragraph_pos_consistency.sql @@ -0,0 +1,38 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS check_paragraphs_pos_consistency ON toolbox.paragraphs; + +-- +-- Function and trigger checking for duplicate positions when a paragraph +-- has been inserted or updated. +-- +-- This trigger only happens after an insert or update and is initially +-- deferred which allows us to wrap our movements in a transaction and +-- examine the results when we are done +-- +-- This is a final check to help ensure data integrity +-- +CREATE OR REPLACE FUNCTION toolbox.check_paragraphs_pos_consistency() RETURNS TRIGGER AS $check_paragraphs_pos_consistency$ + DECLARE + duplicates INTEGER; + BEGIN + + SELECT + INTO duplicates count(*) + FROM toolbox.paragraphs + WHERE page = NEW.page + AND pos = NEW.pos; + + IF (duplicates > 1) THEN + RAISE EXCEPTION 'Duplicate page positions!'; + END IF; + + RETURN NULL; + END; +$check_paragraphs_pos_consistency$ LANGUAGE plpgsql; + +CREATE CONSTRAINT TRIGGER trigger_paragraphs_pos_check_consistency +AFTER INSERT OR UPDATE ON toolbox.paragraphs + DEFERRABLE INITIALLY DEFERRED + FOR EACH ROW EXECUTE PROCEDURE toolbox.check_paragraphs_pos_consistency(); diff --git a/Toolkit/Toolbox/Database/procedures/delete_subtree.sql b/Toolkit/Toolbox/Database/procedures/delete_subtree.sql new file mode 100644 index 0000000..55b1781 --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/delete_subtree.sql @@ -0,0 +1,67 @@ +DROP TABLE IF EXISTS WorkingTable; +CREATE LOCAL TEMPORARY TABLE WorkingTable +(id INTEGER NOT NULL) +ON COMMIT DELETE ROWS; + +CREATE OR REPLACE FUNCTION toolbox.delete_subtree (IN dead_guy INTEGER) RETURNS void AS $$ + DECLARE + old_pos INTEGER; -- current position of the target node + old_par INTEGER; -- current parent of the target node + BEGIN + -- defer consraint that forbids (parent = id) + SET CONSTRAINTS ALL DEFERRED; + + -- set the old_pos and old_par variable + SELECT pos + INTO old_pos + FROM toolbox.pages + WHERE id = dead_guy; + + SELECT parent + INTO old_par + FROM toolbox.pages + WHERE id = dead_guy; + + -- mark root of subtree and immediate subordinates + UPDATE toolbox.pages + SET id = CASE WHEN id = dead_guy + THEN -99999 ELSE id END, + parent = CASE WHEN parent = dead_guy + THEN -99999 ELSE parent END + WHERE dead_guy IN (id, parent); + + WHILE EXISTS -- mark leaf nodes + (SELECT * + FROM toolbox.pages + WHERE parent = -99999 + AND id > -99999) + LOOP -- get list of next level subordinates + + DELETE FROM WorkingTable; + INSERT INTO WorkingTable + SELECT id FROM toolbox.pages WHERE parent = -99999; + + -- delete old markers so we don't keep an infinite loop + DELETE FROM toolbox.pages + WHERE parent = -99999; + + -- mark next level of subordinates + UPDATE toolbox.pages + SET parent = -99999 + WHERE parent IN (SELECT id FROM WorkingTable); + + END LOOP; + + -- delete all marked nodes + DELETE FROM toolbox.pages + WHERE id = -99999; + + -- reset all the positions at the target nodes level + UPDATE toolbox.pages + SET pos = pos - 1 + WHERE parent = old_par + AND pos > old_pos; + + SET CONSTRAINTS ALL IMMEDIATE; + END; +$$ LANGUAGE plpgsql; diff --git a/Toolkit/Toolbox/Database/procedures/files_pos.sql b/Toolkit/Toolbox/Database/procedures/files_pos.sql new file mode 100644 index 0000000..d0a27a6 --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/files_pos.sql @@ -0,0 +1,28 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS files_pos ON toolbox.files; + +-- +-- Function and trigger setting a page pos when inserted +-- +CREATE OR REPLACE FUNCTION toolbox.files_pos() RETURNS TRIGGER AS $files_pos$ + DECLARE + new_pos INTEGER; + BEGIN + + SELECT + INTO new_pos COALESCE(MAX(pos) + 1, 1) + FROM toolbox.files + WHERE paragraph = NEW.paragraph; + + NEW.pos := new_pos; + + RETURN NEW; + + END; +$files_pos$ LANGUAGE plpgsql; + +CREATE TRIGGER files_pos +BEFORE INSERT ON toolbox.files + FOR EACH ROW EXECUTE PROCEDURE toolbox.files_pos(); diff --git a/Toolkit/Toolbox/Database/procedures/files_update.sql b/Toolkit/Toolbox/Database/procedures/files_update.sql new file mode 100644 index 0000000..d018224 --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/files_update.sql @@ -0,0 +1,20 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS files_update ON toolbox.files; + +-- +-- Function and trigger copying a file revision +-- everytime it is updated. +-- +CREATE OR REPLACE FUNCTION toolbox.files_update() RETURNS TRIGGER AS $files_update$ + BEGIN + + INSERT INTO toolbox.files_history SELECT NEW.*; + RETURN NEW; + END; +$files_update$ LANGUAGE plpgsql; + +CREATE TRIGGER files_update +AFTER INSERT OR UPDATE ON toolbox.files + FOR EACH ROW EXECUTE PROCEDURE toolbox.files_update(); diff --git a/Toolkit/Toolbox/Database/procedures/pages_pos.sql b/Toolkit/Toolbox/Database/procedures/pages_pos.sql new file mode 100644 index 0000000..9deffe1 --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/pages_pos.sql @@ -0,0 +1,28 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS pages_pos ON toolbox.pages; + +-- +-- Function and trigger setting a page pos when inserted +-- +CREATE OR REPLACE FUNCTION toolbox.pages_pos() RETURNS TRIGGER AS $pages_pos$ + DECLARE + new_pos INTEGER; + BEGIN + + SELECT + INTO new_pos COALESCE(MAX(pos) + 1, 1) + FROM toolbox.pages + WHERE parent = NEW.parent; + + NEW.pos := new_pos; + + RETURN NEW; + + END; +$pages_pos$ LANGUAGE plpgsql; + +CREATE TRIGGER pages_pos +BEFORE INSERT ON toolbox.pages + FOR EACH ROW EXECUTE PROCEDURE toolbox.pages_pos(); diff --git a/Toolkit/Toolbox/Database/procedures/pages_update.sql b/Toolkit/Toolbox/Database/procedures/pages_update.sql new file mode 100644 index 0000000..df5fba3 --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/pages_update.sql @@ -0,0 +1,30 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS pages_update ON toolbox.pages; + +-- +-- Function and trigger copying a page revision +-- everytime it is updated. +-- +CREATE OR REPLACE FUNCTION toolbox.pages_update() RETURNS TRIGGER AS $pages_update$ + BEGIN + + INSERT INTO toolbox.pages_history + (id,active,mobile_active,headline,headline_intro,include_member_map, + keyword,meta_description,meta_title,navigation_name, + paragraph_links,parent,pos,search_form,region,short_url, + template,include_members,include_coupons) + SELECT + NEW.id,NEW.active,NEW.mobile_active,NEW.headline,NEW.headline_intro,NEW.include_member_map, + NEW.keyword,NEW.meta_description,NEW.meta_title,NEW.navigation_name, + NEW.paragraph_links,NEW.parent,NEW.pos,NEW.search_form,NEW.region, + NEW.short_url,NEW.template,NEW.include_members,NEW.include_coupons; + RETURN NEW; + + END; +$pages_update$ LANGUAGE plpgsql; + +CREATE TRIGGER pages_update +AFTER INSERT OR UPDATE ON toolbox.pages + FOR EACH ROW EXECUTE PROCEDURE toolbox.pages_update(); diff --git a/Toolkit/Toolbox/Database/procedures/paragraphs_draft_pos.sql b/Toolkit/Toolbox/Database/procedures/paragraphs_draft_pos.sql new file mode 100644 index 0000000..3eb789d --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/paragraphs_draft_pos.sql @@ -0,0 +1,28 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS paragraphs_draft_pos ON toolbox.paragraphs_draft; + +-- +-- Function and trigger setting a page pos when inserted +-- +CREATE OR REPLACE FUNCTION toolbox.paragraphs_draft_pos() RETURNS TRIGGER AS $paragraphs_draft_pos$ + DECLARE + new_pos INTEGER; + BEGIN + + SELECT + INTO new_pos COALESCE(MAX(pos) + 1, 1) + FROM toolbox.paragraphs_draft + WHERE page = NEW.page; + + NEW.pos := new_pos; + + RETURN NEW; + + END; +$paragraphs_draft_pos$ LANGUAGE plpgsql; + +CREATE TRIGGER paragraphs_draft_pos +BEFORE INSERT ON toolbox.paragraphs_draft + FOR EACH ROW EXECUTE PROCEDURE toolbox.paragraphs_draft_pos(); diff --git a/Toolkit/Toolbox/Database/procedures/paragraphs_pos.sql b/Toolkit/Toolbox/Database/procedures/paragraphs_pos.sql new file mode 100644 index 0000000..9bfe0ee --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/paragraphs_pos.sql @@ -0,0 +1,48 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS paragraphs_pos ON toolbox.paragraphs; + +-- +-- Function and trigger setting a page pos when inserted +-- +CREATE OR REPLACE FUNCTION toolbox.paragraphs_pos() RETURNS TRIGGER AS $paragraphs_pos$ + DECLARE + new_pos INTEGER; + BEGIN + + SELECT + INTO new_pos COALESCE(MAX(pos) + 1, 1) + FROM toolbox.paragraphs + WHERE page = NEW.page; + + -- Always use the new position when doing an insert + IF (TG_OP = 'INSERT') THEN + NEW.pos := new_pos; + ELSIF (TG_OP = 'UPDATE') THEN + -- Only update the paragraph position + -- on an update if we are changing the + -- page the paragraph is assigned to + IF (OLD.page != NEW.page) THEN + NEW.pos := new_pos; + + -- update the old page paragraph positions so + -- we aren't left with any gaps in the sequence + UPDATE toolbox.paragraphs + SET pos = pos - 1 + WHERE pos > OLD.pos + AND page = OLD.page + AND EXISTS (SELECT * -- ensure the old page still exists + FROM toolbox.pages + WHERE id = OLD.page); + END IF; + END IF; + + RETURN NEW; + + END; +$paragraphs_pos$ LANGUAGE plpgsql; + +CREATE TRIGGER paragraphs_pos +BEFORE INSERT OR UPDATE ON toolbox.paragraphs + FOR EACH ROW EXECUTE PROCEDURE toolbox.paragraphs_pos(); diff --git a/Toolkit/Toolbox/Database/procedures/paragraphs_update.sql b/Toolkit/Toolbox/Database/procedures/paragraphs_update.sql new file mode 100644 index 0000000..dd553bc --- /dev/null +++ b/Toolkit/Toolbox/Database/procedures/paragraphs_update.sql @@ -0,0 +1,21 @@ +--DROP LANGUAGE IF EXISTS plpgsql RESTRICT; +CREATE LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS paragraphs_update ON toolbox.paragraphs; + +-- +-- Function and trigger copying a paragraph revision +-- everytime it is updated. +-- +CREATE OR REPLACE FUNCTION toolbox.paragraphs_update() RETURNS TRIGGER AS $paragraphs_update$ + BEGIN + + INSERT INTO toolbox.paragraphs_history SELECT NEW.*; + RETURN NEW; + + END; +$paragraphs_update$ LANGUAGE plpgsql; + +CREATE TRIGGER paragraphs_update +AFTER INSERT OR UPDATE ON toolbox.paragraphs + FOR EACH ROW EXECUTE PROCEDURE toolbox.paragraphs_update(); diff --git a/Toolkit/Toolbox/Database/removeApplication.sql b/Toolkit/Toolbox/Database/removeApplication.sql new file mode 100644 index 0000000..1a393a9 --- /dev/null +++ b/Toolkit/Toolbox/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 toolbox CASCADE; diff --git a/Toolkit/Toolbox/Database/tables/files.sql b/Toolkit/Toolbox/Database/tables/files.sql new file mode 100644 index 0000000..b6490d2 --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/files.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS toolbox.files CASCADE; + +CREATE TABLE toolbox.files +(id SERIAL, + filename TEXT, + bytes INTEGER NOT NULL DEFAULT 0, + "type" TEXT NOT NULL, + urltext TEXT, + paragraph INTEGER NOT NULL + REFERENCES toolbox.paragraphs(id) + ON UPDATE CASCADE + ON DELETE CASCADE, + pos INTEGER NOT NULL DEFAULT 1, + PRIMARY KEY (id)); + +GRANT ALL ON toolbox.files_id_seq TO nobody; +GRANT ALL ON toolbox.files TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/files_draft.sql b/Toolkit/Toolbox/Database/tables/files_draft.sql new file mode 100644 index 0000000..8e9c7a1 --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/files_draft.sql @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS toolbox.files_draft CASCADE; + +CREATE TABLE toolbox.files_draft +(LIKE toolbox.files + INCLUDING DEFAULTS, + FOREIGN KEY (paragraph) REFERENCES toolbox.paragraphs_draft(id) + ON UPDATE CASCADE + ON DELETE CASCADE, + PRIMARY KEY (id) +); + +GRANT ALL ON toolbox.files_draft TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/files_history.sql b/Toolkit/Toolbox/Database/tables/files_history.sql new file mode 100644 index 0000000..47b1665 --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/files_history.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS toolbox.files_history CASCADE; + +CREATE TABLE toolbox.files_history +(LIKE toolbox.files + INCLUDING DEFAULTS, + revision SERIAL NOT NULL +); + +GRANT ALL ON toolbox.files_history_revision_seq TO nobody; +GRANT ALL ON toolbox.files_history TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/pages.sql b/Toolkit/Toolbox/Database/tables/pages.sql new file mode 100644 index 0000000..551f06d --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/pages.sql @@ -0,0 +1,36 @@ +DROP TABLE IF EXISTS toolbox.pages CASCADE; + +CREATE TABLE toolbox.pages +(id SERIAL, + active BOOLEAN NOT NULL + DEFAULT FALSE, + mobile_active BOOLEAN NOT NULL + DEFAULT FALSE, + headline BOOLEAN NOT NULL + DEFAULT FALSE, + headline_intro TEXT, + include_member_map BOOLEAN NOT NULL + DEFAULT FALSE, + keyword TEXT, + meta_description TEXT, + meta_title TEXT, + navigation_name TEXT, + paragraph_links BOOLEAN NOT NULL + DEFAULT FALSE, + parent INTEGER NOT NULL -- 0 is top level + DEFAULT 0, + pos INTEGER NOT NULL + DEFAULT 1, + search_form BOOLEAN NOT NULL + DEFAULT FALSE, + region INTEGER, + short_url TEXT, + template INTEGER NOT NULL, + include_members BOOLEAN DEFAULT FALSE, + include_coupons BOOLEAN DEFAULT FALSE, + PRIMARY KEY (id), + CHECK (id <> parent), -- Page cannot be own parent, + CHECK (pos > 0)); -- Page position cannot fall below zero + +GRANT ALL ON toolbox.pages_id_seq TO nobody; +GRANT ALL ON toolbox.pages TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/pages_draft.sql b/Toolkit/Toolbox/Database/tables/pages_draft.sql new file mode 100644 index 0000000..070b744 --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/pages_draft.sql @@ -0,0 +1,14 @@ +DROP TABLE IF EXISTS toolbox.pages_draft CASCADE; + +CREATE TABLE toolbox.pages_draft +(LIKE toolbox.pages + INCLUDING DEFAULTS, + published_page INTEGER + DEFAULT NULL + REFERENCES toolbox.pages (id) + ON UPDATE CASCADE + ON DELETE CASCADE, + PRIMARY KEY (id) +); + +GRANT ALL ON toolbox.pages_draft TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/pages_history.sql b/Toolkit/Toolbox/Database/tables/pages_history.sql new file mode 100644 index 0000000..e1d84d1 --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/pages_history.sql @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS toolbox.pages_history CASCADE; + +CREATE TABLE toolbox.pages_history +(LIKE toolbox.pages + INCLUDING DEFAULTS, + revision_timestamp TIMESTAMP NOT NULL + DEFAULT CURRENT_TIMESTAMP, + revision SERIAL NOT NULL +); + +GRANT ALL ON toolbox.pages_history_revision_seq TO nobody; +GRANT ALL ON toolbox.pages_history TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/pages_mobile.sql b/Toolkit/Toolbox/Database/tables/pages_mobile.sql new file mode 100644 index 0000000..e6d816f --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/pages_mobile.sql @@ -0,0 +1,15 @@ +DROP TABLE IF EXISTS toolbox.pages_mobile CASCADE; + +CREATE TABLE toolbox.pages_mobile +(id SERIAL, + page INTEGER NOT NULL + REFERENCES toolbox.pages(id) + ON DELETE CASCADE, + mobile_active BOOLEAN NET NULL + DEFAULT FALSE, +PRIMARY KEY (id)); + +GRANT ALL ON toolbox.pages_mobile TO nobody; +GRANT ALL ON toolbox.pages_mobile_id_seq TO nobody; + +CREATE UNIQUE INDEX page_mobile_page_indx ON toolbox.pages_mobile(page); diff --git a/Toolkit/Toolbox/Database/tables/pages_preview.sql b/Toolkit/Toolbox/Database/tables/pages_preview.sql new file mode 100644 index 0000000..3f4e5ae --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/pages_preview.sql @@ -0,0 +1,7 @@ +CREATE TEMPORARY TABLE toolbox.pages_preview +(LIKE toolbox.pages + INCLUDING DEFAULTS, + PRIMARY KEY (id) +); + +GRANT ALL ON toolbox.pages_preview TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/paragraphs.sql b/Toolkit/Toolbox/Database/tables/paragraphs.sql new file mode 100644 index 0000000..26aa4ee --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/paragraphs.sql @@ -0,0 +1,23 @@ +DROP TABLE IF EXISTS toolbox.paragraphs CASCADE; + +CREATE TABLE toolbox.paragraphs +(id SERIAL, + active BOOLEAN NOT NULL + DEFAULT TRUE, + back_to_top BOOLEAN NOT NULL + DEFAULT FALSE, + caption TEXT, + description TEXT, + image TEXT, + page INTEGER NOT NULL + REFERENCES toolbox.pages (id) + ON UPDATE CASCADE + ON DELETE CASCADE, + pos INTEGER NOT NULL + DEFAULT 1, + title TEXT, + PRIMARY KEY (id), + CHECK (pos > 0)); -- paragraph position cannot fall below zero + +GRANT ALL ON toolbox.paragraphs_id_seq TO nobody; +GRANT ALL ON toolbox.paragraphs TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/paragraphs_draft.sql b/Toolkit/Toolbox/Database/tables/paragraphs_draft.sql new file mode 100644 index 0000000..85c3e33 --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/paragraphs_draft.sql @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS toolbox.paragraphs_draft CASCADE; + +CREATE TABLE toolbox.paragraphs_draft +(LIKE toolbox.paragraphs + INCLUDING DEFAULTS, + FOREIGN KEY (page) REFERENCES toolbox.pages_draft(id) + ON UPDATE CASCADE + ON DELETE CASCADE, + PRIMARY KEY (id) +); + +GRANT ALL ON toolbox.paragraphs_draft TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/paragraphs_history.sql b/Toolkit/Toolbox/Database/tables/paragraphs_history.sql new file mode 100644 index 0000000..6515b02 --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/paragraphs_history.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS toolbox.paragraphs_history CASCADE; + +CREATE TABLE toolbox.paragraphs_history +(LIKE toolbox.paragraphs + INCLUDING DEFAULTS, + revision SERIAL NOT NULL +); + +GRANT ALL ON toolbox.paragraphs_history_revision_seq TO nobody; +GRANT ALL ON toolbox.paragraphs_history TO nobody; diff --git a/Toolkit/Toolbox/Database/tables/paragraphs_preview.sql b/Toolkit/Toolbox/Database/tables/paragraphs_preview.sql new file mode 100644 index 0000000..b669e3f --- /dev/null +++ b/Toolkit/Toolbox/Database/tables/paragraphs_preview.sql @@ -0,0 +1,6 @@ +CREATE TEMPORARY TABLE toolbox.paragraphs_preview +(LIKE toolbox.paragraphs + INCLUDING DEFAULTS +); + +GRANT ALL ON toolbox.paragraphs_preview TO nobody; diff --git a/Toolkit/Toolbox/DraftPagesTree.php b/Toolkit/Toolbox/DraftPagesTree.php new file mode 100644 index 0000000..64c5b9b --- /dev/null +++ b/Toolkit/Toolbox/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 .= ''.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_Toolbox_Exception( + "Unable to update paragraph [$content]" + ); + } + } + + // }}} +} +?> diff --git a/Toolkit/Toolbox/ParagraphGatewayPublishFactory.php b/Toolkit/Toolbox/ParagraphGatewayPublishFactory.php new file mode 100644 index 0000000..3e7083c --- /dev/null +++ b/Toolkit/Toolbox/ParagraphGatewayPublishFactory.php @@ -0,0 +1,10 @@ +dbh); + } +} +?> diff --git a/Toolkit/Toolbox/ParagraphsController.php b/Toolkit/Toolbox/ParagraphsController.php new file mode 100644 index 0000000..6bc23e8 --- /dev/null +++ b/Toolkit/Toolbox/ParagraphsController.php @@ -0,0 +1,315 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @link <> + */ + +/** + * Toolkit_Toolbox_ParagraphsController + * + * Description for Toolkit_Toolbox_ParagraphsController + * + * @category Toolkit + * @package Toolbox + * @author Jamie Kahgee
J_@03-dBiQ~Mpf&PLLjesa95{N;gF%TqH3YE&y`kfH7hoSidC>kn2qpNHH
zlm+X_AXpU;#bQH1P&wy!nnI}VSC%ps0|S1A6b=b97Bz+)3XhPHl9QB=jTix$nwy-R
zo|zJK1_grx1qB2I2B}2^1E>R|0|%I&wzr@F1PiIX3
+ Adding paragraph! PageId:'.$row['id'].'
+ Good Page PageId:'.$row['id'].' fixing page positions fixing paragraphs positions'.print_r($_REQUEST, true).'
';
+ //var_dump($parent);
+ $moveDownStmt->bindParam(
+ ':parent',
+ $parent,
+ PDO::PARAM_INT
+ );
+ $moveDownStmt->bindParam(
+ ':oldpos',
+ $_REQUEST['oldpos'],
+ PDO::PARAM_INT
+ );
+ $moveDownStmt->bindParam(
+ ':newpos',
+ $_REQUEST['newpos'],
+ PDO::PARAM_INT
+ );
+ $moveDownStmt->execute();
+ $pos = $_REQUEST['oldpos'];
+ while ($row = $moveDownStmt->fetch(PDO::FETCH_ASSOC)) {
+ //var_dump($row);
+ $updateStmt->bindParam(
+ ':pos',
+ $pos,
+ PDO::PARAM_INT
+ );
+ $updateStmt->bindParam(
+ ':id',
+ $row['id']
+ );
+ $updateStmt->execute();
+ ++$pos;
+ }
+ // moving up
+ } else {
+ $moveUpStmt->bindParam(
+ ':parent',
+ $parent,
+ PDO::PARAM_INT
+ );
+ $moveUpStmt->bindParam(
+ ':oldpos',
+ $_REQUEST['oldpos'],
+ PDO::PARAM_INT
+ );
+ $moveUpStmt->bindParam(
+ ':newpos',
+ $_REQUEST['newpos'],
+ PDO::PARAM_INT
+ );
+ $moveUpStmt->execute();
+ }
+
+ $updateStmt->bindParam(
+ ':pos',
+ $_REQUEST['newpos'],
+ PDO::PARAM_INT
+ );
+ $updateStmt->bindParam(
+ ':id',
+ $_REQUEST['id'],
+ PDO::PARAM_INT
+ );
+ $updateStmt->execute();
+ $dbh->commit();
+} catch (PDOException $e) {
+ $dbh->rollback();
+ Toolkit_Logger::logException('DB Error', $e);
+}
+$cache = new Cache_Lite($GLOBALS['cacheOptions']);
+$cache->clean('Toolbox');
+header('Location: '.MEDIA_BASE_URL.'admin/toolbox.php?showpos=1');
diff --git a/Toolkit/Toolbox/moveBySelectPara.php b/Toolkit/Toolbox/moveBySelectPara.php
new file mode 100644
index 0000000..b0d0865
--- /dev/null
+++ b/Toolkit/Toolbox/moveBySelectPara.php
@@ -0,0 +1,119 @@
+beginTransaction();
+ $sql = "
+ SELECT page
+ FROM paragraphs
+ WHERE id = :id";
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(
+ ":id",
+ $_REQUEST['id'],
+ PDO::PARAM_INT
+ );
+ $stmt->execute();
+ $page = $stmt->fetchColumn();
+ $updateSql = "
+ UPDATE paragraphs
+ SET pos = :pos
+ WHERE id = :id";
+ $updateStmt = $dbh->prepare($updateSql);
+ $moveDownSql = "
+ SELECT id
+ FROM paragraphs
+ WHERE page = :page
+ AND pos >= :oldpos
+ AND pos <= :newpos
+ ORDER BY pos";
+ $moveDownStmt = $dbh->prepare($moveDownSql);
+ $moveUpSql = "
+ UPDATE paragraphs
+ SET pos = pos + 1
+ WHERE page = :page
+ AND pos BETWEEN :newpos AND :oldpos";
+ $moveUpStmt = $dbh->prepare($moveUpSql);
+
+ $updateStmt->bindParam(
+ ':pos',
+ $someNewPos,
+ PDO::PARAM_INT
+ );
+ $updateStmt->bindParam(
+ ':id',
+ $_REQUEST['id'],
+ PDO::PARAM_INT
+ );
+ $updateStmt->execute();
+ if ($_REQUEST['newpos'] > $_REQUEST['oldpos']) {
+ $moveDownStmt->bindParam(
+ ':page',
+ $page,
+ PDO::PARAM_INT
+ );
+ $moveDownStmt->bindParam(
+ ':oldpos',
+ $_REQUEST['oldpos'],
+ PDO::PARAM_INT
+ );
+ $moveDownStmt->bindParam(
+ ':newpos',
+ $_REQUEST['newpos'],
+ PDO::PARAM_INT
+ );
+ $moveDownStmt->execute();
+ $pos = $_REQUEST['oldpos'];
+ while ($row = $moveDownStmt->fetch(PDO::FETCH_ASSOC)) {
+ //var_dump($row);
+ $updateStmt->bindParam(
+ ':pos',
+ $pos,
+ PDO::PARAM_INT
+ );
+ $updateStmt->bindParam(
+ ':id',
+ $row['id']
+ );
+ $updateStmt->execute();
+ ++$pos;
+ }
+ } else {
+ $moveUpStmt->bindParam(
+ ':page',
+ $page,
+ PDO::PARAM_INT
+ );
+ $moveUpStmt->bindParam(
+ ':oldpos',
+ $_REQUEST['oldpos'],
+ PDO::PARAM_INT
+ );
+ $moveUpStmt->bindParam(
+ ':newpos',
+ $_REQUEST['newpos'],
+ PDO::PARAM_INT
+ );
+ $moveUpStmt->execute();
+ }
+
+ $updateStmt->bindParam(
+ ':pos',
+ $_REQUEST['newpos'],
+ PDO::PARAM_INT
+ );
+ $updateStmt->bindParam(
+ ':id',
+ $_REQUEST['id'],
+ PDO::PARAM_INT
+ );
+ $updateStmt->execute();
+ $dbh->commit();
+} catch (PDOException $e) {
+ $dbh->rollback();
+ Toolkit_Logger::logException('DB Error', $e);
+}
+$cache = new Cache_Lite($GLOBALS['cacheOptions']);
+$cache->clean('Toolbox');
+header('Location: '.MEDIA_BASE_URL.'admin/toolbox.php?rt=Paragraphs&pageid='.$page);
diff --git a/Toolkit/Toolbox/pageChangeState.php b/Toolkit/Toolbox/pageChangeState.php
new file mode 100644
index 0000000..d4da710
--- /dev/null
+++ b/Toolkit/Toolbox/pageChangeState.php
@@ -0,0 +1,32 @@
+prepare($sql);
+ $stmt->bindParam(':id', $_GET['catid'], PDO::PARAM_INT);
+ $res = $stmt->execute();
+
+ $cache = new Cache_Lite($GLOBALS['cacheOptions']);
+ $cache->clean('Toolbox');
+
+ echo (int) $res;
+ return $res;
+} catch (PDOException $e) {
+ Toolkit_Logger::logException('DB Error', $e);
+ return false;
+}
+?>
diff --git a/Toolkit/Toolbox/pageMobileChangeState.php b/Toolkit/Toolbox/pageMobileChangeState.php
new file mode 100644
index 0000000..015aa55
--- /dev/null
+++ b/Toolkit/Toolbox/pageMobileChangeState.php
@@ -0,0 +1,31 @@
+prepare($sql);
+ $stmt->bindParam(':id', $_GET['catid'], PDO::PARAM_INT);
+ $res = $stmt->execute();
+
+ $cache = new Cache_Lite($GLOBALS['cacheOptions']);
+ $cache->clean('Toolbox');
+
+ echo (int) $res;
+ return $res;
+} catch (PDOException $e) {
+ Toolkit_Logger::logException('DB Error', $e);
+ return false;
+}
+?>
diff --git a/Toolkit/Toolbox/pageMove.php b/Toolkit/Toolbox/pageMove.php
new file mode 100644
index 0000000..b989d7b
--- /dev/null
+++ b/Toolkit/Toolbox/pageMove.php
@@ -0,0 +1,96 @@
+setRequest($request);
+$channel->setResponse($response);
+
+// start output buffering
+ob_start();
+
+// Now you can make calls to the logger
+
+$dbh = Toolkit_Database::getInstance();
+
+extract($_GET);
+
+try {
+ $dbh->beginTransaction();
+ if ($direction == 'down') {
+ $sql = "
+ UPDATE pages
+ SET pos = pos - 1
+ WHERE id <> :id
+ AND id <> :home_id
+ AND pos = (
+ SELECT pos + 1
+ FROM pages
+ WHERE id = :id)
+ AND parent = (
+ SELECT parent
+ FROM pages
+ WHERE id = :id)";
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+ $stmt->bindValue(':home_id', HOME_ID, PDO::PARAM_INT);
+ $stmt->execute();
+
+ $sql = "
+ UPDATE pages
+ SET pos = pos + 1
+ WHERE id = :id";
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+ $stmt->execute();
+ } elseif ($direction == 'up') {
+ $sql = "
+ UPDATE pages
+ SET pos = pos + 1
+ WHERE id <> :id
+ AND id <> :home_id
+ AND pos = (
+ SELECT pos - 1
+ FROM pages
+ WHERE id = :id)
+ AND parent = (
+ SELECT parent
+ FROM pages
+ WHERE id = :id)";
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+ $stmt->bindValue(':home_id', HOME_ID, PDO::PARAM_INT);
+ $stmt->execute();
+
+ $sql = "
+ UPDATE pages
+ SET pos = pos - 1
+ WHERE id = :id";
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+ $stmt->execute();
+ }
+
+ $dbh->commit();
+ echo 1;
+} catch (PDOException $e) {
+ $dbh->rollback();
+ if ('production' == strtolower($_SERVER['GLM_HOST_ID'])) {
+ $logger->crit($e->getMessage());
+ } else {
+ Toolkit_Logger::logException('DB Error', $e);
+ }
+ echo 0;
+}
+// Flush log data to browser
+$channel->flush();
+$response->sendHeaders();
+die();
diff --git a/Toolkit/Toolbox/paragraphChangeState.php b/Toolkit/Toolbox/paragraphChangeState.php
new file mode 100644
index 0000000..88aa1a9
--- /dev/null
+++ b/Toolkit/Toolbox/paragraphChangeState.php
@@ -0,0 +1,44 @@
+prepare($sql);
+ $stmt->bindParam(':id', $_GET['paragraphId'], PDO::PARAM_INT);
+ $res = $stmt->execute();
+
+
+ $sql = "
+ SELECT page
+ FROM paragraphs
+ WHERE id = :id";
+
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(':id', $_GET['paragraphId'], PDO::PARAM_INT);
+ $stmt->execute();
+ $stmt->bindColumn('page', $pageId);
+ $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $cache = new Cache_Lite($GLOBALS['cacheOptions']);
+ $cache->clean('Toolbox');
+
+ echo (int) $res;
+ return $res;
+} catch (PDOException $e) {
+ Toolkit_Logger::logException('DB Error', $e);
+ return false;
+}
+?>
diff --git a/Toolkit/Toolbox/paragraphFileUpload.php b/Toolkit/Toolbox/paragraphFileUpload.php
new file mode 100644
index 0000000..2bc5553
--- /dev/null
+++ b/Toolkit/Toolbox/paragraphFileUpload.php
@@ -0,0 +1,14 @@
+upload('userfile');
+} 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 json_encode($res);
+?>
diff --git a/Toolkit/Toolbox/paragraphMove.php b/Toolkit/Toolbox/paragraphMove.php
new file mode 100644
index 0000000..d53ebe7
--- /dev/null
+++ b/Toolkit/Toolbox/paragraphMove.php
@@ -0,0 +1,51 @@
+beginTransaction();
+ if ($direction == 'down') {
+ // Update paragraph nodes on this page who lie at the target node
+ // position and the position just after it.
+ $sql = "
+ UPDATE paragraphs
+ SET pos = CASE WHEN id = :id
+ THEN pos + 1 ELSE pos - 1 END
+ WHERE page = (SELECT page FROM paragraphs WHERE id = :id)
+ AND pos BETWEEN (SELECT pos FROM paragraphs WHERE id = :id)
+ AND (SELECT pos + 1 FROM paragraphs WHERE id = :id)";
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+ $stmt->execute();
+ } elseif ($direction == 'up') {
+ // Update paragraph nodes on this page who lie at the target node
+ // position and the position just before it.
+ $sql = "
+ UPDATE paragraphs
+ SET pos = CASE WHEN id = :id
+ THEN pos - 1 ELSE pos + 1 END
+ WHERE page = (SELECT page FROM paragraphs WHERE id = :id)
+ AND pos BETWEEN (SELECT pos - 1 FROM paragraphs WHERE id = :id)
+ AND (SELECT pos FROM paragraphs WHERE id = :id)";
+ $stmt = $dbh->prepare($sql);
+ $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+ $stmt->execute();
+ }
+
+ $dbh->commit();
+ die();
+} catch (PDOException $e) {
+ $dbh->rollback();
+ Toolkit_Logger::logException('DB Error', $e);
+ throw new Toolkit_Toolbox_Exception(
+ "unable to move paragraph `$id` `$direction`"
+ );
+}
+?>
diff --git a/Toolkit/Toolbox/styles.css b/Toolkit/Toolbox/styles.css
new file mode 100644
index 0000000..3be1ead
--- /dev/null
+++ b/Toolkit/Toolbox/styles.css
@@ -0,0 +1,132 @@
+.webform table { width: 742px; }
+.fieldcell { width: auto; }
+
+/* form section arrows */
+tr.hdr td {
+ background: #DDD url("//app.gaslightmedia.com/assets/icons/bullet_arrow_right.png") no-repeat;
+ padding-left: 15px;
+ cursor: pointer;
+ cursor: hand;
+}
+tr.hdr td:hover {
+ background-color: #e5e5e5;
+}
+tr.hdr td.open{
+ background-image: url("//app.gaslightmedia.com/assets/icons/bullet_arrow_down.png");
+}
+
+/* paragraph files */
+.files {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ width: 60%;
+}
+.files li {
+ margin: 0 3px 3px 3px;
+ padding: 0.4em;
+ padding-left: 1.5em;
+}
+.files li span {
+ position: absolute;
+ margin-left: -1.3em;
+}
+.files .ui-state-highlight {
+ height: 1.5em;
+ line-height: 1.2em;
+}
+#success_notification {
+ font-weight: bold;
+ color: #11a52f;
+}
+
+/* right tree element */
+.right-element {
+ float: left;
+ }
+.paragraph-line {
+ float: none !important;
+}
+.paragraph-line strong {
+ margin-left: 10px;
+ }
+/* highlight search matches in tree */
+.search {
+ color: orange;
+}
+
+/* Ove */
+#q {
+ border: 2px inset black;
+ height: 20px;
+ padding: 2px;
+ font-size: 16px;
+ width: 200px;
+ margin-right: 10px;
+ font-weight: bold}
+
+#tree li {
+ display: block;
+ line-height: 24px !important;
+}
+li.closed { background: url(assets/arrowClosed.png) no-repeat !important;}
+li.open { background: url(assets/arrowOpen.png) no-repeat !important;}
+/*.ltr>li {
+ border-bottom: 1px dashed #ccc;
+}*/
+#tree li.last {
+ float: none;
+}
+#tree {
+ width: 630px;
+}
+
+/*
+ * #tree ul {
+ * background: #ece;
+ * }
+ * #tree ul ul {
+ * background: #cee;
+ * }
+ * #tree ul ul ul {
+ * background: #eec;
+ * }
+ * #tree ul ul ul ul {
+ * background: #ede;
+ * }
+ */
+.right-element a {
+ text-decoration: underline !important;
+}
+
+#tree .editPage, .editPage:hover,
+#tree .editParagraphs, .editParagraphs:hover,
+#tree .pagePreview, .pagePreview:hover {
+ height: 16px;
+ padding: 0 5px 0 0px !important;
+ border: 0;
+}
+
+/*
+#tree .editPage, .editPage:hover { background: url(//app.gaslightmedia.com/assets/icons/page_edit.png) no-repeat; }
+#tree .editParagraphs, .editParagraphs:hover { background: url(//app.gaslightmedia.com/assets/icons/page_add.png) no-repeat; }
+#tree .pagePreview, .pagePreview:hover { background: url(//app.gaslightmedia.com/assets/icons/page_go.png) no-repeat; }
+
+#tree a:hover { color: green;}
+*/
+/* Lines */
+#tree li {
+ /* border-bottom: 1px dotted #666;
+ * padding-bottom: 1px;
+ */
+}
+
+/* Mousetip */
+.moveUp, .moveDown {
+ cursor: hand;
+ cursor: pointer;
+}
+.tOff {
+ visibility: hidden;
+}
+.form-success {border:1px solid green;color:green;padding:10px;margin:5px;}
diff --git a/Toolkit/qfcaptcha.php b/Toolkit/qfcaptcha.php
new file mode 100755
index 0000000..8b789de
--- /dev/null
+++ b/Toolkit/qfcaptcha.php
@@ -0,0 +1,39 @@
+
+ * @copyright 2006-2008 by Philippe Jausions / 11abacus
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD
+ * @version CVS: $Id: qfcaptcha.php,v 1.2 2009/10/01 16:00:02 jamie Exp $
+ * @filesource
+ * @link http://pear.php.net/package/HTML_QuickForm_CAPTCHA
+ * @see qfcaptcha_form_image.php
+ * @see qfcaptcha_form_random.php
+ */
+
+// Require the class before opening the session
+// so the instance unserialize properly
+require_once '../setup.phtml';
+require_once 'Text/CAPTCHA.php';
+require_once 'Text/CAPTCHA/Driver/Image.php';
+
+HTTP_Session2::useCookies(false);
+HTTP_Session2::start();
+
+header('Content-Type: image/jpeg');
+
+$sessionVar = (empty($_REQUEST['var']))
+ ? '_HTML_QuickForm_CAPTCHA'
+ : $_REQUEST['var'];
+
+// Force a new CAPTCHA for each one displayed
+$_SESSION[$sessionVar]->setPhrase();
+
+echo $_SESSION[$sessionVar]->getCAPTCHAAsJPEG();
+?>
diff --git a/admin/.htaccess b/admin/.htaccess
new file mode 100644
index 0000000..38dcd05
--- /dev/null
+++ b/admin/.htaccess
@@ -0,0 +1 @@
+RewriteEngine Off
diff --git a/admin/Contact/contact_inquiry.phtml b/admin/Contact/contact_inquiry.phtml
new file mode 100755
index 0000000..0b89a92
--- /dev/null
+++ b/admin/Contact/contact_inquiry.phtml
@@ -0,0 +1,125 @@
+
+ * @copyright 2009 Gaslight Media
+ * @license Gaslight Media
+ * @version CVS: $Id: contact_inquiry.phtml,v 1.3 2009/07/24 14:27:45 matrix Exp $
+ * @link http://pear.php.net/package/Contacts
+ * @see References to other sections (if any)...
+ */
+
+/**
+ * base setup file for all apps
+ */
+require_once '../../setup.phtml';
+
+/**
+ * base setup for contact admin section
+ */
+require_once "contact_setup.inc";
+GLM_TOOLBOX::top('Contact Inquiries', '');
+// Adjust the nav for this page, add the Edit Groups page.
+if (is_array($nav) && array_key_exists('Contact Inquiry Fields', $nav)) {
+ $tmp = array('Inquiry Groups' => 'list_groups.php');
+ array_insert($nav, 'Contact Inquiry Fields', $tmp);
+}
+GLM_TOOLBOX::html_nav_table($nav, $navWidth);
+$qs = "
+ SELECT id, header, groupid, pos
+ FROM contact_inq
+ ORDER BY groupid, pos;";
+$result = $DB->db_exec($qs);
+$query = "
+ SELECT id, name
+ FROM inq_group
+ ORDER BY name;";
+if ($groupData = $DB->db_auto_get_data($query)) {
+ foreach ($groupData as $groupRow) {
+ $gRow[$groupRow['id']] = $groupRow['name'];
+ }
+}
+?>
+
+
+
diff --git a/admin/Contact/contact_setup.inc b/admin/Contact/contact_setup.inc
new file mode 100755
index 0000000..29f7502
--- /dev/null
+++ b/admin/Contact/contact_setup.inc
@@ -0,0 +1,475 @@
+
+* @copyright 2009 Steve Sutton
+* @license Gaslight Media
+* @version CVS: $Id: contact_setup.inc,v 1.7 2010/05/13 17:05:53 matrix Exp $
+* @link <>
+*/
+extract($_REQUEST);
+// The Contact Type array is now is one location and is used by the
+// Toolkit_Contacts_Admin_EditContact class
+$conf = new Config;
+$contactRoot =& $conf->parseConfig(
+ BASE . 'Toolkit/Contacts/config.ini',
+ 'IniFile'
+);
+if (!defined("ENTRIES_PER_PAGE")) {
+
+ /**
+ * how many per page on list contacts
+ */
+ define("ENTRIES_PER_PAGE", 10); // Entries per Page in list_contact.phtml
+}
+
+/**
+* define for customer table
+*/
+define("CUSTOMER_TABLE", "customer"); // name of customer table
+
+/**
+* define for contact table
+*/
+define("CONTACT_TABLE", "contact"); // name of contact table
+
+$table = $contactRoot->getItem('section', 'conf')
+ ->getItem('directive', 'table')
+ ->getContent();
+/**
+* Table to user in db
+*/
+define("TABLE", $table); // which table to use
+
+/**
+* postgres date formate
+*/
+define("DATEFORMAT", "US"); // date format (for edit_contact.phmtl)
+
+/**
+* template for the newsletter
+*/
+define("NEWSLETTER_PROTOTYPE", "newsletter_template.html"); // date format (for edit_contact.phmtl)
+
+/**
+* class_template needed for GLM_TEMPLATE::get_seo_url()
+*/
+require_once BASE.'classes/class_template.inc';
+$DB = new GLM_DB();
+if (!defined("HTML_EMAIL")) {
+
+ /**
+ * HTML_EMAIL = ON or OFF
+ */
+ define("HTML_EMAIL", "ON");
+}
+if (!defined("PRODUCTION_MODE")) {
+
+ /**
+ * PRODUCTION_MODE off/on mail sent
+ */
+ define("PRODUCTION_MODE", "ON");
+}
+if (!defined("NEWSLETTER")) {
+
+ /**
+ * NEWSLETTER 1 or true will allow newsletters
+ */
+ define("NEWSLETTER", 1); //bool- does the contact database mail out a newsletter?
+}
+
+if (!function_exists("template_read")) {
+
+ /**
+ * Short description for function
+ *
+ * Long description (if any) ...
+ *
+ * @param unknown $template Parameter description (if any) ...
+ *
+ * @return string Return description (if any) ...
+ */
+ function template_read($template)
+ {
+ $fp = fopen($template, "r");
+ $contents = fread($fp, filesize($template));
+ fclose($fp);
+ if ($contents) {
+ return $contents;
+ } else {
+ return "";
+ }
+ }
+}
+// {{{ array_insert()
+
+
+/**
+* insert an array into another array after position.
+* You can specify an associative array key or index key
+* to dictact the positioning of the new array
+*
+* @param array &$array array to be used
+* @param unknown $position position to add array
+* @param unknown $insert_array array to be inserted
+*
+* @return void
+*/
+function array_insert(&$array, $position, $insert_array)
+{
+ if (!is_int($position)) {
+ $i = 0;
+ foreach ($array as $key => $value) {
+ if ($key == $position) {
+ $position = ++$i;
+ break;
+ }
+ ++$i;
+ }
+ }
+ $first_array = array_splice($array, 0, $position);
+ $array = array_merge($first_array, $insert_array, $array);
+}
+// }}}
+// {{{ explode_template()
+if (!function_exists("explode_template")) {
+
+ /**
+ * Short description for function
+ *
+ * Long description (if any) ...
+ *
+ * @param unknown $template Parameter description (if any) ...
+ * @param unknown $data Parameter description (if any) ...
+ *
+ * @return unknown Return description (if any) ...
+ */
+ function explode_template($template, $data)
+ {
+ $template = template_read($template);
+ $output = template_replacement($template, $data);
+ $output = wordwrap($output, 72);
+ return $output;
+
+ }
+}
+// }}}
+// {{{ template_replacement($template, $fieldarr)
+if (!function_exists("template_replacement")) {
+
+ /**
+ * Short description for function
+ *
+ * Long description (if any) ...
+ *
+ * @param unknown $template Parameter description (if any) ...
+ * @param array $fieldarr Parameter description (if any) ...
+ *
+ * @return unknown Return description (if any) ...
+ */
+ function template_replacement($template, $fieldarr)
+ {
+ if (is_array($fieldarr)) {
+ foreach ($fieldarr as $key => $value) {
+ $template = str_replace("", $value, $template);
+ }
+ }
+ return $template;
+ }
+}
+// }}}
+// {{{ add_image($image, $align)
+if (!function_exists("add_image")) {
+
+ /**
+ * Short description for function
+ *
+ * Long description (if any) ...
+ *
+ * @param string $image Parameter description (if any) ...
+ * @param string $align Parameter description (if any) ...
+ *
+ * @return string Return description (if any) ...
+ */
+ function add_image($image, $align)
+ {
+ if ($image != "") {
+ return '
+
+
+
+
+
+db_numrows($result);
+if ($num > 0) {
+ for ($i = 0; $i < $num; $i++) {
+ $data = $DB->db_fetch_array($result, $i, PGSQL_ASSOC);
+ if ($data['groupid'] != $oldgroup && isset($oldgroup)) {
+ echo 'Options:
+ Pos:
+ Group:
+ Inquiry Name:
+ ';
+ }
+ ?>
+
+
+
+
+ [Edit / Delete]
+
+
+ db_exec($qs);
+ $max_data = $DB->db_fetch_array($maxresult, 0, PGSQL_ASSOC);
+ $maxpos = $max_data['maxpos'];
+ $pos = '
+
+
+
+
+
+
+
+
+
+Nothing in the database yet
+
";
+}
+/**
+* Get a group of select elements to represent a date
+*
+* @param string $M Name attribute of the month select list
+* @param string $D Name attribute of the day select list
+* @param string $Y Name attribute of the year select list
+* @param string $m Selected value of the month select list
+* @param string $d Selected value of the day select list
+* @param string $y Selected value of the year select list
+*
+* @return string Html string of group select lists
+* @access public
+*/
+function dateSelector($M, $D, $Y, array $m = null, array $d = null, array $y = null)
+{
+ // Get a Select element
+ $month = new HTML_Select($M);
+ // Get a Range of months jan-dec
+ $monthArray = array_flip(range(1, 12));
+ // Make the keys and values the same
+ foreach ($monthArray as $i => &$j) {
+ $j = $i;
+ }
+ $month->loadArray($monthArray);
+ if (is_null($m)) {
+ $month->setSelectedValues(array(date('m')));
+ } else {
+ $month->setSelectedValues($m);
+ }
+
+ // Get a Select element
+ $day = new HTML_Select($D);
+ // Get a Range of months jan-dec
+ $dayArray = array_flip(range(1, 31));
+ // Make the keys and values the same
+ foreach ($dayArray as $i => &$j) {
+ $j = $i;
+ }
+ $day->loadArray($dayArray);
+ if (is_null($d)) {
+ $day->setSelectedValues(array(date('d')));
+ } else {
+ $day->setSelectedValues($d);
+ }
+
+ // Get a Select element
+ $year = new HTML_Select($Y);
+ // Get a Range of months jan-dec
+ $yearArray = array_flip(range(CONTACTS_FIRST_YEAR, date('Y')));
+ // Make the keys and values the same
+ foreach ($yearArray as $i => &$j) {
+ $j = $i;
+ }
+ $year->loadArray($yearArray);
+ if (is_null($y)) {
+ $year->setSelectedValues(array(date('Y')));
+ } else {
+ $year->setSelectedValues($y);
+ }
+
+ return $month->toHtml() . $day->toHtml() . $year->toHtml();
+}
+
+// }}}
+// default query on create_date
+$c_date_from = GLM_TOOLBOX::contact_date_entry("", "", "", "fc_month", "fc_day", "fc_year");
+$c_date_to = GLM_TOOLBOX::contact_date_entry("", "", "", "tc_month", "tc_day", "tc_year");
+
+// The Following $DB_fields array is no longer used for the edit contact page
+// You must alter the class Toolkit_Contacts_Admin_EditContact
+// The following is only used for the search form and the listing pages
+
+$primaryKey = $contactRoot->getItem('section', 'conf')
+ ->getItem('directive', 'primarykey')
+ ->getContent();
+/**
+* Description for define
+*/
+define("ID", $primaryKey);
+
+/**
+* Description for define
+*/
+define("MAILOK", "mail_ok");
+
+$sequence = $contactRoot->getItem('section', 'conf')
+ ->getItem('directive', 'sequence')
+ ->getContent();
+/**
+* Description for define
+*/
+define("SEQUENCE", $sequence);
+
+/**
+* Description for define
+*/
+define("WHERE", ID." IS NOT NULL");
+// $DB_fields are used for edit and updating contacts
+$DB_fields[] = array("name" => "id", "title" => "id", "type" => "hide");
+$DB_fields[] = array("name" => "create_date", "title" => "Create Date", "type" => "static");
+$DB_fields[] = array("name" => "fname", "title" => "First Name", "type" => "text");
+$DB_fields[] = array("name" => "lname", "title" => "Last Name", "type" => "text");
+if (TABLE == 'customer') {
+ $DB_fields[] = array("name" => "add1", "title" => "Address", "type" => "text");
+ $DB_fields[] = array("name" => "add2", "title" => "Address 2", "type" => "text");
+} else {
+ $DB_fields[] = array("name" => "company", "title" => "Company Name", "type" => "text");
+ $DB_fields[] = array("name" => "address", "title" => "Address", "type" => "text");
+ $DB_fields[] = array("name" => "address2", "title" => "Address 2", "type" => "text");
+}
+$DB_fields[] = array("name" => "city", "title" => "City", "type" => "text");
+$DB_fields[] = array("name" => "state", "title" => "State", "type" => "state");
+$DB_fields[] = array("name" => "zip", "title" => "Zip", "type" => "text");
+$DB_fields[] = array("name" => "phone", "title" => "Phone", "type" => "text");
+$DB_fields[] = array("name" => "fax", "title" => "Fax", "type" => "text");
+$DB_fields[] = array("name" => "email", "title" => "Email", "type" => "text");
+$DB_fields[] = array("name" => "mail_ok", "title" => "Mail Ok?", "type" => "radio");
+$DB_fields[] = array("name" => "interest", "title" => "Interest", "type" => "interest");
+$DB_fields[] = array("name" => "contact_type", "title" => "Contact Type", "type" => "drop", "drop" => $cType);
+
+// $fields are used for building the query page
+foreach ($DB_fields as $key=>$value) {
+ if ($value['type'] == "text" || $value['type'] == "state") {
+ $fields[$value['name']] = $value['title'];
+ } elseif ( $value['type'] == "radio") {
+ $boolean[$value['name']] = $value['title'];
+ } elseif ( $value['type'] == "drop") {
+ $dropdowns[$value['name']] = array('title' => $value['title'], 'drop' => $value['drop']);
+ }
+}
+
+$data['bailout'] .= "You are receiving this message because you have expressed an interest in ";
+$data['bailout'] .= "receiving specials and information from ".SITENAME.". If you do not ";
+$data['bailout'] .= "wish to receive future items of this nature, please reply to this e-mail ";
+$data['bailout'] .= "with the word \"CANCEL\" on the subject line. You will then be removed ";
+$data['bailout'] .= "from future mailings.";
+ $count = 0;
+ foreach ($GLOBALS['int_array'] as $key => $value) {
+ if ($count==0) {
+ echo " ";
+ }
+ echo "$value
";
+ if ($count==5) {
+ echo "";
+ }
+ if ($count==11) {
+ echo " ";
+ }
+ $count++;
+ }
+ echo "
";
+$data['bailout'] .= "".OWNER_EMAIL."
";
+?>
diff --git a/admin/Contact/del_query.phtml b/admin/Contact/del_query.phtml
new file mode 100755
index 0000000..0ad9363
--- /dev/null
+++ b/admin/Contact/del_query.phtml
@@ -0,0 +1,20 @@
+db_auto_exec($qs)) {
+ GLM_TOOLBOX::html_error(DB_ERROR_MSG.$qs,1);
+}
+GLM_TOOLBOX::html_header("Admin","Deleted","");
+?>
+
+Query is Deleted
+
+
+foreach ($row as $key => $value) {
+ switch ($key) {
+
+ case "id":
+ echo "";
+ break;
+
+ case "subject":
+ echo "
+ ";
+ break;
+
+ case "response":
+ echo "Subject: ";
+ GLM_TOOLBOX::text_box("subject", $value);
+ echo " ";
+ break;
+
+ default:
+ break;
+ }
+}
+echo 'Response: ";
+ echo '';
+ echo "
+';
+if ($id) {
+ ?>
+
+
+
+
+
+
+
+ Group Name:
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+