mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-26 05:29:06 +01:00
(stable) Promote 2016 Week 39
This commit is contained in:
commit
27006fedcc
38 changed files with 507 additions and 545 deletions
|
@ -251,20 +251,42 @@ class MimeMailParser {
|
||||||
return $headers;
|
return $headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the attachments contents in order of appearance
|
* Returns the attachments contents in order of appearance
|
||||||
* @return Array
|
* @return Array
|
||||||
* @param $type Object[optional]
|
* @param $type Object[optional]
|
||||||
*/
|
*/
|
||||||
public function getAttachments() {
|
public function getAttachments() {
|
||||||
|
// NOTE: This has been modified for Phabricator. Some mail clients do not
|
||||||
|
// send attachments with "Content-Disposition" headers.
|
||||||
$attachments = array();
|
$attachments = array();
|
||||||
$dispositions = array("attachment","inline");
|
$dispositions = array("attachment","inline");
|
||||||
|
$non_attachment_types = array("text/plain", "text/html");
|
||||||
|
$nonameIter = 0;
|
||||||
foreach ($this->parts as $part) {
|
foreach ($this->parts as $part) {
|
||||||
$disposition = $this->getPartContentDisposition($part);
|
$disposition = $this->getPartContentDisposition($part);
|
||||||
if (in_array($disposition, $dispositions)) {
|
$filename = 'noname';
|
||||||
|
if (isset($part['disposition-filename'])) {
|
||||||
|
$filename = $part['disposition-filename'];
|
||||||
|
} elseif (isset($part['content-name'])) {
|
||||||
|
// if we have no disposition but we have a content-name, it's a valid attachment.
|
||||||
|
// we simulate the presence of an attachment disposition with a disposition filename
|
||||||
|
$filename = $part['content-name'];
|
||||||
|
$disposition = 'attachment';
|
||||||
|
} elseif (!in_array($part['content-type'], $non_attachment_types, true)
|
||||||
|
&& substr($part['content-type'], 0, 10) !== 'multipart/'
|
||||||
|
) {
|
||||||
|
// if we cannot get it with getMessageBody, we assume it is an attachment
|
||||||
|
$disposition = 'attachment';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($disposition, $dispositions) && isset($filename) === true) {
|
||||||
|
if ($filename == 'noname') {
|
||||||
|
$nonameIter++;
|
||||||
|
$filename = 'noname'.$nonameIter;
|
||||||
|
}
|
||||||
$attachments[] = new MimeMailParser_attachment(
|
$attachments[] = new MimeMailParser_attachment(
|
||||||
$part['disposition-filename'],
|
$filename,
|
||||||
$this->getPartContentType($part),
|
$this->getPartContentType($part),
|
||||||
$this->getAttachmentStream($part),
|
$this->getAttachmentStream($part),
|
||||||
$disposition,
|
$disposition,
|
||||||
|
|
|
@ -9,7 +9,7 @@ return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'conpherence.pkg.css' => '80a3fcb3',
|
'conpherence.pkg.css' => '80a3fcb3',
|
||||||
'conpherence.pkg.js' => '89b4837e',
|
'conpherence.pkg.js' => '89b4837e',
|
||||||
'core.pkg.css' => '476e9330',
|
'core.pkg.css' => 'f7b03076',
|
||||||
'core.pkg.js' => '1d376fa9',
|
'core.pkg.js' => '1d376fa9',
|
||||||
'darkconsole.pkg.js' => 'e7393ebb',
|
'darkconsole.pkg.js' => 'e7393ebb',
|
||||||
'differential.pkg.css' => '3fb7f532',
|
'differential.pkg.css' => '3fb7f532',
|
||||||
|
@ -27,7 +27,7 @@ return array(
|
||||||
'rsrc/css/aphront/notification.css' => '3f6c89c9',
|
'rsrc/css/aphront/notification.css' => '3f6c89c9',
|
||||||
'rsrc/css/aphront/panel-view.css' => '8427b78d',
|
'rsrc/css/aphront/panel-view.css' => '8427b78d',
|
||||||
'rsrc/css/aphront/phabricator-nav-view.css' => 'b29426e9',
|
'rsrc/css/aphront/phabricator-nav-view.css' => 'b29426e9',
|
||||||
'rsrc/css/aphront/table-view.css' => '832656fd',
|
'rsrc/css/aphront/table-view.css' => '3225137a',
|
||||||
'rsrc/css/aphront/tokenizer.css' => '056da01b',
|
'rsrc/css/aphront/tokenizer.css' => '056da01b',
|
||||||
'rsrc/css/aphront/tooltip.css' => '1a07aea8',
|
'rsrc/css/aphront/tooltip.css' => '1a07aea8',
|
||||||
'rsrc/css/aphront/typeahead-browse.css' => '8904346a',
|
'rsrc/css/aphront/typeahead-browse.css' => '8904346a',
|
||||||
|
@ -38,7 +38,7 @@ return array(
|
||||||
'rsrc/css/application/base/notification-menu.css' => 'b3ab500d',
|
'rsrc/css/application/base/notification-menu.css' => 'b3ab500d',
|
||||||
'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601',
|
'rsrc/css/application/base/phabricator-application-launch-view.css' => '95351601',
|
||||||
'rsrc/css/application/base/phui-theme.css' => '027ba77e',
|
'rsrc/css/application/base/phui-theme.css' => '027ba77e',
|
||||||
'rsrc/css/application/base/standard-page-view.css' => '2b592894',
|
'rsrc/css/application/base/standard-page-view.css' => '3026770e',
|
||||||
'rsrc/css/application/chatlog/chatlog.css' => 'd295b020',
|
'rsrc/css/application/chatlog/chatlog.css' => 'd295b020',
|
||||||
'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4',
|
'rsrc/css/application/conduit/conduit-api.css' => '7bc725c4',
|
||||||
'rsrc/css/application/config/config-options.css' => '0ede4c9b',
|
'rsrc/css/application/config/config-options.css' => '0ede4c9b',
|
||||||
|
@ -607,7 +607,7 @@ return array(
|
||||||
'aphront-list-filter-view-css' => '5d6f0526',
|
'aphront-list-filter-view-css' => '5d6f0526',
|
||||||
'aphront-multi-column-view-css' => 'fd18389d',
|
'aphront-multi-column-view-css' => 'fd18389d',
|
||||||
'aphront-panel-view-css' => '8427b78d',
|
'aphront-panel-view-css' => '8427b78d',
|
||||||
'aphront-table-view-css' => '832656fd',
|
'aphront-table-view-css' => '3225137a',
|
||||||
'aphront-tokenizer-control-css' => '056da01b',
|
'aphront-tokenizer-control-css' => '056da01b',
|
||||||
'aphront-tooltip-css' => '1a07aea8',
|
'aphront-tooltip-css' => '1a07aea8',
|
||||||
'aphront-typeahead-control-css' => 'd4f16145',
|
'aphront-typeahead-control-css' => 'd4f16145',
|
||||||
|
@ -869,7 +869,7 @@ return array(
|
||||||
'phabricator-shaped-request' => '7cbe244b',
|
'phabricator-shaped-request' => '7cbe244b',
|
||||||
'phabricator-slowvote-css' => 'a94b7230',
|
'phabricator-slowvote-css' => 'a94b7230',
|
||||||
'phabricator-source-code-view-css' => 'cbeef983',
|
'phabricator-source-code-view-css' => 'cbeef983',
|
||||||
'phabricator-standard-page-view' => '2b592894',
|
'phabricator-standard-page-view' => '3026770e',
|
||||||
'phabricator-textareautils' => '320810c8',
|
'phabricator-textareautils' => '320810c8',
|
||||||
'phabricator-title' => 'df5e11d2',
|
'phabricator-title' => 'df5e11d2',
|
||||||
'phabricator-tooltip' => '6323f942',
|
'phabricator-tooltip' => '6323f942',
|
||||||
|
|
14
resources/sql/autopatches/20160921.fileexternalrequest.sql
Normal file
14
resources/sql/autopatches/20160921.fileexternalrequest.sql
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_file.file_externalrequest (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
filePHID VARBINARY(64),
|
||||||
|
ttl INT UNSIGNED NOT NULL,
|
||||||
|
uri LONGTEXT NOT NULL,
|
||||||
|
uriIndex BINARY(12) NOT NULL,
|
||||||
|
isSuccessful BOOL NOT NULL,
|
||||||
|
responseMessage LONGTEXT,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_uriindex` (uriIndex),
|
||||||
|
KEY `key_ttl` (ttl),
|
||||||
|
KEY `key_file` (filePHID)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -2553,10 +2553,13 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php',
|
'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php',
|
||||||
'PhabricatorFileEditController' => 'applications/files/controller/PhabricatorFileEditController.php',
|
'PhabricatorFileEditController' => 'applications/files/controller/PhabricatorFileEditController.php',
|
||||||
'PhabricatorFileEditor' => 'applications/files/editor/PhabricatorFileEditor.php',
|
'PhabricatorFileEditor' => 'applications/files/editor/PhabricatorFileEditor.php',
|
||||||
|
'PhabricatorFileExternalRequest' => 'applications/files/storage/PhabricatorFileExternalRequest.php',
|
||||||
|
'PhabricatorFileExternalRequestGarbageCollector' => 'applications/files/garbagecollector/PhabricatorFileExternalRequestGarbageCollector.php',
|
||||||
'PhabricatorFileFilePHIDType' => 'applications/files/phid/PhabricatorFileFilePHIDType.php',
|
'PhabricatorFileFilePHIDType' => 'applications/files/phid/PhabricatorFileFilePHIDType.php',
|
||||||
'PhabricatorFileHasObjectEdgeType' => 'applications/files/edge/PhabricatorFileHasObjectEdgeType.php',
|
'PhabricatorFileHasObjectEdgeType' => 'applications/files/edge/PhabricatorFileHasObjectEdgeType.php',
|
||||||
'PhabricatorFileIconSetSelectController' => 'applications/files/controller/PhabricatorFileIconSetSelectController.php',
|
'PhabricatorFileIconSetSelectController' => 'applications/files/controller/PhabricatorFileIconSetSelectController.php',
|
||||||
'PhabricatorFileImageMacro' => 'applications/macro/storage/PhabricatorFileImageMacro.php',
|
'PhabricatorFileImageMacro' => 'applications/macro/storage/PhabricatorFileImageMacro.php',
|
||||||
|
'PhabricatorFileImageProxyController' => 'applications/files/controller/PhabricatorFileImageProxyController.php',
|
||||||
'PhabricatorFileImageTransform' => 'applications/files/transform/PhabricatorFileImageTransform.php',
|
'PhabricatorFileImageTransform' => 'applications/files/transform/PhabricatorFileImageTransform.php',
|
||||||
'PhabricatorFileInfoController' => 'applications/files/controller/PhabricatorFileInfoController.php',
|
'PhabricatorFileInfoController' => 'applications/files/controller/PhabricatorFileInfoController.php',
|
||||||
'PhabricatorFileLinkView' => 'view/layout/PhabricatorFileLinkView.php',
|
'PhabricatorFileLinkView' => 'view/layout/PhabricatorFileLinkView.php',
|
||||||
|
@ -3184,6 +3187,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPhurlURLCommentController' => 'applications/phurl/controller/PhabricatorPhurlURLCommentController.php',
|
'PhabricatorPhurlURLCommentController' => 'applications/phurl/controller/PhabricatorPhurlURLCommentController.php',
|
||||||
'PhabricatorPhurlURLCreateCapability' => 'applications/phurl/capability/PhabricatorPhurlURLCreateCapability.php',
|
'PhabricatorPhurlURLCreateCapability' => 'applications/phurl/capability/PhabricatorPhurlURLCreateCapability.php',
|
||||||
'PhabricatorPhurlURLEditController' => 'applications/phurl/controller/PhabricatorPhurlURLEditController.php',
|
'PhabricatorPhurlURLEditController' => 'applications/phurl/controller/PhabricatorPhurlURLEditController.php',
|
||||||
|
'PhabricatorPhurlURLEditEngine' => 'applications/phurl/editor/PhabricatorPhurlURLEditEngine.php',
|
||||||
'PhabricatorPhurlURLEditor' => 'applications/phurl/editor/PhabricatorPhurlURLEditor.php',
|
'PhabricatorPhurlURLEditor' => 'applications/phurl/editor/PhabricatorPhurlURLEditor.php',
|
||||||
'PhabricatorPhurlURLListController' => 'applications/phurl/controller/PhabricatorPhurlURLListController.php',
|
'PhabricatorPhurlURLListController' => 'applications/phurl/controller/PhabricatorPhurlURLListController.php',
|
||||||
'PhabricatorPhurlURLMailReceiver' => 'applications/phurl/mail/PhabricatorPhurlURLMailReceiver.php',
|
'PhabricatorPhurlURLMailReceiver' => 'applications/phurl/mail/PhabricatorPhurlURLMailReceiver.php',
|
||||||
|
@ -7367,6 +7371,11 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
|
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileEditController' => 'PhabricatorFileController',
|
'PhabricatorFileEditController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileEditor' => 'PhabricatorApplicationTransactionEditor',
|
'PhabricatorFileEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
|
'PhabricatorFileExternalRequest' => array(
|
||||||
|
'PhabricatorFileDAO',
|
||||||
|
'PhabricatorDestructibleInterface',
|
||||||
|
),
|
||||||
|
'PhabricatorFileExternalRequestGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorFileFilePHIDType' => 'PhabricatorPHIDType',
|
'PhabricatorFileFilePHIDType' => 'PhabricatorPHIDType',
|
||||||
'PhabricatorFileHasObjectEdgeType' => 'PhabricatorEdgeType',
|
'PhabricatorFileHasObjectEdgeType' => 'PhabricatorEdgeType',
|
||||||
'PhabricatorFileIconSetSelectController' => 'PhabricatorFileController',
|
'PhabricatorFileIconSetSelectController' => 'PhabricatorFileController',
|
||||||
|
@ -7378,6 +7387,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorTokenReceiverInterface',
|
'PhabricatorTokenReceiverInterface',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
|
'PhabricatorFileImageProxyController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileImageTransform' => 'PhabricatorFileTransform',
|
'PhabricatorFileImageTransform' => 'PhabricatorFileTransform',
|
||||||
'PhabricatorFileInfoController' => 'PhabricatorFileController',
|
'PhabricatorFileInfoController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileLinkView' => 'AphrontView',
|
'PhabricatorFileLinkView' => 'AphrontView',
|
||||||
|
@ -8097,6 +8107,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPhurlURLCommentController' => 'PhabricatorPhurlController',
|
'PhabricatorPhurlURLCommentController' => 'PhabricatorPhurlController',
|
||||||
'PhabricatorPhurlURLCreateCapability' => 'PhabricatorPolicyCapability',
|
'PhabricatorPhurlURLCreateCapability' => 'PhabricatorPolicyCapability',
|
||||||
'PhabricatorPhurlURLEditController' => 'PhabricatorPhurlController',
|
'PhabricatorPhurlURLEditController' => 'PhabricatorPhurlController',
|
||||||
|
'PhabricatorPhurlURLEditEngine' => 'PhabricatorEditEngine',
|
||||||
'PhabricatorPhurlURLEditor' => 'PhabricatorApplicationTransactionEditor',
|
'PhabricatorPhurlURLEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
'PhabricatorPhurlURLListController' => 'PhabricatorPhurlController',
|
'PhabricatorPhurlURLListController' => 'PhabricatorPhurlController',
|
||||||
'PhabricatorPhurlURLMailReceiver' => 'PhabricatorObjectMailReceiver',
|
'PhabricatorPhurlURLMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
final class PhabricatorRedirectController extends PhabricatorController {
|
final class PhabricatorRedirectController extends PhabricatorController {
|
||||||
|
|
||||||
private $uri;
|
|
||||||
private $allowExternal;
|
|
||||||
|
|
||||||
public function shouldRequireLogin() {
|
public function shouldRequireLogin() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -13,15 +10,12 @@ final class PhabricatorRedirectController extends PhabricatorController {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$this->uri = $data['uri'];
|
$uri = $request->getURIData('uri');
|
||||||
$this->allowExternal = idx($data, 'external', false);
|
$external = $request->getURIData('external', false);
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
return id(new AphrontRedirectResponse())
|
return id(new AphrontRedirectResponse())
|
||||||
->setURI($this->uri)
|
->setURI($uri)
|
||||||
->setIsExternal($this->allowExternal);
|
->setIsExternal($external);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,9 +143,6 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
|
||||||
'phabricator.auth-permanent',
|
'phabricator.auth-permanent',
|
||||||
'phabricator.application-id',
|
'phabricator.application-id',
|
||||||
'phabricator.application-secret',
|
'phabricator.application-secret',
|
||||||
'maniphest.priorities.unbreak-now',
|
|
||||||
'maniphest.priorities.needs-triage',
|
|
||||||
'welcome.html',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$ancient_config = array_fill_keys($auth_config, $reason_auth);
|
$ancient_config = array_fill_keys($auth_config, $reason_auth);
|
||||||
|
@ -197,6 +194,10 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
|
||||||
'The "Re: Prefix" and "Vary Subjects" settings are now configured '.
|
'The "Re: Prefix" and "Vary Subjects" settings are now configured '.
|
||||||
'in global settings.');
|
'in global settings.');
|
||||||
|
|
||||||
|
$dashboard_reason = pht(
|
||||||
|
'This option has been removed, you can use Dashboards to provide '.
|
||||||
|
'homepage customization. See T11533 for more details.');
|
||||||
|
|
||||||
$ancient_config += array(
|
$ancient_config += array(
|
||||||
'phid.external-loaders' =>
|
'phid.external-loaders' =>
|
||||||
pht(
|
pht(
|
||||||
|
@ -336,17 +337,9 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
|
||||||
'This option has been replaced with `ui.logo`, which provides more '.
|
'This option has been replaced with `ui.logo`, which provides more '.
|
||||||
'flexible configuration options.'),
|
'flexible configuration options.'),
|
||||||
|
|
||||||
'welcome.html' => pht(
|
'welcome.html' => $dashboard_reason,
|
||||||
'This option has been removed, you can use Dashboards to provide '.
|
'maniphest.priorities.unbreak-now' => $dashboard_reason,
|
||||||
'homepage customization. See T11533 for more details.'),
|
'maniphest.priorities.needs-triage' => $dashboard_reason,
|
||||||
|
|
||||||
'maniphest.priorities.unbreak-now' => pht(
|
|
||||||
'This option has been removed, you can use Dashboards to provide '.
|
|
||||||
'homepage customization. See T11533 for more details.'),
|
|
||||||
|
|
||||||
'maniphest.priorities.needs-triage' => pht(
|
|
||||||
'This option has been removed, you can use Dashboards to provide '.
|
|
||||||
'homepage customization. See T11533 for more details.'),
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -112,25 +112,6 @@ final class ConpherenceRoomTestCase extends ConpherenceTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAddMessageWithFileAttachments() {
|
|
||||||
$creator = $this->generateNewTestUser();
|
|
||||||
$friend_1 = $this->generateNewTestUser();
|
|
||||||
|
|
||||||
$participant_map = array(
|
|
||||||
$creator->getPHID() => $creator,
|
|
||||||
$friend_1->getPHID() => $friend_1,
|
|
||||||
);
|
|
||||||
|
|
||||||
$conpherence = $this->createRoom(
|
|
||||||
$creator,
|
|
||||||
array_keys($participant_map));
|
|
||||||
|
|
||||||
foreach ($participant_map as $phid => $user) {
|
|
||||||
$xactions = $this->addMessageWithFile($user, $conpherence);
|
|
||||||
$this->assertEqual(2, count($xactions));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function createRoom(
|
private function createRoom(
|
||||||
PhabricatorUser $creator,
|
PhabricatorUser $creator,
|
||||||
array $participant_phids) {
|
array $participant_phids) {
|
||||||
|
|
|
@ -37,8 +37,7 @@ final class ConpherenceQueryThreadConduitAPIMethod
|
||||||
|
|
||||||
$query = id(new ConpherenceThreadQuery())
|
$query = id(new ConpherenceThreadQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->needParticipantCache(true)
|
->needParticipantCache(true);
|
||||||
->needFilePHIDs(true);
|
|
||||||
|
|
||||||
if ($ids) {
|
if ($ids) {
|
||||||
$conpherences = $query
|
$conpherences = $query
|
||||||
|
@ -73,7 +72,6 @@ final class ConpherenceQueryThreadConduitAPIMethod
|
||||||
'conpherenceTitle' => $conpherence->getTitle(),
|
'conpherenceTitle' => $conpherence->getTitle(),
|
||||||
'messageCount' => $conpherence->getMessageCount(),
|
'messageCount' => $conpherence->getMessageCount(),
|
||||||
'recentParticipantPHIDs' => $conpherence->getRecentParticipantPHIDs(),
|
'recentParticipantPHIDs' => $conpherence->getRecentParticipantPHIDs(),
|
||||||
'filePHIDs' => $conpherence->getFilePHIDs(),
|
|
||||||
'conpherenceURI' => $this->getConpherenceURI($conpherence),
|
'conpherenceURI' => $this->getConpherenceURI($conpherence),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,7 @@ final class ConpherenceUpdateThreadConduitAPIMethod
|
||||||
$id = $request->getValue('id');
|
$id = $request->getValue('id');
|
||||||
$phid = $request->getValue('phid');
|
$phid = $request->getValue('phid');
|
||||||
$query = id(new ConpherenceThreadQuery())
|
$query = id(new ConpherenceThreadQuery())
|
||||||
->setViewer($user)
|
->setViewer($user);
|
||||||
->needFilePHIDs(true);
|
|
||||||
if ($id) {
|
if ($id) {
|
||||||
$query->withIDs(array($id));
|
$query->withIDs(array($id));
|
||||||
} else if ($phid) {
|
} else if ($phid) {
|
||||||
|
|
|
@ -36,7 +36,6 @@ final class ConpherenceUpdateController
|
||||||
$conpherence = id(new ConpherenceThreadQuery())
|
$conpherence = id(new ConpherenceThreadQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withIDs(array($conpherence_id))
|
->withIDs(array($conpherence_id))
|
||||||
->needFilePHIDs(true)
|
|
||||||
->needOrigPics(true)
|
->needOrigPics(true)
|
||||||
->needCropPics(true)
|
->needCropPics(true)
|
||||||
->needParticipants($need_participants)
|
->needParticipants($need_participants)
|
||||||
|
|
|
@ -22,7 +22,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
$topic) {
|
$topic) {
|
||||||
|
|
||||||
$conpherence = ConpherenceThread::initializeNewRoom($creator);
|
$conpherence = ConpherenceThread::initializeNewRoom($creator);
|
||||||
$files = array();
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
if (empty($participant_phids)) {
|
if (empty($participant_phids)) {
|
||||||
$errors[] = self::ERROR_EMPTY_PARTICIPANTS;
|
$errors[] = self::ERROR_EMPTY_PARTICIPANTS;
|
||||||
|
@ -35,26 +34,11 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
$errors[] = self::ERROR_EMPTY_MESSAGE;
|
$errors[] = self::ERROR_EMPTY_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_phids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles(
|
|
||||||
$creator,
|
|
||||||
array($message));
|
|
||||||
if ($file_phids) {
|
|
||||||
$files = id(new PhabricatorFileQuery())
|
|
||||||
->setViewer($creator)
|
|
||||||
->withPHIDs($file_phids)
|
|
||||||
->execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$xactions = array();
|
$xactions = array();
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
|
->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)
|
||||||
->setNewValue(array('+' => $participant_phids));
|
->setNewValue(array('+' => $participant_phids));
|
||||||
if ($files) {
|
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
|
||||||
->setTransactionType(ConpherenceTransaction::TYPE_FILES)
|
|
||||||
->setNewValue(array('+' => mpull($files, 'getPHID')));
|
|
||||||
}
|
|
||||||
if ($title) {
|
if ($title) {
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
|
->setTransactionType(ConpherenceTransaction::TYPE_TITLE)
|
||||||
|
@ -88,27 +72,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
ConpherenceThread $conpherence,
|
ConpherenceThread $conpherence,
|
||||||
$text) {
|
$text) {
|
||||||
|
|
||||||
$files = array();
|
|
||||||
$file_phids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles(
|
|
||||||
$viewer,
|
|
||||||
array($text));
|
|
||||||
// Since these are extracted from text, we might be re-including the
|
|
||||||
// same file -- e.g. a mock under discussion. Filter files we
|
|
||||||
// already have.
|
|
||||||
$existing_file_phids = $conpherence->getFilePHIDs();
|
|
||||||
$file_phids = array_diff($file_phids, $existing_file_phids);
|
|
||||||
if ($file_phids) {
|
|
||||||
$files = id(new PhabricatorFileQuery())
|
|
||||||
->setViewer($this->getActor())
|
|
||||||
->withPHIDs($file_phids)
|
|
||||||
->execute();
|
|
||||||
}
|
|
||||||
$xactions = array();
|
$xactions = array();
|
||||||
if ($files) {
|
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
|
||||||
->setTransactionType(ConpherenceTransaction::TYPE_FILES)
|
|
||||||
->setNewValue(array('+' => mpull($files, 'getPHID')));
|
|
||||||
}
|
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
|
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
|
||||||
->attachComment(
|
->attachComment(
|
||||||
|
@ -126,7 +90,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
$types[] = ConpherenceTransaction::TYPE_TITLE;
|
$types[] = ConpherenceTransaction::TYPE_TITLE;
|
||||||
$types[] = ConpherenceTransaction::TYPE_TOPIC;
|
$types[] = ConpherenceTransaction::TYPE_TOPIC;
|
||||||
$types[] = ConpherenceTransaction::TYPE_PARTICIPANTS;
|
$types[] = ConpherenceTransaction::TYPE_PARTICIPANTS;
|
||||||
$types[] = ConpherenceTransaction::TYPE_FILES;
|
|
||||||
$types[] = ConpherenceTransaction::TYPE_PICTURE;
|
$types[] = ConpherenceTransaction::TYPE_PICTURE;
|
||||||
$types[] = ConpherenceTransaction::TYPE_PICTURE_CROP;
|
$types[] = ConpherenceTransaction::TYPE_PICTURE_CROP;
|
||||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||||
|
@ -154,8 +117,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
return $object->getParticipantPHIDs();
|
return $object->getParticipantPHIDs();
|
||||||
case ConpherenceTransaction::TYPE_FILES:
|
|
||||||
return $object->getFilePHIDs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +133,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
$file = $xaction->getNewValue();
|
$file = $xaction->getNewValue();
|
||||||
return $file->getPHID();
|
return $file->getPHID();
|
||||||
case ConpherenceTransaction::TYPE_PARTICIPANTS:
|
case ConpherenceTransaction::TYPE_PARTICIPANTS:
|
||||||
case ConpherenceTransaction::TYPE_FILES:
|
|
||||||
return $this->getPHIDTransactionNewValue($xaction);
|
return $this->getPHIDTransactionNewValue($xaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,27 +295,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
PhabricatorApplicationTransaction $xaction) {
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
switch ($xaction->getTransactionType()) {
|
switch ($xaction->getTransactionType()) {
|
||||||
case ConpherenceTransaction::TYPE_FILES:
|
|
||||||
$editor = new PhabricatorEdgeEditor();
|
|
||||||
$edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
|
|
||||||
$old = array_fill_keys($xaction->getOldValue(), true);
|
|
||||||
$new = array_fill_keys($xaction->getNewValue(), true);
|
|
||||||
$add_edges = array_keys(array_diff_key($new, $old));
|
|
||||||
$remove_edges = array_keys(array_diff_key($old, $new));
|
|
||||||
foreach ($add_edges as $file_phid) {
|
|
||||||
$editor->addEdge(
|
|
||||||
$object->getPHID(),
|
|
||||||
$edge_type,
|
|
||||||
$file_phid);
|
|
||||||
}
|
|
||||||
foreach ($remove_edges as $file_phid) {
|
|
||||||
$editor->removeEdge(
|
|
||||||
$object->getPHID(),
|
|
||||||
$edge_type,
|
|
||||||
$file_phid);
|
|
||||||
}
|
|
||||||
$editor->save();
|
|
||||||
break;
|
|
||||||
case ConpherenceTransaction::TYPE_PARTICIPANTS:
|
case ConpherenceTransaction::TYPE_PARTICIPANTS:
|
||||||
if ($this->getIsNewObject()) {
|
if ($this->getIsNewObject()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -488,14 +427,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
PhabricatorPolicyCapability::CAN_EDIT);
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// This is similar to PhabricatorTransactions::TYPE_COMMENT so
|
|
||||||
// use CAN_VIEW
|
|
||||||
case ConpherenceTransaction::TYPE_FILES:
|
|
||||||
PhabricatorPolicyFilter::requireCapability(
|
|
||||||
$this->requireActor(),
|
|
||||||
$object,
|
|
||||||
PhabricatorPolicyCapability::CAN_VIEW);
|
|
||||||
break;
|
|
||||||
case ConpherenceTransaction::TYPE_TITLE:
|
case ConpherenceTransaction::TYPE_TITLE:
|
||||||
case ConpherenceTransaction::TYPE_TOPIC:
|
case ConpherenceTransaction::TYPE_TOPIC:
|
||||||
PhabricatorPolicyFilter::requireCapability(
|
PhabricatorPolicyFilter::requireCapability(
|
||||||
|
@ -514,7 +445,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case ConpherenceTransaction::TYPE_TITLE:
|
case ConpherenceTransaction::TYPE_TITLE:
|
||||||
return $v;
|
return $v;
|
||||||
case ConpherenceTransaction::TYPE_FILES:
|
|
||||||
case ConpherenceTransaction::TYPE_PARTICIPANTS:
|
case ConpherenceTransaction::TYPE_PARTICIPANTS:
|
||||||
return $this->mergePHIDOrEdgeTransactions($u, $v);
|
return $this->mergePHIDOrEdgeTransactions($u, $v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,17 +13,11 @@ final class ConpherenceThreadQuery
|
||||||
private $needOrigPics;
|
private $needOrigPics;
|
||||||
private $needTransactions;
|
private $needTransactions;
|
||||||
private $needParticipantCache;
|
private $needParticipantCache;
|
||||||
private $needFilePHIDs;
|
|
||||||
private $afterTransactionID;
|
private $afterTransactionID;
|
||||||
private $beforeTransactionID;
|
private $beforeTransactionID;
|
||||||
private $transactionLimit;
|
private $transactionLimit;
|
||||||
private $fulltext;
|
private $fulltext;
|
||||||
|
|
||||||
public function needFilePHIDs($need_file_phids) {
|
|
||||||
$this->needFilePHIDs = $need_file_phids;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function needParticipantCache($participant_cache) {
|
public function needParticipantCache($participant_cache) {
|
||||||
$this->needParticipantCache = $participant_cache;
|
$this->needParticipantCache = $participant_cache;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -116,9 +110,6 @@ final class ConpherenceThreadQuery
|
||||||
if ($this->needTransactions) {
|
if ($this->needTransactions) {
|
||||||
$this->loadTransactionsAndHandles($conpherences);
|
$this->loadTransactionsAndHandles($conpherences);
|
||||||
}
|
}
|
||||||
if ($this->needFilePHIDs) {
|
|
||||||
$this->loadFilePHIDs($conpherences);
|
|
||||||
}
|
|
||||||
if ($this->needOrigPics || $this->needCropPics) {
|
if ($this->needOrigPics || $this->needCropPics) {
|
||||||
$this->initImages($conpherences);
|
$this->initImages($conpherences);
|
||||||
}
|
}
|
||||||
|
@ -275,19 +266,6 @@ final class ConpherenceThreadQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadFilePHIDs(array $conpherences) {
|
|
||||||
$edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
|
|
||||||
$file_edges = id(new PhabricatorEdgeQuery())
|
|
||||||
->withSourcePHIDs(array_keys($conpherences))
|
|
||||||
->withEdgeTypes(array($edge_type))
|
|
||||||
->execute();
|
|
||||||
foreach ($file_edges as $conpherence_phid => $data) {
|
|
||||||
$conpherence = $conpherences[$conpherence_phid];
|
|
||||||
$conpherence->attachFilePHIDs(array_keys($data[$edge_type]));
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function loadOrigPics(array $conpherences) {
|
private function loadOrigPics(array $conpherences) {
|
||||||
return $this->loadPics(
|
return $this->loadPics(
|
||||||
$conpherences,
|
$conpherences,
|
||||||
|
|
|
@ -20,7 +20,6 @@ final class ConpherenceThread extends ConpherenceDAO
|
||||||
private $participants = self::ATTACHABLE;
|
private $participants = self::ATTACHABLE;
|
||||||
private $transactions = self::ATTACHABLE;
|
private $transactions = self::ATTACHABLE;
|
||||||
private $handles = self::ATTACHABLE;
|
private $handles = self::ATTACHABLE;
|
||||||
private $filePHIDs = self::ATTACHABLE;
|
|
||||||
private $images = self::ATTACHABLE;
|
private $images = self::ATTACHABLE;
|
||||||
|
|
||||||
public static function initializeNewRoom(PhabricatorUser $sender) {
|
public static function initializeNewRoom(PhabricatorUser $sender) {
|
||||||
|
@ -31,7 +30,6 @@ final class ConpherenceThread extends ConpherenceDAO
|
||||||
->setTitle('')
|
->setTitle('')
|
||||||
->setTopic('')
|
->setTopic('')
|
||||||
->attachParticipants(array())
|
->attachParticipants(array())
|
||||||
->attachFilePHIDs(array())
|
|
||||||
->attachImages(array())
|
->attachImages(array())
|
||||||
->setViewPolicy($default_policy)
|
->setViewPolicy($default_policy)
|
||||||
->setEditPolicy($default_policy)
|
->setEditPolicy($default_policy)
|
||||||
|
@ -158,14 +156,6 @@ final class ConpherenceThread extends ConpherenceDAO
|
||||||
$amount);
|
$amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attachFilePHIDs(array $file_phids) {
|
|
||||||
$this->filePHIDs = $file_phids;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
public function getFilePHIDs() {
|
|
||||||
return $this->assertAttached($this->filePHIDs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadImageURI($size) {
|
public function loadImageURI($size) {
|
||||||
$file = $this->getImage($size);
|
$file = $this->getImage($size);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
|
final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
|
||||||
|
|
||||||
const TYPE_FILES = 'files';
|
|
||||||
const TYPE_TITLE = 'title';
|
const TYPE_TITLE = 'title';
|
||||||
const TYPE_TOPIC = 'topic';
|
const TYPE_TOPIC = 'topic';
|
||||||
const TYPE_PARTICIPANTS = 'participants';
|
const TYPE_PARTICIPANTS = 'participants';
|
||||||
|
@ -44,8 +43,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
|
||||||
case self::TYPE_PICTURE:
|
case self::TYPE_PICTURE:
|
||||||
case self::TYPE_DATE_MARKER:
|
case self::TYPE_DATE_MARKER:
|
||||||
return false;
|
return false;
|
||||||
case self::TYPE_FILES:
|
|
||||||
return true;
|
|
||||||
case self::TYPE_PICTURE_CROP:
|
case self::TYPE_PICTURE_CROP:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -68,29 +65,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
|
||||||
case self::TYPE_PICTURE:
|
case self::TYPE_PICTURE:
|
||||||
return $this->getRoomTitle();
|
return $this->getRoomTitle();
|
||||||
break;
|
break;
|
||||||
case self::TYPE_FILES:
|
|
||||||
$add = array_diff($new, $old);
|
|
||||||
$rem = array_diff($old, $new);
|
|
||||||
|
|
||||||
if ($add && $rem) {
|
|
||||||
$title = pht(
|
|
||||||
'%s edited files(s), added %d and removed %d.',
|
|
||||||
$this->renderHandleLink($author_phid),
|
|
||||||
count($add),
|
|
||||||
count($rem));
|
|
||||||
} else if ($add) {
|
|
||||||
$title = pht(
|
|
||||||
'%s added %s files(s).',
|
|
||||||
$this->renderHandleLink($author_phid),
|
|
||||||
phutil_count($add));
|
|
||||||
} else {
|
|
||||||
$title = pht(
|
|
||||||
'%s removed %s file(s).',
|
|
||||||
$this->renderHandleLink($author_phid),
|
|
||||||
phutil_count($rem));
|
|
||||||
}
|
|
||||||
return $title;
|
|
||||||
break;
|
|
||||||
case self::TYPE_PARTICIPANTS:
|
case self::TYPE_PARTICIPANTS:
|
||||||
$add = array_diff($new, $old);
|
$add = array_diff($new, $old);
|
||||||
$rem = array_diff($old, $new);
|
$rem = array_diff($old, $new);
|
||||||
|
@ -252,7 +226,6 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
|
||||||
switch ($this->getTransactionType()) {
|
switch ($this->getTransactionType()) {
|
||||||
case self::TYPE_TITLE:
|
case self::TYPE_TITLE:
|
||||||
case self::TYPE_PICTURE:
|
case self::TYPE_PICTURE:
|
||||||
case self::TYPE_FILES:
|
|
||||||
case self::TYPE_DATE_MARKER:
|
case self::TYPE_DATE_MARKER:
|
||||||
break;
|
break;
|
||||||
case self::TYPE_PARTICIPANTS:
|
case self::TYPE_PARTICIPANTS:
|
||||||
|
|
|
@ -227,9 +227,6 @@ final class ConpherenceTransactionView extends AphrontView {
|
||||||
$content = null;
|
$content = null;
|
||||||
$handles = $this->getHandles();
|
$handles = $this->getHandles();
|
||||||
switch ($transaction->getTransactionType()) {
|
switch ($transaction->getTransactionType()) {
|
||||||
case ConpherenceTransaction::TYPE_FILES:
|
|
||||||
$content = $transaction->getTitle();
|
|
||||||
break;
|
|
||||||
case ConpherenceTransaction::TYPE_TITLE:
|
case ConpherenceTransaction::TYPE_TITLE:
|
||||||
case ConpherenceTransaction::TYPE_TOPIC:
|
case ConpherenceTransaction::TYPE_TOPIC:
|
||||||
case ConpherenceTransaction::TYPE_PICTURE:
|
case ConpherenceTransaction::TYPE_PICTURE:
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
final class DarkConsoleDataController extends PhabricatorController {
|
final class DarkConsoleDataController extends PhabricatorController {
|
||||||
|
|
||||||
private $key;
|
|
||||||
|
|
||||||
public function shouldRequireLogin() {
|
public function shouldRequireLogin() {
|
||||||
return !PhabricatorEnv::getEnvConfig('darkconsole.always-on');
|
return !PhabricatorEnv::getEnvConfig('darkconsole.always-on');
|
||||||
}
|
}
|
||||||
|
@ -16,19 +14,15 @@ final class DarkConsoleDataController extends PhabricatorController {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$this->key = $data['key'];
|
$viewer = $request->getViewer();
|
||||||
}
|
$key = $request->getURIData('key');
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
$cache = new PhabricatorKeyValueDatabaseCache();
|
$cache = new PhabricatorKeyValueDatabaseCache();
|
||||||
$cache = new PhutilKeyValueCacheProfiler($cache);
|
$cache = new PhutilKeyValueCacheProfiler($cache);
|
||||||
$cache->setProfiler(PhutilServiceProfiler::getInstance());
|
$cache->setProfiler(PhutilServiceProfiler::getInstance());
|
||||||
|
|
||||||
$result = $cache->getKey('darkconsole:'.$this->key);
|
$result = $cache->getKey('darkconsole:'.$key);
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
return new Aphront400Response();
|
return new Aphront400Response();
|
||||||
}
|
}
|
||||||
|
@ -43,7 +37,7 @@ final class DarkConsoleDataController extends PhabricatorController {
|
||||||
return new Aphront400Response();
|
return new Aphront400Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($result['user'] != $user->getPHID()) {
|
if ($result['user'] != $viewer->getPHID()) {
|
||||||
return new Aphront400Response();
|
return new Aphront400Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,12 @@
|
||||||
|
|
||||||
final class DifferentialRevisionLandController extends DifferentialController {
|
final class DifferentialRevisionLandController extends DifferentialController {
|
||||||
|
|
||||||
private $revisionID;
|
|
||||||
private $strategyClass;
|
|
||||||
private $pushStrategy;
|
private $pushStrategy;
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->revisionID = $data['id'];
|
|
||||||
$this->strategyClass = $data['strategy'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
$revision_id = $request->getURIData('id');
|
||||||
$revision_id = $this->revisionID;
|
$strategy_class = $request->getURIData('strategy');
|
||||||
|
|
||||||
$revision = id(new DifferentialRevisionQuery())
|
$revision = id(new DifferentialRevisionQuery())
|
||||||
->withIDs(array($revision_id))
|
->withIDs(array($revision_id))
|
||||||
|
@ -24,15 +17,15 @@ final class DifferentialRevisionLandController extends DifferentialController {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_subclass_of($this->strategyClass, 'DifferentialLandingStrategy')) {
|
if (is_subclass_of($strategy_class, 'DifferentialLandingStrategy')) {
|
||||||
$this->pushStrategy = newv($this->strategyClass, array());
|
$this->pushStrategy = newv($strategy_class, array());
|
||||||
} else {
|
} else {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
"Strategy type must be a valid class name and must subclass ".
|
"Strategy type must be a valid class name and must subclass ".
|
||||||
"%s. '%s' is not a subclass of %s",
|
"%s. '%s' is not a subclass of %s",
|
||||||
'DifferentialLandingStrategy',
|
'DifferentialLandingStrategy',
|
||||||
$this->strategyClass,
|
$strategy_class,
|
||||||
'DifferentialLandingStrategy'));
|
'DifferentialLandingStrategy'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ final class PhabricatorFilesApplication extends PhabricatorApplication {
|
||||||
'delete/(?P<id>[1-9]\d*)/' => 'PhabricatorFileDeleteController',
|
'delete/(?P<id>[1-9]\d*)/' => 'PhabricatorFileDeleteController',
|
||||||
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorFileEditController',
|
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorFileEditController',
|
||||||
'info/(?P<phid>[^/]+)/' => 'PhabricatorFileInfoController',
|
'info/(?P<phid>[^/]+)/' => 'PhabricatorFileInfoController',
|
||||||
'proxy/' => 'PhabricatorFileProxyController',
|
'imageproxy/' => 'PhabricatorFileImageProxyController',
|
||||||
'transforms/(?P<id>[1-9]\d*)/' =>
|
'transforms/(?P<id>[1-9]\d*)/' =>
|
||||||
'PhabricatorFileTransformListController',
|
'PhabricatorFileTransformListController',
|
||||||
'uploaddialog/(?P<single>single/)?'
|
'uploaddialog/(?P<single>single/)?'
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorFileImageProxyController
|
||||||
|
extends PhabricatorFileController {
|
||||||
|
|
||||||
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
|
||||||
|
$show_prototypes = PhabricatorEnv::getEnvConfig(
|
||||||
|
'phabricator.show-prototypes');
|
||||||
|
if (!$show_prototypes) {
|
||||||
|
throw new Exception(
|
||||||
|
pht('Show prototypes is disabled.
|
||||||
|
Set `phabricator.show-prototypes` to `true` to use the image proxy'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$viewer = $request->getViewer();
|
||||||
|
$img_uri = $request->getStr('uri');
|
||||||
|
|
||||||
|
// Validate the URI before doing anything
|
||||||
|
PhabricatorEnv::requireValidRemoteURIForLink($img_uri);
|
||||||
|
$uri = new PhutilURI($img_uri);
|
||||||
|
$proto = $uri->getProtocol();
|
||||||
|
if (!in_array($proto, array('http', 'https'))) {
|
||||||
|
throw new Exception(
|
||||||
|
pht('The provided image URI must be either http or https'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we already have the specified image URI downloaded
|
||||||
|
$cached_request = id(new PhabricatorFileExternalRequest())->loadOneWhere(
|
||||||
|
'uriIndex = %s',
|
||||||
|
PhabricatorHash::digestForIndex($img_uri));
|
||||||
|
|
||||||
|
if ($cached_request) {
|
||||||
|
return $this->getExternalResponse($cached_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ttl = PhabricatorTime::getNow() + phutil_units('7 days in seconds');
|
||||||
|
$external_request = id(new PhabricatorFileExternalRequest())
|
||||||
|
->setURI($img_uri)
|
||||||
|
->setTTL($ttl);
|
||||||
|
|
||||||
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
// Cache missed so we'll need to validate and download the image
|
||||||
|
try {
|
||||||
|
// Rate limit outbound fetches to make this mechanism less useful for
|
||||||
|
// scanning networks and ports.
|
||||||
|
PhabricatorSystemActionEngine::willTakeAction(
|
||||||
|
array($viewer->getPHID()),
|
||||||
|
new PhabricatorFilesOutboundRequestAction(),
|
||||||
|
1);
|
||||||
|
|
||||||
|
$file = PhabricatorFile::newFromFileDownload(
|
||||||
|
$uri,
|
||||||
|
array(
|
||||||
|
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
|
||||||
|
'canCDN' => true,
|
||||||
|
));
|
||||||
|
if (!$file->isViewableImage()) {
|
||||||
|
$mime_type = $file->getMimeType();
|
||||||
|
$engine = new PhabricatorDestructionEngine();
|
||||||
|
$engine->destroyObject($file);
|
||||||
|
$file = null;
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'The URI "%s" does not correspond to a valid image file, got '.
|
||||||
|
'a file with MIME type "%s". You must specify the URI of a '.
|
||||||
|
'valid image file.',
|
||||||
|
$uri,
|
||||||
|
$mime_type));
|
||||||
|
} else {
|
||||||
|
$file->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
$external_request->setIsSuccessful(true)
|
||||||
|
->setFilePHID($file->getPHID())
|
||||||
|
->save();
|
||||||
|
unset($unguarded);
|
||||||
|
return $this->getExternalResponse($external_request);
|
||||||
|
} catch (HTTPFutureHTTPResponseStatus $status) {
|
||||||
|
$external_request->setIsSuccessful(false)
|
||||||
|
->setResponseMessage($status->getMessage())
|
||||||
|
->save();
|
||||||
|
return $this->getExternalResponse($external_request);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
// Not actually saving the request in this case
|
||||||
|
$external_request->setResponseMessage($ex->getMessage());
|
||||||
|
return $this->getExternalResponse($external_request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getExternalResponse(
|
||||||
|
PhabricatorFileExternalRequest $request) {
|
||||||
|
if ($request->getIsSuccessful()) {
|
||||||
|
$file = id(new PhabricatorFileQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withPHIDs(array($request->getFilePHID()))
|
||||||
|
->executeOne();
|
||||||
|
if (!file) {
|
||||||
|
throw new Exception(pht(
|
||||||
|
'The underlying file does not exist, but the cached request was '.
|
||||||
|
'successful. This likely means the file record was manually deleted '.
|
||||||
|
'by an administrator.'));
|
||||||
|
}
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setIsExternal(true)
|
||||||
|
->setURI($file->getViewURI());
|
||||||
|
} else {
|
||||||
|
throw new Exception(pht(
|
||||||
|
"The request to get the external file from '%s' was unsuccessful:\n %s",
|
||||||
|
$request->getURI(),
|
||||||
|
$request->getResponseMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorFileExternalRequestGarbageCollector
|
||||||
|
extends PhabricatorGarbageCollector {
|
||||||
|
|
||||||
|
const COLLECTORCONST = 'files.externalttl';
|
||||||
|
|
||||||
|
public function getCollectorName() {
|
||||||
|
return pht('External Requests (TTL)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticPolicy() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function collectGarbage() {
|
||||||
|
$file_requests = id(new PhabricatorFileExternalRequest())->loadAllWhere(
|
||||||
|
'ttl < %d LIMIT 100',
|
||||||
|
PhabricatorTime::getNow());
|
||||||
|
$engine = new PhabricatorDestructionEngine();
|
||||||
|
foreach ($file_requests as $request) {
|
||||||
|
$engine->destroyObject($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (count($file_requests) == 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorFileExternalRequest extends PhabricatorFileDAO
|
||||||
|
implements
|
||||||
|
PhabricatorDestructibleInterface {
|
||||||
|
|
||||||
|
protected $uri;
|
||||||
|
protected $uriIndex;
|
||||||
|
protected $ttl;
|
||||||
|
protected $filePHID;
|
||||||
|
protected $isSuccessful;
|
||||||
|
protected $responseMessage;
|
||||||
|
|
||||||
|
protected function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
|
'uri' => 'text',
|
||||||
|
'uriIndex' => 'bytes12',
|
||||||
|
'ttl' => 'epoch',
|
||||||
|
'filePHID' => 'phid?',
|
||||||
|
'isSuccessful' => 'bool',
|
||||||
|
'responseMessage' => 'text?',
|
||||||
|
),
|
||||||
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
|
'key_uriindex' => array(
|
||||||
|
'columns' => array('uriIndex'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
'key_ttl' => array(
|
||||||
|
'columns' => array('ttl'),
|
||||||
|
),
|
||||||
|
'key_file' => array(
|
||||||
|
'columns' => array('filePHID'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save() {
|
||||||
|
$hash = PhabricatorHash::digestForIndex($this->getURI());
|
||||||
|
$this->setURIIndex($hash);
|
||||||
|
return parent::save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||||
|
|
||||||
|
public function destroyObjectPermanently(
|
||||||
|
PhabricatorDestructionEngine $engine) {
|
||||||
|
|
||||||
|
$file_phid = $this->getFilePHID();
|
||||||
|
if ($file_phid) {
|
||||||
|
$file = id(new PhabricatorFileQuery())
|
||||||
|
->setViewer($engine->getViewer())
|
||||||
|
->withPHIDs(array($file_phid))
|
||||||
|
->executeOne();
|
||||||
|
if ($file) {
|
||||||
|
$engine->destroyObject($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -420,6 +420,10 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
->setKey('initiatorPHID')
|
->setKey('initiatorPHID')
|
||||||
->setType('phid')
|
->setType('phid')
|
||||||
->setDescription(pht('The person (or thing) that started this build.')),
|
->setDescription(pht('The person (or thing) that started this build.')),
|
||||||
|
id(new PhabricatorConduitSearchFieldSpecification())
|
||||||
|
->setKey('name')
|
||||||
|
->setType('string')
|
||||||
|
->setDescription(pht('The name of this build.')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,6 +437,7 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
'name' => HarbormasterBuildStatus::getBuildStatusName($status),
|
'name' => HarbormasterBuildStatus::getBuildStatusName($status),
|
||||||
),
|
),
|
||||||
'initiatorPHID' => nonempty($this->getInitiatorPHID(), null),
|
'initiatorPHID' => nonempty($this->getInitiatorPHID(), null),
|
||||||
|
'name' => $this->getName(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ final class PhabricatorPasteApplication extends PhabricatorApplication {
|
||||||
=> 'PhabricatorPasteViewController',
|
=> 'PhabricatorPasteViewController',
|
||||||
'/paste/' => array(
|
'/paste/' => array(
|
||||||
'(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorPasteListController',
|
'(query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorPasteListController',
|
||||||
'create/' => 'PhabricatorPasteEditController',
|
|
||||||
$this->getEditRoutePattern('edit/') => 'PhabricatorPasteEditController',
|
$this->getEditRoutePattern('edit/') => 'PhabricatorPasteEditController',
|
||||||
'raw/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteRawController',
|
'raw/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteRawController',
|
||||||
'archive/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteArchiveController',
|
'archive/(?P<id>[1-9]\d*)/' => 'PhabricatorPasteArchiveController',
|
||||||
|
|
|
@ -361,7 +361,7 @@ final class PhameBlog extends PhameDAO
|
||||||
|
|
||||||
|
|
||||||
public function isAutomaticallySubscribed($phid) {
|
public function isAutomaticallySubscribed($phid) {
|
||||||
return ($this->creatorPHID == $phid);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ final class PhabricatorPhragmentApplication extends PhabricatorApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTitleGlyph() {
|
public function getTitleGlyph() {
|
||||||
return "\xE2\x26\xB6";
|
return "\xE2\x96\x9B";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getApplicationGroup() {
|
public function getApplicationGroup() {
|
||||||
|
|
|
@ -46,9 +46,7 @@ final class PhabricatorPhurlApplication extends PhabricatorApplication {
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhabricatorPhurlURLListController',
|
=> 'PhabricatorPhurlURLListController',
|
||||||
'url/' => array(
|
'url/' => array(
|
||||||
'create/'
|
$this->getEditRoutePattern('edit/')
|
||||||
=> 'PhabricatorPhurlURLEditController',
|
|
||||||
'edit/(?P<id>[1-9]\d*)/'
|
|
||||||
=> 'PhabricatorPhurlURLEditController',
|
=> 'PhabricatorPhurlURLEditController',
|
||||||
'comment/(?P<id>[1-9]\d*)/'
|
'comment/(?P<id>[1-9]\d*)/'
|
||||||
=> 'PhabricatorPhurlURLCommentController',
|
=> 'PhabricatorPhurlURLCommentController',
|
||||||
|
|
|
@ -3,17 +3,10 @@
|
||||||
abstract class PhabricatorPhurlController extends PhabricatorController {
|
abstract class PhabricatorPhurlController extends PhabricatorController {
|
||||||
|
|
||||||
protected function buildApplicationCrumbs() {
|
protected function buildApplicationCrumbs() {
|
||||||
$can_create = $this->hasApplicationCapability(
|
|
||||||
PhabricatorPhurlURLCreateCapability::CAPABILITY);
|
|
||||||
|
|
||||||
$crumbs = parent::buildApplicationCrumbs();
|
$crumbs = parent::buildApplicationCrumbs();
|
||||||
$crumbs->addAction(
|
id(new PhabricatorPhurlURLEditEngine())
|
||||||
id(new PHUIListItemView())
|
->setViewer($this->getViewer())
|
||||||
->setName(pht('Shorten URL'))
|
->addActionToCrumbs($crumbs);
|
||||||
->setHref($this->getApplicationURI().'url/create/')
|
|
||||||
->setIcon('fa-plus-square')
|
|
||||||
->setDisabled(!$can_create)
|
|
||||||
->setWorkflow(!$can_create));
|
|
||||||
|
|
||||||
return $crumbs;
|
return $crumbs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,263 +4,8 @@ final class PhabricatorPhurlURLEditController
|
||||||
extends PhabricatorPhurlController {
|
extends PhabricatorPhurlController {
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$id = $request->getURIData('id');
|
return id(new PhabricatorPhurlURLEditEngine())
|
||||||
$is_create = !$id;
|
->setController($this)
|
||||||
|
->buildResponse();
|
||||||
$viewer = $this->getViewer();
|
|
||||||
$user_phid = $viewer->getPHID();
|
|
||||||
$error_long_url = true;
|
|
||||||
$error_alias = null;
|
|
||||||
$validation_exception = null;
|
|
||||||
|
|
||||||
$next_workflow = $request->getStr('next');
|
|
||||||
$uri_query = $request->getStr('query');
|
|
||||||
|
|
||||||
if ($is_create) {
|
|
||||||
$this->requireApplicationCapability(
|
|
||||||
PhabricatorPhurlURLCreateCapability::CAPABILITY);
|
|
||||||
|
|
||||||
$url = PhabricatorPhurlURL::initializeNewPhurlURL(
|
|
||||||
$viewer);
|
|
||||||
$submit_label = pht('Create');
|
|
||||||
$page_title = pht('Shorten URL');
|
|
||||||
$header_icon = 'fa-plus-square';
|
|
||||||
$subscribers = array();
|
|
||||||
$cancel_uri = $this->getApplicationURI();
|
|
||||||
} else {
|
|
||||||
$url = id(new PhabricatorPhurlURLQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($id))
|
|
||||||
->requireCapabilities(
|
|
||||||
array(
|
|
||||||
PhabricatorPolicyCapability::CAN_VIEW,
|
|
||||||
PhabricatorPolicyCapability::CAN_EDIT,
|
|
||||||
))
|
|
||||||
->executeOne();
|
|
||||||
|
|
||||||
if (!$url) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
$submit_label = pht('Update');
|
|
||||||
$page_title = pht('Edit URL: %s', $url->getName());
|
|
||||||
$header_icon = 'fa-pencil';
|
|
||||||
|
|
||||||
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
|
||||||
$url->getPHID());
|
|
||||||
|
|
||||||
$cancel_uri = '/U'.$url->getID();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($is_create) {
|
|
||||||
$projects = array();
|
|
||||||
} else {
|
|
||||||
$projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
|
||||||
$url->getPHID(),
|
|
||||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
|
|
||||||
$projects = array_reverse($projects);
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = $url->getName();
|
|
||||||
$long_url = $url->getLongURL();
|
|
||||||
$alias = $url->getAlias();
|
|
||||||
$description = $url->getDescription();
|
|
||||||
$edit_policy = $url->getEditPolicy();
|
|
||||||
$view_policy = $url->getViewPolicy();
|
|
||||||
$space = $url->getSpacePHID();
|
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
|
||||||
$xactions = array();
|
|
||||||
$name = $request->getStr('name');
|
|
||||||
$long_url = $request->getStr('longURL');
|
|
||||||
$alias = $request->getStr('alias');
|
|
||||||
$projects = $request->getArr('projects');
|
|
||||||
$description = $request->getStr('description');
|
|
||||||
$subscribers = $request->getArr('subscribers');
|
|
||||||
$edit_policy = $request->getStr('editPolicy');
|
|
||||||
$view_policy = $request->getStr('viewPolicy');
|
|
||||||
$space = $request->getStr('spacePHID');
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(
|
|
||||||
PhabricatorPhurlURLTransaction::TYPE_NAME)
|
|
||||||
->setNewValue($name);
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(
|
|
||||||
PhabricatorPhurlURLTransaction::TYPE_URL)
|
|
||||||
->setNewValue($long_url);
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(
|
|
||||||
PhabricatorPhurlURLTransaction::TYPE_ALIAS)
|
|
||||||
->setNewValue($alias);
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(
|
|
||||||
PhabricatorTransactions::TYPE_SUBSCRIBERS)
|
|
||||||
->setNewValue(array('=' => array_fuse($subscribers)));
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(
|
|
||||||
PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION)
|
|
||||||
->setNewValue($description);
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
|
|
||||||
->setNewValue($view_policy);
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
|
|
||||||
->setNewValue($edit_policy);
|
|
||||||
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
|
|
||||||
->setNewValue($space);
|
|
||||||
|
|
||||||
$editor = id(new PhabricatorPhurlURLEditor())
|
|
||||||
->setActor($viewer)
|
|
||||||
->setContentSourceFromRequest($request)
|
|
||||||
->setContinueOnNoEffect(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
|
|
||||||
$xactions[] = id(new PhabricatorPhurlURLTransaction())
|
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
|
||||||
->setMetadataValue('edge:type', $proj_edge_type)
|
|
||||||
->setNewValue(array('=' => array_fuse($projects)));
|
|
||||||
|
|
||||||
$xactions = $editor->applyTransactions($url, $xactions);
|
|
||||||
return id(new AphrontRedirectResponse())
|
|
||||||
->setURI($url->getURI());
|
|
||||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
|
||||||
$validation_exception = $ex;
|
|
||||||
$error_long_url = $ex->getShortMessage(
|
|
||||||
PhabricatorPhurlURLTransaction::TYPE_URL);
|
|
||||||
$error_alias = $ex->getShortMessage(
|
|
||||||
PhabricatorPhurlURLTransaction::TYPE_ALIAS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$current_policies = id(new PhabricatorPolicyQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->setObject($url)
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$name = id(new AphrontFormTextControl())
|
|
||||||
->setLabel(pht('Name'))
|
|
||||||
->setName('name')
|
|
||||||
->setValue($name);
|
|
||||||
|
|
||||||
$long_url = id(new AphrontFormTextControl())
|
|
||||||
->setLabel(pht('URL'))
|
|
||||||
->setName('longURL')
|
|
||||||
->setValue($long_url)
|
|
||||||
->setError($error_long_url);
|
|
||||||
|
|
||||||
$alias = id(new AphrontFormTextControl())
|
|
||||||
->setLabel(pht('Alias'))
|
|
||||||
->setName('alias')
|
|
||||||
->setValue($alias)
|
|
||||||
->setError($error_alias);
|
|
||||||
|
|
||||||
$projects = id(new AphrontFormTokenizerControl())
|
|
||||||
->setLabel(pht('Tags'))
|
|
||||||
->setName('projects')
|
|
||||||
->setValue($projects)
|
|
||||||
->setUser($viewer)
|
|
||||||
->setDatasource(new PhabricatorProjectDatasource());
|
|
||||||
|
|
||||||
$description = id(new PhabricatorRemarkupControl())
|
|
||||||
->setLabel(pht('Description'))
|
|
||||||
->setName('description')
|
|
||||||
->setValue($description)
|
|
||||||
->setUser($viewer);
|
|
||||||
|
|
||||||
$view_policies = id(new AphrontFormPolicyControl())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setValue($view_policy)
|
|
||||||
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
|
||||||
->setPolicyObject($url)
|
|
||||||
->setPolicies($current_policies)
|
|
||||||
->setSpacePHID($space)
|
|
||||||
->setName('viewPolicy');
|
|
||||||
$edit_policies = id(new AphrontFormPolicyControl())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setValue($edit_policy)
|
|
||||||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
|
||||||
->setPolicyObject($url)
|
|
||||||
->setPolicies($current_policies)
|
|
||||||
->setName('editPolicy');
|
|
||||||
|
|
||||||
$subscribers = id(new AphrontFormTokenizerControl())
|
|
||||||
->setLabel(pht('Subscribers'))
|
|
||||||
->setName('subscribers')
|
|
||||||
->setValue($subscribers)
|
|
||||||
->setUser($viewer)
|
|
||||||
->setDatasource(new PhabricatorMetaMTAMailableDatasource());
|
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->appendChild($name)
|
|
||||||
->appendChild($long_url)
|
|
||||||
->appendChild($alias)
|
|
||||||
->appendControl($view_policies)
|
|
||||||
->appendControl($edit_policies)
|
|
||||||
->appendControl($subscribers)
|
|
||||||
->appendChild($projects)
|
|
||||||
->appendChild($description);
|
|
||||||
|
|
||||||
|
|
||||||
if ($request->isAjax()) {
|
|
||||||
return $this->newDialog()
|
|
||||||
->setTitle($page_title)
|
|
||||||
->setWidth(AphrontDialogView::WIDTH_FULL)
|
|
||||||
->appendForm($form)
|
|
||||||
->addCancelButton($cancel_uri)
|
|
||||||
->addSubmitButton($submit_label);
|
|
||||||
}
|
|
||||||
|
|
||||||
$submit = id(new AphrontFormSubmitControl())
|
|
||||||
->addCancelButton($cancel_uri)
|
|
||||||
->setValue($submit_label);
|
|
||||||
|
|
||||||
$form->appendChild($submit);
|
|
||||||
|
|
||||||
$form_box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeaderText($page_title)
|
|
||||||
->setForm($form);
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
|
||||||
|
|
||||||
if (!$is_create) {
|
|
||||||
$crumbs->addTextCrumb($url->getMonogram(), $url->getURI());
|
|
||||||
} else {
|
|
||||||
$crumbs->addTextCrumb(pht('Create URL'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$crumbs->addTextCrumb($page_title);
|
|
||||||
$crumbs->setBorder(true);
|
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeaderText(pht('URL'))
|
|
||||||
->setValidationException($validation_exception)
|
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
|
||||||
->appendChild($form);
|
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
|
||||||
->setHeader($page_title)
|
|
||||||
->setHeaderIcon($header_icon);
|
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
|
||||||
->setHeader($header)
|
|
||||||
->setFooter(array(
|
|
||||||
$object_box,
|
|
||||||
));
|
|
||||||
|
|
||||||
return $this->newPage()
|
|
||||||
->setTitle($page_title)
|
|
||||||
->setCrumbs($crumbs)
|
|
||||||
->appendChild($view);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
104
src/applications/phurl/editor/PhabricatorPhurlURLEditEngine.php
Normal file
104
src/applications/phurl/editor/PhabricatorPhurlURLEditEngine.php
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhurlURLEditEngine
|
||||||
|
extends PhabricatorEditEngine {
|
||||||
|
|
||||||
|
const ENGINECONST = 'phurl.url';
|
||||||
|
|
||||||
|
public function getEngineName() {
|
||||||
|
return pht('Phurl');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEngineApplicationClass() {
|
||||||
|
return 'PhabricatorPhurlApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSummaryHeader() {
|
||||||
|
return pht('Configure Phurl Forms');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSummaryText() {
|
||||||
|
return pht('Configure creation and editing forms in Phurl.');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newEditableObject() {
|
||||||
|
return PhabricatorPhurlURL::initializeNewPhurlURL($this->getViewer());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newObjectQuery() {
|
||||||
|
return new PhabricatorPhurlURLQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateTitleText($object) {
|
||||||
|
return pht('Create New URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectEditTitleText($object) {
|
||||||
|
return pht('Edit URL: %s', $object->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectEditShortText($object) {
|
||||||
|
return $object->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateShortText() {
|
||||||
|
return pht('Create URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectName() {
|
||||||
|
return pht('URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateCancelURI($object) {
|
||||||
|
return $this->getApplication()->getApplicationURI('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getEditorURI() {
|
||||||
|
return $this->getApplication()->getApplicationURI('url/edit/');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectViewURI($object) {
|
||||||
|
return $object->getURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCreateNewObjectPolicy() {
|
||||||
|
return $this->getApplication()->getPolicy(
|
||||||
|
PhabricatorPhurlURLCreateCapability::CAPABILITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildCustomEditFields($object) {
|
||||||
|
|
||||||
|
return array(
|
||||||
|
id(new PhabricatorTextEditField())
|
||||||
|
->setKey('name')
|
||||||
|
->setLabel(pht('Name'))
|
||||||
|
->setDescription(pht('URL name.'))
|
||||||
|
->setConduitTypeDescription(pht('New URL name.'))
|
||||||
|
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_NAME)
|
||||||
|
->setValue($object->getName()),
|
||||||
|
id(new PhabricatorTextEditField())
|
||||||
|
->setKey('url')
|
||||||
|
->setLabel(pht('URL'))
|
||||||
|
->setDescription(pht('The URL to shorten.'))
|
||||||
|
->setConduitTypeDescription(pht('New URL.'))
|
||||||
|
->setValue($object->getLongURL())
|
||||||
|
->setIsRequired(true)
|
||||||
|
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_URL),
|
||||||
|
id(new PhabricatorTextEditField())
|
||||||
|
->setKey('alias')
|
||||||
|
->setLabel(pht('Alias'))
|
||||||
|
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_ALIAS)
|
||||||
|
->setDescription(pht('The alias to give the URL.'))
|
||||||
|
->setConduitTypeDescription(pht('New alias.'))
|
||||||
|
->setValue($object->getAlias()),
|
||||||
|
id(new PhabricatorRemarkupEditField())
|
||||||
|
->setKey('description')
|
||||||
|
->setLabel(pht('Description'))
|
||||||
|
->setDescription(pht('URL long description.'))
|
||||||
|
->setConduitTypeDescription(pht('New URL description.'))
|
||||||
|
->setTransactionType(PhabricatorPhurlURLTransaction::TYPE_DESCRIPTION)
|
||||||
|
->setValue($object->getDescription()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -99,10 +99,13 @@ final class PhabricatorPhurlURLSearchEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getNewUserBody() {
|
protected function getNewUserBody() {
|
||||||
|
$create_uri = id(new PhabricatorPhurlURLEditEngine())
|
||||||
|
->getEditURI();
|
||||||
|
|
||||||
$create_button = id(new PHUIButtonView())
|
$create_button = id(new PHUIButtonView())
|
||||||
->setTag('a')
|
->setTag('a')
|
||||||
->setText(pht('Shorten a URL'))
|
->setText(pht('Shorten a URL'))
|
||||||
->setHref('/phurl/url/create/')
|
->setHref($create_uri)
|
||||||
->setColor(PHUIButtonView::GREEN);
|
->setColor(PHUIButtonView::GREEN);
|
||||||
|
|
||||||
$icon = $this->getApplication()->getIcon();
|
$icon = $this->getApplication()->getIcon();
|
||||||
|
|
|
@ -682,7 +682,32 @@ final class PhabricatorRepositoryDiscoveryEngine
|
||||||
|
|
||||||
$data['commitID'] = $commit->getID();
|
$data['commitID'] = $commit->getID();
|
||||||
|
|
||||||
PhabricatorWorker::scheduleTask($class, $data);
|
// If the repository is importing for the first time, we schedule tasks
|
||||||
|
// at IMPORT priority, which is very low. Making progress on importing a
|
||||||
|
// new repository for the first time is less important than any other
|
||||||
|
// daemon task.
|
||||||
|
|
||||||
|
// If the repostitory has finished importing and we're just catching up
|
||||||
|
// on recent commits, we schedule discovery at COMMIT priority, which is
|
||||||
|
// slightly below the default priority.
|
||||||
|
|
||||||
|
// Note that followup tasks and triggered tasks (like those generated by
|
||||||
|
// Herald or Harbormaster) will queue at DEFAULT priority, so that each
|
||||||
|
// commit tends to fully import before we start the next one. This tends
|
||||||
|
// to give imports fairly predictable progress. See T11677 for some
|
||||||
|
// discussion.
|
||||||
|
|
||||||
|
if ($repository->isImporting()) {
|
||||||
|
$task_priority = PhabricatorWorker::PRIORITY_IMPORT;
|
||||||
|
} else {
|
||||||
|
$task_priority = PhabricatorWorker::PRIORITY_COMMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = array(
|
||||||
|
'priority' => $task_priority,
|
||||||
|
);
|
||||||
|
|
||||||
|
PhabricatorWorker::scheduleTask($class, $data, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isInitialImport(array $refs) {
|
private function isInitialImport(array $refs) {
|
||||||
|
|
|
@ -47,6 +47,14 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker
|
||||||
$this->getFollowupTaskClass(),
|
$this->getFollowupTaskClass(),
|
||||||
array(
|
array(
|
||||||
'commitID' => $commit->getID(),
|
'commitID' => $commit->getID(),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
// We queue followup tasks at default priority so that the queue
|
||||||
|
// finishes work it has started before starting more work. If
|
||||||
|
// followups are queued at the same priority level, we do all
|
||||||
|
// message parses first, then all change parses, etc. This makes
|
||||||
|
// progress uneven. See T11677 for discussion.
|
||||||
|
'priority' => PhabricatorWorker::PRIORITY_DEFAULT,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,10 +72,6 @@ final class PhabricatorStandardCustomFieldText
|
||||||
return new AphrontStringHTTPParameterType();
|
return new AphrontStringHTTPParameterType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function shouldAppearInApplicationSearch() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getConduitEditParameterType() {
|
public function getConduitEditParameterType() {
|
||||||
return new ConduitStringParameterType();
|
return new ConduitStringParameterType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ abstract class PhabricatorWorker extends Phobject {
|
||||||
|
|
||||||
const PRIORITY_ALERTS = 1000;
|
const PRIORITY_ALERTS = 1000;
|
||||||
const PRIORITY_DEFAULT = 2000;
|
const PRIORITY_DEFAULT = 2000;
|
||||||
|
const PRIORITY_COMMIT = 2500;
|
||||||
const PRIORITY_BULK = 3000;
|
const PRIORITY_BULK = 3000;
|
||||||
const PRIORITY_IMPORT = 4000;
|
const PRIORITY_IMPORT = 4000;
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,19 @@ final class ManiphestTaskGraph
|
||||||
$assigned = phutil_tag('em', array(), pht('None'));
|
$assigned = phutil_tag('em', array(), pht('None'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$full_title = $object->getTitle();
|
||||||
|
|
||||||
|
$title = id(new PhutilUTF8StringTruncator())
|
||||||
|
->setMaximumGlyphs(80)
|
||||||
|
->truncateString($full_title);
|
||||||
|
|
||||||
$link = phutil_tag(
|
$link = phutil_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
'href' => $object->getURI(),
|
'href' => $object->getURI(),
|
||||||
|
'title' => $full_title,
|
||||||
),
|
),
|
||||||
$object->getTitle());
|
$title);
|
||||||
|
|
||||||
$link = array(
|
$link = array(
|
||||||
phutil_tag(
|
phutil_tag(
|
||||||
|
@ -95,8 +102,6 @@ final class ManiphestTaskGraph
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
$link = AphrontTableView::renderSingleDisplayLine($link);
|
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$marker,
|
$marker,
|
||||||
$trace,
|
$trace,
|
||||||
|
|
|
@ -75,10 +75,19 @@ abstract class PhabricatorLiskDAO extends LiskDAO {
|
||||||
$connection->setReadOnly(true);
|
$connection->setReadOnly(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unless this is a script running from the CLI, prevent any query from
|
// Unless this is a script running from the CLI:
|
||||||
// running for more than 30 seconds. See T10849 for discussion.
|
// - (T10849) Prevent any query from running for more than 30 seconds.
|
||||||
|
// - (T11672) Use persistent connections.
|
||||||
if (php_sapi_name() != 'cli') {
|
if (php_sapi_name() != 'cli') {
|
||||||
$connection->setQueryTimeout(30);
|
|
||||||
|
// TODO: For now, disable this until after T11044: it's better at high
|
||||||
|
// load, but causes us to use slightly more connections at low load and
|
||||||
|
// is pushing users over limits like MySQL "max_connections".
|
||||||
|
$use_persistent = false;
|
||||||
|
|
||||||
|
$connection
|
||||||
|
->setQueryTimeout(30)
|
||||||
|
->setPersistent($use_persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $connection;
|
return $connection;
|
||||||
|
|
|
@ -228,6 +228,10 @@ span.single-display-line-content {
|
||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aphront-table-view td.object-link {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.aphront-table-view tr.closed td.object-link .object-name,
|
.aphront-table-view tr.closed td.object-link .object-name,
|
||||||
.aphront-table-view tr.alt-closed td.object-link .object-name {
|
.aphront-table-view tr.alt-closed td.object-link .object-name {
|
||||||
text-decoration: line-through;
|
text-decoration: line-through;
|
||||||
|
|
|
@ -56,14 +56,6 @@ body.white-background {
|
||||||
color: {$greytext};
|
color: {$greytext};
|
||||||
}
|
}
|
||||||
|
|
||||||
.keyboard-shortcut-help kbd {
|
|
||||||
background: #222222;
|
|
||||||
padding: 6px;
|
|
||||||
color: #ffffff;
|
|
||||||
font-weight: bold;
|
|
||||||
border: 1px solid #555555;
|
|
||||||
}
|
|
||||||
|
|
||||||
.keyboard-focus-focus-reticle {
|
.keyboard-focus-focus-reticle {
|
||||||
background: #ffffd3;
|
background: #ffffd3;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
Loading…
Add table
Reference in a new issue