diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1578,6 +1578,7 @@ 'PhabricatorApplicationConfigurationPanelTestCase' => 'applications/meta/panel/__tests__/PhabricatorApplicationConfigurationPanelTestCase.php', 'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php', 'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php', + 'PhabricatorApplicationEditConfiguration' => 'applications/transactions/storage/PhabricatorApplicationEditConfiguration.php', 'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php', 'PhabricatorApplicationEditEngine' => 'applications/transactions/editengine/PhabricatorApplicationEditEngine.php', 'PhabricatorApplicationEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorApplicationEditEngineAPIMethod.php', @@ -2295,6 +2296,7 @@ 'PhabricatorInlineCommentInterface' => 'infrastructure/diff/interface/PhabricatorInlineCommentInterface.php', 'PhabricatorInlineCommentPreviewController' => 'infrastructure/diff/PhabricatorInlineCommentPreviewController.php', 'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php', + 'PhabricatorInstructionsEditField' => 'applications/transactions/editfield/PhabricatorInstructionsEditField.php', 'PhabricatorInternationalizationManagementExtractWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementExtractWorkflow.php', 'PhabricatorInternationalizationManagementWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php', 'PhabricatorInvalidConfigSetupCheck' => 'applications/config/check/PhabricatorInvalidConfigSetupCheck.php', @@ -5528,6 +5530,10 @@ 'PhabricatorApplicationConfigurationPanelTestCase' => 'PhabricatorTestCase', 'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController', + 'PhabricatorApplicationEditConfiguration' => array( + 'PhabricatorSearchDAO', + 'PhabricatorPolicyInterface', + ), 'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationEditEngine' => 'Phobject', 'PhabricatorApplicationEditEngineAPIMethod' => 'ConduitAPIMethod', @@ -6378,6 +6384,7 @@ 'PhabricatorInlineCommentInterface' => 'PhabricatorMarkupInterface', 'PhabricatorInlineCommentPreviewController' => 'PhabricatorController', 'PhabricatorInlineSummaryView' => 'AphrontView', + 'PhabricatorInstructionsEditField' => 'PhabricatorEditField', 'PhabricatorInternationalizationManagementExtractWorkflow' => 'PhabricatorInternationalizationManagementWorkflow', 'PhabricatorInternationalizationManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorInvalidConfigSetupCheck' => 'PhabricatorSetupCheck', diff --git a/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php b/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php --- a/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorApplicationEditEngine.php @@ -184,6 +184,21 @@ } } + // TODO: This is just silly nonsense for now. + $config = id(new PhabricatorApplicationEditConfiguration()) + ->setProperty( + 'instructions.head', + pht( + '(NOTE) **!!CHALLENGE MODE!!!** Can you figure out how to fill out '. + 'this form?')) + ->setProperty( + 'defaults', + array( + 'text' => 'Feature Request: Natural wood-panel theme (mahogany?).', + )); + + $fields = $config->applyConfigurationToFields($this, $fields); + foreach ($fields as $field) { $field ->setViewer($viewer) @@ -317,7 +332,7 @@ * @return bool True if a new object is being created. * @task load */ - final protected function getIsCreate() { + final public function getIsCreate() { return $this->isCreate; } diff --git a/src/applications/transactions/editfield/PhabricatorEditField.php b/src/applications/transactions/editfield/PhabricatorEditField.php --- a/src/applications/transactions/editfield/PhabricatorEditField.php +++ b/src/applications/transactions/editfield/PhabricatorEditField.php @@ -13,7 +13,7 @@ private $metadata = array(); private $description; private $editTypeKey; - + private $isLocked; public function setKey($key) { $this->key = $key; @@ -69,7 +69,18 @@ return $this->description; } - abstract protected function newControl(); + public function setIsLocked($is_locked) { + $this->isLocked = $is_locked; + return $this; + } + + public function getIsLocked() { + return $this->isLocked; + } + + protected function newControl() { + throw new PhutilMethodNotImplementedException(); + } protected function renderControl() { $control = $this->newControl(); @@ -85,6 +96,10 @@ $control->setLabel($this->getLabel()); } + if ($this->getIsLocked()) { + $control->setDisabled(true); + } + return $control; } @@ -166,6 +181,15 @@ return $this; } + public function readDefaultValueFromConfiguration($value) { + $this->value = $this->getDefaultValueFromConfiguration($value); + return $this; + } + + protected function getDefaultValueFromConfiguration($value) { + return $value; + } + protected function getValueFromObject($object) { if ($this->hasValue) { return $this->value; diff --git a/src/applications/transactions/editfield/PhabricatorInstructionsEditField.php b/src/applications/transactions/editfield/PhabricatorInstructionsEditField.php new file mode 100644 --- /dev/null +++ b/src/applications/transactions/editfield/PhabricatorInstructionsEditField.php @@ -0,0 +1,10 @@ +appendRemarkupInstructions($this->getValue()); + } + +} diff --git a/src/applications/transactions/storage/PhabricatorApplicationEditConfiguration.php b/src/applications/transactions/storage/PhabricatorApplicationEditConfiguration.php new file mode 100644 --- /dev/null +++ b/src/applications/transactions/storage/PhabricatorApplicationEditConfiguration.php @@ -0,0 +1,131 @@ + true, + self::CONFIG_SERIALIZATION => array( + 'properties' => self::SERIALIZATION_JSON, + ), + self::CONFIG_COLUMN_SCHEMA => array( + 'engineKey' => 'text64', + 'builtinKey' => 'text64?', + 'isDisabled' => 'bool', + ), + self::CONFIG_KEY_SCHEMA => array( + 'key_engine' => array( + 'columns' => array('engineKey', 'builtinKey'), + 'unique' => true, + ), + ), + ) + parent::getConfiguration(); + } + + 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 applyConfigurationToFields( + PhabricatorApplicationEditEngine $engine, + array $fields) { + $fields = mpull($fields, null, 'getKey'); + + $values = $this->getProperty('defaults', array()); + $locked = $this->getProperty('locked', array()); + foreach ($fields as $key => $field) { + if ($engine->getIsCreate()) { + if (array_key_exists($key, $values)) { + $field->readDefaultValueFromConfiguration($values[$key]); + } + } + + // Randomly lock half the fields. + if (isset($locked[$key]) || mt_rand(0, 1)) { + $field->setIsLocked(true); + } + } + + $fields = $this->reorderFields($fields); + + $head_instructions = $this->getProperty('instructions.head'); + if (strlen($head_instructions)) { + $fields = array( + 'config.instructions.head' => id(new PhabricatorInstructionsEditField()) + ->setKey('config.instructions.head') + ->setValue($head_instructions), + ) + $fields; + } + + return $fields; + } + + private function reorderFields(array $fields) { + // Shuffle fields randomly. + $keys = array_keys($fields); + shuffle($keys); + $fields = array_select_keys($fields, $keys); + + // Now, move locked fields to the bottom. + $head = array(); + $tail = array(); + foreach ($fields as $key => $field) { + if (!$field->getIsLocked()) { + $head[$key] = $field; + } else { + $tail[$key] = $field; + } + } + + return $head + $tail; + } + +/* -( PhabricatorPolicyInterface Implementation )-------------------------- */ + + + 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; + } + + public function describeAutomaticCapability($capability) { + return null; + } + + +}