Path: blob/master/src/applications/herald/query/HeraldRuleQuery.php
12256 views
<?php12final class HeraldRuleQuery extends PhabricatorCursorPagedPolicyAwareQuery {34private $ids;5private $phids;6private $authorPHIDs;7private $ruleTypes;8private $contentTypes;9private $disabled;10private $active;11private $datasourceQuery;12private $triggerObjectPHIDs;13private $affectedObjectPHIDs;1415private $needConditionsAndActions;16private $needAppliedToPHIDs;17private $needValidateAuthors;1819public function withIDs(array $ids) {20$this->ids = $ids;21return $this;22}2324public function withPHIDs(array $phids) {25$this->phids = $phids;26return $this;27}2829public function withAuthorPHIDs(array $author_phids) {30$this->authorPHIDs = $author_phids;31return $this;32}3334public function withRuleTypes(array $types) {35$this->ruleTypes = $types;36return $this;37}3839public function withContentTypes(array $types) {40$this->contentTypes = $types;41return $this;42}4344public function withDisabled($disabled) {45$this->disabled = $disabled;46return $this;47}4849public function withActive($active) {50$this->active = $active;51return $this;52}5354public function withDatasourceQuery($query) {55$this->datasourceQuery = $query;56return $this;57}5859public function withTriggerObjectPHIDs(array $phids) {60$this->triggerObjectPHIDs = $phids;61return $this;62}6364public function withAffectedObjectPHIDs(array $phids) {65$this->affectedObjectPHIDs = $phids;66return $this;67}6869public function needConditionsAndActions($need) {70$this->needConditionsAndActions = $need;71return $this;72}7374public function needAppliedToPHIDs(array $phids) {75$this->needAppliedToPHIDs = $phids;76return $this;77}7879public function needValidateAuthors($need) {80$this->needValidateAuthors = $need;81return $this;82}8384public function newResultObject() {85return new HeraldRule();86}8788protected function willFilterPage(array $rules) {89$rule_ids = mpull($rules, 'getID');9091// Filter out any rules that have invalid adapters, or have adapters the92// viewer isn't permitted to see or use (for example, Differential rules93// if the user can't use Differential or Differential is not installed).94$types = HeraldAdapter::getEnabledAdapterMap($this->getViewer());95foreach ($rules as $key => $rule) {96if (empty($types[$rule->getContentType()])) {97$this->didRejectResult($rule);98unset($rules[$key]);99}100}101102if ($this->needValidateAuthors || ($this->active !== null)) {103$this->validateRuleAuthors($rules);104}105106if ($this->active !== null) {107$need_active = (bool)$this->active;108foreach ($rules as $key => $rule) {109if ($rule->getIsDisabled()) {110$is_active = false;111} else if (!$rule->hasValidAuthor()) {112$is_active = false;113} else {114$is_active = true;115}116117if ($is_active != $need_active) {118unset($rules[$key]);119}120}121}122123if (!$rules) {124return array();125}126127if ($this->needConditionsAndActions) {128$conditions = id(new HeraldCondition())->loadAllWhere(129'ruleID IN (%Ld)',130$rule_ids);131$conditions = mgroup($conditions, 'getRuleID');132133$actions = id(new HeraldActionRecord())->loadAllWhere(134'ruleID IN (%Ld)',135$rule_ids);136$actions = mgroup($actions, 'getRuleID');137138foreach ($rules as $rule) {139$rule->attachActions(idx($actions, $rule->getID(), array()));140$rule->attachConditions(idx($conditions, $rule->getID(), array()));141}142}143144if ($this->needAppliedToPHIDs) {145$conn_r = id(new HeraldRule())->establishConnection('r');146$applied = queryfx_all(147$conn_r,148'SELECT * FROM %T WHERE ruleID IN (%Ld) AND phid IN (%Ls)',149HeraldRule::TABLE_RULE_APPLIED,150$rule_ids,151$this->needAppliedToPHIDs);152153$map = array();154foreach ($applied as $row) {155$map[$row['ruleID']][$row['phid']] = true;156}157158foreach ($rules as $rule) {159foreach ($this->needAppliedToPHIDs as $phid) {160$rule->setRuleApplied(161$phid,162isset($map[$rule->getID()][$phid]));163}164}165}166167$object_phids = array();168foreach ($rules as $rule) {169if ($rule->isObjectRule()) {170$object_phids[] = $rule->getTriggerObjectPHID();171}172}173174if ($object_phids) {175$objects = id(new PhabricatorObjectQuery())176->setParentQuery($this)177->setViewer($this->getViewer())178->withPHIDs($object_phids)179->execute();180$objects = mpull($objects, null, 'getPHID');181} else {182$objects = array();183}184185foreach ($rules as $key => $rule) {186if ($rule->isObjectRule()) {187$object = idx($objects, $rule->getTriggerObjectPHID());188if (!$object) {189unset($rules[$key]);190continue;191}192$rule->attachTriggerObject($object);193}194}195196return $rules;197}198199protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {200$where = parent::buildWhereClauseParts($conn);201202if ($this->ids !== null) {203$where[] = qsprintf(204$conn,205'rule.id IN (%Ld)',206$this->ids);207}208209if ($this->phids !== null) {210$where[] = qsprintf(211$conn,212'rule.phid IN (%Ls)',213$this->phids);214}215216if ($this->authorPHIDs !== null) {217$where[] = qsprintf(218$conn,219'rule.authorPHID IN (%Ls)',220$this->authorPHIDs);221}222223if ($this->ruleTypes !== null) {224$where[] = qsprintf(225$conn,226'rule.ruleType IN (%Ls)',227$this->ruleTypes);228}229230if ($this->contentTypes !== null) {231$where[] = qsprintf(232$conn,233'rule.contentType IN (%Ls)',234$this->contentTypes);235}236237if ($this->disabled !== null) {238$where[] = qsprintf(239$conn,240'rule.isDisabled = %d',241(int)$this->disabled);242}243244if ($this->active !== null) {245$where[] = qsprintf(246$conn,247'rule.isDisabled = %d',248(int)(!$this->active));249}250251if ($this->datasourceQuery !== null) {252$where[] = qsprintf(253$conn,254'rule.name LIKE %>',255$this->datasourceQuery);256}257258if ($this->triggerObjectPHIDs !== null) {259$where[] = qsprintf(260$conn,261'rule.triggerObjectPHID IN (%Ls)',262$this->triggerObjectPHIDs);263}264265if ($this->affectedObjectPHIDs !== null) {266$where[] = qsprintf(267$conn,268'edge_affects.dst IN (%Ls)',269$this->affectedObjectPHIDs);270}271272return $where;273}274275protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {276$joins = parent::buildJoinClauseParts($conn);277278if ($this->affectedObjectPHIDs !== null) {279$joins[] = qsprintf(280$conn,281'JOIN %T edge_affects ON rule.phid = edge_affects.src282AND edge_affects.type = %d',283PhabricatorEdgeConfig::TABLE_NAME_EDGE,284HeraldRuleActionAffectsObjectEdgeType::EDGECONST);285}286287return $joins;288}289290private function validateRuleAuthors(array $rules) {291// "Global" and "Object" rules always have valid authors.292foreach ($rules as $key => $rule) {293if ($rule->isGlobalRule() || $rule->isObjectRule()) {294$rule->attachValidAuthor(true);295unset($rules[$key]);296continue;297}298}299300if (!$rules) {301return;302}303304// For personal rules, the author needs to exist and not be disabled.305$user_phids = mpull($rules, 'getAuthorPHID');306$users = id(new PhabricatorPeopleQuery())307->setViewer($this->getViewer())308->withPHIDs($user_phids)309->execute();310$users = mpull($users, null, 'getPHID');311312foreach ($rules as $key => $rule) {313$author_phid = $rule->getAuthorPHID();314if (empty($users[$author_phid])) {315$rule->attachValidAuthor(false);316continue;317}318if (!$users[$author_phid]->isUserActivated()) {319$rule->attachValidAuthor(false);320continue;321}322323$rule->attachValidAuthor(true);324$rule->attachAuthor($users[$author_phid]);325}326}327328public function getQueryApplicationClass() {329return 'PhabricatorHeraldApplication';330}331332protected function getPrimaryTableAlias() {333return 'rule';334}335336}337338339