Page MenuHomestyx hydra

No OneTemporary

diff --git a/resources/sql/autopatches/20151219.proj.01.prislug.sql b/resources/sql/autopatches/20151219.proj.01.prislug.sql
new file mode 100644
index 0000000000..8001dd756c
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.01.prislug.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD COLUMN primarySlug VARCHAR(128) COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20151219.proj.02.prislugkey.sql b/resources/sql/autopatches/20151219.proj.02.prislugkey.sql
new file mode 100644
index 0000000000..a1dbf6ff99
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.02.prislugkey.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD UNIQUE KEY `key_primaryslug` (primarySlug);
diff --git a/resources/sql/autopatches/20151219.proj.03.copyslug.sql b/resources/sql/autopatches/20151219.proj.03.copyslug.sql
new file mode 100644
index 0000000000..2b954c6cdc
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.03.copyslug.sql
@@ -0,0 +1,2 @@
+UPDATE {$NAMESPACE}_project.project
+ SET primarySlug = TRIM(TRAILING "/" FROM phrictionSlug);
diff --git a/resources/sql/autopatches/20151219.proj.04.dropslugkey.sql b/resources/sql/autopatches/20151219.proj.04.dropslugkey.sql
new file mode 100644
index 0000000000..bfe1f2eb4b
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.04.dropslugkey.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ DROP KEY `phrictionSlug`;
diff --git a/resources/sql/autopatches/20151219.proj.05.dropslug.sql b/resources/sql/autopatches/20151219.proj.05.dropslug.sql
new file mode 100644
index 0000000000..924f31ff95
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.05.dropslug.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ DROP COLUMN phrictionSlug;
diff --git a/resources/sql/autopatches/20151219.proj.06.defaultpolicy.php b/resources/sql/autopatches/20151219.proj.06.defaultpolicy.php
new file mode 100644
index 0000000000..e3548d026c
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.06.defaultpolicy.php
@@ -0,0 +1,28 @@
+<?php
+
+$app = PhabricatorApplication::getByClass('PhabricatorProjectApplication');
+
+$view_policy = $app->getPolicy(ProjectDefaultViewCapability::CAPABILITY);
+$edit_policy = $app->getPolicy(ProjectDefaultEditCapability::CAPABILITY);
+$join_policy = $app->getPolicy(ProjectDefaultJoinCapability::CAPABILITY);
+
+$table = new PhabricatorProject();
+$conn_w = $table->establishConnection('w');
+
+queryfx(
+ $conn_w,
+ 'UPDATE %T SET viewPolicy = %s WHERE viewPolicy IS NULL',
+ $table->getTableName(),
+ $view_policy);
+
+queryfx(
+ $conn_w,
+ 'UPDATE %T SET editPolicy = %s WHERE editPolicy IS NULL',
+ $table->getTableName(),
+ $edit_policy);
+
+queryfx(
+ $conn_w,
+ 'UPDATE %T SET joinPolicy = %s WHERE joinPolicy IS NULL',
+ $table->getTableName(),
+ $join_policy);
diff --git a/resources/sql/autopatches/20151219.proj.07.viewnull.sql b/resources/sql/autopatches/20151219.proj.07.viewnull.sql
new file mode 100644
index 0000000000..0e5539fc21
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.07.viewnull.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ CHANGE viewPolicy viewPolicy VARBINARY(64) NOT NULL;
diff --git a/resources/sql/autopatches/20151219.proj.08.editnull.sql b/resources/sql/autopatches/20151219.proj.08.editnull.sql
new file mode 100644
index 0000000000..362e72bf4f
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.08.editnull.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ CHANGE editPolicy editPolicy VARBINARY(64) NOT NULL;
diff --git a/resources/sql/autopatches/20151219.proj.09.joinnull.sql b/resources/sql/autopatches/20151219.proj.09.joinnull.sql
new file mode 100644
index 0000000000..9517ed54f7
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.09.joinnull.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ CHANGE joinPolicy joinPolicy VARBINARY(64) NOT NULL;
diff --git a/resources/sql/autopatches/20151219.proj.10.subcolumns.sql b/resources/sql/autopatches/20151219.proj.10.subcolumns.sql
new file mode 100644
index 0000000000..ea6725a8ab
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.10.subcolumns.sql
@@ -0,0 +1,17 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD parentProjectPHID VARBINARY(64);
+
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD hasWorkboard BOOL NOT NULL;
+
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD hasMilestones BOOL NOT NULL;
+
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD hasSubprojects BOOL NOT NULL;
+
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD milestoneNumber INT UNSIGNED;
+
+ALTER TABLE {$NAMESPACE}_project.project
+ ADD UNIQUE KEY `key_milestone` (parentProjectPHID, milestoneNumber);
diff --git a/resources/sql/autopatches/20151219.proj.11.subprojectphids.sql b/resources/sql/autopatches/20151219.proj.11.subprojectphids.sql
new file mode 100644
index 0000000000..4e51b1358d
--- /dev/null
+++ b/resources/sql/autopatches/20151219.proj.11.subprojectphids.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_project.project
+ DROP subprojectPHIDs;
diff --git a/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php b/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php
index f68eae2b49..ad44b6a56e 100644
--- a/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php
+++ b/src/applications/policy/__tests__/PhabricatorPolicyDataTestCase.php
@@ -1,239 +1,231 @@
<?php
final class PhabricatorPolicyDataTestCase extends PhabricatorTestCase {
protected function getPhabricatorTestCaseConfiguration() {
return array(
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true,
);
}
public function testProjectPolicyMembership() {
$author = $this->generateNewTestUser();
- $proj_a = id(new PhabricatorProject())
+ $proj_a = PhabricatorProject::initializeNewProject($author)
->setName('A')
- ->setAuthorPHID($author->getPHID())
- ->setIcon(PhabricatorProject::DEFAULT_ICON)
- ->setColor(PhabricatorProject::DEFAULT_COLOR)
- ->setIsMembershipLocked(0)
->save();
- $proj_b = id(new PhabricatorProject())
+ $proj_b = PhabricatorProject::initializeNewProject($author)
->setName('B')
- ->setAuthorPHID($author->getPHID())
- ->setIcon(PhabricatorProject::DEFAULT_ICON)
- ->setColor(PhabricatorProject::DEFAULT_COLOR)
- ->setIsMembershipLocked(0)
->save();
$proj_a->setViewPolicy($proj_b->getPHID())->save();
$proj_b->setViewPolicy($proj_a->getPHID())->save();
$user = new PhabricatorUser();
$results = id(new PhabricatorProjectQuery())
->setViewer($user)
->execute();
$this->assertEqual(0, count($results));
}
public function testCustomPolicyRuleUser() {
$user_a = $this->generateNewTestUser();
$user_b = $this->generateNewTestUser();
$author = $this->generateNewTestUser();
$policy = id(new PhabricatorPolicy())
->setRules(
array(
array(
'action' => PhabricatorPolicy::ACTION_ALLOW,
'rule' => 'PhabricatorUsersPolicyRule',
'value' => array($user_a->getPHID()),
),
))
->save();
$task = ManiphestTask::initializeNewTask($author);
$task->setViewPolicy($policy->getPHID());
$task->save();
$can_a_view = PhabricatorPolicyFilter::hasCapability(
$user_a,
$task,
PhabricatorPolicyCapability::CAN_VIEW);
$this->assertTrue($can_a_view);
$can_b_view = PhabricatorPolicyFilter::hasCapability(
$user_b,
$task,
PhabricatorPolicyCapability::CAN_VIEW);
$this->assertFalse($can_b_view);
}
public function testCustomPolicyRuleAdministrators() {
$user_a = $this->generateNewTestUser();
$user_a->setIsAdmin(true)->save();
$user_b = $this->generateNewTestUser();
$author = $this->generateNewTestUser();
$policy = id(new PhabricatorPolicy())
->setRules(
array(
array(
'action' => PhabricatorPolicy::ACTION_ALLOW,
'rule' => 'PhabricatorAdministratorsPolicyRule',
'value' => null,
),
))
->save();
$task = ManiphestTask::initializeNewTask($author);
$task->setViewPolicy($policy->getPHID());
$task->save();
$can_a_view = PhabricatorPolicyFilter::hasCapability(
$user_a,
$task,
PhabricatorPolicyCapability::CAN_VIEW);
$this->assertTrue($can_a_view);
$can_b_view = PhabricatorPolicyFilter::hasCapability(
$user_b,
$task,
PhabricatorPolicyCapability::CAN_VIEW);
$this->assertFalse($can_b_view);
}
public function testCustomPolicyRuleLunarPhase() {
$user_a = $this->generateNewTestUser();
$author = $this->generateNewTestUser();
$policy = id(new PhabricatorPolicy())
->setRules(
array(
array(
'action' => PhabricatorPolicy::ACTION_ALLOW,
'rule' => 'PhabricatorLunarPhasePolicyRule',
'value' => 'new',
),
))
->save();
$task = ManiphestTask::initializeNewTask($author);
$task->setViewPolicy($policy->getPHID());
$task->save();
$time_a = PhabricatorTime::pushTime(934354800, 'UTC');
$can_a_view = PhabricatorPolicyFilter::hasCapability(
$user_a,
$task,
PhabricatorPolicyCapability::CAN_VIEW);
$this->assertTrue($can_a_view);
unset($time_a);
$time_b = PhabricatorTime::pushTime(1116745200, 'UTC');
$can_a_view = PhabricatorPolicyFilter::hasCapability(
$user_a,
$task,
PhabricatorPolicyCapability::CAN_VIEW);
$this->assertFalse($can_a_view);
unset($time_b);
}
public function testObjectPolicyRuleTaskAuthor() {
$author = $this->generateNewTestUser();
$viewer = $this->generateNewTestUser();
$rule = new ManiphestTaskAuthorPolicyRule();
$task = ManiphestTask::initializeNewTask($author);
$task->setViewPolicy($rule->getObjectPolicyFullKey());
$task->save();
$this->assertTrue(
PhabricatorPolicyFilter::hasCapability(
$author,
$task,
PhabricatorPolicyCapability::CAN_VIEW));
$this->assertFalse(
PhabricatorPolicyFilter::hasCapability(
$viewer,
$task,
PhabricatorPolicyCapability::CAN_VIEW));
}
public function testObjectPolicyRuleThreadMembers() {
$author = $this->generateNewTestUser();
$viewer = $this->generateNewTestUser();
$rule = new ConpherenceThreadMembersPolicyRule();
$thread = ConpherenceThread::initializeNewRoom($author);
$thread->setViewPolicy($rule->getObjectPolicyFullKey());
$thread->save();
$this->assertFalse(
PhabricatorPolicyFilter::hasCapability(
$author,
$thread,
PhabricatorPolicyCapability::CAN_VIEW));
$this->assertFalse(
PhabricatorPolicyFilter::hasCapability(
$viewer,
$thread,
PhabricatorPolicyCapability::CAN_VIEW));
$participant = id(new ConpherenceParticipant())
->setParticipantPHID($viewer->getPHID())
->setConpherencePHID($thread->getPHID());
$thread->attachParticipants(array($viewer->getPHID() => $participant));
$this->assertTrue(
PhabricatorPolicyFilter::hasCapability(
$viewer,
$thread,
PhabricatorPolicyCapability::CAN_VIEW));
}
public function testObjectPolicyRuleSubscribers() {
$author = $this->generateNewTestUser();
$rule = new PhabricatorSubscriptionsSubscribersPolicyRule();
$task = ManiphestTask::initializeNewTask($author);
$task->setViewPolicy($rule->getObjectPolicyFullKey());
$task->save();
$this->assertFalse(
PhabricatorPolicyFilter::hasCapability(
$author,
$task,
PhabricatorPolicyCapability::CAN_VIEW));
id(new PhabricatorSubscriptionsEditor())
->setActor($author)
->setObject($task)
->subscribeExplicit(array($author->getPHID()))
->save();
$this->assertTrue(
PhabricatorPolicyFilter::hasCapability(
$author,
$task,
PhabricatorPolicyCapability::CAN_VIEW));
}
}
diff --git a/src/applications/project/storage/PhabricatorProject.php b/src/applications/project/storage/PhabricatorProject.php
index 8bbc6e14ad..8e4f3fbfc9 100644
--- a/src/applications/project/storage/PhabricatorProject.php
+++ b/src/applications/project/storage/PhabricatorProject.php
@@ -1,401 +1,411 @@
<?php
final class PhabricatorProject extends PhabricatorProjectDAO
implements
PhabricatorApplicationTransactionInterface,
PhabricatorFlaggableInterface,
PhabricatorPolicyInterface,
PhabricatorSubscribableInterface,
PhabricatorCustomFieldInterface,
PhabricatorDestructibleInterface {
protected $name;
protected $status = PhabricatorProjectStatus::STATUS_ACTIVE;
protected $authorPHID;
- protected $subprojectPHIDs = array();
- protected $phrictionSlug;
+ protected $primarySlug;
protected $profileImagePHID;
protected $icon;
protected $color;
protected $mailKey;
protected $viewPolicy;
protected $editPolicy;
protected $joinPolicy;
protected $isMembershipLocked;
+ protected $parentProjectPHID;
+ protected $hasWorkboard;
+ protected $hasMilestones;
+ protected $hasSubprojects;
+ protected $milestoneNumber;
+
private $memberPHIDs = self::ATTACHABLE;
private $watcherPHIDs = self::ATTACHABLE;
private $sparseWatchers = self::ATTACHABLE;
private $sparseMembers = self::ATTACHABLE;
private $customFields = self::ATTACHABLE;
private $profileImageFile = self::ATTACHABLE;
private $slugs = self::ATTACHABLE;
+ private $parentProject = self::ATTACHABLE;
const DEFAULT_ICON = 'fa-briefcase';
const DEFAULT_COLOR = 'blue';
const TABLE_DATASOURCE_TOKEN = 'project_datasourcetoken';
public static function initializeNewProject(PhabricatorUser $actor) {
$app = id(new PhabricatorApplicationQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withClasses(array('PhabricatorProjectApplication'))
->executeOne();
$view_policy = $app->getPolicy(
ProjectDefaultViewCapability::CAPABILITY);
$edit_policy = $app->getPolicy(
ProjectDefaultEditCapability::CAPABILITY);
$join_policy = $app->getPolicy(
ProjectDefaultJoinCapability::CAPABILITY);
return id(new PhabricatorProject())
->setAuthorPHID($actor->getPHID())
->setIcon(self::DEFAULT_ICON)
->setColor(self::DEFAULT_COLOR)
->setViewPolicy($view_policy)
->setEditPolicy($edit_policy)
->setJoinPolicy($join_policy)
->setIsMembershipLocked(0)
->attachMemberPHIDs(array())
- ->attachSlugs(array());
+ ->attachSlugs(array())
+ ->setHasWorkboard(0)
+ ->setHasMilestones(0)
+ ->setHasSubprojects(0);
}
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
PhabricatorPolicyCapability::CAN_JOIN,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->getViewPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->getEditPolicy();
case PhabricatorPolicyCapability::CAN_JOIN:
return $this->getJoinPolicy();
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
if ($this->isUserMember($viewer->getPHID())) {
// Project members can always view a project.
return true;
}
break;
case PhabricatorPolicyCapability::CAN_EDIT:
break;
case PhabricatorPolicyCapability::CAN_JOIN:
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
if (PhabricatorPolicyFilter::hasCapability($viewer, $this, $can_edit)) {
// Project editors can always join a project.
return true;
}
break;
}
return false;
}
public function describeAutomaticCapability($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return pht('Members of a project can always view it.');
case PhabricatorPolicyCapability::CAN_JOIN:
return pht('Users who can edit a project can always join it.');
}
return null;
}
public function isUserMember($user_phid) {
if ($this->memberPHIDs !== self::ATTACHABLE) {
return in_array($user_phid, $this->memberPHIDs);
}
return $this->assertAttachedKey($this->sparseMembers, $user_phid);
}
public function setIsUserMember($user_phid, $is_member) {
if ($this->sparseMembers === self::ATTACHABLE) {
$this->sparseMembers = array();
}
$this->sparseMembers[$user_phid] = $is_member;
return $this;
}
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
- self::CONFIG_SERIALIZATION => array(
- 'subprojectPHIDs' => self::SERIALIZATION_JSON,
- ),
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'sort128',
'status' => 'text32',
- 'phrictionSlug' => 'text128?',
+ 'primarySlug' => 'text128?',
'isMembershipLocked' => 'bool',
'profileImagePHID' => 'phid?',
'icon' => 'text32',
'color' => 'text32',
'mailKey' => 'bytes20',
-
- // T6203/NULLABILITY
- // These are definitely wrong and should always exist.
- 'editPolicy' => 'policy?',
- 'viewPolicy' => 'policy?',
- 'joinPolicy' => 'policy?',
+ 'joinPolicy' => 'policy',
+ 'parentProjectPHID' => 'phid?',
+ 'hasWorkboard' => 'bool',
+ 'hasMilestones' => 'bool',
+ 'hasSubprojects' => 'bool',
+ 'milestoneNumber' => 'uint32?',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
'phid' => array(
'columns' => array('phid'),
'unique' => true,
),
'key_icon' => array(
'columns' => array('icon'),
),
'key_color' => array(
'columns' => array('color'),
),
- 'phrictionSlug' => array(
- 'columns' => array('phrictionSlug'),
- 'unique' => true,
- ),
'name' => array(
'columns' => array('name'),
'unique' => true,
),
+ 'key_milestone' => array(
+ 'columns' => array('parentProjectPHID', 'milestoneNumber'),
+ 'unique' => true,
+ ),
+ 'key_primaryslug' => array(
+ 'columns' => array('primarySlug'),
+ 'unique' => true,
+ ),
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorProjectProjectPHIDType::TYPECONST);
}
public function attachMemberPHIDs(array $phids) {
$this->memberPHIDs = $phids;
return $this;
}
public function getMemberPHIDs() {
return $this->assertAttached($this->memberPHIDs);
}
- public function setPrimarySlug($slug) {
- $this->phrictionSlug = $slug.'/';
- return $this;
- }
-
- // TODO - once we sever project => phriction automagicalness,
- // migrate getPhrictionSlug to have no trailing slash and be called
- // getPrimarySlug
- public function getPrimarySlug() {
- $slug = $this->getPhrictionSlug();
- return rtrim($slug, '/');
- }
-
public function isArchived() {
return ($this->getStatus() == PhabricatorProjectStatus::STATUS_ARCHIVED);
}
public function getProfileImageURI() {
return $this->getProfileImageFile()->getBestURI();
}
public function attachProfileImageFile(PhabricatorFile $file) {
$this->profileImageFile = $file;
return $this;
}
public function getProfileImageFile() {
return $this->assertAttached($this->profileImageFile);
}
public function isUserWatcher($user_phid) {
if ($this->watcherPHIDs !== self::ATTACHABLE) {
return in_array($user_phid, $this->watcherPHIDs);
}
return $this->assertAttachedKey($this->sparseWatchers, $user_phid);
}
public function setIsUserWatcher($user_phid, $is_watcher) {
if ($this->sparseWatchers === self::ATTACHABLE) {
$this->sparseWatchers = array();
}
$this->sparseWatchers[$user_phid] = $is_watcher;
return $this;
}
public function attachWatcherPHIDs(array $phids) {
$this->watcherPHIDs = $phids;
return $this;
}
public function getWatcherPHIDs() {
return $this->assertAttached($this->watcherPHIDs);
}
public function attachSlugs(array $slugs) {
$this->slugs = $slugs;
return $this;
}
public function getSlugs() {
return $this->assertAttached($this->slugs);
}
public function getColor() {
if ($this->isArchived()) {
return PHUITagView::COLOR_DISABLED;
}
return $this->color;
}
public function save() {
if (!$this->getMailKey()) {
$this->setMailKey(Filesystem::readRandomCharacters(20));
}
$this->openTransaction();
$result = parent::save();
$this->updateDatasourceTokens();
$this->saveTransaction();
return $result;
}
public function updateDatasourceTokens() {
$table = self::TABLE_DATASOURCE_TOKEN;
$conn_w = $this->establishConnection('w');
$id = $this->getID();
$slugs = queryfx_all(
$conn_w,
'SELECT * FROM %T WHERE projectPHID = %s',
id(new PhabricatorProjectSlug())->getTableName(),
$this->getPHID());
$all_strings = ipull($slugs, 'slug');
$all_strings[] = $this->getName();
$all_strings = implode(' ', $all_strings);
$tokens = PhabricatorTypeaheadDatasource::tokenizeString($all_strings);
$sql = array();
foreach ($tokens as $token) {
$sql[] = qsprintf($conn_w, '(%d, %s)', $id, $token);
}
$this->openTransaction();
queryfx(
$conn_w,
'DELETE FROM %T WHERE projectID = %d',
$table,
$id);
foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
queryfx(
$conn_w,
'INSERT INTO %T (projectID, token) VALUES %Q',
$table,
$chunk);
}
$this->saveTransaction();
}
+ public function isMilestone() {
+ return ($this->getMilestoneNumber() !== null);
+ }
+
+ public function getParentProject() {
+ return $this->assertAttached($this->parentProject);
+ }
+
+ public function attachParentProject(PhabricatorProject $project) {
+ $this->parentProject = $project;
+ return $this;
+ }
+
/* -( PhabricatorSubscribableInterface )----------------------------------- */
public function isAutomaticallySubscribed($phid) {
return false;
}
public function shouldShowSubscribersProperty() {
return false;
}
public function shouldAllowSubscription($phid) {
return $this->isUserMember($phid) &&
!$this->isUserWatcher($phid);
}
/* -( PhabricatorCustomFieldInterface )------------------------------------ */
public function getCustomFieldSpecificationForRole($role) {
return PhabricatorEnv::getEnvConfig('projects.fields');
}
public function getCustomFieldBaseClass() {
return 'PhabricatorProjectCustomField';
}
public function getCustomFields() {
return $this->assertAttached($this->customFields);
}
public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
$this->customFields = $fields;
return $this;
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
public function getApplicationTransactionEditor() {
return new PhabricatorProjectTransactionEditor();
}
public function getApplicationTransactionObject() {
return $this;
}
public function getApplicationTransactionTemplate() {
return new PhabricatorProjectTransaction();
}
public function willRenderTimeline(
PhabricatorApplicationTransactionView $timeline,
AphrontRequest $request) {
return $timeline;
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$columns = id(new PhabricatorProjectColumn())
->loadAllWhere('projectPHID = %s', $this->getPHID());
foreach ($columns as $column) {
$engine->destroyObject($column);
}
$slugs = id(new PhabricatorProjectSlug())
->loadAllWhere('projectPHID = %s', $this->getPHID());
foreach ($slugs as $slug) {
$slug->delete();
}
$this->saveTransaction();
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 15, 8:17 PM (4 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
338411
Default Alt Text
(24 KB)

Event Timeline