From: Steve Sutton Date: Tue, 12 Aug 2014 18:49:17 +0000 (-0400) Subject: Work on template X-Git-Tag: V1.0^2~104 X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/?a=commitdiff_plain;h=6251bdb630649895fd9f6261e324db437383a0e7;p=web%2FKeweenaw.git Work on template Output blocks Output main nav Output mobile nav --- diff --git a/.gitignore b/.gitignore index a86e0ec..4c853cb 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ editimagespng/ nbproject Toolkit/Members/MemberImport/upload Toolkit/Members/MemberImport/fileHeaders.txt +Phing +smarty/ diff --git a/Toolkit/Events/AddCommonEventForm.php b/Toolkit/Events/AddCommonEventForm.php new file mode 100644 index 0000000..18e4a6e --- /dev/null +++ b/Toolkit/Events/AddCommonEventForm.php @@ -0,0 +1,1045 @@ + + * @license http://www.gaslightmedia.com Gaslightmedia + * @version CVS: $Id: AddEventForm.php,v 1.20 2010/07/04 23:58:22 jamie Exp $ + * @link http://demo.gaslightmedia.com + */ + +/** + * New Event Form + * + * @category Toolkit + * @package Events + * @author Steve Sutton + * @copyright 2012 Gaslight Media + * @license http://www.gaslightmedia.com Gaslightmedia + * @link http://demo.gaslightmedia.com + */ +class Toolkit_Events_AddCommonEventForm + extends Toolkit_FormBuilder + implements Toolkit_Form +{ + // {{{ properties + + /** + * Table in Database which holds the contact data + * + * @var string + * @access public + */ + public $tableName = 'events.events'; + + /** + * Table meta data + * + * This is used when inserting/updating data for the records + * so the PDO's can use explicit data types for the parameters. + * + * @var array + * @access public + */ + public $tableMetaData; + + /** + * Who to send the email to when the contact form is submitted + * + * If you leave this blank, its value will get set to the OWNER_EMAIL + * in the constructor. + * + * If you ***DO NOT*** want any emails to go out when the form is submitted + * then set the value to false. Do not set it to 0 for false, because the + * check uses a strict type check to determine if the value is actually + * false. This is what allows for the empty value as an option, which sets + * the value to OWNER_EMAIL and won't override the $email property if + * this class gets subclassed and the value for this property gets set in + * the properties of the subclass and not in the constructor after this + * constructor function is called. + * + * tongue twister...I know. + * + * 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 + * + * It gets set to the constant SITENAME in the constructor if you leave + * empty here, but you can set it to something different here to override + * that if you desire. + * + * @var unknown + * @access protected + */ + protected $siteName; + + /** + * Email subject and

header in email + * + * It gets set in the constructor if you leave empty here, but you + * can set it to something different here to override that if you desire. + * + * @var string + * @access protected + */ + protected $subject = 'New Event Submission'; + + /** + * Message to display if the form is successfully submitted + * + * @var string + * @access protected + */ + protected $successMsg = ' + +
+ Your event has been successfully added to the events calendar, + however will not be visible until it has been approved by + the Web site administrator. Thank You. +
'; + + /** + * Extra rules for processesing + * + * This registers the Zip validation rules (and any others listed) for + * QuickForm. + * + * Zip validation checks both US and Canadian Zip codes + * + * @var array + * @access protected + */ + protected $registeredRules = array( + 'phone', + array( + 'checkEmail', + 'callback', + 'email', + 'Validate' + ), + array( + 'checkURI', + 'callback', + 'uri', + 'Validate' + ) + ); + + /** + * Options for flexy templating engine + * + * Pulls the preset options from the setup.phtml file + * overwrites the templateDir and compileDir to match this classes needs + * + * @var array + * @access protected + */ + protected $flexyOptions; + + protected $eventMapper; + + // }}} + // {{{ __construct() + + /** + * Class constructor + * + * @param PDO $pdo PHP Data Object + * @param string $formName Form's name. + * @param string $method (optional)Form's method defaults to 'POST' + * @param string $action (optional)Form's action + * @param string $target (optional)Form's target defaults to '_self' + * @param mixed $attributes (optional)Extra attributes for
tag + * @param bool $trackSubmit (optional)Whether to track if the form was + * submitted by adding a special hidden field + * + * @access public + */ + public function __construct( + PDO $pdo, + $formName, + $method = 'post', + $action = '', + $target = '', + $attributes = null, + $trackSubmit = false, + EventMapper $eventMapper + ) { + parent::__construct( + $formName, $method, $action, $target, $attributes, $trackSubmit + ); + + $this->dbh = $pdo; + $this->eventMapper = $eventMapper; + + if ($this->email !== false && empty($this->email)) { + // Set to false to turn off email function. + $this->email = ADD_EVENT_EMAIL; + } + if (empty($this->siteName)) { + $this->siteName = SITENAME; + } + if (empty($this->subject)) { + $this->subject = 'Contact Request from website ' . SITENAME; + } + + $this->flexyOptions = $GLOBALS['flexyOptions']; + $this->flexyOptions['templateDir'] = dirname(__FILE__) . "/templates/"; + $this->flexyOptions['compileDir'] = dirname(__FILE__) . "/templates/compiled/"; + + $var = basename(__FILE__, '.php'); + + $callbackUrl = MEDIA_BASE_URL; + + $this->captchaOptions = array( + 'width' => 100, + 'height' => 50, + 'callback' => "{$callbackUrl}Toolkit/qfcaptcha.php?var=$var", + 'sessionVar' => $var, + 'imageOptions' => array( + 'font_size' => 16, + 'font_path' => GLM_APP_BASE . 'glmPEAR/Image/Canvas/Fonts/', + 'font_file' => 'times.ttf', + 'background_color' => '#cccccc', + 'obfuscation' => false, + 'angle' => true, + ), + ); + } + + // }}} + // {{{ checkDate() + + /** + * Validate date input + * + * allows for empty dates to be valid + * + * @param array $date date group from form + * + * @return boolean true if valid, false if not + * @access public + */ + public function checkDate($date) + { + if (!$date) { + return true; + } else { + return Validate::date($date, array('format' => '%m/%d/%Y')); + } + } + + // }}} + // {{{ checkDateRange() + + /** + * Validate date input + * + * allows for empty end date to be valid + * + * @param array $d date group from form + * + * @return boolean true if valid, false if not + * @access public + */ + public function checkDateRange(array $d) + { + if (!$this->hasEndDate($d[1])) { + // no end date is a valid date range + return true; + } + $pattern = '/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/'; + if (preg_match($pattern, $d[0], $m)) { + $t1 = mktime(0, 0, 0, (int) $m[1], (int) $m[2], (int) $m[3]); + $bdate = new Date($t1); + } + if (preg_match($pattern, $d[1], $m)) { + $t2 = mktime(0, 0, 0, (int) $m[1], (int) $m[2], (int) $m[3]); + $edate = new Date($t2); + } + if ($bdate && $edate) { + // 0 if the dates are equal - valid + // -1 if $bdate is before $edate - valid + // 1 if $bdate is after $edate - invalid + $res = Date::compare($bdate, $edate); + return ($res !== 1); + } + return true; + } + + // }}} + // {{{ configureElements() + + /** + * Form element definitions + * + * @return void + * @access public + */ + public function configureElements() + { + $e = array(); + + // All Elements are created here. This includes group element definitions. + $e[] = array( + 'type' => 'header', + 'name' => 'eventInfoHdr', + 'display' => 'Event Information' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'header', + 'display' => 'Event Name' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'starting', + 'display' => 'Start Date', + 'opts' => array('id' => 'sdate') + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'ending', + 'display' => 'End Date', + 'opts' => array('id' => 'edate') + ); + $e[] = array( + 'type' => 'date', + 'req' => false, + 'name' => 'btime', + 'display' => 'Start Time', + 'opts' => array( + 'format' => 'h : i A', + 'addEmptyOption' => true, + 'emptyOptionValue' => '', + 'emptyOptionText' => array( + 'h' => 'hh', + 'i' => 'mm', + 'A' => 'am/pm' + ), + 'optionIncrement' => array( + 'i' => 15, + ), + ), + 'error' => 'ERROR: You must select a start time!', + ); + $e[] = array( + 'type' => 'date', + 'req' => false, + 'name' => 'etime', + 'display' => 'End Time', + 'opts' => array( + 'format' => 'h : i A', + 'addEmptyOption' => true, + 'emptyOptionValue' => '', + 'emptyOptionText' => array( + 'h' => 'hh', + 'i' => 'mm', + 'A' => 'am/pm' + ), + 'optionIncrement' => array( + 'i' => 15, + ), + ), + ); + $e[] = array( + 'type' => 'select', + 'req' => true, + 'name' => 'category', + 'display' => 'Category', + 'opts' => $this->getTopicFields(), + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'website', + 'display' => 'Event Website' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'facebook', + 'display' => 'Facebook', + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'twitter', + 'display' => 'Twitter', + ); + + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'cost', + 'display' => 'Cost', + ); + + $e[] = array( + 'type' => 'textarea', + 'req' => false, + 'name' => 'description', + 'display' => 'Event Description', + 'opts' => array('id' => 'description') + ); + $e[] = array( + 'type' => 'header', + 'name' => 'eventLocationInfoHeader_rmv', + 'display' => 'Event Location Information +
+
+
+ Map It' + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'lat', + 'opts' => array('id' => 'lat') + ); + $e[] = array( + 'type' => 'hidden', + 'req' => false, + 'name' => 'lon', + 'opts' => array('id' => 'lon') + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'place', + 'display' => 'Place' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'address', + 'display' => 'Address' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'city', + 'display' => 'City' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'state', + 'display' => 'State' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'zip', + 'display' => 'ZIP' + ); + $e[] = array( + 'type' => 'header', + 'name' => 'eventContactHeader_rmv', + 'display' => 'Event Contact Information' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'contact_name', + 'display' => 'Event Contact Person
(published on Web site)' + ); + $e[] = array( + 'type' => 'text', + 'req' => false, + 'name' => 'contact_email', + 'display' => 'Contact Email
(published on Web site)' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'contact_phone', + 'display' => 'Contact Phone
(published on Web site)' + ); + + $e[] = array( + 'type' => 'header', + 'name' => 'adminInfoHdr', + 'display' => 'Event Admin Information' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'admin_contact', + 'display' => 'Contact Name Submitting Event' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'admin_org', + 'display' => 'Organization Name Submitting Event' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'admin_phone', + 'display' => 'Phone' + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'admin_email', + 'display' => 'Email Address' + ); + + if ($this->useCaptcha) { + $e[] = array( + 'type' => 'CAPTCHA_Image', + 'req' => false, + 'name' => 'captcha_question', + 'display' => 'Verification code', + 'opts' => $this->captchaOptions + ); + $e[] = array( + 'type' => 'text', + 'req' => true, + 'name' => 'captcha_rmv', + 'display' => 'Enter verification code', + ); + } + $e[] = array( + 'type' => 'submit', + 'req' => false, + 'name' => 'submit_rmv', + 'display' => 'Submit' + ); + + $this->setupElements($e); + } + + // }}} + // {{{ configureFilters() + + /** + * Form filter definitions + * + * Applies a data filter for the given fields when the form is submitted + * + * @return void + * @access public + */ + public function configureFilters() + { + $f = array(); + + $f[] = array( + 'element' => '__ALL__', + 'filter' => 'trim' + ); + $f[] = array( + 'element' => 'website', + 'filter' => array('Toolkit_Common', 'filterURI') + ); + + $this->setupFilters($f); + } + + // }}} + // {{{ configureForm() + + /** + * Helper function to handle setting up the form + * + * @return void + * @access public + */ + public function configureForm() + { + $this->configureElements(); + $this->configureFilters(); + $this->configureRules(); + } + + // }}} + // {{{ configureRules() + + /** + * Form rule definitions + * + * Adds validation rules for the given fields + * + * @return void + * @access public + */ + public function configureRules() + { + // Form Rules + $r[] = array( + 'element' => 'topicid', + 'message' => 'ERROR: Invalid Category!', + 'type' => 'numeric', + 'format' => null, + 'validation' => $this->validationType, + 'reset' => true, + 'force' => false + ); + $r[] = array( + 'element' => 'email', + 'message' => 'ERROR: Invalid Email Format!', + 'type' => 'checkEmail', + 'format' => array('use_rfc822' => true), + 'validation' => $this->validationType, + 'reset' => true, + 'force' => false + ); + $r[] = array( + 'element' => array('starting', 'ending'), + 'message' => 'ERROR: Starting Date must be before Ending Date', + 'type' => 'callback', + 'format' => array(&$this, 'checkDateRange'), + 'validation' => $this->validationType, + 'reset' => false, + 'force' => false + ); + $r[] = array( + 'element' => 'starting', + 'message' => 'ERROR: Invalid date!', + 'type' => 'callback', + 'format' => array(&$this, 'checkDate'), + 'validation' => $this->validationType, + 'reset' => false, + 'force' => false + ); + $r[] = array( + 'element' => 'ending', + 'message' => 'ERROR: Invalid date!', + 'type' => 'callback', + 'format' => array(&$this, 'checkDate'), + 'validation' => $this->validationType, + 'reset' => false, + 'force' => false + ); + $r[] = array( + 'element' => 'website', + 'message' => 'ERROR: Invalid URL format', + 'type' => 'checkURI', + 'format' => array( + 'allowed_schemes' => array('http', 'https'), + 'strict' => false + ), + 'validation' => $this->validationType, + 'reset' => false, + 'force' => false + ); + $r[] = array( + 'element' => 'contact_phone', + 'message' => 'ERROR: Invalid Phone Format (xxx) xxx - xxxx!', + 'type' => 'phone', + 'format' => null, + 'validation' => $this->validationType, + 'reset' => true, + 'force' => false + ); + if ($this->useCaptcha) { + $r[] = array( + 'element' => 'captcha_rmv', + 'message' => 'ERROR: What you entered didn\'t match!', + 'type' => 'CAPTCHA', + 'format' => $this->captchaQuestion, + 'validation' => $this->validationType, + 'reset' => true, + 'force' => false + ); + } + + $this->setupRules($r); + } + + // }}} + // {{{ getTopicFields() + + /** + * get event topics + * + * @return array topics + * @access protected + */ + protected function getTopicFields() + { + $categories = array('' => '- select -'); + $catData = $this->eventMapper->fetchAllCategories(); + foreach ($catData as $category) { + $categories[$category->getId()] = $category->getName(); + } + return $categories; + } + + // }}} + // {{{ hasEndDate() + + /** + * verifies if we have a valid end date to work with + * + * @param array $d end date + * + * @return boolean if the end date is + */ + protected function hasEndDate($d) + { + $pattern = '/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/'; + if (preg_match($pattern, $d, $m)) { + return checkdate((int) $m[1], (int) $m[2], (int) $m[3]); + } else { + return false; + } + } + + // }}} + // {{{ emailOwner() + + /** + * Emails the owner the submitted data from the submitted form + * + * Uses a flexy template to render a nice looking html email. + * Fills in the supplied data from the form and doesn't add the + * empty fields the user didn't fill in. + * + * @return boolean result of the mailing + * @access protected + */ + protected function emailOwner() + { + if (!$this->email) { + return; + } + + $template = new HTML_Template_Flexy($this->flexyOptions); + $page = new stdClass(); + // for comments textarea need to replace newlines with br + $this->formData['comments']['element'] = nl2br($this->getSubmitValue('comments')); + unset($this->formData['lat'], $this->formData['lon']); + + // these values are required, therefor will always be part of + // the formData array + $bdate = explode('/', $this->formData['bdate']['element']); + $foo = array_map('trim', $bdate); + $this->formatValue($foo, '%02d/%02d/%d'); + $this->formData['bdate']['element'] = $foo; + + $btime = explode('/', $this->formData['btime']['element']); + $foo = array_map('trim', $btime); + $this->formatValue($foo, '%02d:%02d %s'); + $this->formData['btime']['element'] = $foo; + + // not required, so check to make sure it exists before trying + // to format the value + if (isset($this->formData['edate'])) { + $edate = explode('/', $this->formData['edate']['element']); + $foo = array_map('trim', $edate); + $this->formatValue($foo, '%02d/%02d/%d'); + $this->formData['edate']['element'] = $foo; + } + if (isset($this->formData['etime'])) { + $etime = explode('/', $this->formData['etime']['element']); + $foo = array_map('trim', $etime); + $this->formatValue($foo, '%02d:%02d %s'); + $this->formData['etime']['element'] = $foo; + } + + $category = $this->eventMapper->fetchCategory( + $this->formData['category']['element'] + ); + if ($category) { + $this->formData['category']['element'] = $category->getName(); + } + + $page->email_from = FROM_NEWS_EMAIL; + $page->subject = $this->subject; + $page->formData = $this->formData; + $page->eventAdminURL = MEDIA_BASE_URL . 'admin/CommonEvents/index.php?pending=1'; + + $template->compile('emailOwner.tpl'); + $htmlMsg = $template->bufferedOutputObject($page); + + // Text version can't have HTML in it + $msg = "{$page->subject}\n\n"; + $msg .= "From {$page->fname} {$page->lname}\n\n"; + $msg .= "Information\n\n"; + foreach ($page->formData as $i) { + $msg .= "{$i['label']}: {$i['element']}\n"; + } + + $crlf = "\n"; + $mimeMail = new Mail_mime($crlf); + $mimeMail->setFrom("{$this->siteName} <{$page->email_from}>"); + $mimeMail->setSubject($this->subject); + $mimeMail->setHTMLBody($htmlMsg); + $mimeMail->setTXTBody($msg); + + $mail = Mail::factory('mail'); + $body = $mimeMail->get(); + $headers = $mimeMail->headers(); + + $res = $mail->send($this->email, $headers, $body); + if (PEAR::isError($res)) { + return Toolkit_Common::handleError($res); + } else { + return $res; + } + } + + // }}} + // {{{ formatValue() + + /** + * Format an array into an acceptable string + * + * @param mixed &$i array values to format or null value for + * element that was not filled in + * @param string $format string to format values into + * + * @return string formatted string + * @access public + */ + public function formatValue(&$i, $format) + { + // Allow for 0 to be not empty. This allows for minutes in the + // time arrays to be valid if they are on the hour ie. (1:00 pm) + $notEmpty = create_function('$v', 'return strlen($v) > 0;'); + if (is_array($i) && count(array_filter($i, $notEmpty)) == 3) { + list($x, $y, $z) = array_values($i); + eval("\$i = sprintf('$format', $x, $y, $z);"); + } else { + $i = null; + } + } + + // }}} + // {{{ insertData() + + /** + * Inserts contact data into the contact db + * + * @param array $values submitted values + * + * @return object result of db insert query + * @access protected + */ + protected function insertData($values) + { + $values = $this->_geocode($values); + + try { + // need to set the dates up first + $this->formatValue($values['btime'], '%d:%02d %s'); + $this->formatValue($values['etime'], '%d:%02d %s'); + $values['description'] = nl2br($values['description']); + $values['website'] = preg_replace("/^(http:\/\/)/", "", $values['website']); + if ($values['btime']) { + $values['starthour'] = $values['btime']; + unset($values['btime']); + } + if ($values['etime']) { + $values['endhour'] = $values['etime']; + unset($values['etime']); + } + if ($values['category']) { + $values['category'] = $this->eventMapper->fetchCategory( + $values['category'] + ); + } + if (defined('MEMBERS_DB') && MEMBERS_DB) { + $event = MemberEvent::createByValues($values); + } else { + $event = Event::createByValues($values); + } + return $this->eventMapper->saveEvent($event); + + return false; + } catch (PDOException $e) { + return Toolkit_Common::handleError($e); + } + } + + // }}} + private function _geocode(array $values) + { + $geocoder = new GeocodeYahoo(); + if (!$values['address'] && !$values['city'] && !$values['state']) { + return $values; + } + $address = array( + 'city' => $values['city'], + 'state' => $values['state'], + 'zip' => $values['zip'], + ); + if (!empty($values['address'])) { + $address['street'] = $values['address']; + } + try { + $response = $geocoder->geocodeAddress($address); + $responseArray = unserialize($response); + if ($responseArray['ResultSet']['Result'][0]['Latitude']) { + $values['lat'] = $responseArray['ResultSet']['Result'][0]['Latitude']; + $values['lon'] = $responseArray['ResultSet']['Result'][0]['Longitude']; + } else { + $values['lat'] = $responseArray['ResultSet']['Result']['Latitude']; + $values['lon'] = $responseArray['ResultSet']['Result']['Longitude']; + } + + return $values; + } catch (BadMethodCallException $e) { + Toolkit_Logger::logException('Invalid Arg', $e); + } catch (Exception $e) { + Toolkit_Logger::logException('Yahoo GeoCode', $e); + } + + } + // {{{ processData() + + /** + * Handles how to process the form when submitted + * + * @param array $values Form submitted values + * + * @return array Result of Insert / Update function + * @access protected + */ + public function processData($values) + { + // Form data used for the insert/update sql queries and + // the form email. + $e = array(); + $this->setFormData($e); + + // Get rid of any defined un-needed elements. + // un-needed elements after the form is submitted are defined + // by the ending _rmv name. + foreach ($values as $k => &$v) { + if (!is_array($v)) { + $values[$k] = preg_replace("/\r/", "\n", $v); + } + if (preg_match('/^.+_rmv$/', $k)) { + unset($values[$k]); + } + } + $values['create_date'] = date('m/d/Y'); + + return $this->insertData($values); + } + + // }}} + // {{{ setupRenderers() + + /** + * Custom rendering templates for special fields on the form + * + * @return void + * @access protected + */ + protected function setupRenderers() + { + parent::setupRenderers(); + $renderer = $this->defaultRenderer(); + $required = '*'; + $error = '
{error}
'; + + $renderer->setElementTemplate('' . $required . '{label}' . $error . '{element}', 'descr'); + $renderer->setElementTemplate('' . $required . '{label}' . $error . '{element}', 'submit_rmv'); + + if ($this->useCaptcha) { + $renderer->setElementTemplate('{element}', 'captcha_question'); + $renderer->setElementTemplate('' . $required . '' . $error . '{element}What is this?', 'captcha_rmv'); + } + } + + // }}} + // {{{ toHtml() + + /** + * Handles how to display the current step the user is at in the form + * + * destroying and resetting the captcha value dis-allows someone from + * re-sending a form on a previous captcha. + * + * @return string form HTML state + * @access public + */ + public function toHtml() + { + $this->setupRenderers(); + if ($this->validate()) { + $this->captchaQuestion->destroy(); + $this->cleanForm(); + + if ($this->process(array(&$this, 'processData'), $this->mergeFiles)) { + $this->freeze(); + $this->emailOwner(); + $output = $this->successMsg; + } + $this->sent = true; + } elseif ($this->isSubmitted()) { + if ($this->useCaptcha) { + $this->captchaQuestion->destroy(); + $this->captchaAnswer->setValue(''); + } + $output = $this->errorMsg; + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL + . 'libjs/jqueryui/1.8.13/js/jquery-ui-1.8.13.custom.min.js'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL + . 'libjs/jqueryui/1.8.13/development-bundle/themes/base/jquery.ui.all.css'; + $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/textlimit.js'; + $GLOBALS['topScripts'][] + = 'http://maps.googleapis.com/maps/api/js?sensor=true'; + $GLOBALS['bottomScripts'][] + = MEDIA_BASE_URL . 'Toolkit/Maps/geoCoder.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_BASE_URL . 'Toolkit/Events/libjs/addEvent.js'; + $output .= parent::toHtml(); + } else { + if ($this->useCaptcha) { + $this->captchaQuestion->destroy(); + $this->captchaAnswer->setValue(''); + } + $GLOBALS['topScripts'][] + = MEDIA_APP_BASE_URL + . 'libjs/jqueryui/1.8.13/js/jquery-ui-1.8.13.custom.min.js'; + $GLOBALS['styleSheets'][] + = MEDIA_APP_BASE_URL + . 'libjs/jqueryui/1.8.13/development-bundle/themes/base/jquery.ui.all.css'; + $GLOBALS['bottomScripts'][] = MEDIA_APP_BASE_URL . 'libjs/textlimit.js'; + $GLOBALS['topScripts'][] + = 'http://maps.googleapis.com/maps/api/js?sensor=true'; + $GLOBALS['bottomScripts'][] + = MEDIA_BASE_URL . 'Toolkit/Maps/geoCoder.js'; + $GLOBALS['bottomScripts'][] + = MEDIA_BASE_URL . 'Toolkit/Events/libjs/addEvent.js'; + $output = parent::toHtml(); + } + return $output; + } + + // }}} +} + +?> diff --git a/Toolkit/Events/css/event.css b/Toolkit/Events/css/event.css new file mode 100755 index 0000000..d6e4289 --- /dev/null +++ b/Toolkit/Events/css/event.css @@ -0,0 +1,479 @@ +/* Events */ +#event-main-column, +#event-second-column { + position: relative; + } +#event-main-column #slider-wrapper { + position: relative; + } +#event-main-column #slider-wrapper .nivo-controlNav { + position: absolute; + bottom: 10px; + width: 100%; + z-index: 100; + } +.eventrow { + font-size: 13px; + } +/* Main Columns on all even pages */ +#event-main-column { + float: left; + margin: 0 0 20px 0; + } +#event-second-column { + float: right; + /*border: 1px solid #c4d2da;*/ + margin: 0 0 20px 0; + } + +/* Search Column */ +#event-second-column h3 { + margin: 0; + /*padding: 15px 5px 5px;*/ + padding: 0 5px 5px 5px; + color: #0578B2; + /*border-top: 1px solid #999;*/ + font-size: 18px; + } +/* Event Shortcuts */ +#event-shortcuts ul { + /*background: #c4d2da;*/ + padding-bottom: 20px; + /*background: #114C75; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + -moz-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + */ + background: no-repeat url(../../../assets/navBg.png); + background-size: cover; + } +#event-shortcuts li { + padding: 5px 5px 0; + } +#event-shortcuts a { + display: block; + padding: 5px; + text-align: center; + border: 1px solid; + border-top-color: #ccc; + border-right-color: #aaa; + border-bottom-color: #aaa; + border-left-color: #ccc; + background: #fff; + text-decoration: none; + color: black; + font-size: 14px; + } +#event-shortcuts a:hover { + border-top-color: #aaa; + border-right-color: #ccc; + border-bottom-color: #ccc; + border-left-color: #aaa; + background: #eee; + } +#event-shortcuts h3 { + margin-top: 20px; + } +/* Event Search Form Side */ +#event-search form { + background: #c4d2da; + background: #eee; + background: #0578B2; + background: no-repeat url(../../../assets/navBg.png); + background-size: cover; + padding: 5px 5px 15px 5px; + /* background: #114C75; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + -moz-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + */ + } +#event-search form span { + color: white; + font-size: 14px; + display: block; + padding: 5px 0; + } +#eventNameSearchWrapper form span { + text-align: center; + } + +#event-search #startMonth, +#event-search #endMonth { + border: 1px solid #aaa; + padding: 2px 4px; + display: block; + /*background: #fff url(http://app.gaslightmedia.com/assets/icons/calendar.png) no-repeat 156px center;*/ + background: #fff; + margin: 6px 0; + width: 100%; + } +#startMonthWrapper, #endMonthWrapper { + position: relative; + z-index: 5; + } +.ui-datepicker-trigger { + position: absolute; + z-index: 6; + right: 5px; + top: 3px; + cursor: pointer; + } +#event-search select { + border: 1px solid #aaa; + padding: 2px 4px; + width: 100%; + display: block; + } +#submitWrapper, #submitNameWrapper, #event-search input[type="image"] { + text-align: center; + } +#event-search span { + font-weight: bold; + } +/* Featured Events Side */ +#event-featured div { + background-repeat: no-repeat; + padding-bottom: 20px; + height: 100px; + position: relative; + /* border: 1px solid #c4d2da; + border-bottom: 1px solid #c4d2da; */ + margin: 0 0 10px 0px; + } +#event-featured h3 { + margin-top: 20px; + } +#event-featured p { + position: absolute; + right: 0; + bottom: 5px; + display: inline-block; + /*background: #ddd;*/ + background: rgba(255, 255, 255, .8); + margin: 0; + padding: 3px 6px; + font-size: 11px; + /* font-size: 1rem; */ + } +#event-featured a { + position: absolute; + left: 0; + top: 0; + width: 100%; + background: #ddd; + background: rgba(255, 255, 255, .9); + padding: 3px 5px; + font-size: 12px; + /* font-size: 1rem; */ + } +/* MAIN EVENT PAGE */ +.eventrow { + overflow: hidden; + height: 1%; + clear: left; + } +.event-category-block { + background: #eee; + border: 1px solid #ccc; + + margin: 20px 20px 0 0; + float: left; + width: 240px; +/* -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + -moz-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); + box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); +*/ } +.event-category-2 { + margin-right: 0; + } +#event-main-column .event-category-block h2 { + /* font-size: 1.3rem; */ + border-bottom: 1px solid #999; + margin: 0; + padding: 5px 10px; + background: #ddd; + -webkit-border-top-left-radius: 6px; + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topleft: 6px; + -moz-border-radius-topright: 6px; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + } +.event-category-block div { + /*border-bottom: 1px solid #ccc;*/ + padding: 5px 10px; + font-weight: bold; + } +.event-category-block b { + margin-right: 10px; + font-weight: bold; + display: block; + } +.event-category-block a, .event-list a, .eventDetail a, #eventDetailContact a { + color: #114C75; + } +.event-more { + display: block; + text-align: right; + padding: 5px; + font-size: 12px; + /* font-size: 1.2rem; */ + display: none; + } +.event-more:hover { + background: #fefefe; + } +/* Event Detail page */ +.gmnoprint { /* removes map ui */ + display: none !important; + } +#eventDetail { + margin-top: 1em; + font-size: 12px; + } +#eventDetail h2 { + position: relative; + margin: 0; + padding: 10px; + border: 1px solid #ccc; + } +#eventDetail h2 p { + display: inline-block; + background: white; + background: rgba(255, 255, 255, .9); + padding: 10px; + margin: 0; + position: absolute; + bottom: 20px; + left: 20px; + font-size: 18px; + /* font-size: 1.8rem; */ + } +#eventDetailTop { + background: #eee; + height: 1%; + overflow: hidden; + border: 1px solid #ccc; + border-top: 1px solid #eee; + } +#eventDetailMap { + + border: 1px solid; + border-top-color: #ccc; + border-right-color: #aaa; + border-bottom-color: #aaa; + border-left-color: #ccc; + margin-top: 10px; + } +#eventDetailMap:hover { + border-top-color: #aaa; + border-right-color: #ccc; + border-bottom-color: #ccc; + border-left-color: #aaa; + } +#eventDetail-map { + cursor: pointer; + height:160px; + } +#EventDrivingDirectionsContainer { + margin: 10px 0 0 0; + } +#EventDrivingDirectionsForm { + margin: 0; + } +#EventDrivingDirectionSubmit { + display: block; + width: 100%; + line-height: 28px; + height: 28px; + border: 1px solid; + border-top-color: #ccc; + border-right-color: #aaa; + border-bottom-color: #aaa; + border-left-color: #ccc; + background: white; + font-size: 12px; + /* font-size: 1.0rem; */ + color: #000; + cursor: pointer; + } +#EventDrivingDirectionSubmit:hover { + border-top-color: #aaa; + border-right-color: #ccc; + border-bottom-color: #ccc; + border-left-color: #aaa; + background: #eee; + } +#EventDrivingDirectionSubmit:hover { + background-position: 0px -28px; + } +#eventDetailInfo { + padding: 10px; + font-size: 12px; + /* font-size: .8rem; */ + height: 1%; + overflow: hidden; + line-height: 1.5; + } +#eventDetailInfo > div { + height: 1%; + overflow: hidden; + padding: 5px 5px 5px 30px; + margin: 0 5px 5px 0; + border-top: 1px solid #ededed; + border-left: 1px solid #ededed; + border-right: 1px solid #ddd; + border-bottom: 1px solid #ddd; + background-color: #fefefe; + background-repeat: no-repeat; + background-position: 6px 6px; + } +#eventDetailTime { + background-image: url(http://app.gaslightmedia.com/assets/icons/clock.png); + } +#eventDetailDate { + font-weight: bold; + float: left; + margin-right: 20px; + } +#eventDetailHour { + float: left; + } +#eventDetailPlace { + background-image: url(http://app.gaslightmedia.com/assets/icons/map.png); + background-position: 7px 7px; + } +#eventDetailLocation { + font-weight: bold; + } +#eventCost { + background-image: url(http://app.gaslightmedia.com/assets/icons/coins.png); + } +#eventDetailContact { + background-image: url(http://app.gaslightmedia.com/assets/icons/vcard.png); + } +#eventDetailContact h3 { + margin: 0; + font-size: 12px; + /* font-size: 1.0rem; */ + } +#eventDetailContact p { + margin: 0; + } +#eventDetailAddress, +#eventDetailCity { + display: block; + } +#eventDetailDesc { + margin: 0; + padding: 20px; + border: 1px solid #ccc; + border-top: 0; + } +#eventDetailDesc p { + margin-top: 0; + } +/* Event Search Result */ +.event-search { + font-size: 12px; + /* font-size: 1.2rem; */ + background: #eee; + border: 1px dashed #ccc; + padding: 3px 6px; + } +.event-list { + border-bottom: 1px solid #ccc; + height: 1%; + overflow: hidden; + padding: 6px 0; + } +.event-list-date { + width: 130px; + float: left; + padding: 3px 6px; + display: block; + margin: 0; + font-size: 12px; + /* font-size: 1.2rem; */ + font-weight: bold; + } +.event-list h3 { + font-size: 12px; + /* font-size: 1.2rem; */ + float: left; + padding: 3px; + width: 280px; + background-image: none !important; + margin: 0; + line-height: 1.5em; + } +.event-list h3 a { + font-size: 13px; + /* font-size: 1.3rem; */ + } +.event-list-Frequency { + float: right; + text-align: right; + width: 80px; + font-size: 11px; + /* font-size: 1.1rem; */ + margin: 0; + } +.ulCr, .ulCr li, .ulCr ul { + list-style-type: none; + margin: 0; + padding: 0; + display: block; + } +#EventSocialLinks { + clear: right; + /*width: 162px;*/ + /*background: #0F0;*/ + margin: 0 2% 10px 0; + } +#EventSocialLinks ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + } +#EventSocialLinks ul li { + display: block; + float: right; + height: 28px; + /*width: 81px;*/ + width: 100%; + margin: 8px 0 0 0; + padding: 0; + } +#EventSocialLinks ul li a { + display: block; + text-indent: -9999px; + width: 100%; + height: 28px; + margin: 0; + border-top: 1px solid #CCC; + border-right: 1px solid #CCC; + border-left: 1px solid #AAA; + border-bottom: 1px solid #AAA; + box-sizing: border-box; + -moz-box-sizing: border-box; + } +#EventSocialLinks ul li a#fb { + float: right; + background: #39588F url(http://app.gaslightmedia.com/Common/EventCalendar_V0/assets/fb.jpg) center center no-repeat; + } +#EventSocialLinks ul li a#tw { + float: right; + background: #FFF url(http://app.gaslightmedia.com/Common/EventCalendar_V0/assets/tw.jpg) center center no-repeat; + } \ No newline at end of file diff --git a/Toolkit/Events/views/eventDetail.html b/Toolkit/Events/views/eventDetail.html new file mode 100755 index 0000000..e7c94a1 --- /dev/null +++ b/Toolkit/Events/views/eventDetail.html @@ -0,0 +1,75 @@ + + +
+
+ {if:event.image} + + {end:} +

{event.header:h}

+
+
+
+
{event.dates}
+
{event.getEventTimes()}
+
+
+
{event.place}
+ {if:!event.hideAddress} + {event.address} + {event.city}, {event.state} {event.zip} + {end:} +
+
+
+
{event.cost}
+ + +
+

Contact & More Info

+
Contact: {event.contactName}
+ +
Phone: {event.contactPhone}
+
+
+
+
+
map...
+
Loading...
+
+
+ + + + + + +
+ +
+
+
{event.description:h}
+
+
diff --git a/Toolkit/Events/views/eventHomePage.html b/Toolkit/Events/views/eventHomePage.html new file mode 100755 index 0000000..aa3fec0 --- /dev/null +++ b/Toolkit/Events/views/eventHomePage.html @@ -0,0 +1,75 @@ +{if:hasSlideshowEvents} +
+
+
+ {foreach:slideShow,e} + {if:e.href} + + {end:} + {e.header} + {if:e.href} + + {end:} + {end:} +
+
+
+ {e.header} + {e.dates} +
+ +{end:} +
+options['strict'] + || (is_array($t->blocks) + || is_object($t->blocks))) { + foreach($t->blocks as $category => $events) { + if ($index % 2 == 0) { echo '
'; } ?> +
+

+ +

+ options['strict'] + || (is_array($events['data']) + || is_object($events['data']))) { + foreach($events['data'] as $event) { + ?> +
+ getDates();?> + + getHeader();?> +
+ + All +
+ '; + } ?> + blocks)-1 && ($index + 1) % 2 != 0) { + echo '
'; + } ?> + + +
\ No newline at end of file diff --git a/Toolkit/Events/views/eventList.html b/Toolkit/Events/views/eventList.html new file mode 100755 index 0000000..7d3fc10 --- /dev/null +++ b/Toolkit/Events/views/eventList.html @@ -0,0 +1,152 @@ + +
+{if:search} + + +{end:} + +{if:events} + {foreach:events,dateTime,date} +

{dateTime}

+ {foreach:date,categoryName,category} +
+ +

{categoryName}

+ {foreach:category,event} + {if:event.spans}
{end:} + {if:event.recurr}
{end:} + {if:event.normal}
{end:} +

+ {event.header} +

+
+ {event.getEventTimes()} + {if:event.spans}Ongoing Event{end:} + {if:event.recurr}Repeating Event{end:} +
+ {if:event.image} + + {end:} +
+ {event.intro:h} +
+
+ {end:} +
+ {end:} + {end:} +{else:} +

No events were found for your search.

+{end:} +
diff --git a/Toolkit/Events/views/eventSearchForm.html b/Toolkit/Events/views/eventSearchForm.html new file mode 100755 index 0000000..466c47d --- /dev/null +++ b/Toolkit/Events/views/eventSearchForm.html @@ -0,0 +1,122 @@ + +{if:options.hasNameSearch} + +{end:} diff --git a/Toolkit/Events/views/mainEventWrapper.html b/Toolkit/Events/views/mainEventWrapper.html new file mode 100755 index 0000000..b43bfbc --- /dev/null +++ b/Toolkit/Events/views/mainEventWrapper.html @@ -0,0 +1,62 @@ +{if:styleSheets} + {foreach:styleSheets,style} + + {end:} +{end:} +{if:topScripts} + {foreach:topScripts,script} + + {end:} +{end:} + + +
+
+
+ {if:eventHomePage}{end:} + {if:eventListResults}{end:} + {if:eventDetailPage}{end:} +
+
+ +
+

{front.shortCuts.title}

+ +
+ +
+
+
+{if:bottomScripts} + {foreach:bottomScripts,script} + + {end:} +{end:} +{startScriptTag:h} + + diff --git a/Toolkit/Page.php b/Toolkit/Page.php index 11e8e02..73c918b 100755 --- a/Toolkit/Page.php +++ b/Toolkit/Page.php @@ -456,7 +456,8 @@ class Toolkit_Page $this->mainNav = $this->_getMainNav($this->_catid); $this->sideNav = $this->_getSideNav($this->_catid); // main Navigation output - $this->mainNavigationUl = $this->_getMainNavigation(); + $this->mainNavigationUl = $this->_getMainNavigation(); + $this->mobileNavigationUl = $this->_getMobileNavigation(); $this->newsletterAction = Toolkit_Template_Page::getSeoUrl( $this->_pageGateway, 10 @@ -598,7 +599,36 @@ class Toolkit_Page return ($html) ? $html : ''; } - private function _arrayToListHTML($array, $level = 0, $className = null) + private function _getMobileNavigation() + { + if (defined('MAIN_LEVEL_NAV_ARRAY') && MAIN_LEVEL_NAV_ARRAY) { + $mainNavArray = unserialize(MAIN_LEVEL_NAV_ARRAY); + } + $sideNav = new Toolkit_Template_Navigation_AllInOneSideNav( + $this->_pageGateway + ); + $nav = $sideNav->getNavigation(); + $newNav = array(); + foreach ($nav as $key => $item) { + if ($item['id'] == HOME_ID) { + $item['class'] = 'home'; + } + if (in_array($item['id'], $mainNavArray) + || $item['id'] == HOME_ID + ) { + $key = array_search($item['id'], $mainNavArray); + if ($key !== false) { + $item['class'] = $key; + } + $newNav[] = $item; + } + } +// echo '
'.print_r($newNav, true).'
';exit; + $html = $this->_arrayToListHTML($newNav, 0, 'off-canvas-list', true); + return ($html) ? $html : ''; + } + + private function _arrayToListHTML($array, $level = 0, $className = null, $mobile = false) { static $tab = "\t", $format = '%s'; @@ -606,37 +636,49 @@ class Toolkit_Page return; } $tabs = str_repeat($tab, $level * 2); - $mainClass = ($level == 0 && $className) - ? ' class="'.$className.'"' - : ' class="dropdown"'; + if ($mobile) { + $mainClass = ' class="'.$className.'"'; + } else { + $mainClass = ($level == 0 && $className) + ? ' class="'.$className.'"' + : ' class="dropdown"'; + } + $result = "{$tabs}\n"; foreach ($array as $i => $node) { $classes = array(); -// $class -// = ($node['class'] == 'current') -// ? ' class="'.$node['class'].'"' -// : ''; - if ($node['class']) { - $classes[] = $node['class']; + if ($mobile && $node['class']) { + $class = ' class="'.$node['class'].'"'; + } else { + if ($node['class']) { + $classes[] = $node['class']; + } } + + if (!empty($node['pages'])) { $classes[] = 'has-dropdown'; } $parent = ' class="'.implode(' ', $classes).'"'; -// $parent -// = ($node['class'] == 'parent') -// ? ' class="'.$node['class'].'"' -// : ' class="not-click"'; $link = sprintf( $format, $node['uri'], $class, $node['label'] ); - $result .= "{$tabs}{$tab}\n{$tabs}{$tab}{$tab}" - . "{$link}\n" - . $this->_arrayToListHTML($node['pages'], $level + 1) - . "{$tabs}{$tab}\n"; + $result .= "{$tabs}{$tab}\n{$tabs}{$tab}{$tab}{$link}\n"; + if ($mobile) { + if (!empty($node['pages'])) { + $result .= ''; + } + + $result .= $this->_arrayToListHTML($node['pages'], $level + 1, '', true); + } else { + $result .= $this->_arrayToListHTML($node['pages'], $level + 1); + } + + + $result .= "{$tabs}{$tab}\n"; } $result .= "{$tabs}\n"; return $result; diff --git a/Toolkit/Template/BreadCrumbs.php b/Toolkit/Template/BreadCrumbs.php index 3a2a20e..fc37b45 100644 --- a/Toolkit/Template/BreadCrumbs.php +++ b/Toolkit/Template/BreadCrumbs.php @@ -131,10 +131,13 @@ class Toolkit_Template_BreadCrumbs public function toHtml($id) { $breadCrumbsArray = $this->getBreadCrumbsArray($id); - $breadCrumbs = implode(' > ', $breadCrumbsArray); +// echo '
'.print_r($breadCrumbsArray, true).'
'; +// exit; + $breadCrumbs = '
  • '.implode('
  • ', $breadCrumbsArray).'
  • '; return !empty($breadCrumbsArray) - ? '' + ? '' : ''; } diff --git a/Toolkit/Toolbox/Forms/EditPage.php b/Toolkit/Toolbox/Forms/EditPage.php index 10a9cc1..6d89cbd 100644 --- a/Toolkit/Toolbox/Forms/EditPage.php +++ b/Toolkit/Toolbox/Forms/EditPage.php @@ -42,7 +42,7 @@ class Toolkit_Toolbox_Forms_EditPage * @var integer * @access protected */ - protected $maxDepth = 0; + protected $maxDepth = 2; /** * Don't need to register any rules for this form. diff --git a/assets/go.png b/assets/go.png new file mode 100755 index 0000000..2b307a9 Binary files /dev/null and b/assets/go.png differ diff --git a/assets/navBg.png b/assets/navBg.png new file mode 100755 index 0000000..51e3030 Binary files /dev/null and b/assets/navBg.png differ diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..084cd33 --- /dev/null +++ b/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: /admin/ diff --git a/templates/template.html b/templates/template.html index 8f2e941..ca8ced5 100644 --- a/templates/template.html +++ b/templates/template.html @@ -63,38 +63,12 @@
    {mainNavigationUl:h} -