mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 21:02:41 +01:00
Add transaction-oriented editing to projects
Summary: - Make some editing operations transaction-oriented, like Maniphest. (This seems to be a good model, particularly for extensibility.) I'll move the rest of the editing operations to transactions in future diffs. - Make transaction-oriented operations publish feed stories. Test Plan: - Created a new project. - Edited an existing project. - Created a new project via quick create flow from Maniphest. - Verified feed stories publish correctly. Reviewers: btrahan, jungejason Reviewed By: btrahan CC: aran, epriestley Maniphest Tasks: T681 Differential Revision: https://secure.phabricator.com/D1477
This commit is contained in:
parent
3c8bb8a608
commit
b43eb5aa7c
18 changed files with 383 additions and 26 deletions
11
resources/sql/patches/100.projectxaction.sql
Normal file
11
resources/sql/patches/100.projectxaction.sql
Normal file
|
@ -0,0 +1,11 @@
|
|||
CREATE TABLE phabricator_project.project_transaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
projectID INT UNSIGNED NOT NULL,
|
||||
authorPHID VARCHAR(64) BINARY NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL,
|
||||
oldValue LONGBLOB NOT NULL,
|
||||
newValue LONGBLOB NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
KEY (projectID)
|
||||
) ENGINE=InnoDB;
|
|
@ -485,6 +485,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFeedStoryDifferential' => 'applications/feed/story/differential',
|
||||
'PhabricatorFeedStoryManiphest' => 'applications/feed/story/maniphest',
|
||||
'PhabricatorFeedStoryPhriction' => 'applications/feed/story/phriction',
|
||||
'PhabricatorFeedStoryProject' => 'applications/feed/story/project',
|
||||
'PhabricatorFeedStoryPublisher' => 'applications/feed/publisher',
|
||||
'PhabricatorFeedStoryReference' => 'applications/feed/storage/storyreference',
|
||||
'PhabricatorFeedStoryStatus' => 'applications/feed/story/status',
|
||||
|
@ -611,6 +612,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProject' => 'applications/project/storage/project',
|
||||
'PhabricatorProjectAffiliation' => 'applications/project/storage/affiliation',
|
||||
'PhabricatorProjectAffiliationEditController' => 'applications/project/controller/editaffiliation',
|
||||
'PhabricatorProjectConstants' => 'applications/project/constants/base',
|
||||
'PhabricatorProjectController' => 'applications/project/controller/base',
|
||||
'PhabricatorProjectCreateController' => 'applications/project/controller/create',
|
||||
'PhabricatorProjectDAO' => 'applications/project/storage/base',
|
||||
|
@ -623,6 +625,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectQuery' => 'applications/project/query/project',
|
||||
'PhabricatorProjectStatus' => 'applications/project/constants/status',
|
||||
'PhabricatorProjectSubproject' => 'applications/project/storage/subproject',
|
||||
'PhabricatorProjectTransaction' => 'applications/project/storage/transaction',
|
||||
'PhabricatorProjectTransactionType' => 'applications/project/constants/transaction',
|
||||
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
|
||||
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/refresh',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
|
||||
|
@ -1192,6 +1196,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorFeedStoryDifferential' => 'PhabricatorFeedStory',
|
||||
'PhabricatorFeedStoryManiphest' => 'PhabricatorFeedStory',
|
||||
'PhabricatorFeedStoryPhriction' => 'PhabricatorFeedStory',
|
||||
'PhabricatorFeedStoryProject' => 'PhabricatorFeedStory',
|
||||
'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
|
||||
'PhabricatorFeedStoryStatus' => 'PhabricatorFeedStory',
|
||||
'PhabricatorFeedStoryTypeConstants' => 'PhabricatorFeedConstants',
|
||||
|
@ -1304,6 +1309,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectSubproject' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectTransaction' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectTransactionType' => 'PhabricatorProjectConstants',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -24,5 +24,6 @@ final class PhabricatorFeedStoryTypeConstants
|
|||
const STORY_DIFFERENTIAL = 'PhabricatorFeedStoryDifferential';
|
||||
const STORY_PHRICTION = 'PhabricatorFeedStoryPhriction';
|
||||
const STORY_MANIPHEST = 'PhabricatorFeedStoryManiphest';
|
||||
const STORY_PROJECT = 'PhabricatorFeedStoryProject';
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class PhabricatorFeedStoryProject extends PhabricatorFeedStory {
|
||||
|
||||
public function getRequiredHandlePHIDs() {
|
||||
return array(
|
||||
$this->getStoryData()->getAuthorPHID(),
|
||||
$this->getStoryData()->getValue('projectPHID'),
|
||||
);
|
||||
}
|
||||
|
||||
public function getRequiredObjectPHIDs() {
|
||||
return array(
|
||||
$this->getStoryData()->getAuthorPHID(),
|
||||
);
|
||||
}
|
||||
|
||||
public function renderView() {
|
||||
$data = $this->getStoryData();
|
||||
|
||||
$view = new PhabricatorFeedStoryView();
|
||||
|
||||
$type = $data->getValue('type');
|
||||
$old = $data->getValue('old');
|
||||
$new = $data->getValue('new');
|
||||
$proj = $this->getHandle($data->getValue('projectPHID'));
|
||||
$auth = $this->getHandle($data->getAuthorPHID());
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorProjectTransactionType::TYPE_NAME:
|
||||
if (strlen($old)) {
|
||||
$action = 'renamed project '.
|
||||
'<strong>'.$proj->renderLink().'</strong>'.
|
||||
' from '.
|
||||
'<strong>'.phutil_escape_html($old).'</strong>'.
|
||||
' to '.
|
||||
'<strong>'.phutil_escape_html($new).'</strong>.';
|
||||
} else {
|
||||
$action = 'created project '.
|
||||
'<strong>'.$proj->renderLink().'</strong>'.
|
||||
' (as '.
|
||||
'<strong>'.phutil_escape_html($new).'</strong>).';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$action = 'updated project <strong>'.$proj->renderLink().'</strong>';
|
||||
break;
|
||||
}
|
||||
$view->setTitle('<strong>'.$auth->renderLink().'</strong> '.$action);
|
||||
$view->setOneLineStory(true);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
16
src/applications/feed/story/project/__init__.php
Normal file
16
src/applications/feed/story/project/__init__.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/feed/story/base');
|
||||
phutil_require_module('phabricator', 'applications/feed/view/story');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/transaction');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorFeedStoryProject.php');
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
abstract class PhabricatorProjectConstants {
|
||||
|
||||
}
|
10
src/applications/project/constants/base/__init__.php
Normal file
10
src/applications/project/constants/base/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectConstants.php');
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
final class PhabricatorProjectTransactionType
|
||||
extends PhabricatorProjectConstants {
|
||||
|
||||
const TYPE_NAME = 'name';
|
||||
const TYPE_MEMBERS = 'members';
|
||||
|
||||
}
|
12
src/applications/project/constants/transaction/__init__.php
Normal file
12
src/applications/project/constants/transaction/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/project/constants/base');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectTransactionType.php');
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -34,10 +34,16 @@ class PhabricatorProjectCreateController
|
|||
if ($request->isFormPost()) {
|
||||
|
||||
try {
|
||||
$xactions = array();
|
||||
$xaction = new PhabricatorProjectTransaction();
|
||||
$xaction->setTransactionType(
|
||||
PhabricatorProjectTransactionType::TYPE_NAME);
|
||||
$xaction->setNewValue($request->getStr('name'));
|
||||
$xactions[] = $xaction;
|
||||
|
||||
$editor = new PhabricatorProjectEditor($project);
|
||||
$editor->setUser($user);
|
||||
$editor->setName($request->getStr('name'));
|
||||
$editor->save();
|
||||
$editor->applyTransactions($xactions);
|
||||
} catch (PhabricatorProjectNameCollisionException $ex) {
|
||||
$e_name = 'Not Unique';
|
||||
$errors[] = $ex->getMessage();
|
||||
|
|
|
@ -10,11 +10,13 @@ phutil_require_module('phabricator', 'aphront/response/ajax');
|
|||
phutil_require_module('phabricator', 'aphront/response/dialog');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/transaction');
|
||||
phutil_require_module('phabricator', 'applications/project/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/project/editor/project');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/profile');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/transaction');
|
||||
phutil_require_module('phabricator', 'view/dialog');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
|
|
|
@ -58,10 +58,16 @@ class PhabricatorProjectProfileEditController
|
|||
if ($request->isFormPost()) {
|
||||
|
||||
try {
|
||||
$xactions = array();
|
||||
$xaction = new PhabricatorProjectTransaction();
|
||||
$xaction->setTransactionType(
|
||||
PhabricatorProjectTransactionType::TYPE_NAME);
|
||||
$xaction->setNewValue($request->getStr('name'));
|
||||
$xactions[] = $xaction;
|
||||
|
||||
$editor = new PhabricatorProjectEditor($project);
|
||||
$editor->setUser($user);
|
||||
$editor->setName($request->getStr('name'));
|
||||
$editor->save();
|
||||
$editor->applyTransactions($xactions);
|
||||
} catch (PhabricatorProjectNameCollisionException $ex) {
|
||||
$e_name = 'Not Unique';
|
||||
$errors[] = $ex->getMessage();
|
||||
|
|
|
@ -12,11 +12,13 @@ phutil_require_module('phabricator', 'applications/files/storage/file');
|
|||
phutil_require_module('phabricator', 'applications/files/transform');
|
||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/transaction');
|
||||
phutil_require_module('phabricator', 'applications/project/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/project/editor/project');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/profile');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/transaction');
|
||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,45 +20,64 @@ final class PhabricatorProjectEditor {
|
|||
|
||||
private $project;
|
||||
private $user;
|
||||
|
||||
private $projectName;
|
||||
|
||||
private $addAffiliations;
|
||||
private $remAffiliations;
|
||||
|
||||
public function __construct(PhabricatorProject $project) {
|
||||
$this->project = $project;
|
||||
}
|
||||
|
||||
public function setName($name) {
|
||||
$this->projectName = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function save() {
|
||||
public function applyTransactions(array $transactions) {
|
||||
if (!$this->user) {
|
||||
throw new Exception('Call setUser() before save()!');
|
||||
}
|
||||
$user = $this->user;
|
||||
|
||||
$project = $this->project;
|
||||
|
||||
$is_new = !$project->getID();
|
||||
|
||||
if ($is_new) {
|
||||
$project->setAuthorPHID($this->user->getPHID());
|
||||
$project->setAuthorPHID($user->getPHID());
|
||||
}
|
||||
|
||||
if (($this->projectName !== null) &&
|
||||
($this->projectName !== $project->getName())) {
|
||||
$project->setName($this->projectName);
|
||||
$project->setPhrictionSlug($this->projectName);
|
||||
$this->validateName($project);
|
||||
foreach ($transactions as $xaction) {
|
||||
$type = $xaction->getTransactionType();
|
||||
|
||||
$this->setTransactionOldValue($project, $xaction);
|
||||
$this->applyTransactionEffect($project, $xaction);
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
$project->save();
|
||||
|
||||
foreach ($transactions as $xaction) {
|
||||
$xaction->setAuthorPHID($user->getPHID());
|
||||
$xaction->setProjectID($project->getID());
|
||||
$xaction->save();
|
||||
}
|
||||
|
||||
foreach ($this->remAffiliations as $affil) {
|
||||
$affil->delete();
|
||||
}
|
||||
|
||||
foreach ($this->addAffiliations as $affil) {
|
||||
$affil->setProjectPHID($project->getPHID());
|
||||
$affil->save();
|
||||
}
|
||||
|
||||
foreach ($transactions as $xaction) {
|
||||
$this->publishTransactionStory($project, $xaction);
|
||||
}
|
||||
|
||||
} catch (AphrontQueryDuplicateKeyException $ex) {
|
||||
// We already validated the slug, but might race. Try again to see if
|
||||
// that's the issue. If it is, we'll throw a more specific exception. If
|
||||
|
@ -100,4 +119,97 @@ final class PhabricatorProjectEditor {
|
|||
}
|
||||
}
|
||||
|
||||
private function setTransactionOldValue(
|
||||
PhabricatorProject $project,
|
||||
PhabricatorProjectTransaction $xaction) {
|
||||
|
||||
$type = $xaction->getTransactionType();
|
||||
switch ($type) {
|
||||
case PhabricatorProjectTransactionType::TYPE_NAME:
|
||||
$xaction->setOldValue($project->getName());
|
||||
break;
|
||||
case PhabricatorProjectTransactionType::TYPE_MEMBERS:
|
||||
$affils = $project->loadAffiliations();
|
||||
$project->attachAffiliations($affils);
|
||||
|
||||
$old_value = mpull($affils, 'getUserPHID');
|
||||
$old_value = array_values($old_value);
|
||||
$xaction->setOldValue($affils);
|
||||
|
||||
$new_value = $xaction->getNewValue();
|
||||
$new_value = array_filter($new_value);
|
||||
$new_value = array_unique($new_value);
|
||||
$new_value = array_values($new_value);
|
||||
$xaction->setNewValue($new_value);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown transaction type '{$type}'!");
|
||||
}
|
||||
}
|
||||
|
||||
private function applyTransactionEffect(
|
||||
PhabricatorProject $project,
|
||||
PhabricatorProjectTransaction $xaction) {
|
||||
|
||||
$type = $xaction->getTransactionType();
|
||||
switch ($type) {
|
||||
case PhabricatorProjectTransactionType::TYPE_NAME:
|
||||
$project->setName($xaction->getNewValue());
|
||||
$project->setPhrictionSlug($xaction->getNewValue());
|
||||
$this->validateName($project);
|
||||
break;
|
||||
case PhabricatorProjectTransactionType::TYPE_MEMBERS:
|
||||
$old = array_fill_keys($xaction->getOldValue(), true);
|
||||
$new = array_fill_keys($xaction->getNewValue(), true);
|
||||
|
||||
$add = array();
|
||||
$rem = array();
|
||||
|
||||
foreach ($project->getAffiliations() as $affil) {
|
||||
if (empty($new[$affil->getUserPHID()])) {
|
||||
$rem[] = $affil;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($new as $phid => $ignored) {
|
||||
if (empty($old[$phid])) {
|
||||
$affil = new PhabricatorProjectAffiliation();
|
||||
$affil->setUserPHID($phid);
|
||||
$add[] = $affil;
|
||||
}
|
||||
}
|
||||
|
||||
$this->addAffiliations = $add;
|
||||
$this->remAffiliations = $rem;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown transaction type '{$type}'!");
|
||||
}
|
||||
}
|
||||
|
||||
private function publishTransactionStory(
|
||||
PhabricatorProject $project,
|
||||
PhabricatorProjectTransaction $xaction) {
|
||||
|
||||
$related_phids = array(
|
||||
$project->getPHID(),
|
||||
$xaction->getAuthorPHID(),
|
||||
);
|
||||
|
||||
id(new PhabricatorFeedStoryPublisher())
|
||||
->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_PROJECT)
|
||||
->setStoryData(
|
||||
array(
|
||||
'projectPHID' => $project->getPHID(),
|
||||
'transactionID' => $xaction->getID(),
|
||||
'type' => $xaction->getTransactionType(),
|
||||
'old' => $xaction->getOldValue(),
|
||||
'new' => $xaction->getNewValue(),
|
||||
))
|
||||
->setStoryTime(time())
|
||||
->setStoryAuthorPHID($xaction->getAuthorPHID())
|
||||
->setRelatedPHIDs($related_phids)
|
||||
->publish();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/feed/constants/story');
|
||||
phutil_require_module('phabricator', 'applications/feed/publisher');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/transaction');
|
||||
phutil_require_module('phabricator', 'applications/project/exception/namecollison');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group project
|
||||
*/
|
||||
class PhabricatorProjectTransaction extends PhabricatorProjectDAO {
|
||||
|
||||
protected $projectID;
|
||||
protected $authorPHID;
|
||||
protected $transactionType;
|
||||
protected $oldValue;
|
||||
protected $newValue;
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_SERIALIZATION => array(
|
||||
'oldValue' => self::SERIALIZATION_JSON,
|
||||
'newValue' => self::SERIALIZATION_JSON,
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
}
|
12
src/applications/project/storage/transaction/__init__.php
Normal file
12
src/applications/project/storage/transaction/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/project/storage/base');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectTransaction.php');
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
Loading…
Reference in a new issue