PageRenderTime 52ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

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

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