| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							| 
									
										
										
										
											2012-01-05 13:07:08 -08:00
										 |  |  |  * Copyright 2012 Facebook, Inc. | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-09 15:46:25 -08:00
										 |  |  | final class HeraldRuleController extends HeraldController { | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   private $id; | 
					
						
							| 
									
										
										
										
											2011-12-16 13:29:32 -08:00
										 |  |  |   private $filter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |   public function willProcessRequest(array $data) { | 
					
						
							|  |  |  |     $this->id = (int)idx($data, 'id'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public function processRequest() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $request = $this->getRequest(); | 
					
						
							|  |  |  |     $user = $request->getUser(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $content_type_map = HeraldContentTypeConfig::getContentTypeMap(); | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |     $rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap(); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ($this->id) { | 
					
						
							|  |  |  |       $rule = id(new HeraldRule())->load($this->id); | 
					
						
							|  |  |  |       if (!$rule) { | 
					
						
							|  |  |  |         return new Aphront404Response(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |       if (!$this->canEditRule($rule, $user)) { | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |         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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |       $content_type = $request->getStr('content_type'); | 
					
						
							|  |  |  |       if (!isset($content_type_map[$content_type])) { | 
					
						
							|  |  |  |         $content_type = HeraldContentTypeConfig::CONTENT_TYPE_DIFFERENTIAL; | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |       $rule->setContentType($content_type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $rule_type = $request->getStr('rule_type'); | 
					
						
							|  |  |  |       if (!isset($rule_type_map[$rule_type])) { | 
					
						
							|  |  |  |         $rule_type = HeraldRuleTypeConfig::RULE_TYPE_GLOBAL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       $rule->setRuleType($rule_type); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $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 ". | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |         "view or edit it in this older version. Upgrade your Phabricator ". | 
					
						
							|  |  |  |         "deployment."); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 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')) { | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |       list($e_name, $errors) = $this->saveRule($rule, $request); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       if (!$errors) { | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |         $uri = '/herald/view/'. | 
					
						
							|  |  |  |           $rule->getContentType().'/'. | 
					
						
							|  |  |  |           $rule->getRuleType().'/'; | 
					
						
							|  |  |  |         return id(new AphrontRedirectResponse())->setURI($uri); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($errors) { | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  |       $error_view = new AphrontErrorView(); | 
					
						
							|  |  |  |       $error_view->setTitle('Form Errors'); | 
					
						
							|  |  |  |       $error_view->setErrors($errors); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $error_view = null; | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |     $must_match_selector = $this->renderMustMatchSelector($rule); | 
					
						
							|  |  |  |     $repetition_selector = $this->renderRepetitionSelector($rule); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-15 14:11:40 -07:00
										 |  |  |     $handles = $this->loadHandlesForRule($rule); | 
					
						
							| 
									
										
										
										
											2011-05-27 15:52:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  |     require_celerity_resource('herald-css'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |     $content_type_name = $content_type_map[$rule->getContentType()]; | 
					
						
							|  |  |  |     $rule_type_name = $rule_type_map[$rule->getRuleType()]; | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $form = id(new AphrontFormView()) | 
					
						
							|  |  |  |       ->setUser($user) | 
					
						
							| 
									
										
										
										
											2011-03-22 17:08:08 -07:00
										 |  |  |       ->setID('herald-rule-edit-form') | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |       ->addHiddenInput('content_type', $rule->getContentType()) | 
					
						
							|  |  |  |       ->addHiddenInput('rule_type', $rule->getRuleType()) | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  |       ->addHiddenInput('save', 1) | 
					
						
							|  |  |  |       ->appendChild( | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |         // Build this explicitly (instead of using addHiddenInput())
 | 
					
						
							|  |  |  |         // so we can add a sigil to it.
 | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  |         javelin_render_tag( | 
					
						
							|  |  |  |           'input', | 
					
						
							|  |  |  |           array( | 
					
						
							|  |  |  |             'type'  => 'hidden', | 
					
						
							|  |  |  |             'name'  => 'rule', | 
					
						
							|  |  |  |             'sigil' => 'rule', | 
					
						
							|  |  |  |           ))) | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       ->appendChild( | 
					
						
							|  |  |  |         id(new AphrontFormTextControl()) | 
					
						
							|  |  |  |           ->setLabel('Rule Name') | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  |           ->setName('name') | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |           ->setError($e_name) | 
					
						
							| 
									
										
										
											
												Improve Herald personal/global UI/UX
Summary:
  - Default "personal" vs "global" choice to "personal".
  - Don't show global rules under "My Rules".
  - After editing or creating a global rule, redirect back to global rule list.
  - Use radio buttons for "personal" vs "global" and add captions explaining the
difference.
  - For "global" rules, don't show the owner/author in the rule detail view --
they effectively have no owner (see also D1387).
  - For "global" rules, don't show the owner/author in the rule list view, as
above.
  - For admin views, show rule type (global vs personal).
Test Plan:
  - Created and edited new global and personal rules.
  - Viewed "my", "global" and "admin" views.
Reviewers: btrahan, jungejason, nh, xela
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D1518
											
										 
											2012-01-31 12:09:29 -08:00
										 |  |  |           ->setValue($rule->getName())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $form | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       ->appendChild( | 
					
						
							|  |  |  |         id(new AphrontFormMarkupControl()) | 
					
						
							|  |  |  |           ->setValue( | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |             "This <strong>${rule_type_name}</strong> rule triggers for " . | 
					
						
							|  |  |  |             "<strong>${content_type_name}</strong>.")) | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       ->appendChild( | 
					
						
							| 
									
										
										
										
											2012-03-15 17:10:19 -07:00
										 |  |  |         id(new AphrontFormInsetView()) | 
					
						
							|  |  |  |           ->setTitle('Conditions') | 
					
						
							|  |  |  |           ->setRightButton(javelin_render_tag( | 
					
						
							|  |  |  |             'a', | 
					
						
							|  |  |  |             array( | 
					
						
							|  |  |  |               'href' => '#', | 
					
						
							|  |  |  |               'class' => 'button green', | 
					
						
							|  |  |  |               'sigil' => 'create-condition', | 
					
						
							|  |  |  |               'mustcapture' => true | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             'Create New Condition')) | 
					
						
							|  |  |  |           ->setDescription( | 
					
						
							|  |  |  |             'When '.$must_match_selector . | 
					
						
							|  |  |  |             ' these conditions are met:') | 
					
						
							|  |  |  |           ->setContent(javelin_render_tag( | 
					
						
							| 
									
										
										
										
											2011-03-22 17:08:08 -07:00
										 |  |  |             'table', | 
					
						
							|  |  |  |             array( | 
					
						
							|  |  |  |               'sigil' => 'rule-conditions', | 
					
						
							| 
									
										
										
										
											2012-03-15 17:10:19 -07:00
										 |  |  |               'class' => 'herald-condition-table' | 
					
						
							| 
									
										
										
										
											2011-03-22 17:08:08 -07:00
										 |  |  |             ), | 
					
						
							| 
									
										
										
										
											2012-03-15 17:10:19 -07:00
										 |  |  |             ''))) | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       ->appendChild( | 
					
						
							| 
									
										
										
										
											2012-03-15 17:10:19 -07:00
										 |  |  |         id(new AphrontFormInsetView()) | 
					
						
							|  |  |  |           ->setTitle('Action') | 
					
						
							|  |  |  |           ->setRightButton(javelin_render_tag( | 
					
						
							| 
									
										
										
										
											2011-03-22 20:41:02 -07:00
										 |  |  |             'a', | 
					
						
							|  |  |  |             array( | 
					
						
							|  |  |  |               'href' => '#', | 
					
						
							|  |  |  |               'class' => 'button green', | 
					
						
							|  |  |  |               'sigil' => 'create-action', | 
					
						
							|  |  |  |               'mustcapture' => true, | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2012-03-15 17:10:19 -07:00
										 |  |  |             'Create New Action')) | 
					
						
							|  |  |  |           ->setDescription('Take these actions '.$repetition_selector. | 
					
						
							|  |  |  |             ' this rule matches:') | 
					
						
							|  |  |  |           ->setContent(javelin_render_tag( | 
					
						
							|  |  |  |               'table', | 
					
						
							|  |  |  |               array( | 
					
						
							|  |  |  |                 'sigil' => 'rule-actions', | 
					
						
							|  |  |  |                 'class' => 'herald-action-table', | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |               ''))) | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       ->appendChild( | 
					
						
							|  |  |  |         id(new AphrontFormSubmitControl()) | 
					
						
							| 
									
										
										
										
											2011-03-22 20:41:02 -07:00
										 |  |  |           ->setValue('Save Rule') | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |           ->addCancelButton('/herald/view/'.$rule->getContentType().'/')); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     $this->setupEditorBehavior($rule, $handles); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $panel = new AphrontPanelView(); | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |     $panel->setHeader( | 
					
						
							|  |  |  |       $rule->getID() | 
					
						
							|  |  |  |         ? 'Edit Herald Rule' | 
					
						
							|  |  |  |         : 'Create Herald Rule'); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     $panel->setWidth(AphrontPanelView::WIDTH_WIDE); | 
					
						
							|  |  |  |     $panel->appendChild($form); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |     $nav = $this->renderNav(); | 
					
						
							|  |  |  |     $nav->selectFilter( | 
					
						
							|  |  |  |       'view/'.$rule->getContentType().'/'.$rule->getRuleType()); | 
					
						
							|  |  |  |     $nav->appendChild( | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |       array( | 
					
						
							|  |  |  |         $error_view, | 
					
						
							|  |  |  |         $panel, | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |       )); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return $this->buildStandardPageResponse( | 
					
						
							|  |  |  |       $nav, | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |       array( | 
					
						
							|  |  |  |         'title' => 'Edit Rule', | 
					
						
							|  |  |  |       )); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |   private function canEditRule($rule, $user) { | 
					
						
							|  |  |  |     return | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |       ($user->getIsAdmin()) || | 
					
						
							|  |  |  |       ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) || | 
					
						
							|  |  |  |       ($rule->getAuthorPHID() == $user->getPHID()); | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |   private function saveRule($rule, $request) { | 
					
						
							|  |  |  |     $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) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $e_name = true; | 
					
						
							|  |  |  |     $errors = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!isset($action[1])) { | 
					
						
							|  |  |  |         // Legitimate for any action which doesn't need a target, like
 | 
					
						
							|  |  |  |         // "Do nothing".
 | 
					
						
							|  |  |  |         $action[1] = null; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |       $actions[] = HeraldActionConfig::willSaveAction($rule->getRuleType(), | 
					
						
							|  |  |  |                                                       $rule->getAuthorPHID(), | 
					
						
							|  |  |  |                                                       $action); | 
					
						
							| 
									
										
										
										
											2012-01-05 13:07:08 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     $rule->attachConditions($conditions); | 
					
						
							|  |  |  |     $rule->attachActions($actions); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!$errors) { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |         $edit_action = $rule->getID() ? 'edit' : 'create'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $rule->openTransaction(); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |           $rule->save(); | 
					
						
							|  |  |  |           $rule->saveConditions($conditions); | 
					
						
							|  |  |  |           $rule->saveActions($actions); | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |           $rule->logEdit($request->getUser()->getPHID(), $edit_action); | 
					
						
							|  |  |  |         $rule->saveTransaction(); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       } catch (AphrontQueryDuplicateKeyException $ex) { | 
					
						
							|  |  |  |         $e_name = "Not Unique"; | 
					
						
							|  |  |  |         $errors[] = "Rule name is not unique. Choose a unique name."; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return array($e_name, $errors); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private function setupEditorBehavior($rule, $handles) { | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     $serial_conditions = array( | 
					
						
							|  |  |  |       array('default', 'default', ''), | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     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) { | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  |             $value_map[$fbid] = $handles[$fbid]->getName(); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |           } | 
					
						
							|  |  |  |           $value = $value_map; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $serial_conditions[] = array( | 
					
						
							|  |  |  |           $condition->getFieldName(), | 
					
						
							| 
									
										
										
										
											2011-03-24 11:07:36 -07:00
										 |  |  |           $condition->getFieldCondition(), | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |           $value, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $serial_actions = array( | 
					
						
							|  |  |  |       array('default', ''), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |     if ($rule->getActions()) { | 
					
						
							|  |  |  |       $serial_actions = array(); | 
					
						
							|  |  |  |       foreach ($rule->getActions() as $action) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-30 13:51:54 -07:00
										 |  |  |         switch ($action->getAction()) { | 
					
						
							|  |  |  |           case HeraldActionConfig::ACTION_FLAG: | 
					
						
							|  |  |  |             $current_value = $action->getTarget(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           default: | 
					
						
							|  |  |  |             $target_map = array(); | 
					
						
							|  |  |  |             foreach ((array)$action->getTarget() as $fbid) { | 
					
						
							|  |  |  |               $target_map[$fbid] = $handles[$fbid]->getName(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $current_value = $target_map; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $serial_actions[] = array( | 
					
						
							|  |  |  |           $action->getAction(), | 
					
						
							| 
									
										
										
										
											2012-03-30 13:51:54 -07:00
										 |  |  |           $current_value, | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |     $all_rules = $this->loadRulesThisRuleMayDependUpon($rule); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     $all_rules = mpull($all_rules, 'getName', 'getID'); | 
					
						
							|  |  |  |     asort($all_rules); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $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'] = | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |       HeraldActionConfig::getActionMessageMap($rule->getContentType(), | 
					
						
							|  |  |  |                                               $rule->getRuleType()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $config_info['rule_type'] = $rule->getRuleType(); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     foreach ($config_info['actions'] as $action => $name) { | 
					
						
							|  |  |  |       $config_info['targets'][$action] = | 
					
						
							| 
									
										
										
										
											2012-01-13 15:24:56 -08:00
										 |  |  |         HeraldValueTypeConfig::getValueTypeForAction($action, | 
					
						
							|  |  |  |                                                      $rule->getRuleType()); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Javelin::initBehavior( | 
					
						
							|  |  |  |       'herald-rule-editor', | 
					
						
							|  |  |  |       array( | 
					
						
							| 
									
										
										
										
											2011-03-22 17:08:08 -07:00
										 |  |  |         'root' => 'herald-rule-edit-form', | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |         'conditions' => (object)$serial_conditions, | 
					
						
							|  |  |  |         'actions' => (object)$serial_actions, | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |         'template' => $this->buildTokenizerTemplates() + array( | 
					
						
							|  |  |  |           'rules' => $all_rules, | 
					
						
							| 
									
										
										
										
											2012-03-30 13:51:54 -07:00
										 |  |  |           'colors' => PhabricatorFlagColor::getColorNameMap(), | 
					
						
							|  |  |  |           'defaultColor' => PhabricatorFlagColor::COLOR_BLUE, | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |         ), | 
					
						
							| 
									
										
										
										
											2012-01-05 13:07:08 -08:00
										 |  |  |         'author' => array($rule->getAuthorPHID() => | 
					
						
							|  |  |  |                           $handles[$rule->getAuthorPHID()]->getName()), | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |         'info' => $config_info, | 
					
						
							|  |  |  |       )); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-15 14:11:40 -07:00
										 |  |  |   private function loadHandlesForRule($rule) { | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     $phids = array(); | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |     $phids[] = $rule->getAuthorPHID(); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |     return id(new PhabricatorObjectHandleData($phids))->loadHandles(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Render the selector for the "When (all of | any of) these conditions are
 | 
					
						
							|  |  |  |    * met:" element.
 | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   private function renderMustMatchSelector($rule) { | 
					
						
							|  |  |  |     return AphrontFormSelectControl::renderSelectTag( | 
					
						
							|  |  |  |       $rule->getMustMatchAll() ? 'all' : 'any', | 
					
						
							|  |  |  |       array( | 
					
						
							|  |  |  |         'all' => 'all of', | 
					
						
							|  |  |  |         'any' => 'any of', | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |       array( | 
					
						
							|  |  |  |         'name' => 'must_match', | 
					
						
							|  |  |  |       )); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Render the selector for "Take these actions (every time | only the first
 | 
					
						
							|  |  |  |    * time) this rule matches..." element.
 | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   private function renderRepetitionSelector($rule) { | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     // Make the selector for choosing how often this rule should be repeated
 | 
					
						
							|  |  |  |     $repetition_policy = HeraldRepetitionPolicyConfig::toString( | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |       $rule->getRepetitionPolicy()); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     $repetition_options = HeraldRepetitionPolicyConfig::getMapForContentType( | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |       $rule->getContentType()); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (empty($repetition_options)) { | 
					
						
							|  |  |  |       // default option is 'every time'
 | 
					
						
							|  |  |  |       $repetition_selector = idx( | 
					
						
							|  |  |  |         HeraldRepetitionPolicyConfig::getMap(), | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |         HeraldRepetitionPolicyConfig::EVERY); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |       return $repetition_selector; | 
					
						
							|  |  |  |     } else if (count($repetition_options) == 1) { | 
					
						
							|  |  |  |       // if there's only 1 option, just pick it for the user
 | 
					
						
							|  |  |  |       $repetition_selector = reset($repetition_options); | 
					
						
							|  |  |  |       return $repetition_selector; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  |       return AphrontFormSelectControl::renderSelectTag( | 
					
						
							|  |  |  |         $repetition_policy, | 
					
						
							|  |  |  |         $repetition_options, | 
					
						
							|  |  |  |         array( | 
					
						
							|  |  |  |           'name' => 'repetition_policy', | 
					
						
							|  |  |  |         )); | 
					
						
							| 
									
										
										
										
											2011-10-21 18:34:38 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |   protected function buildTokenizerTemplates() { | 
					
						
							| 
									
										
										
										
											2011-03-22 20:41:02 -07:00
										 |  |  |     $template = new AphrontTokenizerTemplateView(); | 
					
						
							|  |  |  |     $template = $template->render(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     return array( | 
					
						
							|  |  |  |       'source' => array( | 
					
						
							| 
									
										
										
										
											2011-03-22 20:41:02 -07:00
										 |  |  |         'email'       => '/typeahead/common/mailable/', | 
					
						
							| 
									
										
										
										
											2011-03-24 21:32:26 -07:00
										 |  |  |         'user'        => '/typeahead/common/users/', | 
					
						
							| 
									
										
										
										
											2011-04-03 22:23:31 -07:00
										 |  |  |         'repository'  => '/typeahead/common/repositories/', | 
					
						
							|  |  |  |         'package'     => '/typeahead/common/packages/', | 
					
						
							| 
									
										
											  
											
												Allow Herald to trigger audits for users or projects
Summary:
Allows you to write a commit rule that triggers an audit by a user (personal
rules) or a project (global rules).
Mostly this is trying to make auditing more lightweight and accessible in
environments where setting up Owners packages doesn't make sense.
For instance, Disqus wants a rule like "trigger an audit for everything that
didn't have a Differential revision". While not necessarily scalable, this is a
perfectly reasonable rule for a small company, but a lot of work to implement
with Owners (and you'll get a lot of collateral damage if you don't make every
committer a project owner).
Instead, they can create a project called 'Unreviewed Commits' and write a rule
like:
	- When: Differential revision does not exist
 	- Action: Trigger an Audit for project: "Unreviewed Commits"
Then whoever cares can join that project and they'll see those audits in their
queue, and when they approve/raise on commits their actions will affect the
project audit.
Similarly, if I want to look at all commits that match some other rule (say,
XSS) but only want to do it like once a month, I can just set up an audit rule
and go through the queue when I feel like it.
NOTE: This abuses the 'packagePHID' field to also store user and project PHIDs.
Through the magic of handles, this (apparently) works fine for now; I'll do a
big schema patch soon but have several other edits I want to make at the same
time.
Also:
	- Adds an "active" fiew for /audit/, eventually this will be like the
Differential "active" view (stuff that is relevant to you right now).
	- On commits, highlight triggered audits you are responsible for.
Test Plan: Added personal and global audit triggers to Herald, reparsed some
commits with --herald, got audits. Browsed all audit interfaces to make sure
nothing exploded. Viewed a commit where I was responsible for only some audits.
Performed audits and made sure the triggers I am supposed to be responsible for
updated properly.
Reviewers: btrahan, jungejason
Reviewed By: jungejason
CC: aran, epriestley
Maniphest Tasks: T904
Differential Revision: https://secure.phabricator.com/D1690
											
										 
											2012-02-27 09:36:30 -08:00
										 |  |  |         'project'     => '/typeahead/common/projects/', | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |       ), | 
					
						
							| 
									
										
										
										
											2011-03-22 20:41:02 -07:00
										 |  |  |       'markup' => $template, | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
											  
											
												General Herald refactoring pass
Summary:
**Who can delete global rules?**: I discussed this with @jungejason. The current behavior is that the rule author or any administrator can delete a global rule, but this
isn't consistent with who can edit a rule (anyone) and doesn't really make much sense (it's an artifact of the global/personal split). I proposed that anyone can delete a
rule but we don't actually delete them, and log the deletion. However, when it came time to actually write the code for this I backed off a bit and continued actually
deleting the rules -- I think this does a reasonable job of balancing accountability with complexity. So the new impelmentation is:
  - Personal rules can be deleted only by their owners.
  - Global rules can be deleted by any user.
  - All deletes are logged.
  - Logs are more detailed.
  - All logged actions can be viewed in aggregate.
**Minor Cleanup**
  - Merged `HomeController` and `AllController`.
  - Moved most queries to Query classes.
  - Use AphrontFormSelectControl::renderSelectTag() where appropriate (this is a fairly recent addition).
  - Use an AphrontErrorView to render the dry run notice (this didn't exist when I ported).
  - Reenable some transaction code (this works again now).
  - Removed the ability for admins to change rule authors (this was a little buggy, messy, and doesn't make tons of sense after the personal/global rule split).
  - Rules which depend on other rules now display the right options (all global rules, all your personal rules for personal rules).
  - Fix a bug in AphrontTableView where the "no data" cell would be rendered too wide if some columns are not visible.
  - Allow selectFilter() in AphrontNavFilterView to be called without a 'default' argument.
Test Plan:
  - Browsed, created, edited, deleted personal and gules.
  - Verified generated logs.
  - Did some dry runs.
  - Verified transcript list and transcript details.
  - Created/edited all/any rules; created/edited once/every time rules.
  - Filtered admin views by users.
Reviewers: jungejason, btrahan
Reviewed By: btrahan
CC: aran, epriestley
Differential Revision: https://secure.phabricator.com/D2040
											
										 
											2012-03-30 10:49:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Load rules for the "Another Herald rule..." condition dropdown, which | 
					
						
							|  |  |  |    * allows one rule to depend upon the success or failure of another rule. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   private function loadRulesThisRuleMayDependUpon(HeraldRule $rule) { | 
					
						
							|  |  |  |     // Any rule can depend on a global rule.
 | 
					
						
							|  |  |  |     $all_rules = id(new HeraldRuleQuery()) | 
					
						
							|  |  |  |       ->withRuleTypes(array(HeraldRuleTypeConfig::RULE_TYPE_GLOBAL)) | 
					
						
							|  |  |  |       ->withContentTypes(array($rule->getContentType())) | 
					
						
							|  |  |  |       ->execute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL) { | 
					
						
							|  |  |  |       // Personal rules may depend upon your other personal rules.
 | 
					
						
							|  |  |  |       $all_rules += id(new HeraldRuleQuery()) | 
					
						
							|  |  |  |         ->withRuleTypes(array(HeraldRuleTypeConfig::RULE_TYPE_PERSONAL)) | 
					
						
							|  |  |  |         ->withContentTypes(array($rule->getContentType())) | 
					
						
							|  |  |  |         ->withAuthorPHIDs(array($rule->getAuthorPHID())) | 
					
						
							|  |  |  |         ->execute(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // A rule can not depend upon itself.
 | 
					
						
							|  |  |  |     unset($all_rules[$rule->getID()]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return $all_rules; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-22 15:27:52 -07:00
										 |  |  | } |