@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.

Move "Send Welcome Email" to profiles and nuke old weird edit UI

Summary: Ref T4065. Moves the last of the weird alternate edit UI to profiles. The old "Edit" controller is now for creation only, and the funky pencil icon is gone.

Test Plan: Created accounts; sent welcome email.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T4065

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

+132 -204
+2
src/__phutil_library_map__.php
··· 1822 1822 'PhabricatorPeopleRenameController' => 'applications/people/controller/PhabricatorPeopleRenameController.php', 1823 1823 'PhabricatorPeopleSearchEngine' => 'applications/people/query/PhabricatorPeopleSearchEngine.php', 1824 1824 'PhabricatorPeopleTestDataGenerator' => 'applications/people/lipsum/PhabricatorPeopleTestDataGenerator.php', 1825 + 'PhabricatorPeopleWelcomeController' => 'applications/people/controller/PhabricatorPeopleWelcomeController.php', 1825 1826 'PhabricatorPhameConfigOptions' => 'applications/phame/config/PhabricatorPhameConfigOptions.php', 1826 1827 'PhabricatorPhamePHIDTypeBlog' => 'applications/phame/phid/PhabricatorPhamePHIDTypeBlog.php', 1827 1828 'PhabricatorPhamePHIDTypePost' => 'applications/phame/phid/PhabricatorPhamePHIDTypePost.php', ··· 4632 4633 'PhabricatorPeopleRenameController' => 'PhabricatorPeopleController', 4633 4634 'PhabricatorPeopleSearchEngine' => 'PhabricatorApplicationSearchEngine', 4634 4635 'PhabricatorPeopleTestDataGenerator' => 'PhabricatorTestDataGenerator', 4636 + 'PhabricatorPeopleWelcomeController' => 'PhabricatorPeopleController', 4635 4637 'PhabricatorPhameConfigOptions' => 'PhabricatorApplicationConfigOptions', 4636 4638 'PhabricatorPhamePHIDTypeBlog' => 'PhabricatorPHIDType', 4637 4639 'PhabricatorPhamePHIDTypePost' => 'PhabricatorPHIDType',
+2 -2
src/applications/people/application/PhabricatorApplicationPeople.php
··· 49 49 'empower/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleEmpowerController', 50 50 'delete/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleDeleteController', 51 51 'rename/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleRenameController', 52 - 'edit/(?:(?P<id>[1-9]\d*)/(?:(?P<view>\w+)/)?)?' 53 - => 'PhabricatorPeopleEditController', 52 + 'welcome/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleWelcomeController', 53 + 'edit/' => 'PhabricatorPeopleEditController', 54 54 'ldap/' => 'PhabricatorPeopleLdapController', 55 55 'editprofile/(?P<id>[1-9]\d*)/' => 56 56 'PhabricatorPeopleProfileEditController',
+1 -1
src/applications/people/controller/PhabricatorPeopleDeleteController.php
··· 21 21 return new Aphront404Response(); 22 22 } 23 23 24 - $profile_uri = '/p/'.$user->getUsername(); 24 + $profile_uri = '/p/'.$user->getUsername().'/'; 25 25 26 26 if ($user->getPHID() == $admin->getPHID()) { 27 27 return $this->buildDeleteSelfResponse($profile_uri);
+64 -188
src/applications/people/controller/PhabricatorPeopleEditController.php
··· 3 3 final class PhabricatorPeopleEditController 4 4 extends PhabricatorPeopleController { 5 5 6 - private $id; 7 - private $view; 8 - 9 - public function willProcessRequest(array $data) { 10 - $this->id = idx($data, 'id'); 11 - $this->view = idx($data, 'view'); 12 - } 13 - 14 6 public function processRequest() { 15 7 16 8 $request = $this->getRequest(); 17 9 $admin = $request->getUser(); 18 10 19 11 $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView()); 20 - if ($this->id) { 21 - $user = id(new PhabricatorUser())->load($this->id); 22 - if (!$user) { 23 - return new Aphront404Response(); 24 - } 25 - $base_uri = '/people/edit/'.$user->getID().'/'; 26 - $crumbs->addTextCrumb(pht('Edit User'), '/people/edit/'); 27 - $crumbs->addTextCrumb($user->getFullName(), $base_uri); 28 - } else { 29 - $user = new PhabricatorUser(); 30 - $base_uri = '/people/edit/'; 31 - $crumbs->addTextCrumb(pht('Create New User'), $base_uri); 32 - } 33 12 34 - $nav = new AphrontSideNavFilterView(); 35 - $nav->setBaseURI(new PhutilURI($base_uri)); 36 - $nav->addLabel(pht('User Information')); 37 - $nav->addFilter('basic', pht('Basic Information')); 38 - $nav->addFilter('profile', 39 - pht('View Profile'), '/p/'.$user->getUsername().'/'); 40 - 41 - if (!$user->getID()) { 42 - $this->view = 'basic'; 43 - } 44 - 45 - $view = $nav->selectFilter($this->view, 'basic'); 13 + $user = new PhabricatorUser(); 14 + $base_uri = '/people/edit/'; 15 + $crumbs->addTextCrumb(pht('Create New User'), $base_uri); 46 16 47 17 $content = array(); 48 18 49 - if ($request->getStr('saved')) { 50 - $notice = new AphrontErrorView(); 51 - $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE); 52 - $notice->setTitle(pht('Changes Saved')); 53 - $notice->appendChild( 54 - phutil_tag('p', array(), pht('Your changes were saved.'))); 55 - $content[] = $notice; 56 - } 57 - 58 - switch ($view) { 59 - case 'basic': 60 - $response = $this->processBasicRequest($user); 61 - break; 62 - default: 63 - return new Aphront404Response(); 64 - } 65 - 19 + $response = $this->processBasicRequest($user); 66 20 if ($response instanceof AphrontResponse) { 67 21 return $response; 68 22 } 69 23 70 24 $content[] = $response; 71 25 72 - if ($user->getID()) { 73 - $nav->appendChild($content); 74 - } else { 75 - $nav = $this->buildSideNavView(); 76 - $nav->selectFilter('edit'); 77 - $nav->appendChild($content); 78 - } 79 - 80 - $nav->setCrumbs($crumbs); 81 26 return $this->buildApplicationPage( 82 - $nav, 27 + array( 28 + $crumbs, 29 + $content, 30 + ), 83 31 array( 84 32 'title' => pht('Edit User'), 85 33 'device' => true, ··· 102 50 $request = $this->getRequest(); 103 51 if ($request->isFormPost()) { 104 52 $welcome_checked = $request->getInt('welcome'); 105 - $is_new = !$user->getID(); 106 53 107 - if ($is_new) { 108 - $user->setUsername($request->getStr('username')); 109 - 110 - $new_email = $request->getStr('email'); 111 - if (!strlen($new_email)) { 112 - $errors[] = pht('Email is required.'); 113 - $e_email = pht('Required'); 114 - } else if (!PhabricatorUserEmail::isAllowedAddress($new_email)) { 115 - $e_email = pht('Invalid'); 116 - $errors[] = PhabricatorUserEmail::describeAllowedAddresses(); 117 - } else { 118 - $e_email = null; 119 - } 54 + $user->setUsername($request->getStr('username')); 120 55 56 + $new_email = $request->getStr('email'); 57 + if (!strlen($new_email)) { 58 + $errors[] = pht('Email is required.'); 59 + $e_email = pht('Required'); 60 + } else if (!PhabricatorUserEmail::isAllowedAddress($new_email)) { 61 + $e_email = pht('Invalid'); 62 + $errors[] = PhabricatorUserEmail::describeAllowedAddresses(); 63 + } else { 64 + $e_email = null; 121 65 } 66 + 122 67 $user->setRealName($request->getStr('realname')); 123 68 124 69 if (!strlen($user->getUsername())) { ··· 141 86 if (!$errors) { 142 87 try { 143 88 144 - if (!$is_new) { 145 - id(new PhabricatorUserEditor()) 146 - ->setActor($admin) 147 - ->updateUser($user); 148 - } else { 149 - $email = id(new PhabricatorUserEmail()) 150 - ->setAddress($new_email) 151 - ->setIsVerified(0); 89 + $email = id(new PhabricatorUserEmail()) 90 + ->setAddress($new_email) 91 + ->setIsVerified(0); 152 92 153 - // Automatically approve the user, since an admin is creating them. 154 - $user->setIsApproved(1); 93 + // Automatically approve the user, since an admin is creating them. 94 + $user->setIsApproved(1); 95 + 96 + id(new PhabricatorUserEditor()) 97 + ->setActor($admin) 98 + ->createNewUser($user, $email); 155 99 100 + if ($request->getStr('role') == 'agent') { 156 101 id(new PhabricatorUserEditor()) 157 102 ->setActor($admin) 158 - ->createNewUser($user, $email); 159 - 160 - if ($request->getStr('role') == 'agent') { 161 - id(new PhabricatorUserEditor()) 162 - ->setActor($admin) 163 - ->makeSystemAgentUser($user, true); 164 - } 165 - 103 + ->makeSystemAgentUser($user, true); 166 104 } 167 105 168 106 if ($welcome_checked) { ··· 170 108 } 171 109 172 110 $response = id(new AphrontRedirectResponse()) 173 - ->setURI('/people/edit/'.$user->getID().'/?saved=true'); 111 + ->setURI('/p/'.$user->getUsername().'/'); 174 112 return $response; 175 113 } catch (AphrontQueryDuplicateKeyException $ex) { 176 114 $errors[] = pht('Username and email must be unique.'); ··· 193 131 194 132 $form = new AphrontFormView(); 195 133 $form->setUser($admin); 196 - if ($user->getID()) { 197 - $form->setAction('/people/edit/'.$user->getID().'/'); 198 - } else { 199 - $form->setAction('/people/edit/'); 200 - } 134 + $form->setAction('/people/edit/'); 201 135 202 - if ($user->getID()) { 203 - $is_immutable = true; 204 - } else { 205 - $is_immutable = false; 206 - } 136 + $is_immutable = false; 207 137 208 138 $form 209 139 ->appendChild( ··· 220 150 ->setValue($user->getRealName()) 221 151 ->setError($e_realname)); 222 152 223 - if (!$user->getID()) { 224 - $form->appendChild( 225 - id(new AphrontFormTextControl()) 226 - ->setLabel(pht('Email')) 227 - ->setName('email') 228 - ->setDisabled($is_immutable) 229 - ->setValue($new_email) 230 - ->setCaption(PhabricatorUserEmail::describeAllowedAddresses()) 231 - ->setError($e_email)); 232 - } else { 233 - $email = $user->loadPrimaryEmail(); 234 - if ($email) { 235 - $status = $email->getIsVerified() ? 236 - pht('Verified') : pht('Unverified'); 237 - } else { 238 - $status = pht('No Email Address'); 239 - } 240 - 241 - $form->appendChild( 242 - id(new AphrontFormStaticControl()) 243 - ->setLabel(pht('Email')) 244 - ->setValue($status)); 245 - 246 - $form->appendChild( 247 - id(new AphrontFormCheckboxControl()) 248 - ->addCheckbox( 249 - 'welcome', 250 - 1, 251 - pht('Re-send "Welcome to Phabricator" email.'), 252 - false)); 253 - 254 - } 153 + $form->appendChild( 154 + id(new AphrontFormTextControl()) 155 + ->setLabel(pht('Email')) 156 + ->setName('email') 157 + ->setDisabled($is_immutable) 158 + ->setValue($new_email) 159 + ->setCaption(PhabricatorUserEmail::describeAllowedAddresses()) 160 + ->setError($e_email)); 255 161 256 162 $form->appendChild($this->getRoleInstructions()); 257 163 258 - if (!$user->getID()) { 259 - $form 260 - ->appendChild( 261 - id(new AphrontFormSelectControl()) 262 - ->setLabel(pht('Role')) 263 - ->setName('role') 264 - ->setValue('user') 265 - ->setOptions( 266 - array( 267 - 'user' => pht('Normal User'), 268 - 'agent' => pht('System Agent'), 269 - )) 270 - ->setCaption( 271 - pht('You can create a "system agent" account for bots, '. 272 - 'scripts, etc.'))) 273 - ->appendChild( 274 - id(new AphrontFormCheckboxControl()) 275 - ->addCheckbox( 276 - 'welcome', 277 - 1, 278 - pht('Send "Welcome to Phabricator" email.'), 279 - $welcome_checked)); 280 - } else { 281 - $roles = array(); 282 - 283 - if ($user->getIsSystemAgent()) { 284 - $roles[] = pht('System Agent'); 285 - } 286 - if ($user->getIsAdmin()) { 287 - $roles[] = pht('Admin'); 288 - } 289 - if ($user->getIsDisabled()) { 290 - $roles[] = pht('Disabled'); 291 - } 292 - if (!$user->getIsApproved()) { 293 - $roles[] = pht('Not Approved'); 294 - } 295 - if (!$roles) { 296 - $roles[] = pht('Normal User'); 297 - } 298 - 299 - $roles = implode(', ', $roles); 300 - 301 - $form->appendChild( 302 - id(new AphrontFormStaticControl()) 303 - ->setLabel(pht('Roles')) 304 - ->setValue($roles)); 305 - } 164 + $form 165 + ->appendChild( 166 + id(new AphrontFormSelectControl()) 167 + ->setLabel(pht('Role')) 168 + ->setName('role') 169 + ->setValue('user') 170 + ->setOptions( 171 + array( 172 + 'user' => pht('Normal User'), 173 + 'agent' => pht('System Agent'), 174 + )) 175 + ->setCaption( 176 + pht('You can create a "system agent" account for bots, '. 177 + 'scripts, etc.'))) 178 + ->appendChild( 179 + id(new AphrontFormCheckboxControl()) 180 + ->addCheckbox( 181 + 'welcome', 182 + 1, 183 + pht('Send "Welcome to Phabricator" email.'), 184 + $welcome_checked)); 306 185 307 186 $form 308 187 ->appendChild( 309 188 id(new AphrontFormSubmitControl()) 189 + ->addCancelButton($this->getApplicationURI()) 310 190 ->setValue(pht('Save'))); 311 191 312 - if ($user->getID()) { 313 - $title = pht('Edit User'); 314 - } else { 315 - $title = pht('Create New User'); 316 - } 192 + $title = pht('Create New User'); 317 193 318 194 $form_box = id(new PHUIObjectBoxView()) 319 195 ->setHeaderText($title)
+1 -1
src/applications/people/controller/PhabricatorPeopleEmpowerController.php
··· 21 21 return new Aphront404Response(); 22 22 } 23 23 24 - $profile_uri = '/p/'.$user->getUsername(); 24 + $profile_uri = '/p/'.$user->getUsername().'/'; 25 25 26 26 if ($user->getPHID() == $admin->getPHID()) { 27 27 return $this->newDialog()
-5
src/applications/people/controller/PhabricatorPeopleListController.php
··· 99 99 ->setName(pht('Approve')) 100 100 ->setWorkflow(true) 101 101 ->setHref($this->getApplicationURI('approve/'.$user_id.'/'))); 102 - } else { 103 - $item->addAction( 104 - id(new PHUIListItemView()) 105 - ->setIcon('edit') 106 - ->setHref($this->getApplicationURI('edit/'.$user_id.'/'))); 107 102 } 108 103 } 109 104
+4 -3
src/applications/people/controller/PhabricatorPeopleProfileController.php
··· 121 121 122 122 $actions->addAction( 123 123 id(new PhabricatorActionView()) 124 - ->setIcon('blame') 125 - ->setName(pht('Administrate User')) 126 - ->setHref($this->getApplicationURI('edit/'.$user->getID().'/'))); 124 + ->setIcon('message') 125 + ->setName(pht('Send Welcome Email')) 126 + ->setWorkflow(true) 127 + ->setHref($this->getApplicationURI('welcome/'.$user->getID().'/'))); 127 128 } 128 129 129 130 $properties = $this->buildPropertyView($user, $actions);
+8 -3
src/applications/people/controller/PhabricatorPeopleRenameController.php
··· 21 21 return new Aphront404Response(); 22 22 } 23 23 24 - $profile_uri = '/p/'.$user->getUsername(); 24 + $profile_uri = '/p/'.$user->getUsername().'/'; 25 25 26 26 $errors = array(); 27 27 ··· 75 75 $inst4 = pht( 76 76 'Users who rely on password authentication will need to reset their '. 77 77 'password after their username is changed (their username is part of '. 78 - 'the salt in the password hash). They will receive an email with '. 79 - 'instructions on how to do this.'); 78 + 'the salt in the password hash).'); 79 + 80 + $inst5 = pht( 81 + 'The user will receive an email notifying them that you changed their '. 82 + 'username, with instructions for logging in and resetting their '. 83 + 'password if necessary.'); 80 84 81 85 $form = id(new AphrontFormView()) 82 86 ->setUser($admin) ··· 103 107 ->appendParagraph($inst2) 104 108 ->appendParagraph($inst3) 105 109 ->appendParagraph($inst4) 110 + ->appendParagraph($inst5) 106 111 ->appendParagraph(null) 107 112 ->appendChild($form->buildLayoutView()) 108 113 ->addSubmitButton(pht('Rename User'))
+50
src/applications/people/controller/PhabricatorPeopleWelcomeController.php
··· 1 + <?php 2 + 3 + final class PhabricatorPeopleWelcomeController 4 + extends PhabricatorPeopleController { 5 + 6 + private $id; 7 + 8 + public function willProcessRequest(array $data) { 9 + $this->id = $data['id']; 10 + } 11 + 12 + public function processRequest() { 13 + $request = $this->getRequest(); 14 + $admin = $request->getUser(); 15 + 16 + $user = id(new PhabricatorPeopleQuery()) 17 + ->setViewer($admin) 18 + ->withIDs(array($this->id)) 19 + ->executeOne(); 20 + if (!$user) { 21 + return new Aphront404Response(); 22 + } 23 + 24 + $profile_uri = '/p/'.$user->getUsername().'/'; 25 + 26 + if ($request->isFormPost()) { 27 + $user->sendWelcomeEmail($admin); 28 + return id(new AphrontRedirectResponse())->setURI($profile_uri); 29 + } 30 + 31 + return $this->newDialog() 32 + ->setTitle(pht('Send Welcome Email')) 33 + ->appendParagraph( 34 + pht( 35 + 'This will send the user another copy of the "Welcome to '. 36 + 'Phabricator" email that users normally receive when their '. 37 + 'accounts are created.')) 38 + ->appendParagraph( 39 + pht( 40 + 'The email contains a link to log in to their account. Sending '. 41 + 'another copy of the email can be useful if the original was lost '. 42 + 'or never sent.')) 43 + ->appendParagraph( 44 + pht( 45 + 'The email will identify you as the sender.')) 46 + ->addSubmitButton(pht('Send Email')) 47 + ->addCancelButton($profile_uri); 48 + } 49 + 50 + }
-1
src/applications/settings/controller/PhabricatorSettingsMainController.php
··· 51 51 52 52 $key = $nav->selectFilter($this->key, head($panels)->getPanelKey()); 53 53 54 - 55 54 $panel = $panels[$key]; 56 55 $panel->setUser($this->getUser()); 57 56 $panel->setViewer($viewer);