@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Migrate project blurb/description to standard custom field storage

Summary: Ref T4379. Major goal here is to remove `ProjectProfile` so all edits use ApplicationTransactions. This also makes things more flexible, allowing users to disable this field if they don't like it.

Test Plan: Ran migration, verified data survived, edited/created projects, reordered fields.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T4379

Differential Revision: https://secure.phabricator.com/D8182

+83 -54
+26
resources/sql/autopatches/20140210.projcfield.1.blurb.php
··· 1 + <?php 2 + 3 + $conn_w = id(new PhabricatorProject())->establishConnection('w'); 4 + $table_name = id(new PhabricatorProjectCustomFieldStorage())->getTableName(); 5 + 6 + $rows = new LiskRawMigrationIterator($conn_w, 'project_profile'); 7 + 8 + echo "Migrating project descriptions to custom storage...\n"; 9 + foreach ($rows as $row) { 10 + $phid = $row['projectPHID']; 11 + echo "Migrating {$phid}...\n"; 12 + 13 + $desc = $row['blurb']; 14 + if (strlen($desc)) { 15 + queryfx( 16 + $conn_w, 17 + 'INSERT IGNORE INTO %T (objectPHID, fieldIndex, fieldValue) 18 + VALUES (%s, %s, %s)', 19 + $table_name, 20 + $phid, 21 + PhabricatorHash::digestForIndex('std:project:internal:description'), 22 + $desc); 23 + } 24 + } 25 + 26 + echo "Done.\n";
+9 -1
src/__phutil_library_map__.php
··· 1840 1840 'PhabricatorProjectCustomFieldStorage' => 'applications/project/storage/PhabricatorProjectCustomFieldStorage.php', 1841 1841 'PhabricatorProjectCustomFieldStringIndex' => 'applications/project/storage/PhabricatorProjectCustomFieldStringIndex.php', 1842 1842 'PhabricatorProjectDAO' => 'applications/project/storage/PhabricatorProjectDAO.php', 1843 + 'PhabricatorProjectDescriptionField' => 'applications/project/customfield/PhabricatorProjectDescriptionField.php', 1843 1844 'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php', 1844 1845 'PhabricatorProjectHistoryController' => 'applications/project/controller/PhabricatorProjectHistoryController.php', 1845 1846 'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php', ··· 1855 1856 'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php', 1856 1857 'PhabricatorProjectSearchEngine' => 'applications/project/query/PhabricatorProjectSearchEngine.php', 1857 1858 'PhabricatorProjectSearchIndexer' => 'applications/project/search/PhabricatorProjectSearchIndexer.php', 1859 + 'PhabricatorProjectStandardCustomField' => 'applications/project/customfield/PhabricatorProjectStandardCustomField.php', 1858 1860 'PhabricatorProjectStatus' => 'applications/project/constants/PhabricatorProjectStatus.php', 1859 1861 'PhabricatorProjectTestDataGenerator' => 'applications/project/lipsum/PhabricatorProjectTestDataGenerator.php', 1860 1862 'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php', ··· 4574 4576 'PhabricatorProjectConfigOptions' => 'PhabricatorApplicationConfigOptions', 4575 4577 'PhabricatorProjectConfiguredCustomField' => 4576 4578 array( 4577 - 0 => 'PhabricatorProjectCustomField', 4579 + 0 => 'PhabricatorProjectStandardCustomField', 4578 4580 1 => 'PhabricatorStandardCustomFieldInterface', 4579 4581 ), 4580 4582 'PhabricatorProjectController' => 'PhabricatorController', ··· 4584 4586 'PhabricatorProjectCustomFieldStorage' => 'PhabricatorCustomFieldStorage', 4585 4587 'PhabricatorProjectCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage', 4586 4588 'PhabricatorProjectDAO' => 'PhabricatorLiskDAO', 4589 + 'PhabricatorProjectDescriptionField' => 'PhabricatorProjectStandardCustomField', 4587 4590 'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase', 4588 4591 'PhabricatorProjectHistoryController' => 'PhabricatorProjectController', 4589 4592 'PhabricatorProjectListController' => ··· 4603 4606 'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4604 4607 'PhabricatorProjectSearchEngine' => 'PhabricatorApplicationSearchEngine', 4605 4608 'PhabricatorProjectSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 4609 + 'PhabricatorProjectStandardCustomField' => 4610 + array( 4611 + 0 => 'PhabricatorProjectCustomField', 4612 + 1 => 'PhabricatorStandardCustomFieldInterface', 4613 + ), 4606 4614 'PhabricatorProjectTestDataGenerator' => 'PhabricatorTestDataGenerator', 4607 4615 'PhabricatorProjectTransaction' => 'PhabricatorApplicationTransaction', 4608 4616 'PhabricatorProjectTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
+3 -3
src/applications/project/config/PhabricatorProjectConfigOptions.php
··· 12 12 } 13 13 14 14 public function getOptions() { 15 - // This is intentionally blank for now, until we can move more Project 16 - // logic to custom fields. 17 - $default_fields = array(); 15 + $default_fields = array( 16 + 'std:project:internal:description' => true, 17 + ); 18 18 19 19 foreach ($default_fields as $key => $enabled) { 20 20 $default_fields[$key] = array(
+2 -9
src/applications/project/controller/PhabricatorProjectCreateController.php
··· 40 40 41 41 // TODO: Deal with name collision exceptions more gracefully. 42 42 43 - $profile->setBlurb($request->getStr('blurb')); 44 - 45 43 if (!$errors) { 46 44 $project->save(); 47 45 $profile->setProjectPHID($project->getPHID()); 46 + $profile->setBlurb(''); 48 47 $profile->save(); 49 48 50 49 if ($request->isAjax()) { ··· 79 78 ->setLabel(pht('Name')) 80 79 ->setName('name') 81 80 ->setValue($project->getName()) 82 - ->setError($e_name)) 83 - ->appendChild( 84 - id(new AphrontFormTextAreaControl()) 85 - ->setLabel(pht('Blurb')) 86 - ->setName('blurb') 87 - ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT) 88 - ->setValue($profile->getBlurb())); 81 + ->setError($e_name)); 89 82 90 83 if ($request->isAjax()) { 91 84 $dialog = id(new AphrontDialogView())
-7
src/applications/project/controller/PhabricatorProjectProfileController.php
··· 271 271 PhabricatorCustomField::ROLE_VIEW); 272 272 $field_list->appendFieldsToPropertyList($project, $viewer, $view); 273 273 274 - $view->addSectionHeader(pht('Description')); 275 - $view->addTextContent( 276 - PhabricatorMarkupEngine::renderOneObject( 277 - id(new PhabricatorMarkupOneOff())->setContent($profile->getBlurb()), 278 - 'default', 279 - $viewer)); 280 - 281 274 return $view; 282 275 } 283 276
+1 -21
src/applications/project/controller/PhabricatorProjectProfileEditController.php
··· 21 21 PhabricatorPolicyCapability::CAN_VIEW, 22 22 PhabricatorPolicyCapability::CAN_EDIT, 23 23 )) 24 - ->needProfiles(true) 25 24 ->executeOne(); 26 25 if (!$project) { 27 26 return new Aphront404Response(); 28 27 } 29 - 30 - $profile = $project->getProfile(); 31 28 32 29 $field_list = PhabricatorCustomField::getObjectFields( 33 30 $project, ··· 42 39 $e_edit = null; 43 40 44 41 $v_name = $project->getName(); 45 - $v_desc = $profile->getBlurb(); 46 42 47 43 $validation_exception = null; 48 44 ··· 50 46 $e_name = null; 51 47 52 48 $v_name = $request->getStr('name'); 53 - $v_desc = $request->getStr('blurb'); 54 49 $v_view = $request->getStr('can_view'); 55 50 $v_edit = $request->getStr('can_edit'); 56 51 $v_join = $request->getStr('can_join'); ··· 86 81 try { 87 82 $editor->applyTransactions($project, $xactions); 88 83 89 - // TODO: Move this into a custom field. 90 - $profile->setBlurb($request->getStr('blurb')); 91 - if (!$profile->getProjectPHID()) { 92 - $profile->setProjectPHID($project->getPHID()); 93 - } 94 - $profile->save(); 95 - 96 84 return id(new AphrontRedirectResponse())->setURI($view_uri); 97 85 } catch (PhabricatorApplicationTransactionValidationException $ex) { 98 86 $validation_exception = $ex; ··· 108 96 109 97 $header_name = pht('Edit Project'); 110 98 $title = pht('Edit Project'); 111 - $action = '/project/edit/'.$project->getID().'/'; 112 99 113 100 $policies = id(new PhabricatorPolicyQuery()) 114 101 ->setViewer($viewer) ··· 117 104 118 105 $form = new AphrontFormView(); 119 106 $form 120 - ->setID('project-edit-form') 121 107 ->setUser($viewer) 122 - ->setAction($action) 123 108 ->appendChild( 124 109 id(new AphrontFormTextControl()) 125 110 ->setLabel(pht('Name')) 126 111 ->setName('name') 127 112 ->setValue($v_name) 128 - ->setError($e_name)) 129 - ->appendChild( 130 - id(new PhabricatorRemarkupControl()) 131 - ->setLabel(pht('Description')) 132 - ->setName('blurb') 133 - ->setValue($v_desc)); 113 + ->setError($e_name)); 134 114 135 115 $field_list->appendFieldsToForm($form); 136 116
+1 -13
src/applications/project/customfield/PhabricatorProjectConfiguredCustomField.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorProjectConfiguredCustomField 4 - extends PhabricatorProjectCustomField 4 + extends PhabricatorProjectStandardCustomField 5 5 implements PhabricatorStandardCustomFieldInterface { 6 6 7 7 public function getStandardCustomFieldNamespace() { ··· 14 14 PhabricatorEnv::getEnvConfig( 15 15 'projects.custom-field-definitions', 16 16 array())); 17 - } 18 - 19 - public function newStorageObject() { 20 - return new PhabricatorProjectCustomFieldStorage(); 21 - } 22 - 23 - protected function newStringIndexStorage() { 24 - return new PhabricatorProjectCustomFieldStringIndex(); 25 - } 26 - 27 - protected function newNumericIndexStorage() { 28 - return new PhabricatorProjectCustomFieldNumericIndex(); 29 17 } 30 18 31 19 }
+18
src/applications/project/customfield/PhabricatorProjectDescriptionField.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectDescriptionField 4 + extends PhabricatorProjectStandardCustomField { 5 + 6 + public function createFields() { 7 + return PhabricatorStandardCustomField::buildStandardFields( 8 + $this, 9 + array( 10 + 'description' => array( 11 + 'name' => pht('Description'), 12 + 'type' => 'remarkup', 13 + 'description' => pht('Short project description.'), 14 + ), 15 + )); 16 + } 17 + 18 + }
+23
src/applications/project/customfield/PhabricatorProjectStandardCustomField.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorProjectStandardCustomField 4 + extends PhabricatorProjectCustomField 5 + implements PhabricatorStandardCustomFieldInterface { 6 + 7 + public function getStandardCustomFieldNamespace() { 8 + return 'project:internal'; 9 + } 10 + 11 + public function newStorageObject() { 12 + return new PhabricatorProjectCustomFieldStorage(); 13 + } 14 + 15 + protected function newStringIndexStorage() { 16 + return new PhabricatorProjectCustomFieldStringIndex(); 17 + } 18 + 19 + protected function newNumericIndexStorage() { 20 + return new PhabricatorProjectCustomFieldNumericIndex(); 21 + } 22 + 23 + }