Modularize Dashboard transactions
Summary: Depends on D20399. Ref T13272. I'm moving toward fixing all the "moving panels around on Dashboards breaks the entire world" problems. On the way there, modularize Dashboard transactions. Test Plan: - Created a new Dashboard. - Edited all fiedls of a dashboard. - Archived/restored a dashboard. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13272 Differential Revision: https://secure.phabricator.com/D20402
This commit is contained in:
		@@ -2920,12 +2920,15 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PhabricatorDashboardFavoritesInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardFavoritesInstallWorkflow.php',
 | 
			
		||||
    'PhabricatorDashboardHomeInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardHomeInstallWorkflow.php',
 | 
			
		||||
    'PhabricatorDashboardIconSet' => 'applications/dashboard/icon/PhabricatorDashboardIconSet.php',
 | 
			
		||||
    'PhabricatorDashboardIconTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardIconTransaction.php',
 | 
			
		||||
    'PhabricatorDashboardInstall' => 'applications/dashboard/storage/PhabricatorDashboardInstall.php',
 | 
			
		||||
    'PhabricatorDashboardInstallController' => 'applications/dashboard/controller/dashboard/PhabricatorDashboardInstallController.php',
 | 
			
		||||
    'PhabricatorDashboardInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardInstallWorkflow.php',
 | 
			
		||||
    'PhabricatorDashboardLayoutConfig' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php',
 | 
			
		||||
    'PhabricatorDashboardLayoutTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardLayoutTransaction.php',
 | 
			
		||||
    'PhabricatorDashboardListController' => 'applications/dashboard/controller/PhabricatorDashboardListController.php',
 | 
			
		||||
    'PhabricatorDashboardMovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardMovePanelController.php',
 | 
			
		||||
    'PhabricatorDashboardNameTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardNameTransaction.php',
 | 
			
		||||
    'PhabricatorDashboardNgrams' => 'applications/dashboard/storage/PhabricatorDashboardNgrams.php',
 | 
			
		||||
    'PhabricatorDashboardObjectInstallWorkflow' => 'applications/dashboard/install/PhabricatorDashboardObjectInstallWorkflow.php',
 | 
			
		||||
    'PhabricatorDashboardPanel' => 'applications/dashboard/storage/PhabricatorDashboardPanel.php',
 | 
			
		||||
@@ -2993,6 +2996,7 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php',
 | 
			
		||||
    'PhabricatorDashboardSchemaSpec' => 'applications/dashboard/storage/PhabricatorDashboardSchemaSpec.php',
 | 
			
		||||
    'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
 | 
			
		||||
    'PhabricatorDashboardStatusTransaction' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardStatusTransaction.php',
 | 
			
		||||
    'PhabricatorDashboardTabsPanelTabsTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardTabsPanelTabsTransaction.php',
 | 
			
		||||
    'PhabricatorDashboardTabsPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php',
 | 
			
		||||
    'PhabricatorDashboardTextPanelTextTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardTextPanelTextTransaction.php',
 | 
			
		||||
@@ -3000,6 +3004,7 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
 | 
			
		||||
    'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php',
 | 
			
		||||
    'PhabricatorDashboardTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardTransactionQuery.php',
 | 
			
		||||
    'PhabricatorDashboardTransactionType' => 'applications/dashboard/xaction/dashboard/PhabricatorDashboardTransactionType.php',
 | 
			
		||||
    'PhabricatorDashboardViewController' => 'applications/dashboard/controller/dashboard/PhabricatorDashboardViewController.php',
 | 
			
		||||
    'PhabricatorDataCacheSpec' => 'applications/cache/spec/PhabricatorDataCacheSpec.php',
 | 
			
		||||
    'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php',
 | 
			
		||||
@@ -8908,12 +8913,15 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PhabricatorDashboardFavoritesInstallWorkflow' => 'PhabricatorDashboardApplicationInstallWorkflow',
 | 
			
		||||
    'PhabricatorDashboardHomeInstallWorkflow' => 'PhabricatorDashboardApplicationInstallWorkflow',
 | 
			
		||||
    'PhabricatorDashboardIconSet' => 'PhabricatorIconSet',
 | 
			
		||||
    'PhabricatorDashboardIconTransaction' => 'PhabricatorDashboardTransactionType',
 | 
			
		||||
    'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
 | 
			
		||||
    'PhabricatorDashboardInstallController' => 'PhabricatorDashboardController',
 | 
			
		||||
    'PhabricatorDashboardInstallWorkflow' => 'Phobject',
 | 
			
		||||
    'PhabricatorDashboardLayoutConfig' => 'Phobject',
 | 
			
		||||
    'PhabricatorDashboardLayoutTransaction' => 'PhabricatorDashboardTransactionType',
 | 
			
		||||
    'PhabricatorDashboardListController' => 'PhabricatorDashboardController',
 | 
			
		||||
    'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController',
 | 
			
		||||
    'PhabricatorDashboardNameTransaction' => 'PhabricatorDashboardTransactionType',
 | 
			
		||||
    'PhabricatorDashboardNgrams' => 'PhabricatorSearchNgrams',
 | 
			
		||||
    'PhabricatorDashboardObjectInstallWorkflow' => 'PhabricatorDashboardInstallWorkflow',
 | 
			
		||||
    'PhabricatorDashboardPanel' => array(
 | 
			
		||||
@@ -8996,13 +9004,15 @@ phutil_register_library_map(array(
 | 
			
		||||
    'PhabricatorDashboardRenderingEngine' => 'Phobject',
 | 
			
		||||
    'PhabricatorDashboardSchemaSpec' => 'PhabricatorConfigSchemaSpec',
 | 
			
		||||
    'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
 | 
			
		||||
    'PhabricatorDashboardStatusTransaction' => 'PhabricatorDashboardTransactionType',
 | 
			
		||||
    'PhabricatorDashboardTabsPanelTabsTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
 | 
			
		||||
    'PhabricatorDashboardTabsPanelType' => 'PhabricatorDashboardPanelType',
 | 
			
		||||
    'PhabricatorDashboardTextPanelTextTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
 | 
			
		||||
    'PhabricatorDashboardTextPanelType' => 'PhabricatorDashboardPanelType',
 | 
			
		||||
    'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
 | 
			
		||||
    'PhabricatorDashboardTransaction' => 'PhabricatorModularTransaction',
 | 
			
		||||
    'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
 | 
			
		||||
    'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
 | 
			
		||||
    'PhabricatorDashboardTransactionType' => 'PhabricatorModularTransactionType',
 | 
			
		||||
    'PhabricatorDashboardViewController' => 'PhabricatorDashboardProfileController',
 | 
			
		||||
    'PhabricatorDataCacheSpec' => 'PhabricatorCacheSpec',
 | 
			
		||||
    'PhabricatorDataNotAttachedException' => 'Exception',
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,8 @@ final class PhabricatorDashboardArchiveController
 | 
			
		||||
      $xactions = array();
 | 
			
		||||
 | 
			
		||||
      $xactions[] = id(new PhabricatorDashboardTransaction())
 | 
			
		||||
        ->setTransactionType(PhabricatorDashboardTransaction::TYPE_STATUS)
 | 
			
		||||
        ->setTransactionType(
 | 
			
		||||
          PhabricatorDashboardStatusTransaction::TRANSACTIONTYPE)
 | 
			
		||||
        ->setNewValue($new_status);
 | 
			
		||||
 | 
			
		||||
      id(new PhabricatorDashboardTransactionEditor())
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ final class PhabricatorDashboardEditController
 | 
			
		||||
 | 
			
		||||
    $v_name = $dashboard->getName();
 | 
			
		||||
    $v_icon = $dashboard->getIcon();
 | 
			
		||||
    $v_layout_mode = $dashboard->getLayoutConfigObject()->getLayoutMode();
 | 
			
		||||
    $v_layout_mode = $dashboard->getRawLayoutMode();
 | 
			
		||||
    $e_name = true;
 | 
			
		||||
 | 
			
		||||
    $validation_exception = null;
 | 
			
		||||
@@ -68,9 +68,10 @@ final class PhabricatorDashboardEditController
 | 
			
		||||
 | 
			
		||||
      $xactions = array();
 | 
			
		||||
 | 
			
		||||
      $type_name = PhabricatorDashboardTransaction::TYPE_NAME;
 | 
			
		||||
      $type_icon = PhabricatorDashboardTransaction::TYPE_ICON;
 | 
			
		||||
      $type_layout_mode = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
 | 
			
		||||
      $type_name = PhabricatorDashboardNameTransaction::TRANSACTIONTYPE;
 | 
			
		||||
      $type_icon = PhabricatorDashboardIconTransaction::TRANSACTIONTYPE;
 | 
			
		||||
      $type_layout_mode =
 | 
			
		||||
        PhabricatorDashboardLayoutTransaction::TRANSACTIONTYPE;
 | 
			
		||||
      $type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
 | 
			
		||||
      $type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY;
 | 
			
		||||
 | 
			
		||||
@@ -184,31 +185,4 @@ final class PhabricatorDashboardEditController
 | 
			
		||||
      ->appendChild($view);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private function newPanel(
 | 
			
		||||
    AphrontRequest $request,
 | 
			
		||||
    PhabricatorUser $viewer,
 | 
			
		||||
    $type,
 | 
			
		||||
    $name,
 | 
			
		||||
    array $properties) {
 | 
			
		||||
 | 
			
		||||
    $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer)
 | 
			
		||||
      ->setPanelType($type)
 | 
			
		||||
      ->setProperties($properties);
 | 
			
		||||
 | 
			
		||||
    $xactions = array();
 | 
			
		||||
 | 
			
		||||
    $xactions[] = id(new PhabricatorDashboardPanelTransaction())
 | 
			
		||||
      ->setTransactionType(
 | 
			
		||||
        PhabricatorDashboardPanelNameTransaction::TRANSACTIONTYPE)
 | 
			
		||||
      ->setNewValue($name);
 | 
			
		||||
 | 
			
		||||
    $editor = id(new PhabricatorDashboardPanelTransactionEditor())
 | 
			
		||||
      ->setActor($viewer)
 | 
			
		||||
      ->setContinueOnNoEffect(true)
 | 
			
		||||
      ->setContentSourceFromRequest($request)
 | 
			
		||||
      ->applyTransactions($panel, $xactions);
 | 
			
		||||
 | 
			
		||||
    return $panel;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -50,134 +50,9 @@ final class PhabricatorDashboardTransactionEditor
 | 
			
		||||
    $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
 | 
			
		||||
    $types[] = PhabricatorTransactions::TYPE_EDGE;
 | 
			
		||||
 | 
			
		||||
    $types[] = PhabricatorDashboardTransaction::TYPE_NAME;
 | 
			
		||||
    $types[] = PhabricatorDashboardTransaction::TYPE_ICON;
 | 
			
		||||
    $types[] = PhabricatorDashboardTransaction::TYPE_STATUS;
 | 
			
		||||
    $types[] = PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE;
 | 
			
		||||
 | 
			
		||||
    return $types;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function getCustomTransactionOldValue(
 | 
			
		||||
    PhabricatorLiskDAO $object,
 | 
			
		||||
    PhabricatorApplicationTransaction $xaction) {
 | 
			
		||||
    switch ($xaction->getTransactionType()) {
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_NAME:
 | 
			
		||||
        if ($this->getIsNewObject()) {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
        return $object->getName();
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_ICON:
 | 
			
		||||
        if ($this->getIsNewObject()) {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
        return $object->getIcon();
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_STATUS:
 | 
			
		||||
        if ($this->getIsNewObject()) {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
        return $object->getStatus();
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
 | 
			
		||||
        if ($this->getIsNewObject()) {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
        $layout_config = $object->getLayoutConfigObject();
 | 
			
		||||
        return $layout_config->getLayoutMode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return parent::getCustomTransactionOldValue($object, $xaction);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function getCustomTransactionNewValue(
 | 
			
		||||
    PhabricatorLiskDAO $object,
 | 
			
		||||
    PhabricatorApplicationTransaction $xaction) {
 | 
			
		||||
    switch ($xaction->getTransactionType()) {
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_NAME:
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_ICON:
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_STATUS:
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
 | 
			
		||||
        return $xaction->getNewValue();
 | 
			
		||||
    }
 | 
			
		||||
    return parent::getCustomTransactionNewValue($object, $xaction);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function applyCustomInternalTransaction(
 | 
			
		||||
    PhabricatorLiskDAO $object,
 | 
			
		||||
    PhabricatorApplicationTransaction $xaction) {
 | 
			
		||||
    switch ($xaction->getTransactionType()) {
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_NAME:
 | 
			
		||||
        $object->setName($xaction->getNewValue());
 | 
			
		||||
        return;
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_ICON:
 | 
			
		||||
        $object->setIcon($xaction->getNewValue());
 | 
			
		||||
        return;
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_STATUS:
 | 
			
		||||
        $object->setStatus($xaction->getNewValue());
 | 
			
		||||
        return;
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
 | 
			
		||||
        $old_layout = $object->getLayoutConfigObject();
 | 
			
		||||
        $new_layout = clone $old_layout;
 | 
			
		||||
        $new_layout->setLayoutMode($xaction->getNewValue());
 | 
			
		||||
        if ($old_layout->isMultiColumnLayout() !=
 | 
			
		||||
            $new_layout->isMultiColumnLayout()) {
 | 
			
		||||
          $panel_phids = $object->getPanelPHIDs();
 | 
			
		||||
          $new_locations = $new_layout->getDefaultPanelLocations();
 | 
			
		||||
          foreach ($panel_phids as $panel_phid) {
 | 
			
		||||
            $new_locations[0][] = $panel_phid;
 | 
			
		||||
          }
 | 
			
		||||
          $new_layout->setPanelLocations($new_locations);
 | 
			
		||||
        }
 | 
			
		||||
        $object->setLayoutConfigFromObject($new_layout);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return parent::applyCustomInternalTransaction($object, $xaction);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function applyCustomExternalTransaction(
 | 
			
		||||
    PhabricatorLiskDAO $object,
 | 
			
		||||
    PhabricatorApplicationTransaction $xaction) {
 | 
			
		||||
 | 
			
		||||
    switch ($xaction->getTransactionType()) {
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_NAME:
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_ICON:
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_STATUS:
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_LAYOUT_MODE:
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return parent::applyCustomExternalTransaction($object, $xaction);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function validateTransaction(
 | 
			
		||||
    PhabricatorLiskDAO $object,
 | 
			
		||||
    $type,
 | 
			
		||||
    array $xactions) {
 | 
			
		||||
 | 
			
		||||
    $errors = parent::validateTransaction($object, $type, $xactions);
 | 
			
		||||
 | 
			
		||||
    switch ($type) {
 | 
			
		||||
      case PhabricatorDashboardTransaction::TYPE_NAME:
 | 
			
		||||
        $missing = $this->validateIsEmptyTextField(
 | 
			
		||||
          $object->getName(),
 | 
			
		||||
          $xactions);
 | 
			
		||||
 | 
			
		||||
        if ($missing) {
 | 
			
		||||
          $error = new PhabricatorApplicationTransactionValidationError(
 | 
			
		||||
            $type,
 | 
			
		||||
            pht('Required'),
 | 
			
		||||
            pht('Dashboard name is required.'),
 | 
			
		||||
            nonempty(last($xactions), null));
 | 
			
		||||
 | 
			
		||||
          $error->setIsMissingFieldError(true);
 | 
			
		||||
          $errors[] = $error;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $errors;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function supportsSearch() {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -107,33 +107,6 @@ final class PhabricatorDashboardLayoutConfig extends Phobject {
 | 
			
		||||
    return $class;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function isMultiColumnLayout() {
 | 
			
		||||
    return $this->getLayoutMode() != self::MODE_FULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getColumnSelectOptions() {
 | 
			
		||||
    $options = array();
 | 
			
		||||
 | 
			
		||||
    switch ($this->getLayoutMode()) {
 | 
			
		||||
      case self::MODE_HALF_AND_HALF:
 | 
			
		||||
      case self::MODE_THIRD_AND_THIRDS:
 | 
			
		||||
      case self::MODE_THIRDS_AND_THIRD:
 | 
			
		||||
        return array(
 | 
			
		||||
          0 => pht('Left'),
 | 
			
		||||
          1 => pht('Right'),
 | 
			
		||||
        );
 | 
			
		||||
        break;
 | 
			
		||||
      case self::MODE_FULL:
 | 
			
		||||
        throw new Exception(pht('There is only one column in mode full.'));
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        throw new Exception(pht('Unknown layout mode!'));
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $options;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static function getLayoutModeSelectOptions() {
 | 
			
		||||
    return array(
 | 
			
		||||
      self::MODE_FULL             => pht('One full-width column'),
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,27 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
 | 
			
		||||
      PhabricatorDashboardDashboardPHIDType::TYPECONST);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getRawLayoutMode() {
 | 
			
		||||
    $config = $this->getRawLayoutConfig();
 | 
			
		||||
    return idx($config, 'layoutMode');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function setRawLayoutMode($mode) {
 | 
			
		||||
    $config = $this->getRawLayoutConfig();
 | 
			
		||||
    $config['layoutMode'] = $mode;
 | 
			
		||||
    return $this->setLayoutConfig($config);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private function getRawLayoutConfig() {
 | 
			
		||||
    $config = $this->getLayoutConfig();
 | 
			
		||||
 | 
			
		||||
    if (!is_array($config)) {
 | 
			
		||||
      $config = array();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $config;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getLayoutConfigObject() {
 | 
			
		||||
    return PhabricatorDashboardLayoutConfig::newFromDictionary(
 | 
			
		||||
      $this->getLayoutConfig());
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PhabricatorDashboardTransaction
 | 
			
		||||
  extends PhabricatorApplicationTransaction {
 | 
			
		||||
 | 
			
		||||
  const TYPE_NAME = 'dashboard:name';
 | 
			
		||||
  const TYPE_ICON = 'dashboard:icon';
 | 
			
		||||
  const TYPE_STATUS = 'dashboard:status';
 | 
			
		||||
  const TYPE_LAYOUT_MODE = 'dashboard:layoutmode';
 | 
			
		||||
  extends PhabricatorModularTransaction {
 | 
			
		||||
 | 
			
		||||
  public function getApplicationName() {
 | 
			
		||||
    return 'dashboard';
 | 
			
		||||
@@ -16,170 +11,8 @@ final class PhabricatorDashboardTransaction
 | 
			
		||||
    return PhabricatorDashboardDashboardPHIDType::TYPECONST;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getTitle() {
 | 
			
		||||
    $author_phid = $this->getAuthorPHID();
 | 
			
		||||
    $object_phid = $this->getObjectPHID();
 | 
			
		||||
 | 
			
		||||
    $old = $this->getOldValue();
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    $author_link = $this->renderHandleLink($author_phid);
 | 
			
		||||
 | 
			
		||||
    $type = $this->getTransactionType();
 | 
			
		||||
    switch ($type) {
 | 
			
		||||
      case self::TYPE_NAME:
 | 
			
		||||
        if (!strlen($old)) {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s created this dashboard.',
 | 
			
		||||
            $author_link);
 | 
			
		||||
        } else {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s renamed this dashboard from "%s" to "%s".',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $old,
 | 
			
		||||
            $new);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case self::TYPE_ICON:
 | 
			
		||||
        if (!strlen($old)) {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s set the dashboard icon.',
 | 
			
		||||
            $author_link);
 | 
			
		||||
        } else {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s changed this dashboard icon from "%s" to "%s".',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $old,
 | 
			
		||||
            $new);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case self::TYPE_STATUS:
 | 
			
		||||
        if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s activated this dashboard.',
 | 
			
		||||
            $author_link);
 | 
			
		||||
        } else {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s archived this dashboard.',
 | 
			
		||||
            $author_link);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
  public function getBaseTransactionClass() {
 | 
			
		||||
    return 'PhabricatorDashboardTransactionType';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    return parent::getTitle();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getTitleForFeed() {
 | 
			
		||||
    $author_phid = $this->getAuthorPHID();
 | 
			
		||||
    $object_phid = $this->getObjectPHID();
 | 
			
		||||
 | 
			
		||||
    $old = $this->getOldValue();
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    $author_link = $this->renderHandleLink($author_phid);
 | 
			
		||||
    $object_link = $this->renderHandleLink($object_phid);
 | 
			
		||||
 | 
			
		||||
    $type = $this->getTransactionType();
 | 
			
		||||
    switch ($type) {
 | 
			
		||||
      case self::TYPE_NAME:
 | 
			
		||||
        if (!strlen($old)) {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s created dashboard %s.',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $object_link);
 | 
			
		||||
        } else {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s renamed dashboard %s from "%s" to "%s".',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $object_link,
 | 
			
		||||
            $old,
 | 
			
		||||
            $new);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case self::TYPE_ICON:
 | 
			
		||||
        if (!strlen($old)) {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s set dashboard icon for %s.',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $object_link);
 | 
			
		||||
        } else {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s set the dashboard icon on %s from "%s" to "%s".',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $object_link,
 | 
			
		||||
            $old,
 | 
			
		||||
            $new);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case self::TYPE_STATUS:
 | 
			
		||||
        if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s activated dashboard %s.',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $object_link);
 | 
			
		||||
        } else {
 | 
			
		||||
          return pht(
 | 
			
		||||
            '%s archived dashboard %s.',
 | 
			
		||||
            $author_link,
 | 
			
		||||
            $object_link);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return parent::getTitleForFeed();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getColor() {
 | 
			
		||||
    $old = $this->getOldValue();
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    switch ($this->getTransactionType()) {
 | 
			
		||||
      case self::TYPE_NAME:
 | 
			
		||||
        if (!strlen($old)) {
 | 
			
		||||
          return PhabricatorTransactions::COLOR_GREEN;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case self::TYPE_STATUS:
 | 
			
		||||
        if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
 | 
			
		||||
          return PhabricatorTransactions::COLOR_GREEN;
 | 
			
		||||
        } else {
 | 
			
		||||
          return PhabricatorTransactions::COLOR_INDIGO;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return parent::getColor();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getIcon() {
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    switch ($this->getTransactionType()) {
 | 
			
		||||
      case self::TYPE_NAME:
 | 
			
		||||
        return 'fa-pencil';
 | 
			
		||||
        break;
 | 
			
		||||
      case self::TYPE_STATUS:
 | 
			
		||||
        if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
 | 
			
		||||
          return 'fa-check';
 | 
			
		||||
        } else {
 | 
			
		||||
          return 'fa-ban';
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case self::TYPE_LAYOUT_MODE:
 | 
			
		||||
        return 'fa-columns';
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    return parent::getIcon();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function shouldHide() {
 | 
			
		||||
    $old = $this->getOldValue();
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    switch ($this->getTransactionType()) {
 | 
			
		||||
      case self::TYPE_LAYOUT_MODE:
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return parent::shouldHide();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PhabricatorDashboardIconTransaction
 | 
			
		||||
  extends PhabricatorDashboardTransactionType {
 | 
			
		||||
 | 
			
		||||
  const TRANSACTIONTYPE = 'dashboard:icon';
 | 
			
		||||
 | 
			
		||||
  public function generateOldValue($object) {
 | 
			
		||||
    return $object->getIcon();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function applyInternalEffects($object, $value) {
 | 
			
		||||
    $object->setIcon($value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getTitle() {
 | 
			
		||||
    $old = $this->getOldValue();
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    return pht(
 | 
			
		||||
      '%s changed the icon for this dashboard from %s to %s.',
 | 
			
		||||
      $this->renderAuthor(),
 | 
			
		||||
      $this->renderOldValue(),
 | 
			
		||||
      $this->renderNewValue());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,55 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PhabricatorDashboardLayoutTransaction
 | 
			
		||||
  extends PhabricatorDashboardTransactionType {
 | 
			
		||||
 | 
			
		||||
  const TRANSACTIONTYPE = 'dashboard:layoutmode';
 | 
			
		||||
 | 
			
		||||
  public function generateOldValue($object) {
 | 
			
		||||
    return $object->getRawLayoutMode();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function applyInternalEffects($object, $value) {
 | 
			
		||||
    $object->setRawLayoutMode($value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getTitle() {
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    return pht(
 | 
			
		||||
      '%s changed the layout mode for this dashboard from %s to %s.',
 | 
			
		||||
      $this->renderAuthor(),
 | 
			
		||||
      $this->renderOldValue(),
 | 
			
		||||
      $this->renderNewValue());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function validateTransactions($object, array $xactions) {
 | 
			
		||||
    $errors = array();
 | 
			
		||||
 | 
			
		||||
    $mode_map = PhabricatorDashboardLayoutConfig::getLayoutModeSelectOptions();
 | 
			
		||||
 | 
			
		||||
    $old_value = $object->getRawLayoutMode();
 | 
			
		||||
    foreach ($xactions as $xaction) {
 | 
			
		||||
      $new_value = $xaction->getNewValue();
 | 
			
		||||
 | 
			
		||||
      if ($new_value === $old_value) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!isset($mode_map[$new_value])) {
 | 
			
		||||
        $errors[] = $this->newInvalidError(
 | 
			
		||||
          pht(
 | 
			
		||||
            'Layout mode "%s" is not valid. Supported layout modes '.
 | 
			
		||||
            'are: %s.',
 | 
			
		||||
            $new_value,
 | 
			
		||||
            implode(', ', array_keys($mode_map))),
 | 
			
		||||
          $xaction);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $errors;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,70 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PhabricatorDashboardNameTransaction
 | 
			
		||||
  extends PhabricatorDashboardTransactionType {
 | 
			
		||||
 | 
			
		||||
  const TRANSACTIONTYPE = 'dashboard:name';
 | 
			
		||||
 | 
			
		||||
  public function generateOldValue($object) {
 | 
			
		||||
    return $object->getName();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function applyInternalEffects($object, $value) {
 | 
			
		||||
    $object->setName($value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getTitle() {
 | 
			
		||||
    $old = $this->getOldValue();
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    return pht(
 | 
			
		||||
      '%s renamed this dashboard from %s to %s.',
 | 
			
		||||
      $this->renderAuthor(),
 | 
			
		||||
      $this->renderOldValue(),
 | 
			
		||||
      $this->renderNewValue());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function validateTransactions($object, array $xactions) {
 | 
			
		||||
    $errors = array();
 | 
			
		||||
 | 
			
		||||
    $max_length = $object->getColumnMaximumByteLength('name');
 | 
			
		||||
    foreach ($xactions as $xaction) {
 | 
			
		||||
      $new = $xaction->getNewValue();
 | 
			
		||||
      if (!strlen($new)) {
 | 
			
		||||
        $errors[] = $this->newInvalidError(
 | 
			
		||||
          pht('Dashboards must have a name.'),
 | 
			
		||||
          $xaction);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (strlen($new) > $max_length) {
 | 
			
		||||
        $errors[] = $this->newInvalidError(
 | 
			
		||||
          pht(
 | 
			
		||||
            'Dashboard names must not be longer than %s characters.',
 | 
			
		||||
            $max_length));
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!$errors) {
 | 
			
		||||
      if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
 | 
			
		||||
        $errors[] = $this->newRequiredError(
 | 
			
		||||
          pht('Dashboards must have a name.'));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $errors;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getTransactionTypeForConduit($xaction) {
 | 
			
		||||
    return 'name';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getFieldValuesForConduit($xaction, $data) {
 | 
			
		||||
    return array(
 | 
			
		||||
      'old' => $xaction->getOldValue(),
 | 
			
		||||
      'new' => $xaction->getNewValue(),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,59 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
final class PhabricatorDashboardStatusTransaction
 | 
			
		||||
  extends PhabricatorDashboardTransactionType {
 | 
			
		||||
 | 
			
		||||
  const TRANSACTIONTYPE = 'dashboard:status';
 | 
			
		||||
 | 
			
		||||
  public function generateOldValue($object) {
 | 
			
		||||
    return $object->getStatus();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function applyInternalEffects($object, $value) {
 | 
			
		||||
    $object->setStatus($value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function getTitle() {
 | 
			
		||||
    $new = $this->getNewValue();
 | 
			
		||||
 | 
			
		||||
    switch ($new) {
 | 
			
		||||
      case PhabricatorDashboard::STATUS_ACTIVE:
 | 
			
		||||
        return pht(
 | 
			
		||||
          '%s activated this dashboard.',
 | 
			
		||||
          $this->renderAuthor());
 | 
			
		||||
      case PhabricatorDashboard::STATUS_ARCHIVED:
 | 
			
		||||
        return pht(
 | 
			
		||||
          '%s archived this dashboard.',
 | 
			
		||||
          $this->renderAuthor());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public function validateTransactions($object, array $xactions) {
 | 
			
		||||
    $errors = array();
 | 
			
		||||
 | 
			
		||||
    $valid_statuses = PhabricatorDashboard::getStatusNameMap();
 | 
			
		||||
 | 
			
		||||
    $old_value = $object->getStatus();
 | 
			
		||||
    foreach ($xactions as $xaction) {
 | 
			
		||||
      $new_value = $xaction->getNewValue();
 | 
			
		||||
 | 
			
		||||
      if ($new_value === $old_value) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!isset($valid_statuses[$new_value])) {
 | 
			
		||||
        $errors[] = $this->newInvalidError(
 | 
			
		||||
          pht(
 | 
			
		||||
            'Status "%s" is not valid. Supported status constants are: %s.',
 | 
			
		||||
            $new_value,
 | 
			
		||||
            implode(', ', array_keys($valid_statuses))),
 | 
			
		||||
          $xaction);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $errors;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,4 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
abstract class PhabricatorDashboardTransactionType
 | 
			
		||||
  extends PhabricatorModularTransactionType {}
 | 
			
		||||
		Reference in New Issue
	
	Block a user