public function newBranchFromCommit(PhabricatorRepositoryCommit $cut_point, $branch_date, $symbolic_name = null)
 {
     $template = $this->releephProject->getDetail('branchTemplate');
     if (!$template) {
         $template = ReleephBranchTemplate::getRequiredDefaultTemplate();
     }
     $cut_point_handle = id(new PhabricatorHandleQuery())->setViewer($this->requireActor())->withPHIDs(array($cut_point->getPHID()))->executeOne();
     list($name, $errors) = id(new ReleephBranchTemplate())->setCommitHandle($cut_point_handle)->setBranchDate($branch_date)->setReleephProjectName($this->releephProject->getName())->interpolate($template);
     $basename = last(explode('/', $name));
     $table = id(new ReleephBranch());
     $transaction = $table->openTransaction();
     $branch = id(new ReleephBranch())->setName($name)->setBasename($basename)->setReleephProjectID($this->releephProject->getID())->setCreatedByUserPHID($this->requireActor()->getPHID())->setCutPointCommitPHID($cut_point->getPHID())->setIsActive(1)->setDetail('branchDate', $branch_date)->save();
     /**
      * Steal the symbolic name from any other branch that has it (in this
      * project).
      */
     if ($symbolic_name) {
         $others = id(new ReleephBranch())->loadAllWhere('releephProjectID = %d', $this->releephProject->getID());
         foreach ($others as $other) {
             if ($other->getSymbolicName() == $symbolic_name) {
                 $other->setSymbolicName(null)->save();
             }
         }
         $branch->setSymbolicName($symbolic_name)->save();
     }
     $table->saveTransaction();
     return $branch;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $is_symbolic = $request->getBool('isSymbolic');
     $template = $request->getStr('template');
     if (!$is_symbolic && !$template) {
         $template = ReleephBranchTemplate::getDefaultTemplate();
     }
     $repository_phid = $request->getInt('repositoryPHID');
     $fake_commit_handle = ReleephBranchTemplate::getFakeCommitHandleFor($repository_phid, $request->getUser());
     list($name, $errors) = id(new ReleephBranchTemplate())->setCommitHandle($fake_commit_handle)->setReleephProjectName($request->getStr('projectName'))->setSymbolic($is_symbolic)->interpolate($template);
     $markup = '';
     if ($name) {
         $markup = phutil_tag('div', array('class' => 'name'), $name);
     }
     if ($errors) {
         $markup .= phutil_tag('div', array('class' => 'error'), head($errors));
     }
     return id(new AphrontAjaxResponse())->setContent(array('markup' => $markup));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('projectID');
     $product = id(new ReleephProductQuery())->setViewer($viewer)->withIDs(array($id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$product) {
         return new Aphront404Response();
     }
     $this->setProduct($product);
     $e_name = true;
     $e_trunk_branch = true;
     $e_branch_template = false;
     $errors = array();
     $product_name = $request->getStr('name', $product->getName());
     $trunk_branch = $request->getStr('trunkBranch', $product->getTrunkBranch());
     $branch_template = $request->getStr('branchTemplate');
     if ($branch_template === null) {
         $branch_template = $product->getDetail('branchTemplate');
     }
     $pick_failure_instructions = $request->getStr('pickFailureInstructions', $product->getDetail('pick_failure_instructions'));
     $test_paths = $request->getStr('testPaths');
     if ($test_paths !== null) {
         $test_paths = array_filter(explode("\n", $test_paths));
     } else {
         $test_paths = $product->getDetail('testPaths', array());
     }
     $repository_phid = $product->getRepositoryPHID();
     if ($request->isFormPost()) {
         $pusher_phids = $request->getArr('pushers');
         if (!$product_name) {
             $e_name = pht('Required');
             $errors[] = pht('Your Releeph product should have a simple descriptive name.');
         }
         if (!$trunk_branch) {
             $e_trunk_branch = pht('Required');
             $errors[] = pht('You must specify which branch you will be picking from.');
         }
         $other_releeph_products = id(new ReleephProject())->loadAllWhere('id != %d', $product->getID());
         $other_releeph_product_names = mpull($other_releeph_products, 'getName', 'getID');
         if (in_array($product_name, $other_releeph_product_names)) {
             $errors[] = pht('Releeph product name %s is already taken', $product_name);
         }
         foreach ($test_paths as $test_path) {
             $result = @preg_match($test_path, '');
             $is_a_valid_regexp = $result !== false;
             if (!$is_a_valid_regexp) {
                 $errors[] = pht('Please provide a valid regular expression: ' . '%s is not valid', $test_path);
             }
         }
         $product->setName($product_name)->setTrunkBranch($trunk_branch)->setDetail('pushers', $pusher_phids)->setDetail('pick_failure_instructions', $pick_failure_instructions)->setDetail('branchTemplate', $branch_template)->setDetail('testPaths', $test_paths);
         $fake_commit_handle = ReleephBranchTemplate::getFakeCommitHandleFor($repository_phid, $viewer);
         if ($branch_template) {
             list($branch_name, $template_errors) = id(new ReleephBranchTemplate())->setCommitHandle($fake_commit_handle)->setReleephProjectName($product_name)->interpolate($branch_template);
             if ($template_errors) {
                 $e_branch_template = pht('Whoopsies!');
                 foreach ($template_errors as $template_error) {
                     $errors[] = pht('Template error: %s', $template_error);
                 }
             }
         }
         if (!$errors) {
             $product->save();
             return id(new AphrontRedirectResponse())->setURI($product->getURI());
         }
     }
     $pusher_phids = $request->getArr('pushers', $product->getDetail('pushers', array()));
     $form = id(new AphrontFormView())->setUser($request->getUser())->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Name'))->setName('name')->setValue($product_name)->setError($e_name)->setCaption(pht('A name like "Thrift" but not "Thrift releases".')))->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Repository'))->setValue($product->getRepository()->getName()))->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Repository'))->setValue($product->getRepository()->getName()))->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Releeph Project PHID'))->setValue($product->getPHID()))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Trunk'))->setValue($trunk_branch)->setName('trunkBranch')->setError($e_trunk_branch))->appendChild(id(new AphrontFormTextAreaControl())->setLabel(pht('Pick Instructions'))->setValue($pick_failure_instructions)->setName('pickFailureInstructions')->setCaption(pht('Instructions for pick failures, which will be used ' . 'in emails generated by failed picks')))->appendChild(id(new AphrontFormTextAreaControl())->setLabel(pht('Tests paths'))->setValue(implode("\n", $test_paths))->setName('testPaths')->setCaption(pht('List of strings that all test files contain in their path ' . 'in this project. One string per line. ' . 'Examples: \'__tests__\', \'/javatests/\'...')));
     $branch_template_input = id(new AphrontFormTextControl())->setName('branchTemplate')->setValue($branch_template)->setLabel(pht('Branch Template'))->setError($e_branch_template)->setCaption(pht("Leave this blank to use your installation's default."));
     $branch_template_preview = id(new ReleephBranchPreviewView())->setLabel(pht('Preview'))->addControl('template', $branch_template_input)->addStatic('repositoryPHID', $repository_phid)->addStatic('isSymbolic', false)->addStatic('projectName', $product->getName());
     $form->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Pushers'))->setName('pushers')->setDatasource(new PhabricatorPeopleDatasource())->setValue($pusher_phids))->appendChild($branch_template_input)->appendChild($branch_template_preview)->appendRemarkupInstructions($this->getBranchHelpText());
     $form->appendChild(id(new AphrontFormSubmitControl())->addCancelButton('/releeph/product/')->setValue(pht('Save')));
     $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Product'))->setFormErrors($errors)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->appendChild($form);
     $title = pht('Edit Product');
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Edit Product'));
     $crumbs->setBorder(true);
     $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-pencil');
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter($box);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view);
 }