1
0
Fork 0
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:
epriestley 2016-09-23 17:20:19 -07:00
commit 27006fedcc
38 changed files with 507 additions and 545 deletions

View file

@ -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,

View file

@ -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',

View 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};

View file

@ -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',

View file

@ -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);
} }
} }

View file

@ -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.'),
); );

View file

@ -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) {

View file

@ -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),
); );
} }

View file

@ -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) {

View file

@ -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)

View file

@ -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);
} }

View file

@ -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,

View file

@ -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);

View file

@ -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:

View file

@ -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:

View file

@ -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();
} }

View file

@ -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'));
} }

View file

@ -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/)?'

View file

@ -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()));
}
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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(),
); );
} }

View file

@ -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',

View file

@ -361,7 +361,7 @@ final class PhameBlog extends PhameDAO
public function isAutomaticallySubscribed($phid) { public function isAutomaticallySubscribed($phid) {
return ($this->creatorPHID == $phid); return false;
} }

View file

@ -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() {

View file

@ -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',

View file

@ -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;
} }

View file

@ -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);
} }
} }

View 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()),
);
}
}

View file

@ -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();

View file

@ -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) {

View file

@ -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,
)); ));
} }
} }

View file

@ -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();
} }

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;