| Code Coverage | ||||||||||
| Classes and Traits | Functions and Methods | Lines | ||||||||
| Total |  | 0.00% | 0 / 1 |  | 0.00% | 0 / 21 | CRAP |  | 0.00% | 0 / 162 | 
| TaskForm |  | 0.00% | 0 / 1 |  | 0.00% | 0 / 21 | 2162 |  | 0.00% | 0 / 162 | 
| init |  | 0.00% | 0 / 1 | 20 |  | 0.00% | 0 / 11 | |||
| rules |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 10 | |||
| anonymous function |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 2 | |||
| getTimeFormat |  | 0.00% | 0 / 1 | 6 |  | 0.00% | 0 / 3 | |||
| beforeValidate |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 4 | |||
| checkAllDay |  | 0.00% | 0 / 1 | 6 |  | 0.00% | 0 / 11 | |||
| validateEndTime |  | 0.00% | 0 / 1 | 6 |  | 0.00% | 0 / 5 | |||
| attributeLabels |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 10 | |||
| getTitle |  | 0.00% | 0 / 1 | 6 |  | 0.00% | 0 / 6 | |||
| createNew |  | 0.00% | 0 / 1 | 6 |  | 0.00% | 0 / 5 | |||
| load |  | 0.00% | 0 / 1 | 72 |  | 0.00% | 0 / 13 | |||
| save |  | 0.00% | 0 / 1 | 20 |  | 0.00% | 0 / 21 | |||
| showTimeFields |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 3 | |||
| getListIdsToReload |  | 0.00% | 0 / 1 | 20 |  | 0.00% | 0 / 10 | |||
| translateDateTimes |  | 0.00% | 0 / 1 | 20 |  | 0.00% | 0 / 15 | |||
| getSubmitUrl |  | 0.00% | 0 / 1 | 6 |  | 0.00% | 0 / 3 | |||
| getDeleteUrl |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 3 | |||
| getTaskAssignedPickerUrl |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 3 | |||
| getTaskResponsiblePickerUrl |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 3 | |||
| getContentContainer |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 3 | |||
| getRemindModeItems |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 12 | |||
| <?php | |
| /** | |
| * @link https://www.humhub.org/ | |
| * @copyright Copyright (c) 2018 HumHub GmbH & Co. KG | |
| * @license https://www.humhub.com/licences | |
| * | |
| */ | |
| /** | |
| * Created by PhpStorm. | |
| * User: davidborn | |
| */ | |
| namespace humhub\modules\tasks\models\forms; | |
| use humhub\modules\content\widgets\richtext\RichText; | |
| use humhub\modules\tasks\helpers\TaskUrl; | |
| use Yii; | |
| use yii\base\Model; | |
| use DateInterval; | |
| use DateTime; | |
| use DateTimeZone; | |
| use humhub\libs\DbDateValidator; | |
| use humhub\modules\tasks\models\scheduling\TaskReminder; | |
| use humhub\modules\content\components\ContentContainerActiveRecord; | |
| use humhub\modules\content\models\Content; | |
| use humhub\modules\tasks\models\Task; | |
| use humhub\modules\tasks\CalendarUtils; | |
| use yii\web\HttpException; | |
| class TaskForm extends Model | |
| { | |
| /** | |
| * @var integer Content visibility | |
| */ | |
| public $is_public; | |
| /** | |
| * @var Task | |
| */ | |
| public $task; | |
| /** | |
| * @var string start date submitted by user will be converted to db date format and timezone after validation | |
| */ | |
| public $start_date; | |
| /** | |
| * @var string start time string | |
| */ | |
| public $start_time; | |
| /** | |
| * @var string end date submitted by user will be converted to db date format and timezone after validation | |
| */ | |
| public $end_date; | |
| /** | |
| * @var string end time string | |
| */ | |
| public $end_time; | |
| /** | |
| * @var string time zone of the task | |
| */ | |
| public $timeZone; | |
| /** | |
| * @var boolean defines if the request came from a calendar | |
| */ | |
| public $cal; | |
| /** | |
| * @var boolean defines if the request should be redirected after success | |
| */ | |
| public $redirect; | |
| /** | |
| * @var integer | |
| */ | |
| public $taskListId; | |
| /** | |
| * @var array | |
| */ | |
| public $newItems; | |
| /** | |
| * @var array | |
| */ | |
| public $editItems; | |
| /** | |
| * @var | |
| */ | |
| public $reloadListId; | |
| /** | |
| * @var string | |
| */ | |
| public $submitUrl; | |
| /** | |
| * @inheritdoc | |
| */ | |
| public function init() | |
| { | |
| $this->timeZone = empty($this->timeZone) ? Yii::$app->formatter->timeZone : $this->timeZone; | |
| if ($this->task) { | |
| $this->task->scenario = Task::SCENARIO_EDIT; | |
| if($this->task->all_day) { | |
| $this->timeZone = $this->task->time_zone; | |
| } | |
| $this->translateDateTimes($this->task->start_datetime, $this->task->end_datetime, Yii::$app->timeZone, $this->timeZone); | |
| $this->is_public = $this->task->content->visibility; | |
| } | |
| } | |
| /** | |
| * @inheritdoc | |
| */ | |
| public function rules() | |
| { | |
| return [ | |
| [['start_time', 'end_time'], 'date', 'type' => 'time', 'format' => $this->getTimeFormat()], | |
| [['start_date'], DbDateValidator::class, 'format' => Yii::$app->params['formatter']['defaultDateFormat'], 'timeAttribute' => 'start_time', 'timeZone' => $this->timeZone], | |
| [['end_date'], DbDateValidator::class, 'format' => Yii::$app->params['formatter']['defaultDateFormat'], 'timeAttribute' => 'end_time', 'timeZone' => $this->timeZone], | |
| [['end_date'], 'validateEndTime'], | |
| [['start_date', 'end_date'], 'required', 'when' => function($model) { | |
| return $model->task->scheduling == 1; | |
| }, 'whenClient' => "function (attribute, value) { | |
| return $('#task-scheduling').val() == 1; | |
| }"], | |
| [['start_time', 'end_time'], 'required', 'when' => function($model) { | |
| return $model->task->all_day == 0; | |
| }, 'whenClient' => "function (attribute, value) { | |
| return $('#task-all_day').val() == 0; | |
| }"], | |
| [['is_public'], 'integer'], | |
| [['newItems', 'editItems'], 'safe'], | |
| ]; | |
| } | |
| public function getTimeFormat() | |
| { | |
| return Yii::$app->formatter->isShowMeridiem() ? 'h:mm a' : 'php:H:i'; | |
| } | |
| public function beforeValidate() | |
| { | |
| $this->checkAllDay(); | |
| return parent::beforeValidate(); // TODO: Change the autogenerated stub | |
| } | |
| public function checkAllDay() | |
| { | |
| Yii::$app->formatter->timeZone = $this->timeZone; | |
| if($this->task->all_day) { | |
| $date = new DateTime('now', new DateTimeZone($this->timeZone)); | |
| $date->setTime(0,0); | |
| $this->start_time = Yii::$app->formatter->asTime($date, $this->getTimeFormat()); | |
| $date->setTime(23,59); | |
| $this->end_time = Yii::$app->formatter->asTime($date, $this->getTimeFormat()); | |
| } | |
| Yii::$app->i18n->autosetLocale(); | |
| } | |
| /** | |
| * Validator for the endtime field. | |
| * Execute this after DbDateValidator | |
| * | |
| * @param string $attribute attribute name | |
| * @param [] $params parameters | |
| */ | |
| public function validateEndTime($attribute, $params) | |
| { | |
| if (new DateTime($this->start_date) >= new DateTime($this->end_date)) { | |
| $this->addError($attribute, Yii::t('TasksModule.models_forms_TaskForm', 'End time must be after start time!')); | |
| } | |
| } | |
| /** | |
| * @inheritdoc | |
| */ | |
| public function attributeLabels() | |
| { | |
| return array_merge(parent::attributeLabels(), [ | |
| 'start_date' => Yii::t('TasksModule.models_forms_TaskForm', 'Start Date'), | |
| // 'type_id' => Yii::t('TasksModule.models_forms_TaskForm', 'Event Type'), | |
| 'end_date' => Yii::t('TasksModule.models_forms_TaskForm', 'End Date'), | |
| 'start_time' => Yii::t('TasksModule.models_forms_TaskForm', 'Start Time'), | |
| 'end_time' => Yii::t('TasksModule.models_forms_TaskForm', 'End Time'), | |
| 'timeZone' => Yii::t('TasksModule.models_forms_TaskForm', 'Time Zone'), | |
| 'is_public' => Yii::t('TasksModule.models_forms_TaskForm', 'Public'), | |
| ]); | |
| } | |
| public function getTitle() | |
| { | |
| if($this->task->isNewRecord) { | |
| return Yii::t('TasksModule.views_index_edit', '<strong>Create</strong> new task'); | |
| } | |
| return Yii::t('TasksModule.views_index_edit', '<strong>Edit</strong> task'); | |
| } | |
| /** | |
| * Instantiates a new task for the given ContentContainerActiveRecord. | |
| * | |
| * @param ContentContainerActiveRecord $contentContainer | |
| */ | |
| public function createNew(ContentContainerActiveRecord $contentContainer) | |
| { | |
| $this->task = new Task($contentContainer, Content::VISIBILITY_PRIVATE, ['task_list_id' => $this->taskListId]); | |
| $this->task->scenario = Task::SCENARIO_EDIT; | |
| $this->is_public = ($this->task->content->visibility != null) ? $this->task->content->visibility : Content::VISIBILITY_PRIVATE; | |
| } | |
| /** | |
| * Loads this model and the task model with the given data. | |
| * | |
| * @inheritdoc | |
| * | |
| * @param array $data | |
| * @param null $formName | |
| * @return bool | |
| */ | |
| public function load($data, $formName = null) | |
| { | |
| // Make sure we load the timezone beforehand so its available in validators etc.. | |
| if($data && isset($data[$this->formName()]) && isset($data[$this->formName()]['timeZone']) && !empty($data[$this->formName()]['timeZone'])) { | |
| $this->timeZone = $data[$this->formName()]['timeZone']; | |
| } | |
| if(parent::load($data) && !empty($this->timeZone)) { | |
| $this->task->time_zone = $this->timeZone; | |
| } | |
| $this->task->content->visibility = $this->is_public; | |
| if(!$this->task->load($data)) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| /** | |
| * Validates and saves the task instance. | |
| * @return bool | |
| * @throws HttpException | |
| * @throws \yii\base\InvalidConfigException | |
| */ | |
| public function save() | |
| { | |
| $this->task->setEditItems($this->editItems); | |
| $this->task->setNewItems($this->newItems); | |
| if(!$this->validate()) { | |
| return false; | |
| } | |
| if(!$this->task->content->canEdit()) | |
| { | |
| throw new HttpException(403); | |
| } | |
| // After validation the date was translated to system time zone, which we expect in the database. | |
| $this->task->start_datetime = $this->start_date; | |
| $this->task->end_datetime = $this->end_date; | |
| // The form expects user time zone, so we translate back from app to user timezone | |
| $this->translateDateTimes($this->task->start_datetime, $this->task->end_datetime, Yii::$app->timeZone, $this->timeZone); | |
| // We save the list ids to reload in the view this has to be called before $task->save()! | |
| $this->reloadListId = $this->getListIdsToReload(); | |
| if($this->task->save()) { | |
| RichText::postProcess($this->task->description, $this->task); | |
| // Required for attached files | |
| $this->task->fileManager->attach(Yii::$app->request->post('fileList')); | |
| return true; | |
| } | |
| return false; | |
| } | |
| public function showTimeFields() | |
| { | |
| return !$this->task->all_day; | |
| } | |
| private function getListIdsToReload() | |
| { | |
| $result = false; | |
| if(!$this->task->isNewRecord && $this->task->isAttributeChanged('task_list_id', false)) { | |
| $result = [$this->task->task_list_id]; | |
| $result[] = $this->task->getOldAttribute('task_list_id'); | |
| } else if($this->task->isNewRecord) { | |
| $result = [$this->task->task_list_id]; | |
| } | |
| return $result; | |
| } | |
| /** | |
| * Translates the given start and end dates from $sourceTimeZone to $targetTimeZone and populates the form start/end time | |
| * and dates. | |
| * | |
| * By default $sourceTimeZone is the forms timeZone e.g user timeZone and $targetTimeZone is the app timeZone. | |
| * | |
| * @param string $start start string date in $sourceTimeZone | |
| * @param string $end end string date in $targetTimeZone | |
| * @param string $sourceTimeZone | |
| * @param string $targetTimeZone | |
| */ | |
| public function translateDateTimes($start = null, $end = null, $sourceTimeZone = null, $targetTimeZone = null, $dateFormat = 'php:Y-m-d H:i:s e') | |
| { | |
| if(!$start) { | |
| return; | |
| } | |
| $sourceTimeZone = (empty($sourceTimeZone)) ? $this->timeZone : $sourceTimeZone; | |
| $targetTimeZone = (empty($targetTimeZone)) ? Yii::$app->timeZone : $targetTimeZone; | |
| $startTime = new DateTime($start, new DateTimeZone($sourceTimeZone)); | |
| $endTime = new DateTime($end, new DateTimeZone($sourceTimeZone)); | |
| Yii::$app->formatter->timeZone = $targetTimeZone; | |
| // Todo: check if this is really necessary | |
| // Fix FullCalendar EndTime | |
| /*if (CalendarUtils::isFullDaySpan($startTime, $endTime, true)) { | |
| // In Fullcalendar the EndTime is the moment AFTER the event so we substract one second | |
| $endTime->sub(new DateInterval("PT1S")); | |
| $this->task->all_day = 1; | |
| }*/ | |
| $this->start_date = Yii::$app->formatter->asDateTime($startTime, $dateFormat); | |
| $this->start_time = Yii::$app->formatter->asTime($startTime, $this->getTimeFormat()); | |
| $this->end_date = Yii::$app->formatter->asDateTime($endTime, $dateFormat); | |
| $this->end_time = Yii::$app->formatter->asTime($endTime, $this->getTimeFormat()); | |
| Yii::$app->i18n->autosetLocale(); | |
| } | |
| public function getSubmitUrl() | |
| { | |
| return ($this->submitUrl) ? $this->submitUrl : TaskUrl::editTask($this->task, $this->cal, $this->redirect, $this->taskListId); | |
| } | |
| public function getDeleteUrl() | |
| { | |
| return TaskUrl::deleteTask($this->task, $this->cal, $this->redirect); | |
| } | |
| public function getTaskAssignedPickerUrl() | |
| { | |
| return TaskUrl::pickerAssigned($this->task); | |
| } | |
| public function getTaskResponsiblePickerUrl() | |
| { | |
| return TaskUrl::pickerResponsible($this->task); | |
| } | |
| /** | |
| * @return ContentContainerActiveRecord | |
| */ | |
| public function getContentContainer() | |
| { | |
| return $this->task->content->container; | |
| } | |
| public function getRemindModeItems() | |
| { | |
| return [ | |
| TaskReminder::REMIND_ONE_HOUR => Yii::t('TasksModule.models_taskReminder', 'At least 1 Hour before'), | |
| TaskReminder::REMIND_TWO_HOURS => Yii::t('TasksModule.models_taskReminder', 'At least 2 Hours before'), | |
| TaskReminder::REMIND_ONE_DAY => Yii::t('TasksModule.models_taskReminder', '1 Day before'), | |
| TaskReminder::REMIND_TWO_DAYS => Yii::t('TasksModule.models_taskReminder', '2 Days before'), | |
| TaskReminder::REMIND_ONE_WEEK => Yii::t('TasksModule.models_taskReminder', '1 Week before'), | |
| TaskReminder::REMIND_TWO_WEEKS => Yii::t('TasksModule.models_taskReminder', '2 Weeks before'), | |
| TaskReminder::REMIND_THREE_WEEKS => Yii::t('TasksModule.models_taskReminder', '3 Weeks before'), | |
| TaskReminder::REMIND_ONE_MONTH => Yii::t('TasksModule.models_taskReminder', '1 Month before'), | |
| ]; | |
| } | |
| } |