1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-24 06:20:56 +01:00

Move handle fetching into tokenizer Datasources

Summary:
Ref T7689. This serves two goals:

  - I want to remove Controller->loadViewerHandles(). A nontrivial number of these callsites are loading handles to pass to tokenizers. Since tokenizers need to take strings eventually anyway, we can do less work by letting them take PHIDs now.
  - A few changes out, I want tokenizers to accept parameterized tokens (like `viewer()`, `members(differential)`, etc.), so the `setValues()` signature needs to change eventually anyway.

I made this work and converted a handful of callsites as an example; upcoming changes will convert more.

Test Plan:
- Viewed Almanac binding editor; used "Interface".
- Edited Almanac services; used "Projects".
- Edited Almanac devices; used "Projects".
- Searched for commits; used "Auditors"; "Commit Authors", "Repositories".
- Searched for calendar events; used "Created By"; used "Invited".

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7689

Differential Revision: https://secure.phabricator.com/D12218
This commit is contained in:
epriestley 2015-03-31 14:10:32 -07:00
parent ba10e8ed41
commit 7711ea9855
7 changed files with 79 additions and 73 deletions

View file

@ -82,20 +82,15 @@ final class AlmanacBindingEditController
} }
} }
$interface_handles = array();
if ($v_interface) {
$interface_handles = $this->loadViewerHandles($v_interface);
}
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($viewer) ->setUser($viewer)
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setName('interfacePHIDs') ->setName('interfacePHIDs')
->setLabel('Interface') ->setLabel('Interface')
->setLimit(1) ->setLimit(1)
->setDatasource(new AlmanacInterfaceDatasource()) ->setDatasource(new AlmanacInterfaceDatasource())
->setValue($interface_handles) ->setValue($v_interface)
->setError($e_interface)) ->setError($e_interface))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())

View file

@ -107,12 +107,6 @@ final class AlmanacDeviceEditController
->setObject($device) ->setObject($device)
->execute(); ->execute();
if ($v_projects) {
$project_handles = $this->loadViewerHandles($v_projects);
} else {
$project_handles = array();
}
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($viewer) ->setUser($viewer)
->appendChild( ->appendChild(
@ -133,11 +127,11 @@ final class AlmanacDeviceEditController
->setPolicyObject($device) ->setPolicyObject($device)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT) ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies)) ->setPolicies($policies))
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setLabel(pht('Projects')) ->setLabel(pht('Projects'))
->setName('projects') ->setName('projects')
->setValue($project_handles) ->setValue($v_projects)
->setDatasource(new PhabricatorProjectDatasource())) ->setDatasource(new PhabricatorProjectDatasource()))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())

View file

@ -122,12 +122,6 @@ final class AlmanacServiceEditController
->setObject($service) ->setObject($service)
->execute(); ->execute();
if ($v_projects) {
$project_handles = $this->loadViewerHandles($v_projects);
} else {
$project_handles = array();
}
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($viewer) ->setUser($viewer)
->addHiddenInput('edit', true) ->addHiddenInput('edit', true)
@ -150,11 +144,11 @@ final class AlmanacServiceEditController
->setPolicyObject($service) ->setPolicyObject($service)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT) ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies)) ->setPolicies($policies))
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setLabel(pht('Projects')) ->setLabel(pht('Projects'))
->setName('projects') ->setName('projects')
->setValue($project_handles) ->setValue($v_projects)
->setDatasource(new PhabricatorProjectDatasource())) ->setDatasource(new PhabricatorProjectDatasource()))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())

View file

@ -82,43 +82,31 @@ final class PhabricatorCommitSearchEngine
$audit_status = $saved->getParameter('auditStatus', null); $audit_status = $saved->getParameter('auditStatus', null);
$repository_phids = $saved->getParameter('repositoryPHIDs', array()); $repository_phids = $saved->getParameter('repositoryPHIDs', array());
$phids = array_mergev(
array(
$auditor_phids,
$commit_author_phids,
$repository_phids,
));
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->requireViewer())
->withPHIDs($phids)
->execute();
$form $form
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setDatasource(new DiffusionAuditorDatasource()) ->setDatasource(new DiffusionAuditorDatasource())
->setName('auditorPHIDs') ->setName('auditorPHIDs')
->setLabel(pht('Auditors')) ->setLabel(pht('Auditors'))
->setValue(array_select_keys($handles, $auditor_phids))) ->setValue($auditor_phids))
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource()) ->setDatasource(new PhabricatorPeopleDatasource())
->setName('authors') ->setName('authors')
->setLabel(pht('Commit Authors')) ->setLabel(pht('Commit Authors'))
->setValue(array_select_keys($handles, $commit_author_phids))) ->setValue($commit_author_phids))
->appendChild( ->appendChild(
id(new AphrontFormSelectControl()) id(new AphrontFormSelectControl())
->setName('auditStatus') ->setName('auditStatus')
->setLabel(pht('Audit Status')) ->setLabel(pht('Audit Status'))
->setOptions($this->getAuditStatusOptions()) ->setOptions($this->getAuditStatusOptions())
->setValue($audit_status)) ->setValue($audit_status))
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setLabel(pht('Repositories')) ->setLabel(pht('Repositories'))
->setName('repositoryPHIDs') ->setName('repositoryPHIDs')
->setDatasource(new DiffusionRepositoryDatasource()) ->setDatasource(new DiffusionRepositoryDatasource())
->setValue(array_select_keys($handles, $repository_phids))); ->setValue($repository_phids));
} }

View file

@ -87,35 +87,19 @@ final class PhabricatorCalendarEventSearchEngine
$invited_phids = $saved->getParameter('invitedPHIDs', array()); $invited_phids = $saved->getParameter('invitedPHIDs', array());
$creator_phids = $saved->getParameter('creatorPHIDs', array()); $creator_phids = $saved->getParameter('creatorPHIDs', array());
$all_phids = array_merge(
$invited_phids,
$creator_phids);
if ($all_phids) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($this->requireViewer())
->withPHIDs($all_phids)
->execute();
} else {
$handles = array();
}
$invited_handles = array_select_keys($handles, $invited_phids);
$creator_handles = array_select_keys($handles, $creator_phids);
$form $form
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource()) ->setDatasource(new PhabricatorPeopleDatasource())
->setName('creators') ->setName('creators')
->setLabel(pht('Created By')) ->setLabel(pht('Created By'))
->setValue($creator_handles)) ->setValue($creator_phids))
->appendChild( ->appendControl(
id(new AphrontFormTokenizerControl()) id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorPeopleDatasource()) ->setDatasource(new PhabricatorPeopleDatasource())
->setName('invited') ->setName('invited')
->setLabel(pht('Invited')) ->setLabel(pht('Invited'))
->setValue($invited_handles)) ->setValue($invited_phids))
->appendChild( ->appendChild(
id(new AphrontFormDateControl()) id(new AphrontFormDateControl())
->setLabel(pht('Occurs After')) ->setLabel(pht('Occurs After'))

View file

@ -12,7 +12,7 @@ final class AphrontFormView extends AphrontView {
private $shaded = false; private $shaded = false;
private $sigils = array(); private $sigils = array();
private $metadata; private $metadata;
private $controls = array();
public function setMetadata($metadata) { public function setMetadata($metadata) {
$this->metadata = $metadata; $this->metadata = $metadata;
@ -87,9 +87,30 @@ final class AphrontFormView extends AphrontView {
->appendChild($this->renderChildren()); ->appendChild($this->renderChildren());
} }
/**
* Append a control to the form.
*
* This method behaves like @{method:appendChild}, but it only takes
* controls. It will propagate some information from the form to the
* control to simplify rendering.
*
* @param AphrontFormControl Control to append.
* @return this
*/
public function appendControl(AphrontFormControl $control) {
$this->controls[] = $control;
return $this->appendChild($control);
}
public function render() { public function render() {
require_celerity_resource('phui-form-view-css'); require_celerity_resource('phui-form-view-css');
foreach ($this->controls as $control) {
$control->setUser($this->getUser());
}
$layout = $this->buildLayoutView(); $layout = $this->buildLayoutView();
if (!$this->user) { if (!$this->user) {

View file

@ -35,7 +35,37 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
$name = $this->getName(); $name = $this->getName();
$values = nonempty($this->getValue(), array()); $values = nonempty($this->getValue(), array());
assert_instances_of($values, 'PhabricatorObjectHandle'); // Values may either be handles (which are now legacy/deprecated) or
// strings. Load handles for any PHIDs.
$load = array();
$handles = array();
$select = array();
foreach ($values as $value) {
if ($value instanceof PhabricatorObjectHandle) {
$handles[$value->getPHID()] = $value;
$select[] = $value->getPHID();
} else {
$load[] = $value;
$select[] = $value;
}
}
// TODO: Once this code path simplifies, move this prefetch to setValue()
// so we can bulk load across multiple controls.
if ($load) {
$viewer = $this->getUser();
if (!$viewer) {
// TODO: Clean this up when handles go away.
throw new Exception(
pht('Call setUser() before rendering tokenizer string values.'));
}
$loaded_handles = $viewer->loadHandles($load);
$handles = $handles + iterator_to_array($loaded_handles);
}
// Reorder the list into input order.
$handles = array_select_keys($handles, $select);
if ($this->getID()) { if ($this->getID()) {
$id = $this->getID(); $id = $this->getID();
@ -55,7 +85,7 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
$template = new AphrontTokenizerTemplateView(); $template = new AphrontTokenizerTemplateView();
$template->setName($name); $template->setName($name);
$template->setID($id); $template->setID($id);
$template->setValue($values); $template->setValue($handles);
$username = null; $username = null;
if ($this->user) { if ($this->user) {
@ -71,8 +101,8 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
Javelin::initBehavior('aphront-basic-tokenizer', array( Javelin::initBehavior('aphront-basic-tokenizer', array(
'id' => $id, 'id' => $id,
'src' => $datasource_uri, 'src' => $datasource_uri,
'value' => mpull($values, 'getFullName', 'getPHID'), 'value' => mpull($handles, 'getFullName', 'getPHID'),
'icons' => mpull($values, 'getIcon', 'getPHID'), 'icons' => mpull($handles, 'getIcon', 'getPHID'),
'limit' => $this->limit, 'limit' => $this->limit,
'username' => $username, 'username' => $username,
'placeholder' => $placeholder, 'placeholder' => $placeholder,