@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<?php
2
3final class PhabricatorPolicyManagementUnlockWorkflow
4 extends PhabricatorPolicyManagementWorkflow {
5
6 protected function didConstruct() {
7 $this
8 ->setName('unlock')
9 ->setSynopsis(
10 pht(
11 'Unlock one or more objects by changing their view policies, edit '.
12 'policies, or owners.'))
13 ->setHelp(
14 pht(
15 'Identify each __object__ by passing an object name '.
16 '(like "T123") or a PHID (like "PHID-ABCD-1234...").'.
17 "\n\n".
18 'Not every type of object has an editable view policy, edit '.
19 'policy, or owner, so not all modes will work with all objects. '))
20 ->setExamples('**unlock** --view __user__ __object__ ...')
21 ->setArguments(
22 array(
23 array(
24 'name' => 'view',
25 'param' => 'username',
26 'help' => pht(
27 'Change the view policy of an object so that the specified '.
28 'user may view it.'),
29 ),
30 array(
31 'name' => 'edit',
32 'param' => 'username',
33 'help' => pht(
34 'Change the edit policy of an object so that the specified '.
35 'user may edit it.'),
36 ),
37 array(
38 'name' => 'owner',
39 'param' => 'username',
40 'help' => pht(
41 'Change the owner of an object to the specified user.'),
42 ),
43 array(
44 'name' => 'objects',
45 'wildcard' => true,
46 ),
47 ));
48 }
49
50 public function execute(PhutilArgumentParser $args) {
51 $viewer = $this->getViewer();
52
53 $object_names = $args->getArg('objects');
54 if (!$object_names) {
55 throw new PhutilArgumentUsageException(
56 pht('Specify the name of an object to unlock.'));
57 } else if (count($object_names) > 1) {
58 throw new PhutilArgumentUsageException(
59 pht('Specify the name of exactly one object to unlock.'));
60 }
61
62 $object_name = head($object_names);
63
64 $object = id(new PhabricatorObjectQuery())
65 ->setViewer($viewer)
66 ->withNames(array($object_name))
67 ->executeOne();
68 if (!$object) {
69 throw new PhutilArgumentUsageException(
70 pht(
71 'Unable to find any object with the specified name ("%s").',
72 $object_name));
73 }
74
75 $view_user = $this->loadUser($args->getArg('view'));
76 $edit_user = $this->loadUser($args->getArg('edit'));
77 $owner_user = $this->loadUser($args->getArg('owner'));
78
79 if (!$view_user && !$edit_user && !$owner_user) {
80 throw new PhutilArgumentUsageException(
81 pht(
82 'Choose which capabilities to unlock with "--view", "--edit", '.
83 'or "--owner".'));
84 }
85
86 $handle = id(new PhabricatorHandleQuery())
87 ->setViewer($viewer)
88 ->withPHIDs(array($object->getPHID()))
89 ->executeOne();
90
91 echo tsprintf(
92 "<bg:blue>** %s **</bg> %s\n",
93 pht('UNLOCKING'),
94 pht('Unlocking: %s', $handle->getFullName()));
95
96 $engine = PhabricatorUnlockEngine::newUnlockEngineForObject($object);
97
98 $xactions = array();
99 if ($view_user) {
100 $xactions[] = $engine->newUnlockViewTransactions($object, $view_user);
101 }
102 if ($edit_user) {
103 $xactions[] = $engine->newUnlockEditTransactions($object, $edit_user);
104 }
105 if ($owner_user) {
106 $xactions[] = $engine->newUnlockOwnerTransactions($object, $owner_user);
107 }
108 $xactions = array_mergev($xactions);
109
110 $policy_application = new PhabricatorPolicyApplication();
111 $content_source = $this->newContentSource();
112
113 $editor = $object->getApplicationTransactionEditor()
114 ->setActor($viewer)
115 ->setActingAsPHID($policy_application->getPHID())
116 ->setContinueOnMissingFields(true)
117 ->setContinueOnNoEffect(true)
118 ->setContentSource($content_source);
119
120 $editor->applyTransactions($object, $xactions);
121
122 echo tsprintf(
123 "<bg:green>** %s **</bg> %s\n",
124 pht('UNLOCKED'),
125 pht('Modified object policies.'));
126
127 $uri = $handle->getURI();
128 if (strlen($uri)) {
129 echo tsprintf(
130 "\n **%s**: __%s__\n\n",
131 pht('Object URI'),
132 PhabricatorEnv::getURI($uri));
133 }
134
135 return 0;
136 }
137
138 private function loadUser($username) {
139 $viewer = $this->getViewer();
140
141 if ($username === null) {
142 return null;
143 }
144
145 $user = id(new PhabricatorPeopleQuery())
146 ->setViewer($viewer)
147 ->withUsernames(array($username))
148 ->executeOne();
149
150 if (!$user) {
151 throw new PhutilArgumentUsageException(
152 pht(
153 'No user with username "%s" exists.',
154 $username));
155 }
156
157 return $user;
158 }
159
160}