protected function getRuleEffects(HeraldRule $rule, HeraldAdapter $object) { $effects = array(); foreach ($rule->getActions() as $action) { $effect = new HeraldEffect(); $effect->setObjectPHID($object->getPHID()); $effect->setAction($action->getAction()); $effect->setTarget($action->getTarget()); $effect->setRuleID($rule->getID()); $effect->setRulePHID($rule->getPHID()); $name = $rule->getName(); $id = $rule->getID(); $effect->setReason(pht('Conditions were met for %s', "H{$id} {$name}")); $effects[] = $effect; } return $effects; }
private function setupEditorBehavior(HeraldRule $rule, array $handles, HeraldAdapter $adapter) { $serial_conditions = array(array('default', 'default', '')); if ($rule->getConditions()) { $serial_conditions = array(); foreach ($rule->getConditions() as $condition) { $value = $adapter->getEditorValueForCondition($this->getViewer(), $condition, $handles); $serial_conditions[] = array($condition->getFieldName(), $condition->getFieldCondition(), $value); } } $serial_actions = array(array('default', '')); if ($rule->getActions()) { $serial_actions = array(); foreach ($rule->getActions() as $action) { switch ($action->getAction()) { case HeraldAdapter::ACTION_FLAG: case HeraldAdapter::ACTION_BLOCK: $current_value = $action->getTarget(); break; default: if (is_array($action->getTarget())) { $target_map = array(); foreach ((array) $action->getTarget() as $fbid) { $target_map[$fbid] = $handles[$fbid]->getName(); } $current_value = $target_map; } else { $current_value = $action->getTarget(); } break; } $serial_actions[] = array($action->getAction(), $current_value); } } $all_rules = $this->loadRulesThisRuleMayDependUpon($rule); $all_rules = mpull($all_rules, 'getName', 'getPHID'); asort($all_rules); $all_fields = $adapter->getFieldNameMap(); $all_conditions = $adapter->getConditionNameMap(); $all_actions = $adapter->getActionNameMap($rule->getRuleType()); $fields = $adapter->getFields(); $field_map = array_select_keys($all_fields, $fields); // Populate any fields which exist in the rule but which we don't know the // names of, so that saving a rule without touching anything doesn't change // it. foreach ($rule->getConditions() as $condition) { $field_name = $condition->getFieldName(); if (empty($field_map[$field_name])) { $field_map[$field_name] = pht('<Unknown Field "%s">', $field_name); } } $actions = $adapter->getActions($rule->getRuleType()); $action_map = array_select_keys($all_actions, $actions); // Populate any actions which exist in the rule but which we don't know the // names of, so that saving a rule without touching anything doesn't change // it. foreach ($rule->getActions() as $action) { $action_name = $action->getAction(); if (empty($action_map[$action_name])) { $action_map[$action_name] = pht('<Unknown Action "%s">', $action_name); } } $config_info = array(); $config_info['fields'] = $field_map; $config_info['conditions'] = $all_conditions; $config_info['actions'] = $action_map; foreach ($config_info['fields'] as $field => $name) { try { $field_conditions = $adapter->getConditionsForField($field); } catch (Exception $ex) { $field_conditions = array(HeraldAdapter::CONDITION_UNCONDITIONALLY); } $config_info['conditionMap'][$field] = $field_conditions; } foreach ($config_info['fields'] as $field => $fname) { foreach ($config_info['conditionMap'][$field] as $condition) { $value_type = $adapter->getValueTypeForFieldAndCondition($field, $condition); $config_info['values'][$field][$condition] = $value_type; } } $config_info['rule_type'] = $rule->getRuleType(); foreach ($config_info['actions'] as $action => $name) { try { $action_value = $adapter->getValueTypeForAction($action, $rule->getRuleType()); } catch (Exception $ex) { $action_value = array(HeraldAdapter::VALUE_NONE); } $config_info['targets'][$action] = $action_value; } $changeflag_options = PhabricatorRepositoryPushLog::getHeraldChangeFlagConditionOptions(); Javelin::initBehavior('herald-rule-editor', array('root' => 'herald-rule-edit-form', 'conditions' => (object) $serial_conditions, 'actions' => (object) $serial_actions, 'select' => array(HeraldAdapter::VALUE_CONTENT_SOURCE => array('options' => PhabricatorContentSource::getSourceNameMap(), 'default' => PhabricatorContentSource::SOURCE_WEB), HeraldAdapter::VALUE_FLAG_COLOR => array('options' => PhabricatorFlagColor::getColorNameMap(), 'default' => PhabricatorFlagColor::COLOR_BLUE), HeraldPreCommitRefAdapter::VALUE_REF_TYPE => array('options' => array(PhabricatorRepositoryPushLog::REFTYPE_BRANCH => pht('branch (git/hg)'), PhabricatorRepositoryPushLog::REFTYPE_TAG => pht('tag (git)'), PhabricatorRepositoryPushLog::REFTYPE_BOOKMARK => pht('bookmark (hg)')), 'default' => PhabricatorRepositoryPushLog::REFTYPE_BRANCH), HeraldPreCommitRefAdapter::VALUE_REF_CHANGE => array('options' => $changeflag_options, 'default' => PhabricatorRepositoryPushLog::CHANGEFLAG_ADD)), 'template' => $this->buildTokenizerTemplates($handles) + array('rules' => $all_rules), 'author' => array($rule->getAuthorPHID() => $handles[$rule->getAuthorPHID()]->getName()), 'info' => $config_info)); }
protected function getRuleEffects(HeraldRule $rule, HeraldObjectAdapter $object) { $effects = array(); foreach ($rule->getActions() as $action) { $effect = new HeraldEffect(); $effect->setObjectPHID($object->getPHID()); $effect->setAction($action->getAction()); $effect->setTarget($action->getTarget()); $effect->setRuleID($rule->getID()); $name = $rule->getName(); $id = $rule->getID(); $effect->setReason('Conditions were met for Herald rule "' . $name . '" (#' . $id . ').'); $effects[] = $effect; } return $effects; }
/** * Given a @{class:HeraldRule}, this function extracts all the phids that * we'll want to load as handles later. * * This function performs a somewhat hacky approach to figuring out what * is and is not a phid - try to get the phid type and if the type is * *not* unknown assume its a valid phid. * * Don't try this at home. Use more strongly typed data at home. * * Think of the children. */ public static function getHandlePHIDs(HeraldRule $rule) { $phids = array($rule->getAuthorPHID()); foreach ($rule->getConditions() as $condition) { $value = $condition->getValue(); if (!is_array($value)) { $value = array($value); } foreach ($value as $val) { if (phid_get_type($val) != PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) { $phids[] = $val; } } } foreach ($rule->getActions() as $action) { $target = $action->getTarget(); if (!is_array($target)) { $target = array($target); } foreach ($target as $val) { if (phid_get_type($val) != PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) { $phids[] = $val; } } } if ($rule->isObjectRule()) { $phids[] = $rule->getTriggerObjectPHID(); } return $phids; }
private function setupEditorBehavior(HeraldRule $rule, array $handles, HeraldAdapter $adapter) { $serial_conditions = array(array('default', 'default', '')); if ($rule->getConditions()) { $serial_conditions = array(); foreach ($rule->getConditions() as $condition) { $value = $adapter->getEditorValueForCondition($this->getViewer(), $condition); $serial_conditions[] = array($condition->getFieldName(), $condition->getFieldCondition(), $value); } } $serial_actions = array(array('default', '')); if ($rule->getActions()) { $serial_actions = array(); foreach ($rule->getActions() as $action) { $value = $adapter->getEditorValueForAction($this->getViewer(), $action); $serial_actions[] = array($action->getAction(), $value); } } $all_rules = $this->loadRulesThisRuleMayDependUpon($rule); $all_rules = mpull($all_rules, 'getName', 'getPHID'); asort($all_rules); $all_fields = $adapter->getFieldNameMap(); $all_conditions = $adapter->getConditionNameMap(); $all_actions = $adapter->getActionNameMap($rule->getRuleType()); $fields = $adapter->getFields(); $field_map = array_select_keys($all_fields, $fields); // Populate any fields which exist in the rule but which we don't know the // names of, so that saving a rule without touching anything doesn't change // it. foreach ($rule->getConditions() as $condition) { $field_name = $condition->getFieldName(); if (empty($field_map[$field_name])) { $field_map[$field_name] = pht('<Unknown Field "%s">', $field_name); } } $actions = $adapter->getActions($rule->getRuleType()); $action_map = array_select_keys($all_actions, $actions); // Populate any actions which exist in the rule but which we don't know the // names of, so that saving a rule without touching anything doesn't change // it. foreach ($rule->getActions() as $action) { $action_name = $action->getAction(); if (empty($action_map[$action_name])) { $action_map[$action_name] = pht('<Unknown Action "%s">', $action_name); } } $config_info = array(); $config_info['fields'] = $this->getFieldGroups($adapter, $field_map); $config_info['conditions'] = $all_conditions; $config_info['actions'] = $this->getActionGroups($adapter, $action_map); $config_info['valueMap'] = array(); foreach ($field_map as $field => $name) { try { $field_conditions = $adapter->getConditionsForField($field); } catch (Exception $ex) { $field_conditions = array(HeraldAdapter::CONDITION_UNCONDITIONALLY); } $config_info['conditionMap'][$field] = $field_conditions; } foreach ($field_map as $field => $fname) { foreach ($config_info['conditionMap'][$field] as $condition) { $value_key = $adapter->getValueTypeForFieldAndCondition($field, $condition); if ($value_key instanceof HeraldFieldValue) { $value_key->setViewer($this->getViewer()); $spec = $value_key->getControlSpecificationDictionary(); $value_key = $value_key->getFieldValueKey(); $config_info['valueMap'][$value_key] = $spec; } $config_info['values'][$field][$condition] = $value_key; } } $config_info['rule_type'] = $rule->getRuleType(); foreach ($action_map as $action => $name) { try { $value_key = $adapter->getValueTypeForAction($action, $rule->getRuleType()); } catch (Exception $ex) { $value_key = new HeraldEmptyFieldValue(); } if ($value_key instanceof HeraldFieldValue) { $value_key->setViewer($this->getViewer()); $spec = $value_key->getControlSpecificationDictionary(); $value_key = $value_key->getFieldValueKey(); $config_info['valueMap'][$value_key] = $spec; } $config_info['targets'][$action] = $value_key; } Javelin::initBehavior('herald-rule-editor', array('root' => 'herald-rule-edit-form', 'conditions' => (object) $serial_conditions, 'actions' => (object) $serial_actions, 'template' => $this->buildTokenizerTemplates() + array('rules' => $all_rules), 'info' => $config_info)); }
public function serializeRule(HeraldRule $rule) { return $this->serializeRuleComponents((bool) $rule->getMustMatchAll(), $rule->getConditions(), $rule->getActions(), HeraldRepetitionPolicyConfig::toString($rule->getRepetitionPolicy())); }
private function setupEditorBehavior(HeraldRule $rule, array $handles, HeraldAdapter $adapter) { $serial_conditions = array(array('default', 'default', '')); if ($rule->getConditions()) { $serial_conditions = array(); foreach ($rule->getConditions() as $condition) { $value = $adapter->getEditorValueForCondition($this->getViewer(), $condition, $handles); $serial_conditions[] = array($condition->getFieldName(), $condition->getFieldCondition(), $value); } } $serial_actions = array(array('default', '')); if ($rule->getActions()) { $serial_actions = array(); foreach ($rule->getActions() as $action) { switch ($action->getAction()) { case HeraldAdapter::ACTION_FLAG: case HeraldAdapter::ACTION_BLOCK: $current_value = $action->getTarget(); break; default: if (is_array($action->getTarget())) { $target_map = array(); foreach ((array) $action->getTarget() as $fbid) { $target_map[$fbid] = $handles[$fbid]->getName(); } $current_value = $target_map; } else { $current_value = $action->getTarget(); } break; } $serial_actions[] = array($action->getAction(), $current_value); } } $all_rules = $this->loadRulesThisRuleMayDependUpon($rule); $all_rules = mpull($all_rules, 'getName', 'getPHID'); asort($all_rules); $all_fields = $adapter->getFieldNameMap(); $all_conditions = $adapter->getConditionNameMap(); $all_actions = $adapter->getActionNameMap($rule->getRuleType()); $fields = $adapter->getFields(); $field_map = array_select_keys($all_fields, $fields); // Populate any fields which exist in the rule but which we don't know the // names of, so that saving a rule without touching anything doesn't change // it. foreach ($rule->getConditions() as $condition) { $field_name = $condition->getFieldName(); if (empty($field_map[$field_name])) { $field_map[$field_name] = pht('<Unknown Field "%s">', $field_name); } } $actions = $adapter->getActions($rule->getRuleType()); $action_map = array_select_keys($all_actions, $actions); // Populate any actions which exist in the rule but which we don't know the // names of, so that saving a rule without touching anything doesn't change // it. foreach ($rule->getActions() as $action) { $action_name = $action->getAction(); if (empty($action_map[$action_name])) { $action_map[$action_name] = pht('<Unknown Action "%s">', $action_name); } } $group_map = array(); foreach ($field_map as $field_key => $field_name) { $group_key = $adapter->getFieldGroupKey($field_key); $group_map[$group_key][$field_key] = $field_name; } $field_groups = HeraldFieldGroup::getAllFieldGroups(); $groups = array(); foreach ($group_map as $group_key => $options) { asort($options); $field_group = idx($field_groups, $group_key); if ($field_group) { $group_label = $field_group->getGroupLabel(); $group_order = $field_group->getSortKey(); } else { $group_label = nonempty($group_key, pht('Other')); $group_order = 'Z'; } $groups[] = array('label' => $group_label, 'options' => $options, 'order' => $group_order); } $groups = array_values(isort($groups, 'order')); $config_info = array(); $config_info['fields'] = $groups; $config_info['conditions'] = $all_conditions; $config_info['actions'] = $action_map; $config_info['valueMap'] = array(); foreach ($field_map as $field => $name) { try { $field_conditions = $adapter->getConditionsForField($field); } catch (Exception $ex) { $field_conditions = array(HeraldAdapter::CONDITION_UNCONDITIONALLY); } $config_info['conditionMap'][$field] = $field_conditions; } foreach ($field_map as $field => $fname) { foreach ($config_info['conditionMap'][$field] as $condition) { $value_key = $adapter->getValueTypeForFieldAndCondition($field, $condition); if ($value_key instanceof HeraldFieldValue) { $value_key->setViewer($this->getViewer()); $spec = $value_key->getControlSpecificationDictionary(); $value_key = $value_key->getFieldValueKey(); $config_info['valueMap'][$value_key] = $spec; } $config_info['values'][$field][$condition] = $value_key; } } $config_info['rule_type'] = $rule->getRuleType(); foreach ($config_info['actions'] as $action => $name) { try { $value_key = $adapter->getValueTypeForAction($action, $rule->getRuleType()); } catch (Exception $ex) { $value_key = new HeraldEmptyFieldValue(); } if ($value_key instanceof HeraldFieldValue) { $value_key->setViewer($this->getViewer()); $spec = $value_key->getControlSpecificationDictionary(); $value_key = $value_key->getFieldValueKey(); $config_info['valueMap'][$value_key] = $spec; } $config_info['targets'][$action] = $value_key; } Javelin::initBehavior('herald-rule-editor', array('root' => 'herald-rule-edit-form', 'conditions' => (object) $serial_conditions, 'actions' => (object) $serial_actions, 'template' => $this->buildTokenizerTemplates() + array('rules' => $all_rules), 'info' => $config_info)); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $content_type_map = HeraldContentTypeConfig::getContentTypeMap(); if ($this->id) { $rule = id(new HeraldRule())->load($this->id); if (!$rule) { return new Aphront404Response(); } if ($rule->getAuthorPHID() != $user->getPHID()) { throw new Exception("You don't own this rule and can't edit it."); } } else { $rule = new HeraldRule(); $rule->setAuthorPHID($user->getPHID()); $rule->setMustMatchAll(true); $type = $request->getStr('type'); if (!isset($content_type_map[$type])) { $type = HeraldContentTypeConfig::CONTENT_TYPE_DIFFERENTIAL; } $rule->setContentType($type); } $local_version = id(new HeraldRule())->getConfigVersion(); if ($rule->getConfigVersion() > $local_version) { throw new Exception("This rule was created with a newer version of Herald. You can not " . "view or edit it in this older version. Try dev or wait for a push."); } // Upgrade rule version to our version, since we might add newly-defined // conditions, etc. $rule->setConfigVersion($local_version); $rule_conditions = $rule->loadConditions(); $rule_actions = $rule->loadActions(); $rule->attachConditions($rule_conditions); $rule->attachActions($rule_actions); $e_name = true; $errors = array(); if ($request->isFormPost() && $request->getStr('save')) { $rule->setName($request->getStr('name')); $rule->setMustMatchAll($request->getStr('must_match') == 'all'); $repetition_policy_param = $request->getStr('repetition_policy'); $rule->setRepetitionPolicy(HeraldRepetitionPolicyConfig::toInt($repetition_policy_param)); if (!strlen($rule->getName())) { $e_name = "Required"; $errors[] = "Rule must have a name."; } $data = json_decode($request->getStr('rule'), true); if (!is_array($data) || !$data['conditions'] || !$data['actions']) { throw new Exception("Failed to decode rule data."); } $conditions = array(); foreach ($data['conditions'] as $condition) { if ($condition === null) { // We manage this as a sparse array on the client, so may receive // NULL if conditions have been removed. continue; } $obj = new HeraldCondition(); $obj->setFieldName($condition[0]); $obj->setFieldCondition($condition[1]); if (is_array($condition[2])) { $obj->setValue(array_keys($condition[2])); } else { $obj->setValue($condition[2]); } $cond_type = $obj->getFieldCondition(); if ($cond_type == HeraldConditionConfig::CONDITION_REGEXP) { if (@preg_match($obj->getValue(), '') === false) { $errors[] = 'The regular expression "' . $obj->getValue() . '" is not valid. ' . 'Regular expressions must have enclosing characters (e.g. ' . '"@/path/to/file@", not "/path/to/file") and be syntactically ' . 'correct.'; } } if ($cond_type == HeraldConditionConfig::CONDITION_REGEXP_PAIR) { $json = json_decode($obj->getValue(), true); if (!is_array($json)) { $errors[] = 'The regular expression pair "' . $obj->getValue() . '" is not ' . 'valid JSON. Enter a valid JSON array with two elements.'; } else { if (count($json) != 2) { $errors[] = 'The regular expression pair "' . $obj->getValue() . '" must have ' . 'exactly two elements.'; } else { $key_regexp = array_shift($json); $val_regexp = array_shift($json); if (@preg_match($key_regexp, '') === false) { $errors[] = 'The first regexp, "' . $key_regexp . '" in the regexp pair ' . 'is not a valid regexp.'; } if (@preg_match($val_regexp, '') === false) { $errors[] = 'The second regexp, "' . $val_regexp . '" in the regexp pair ' . 'is not a valid regexp.'; } } } } $conditions[] = $obj; } $actions = array(); foreach ($data['actions'] as $action) { if ($action === null) { // Sparse on the client; removals can give us NULLs. continue; } $obj = new HeraldAction(); $obj->setAction($action[0]); if (!isset($action[1])) { // Legitimate for any action which doesn't need a target, like // "Do nothing". $action[1] = null; } if (is_array($action[1])) { $obj->setTarget(array_keys($action[1])); } else { $obj->setTarget($action[1]); } $actions[] = $obj; } $rule->attachConditions($conditions); $rule->attachActions($actions); if (!$errors) { try { // TODO // $rule->openTransaction(); $rule->save(); $rule->saveConditions($conditions); $rule->saveActions($actions); // $rule->saveTransaction(); $uri = '/herald/view/' . $rule->getContentType() . '/'; return id(new AphrontRedirectResponse())->setURI($uri); } catch (AphrontQueryDuplicateKeyException $ex) { $e_name = "Not Unique"; $errors[] = "Rule name is not unique. Choose a unique name."; } } } $phids = array(); $phids[] = $rule->getAuthorPHID(); foreach ($rule->getActions() as $action) { if (!is_array($action->getTarget())) { continue; } foreach ($action->getTarget() as $target) { $target = (array) $target; foreach ($target as $phid) { $phids[] = $phid; } } } foreach ($rule->getConditions() as $condition) { $value = $condition->getValue(); if (is_array($value)) { foreach ($value as $phid) { $phids[] = $phid; } } } $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); if ($errors) { $error_view = new AphrontErrorView(); $error_view->setTitle('Form Errors'); $error_view->setErrors($errors); } else { $error_view = null; } $options = array('all' => 'all of', 'any' => 'any of'); $selected = $rule->getMustMatchAll() ? 'all' : 'any'; $must_match = array(); foreach ($options as $key => $option) { $must_match[] = phutil_render_tag('option', array('selected' => $selected == $key ? 'selected' : null, 'value' => $key), phutil_escape_html($option)); } $must_match = '<select name="must_match">' . implode("\n", $must_match) . '</select>'; if ($rule->getID()) { $action = '/herald/rule/' . $rule->getID() . '/'; } else { $action = '/herald/rule/' . $rule->getID() . '/'; } // Make the selector for choosing how often this rule should be repeated $repetition_selector = ""; $repetition_policy = HeraldRepetitionPolicyConfig::toString($rule->getRepetitionPolicy()); $repetition_options = HeraldRepetitionPolicyConfig::getMapForContentType($rule->getContentType()); if (empty($repetition_options)) { // default option is 'every time' $repetition_selector = idx(HeraldRepetitionPolicyConfig::getMap(), HeraldRepetitionPolicyConfig::EVERY); } else { if (count($repetition_options) == 1) { // if there's only 1 option, just pick it for the user $repetition_selector = reset($repetition_options); } else { // give the user all the options for this rule type $tags = array(); foreach ($repetition_options as $name => $option) { $tags[] = phutil_render_tag('option', array('selected' => $repetition_policy == $name ? 'selected' : null, 'value' => $name), phutil_escape_html($option)); } $repetition_selector = '<select name="repetition_policy">' . implode("\n", $tags) . '</select>'; } } require_celerity_resource('herald-css'); $type_name = $content_type_map[$rule->getContentType()]; $form = id(new AphrontFormView())->setUser($user)->setID('herald-rule-edit-form')->addHiddenInput('type', $rule->getContentType())->addHiddenInput('save', 1)->appendChild(javelin_render_tag('input', array('type' => 'hidden', 'name' => 'rule', 'sigil' => 'rule')))->appendChild(id(new AphrontFormTextControl())->setLabel('Rule Name')->setName('name')->setError($e_name)->setValue($rule->getName()))->appendChild(id(new AphrontFormStaticControl())->setLabel('Author')->setValue($handles[$rule->getAuthorPHID()]->getName()))->appendChild(id(new AphrontFormMarkupControl())->setValue("This rule triggers for <strong>{$type_name}</strong>."))->appendChild('<h1>Conditions</h1>' . '<div class="aphront-form-inset">' . '<div style="float: right;">' . javelin_render_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'create-condition', 'mustcapture' => true), 'Create New Condition') . '</div>' . '<p>When ' . $must_match . ' these conditions are met:</p>' . '<div style="clear: both;"></div>' . javelin_render_tag('table', array('sigil' => 'rule-conditions', 'class' => 'herald-condition-table'), '') . '</div>')->appendChild('<h1>Action</h1>' . '<div class="aphront-form-inset">' . '<div style="float: right;">' . javelin_render_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'create-action', 'mustcapture' => true), 'Create New Action') . '</div>' . '<p>' . 'Take these actions ' . $repetition_selector . ' this rule matches:' . '</p>' . '<div style="clear: both;"></div>' . javelin_render_tag('table', array('sigil' => 'rule-actions', 'class' => 'herald-action-table'), '') . '</div>')->appendChild(id(new AphrontFormSubmitControl())->setValue('Save Rule')->addCancelButton('/herald/view/' . $rule->getContentType() . '/')); $serial_conditions = array(array('default', 'default', '')); if ($rule->getConditions()) { $serial_conditions = array(); foreach ($rule->getConditions() as $condition) { $value = $condition->getValue(); if (is_array($value)) { $value_map = array(); foreach ($value as $k => $fbid) { $value_map[$fbid] = $handles[$fbid]->getName(); } $value = $value_map; } $serial_conditions[] = array($condition->getFieldName(), $condition->getFieldCondition(), $value); } } $serial_actions = array(array('default', '')); if ($rule->getActions()) { $serial_actions = array(); foreach ($rule->getActions() as $action) { $target_map = array(); foreach ((array) $action->getTarget() as $fbid) { $target_map[$fbid] = $handles[$fbid]->getName(); } $serial_actions[] = array($action->getAction(), $target_map); } } $all_rules = id(new HeraldRule())->loadAllWhere('authorPHID = %d AND contentType = %s', $rule->getAuthorPHID(), $rule->getContentType()); $all_rules = mpull($all_rules, 'getName', 'getID'); asort($all_rules); unset($all_rules[$rule->getID()]); $config_info = array(); $config_info['fields'] = HeraldFieldConfig::getFieldMapForContentType($rule->getContentType()); $config_info['conditions'] = HeraldConditionConfig::getConditionMap(); foreach ($config_info['fields'] as $field => $name) { $config_info['conditionMap'][$field] = array_keys(HeraldConditionConfig::getConditionMapForField($field)); } foreach ($config_info['fields'] as $field => $fname) { foreach ($config_info['conditions'] as $condition => $cname) { $config_info['values'][$field][$condition] = HeraldValueTypeConfig::getValueTypeForFieldAndCondition($field, $condition); } } $config_info['actions'] = HeraldActionConfig::getActionMapForContentType($rule->getContentType()); foreach ($config_info['actions'] as $action => $name) { $config_info['targets'][$action] = HeraldValueTypeConfig::getValueTypeForAction($action); } Javelin::initBehavior('herald-rule-editor', array('root' => 'herald-rule-edit-form', 'conditions' => (object) $serial_conditions, 'actions' => (object) $serial_actions, 'template' => $this->buildTokenizerTemplates() + array('rules' => $all_rules), 'info' => $config_info)); $panel = new AphrontPanelView(); $panel->setHeader('Edit Herald Rule'); $panel->setWidth(AphrontPanelView::WIDTH_WIDE); $panel->appendChild($form); return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Edit Rule')); }