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

Make it possible for applications to generate concrete subscriptions

Summary:
Ref T6881. This still doesn't "work" in any reasonable sense of the word, but gets us a bit further.

I'll build out the Phortune UI a little bit next, then look at implementing the Worker to do actual billing.

Test Plan:
- Allocated an instance and saw a Subscription generate properly.
- Saw subscription show up in the Phortune UI, albeit in a very limited way.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T6881

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

+97 -6
+3
src/applications/phortune/controller/PhortuneAccountViewController.php
··· 275 275 $subscriptions_uri = $this->getApplicationURI( 276 276 $account->getID().'/subscription/'); 277 277 278 + $handles = $this->loadViewerHandles(mpull($subscriptions, 'getPHID')); 279 + 278 280 $table = id(new PhortuneSubscriptionTableView()) 279 281 ->setUser($viewer) 282 + ->setHandles($handles) 280 283 ->setSubscriptions($subscriptions); 281 284 282 285 $header = id(new PHUIHeaderView())
+6 -3
src/applications/phortune/query/PhortuneSubscriptionQuery.php
··· 85 85 $subscription_map = mgroup($subscriptions, 'getSubscriptionClass'); 86 86 foreach ($subscription_map as $class => $class_subscriptions) { 87 87 $sub = newv($class, array()); 88 - $implementations += $sub->loadImplementationsForSubscriptions( 88 + $impl_objects = $sub->loadImplementationsForRefs( 89 89 $this->getViewer(), 90 - $class_subscriptions); 90 + mpull($class_subscriptions, 'getSubscriptionRef')); 91 + 92 + $implementations += mpull($impl_objects, null, 'getRef'); 91 93 } 92 94 93 95 foreach ($subscriptions as $key => $subscription) { 94 - $implementation = idx($implementations, $key); 96 + $ref = $subscription->getSubscriptionRef(); 97 + $implementation = idx($implementations, $ref); 95 98 if (!$implementation) { 96 99 unset($subscriptions[$key]); 97 100 continue;
+1
src/applications/phortune/query/PhortuneSubscriptionSearchEngine.php
··· 138 138 139 139 $table = id(new PhortuneSubscriptionTableView()) 140 140 ->setUser($viewer) 141 + ->setHandles($handles) 141 142 ->setSubscriptions($subscriptions); 142 143 143 144 $merchant = $this->getMerchant();
+87 -3
src/applications/phortune/storage/PhortuneSubscription.php
··· 58 58 PhortuneSubscriptionPHIDType::TYPECONST); 59 59 } 60 60 61 - public static function initializeNewSubscription() { 62 - return id(new PhortuneSubscription()); 61 + public static function initializeNewSubscription( 62 + PhortuneAccount $account, 63 + PhortuneMerchant $merchant, 64 + PhabricatorUser $author, 65 + PhortuneSubscriptionImplementation $implementation, 66 + PhabricatorTriggerClock $clock) { 67 + 68 + $trigger = id(new PhabricatorWorkerTrigger()) 69 + ->setClock($clock); 70 + 71 + return id(new PhortuneSubscription()) 72 + ->setStatus(self::STATUS_ACTIVE) 73 + ->setAccountPHID($account->getPHID()) 74 + ->attachAccount($account) 75 + ->setMerchantPHID($merchant->getPHID()) 76 + ->attachMerchant($merchant) 77 + ->setAuthorPHID($author->getPHID()) 78 + ->setSubscriptionClass(get_class($implementation)) 79 + ->setSubscriptionRef($implementation->getRef()) 80 + ->attachImplementation($implementation) 81 + ->attachTrigger($trigger); 63 82 } 64 83 65 84 public function attachImplementation( 66 85 PhortuneSubscriptionImplementation $impl) { 67 86 $this->implementation = $impl; 87 + return $this; 68 88 } 69 89 70 90 public function getImplementation() { 71 91 return $this->assertAttached($this->implementation); 72 92 } 73 93 94 + public function attachAccount(PhortuneAccount $account) { 95 + $this->account = $account; 96 + return $this; 97 + } 98 + 99 + public function getAccount() { 100 + return $this->assertAttached($this->account); 101 + } 102 + 103 + public function attachMerchant(PhortuneMerchant $merchant) { 104 + $this->merchant = $merchant; 105 + return $this; 106 + } 107 + 108 + public function getMerchant() { 109 + return $this->assertAttached($this->merchant); 110 + } 111 + 112 + public function attachTrigger(PhabricatorWorkerTrigger $trigger) { 113 + $this->trigger = $trigger; 114 + return $this; 115 + } 116 + 117 + public function getTrigger() { 118 + return $this->assertAttached($this->trigger); 119 + } 120 + 74 121 public function save() { 75 122 $this->subscriptionClassKey = PhabricatorHash::digestForIndex( 76 123 $this->subscriptionClass); ··· 78 125 $this->subscriptionRefKey = PhabricatorHash::digestForIndex( 79 126 $this->subscriptionRef); 80 127 81 - return parent::save(); 128 + $trigger = $this->getTrigger(); 129 + $is_new = (!$this->getID()); 130 + 131 + $this->openTransaction(); 132 + 133 + // If we're saving this subscription for the first time, we're also 134 + // going to set up the trigger for it. 135 + if ($is_new) { 136 + $trigger_phid = PhabricatorPHID::generateNewPHID( 137 + PhabricatorWorkerTriggerPHIDType::TYPECONST); 138 + $this->setTriggerPHID($trigger_phid); 139 + } 140 + 141 + $result = parent::save(); 142 + 143 + if ($is_new) { 144 + $trigger_action = new PhabricatorScheduleTaskTriggerAction( 145 + array( 146 + 'class' => 'PhortuneSubscriptionWorker', 147 + 'data' => array( 148 + 'subscriptionPHID' => $this->getPHID(), 149 + ), 150 + 'options' => array( 151 + 'objectPHID' => $this->getPHID(), 152 + 'priority' => PhabricatorWorker::PRIORITY_BULK, 153 + ), 154 + )); 155 + 156 + $trigger->setAction($trigger_action); 157 + $trigger->save(); 158 + } 159 + $this->saveTransaction(); 160 + 161 + return $result; 162 + } 163 + 164 + public function getSubscriptionName() { 165 + return $this->getImplementation()->getName($this); 82 166 } 83 167 84 168