public function __construct(PhabricatorCustomField $field) { $key = $field->getFieldKey(); $name = $field->getFieldName(); $class = get_class($field); parent::__construct("Custom field '{$name}' (with key '{$key}', of class '{$class}') can " . "not have a proxy set with setProxy(), because it returned false from " . "canSetProxy()."); }
public function __construct(PhabricatorCustomField $field) { $key = $field->getFieldKey(); $name = $field->getFieldName(); $class = get_class($field); parent::__construct("Custom field '{$name}' (with key '{$key}', of class '{$class}') is " . "attempting to access data which is not available in this context."); }
public function setCustomField(PhabricatorCustomField $field) { $this->customField = $field; $this->setKey('custom:' . $field->getFieldIndex()); $aliases = array(); $aliases[] = $field->getFieldKey(); $this->setAliases($aliases); return $this; }
public function __construct(PhabricatorCustomField $field, $field_key_is_incomplete = false) { if ($field_key_is_incomplete) { $key = pht('<incomplete key>'); $name = pht('<incomplete name>'); } else { $key = $field->getFieldKey(); $name = $field->getFieldName(); } parent::__construct(pht("Custom field '%s' (with key '%s', of class '%s') is incompletely " . "implemented: it claims to support a feature, but does not " . "implement all of the required methods for that feature.", $name, $key, get_class($field))); }
public function addField(PhabricatorCustomField $field) { $role_storage = PhabricatorCustomField::ROLE_STORAGE; if (!$field->shouldEnableForRole($role_storage)) { return $this; } $storage = $field->newStorageObject(); $source_key = $storage->getStorageSourceKey(); $this->fieldMap[$source_key][] = $field; if (empty($this->storageSources[$source_key])) { $this->storageSources[$source_key] = $storage; } return $this; }
public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $id = $request->getURIData('id'); $step = id(new HarbormasterBuildStepQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(); if (!$step) { return new Aphront404Response(); } $plan = $step->getBuildPlan(); $plan_id = $plan->getID(); $plan_uri = $this->getApplicationURI("plan/{$plan_id}/"); $field_list = PhabricatorCustomField::getObjectFields($step, PhabricatorCustomField::ROLE_VIEW); $field_list->setViewer($viewer)->readFieldsFromStorage($step); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Plan %d', $plan_id), $plan_uri); $crumbs->addTextCrumb(pht('Step %d', $id)); $crumbs->setBorder(true); $header = id(new PHUIHeaderView())->setHeader(pht('Build Step %d: %s', $id, $step->getName()))->setHeaderIcon('fa-chevron-circle-right'); $properties = $this->buildPropertyList($step, $field_list); $curtain = $this->buildCurtainView($step); $timeline = $this->buildTransactionTimeline($step, new HarbormasterBuildStepTransactionQuery()); $timeline->setShouldTerminate(true); $view = id(new PHUITwoColumnView())->setHeader($header)->setCurtain($curtain)->setMainColumn(array($properties, $timeline)); return $this->newPage()->setTitle(pht('Step %d', $id))->setCrumbs($crumbs)->appendChild($view); }
function buildSetFieldTransaction($object, $field_key, $field_value, $template, $viewer) { $role = PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS; $fields = PhabricatorCustomField::getObjectFields($object, $role)->setViewer($viewer)->readFieldsFromStorage($object)->getFields(); $field = idx($fields, $field_key); $transaction_type = $field->getApplicationTransactionType(); $xaction = id(clone $template)->setTransactionType($transaction_type); if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { // For TYPE_CUSTOMFIELD transactions only, we provide the old value // as an input. $old_value = $field->getOldValueForApplicationTransactions(); $xaction->setOldValue($old_value); } $field->getProxy()->setFieldValue($field_value); $new_value = $field->getNewValueForApplicationTransactions(); $xaction->setNewValue($new_value); if ($transaction_type == PhabricatorTransactions::TYPE_CUSTOMFIELD) { // For TYPE_CUSTOMFIELD transactions, add the field key in metadata. $xaction->setMetadataValue('customfield:key', $field->getFieldKey()); } $metadata = $field->getApplicationTransactionMetadata(); foreach ($metadata as $key => $value) { $xaction->setMetadataValue($key, $value); } return $xaction; }
protected function execute(ConduitAPIRequest $request) { $viewer = $request->getUser(); $corpus = $request->getValue('corpus'); $is_partial = $request->getValue('partial'); $revision = new DifferentialRevision(); $field_list = PhabricatorCustomField::getObjectFields($revision, DifferentialCustomField::ROLE_COMMITMESSAGE); $field_list->setViewer($viewer); $field_map = mpull($field_list->getFields(), null, 'getFieldKeyForConduit'); $this->errors = array(); $label_map = $this->buildLabelMap($field_list); $corpus_map = $this->parseCommitMessage($corpus, $label_map); $values = array(); foreach ($corpus_map as $field_key => $text_value) { $field = idx($field_map, $field_key); if (!$field) { throw new Exception(pht('Parser emitted text value for field key "%s", but no such ' . 'field exists.', $field_key)); } try { $values[$field_key] = $field->parseValueFromCommitMessage($text_value); } catch (DifferentialFieldParseException $ex) { $this->errors[] = pht('Error parsing field "%s": %s', $field->renderCommitMessageLabel(), $ex->getMessage()); } } if (!$is_partial) { foreach ($field_map as $key => $field) { try { $field->validateCommitMessageValue(idx($values, $key)); } catch (DifferentialFieldValidationException $ex) { $this->errors[] = pht('Invalid or missing field "%s": %s', $field->renderCommitMessageLabel(), $ex->getMessage()); } } } return array('errors' => $this->errors, 'fields' => $values); }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $id = $request->getURIData('id'); $blueprint = id(new DrydockBlueprintQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(); if (!$blueprint) { return new Aphront404Response(); } $title = $blueprint->getBlueprintName(); $header = id(new PHUIHeaderView())->setHeader($title)->setUser($viewer)->setPolicyObject($blueprint); if ($blueprint->getIsDisabled()) { $header->setStatus('fa-ban', 'red', pht('Disabled')); } else { $header->setStatus('fa-check', 'bluegrey', pht('Active')); } $actions = $this->buildActionListView($blueprint); $properties = $this->buildPropertyListView($blueprint, $actions); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Blueprint %d', $blueprint->getID())); $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties); $field_list = PhabricatorCustomField::getObjectFields($blueprint, PhabricatorCustomField::ROLE_VIEW); $field_list->setViewer($viewer)->readFieldsFromStorage($blueprint); $field_list->appendFieldsToPropertyList($blueprint, $viewer, $properties); $resource_box = $this->buildResourceBox($blueprint); $authorizations_box = $this->buildAuthorizationsBox($blueprint); $timeline = $this->buildTransactionTimeline($blueprint, new DrydockBlueprintTransactionQuery()); $timeline->setShouldTerminate(true); $log_query = id(new DrydockLogQuery())->withBlueprintPHIDs(array($blueprint->getPHID())); $log_box = $this->buildLogBox($log_query, $this->getApplicationURI("blueprint/{$id}/logs/query/all/")); return $this->buildApplicationPage(array($crumbs, $object_box, $resource_box, $authorizations_box, $log_box, $timeline), array('title' => $title)); }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); // Load all projects with "Sprint" in the name. $projects = id(new PhabricatorProjectQuery())->setViewer($viewer)->withDatasourceQuery('sprint')->execute(); $rows = array(); foreach ($projects as $project) { // We need the custom fields so we can pull out the start and end date // TODO: query in a loop is bad $field_list = PhabricatorCustomField::getObjectFields($project, PhabricatorCustomField::ROLE_EDIT); $field_list->setViewer($viewer); $field_list->readFieldsFromStorage($project); $aux_fields = $field_list->getFields(); $start = idx($aux_fields, 'isdc:sprint:startdate')->getProxy()->getFieldValue(); $end = idx($aux_fields, 'isdc:sprint:enddate')->getProxy()->getFieldValue(); $rows[] = array('project' => phutil_tag('a', array('href' => '/burndown/view/' . $project->getId(), 'style' => 'font-weight:bold'), $project->getName()), 'start' => phabricator_datetime($start, $viewer), 'end' => phabricator_datetime($end, $viewer)); } $projects_table = id(new AphrontTableView($rows))->setHeaders(array('Project/Sprint name', 'Start Date', 'End Date'))->setColumnClasses(array('wide', 'date', 'date')); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Burndown List')); $help = id(new PHUIBoxView())->appendChild(phutil_tag('p', array(), "To have a project show up in this list, make sure it's name includes" . "\"sprint\" and then edit it to set the start and end date."))->addMargin(PHUI::MARGIN_LARGE); $box = id(new PHUIBoxView())->appendChild($projects_table)->addMargin(PHUI::MARGIN_LARGE); return $this->buildApplicationPage(array($crumbs, $help, $box), array('title' => array(pht('Burndown List')), 'device' => true)); }
public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $id = $request->getURIData('id'); $step = id(new HarbormasterBuildStepQuery())->setViewer($viewer)->withIDs(array($id))->executeOne(); if (!$step) { return new Aphront404Response(); } $plan = $step->getBuildPlan(); $plan_id = $plan->getID(); $plan_uri = $this->getApplicationURI("plan/{$plan_id}/"); $field_list = PhabricatorCustomField::getObjectFields($step, PhabricatorCustomField::ROLE_VIEW); $field_list->setViewer($viewer)->readFieldsFromStorage($step); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Plan %d', $plan_id), $plan_uri); $crumbs->addTextCrumb(pht('Step %d', $id)); $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Build Step %d: %s', $id, $step->getName())); $properties = $this->buildPropertyList($step, $field_list); $actions = $this->buildActionList($step); $properties->setActionList($actions); $box->addPropertyList($properties); $timeline = $this->buildTransactionTimeline($step, new HarbormasterBuildStepTransactionQuery()); $timeline->setShouldTerminate(true); return $this->buildApplicationPage(array($crumbs, $box, $timeline), array('title' => pht('Step %d', $id))); }
public function getCustomFieldList() { $field_list = PhabricatorCustomField::getObjectFields($this->project, PhabricatorCustomField::ROLE_EDIT); $field_list->setViewer($this->viewer); $field_list->readFieldsFromStorage($this->project); return $field_list; }
/** * @task apps */ public static function getObjectFields(PhabricatorCustomFieldInterface $object, $role) { try { $attachment = $object->getCustomFields(); } catch (PhabricatorDataNotAttachedException $ex) { $attachment = new PhabricatorCustomFieldAttachment(); $object->attachCustomFields($attachment); } try { $field_list = $attachment->getCustomFieldList($role); } catch (PhabricatorCustomFieldNotAttachedException $ex) { $base_class = $object->getCustomFieldBaseClass(); $spec = $object->getCustomFieldSpecificationForRole($role); if (!is_array($spec)) { $obj_class = get_class($object); throw new Exception("Expected an array from getCustomFieldSpecificationForRole() for " . "object of class '{$obj_class}'."); } $fields = PhabricatorCustomField::buildFieldList($base_class, $spec, $object); foreach ($fields as $key => $field) { if (!$field->shouldEnableForRole($role)) { unset($fields[$key]); } } foreach ($fields as $field) { $field->setObject($object); } $field_list = new PhabricatorCustomFieldList($fields); $attachment->addCustomFieldList($role, $field_list); } return $field_list; }
public function renderResultsList(array $requests, PhabricatorSavedQuery $query) { assert_instances_of($requests, 'ReleephRequest'); $viewer = $this->getRequest()->getUser(); // TODO: This is generally a bit sketchy, but we don't do this kind of // thing elsewhere at the moment. For the moment it shouldn't be hugely // costly, and we can batch things later. Generally, this commits fewer // sins than the old code did. $engine = id(new PhabricatorMarkupEngine())->setViewer($viewer); $list = array(); foreach ($requests as $pull) { $field_list = PhabricatorCustomField::getObjectFields($pull, PhabricatorCustomField::ROLE_VIEW); $field_list->setViewer($viewer)->readFieldsFromStorage($pull); foreach ($field_list->getFields() as $field) { if ($field->shouldMarkup()) { $field->setMarkupEngine($engine); } } $list[] = id(new ReleephRequestView())->setUser($viewer)->setCustomFields($field_list)->setPullRequest($pull)->setIsListView(true); } // This is quite sketchy, but the list has not actually rendered yet, so // this still allows us to batch the markup rendering. $engine->process(); return $list; }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $user = id(new PhabricatorPeopleQuery())->setViewer($viewer)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$user) { return new Aphront404Response(); } $profile_uri = '/p/' . $user->getUsername() . '/'; $field_list = PhabricatorCustomField::getObjectFields($user, PhabricatorCustomField::ROLE_EDIT); $field_list->setViewer($viewer)->readFieldsFromStorage($user); $validation_exception = null; if ($request->isFormPost()) { $xactions = $field_list->buildFieldTransactionsFromRequest(new PhabricatorUserTransaction(), $request); $editor = id(new PhabricatorUserProfileEditor())->setActor($viewer)->setContentSource(PhabricatorContentSource::newFromRequest($request))->setContinueOnNoEffect(true); try { $editor->applyTransactions($user, $xactions); return id(new AphrontRedirectResponse())->setURI($profile_uri); } catch (PhabricatorApplicationTransactionValidationException $ex) { $validation_exception = $ex; } } $title = pht('Edit Profile'); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($user->getUsername(), $profile_uri); $crumbs->addTextCrumb($title); $form = id(new AphrontFormView())->setUser($viewer); $field_list->appendFieldsToForm($form); $form->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($profile_uri)->setValue(pht('Save Profile'))); $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Edit Profile'))->setValidationException($validation_exception)->setForm($form); return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $title)); }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $blueprint = id(new DrydockBlueprintQuery())->setViewer($viewer)->withIDs(array($this->id))->executeOne(); if (!$blueprint) { return new Aphront404Response(); } $title = $blueprint->getBlueprintName(); $header = id(new PHUIHeaderView())->setHeader($title)->setUser($viewer)->setPolicyObject($blueprint); $actions = $this->buildActionListView($blueprint); $properties = $this->buildPropertyListView($blueprint, $actions); $blueprint_uri = 'blueprint/' . $blueprint->getID() . '/'; $blueprint_uri = $this->getApplicationURI($blueprint_uri); $resources = id(new DrydockResourceQuery())->withBlueprintPHIDs(array($blueprint->getPHID()))->setViewer($viewer)->execute(); $resource_list = id(new DrydockResourceListView())->setUser($viewer)->setResources($resources)->render(); $resource_list->setNoDataString(pht('This blueprint has no resources.')); $pager = new AphrontPagerView(); $pager->setURI(new PhutilURI($blueprint_uri), 'offset'); $pager->setOffset($request->getInt('offset')); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Blueprint %d', $blueprint->getID())); $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties); $field_list = PhabricatorCustomField::getObjectFields($blueprint, PhabricatorCustomField::ROLE_VIEW); $field_list->setViewer($viewer)->readFieldsFromStorage($blueprint); $field_list->appendFieldsToPropertyList($blueprint, $viewer, $properties); $timeline = $this->buildTransactionTimeline($blueprint, new DrydockBlueprintTransactionQuery()); $timeline->setShouldTerminate(true); return $this->buildApplicationPage(array($crumbs, $object_box, $resource_list, $timeline), array('title' => $title)); }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $request->validateCSRF(); $pull = id(new ReleephRequestQuery())->setViewer($viewer)->withIDs(array($this->requestID))->executeOne(); if (!$pull) { return new Aphront404Response(); } $branch = $pull->getBranch(); $product = $branch->getProduct(); $action = $this->action; $origin_uri = '/' . $pull->getMonogram(); $editor = id(new ReleephRequestTransactionalEditor())->setActor($viewer)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request); $xactions = array(); switch ($action) { case 'want': case 'pass': static $action_map = array('want' => ReleephRequest::INTENT_WANT, 'pass' => ReleephRequest::INTENT_PASS); $intent = $action_map[$action]; $xactions[] = id(new ReleephRequestTransaction())->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT)->setMetadataValue('isAuthoritative', $product->isAuthoritative($viewer))->setNewValue($intent); break; case 'mark-manually-picked': case 'mark-manually-reverted': if ($pull->getRequestUserPHID() === $viewer->getPHID() || $product->isAuthoritative($viewer)) { // We're all good! } else { throw new Exception(pht("Bug! Only pushers or the requestor can manually change a " . "request's in-branch status!")); } if ($action === 'mark-manually-picked') { $in_branch = 1; $intent = ReleephRequest::INTENT_WANT; } else { $in_branch = 0; $intent = ReleephRequest::INTENT_PASS; } $xactions[] = id(new ReleephRequestTransaction())->setTransactionType(ReleephRequestTransaction::TYPE_USER_INTENT)->setMetadataValue('isManual', true)->setMetadataValue('isAuthoritative', true)->setNewValue($intent); $xactions[] = id(new ReleephRequestTransaction())->setTransactionType(ReleephRequestTransaction::TYPE_MANUAL_IN_BRANCH)->setNewValue($in_branch); break; default: throw new Exception(pht('Unknown or unimplemented action %s.', $action)); } $editor->applyTransactions($pull, $xactions); if ($request->getBool('render')) { $field_list = PhabricatorCustomField::getObjectFields($pull, PhabricatorCustomField::ROLE_VIEW); $field_list->setViewer($viewer)->readFieldsFromStorage($pull); // TODO: This should be more modern and general. $engine = id(new PhabricatorMarkupEngine())->setViewer($viewer); foreach ($field_list->getFields() as $field) { if ($field->shouldMarkup()) { $field->setMarkupEngine($engine); } } $engine->process(); $pull_box = id(new ReleephRequestView())->setUser($viewer)->setCustomFields($field_list)->setPullRequest($pull)->setIsListView(true); return id(new AphrontAjaxResponse())->setContent(array('markup' => hsprintf('%s', $pull_box))); } return id(new AphrontRedirectResponse())->setURI($origin_uri); }
private function buildPropertyView(PhabricatorUser $user, PhabricatorActionListView $actions) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView())->setUser($viewer)->setObject($user)->setActionList($actions); $field_list = PhabricatorCustomField::getObjectFields($user, PhabricatorCustomField::ROLE_VIEW); $field_list->appendFieldsToPropertyList($user, $viewer, $view); return $view; }
protected function buildAlmanacPropertiesTable(AlmanacPropertyInterface $object) { $viewer = $this->getViewer(); $properties = $object->getAlmanacProperties(); $this->requireResource('almanac-css'); $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $object, PhabricatorPolicyCapability::CAN_EDIT); $field_list = PhabricatorCustomField::getObjectFields($object, PhabricatorCustomField::ROLE_DEFAULT); // Before reading values from the object, read defaults. $defaults = mpull($field_list->getFields(), 'getValueForStorage', 'getFieldKey'); $field_list->setViewer($viewer)->readFieldsFromStorage($object); Javelin::initBehavior('phabricator-tooltips', array()); $icon_builtin = id(new PHUIIconView())->setIcon('fa-circle')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Builtin Property'), 'align' => 'E')); $icon_custom = id(new PHUIIconView())->setIcon('fa-circle-o grey')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Custom Property'), 'align' => 'E')); $builtins = $object->getAlmanacPropertyFieldSpecifications(); // Sort fields so builtin fields appear first, then fields are ordered // alphabetically. $fields = $field_list->getFields(); $fields = msort($fields, 'getFieldKey'); $head = array(); $tail = array(); foreach ($fields as $field) { $key = $field->getFieldKey(); if (isset($builtins[$key])) { $head[$key] = $field; } else { $tail[$key] = $field; } } $fields = $head + $tail; $rows = array(); foreach ($fields as $key => $field) { $value = $field->getValueForStorage(); $is_builtin = isset($builtins[$key]); $delete_uri = $this->getApplicationURI('property/delete/'); $delete_uri = id(new PhutilURI($delete_uri))->setQueryParams(array('objectPHID' => $object->getPHID(), 'key' => $key)); $edit_uri = $this->getApplicationURI('property/edit/'); $edit_uri = id(new PhutilURI($edit_uri))->setQueryParams(array('objectPHID' => $object->getPHID(), 'key' => $key)); $delete = javelin_tag('a', array('class' => $can_edit ? 'button grey small' : 'button grey small disabled', 'sigil' => 'workflow', 'href' => $delete_uri), $is_builtin ? pht('Reset') : pht('Delete')); $default = idx($defaults, $key); $is_default = $default !== null && $default === $value; $display_value = PhabricatorConfigJSON::prettyPrintJSON($value); if ($is_default) { $display_value = phutil_tag('span', array('class' => 'almanac-default-property-value'), $display_value); } $display_key = $key; if ($can_edit) { $display_key = javelin_tag('a', array('href' => $edit_uri, 'sigil' => 'workflow'), $display_key); } $rows[] = array($is_builtin ? $icon_builtin : $icon_custom, $display_key, $display_value, $delete); } $table = id(new AphrontTableView($rows))->setNoDataString(pht('No properties.'))->setHeaders(array(null, pht('Name'), pht('Value'), null))->setColumnClasses(array(null, null, 'wide', 'action')); $phid = $object->getPHID(); $add_uri = $this->getApplicationURI("property/edit/?objectPHID={$phid}"); $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $object, PhabricatorPolicyCapability::CAN_EDIT); $add_button = id(new PHUIButtonView())->setTag('a')->setHref($add_uri)->setWorkflow(true)->setDisabled(!$can_edit)->setText(pht('Add Property'))->setIcon('fa-plus'); $header = id(new PHUIHeaderView())->setHeader(pht('Properties'))->addActionLink($add_button); return id(new PHUIObjectBoxView())->setHeader($header)->setTable($table); }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $object = id(new PhabricatorObjectQuery())->setViewer($viewer)->withPHIDs(array($request->getStr('objectPHID')))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$object) { return new Aphront404Response(); } if (!$object instanceof AlmanacPropertyInterface) { return new Aphront404Response(); } $key = $request->getStr('key'); if (!strlen($key)) { return new Aphront404Response(); } $cancel_uri = $object->getURI(); $builtins = $object->getAlmanacPropertyFieldSpecifications(); $is_builtin = isset($builtins[$key]); if ($is_builtin) { // This is a builtin property, so we're going to reset it to the // default value. $field_list = PhabricatorCustomField::getObjectFields($object, PhabricatorCustomField::ROLE_DEFAULT); // Note that we're NOT loading field values from the object: we just want // to get the field's default value so we can reset it. $fields = $field_list->getFields(); $field = $fields[$key]; $is_delete = false; $new_value = $field->getValueForStorage(); // Now, load the field to get the old value. $field_list->setViewer($viewer)->readFieldsFromStorage($object); $old_value = $field->getValueForStorage(); $title = pht('Reset Property'); $body = pht('Reset this property to its default value?'); $submit_text = pht('Reset'); } else { // This is a custom property, so we're going to delete it outright. $is_delete = true; $old_value = $object->getAlmanacPropertyValue($key); $new_value = null; $title = pht('Delete Property'); $body = pht('Delete this property? TODO: DOES NOT WORK YET'); $submit_text = pht('Delete'); } $validation_exception = null; if ($request->isFormPost()) { $xaction = $object->getApplicationTransactionTemplate()->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)->setMetadataValue('customfield:key', $key)->setOldValue($old_value)->setNewValue($new_value); // TODO: We aren't really deleting properties that we claim to delete // yet, but that needs to be specialized a little bit. $editor = $object->getApplicationTransactionEditor()->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setContinueOnMissingFields(true); try { $editor->applyTransactions($object, array($xaction)); return id(new AphrontRedirectResponse())->setURI($cancel_uri); } catch (PhabricatorApplicationTransactionValidationException $ex) { $validation_exception = $ex; } } return $this->newDialog()->setTitle($title)->setValidationException($validation_exception)->addHiddenInput('objectPHID', $object->getPHID())->addHiddenInput('key', $key)->appendParagraph($body)->addCancelButton($cancel_uri)->addSubmitButton($submit_text); }
private function loadCustomFields() { if ($this->fields === null) { $field_list = PhabricatorCustomField::getObjectFields($this, PhabricatorCustomField::ROLE_VIEW); $field_list->readFieldsFromStorage($this); $this->fields = $field_list->getFields(); } return $this->fields; }
private function buildPropertyListView(PhabricatorProject $project) { $viewer = $this->getViewer(); $view = id(new PHUIPropertyListView())->setUser($viewer); $view->addProperty(pht('Looks Like'), $viewer->renderHandle($project->getPHID())->setAsTag(true)); $field_list = PhabricatorCustomField::getObjectFields($project, PhabricatorCustomField::ROLE_VIEW); $field_list->appendFieldsToPropertyList($project, $viewer, $view); return $view; }
public function shouldEnableForRole($role) { switch ($role) { case self::ROLE_COMMITMESSAGE: return $this->shouldAppearInCommitMessage(); case self::ROLE_COMMITMESSAGEEDIT: return $this->shouldAppearInCommitMessage() && $this->shouldAllowEditInCommitMessage(); } return parent::shouldEnableForRole($role); }
public function runTask(PhabricatorUser $actor, PhabricatorWorkerBulkJob $job, PhabricatorWorkerBulkTask $task) { $object = id(new ManiphestTaskQuery())->setViewer($actor)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withPHIDs(array($task->getObjectPHID()))->needProjectPHIDs(true)->needSubscriberPHIDs(true)->executeOne(); if (!$object) { return; } $field_list = PhabricatorCustomField::getObjectFields($object, PhabricatorCustomField::ROLE_EDIT); $field_list->readFieldsFromStorage($object); $actions = $job->getParameter('actions'); $xactions = $this->buildTransactions($actions, $object); $editor = id(new ManiphestTransactionEditor())->setActor($actor)->setContentSource($job->newContentSource())->setContinueOnNoEffect(true)->setContinueOnMissingFields(true)->applyTransactions($object, $xactions); }
private function buildPropertyView(PhabricatorUser $user) { $viewer = $this->getRequest()->getUser(); $view = id(new PHUIPropertyListView())->setUser($viewer)->setObject($user); $field_list = PhabricatorCustomField::getObjectFields($user, PhabricatorCustomField::ROLE_VIEW); $field_list->appendFieldsToPropertyList($user, $viewer, $view); if (!$view->hasAnyProperties()) { return null; } $view = id(new PHUIObjectBoxView())->appendChild($view)->addClass('project-view-properties'); return $view; }
public function processRequest() { $this->requireApplicationCapability(ManiphestBulkEditCapability::CAPABILITY); $request = $this->getRequest(); $user = $request->getUser(); $task_ids = $request->getArr('batch'); $tasks = id(new ManiphestTaskQuery())->setViewer($user)->withIDs($task_ids)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute(); $actions = $request->getStr('actions'); if ($actions) { $actions = json_decode($actions, true); } if ($request->isFormPost() && is_array($actions)) { foreach ($tasks as $task) { $field_list = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_EDIT); $field_list->readFieldsFromStorage($task); $xactions = $this->buildTransactions($actions, $task); if ($xactions) { // TODO: Set content source to "batch edit". $editor = id(new ManiphestTransactionEditor())->setActor($user)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setContinueOnMissingFields(true)->applyTransactions($task, $xactions); } } $task_ids = implode(',', mpull($tasks, 'getID')); return id(new AphrontRedirectResponse())->setURI('/maniphest/?ids=' . $task_ids); } $handles = ManiphestTaskListView::loadTaskHandles($user, $tasks); $list = new ManiphestTaskListView(); $list->setTasks($tasks); $list->setUser($user); $list->setHandles($handles); $template = new AphrontTokenizerTemplateView(); $template = $template->render(); $projects_source = new PhabricatorProjectDatasource(); $mailable_source = new PhabricatorMetaMTAMailableDatasource(); $owner_source = new PhabricatorTypeaheadOwnerDatasource(); require_celerity_resource('maniphest-batch-editor'); Javelin::initBehavior('maniphest-batch-editor', array('root' => 'maniphest-batch-edit-form', 'tokenizerTemplate' => $template, 'sources' => array('project' => array('src' => $projects_source->getDatasourceURI(), 'placeholder' => $projects_source->getPlaceholderText()), 'owner' => array('src' => $owner_source->getDatasourceURI(), 'placeholder' => $owner_source->getPlaceholderText(), 'limit' => 1), 'cc' => array('src' => $mailable_source->getDatasourceURI(), 'placeholder' => $mailable_source->getPlaceholderText())), 'input' => 'batch-form-actions', 'priorityMap' => ManiphestTaskPriority::getTaskPriorityMap(), 'statusMap' => ManiphestTaskStatus::getTaskStatusMap())); $form = new AphrontFormView(); $form->setUser($user); $form->setID('maniphest-batch-edit-form'); foreach ($tasks as $task) { $form->appendChild(phutil_tag('input', array('type' => 'hidden', 'name' => 'batch[]', 'value' => $task->getID()))); } $form->appendChild(phutil_tag('input', array('type' => 'hidden', 'name' => 'actions', 'id' => 'batch-form-actions'))); $form->appendChild(phutil_tag('p', array(), pht('These tasks will be edited:'))); $form->appendChild($list); $form->appendChild(id(new AphrontFormInsetView())->setTitle('Actions')->setRightButton(javelin_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'add-action', 'mustcapture' => true), pht('Add Another Action')))->setContent(javelin_tag('table', array('sigil' => 'maniphest-batch-actions', 'class' => 'maniphest-batch-actions-table'), '')))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Update Tasks'))->addCancelButton('/maniphest/')); $title = pht('Batch Editor'); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($title); $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Batch Edit Tasks'))->setForm($form); return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $title, 'device' => false)); }
public function getFieldValuesForConduit($object) { // TODO: This is currently very inefficient. We should bulk-load these // field values instead. $fields = PhabricatorCustomField::getObjectFields($object, PhabricatorCustomField::ROLE_CONDUIT); $fields->setViewer($this->getViewer())->readFieldsFromStorage($object); $map = array(); foreach ($fields->getFields() as $field) { $key = $field->getModernFieldKey(); $map[$key] = $field->getConduitDictionaryValue(); } return $map; }
private function buildPropertyListView(PhabricatorProject $project) { $request = $this->getRequest(); $viewer = $request->getUser(); $view = id(new PHUIPropertyListView())->setUser($viewer)->setObject($project); $field_list = PhabricatorCustomField::getObjectFields($project, PhabricatorCustomField::ROLE_VIEW); $field_list->appendFieldsToPropertyList($project, $viewer, $view); if ($view->isEmpty()) { return null; } $view = id(new PHUIBoxView())->setColor(PHUIBoxView::GREY)->appendChild($view)->addClass('project-view-properties'); return $view; }
public function indexFulltextObject($object, PhabricatorSearchAbstractDocument $document) { // Rebuild the ApplicationSearch indexes. These are internal and not part // of the fulltext search, but putting them in this workflow allows users // to use the same tools to rebuild the indexes, which is easy to // understand. $field_list = PhabricatorCustomField::getObjectFields($object, PhabricatorCustomField::ROLE_DEFAULT); $field_list->setViewer($this->getViewer()); $field_list->readFieldsFromStorage($object); // Rebuild ApplicationSearch indexes. $field_list->rebuildIndexes($object); // Rebuild global search indexes. $field_list->updateAbstractDocument($document); }
/** * @phutil-external-symbol class PHPExcel * @phutil-external-symbol class PHPExcel_IOFactory * @phutil-external-symbol class PHPExcel_Style_NumberFormat * @phutil-external-symbol class PHPExcel_Cell_DataType */ public function buildWorkbook(PHPExcel $workbook, array $tasks, array $handles, PhabricatorUser $user) { $sheet = $workbook->setActiveSheetIndex(0); $sheet->setTitle(pht('Tasks')); $widths = array(null, 15, null, 10, 15, 15, 60, 30, 20, 100); foreach ($widths as $col => $width) { if ($width !== null) { $sheet->getColumnDimension($this->col($col))->setWidth($width); } } $status_map = ManiphestTaskStatus::getTaskStatusMap(); $pri_map = ManiphestTaskPriority::getTaskPriorityMap(); $date_format = null; $rows = array(); $rows[] = array(pht('ID'), pht('Owner'), pht('Status'), pht('Priority'), pht('Date Created'), pht('Date Updated'), pht('Deadline'), pht('Title'), pht('Projects'), pht('Description')); $is_date = array(false, false, false, false, true, true, true, false, false, false); $header_format = array('font' => array('bold' => true)); foreach ($tasks as $task) { $task_owner = null; if ($task->getOwnerPHID()) { $task_owner = $handles[$task->getOwnerPHID()]->getName(); } $projects = array(); foreach ($task->getProjectPHIDs() as $phid) { $projects[] = $handles[$phid]->getName(); } $projects = implode(', ', $projects); $custom_fields = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_VIEW); $custom_fields->setViewer($user)->readFieldsFromStorage($task); $fields = $custom_fields->getFields(); $rows[] = array('T' . $task->getID(), $task_owner, idx($status_map, $task->getStatus(), '?'), idx($pri_map, $task->getPriority(), '?'), $this->computeExcelDate($task->getDateCreated()), $this->computeExcelDate($task->getDateModified()), $this->computeExcelDate($fields['std:maniphest:Deadline']->getValueForStorage()), $task->getTitle(), $projects, id(new PhutilUTF8StringTruncator())->setMaximumBytes(512)->truncateString($task->getDescription())); } foreach ($rows as $row => $cols) { foreach ($cols as $col => $spec) { $cell_name = $this->col($col) . ($row + 1); $cell = $sheet->setCellValue($cell_name, $spec, $return_cell = true); if ($row == 0) { $sheet->getStyle($cell_name)->applyFromArray($header_format); } if ($is_date[$col]) { $code = PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2; $sheet->getStyle($cell_name)->getNumberFormat()->setFormatCode($code); } else { $cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING); } } } }