Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php b/src/applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php
index 6f3040e4df..a229fcb41c 100644
--- a/src/applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php
+++ b/src/applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php
@@ -1,195 +1,169 @@
<?php
final class PhabricatorDashboardQueryPanelInstallController
extends PhabricatorDashboardController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$v_dashboard = null;
- $v_name = null;
- $v_column = 0;
- $v_engine = $request->getURIData('engineKey');
- $v_query = $request->getURIData('queryKey');
+ $e_dashboard = null;
+ $v_name = null;
$e_name = true;
- // Validate Engines
- $engines = PhabricatorApplicationSearchEngine::getAllEngines();
- foreach ($engines as $name => $engine) {
- if (!$engine->canUseInPanelContext()) {
- unset($engines[$name]);
- }
- }
- if (!in_array($v_engine, array_keys($engines))) {
- return new Aphront404Response();
+ $v_engine = $request->getStr('engine');
+ if (!strlen($v_engine)) {
+ $v_engine = $request->getURIData('engineKey');
}
- // Validate Queries
- $engine = $engines[$v_engine];
- $engine->setViewer($viewer);
- $good_query = false;
- if ($engine->isBuiltinQuery($v_query)) {
- $good_query = true;
- } else {
- $saved_query = id(new PhabricatorSavedQueryQuery())
- ->setViewer($viewer)
- ->withEngineClassNames(array($v_engine))
- ->withQueryKeys(array($v_query))
- ->executeOne();
- if ($saved_query) {
- $good_query = true;
- }
- }
- if (!$good_query) {
- return new Aphront404Response();
+ $v_query = $request->getStr('query');
+ if (!strlen($v_query)) {
+ $v_query = $request->getURIData('queryKey');
}
- $named_query = idx($engine->loadEnabledNamedQueries(), $v_query);
- if ($named_query) {
- $v_name = $named_query->getQueryName();
+ $engines = PhabricatorApplicationSearchEngine::getAllEngines();
+ $engine = idx($engines, $v_engine);
+ if ($engine) {
+ $engine = id(clone $engine)
+ ->setViewer($viewer);
+
+ $redirect_uri = $engine->getQueryResultsPageURI($v_query);
+
+ $named_query = idx($engine->loadEnabledNamedQueries(), $v_query);
+ if ($named_query) {
+ $v_name = $named_query->getQueryName();
+ }
+ } else {
+ $redirect_uri = '/';
}
$errors = array();
+ $xaction_name = PhabricatorDashboardPanelNameTransaction::TRANSACTIONTYPE;
+ $xaction_engine =
+ PhabricatorDashboardQueryPanelApplicationTransaction::TRANSACTIONTYPE;
+ $xaction_query =
+ PhabricatorDashboardQueryPanelQueryTransaction::TRANSACTIONTYPE;
+
if ($request->isFormPost()) {
- $v_dashboard = $request->getInt('dashboardID');
$v_name = $request->getStr('name');
if (!$v_name) {
$errors[] = pht('You must provide a name for this panel.');
$e_name = pht('Required');
}
- $dashboard = id(new PhabricatorDashboardQuery())
- ->setViewer($viewer)
- ->withIDs(array($v_dashboard))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->executeOne();
-
- if (!$dashboard) {
- $errors[] = pht('Please select a valid dashboard.');
+ $v_dashboard = head($request->getArr('dashboardPHIDs'));
+ if (!$v_dashboard) {
+ $errors[] = pht('You must select a dashboard.');
+ $e_dashboard = pht('Required');
+ } else {
+ $dashboard = id(new PhabricatorDashboardQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($v_dashboard))
+ ->executeOne();
+ if (!$dashboard) {
+ $errors[] = pht('You must select a valid dashboard.');
+ $e_dashboard = pht('Invalid');
+ }
+
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $dashboard,
+ PhabricatorPolicyCapability::CAN_EDIT);
+ if (!$can_edit) {
+ $errors[] = pht(
+ 'You must select a dashboard you have permission to edit.');
+ }
}
if (!$errors) {
- $redirect_uri = "/dashboard/view/{$v_dashboard}/";
+ $done_uri = $dashboard->getURI();
+
+ // First, create a new panel.
$panel_type = id(new PhabricatorDashboardQueryPanelType())
->getPanelTypeKey();
- $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
- $panel->setPanelType($panel_type);
- $field_list = PhabricatorCustomField::getObjectFields(
- $panel,
- PhabricatorCustomField::ROLE_EDIT);
-
- $field_list
- ->setViewer($viewer)
- ->readFieldsFromStorage($panel);
-
- $panel->requireImplementation()->initializeFieldsFromRequest(
- $panel,
- $field_list,
- $request);
+ $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer)
+ ->setPanelType($panel_type);
$xactions = array();
- $xactions[] = id(new PhabricatorDashboardPanelTransaction())
- ->setTransactionType(
- PhabricatorDashboardPanelNameTransaction::TRANSACTIONTYPE)
- ->setNewValue($v_name);
-
- $xactions[] = id(new PhabricatorDashboardPanelTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
- ->setMetadataValue('customfield:key', 'std:dashboard:core:class')
- ->setOldValue(null)
+ $xactions[] = $panel->getApplicationTransactionTemplate()
+ ->setTransactionType($xaction_engine)
->setNewValue($v_engine);
- $xactions[] = id(new PhabricatorDashboardPanelTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
- ->setMetadataValue('customfield:key', 'std:dashboard:core:key')
- ->setOldValue(null)
+ $xactions[] = $panel->getApplicationTransactionTemplate()
+ ->setTransactionType($xaction_query)
->setNewValue($v_query);
- $editor = id(new PhabricatorDashboardPanelTransactionEditor())
+ $xactions[] = $panel->getApplicationTransactionTemplate()
+ ->setTransactionType($xaction_name)
+ ->setNewValue($v_name);
+
+ $editor = $panel->getApplicationTransactionEditor()
->setActor($viewer)
- ->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request)
->applyTransactions($panel, $xactions);
- PhabricatorDashboardTransactionEditor::addPanelToDashboard(
- $viewer,
- PhabricatorContentSource::newFromRequest($request),
- $panel,
- $dashboard,
- $request->getInt('column', 0));
+ // Now that we've created a panel, add it to the dashboard.
+
+ $xactions = array();
+
+ $ref_list = clone $dashboard->getPanelRefList();
+ $ref_list->newPanelRef($panel);
+ $new_panels = $ref_list->toDictionary();
+
+ $xactions[] = $dashboard->getApplicationTransactionTemplate()
+ ->setTransactionType(
+ PhabricatorDashboardPanelsTransaction::TRANSACTIONTYPE)
+ ->setNewValue($new_panels);
- return id(new AphrontRedirectResponse())->setURI($redirect_uri);
+ $editor = $dashboard->getApplicationTransactionEditor()
+ ->setActor($viewer)
+ ->setContentSourceFromRequest($request)
+ ->setContinueOnNoEffect(true)
+ ->setContinueOnMissingFields(true)
+ ->applyTransactions($dashboard, $xactions);
+
+ return id(new AphrontRedirectResponse())->setURI($done_uri);
}
}
- // Make this a select for now, as we don't expect someone to have
- // edit access to a vast number of dashboards.
- // Can add optiongroup if needed down the road.
- $dashboards = id(new PhabricatorDashboardQuery())
- ->setViewer($viewer)
- ->withStatuses(array(
- PhabricatorDashboard::STATUS_ACTIVE,
- ))
- ->requireCapabilities(
- array(
- PhabricatorPolicyCapability::CAN_VIEW,
- PhabricatorPolicyCapability::CAN_EDIT,
- ))
- ->execute();
- $options = mpull($dashboards, 'getName', 'getID');
- asort($options);
-
- $redirect_uri = $engine->getQueryResultsPageURI($v_query);
-
- if (!$options) {
- $notice = id(new PHUIInfoView())
- ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
- ->appendChild(pht('You do not have access to any dashboards. To '.
- 'continue, please create a dashboard first.'));
-
- return $this->newDialog()
- ->setTitle(pht('No Dashboards'))
- ->setWidth(AphrontDialogView::WIDTH_FORM)
- ->appendChild($notice)
- ->addCancelButton($redirect_uri);
+ if ($v_dashboard) {
+ $dashboard_phids = array($v_dashboard);
+ } else {
+ $dashboard_phids = array();
}
$form = id(new AphrontFormView())
- ->setUser($viewer)
- ->addHiddenInput('engine', $v_engine)
- ->addHiddenInput('query', $v_query)
- ->addHiddenInput('column', $v_column)
- ->appendChild(
+ ->setViewer($viewer)
+ ->appendControl(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setValue($v_name)
->setError($e_name))
- ->appendChild(
- id(new AphrontFormSelectControl())
- ->setUser($this->getViewer())
- ->setValue($v_dashboard)
- ->setName('dashboardID')
- ->setOptions($options)
+ ->appendControl(
+ id(new AphrontFormTokenizerControl())
+ ->setValue($dashboard_phids)
+ ->setError($e_dashboard)
+ ->setName('dashboardPHIDs')
+ ->setLimit(1)
+ ->setDatasource(new PhabricatorDashboardDatasource())
->setLabel(pht('Dashboard')));
return $this->newDialog()
->setTitle(pht('Add Panel to Dashboard'))
->setErrors($errors)
->setWidth(AphrontDialogView::WIDTH_FORM)
- ->appendChild($form->buildLayoutView())
+ ->addHiddenInput('engine', $v_engine)
+ ->addHiddenInput('query', $v_query)
+ ->appendForm($form)
->addCancelButton($redirect_uri)
->addSubmitButton(pht('Add Panel'));
}
}
diff --git a/src/applications/dashboard/layoutconfig/PhabricatorDashboardPanelRefList.php b/src/applications/dashboard/layoutconfig/PhabricatorDashboardPanelRefList.php
index dc05bff994..2f74d0a937 100644
--- a/src/applications/dashboard/layoutconfig/PhabricatorDashboardPanelRefList.php
+++ b/src/applications/dashboard/layoutconfig/PhabricatorDashboardPanelRefList.php
@@ -1,156 +1,163 @@
<?php
final class PhabricatorDashboardPanelRefList
extends Phobject {
private $refs;
private $columns;
public static function newFromDictionary($config) {
if (!is_array($config)) {
$config = array();
}
$mode_map = PhabricatorDashboardLayoutMode::getAllLayoutModes();
$mode_key = idx($config, 'layoutMode');
if (!isset($mode_map[$mode_key])) {
$mode_key = head_key($mode_map);
}
$mode = $mode_map[$mode_key];
$columns = $mode->getLayoutModeColumns();
$columns = mpull($columns, null, 'getColumnKey');
$default_column = head($columns);
$panels = idx($config, 'panels');
if (!is_array($panels)) {
$panels = array();
}
$seen_panels = array();
$refs = array();
foreach ($panels as $panel) {
$panel_phid = idx($panel, 'panelPHID');
if (!strlen($panel_phid)) {
continue;
}
$panel_key = idx($panel, 'panelKey');
if (!strlen($panel_key)) {
continue;
}
if (isset($seen_panels[$panel_key])) {
continue;
}
$seen_panels[$panel_key] = true;
$column_key = idx($panel, 'columnKey');
$column = idx($columns, $column_key, $default_column);
$ref = id(new PhabricatorDashboardPanelRef())
->setPanelPHID($panel_phid)
->setPanelKey($panel_key)
->setColumnKey($column->getColumnKey());
$column->addPanelRef($ref);
$refs[] = $ref;
}
$list = new self();
$list->columns = $columns;
$list->refs = $refs;
return $list;
}
public function getColumns() {
return $this->columns;
}
public function getPanelRefs() {
return $this->refs;
}
public function getPanelRef($panel_key) {
foreach ($this->getPanelRefs() as $ref) {
if ($ref->getPanelKey() === $panel_key) {
return $ref;
}
}
return null;
}
public function toDictionary() {
return array_values(mpull($this->getPanelRefs(), 'toDictionary'));
}
- public function newPanelRef(PhabricatorDashboardPanel $panel, $column_key) {
+ public function newPanelRef(
+ PhabricatorDashboardPanel $panel,
+ $column_key = null) {
+
+ if ($column_key === null) {
+ $column_key = head_key($this->columns);
+ }
+
$ref = id(new PhabricatorDashboardPanelRef())
->setPanelKey($this->newPanelKey())
->setPanelPHID($panel->getPHID())
->setColumnKey($column_key);
$this->refs[] = $ref;
return $ref;
}
public function removePanelRef(PhabricatorDashboardPanelRef $target) {
foreach ($this->refs as $key => $ref) {
if ($ref->getPanelKey() !== $target->getPanelKey()) {
continue;
}
unset($this->refs[$key]);
return $ref;
}
return null;
}
public function movePanelRef(
PhabricatorDashboardPanelRef $target,
$column_key,
PhabricatorDashboardPanelRef $after = null) {
$target->setColumnKey($column_key);
$results = array();
if (!$after) {
$results[] = $target;
}
foreach ($this->refs as $ref) {
if ($ref->getPanelKey() === $target->getPanelKey()) {
continue;
}
$results[] = $ref;
if ($after) {
if ($ref->getPanelKey() === $after->getPanelKey()) {
$results[] = $target;
}
}
}
$this->refs = $results;
$column_map = mgroup($results, 'getColumnKey');
foreach ($this->columns as $column_key => $column) {
$column->setPanelRefs(idx($column_map, $column_key, array()));
}
return $ref;
}
private function newPanelKey() {
return Filesystem::readRandomCharacters(8);
}
}
diff --git a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php
index 6cf9d45a8c..a8bf58e8ab 100644
--- a/src/applications/dashboard/storage/PhabricatorDashboardPanel.php
+++ b/src/applications/dashboard/storage/PhabricatorDashboardPanel.php
@@ -1,177 +1,176 @@
<?php
/**
* An individual dashboard panel.
*/
final class PhabricatorDashboardPanel
extends PhabricatorDashboardDAO
implements
PhabricatorApplicationTransactionInterface,
PhabricatorPolicyInterface,
PhabricatorFlaggableInterface,
PhabricatorDestructibleInterface,
PhabricatorFulltextInterface,
PhabricatorFerretInterface,
PhabricatorDashboardPanelContainerInterface {
protected $name;
protected $panelType;
protected $viewPolicy;
protected $editPolicy;
protected $authorPHID;
protected $isArchived = 0;
protected $properties = array();
public static function initializeNewPanel(PhabricatorUser $actor) {
return id(new PhabricatorDashboardPanel())
->setName('')
->setAuthorPHID($actor->getPHID())
->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
->setEditPolicy($actor->getPHID());
}
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'properties' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'sort255',
'panelType' => 'text64',
'authorPHID' => 'phid',
'isArchived' => 'bool',
),
) + parent::getConfiguration();
}
- public function generatePHID() {
- return PhabricatorPHID::generateNewPHID(
- PhabricatorDashboardPanelPHIDType::TYPECONST);
+ public function getPHIDType() {
+ return PhabricatorDashboardPanelPHIDType::TYPECONST;
}
public function getProperty($key, $default = null) {
return idx($this->properties, $key, $default);
}
public function setProperty($key, $value) {
$this->properties[$key] = $value;
return $this;
}
public function getMonogram() {
return 'W'.$this->getID();
}
public function getURI() {
return '/'.$this->getMonogram();
}
public function getPanelTypes() {
$panel_types = PhabricatorDashboardPanelType::getAllPanelTypes();
$panel_types = mpull($panel_types, 'getPanelTypeName', 'getPanelTypeKey');
asort($panel_types);
$panel_types = (array('' => pht('(All Types)')) + $panel_types);
return $panel_types;
}
public function getStatuses() {
$statuses =
array(
'' => pht('(All Panels)'),
'active' => pht('Active Panels'),
'archived' => pht('Archived Panels'),
);
return $statuses;
}
public function getImplementation() {
return idx(
PhabricatorDashboardPanelType::getAllPanelTypes(),
$this->getPanelType());
}
public function requireImplementation() {
$impl = $this->getImplementation();
if (!$impl) {
throw new Exception(
pht(
'Attempting to use a panel in a way that requires an '.
'implementation, but the panel implementation ("%s") is unknown to '.
'Phabricator.',
$this->getPanelType()));
}
return $impl;
}
public function getEditEngineFields() {
return $this->requireImplementation()->getEditEngineFields($this);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new PhabricatorDashboardPanelTransactionEditor();
}
public function getApplicationTransactionTemplate() {
return new PhabricatorDashboardPanelTransaction();
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$this->saveTransaction();
}
/* -( PhabricatorDashboardPanelContainerInterface )------------------------ */
public function getDashboardPanelContainerPanelPHIDs() {
return $this->requireImplementation()->getSubpanelPHIDs($this);
}
/* -( PhabricatorFulltextInterface )--------------------------------------- */
public function newFulltextEngine() {
return new PhabricatorDashboardPanelFulltextEngine();
}
/* -( PhabricatorFerretInterface )----------------------------------------- */
public function newFerretEngine() {
return new PhabricatorDashboardPanelFerretEngine();
}
}
diff --git a/src/applications/dashboard/xaction/panel/PhabricatorDashboardQueryPanelApplicationTransaction.php b/src/applications/dashboard/xaction/panel/PhabricatorDashboardQueryPanelApplicationTransaction.php
index 37262cd108..eca3ba4e56 100644
--- a/src/applications/dashboard/xaction/panel/PhabricatorDashboardQueryPanelApplicationTransaction.php
+++ b/src/applications/dashboard/xaction/panel/PhabricatorDashboardQueryPanelApplicationTransaction.php
@@ -1,12 +1,39 @@
<?php
final class PhabricatorDashboardQueryPanelApplicationTransaction
extends PhabricatorDashboardPanelPropertyTransaction {
const TRANSACTIONTYPE = 'query.application';
protected function getPropertyKey() {
return 'class';
}
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ $engines = PhabricatorApplicationSearchEngine::getAllEngines();
+
+ $old_value = $object->getProperty($this->getPropertyKey());
+ foreach ($xactions as $xaction) {
+ $new_value = $xaction->getNewValue();
+
+ if ($new_value === $old_value) {
+ continue;
+ }
+
+ if (!isset($engines[$new_value])) {
+ $errors[] = $this->newInvalidError(
+ pht(
+ 'Application search engine class "%s" is unknown. Query panels '.
+ 'must use a known search engine class.',
+ $new_value),
+ $xaction);
+ continue;
+ }
+ }
+
+ return $errors;
+ }
+
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Aug 14, 5:53 AM (2 d, 3 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
199587
Default Alt Text
(21 KB)

Event Timeline