@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
3abstract class NuanceCommandImplementation
4 extends Phobject {
5
6 private $actor;
7
8 private $transactionQueue = array();
9
10 final public function setActor(PhabricatorUser $actor) {
11 $this->actor = $actor;
12 return $this;
13 }
14
15 final public function getActor() {
16 return $this->actor;
17 }
18
19 abstract public function getCommandName();
20 abstract public function canApplyToItem(NuanceItem $item);
21
22 public function canApplyImmediately(
23 NuanceItem $item,
24 NuanceItemCommand $command) {
25 return false;
26 }
27
28 abstract protected function executeCommand(
29 NuanceItem $item,
30 NuanceItemCommand $command);
31
32 final public function applyCommand(
33 NuanceItem $item,
34 NuanceItemCommand $command) {
35
36 $command_key = $command->getCommand();
37 $implementation_key = $this->getCommandKey();
38 if ($command_key !== $implementation_key) {
39 throw new Exception(
40 pht(
41 'This command implementation("%s") can not apply a command of a '.
42 'different type ("%s").',
43 $implementation_key,
44 $command_key));
45 }
46
47 if (!$this->canApplyToItem($item)) {
48 throw new Exception(
49 pht(
50 'This command implementation ("%s") can not be applied to an '.
51 'item of type "%s".',
52 $implementation_key,
53 $item->getItemType()));
54 }
55
56 $this->transactionQueue = array();
57
58 $command_type = NuanceItemCommandTransaction::TRANSACTIONTYPE;
59 $command_xaction = $this->newTransaction($command_type);
60
61 $result = $this->executeCommand($item, $command);
62
63 $xactions = $this->transactionQueue;
64 $this->transactionQueue = array();
65
66 $command_xaction->setNewValue(
67 array(
68 'command' => $command->getCommand(),
69 'parameters' => $command->getParameters(),
70 'result' => $result,
71 ));
72
73 // TODO: Maybe preserve the actor's original content source?
74 $source = PhabricatorContentSource::newForSource(
75 PhabricatorDaemonContentSource::SOURCECONST);
76
77 $actor = $this->getActor();
78
79 id(new NuanceItemEditor())
80 ->setActor($actor)
81 ->setActingAsPHID($command->getAuthorPHID())
82 ->setContentSource($source)
83 ->setContinueOnMissingFields(true)
84 ->setContinueOnNoEffect(true)
85 ->applyTransactions($item, $xactions);
86 }
87
88 final public function getCommandKey() {
89 return $this->getPhobjectClassConstant('COMMANDKEY');
90 }
91
92 final public static function getAllCommands() {
93 return id(new PhutilClassMapQuery())
94 ->setAncestorClass(self::class)
95 ->setUniqueMethod('getCommandKey')
96 ->execute();
97 }
98
99 protected function newTransaction($type) {
100 $xaction = id(new NuanceItemTransaction())
101 ->setTransactionType($type);
102
103 $this->transactionQueue[] = $xaction;
104
105 return $xaction;
106 }
107
108 protected function newStatusTransaction($status) {
109 return $this->newTransaction(NuanceItemStatusTransaction::TRANSACTIONTYPE)
110 ->setNewValue($status);
111 }
112
113}