@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
at recaptime-dev/main 191 lines 5.1 kB view raw
1<?php 2 3abstract class PhabricatorManagementWorkflow extends PhutilArgumentWorkflow { 4 5 public function isExecutable() { 6 return true; 7 } 8 9 public function getViewer() { 10 // Some day, we might provide a more general viewer mechanism to scripts. 11 // For now, workflows can call this method for convenience and future 12 // flexibility. 13 return PhabricatorUser::getOmnipotentUser(); 14 } 15 16 protected function parseTimeArgument($time) { 17 if (!strlen($time)) { 18 return null; 19 } 20 21 $epoch = strtotime($time); 22 if ($epoch <= 0) { 23 throw new PhutilArgumentUsageException( 24 pht('Unable to parse time "%s".', $time)); 25 } 26 return $epoch; 27 } 28 29 protected function newContentSource() { 30 return PhabricatorContentSource::newForSource( 31 PhabricatorConsoleContentSource::SOURCECONST); 32 } 33 34 protected function logInfo($label, $message) { 35 $this->logRaw( 36 tsprintf( 37 "**<bg:blue> %s </bg>** %s\n", 38 $label, 39 $message)); 40 } 41 42 protected function logOkay($label, $message) { 43 $this->logRaw( 44 tsprintf( 45 "**<bg:green> %s </bg>** %s\n", 46 $label, 47 $message)); 48 } 49 50 protected function logWarn($label, $message) { 51 $this->logRaw( 52 tsprintf( 53 "**<bg:yellow> %s </bg>** %s\n", 54 $label, 55 $message)); 56 } 57 58 protected function logFail($label, $message) { 59 $this->logRaw( 60 tsprintf( 61 "**<bg:red> %s </bg>** %s\n", 62 $label, 63 $message)); 64 } 65 66 private function logRaw($message) { 67 fprintf(STDERR, '%s', $message); 68 } 69 70 final protected function loadUsersFromArguments(array $identifiers) { 71 if (!$identifiers) { 72 return array(); 73 } 74 75 $ids = array(); 76 $phids = array(); 77 $usernames = array(); 78 79 $user_type = PhabricatorPeopleUserPHIDType::TYPECONST; 80 81 foreach ($identifiers as $identifier) { 82 // If the value is a user PHID, treat as a PHID. 83 if (phid_get_type($identifier) === $user_type) { 84 $phids[$identifier] = $identifier; 85 continue; 86 } 87 88 // If the value is "@..." and then some text, treat it as a username. 89 if ((strlen($identifier) > 1) && ($identifier[0] == '@')) { 90 $usernames[$identifier] = substr($identifier, 1); 91 continue; 92 } 93 94 // If the value is digits, treat it as both an ID and a username. 95 // Entirely numeric usernames, like "1234", are valid. 96 if (ctype_digit($identifier)) { 97 $ids[$identifier] = $identifier; 98 $usernames[$identifier] = $identifier; 99 continue; 100 } 101 102 // Otherwise, treat it as an unescaped username. 103 $usernames[$identifier] = $identifier; 104 } 105 106 $viewer = $this->getViewer(); 107 $results = array(); 108 109 if ($phids) { 110 $users = id(new PhabricatorPeopleQuery()) 111 ->setViewer($viewer) 112 ->withPHIDs($phids) 113 ->execute(); 114 foreach ($users as $user) { 115 $phid = $user->getPHID(); 116 $results[$phid][] = $user; 117 } 118 } 119 120 if ($usernames) { 121 $users = id(new PhabricatorPeopleQuery()) 122 ->setViewer($viewer) 123 ->withUsernames($usernames) 124 ->execute(); 125 126 $reverse_map = array(); 127 foreach ($usernames as $identifier => $username) { 128 $username = phutil_utf8_strtolower($username); 129 $reverse_map[$username][] = $identifier; 130 } 131 132 foreach ($users as $user) { 133 $username = $user->getUsername(); 134 $username = phutil_utf8_strtolower($username); 135 136 $reverse_identifiers = idx($reverse_map, $username, array()); 137 138 if (count($reverse_identifiers) > 1) { 139 throw new PhutilArgumentUsageException( 140 pht( 141 'Multiple user identifiers (%s) correspond to the same user. '. 142 'Identify each user exactly once.', 143 implode(', ', $reverse_identifiers))); 144 } 145 146 foreach ($reverse_identifiers as $reverse_identifier) { 147 $results[$reverse_identifier][] = $user; 148 } 149 } 150 } 151 152 if ($ids) { 153 $users = id(new PhabricatorPeopleQuery()) 154 ->setViewer($viewer) 155 ->withIDs($ids) 156 ->execute(); 157 158 foreach ($users as $user) { 159 $id = $user->getID(); 160 $results[$id][] = $user; 161 } 162 } 163 164 $list = array(); 165 foreach ($identifiers as $identifier) { 166 $users = idx($results, $identifier, array()); 167 if (!$users) { 168 throw new PhutilArgumentUsageException( 169 pht( 170 'No user "%s" exists. Specify users by username, ID, or PHID.', 171 $identifier)); 172 } 173 174 if (count($users) > 1) { 175 // This can happen if you have a user "@25", a user with ID 25, and 176 // specify "--user 25". You can disambiguate this by specifying 177 // "--user @25". 178 throw new PhutilArgumentUsageException( 179 pht( 180 'Identifier "%s" matches multiple users. Specify each user '. 181 'unambiguously with "@username" or by using user PHIDs.', 182 $identifier)); 183 } 184 185 $list[] = head($users); 186 } 187 188 return $list; 189 } 190 191}