Rough cut of herald transcripts and Differential adapter.
This commit is contained in:
		| @@ -267,6 +267,7 @@ return array( | ||||
|     'image/jpeg'  => 'image/jpeg', | ||||
|     'image/jpg'   => 'image/jpg', | ||||
|     'image/png'   => 'image/png', | ||||
|     'image/gif'   => 'image/gif', | ||||
|     'text/plain'  => 'text/plain; charset=utf-8', | ||||
|   ), | ||||
|  | ||||
|   | ||||
| @@ -188,6 +188,7 @@ phutil_register_library_map(array( | ||||
|     'HeraldController' => 'applications/herald/controller/base', | ||||
|     'HeraldDAO' => 'applications/herald/storage/base', | ||||
|     'HeraldDeleteController' => 'applications/herald/controller/delete', | ||||
|     'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/differential', | ||||
|     'HeraldDryRunAdapter' => 'applications/herald/adapter/dryrun', | ||||
|     'HeraldEffect' => 'applications/herald/engine/effect', | ||||
|     'HeraldEngine' => 'applications/herald/engine/engine', | ||||
| @@ -204,6 +205,8 @@ phutil_register_library_map(array( | ||||
|     'HeraldRuleTranscript' => 'applications/herald/storage/transcript/rule', | ||||
|     'HeraldTestConsoleController' => 'applications/herald/controller/test', | ||||
|     'HeraldTranscript' => 'applications/herald/storage/transcript/base', | ||||
|     'HeraldTranscriptController' => 'applications/herald/controller/transcript', | ||||
|     'HeraldTranscriptListController' => 'applications/herald/controller/transcriptlist', | ||||
|     'HeraldValueTypeConfig' => 'applications/herald/config/valuetype', | ||||
|     'Javelin' => 'infrastructure/javelin/api', | ||||
|     'LiskDAO' => 'storage/lisk/dao', | ||||
| @@ -539,6 +542,7 @@ phutil_register_library_map(array( | ||||
|     'HeraldController' => 'PhabricatorController', | ||||
|     'HeraldDAO' => 'PhabricatorLiskDAO', | ||||
|     'HeraldDeleteController' => 'HeraldController', | ||||
|     'HeraldDifferentialRevisionAdapter' => 'HeraldObjectAdapter', | ||||
|     'HeraldDryRunAdapter' => 'HeraldObjectAdapter', | ||||
|     'HeraldHomeController' => 'HeraldController', | ||||
|     'HeraldNewController' => 'HeraldController', | ||||
| @@ -546,6 +550,8 @@ phutil_register_library_map(array( | ||||
|     'HeraldRuleController' => 'HeraldController', | ||||
|     'HeraldTestConsoleController' => 'HeraldController', | ||||
|     'HeraldTranscript' => 'HeraldDAO', | ||||
|     'HeraldTranscriptController' => 'HeraldController', | ||||
|     'HeraldTranscriptListController' => 'HeraldController', | ||||
|     'ManiphestController' => 'PhabricatorController', | ||||
|     'ManiphestDAO' => 'PhabricatorLiskDAO', | ||||
|     'ManiphestTask' => 'ManiphestDAO', | ||||
|   | ||||
| @@ -225,7 +225,8 @@ class AphrontDefaultApplicationConfiguration | ||||
|         'delete/(?P<id>\d+)/$' => 'HeraldDeleteController', | ||||
|         'test/$' => 'HeraldTestConsoleController', | ||||
|         'transcript/$' => 'HeraldTranscriptListController', | ||||
|         'transcript/(?P<id>\d+)/$' => 'HeraldTranscriptController', | ||||
|         'transcript/(?P<id>\d+)/(?:(?P<filter>\w+)/)?$' | ||||
|           => 'HeraldTranscriptController', | ||||
|       ), | ||||
|  | ||||
|     ); | ||||
|   | ||||
| @@ -38,6 +38,11 @@ class DifferentialRevisionViewController extends DifferentialController { | ||||
|  | ||||
|     $diffs = $revision->loadDiffs(); | ||||
|  | ||||
|     if (!$diffs) { | ||||
|       throw new Exception( | ||||
|         "This revision has no diffs. Something has gone quite wrong."); | ||||
|     } | ||||
|  | ||||
|     $diff_vs = $request->getInt('vs'); | ||||
|     $target = end($diffs); | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,257 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * Copyright 2011 Facebook, Inc. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| class HeraldDifferentialRevisionAdapter extends HeraldObjectAdapter { | ||||
|  | ||||
|   protected $revision; | ||||
|   protected $changesets; | ||||
|   protected $diff = null; | ||||
|  | ||||
|   protected $explicitCCs; | ||||
|   protected $explicitReviewers; | ||||
|   protected $forbiddenCCs; | ||||
|   protected $forbiddenReviewers; | ||||
|  | ||||
|   protected $newCCs = array(); | ||||
|   protected $remCCs = array(); | ||||
|  | ||||
|   public function __construct(DifferentialRevision $revision) { | ||||
|     $revision->loadRelationships(); | ||||
|     $this->revision = $revision; | ||||
|   } | ||||
|  | ||||
|   public function setDiff(Diff $diff) { | ||||
|     $this->diff = $diff; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function setExplicitCCs($explicit_ccs) { | ||||
|     $this->explicitCCs = $explicit_ccs; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function setExplicitReviewers($explicit_reviewers) { | ||||
|     $this->explicitReviewers = $explicit_reviewers; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function setForbiddenCCs($forbidden_ccs) { | ||||
|     $this->forbiddenCCs = $forbidden_ccs; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function setForbiddenReviewers($forbidden_reviewers) { | ||||
|     $this->forbiddenReviewers = $forbidden_reviewers; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function getCCsAddedByHerald() { | ||||
|     return array_diff_key($this->newCCs, $this->remCCs); | ||||
|   } | ||||
|  | ||||
|   public function getCCsRemovedByHerald() { | ||||
|     return $this->remCCs; | ||||
|   } | ||||
|  | ||||
|   public function getPHID() { | ||||
|     return $this->revision->getPHID(); | ||||
|   } | ||||
|  | ||||
|   public function getHeraldName() { | ||||
|     return $this->revision->getTitle(); | ||||
|   } | ||||
|  | ||||
|   public function getHeraldTypeName() { | ||||
|     return HeraldContentTypeConfig::CONTENT_TYPE_DIFFERENTIAL; | ||||
|   } | ||||
|  | ||||
|   protected function loadChangesets() { | ||||
|     if ($this->changesets) { | ||||
|       return $this->changesets; | ||||
|     } | ||||
|     $diff = $this->loadDiff(); | ||||
|     $changes = $diff->getChangesets(); | ||||
|     return ($this->changesets = $changes); | ||||
|   } | ||||
|  | ||||
|   protected function loadDiff() { | ||||
|     if ($this->diff === null) { | ||||
|       $this->diff = $this->revision->getActiveDiff(); | ||||
|     } | ||||
|     return $this->diff; | ||||
|   } | ||||
|  | ||||
|   protected function getContentDictionary() { | ||||
|     $changes = $this->loadChangesets(); | ||||
|  | ||||
|     $hunks = array(); | ||||
|     if ($changes) { | ||||
|       $hunks = id(new DifferentialHunk())->loadAllwhere( | ||||
|         'changesetID in (%Ld)', | ||||
|         mpull($changes, 'getID')); | ||||
|     } | ||||
|  | ||||
|     $dict = array(); | ||||
|     $hunks = mgroup($hunks, 'getChangesetID'); | ||||
|     $changes = mpull($changes, null, 'getID'); | ||||
|     foreach ($changes as $id => $change) { | ||||
|       $filename = $change->getFilename(); | ||||
|       $content = array(); | ||||
|       foreach (idx($hunks, $id, array()) as $hunk) { | ||||
|         $content[] = $hunk->makeChanges(); | ||||
|       } | ||||
|       $dict[$filename] = implode("\n", $content); | ||||
|     } | ||||
|  | ||||
|     return $dict; | ||||
|   } | ||||
|  | ||||
|   public function getHeraldField($field) { | ||||
|     switch ($field) { | ||||
|       case HeraldFieldConfig::FIELD_TITLE: | ||||
|         return $this->revision->getTitle(); | ||||
|         break; | ||||
|       case HeraldFieldConfig::FIELD_BODY: | ||||
|         return $this->revision->getSummary()."\n". | ||||
|                $this->revision->getTestPlan(); | ||||
|         break; | ||||
|       case HeraldFieldConfig::FIELD_AUTHOR: | ||||
|         return $this->revision->getAuthorPHID(); | ||||
|         break; | ||||
|       case HeraldFieldConfig::FIELD_DIFF_FILE: | ||||
|         $changes = $this->loadChangesets(); | ||||
|         return array_values(mpull($changes, 'getFilename')); | ||||
|       case HeraldFieldConfig::FIELD_CC: | ||||
|         if (isset($this->explicitCCs)) { | ||||
|           return array_keys($this->explicitCCs); | ||||
|         } else { | ||||
|           return $this->revision->getCCPHIDs(); | ||||
|         } | ||||
|       case HeraldFieldConfig::FIELD_REVIEWERS: | ||||
|         if (isset($this->explicitReviewers)) { | ||||
|           return array_keys($this->explicitReviewers); | ||||
|         } else { | ||||
|           return $this->revision->getReviewers(); | ||||
|         } | ||||
| /* TODO | ||||
|       case HeraldFieldConfig::FIELD_REPOSITORY: | ||||
|         $id = $this->revision->getRepositoryID(); | ||||
|         if (!$id) { | ||||
|           return null; | ||||
|         } | ||||
|         require_module_lazy('intern/repository'); | ||||
|         $repository = RepositoryRef::getByID($id); | ||||
|         if (!$repository) { | ||||
|           return null; | ||||
|         } | ||||
|         return $repository->getFBID(); | ||||
| */ | ||||
|       case HeraldFieldConfig::FIELD_DIFF_CONTENT: | ||||
|         return $this->getContentDictionary(); | ||||
| /* TODO | ||||
|       case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE: | ||||
|         return mpull( | ||||
|           DiffOwners::getPackages($this->loadDiff()), | ||||
|           'getFBID'); | ||||
| */ | ||||
| /* TODO | ||||
|       case HeraldFieldConfig::FIELD_AFFECTED_PACKAGE_OWNER: | ||||
|         return DiffOwners::getOwners($this->loadDiff()); | ||||
| */ | ||||
|       default: | ||||
|         throw new Exception("Invalid field '{$field}'."); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public function applyHeraldEffects(array $effects) { | ||||
|     $result = array(); | ||||
|     if ($this->explicitCCs) { | ||||
|       $effect = new HeraldEffect(); | ||||
|       $effect->setAction(HeraldActionConfig::ACTION_ADD_CC); | ||||
|       $effect->setTarget(array_keys($this->explicitCCs)); | ||||
|       $effect->setReason( | ||||
|         'CCs provided explicitly by revision author or carried over from a '. | ||||
|         'previous version of the revision.'); | ||||
|       $result[] = new HeraldApplyTranscript( | ||||
|         $effect, | ||||
|         true, | ||||
|         'Added addresses to CC list.'); | ||||
|     } | ||||
|  | ||||
|     $forbidden_ccs = array_fill_keys( | ||||
|       nonempty($this->forbiddenCCs, array()), | ||||
|       true); | ||||
|  | ||||
|     foreach ($effects as $effect) { | ||||
|       $action = $effect->getAction(); | ||||
|       switch ($action) { | ||||
|         case HeraldActionConfig::ACTION_NOTHING: | ||||
|           $result[] = new HeraldApplyTranscript( | ||||
|             $effect, | ||||
|             true, | ||||
|             'OK, did nothing.'); | ||||
|           break; | ||||
|         case HeraldActionConfig::ACTION_ADD_CC: | ||||
|           $base_target = $effect->getTarget(); | ||||
|           $forbidden = array(); | ||||
|           foreach ($base_target as $key => $fbid) { | ||||
|             if (isset($forbidden_ccs[$fbid])) { | ||||
|               $forbidden[] = $fbid; | ||||
|               unset($base_target[$key]); | ||||
|             } else { | ||||
|               $this->newCCs[$fbid] = true; | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           if ($forbidden) { | ||||
|             $failed = clone $effect; | ||||
|             $failed->setTarget($forbidden); | ||||
|             if ($base_target) { | ||||
|               $effect->setTarget($base_target); | ||||
|               $result[] = new HeraldApplyTranscript( | ||||
|                 $effect, | ||||
|                 true, | ||||
|                 'Added these addresses to CC list. Others could not be added.'); | ||||
|             } | ||||
|             $result[] = new HeraldApplyTranscript( | ||||
|               $failed, | ||||
|               false, | ||||
|               'CC forbidden, these addresses have unsubscribed.'); | ||||
|           } else { | ||||
|             $result[] = new HeraldApplyTranscript( | ||||
|               $effect, | ||||
|               true, | ||||
|               'Added addresses to CC list.'); | ||||
|           } | ||||
|           break; | ||||
|         case HeraldActionConfig::ACTION_REMOVE_CC: | ||||
|           foreach ($effect->getTarget() as $fbid) { | ||||
|             $this->remCCs[$fbid] = true; | ||||
|           } | ||||
|           $result[] = new HeraldApplyTranscript( | ||||
|             $effect, | ||||
|             true, | ||||
|             'Removed addresses from CC list.'); | ||||
|           break; | ||||
|         default: | ||||
|           throw new Exception("No rules to handle action '{$action}'."); | ||||
|       } | ||||
|     } | ||||
|     return $result; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/applications/herald/adapter/differential/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/applications/herald/adapter/differential/__init__.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| <?php | ||||
| /** | ||||
|  * This file is automatically generated. Lint this module to rebuild it. | ||||
|  * @generated | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| phutil_require_module('phabricator', 'applications/differential/storage/hunk'); | ||||
| phutil_require_module('phabricator', 'applications/herald/adapter/base'); | ||||
| phutil_require_module('phabricator', 'applications/herald/config/action'); | ||||
| phutil_require_module('phabricator', 'applications/herald/config/contenttype'); | ||||
| phutil_require_module('phabricator', 'applications/herald/config/field'); | ||||
| phutil_require_module('phabricator', 'applications/herald/engine/effect'); | ||||
| phutil_require_module('phabricator', 'applications/herald/storage/transcript/apply'); | ||||
|  | ||||
| phutil_require_module('phutil', 'utils'); | ||||
|  | ||||
|  | ||||
| phutil_require_source('HeraldDifferentialRevisionAdapter.php'); | ||||
| @@ -444,7 +444,7 @@ class HeraldRuleController extends HeraldController { | ||||
|     return array( | ||||
|       'source' => array( | ||||
|         'email'       => '/typeahead/common/mailable/', | ||||
|         'user'        => '/typeahead/common/user/', | ||||
|         'user'        => '/typeahead/common/users/', | ||||
|         'repository'  => '/typeahead/common/repository/', | ||||
| /* | ||||
|         'tag'         => '/datasource/tag/', | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
|  | ||||
| phutil_require_module('phabricator', 'aphront/response/redirect'); | ||||
| phutil_require_module('phabricator', 'applications/differential/storage/revision'); | ||||
| phutil_require_module('phabricator', 'applications/herald/adapter/differential'); | ||||
| phutil_require_module('phabricator', 'applications/herald/adapter/dryrun'); | ||||
| phutil_require_module('phabricator', 'applications/herald/controller/base'); | ||||
| phutil_require_module('phabricator', 'applications/herald/engine/engine'); | ||||
|   | ||||
| @@ -0,0 +1,543 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * Copyright 2011 Facebook, Inc. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| class HeraldTranscriptController extends HeraldController { | ||||
|  | ||||
|   const FILTER_AFFECTED = 'affected'; | ||||
|   const FILTER_OWNED    = 'owned'; | ||||
|   const FILTER_ALL      = 'all'; | ||||
|  | ||||
|   private $id; | ||||
|   private $filter; | ||||
|   private $handles; | ||||
|  | ||||
|   public function willProcessRequest(array $data) { | ||||
|     $this->id = $data['id']; | ||||
|     $map = $this->getFilterMap(); | ||||
|     $this->filter = idx($data, 'filter'); | ||||
|     if (empty($map[$this->filter])) { | ||||
|       $this->filter = self::FILTER_AFFECTED; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public function processRequest() { | ||||
|  | ||||
|     $xscript = id(new HeraldTranscript())->load($this->id); | ||||
|     if (!$xscript) { | ||||
|       throw new Exception('Uknown transcript!'); | ||||
|     } | ||||
|  | ||||
|     $field_names = HeraldFieldConfig::getFieldMap(); | ||||
|     $condition_names = HeraldConditionConfig::getConditionMap(); | ||||
|     $action_names = HeraldActionConfig::getActionMap(); | ||||
|  | ||||
|     require_celerity_resource('herald-test-css'); | ||||
|  | ||||
|     $filter = $this->getFilterPHIDs(); | ||||
|     $this->filterTranscript($xscript, $filter); | ||||
|     $phids = array_merge($filter, $this->getTranscriptPHIDs($xscript)); | ||||
|     $phids = array_unique($phids); | ||||
|     $phids = array_filter($phids); | ||||
|  | ||||
|     $handles = id(new PhabricatorObjectHandleData($phids)) | ||||
|       ->loadHandles(); | ||||
|     $this->handles = $handles; | ||||
|  | ||||
|     $object_xscript = $xscript->getObjectTranscript(); | ||||
|  | ||||
|     $nav = $this->buildSideNav(); | ||||
|  | ||||
|     $apply_xscript_panel = $this->buildApplyTranscriptPanel( | ||||
|       $xscript); | ||||
|     $nav->appendChild($apply_xscript_panel); | ||||
|  | ||||
|     $action_xscript_panel = $this->buildActionTranscriptPanel( | ||||
|       $xscript); | ||||
|     $nav->appendChild($action_xscript_panel); | ||||
|  | ||||
|     $object_xscript_panel = $this->buildObjectTranscriptPanel( | ||||
|       $xscript); | ||||
|     $nav->appendChild($object_xscript_panel); | ||||
|  | ||||
| /* | ||||
|  | ||||
|  | ||||
|     $notice = null; | ||||
|     if ($xscript->getDryRun()) { | ||||
|       $notice = | ||||
|         <tools:notice title="Dry Run"> | ||||
|           This was a dry run to test Herald rules, no actions were executed. | ||||
|         </tools:notice>; | ||||
|     } | ||||
|  | ||||
|     if (!$object_xscript) { | ||||
|       $notice = | ||||
|         <x:frag> | ||||
|           <tools:notice title="Old Transcript"> | ||||
|             Details of this transcript have been discarded. Full transcripts | ||||
|             are retained for 30 days. | ||||
|           </tools:notice> | ||||
|           {$notice} | ||||
|         </x:frag>; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     return | ||||
|       <herald:standard-page title="Transcript"> | ||||
|         <div style="padding: 1em;"> | ||||
|           <tools:side-nav items={$this->renderNavItems()}> | ||||
|             {$notice} | ||||
|             {$apply_xscript_markup} | ||||
|             {$rule_table} | ||||
|             {$object_xscript_table} | ||||
|           </tools:side-nav> | ||||
|         </div> | ||||
|       </herald:standard-page>; | ||||
| */ | ||||
|  | ||||
|     return $this->buildStandardPageResponse( | ||||
|       $nav, | ||||
|       array( | ||||
|         'title' => 'Transcript', | ||||
|       )); | ||||
|   } | ||||
|  | ||||
|   protected function renderConditionTestValue($condition, $handles) { | ||||
|     $value = $condition->getTestValue(); | ||||
|     if (!is_scalar($value) && $value !== null) { | ||||
|       foreach ($value as $key => $phid) { | ||||
|         $handle = idx($handles, $phid); | ||||
|         if ($handle) { | ||||
|           $value[$key] = $handle->getName(); | ||||
|         } else { | ||||
|           // This shouldn't ever really happen as we are supposed to have | ||||
|           // grabbed handles for everything, but be super liberal in what | ||||
|           // we accept here since we expect all sorts of weird issues as we | ||||
|           // version the system. | ||||
|           $value[$key] = 'Unknown Object #'.$phid; | ||||
|         } | ||||
|       } | ||||
|       sort($value); | ||||
|       $value = implode(', ', $value); | ||||
|     } | ||||
|  | ||||
|     return | ||||
|       '<span class="condition-test-value">'. | ||||
|         phutil_escape_html($value). | ||||
|       '</span>'; | ||||
|   } | ||||
|  | ||||
|   private function buildSideNav() { | ||||
|     $nav = new AphrontSideNavView(); | ||||
|  | ||||
|     $items = array(); | ||||
|     $filters = $this->getFilterMap(); | ||||
|     foreach ($filters as $key => $name) { | ||||
|       $nav->addNavItem( | ||||
|         phutil_render_tag( | ||||
|           'a', | ||||
|           array( | ||||
|             'href' => '/herald/transcript/'.$this->id.'/'.$key.'/', | ||||
|             'class' => | ||||
|               ($key == $this->filter) | ||||
|                 ? 'aphront-side-nav-selected' | ||||
|                 : null, | ||||
|           ), | ||||
|           phutil_escape_html($name))); | ||||
|     } | ||||
|  | ||||
|     return $nav; | ||||
|   } | ||||
|  | ||||
|   protected function getFilterMap() { | ||||
|     return array( | ||||
|       self::FILTER_AFFECTED => 'Rules that Affected Me', | ||||
|       self::FILTER_OWNED    => 'Rules I Own', | ||||
|       self::FILTER_ALL      => 'All Rules', | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   protected function getFilterPHIDs() { | ||||
|     return array($this->getRequest()->getUser()->getPHID()); | ||||
|  | ||||
| /* TODO | ||||
|     $viewer_id = $this->getRequest()->getUser()->getPHID(); | ||||
|  | ||||
|     $fbids = array(); | ||||
|     if ($this->filter == self::FILTER_AFFECTED) { | ||||
|       $fbids[] = $viewer_id; | ||||
|       require_module_lazy('intern/subscriptions'); | ||||
|       $datastore = new SubscriberDatabaseStore(); | ||||
|       $lists = $datastore->getUserMailmanLists($viewer_id); | ||||
|       foreach ($lists as $list) { | ||||
|         $fbids[] = $list; | ||||
|       } | ||||
|     } | ||||
|     return $fbids; | ||||
| */ | ||||
|   } | ||||
|  | ||||
|   protected function getTranscriptPHIDs($xscript) { | ||||
|     $phids = array(); | ||||
|  | ||||
|     $object_xscript = $xscript->getObjectTranscript(); | ||||
|     if (!$object_xscript) { | ||||
|       return array(); | ||||
|     } | ||||
|  | ||||
|     $phids[] = $object_xscript->getPHID(); | ||||
|  | ||||
|     foreach ($xscript->getApplyTranscripts() as $apply_xscript) { | ||||
|       // TODO: This is total hacks. Add another amazing layer of abstraction. | ||||
|       $target = (array)$apply_xscript->getTarget(); | ||||
|       foreach ($target as $phid) { | ||||
|         if ($phid) { | ||||
|           $phids[] = $phid; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     foreach ($xscript->getRuleTranscripts() as $rule_xscript) { | ||||
|       $phids[] = $rule_xscript->getRuleOwner(); | ||||
|     } | ||||
|  | ||||
|     $condition_xscripts = $xscript->getConditionTranscripts(); | ||||
|     if ($condition_xscripts) { | ||||
|       $condition_xscripts = call_user_func_array( | ||||
|         'array_merge', | ||||
|         $condition_xscripts); | ||||
|     } | ||||
|     foreach ($condition_xscripts as $condition_xscript) { | ||||
|       $value = $condition_xscript->getTestValue(); | ||||
|       // TODO: Also total hacks. | ||||
|       if (is_array($value)) { | ||||
|         foreach ($value as $phid) { | ||||
|           if ($phid) { // TODO: Probably need to make sure this "looks like" a | ||||
|                        // PHID or decrease the level of hacks here; this used | ||||
|                        // to be an is_numeric() check in Facebook land. | ||||
|             $phids[] = $phid; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return $phids; | ||||
|   } | ||||
|  | ||||
|   protected function filterTranscript($xscript, $filter_phids) { | ||||
|     $filter_owned = ($this->filter == self::FILTER_OWNED); | ||||
|     $filter_affected = ($this->filter == self::FILTER_AFFECTED); | ||||
|  | ||||
|     if (!$filter_owned && !$filter_affected) { | ||||
|       // No filtering to be done. | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     if (!$xscript->getObjectTranscript()) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     $user_phid = $this->getRequest()->getUser()->getPHID(); | ||||
|  | ||||
|     $keep_apply_xscripts = array(); | ||||
|     $keep_rule_xscripts  = array(); | ||||
|  | ||||
|     $filter_phids = array_fill_keys($filter_phids, true); | ||||
|  | ||||
|     $rule_xscripts = $xscript->getRuleTranscripts(); | ||||
|     foreach ($xscript->getApplyTranscripts() as $id => $apply_xscript) { | ||||
|       $rule_id = $apply_xscript->getRuleID(); | ||||
|       if ($filter_owned) { | ||||
|         if (!$rule_xscripts[$rule_id]) { | ||||
|           // No associated rule so you can't own this effect. | ||||
|           continue; | ||||
|         } | ||||
|         if ($rule_xscripts[$rule_id]->getRuleOwner() != $user_phid) { | ||||
|           continue; | ||||
|         } | ||||
|       } else if ($filter_affected) { | ||||
|         $targets = (array)$apply_xscript->getTarget(); | ||||
|         if (!array_select_keys($filter_phids, $targets)) { | ||||
|           continue; | ||||
|         } | ||||
|       } | ||||
|       $keep_apply_xscripts[$id] = true; | ||||
|       if ($rule_id) { | ||||
|         $keep_rule_xscripts[$rule_id] = true; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     foreach ($rule_xscripts as $rule_id => $rule_xscript) { | ||||
|       if ($filter_owned && $rule_xscript->getRuleOwner() == $user_phid) { | ||||
|         $keep_rule_xscripts[$rule_id] = true; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     $xscript->setRuleTranscripts( | ||||
|       array_intersect_key( | ||||
|         $xscript->getRuleTranscripts(), | ||||
|         $keep_rule_xscripts)); | ||||
|  | ||||
|     $xscript->setApplyTranscripts( | ||||
|       array_intersect_key( | ||||
|         $xscript->getApplyTranscripts(), | ||||
|         $keep_apply_xscripts)); | ||||
|  | ||||
|     $xscript->setConditionTranscripts( | ||||
|       array_intersect_key( | ||||
|         $xscript->getConditionTranscripts(), | ||||
|         $keep_rule_xscripts)); | ||||
|   } | ||||
|  | ||||
|   private function buildApplyTranscriptPanel($xscript) { | ||||
|     $handles = $this->handles; | ||||
|  | ||||
|     $action_names = HeraldActionConfig::getActionMap(); | ||||
|  | ||||
|     $rows = array(); | ||||
|     foreach ($xscript->getApplyTranscripts() as $apply_xscript) { | ||||
|       // TODO: Hacks, this is an approximate guess at the target type. | ||||
|       $target = (array)$apply_xscript->getTarget(); | ||||
|       if (!$target) { | ||||
|         if ($apply_xscript->getAction() == HeraldActionConfig::ACTION_NOTHING) { | ||||
|           $target = ''; | ||||
|         } else { | ||||
|           $target = '<empty>'; | ||||
|         } | ||||
|       } else { | ||||
|         foreach ($target as $k => $phid) { | ||||
|           $target[$k] = $handles[$phid]->getName(); | ||||
|         } | ||||
|         $target = implode("\n", $target); | ||||
|       } | ||||
|       $target = phutil_escape_html($target); | ||||
|  | ||||
|       if ($apply_xscript->getApplied()) { | ||||
|         $outcome = '<span class="outcome-success">SUCCESS</span>'; | ||||
|       } else { | ||||
|         $outcome = '<span class="outcome-failure">FAILURE</span>'; | ||||
|       } | ||||
|       $outcome .= ' '.phutil_escape_html($apply_xscript->getAppliedReason()); | ||||
|  | ||||
|       $rows[] = array( | ||||
|         phutil_escape_html($action_names[$apply_xscript->getAction()]), | ||||
|         $target, | ||||
|         '<strong>Taken because:</strong> '. | ||||
|         phutil_escape_html($apply_xscript->getReason()). | ||||
|         '<br />'. | ||||
|         '<strong>Outcome:</strong> '.$outcome, | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     $table = new AphrontTableView($rows); | ||||
|     $table->setNoDataString('No actions were taken.'); | ||||
|     $table->setHeaders( | ||||
|       array( | ||||
|         'Action', | ||||
|         'Target', | ||||
|         'Details', | ||||
|       )); | ||||
|     $table->setColumnClasses( | ||||
|       array( | ||||
|         '', | ||||
|         '', | ||||
|         'wide', | ||||
|       )); | ||||
|  | ||||
|     $panel = new AphrontPanelView(); | ||||
|     $panel->setHeader('Actions Taken'); | ||||
|     $panel->appendChild($table); | ||||
|  | ||||
|     return $panel; | ||||
|   } | ||||
|  | ||||
|   private function buildActionTranscriptPanel($xscript) { | ||||
|     $action_xscript = mgroup($xscript->getApplyTranscripts(), 'getRuleID'); | ||||
|  | ||||
|     $field_names = HeraldFieldConfig::getFieldMap(); | ||||
|     $condition_names = HeraldConditionConfig::getConditionMap(); | ||||
|     $action_names = HeraldActionConfig::getActionMap(); | ||||
|  | ||||
|     $handles = $this->handles; | ||||
|  | ||||
|     $rule_markup = array(); | ||||
|     foreach ($xscript->getRuleTranscripts() as $rule_id => $rule) { | ||||
|       $cond_markup = array(); | ||||
|       foreach ($xscript->getConditionTranscriptsForRule($rule_id) as $cond) { | ||||
|         if ($cond->getNote()) { | ||||
|           $note = | ||||
|             '<div class="herald-condition-note">'. | ||||
|               phutil_escape_html($cond->getNote()). | ||||
|             '</div>'; | ||||
|         } else { | ||||
|           $note = null; | ||||
|         } | ||||
|  | ||||
|         if ($cond->getResult()) { | ||||
|           $result = | ||||
|             '<span class="herald-outcome condition-pass">'. | ||||
|               "\xE2\x9C\x93". | ||||
|             '</span>'; | ||||
|         } else { | ||||
|           $result = | ||||
|             '<span class="herald-outcome condition-fail">'. | ||||
|               "\xE2\x9C\x98". | ||||
|             '</span>'; | ||||
|         } | ||||
|  | ||||
|         $cond_markup[] = | ||||
|           '<li>'. | ||||
|             $result.' Condition: '. | ||||
|             phutil_escape_html($field_names[$cond->getFieldName()]). | ||||
|             ' '. | ||||
|             phutil_escape_html($condition_names[$cond->getCondition()]). | ||||
|             ' '. | ||||
|             $this->renderConditionTestValue($cond, $handles). | ||||
|             $note. | ||||
|           '</li>'; | ||||
|       } | ||||
|  | ||||
|       if ($rule->getResult()) { | ||||
|         $result = '<span class="herald-outcome rule-pass">PASS</span>'; | ||||
|         $class = 'herald-rule-pass'; | ||||
|       } else { | ||||
|         $result = '<span class="herald-outcome rule-fail">FAIL</span>'; | ||||
|         $class = 'herald-rule-fail'; | ||||
|       } | ||||
|  | ||||
|       $cond_markup[] = | ||||
|         '<li>'.$result.' '.phutil_escape_html($rule->getReason()).'</li>'; | ||||
|  | ||||
| /* | ||||
|       if ($rule->getResult()) { | ||||
|         $actions = idx($action_xscript, $rule_id, array()); | ||||
|         if ($actions) { | ||||
|           $cond_markup[] = <li><div class="action-header">Actions</div></li>; | ||||
|           foreach ($actions as $action) { | ||||
|  | ||||
|             $target = $action->getTarget(); | ||||
|             if ($target) { | ||||
|               foreach ((array)$target as $k => $phid) { | ||||
|                 $target[$k] = $handles[$phid]->getName(); | ||||
|               } | ||||
|               $target = <strong>: {implode(', ', $target)}</strong>; | ||||
|             } | ||||
|  | ||||
|             $cond_markup[] = | ||||
|               <li> | ||||
|                 {$action_names[$action->getAction()]} | ||||
|                 {$target} | ||||
|               </li>; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| */ | ||||
|       $user_phid = $this->getRequest()->getUser()->getPHID(); | ||||
|  | ||||
|       $name = $rule->getRuleName(); | ||||
|       if ($rule->getRuleOwner() == $user_phid) { | ||||
| //        $name = <a href={"/herald/rule/".$rule->getRuleID()."/"}>{$name}</a>; | ||||
|       } | ||||
|  | ||||
|       $rule_markup[] = | ||||
|         phutil_render_tag( | ||||
|           'li', | ||||
|           array( | ||||
|             'class' => $class, | ||||
|           ), | ||||
|           '<div class="rule-name">'. | ||||
|             '<strong>'.phutil_escape_html($name).'</strong> '. | ||||
|             phutil_escape_html($handles[$rule->getRuleOwner()]->getName()). | ||||
|           '</div>'. | ||||
|           '<ul>'.implode("\n", $cond_markup).'</ul>'); | ||||
|     } | ||||
|  | ||||
|     $panel = new AphrontPanelView(); | ||||
|     $panel->setHeader('Rule Details'); | ||||
|     $panel->appendChild( | ||||
|       '<ul class="herald-explain-list">'. | ||||
|         implode("\n", $rule_markup). | ||||
|       '</ul>'); | ||||
|  | ||||
|     return $panel; | ||||
|   } | ||||
|  | ||||
|   private function buildObjectTranscriptPanel($xscript) { | ||||
|  | ||||
|     $field_names = HeraldFieldConfig::getFieldMap(); | ||||
|  | ||||
|     $object_xscript = $xscript->getObjectTranscript(); | ||||
|  | ||||
|     $data = array(); | ||||
|     if ($object_xscript) { | ||||
|       $data += array( | ||||
|         'Object Name' => $object_xscript->getName(), | ||||
|         'Object Type' => $object_xscript->getType(), | ||||
|         'Object PHID' => $object_xscript->getPHID(), | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     $data += $xscript->getMetadataMap(); | ||||
|  | ||||
|     if ($object_xscript) { | ||||
|       foreach ($object_xscript->getFields() as $field => $value) { | ||||
|         $field = idx($field_names, $field, '['.$field.'?]'); | ||||
|         $data['Field: '.$field] = $value; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     $rows = array(); | ||||
|     foreach ($data as $name => $value) { | ||||
|       if (!is_scalar($value) && !is_null($value)) { | ||||
|         $value = implode("\n", $value); | ||||
|       } | ||||
|  | ||||
|       if (strlen($value) > 256) { | ||||
|         $value = phutil_render_tag( | ||||
|           'textarea', | ||||
|           array( | ||||
|             'class' => 'herald-field-value-transcript', | ||||
|           ), | ||||
|           phutil_escape_html($value)); | ||||
|       } else { | ||||
|         $value = phutil_escape_html($value); | ||||
|       } | ||||
|  | ||||
|       $rows[] = array( | ||||
|         phutil_escape_html($name), | ||||
|         $value, | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     $table = new AphrontTableView($rows); | ||||
|     $table->setColumnClasses( | ||||
|       array( | ||||
|         'header', | ||||
|         'wide', | ||||
|       )); | ||||
|  | ||||
|     $panel = new AphrontPanelView(); | ||||
|     $panel->setHeader('Object Transcript'); | ||||
|     $panel->appendChild($table); | ||||
|  | ||||
|     return $panel; | ||||
|   } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/applications/herald/controller/transcript/__init__.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/applications/herald/controller/transcript/__init__.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| <?php | ||||
| /** | ||||
|  * This file is automatically generated. Lint this module to rebuild it. | ||||
|  * @generated | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| phutil_require_module('phabricator', 'applications/herald/config/action'); | ||||
| phutil_require_module('phabricator', 'applications/herald/config/condition'); | ||||
| phutil_require_module('phabricator', 'applications/herald/config/field'); | ||||
| phutil_require_module('phabricator', 'applications/herald/controller/base'); | ||||
| phutil_require_module('phabricator', 'applications/herald/storage/transcript/base'); | ||||
| phutil_require_module('phabricator', 'applications/phid/handle/data'); | ||||
| phutil_require_module('phabricator', 'infrastructure/celerity/api'); | ||||
| phutil_require_module('phabricator', 'view/control/table'); | ||||
| phutil_require_module('phabricator', 'view/layout/panel'); | ||||
| phutil_require_module('phabricator', 'view/layout/sidenav'); | ||||
|  | ||||
| phutil_require_module('phutil', 'markup'); | ||||
| phutil_require_module('phutil', 'utils'); | ||||
|  | ||||
|  | ||||
| phutil_require_source('HeraldTranscriptController.php'); | ||||
| @@ -0,0 +1,120 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * Copyright 2011 Facebook, Inc. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| class HeraldTranscriptListController extends HeraldController { | ||||
|  | ||||
|   public function processRequest() { | ||||
|  | ||||
|     $request = $this->getRequest(); | ||||
|  | ||||
|     // Pull these objects manually since the serialized fields are gigantic. | ||||
|     $transcript = new HeraldTranscript(); | ||||
|     $data = queryfx_all( | ||||
|       $transcript->establishConnection('r'), | ||||
|       'SELECT id, objectPHID, time, duration, dryRun FROM %T | ||||
|         ORDER BY id DESC | ||||
|         LIMIT 100', | ||||
|       $transcript->getTableName()); | ||||
|  | ||||
|     /* | ||||
|  | ||||
|     $conn_r = smc_get_db('cdb.herald', 'r'); | ||||
|  | ||||
|     $page_size = 100; | ||||
|  | ||||
|     $pager = new SimplePager(); | ||||
|     $pager->setPageSize($page_size); | ||||
|     $pager->setOffset((((int)$request->getInt('page')) - 1) * $page_size); | ||||
|     $pager->order('id', array('id')); | ||||
|  | ||||
|  | ||||
|     $fbid = $request->getInt('fbid'); | ||||
|     if ($fbid) { | ||||
|       $filter = qsprintf( | ||||
|         $conn_r, | ||||
|         'WHERE objectID = %d', | ||||
|         $fbid); | ||||
|     } else { | ||||
|       $filter = ''; | ||||
|     } | ||||
|  | ||||
|     $data = $pager->select( | ||||
|       $conn_r, | ||||
|       'id, objectID, time, duration, dryRun FROM transcript %Q', | ||||
|       $filter); | ||||
| */ | ||||
|  | ||||
|     $handles = array(); | ||||
|     if ($data) { | ||||
|       $phids = ipull($data, 'objectPHID', 'objectPHID'); | ||||
|       $handles = id(new PhabricatorObjectHandleData($phids)) | ||||
|         ->loadHandles(); | ||||
|     } | ||||
|  | ||||
|     $rows = array(); | ||||
|     foreach ($data as $xscript) { | ||||
|       $rows[] = array( | ||||
|         date('F jS', $xscript['time']), | ||||
|         date('g:i:s A', $xscript['time']), | ||||
|         $handles[$xscript['objectPHID']]->renderLink(), | ||||
|         $xscript['dryRun'] ? 'Yes' : '', | ||||
|         number_format((int)(1000 * $xscript['duration'])).' ms', | ||||
|         phutil_render_tag( | ||||
|           'a', | ||||
|           array( | ||||
|             'href' => '/herald/transcript/'.$xscript['id'].'/', | ||||
|             'class' => 'button small grey', | ||||
|           ), | ||||
|           'View Transcript'), | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     $table = new AphrontTableView($rows); | ||||
|     $table->setHeaders( | ||||
|       array( | ||||
|         'Date', | ||||
|         'Time', | ||||
|         'Object', | ||||
|         'Dry Run', | ||||
|         'Duration', | ||||
|         'View', | ||||
|       )); | ||||
|     $table->setColumnClasses( | ||||
|       array( | ||||
|         '', | ||||
|         'right', | ||||
|         'wide wrap', | ||||
|         '', | ||||
|         '', | ||||
|         'action', | ||||
|       )); | ||||
|  | ||||
|  | ||||
|     $panel = new AphrontPanelView(); | ||||
|     $panel->setHeader('Herald Transcripts'); | ||||
|     $panel->appendChild($table); | ||||
|  | ||||
|     return $this->buildStandardPageResponse( | ||||
|       $panel, | ||||
|       array( | ||||
|         'title' => 'Herald Transcripts', | ||||
|         'tab' => 'transcripts', | ||||
|       )); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,20 @@ | ||||
| <?php | ||||
| /** | ||||
|  * This file is automatically generated. Lint this module to rebuild it. | ||||
|  * @generated | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| phutil_require_module('phabricator', 'applications/herald/controller/base'); | ||||
| phutil_require_module('phabricator', 'applications/herald/storage/transcript/base'); | ||||
| phutil_require_module('phabricator', 'applications/phid/handle/data'); | ||||
| phutil_require_module('phabricator', 'storage/queryfx'); | ||||
| phutil_require_module('phabricator', 'view/control/table'); | ||||
| phutil_require_module('phabricator', 'view/layout/panel'); | ||||
|  | ||||
| phutil_require_module('phutil', 'markup'); | ||||
| phutil_require_module('phutil', 'utils'); | ||||
|  | ||||
|  | ||||
| phutil_require_source('HeraldTranscriptListController.php'); | ||||
| @@ -18,7 +18,7 @@ | ||||
|  | ||||
| class HeraldEffect { | ||||
|  | ||||
|   protected $objectID; | ||||
|   protected $objectPHID; | ||||
|   protected $action; | ||||
|   protected $target; | ||||
|  | ||||
| @@ -27,13 +27,13 @@ class HeraldEffect { | ||||
|  | ||||
|   protected $reason; | ||||
|  | ||||
|   public function setObjectID($object_id) { | ||||
|     $this->objectID = $object_id; | ||||
|   public function setObjectPHID($object_phid) { | ||||
|     $this->objectPHID = $object_phid; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function getObjectID() { | ||||
|     return $this->objectID; | ||||
|   public function getObjectPHID() { | ||||
|     return $this->objectPHID; | ||||
|   } | ||||
|  | ||||
|   public function setAction($action) { | ||||
|   | ||||
| @@ -26,7 +26,7 @@ class HeraldEngine { | ||||
|   protected $fieldCache = array(); | ||||
|   protected $object = null; | ||||
|  | ||||
|   public static function loadAndApplyRules(IHeraldable $object) { | ||||
|   public static function loadAndApplyRules(HeraldObjectAdapter $object) { | ||||
|     $content_type = $object->getHeraldTypeName(); | ||||
|     $rules = HeraldRule::loadAllByContentTypeWithFullData($content_type); | ||||
|  | ||||
| @@ -37,13 +37,13 @@ class HeraldEngine { | ||||
|     return $engine->getTranscript(); | ||||
|   } | ||||
|  | ||||
|   public function applyRules(array $rules, IHeraldable $object) { | ||||
|   public function applyRules(array $rules, HeraldObjectAdapter $object) { | ||||
|     $t_start = microtime(true); | ||||
|  | ||||
|     $rules = mpull($rules, null, 'getID'); | ||||
|  | ||||
|     $this->transcript = new HeraldTranscript(); | ||||
|     $this->transcript->setObjectID((string)$object->getFBID()); | ||||
|     $this->transcript->setObjectPHID((string)$object->getPHID()); | ||||
|     $this->fieldCache = array(); | ||||
|     $this->results = array(); | ||||
|     $this->rules   = $rules; | ||||
| @@ -71,7 +71,7 @@ class HeraldEngine { | ||||
|             "Don't do this! You have formed an unresolvable cycle in the ". | ||||
|             "dependency graph!"); | ||||
|           $xscript->setRuleName($rules[$rule_id]->getName()); | ||||
|           $xscript->setRuleOwner($rules[$rule_id]->getOwnerID()); | ||||
|           $xscript->setRuleOwner($rules[$rule_id]->getAuthorPHID()); | ||||
|           $this->transcript->addRuleTranscript($xscript); | ||||
|         } | ||||
|         $rule_matches = false; | ||||
| @@ -86,7 +86,7 @@ class HeraldEngine { | ||||
|     } | ||||
|  | ||||
|     $object_transcript = new HeraldObjectTranscript(); | ||||
|     $object_transcript->setFBID($object->getFBID()); | ||||
|     $object_transcript->setPHID($object->getPHID()); | ||||
|     $object_transcript->setName($object->getHeraldName()); | ||||
|     $object_transcript->setType($object->getHeraldTypeName()); | ||||
|     $object_transcript->setFields($this->fieldCache); | ||||
| @@ -100,7 +100,7 @@ class HeraldEngine { | ||||
|     return $effects; | ||||
|   } | ||||
|  | ||||
|   public function applyEffects(array $effects, IHeraldable $object) { | ||||
|   public function applyEffects(array $effects, HeraldObjectAdapter $object) { | ||||
|     if ($object instanceof DryRunHeraldable) { | ||||
|       $this->transcript->setDryRun(true); | ||||
|     } else { | ||||
| @@ -121,7 +121,10 @@ class HeraldEngine { | ||||
|     return $this->transcript; | ||||
|   } | ||||
|  | ||||
|   protected function doesRuleMatch(HeraldRule $rule, IHeraldable $object) { | ||||
|   protected function doesRuleMatch( | ||||
|     HeraldRule $rule, | ||||
|     HeraldObjectAdapter $object) { | ||||
|  | ||||
|     $id = $rule->getID(); | ||||
|  | ||||
|     if (isset($this->results[$id])) { | ||||
| @@ -157,7 +160,7 @@ class HeraldEngine { | ||||
|       $reason = "Rule failed automatically because it has no conditions."; | ||||
|       $result = false; | ||||
| /* TOOD: Restore this in some form? | ||||
|     } else if (!is_fb_employee($rule->getOwnerID())) { | ||||
|     } else if (!is_fb_employee($rule->getAuthorPHID())) { | ||||
|       $reason = "Rule failed automatically because its owner is not an ". | ||||
|                 "active employee."; | ||||
|       $result = false; | ||||
| @@ -195,7 +198,7 @@ class HeraldEngine { | ||||
|     $rule_transcript->setResult($result); | ||||
|     $rule_transcript->setReason($reason); | ||||
|     $rule_transcript->setRuleName($rule->getName()); | ||||
|     $rule_transcript->setRuleOwner($rule->getOwnerID()); | ||||
|     $rule_transcript->setRuleOwner($rule->getAuthorPHID()); | ||||
|  | ||||
|     $this->transcript->addRuleTranscript($rule_transcript); | ||||
|  | ||||
| @@ -205,12 +208,12 @@ class HeraldEngine { | ||||
|   protected function doesConditionMatch( | ||||
|     HeraldRule $rule, | ||||
|     HeraldCondition $condition, | ||||
|     IHeraldable $object) { | ||||
|     HeraldObjectAdapter $object) { | ||||
|  | ||||
|     $object_value = $this->getConditionObjectValue($condition, $object); | ||||
|     $test_value   = $condition->getValue(); | ||||
|  | ||||
|     $cond = $condition->getCondition(); | ||||
|     $cond = $condition->getFieldCondition(); | ||||
|  | ||||
|     $transcript = new HeraldConditionTranscript(); | ||||
|     $transcript->setRuleID($rule->getID()); | ||||
| @@ -241,10 +244,10 @@ class HeraldEngine { | ||||
|         $result = ($object_value != $test_value); | ||||
|         break; | ||||
|       case HeraldConditionConfig::CONDITION_IS_ME: | ||||
|         $result = ($object_value == $rule->getOwnerID()); | ||||
|         $result = ($object_value == $rule->getAuthorPHID()); | ||||
|         break; | ||||
|       case HeraldConditionConfig::CONDITION_IS_NOT_ME: | ||||
|         $result = ($object_value != $rule->getOwnerID()); | ||||
|         $result = ($object_value != $rule->getAuthorPHID()); | ||||
|         break; | ||||
|       case HeraldConditionConfig::CONDITION_IS_ANY: | ||||
|         $test_value = array_flip($test_value); | ||||
| @@ -364,7 +367,7 @@ class HeraldEngine { | ||||
|  | ||||
|   protected function getConditionObjectValue( | ||||
|     HeraldCondition $condition, | ||||
|     IHeraldable $object) { | ||||
|     HeraldObjectAdapter $object) { | ||||
|  | ||||
|     $field = $condition->getFieldName(); | ||||
|  | ||||
| @@ -391,7 +394,7 @@ class HeraldEngine { | ||||
|       case HeraldFieldConfig::FIELD_AUTHOR: | ||||
|       case HeraldFieldConfig::FIELD_REPOSITORY: | ||||
|       case HeraldFieldConfig::FIELD_MERGE_REQUESTER: | ||||
|         // TODO: Type should be fbid. | ||||
|         // TODO: Type should be PHID. | ||||
|         $result = $this->object->getHeraldField($field); | ||||
|         break; | ||||
|       case HeraldFieldConfig::FIELD_TAGS: | ||||
| @@ -424,11 +427,14 @@ class HeraldEngine { | ||||
|     return $result; | ||||
|   } | ||||
|  | ||||
|   protected function getRuleEffects(HeraldRule $rule, IHeraldable $object) { | ||||
|   protected function getRuleEffects( | ||||
|     HeraldRule $rule, | ||||
|     HeraldObjectAdapter $object) { | ||||
|  | ||||
|     $effects = array(); | ||||
|     foreach ($rule->getActions() as $action) { | ||||
|       $effect = new HeraldEffect(); | ||||
|       $effect->setObjectID($object->getFBID()); | ||||
|       $effect->setObjectPHID($object->getPHID()); | ||||
|       $effect->setAction($action->getAction()); | ||||
|       $effect->setTarget($action->getTarget()); | ||||
|  | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
| class HeraldTranscript extends HeraldDAO { | ||||
|  | ||||
|   protected $id; | ||||
|   protected $fbid; | ||||
|   protected $phid; | ||||
|  | ||||
|   protected $objectTranscript; | ||||
|   protected $ruleTranscripts = array(); | ||||
| @@ -28,10 +28,9 @@ class HeraldTranscript extends HeraldDAO { | ||||
|  | ||||
|   protected $time; | ||||
|   protected $host; | ||||
|   protected $path; | ||||
|   protected $duration; | ||||
|  | ||||
|   protected $objectID; | ||||
|   protected $objectPHID; | ||||
|   protected $dryRun; | ||||
|  | ||||
|   public function getXHeraldRulesHeader() { | ||||
| @@ -61,7 +60,8 @@ class HeraldTranscript extends HeraldDAO { | ||||
|   protected function getConfiguration() { | ||||
|     // Ugh. Too much of a mess to deal with. | ||||
|     return array( | ||||
|       self::CONFIG_AUX_FBID     => 'HERALD_TRANSCRIPT', | ||||
|       self::CONFIG_AUX_PHID     => true, | ||||
|       self::CONFIG_TIMESTAMPS   => false, | ||||
|       self::CONFIG_SERIALIZATION => array( | ||||
|         'objectTranscript'      => self::SERIALIZATION_PHP, | ||||
|         'ruleTranscripts'       => self::SERIALIZATION_PHP, | ||||
| @@ -74,7 +74,6 @@ class HeraldTranscript extends HeraldDAO { | ||||
|   public function __construct() { | ||||
|     $this->time = time(); | ||||
|     $this->host = php_uname('n'); | ||||
|     $this->path = realpath($_SERVER['PHP_ROOT']); | ||||
|   } | ||||
|  | ||||
|   public function addApplyTranscript(HeraldApplyTranscript $transcript) { | ||||
| @@ -131,14 +130,14 @@ class HeraldTranscript extends HeraldDAO { | ||||
|  | ||||
|   public function getMetadataMap() { | ||||
|     return array( | ||||
|       'Run At Epoch' => date('F jS, g:i A', $this->time), | ||||
|       'Run On Host'  => $this->host.':'.$this->path, | ||||
|       'Run At Epoch' => date('F jS, g:i:s A', $this->time), | ||||
|       'Run On Host'  => $this->host, | ||||
|       'Run Duration' => (int)(1000 * $this->duration).' ms', | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   public function getURI() { | ||||
|     return 'http://tools.facebook.com/herald/transcript/'.$this->getID().'/'; | ||||
|   public function generatePHID() { | ||||
|     return PhabricatorPHID::generateNewPHID('HLXS'); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|  | ||||
|  | ||||
| phutil_require_module('phabricator', 'applications/herald/storage/base'); | ||||
| phutil_require_module('phabricator', 'applications/phid/storage/phid'); | ||||
|  | ||||
| phutil_require_module('phutil', 'utils'); | ||||
|  | ||||
|   | ||||
| @@ -18,18 +18,18 @@ | ||||
|  | ||||
| class HeraldObjectTranscript { | ||||
|  | ||||
|   protected $fbid; | ||||
|   protected $phid; | ||||
|   protected $type; | ||||
|   protected $name; | ||||
|   protected $fields; | ||||
|  | ||||
|   public function setFBID($fbid) { | ||||
|     $this->fbid = $fbid; | ||||
|   public function setPHID($phid) { | ||||
|     $this->phid = $phid; | ||||
|     return $this; | ||||
|   } | ||||
|  | ||||
|   public function getFBID() { | ||||
|     return $this->fbid; | ||||
|   public function getPHID() { | ||||
|     return $this->phid; | ||||
|   } | ||||
|  | ||||
|   public function setType($type) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley