private function saveRule(HeraldAdapter $adapter, $rule, $request) { $rule->setName($request->getStr('name')); $match_all = $request->getStr('must_match') == 'all'; $rule->setMustMatchAll((int) $match_all); $repetition_policy_param = $request->getStr('repetition_policy'); $rule->setRepetitionPolicy(HeraldRepetitionPolicyConfig::toInt($repetition_policy_param)); $e_name = true; $errors = array(); if (!strlen($rule->getName())) { $e_name = pht('Required'); $errors[] = pht('Rule must have a name.'); } $data = null; try { $data = phutil_json_decode($request->getStr('rule')); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Failed to decode rule data.'), $ex); } if (!is_array($data) || !$data['conditions'] || !$data['actions']) { throw new Exception(pht('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]); } try { $adapter->willSaveCondition($obj); } catch (HeraldInvalidConditionException $ex) { $errors[] = $ex->getMessage(); } $conditions[] = $obj; } $actions = array(); foreach ($data['actions'] as $action) { if ($action === null) { // Sparse on the client; removals can give us NULLs. continue; } if (!isset($action[1])) { // Legitimate for any action which doesn't need a target, like // "Do nothing". $action[1] = null; } $obj = new HeraldAction(); $obj->setAction($action[0]); $obj->setTarget($action[1]); try { $adapter->willSaveAction($rule, $obj); } catch (HeraldInvalidActionException $ex) { $errors[] = $ex->getMessage(); } $actions[] = $obj; } $rule->attachConditions($conditions); $rule->attachActions($actions); if (!$errors) { $edit_action = $rule->getID() ? 'edit' : 'create'; $rule->openTransaction(); $rule->save(); $rule->saveConditions($conditions); $rule->saveActions($actions); $rule->saveTransaction(); } return array($e_name, $errors); }
private function saveRule(HeraldAdapter $adapter, $rule, $request) { $new_name = $request->getStr('name'); $match_all = $request->getStr('must_match') == 'all'; $repetition_policy_param = $request->getStr('repetition_policy'); $e_name = true; $errors = array(); if (!strlen($new_name)) { $e_name = pht('Required'); $errors[] = pht('Rule must have a name.'); } $data = null; try { $data = phutil_json_decode($request->getStr('rule')); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Failed to decode rule data.'), $ex); } if (!is_array($data) || !$data['conditions'] || !$data['actions']) { throw new Exception(pht('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]); } try { $adapter->willSaveCondition($obj); } catch (HeraldInvalidConditionException $ex) { $errors[] = $ex->getMessage(); } $conditions[] = $obj; } $actions = array(); foreach ($data['actions'] as $action) { if ($action === null) { // Sparse on the client; removals can give us NULLs. continue; } if (!isset($action[1])) { // Legitimate for any action which doesn't need a target, like // "Do nothing". $action[1] = null; } $obj = new HeraldActionRecord(); $obj->setAction($action[0]); $obj->setTarget($action[1]); try { $adapter->willSaveAction($rule, $obj); } catch (HeraldInvalidActionException $ex) { $errors[] = $ex->getMessage(); } $actions[] = $obj; } if (!$errors) { $new_state = id(new HeraldRuleSerializer())->serializeRuleComponents($match_all, $conditions, $actions, $repetition_policy_param); $xactions = array(); $xactions[] = id(new HeraldRuleTransaction())->setTransactionType(HeraldRuleTransaction::TYPE_EDIT)->setNewValue($new_state); $xactions[] = id(new HeraldRuleTransaction())->setTransactionType(HeraldRuleTransaction::TYPE_NAME)->setNewValue($new_name); try { id(new HeraldRuleEditor())->setActor($this->getViewer())->setContinueOnNoEffect(true)->setContentSourceFromRequest($request)->applyTransactions($rule, $xactions); return array(null, null); } catch (Exception $ex) { $errors[] = $ex->getMessage(); } } // mutate current rule, so it would be sent to the client in the right state $rule->setMustMatchAll((int) $match_all); $rule->setName($new_name); $rule->setRepetitionPolicy(HeraldRepetitionPolicyConfig::toInt($repetition_policy_param)); $rule->attachConditions($conditions); $rule->attachActions($actions); return array($e_name, $errors); }