mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-15 18:10:53 +01:00
(stable) Promote 2017 Week 19
This commit is contained in:
commit
6c211317fc
83 changed files with 1272 additions and 1205 deletions
|
@ -1138,9 +1138,9 @@ phutil_register_library_map(array(
|
|||
'FundInitiativeBackController' => 'applications/fund/controller/FundInitiativeBackController.php',
|
||||
'FundInitiativeBackerTransaction' => 'applications/fund/xaction/FundInitiativeBackerTransaction.php',
|
||||
'FundInitiativeCloseController' => 'applications/fund/controller/FundInitiativeCloseController.php',
|
||||
'FundInitiativeCommentController' => 'applications/fund/controller/FundInitiativeCommentController.php',
|
||||
'FundInitiativeDescriptionTransaction' => 'applications/fund/xaction/FundInitiativeDescriptionTransaction.php',
|
||||
'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php',
|
||||
'FundInitiativeEditEngine' => 'applications/fund/editor/FundInitiativeEditEngine.php',
|
||||
'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php',
|
||||
'FundInitiativeFulltextEngine' => 'applications/fund/search/FundInitiativeFulltextEngine.php',
|
||||
'FundInitiativeListController' => 'applications/fund/controller/FundInitiativeListController.php',
|
||||
|
@ -1404,10 +1404,10 @@ phutil_register_library_map(array(
|
|||
'LegalpadDefaultViewCapability' => 'applications/legalpad/capability/LegalpadDefaultViewCapability.php',
|
||||
'LegalpadDocument' => 'applications/legalpad/storage/LegalpadDocument.php',
|
||||
'LegalpadDocumentBody' => 'applications/legalpad/storage/LegalpadDocumentBody.php',
|
||||
'LegalpadDocumentCommentController' => 'applications/legalpad/controller/LegalpadDocumentCommentController.php',
|
||||
'LegalpadDocumentDatasource' => 'applications/legalpad/typeahead/LegalpadDocumentDatasource.php',
|
||||
'LegalpadDocumentDoneController' => 'applications/legalpad/controller/LegalpadDocumentDoneController.php',
|
||||
'LegalpadDocumentEditController' => 'applications/legalpad/controller/LegalpadDocumentEditController.php',
|
||||
'LegalpadDocumentEditEngine' => 'applications/legalpad/editor/LegalpadDocumentEditEngine.php',
|
||||
'LegalpadDocumentEditor' => 'applications/legalpad/editor/LegalpadDocumentEditor.php',
|
||||
'LegalpadDocumentListController' => 'applications/legalpad/controller/LegalpadDocumentListController.php',
|
||||
'LegalpadDocumentManageController' => 'applications/legalpad/controller/LegalpadDocumentManageController.php',
|
||||
|
@ -1451,6 +1451,7 @@ phutil_register_library_map(array(
|
|||
'LiskRawMigrationIterator' => 'infrastructure/storage/lisk/LiskRawMigrationIterator.php',
|
||||
'MacroConduitAPIMethod' => 'applications/macro/conduit/MacroConduitAPIMethod.php',
|
||||
'MacroCreateMemeConduitAPIMethod' => 'applications/macro/conduit/MacroCreateMemeConduitAPIMethod.php',
|
||||
'MacroEditConduitAPIMethod' => 'applications/macro/conduit/MacroEditConduitAPIMethod.php',
|
||||
'MacroEmojiExample' => 'applications/uiexample/examples/MacroEmojiExample.php',
|
||||
'MacroQueryConduitAPIMethod' => 'applications/macro/conduit/MacroQueryConduitAPIMethod.php',
|
||||
'ManiphestAssignEmailCommand' => 'applications/maniphest/command/ManiphestAssignEmailCommand.php',
|
||||
|
@ -3633,6 +3634,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectOrUserDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserDatasource.php',
|
||||
'PhabricatorProjectOrUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserFunctionDatasource.php',
|
||||
'PhabricatorProjectPHIDResolver' => 'applications/phid/resolver/PhabricatorProjectPHIDResolver.php',
|
||||
'PhabricatorProjectPictureProfileMenuItem' => 'applications/project/menuitem/PhabricatorProjectPictureProfileMenuItem.php',
|
||||
'PhabricatorProjectPointsProfileMenuItem' => 'applications/project/menuitem/PhabricatorProjectPointsProfileMenuItem.php',
|
||||
'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
|
||||
'PhabricatorProjectProfileMenuEngine' => 'applications/project/engine/PhabricatorProjectProfileMenuEngine.php',
|
||||
|
@ -3912,12 +3914,12 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSlowvoteApplication' => 'applications/slowvote/application/PhabricatorSlowvoteApplication.php',
|
||||
'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php',
|
||||
'PhabricatorSlowvoteCloseController' => 'applications/slowvote/controller/PhabricatorSlowvoteCloseController.php',
|
||||
'PhabricatorSlowvoteCloseTransaction' => 'applications/slowvote/xactions/PhabricatorSlowvoteCloseTransaction.php',
|
||||
'PhabricatorSlowvoteCloseTransaction' => 'applications/slowvote/xaction/PhabricatorSlowvoteCloseTransaction.php',
|
||||
'PhabricatorSlowvoteCommentController' => 'applications/slowvote/controller/PhabricatorSlowvoteCommentController.php',
|
||||
'PhabricatorSlowvoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteController.php',
|
||||
'PhabricatorSlowvoteDAO' => 'applications/slowvote/storage/PhabricatorSlowvoteDAO.php',
|
||||
'PhabricatorSlowvoteDefaultViewCapability' => 'applications/slowvote/capability/PhabricatorSlowvoteDefaultViewCapability.php',
|
||||
'PhabricatorSlowvoteDescriptionTransaction' => 'applications/slowvote/xactions/PhabricatorSlowvoteDescriptionTransaction.php',
|
||||
'PhabricatorSlowvoteDescriptionTransaction' => 'applications/slowvote/xaction/PhabricatorSlowvoteDescriptionTransaction.php',
|
||||
'PhabricatorSlowvoteEditController' => 'applications/slowvote/controller/PhabricatorSlowvoteEditController.php',
|
||||
'PhabricatorSlowvoteEditor' => 'applications/slowvote/editor/PhabricatorSlowvoteEditor.php',
|
||||
'PhabricatorSlowvoteListController' => 'applications/slowvote/controller/PhabricatorSlowvoteListController.php',
|
||||
|
@ -3927,16 +3929,16 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSlowvotePollController' => 'applications/slowvote/controller/PhabricatorSlowvotePollController.php',
|
||||
'PhabricatorSlowvotePollPHIDType' => 'applications/slowvote/phid/PhabricatorSlowvotePollPHIDType.php',
|
||||
'PhabricatorSlowvoteQuery' => 'applications/slowvote/query/PhabricatorSlowvoteQuery.php',
|
||||
'PhabricatorSlowvoteQuestionTransaction' => 'applications/slowvote/xactions/PhabricatorSlowvoteQuestionTransaction.php',
|
||||
'PhabricatorSlowvoteQuestionTransaction' => 'applications/slowvote/xaction/PhabricatorSlowvoteQuestionTransaction.php',
|
||||
'PhabricatorSlowvoteReplyHandler' => 'applications/slowvote/mail/PhabricatorSlowvoteReplyHandler.php',
|
||||
'PhabricatorSlowvoteResponsesTransaction' => 'applications/slowvote/xactions/PhabricatorSlowvoteResponsesTransaction.php',
|
||||
'PhabricatorSlowvoteResponsesTransaction' => 'applications/slowvote/xaction/PhabricatorSlowvoteResponsesTransaction.php',
|
||||
'PhabricatorSlowvoteSchemaSpec' => 'applications/slowvote/storage/PhabricatorSlowvoteSchemaSpec.php',
|
||||
'PhabricatorSlowvoteSearchEngine' => 'applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php',
|
||||
'PhabricatorSlowvoteShuffleTransaction' => 'applications/slowvote/xactions/PhabricatorSlowvoteShuffleTransaction.php',
|
||||
'PhabricatorSlowvoteShuffleTransaction' => 'applications/slowvote/xaction/PhabricatorSlowvoteShuffleTransaction.php',
|
||||
'PhabricatorSlowvoteTransaction' => 'applications/slowvote/storage/PhabricatorSlowvoteTransaction.php',
|
||||
'PhabricatorSlowvoteTransactionComment' => 'applications/slowvote/storage/PhabricatorSlowvoteTransactionComment.php',
|
||||
'PhabricatorSlowvoteTransactionQuery' => 'applications/slowvote/query/PhabricatorSlowvoteTransactionQuery.php',
|
||||
'PhabricatorSlowvoteTransactionType' => 'applications/slowvote/xactions/PhabricatorSlowvoteTransactionType.php',
|
||||
'PhabricatorSlowvoteTransactionType' => 'applications/slowvote/xaction/PhabricatorSlowvoteTransactionType.php',
|
||||
'PhabricatorSlowvoteVoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteVoteController.php',
|
||||
'PhabricatorSlug' => 'infrastructure/util/PhabricatorSlug.php',
|
||||
'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
|
||||
|
@ -4358,8 +4360,11 @@ phutil_register_library_map(array(
|
|||
'PholioDefaultEditCapability' => 'applications/pholio/capability/PholioDefaultEditCapability.php',
|
||||
'PholioDefaultViewCapability' => 'applications/pholio/capability/PholioDefaultViewCapability.php',
|
||||
'PholioImage' => 'applications/pholio/storage/PholioImage.php',
|
||||
'PholioImageDescriptionTransaction' => 'applications/pholio/xaction/PholioImageDescriptionTransaction.php',
|
||||
'PholioImageNameTransaction' => 'applications/pholio/xaction/PholioImageNameTransaction.php',
|
||||
'PholioImagePHIDType' => 'applications/pholio/phid/PholioImagePHIDType.php',
|
||||
'PholioImageQuery' => 'applications/pholio/query/PholioImageQuery.php',
|
||||
'PholioImageTransactionType' => 'applications/pholio/xaction/PholioImageTransactionType.php',
|
||||
'PholioImageUploadController' => 'applications/pholio/controller/PholioImageUploadController.php',
|
||||
'PholioInlineController' => 'applications/pholio/controller/PholioInlineController.php',
|
||||
'PholioInlineListController' => 'applications/pholio/controller/PholioInlineListController.php',
|
||||
|
@ -4368,6 +4373,7 @@ phutil_register_library_map(array(
|
|||
'PholioMockAuthorHeraldField' => 'applications/pholio/herald/PholioMockAuthorHeraldField.php',
|
||||
'PholioMockCommentController' => 'applications/pholio/controller/PholioMockCommentController.php',
|
||||
'PholioMockDescriptionHeraldField' => 'applications/pholio/herald/PholioMockDescriptionHeraldField.php',
|
||||
'PholioMockDescriptionTransaction' => 'applications/pholio/xaction/PholioMockDescriptionTransaction.php',
|
||||
'PholioMockEditController' => 'applications/pholio/controller/PholioMockEditController.php',
|
||||
'PholioMockEditor' => 'applications/pholio/editor/PholioMockEditor.php',
|
||||
'PholioMockEmbedView' => 'applications/pholio/view/PholioMockEmbedView.php',
|
||||
|
@ -4380,12 +4386,15 @@ phutil_register_library_map(array(
|
|||
'PholioMockListController' => 'applications/pholio/controller/PholioMockListController.php',
|
||||
'PholioMockMailReceiver' => 'applications/pholio/mail/PholioMockMailReceiver.php',
|
||||
'PholioMockNameHeraldField' => 'applications/pholio/herald/PholioMockNameHeraldField.php',
|
||||
'PholioMockNameTransaction' => 'applications/pholio/xaction/PholioMockNameTransaction.php',
|
||||
'PholioMockPHIDType' => 'applications/pholio/phid/PholioMockPHIDType.php',
|
||||
'PholioMockQuery' => 'applications/pholio/query/PholioMockQuery.php',
|
||||
'PholioMockRelationship' => 'applications/pholio/relationships/PholioMockRelationship.php',
|
||||
'PholioMockRelationshipSource' => 'applications/search/relationship/PholioMockRelationshipSource.php',
|
||||
'PholioMockSearchEngine' => 'applications/pholio/query/PholioMockSearchEngine.php',
|
||||
'PholioMockStatusTransaction' => 'applications/pholio/xaction/PholioMockStatusTransaction.php',
|
||||
'PholioMockThumbGridView' => 'applications/pholio/view/PholioMockThumbGridView.php',
|
||||
'PholioMockTransactionType' => 'applications/pholio/xaction/PholioMockTransactionType.php',
|
||||
'PholioMockViewController' => 'applications/pholio/controller/PholioMockViewController.php',
|
||||
'PholioRemarkupRule' => 'applications/pholio/remarkup/PholioRemarkupRule.php',
|
||||
'PholioReplyHandler' => 'applications/pholio/mail/PholioReplyHandler.php',
|
||||
|
@ -4393,6 +4402,7 @@ phutil_register_library_map(array(
|
|||
'PholioTransaction' => 'applications/pholio/storage/PholioTransaction.php',
|
||||
'PholioTransactionComment' => 'applications/pholio/storage/PholioTransactionComment.php',
|
||||
'PholioTransactionQuery' => 'applications/pholio/query/PholioTransactionQuery.php',
|
||||
'PholioTransactionType' => 'applications/pholio/xaction/PholioTransactionType.php',
|
||||
'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php',
|
||||
'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php',
|
||||
'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php',
|
||||
|
@ -6102,9 +6112,9 @@ phutil_register_library_map(array(
|
|||
'FundInitiativeBackController' => 'FundController',
|
||||
'FundInitiativeBackerTransaction' => 'FundInitiativeTransactionType',
|
||||
'FundInitiativeCloseController' => 'FundController',
|
||||
'FundInitiativeCommentController' => 'FundController',
|
||||
'FundInitiativeDescriptionTransaction' => 'FundInitiativeTransactionType',
|
||||
'FundInitiativeEditController' => 'FundController',
|
||||
'FundInitiativeEditEngine' => 'PhabricatorEditEngine',
|
||||
'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'FundInitiativeFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'FundInitiativeListController' => 'FundController',
|
||||
|
@ -6427,10 +6437,10 @@ phutil_register_library_map(array(
|
|||
'LegalpadDAO',
|
||||
'PhabricatorMarkupInterface',
|
||||
),
|
||||
'LegalpadDocumentCommentController' => 'LegalpadController',
|
||||
'LegalpadDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'LegalpadDocumentDoneController' => 'LegalpadController',
|
||||
'LegalpadDocumentEditController' => 'LegalpadController',
|
||||
'LegalpadDocumentEditEngine' => 'PhabricatorEditEngine',
|
||||
'LegalpadDocumentEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'LegalpadDocumentListController' => 'LegalpadController',
|
||||
'LegalpadDocumentManageController' => 'LegalpadController',
|
||||
|
@ -6477,6 +6487,7 @@ phutil_register_library_map(array(
|
|||
'LiskRawMigrationIterator' => 'PhutilBufferedIterator',
|
||||
'MacroConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'MacroCreateMemeConduitAPIMethod' => 'MacroConduitAPIMethod',
|
||||
'MacroEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'MacroEmojiExample' => 'PhabricatorUIExample',
|
||||
'MacroQueryConduitAPIMethod' => 'MacroConduitAPIMethod',
|
||||
'ManiphestAssignEmailCommand' => 'ManiphestEmailCommand',
|
||||
|
@ -9010,6 +9021,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectOrUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'PhabricatorProjectOrUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'PhabricatorProjectPHIDResolver' => 'PhabricatorPHIDResolver',
|
||||
'PhabricatorProjectPictureProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorProjectPointsProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||
|
@ -9895,8 +9907,11 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMarkupInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
),
|
||||
'PholioImageDescriptionTransaction' => 'PholioImageTransactionType',
|
||||
'PholioImageNameTransaction' => 'PholioImageTransactionType',
|
||||
'PholioImagePHIDType' => 'PhabricatorPHIDType',
|
||||
'PholioImageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PholioImageTransactionType' => 'PholioTransactionType',
|
||||
'PholioImageUploadController' => 'PholioController',
|
||||
'PholioInlineController' => 'PholioController',
|
||||
'PholioInlineListController' => 'PholioController',
|
||||
|
@ -9918,6 +9933,7 @@ phutil_register_library_map(array(
|
|||
'PholioMockAuthorHeraldField' => 'PholioMockHeraldField',
|
||||
'PholioMockCommentController' => 'PholioController',
|
||||
'PholioMockDescriptionHeraldField' => 'PholioMockHeraldField',
|
||||
'PholioMockDescriptionTransaction' => 'PholioMockTransactionType',
|
||||
'PholioMockEditController' => 'PholioController',
|
||||
'PholioMockEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PholioMockEmbedView' => 'AphrontView',
|
||||
|
@ -9930,19 +9946,23 @@ phutil_register_library_map(array(
|
|||
'PholioMockListController' => 'PholioController',
|
||||
'PholioMockMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'PholioMockNameHeraldField' => 'PholioMockHeraldField',
|
||||
'PholioMockNameTransaction' => 'PholioMockTransactionType',
|
||||
'PholioMockPHIDType' => 'PhabricatorPHIDType',
|
||||
'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PholioMockRelationship' => 'PhabricatorObjectRelationship',
|
||||
'PholioMockRelationshipSource' => 'PhabricatorObjectRelationshipSource',
|
||||
'PholioMockSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PholioMockStatusTransaction' => 'PholioMockTransactionType',
|
||||
'PholioMockThumbGridView' => 'AphrontView',
|
||||
'PholioMockTransactionType' => 'PholioTransactionType',
|
||||
'PholioMockViewController' => 'PholioController',
|
||||
'PholioRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||
'PholioReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
'PholioSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'PholioTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PholioTransaction' => 'PhabricatorModularTransaction',
|
||||
'PholioTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PholioTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PholioTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PholioTransactionView' => 'PhabricatorApplicationTransactionView',
|
||||
'PholioUploadedImageView' => 'AphrontView',
|
||||
'PhortuneAccount' => array(
|
||||
|
|
|
@ -7,10 +7,17 @@ final class AphrontFileHTTPParameterType
|
|||
return $key.'_raw';
|
||||
}
|
||||
|
||||
private function getDefaultKey($key) {
|
||||
return $key.'_default';
|
||||
}
|
||||
|
||||
protected function getParameterExists(AphrontRequest $request, $key) {
|
||||
$file_key = $this->getFileKey($key);
|
||||
$default_key = $this->getDefaultKey($key);
|
||||
|
||||
return $request->getExists($key) ||
|
||||
$request->getFileExists($file_key);
|
||||
$request->getFileExists($file_key) ||
|
||||
$request->getExists($default_key);
|
||||
}
|
||||
|
||||
protected function getParameterValue(AphrontRequest $request, $key) {
|
||||
|
@ -27,8 +34,9 @@ final class AphrontFileHTTPParameterType
|
|||
// this code around as a fallback if the client-side JS goes awry.
|
||||
|
||||
$file_key = $this->getFileKey($key);
|
||||
$default_key = $this->getDefaultKey($key);
|
||||
if (!$request->getFileExists($file_key)) {
|
||||
return null;
|
||||
return $request->getStr($default_key);
|
||||
}
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
final class PhabricatorAuditListView extends AphrontView {
|
||||
|
||||
private $commits;
|
||||
private $commits = array();
|
||||
private $header;
|
||||
private $showDrafts;
|
||||
private $noDataString;
|
||||
|
|
|
@ -642,7 +642,7 @@ abstract class PhabricatorApplication
|
|||
|
||||
|
||||
public function getApplicationTransactionEditor() {
|
||||
return new PhutilMethodNotImplementedException(pht('Coming Soon!'));
|
||||
return new PhabricatorApplicationEditor();
|
||||
}
|
||||
|
||||
public function getApplicationTransactionObject() {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
final class DifferentialRevisionListView extends AphrontView {
|
||||
|
||||
private $revisions;
|
||||
private $revisions = array();
|
||||
private $handles;
|
||||
private $header;
|
||||
private $noDataString;
|
||||
|
|
|
@ -42,8 +42,8 @@ final class PhabricatorFundApplication extends PhabricatorApplication {
|
|||
'/fund/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'FundInitiativeListController',
|
||||
'create/' => 'FundInitiativeEditController',
|
||||
'comment/(?P<id>[1-9]\d*)/' => 'FundInitiativeCommentController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'FundInitiativeEditController',
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'FundInitiativeEditController',
|
||||
'close/(?P<id>\d+)/' => 'FundInitiativeCloseController',
|
||||
'back/(?P<id>\d+)/' => 'FundInitiativeBackController',
|
||||
'backers/(?:(?P<id>\d+)/)?(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class FundInitiativeCommentController
|
||||
extends FundController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if (!$request->isFormPost()) {
|
||||
return new Aphront400Response();
|
||||
}
|
||||
|
||||
$initiative = id(new FundInitiativeQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$initiative) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$is_preview = $request->isPreviewRequest();
|
||||
$draft = PhabricatorDraft::buildFromRequest($request);
|
||||
|
||||
$view_uri = '/'.$initiative->getMonogram();
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
|
||||
->attachComment(
|
||||
id(new FundInitiativeTransactionComment())
|
||||
->setContent($request->getStr('comment')));
|
||||
|
||||
$editor = id(new FundInitiativeEditor())
|
||||
->setActor($viewer)
|
||||
->setContinueOnNoEffect($request->isContinueRequest())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setIsPreview($is_preview);
|
||||
|
||||
try {
|
||||
$xactions = $editor->applyTransactions($initiative, $xactions);
|
||||
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
|
||||
return id(new PhabricatorApplicationTransactionNoEffectResponse())
|
||||
->setCancelURI($view_uri)
|
||||
->setException($ex);
|
||||
}
|
||||
|
||||
if ($draft) {
|
||||
$draft->replaceOrDelete();
|
||||
}
|
||||
|
||||
if ($request->isAjax() && $is_preview) {
|
||||
return id(new PhabricatorApplicationTransactionResponse())
|
||||
->setViewer($viewer)
|
||||
->setTransactions($xactions)
|
||||
->setIsPreview($is_preview);
|
||||
} else {
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($view_uri);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,256 +1,11 @@
|
|||
<?php
|
||||
|
||||
final class FundInitiativeEditController
|
||||
extends FundController {
|
||||
|
||||
final class FundInitiativeEditController extends
|
||||
FundController {
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if ($id) {
|
||||
$initiative = id(new FundInitiativeQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$initiative) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$is_new = false;
|
||||
} else {
|
||||
$initiative = FundInitiative::initializeNewInitiative($viewer);
|
||||
$is_new = true;
|
||||
}
|
||||
|
||||
if ($is_new) {
|
||||
$title = pht('Create Initiative');
|
||||
$button_text = pht('Create Initiative');
|
||||
$cancel_uri = $this->getApplicationURI();
|
||||
$header_icon = 'fa-plus-square';
|
||||
} else {
|
||||
$title = pht(
|
||||
'Edit Initiative: %s',
|
||||
$initiative->getName());
|
||||
$button_text = pht('Save Changes');
|
||||
$cancel_uri = '/'.$initiative->getMonogram();
|
||||
$header_icon = 'fa-pencil';
|
||||
}
|
||||
|
||||
$e_name = true;
|
||||
$v_name = $initiative->getName();
|
||||
|
||||
$e_merchant = null;
|
||||
$v_merchant = $initiative->getMerchantPHID();
|
||||
|
||||
$v_desc = $initiative->getDescription();
|
||||
$v_risk = $initiative->getRisks();
|
||||
|
||||
if ($is_new) {
|
||||
$v_projects = array();
|
||||
} else {
|
||||
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$initiative->getPHID(),
|
||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
||||
$v_projects = array_reverse($v_projects);
|
||||
}
|
||||
|
||||
$validation_exception = null;
|
||||
if ($request->isFormPost()) {
|
||||
$v_name = $request->getStr('name');
|
||||
$v_desc = $request->getStr('description');
|
||||
$v_risk = $request->getStr('risks');
|
||||
$v_view = $request->getStr('viewPolicy');
|
||||
$v_edit = $request->getStr('editPolicy');
|
||||
$v_merchant = $request->getStr('merchantPHID');
|
||||
$v_projects = $request->getArr('projects');
|
||||
|
||||
$type_name = FundInitiativeNameTransaction::TRANSACTIONTYPE;
|
||||
$type_desc = FundInitiativeDescriptionTransaction::TRANSACTIONTYPE;
|
||||
$type_risk = FundInitiativeRisksTransaction::TRANSACTIONTYPE;
|
||||
$type_merchant = FundInitiativeMerchantTransaction::TRANSACTIONTYPE;
|
||||
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType($type_name)
|
||||
->setNewValue($v_name);
|
||||
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType($type_desc)
|
||||
->setNewValue($v_desc);
|
||||
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType($type_risk)
|
||||
->setNewValue($v_risk);
|
||||
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType($type_merchant)
|
||||
->setNewValue($v_merchant);
|
||||
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType($type_view)
|
||||
->setNewValue($v_view);
|
||||
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType($type_edit)
|
||||
->setNewValue($v_edit);
|
||||
|
||||
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
||||
$xactions[] = id(new FundInitiativeTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $proj_edge_type)
|
||||
->setNewValue(array('=' => array_fuse($v_projects)));
|
||||
|
||||
$editor = id(new FundInitiativeEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true);
|
||||
|
||||
try {
|
||||
$editor->applyTransactions($initiative, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/'.$initiative->getMonogram());
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
|
||||
$e_name = $ex->getShortMessage($type_name);
|
||||
$e_merchant = $ex->getShortMessage($type_merchant);
|
||||
|
||||
$initiative->setViewPolicy($v_view);
|
||||
$initiative->setEditPolicy($v_edit);
|
||||
}
|
||||
}
|
||||
|
||||
$policies = id(new PhabricatorPolicyQuery())
|
||||
->setViewer($viewer)
|
||||
->setObject($initiative)
|
||||
->execute();
|
||||
|
||||
$merchants = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->execute();
|
||||
|
||||
$merchant_options = array();
|
||||
foreach ($merchants as $merchant) {
|
||||
$merchant_options[$merchant->getPHID()] = pht(
|
||||
'Merchant %d %s',
|
||||
$merchant->getID(),
|
||||
$merchant->getName());
|
||||
}
|
||||
|
||||
if ($v_merchant && empty($merchant_options[$v_merchant])) {
|
||||
$merchant_options = array(
|
||||
$v_merchant => pht('(Restricted Merchant)'),
|
||||
) + $merchant_options;
|
||||
}
|
||||
|
||||
if (!$merchant_options) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Valid Phortune Merchant Accounts'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You do not control any merchant accounts which can receive '.
|
||||
'payments from this initiative. When you create an initiative, '.
|
||||
'you need to specify a merchant account where funds will be paid '.
|
||||
'to.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Create a merchant account in the Phortune application before '.
|
||||
'creating an initiative in Fund.'))
|
||||
->addCancelButton($this->getApplicationURI());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setName('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setValue($v_name)
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setName('merchantPHID')
|
||||
->setLabel(pht('Pay To Merchant'))
|
||||
->setValue($v_merchant)
|
||||
->setError($e_merchant)
|
||||
->setOptions($merchant_options))
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($viewer)
|
||||
->setName('description')
|
||||
->setLabel(pht('Description'))
|
||||
->setValue($v_desc))
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($viewer)
|
||||
->setName('risks')
|
||||
->setLabel(pht('Risks/Challenges'))
|
||||
->setValue($v_risk))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setLabel(pht('Tags'))
|
||||
->setName('projects')
|
||||
->setValue($v_projects)
|
||||
->setDatasource(new PhabricatorProjectDatasource()))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('viewPolicy')
|
||||
->setPolicyObject($initiative)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||
->setPolicies($policies))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('editPolicy')
|
||||
->setPolicyObject($initiative)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||
->setPolicies($policies))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue($button_text)
|
||||
->addCancelButton($cancel_uri));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
if ($is_new) {
|
||||
$crumbs->addTextCrumb(pht('Create Initiative'));
|
||||
} else {
|
||||
$crumbs->addTextCrumb(
|
||||
$initiative->getMonogram(),
|
||||
'/'.$initiative->getMonogram());
|
||||
$crumbs->addTextCrumb(pht('Edit'));
|
||||
}
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setValidationException($validation_exception)
|
||||
->setHeaderText(pht('Initiative'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($form);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon($header_icon);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter($box);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
return id(new FundInitiativeEditEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,15 +52,16 @@ final class FundInitiativeViewController
|
|||
$timeline = $this->buildTransactionTimeline(
|
||||
$initiative,
|
||||
new FundInitiativeTransactionQuery());
|
||||
$timeline->setQuoteRef($initiative->getMonogram());
|
||||
|
||||
$add_comment = $this->buildCommentForm($initiative);
|
||||
$comment_view = $this->buildCommentForm($initiative, $timeline);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$timeline,
|
||||
$add_comment,
|
||||
$comment_view,
|
||||
))
|
||||
->addPropertySection(pht('Details'), $details);
|
||||
|
||||
|
@ -164,26 +165,14 @@ final class FundInitiativeViewController
|
|||
return $curtain;
|
||||
}
|
||||
|
||||
private function buildCommentForm(FundInitiative $initiative) {
|
||||
private function buildCommentForm(FundInitiative $initiative, $timeline) {
|
||||
$viewer = $this->getViewer();
|
||||
$box = id(new FundInitiativeEditEngine())
|
||||
->setViewer($viewer)
|
||||
->buildEditEngineCommentView($initiative)
|
||||
->setTransactionTimeline($timeline);
|
||||
|
||||
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
||||
|
||||
$add_comment_header = $is_serious
|
||||
? pht('Add Comment')
|
||||
: pht('Add Liquidity');
|
||||
|
||||
$draft = PhabricatorDraft::newFromUserAndKey(
|
||||
$viewer, $initiative->getPHID());
|
||||
|
||||
return id(new PhabricatorApplicationTransactionCommentView())
|
||||
->setUser($viewer)
|
||||
->setObjectPHID($initiative->getPHID())
|
||||
->setDraft($draft)
|
||||
->setHeaderText($add_comment_header)
|
||||
->setAction(
|
||||
$this->getApplicationURI('/comment/'.$initiative->getID().'/'))
|
||||
->setSubmitButtonName(pht('Add Comment'));
|
||||
return $box;
|
||||
}
|
||||
|
||||
|
||||
|
|
152
src/applications/fund/editor/FundInitiativeEditEngine.php
Normal file
152
src/applications/fund/editor/FundInitiativeEditEngine.php
Normal file
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
final class FundInitiativeEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'fund.initiative';
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Fund');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorFundApplication';
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Configure Fund Forms');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('Configure creation and editing forms in Fund.');
|
||||
}
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
return FundInitiative::initializeNewInitiative($this->getViewer());
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return new FundInitiativeQuery();
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create New Initiative');
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Initiative: %s', $object->getName());
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
return $object->getName();
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('Create Initiative');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Initivative');
|
||||
}
|
||||
|
||||
protected function getObjectCreateCancelURI($object) {
|
||||
return $this->getApplication()->getApplicationURI('/');
|
||||
}
|
||||
|
||||
protected function getEditorURI() {
|
||||
return $this->getApplication()->getApplicationURI('edit/');
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
return $object->getViewURI();
|
||||
}
|
||||
|
||||
protected function getCreateNewObjectPolicy() {
|
||||
return $this->getApplication()->getPolicy(
|
||||
FundCreateInitiativesCapability::CAPABILITY);
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
$viewer = $this->getViewer();
|
||||
$v_merchant = $object->getMerchantPHID();
|
||||
|
||||
$merchants = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->execute();
|
||||
|
||||
$merchant_options = array();
|
||||
foreach ($merchants as $merchant) {
|
||||
$merchant_options[$merchant->getPHID()] = pht(
|
||||
'Merchant %d %s',
|
||||
$merchant->getID(),
|
||||
$merchant->getName());
|
||||
}
|
||||
|
||||
if ($v_merchant && empty($merchant_options[$v_merchant])) {
|
||||
$merchant_options = array(
|
||||
$v_merchant => pht('(Restricted Merchant)'),
|
||||
) + $merchant_options;
|
||||
}
|
||||
|
||||
$merchant_instructions = null;
|
||||
if (!$merchant_options) {
|
||||
$merchant_instructions = pht(
|
||||
'NOTE: You do not control any merchant accounts which can receive '.
|
||||
'payments from this initiative. When you create an initiative, '.
|
||||
'you need to specify a merchant account where funds will be paid '.
|
||||
'to. Create a merchant account in the Phortune application before '.
|
||||
'creating an initiative in Fund.');
|
||||
}
|
||||
|
||||
return array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setDescription(pht('Initiative name.'))
|
||||
->setConduitTypeDescription(pht('New initiative name.'))
|
||||
->setTransactionType(
|
||||
FundInitiativeNameTransaction::TRANSACTIONTYPE)
|
||||
->setValue($object->getName())
|
||||
->setIsRequired(true),
|
||||
id(new PhabricatorSelectEditField())
|
||||
->setKey('merchantPHID')
|
||||
->setLabel(pht('Merchant'))
|
||||
->setDescription(pht('Merchant operating the initiative.'))
|
||||
->setConduitTypeDescription(pht('New initiative merchant.'))
|
||||
->setControlInstructions($merchant_instructions)
|
||||
->setValue($object->getMerchantPHID())
|
||||
->setTransactionType(
|
||||
FundInitiativeMerchantTransaction::TRANSACTIONTYPE)
|
||||
->setOptions($merchant_options)
|
||||
->setIsRequired(true),
|
||||
id(new PhabricatorRemarkupEditField())
|
||||
->setKey('description')
|
||||
->setLabel(pht('Description'))
|
||||
->setDescription(pht('Initiative long description.'))
|
||||
->setConduitTypeDescription(pht('New initiative description.'))
|
||||
->setTransactionType(
|
||||
FundInitiativeDescriptionTransaction::TRANSACTIONTYPE)
|
||||
->setValue($object->getDescription()),
|
||||
id(new PhabricatorRemarkupEditField())
|
||||
->setKey('risks')
|
||||
->setLabel(pht('Risks/Challenges'))
|
||||
->setDescription(pht('Initiative risks and challenges.'))
|
||||
->setConduitTypeDescription(pht('Initiative risks and challenges.'))
|
||||
->setTransactionType(
|
||||
FundInitiativeRisksTransaction::TRANSACTIONTYPE)
|
||||
->setValue($object->getRisks()),
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -126,6 +126,7 @@ final class FundBackerSearchEngine
|
|||
}
|
||||
|
||||
$table = id(new AphrontTableView($rows))
|
||||
->setNoDataString(pht('No backers found.'))
|
||||
->setHeaders(
|
||||
array(
|
||||
pht('Initiative'),
|
||||
|
|
|
@ -85,6 +85,10 @@ final class FundInitiative extends FundDAO
|
|||
return 'I'.$this->getID();
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
}
|
||||
|
||||
public function getProjectPHIDs() {
|
||||
return $this->assertAttached($this->projectPHIDs);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ final class FundInitiativeMerchantTransaction
|
|||
|
||||
return pht(
|
||||
'%s changed the merchant receiving funds from %s '.
|
||||
'initiative from %s to %s.',
|
||||
'from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$old_merchant,
|
||||
|
|
|
@ -37,7 +37,7 @@ final class FundInitiativeNameTransaction
|
|||
$this->renderObject());
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed %s initiative from %s to %s.',
|
||||
'%s renamed %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderOldValue(),
|
||||
|
|
|
@ -55,7 +55,7 @@ final class FundInitiativeRefundTransaction
|
|||
'%s refunded %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$amount->formatForDisplay(),
|
||||
$this->renderHandleLink($backer_phid));
|
||||
$this->renderHandle($backer_phid));
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
|
@ -69,7 +69,7 @@ final class FundInitiativeRefundTransaction
|
|||
'%s refunded %s to %s for %s.',
|
||||
$this->renderAuthor(),
|
||||
$amount->formatForDisplay(),
|
||||
$this->renderHandleLink($backer_phid),
|
||||
$this->renderHandle($backer_phid),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
|
|
|
@ -28,12 +28,12 @@ final class FundInitiativeStatusTransaction
|
|||
public function getTitleForFeed() {
|
||||
if ($this->getNewValue() == FundInitiative::STATUS_CLOSED) {
|
||||
return pht(
|
||||
'%s closed the initiative %s.',
|
||||
'%s closed %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
} else {
|
||||
return pht(
|
||||
'%s reopened the initiative %s.',
|
||||
'%s reopened %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
|
|
@ -53,10 +53,10 @@ final class PhabricatorLegalpadApplication extends PhabricatorApplication {
|
|||
'/L(?P<id>\d+)' => 'LegalpadDocumentSignController',
|
||||
'/legalpad/' => array(
|
||||
'' => 'LegalpadDocumentListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'LegalpadDocumentListController',
|
||||
'create/' => 'LegalpadDocumentEditController',
|
||||
'edit/(?P<id>\d+)/' => 'LegalpadDocumentEditController',
|
||||
'comment/(?P<id>\d+)/' => 'LegalpadDocumentCommentController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'LegalpadDocumentListController',
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'LegalpadDocumentEditController',
|
||||
'view/(?P<id>\d+)/' => 'LegalpadDocumentManageController',
|
||||
'done/' => 'LegalpadDocumentDoneController',
|
||||
'verify/(?P<code>[^/]+)/'
|
||||
|
|
|
@ -9,7 +9,7 @@ abstract class LegalpadController extends PhabricatorController {
|
|||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
if ($for_app) {
|
||||
$nav->addFilter('create/', pht('Create Document'));
|
||||
$nav->addFilter('edit/', pht('Create Document'));
|
||||
}
|
||||
|
||||
id(new LegalpadDocumentSearchEngine())
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class LegalpadDocumentCommentController extends LegalpadController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if (!$request->isFormPost()) {
|
||||
return new Aphront400Response();
|
||||
}
|
||||
|
||||
$document = id(new LegalpadDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needDocumentBodies(true)
|
||||
->executeOne();
|
||||
|
||||
if (!$document) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$is_preview = $request->isPreviewRequest();
|
||||
|
||||
$draft = PhabricatorDraft::buildFromRequest($request);
|
||||
|
||||
$document_uri = $this->getApplicationURI('view/'.$document->getID());
|
||||
|
||||
$comment = $request->getStr('comment');
|
||||
|
||||
$xactions = array();
|
||||
|
||||
if (strlen($comment)) {
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
|
||||
->attachComment(
|
||||
id(new LegalpadTransactionComment())
|
||||
->setDocumentID($document->getID())
|
||||
->setLineNumber(0)
|
||||
->setLineLength(0)
|
||||
->setContent($comment));
|
||||
}
|
||||
|
||||
$editor = id(new LegalpadDocumentEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect($request->isContinueRequest())
|
||||
->setIsPreview($is_preview);
|
||||
|
||||
try {
|
||||
$xactions = $editor->applyTransactions($document, $xactions);
|
||||
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
|
||||
return id(new PhabricatorApplicationTransactionNoEffectResponse())
|
||||
->setCancelURI($document_uri)
|
||||
->setException($ex);
|
||||
}
|
||||
|
||||
if ($draft) {
|
||||
$draft->replaceOrDelete();
|
||||
}
|
||||
|
||||
if ($request->isAjax() && $is_preview) {
|
||||
return id(new PhabricatorApplicationTransactionResponse())
|
||||
->setViewer($viewer)
|
||||
->setTransactions($xactions)
|
||||
->setIsPreview($is_preview);
|
||||
} else {
|
||||
return id(new AphrontRedirectResponse())->setURI($document_uri);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,275 +3,9 @@
|
|||
final class LegalpadDocumentEditController extends LegalpadController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if (!$id) {
|
||||
$is_create = true;
|
||||
|
||||
$this->requireApplicationCapability(
|
||||
LegalpadCreateDocumentsCapability::CAPABILITY);
|
||||
|
||||
$document = LegalpadDocument::initializeNewDocument($viewer);
|
||||
$body = id(new LegalpadDocumentBody())
|
||||
->setCreatorPHID($viewer->getPHID());
|
||||
$document->attachDocumentBody($body);
|
||||
$document->setDocumentBodyPHID(PhabricatorPHIDConstants::PHID_VOID);
|
||||
} else {
|
||||
$is_create = false;
|
||||
|
||||
$document = id(new LegalpadDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->needDocumentBodies(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$document) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
}
|
||||
|
||||
$e_title = true;
|
||||
$e_text = true;
|
||||
|
||||
$title = $document->getDocumentBody()->getTitle();
|
||||
$text = $document->getDocumentBody()->getText();
|
||||
$v_signature_type = $document->getSignatureType();
|
||||
$v_preamble = $document->getPreamble();
|
||||
$v_require_signature = $document->getRequireSignature();
|
||||
|
||||
$errors = array();
|
||||
$can_view = null;
|
||||
$can_edit = null;
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$title = $request->getStr('title');
|
||||
if (!strlen($title)) {
|
||||
$e_title = pht('Required');
|
||||
$errors[] = pht('The document title may not be blank.');
|
||||
} else {
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(
|
||||
LegalpadDocumentTitleTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($title);
|
||||
}
|
||||
|
||||
$text = $request->getStr('text');
|
||||
if (!strlen($text)) {
|
||||
$e_text = pht('Required');
|
||||
$errors[] = pht('The document may not be blank.');
|
||||
} else {
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(
|
||||
LegalpadDocumentTextTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($text);
|
||||
}
|
||||
|
||||
$can_view = $request->getStr('can_view');
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
||||
->setNewValue($can_view);
|
||||
$can_edit = $request->getStr('can_edit');
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
|
||||
->setNewValue($can_edit);
|
||||
|
||||
if ($is_create) {
|
||||
$v_signature_type = $request->getStr('signatureType');
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(
|
||||
LegalpadDocumentSignatureTypeTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($v_signature_type);
|
||||
}
|
||||
|
||||
$v_preamble = $request->getStr('preamble');
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(
|
||||
LegalpadDocumentPreambleTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($v_preamble);
|
||||
|
||||
$v_require_signature = $request->getBool('requireSignature', 0);
|
||||
if ($v_require_signature) {
|
||||
if (!$viewer->getIsAdmin()) {
|
||||
$errors[] = pht('Only admins may require signature.');
|
||||
}
|
||||
$individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
|
||||
if ($v_signature_type != $individual) {
|
||||
$errors[] = pht(
|
||||
'Only documents with signature type "individual" may require '.
|
||||
'signing to use Phabricator.');
|
||||
}
|
||||
}
|
||||
if ($viewer->getIsAdmin()) {
|
||||
$xactions[] = id(new LegalpadTransaction())
|
||||
->setTransactionType(
|
||||
LegalpadDocumentRequireSignatureTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($v_require_signature);
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$editor = id(new LegalpadDocumentEditor())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setActor($viewer);
|
||||
|
||||
$xactions = $editor->applyTransactions($document, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getApplicationURI('view/'.$document->getID()));
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
// set these to what was specified in the form on post
|
||||
$document->setViewPolicy($can_view);
|
||||
$document->setEditPolicy($can_edit);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setID('document-title')
|
||||
->setLabel(pht('Title'))
|
||||
->setError($e_title)
|
||||
->setValue($title)
|
||||
->setName('title'));
|
||||
|
||||
if ($is_create) {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Who Should Sign?'))
|
||||
->setName(pht('signatureType'))
|
||||
->setValue($v_signature_type)
|
||||
->setOptions(LegalpadDocument::getSignatureTypeMap()));
|
||||
$show_require = true;
|
||||
$caption = pht('Applies only to documents individuals sign.');
|
||||
} else {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Who Should Sign?'))
|
||||
->setValue($document->getSignatureTypeName()));
|
||||
$individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
|
||||
$show_require = $document->getSignatureType() == $individual;
|
||||
$caption = null;
|
||||
}
|
||||
|
||||
if ($show_require) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormCheckboxControl())
|
||||
->setDisabled(!$viewer->getIsAdmin())
|
||||
->setLabel(pht('Require Signature'))
|
||||
->addCheckbox(
|
||||
'requireSignature',
|
||||
'requireSignature',
|
||||
pht('Should signing this document be required to use Phabricator?'),
|
||||
$v_require_signature)
|
||||
->setCaption($caption));
|
||||
}
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($viewer)
|
||||
->setID('preamble')
|
||||
->setLabel(pht('Preamble'))
|
||||
->setValue($v_preamble)
|
||||
->setName('preamble')
|
||||
->setCaption(
|
||||
pht('Optional help text for users signing this document.')))
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($viewer)
|
||||
->setID('document-text')
|
||||
->setLabel(pht('Document Body'))
|
||||
->setError($e_text)
|
||||
->setValue($text)
|
||||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
||||
->setName('text'));
|
||||
|
||||
$policies = id(new PhabricatorPolicyQuery())
|
||||
->setViewer($viewer)
|
||||
->setObject($document)
|
||||
->execute();
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setUser($viewer)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||
->setPolicyObject($document)
|
||||
->setPolicies($policies)
|
||||
->setName('can_view'))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setUser($viewer)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||
->setPolicyObject($document)
|
||||
->setPolicies($policies)
|
||||
->setName('can_edit'));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$submit = new AphrontFormSubmitControl();
|
||||
if ($is_create) {
|
||||
$submit->setValue(pht('Create Document'));
|
||||
$submit->addCancelButton($this->getApplicationURI());
|
||||
$title = pht('Create Document');
|
||||
$short = pht('Create');
|
||||
$header_icon = 'fa-plus-square';
|
||||
} else {
|
||||
$submit->setValue(pht('Save Document'));
|
||||
$submit->addCancelButton(
|
||||
$this->getApplicationURI('view/'.$document->getID()));
|
||||
$title = pht('Edit Document: %s', $document->getTitle());
|
||||
$short = pht('Edit');
|
||||
$header_icon = 'fa-pencil';
|
||||
|
||||
$crumbs->addTextCrumb(
|
||||
$document->getMonogram(),
|
||||
$this->getApplicationURI('view/'.$document->getID()));
|
||||
}
|
||||
|
||||
$form->appendChild($submit);
|
||||
|
||||
$form_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Document'))
|
||||
->setFormErrors($errors)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$crumbs->addTextCrumb($short);
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$preview = id(new PHUIRemarkupPreviewPanel())
|
||||
->setHeader($document->getTitle())
|
||||
->setPreviewURI($this->getApplicationURI('document/preview/'))
|
||||
->setControlID('document-text')
|
||||
->setPreviewType(PHUIRemarkupPreviewPanel::DOCUMENT);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon($header_icon);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$form_box,
|
||||
$preview,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
return id(new LegalpadDocumentEditEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ final class LegalpadDocumentListController extends LegalpadController {
|
|||
$crumbs->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Create Document'))
|
||||
->setHref($this->getApplicationURI('create/'))
|
||||
->setHref($this->getApplicationURI('edit/'))
|
||||
->setIcon('fa-plus-square')
|
||||
->setDisabled(!$can_create)
|
||||
->setWorkflow(!$can_create));
|
||||
|
|
|
@ -37,6 +37,7 @@ final class LegalpadDocumentManageController extends LegalpadController {
|
|||
$document,
|
||||
new LegalpadTransactionQuery(),
|
||||
$engine);
|
||||
$timeline->setQuoteRef($document->getMonogram());
|
||||
|
||||
$title = $document_body->getTitle();
|
||||
|
||||
|
@ -50,9 +51,7 @@ final class LegalpadDocumentManageController extends LegalpadController {
|
|||
$properties = $this->buildPropertyView($document, $engine);
|
||||
$document_view = $this->buildDocumentView($document, $engine);
|
||||
|
||||
$comment_form_id = celerity_generate_unique_node_id();
|
||||
|
||||
$add_comment = $this->buildAddCommentView($document, $comment_form_id);
|
||||
$comment_form = $this->buildCommentView($document, $timeline);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
|
@ -69,7 +68,7 @@ final class LegalpadDocumentManageController extends LegalpadController {
|
|||
$properties,
|
||||
$document_view,
|
||||
$timeline,
|
||||
$add_comment,
|
||||
$comment_form,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
|
@ -181,31 +180,14 @@ final class LegalpadDocumentManageController extends LegalpadController {
|
|||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||
}
|
||||
|
||||
private function buildAddCommentView(
|
||||
LegalpadDocument $document,
|
||||
$comment_form_id) {
|
||||
private function buildCommentView(LegalpadDocument $document, $timeline) {
|
||||
$viewer = $this->getViewer();
|
||||
$box = id(new LegalpadDocumentEditEngine())
|
||||
->setViewer($viewer)
|
||||
->buildEditEngineCommentView($document)
|
||||
->setTransactionTimeline($timeline);
|
||||
|
||||
$draft = PhabricatorDraft::newFromUserAndKey($viewer, $document->getPHID());
|
||||
|
||||
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
||||
|
||||
$title = $is_serious
|
||||
? pht('Add Comment')
|
||||
: pht('Debate Legislation');
|
||||
|
||||
$form = id(new PhabricatorApplicationTransactionCommentView())
|
||||
->setUser($viewer)
|
||||
->setObjectPHID($document->getPHID())
|
||||
->setFormID($comment_form_id)
|
||||
->setHeaderText($title)
|
||||
->setDraft($draft)
|
||||
->setSubmitButtonName(pht('Add Comment'))
|
||||
->setAction($this->getApplicationURI('/comment/'.$document->getID().'/'))
|
||||
->setRequestURI($this->getRequest()->getRequestURI());
|
||||
|
||||
return $form;
|
||||
|
||||
return $box;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
169
src/applications/legalpad/editor/LegalpadDocumentEditEngine.php
Normal file
169
src/applications/legalpad/editor/LegalpadDocumentEditEngine.php
Normal file
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
final class LegalpadDocumentEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'legalpad.document';
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Legalpad');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorLegalpadApplication';
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Configure Legalpad Forms');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('Configure creation and editing documents in Legalpad.');
|
||||
}
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$document = LegalpadDocument::initializeNewDocument($viewer);
|
||||
$body = id(new LegalpadDocumentBody())
|
||||
->setCreatorPHID($viewer->getPHID());
|
||||
$document->attachDocumentBody($body);
|
||||
$document->setDocumentBodyPHID(PhabricatorPHIDConstants::PHID_VOID);
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return id(new LegalpadDocumentQuery())
|
||||
->needDocumentBodies(true);
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create New Document');
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
$body = $object->getDocumentBody();
|
||||
$title = $body->getTitle();
|
||||
return pht('Edit Document: %s', $title);
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
$body = $object->getDocumentBody();
|
||||
return $body->getTitle();
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('Create Document');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Document');
|
||||
}
|
||||
|
||||
protected function getObjectCreateCancelURI($object) {
|
||||
return $this->getApplication()->getApplicationURI('/');
|
||||
}
|
||||
|
||||
protected function getEditorURI() {
|
||||
return $this->getApplication()->getApplicationURI('edit/');
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
$id = $object->getID();
|
||||
return $this->getApplication()->getApplicationURI('view/'.$id.'/');
|
||||
}
|
||||
|
||||
|
||||
protected function getCreateNewObjectPolicy() {
|
||||
return $this->getApplication()->getPolicy(
|
||||
LegalpadCreateDocumentsCapability::CAPABILITY);
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$body = $object->getDocumentBody();
|
||||
$document_body = $body->getText();
|
||||
|
||||
$is_create = $this->getIsCreate();
|
||||
$is_admin = $viewer->getIsAdmin();
|
||||
|
||||
$fields = array();
|
||||
$fields[] =
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('title')
|
||||
->setLabel(pht('Title'))
|
||||
->setDescription(pht('Document Title.'))
|
||||
->setConduitTypeDescription(pht('New document title.'))
|
||||
->setValue($object->getTitle())
|
||||
->setIsRequired(true)
|
||||
->setTransactionType(
|
||||
LegalpadDocumentTitleTransaction::TRANSACTIONTYPE);
|
||||
|
||||
if ($is_create) {
|
||||
$fields[] =
|
||||
id(new PhabricatorSelectEditField())
|
||||
->setKey('signatureType')
|
||||
->setLabel(pht('Who Should Sign?'))
|
||||
->setDescription(pht('Type of signature required'))
|
||||
->setConduitTypeDescription(pht('New document signature type.'))
|
||||
->setValue($object->getSignatureType())
|
||||
->setOptions(LegalpadDocument::getSignatureTypeMap())
|
||||
->setTransactionType(
|
||||
LegalpadDocumentSignatureTypeTransaction::TRANSACTIONTYPE);
|
||||
$show_require = true;
|
||||
} else {
|
||||
$fields[] = id(new PhabricatorStaticEditField())
|
||||
->setLabel(pht('Who Should Sign?'))
|
||||
->setValue($object->getSignatureTypeName());
|
||||
$individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
|
||||
$show_require = $object->getSignatureType() == $individual;
|
||||
}
|
||||
|
||||
if ($show_require && $is_admin) {
|
||||
$fields[] =
|
||||
id(new PhabricatorBoolEditField())
|
||||
->setKey('requireSignature')
|
||||
->setOptions(
|
||||
pht('No Signature Required'),
|
||||
pht('Signature Required to use Phabricator'))
|
||||
->setAsCheckbox(true)
|
||||
->setTransactionType(
|
||||
LegalpadDocumentRequireSignatureTransaction::TRANSACTIONTYPE)
|
||||
->setDescription(pht('Marks this document as required signing.'))
|
||||
->setConduitDescription(
|
||||
pht('Marks this document as required signing.'))
|
||||
->setValue($object->getRequireSignature());
|
||||
}
|
||||
|
||||
$fields[] =
|
||||
id(new PhabricatorRemarkupEditField())
|
||||
->setKey('preamble')
|
||||
->setLabel(pht('Preamble'))
|
||||
->setDescription(pht('The preamble of the document.'))
|
||||
->setConduitTypeDescription(pht('New document preamble.'))
|
||||
->setValue($object->getPreamble())
|
||||
->setTransactionType(
|
||||
LegalpadDocumentPreambleTransaction::TRANSACTIONTYPE);
|
||||
|
||||
$fields[] =
|
||||
id(new PhabricatorRemarkupEditField())
|
||||
->setKey('text')
|
||||
->setLabel(pht('Document Body'))
|
||||
->setDescription(pht('The body of text of the document.'))
|
||||
->setConduitTypeDescription(pht('New document body.'))
|
||||
->setValue($document_body)
|
||||
->setIsRequired(true)
|
||||
->setTransactionType(
|
||||
LegalpadDocumentTextTransaction::TRANSACTIONTYPE);
|
||||
|
||||
return $fields;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -21,6 +21,14 @@ final class LegalpadDocumentEditor
|
|||
return $types;
|
||||
}
|
||||
|
||||
public function getCreateObjectTitle($author, $object) {
|
||||
return pht('%s created this document.', $author);
|
||||
}
|
||||
|
||||
public function getCreateObjectTitleForFeed($author, $object) {
|
||||
return pht('%s created %s.', $author, $object);
|
||||
}
|
||||
|
||||
protected function applyFinalEffects(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
@ -64,6 +72,37 @@ final class LegalpadDocumentEditor
|
|||
return $xactions;
|
||||
}
|
||||
|
||||
protected function validateAllTransactions(PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
$is_required = (bool)$object->getRequireSignature();
|
||||
$document_type = $object->getSignatureType();
|
||||
$individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case LegalpadDocumentRequireSignatureTransaction::TRANSACTIONTYPE:
|
||||
$is_required = (bool)$xaction->getNewValue();
|
||||
break;
|
||||
case LegalpadDocumentSignatureTypeTransaction::TRANSACTIONTYPE:
|
||||
$document_type = $xaction->getNewValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_required && ($document_type != $individual)) {
|
||||
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||
LegalpadDocumentRequireSignatureTransaction::TRANSACTIONTYPE,
|
||||
pht('Invalid'),
|
||||
pht('Only documents with signature type "individual" may '.
|
||||
'require signing to use Phabricator.'),
|
||||
null);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
/* -( Sending Mail )------------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -120,6 +120,10 @@ final class LegalpadDocument extends LegalpadDAO
|
|||
return 'L'.$this->getID();
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
}
|
||||
|
||||
public function getUserSignature($phid) {
|
||||
return $this->assertAttachedKey($this->userSignatures, $phid);
|
||||
}
|
||||
|
|
|
@ -6,15 +6,15 @@ final class LegalpadDocumentRequireSignatureTransaction
|
|||
const TRANSACTIONTYPE = 'legalpad:require-signature';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getRequireSignature();
|
||||
return (int)$object->getRequireSignature();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setRequireSignature($value);
|
||||
$object->setRequireSignature((int)$value);
|
||||
}
|
||||
|
||||
public function applyExternalEffects($object, $value) {
|
||||
if (strlen($value)) {
|
||||
if ($value) {
|
||||
$session = new PhabricatorAuthSession();
|
||||
queryfx(
|
||||
$session->establishConnection('w'),
|
||||
|
@ -25,6 +25,7 @@ final class LegalpadDocumentRequireSignatureTransaction
|
|||
|
||||
public function getTitle() {
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s set the document to require signatures.',
|
||||
|
@ -51,6 +52,19 @@ final class LegalpadDocumentRequireSignatureTransaction
|
|||
}
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
$is_admin = $this->getActor()->getIsAdmin();
|
||||
|
||||
if (!$is_admin) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht('Only admins may require signature.'));
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-pencil-square';
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ final class LegalpadDocumentSignatureTypeTransaction
|
|||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s set the document signature type.',
|
||||
'%s updated the document signature type.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s set the document signature type for %s.',
|
||||
'%s updated the document signature type for %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
|
|
@ -17,9 +17,17 @@ final class LegalpadDocumentTextTransaction
|
|||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s updated the document text.',
|
||||
$this->renderAuthor());
|
||||
$old = $this->getOldValue();
|
||||
|
||||
if (!strlen($old)) {
|
||||
return pht(
|
||||
'%s set the document text.',
|
||||
$this->renderAuthor());
|
||||
} else {
|
||||
return pht(
|
||||
'%s updated the document text.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
|
|
|
@ -17,20 +17,37 @@ final class LegalpadDocumentTitleTransaction
|
|||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s renamed this document from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderOldValue(),
|
||||
$this->renderNewValue());
|
||||
$old = $this->getOldValue();
|
||||
|
||||
if (!strlen($old)) {
|
||||
return pht(
|
||||
'%s created this document.',
|
||||
$this->renderAuthor());
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed this document from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderOldValue(),
|
||||
$this->renderNewValue());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s renamed document %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderOldValue(),
|
||||
$this->renderNewValue());
|
||||
$old = $this->getOldValue();
|
||||
|
||||
if (!strlen($old)) {
|
||||
return pht(
|
||||
'%s created %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderOldValue(),
|
||||
$this->renderNewValue());
|
||||
}
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
|
|
19
src/applications/macro/conduit/MacroEditConduitAPIMethod.php
Normal file
19
src/applications/macro/conduit/MacroEditConduitAPIMethod.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
final class MacroEditConduitAPIMethod
|
||||
extends PhabricatorEditEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'macro.edit';
|
||||
}
|
||||
|
||||
public function newEditEngine() {
|
||||
return new PhabricatorMacroEditEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht(
|
||||
'Apply transactions to create a new macro or edit an existing one.');
|
||||
}
|
||||
|
||||
}
|
|
@ -50,7 +50,9 @@ final class PhabricatorMacroAudioController extends PhabricatorMacroController {
|
|||
|
||||
if ($file) {
|
||||
if (!$file->isAudio()) {
|
||||
$errors[] = pht('You must upload audio.');
|
||||
$errors[] = pht(
|
||||
'The file you uploaded is invalid: it is not recognizable as '.
|
||||
'a valid audio file.');
|
||||
$e_file = pht('Invalid');
|
||||
} else {
|
||||
$xactions[] = id(new PhabricatorMacroTransaction())
|
||||
|
@ -59,7 +61,9 @@ final class PhabricatorMacroAudioController extends PhabricatorMacroController {
|
|||
->setNewValue($file->getPHID());
|
||||
}
|
||||
} else {
|
||||
$errors[] = pht('You must upload an audio file.');
|
||||
$errors[] = pht(
|
||||
'To change the audio for a macro, you must upload an audio '.
|
||||
'file.');
|
||||
$e_file = pht('Required');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ final class PhabricatorMacroEditEngine
|
|||
return 'PhabricatorMacroApplication';
|
||||
}
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
$viewer = $this->getViewer();
|
||||
return PhabricatorFileImageMacro::initializeNewFileImageMacro($viewer);
|
||||
|
@ -35,7 +39,7 @@ final class PhabricatorMacroEditEngine
|
|||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit %s', $object->getName());
|
||||
return pht('Edit Macro %s', $object->getName());
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
|
@ -63,6 +67,19 @@ final class PhabricatorMacroEditEngine
|
|||
PhabricatorMacroManageCapability::CAPABILITY);
|
||||
}
|
||||
|
||||
protected function willConfigureFields($object, array $fields) {
|
||||
if ($this->getIsCreate()) {
|
||||
$subscribers_field = idx($fields,
|
||||
PhabricatorSubscriptionsEditEngineExtension::FIELDKEY);
|
||||
if ($subscribers_field) {
|
||||
// By default, hide the subscribers field when creating a macro
|
||||
// because it makes the workflow SO HARD and wastes SO MUCH TIME.
|
||||
$subscribers_field->setIsHidden(true);
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
|
||||
return array(
|
||||
|
@ -70,9 +87,10 @@ final class PhabricatorMacroEditEngine
|
|||
->setKey('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setDescription(pht('Macro name.'))
|
||||
->setConduitDescription(pht('Rename the macro.'))
|
||||
->setConduitDescription(pht('Name of the macro.'))
|
||||
->setConduitTypeDescription(pht('New macro name.'))
|
||||
->setTransactionType(PhabricatorMacroNameTransaction::TRANSACTIONTYPE)
|
||||
->setIsRequired(true)
|
||||
->setValue($object->getName()),
|
||||
id(new PhabricatorFileEditField())
|
||||
->setKey('filePHID')
|
||||
|
@ -80,7 +98,8 @@ final class PhabricatorMacroEditEngine
|
|||
->setDescription(pht('Image file to import.'))
|
||||
->setTransactionType(PhabricatorMacroFileTransaction::TRANSACTIONTYPE)
|
||||
->setConduitDescription(pht('File PHID to import.'))
|
||||
->setConduitTypeDescription(pht('File PHID.')),
|
||||
->setConduitTypeDescription(pht('File PHID.'))
|
||||
->setValue($object->getFilePHID()),
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ final class PhabricatorMacroFileTransaction
|
|||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s changed the image for macro %s.',
|
||||
'%s changed the image for %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
@ -58,29 +58,37 @@ final class PhabricatorMacroFileTransaction
|
|||
$errors = array();
|
||||
$viewer = $this->getActor();
|
||||
|
||||
$old_phid = $object->getFilePHID();
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
$file_phid = $xaction->getNewValue();
|
||||
|
||||
if ($this->isEmptyTextTransaction($file_phid, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('Image macros must have a file.'));
|
||||
if (!$old_phid) {
|
||||
if ($this->isEmptyTextTransaction($file_phid, $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('Image macros must have a file.'));
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
|
||||
$file = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($file_phid))
|
||||
->executeOne();
|
||||
// Only validate if file was uploaded
|
||||
if ($file_phid) {
|
||||
$file = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($file_phid))
|
||||
->executeOne();
|
||||
|
||||
if (!$file) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht('"%s" is not a valid file PHID.',
|
||||
$file_phid));
|
||||
} else {
|
||||
if (!$file->isViewableInBrowser()) {
|
||||
$mime_type = $file->getMimeType();
|
||||
if (!$file) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht('File mime type of "%s" is not a valid viewable image.',
|
||||
$mime_type));
|
||||
pht('"%s" is not a valid file PHID.',
|
||||
$file_phid));
|
||||
} else {
|
||||
if (!$file->isViewableImage()) {
|
||||
$mime_type = $file->getMimeType();
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht('File mime type of "%s" is not a valid viewable image.',
|
||||
$mime_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ final class PhabricatorMacroNameTransaction
|
|||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s renamed %s macro %s to %s.',
|
||||
'%s renamed %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderOldValue(),
|
||||
|
@ -37,6 +37,7 @@ final class PhabricatorMacroNameTransaction
|
|||
if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
|
||||
$errors[] = $this->newRequiredError(
|
||||
pht('Macros must have a name.'));
|
||||
return $errors;
|
||||
}
|
||||
|
||||
$max_length = $object->getColumnMaximumByteLength('name');
|
||||
|
|
|
@ -32,7 +32,6 @@ final class PhabricatorApplicationEditController
|
|||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$result = array();
|
||||
$template = $application->getApplicationTransactionTemplate();
|
||||
foreach ($application->getCapabilities() as $capability) {
|
||||
if (!$application->isCapabilityEditable($capability)) {
|
||||
|
@ -47,8 +46,6 @@ final class PhabricatorApplicationEditController
|
|||
continue;
|
||||
}
|
||||
|
||||
$result[$capability] = $new;
|
||||
|
||||
$xactions[] = id(clone $template)
|
||||
->setTransactionType(
|
||||
PhabricatorApplicationPolicyChangeTransaction::TRANSACTIONTYPE)
|
||||
|
@ -58,25 +55,23 @@ final class PhabricatorApplicationEditController
|
|||
->setNewValue($new);
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$editor = id(new PhabricatorApplicationEditor())
|
||||
->setActor($user)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
$editor = id(new PhabricatorApplicationEditor())
|
||||
->setActor($user)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
try {
|
||||
$editor->applyTransactions($application, $xactions);
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle('Validation Failed')
|
||||
->setValidationException($validation_exception)
|
||||
->addCancelButton($view_uri);
|
||||
try {
|
||||
$editor->applyTransactions($application, $xactions);
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Validation Failed'))
|
||||
->setValidationException($validation_exception)
|
||||
->addCancelButton($view_uri);
|
||||
}
|
||||
|
||||
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
|
||||
|
|
|
@ -244,8 +244,8 @@ final class PassphraseCredentialEditController extends PassphraseController {
|
|||
->setValue($v_name)
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($viewer)
|
||||
->setName('description')
|
||||
->setLabel(pht('Description'))
|
||||
->setValue($v_desc))
|
||||
|
|
|
@ -17,17 +17,9 @@ final class PassphraseCredentialSecretIDTransaction
|
|||
$object->setSecretID($value);
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
if (!$this->getOldValue()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old = $this->getOldValue();
|
||||
if ($old === null) {
|
||||
if (!$old) {
|
||||
return pht(
|
||||
'%s attached a new secret to this credential.',
|
||||
$this->renderAuthor());
|
||||
|
@ -53,4 +45,8 @@ final class PassphraseCredentialSecretIDTransaction
|
|||
}
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-key';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ final class PhameBlogEditEngine
|
|||
->setConduitDescription(pht('Retitle the blog.'))
|
||||
->setConduitTypeDescription(pht('New blog title.'))
|
||||
->setTransactionType(PhameBlogNameTransaction::TRANSACTIONTYPE)
|
||||
->setIsRequired(true)
|
||||
->setValue($object->getName()),
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('subtitle')
|
||||
|
|
|
@ -98,6 +98,7 @@ final class PhamePostEditEngine
|
|||
->setConduitDescription(pht('Retitle the post.'))
|
||||
->setConduitTypeDescription(pht('New post title.'))
|
||||
->setTransactionType(PhamePostTitleTransaction::TRANSACTIONTYPE)
|
||||
->setIsRequired(true)
|
||||
->setValue($object->getTitle()),
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('subtitle')
|
||||
|
|
|
@ -88,7 +88,7 @@ final class PhamePostEditor
|
|||
} else {
|
||||
foreach ($xactions as $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhamePostTransaction::TYPE_VISIBILITY:
|
||||
case PhamePostVisibilityTransaction::TRANSACTIONTYPE:
|
||||
if (!$object->isDraft() && !$object->isArchived()) {
|
||||
$body->addRemarkupSection(null, $object->getBody());
|
||||
}
|
||||
|
|
|
@ -26,14 +26,14 @@ final class PhameBlogTransaction
|
|||
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
||||
$tags[] = self::MAILTAG_SUBSCRIBERS;
|
||||
break;
|
||||
case self::TYPE_NAME:
|
||||
case self::TYPE_SUBTITLE:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_FULLDOMAIN:
|
||||
case self::TYPE_PARENTSITE:
|
||||
case self::TYPE_PARENTDOMAIN:
|
||||
case self::TYPE_PROFILEIMAGE:
|
||||
case self::TYPE_HEADERIMAGE:
|
||||
case PhameBlogNameTransaction::TRANSACTIONTYPE:
|
||||
case PhameBlogSubtitleTransaction::TRANSACTIONTYPE:
|
||||
case PhameBlogDescriptionTransaction::TRANSACTIONTYPE:
|
||||
case PhameBlogFullDomainTransaction::TRANSACTIONTYPE:
|
||||
case PhameBlogParentSiteTransaction::TRANSACTIONTYPE:
|
||||
case PhameBlogParentDomainTransaction::TRANSACTIONTYPE:
|
||||
case PhameBlogProfileImageTransaction::TRANSACTIONTYPE:
|
||||
case PhameBlogHeaderImageTransaction::TRANSACTIONTYPE:
|
||||
$tags[] = self::MAILTAG_DETAILS;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -34,9 +34,9 @@ final class PhamePostTransaction
|
|||
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
||||
$tags[] = self::MAILTAG_SUBSCRIBERS;
|
||||
break;
|
||||
case self::TYPE_TITLE:
|
||||
case self::TYPE_SUBTITLE:
|
||||
case self::TYPE_BODY:
|
||||
case PhamePostTitleTransaction::TRANSACTIONTYPE:
|
||||
case PhamePostSubtitleTransaction::TRANSACTIONTYPE:
|
||||
case PhamePostBodyTransaction::TRANSACTIONTYPE:
|
||||
$tags[] = self::MAILTAG_CONTENT;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -32,7 +32,7 @@ final class PholioMockArchiveController
|
|||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PholioTransaction())
|
||||
->setTransactionType(PholioTransaction::TYPE_STATUS)
|
||||
->setTransactionType(PholioMockStatusTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_status);
|
||||
|
||||
id(new PholioMockEditor())
|
||||
|
|
|
@ -65,8 +65,8 @@ final class PholioMockEditController extends PholioController {
|
|||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$type_name = PholioTransaction::TYPE_NAME;
|
||||
$type_desc = PholioTransaction::TYPE_DESCRIPTION;
|
||||
$type_name = PholioMockNameTransaction::TRANSACTIONTYPE;
|
||||
$type_desc = PholioMockDescriptionTransaction::TRANSACTIONTYPE;
|
||||
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
$type_cc = PhabricatorTransactions::TYPE_SUBSCRIBERS;
|
||||
|
@ -88,11 +88,6 @@ final class PholioMockEditController extends PholioController {
|
|||
$mock_xactions[$type_cc] = array('=' => $v_cc);
|
||||
$mock_xactions[$type_space] = $v_space;
|
||||
|
||||
if (!strlen($request->getStr('name'))) {
|
||||
$e_name = pht('Required');
|
||||
$errors[] = pht('You must give the mock a name.');
|
||||
}
|
||||
|
||||
$file_phids = $request->getArr('file_phids');
|
||||
if ($file_phids) {
|
||||
$files = id(new PhabricatorFileQuery())
|
||||
|
@ -173,12 +168,12 @@ final class PholioMockEditController extends PholioController {
|
|||
$posted_mock_images[] = $add_image;
|
||||
} else {
|
||||
$xactions[] = id(new PholioTransaction())
|
||||
->setTransactionType(PholioTransaction::TYPE_IMAGE_NAME)
|
||||
->setTransactionType(PholioImageNameTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(
|
||||
array($existing_image->getPHID() => $title));
|
||||
$xactions[] = id(new PholioTransaction())
|
||||
->setTransactionType(
|
||||
PholioTransaction::TYPE_IMAGE_DESCRIPTION)
|
||||
PholioImageDescriptionTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(
|
||||
array($existing_image->getPHID() => $description));
|
||||
$xactions[] = id(new PholioTransaction())
|
||||
|
|
|
@ -29,14 +29,9 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
|
|||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
$types[] = PholioTransaction::TYPE_NAME;
|
||||
$types[] = PholioTransaction::TYPE_DESCRIPTION;
|
||||
$types[] = PholioTransaction::TYPE_STATUS;
|
||||
$types[] = PholioTransaction::TYPE_INLINE;
|
||||
|
||||
$types[] = PholioTransaction::TYPE_IMAGE_FILE;
|
||||
$types[] = PholioTransaction::TYPE_IMAGE_NAME;
|
||||
$types[] = PholioTransaction::TYPE_IMAGE_DESCRIPTION;
|
||||
$types[] = PholioTransaction::TYPE_IMAGE_REPLACE;
|
||||
$types[] = PholioTransaction::TYPE_IMAGE_SEQUENCE;
|
||||
|
||||
|
@ -48,33 +43,9 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
|
|||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PholioTransaction::TYPE_NAME:
|
||||
return $object->getName();
|
||||
case PholioTransaction::TYPE_DESCRIPTION:
|
||||
return $object->getDescription();
|
||||
case PholioTransaction::TYPE_STATUS:
|
||||
return $object->getStatus();
|
||||
case PholioTransaction::TYPE_IMAGE_FILE:
|
||||
$images = $object->getImages();
|
||||
return mpull($images, 'getPHID');
|
||||
case PholioTransaction::TYPE_IMAGE_NAME:
|
||||
$name = null;
|
||||
$phid = null;
|
||||
$image = $this->getImageForXaction($object, $xaction);
|
||||
if ($image) {
|
||||
$name = $image->getName();
|
||||
$phid = $image->getPHID();
|
||||
}
|
||||
return array($phid => $name);
|
||||
case PholioTransaction::TYPE_IMAGE_DESCRIPTION:
|
||||
$description = null;
|
||||
$phid = null;
|
||||
$image = $this->getImageForXaction($object, $xaction);
|
||||
if ($image) {
|
||||
$description = $image->getDescription();
|
||||
$phid = $image->getPHID();
|
||||
}
|
||||
return array($phid => $description);
|
||||
case PholioTransaction::TYPE_IMAGE_REPLACE:
|
||||
$raw = $xaction->getNewValue();
|
||||
return $raw->getReplacesImagePHID();
|
||||
|
@ -95,11 +66,6 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
|
|||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PholioTransaction::TYPE_NAME:
|
||||
case PholioTransaction::TYPE_DESCRIPTION:
|
||||
case PholioTransaction::TYPE_STATUS:
|
||||
case PholioTransaction::TYPE_IMAGE_NAME:
|
||||
case PholioTransaction::TYPE_IMAGE_DESCRIPTION:
|
||||
case PholioTransaction::TYPE_IMAGE_SEQUENCE:
|
||||
return $xaction->getNewValue();
|
||||
case PholioTransaction::TYPE_IMAGE_REPLACE:
|
||||
|
@ -204,26 +170,6 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
|
|||
$this->setNewImages($new_images);
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PholioTransaction::TYPE_NAME:
|
||||
$object->setName($xaction->getNewValue());
|
||||
if ($object->getOriginalName() === null) {
|
||||
$object->setOriginalName($xaction->getNewValue());
|
||||
}
|
||||
break;
|
||||
case PholioTransaction::TYPE_DESCRIPTION:
|
||||
$object->setDescription($xaction->getNewValue());
|
||||
break;
|
||||
case PholioTransaction::TYPE_STATUS:
|
||||
$object->setStatus($xaction->getNewValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function getImageForXaction(
|
||||
PholioMock $mock,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
@ -270,18 +216,6 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
|
|||
}
|
||||
$object->attachImages($images);
|
||||
break;
|
||||
case PholioTransaction::TYPE_IMAGE_NAME:
|
||||
$image = $this->getImageForXaction($object, $xaction);
|
||||
$value = (string)head($xaction->getNewValue());
|
||||
$image->setName($value);
|
||||
$image->save();
|
||||
break;
|
||||
case PholioTransaction::TYPE_IMAGE_DESCRIPTION:
|
||||
$image = $this->getImageForXaction($object, $xaction);
|
||||
$value = (string)head($xaction->getNewValue());
|
||||
$image->setDescription($value);
|
||||
$image->save();
|
||||
break;
|
||||
case PholioTransaction::TYPE_IMAGE_SEQUENCE:
|
||||
$image = $this->getImageForXaction($object, $xaction);
|
||||
$value = (int)head($xaction->getNewValue());
|
||||
|
@ -310,10 +244,6 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
|
|||
|
||||
$type = $u->getTransactionType();
|
||||
switch ($type) {
|
||||
case PholioTransaction::TYPE_NAME:
|
||||
case PholioTransaction::TYPE_DESCRIPTION:
|
||||
case PholioTransaction::TYPE_STATUS:
|
||||
return $v;
|
||||
case PholioTransaction::TYPE_IMAGE_REPLACE:
|
||||
$u_img = $u->getNewValue();
|
||||
$v_img = $v->getNewValue();
|
||||
|
@ -323,8 +253,6 @@ final class PholioMockEditor extends PhabricatorApplicationTransactionEditor {
|
|||
break;
|
||||
case PholioTransaction::TYPE_IMAGE_FILE:
|
||||
return $this->mergePHIDOrEdgeTransactions($u, $v);
|
||||
case PholioTransaction::TYPE_IMAGE_NAME:
|
||||
case PholioTransaction::TYPE_IMAGE_DESCRIPTION:
|
||||
case PholioTransaction::TYPE_IMAGE_SEQUENCE:
|
||||
$raw_new_value_u = $u->getNewValue();
|
||||
$raw_new_value_v = $v->getNewValue();
|
||||
|
|
|
@ -22,9 +22,9 @@ final class PhabricatorPholioMockTestDataGenerator
|
|||
|
||||
// Accumulate Transactions
|
||||
$changes = array();
|
||||
$changes[PholioTransaction::TYPE_NAME] =
|
||||
$changes[PholioMockNameTransaction::TRANSACTIONTYPE] =
|
||||
$this->generateTitle();
|
||||
$changes[PholioTransaction::TYPE_DESCRIPTION] =
|
||||
$changes[PholioMockDescriptionTransaction::TRANSACTIONTYPE] =
|
||||
$this->generateDescription();
|
||||
$changes[PhabricatorTransactions::TYPE_VIEW_POLICY] =
|
||||
PhabricatorPolicies::POLICY_PUBLIC;
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
<?php
|
||||
|
||||
final class PholioTransaction extends PhabricatorApplicationTransaction {
|
||||
|
||||
// Edits to the high level mock
|
||||
const TYPE_NAME = 'name';
|
||||
const TYPE_DESCRIPTION = 'description';
|
||||
const TYPE_STATUS = 'status';
|
||||
final class PholioTransaction extends PhabricatorModularTransaction {
|
||||
|
||||
// Edits to images within the mock
|
||||
const TYPE_IMAGE_FILE = 'image-file';
|
||||
const TYPE_IMAGE_NAME= 'image-name';
|
||||
const TYPE_IMAGE_DESCRIPTION = 'image-description';
|
||||
const TYPE_IMAGE_REPLACE = 'image-replace';
|
||||
const TYPE_IMAGE_SEQUENCE = 'image-sequence';
|
||||
|
||||
|
@ -26,6 +19,10 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
return 'pholio';
|
||||
}
|
||||
|
||||
public function getBaseTransactionClass() {
|
||||
return 'PholioTransactionType';
|
||||
}
|
||||
|
||||
public function getApplicationTransactionType() {
|
||||
return PholioMockPHIDType::TYPECONST;
|
||||
}
|
||||
|
@ -53,8 +50,8 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
$phids[] = $new;
|
||||
$phids[] = $old;
|
||||
break;
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
case self::TYPE_IMAGE_NAME:
|
||||
case PholioImageDescriptionTransaction::TRANSACTIONTYPE:
|
||||
case PholioImageNameTransaction::TRANSACTIONTYPE:
|
||||
case self::TYPE_IMAGE_SEQUENCE:
|
||||
$phids[] = key($new);
|
||||
break;
|
||||
|
@ -67,11 +64,6 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
$old = $this->getOldValue();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return ($old === null);
|
||||
case self::TYPE_IMAGE_NAME:
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
return ($old === array(null => null));
|
||||
// this is boring / silly to surface; changing sequence is NBD
|
||||
case self::TYPE_IMAGE_SEQUENCE:
|
||||
return true;
|
||||
|
@ -88,16 +80,6 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_INLINE:
|
||||
return 'fa-comment';
|
||||
case self::TYPE_NAME:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_STATUS:
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return 'fa-ban';
|
||||
} else {
|
||||
return 'fa-check';
|
||||
}
|
||||
case self::TYPE_IMAGE_NAME:
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
case self::TYPE_IMAGE_SEQUENCE:
|
||||
return 'fa-pencil';
|
||||
case self::TYPE_IMAGE_FILE:
|
||||
|
@ -115,13 +97,13 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
$tags[] = self::MAILTAG_COMMENT;
|
||||
break;
|
||||
case self::TYPE_STATUS:
|
||||
case PholioMockStatusTransaction::TRANSACTIONTYPE:
|
||||
$tags[] = self::MAILTAG_STATUS;
|
||||
break;
|
||||
case self::TYPE_NAME:
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_IMAGE_NAME:
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
case PholioMockNameTransaction::TRANSACTIONTYPE:
|
||||
case PholioMockDescriptionTransaction::TRANSACTIONTYPE:
|
||||
case PholioImageNameTransaction::TRANSACTIONTYPE:
|
||||
case PholioImageDescriptionTransaction::TRANSACTIONTYPE:
|
||||
case self::TYPE_IMAGE_SEQUENCE:
|
||||
case self::TYPE_IMAGE_FILE:
|
||||
case self::TYPE_IMAGE_REPLACE:
|
||||
|
@ -142,36 +124,6 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
|
||||
$type = $this->getTransactionType();
|
||||
switch ($type) {
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed this mock from "%s" to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
break;
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return pht(
|
||||
"%s updated the mock's description.",
|
||||
$this->renderHandleLink($author_phid));
|
||||
break;
|
||||
case self::TYPE_STATUS:
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return pht(
|
||||
'%s closed this mock.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s opened this mock.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_INLINE:
|
||||
$count = 1;
|
||||
foreach ($this->getTransactionGroup() as $xaction) {
|
||||
|
@ -218,21 +170,6 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
$this->renderHandleList($rem));
|
||||
}
|
||||
break;
|
||||
|
||||
case self::TYPE_IMAGE_NAME:
|
||||
return pht(
|
||||
'%s renamed an image (%s) from "%s" to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink(key($new)),
|
||||
reset($old),
|
||||
reset($new));
|
||||
break;
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
return pht(
|
||||
'%s updated an image\'s (%s) description.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink(key($new)));
|
||||
break;
|
||||
case self::TYPE_IMAGE_SEQUENCE:
|
||||
return pht(
|
||||
'%s updated an image\'s (%s) sequence.',
|
||||
|
@ -253,40 +190,6 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
|
||||
$type = $this->getTransactionType();
|
||||
switch ($type) {
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed %s from "%s" to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid),
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
break;
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return pht(
|
||||
'%s updated the description for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_STATUS:
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return pht(
|
||||
'%s closed a mock %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s opened a mock %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_INLINE:
|
||||
return pht(
|
||||
'%s added an inline comment to %s.',
|
||||
|
@ -300,18 +203,6 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_IMAGE_NAME:
|
||||
return pht(
|
||||
'%s updated the image names of %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
return pht(
|
||||
'%s updated image descriptions of %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
break;
|
||||
case self::TYPE_IMAGE_SEQUENCE:
|
||||
return pht(
|
||||
'%s updated image sequence of %s.',
|
||||
|
@ -323,62 +214,11 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
return parent::getTitleForFeed();
|
||||
}
|
||||
|
||||
public function getRemarkupBodyForFeed(PhabricatorFeedStory $story) {
|
||||
$text = null;
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_NAME:
|
||||
if ($this->getOldValue() === null) {
|
||||
$mock = $story->getPrimaryObject();
|
||||
$text = $mock->getDescription();
|
||||
}
|
||||
break;
|
||||
case self::TYPE_INLINE:
|
||||
$text = $this->getComment()->getContent();
|
||||
break;
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
public function hasChangeDetails() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_DESCRIPTION:
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
return true;
|
||||
}
|
||||
return parent::hasChangeDetails();
|
||||
}
|
||||
|
||||
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
if ($this->getTransactionType() ==
|
||||
self::TYPE_IMAGE_DESCRIPTION) {
|
||||
$old = reset($old);
|
||||
$new = reset($new);
|
||||
}
|
||||
|
||||
return $this->renderTextCorpusChangeDetails(
|
||||
$viewer,
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_STATUS:
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return PhabricatorTransactions::COLOR_INDIGO;
|
||||
} else {
|
||||
return PhabricatorTransactions::COLOR_GREEN;
|
||||
}
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return PhabricatorTransactions::COLOR_GREEN;
|
||||
}
|
||||
case self::TYPE_IMAGE_REPLACE:
|
||||
return PhabricatorTransactions::COLOR_YELLOW;
|
||||
case self::TYPE_IMAGE_FILE:
|
||||
|
@ -396,16 +236,4 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
return parent::getColor();
|
||||
}
|
||||
|
||||
public function getNoEffectDescription() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_IMAGE_NAME:
|
||||
return pht('The image title was not updated.');
|
||||
case self::TYPE_IMAGE_DESCRIPTION:
|
||||
return pht('The image description was not updated.');
|
||||
case self::TYPE_IMAGE_SEQUENCE:
|
||||
return pht('The image sequence was not updated.');
|
||||
}
|
||||
|
||||
return parent::getNoEffectDescription();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
final class PholioImageDescriptionTransaction
|
||||
extends PholioImageTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'image-description';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
$description = null;
|
||||
$phid = null;
|
||||
$image = $this->getImageForXaction($object);
|
||||
if ($image) {
|
||||
$description = $image->getDescription();
|
||||
$phid = $image->getPHID();
|
||||
}
|
||||
return array($phid => $description);
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$image = $this->getImageForXaction($object);
|
||||
$value = (string)head($this->getNewValue());
|
||||
$image->setDescription($value);
|
||||
$image->save();
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$new = $this->getNewValue();
|
||||
|
||||
return pht(
|
||||
'%s updated an image\'s (%s) description.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderHandle(head_key($new)));
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s updated image descriptions of %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
public function mergeTransactions(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $u,
|
||||
PhabricatorApplicationTransaction $v) {
|
||||
|
||||
$raw_new_value_u = $u->getNewValue();
|
||||
$raw_new_value_v = $v->getNewValue();
|
||||
$phid_u = head_key($raw_new_value_u);
|
||||
$phid_v = head_key($raw_new_value_v);
|
||||
if ($phid_u == $phid_v) {
|
||||
return $v;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
return ($old === array(null => null));
|
||||
}
|
||||
|
||||
public function hasChangeDetailView() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function newChangeDetailView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||
->setViewer($viewer)
|
||||
->setOldText(head($this->getOldValue()))
|
||||
->setNewText(head($this->getNewValue()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
final class PholioImageNameTransaction
|
||||
extends PholioImageTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'image-name';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
$name = null;
|
||||
$phid = null;
|
||||
$image = $this->getImageForXaction($object);
|
||||
if ($image) {
|
||||
$name = $image->getName();
|
||||
$phid = $image->getPHID();
|
||||
}
|
||||
return array($phid => $name);
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$image = $this->getImageForXaction($object);
|
||||
$value = (string)head($this->getNewValue());
|
||||
$image->setName($value);
|
||||
$image->save();
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
return pht(
|
||||
'%s renamed an image (%s) from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderHandle(key($new)),
|
||||
$this->renderValue($old),
|
||||
$this->renderValue($new));
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s updated the image names of %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
public function mergeTransactions(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $u,
|
||||
PhabricatorApplicationTransaction $v) {
|
||||
|
||||
$raw_new_value_u = $u->getNewValue();
|
||||
$raw_new_value_v = $v->getNewValue();
|
||||
$phid_u = head_key($raw_new_value_u);
|
||||
$phid_v = head_key($raw_new_value_v);
|
||||
if ($phid_u == $phid_v) {
|
||||
return $v;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
return ($old === array(null => null));
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
$max_length = $object->getColumnMaximumByteLength('name');
|
||||
foreach ($xactions as $xaction) {
|
||||
$new_value = head(array_values($xaction->getNewValue()));
|
||||
$new_length = strlen($new_value);
|
||||
if ($new_length > $max_length) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'Mock image names must not be longer than %s character(s).',
|
||||
new PhutilNumber($max_length)));
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
abstract class PholioImageTransactionType
|
||||
extends PholioTransactionType {
|
||||
|
||||
protected function getImageForXaction(PholioMock $mock) {
|
||||
$raw_new_value = $this->getNewValue();
|
||||
$image_phid = head_key($raw_new_value);
|
||||
$images = $mock->getImages();
|
||||
foreach ($images as $image) {
|
||||
if ($image->getPHID() == $image_phid) {
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
final class PholioMockDescriptionTransaction
|
||||
extends PholioMockTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'description';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getDescription();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setDescription($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
"%s updated the mock's description.",
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s updated the description for %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
return ($old === null);
|
||||
}
|
||||
|
||||
public function hasChangeDetailView() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function newChangeDetailView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||
->setViewer($viewer)
|
||||
->setOldText($this->getOldValue())
|
||||
->setNewText($this->getNewValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
final class PholioMockNameTransaction
|
||||
extends PholioMockTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'name';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getName();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setName($value);
|
||||
if ($object->getOriginalName() === null) {
|
||||
$object->setOriginalName($this->getNewValue());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderValue($new));
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed this mock from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderValue($old),
|
||||
$this->renderValue($new));
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed %s from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject(),
|
||||
$this->renderValue($old),
|
||||
$this->renderValue($new));
|
||||
}
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
$old = $this->getOldValue();
|
||||
|
||||
if ($old === null) {
|
||||
return PhabricatorTransactions::COLOR_GREEN;
|
||||
}
|
||||
|
||||
return parent::getColor();
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
|
||||
$errors[] = $this->newRequiredError(pht('Mocks must have a name.'));
|
||||
}
|
||||
|
||||
$max_length = $object->getColumnMaximumByteLength('name');
|
||||
foreach ($xactions as $xaction) {
|
||||
$new_value = $xaction->getNewValue();
|
||||
$new_length = strlen($new_value);
|
||||
if ($new_length > $max_length) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht(
|
||||
'Mock names must not be longer than %s character(s).',
|
||||
new PhutilNumber($max_length)));
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
final class PholioMockStatusTransaction
|
||||
extends PholioMockTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'status';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getStatus();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setStatus($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return pht(
|
||||
'%s closed this mock.',
|
||||
$this->renderAuthor());
|
||||
} else {
|
||||
return pht(
|
||||
'%s opened this mock.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return pht(
|
||||
'%s closed mock %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
} else {
|
||||
return pht(
|
||||
'%s opened mock %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return 'fa-ban';
|
||||
} else {
|
||||
return 'fa-check';
|
||||
}
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if ($new == PholioMock::STATUS_CLOSED) {
|
||||
return PhabricatorTransactions::COLOR_INDIGO;
|
||||
} else {
|
||||
return PhabricatorTransactions::COLOR_GREEN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class PholioMockTransactionType
|
||||
extends PholioTransactionType {}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class PholioTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
|
@ -65,6 +65,11 @@ final class PhortuneMerchantEditEngine
|
|||
return false;
|
||||
}
|
||||
|
||||
protected function getCreateNewObjectPolicy() {
|
||||
return $this->getApplication()->getPolicy(
|
||||
PhortuneMerchantCapability::CAPABILITY);
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ final class PonderAnswerEditor extends PonderEditor {
|
|||
foreach ($xactions as $xaction) {
|
||||
$type = $xaction->getTransactionType();
|
||||
$new = $xaction->getNewValue();
|
||||
if ($type == PonderAnswerTransaction::TYPE_CONTENT) {
|
||||
if ($type == PonderAnswerContentTransaction::TRANSACTIONTYPE) {
|
||||
$body->addRawSection($new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ final class PhabricatorProjectBoardBackgroundController
|
|||
$this->setProject($board);
|
||||
$id = $board->getID();
|
||||
|
||||
$view_uri = $this->getApplicationURI("board/{$id}/");
|
||||
$manage_uri = $this->getApplicationURI("board/{$id}/manage/");
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
|
@ -47,7 +48,7 @@ final class PhabricatorProjectBoardBackgroundController
|
|||
->applyTransactions($board, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($manage_uri);
|
||||
->setURI($view_uri);
|
||||
}
|
||||
|
||||
$nav = $this->getProfileMenu();
|
||||
|
|
|
@ -31,112 +31,58 @@ final class PhabricatorProjectBoardManageController
|
|||
$board_id = $board->getID();
|
||||
|
||||
$header = $this->buildHeaderView($board);
|
||||
$actions = $this->buildActionView($board);
|
||||
$properties = $this->buildPropertyView($board);
|
||||
|
||||
$properties->setActionList($actions);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Workboard'), "/project/board/{$board_id}/");
|
||||
$crumbs->addTextCrumb(pht('Manage'));
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->addPropertyList($properties);
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$nav = $this->getProfileMenu();
|
||||
$columns_list = $this->buildColumnsList($board, $columns);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter($columns_list);
|
||||
|
||||
$title = array(
|
||||
pht('Manage Workboard'),
|
||||
$board->getDisplayName(),
|
||||
);
|
||||
|
||||
$columns_list = $this->buildColumnsList($board, $columns);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setNavigation($nav)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild(
|
||||
array(
|
||||
$box,
|
||||
$columns_list,
|
||||
));
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildHeaderView(PhabricatorProject $board) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setUser($viewer)
|
||||
->setHeader(pht('Workboard: %s', $board->getDisplayName()));
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
private function buildActionView(PhabricatorProject $board) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
$id = $board->getID();
|
||||
|
||||
$actions = id(new PhabricatorActionListView())
|
||||
->setUser($viewer);
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$board,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$reorder_uri = $this->getApplicationURI("board/{$id}/reorder/");
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-exchange')
|
||||
->setName(pht('Reorder Columns'))
|
||||
->setHref($reorder_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
$background_uri = $this->getApplicationURI("board/{$id}/background/");
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-paint-brush')
|
||||
->setName(pht('Change Background Color'))
|
||||
->setHref($background_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$id = $board->getID();
|
||||
$disable_uri = $this->getApplicationURI("board/{$id}/disable/");
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-ban')
|
||||
->setName(pht('Disable Board'))
|
||||
->setHref($disable_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-ban')
|
||||
->setText(pht('Disable Board'))
|
||||
->setHref($disable_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
private function buildPropertyView(
|
||||
PhabricatorProject $board) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Workboard: %s', $board->getDisplayName()))
|
||||
->setUser($viewer)
|
||||
->setObject($board);
|
||||
->setPolicyObject($board)
|
||||
->setProfileHeader(true)
|
||||
->addActionLink($button);
|
||||
|
||||
$background = $board->getDisplayWorkboardBackgroundColor();
|
||||
if ($background !== null) {
|
||||
$map = PhabricatorProjectWorkboardBackgroundColor::getOptions();
|
||||
$map = ipull($map, 'name');
|
||||
|
||||
$name = idx($map, $background, $background);
|
||||
$properties->addProperty(pht('Background Color'), $name);
|
||||
}
|
||||
|
||||
return $properties;
|
||||
return $header;
|
||||
}
|
||||
|
||||
private function buildColumnsList(
|
||||
|
@ -165,6 +111,11 @@ final class PhabricatorProjectBoardManageController
|
|||
|
||||
if ($column->isHidden()) {
|
||||
$item->setDisabled(true);
|
||||
$item->addAttribute(pht('Hidden'));
|
||||
$item->setImageIcon('fa-columns grey');
|
||||
} else {
|
||||
$item->addAttribute(pht('Visible'));
|
||||
$item->setImageIcon('fa-columns');
|
||||
}
|
||||
|
||||
$view->addItem($item);
|
||||
|
|
|
@ -23,13 +23,13 @@ final class PhabricatorProjectBoardReorderController
|
|||
$this->setProject($project);
|
||||
$project_id = $project->getID();
|
||||
|
||||
$manage_uri = $this->getApplicationURI("board/{$project_id}/manage/");
|
||||
$view_uri = $this->getApplicationURI("board/{$project_id}/");
|
||||
$reorder_uri = $this->getApplicationURI("board/{$project_id}/reorder/");
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
// User clicked "Done", make sure the page reloads to show the new
|
||||
// column order.
|
||||
return id(new AphrontRedirectResponse())->setURI($manage_uri);
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
}
|
||||
|
||||
$columns = id(new PhabricatorProjectColumnQuery())
|
||||
|
|
|
@ -705,10 +705,21 @@ final class PhabricatorProjectBoardViewController
|
|||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
|
||||
$reorder_uri = $this->getApplicationURI("board/{$id}/reorder/");
|
||||
$manage_items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Manage Board'))
|
||||
->setHref($manage_uri);
|
||||
->setIcon('fa-exchange')
|
||||
->setName(pht('Reorder Columns'))
|
||||
->setHref($reorder_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
|
||||
$background_uri = $this->getApplicationURI("board/{$id}/background/");
|
||||
$manage_items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-paint-brush')
|
||||
->setName(pht('Change Background Color'))
|
||||
->setHref($background_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(false);
|
||||
|
||||
if ($show_hidden) {
|
||||
$hidden_uri = $this->getURIWithState()
|
||||
|
@ -727,6 +738,12 @@ final class PhabricatorProjectBoardViewController
|
|||
->setName($hidden_text)
|
||||
->setHref($hidden_uri);
|
||||
|
||||
$manage_uri = $this->getApplicationURI("board/{$id}/manage/");
|
||||
$manage_items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-gear')
|
||||
->setName(pht('Manage Workboard'))
|
||||
->setHref($manage_uri);
|
||||
|
||||
$batch_edit_uri = $request->getRequestURI();
|
||||
$batch_edit_uri->setQueryParam('batch', self::BATCH_EDIT_ALL);
|
||||
$can_batch_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
|
@ -734,12 +751,6 @@ final class PhabricatorProjectBoardViewController
|
|||
PhabricatorApplication::getByClass('PhabricatorManiphestApplication'),
|
||||
ManiphestBulkEditCapability::CAPABILITY);
|
||||
|
||||
$manage_items[] = id(new PhabricatorActionView())
|
||||
->setIcon('fa-list-ul')
|
||||
->setName(pht('Batch Edit Visible Tasks...'))
|
||||
->setHref($batch_edit_uri)
|
||||
->setDisabled(!$can_batch_edit);
|
||||
|
||||
$manage_menu = id(new PhabricatorActionListView())
|
||||
->setUser($viewer);
|
||||
foreach ($manage_items as $item) {
|
||||
|
@ -837,6 +848,16 @@ final class PhabricatorProjectBoardViewController
|
|||
->setHref($batch_edit_uri)
|
||||
->setDisabled(!$can_batch_edit);
|
||||
|
||||
// Column Related Actions Below
|
||||
//
|
||||
$edit_uri = 'board/'.$this->id.'/edit/'.$column->getID().'/';
|
||||
$column_items[] = id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Column'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($this->getApplicationURI($edit_uri))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
|
||||
$can_hide = ($can_edit && !$column->isDefaultColumn());
|
||||
$hide_uri = 'board/'.$this->id.'/hide/'.$column->getID().'/';
|
||||
$hide_uri = $this->getApplicationURI($hide_uri);
|
||||
|
@ -858,6 +879,12 @@ final class PhabricatorProjectBoardViewController
|
|||
->setWorkflow(true);
|
||||
}
|
||||
|
||||
$details_uri = 'board/'.$this->id.'/column/'.$column->getID().'/';
|
||||
$column_items[] = id(new PhabricatorActionView())
|
||||
->setName(pht('Column History'))
|
||||
->setIcon('fa-columns')
|
||||
->setHref($this->getApplicationURI($details_uri));
|
||||
|
||||
$column_menu = id(new PhabricatorActionListView())
|
||||
->setUser($viewer);
|
||||
foreach ($column_items as $item) {
|
||||
|
|
|
@ -103,7 +103,7 @@ final class PhabricatorProjectColumnDetailController
|
|||
->setIcon('fa-pencil')
|
||||
->setHref($this->getApplicationURI($base_uri.'edit/'.$id.'/'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
->setWorkflow(true));
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
|
|
@ -51,12 +51,7 @@ final class PhabricatorProjectColumnEditController
|
|||
|
||||
$validation_exception = null;
|
||||
$base_uri = '/board/'.$project_id.'/';
|
||||
if ($is_new) {
|
||||
// we want to go back to the board
|
||||
$view_uri = $this->getApplicationURI($base_uri);
|
||||
} else {
|
||||
$view_uri = $this->getApplicationURI($base_uri.'column/'.$id.'/');
|
||||
}
|
||||
$view_uri = $this->getApplicationURI($base_uri);
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$v_name = $request->getStr('name');
|
||||
|
|
|
@ -21,8 +21,7 @@ final class PhabricatorProjectManageController
|
|||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Project History'))
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($project)
|
||||
->setImage($picture);
|
||||
->setPolicyObject($project);
|
||||
|
||||
if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) {
|
||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||
|
@ -45,10 +44,14 @@ final class PhabricatorProjectManageController
|
|||
$crumbs->addTextCrumb(pht('Manage'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
require_celerity_resource('project-view-css');
|
||||
|
||||
$manage = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->addPropertySection(pht('Details'), $properties)
|
||||
->addClass('project-view-home')
|
||||
->addClass('project-view-people-home')
|
||||
->setMainColumn(
|
||||
array(
|
||||
$timeline,
|
||||
|
|
|
@ -29,7 +29,6 @@ final class PhabricatorProjectProfileController
|
|||
->setHeader(array($project->getDisplayName(), $tag))
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($project)
|
||||
->setImage($picture)
|
||||
->setProfileHeader(true);
|
||||
|
||||
if ($project->getStatus() == PhabricatorProjectStatus::STATUS_ACTIVE) {
|
||||
|
@ -92,6 +91,7 @@ final class PhabricatorProjectProfileController
|
|||
$home = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->addClass('project-view-home')
|
||||
->addClass('project-view-people-home')
|
||||
->setMainColumn(
|
||||
array(
|
||||
$properties,
|
||||
|
|
|
@ -20,6 +20,10 @@ final class PhabricatorProjectProfileMenuEngine
|
|||
protected function getBuiltinProfileItems($object) {
|
||||
$items = array();
|
||||
|
||||
$items[] = $this->newItem()
|
||||
->setBuiltinKey(PhabricatorProject::ITEM_PICTURE)
|
||||
->setMenuItemKey(PhabricatorProjectPictureProfileMenuItem::MENUITEMKEY);
|
||||
|
||||
$items[] = $this->newItem()
|
||||
->setBuiltinKey(PhabricatorProject::ITEM_PROFILE)
|
||||
->setMenuItemKey(PhabricatorProjectDetailsProfileMenuItem::MENUITEMKEY);
|
||||
|
|
|
@ -46,15 +46,15 @@ final class PhabricatorProjectDetailsProfileMenuItem
|
|||
$project = $config->getProfileObject();
|
||||
|
||||
$id = $project->getID();
|
||||
$picture = $project->getProfileImageURI();
|
||||
$name = $project->getName();
|
||||
$icon = $project->getDisplayIconIcon();
|
||||
|
||||
$href = "/project/profile/{$id}/";
|
||||
|
||||
$item = $this->newItem()
|
||||
->setHref($href)
|
||||
->setName($name)
|
||||
->setProfileImage($picture);
|
||||
->setIcon($icon);
|
||||
|
||||
return array(
|
||||
$item,
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectPictureProfileMenuItem
|
||||
extends PhabricatorProfileMenuItem {
|
||||
|
||||
const MENUITEMKEY = 'project.picture';
|
||||
|
||||
public function getMenuItemTypeName() {
|
||||
return pht('Project Picture');
|
||||
}
|
||||
|
||||
private function getDefaultName() {
|
||||
return pht('Project Picture');
|
||||
}
|
||||
|
||||
public function canHideMenuItem(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDisplayName(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return $this->getDefaultName();
|
||||
}
|
||||
|
||||
public function buildEditEngineFields(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function newNavigationMenuItems(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
|
||||
$project = $config->getProfileObject();
|
||||
require_celerity_resource('people-picture-menu-item-css');
|
||||
|
||||
$picture = $project->getProfileImageURI();
|
||||
$href = $project->getProfileURI();
|
||||
|
||||
$classes = array();
|
||||
$classes[] = 'people-menu-image';
|
||||
if ($project->isArchived()) {
|
||||
$classes[] = 'phui-image-disabled';
|
||||
}
|
||||
|
||||
$photo = phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'src' => $picture,
|
||||
'class' => implode(' ', $classes),
|
||||
));
|
||||
|
||||
$view = phutil_tag_div('people-menu-image-container', $photo);
|
||||
$view = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $href,
|
||||
),
|
||||
$view);
|
||||
|
||||
$item = $this->newItem()
|
||||
->appendChild($view);
|
||||
|
||||
return array(
|
||||
$item,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -128,6 +128,10 @@ final class PhabricatorProjectSearchEngine
|
|||
$names['joined'] = pht('Joined');
|
||||
}
|
||||
|
||||
if ($this->requireViewer()->isLoggedIn()) {
|
||||
$names['watching'] = pht('Watching');
|
||||
}
|
||||
|
||||
$names['active'] = pht('Active');
|
||||
$names['all'] = pht('All');
|
||||
|
||||
|
@ -153,6 +157,10 @@ final class PhabricatorProjectSearchEngine
|
|||
return $query
|
||||
->setParameter('memberPHIDs', array($viewer_phid))
|
||||
->setParameter('status', 'active');
|
||||
case 'watching':
|
||||
return $query
|
||||
->setParameter('watcherPHIDs', array($viewer_phid))
|
||||
->setParameter('status', 'active');
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
|
|
|
@ -49,6 +49,7 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
|||
|
||||
const TABLE_DATASOURCE_TOKEN = 'project_datasourcetoken';
|
||||
|
||||
const ITEM_PICTURE = 'project.picture';
|
||||
const ITEM_PROFILE = 'project.profile';
|
||||
const ITEM_POINTS = 'project.points';
|
||||
const ITEM_WORKBOARD = 'project.workboard';
|
||||
|
|
|
@ -68,7 +68,13 @@ final class PhabricatorSlowvoteEditController
|
|||
}
|
||||
|
||||
if ($is_new) {
|
||||
$responses = array_filter($responses);
|
||||
// NOTE: Make sure common and useful response "0" is preserved.
|
||||
foreach ($responses as $key => $response) {
|
||||
if (!strlen($response)) {
|
||||
unset($responses[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($responses)) {
|
||||
$errors[] = pht('You must offer at least one response.');
|
||||
$e_response = pht('Required');
|
||||
|
@ -139,13 +145,14 @@ final class PhabricatorSlowvoteEditController
|
|||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/V'.$poll->getID());
|
||||
->setURI($poll->getURI());
|
||||
} else {
|
||||
$poll->setViewPolicy($v_view_policy);
|
||||
}
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setAction($request->getrequestURI())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
|
|
|
@ -35,9 +35,9 @@ final class PhabricatorSlowvotePollController
|
|||
));
|
||||
}
|
||||
|
||||
$header_icon = $poll->getIsClosed() ? 'fa-ban' : 'fa-circle-o';
|
||||
$header_icon = $poll->getIsClosed() ? 'fa-ban' : 'fa-square-o';
|
||||
$header_name = $poll->getIsClosed() ? pht('Closed') : pht('Open');
|
||||
$header_color = $poll->getIsClosed() ? 'dark' : 'bluegrey';
|
||||
$header_color = $poll->getIsClosed() ? 'indigo' : 'bluegrey';
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($poll->getQuestion())
|
||||
|
@ -89,7 +89,7 @@ final class PhabricatorSlowvotePollController
|
|||
|
||||
$is_closed = $poll->getIsClosed();
|
||||
$close_poll_text = $is_closed ? pht('Reopen Poll') : pht('Close Poll');
|
||||
$close_poll_icon = $is_closed ? 'fa-play-circle-o' : 'fa-ban';
|
||||
$close_poll_icon = $is_closed ? 'fa-check' : 'fa-ban';
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
|
|
|
@ -11,6 +11,14 @@ final class PhabricatorSlowvoteEditor
|
|||
return pht('Slowvote');
|
||||
}
|
||||
|
||||
public function getCreateObjectTitle($author, $object) {
|
||||
return pht('%s created this poll.', $author);
|
||||
}
|
||||
|
||||
public function getCreateObjectTitleForFeed($author, $object) {
|
||||
return pht('%s created %s.', $author, $object);
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
|
|
|
@ -55,6 +55,7 @@ final class PhabricatorSlowvoteSearchEngine
|
|||
|
||||
id(new PhabricatorSearchCheckboxesField())
|
||||
->setKey('statuses')
|
||||
->setLabel(pht('Statuses'))
|
||||
->setOptions(array(
|
||||
'open' => pht('Open'),
|
||||
'closed' => pht('Closed'),
|
||||
|
|
|
@ -112,6 +112,10 @@ final class PhabricatorSlowvotePoll extends PhabricatorSlowvoteDAO
|
|||
return 'V'.$this->getID();
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
}
|
||||
|
||||
public function save() {
|
||||
if (!$this->getMailKey()) {
|
||||
$this->setMailKey(Filesystem::readRandomCharacters(20));
|
||||
|
|
|
@ -36,15 +36,21 @@ final class PhabricatorSlowvoteDescriptionTransaction
|
|||
}
|
||||
}
|
||||
|
||||
public function hasChangeDetails() {
|
||||
public function hasChangeDetailView() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getMailDiffSectionHeader() {
|
||||
return pht('CHANGES TO POLL DESCRIPTION');
|
||||
}
|
||||
|
||||
public function newChangeDetailView() {
|
||||
return $this->renderTextCorpusChangeDetails(
|
||||
$this->getViewer(),
|
||||
$this->getOldValue(),
|
||||
$this->getNewValue());
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||
->setViewer($viewer)
|
||||
->setOldText($this->getOldValue())
|
||||
->setNewText($this->getNewValue());
|
||||
}
|
||||
|
||||
public function newRemarkupChanges() {
|
|
@ -4,6 +4,7 @@ final class PhabricatorSubscriptionsEditEngineExtension
|
|||
extends PhabricatorEditEngineExtension {
|
||||
|
||||
const EXTENSIONKEY = 'subscriptions.subscribers';
|
||||
const FIELDKEY = 'subscriberPHIDs';
|
||||
|
||||
const EDITKEY_ADD = 'subscribers.add';
|
||||
const EDITKEY_SET = 'subscribers.set';
|
||||
|
@ -42,7 +43,7 @@ final class PhabricatorSubscriptionsEditEngineExtension
|
|||
}
|
||||
|
||||
$subscribers_field = id(new PhabricatorSubscribersEditField())
|
||||
->setKey('subscriberPHIDs')
|
||||
->setKey(self::FIELDKEY)
|
||||
->setLabel(pht('Subscribers'))
|
||||
->setEditTypeKey('subscribers')
|
||||
->setAliases(array('subscriber', 'subscribers'))
|
||||
|
|
|
@ -30,15 +30,47 @@ final class PHUIFormFileControl
|
|||
'chunkThreshold' => PhabricatorFileStorageEngine::getChunkThreshold(),
|
||||
));
|
||||
|
||||
return phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'file',
|
||||
'multiple' => $this->getAllowMultiple() ? 'multiple' : null,
|
||||
'name' => $this->getName().'.raw',
|
||||
'id' => $file_id,
|
||||
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||
));
|
||||
|
||||
// If the control has a value, add a hidden input which submits it as a
|
||||
// default. This allows the file control to mean "don't change anything",
|
||||
// instead of "remove the file", if the user submits the form without
|
||||
// touching it.
|
||||
|
||||
// This also allows the input to "hold" the value of an uploaded file if
|
||||
// there is another error in the form: when you submit the form but are
|
||||
// stopped because of an unrelated error, submitting it again will keep
|
||||
// the value around (if you don't upload a new file) instead of requiring
|
||||
// you to pick the file again.
|
||||
|
||||
// TODO: This works alright, but is a bit of a hack, and the UI should
|
||||
// provide the user better feedback about whether the state of the control
|
||||
// is "keep the value the same" or "remove the value", and about whether
|
||||
// or not the control is "holding" a value from a previous submission.
|
||||
|
||||
$default_input = null;
|
||||
$default_value = $this->getValue();
|
||||
if ($default_value !== null) {
|
||||
$default_input = phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'hidden',
|
||||
'name' => $this->getName().'_default',
|
||||
'value' => $default_value,
|
||||
));
|
||||
}
|
||||
|
||||
return array(
|
||||
phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'file',
|
||||
'multiple' => $this->getAllowMultiple() ? 'multiple' : null,
|
||||
'name' => $this->getName().'_raw',
|
||||
'id' => $file_id,
|
||||
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||
)),
|
||||
$default_input,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue