/src/applications/herald/storage/transcript/HeraldTranscript.php

https://github.com/dannysu/phabricator · PHP · 235 lines · 184 code · 44 blank · 7 comment · 5 complexity · 1144c211bd136393858bde5aa25a85d1 MD5 · raw file

  1. <?php
  2. final class HeraldTranscript extends HeraldDAO
  3. implements
  4. PhabricatorPolicyInterface,
  5. PhabricatorDestructibleInterface {
  6. protected $objectTranscript;
  7. protected $ruleTranscripts = array();
  8. protected $conditionTranscripts = array();
  9. protected $applyTranscripts = array();
  10. protected $time;
  11. protected $host;
  12. protected $duration;
  13. protected $objectPHID;
  14. protected $dryRun;
  15. protected $garbageCollected = 0;
  16. const TABLE_SAVED_HEADER = 'herald_savedheader';
  17. public function getXHeraldRulesHeader() {
  18. $ids = array();
  19. foreach ($this->applyTranscripts as $xscript) {
  20. if ($xscript->getApplied()) {
  21. if ($xscript->getRuleID()) {
  22. $ids[] = $xscript->getRuleID();
  23. }
  24. }
  25. }
  26. if (!$ids) {
  27. return 'none';
  28. }
  29. // A rule may have multiple effects, which will cause it to be listed
  30. // multiple times.
  31. $ids = array_unique($ids);
  32. foreach ($ids as $k => $id) {
  33. $ids[$k] = '<'.$id.'>';
  34. }
  35. return implode(', ', $ids);
  36. }
  37. public static function saveXHeraldRulesHeader($phid, $header) {
  38. // Combine any existing header with the new header, listing all rules
  39. // which have ever triggered for this object.
  40. $header = self::combineXHeraldRulesHeaders(
  41. self::loadXHeraldRulesHeader($phid),
  42. $header);
  43. queryfx(
  44. id(new HeraldTranscript())->establishConnection('w'),
  45. 'INSERT INTO %T (phid, header) VALUES (%s, %s)
  46. ON DUPLICATE KEY UPDATE header = VALUES(header)',
  47. self::TABLE_SAVED_HEADER,
  48. $phid,
  49. $header);
  50. return $header;
  51. }
  52. private static function combineXHeraldRulesHeaders($u, $v) {
  53. $u = preg_split('/[, ]+/', $u);
  54. $v = preg_split('/[, ]+/', $v);
  55. $combined = array_unique(array_filter(array_merge($u, $v)));
  56. return implode(', ', $combined);
  57. }
  58. public static function loadXHeraldRulesHeader($phid) {
  59. $header = queryfx_one(
  60. id(new HeraldTranscript())->establishConnection('r'),
  61. 'SELECT * FROM %T WHERE phid = %s',
  62. self::TABLE_SAVED_HEADER,
  63. $phid);
  64. if ($header) {
  65. return idx($header, 'header');
  66. }
  67. return null;
  68. }
  69. protected function getConfiguration() {
  70. // Ugh. Too much of a mess to deal with.
  71. return array(
  72. self::CONFIG_AUX_PHID => true,
  73. self::CONFIG_TIMESTAMPS => false,
  74. self::CONFIG_SERIALIZATION => array(
  75. 'objectTranscript' => self::SERIALIZATION_PHP,
  76. 'ruleTranscripts' => self::SERIALIZATION_PHP,
  77. 'conditionTranscripts' => self::SERIALIZATION_PHP,
  78. 'applyTranscripts' => self::SERIALIZATION_PHP,
  79. ),
  80. self::CONFIG_BINARY => array(
  81. 'objectTranscript' => true,
  82. 'ruleTranscripts' => true,
  83. 'conditionTranscripts' => true,
  84. 'applyTranscripts' => true,
  85. ),
  86. self::CONFIG_COLUMN_SCHEMA => array(
  87. 'time' => 'epoch',
  88. 'host' => 'text255',
  89. 'duration' => 'double',
  90. 'dryRun' => 'bool',
  91. 'garbageCollected' => 'bool',
  92. ),
  93. self::CONFIG_KEY_SCHEMA => array(
  94. 'key_phid' => null,
  95. 'phid' => array(
  96. 'columns' => array('phid'),
  97. 'unique' => true,
  98. ),
  99. 'objectPHID' => array(
  100. 'columns' => array('objectPHID'),
  101. ),
  102. 'garbageCollected' => array(
  103. 'columns' => array('garbageCollected', 'time'),
  104. ),
  105. ),
  106. ) + parent::getConfiguration();
  107. }
  108. public function __construct() {
  109. $this->time = time();
  110. $this->host = php_uname('n');
  111. }
  112. public function addApplyTranscript(HeraldApplyTranscript $transcript) {
  113. $this->applyTranscripts[] = $transcript;
  114. return $this;
  115. }
  116. public function getApplyTranscripts() {
  117. return nonempty($this->applyTranscripts, array());
  118. }
  119. public function setDuration($duration) {
  120. $this->duration = $duration;
  121. return $this;
  122. }
  123. public function setObjectTranscript(HeraldObjectTranscript $transcript) {
  124. $this->objectTranscript = $transcript;
  125. return $this;
  126. }
  127. public function getObjectTranscript() {
  128. return $this->objectTranscript;
  129. }
  130. public function addRuleTranscript(HeraldRuleTranscript $transcript) {
  131. $this->ruleTranscripts[$transcript->getRuleID()] = $transcript;
  132. return $this;
  133. }
  134. public function discardDetails() {
  135. $this->applyTranscripts = null;
  136. $this->ruleTranscripts = null;
  137. $this->objectTranscript = null;
  138. $this->conditionTranscripts = null;
  139. }
  140. public function getRuleTranscripts() {
  141. return nonempty($this->ruleTranscripts, array());
  142. }
  143. public function addConditionTranscript(
  144. HeraldConditionTranscript $transcript) {
  145. $rule_id = $transcript->getRuleID();
  146. $cond_id = $transcript->getConditionID();
  147. $this->conditionTranscripts[$rule_id][$cond_id] = $transcript;
  148. return $this;
  149. }
  150. public function getConditionTranscriptsForRule($rule_id) {
  151. return idx($this->conditionTranscripts, $rule_id, array());
  152. }
  153. public function getMetadataMap() {
  154. return array(
  155. pht('Run At Epoch') => date('F jS, g:i:s A', $this->time),
  156. pht('Run On Host') => $this->host,
  157. pht('Run Duration') => (int)(1000 * $this->duration).' ms',
  158. );
  159. }
  160. public function generatePHID() {
  161. return PhabricatorPHID::generateNewPHID(
  162. HeraldTranscriptPHIDType::TYPECONST);
  163. }
  164. /* -( PhabricatorPolicyInterface )----------------------------------------- */
  165. public function getCapabilities() {
  166. return array(
  167. PhabricatorPolicyCapability::CAN_VIEW,
  168. );
  169. }
  170. public function getPolicy($capability) {
  171. switch ($capability) {
  172. case PhabricatorPolicyCapability::CAN_VIEW:
  173. return PhabricatorPolicies::POLICY_USER;
  174. }
  175. }
  176. public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
  177. return false;
  178. }
  179. public function describeAutomaticCapability($capability) {
  180. return pht(
  181. 'To view a transcript, you must be able to view the object the '.
  182. 'transcript is about.');
  183. }
  184. /* -( PhabricatorDestructibleInterface )----------------------------------- */
  185. public function destroyObjectPermanently(
  186. PhabricatorDestructionEngine $engine) {
  187. $this->openTransaction();
  188. $this->delete();
  189. $this->saveTransaction();
  190. }
  191. }