2012-10-24 22:22:24 +02:00
|
|
|
<?php
|
|
|
|
|
2014-02-06 19:10:07 +01:00
|
|
|
final class PhabricatorCalendarEventEditController
|
2012-10-24 22:22:24 +02:00
|
|
|
extends PhabricatorCalendarController {
|
|
|
|
|
|
|
|
private $id;
|
|
|
|
|
|
|
|
public function isCreate() {
|
|
|
|
return !$this->id;
|
|
|
|
}
|
|
|
|
|
2015-05-19 22:09:28 +02:00
|
|
|
public function handleRequest(AphrontRequest $request) {
|
2015-05-24 20:22:33 +02:00
|
|
|
$viewer = $request->getViewer();
|
|
|
|
$user_phid = $viewer->getPHID();
|
2015-08-02 00:43:14 +02:00
|
|
|
$this->id = $request->getURIData('id');
|
|
|
|
|
2015-04-28 17:34:26 +02:00
|
|
|
$error_name = true;
|
2015-06-11 00:37:29 +02:00
|
|
|
$error_recurrence_end_date = null;
|
2015-05-02 01:07:57 +02:00
|
|
|
$error_start_date = true;
|
|
|
|
$error_end_date = true;
|
2015-04-28 17:34:26 +02:00
|
|
|
$validation_exception = null;
|
|
|
|
|
2015-05-29 02:27:25 +02:00
|
|
|
$is_recurring_id = celerity_generate_unique_node_id();
|
2015-06-02 03:56:11 +02:00
|
|
|
$recurrence_end_date_id = celerity_generate_unique_node_id();
|
2015-05-29 02:27:25 +02:00
|
|
|
$frequency_id = celerity_generate_unique_node_id();
|
2015-05-21 02:10:12 +02:00
|
|
|
$all_day_id = celerity_generate_unique_node_id();
|
|
|
|
$start_date_id = celerity_generate_unique_node_id();
|
2015-05-29 02:27:25 +02:00
|
|
|
$end_date_id = celerity_generate_unique_node_id();
|
2015-05-21 02:10:12 +02:00
|
|
|
|
2015-05-24 20:22:33 +02:00
|
|
|
$next_workflow = $request->getStr('next');
|
|
|
|
$uri_query = $request->getStr('query');
|
|
|
|
|
2012-10-24 22:22:24 +02:00
|
|
|
if ($this->isCreate()) {
|
2015-05-27 20:11:11 +02:00
|
|
|
$mode = $request->getStr('mode');
|
|
|
|
$event = PhabricatorCalendarEvent::initializeNewCalendarEvent(
|
|
|
|
$viewer,
|
|
|
|
$mode);
|
2015-05-24 20:22:33 +02:00
|
|
|
|
|
|
|
$create_start_year = $request->getInt('year');
|
|
|
|
$create_start_month = $request->getInt('month');
|
|
|
|
$create_start_day = $request->getInt('day');
|
|
|
|
$create_start_time = $request->getStr('time');
|
|
|
|
|
|
|
|
if ($create_start_year) {
|
|
|
|
$start = AphrontFormDateControlValue::newFromParts(
|
|
|
|
$viewer,
|
|
|
|
$create_start_year,
|
|
|
|
$create_start_month,
|
|
|
|
$create_start_day,
|
|
|
|
$create_start_time);
|
|
|
|
if (!$start->isValid()) {
|
|
|
|
return new Aphront400Response();
|
|
|
|
}
|
|
|
|
$start_value = AphrontFormDateControlValue::newFromEpoch(
|
|
|
|
$viewer,
|
|
|
|
$start->getEpoch());
|
|
|
|
|
|
|
|
$end = clone $start_value->getDateTime();
|
|
|
|
$end->modify('+1 hour');
|
|
|
|
$end_value = AphrontFormDateControlValue::newFromEpoch(
|
|
|
|
$viewer,
|
|
|
|
$end->format('U'));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
list($start_value, $end_value) = $this->getDefaultTimeValues($viewer);
|
|
|
|
}
|
|
|
|
|
2015-06-02 03:56:11 +02:00
|
|
|
$recurrence_end_date_value = clone $end_value;
|
|
|
|
$recurrence_end_date_value->setOptional(true);
|
2015-05-20 19:59:41 +02:00
|
|
|
|
2012-10-24 22:22:24 +02:00
|
|
|
$submit_label = pht('Create');
|
2016-04-01 22:40:29 +02:00
|
|
|
$title = pht('Create Event');
|
|
|
|
$header_icon = 'fa-plus-square';
|
2015-04-28 15:26:48 +02:00
|
|
|
$redirect = 'created';
|
2015-04-28 19:40:35 +02:00
|
|
|
$subscribers = array();
|
2015-04-30 00:31:02 +02:00
|
|
|
$invitees = array($user_phid);
|
2015-05-01 02:09:45 +02:00
|
|
|
$cancel_uri = $this->getApplicationURI();
|
2012-10-24 22:22:24 +02:00
|
|
|
} else {
|
2015-04-28 17:34:26 +02:00
|
|
|
$event = id(new PhabricatorCalendarEventQuery())
|
Generate "stub" events earlier, so more infrastructure works with Calendar
Summary:
Ref T9275. When you create a recurring event which recurs forever, we want to avoid writing an infinite number of rows to the database.
Currently, we write a row to the database right before you edit the event. Until then, we refer to it as `E123/999` or whatever ("instance 999 of event 123").
This creates a big mess with trying to make recurring events work with EditEngine, Subscriptions, Projects, Flags, Tokens, etc -- all of this stuff assumes that whatever you're working with has a PHID.
I poked at letting this stuff work without a PHID a little bit, but that looked like a gigantic mess.
Instead, generate an event "stub" a little sooner (when you look at the event detail page). This is basically just an ID/PHID to refer to the instance.
Then, when you edit the stub, "materialize" it into a real event.
This still has some issues, but I think it's more promising than the other approach was.
Also:
- Removes dead user profile calendar controller.
- Replaces comments with EditEngine comments.
Test Plan:
- Commented on a recurring event.
- Awarded tokens to a recurring event.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9275
Differential Revision: https://secure.phabricator.com/D16248
2016-07-07 16:19:58 +02:00
|
|
|
->setViewer($viewer)
|
|
|
|
->withIDs(array($this->id))
|
|
|
|
->requireCapabilities(
|
|
|
|
array(
|
|
|
|
PhabricatorPolicyCapability::CAN_VIEW,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT,
|
|
|
|
))
|
|
|
|
->executeOne();
|
2015-04-28 17:34:26 +02:00
|
|
|
if (!$event) {
|
2014-03-22 03:11:48 +01:00
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
2014-02-06 19:07:42 +01:00
|
|
|
|
2015-05-02 01:07:57 +02:00
|
|
|
$end_value = AphrontFormDateControlValue::newFromEpoch(
|
2015-05-24 20:22:33 +02:00
|
|
|
$viewer,
|
2015-05-02 01:07:57 +02:00
|
|
|
$event->getDateTo());
|
|
|
|
$start_value = AphrontFormDateControlValue::newFromEpoch(
|
2015-05-24 20:22:33 +02:00
|
|
|
$viewer,
|
2015-05-02 01:07:57 +02:00
|
|
|
$event->getDateFrom());
|
2015-06-02 03:56:11 +02:00
|
|
|
$recurrence_end_date_value = id(clone $end_value)
|
|
|
|
->setOptional(true);
|
2015-05-02 01:07:57 +02:00
|
|
|
|
2012-10-24 22:22:24 +02:00
|
|
|
$submit_label = pht('Update');
|
2016-04-01 22:40:29 +02:00
|
|
|
$title = pht('Edit Event: %s', $event->getName());
|
|
|
|
$header_icon = 'fa-pencil';
|
2015-04-28 19:40:35 +02:00
|
|
|
|
|
|
|
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
|
|
|
$event->getPHID());
|
2015-04-30 04:48:46 +02:00
|
|
|
|
2015-04-30 00:31:02 +02:00
|
|
|
$invitees = array();
|
|
|
|
foreach ($event->getInvitees() as $invitee) {
|
|
|
|
if ($invitee->isUninvited()) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
$invitees[] = $invitee->getInviteePHID();
|
|
|
|
}
|
|
|
|
}
|
2015-05-01 02:09:45 +02:00
|
|
|
|
Generate "stub" events earlier, so more infrastructure works with Calendar
Summary:
Ref T9275. When you create a recurring event which recurs forever, we want to avoid writing an infinite number of rows to the database.
Currently, we write a row to the database right before you edit the event. Until then, we refer to it as `E123/999` or whatever ("instance 999 of event 123").
This creates a big mess with trying to make recurring events work with EditEngine, Subscriptions, Projects, Flags, Tokens, etc -- all of this stuff assumes that whatever you're working with has a PHID.
I poked at letting this stuff work without a PHID a little bit, but that looked like a gigantic mess.
Instead, generate an event "stub" a little sooner (when you look at the event detail page). This is basically just an ID/PHID to refer to the instance.
Then, when you edit the stub, "materialize" it into a real event.
This still has some issues, but I think it's more promising than the other approach was.
Also:
- Removes dead user profile calendar controller.
- Replaces comments with EditEngine comments.
Test Plan:
- Commented on a recurring event.
- Awarded tokens to a recurring event.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9275
Differential Revision: https://secure.phabricator.com/D16248
2016-07-07 16:19:58 +02:00
|
|
|
$cancel_uri = $event->getURI();
|
2012-10-24 22:22:24 +02:00
|
|
|
}
|
|
|
|
|
2015-06-22 22:27:37 +02:00
|
|
|
if ($this->isCreate()) {
|
|
|
|
$projects = array();
|
|
|
|
} else {
|
|
|
|
$projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
|
|
|
$event->getPHID(),
|
|
|
|
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
|
|
|
$projects = array_reverse($projects);
|
|
|
|
}
|
|
|
|
|
2015-05-01 18:11:51 +02:00
|
|
|
$name = $event->getName();
|
|
|
|
$description = $event->getDescription();
|
2015-05-08 03:57:28 +02:00
|
|
|
$is_all_day = $event->getIsAllDay();
|
2015-05-29 02:27:25 +02:00
|
|
|
$is_recurring = $event->getIsRecurring();
|
Generate "stub" events earlier, so more infrastructure works with Calendar
Summary:
Ref T9275. When you create a recurring event which recurs forever, we want to avoid writing an infinite number of rows to the database.
Currently, we write a row to the database right before you edit the event. Until then, we refer to it as `E123/999` or whatever ("instance 999 of event 123").
This creates a big mess with trying to make recurring events work with EditEngine, Subscriptions, Projects, Flags, Tokens, etc -- all of this stuff assumes that whatever you're working with has a PHID.
I poked at letting this stuff work without a PHID a little bit, but that looked like a gigantic mess.
Instead, generate an event "stub" a little sooner (when you look at the event detail page). This is basically just an ID/PHID to refer to the instance.
Then, when you edit the stub, "materialize" it into a real event.
This still has some issues, but I think it's more promising than the other approach was.
Also:
- Removes dead user profile calendar controller.
- Replaces comments with EditEngine comments.
Test Plan:
- Commented on a recurring event.
- Awarded tokens to a recurring event.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9275
Differential Revision: https://secure.phabricator.com/D16248
2016-07-07 16:19:58 +02:00
|
|
|
$is_parent = $event->isParentEvent();
|
2015-05-29 02:27:25 +02:00
|
|
|
$frequency = idx($event->getRecurrenceFrequency(), 'rule');
|
2015-05-19 22:09:28 +02:00
|
|
|
$icon = $event->getIcon();
|
2015-06-26 19:41:26 +02:00
|
|
|
$edit_policy = $event->getEditPolicy();
|
|
|
|
$view_policy = $event->getViewPolicy();
|
Events should offer Spaces as the view policy options
Summary: Ref T8687, Events should offer Spaces as the view policy options
Test Plan: Create event, choose default Space, save, edit, choose different Space, save, new policy should be reflected on Event.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley, Korvin
Maniphest Tasks: T8687
Differential Revision: https://secure.phabricator.com/D13459
2015-06-27 19:26:24 +02:00
|
|
|
$space = $event->getSpacePHID();
|
2015-05-01 18:11:51 +02:00
|
|
|
|
2012-10-24 22:22:24 +02:00
|
|
|
if ($request->isFormPost()) {
|
2015-04-28 17:34:26 +02:00
|
|
|
$xactions = array();
|
|
|
|
$name = $request->getStr('name');
|
2015-05-02 01:07:57 +02:00
|
|
|
|
|
|
|
$start_value = AphrontFormDateControlValue::newFromRequest(
|
|
|
|
$request,
|
|
|
|
'start');
|
|
|
|
$end_value = AphrontFormDateControlValue::newFromRequest(
|
|
|
|
$request,
|
|
|
|
'end');
|
2015-06-02 03:56:11 +02:00
|
|
|
$recurrence_end_date_value = AphrontFormDateControlValue::newFromRequest(
|
|
|
|
$request,
|
|
|
|
'recurrenceEndDate');
|
|
|
|
$recurrence_end_date_value->setOptional(true);
|
2015-06-22 22:27:37 +02:00
|
|
|
$projects = $request->getArr('projects');
|
2012-10-24 22:22:24 +02:00
|
|
|
$description = $request->getStr('description');
|
2015-04-28 19:40:35 +02:00
|
|
|
$subscribers = $request->getArr('subscribers');
|
2015-05-01 18:11:51 +02:00
|
|
|
$edit_policy = $request->getStr('editPolicy');
|
|
|
|
$view_policy = $request->getStr('viewPolicy');
|
Events should offer Spaces as the view policy options
Summary: Ref T8687, Events should offer Spaces as the view policy options
Test Plan: Create event, choose default Space, save, edit, choose different Space, save, new policy should be reflected on Event.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley, Korvin
Maniphest Tasks: T8687
Differential Revision: https://secure.phabricator.com/D13459
2015-06-27 19:26:24 +02:00
|
|
|
$space = $request->getStr('spacePHID');
|
2015-05-29 02:27:25 +02:00
|
|
|
$is_recurring = $request->getStr('isRecurring') ? 1 : 0;
|
|
|
|
$frequency = $request->getStr('frequency');
|
2015-05-08 03:57:28 +02:00
|
|
|
$is_all_day = $request->getStr('isAllDay');
|
2015-05-19 22:09:28 +02:00
|
|
|
$icon = $request->getStr('icon');
|
2015-04-30 04:48:46 +02:00
|
|
|
|
2015-04-30 00:31:02 +02:00
|
|
|
$invitees = $request->getArr('invitees');
|
|
|
|
$new_invitees = $this->getNewInviteeList($invitees, $event);
|
2015-04-30 04:48:46 +02:00
|
|
|
$status_attending = PhabricatorCalendarEventInvitee::STATUS_ATTENDING;
|
2015-04-30 00:31:02 +02:00
|
|
|
if ($this->isCreate()) {
|
2015-05-24 20:22:33 +02:00
|
|
|
$status = idx($new_invitees, $viewer->getPHID());
|
2015-04-30 00:31:02 +02:00
|
|
|
if ($status) {
|
2015-05-24 20:22:33 +02:00
|
|
|
$new_invitees[$viewer->getPHID()] = $status_attending;
|
2015-04-30 00:31:02 +02:00
|
|
|
}
|
|
|
|
}
|
2012-10-24 22:22:24 +02:00
|
|
|
|
2015-05-02 01:07:57 +02:00
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_NAME)
|
|
|
|
->setNewValue($name);
|
|
|
|
|
2015-06-15 20:52:57 +02:00
|
|
|
if ($is_recurring && $this->isCreate()) {
|
2015-06-01 05:45:51 +02:00
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_RECURRING)
|
|
|
|
->setNewValue($is_recurring);
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_FREQUENCY)
|
|
|
|
->setNewValue(array('rule' => $frequency));
|
2015-06-02 03:56:11 +02:00
|
|
|
|
2015-06-08 20:58:45 +02:00
|
|
|
if (!$recurrence_end_date_value->isDisabled()) {
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE)
|
|
|
|
->setNewValue($recurrence_end_date_value);
|
|
|
|
}
|
2015-06-01 05:45:51 +02:00
|
|
|
}
|
2015-05-29 02:27:25 +02:00
|
|
|
|
2015-06-15 20:52:57 +02:00
|
|
|
if (($is_recurring && $this->isCreate()) || !$is_parent) {
|
2015-06-10 02:22:08 +02:00
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_ALL_DAY)
|
|
|
|
->setNewValue($is_all_day);
|
2015-05-08 03:57:28 +02:00
|
|
|
|
2015-06-10 02:22:08 +02:00
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_ICON)
|
|
|
|
->setNewValue($icon);
|
2015-05-19 22:09:28 +02:00
|
|
|
|
2015-06-10 02:22:08 +02:00
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_START_DATE)
|
|
|
|
->setNewValue($start_value);
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_END_DATE)
|
|
|
|
->setNewValue($end_value);
|
|
|
|
}
|
2015-05-02 01:07:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorTransactions::TYPE_SUBSCRIBERS)
|
|
|
|
->setNewValue(array('=' => array_fuse($subscribers)));
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_INVITE)
|
|
|
|
->setNewValue($new_invitees);
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(
|
|
|
|
PhabricatorCalendarEventTransaction::TYPE_DESCRIPTION)
|
|
|
|
->setNewValue($description);
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
|
|
|
->setNewValue($request->getStr('viewPolicy'));
|
|
|
|
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
|
|
|
|
->setNewValue($request->getStr('editPolicy'));
|
|
|
|
|
Events should offer Spaces as the view policy options
Summary: Ref T8687, Events should offer Spaces as the view policy options
Test Plan: Create event, choose default Space, save, edit, choose different Space, save, new policy should be reflected on Event.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley, Korvin
Maniphest Tasks: T8687
Differential Revision: https://secure.phabricator.com/D13459
2015-06-27 19:26:24 +02:00
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
|
|
|
|
->setNewValue($space);
|
|
|
|
|
2015-05-02 01:07:57 +02:00
|
|
|
$editor = id(new PhabricatorCalendarEventEditor())
|
2015-05-24 20:22:33 +02:00
|
|
|
->setActor($viewer)
|
2015-05-02 01:07:57 +02:00
|
|
|
->setContentSourceFromRequest($request)
|
|
|
|
->setContinueOnNoEffect(true);
|
|
|
|
|
|
|
|
try {
|
2015-06-22 22:27:37 +02:00
|
|
|
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
|
|
|
$xactions[] = id(new PhabricatorCalendarEventTransaction())
|
|
|
|
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
|
|
|
->setMetadataValue('edge:type', $proj_edge_type)
|
|
|
|
->setNewValue(array('=' => array_fuse($projects)));
|
|
|
|
|
2015-05-02 01:07:57 +02:00
|
|
|
$xactions = $editor->applyTransactions($event, $xactions);
|
|
|
|
$response = id(new AphrontRedirectResponse());
|
2015-05-24 20:22:33 +02:00
|
|
|
switch ($next_workflow) {
|
|
|
|
case 'day':
|
|
|
|
if (!$uri_query) {
|
|
|
|
$uri_query = 'month';
|
|
|
|
}
|
|
|
|
$year = $start_value->getDateTime()->format('Y');
|
|
|
|
$month = $start_value->getDateTime()->format('m');
|
|
|
|
$day = $start_value->getDateTime()->format('d');
|
|
|
|
$response->setURI(
|
|
|
|
'/calendar/query/'.$uri_query.'/'.$year.'/'.$month.'/'.$day.'/');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
$response->setURI('/E'.$event->getID());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return $response;
|
2015-05-02 01:07:57 +02:00
|
|
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
|
|
|
$validation_exception = $ex;
|
|
|
|
$error_name = $ex->getShortMessage(
|
2015-07-07 14:52:59 +02:00
|
|
|
PhabricatorCalendarEventTransaction::TYPE_NAME);
|
2015-05-02 01:07:57 +02:00
|
|
|
$error_start_date = $ex->getShortMessage(
|
2015-07-07 14:52:59 +02:00
|
|
|
PhabricatorCalendarEventTransaction::TYPE_START_DATE);
|
2015-05-02 01:07:57 +02:00
|
|
|
$error_end_date = $ex->getShortMessage(
|
2015-07-07 14:52:59 +02:00
|
|
|
PhabricatorCalendarEventTransaction::TYPE_END_DATE);
|
2015-06-02 03:56:11 +02:00
|
|
|
$error_recurrence_end_date = $ex->getShortMessage(
|
2015-07-07 14:52:59 +02:00
|
|
|
PhabricatorCalendarEventTransaction::TYPE_RECURRENCE_END_DATE);
|
2012-10-24 22:22:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-01 05:45:51 +02:00
|
|
|
$is_recurring_checkbox = null;
|
2015-06-02 03:56:11 +02:00
|
|
|
$recurrence_end_date_control = null;
|
2015-06-01 05:45:51 +02:00
|
|
|
$recurrence_frequency_select = null;
|
|
|
|
|
2015-06-10 02:22:08 +02:00
|
|
|
$all_day_checkbox = null;
|
|
|
|
$start_control = null;
|
|
|
|
$end_control = null;
|
|
|
|
|
|
|
|
$recurring_date_edit_label = null;
|
|
|
|
|
2015-06-26 19:41:26 +02:00
|
|
|
$current_policies = id(new PhabricatorPolicyQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->setObject($event)
|
|
|
|
->execute();
|
|
|
|
|
2015-04-28 17:34:26 +02:00
|
|
|
$name = id(new AphrontFormTextControl())
|
|
|
|
->setLabel(pht('Name'))
|
|
|
|
->setName('name')
|
2015-05-01 18:11:51 +02:00
|
|
|
->setValue($name)
|
2015-04-28 17:34:26 +02:00
|
|
|
->setError($error_name);
|
|
|
|
|
2015-06-01 05:45:51 +02:00
|
|
|
if ($this->isCreate()) {
|
|
|
|
Javelin::initBehavior('recurring-edit', array(
|
|
|
|
'isRecurring' => $is_recurring_id,
|
|
|
|
'frequency' => $frequency_id,
|
2015-06-02 03:56:11 +02:00
|
|
|
'recurrenceEndDate' => $recurrence_end_date_id,
|
2015-06-01 05:45:51 +02:00
|
|
|
));
|
|
|
|
|
|
|
|
$is_recurring_checkbox = id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'isRecurring',
|
|
|
|
1,
|
|
|
|
pht('Recurring Event'),
|
|
|
|
$is_recurring,
|
|
|
|
$is_recurring_id);
|
|
|
|
|
2015-06-02 03:56:11 +02:00
|
|
|
$recurrence_end_date_control = id(new AphrontFormDateControl())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setName('recurrenceEndDate')
|
|
|
|
->setLabel(pht('Recurrence End Date'))
|
|
|
|
->setError($error_recurrence_end_date)
|
|
|
|
->setValue($recurrence_end_date_value)
|
|
|
|
->setID($recurrence_end_date_id)
|
|
|
|
->setIsTimeDisabled(true)
|
2015-06-10 02:22:08 +02:00
|
|
|
->setIsDisabled($recurrence_end_date_value->isDisabled())
|
2015-06-11 00:37:29 +02:00
|
|
|
->setAllowNull(true);
|
2015-06-02 03:56:11 +02:00
|
|
|
|
2015-06-01 05:45:51 +02:00
|
|
|
$recurrence_frequency_select = id(new AphrontFormSelectControl())
|
|
|
|
->setName('frequency')
|
|
|
|
->setOptions(array(
|
2015-06-20 18:45:37 +02:00
|
|
|
PhabricatorCalendarEvent::FREQUENCY_DAILY => pht('Daily'),
|
|
|
|
PhabricatorCalendarEvent::FREQUENCY_WEEKLY => pht('Weekly'),
|
|
|
|
PhabricatorCalendarEvent::FREQUENCY_MONTHLY => pht('Monthly'),
|
|
|
|
PhabricatorCalendarEvent::FREQUENCY_YEARLY => pht('Yearly'),
|
2015-06-01 05:45:51 +02:00
|
|
|
))
|
|
|
|
->setValue($frequency)
|
|
|
|
->setLabel(pht('Recurring Event Frequency'))
|
|
|
|
->setID($frequency_id)
|
|
|
|
->setDisabled(!$is_recurring);
|
|
|
|
}
|
2015-05-29 02:27:25 +02:00
|
|
|
|
2015-06-10 02:22:08 +02:00
|
|
|
if ($this->isCreate() || (!$is_parent && !$this->isCreate())) {
|
|
|
|
Javelin::initBehavior('event-all-day', array(
|
|
|
|
'allDayID' => $all_day_id,
|
|
|
|
'startDateID' => $start_date_id,
|
|
|
|
'endDateID' => $end_date_id,
|
|
|
|
));
|
|
|
|
|
|
|
|
$all_day_checkbox = id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'isAllDay',
|
|
|
|
1,
|
|
|
|
pht('All Day Event'),
|
|
|
|
$is_all_day,
|
|
|
|
$all_day_id);
|
|
|
|
|
|
|
|
$start_control = id(new AphrontFormDateControl())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setName('start')
|
|
|
|
->setLabel(pht('Start'))
|
|
|
|
->setError($error_start_date)
|
|
|
|
->setValue($start_value)
|
|
|
|
->setID($start_date_id)
|
|
|
|
->setIsTimeDisabled($is_all_day)
|
|
|
|
->setEndDateID($end_date_id);
|
|
|
|
|
|
|
|
$end_control = id(new AphrontFormDateControl())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setName('end')
|
|
|
|
->setLabel(pht('End'))
|
|
|
|
->setError($error_end_date)
|
|
|
|
->setValue($end_value)
|
|
|
|
->setID($end_date_id)
|
|
|
|
->setIsTimeDisabled($is_all_day);
|
|
|
|
} else if ($is_parent) {
|
|
|
|
$recurring_date_edit_label = id(new AphrontFormStaticControl())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setValue(pht('Date and time of recurring event cannot be edited.'));
|
|
|
|
|
|
|
|
if (!$recurrence_end_date_value->isDisabled()) {
|
|
|
|
$disabled_recurrence_end_date_value =
|
|
|
|
$recurrence_end_date_value->getValueAsFormat('M d, Y');
|
|
|
|
$recurrence_end_date_control = id(new AphrontFormStaticControl())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setLabel(pht('Recurrence End Date'))
|
|
|
|
->setValue($disabled_recurrence_end_date_value)
|
|
|
|
->setDisabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
$recurrence_frequency_select = id(new AphrontFormSelectControl())
|
|
|
|
->setName('frequency')
|
|
|
|
->setOptions(array(
|
2015-07-07 14:52:59 +02:00
|
|
|
'daily' => pht('Daily'),
|
|
|
|
'weekly' => pht('Weekly'),
|
|
|
|
'monthly' => pht('Monthly'),
|
|
|
|
'yearly' => pht('Yearly'),
|
|
|
|
))
|
2015-06-10 02:22:08 +02:00
|
|
|
->setValue($frequency)
|
|
|
|
->setLabel(pht('Recurring Event Frequency'))
|
|
|
|
->setID($frequency_id)
|
|
|
|
->setDisabled(true);
|
|
|
|
|
|
|
|
$all_day_checkbox = id(new AphrontFormCheckboxControl())
|
|
|
|
->addCheckbox(
|
|
|
|
'isAllDay',
|
|
|
|
1,
|
|
|
|
pht('All Day Event'),
|
|
|
|
$is_all_day,
|
|
|
|
$all_day_id)
|
|
|
|
->setDisabled(true);
|
|
|
|
|
|
|
|
$start_disabled = $start_value->getValueAsFormat('M d, Y, g:i A');
|
|
|
|
$end_disabled = $end_value->getValueAsFormat('M d, Y, g:i A');
|
|
|
|
|
|
|
|
$start_control = id(new AphrontFormStaticControl())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setLabel(pht('Start'))
|
|
|
|
->setValue($start_disabled)
|
|
|
|
->setDisabled(true);
|
|
|
|
|
|
|
|
$end_control = id(new AphrontFormStaticControl())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setLabel(pht('End'))
|
|
|
|
->setValue($end_disabled);
|
|
|
|
}
|
2015-05-02 01:07:57 +02:00
|
|
|
|
2015-06-22 22:27:37 +02:00
|
|
|
$projects = id(new AphrontFormTokenizerControl())
|
Consistently refer to 'Projects' as 'Tags'
Summary:
In calendar, dashboard, diffusion, diviner, feed, fund,
maniphest, pholio, ponder, and slowvote use the term 'tags' if possible.
This intenctionally skips diffusion, differential, and the projects application itself.
Ref T10326 Ref T10349
Test Plan: inspection on a running, locally modified, system
Reviewers: avivey, epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin
Maniphest Tasks: T10835, T10326, T10349
Differential Revision: https://secure.phabricator.com/D15753
2016-04-19 18:48:21 +02:00
|
|
|
->setLabel(pht('Tags'))
|
2015-06-22 22:27:37 +02:00
|
|
|
->setName('projects')
|
|
|
|
->setValue($projects)
|
|
|
|
->setUser($viewer)
|
|
|
|
->setDatasource(new PhabricatorProjectDatasource());
|
|
|
|
|
2015-06-19 17:32:50 +02:00
|
|
|
$description = id(new PhabricatorRemarkupControl())
|
2012-10-24 22:22:24 +02:00
|
|
|
->setLabel(pht('Description'))
|
|
|
|
->setName('description')
|
2015-06-19 17:32:50 +02:00
|
|
|
->setValue($description)
|
|
|
|
->setUser($viewer);
|
2013-05-29 23:35:34 +02:00
|
|
|
|
2015-04-30 23:43:48 +02:00
|
|
|
$view_policies = id(new AphrontFormPolicyControl())
|
2015-05-24 20:22:33 +02:00
|
|
|
->setUser($viewer)
|
2015-06-26 19:41:26 +02:00
|
|
|
->setValue($view_policy)
|
2015-04-30 23:43:48 +02:00
|
|
|
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
|
|
|
->setPolicyObject($event)
|
|
|
|
->setPolicies($current_policies)
|
Events should offer Spaces as the view policy options
Summary: Ref T8687, Events should offer Spaces as the view policy options
Test Plan: Create event, choose default Space, save, edit, choose different Space, save, new policy should be reflected on Event.
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: epriestley, Korvin
Maniphest Tasks: T8687
Differential Revision: https://secure.phabricator.com/D13459
2015-06-27 19:26:24 +02:00
|
|
|
->setSpacePHID($space)
|
2015-04-30 23:43:48 +02:00
|
|
|
->setName('viewPolicy');
|
|
|
|
$edit_policies = id(new AphrontFormPolicyControl())
|
2015-05-24 20:22:33 +02:00
|
|
|
->setUser($viewer)
|
2015-06-26 19:41:26 +02:00
|
|
|
->setValue($edit_policy)
|
2015-04-30 23:43:48 +02:00
|
|
|
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
|
|
|
->setPolicyObject($event)
|
|
|
|
->setPolicies($current_policies)
|
|
|
|
->setName('editPolicy');
|
|
|
|
|
2015-04-28 19:40:35 +02:00
|
|
|
$subscribers = id(new AphrontFormTokenizerControl())
|
|
|
|
->setLabel(pht('Subscribers'))
|
|
|
|
->setName('subscribers')
|
|
|
|
->setValue($subscribers)
|
2015-05-24 20:22:33 +02:00
|
|
|
->setUser($viewer)
|
2015-04-28 19:40:35 +02:00
|
|
|
->setDatasource(new PhabricatorMetaMTAMailableDatasource());
|
|
|
|
|
2015-04-30 00:31:02 +02:00
|
|
|
$invitees = id(new AphrontFormTokenizerControl())
|
|
|
|
->setLabel(pht('Invitees'))
|
|
|
|
->setName('invitees')
|
|
|
|
->setValue($invitees)
|
2015-05-24 20:22:33 +02:00
|
|
|
->setUser($viewer)
|
2015-04-30 00:31:02 +02:00
|
|
|
->setDatasource(new PhabricatorMetaMTAMailableDatasource());
|
|
|
|
|
2015-12-16 16:53:13 +01:00
|
|
|
|
|
|
|
$icon = id(new PHUIFormIconSetControl())
|
2015-05-19 22:09:28 +02:00
|
|
|
->setLabel(pht('Icon'))
|
|
|
|
->setName('icon')
|
2015-12-16 16:53:13 +01:00
|
|
|
->setIconSet(new PhabricatorCalendarIconSet())
|
2015-05-19 22:09:28 +02:00
|
|
|
->setValue($icon);
|
|
|
|
|
2015-04-28 17:34:26 +02:00
|
|
|
$form = id(new AphrontFormView())
|
2015-05-24 20:22:33 +02:00
|
|
|
->addHiddenInput('next', $next_workflow)
|
|
|
|
->addHiddenInput('query', $uri_query)
|
|
|
|
->setUser($viewer)
|
2015-06-01 05:45:51 +02:00
|
|
|
->appendChild($name);
|
|
|
|
|
2015-06-10 02:22:08 +02:00
|
|
|
if ($recurring_date_edit_label) {
|
|
|
|
$form->appendControl($recurring_date_edit_label);
|
|
|
|
}
|
2015-06-01 05:45:51 +02:00
|
|
|
if ($is_recurring_checkbox) {
|
|
|
|
$form->appendChild($is_recurring_checkbox);
|
|
|
|
}
|
2015-06-02 03:56:11 +02:00
|
|
|
if ($recurrence_end_date_control) {
|
|
|
|
$form->appendChild($recurrence_end_date_control);
|
|
|
|
}
|
2015-06-01 05:45:51 +02:00
|
|
|
if ($recurrence_frequency_select) {
|
|
|
|
$form->appendControl($recurrence_frequency_select);
|
|
|
|
}
|
|
|
|
|
|
|
|
$form
|
2015-05-08 19:01:13 +02:00
|
|
|
->appendChild($all_day_checkbox)
|
2015-05-02 01:07:57 +02:00
|
|
|
->appendChild($start_control)
|
|
|
|
->appendChild($end_control)
|
2015-04-30 23:43:48 +02:00
|
|
|
->appendControl($view_policies)
|
|
|
|
->appendControl($edit_policies)
|
2015-04-28 19:40:35 +02:00
|
|
|
->appendControl($subscribers)
|
2015-04-30 00:31:02 +02:00
|
|
|
->appendControl($invitees)
|
2015-06-22 22:27:37 +02:00
|
|
|
->appendChild($projects)
|
2015-05-19 22:09:28 +02:00
|
|
|
->appendChild($description)
|
|
|
|
->appendChild($icon);
|
2012-10-24 22:22:24 +02:00
|
|
|
|
2015-05-01 02:09:45 +02:00
|
|
|
|
|
|
|
if ($request->isAjax()) {
|
|
|
|
return $this->newDialog()
|
2016-04-01 22:40:29 +02:00
|
|
|
->setTitle($title)
|
2015-05-01 02:09:45 +02:00
|
|
|
->setWidth(AphrontDialogView::WIDTH_FULL)
|
|
|
|
->appendForm($form)
|
|
|
|
->addCancelButton($cancel_uri)
|
|
|
|
->addSubmitButton($submit_label);
|
|
|
|
}
|
|
|
|
|
2015-04-28 17:34:26 +02:00
|
|
|
$submit = id(new AphrontFormSubmitControl())
|
2015-05-01 02:09:45 +02:00
|
|
|
->addCancelButton($cancel_uri)
|
2015-04-28 17:34:26 +02:00
|
|
|
->setValue($submit_label);
|
2013-05-29 23:35:34 +02:00
|
|
|
|
2012-10-24 22:22:24 +02:00
|
|
|
$form->appendChild($submit);
|
|
|
|
|
2013-09-25 20:23:29 +02:00
|
|
|
$form_box = id(new PHUIObjectBoxView())
|
2016-04-01 22:40:29 +02:00
|
|
|
->setHeaderText(pht('Event'))
|
|
|
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
|
|
|
->setValidationException($validation_exception)
|
2013-08-26 20:53:11 +02:00
|
|
|
->setForm($form);
|
|
|
|
|
2015-04-27 23:27:00 +02:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
|
|
|
|
if (!$this->isCreate()) {
|
2015-04-28 17:34:26 +02:00
|
|
|
$crumbs->addTextCrumb('E'.$event->getId(), '/E'.$event->getId());
|
2016-04-01 22:40:29 +02:00
|
|
|
$crumb_title = pht('Edit Event');
|
|
|
|
} else {
|
|
|
|
$crumb_title = pht('Create Event');
|
2015-04-27 23:27:00 +02:00
|
|
|
}
|
|
|
|
|
2016-04-01 22:40:29 +02:00
|
|
|
$crumbs->addTextCrumb($crumb_title);
|
|
|
|
$crumbs->setBorder(true);
|
2014-02-18 01:08:50 +01:00
|
|
|
|
2016-04-01 22:40:29 +02:00
|
|
|
$header = id(new PHUIHeaderView())
|
|
|
|
->setHeader($title)
|
|
|
|
->setHeaderIcon($header_icon);
|
|
|
|
|
|
|
|
$view = id(new PHUITwoColumnView())
|
|
|
|
->setHeader($header)
|
|
|
|
->setFooter($form_box);
|
|
|
|
|
|
|
|
return $this->newPage()
|
|
|
|
->setTitle($title)
|
|
|
|
->setCrumbs($crumbs)
|
|
|
|
->appendChild($view);
|
2012-10-24 22:22:24 +02:00
|
|
|
}
|
|
|
|
|
2015-04-30 00:31:02 +02:00
|
|
|
|
|
|
|
public function getNewInviteeList(array $phids, $event) {
|
|
|
|
$invitees = $event->getInvitees();
|
|
|
|
$invitees = mpull($invitees, null, 'getInviteePHID');
|
|
|
|
$invited_status = PhabricatorCalendarEventInvitee::STATUS_INVITED;
|
|
|
|
$uninvited_status = PhabricatorCalendarEventInvitee::STATUS_UNINVITED;
|
|
|
|
$phids = array_fuse($phids);
|
|
|
|
|
|
|
|
$new = array();
|
|
|
|
foreach ($phids as $phid) {
|
2015-04-30 04:48:46 +02:00
|
|
|
$old_status = $event->getUserInviteStatus($phid);
|
|
|
|
if ($old_status != $uninvited_status) {
|
|
|
|
continue;
|
2015-04-30 00:31:02 +02:00
|
|
|
}
|
|
|
|
$new[$phid] = $invited_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($invitees as $invitee) {
|
|
|
|
$deleted_invitee = !idx($phids, $invitee->getInviteePHID());
|
|
|
|
if ($deleted_invitee) {
|
|
|
|
$new[$invitee->getInviteePHID()] = $uninvited_status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $new;
|
|
|
|
}
|
|
|
|
|
2015-05-24 20:22:33 +02:00
|
|
|
private function getDefaultTimeValues($viewer) {
|
2015-05-20 19:59:41 +02:00
|
|
|
$start = new DateTime('@'.time());
|
2015-05-24 20:22:33 +02:00
|
|
|
$start->setTimeZone($viewer->getTimeZone());
|
2015-05-20 19:59:41 +02:00
|
|
|
|
|
|
|
$start->setTime($start->format('H'), 0, 0);
|
|
|
|
$start->modify('+1 hour');
|
|
|
|
$end = id(clone $start)->modify('+1 hour');
|
|
|
|
|
|
|
|
$start_value = AphrontFormDateControlValue::newFromEpoch(
|
2015-05-24 20:22:33 +02:00
|
|
|
$viewer,
|
2015-05-20 19:59:41 +02:00
|
|
|
$start->format('U'));
|
|
|
|
$end_value = AphrontFormDateControlValue::newFromEpoch(
|
2015-05-24 20:22:33 +02:00
|
|
|
$viewer,
|
2015-05-20 19:59:41 +02:00
|
|
|
$end->format('U'));
|
|
|
|
|
|
|
|
return array($start_value, $end_value);
|
|
|
|
}
|
|
|
|
|
2012-10-24 22:22:24 +02:00
|
|
|
}
|