Common Events Application
authorSteve Sutton <steve@gaslightmedia.com>
Thu, 28 Aug 2014 14:15:59 +0000 (10:15 -0400)
committerSteve Sutton <steve@gaslightmedia.com>
Thu, 28 Aug 2014 14:15:59 +0000 (10:15 -0400)
Install common events
Import their old events.

Toolkit/Events/libjs/AddCommonEventForm.php [new file with mode: 0644]
Toolkit/Events/libjs/addEvent.js [new file with mode: 0644]
Toolkit/Events/libjs/edit-event.js [new file with mode: 0644]
Toolkit/Events/templates/emailOwner.tpl [new file with mode: 0755]
admin/CommonEvents/.htaccess [new file with mode: 0644]
admin/CommonEvents/index.php [new file with mode: 0644]
config/application.ini

diff --git a/Toolkit/Events/libjs/AddCommonEventForm.php b/Toolkit/Events/libjs/AddCommonEventForm.php
new file mode 100644 (file)
index 0000000..4fc56f0
--- /dev/null
@@ -0,0 +1,1061 @@
+<?php
+
+//     vim:set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker syntax=php:
+
+/**
+ * New Event Form
+ *
+ * PHP version 5
+ *
+ * @category Toolkit
+ * @package  Events
+ * @author   Steve Sutton <steve@gaslightmedia.com>
+ * @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 <steve@gaslightmedia.com>
+ * @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.
+     * <code>
+     * protected $email = false;
+     * </code>
+     *
+     * @var    unknown
+     * @access protected
+     */
+    protected $email;
+
+    /**
+     * From header in the owner email
+     *
+     * This just sets the From header in the owner email
+     * SITENAME <from@email.com>
+     *
+     * 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 <h1> 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';
+    public $formTemplate = 'form.html';
+
+    /**
+     * Message to display if the form is successfully submitted
+     *
+     * @var    string
+     * @access protected
+     */
+    protected $successMsg = '
+    <style type="text/css">
+        #category {display:none};
+        .listings {display:none};
+    </style>
+               <div id="form-sucess-top">
+            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.
+               </div>';
+
+    /**
+     * 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 <form> 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'    => 'eventNameHdr',
+            'display' => 'Event Name'
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => true,
+            'name'    => 'header',
+            'display' => 'Event Name'
+        );
+        $e[] = array(
+            'type'    => 'header',
+            'name'    => 'eventDateHdr',
+            'display' => 'Event Date / Time'
+        );
+        $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'    => 'header',
+            'name'    => 'eventInfoHdr',
+            'display' => 'Event Information'
+        );
+        $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
+                <div id="map-dialog">
+                    <div id="map_canvas" style="width:500px; height:400px"></div>
+                </div>
+                <a id="map-it" href="#">Map It</a>'
+        );
+        $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',
+            'opts'    => array('id' => 'address')
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => true,
+            'name'    => 'city',
+            'display' => 'City',
+            'opts'    => array('id' => 'city')
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'state',
+            'display' => 'State',
+            'opts'    => array('id' => 'state')
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'zip',
+            'display' => 'ZIP',
+            'opts'    => array('id' => '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<br>(published on Web site)'
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => false,
+            'name'    => 'contact_email',
+            'display' => 'Contact Email<br>(published on Web site)'
+        );
+        $e[] = array(
+            'type'    => 'text',
+            'req'     => true,
+            'name'    => 'contact_phone',
+            'display' => 'Contact Phone<br>(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',
+            'opts'    => array('class' => 'button')
+        );
+
+        $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()
+    {
+        $formConfig = new Zend_Config_Ini(
+            BASE . 'Toolkit/Events/application.ini',
+            strtolower($_ENV['GLM_HOST_ID'])
+        );
+
+        $renderer = new HTML_QuickForm_Renderer_Object(true);
+        $this->accept($renderer);
+        $this->template = new HTML_Template_Flexy(
+            $formConfig->flexyOptions->toArray()
+        );
+
+        $this->view = $this;
+        $this->view->form = $renderer->toObject();
+        $this->template->compile($this->formTemplate);
+    }
+
+    // }}}
+    // {{{     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()
+    {
+        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'][]
+                = '//code.jquery.com/ui/1.11.1/jquery-ui.min.js';
+            $GLOBALS['styleSheets'][]
+                = '//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.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  = $this->errorMsg;
+            $this->setupRenderers();
+            $output .= $this->template->bufferedOutputObject($this->view);
+        } else {
+            if ($this->useCaptcha) {
+                $this->captchaQuestion->destroy();
+                $this->captchaAnswer->setValue('');
+            }
+            $GLOBALS['topScripts'][]
+                = '//code.jquery.com/ui/1.11.1/jquery-ui.min.js';
+            $GLOBALS['styleSheets'][]
+                = '//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.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';
+            $this->setupRenderers();
+            $output .= $this->template->bufferedOutputObject($this->view);
+        }
+        return $output;
+    }
+
+    // }}}
+}
+
+?>
diff --git a/Toolkit/Events/libjs/addEvent.js b/Toolkit/Events/libjs/addEvent.js
new file mode 100644 (file)
index 0000000..b912912
--- /dev/null
@@ -0,0 +1,28 @@
+var AddEvent =
+{
+       init: function()
+       {
+        $('#description')
+            .after('You have <span class="counter">1000</span>')
+            .textlimit('span.counter', 1000);
+        $('#sdate').datepicker({
+            altField: "#edate"
+        });
+        $('#edate').datepicker();
+        // For the Event Map
+        // Create a jquery dialog with #map-dialog
+        $('#map-dialog').dialog({
+            height: 480,
+            width: 520,
+            modal: true,
+            autoOpen: false
+        });
+        $("#map-it").click(function(e){
+            e.preventDefault();
+            $("#map-dialog").dialog('open');
+            GLM_GeoMap.initialize();
+        });
+       }
+}
+
+$(document).ready(AddEvent.init);
\ No newline at end of file
diff --git a/Toolkit/Events/libjs/edit-event.js b/Toolkit/Events/libjs/edit-event.js
new file mode 100644 (file)
index 0000000..16be645
--- /dev/null
@@ -0,0 +1,123 @@
+var Events =
+{
+       calendar: '//app.gaslightmedia.com/assets/icons/calendar.png',
+
+    init: function()
+    {
+        if ($("#descr").length) {
+            //  Only try to replace the textarea if the
+            //  CKEditor is compatible w/ the browser.
+            if (CKEDITOR.env.isCompatible) {
+                // test to see if this is in the Member only section
+                var hostPattern = new RegExp('/members-only-area/');
+                if (hostPattern.test(window.location.pathname)) {
+                    CKEDITOR.replace("descr",
+                    {
+                        toolbar : "Default",
+                        width : 600,
+                        height : 200,
+                        filebrowserImageBrowseUrl : "../Toolkit/CKImages/browser.php?folder=1",
+                        filebrowserImageUploadUrl : "../Toolkit/CKImages/controller.php?command=Upload",
+                        filebrowserImageWindowWidth : "760",
+                        filebrowserImageWindowHeight : "500"
+                    });
+                } else {
+                        CKEDITOR.replace("descr",
+                    {
+                        toolbar : "Default",
+                        width : 600,
+                        height : 200,
+                        filebrowserImageBrowseUrl : "../../Toolkit/CKImages/browser.php?folder=1",
+                        filebrowserImageUploadUrl : "../../Toolkit/CKImages/controller.php?command=Upload",
+                        filebrowserImageWindowWidth : "760",
+                        filebrowserImageWindowHeight : "500"
+                    });
+                }
+
+            }
+        }
+        if ($("#intro").length > 0) {
+            $("#intro").textlimit("#charleft", 350);
+        }
+        if ($("#sdate").length > 0) {
+            $('#sdate').datepicker({
+                altField: "#edate"
+            });
+            $('#edate').datepicker();
+        }
+        $(":checkbox[name='all_day']").change(function (){
+               Events.show_hide_time();
+        });
+        $("select[name='dayom']").change(function (){
+               Events.act_day_om($(this).val());
+        });
+        if ($(":checkbox[name='recurr']").length > 0) {
+            $(":checkbox[name='recurr']").change(function (){
+                Events.show_hide_recurr();
+            });
+            Events.show_hide_recurr();
+        }
+        if ($(":checkbox[name='reacur']").length > 0) {
+            $(":checkbox[name='reacur']").change(function (){
+                Events.show_hide_reacur();
+            });
+            Events.show_hide_reacur();
+        }
+        Events.show_hide_time();
+
+        Events.act_day_om($("select[name='dayom']").val());
+
+        // For the Event Map
+        // Create a jquery dialog with #map-dialog
+        $('#map-dialog').dialog({
+            height: 480,
+            width: 520,
+            modal: true,
+            autoOpen: false
+        });
+        $("#map-it").click(function(e){
+            e.preventDefault();
+            $("#map-dialog").dialog('open');
+            GLM_GeoMap.initialize();
+        });
+    },
+    show_hide_time: function() {
+       if ($(":checkbox[name='all_day']").attr('checked')) {
+               $("select[name^='btime']").val('');
+               $("select[name^='btime']").attr('disabled', 'disabled');
+               $("select[name^='etime']").val('');
+               $("select[name^='etime']").attr('disabled', 'disabled');
+       } else {
+               $("select[name^='btime']").removeAttr('disabled');
+               $("select[name^='etime']").removeAttr('disabled');
+       }
+    },
+    show_hide_reacur: function() {
+       if ($(":checkbox[name='reacur']").attr('checked')) {
+               $(".recur-event").show();
+       } else {
+               $(".recur-event").hide();
+       }
+    },
+    show_hide_recurr: function() {
+       if ($(":checkbox[name='recurr']").attr('checked')) {
+               $(".recur-event").show();
+       } else {
+               $(".recur-event").hide();
+       }
+    },
+    act_day_om: function(val)
+    {
+       if (val) {
+               $("input[name^='daysow']").attr('disabled', 'disabled');
+               $("input[name^='daysow']").removeAttr('checked');
+               $("select[name='weekom']").attr('disabled', 'disabled');
+               $("select[name='weekom']").val('');
+       } else {
+               $("input[name^='daysow']").removeAttr('disabled');
+               $("select[name='weekom']").removeAttr('disabled');
+       }
+    }
+};
+
+$(document).ready(Events.init);
diff --git a/Toolkit/Events/templates/emailOwner.tpl b/Toolkit/Events/templates/emailOwner.tpl
new file mode 100755 (executable)
index 0000000..944a364
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+       <meta http-equiv="content-type" content="text/html;charset=utf-8">
+       <title>{title:h}</title>
+</head>
+<body>
+       <style>
+               td {line-height:13px;}
+               body {font-size: 14px;}
+       </style>
+       <h2>{subject:h}</h2>
+       <h3>Information</h3>
+       <table cellspacing="0" cellpadding="0" width="500" style="border:1px solid #ccc;border-collapse:collapse;">
+               <tbody>
+                       <tr flexy:foreach="formData,v">
+                               <td flexy:if="v[element]" style="font-weight:bold;width:200px;padding:5px;border:1px solid #ccc;" align="right">{v[label]:h}</td>
+                               {if:v[nowrap]}
+                                       <td flexy:if="v[element]" nowrap style="padding:3px;border:1px solid #ccc;">{v[element]:h}</td>
+                               {else:}
+                                       <td flexy:if="v[element]" style="padding:3px;border:1px solid #ccc;">{v[element]:h}</td>
+                               {end:}
+                       </tr>
+               </tbody>
+       </table>
+       <p>A new Event has been added to your Website from your &quot;Add Your Event&quot; page.</p>
+       <p>To approve it, please go to the <a href="{eventAdminURL}">Pending Events</a> page in your admin.</p>
+</body>
+</html>
diff --git a/admin/CommonEvents/.htaccess b/admin/CommonEvents/.htaccess
new file mode 100644 (file)
index 0000000..7f2df55
--- /dev/null
@@ -0,0 +1,3 @@
+AddDefaultCharset utf-8
+php_flag register_globals off
+php_flag magic_quotes_gpc off
diff --git a/admin/CommonEvents/index.php b/admin/CommonEvents/index.php
new file mode 100644 (file)
index 0000000..36a4a66
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+try {
+    // look for a setup.phtml file in the directory one up from here
+    if (file_exists('../../setup.phtml')) {
+        include_once '../../setup.phtml';
+    } else {
+        throw new Exception('setup.phtml file not found!');
+    }
+    // set CommonApp define if not set
+    if (!defined('COMMON_APP_BASE')) {
+        define('COMMON_APP_BASE', '/var/www/server/CommonApps/');
+    }
+    // load the event application config files form CommonApps
+    define('COMMON_APP_NAME', 'EventCalendar');
+    define('COMMON_APP_VERSION', 'V1');
+    define('COMMON_APP_INI', 'application.ini');
+    define('COMMON_APP_SITE_INI', 'eventCalendar.ini');
+
+    define('COMMON_APP_CONTROLLER', 'AdminController');
+    $appPath = COMMON_APP_BASE . COMMON_APP_NAME . '/' . COMMON_APP_VERSION . '/';
+    define('COMMON_APP_PATH', $appPath);
+    // now only need to pull in the main file to run the app
+    // pull in admin.php file
+    require COMMON_APP_PATH . 'Bootstrap.php';
+
+} catch(Exception $e) {
+    die($e->getMessage());
+}
index 931c60d..a452e90 100644 (file)
@@ -47,11 +47,11 @@ constantcontact.list.0 = Off
 coupons.application = Off
 
 ; Turn the event application On or Off
-eventdb.application = Off
+eventdb.application = On
 ; Turn the Events Common Application On or Off
 eventdb.commonEvents = On
 ; The page id in the toolbox that holds the event calendar
-eventdb.event_page = Off
+eventdb.event_page = 7
 ; Turn the home page events module On or Off for the event application
 eventdb.home_events = Off