Add time-related content conditions
authorMatthias Schmidt <gravatronics@live.com>
Sun, 1 Jun 2014 07:57:26 +0000 (09:57 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 1 Jun 2014 07:57:33 +0000 (09:57 +0200)
com.woltlab.wcf/objectType.xml
wcfsetup/install/files/acp/templates/noticeAdd.tpl
wcfsetup/install/files/js/WCF.js
wcfsetup/install/files/lib/system/condition/DaysOfWeekCondition.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/condition/TimeCondition.class.php [new file with mode: 0644]
wcfsetup/install/files/style/datePicker.less
wcfsetup/install/lang/de.xml

index 8597bdb9d20250c3c5f1b6fe1a37bfaa04810382..16f6b23c85e6d6b784fd373d3068bb28c58b0d93 100644 (file)
                        <conditionobject>com.woltlab.wcf.page</conditionobject>
                </type>
                
+               <type>
+                       <name>com.woltlab.wcf.pointInTime.daysOfWeek</name>
+                       <definitionname>com.woltlab.wcf.condition.notice</definitionname>
+                       <classname><![CDATA[wcf\system\condition\DaysOfWeekCondition]]></classname>
+                       <conditionobject>com.woltlab.wcf.pointInTime</conditionobject>
+               </type>
+               <type>
+                       <name>com.woltlab.wcf.pointInTime.time</name>
+                       <definitionname>com.woltlab.wcf.condition.notice</definitionname>
+                       <classname><![CDATA[wcf\system\condition\TimeCondition]]></classname>
+                       <conditionobject>com.woltlab.wcf.pointInTime</conditionobject>
+               </type>
+               
                <type>
                        <name>com.woltlab.wcf.user.username</name>
                        <definitionname>com.woltlab.wcf.condition.notice</definitionname>
index 7b735be3f26b2a7ef707fd5deb08b06c12e77145..90840419bfdf98437e8490eb767b06806b94d47e 100644 (file)
                                {@$pageConditionObjectType->getProcessor()->getHtml()}
                        {/foreach}
                </fieldset>
+               
+               <fieldset>
+                       <legend>{lang}wcf.acp.notice.conditions.pointInTime{/lang}</legend>
+                       <small>{lang}wcf.acp.notice.conditions.pointInTime.description{/lang}</small>
+                       
+                       {foreach from=$groupedConditionObjectTypes['com.woltlab.wcf.pointInTime'] item='pointInTimeConditionObjectType'}
+                               {@$pointInTimeConditionObjectType->getProcessor()->getHtml()}
+                       {/foreach}
+               </fieldset>
+               
+               {event name='conditionTypeFieldsets'}
        </div>
        
        <header class="boxHeadline boxSubHeadline">
index 5209f95e42b78cbbaa0e96e48cf30880a573535d..1557b36581db544cb05bf3b6382f42b4934832dd 100755 (executable)
@@ -2963,6 +2963,18 @@ WCF.Date.Picker = {
                                }
                                $inputValue = $inputValue.replace(' ', 'T');
                                
+                               // Date objects require a date and a time, thus
+                               // add the current date to a time only-value
+                               if (false && $input.data('timeOnly')) {
+                                       $dateComponents = $inputValue.split(':');
+                                       $date = new Date();
+                                       $date.setHours($dateComponents[0]);
+                                       $date.setMinutes($dateComponents[1]);
+                                       $date.setSeconds(0);
+                                       
+                                       $inputValue = $date.toString();
+                               }
+                               
                                if ($input.data('ignoreTimezone')) {
                                        var $timezoneOffset = new Date($inputValue).getTimezoneOffset();
                                        var $timezone = ($timezoneOffset > 0) ? '-' : '+'; // -120 equals GMT+0200
@@ -2984,6 +2996,7 @@ WCF.Date.Picker = {
                                        minuteText: WCF.Language.get('wcf.date.minute'),
                                        showTime: false,
                                        timeFormat: this._timeFormat,
+                                       timeOnly: $input.data('timeOnly') ? true : false,
                                        yearRange: ($input.hasClass('birthday') ? '-100:+0' : '1900:2038')
                                });
                        }
@@ -3008,6 +3021,10 @@ WCF.Date.Picker = {
                        
                        // bug workaround: setDate creates the widget but unfortunately doesn't hide it...
                        $input.datepicker('widget').hide();
+                       
+                       if ($input.data('timeOnly')) {
+                               $input.datepicker('widget').addClass('timeOnlyPicker');
+                       }
                }, this));
        }
 };
diff --git a/wcfsetup/install/files/lib/system/condition/DaysOfWeekCondition.class.php b/wcfsetup/install/files/lib/system/condition/DaysOfWeekCondition.class.php
new file mode 100644 (file)
index 0000000..a053dff
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+namespace wcf\system\condition;
+use wcf\data\condition\Condition;
+use wcf\system\WCF;
+use wcf\util\DateUtil;
+
+/**
+ * Condition implementation for the day of the week.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2014 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.condition
+ * @category   Community Framework
+ */
+class DaysOfWeekCondition extends AbstractMultiSelectCondition implements IContentCondition {
+       /**
+        * @see wcf\system\condition\AbstractSelectCondition::$fieldName
+        */
+       protected $fieldName = 'daysOfWeek';
+       
+       /**
+        * @see \wcf\system\condition\AbstractSingleFieldCondition::$label
+        */
+       protected $label = 'wcf.date.daysOfWeek';
+       
+       /**
+        * @see \wcf\system\condition\AbstractSelectCondition::getOptions()
+        */
+       protected function getOptions() {
+               $options = array();
+               
+               $daysOfWeek = DateUtil::getWeekDays();
+               foreach ($daysOfWeek as $index => $day) {
+                       $options[$index] = WCF::getLanguage()->get('wcf.date.day.'.$day);
+               }
+               
+               return $options;
+       }
+       
+       /**
+        * @see \wcf\system\condition\IContentCondition::showContent()
+        */
+       public function showContent(Condition $condition) {
+               $date = DateUtil::getDateTimeByTimestamp(TIME_NOW);
+               $date->setTimezone(WCF::getUser()->getTimeZone());
+
+               return in_array($date->format('w'), $condition->daysOfWeek);
+       }
+}
diff --git a/wcfsetup/install/files/lib/system/condition/TimeCondition.class.php b/wcfsetup/install/files/lib/system/condition/TimeCondition.class.php
new file mode 100644 (file)
index 0000000..321593f
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+namespace wcf\system\condition;
+use wcf\data\condition\Condition;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
+use wcf\util\DateUtil;
+use wcf\util\StringUtil;
+
+/**
+ * Condition implementation for the current time.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2014 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.condition
+ * @category   Community Framework
+ */
+class TimeCondition extends AbstractMultipleFieldsCondition implements IContentCondition {
+       /**
+        * end time
+        * @var string
+        */
+       protected $endTime = '';
+       
+       /**
+        * @see \wcf\system\condition\AbstractMultipleFieldsCondition::$label
+        */
+       protected $labels = array(
+               'time' => 'wcf.date.time',
+               'timezone' => 'wcf.date.timezone'
+       );
+       
+       /**
+        * start time
+        * @var string
+        */
+       protected $startTime = '';
+
+       /**
+        * timezone used to evaluate the start/end time
+        * @var string
+        */
+       protected $timezone = 0;
+       
+       /**
+        * @see \wcf\system\condition\ICondition::getData()
+        */
+       public function getData() {
+               $data = array();
+               
+               if ($this->startTime) {
+                       $data['startTime'] = $this->startTime;
+               }
+               if ($this->endTime) {
+                       $data['endTime'] = $this->endTime;
+               }
+
+               if (!empty($data) && $this->timezone) {
+                       $data['timezone'] = $this->timezone;
+               }
+               
+               if (!empty($data)) {
+                       return $data;
+               }
+               
+               return null;
+       }
+       
+       /**
+        * @see \wcf\system\condition\ICondition::getHTML()
+        */
+       public function getHTML() {
+               $start = WCF::getLanguage()->get('wcf.date.period.start');
+               $end = WCF::getLanguage()->get('wcf.date.period.end');
+               
+               return <<<HTML
+<dl>
+       <dt>{$this->getLabel('time')}</dt>
+       <dd>
+               <input type="datetime" data-ignore-timezone="1" data-time-only="1" id="startTime" name="startTime" value="{$this->startTime}" placeholder="{$start}" />
+               <input type="datetime" data-ignore-timezone="1" data-time-only="1" id="endTime" name="endTime" value="{$this->endTime}" placeholder="{$end}" />
+               {$this->getDescriptionElement('time')}
+               {$this->getErrorMessageElement('time')}
+       </dd>
+</dl>
+<dl>
+       <dt>{$this->getLabel('timezone')}</dt>
+       <dd>
+               {$this->getTimezoneFieldElement()}
+               {$this->getDescriptionElement('timezone')}
+               {$this->getErrorMessageElement('timezone')}
+       </dd>
+</dl>
+HTML;
+       }
+       
+       protected function getTimezoneFieldElement() {
+               $fieldElement = '<select name="timezone" id="timezone"><option value="0"'.($this->timezone  ? ' selected="selected"' : '').'>'.WCF::getLanguage()->get('wcf.date.timezone.user').'</option>';
+               foreach (DateUtil::getAvailableTimezones() as $timezone) {
+                       $fieldElement .= '<option value="'.$timezone.'"'.($this->timezone === $timezone ? ' selected="selected"' : '').'>'.WCF::getLanguage()->get('wcf.date.timezone.'.str_replace('/', '.', strtolower($timezone))).'</option>';
+               }
+               $fieldElement .= '</select>';
+
+               return $fieldElement;
+       }
+       
+       /**
+        * @see \wcf\system\condition\ICondition::readFormParameters()
+        */
+       public function readFormParameters() {
+               if (isset($_POST['endTime'])) $this->endTime = StringUtil::trim($_POST['endTime']);
+               if (isset($_POST['startTime'])) $this->startTime = StringUtil::trim($_POST['startTime']);
+               if (isset($_POST['timezone'])) $this->timezone = StringUtil::trim($_POST['timezone']);
+       }
+       
+       /**
+        * @see \wcf\system\condition\ICondition::reset()
+        */
+       public function reset() {
+               $this->endTime = '';
+               $this->startTime = '';
+               $this->timezone = 0;
+       }
+       
+       /**
+        * @see \wcf\system\condition\ICondition::setData()
+        */
+       public function setData(Condition $condition) {
+               if ($condition->endTime) {
+                       $this->endTime = $condition->endTime;
+               }
+               if ($condition->startTime) {
+                       $this->startTime = $condition->startTime;
+               }
+               if ($condition->timezone) {
+                       $this->timezone = $condition->timezone;
+               }
+       }
+       
+       /**
+        * @see \wcf\system\condition\ICondition::validate()
+        */
+       public function validate() {
+               if ($this->startTime == '00:00' && $this->endTime == '00:00') {
+                       $this->startTime = $this->endTime = '';
+                       return;
+               }
+               
+               $startDateTime = $endDateTime = null;
+               if ($this->startTime) {
+                       $startDateTime = \DateTime::createFromFormat('H:i', $this->startTime);
+                       if ($startDateTime === false) {
+                               $this->errorMessages['time'] = 'wcf.date.startTime.error.notValid';
+                               
+                               throw new UserInputException('startTime', 'notValid');
+                       }
+               }
+               if ($this->endTime) {
+                       $endDateTime = \DateTime::createFromFormat('H:i', $this->endTime);
+                       if ($endDateTime === false) {
+                               $this->errorMessages['time'] = 'wcf.date.endTime.error.notValid';
+                               
+                               throw new UserInputException('endTime', 'notValid');
+                       }
+               }
+               
+               if ($startDateTime !== null && $endDateTime !== null) {
+                       if ($startDateTime->getTimestamp() >= $endDateTime->getTimeStamp()) {
+                               $this->errorMessages['time'] = 'wcf.date.endTime.error.beforeStartTime';
+                               
+                               throw new UserInputException('endTime', 'beforeStartTime');
+                       }
+               }
+               
+               if ($this->timezone && !in_array($this->timezone, DateUtil::getAvailableTimezones())) {
+                       $this->errorMessages['timezone'] = 'wcf.global.form.error.notValidSelection';
+                       
+                       throw new UserInputException('timezone', 'notValidSelection');
+               }
+       }
+       
+       /**
+        * @see \wcf\system\condition\IContentCondition::showContent()
+        */
+       public function showContent(Condition $condition) {
+               $timezone = WCF::getUser()->getTimeZone();
+               if ($condition->timezone) {
+                       $timezone = new \DateTimeZone($condition->timezone);
+               }
+               
+               if ($condition->startTime) {
+                       $dateTime = \DateTime::createFromFormat('H:i', $condition->startTime, $timezone);
+                       if ($dateTime->getTimestamp() > TIME_NOW) {
+                               return false;
+                       }
+               }
+               
+               if ($condition->endTime) {
+                       $dateTime = \DateTime::createFromFormat('H:i', $condition->endTime, $timezone);
+                       if ($dateTime->getTimestamp() < TIME_NOW) {
+                               return false;
+                       }
+               }
+               
+               return true;
+       }
+}
index 25e9e60d6cb8c0eb5330429e682cf6d2745b8764..ea7b957ee2f9a017d28bafb46b0ed1a17b68dd9b 100644 (file)
                        }
                }
        }
+       
+       &.timeOnlyPicker {
+               .ui-timepicker-div {
+                       border-top: none;
+                       
+                       > .ui-widget-header {
+                               display: none;
+                       }
+                       
+                       > dl {
+                               margin-right: @wcfGapTiny;
+                               
+                               > dt {
+                                       width: 70px;
+                               }
+                               
+                               > dd {
+                                       margin-left: 90px;
+                               }
+                       }
+               }
+       }
 }
index f98bcd1fed71836af9e8ed72e1a02522fd37dd0a..530e4375e08ec7f66b1bb5b42ea0ef0e0ebd0dd3 100644 (file)
                <item name="wcf.acp.notice.conditions.description"><![CDATA[Werden keine Bedingungen ausgewählt, wird der Hinweis für jeden Benutzer auf allen Seiten angezeigt.]]></item>
                <item name="wcf.acp.notice.conditions.page"><![CDATA[Seite]]></item>
                <item name="wcf.acp.notice.conditions.page.description"><![CDATA[Die vom Benutzer aufgerufene Seite muss folgende Bedingungen erfüllen, damit der Hinweis angezeigt wird.]]></item>
+               <item name="wcf.acp.notice.conditions.pointInTime"><![CDATA[Zeitpunkt]]></item>
+               <item name="wcf.acp.notice.conditions.pointInTime.description"><![CDATA[Legen Sie den Zeitpunkt fest, zu dem der Hinweis angezeigt werden soll.]]></item>
                <item name="wcf.acp.notice.conditions.user"><![CDATA[Aktiver Benutzer]]></item>
                <item name="wcf.acp.notice.conditions.user.description"><![CDATA[Der aktive Benutzer muss die folgenden Bedingungen erfüllen, damit der Hinweis angezeigt wird.]]></item>
                <item name="wcf.acp.notice.delete.confirmMessage"><![CDATA[Wollen Sie diesen Hinweis wirklich löschen?]]></item>
@@ -1825,6 +1827,13 @@ Fehler sind beispielsweise:
                <item name="wcf.date.period.start"><![CDATA[von]]></item>
                <item name="wcf.date.period.end"><![CDATA[bis]]></item>
                <item name="wcf.date.firstDayOfTheWeek"><![CDATA[1]]></item>
+               <item name="wcf.date.daysOfWeek"><![CDATA[Wochentage]]></item>
+               <item name="wcf.date.time"><![CDATA[Uhrzeit]]></item>
+               <item name="wcf.date.timezone"><![CDATA[Zeitzone]]></item>
+               <item name="wcf.date.timezone.user"><![CDATA[Zeitzone des Benutzers]]></item>
+               <item name="wcf.date.endTime.error.beforeStartTime"><![CDATA[Der Endzeitpunkt muss nach dem Startzeitpunkt liegen.]]></item>
+               <item name="wcf.date.startTime.error.notValid"><![CDATA[Der Startzeitpunkt ist ungültig.]]></item>
+               <item name="wcf.date.endTime.error.notValid"><![CDATA[Der Endzeitpunkt ist ungültig.]]></item>
        </category>
        
        <category name="wcf.global">