Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/arcanist/conduit/ArcanistProjectInfoConduitAPIMethod.php b/src/applications/arcanist/conduit/ArcanistProjectInfoConduitAPIMethod.php
index 5522fc7261..de47050157 100644
--- a/src/applications/arcanist/conduit/ArcanistProjectInfoConduitAPIMethod.php
+++ b/src/applications/arcanist/conduit/ArcanistProjectInfoConduitAPIMethod.php
@@ -1,64 +1,70 @@
<?php
final class ArcanistProjectInfoConduitAPIMethod
extends ArcanistConduitAPIMethod {
public function getAPIMethodName() {
return 'arcanist.projectinfo';
}
public function getMethodDescription() {
return 'Get information about Arcanist projects.';
}
public function defineParamTypes() {
return array(
'name' => 'required string',
);
}
public function defineReturnType() {
return 'nonempty dict';
}
public function defineErrorTypes() {
return array(
'ERR-BAD-ARCANIST-PROJECT' => 'No such project exists.',
);
}
protected function execute(ConduitAPIRequest $request) {
$name = $request->getValue('name');
$project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere(
'name = %s',
$name);
if (!$project) {
throw new ConduitException('ERR-BAD-ARCANIST-PROJECT');
}
- $repository = $project->loadRepository();
+ $repository = null;
+ if ($project->getRepositoryID()) {
+ $repository = id(new PhabricatorRepositoryQuery())
+ ->setViewer($request->getUser())
+ ->withRepositoryIDs(array($project->getRepositoryID()))
+ ->executeOne();
+ }
$repository_phid = null;
$tracked = false;
$encoding = null;
$dictionary = array();
if ($repository) {
$repository_phid = $repository->getPHID();
$tracked = $repository->isTracked();
$encoding = $repository->getDetail('encoding');
$dictionary = $repository->toDictionary();
}
return array(
'name' => $project->getName(),
'phid' => $project->getPHID(),
'repositoryPHID' => $repository_phid,
'tracked' => $tracked,
'encoding' => $encoding,
'repository' => $dictionary,
);
}
}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php b/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php
index 8d225ea6b8..6eefc0dc83 100644
--- a/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php
+++ b/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php
@@ -1,46 +1,48 @@
<?php
final class ReleephBranchNamePreviewController
extends ReleephController {
public function processRequest() {
$request = $this->getRequest();
$is_symbolic = $request->getBool('isSymbolic');
$template = $request->getStr('template');
if (!$is_symbolic && !$template) {
$template = ReleephBranchTemplate::getDefaultTemplate();
}
$arc_project_id = $request->getInt('arcProjectID');
$fake_commit_handle =
- ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id);
+ ReleephBranchTemplate::getFakeCommitHandleFor(
+ $arc_project_id,
+ $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));
}
}
diff --git a/src/applications/releeph/controller/product/ReleephProductCreateController.php b/src/applications/releeph/controller/product/ReleephProductCreateController.php
index 6168c5fa1e..0bad1031b8 100644
--- a/src/applications/releeph/controller/product/ReleephProductCreateController.php
+++ b/src/applications/releeph/controller/product/ReleephProductCreateController.php
@@ -1,162 +1,169 @@
<?php
final class ReleephProductCreateController extends ReleephProductController {
public function processRequest() {
$request = $this->getRequest();
$name = trim($request->getStr('name'));
$trunk_branch = trim($request->getStr('trunkBranch'));
$arc_pr_id = $request->getInt('arcPrID');
$arc_projects = $this->loadArcProjects();
$e_name = true;
$e_trunk_branch = true;
$errors = array();
if ($request->isFormPost()) {
if (!$name) {
$e_name = pht('Required');
$errors[] = pht(
'Your 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.');
}
$arc_project = $arc_projects[$arc_pr_id];
- $pr_repository = $arc_project->loadRepository();
+ $pr_repository = null;
+ if ($arc_project->getRepositoryID()) {
+ $pr_repository = id(new PhabricatorRepositoryQuery())
+ ->setViewer($request->getUser())
+ ->withRepositoryIDs(array($arc_project->getRepositoryID()))
+ ->executeOne();
+ }
+
if (!$errors) {
$releeph_product = id(new ReleephProject())
->setName($name)
->setTrunkBranch($trunk_branch)
->setRepositoryPHID($pr_repository->getPHID())
->setArcanistProjectID($arc_project->getID())
->setCreatedByUserPHID($request->getUser()->getPHID())
->setIsActive(1);
try {
$releeph_product->save();
return id(new AphrontRedirectResponse())
->setURI($releeph_product->getURI());
} catch (AphrontDuplicateKeyQueryException $ex) {
$e_name = pht('Not Unique');
$errors[] = pht('Another product already uses this name.');
}
}
}
$arc_project_options = $this->getArcProjectSelectOptions($arc_projects);
$product_name_input = id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setDisableAutocomplete(true)
->setName('name')
->setValue($name)
->setError($e_name)
->setCaption(pht('A name like "Thrift" but not "Thrift releases".'));
$arc_project_input = id(new AphrontFormSelectControl())
->setLabel(pht('Arc Project'))
->setName('arcPrID')
->setValue($arc_pr_id)
->setCaption(pht(
'If your Arc project isn\'t listed, associate it with a repository %s',
phutil_tag(
'a',
array(
'href' => '/repository/',
'target' => '_blank',
),
'here')))
->setOptions($arc_project_options);
$branch_name_preview = id(new ReleephBranchPreviewView())
->setLabel(pht('Example Branch'))
->addControl('projectName', $product_name_input)
->addControl('arcProjectID', $arc_project_input)
->addStatic('template', '')
->addStatic('isSymbolic', false);
$form = id(new AphrontFormView())
->setUser($request->getUser())
->appendChild($product_name_input)
->appendChild($arc_project_input)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Trunk'))
->setName('trunkBranch')
->setValue($trunk_branch)
->setError($e_trunk_branch)
->setCaption(pht('The development branch, '.
'from which requests will be picked.')))
->appendChild($branch_name_preview)
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton('/releeph/project/')
->setValue(pht('Create Release Product')));
$form_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Create New Product'))
->setFormErrors($errors)
->setForm($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('New Product'));
return $this->buildApplicationPage(
array(
$crumbs,
$form_box,
),
array(
'title' => pht('Create New Product'),
));
}
private function loadArcProjects() {
$viewer = $this->getRequest()->getUser();
$projects = id(new PhabricatorRepositoryArcanistProjectQuery())
->setViewer($viewer)
->needRepositories(true)
->execute();
$projects = mfilter($projects, 'getRepository');
$projects = msort($projects, 'getName');
return $projects;
}
private function getArcProjectSelectOptions(array $arc_projects) {
assert_instances_of($arc_projects, 'PhabricatorRepositoryArcanistProject');
$repos = mpull($arc_projects, 'getRepository');
$repos = mpull($repos, null, 'getID');
$groups = array();
foreach ($arc_projects as $arc_project) {
$id = $arc_project->getID();
$repo_id = $arc_project->getRepository()->getID();
$groups[$repo_id][$id] = $arc_project->getName();
}
$choices = array();
foreach ($groups as $repo_id => $group) {
$repo_name = $repos[$repo_id]->getName();
$callsign = $repos[$repo_id]->getCallsign();
$name = "r{$callsign} ({$repo_name})";
$choices[$name] = $group;
}
ksort($choices);
return $choices;
}
}
diff --git a/src/applications/releeph/controller/product/ReleephProductEditController.php b/src/applications/releeph/controller/product/ReleephProductEditController.php
index 34a3a48091..2399548206 100644
--- a/src/applications/releeph/controller/product/ReleephProductEditController.php
+++ b/src/applications/releeph/controller/product/ReleephProductEditController.php
@@ -1,280 +1,280 @@
<?php
final class ReleephProductEditController extends ReleephProductController {
private $productID;
public function willProcessRequest(array $data) {
$this->productID = $data['projectID'];
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$product = id(new ReleephProductQuery())
->setViewer($viewer)
->withIDs(array($this->productID))
->needArcanistProjects(true)
->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());
}
$arc_project_id = $product->getArcanistProjectID();
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($arc_project_id);
+ ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id, $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[] = "Template error: {$template_error}";
}
}
}
if (!$errors) {
$product->save();
return id(new AphrontRedirectResponse())->setURI($product->getURI());
}
}
$pusher_phids = $request->getArr(
'pushers',
$product->getDetail('pushers', array()));
$handles = id(new PhabricatorHandleQuery())
->setViewer($request->getUser())
->withPHIDs($pusher_phids)
->execute();
$pusher_handles = array_select_keys($handles, $pusher_phids);
$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('Arc Project'))
->setValue(
$product->getArcanistProject()->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('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('arcProjectID', $arc_project_id)
->addStatic('isSymbolic', false)
->addStatic('projectName', $product->getName());
$form
->appendChild(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Pushers'))
->setName('pushers')
->setDatasource(new PhabricatorPeopleDatasource())
->setValue($pusher_handles))
->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('Edit Releeph Product'))
->setFormErrors($errors)
->appendChild($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Edit Product'));
return $this->buildStandardPageResponse(
array(
$crumbs,
$box,
),
array(
'title' => pht('Edit Releeph Product'),
'device' => true,
));
}
private function getBranchHelpText() {
return <<<EOTEXT
==== Interpolations ====
| Code | Meaning
| ----- | -------
| `%P` | The name of your product, with spaces changed to "-".
| `%p` | Like %P, but all lowercase.
| `%Y` | The four digit year associated with the branch date.
| `%m` | The two digit month.
| `%d` | The two digit day.
| `%v` | The handle of the commit where the branch was cut ("rXYZa4b3c2d1").
| `%V` | The abbreviated commit id where the branch was cut ("a4b3c2d1").
| `%..` | Any other sequence interpreted by `strftime()`.
| `%%` | A literal percent sign.
==== Tips for Branch Templates ====
Use a directory to separate your release branches from other branches:
lang=none
releases/%Y-%M-%d-%v
=> releases/2012-30-16-rHERGE32cd512a52b7
Include a second hierarchy if you share your repository with other products:
lang=none
releases/%P/%p-release-%Y%m%d-%V
=> releases/Tintin/tintin-release-20121116-32cd512a52b7
Keep your branch names simple, avoiding strange punctuation, most of which is
forbidden or escaped anyway:
lang=none, counterexample
releases//..clown-releases..//`date --iso=seconds`-$(sudo halt)
Include the date early in your template, in an order which sorts properly:
lang=none
releases/%Y%m%d-%v
=> releases/20121116-rHERGE32cd512a52b7 (good!)
releases/%V-%m.%d.%Y
=> releases/32cd512a52b7-11.16.2012 (awful!)
EOTEXT;
}
}
diff --git a/src/applications/releeph/view/branch/ReleephBranchTemplate.php b/src/applications/releeph/view/branch/ReleephBranchTemplate.php
index 4672fc020b..73c5d5200e 100644
--- a/src/applications/releeph/view/branch/ReleephBranchTemplate.php
+++ b/src/applications/releeph/view/branch/ReleephBranchTemplate.php
@@ -1,188 +1,201 @@
<?php
final class ReleephBranchTemplate {
const KEY = 'releeph.default-branch-template';
public static function getDefaultTemplate() {
return PhabricatorEnv::getEnvConfig(self::KEY);
}
public static function getRequiredDefaultTemplate() {
$template = self::getDefaultTemplate();
if (!$template) {
throw new Exception(sprintf(
"Config setting '%s' must be set, ".
"or you must provide a branch-template for each project!",
self::KEY));
}
return $template;
}
- public static function getFakeCommitHandleFor($arc_project_id) {
+ public static function getFakeCommitHandleFor(
+ $arc_project_id,
+ PhabricatorUser $viewer) {
+
$arc_project = id(new PhabricatorRepositoryArcanistProject())
->load($arc_project_id);
if (!$arc_project) {
throw new Exception(
"No Arc project found with id '{$arc_project_id}'!");
}
- $repository = $arc_project->loadRepository();
- return id(new PhabricatorObjectHandle())
- ->setName($repository->formatCommitName('100000000000'));
+ $repository = null;
+ if ($arc_project->getRepositoryID()) {
+ $repository = id(new PhabricatorRepositoryQuery())
+ ->setViewer($viewer)
+ ->withRepositoryIDs(array($arc_project->getRepositoryID()))
+ ->executeOne();
+ }
+ $fake_handle = 'SOFAKE';
+ if ($repository) {
+ $fake_handle = id(new PhabricatorObjectHandle())
+ ->setName($repository->formatCommitName('100000000000'));
+ }
+ return $fake_handle;
}
private $commitHandle;
private $branchDate = null;
private $projectName;
private $isSymbolic;
public function setCommitHandle(PhabricatorObjectHandle $handle) {
$this->commitHandle = $handle;
return $this;
}
public function setBranchDate($branch_date) {
$this->branchDate = $branch_date;
return $this;
}
public function setReleephProjectName($project_name) {
$this->projectName = $project_name;
return $this;
}
public function setSymbolic($is_symbolic) {
$this->isSymbolic = $is_symbolic;
return $this;
}
public function interpolate($template) {
if (!$this->projectName) {
return array('', array());
}
list($name, $name_errors) = $this->interpolateInner(
$template,
$this->isSymbolic);
if ($this->isSymbolic) {
return array($name, $name_errors);
} else {
$validate_errors = $this->validateAsBranchName($name);
$errors = array_merge($name_errors, $validate_errors);
return array($name, $errors);
}
}
/*
* xsprintf() would be useful here, but that's for formatting concrete lists
* of things in a certain way...
*
* animal_printf('%A %A %A', $dog1, $dog2, $dog3);
*
* ...rather than interpolating percent-control-strings like strftime does.
*/
private function interpolateInner($template, $is_symbolic) {
$name = $template;
$errors = array();
$safe_project_name = str_replace(' ', '-', $this->projectName);
$short_commit_id = last(
preg_split('/r[A-Z]+/', $this->commitHandle->getName()));
$interpolations = array();
for ($ii = 0; $ii < strlen($name); $ii++) {
$char = substr($name, $ii, 1);
$prev = null;
if ($ii > 0) {
$prev = substr($name, $ii - 1, 1);
}
$next = substr($name, $ii + 1, 1);
if ($next && $char == '%' && $prev != '%') {
$interpolations[$ii] = $next;
}
}
$variable_interpolations = array();
$reverse_interpolations = $interpolations;
krsort($reverse_interpolations);
if ($this->branchDate) {
$branch_date = $this->branchDate;
} else {
$branch_date = $this->commitHandle->getTimestamp();
}
foreach ($reverse_interpolations as $position => $code) {
$replacement = null;
switch ($code) {
case 'v':
$replacement = $this->commitHandle->getName();
$is_variable = true;
break;
case 'V':
$replacement = $short_commit_id;
$is_variable = true;
break;
case 'P':
$replacement = $safe_project_name;
$is_variable = false;
break;
case 'p':
$replacement = strtolower($safe_project_name);
$is_variable = false;
break;
default:
// Format anything else using strftime()
$replacement = strftime("%{$code}", $branch_date);
$is_variable = true;
break;
}
if ($is_variable) {
$variable_interpolations[] = $code;
}
$name = substr_replace($name, $replacement, $position, 2);
}
if (!$is_symbolic && !$variable_interpolations) {
$errors[] = "Include additional interpolations that aren't static!";
}
return array($name, $errors);
}
private function validateAsBranchName($name) {
$errors = array();
if (preg_match('{^/}', $name) || preg_match('{/$}', $name)) {
$errors[] = "Branches cannot begin or end with '/'";
}
if (preg_match('{//+}', $name)) {
$errors[] = "Branches cannot contain multiple consective '/'";
}
$parts = array_filter(explode('/', $name));
foreach ($parts as $index => $part) {
$part_error = null;
if (preg_match('{^\.}', $part) || preg_match('{\.$}', $part)) {
$errors[] = "Path components cannot begin or end with '.'";
} else if (preg_match('{^(?!\w)}', $part)) {
$errors[] = 'Path components must begin with an alphanumeric';
} else if (!preg_match('{^\w ([\w-_%\.]* [\w-_%])?$}x', $part)) {
$errors[] =
"Path components may only contain alphanumerics ".
"or '-', '_', or '.'";
}
}
return $errors;
}
}
diff --git a/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php b/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php
index 08a89175b0..dc18025827 100644
--- a/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryArcanistProject.php
@@ -1,118 +1,110 @@
<?php
final class PhabricatorRepositoryArcanistProject
extends PhabricatorRepositoryDAO
implements
PhabricatorPolicyInterface,
PhabricatorDestructibleInterface {
protected $name;
protected $repositoryID;
protected $symbolIndexLanguages = array();
protected $symbolIndexProjects = array();
private $repository = self::ATTACHABLE;
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_SERIALIZATION => array(
'symbolIndexLanguages' => self::SERIALIZATION_JSON,
'symbolIndexProjects' => self::SERIALIZATION_JSON,
),
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text128',
'repositoryID' => 'id?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
'phid' => array(
'columns' => array('phid'),
'unique' => true,
),
'name' => array(
'columns' => array('name'),
'unique' => true,
),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorRepositoryArcanistProjectPHIDType::TYPECONST);
}
- // TODO: Remove. Also, T603.
- public function loadRepository() {
- if (!$this->getRepositoryID()) {
- return null;
- }
- return id(new PhabricatorRepository())->load($this->getRepositoryID());
- }
-
public function delete() {
$this->openTransaction();
queryfx(
$this->establishConnection('w'),
'DELETE FROM %T WHERE arcanistProjectID = %d',
id(new PhabricatorRepositorySymbol())->getTableName(),
$this->getID());
$result = parent::delete();
$this->saveTransaction();
return $result;
}
public function getRepository() {
return $this->assertAttached($this->repository);
}
public function attachRepository(PhabricatorRepository $repository = null) {
$this->repository = $repository;
return $this;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return PhabricatorPolicies::POLICY_USER;
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::POLICY_ADMIN;
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
public function describeAutomaticCapability($capability) {
return null;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$this->saveTransaction();
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Apr 28, 1:59 PM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
108008
Default Alt Text
(28 KB)

Event Timeline