1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +01:00

(stable) Promote 2015 Week 52

This commit is contained in:
epriestley 2015-12-26 03:19:24 -08:00
commit 571960e712
606 changed files with 18533 additions and 9045 deletions

View file

@ -1 +0,0 @@
<h2>404 Not Found</h2>

View file

@ -1,76 +0,0 @@
html, body, p, h1, h2, h3 {
padding: 0;
margin: 0;
font-weight: normal;
}
html {
font-family: "Helvetica Neue", "Arial", sans-serif;
font-size: 16px;
overflow-y: scroll;
color: #555555;
}
.oblivious-info {
position: fixed;
width: 15%;
border-right: 1px solid #dfdfdf;
top: 0;
bottom: 0;
left: 0;
padding: 140px 2% 0;
overflow: hidden;
background: url(/image/badge.png);
background-repeat: no-repeat;
background-position: 20px 20px;
}
.oblivious-content {
padding-top: 3%;
margin-left: 22%;
max-width: 800px;
}
a {
color: #2980b9;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1 {
font-size: 24px;
font-weight: normal;
}
h2 {
font-size: 22px;
font-weight: bold;
margin-bottom: 8px;
}
.phame-post {
margin: 0 0 2em;
}
.phame-post-title {
font-size: 28px;
}
.phame-post-date {
font-size: 12px;
margin: .25em 0 2em;
}
.oblivious-content .phabricator-remarkup ul.remarkup-list {
margin-left: 0;
}
.fb-comments,
.fb-comments span,
.fb-comments iframe[style] {
width: 100% !important;
}

View file

@ -1,3 +0,0 @@
</div>
</body>
</html>

View file

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title><?php echo _e($title); ?></title>
<?php echo $skin->getCSSResources(); ?>
</head>
<body>
<div class="oblivious-info">
<h1>
<a href="<?php echo _e($home_uri); ?>"><?php
echo _e($blog->getName());
?></a>
</h1>
<p><?php echo $skin->remarkup($blog->getDescription()); ?></p>
</div>
<div class="oblivious-content">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1 +0,0 @@
<?php echo $post->render(); ?>

View file

@ -1,13 +0,0 @@
<div class="oblivious-post-list">
<?php
foreach ($posts as $post) {
echo $post->renderWithSummary();
}
?>
</div>
<div class="oblivious-pager">
<?php echo $older; ?>
<?php echo $newer; ?>
</div>

View file

@ -1,3 +0,0 @@
{
"name": "Oblivious"
}

View file

@ -7,15 +7,15 @@
*/
return array(
'names' => array(
'core.pkg.css' => '4d47b0a9',
'core.pkg.js' => '47dc9ebb',
'core.pkg.css' => 'a419cf4b',
'core.pkg.js' => '400453e4',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => '2de124c9',
'differential.pkg.js' => '6223dd9d',
'differential.pkg.js' => '64e69521',
'diffusion.pkg.css' => 'f45955ed',
'diffusion.pkg.js' => 'ca1c8b5a',
'maniphest.pkg.css' => '4845691a',
'maniphest.pkg.js' => '3ec6a6d5',
'maniphest.pkg.js' => '949a7498',
'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
'rsrc/css/aphront/dark-console.css' => '6378ef3d',
'rsrc/css/aphront/dialog-view.css' => 'be0e3a46',
@ -80,9 +80,9 @@ return array(
'rsrc/css/application/maniphest/task-summary.css' => '11cc5344',
'rsrc/css/application/objectselector/object-selector.css' => '85ee8ce6',
'rsrc/css/application/owners/owners-path-editor.css' => '2f00933b',
'rsrc/css/application/paste/paste.css' => 'b2f5a543',
'rsrc/css/application/paste/paste.css' => 'a5157c48',
'rsrc/css/application/people/people-profile.css' => '25970776',
'rsrc/css/application/phame/phame.css' => 'cea3c9e1',
'rsrc/css/application/phame/phame.css' => '09a39e8d',
'rsrc/css/application/pholio/pholio-edit.css' => '3ad9d1ee',
'rsrc/css/application/pholio/pholio-inline-comments.css' => '8e545e49',
'rsrc/css/application/pholio/pholio.css' => '95174bdd',
@ -104,7 +104,7 @@ return array(
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
'rsrc/css/application/uiexample/example.css' => '528b19de',
'rsrc/css/core/core.css' => 'a76cefc9',
'rsrc/css/core/remarkup.css' => 'b1c10368',
'rsrc/css/core/remarkup.css' => '7afb543c',
'rsrc/css/core/syntax.css' => '9fd11da8',
'rsrc/css/core/z-index.css' => '57ddcaa2',
'rsrc/css/diviner/diviner-shared.css' => 'aa3656aa',
@ -123,22 +123,23 @@ return array(
'rsrc/css/phui/phui-action-list.css' => 'c5eba19d',
'rsrc/css/phui/phui-action-panel.css' => '91c7b835',
'rsrc/css/phui/phui-badge.css' => 'f25c3476',
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
'rsrc/css/phui/phui-box.css' => 'a5bb366d',
'rsrc/css/phui/phui-button.css' => '16020a60',
'rsrc/css/phui/phui-crumbs-view.css' => '414406b5',
'rsrc/css/phui/phui-document-pro.css' => 'e0fad431',
'rsrc/css/phui/phui-document-summary.css' => '8c1e0aca',
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
'rsrc/css/phui/phui-document.css' => 'a4a1c3b9',
'rsrc/css/phui/phui-feed-story.css' => 'b7b26d23',
'rsrc/css/phui/phui-fontkit.css' => '9cda225e',
'rsrc/css/phui/phui-form-view.css' => 'c1d2ef29',
'rsrc/css/phui/phui-form.css' => 'afdb2c6e',
'rsrc/css/phui/phui-form-view.css' => '4a1a0f5e',
'rsrc/css/phui/phui-form.css' => '0b98e572',
'rsrc/css/phui/phui-header-view.css' => '55bb32dd',
'rsrc/css/phui/phui-icon.css' => 'b0a6b1b6',
'rsrc/css/phui/phui-image-mask.css' => '5a8b09c8',
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
'rsrc/css/phui/phui-info-view.css' => '6d7c3509',
'rsrc/css/phui/phui-list.css' => '125599df',
'rsrc/css/phui/phui-list.css' => '9da2aa00',
'rsrc/css/phui/phui-object-box.css' => '407eaf5a',
'rsrc/css/phui/phui-object-item-list-view.css' => '26c30d3f',
'rsrc/css/phui/phui-pager.css' => 'bea33d23',
@ -151,7 +152,7 @@ return array(
'rsrc/css/phui/phui-text.css' => 'cf019f54',
'rsrc/css/phui/phui-timeline-view.css' => '2efceff8',
'rsrc/css/phui/phui-two-column-view.css' => '39ecafb1',
'rsrc/css/phui/phui-workboard-view.css' => '6704d68d',
'rsrc/css/phui/phui-workboard-view.css' => '24fe2a66',
'rsrc/css/phui/phui-workpanel-view.css' => 'adec7699',
'rsrc/css/sprite-login.css' => '60e8560e',
'rsrc/css/sprite-main-header.css' => 'f07bbb87',
@ -227,14 +228,14 @@ return array(
'rsrc/externals/javelin/lib/JSON.js' => '69adf288',
'rsrc/externals/javelin/lib/Leader.js' => '331b1611',
'rsrc/externals/javelin/lib/Mask.js' => '8a41885b',
'rsrc/externals/javelin/lib/Quicksand.js' => '4cebc641',
'rsrc/externals/javelin/lib/Quicksand.js' => '6b8ef10b',
'rsrc/externals/javelin/lib/Request.js' => '94b750d2',
'rsrc/externals/javelin/lib/Resource.js' => '44959b73',
'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692',
'rsrc/externals/javelin/lib/Router.js' => '29274e2b',
'rsrc/externals/javelin/lib/Scrollbar.js' => '087e919c',
'rsrc/externals/javelin/lib/Sound.js' => '949c0fe5',
'rsrc/externals/javelin/lib/URI.js' => '6eff08aa',
'rsrc/externals/javelin/lib/URI.js' => 'c989ade3',
'rsrc/externals/javelin/lib/Vector.js' => '2caa8fb8',
'rsrc/externals/javelin/lib/WebSocket.js' => 'e292eaf4',
'rsrc/externals/javelin/lib/Workflow.js' => '5b2e3e2b',
@ -244,7 +245,7 @@ return array(
'rsrc/externals/javelin/lib/__tests__/URI.js' => '1e45fda9',
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783',
'rsrc/externals/javelin/lib/behavior.js' => '61cbc29a',
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'ab5f468d',
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '8d3bc1b2',
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '70baed2f',
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'e6e25838',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
@ -399,7 +400,7 @@ return array(
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
'rsrc/js/application/files/behavior-icon-composer.js' => '8ef9ab58',
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/herald/HeraldRuleEditor.js' => '91a6031b',
'rsrc/js/application/herald/HeraldRuleEditor.js' => '5bd8f385',
'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec',
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
'rsrc/js/application/maniphest/behavior-batch-editor.js' => '782ab6e7',
@ -407,19 +408,15 @@ return array(
'rsrc/js/application/maniphest/behavior-line-chart.js' => '88f0c5b3',
'rsrc/js/application/maniphest/behavior-list-edit.js' => 'a9f88de2',
'rsrc/js/application/maniphest/behavior-subpriorityeditor.js' => '71237763',
'rsrc/js/application/maniphest/behavior-transaction-controls.js' => '44168bad',
'rsrc/js/application/maniphest/behavior-transaction-expand.js' => '5fefb143',
'rsrc/js/application/maniphest/behavior-transaction-preview.js' => '4c95d29e',
'rsrc/js/application/owners/OwnersPathEditor.js' => 'aa1733d0',
'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3',
'rsrc/js/application/passphrase/passphrase-credential-control.js' => '3cb0b2fc',
'rsrc/js/application/phame/phame-post-preview.js' => 'd6bba572',
'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '246dc085',
'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'fbe497e7',
'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '3f5d6dbf',
'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'fc91ab6c',
'rsrc/js/application/phortune/phortune-credit-card-form.js' => '2290aeef',
'rsrc/js/application/policy/behavior-policy-control.js' => '7d470398',
'rsrc/js/application/policy/behavior-policy-control.js' => 'ae45872f',
'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '5e9f347c',
'rsrc/js/application/projects/behavior-project-boards.js' => 'ba4fa35c',
'rsrc/js/application/projects/behavior-project-create.js' => '065227cc',
@ -430,7 +427,8 @@ return array(
'rsrc/js/application/repository/repository-crossreference.js' => 'e5339c43',
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
'rsrc/js/application/transactions/behavior-comment-actions.js' => 'f2c64202',
'rsrc/js/application/transactions/behavior-comment-actions.js' => 'b65559c0',
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => 'dbbf48b6',
'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => 'b23b49e6',
@ -454,24 +452,24 @@ return array(
'rsrc/js/core/DragAndDropFileUpload.js' => 'ad10aeac',
'rsrc/js/core/DraggableList.js' => 'a16ec1c6',
'rsrc/js/core/FileUpload.js' => '477359c8',
'rsrc/js/core/Hovercard.js' => '14ac66f5',
'rsrc/js/core/Hovercard.js' => 'c6f720ff',
'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2',
'rsrc/js/core/KeyboardShortcutManager.js' => 'c1700f6f',
'rsrc/js/core/MultirowRowManager.js' => 'b5d57730',
'rsrc/js/core/Notification.js' => 'ccf1cbf8',
'rsrc/js/core/Prefab.js' => '6920d200',
'rsrc/js/core/Prefab.js' => '666c80c5',
'rsrc/js/core/ShapedRequest.js' => '7cbe244b',
'rsrc/js/core/TextAreaUtils.js' => '5c93c52c',
'rsrc/js/core/TextAreaUtils.js' => '9e54692d',
'rsrc/js/core/Title.js' => 'df5e11d2',
'rsrc/js/core/ToolTip.js' => '1d298e3a',
'rsrc/js/core/behavior-active-nav.js' => 'e379b58e',
'rsrc/js/core/behavior-audio-source.js' => '59b251eb',
'rsrc/js/core/behavior-autofocus.js' => '7319e029',
'rsrc/js/core/behavior-choose-control.js' => '6153c708',
'rsrc/js/core/behavior-choose-control.js' => 'dfaafb14',
'rsrc/js/core/behavior-crop.js' => 'fa0f4fc2',
'rsrc/js/core/behavior-dark-console.js' => 'f411b6ae',
'rsrc/js/core/behavior-device.js' => 'a205cf28',
'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '6d49590e',
'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '4f6a4b4e',
'rsrc/js/core/behavior-error-log.js' => '6882e80a',
'rsrc/js/core/behavior-fancy-datepicker.js' => '8ae55229',
'rsrc/js/core/behavior-file-tree.js' => '88236f00',
@ -480,7 +478,7 @@ return array(
'rsrc/js/core/behavior-global-drag-and-drop.js' => 'c8e57404',
'rsrc/js/core/behavior-high-security-warning.js' => 'a464fe03',
'rsrc/js/core/behavior-history-install.js' => '7ee2b591',
'rsrc/js/core/behavior-hovercard.js' => 'f36e01af',
'rsrc/js/core/behavior-hovercard.js' => '66dd6e9e',
'rsrc/js/core/behavior-keyboard-pager.js' => 'a8da01f0',
'rsrc/js/core/behavior-keyboard-shortcuts.js' => 'd75709e6',
'rsrc/js/core/behavior-lightbox-attachments.js' => 'f8ba29d7',
@ -489,8 +487,8 @@ return array(
'rsrc/js/core/behavior-object-selector.js' => '49b73b36',
'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
'rsrc/js/core/behavior-phabricator-nav.js' => '56a1ca03',
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'eeaa9e5a',
'rsrc/js/core/behavior-refresh-csrf.js' => '7814b593',
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'ecddcbe2',
'rsrc/js/core/behavior-refresh-csrf.js' => 'ab2f381b',
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
@ -509,7 +507,7 @@ return array(
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
'rsrc/js/phuix/PHUIXActionView.js' => '8cf6d262',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca',
'rsrc/js/phuix/PHUIXFormControl.js' => 'f9fba5ee',
'rsrc/js/phuix/PHUIXFormControl.js' => '8fba1997',
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
),
'symbols' => array(
@ -557,7 +555,7 @@ return array(
'global-drag-and-drop-css' => '697324ad',
'harbormaster-css' => 'b0758ca5',
'herald-css' => '826075fa',
'herald-rule-editor' => '91a6031b',
'herald-rule-editor' => '5bd8f385',
'herald-test-css' => 'a52e323e',
'inline-comment-summary-css' => '51efda3a',
'javelin-aphlict' => '5359e785',
@ -567,14 +565,14 @@ return array(
'javelin-behavior-aphlict-status' => 'ea681761',
'javelin-behavior-aphront-basic-tokenizer' => 'b3a4b884',
'javelin-behavior-aphront-crop' => 'fa0f4fc2',
'javelin-behavior-aphront-drag-and-drop-textarea' => '6d49590e',
'javelin-behavior-aphront-drag-and-drop-textarea' => '4f6a4b4e',
'javelin-behavior-aphront-form-disable-on-submit' => '5c54cbf3',
'javelin-behavior-aphront-more' => 'a80d0378',
'javelin-behavior-audio-source' => '59b251eb',
'javelin-behavior-audit-preview' => 'd835b03a',
'javelin-behavior-bulk-job-reload' => 'edf8a145',
'javelin-behavior-choose-control' => '6153c708',
'javelin-behavior-comment-actions' => 'f2c64202',
'javelin-behavior-choose-control' => 'dfaafb14',
'javelin-behavior-comment-actions' => 'b65559c0',
'javelin-behavior-config-reorder-fields' => 'b6993408',
'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a',
'javelin-behavior-conpherence-menu' => '1d45c74d',
@ -607,6 +605,7 @@ return array(
'javelin-behavior-doorkeeper-tag' => 'e5822781',
'javelin-behavior-drydock-live-operation-status' => '901935ef',
'javelin-behavior-durable-column' => 'c72aa091',
'javelin-behavior-editengine-reorder-configs' => 'd7a74243',
'javelin-behavior-editengine-reorder-fields' => 'b59e1e96',
'javelin-behavior-error-log' => '6882e80a',
'javelin-behavior-event-all-day' => '38dcf3c8',
@ -624,9 +623,6 @@ return array(
'javelin-behavior-maniphest-batch-selector' => '7b98d7c5',
'javelin-behavior-maniphest-list-editor' => 'a9f88de2',
'javelin-behavior-maniphest-subpriority-editor' => '71237763',
'javelin-behavior-maniphest-transaction-controls' => '44168bad',
'javelin-behavior-maniphest-transaction-expand' => '5fefb143',
'javelin-behavior-maniphest-transaction-preview' => '4c95d29e',
'javelin-behavior-owners-path-editor' => '7a68dda3',
'javelin-behavior-passphrase-credential-control' => '3cb0b2fc',
'javelin-behavior-persona-login' => '9414ff18',
@ -636,7 +632,7 @@ return array(
'javelin-behavior-phabricator-file-tree' => '88236f00',
'javelin-behavior-phabricator-gesture' => '3ab51e2c',
'javelin-behavior-phabricator-gesture-example' => '558829c2',
'javelin-behavior-phabricator-hovercards' => 'f36e01af',
'javelin-behavior-phabricator-hovercards' => '66dd6e9e',
'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0',
'javelin-behavior-phabricator-keyboard-shortcuts' => 'd75709e6',
'javelin-behavior-phabricator-line-linker' => '1499a8cb',
@ -644,7 +640,7 @@ return array(
'javelin-behavior-phabricator-notification-example' => '8ce821c5',
'javelin-behavior-phabricator-object-selector' => '49b73b36',
'javelin-behavior-phabricator-oncopy' => '2926fff2',
'javelin-behavior-phabricator-remarkup-assist' => 'eeaa9e5a',
'javelin-behavior-phabricator-remarkup-assist' => 'ecddcbe2',
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
'javelin-behavior-phabricator-search-typeahead' => '048330fa',
'javelin-behavior-phabricator-show-older-transactions' => 'dbbf48b6',
@ -652,18 +648,17 @@ return array(
'javelin-behavior-phabricator-transaction-comment-form' => 'b23b49e6',
'javelin-behavior-phabricator-transaction-list' => '13c739ea',
'javelin-behavior-phabricator-watch-anchor' => '9f36c42d',
'javelin-behavior-phame-post-preview' => 'd6bba572',
'javelin-behavior-pholio-mock-edit' => '246dc085',
'javelin-behavior-pholio-mock-view' => 'fbe497e7',
'javelin-behavior-phui-dropdown-menu' => '54733475',
'javelin-behavior-phui-object-box-tabs' => '2bfa2836',
'javelin-behavior-policy-control' => '7d470398',
'javelin-behavior-policy-control' => 'ae45872f',
'javelin-behavior-policy-rule-editor' => '5e9f347c',
'javelin-behavior-project-boards' => 'ba4fa35c',
'javelin-behavior-project-create' => '065227cc',
'javelin-behavior-quicksand-blacklist' => '7927a7d3',
'javelin-behavior-recurring-edit' => '5f1c4d5f',
'javelin-behavior-refresh-csrf' => '7814b593',
'javelin-behavior-refresh-csrf' => 'ab2f381b',
'javelin-behavior-releeph-preview-branch' => 'b2b4fbaf',
'javelin-behavior-releeph-request-state-change' => 'a0b57eb8',
'javelin-behavior-releeph-request-typeahead' => 'de2e896f',
@ -696,7 +691,7 @@ return array(
'javelin-leader' => '331b1611',
'javelin-magical-init' => '3010e992',
'javelin-mask' => '8a41885b',
'javelin-quicksand' => '4cebc641',
'javelin-quicksand' => '6b8ef10b',
'javelin-reactor' => '2b8de964',
'javelin-reactor-dom' => 'c90a04fc',
'javelin-reactor-node-calmer' => '76f4ebed',
@ -708,7 +703,7 @@ return array(
'javelin-scrollbar' => '087e919c',
'javelin-sound' => '949c0fe5',
'javelin-stratcom' => '6c53634d',
'javelin-tokenizer' => 'ab5f468d',
'javelin-tokenizer' => '8d3bc1b2',
'javelin-typeahead' => '70baed2f',
'javelin-typeahead-composite-source' => '503e17fd',
'javelin-typeahead-normalizer' => 'e6e25838',
@ -716,7 +711,7 @@ return array(
'javelin-typeahead-preloaded-source' => '54f314a0',
'javelin-typeahead-source' => '2818f5ce',
'javelin-typeahead-static-source' => '6c0e62fa',
'javelin-uri' => '6eff08aa',
'javelin-uri' => 'c989ade3',
'javelin-util' => '93cc50d6',
'javelin-vector' => '2caa8fb8',
'javelin-view' => '0f764c35',
@ -734,7 +729,7 @@ return array(
'multirow-row-manager' => 'b5d57730',
'owners-path-editor' => 'aa1733d0',
'owners-path-editor-css' => '2f00933b',
'paste-css' => 'b2f5a543',
'paste-css' => 'a5157c48',
'path-typeahead' => 'f7fc67ec',
'people-profile-css' => '25970776',
'phabricator-action-list-view-css' => 'c5eba19d',
@ -752,7 +747,7 @@ return array(
'phabricator-file-upload' => '477359c8',
'phabricator-filetree-view-css' => 'fccf9f82',
'phabricator-flag-css' => '5337623f',
'phabricator-hovercard' => '14ac66f5',
'phabricator-hovercard' => 'c6f720ff',
'phabricator-hovercard-view-css' => '1239cd52',
'phabricator-keyboard-shortcut' => '1ae869f2',
'phabricator-keyboard-shortcut-manager' => 'c1700f6f',
@ -763,15 +758,15 @@ return array(
'phabricator-notification-menu-css' => 'f31c0bde',
'phabricator-object-selector-css' => '85ee8ce6',
'phabricator-phtize' => 'd254d646',
'phabricator-prefab' => '6920d200',
'phabricator-remarkup-css' => 'b1c10368',
'phabricator-prefab' => '666c80c5',
'phabricator-remarkup-css' => '7afb543c',
'phabricator-search-results-css' => '7dea472c',
'phabricator-shaped-request' => '7cbe244b',
'phabricator-side-menu-view-css' => 'bec2458e',
'phabricator-slowvote-css' => 'da0afb1b',
'phabricator-source-code-view-css' => 'cbeef983',
'phabricator-standard-page-view' => '3c99cdf4',
'phabricator-textareautils' => '5c93c52c',
'phabricator-textareautils' => '9e54692d',
'phabricator-title' => 'df5e11d2',
'phabricator-tooltip' => '1d298e3a',
'phabricator-ui-example-css' => '528b19de',
@ -786,7 +781,7 @@ return array(
'phabricator-uiexample-reactor-sendclass' => '1def2711',
'phabricator-uiexample-reactor-sendproperties' => 'b1f0ccee',
'phabricator-zindex-css' => '57ddcaa2',
'phame-css' => 'cea3c9e1',
'phame-css' => '09a39e8d',
'pholio-css' => '95174bdd',
'pholio-edit-css' => '3ad9d1ee',
'pholio-inline-comments-css' => '8e545e49',
@ -797,6 +792,7 @@ return array(
'phriction-document-css' => 'd1861e06',
'phui-action-panel-css' => '91c7b835',
'phui-badge-view-css' => 'f25c3476',
'phui-big-info-view-css' => 'bd903741',
'phui-box-css' => 'a5bb366d',
'phui-button-css' => '16020a60',
'phui-calendar-css' => 'ccabe893',
@ -804,21 +800,21 @@ return array(
'phui-calendar-list-css' => 'c1c7f338',
'phui-calendar-month-css' => '476be7e0',
'phui-crumbs-view-css' => '414406b5',
'phui-document-summary-view-css' => '8c1e0aca',
'phui-document-summary-view-css' => '9ca48bdf',
'phui-document-view-css' => 'a4a1c3b9',
'phui-document-view-pro-css' => 'e0fad431',
'phui-feed-story-css' => 'b7b26d23',
'phui-font-icon-base-css' => 'ecbbb4c2',
'phui-fontkit-css' => '9cda225e',
'phui-form-css' => 'afdb2c6e',
'phui-form-view-css' => 'c1d2ef29',
'phui-form-css' => '0b98e572',
'phui-form-view-css' => '4a1a0f5e',
'phui-header-view-css' => '55bb32dd',
'phui-icon-view-css' => 'b0a6b1b6',
'phui-image-mask-css' => '5a8b09c8',
'phui-info-panel-css' => '27ea50a1',
'phui-info-view-css' => '6d7c3509',
'phui-inline-comment-view-css' => '0fdb3667',
'phui-list-view-css' => '125599df',
'phui-list-view-css' => '9da2aa00',
'phui-object-box-css' => '407eaf5a',
'phui-object-item-list-view-css' => '26c30d3f',
'phui-pager-css' => 'bea33d23',
@ -832,12 +828,12 @@ return array(
'phui-theme-css' => '6b451f24',
'phui-timeline-view-css' => '2efceff8',
'phui-two-column-view-css' => '39ecafb1',
'phui-workboard-view-css' => '6704d68d',
'phui-workboard-view-css' => '24fe2a66',
'phui-workpanel-view-css' => 'adec7699',
'phuix-action-list-view' => 'b5c256b8',
'phuix-action-view' => '8cf6d262',
'phuix-dropdown-menu' => 'bd4c8dca',
'phuix-form-control-view' => 'f9fba5ee',
'phuix-form-control-view' => '8fba1997',
'phuix-icon-view' => 'bff6884b',
'policy-css' => '957ea14c',
'policy-edit-css' => '815c66f7',
@ -939,13 +935,6 @@ return array(
'javelin-dom',
'javelin-history',
),
'14ac66f5' => array(
'javelin-install',
'javelin-dom',
'javelin-vector',
'javelin-request',
'javelin-uri',
),
'1ad0a787' => array(
'javelin-install',
'javelin-reactor',
@ -1095,11 +1084,6 @@ return array(
'javelin-dom',
'javelin-request',
),
'44168bad' => array(
'javelin-behavior',
'javelin-dom',
'phabricator-prefab',
),
'44959b73' => array(
'javelin-util',
'javelin-uri',
@ -1141,22 +1125,17 @@ return array(
'javelin-request',
'javelin-util',
),
'4c95d29e' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-json',
'javelin-stratcom',
'phabricator-shaped-request',
),
'4cebc641' => array(
'javelin-install',
),
'4e3e79a6' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
),
'4f6a4b4e' => array(
'javelin-behavior',
'javelin-dom',
'phabricator-drag-and-drop-file-upload',
'phabricator-textareautils',
),
'4fdb476d' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1244,16 +1223,20 @@ return array(
'javelin-uri',
'javelin-routable',
),
'5bd8f385' => array(
'multirow-row-manager',
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-stratcom',
'javelin-json',
'phabricator-prefab',
),
'5c54cbf3' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
),
'5c93c52c' => array(
'javelin-install',
'javelin-dom',
'javelin-vector',
),
'5d7c9f33' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1267,12 +1250,6 @@ return array(
'phabricator-prefab',
'javelin-json',
),
'5fefb143' => array(
'javelin-behavior',
'javelin-dom',
'javelin-workflow',
'javelin-stratcom',
),
60479091 => array(
'phabricator-busy',
'javelin-behavior',
@ -1282,12 +1259,6 @@ return array(
'javelin-stratcom',
'javelin-dom',
),
'6153c708' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-workflow',
),
'61cbc29a' => array(
'javelin-magical-init',
'javelin-util',
@ -1318,10 +1289,7 @@ return array(
'javelin-vector',
'differential-inline-comment-editor',
),
'6882e80a' => array(
'javelin-dom',
),
'6920d200' => array(
'666c80c5' => array(
'javelin-install',
'javelin-util',
'javelin-dom',
@ -1333,9 +1301,22 @@ return array(
'javelin-stratcom',
'javelin-util',
),
'66dd6e9e' => array(
'javelin-behavior',
'javelin-behavior-device',
'javelin-stratcom',
'javelin-vector',
'phabricator-hovercard',
),
'6882e80a' => array(
'javelin-dom',
),
'69adf288' => array(
'javelin-install',
),
'6b8ef10b' => array(
'javelin-install',
),
'6c0e62fa' => array(
'javelin-install',
'javelin-typeahead-source',
@ -1357,17 +1338,6 @@ return array(
'javelin-typeahead',
'javelin-uri',
),
'6d49590e' => array(
'javelin-behavior',
'javelin-dom',
'phabricator-drag-and-drop-file-upload',
'phabricator-textareautils',
),
'6eff08aa' => array(
'javelin-install',
'javelin-util',
'javelin-stratcom',
),
'70baed2f' => array(
'javelin-install',
'javelin-dom',
@ -1402,14 +1372,6 @@ return array(
'javelin-reactor',
'javelin-util',
),
'7814b593' => array(
'javelin-request',
'javelin-behavior',
'javelin-dom',
'javelin-router',
'javelin-util',
'phabricator-busy',
),
'782ab6e7' => array(
'javelin-behavior',
'javelin-dom',
@ -1438,15 +1400,6 @@ return array(
'javelin-request',
'javelin-router',
),
'7d470398' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'phuix-dropdown-menu',
'phuix-action-list-view',
'phuix-action-view',
'javelin-workflow',
),
'7e41274a' => array(
'javelin-install',
),
@ -1543,11 +1496,21 @@ return array(
'javelin-dom',
'javelin-util',
),
'8d3bc1b2' => array(
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-install',
),
'8ef9ab58' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
),
'8fba1997' => array(
'javelin-install',
'javelin-dom',
),
'9007c197' => array(
'javelin-behavior',
'javelin-dom',
@ -1558,15 +1521,6 @@ return array(
'javelin-dom',
'javelin-request',
),
'91a6031b' => array(
'multirow-row-manager',
'javelin-install',
'javelin-util',
'javelin-dom',
'javelin-stratcom',
'javelin-json',
'phabricator-prefab',
),
'93d0c9e3' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1598,6 +1552,11 @@ return array(
'javelin-dom',
'javelin-reactor-dom',
),
'9e54692d' => array(
'javelin-install',
'javelin-dom',
'javelin-vector',
),
'9f36c42d' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1681,11 +1640,13 @@ return array(
'javelin-util',
'phabricator-prefab',
),
'ab5f468d' => array(
'ab2f381b' => array(
'javelin-request',
'javelin-behavior',
'javelin-dom',
'javelin-router',
'javelin-util',
'javelin-stratcom',
'javelin-install',
'phabricator-busy',
),
'ad10aeac' => array(
'javelin-install',
@ -1695,6 +1656,15 @@ return array(
'javelin-uri',
'phabricator-file-upload',
),
'ae45872f' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'phuix-dropdown-menu',
'phuix-action-list-view',
'phuix-action-view',
'javelin-workflow',
),
'b064af76' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1751,6 +1721,15 @@ return array(
'javelin-dom',
'javelin-util',
),
'b65559c0' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'b6993408' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1794,6 +1773,13 @@ return array(
'javelin-dom',
'javelin-vector',
),
'c6f720ff' => array(
'javelin-install',
'javelin-dom',
'javelin-vector',
'javelin-request',
'javelin-uri',
),
'c72aa091' => array(
'javelin-behavior',
'javelin-dom',
@ -1822,6 +1808,11 @@ return array(
'javelin-install',
'javelin-util',
),
'c989ade3' => array(
'javelin-install',
'javelin-util',
'javelin-stratcom',
),
'ca3f91eb' => array(
'javelin-behavior',
'javelin-dom',
@ -1867,12 +1858,6 @@ return array(
'javelin-dom',
'javelin-stratcom',
),
'd6bba572' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'phabricator-shaped-request',
),
'd75709e6' => array(
'javelin-behavior',
'javelin-workflow',
@ -1880,6 +1865,13 @@ return array(
'javelin-dom',
'phabricator-keyboard-shortcut',
),
'd7a74243' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phabricator-draggable-list',
),
'd835b03a' => array(
'javelin-behavior',
'javelin-dom',
@ -1902,6 +1894,12 @@ return array(
'df5e11d2' => array(
'javelin-install',
),
'dfaafb14' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-workflow',
),
'e10f8e18' => array(
'javelin-behavior',
'javelin-dom',
@ -1962,6 +1960,15 @@ return array(
'phabricator-phtize',
'javelin-dom',
),
'ecddcbe2' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'phabricator-phtize',
'phabricator-textareautils',
'javelin-workflow',
'javelin-vector',
),
'edd1ba66' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1973,15 +1980,6 @@ return array(
'javelin-behavior',
'javelin-uri',
),
'eeaa9e5a' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'phabricator-phtize',
'phabricator-textareautils',
'javelin-workflow',
'javelin-vector',
),
'efe49472' => array(
'javelin-install',
'javelin-util',
@ -1993,21 +1991,6 @@ return array(
'javelin-workflow',
'javelin-json',
),
'f2c64202' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
),
'f36e01af' => array(
'javelin-behavior',
'javelin-behavior-device',
'javelin-stratcom',
'javelin-vector',
'phabricator-hovercard',
),
'f411b6ae' => array(
'javelin-behavior',
'javelin-stratcom',
@ -2057,10 +2040,6 @@ return array(
'javelin-util',
'phabricator-busy',
),
'f9fba5ee' => array(
'javelin-install',
'javelin-dom',
),
'fa0f4fc2' => array(
'javelin-behavior',
'javelin-dom',
@ -2291,9 +2270,6 @@ return array(
),
'maniphest.pkg.js' => array(
'javelin-behavior-maniphest-batch-selector',
'javelin-behavior-maniphest-transaction-controls',
'javelin-behavior-maniphest-transaction-preview',
'javelin-behavior-maniphest-transaction-expand',
'javelin-behavior-maniphest-subpriority-editor',
'javelin-behavior-maniphest-list-editor',
),

View file

@ -187,9 +187,6 @@ return array(
),
'maniphest.pkg.js' => array(
'javelin-behavior-maniphest-batch-selector',
'javelin-behavior-maniphest-transaction-controls',
'javelin-behavior-maniphest-transaction-preview',
'javelin-behavior-maniphest-transaction-expand',
'javelin-behavior-maniphest-subpriority-editor',
'javelin-behavior-maniphest-list-editor',
),

View file

@ -0,0 +1,11 @@
ALTER TABLE {$NAMESPACE}_search.search_editengineconfiguration
DROP editPolicy;
ALTER TABLE {$NAMESPACE}_search.search_editengineconfiguration
ADD isEdit BOOL NOT NULL;
ALTER TABLE {$NAMESPACE}_search.search_editengineconfiguration
ADD createOrder INT UNSIGNED NOT NULL;
ALTER TABLE {$NAMESPACE}_search.search_editengineconfiguration
ADD editOrder INT UNSIGNED NOT NULL;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_repository.repository_refcursor
ADD phid VARBINARY(64) NOT NULL AFTER id;

View file

@ -0,0 +1,17 @@
<?php
$table = new PhabricatorRepositoryRefCursor();
$conn_w = $table->establishConnection('w');
foreach (new LiskMigrationIterator($table) as $cursor) {
if (strlen($cursor->getPHID())) {
continue;
}
queryfx(
$conn_w,
'UPDATE %T SET phid = %s WHERE id = %d',
$table->getTableName(),
$table->generatePHID(),
$cursor->getID());
}

View file

@ -0,0 +1,5 @@
ALTER TABLE {$NAMESPACE}_phame.phame_post
DROP KEY phameTitle;
ALTER TABLE {$NAMESPACE}_phame.phame_post
CHANGE phameTitle phameTitle VARCHAR(64) COLLATE {$COLLATE_SORT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_auth.auth_sshkey
ADD phid VARBINARY(64) NOT NULL AFTER id;

View file

@ -0,0 +1,17 @@
<?php
$table = new PhabricatorAuthSSHKey();
$conn_w = $table->establishConnection('w');
foreach (new LiskMigrationIterator($table) as $cursor) {
if (strlen($cursor->getPHID())) {
continue;
}
queryfx(
$conn_w,
'UPDATE %T SET phid = %s WHERE id = %d',
$table->getTableName(),
$table->generatePHID(),
$cursor->getID());
}

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD COLUMN primarySlug VARCHAR(128) COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD UNIQUE KEY `key_primaryslug` (primarySlug);

View file

@ -0,0 +1,2 @@
UPDATE {$NAMESPACE}_project.project
SET primarySlug = TRIM(TRAILING "/" FROM phrictionSlug);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
DROP KEY `phrictionSlug`;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
DROP COLUMN phrictionSlug;

View file

@ -0,0 +1,28 @@
<?php
$app = PhabricatorApplication::getByClass('PhabricatorProjectApplication');
$view_policy = $app->getPolicy(ProjectDefaultViewCapability::CAPABILITY);
$edit_policy = $app->getPolicy(ProjectDefaultEditCapability::CAPABILITY);
$join_policy = $app->getPolicy(ProjectDefaultJoinCapability::CAPABILITY);
$table = new PhabricatorProject();
$conn_w = $table->establishConnection('w');
queryfx(
$conn_w,
'UPDATE %T SET viewPolicy = %s WHERE viewPolicy IS NULL',
$table->getTableName(),
$view_policy);
queryfx(
$conn_w,
'UPDATE %T SET editPolicy = %s WHERE editPolicy IS NULL',
$table->getTableName(),
$edit_policy);
queryfx(
$conn_w,
'UPDATE %T SET joinPolicy = %s WHERE joinPolicy IS NULL',
$table->getTableName(),
$join_policy);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
CHANGE viewPolicy viewPolicy VARBINARY(64) NOT NULL;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
CHANGE editPolicy editPolicy VARBINARY(64) NOT NULL;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
CHANGE joinPolicy joinPolicy VARBINARY(64) NOT NULL;

View file

@ -0,0 +1,17 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD parentProjectPHID VARBINARY(64);
ALTER TABLE {$NAMESPACE}_project.project
ADD hasWorkboard BOOL NOT NULL;
ALTER TABLE {$NAMESPACE}_project.project
ADD hasMilestones BOOL NOT NULL;
ALTER TABLE {$NAMESPACE}_project.project
ADD hasSubprojects BOOL NOT NULL;
ALTER TABLE {$NAMESPACE}_project.project
ADD milestoneNumber INT UNSIGNED;
ALTER TABLE {$NAMESPACE}_project.project
ADD UNIQUE KEY `key_milestone` (parentProjectPHID, milestoneNumber);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
DROP subprojectPHIDs;

View file

@ -0,0 +1,7 @@
CREATE TABLE {$NAMESPACE}_search.search_indexversion (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
objectPHID VARBINARY(64) NOT NULL,
extensionKey VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT},
version VARCHAR(128) NOT NULL COLLATE {$COLLATE_TEXT},
UNIQUE KEY `key_object` (objectPHID, extensionKey)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,7 @@
CREATE TABLE {$NAMESPACE}_owners.owners_name_ngrams (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
objectID INT UNSIGNED NOT NULL,
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
KEY `key_object` (objectID),
KEY `key_ngram` (ngram, objectID)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,11 @@
<?php
$table = new PhabricatorOwnersPackage();
foreach (new LiskMigrationIterator($table) as $package) {
PhabricatorSearchWorker::queueDocumentForIndexing(
$package->getPHID(),
array(
'force' => true,
));
}

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD projectPath VARBINARY(64) NOT NULL;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD projectDepth INT UNSIGNED NOT NULL;

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD KEY `key_path` (projectPath, projectDepth);

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD projectPathKey BINARY(4) NOT NULL;

View file

@ -0,0 +1,24 @@
<?php
$table = new PhabricatorProject();
$conn_w = $table->establishConnection('w');
foreach (new LiskMigrationIterator($table) as $project) {
$path = $project->getProjectPath();
$key = $project->getProjectPathKey();
if (strlen($path) && ($key !== "\0\0\0\0")) {
continue;
}
$path_key = PhabricatorHash::digestForIndex($project->getPHID());
$path_key = substr($path_key, 0, 4);
queryfx(
$conn_w,
'UPDATE %T SET projectPath = %s, projectPathKey = %s WHERE id = %d',
$project->getTableName(),
$path_key,
$path_key,
$project->getID());
}

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_project.project
ADD UNIQUE KEY `key_pathkey` (projectPathKey);

View file

@ -5,10 +5,10 @@ $root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline(pht('manage lipsum'));
$args->setTagline(pht('synthetic data generator'));
$args->setSynopsis(<<<EOSYNOPSIS
**lipsum** __command__ [__options__]
Manage Phabricator Test Data Generator.
Generate synthetic test data to make development easier.
EOSYNOPSIS
);

File diff suppressed because it is too large Load diff

View file

@ -236,6 +236,10 @@ final class AphrontRequest extends Phobject {
return 'X-Phabricator-Csrf';
}
public static function getViaHeaderName() {
return 'X-Phabricator-Via';
}
public function validateCSRF() {
$token_name = self::getCSRFTokenName();
$token = $this->getStr($token_name);

View file

@ -0,0 +1,32 @@
<?php
final class AlmanacPropertiesDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'almanac.properties';
public function getExtensionName() {
return pht('Almanac Properties');
}
public function canDestroyObject(
PhabricatorDestructionEngine $engine,
$object) {
return ($object instanceof AlmanacPropertyInterface);
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$table = new AlmanacProperty();
$conn_w = $table->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE objectPHID = %s',
$table->getTableName(),
$object->getPHID());
}
}

View file

@ -178,4 +178,16 @@ final class PhabricatorCommitSearchEngine
return $result;
}
protected function getNewUserBody() {
$view = id(new PHUIBigInfoView())
->setIcon('fa-check-circle-o')
->setTitle(pht('Welcome to Audit'))
->setDescription(
pht('Post-commit code review and auditing. Audits you are assigned '.
'to will appear here.'));
return $view;
}
}

View file

@ -14,6 +14,7 @@ final class PhabricatorAuthQueryPublicKeysConduitAPIMethod
protected function defineParamTypes() {
return array(
'ids' => 'optional list<id>',
'phids' => 'optional list<phid>',
'objectPHIDs' => 'optional list<phid>',
'keys' => 'optional list<string>',
) + self::getPagerParamTypes();
@ -34,6 +35,11 @@ final class PhabricatorAuthQueryPublicKeysConduitAPIMethod
$query->withIDs($ids);
}
$phids = $request->getValue('phids');
if ($phids !== null) {
$query->withPHIDs($phids);
}
$object_phids = $request->getValue('objectPHIDs');
if ($object_phids !== null) {
$query->withObjectPHIDs($object_phids);
@ -57,6 +63,7 @@ final class PhabricatorAuthQueryPublicKeysConduitAPIMethod
$data[] = array(
'id' => $public_key->getID(),
'name' => $public_key->getName(),
'phid' => $public_key->getPHID(),
'objectPHID' => $public_key->getObjectPHID(),
'isTrusted' => (bool)$public_key->getIsTrusted(),
'key' => $public_key->getEntireKey(),

View file

@ -214,14 +214,24 @@ final class PhabricatorAuthStartController
$request->getRequestURI());
}
$dialog = new AphrontDialogView();
$dialog->setUser($viewer);
$dialog->setTitle(pht('Login Required'));
$dialog->appendChild(pht('You must login to continue.'));
$dialog->addSubmitButton(pht('Login'));
$dialog->addCancelButton('/');
// Often, users end up here by clicking a disabled action link in the UI
// (for example, they might click "Edit Blocking Tasks" on a Maniphest
// task page). After they log in we want to send them back to that main
// object page if we can, since it's confusing to end up on a standalone
// page with only a dialog (particularly if that dialog is another error,
// like a policy exception).
return id(new AphrontDialogResponse())->setDialog($dialog);
$via_header = AphrontRequest::getViaHeaderName();
$via_uri = AphrontRequest::getHTTPHeader($via_header);
if (strlen($via_uri)) {
PhabricatorCookies::setNextURICookie($request, $via_uri, $force = true);
}
return $this->newDialog()
->setTitle(pht('Login Required'))
->appendParagraph(pht('You must login to take this action.'))
->addSubmitButton(pht('Login'))
->addCancelButton('/');
}

View file

@ -0,0 +1,38 @@
<?php
final class PhabricatorAuthSSHKeyPHIDType
extends PhabricatorPHIDType {
const TYPECONST = 'AKEY';
public function getTypeName() {
return pht('Public SSH Key');
}
public function newObject() {
return new PhabricatorAuthSSHKey();
}
public function getPHIDTypeApplicationClass() {
return 'PhabricatorAuthApplication';
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new PhabricatorAuthSSHKeyQuery())
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$key = $objects[$phid];
$handle->setName(pht('SSH Key %d', $key->getID()));
}
}
}

View file

@ -4,6 +4,7 @@ final class PhabricatorAuthSSHKeyQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $objectPHIDs;
private $keys;
@ -12,6 +13,11 @@ final class PhabricatorAuthSSHKeyQuery
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
@ -23,19 +29,12 @@ final class PhabricatorAuthSSHKeyQuery
return $this;
}
public function newResultObject() {
return new PhabricatorAuthSSHKey();
}
protected function loadPage() {
$table = new PhabricatorAuthSSHKey();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
return $this->loadStandardPage($this->newResultObject());
}
protected function willFilterPage(array $keys) {
@ -54,6 +53,7 @@ final class PhabricatorAuthSSHKeyQuery
// We must have an object, and that object must be a valid object for
// SSH keys.
if (!$object || !($object instanceof PhabricatorSSHPublicKeyInterface)) {
$this->didRejectResult($ssh_key);
unset($keys[$key]);
continue;
}
@ -64,19 +64,26 @@ final class PhabricatorAuthSSHKeyQuery
return $keys;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
@ -85,7 +92,7 @@ final class PhabricatorAuthSSHKeyQuery
$sql = array();
foreach ($this->keys as $key) {
$sql[] = qsprintf(
$conn_r,
$conn,
'(keyType = %s AND keyIndex = %s)',
$key->getType(),
$key->getHash());
@ -93,9 +100,8 @@ final class PhabricatorAuthSSHKeyQuery
$where[] = implode(' OR ', $sql);
}
$where[] = $this->buildPagingClause($conn_r);
return $where;
return $this->formatWhereClause($where);
}
public function getQueryApplicationClass() {

View file

@ -2,7 +2,9 @@
final class PhabricatorAuthSSHKey
extends PhabricatorAuthDAO
implements PhabricatorPolicyInterface {
implements
PhabricatorPolicyInterface,
PhabricatorDestructibleInterface {
protected $objectPHID;
protected $name;
@ -16,6 +18,7 @@ final class PhabricatorAuthSSHKey
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text255',
'keyType' => 'text255',
@ -63,8 +66,10 @@ final class PhabricatorAuthSSHKey
return $this;
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorAuthSSHKeyPHIDType::TYPECONST);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
@ -89,4 +94,15 @@ final class PhabricatorAuthSSHKey
'SSH keys inherit the policies of the user or object they authenticate.');
}
/* -( PhabricatorDestructibleInterface )----------------------------------- */
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$this->saveTransaction();
}
}

View file

@ -45,12 +45,10 @@ final class PhabricatorBadgesApplication extends PhabricatorApplication {
=> 'PhabricatorBadgesCommentController',
'edit/(?:(?P<id>\d+)/)?'
=> 'PhabricatorBadgesEditController',
'archive/(?:(?P<id>\d+)/)?'
=> 'PhabricatorBadgesArchiveController',
'view/(?:(?P<id>\d+)/)?'
=> 'PhabricatorBadgesViewController',
'icon/(?P<id>[1-9]\d*)/'
=> 'PhabricatorBadgesEditIconController',
'icon/'
=> 'PhabricatorBadgesEditIconController',
'recipients/(?P<id>[1-9]\d*)/'
=> 'PhabricatorBadgesEditRecipientsController',
'recipients/(?P<id>[1-9]\d*)/remove/'

View file

@ -0,0 +1,68 @@
<?php
final class PhabricatorBadgesArchiveController
extends PhabricatorBadgesController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$badge = id(new PhabricatorBadgesQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$badge) {
return new Aphront404Response();
}
$view_uri = $this->getApplicationURI('view/'.$badge->getID().'/');
if ($request->isFormPost()) {
if ($badge->isArchived()) {
$new_status = PhabricatorBadgesBadge::STATUS_ACTIVE;
} else {
$new_status = PhabricatorBadgesBadge::STATUS_ARCHIVED;
}
$xactions = array();
$xactions[] = id(new PhabricatorBadgesTransaction())
->setTransactionType(PhabricatorBadgesTransaction::TYPE_STATUS)
->setNewValue($new_status);
id(new PhabricatorBadgesEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true)
->applyTransactions($badge, $xactions);
return id(new AphrontRedirectResponse())->setURI($view_uri);
}
if ($badge->isArchived()) {
$title = pht('Activate Badge');
$body = pht('This badge will be re-commissioned into service.');
$button = pht('Activate Badge');
} else {
$title = pht('Archive Badge');
$body = pht(
'This dedicated badge, once a distinguish icon of this install, '.
'shall be immediately retired from service, but will never far from '.
'our hearts. Godspeed.');
$button = pht('Archive Badge');
}
return $this->newDialog()
->setTitle($title)
->appendChild($body)
->addCancelButton($view_uri)
->addSubmitButton($button);
}
}

View file

@ -43,14 +43,10 @@ final class PhabricatorBadgesEditController
$e_name = true;
$v_name = $badge->getName();
$v_icon = $badge->getIcon();
$v_flav = $badge->getFlavor();
$v_desc = $badge->getDescription();
$v_qual = $badge->getQuality();
$v_stat = $badge->getStatus();
$v_edit = $badge->getEditPolicy();
$validation_exception = null;
@ -59,7 +55,6 @@ final class PhabricatorBadgesEditController
$v_flav = $request->getStr('flavor');
$v_desc = $request->getStr('description');
$v_icon = $request->getStr('icon');
$v_stat = $request->getStr('status');
$v_qual = $request->getStr('quality');
$v_view = $request->getStr('viewPolicy');
@ -70,7 +65,6 @@ final class PhabricatorBadgesEditController
$type_desc = PhabricatorBadgesTransaction::TYPE_DESCRIPTION;
$type_icon = PhabricatorBadgesTransaction::TYPE_ICON;
$type_qual = PhabricatorBadgesTransaction::TYPE_QUALITY;
$type_stat = PhabricatorBadgesTransaction::TYPE_STATUS;
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
@ -96,10 +90,6 @@ final class PhabricatorBadgesEditController
->setTransactionType($type_qual)
->setNewValue($v_qual);
$xactions[] = id(new PhabricatorBadgesTransaction())
->setTransactionType($type_stat)
->setNewValue($v_stat);
$xactions[] = id(new PhabricatorBadgesTransaction())
->setTransactionType($type_edit)
->setNewValue($v_edit);
@ -121,13 +111,6 @@ final class PhabricatorBadgesEditController
}
}
if ($is_new) {
$icon_uri = $this->getApplicationURI('icon/');
} else {
$icon_uri = $this->getApplicationURI('icon/'.$badge->getID().'/');
}
$icon_display = PhabricatorBadgesIcon::renderIconForChooser($v_icon);
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($badge)
@ -147,12 +130,10 @@ final class PhabricatorBadgesEditController
->setLabel(pht('Flavor Text'))
->setValue($v_flav))
->appendChild(
id(new AphrontFormChooseButtonControl())
id(new PHUIFormIconSetControl())
->setLabel(pht('Icon'))
->setName('icon')
->setDisplayValue($icon_display)
->setButtonText(pht('Choose Icon...'))
->setChooseURI($icon_uri)
->setIconSet(new PhabricatorBadgesIconSet())
->setValue($v_icon))
->appendChild(
id(new AphrontFormSelectControl())
@ -160,12 +141,6 @@ final class PhabricatorBadgesEditController
->setLabel(pht('Quality'))
->setValue($v_qual)
->setOptions($badge->getQualityNameMap()))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Status'))
->setName('status')
->setValue($v_stat)
->setOptions($badge->getStatusNameMap()))
->appendChild(
id(new PhabricatorRemarkupControl())
->setUser($viewer)

View file

@ -1,101 +0,0 @@
<?php
final class PhabricatorBadgesEditIconController
extends PhabricatorBadgesController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$badge = id(new PhabricatorBadgesQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$badge) {
return new Aphront404Response();
}
$cancel_uri =
$this->getApplicationURI('view/'.$badge->getID().'/');
$badge_icon = $badge->getIcon();
} else {
$this->requireApplicationCapability(
PhabricatorBadgesCreateCapability::CAPABILITY);
$cancel_uri = '/badges/';
$badge_icon = $request->getStr('value');
}
require_celerity_resource('project-icon-css');
Javelin::initBehavior('phabricator-tooltips');
$badge_icons = PhabricatorBadgesIcon::getIconMap();
if ($request->isFormPost()) {
$v_icon = $request->getStr('icon');
return id(new AphrontAjaxResponse())->setContent(
array(
'value' => $v_icon,
'display' => PhabricatorBadgesIcon::renderIconForChooser($v_icon),
));
}
$ii = 0;
$buttons = array();
foreach ($badge_icons as $icon => $label) {
$view = id(new PHUIIconView())
->setIconFont($icon);
$aural = javelin_tag(
'span',
array(
'aural' => true,
),
pht('Choose "%s" Icon', $label));
if ($icon == $badge_icon) {
$class_extra = ' selected';
} else {
$class_extra = null;
}
$buttons[] = javelin_tag(
'button',
array(
'class' => 'icon-button'.$class_extra,
'name' => 'icon',
'value' => $icon,
'type' => 'submit',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $label,
),
),
array(
$aural,
$view,
));
if ((++$ii % 4) == 0) {
$buttons[] = phutil_tag('br');
}
}
$buttons = phutil_tag(
'div',
array(
'class' => 'icon-grid',
),
$buttons);
return $this->newDialog()
->setTitle(pht('Choose Badge Icon'))
->appendChild($buttons)
->addCancelButton($cancel_uri);
}
}

View file

@ -24,7 +24,7 @@ final class PhabricatorBadgesViewController
$crumbs->addTextCrumb($badge->getName());
$title = $badge->getName();
if ($badge->isClosed()) {
if ($badge->isArchived()) {
$status_icon = 'fa-ban';
$status_color = 'dark';
} else {
@ -85,7 +85,6 @@ final class PhabricatorBadgesViewController
->setObject($badge);
$quality = idx($badge->getQualityNameMap(), $badge->getQuality());
$icon = idx($badge->getIconNameMap(), $badge->getIcon());
$view->addProperty(
pht('Quality'),
@ -93,7 +92,8 @@ final class PhabricatorBadgesViewController
$view->addProperty(
pht('Icon'),
$icon);
id(new PhabricatorBadgesIconSet())
->getIconLabel($badge->getIcon()));
$view->addProperty(
pht('Flavor'),
@ -138,9 +138,26 @@ final class PhabricatorBadgesViewController
->setName(pht('Edit Badge'))
->setIcon('fa-pencil')
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit)
->setHref($this->getApplicationURI("/edit/{$id}/")));
if ($badge->isArchived()) {
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('Activate Badge'))
->setIcon('fa-check')
->setDisabled(!$can_edit)
->setWorkflow($can_edit)
->setHref($this->getApplicationURI("/archive/{$id}/")));
} else {
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('Archive Badge'))
->setIcon('fa-ban')
->setDisabled(!$can_edit)
->setWorkflow($can_edit)
->setHref($this->getApplicationURI("/archive/{$id}/")));
}
$view->addAction(
id(new PhabricatorActionView())
->setName('Manage Recipients')

View file

@ -194,7 +194,7 @@ final class PhabricatorBadgesEditor
$body = parent::buildMailBody($object, $xactions);
if (strlen($description)) {
$body->addRemarkupSeciton(
$body->addRemarkupSection(
pht('BADGE DESCRIPTION'),
$object->getDescription());
}

View file

@ -1,53 +0,0 @@
<?php
final class PhabricatorBadgesIcon extends Phobject {
public static function getIconMap() {
return
array(
'fa-star' => pht('Superstar'),
'fa-user' => pht('Average Person'),
'fa-bug' => pht('Ladybug'),
'fa-users' => pht('Triplets'),
'fa-book' => pht('Nominomicon'),
'fa-rocket' => pht('Escape Route'),
'fa-life-ring' => pht('Foam Circle'),
'fa-birthday-cake' => pht('Cake Day'),
'fa-camera-retro' => pht('Leica Enthusiast'),
'fa-beer' => pht('Liquid Lunch'),
'fa-gift' => pht('Free Stuff'),
'fa-eye' => pht('Eye See You'),
'fa-heart' => pht('Love is Love'),
'fa-trophy' => pht('Winner at Things'),
'fa-umbrella' => pht('Rain Defender'),
'fa-graduation-cap' => pht('In Debt'),
);
}
public static function getLabel($key) {
$map = self::getIconMap();
return $map[$key];
}
public static function getAPIName($key) {
return substr($key, 3);
}
public static function renderIconForChooser($icon) {
$badge_icons = self::getIconMap();
return phutil_tag(
'span',
array(),
array(
id(new PHUIIconView())->setIconFont($icon),
' ',
idx($badge_icons, $icon, pht('Unknown Icon')),
));
}
}

View file

@ -0,0 +1,45 @@
<?php
final class PhabricatorBadgesIconSet
extends PhabricatorIconSet {
const ICONSETKEY = 'badges';
public function getSelectIconTitleText() {
return pht('Choose Badge Icon');
}
protected function newIcons() {
$map = array(
'fa-star' => pht('Superstar'),
'fa-user' => pht('Average Person'),
'fa-bug' => pht('Ladybug'),
'fa-users' => pht('Triplets'),
'fa-book' => pht('Nominomicon'),
'fa-rocket' => pht('Escape Route'),
'fa-life-ring' => pht('Foam Circle'),
'fa-birthday-cake' => pht('Cake Day'),
'fa-camera-retro' => pht('Leica Enthusiast'),
'fa-beer' => pht('Liquid Lunch'),
'fa-gift' => pht('Free Stuff'),
'fa-eye' => pht('Eye See You'),
'fa-heart' => pht('Love is Love'),
'fa-trophy' => pht('Winner at Things'),
'fa-umbrella' => pht('Rain Defender'),
'fa-graduation-cap' => pht('In Debt'),
);
$icons = array();
foreach ($map as $key => $label) {
$icons[] = id(new PhabricatorIconSetIcon())
->setKey($key)
->setLabel($label);
}
return $icons;
}
}

View file

@ -35,7 +35,7 @@ final class PhabricatorBadgesPHIDType extends PhabricatorPHIDType {
$id = $badge->getID();
$name = $badge->getName();
if ($badge->isClosed()) {
if ($badge->isArchived()) {
$handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
}

View file

@ -84,7 +84,7 @@ final class PhabricatorBadgesSearchEngine
return $query->setParameter(
'statuses',
array(
PhabricatorBadgesBadge::STATUS_OPEN,
PhabricatorBadgesBadge::STATUS_ACTIVE,
));
}
@ -124,7 +124,7 @@ final class PhabricatorBadgesSearchEngine
->addAttribute($quality)
->addAttribute($badge->getFlavor());
if ($badge->isClosed()) {
if ($badge->isArchived()) {
$item->setDisabled(true);
$item->addIcon('fa-ban', pht('Archived'));
}
@ -140,4 +140,24 @@ final class PhabricatorBadgesSearchEngine
}
protected function getNewUserBody() {
$create_button = id(new PHUIButtonView())
->setTag('a')
->setText(pht('Create a Badge'))
->setHref('/badges/create/')
->setColor(PHUIButtonView::GREEN);
$icon = $this->getApplication()->getFontIcon();
$app_name = $this->getApplication()->getName();
$view = id(new PHUIBigInfoView())
->setIcon($icon)
->setTitle(pht('Welcome to %s', $app_name))
->setDescription(
pht('Badges let you award and distinguish special users '.
'throughout your instance.'))
->addAction($create_button);
return $view;
}
}

View file

@ -21,8 +21,8 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
private $recipientPHIDs = self::ATTACHABLE;
const STATUS_OPEN = 'open';
const STATUS_CLOSED = 'closed';
const STATUS_ACTIVE = 'open';
const STATUS_ARCHIVED = 'closed';
const DEFAULT_ICON = 'fa-star';
const DEFAULT_QUALITY = 'green';
@ -37,8 +37,8 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
public static function getStatusNameMap() {
return array(
self::STATUS_OPEN => pht('Active'),
self::STATUS_CLOSED => pht('Archived'),
self::STATUS_ACTIVE => pht('Active'),
self::STATUS_ARCHIVED => pht('Archived'),
);
}
@ -54,10 +54,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
);
}
public static function getIconNameMap() {
return PhabricatorBadgesIcon::getIconMap();
}
public static function initializeNewBadge(PhabricatorUser $actor) {
$app = id(new PhabricatorApplicationQuery())
->setViewer($actor)
@ -74,7 +70,7 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
->setQuality(self::DEFAULT_QUALITY)
->setCreatorPHID($actor->getPHID())
->setEditPolicy($edit_policy)
->setStatus(self::STATUS_OPEN);
->setStatus(self::STATUS_ACTIVE);
}
protected function getConfiguration() {
@ -102,8 +98,8 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
PhabricatorPHID::generateNewPHID(PhabricatorBadgesPHIDType::TYPECONST);
}
public function isClosed() {
return ($this->getStatus() == self::STATUS_CLOSED);
public function isArchived() {
return ($this->getStatus() == self::STATUS_ARCHIVED);
}
public function attachRecipientPHIDs(array $phids) {

View file

@ -78,9 +78,11 @@ final class PhabricatorBadgesTransaction
$this->renderHandleLink($author_phid),
$new);
} else {
$icon_map = PhabricatorBadgesBadge::getIconNameMap();
$icon_new = idx($icon_map, $new, $new);
$icon_old = idx($icon_map, $old, $old);
$set = new PhabricatorBadgesIconSet();
$icon_old = $set->getIconLabel($old);
$icon_new = $set->getIconLabel($new);
return pht(
'%s updated the icon for this badge from "%s" to "%s".',
$this->renderHandleLink($author_phid),
@ -155,12 +157,12 @@ final class PhabricatorBadgesTransaction
$this->renderHandleLink($object_phid));
case self::TYPE_STATUS:
switch ($new) {
case PhabricatorBadgesBadge::STATUS_OPEN:
case PhabricatorBadgesBadge::STATUS_ACTIVE:
return pht(
'%s activated %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
case PhabricatorBadgesBadge::STATUS_CLOSED:
case PhabricatorBadgesBadge::STATUS_ARCHIVED:
return pht(
'%s archived %s.',
$this->renderHandleLink($author_phid),

View file

@ -624,7 +624,7 @@ abstract class PhabricatorApplication
'(?P<id>[0-9]\d*)/)?'.
'(?:'.
'(?:'.
'(?P<editAction>parameters|nodefault|comment)'.
'(?P<editAction>parameters|nodefault|nocreate|nomanage|comment)'.
'|'.
'(?:form/(?P<formKey>[^/]+))'.
')'.

View file

@ -46,10 +46,6 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication {
'(?:query/(?P<queryKey>[^/]+)/(?:(?P<year>\d+)/'.
'(?P<month>\d+)/)?(?:(?P<day>\d+)/)?)?'
=> 'PhabricatorCalendarEventListController',
'icon/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCalendarEventEditIconController',
'icon/'
=> 'PhabricatorCalendarEventEditIconController',
'event/' => array(
'create/'
=> 'PhabricatorCalendarEventEditController',

View file

@ -499,18 +499,11 @@ final class PhabricatorCalendarEventEditController
->setUser($viewer)
->setDatasource(new PhabricatorMetaMTAMailableDatasource());
if ($this->isCreate()) {
$icon_uri = $this->getApplicationURI('icon/');
} else {
$icon_uri = $this->getApplicationURI('icon/'.$event->getID().'/');
}
$icon_display = PhabricatorCalendarIcon::renderIconForChooser($icon);
$icon = id(new AphrontFormChooseButtonControl())
$icon = id(new PHUIFormIconSetControl())
->setLabel(pht('Icon'))
->setName('icon')
->setDisplayValue($icon_display)
->setButtonText(pht('Choose Icon...'))
->setChooseURI($icon_uri)
->setIconSet(new PhabricatorCalendarIconSet())
->setValue($icon);
$form = id(new AphrontFormView())

View file

@ -1,97 +0,0 @@
<?php
final class PhabricatorCalendarEventEditIconController
extends PhabricatorCalendarController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getUser();
$id = $request->getURIData('id');
if ($id) {
$event = id(new PhabricatorCalendarEventQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$event) {
return new Aphront404Response();
}
$cancel_uri = $this->getApplicationURI('/E'.$event->getID());
$event_icon = $event->getIcon();
} else {
$cancel_uri = '/calendar/';
$event_icon = $request->getStr('value');
}
require_celerity_resource('calendar-icon-css');
Javelin::initBehavior('phabricator-tooltips');
$calendar_icons = PhabricatorCalendarIcon::getIconMap();
if ($request->isFormPost()) {
$v_icon = $request->getStr('icon');
return id(new AphrontAjaxResponse())->setContent(
array(
'value' => $v_icon,
'display' => PhabricatorCalendarIcon::renderIconForChooser($v_icon),
));
}
$ii = 0;
$buttons = array();
foreach ($calendar_icons as $icon => $label) {
$view = id(new PHUIIconView())
->setIconFont($icon);
$aural = javelin_tag(
'span',
array(
'aural' => true,
),
pht('Choose "%s" Icon', $label));
if ($icon == $event_icon) {
$class_extra = ' selected';
} else {
$class_extra = null;
}
$buttons[] = javelin_tag(
'button',
array(
'class' => 'icon-button'.$class_extra,
'name' => 'icon',
'value' => $icon,
'type' => 'submit',
'sigil' => 'has-tooltip',
'meta' => array(
'tip' => $label,
),
),
array(
$aural,
$view,
));
if ((++$ii % 4) == 0) {
$buttons[] = phutil_tag('br');
}
}
$buttons = phutil_tag(
'div',
array(
'class' => 'icon-grid',
),
$buttons);
return $this->newDialog()
->setTitle(pht('Choose Calendar Event Icon'))
->appendChild($buttons)
->addCancelButton($cancel_uri);
}
}

View file

@ -152,7 +152,6 @@ final class PhabricatorCalendarEventViewController
$is_attending = $event->getIsUserAttending($viewer->getPHID());
$actions = id(new PhabricatorActionListView())
->setObjectURI($this->getApplicationURI('event/'.$id.'/'))
->setUser($viewer)
->setObject($event);
@ -360,11 +359,10 @@ final class PhabricatorCalendarEventViewController
$properties->invokeWillRenderEvent();
$icon_display = PhabricatorCalendarIcon::renderIconForChooser(
$event->getIcon());
$properties->addProperty(
pht('Icon'),
$icon_display);
id(new PhabricatorCalendarIconSet())
->getIconLabel($event->getIcon()));
if (strlen($event->getDescription())) {
$description = PhabricatorMarkupEngine::renderOneObject(

View file

@ -1,49 +0,0 @@
<?php
final class PhabricatorCalendarIcon extends Phobject {
public static function getIconMap() {
return
array(
'fa-calendar' => pht('Default'),
'fa-glass' => pht('Party'),
'fa-plane' => pht('Travel'),
'fa-plus-square' => pht('Health / Appointment'),
'fa-rocket' => pht('Sabatical / Leave'),
'fa-home' => pht('Working From Home'),
'fa-tree' => pht('Holiday'),
'fa-gamepad' => pht('Staycation'),
'fa-coffee' => pht('Coffee Meeting'),
'fa-film' => pht('Movie'),
'fa-users' => pht('Meeting'),
'fa-cutlery' => pht('Meal'),
'fa-paw' => pht('Pet Activity'),
'fa-institution' => pht('Official Business'),
'fa-bus' => pht('Field Trip'),
'fa-microphone' => pht('Conference'),
);
}
public static function getLabel($key) {
$map = self::getIconMap();
return $map[$key];
}
public static function getAPIName($key) {
return substr($key, 3);
}
public static function renderIconForChooser($icon) {
$calendar_icons = self::getIconMap();
return phutil_tag(
'span',
array(),
array(
id(new PHUIIconView())->setIconFont($icon),
' ',
idx($calendar_icons, $icon, pht('Unknown Icon')),
));
}
}

View file

@ -0,0 +1,45 @@
<?php
final class PhabricatorCalendarIconSet
extends PhabricatorIconSet {
const ICONSETKEY = 'calendar.event';
public function getSelectIconTitleText() {
return pht('Choose Event Icon');
}
protected function newIcons() {
$map = array(
'fa-calendar' => pht('Default'),
'fa-glass' => pht('Party'),
'fa-plane' => pht('Travel'),
'fa-plus-square' => pht('Health / Appointment'),
'fa-rocket' => pht('Sabatical / Leave'),
'fa-home' => pht('Working From Home'),
'fa-tree' => pht('Holiday'),
'fa-gamepad' => pht('Staycation'),
'fa-coffee' => pht('Coffee Meeting'),
'fa-film' => pht('Movie'),
'fa-users' => pht('Meeting'),
'fa-cutlery' => pht('Meal'),
'fa-paw' => pht('Pet Activity'),
'fa-institution' => pht('Official Business'),
'fa-bus' => pht('Field Trip'),
'fa-microphone' => pht('Conference'),
);
$icons = array();
foreach ($map as $key => $label) {
$icons[] = id(new PhabricatorIconSetIcon())
->setKey($key)
->setLabel($label);
}
return $icons;
}
}

View file

@ -0,0 +1,39 @@
<?php
final class PhabricatorCalendarEventFulltextEngine
extends PhabricatorFulltextEngine {
protected function buildAbstractDocument(
PhabricatorSearchAbstractDocument $document,
$object) {
$event = $object;
$document->setDocumentTitle($event->getName());
$document->addField(
PhabricatorSearchDocumentFieldType::FIELD_BODY,
$event->getDescription());
$document->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
$event->getUserPHID(),
PhabricatorPeopleUserPHIDType::TYPECONST,
$event->getDateCreated());
$document->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
$event->getUserPHID(),
PhabricatorPeopleUserPHIDType::TYPECONST,
$event->getDateCreated());
$document->addRelationship(
$event->getIsCancelled()
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$event->getPHID(),
PhabricatorCalendarEventPHIDType::TYPECONST,
PhabricatorTime::getNow());
}
}

View file

@ -1,52 +0,0 @@
<?php
final class PhabricatorCalendarEventSearchIndexer
extends PhabricatorSearchDocumentIndexer {
public function getIndexableObject() {
return new PhabricatorCalendarEvent();
}
protected function buildAbstractDocumentByPHID($phid) {
$event = $this->loadDocumentByPHID($phid);
$doc = new PhabricatorSearchAbstractDocument();
$doc->setPHID($event->getPHID());
$doc->setDocumentType(PhabricatorCalendarEventPHIDType::TYPECONST);
$doc->setDocumentTitle($event->getName());
$doc->setDocumentCreated($event->getDateCreated());
$doc->setDocumentModified($event->getDateModified());
$doc->addField(
PhabricatorSearchDocumentFieldType::FIELD_BODY,
$event->getDescription());
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR,
$event->getUserPHID(),
PhabricatorPeopleUserPHIDType::TYPECONST,
$event->getDateCreated());
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OWNER,
$event->getUserPHID(),
PhabricatorPeopleUserPHIDType::TYPECONST,
$event->getDateCreated());
$doc->addRelationship(
$event->getIsCancelled()
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$event->getPHID(),
PhabricatorCalendarEventPHIDType::TYPECONST,
time());
$this->indexTransactions(
$doc,
new PhabricatorCalendarEventTransactionQuery(),
array($phid));
return $doc;
}
}

View file

@ -10,7 +10,8 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
PhabricatorDestructibleInterface,
PhabricatorMentionableInterface,
PhabricatorFlaggableInterface,
PhabricatorSpacesInterface {
PhabricatorSpacesInterface,
PhabricatorFulltextInterface {
protected $name;
protected $userPHID;
@ -562,4 +563,13 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
public function getSpacePHID() {
return $this->spacePHID;
}
/* -( PhabricatorFulltextInterface )--------------------------------------- */
public function newFulltextEngine() {
return new PhabricatorCalendarEventFulltextEngine();
}
}

View file

@ -156,10 +156,11 @@ final class PhabricatorCalendarEventTransaction
$this->renderHandleLink($author_phid));
}
case self::TYPE_ICON:
$set = new PhabricatorCalendarIconSet();
return pht(
'%s set this event\'s icon to %s.',
$this->renderHandleLink($author_phid),
PhabricatorCalendarIcon::getLabel($new));
$set->getIconLabel($new));
break;
case self::TYPE_CANCEL:
if ($new) {
@ -356,11 +357,12 @@ final class PhabricatorCalendarEventTransaction
$this->renderHandleLink($object_phid));
}
case self::TYPE_ICON:
$set = new PhabricatorCalendarIconSet();
return pht(
'%s set the icon for %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
PhabricatorCalendarIcon::getLabel($new));
$set->getIconLabel($new));
case self::TYPE_CANCEL:
if ($new) {
return pht(

View file

@ -17,8 +17,8 @@ final class PhabricatorConduitApplication extends PhabricatorApplication {
public function getHelpDocumentationArticles(PhabricatorUser $viewer) {
return array(
array(
'name' => pht('Conduit Technical Documentation'),
'href' => PhabricatorEnv::getDoclink('Conduit Technical Documentation'),
'name' => pht('Conduit API Overview'),
'href' => PhabricatorEnv::getDoclink('Conduit API Overview'),
),
);
}
@ -48,7 +48,8 @@ final class PhabricatorConduitApplication extends PhabricatorApplication {
'/conduit/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorConduitListController',
'method/(?P<method>[^/]+)/' => 'PhabricatorConduitConsoleController',
'log/' => 'PhabricatorConduitLogController',
'log/(?:query/(?P<queryKey>[^/]+)/)?' =>
'PhabricatorConduitLogController',
'log/view/(?P<view>[^/]+)/' => 'PhabricatorConduitLogController',
'token/' => 'PhabricatorConduitTokenController',
'token/edit/(?:(?P<id>\d+)/)?' =>

View file

@ -1,65 +0,0 @@
<?php
final class ConduitDeprecatedCallSetupCheck extends PhabricatorSetupCheck {
protected function executeChecks() {
$methods = id(new PhabricatorConduitMethodQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIsDeprecated(true)
->execute();
if (!$methods) {
return;
}
$methods = mpull($methods, null, 'getAPIMethodName');
$method_names = mpull($methods, 'getAPIMethodName');
$table = new PhabricatorConduitMethodCallLog();
$conn_r = $table->establishConnection('r');
$calls = queryfx_all(
$conn_r,
'SELECT DISTINCT method FROM %T WHERE dateCreated > %d
AND method IN (%Ls)',
$table->getTableName(),
time() - (60 * 60 * 24 * 30),
$method_names);
$calls = ipull($calls, 'method', 'method');
foreach ($calls as $method_name) {
$method = $methods[$method_name];
$summary = pht(
'Deprecated Conduit method `%s` was called in the last 30 days. '.
'You should migrate away from use of this method: it will be '.
'removed in a future version of Phabricator.',
$method_name);
$uri = PhabricatorEnv::getURI('/conduit/log/?methods='.$method_name);
$description = $method->getMethodStatusDescription();
$message = pht(
'Deprecated Conduit method %s was called in the last 30 days. '.
'You should migrate away from use of this method: it will be '.
'removed in a future version of Phabricator.'.
"\n\n".
"%s: %s".
"\n\n".
'If you have already migrated all callers away from this method, '.
'you can safely ignore this setup issue.',
phutil_tag('tt', array(), $method_name),
phutil_tag('tt', array(), $method_name),
$description);
$this
->newIssue('conduit.deprecated.'.$method_name)
->setShortName(pht('Deprecated Conduit Method'))
->setName(pht('Deprecated Conduit Method "%s" In Use', $method_name))
->setSummary($summary)
->setMessage($message)
->addLink($uri, pht('View Method Call Logs'));
}
}
}

View file

@ -110,19 +110,11 @@ final class PhabricatorConduitAPIController
$time_end = microtime(true);
$connection_id = null;
if (idx($metadata, 'connectionID')) {
$connection_id = $metadata['connectionID'];
} else if (($method == 'conduit.connect') && $result) {
$connection_id = idx($result, 'connectionID');
}
$log
->setCallerPHID(
isset($conduit_user)
? $conduit_user->getPHID()
: null)
->setConnectionID($connection_id)
->setError((string)$error_code)
->setDuration(1000000 * ($time_end - $time_start));

View file

@ -19,6 +19,8 @@ final class PhabricatorConduitConsoleController
return new Aphront404Response();
}
$method->setViewer($viewer);
$call_uri = '/api/'.$method->getAPIMethodName();
$status = $method->getMethodStatus();
@ -99,65 +101,10 @@ final class PhabricatorConduitConsoleController
->appendChild($properties);
$content[] = $info_box;
$content[] = $method->getMethodDocumentation();
$content[] = $form_box;
$content[] = $this->renderExampleBox($method, null);
$query = $method->newQueryObject();
if ($query) {
$orders = $query->getBuiltinOrders();
$rows = array();
foreach ($orders as $key => $order) {
$rows[] = array(
$key,
$order['name'],
implode(', ', $order['vector']),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Key'),
pht('Description'),
pht('Columns'),
))
->setColumnClasses(
array(
'pri',
'',
'wide',
));
$content[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Builtin Orders'))
->setTable($table);
$columns = $query->getOrderableColumns();
$rows = array();
foreach ($columns as $key => $column) {
$rows[] = array(
$key,
idx($column, 'unique') ? pht('Yes') : pht('No'),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Key'),
pht('Unique'),
))
->setColumnClasses(
array(
'pri',
'wide',
));
$content[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Column Orders'))
->setTable($table);
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($method->getAPIMethodName());

View file

@ -4,127 +4,9 @@ final class PhabricatorConduitLogController
extends PhabricatorConduitController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$conn_table = new PhabricatorConduitConnectionLog();
$call_table = new PhabricatorConduitMethodCallLog();
$conn_r = $call_table->establishConnection('r');
$pager = new AphrontCursorPagerView();
$pager->readFromRequest($request);
$pager->setPageSize(500);
$query = id(new PhabricatorConduitLogQuery())
->setViewer($viewer);
$methods = $request->getStrList('methods');
if ($methods) {
$query->withMethods($methods);
}
$calls = $query->executeWithCursorPager($pager);
$conn_ids = array_filter(mpull($calls, 'getConnectionID'));
$conns = array();
if ($conn_ids) {
$conns = $conn_table->loadAllWhere(
'id IN (%Ld)',
$conn_ids);
}
$table = $this->renderCallTable($calls, $conns);
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Call Logs'))
->setTable($table);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Call Logs'));
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$pager,
),
array(
'title' => pht('Conduit Logs'),
));
}
private function renderCallTable(array $calls, array $conns) {
assert_instances_of($calls, 'PhabricatorConduitMethodCallLog');
assert_instances_of($conns, 'PhabricatorConduitConnectionLog');
$viewer = $this->getRequest()->getUser();
$methods = id(new PhabricatorConduitMethodQuery())
->setViewer($viewer)
->execute();
$methods = mpull($methods, null, 'getAPIMethodName');
$rows = array();
foreach ($calls as $call) {
$conn = idx($conns, $call->getConnectionID());
if ($conn) {
$name = $conn->getUserName();
$client = ' '.pht('(via %s)', $conn->getClient());
} else {
$name = null;
$client = null;
}
$method = idx($methods, $call->getMethod());
if ($method) {
switch ($method->getMethodStatus()) {
case ConduitAPIMethod::METHOD_STATUS_STABLE:
$status = null;
break;
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
$status = pht('Unstable');
break;
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
$status = pht('Deprecated');
break;
}
} else {
$status = pht('Unknown');
}
$rows[] = array(
$call->getConnectionID(),
$name,
array($call->getMethod(), $client),
$status,
$call->getError(),
pht('%s us', new PhutilNumber($call->getDuration())),
phabricator_datetime($call->getDateCreated(), $viewer),
);
}
$table = id(new AphrontTableView($rows));
$table->setHeaders(
array(
pht('Connection'),
pht('User'),
pht('Method'),
pht('Status'),
pht('Error'),
pht('Duration'),
pht('Date'),
));
$table->setColumnClasses(
array(
'',
'',
'wide',
'',
'',
'n',
'right',
));
return $table;
return id(new PhabricatorConduitLogSearchEngine())
->setController($this)
->buildResponse();
}
}

View file

@ -1,30 +0,0 @@
<?php
final class ConduitConnectionGarbageCollector
extends PhabricatorGarbageCollector {
const COLLECTORCONST = 'conduit.connections';
public function getCollectorName() {
return pht('Conduit Connections');
}
public function getDefaultRetentionPolicy() {
return phutil_units('180 days in seconds');
}
protected function collectGarbage() {
$table = new PhabricatorConduitConnectionLog();
$conn_w = $table->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE dateCreated < %d
ORDER BY dateCreated ASC LIMIT 100',
$table->getTableName(),
$this->getGarbageEpoch());
return ($conn_w->getAffectedRows() == 100);
}
}

View file

@ -0,0 +1,36 @@
<?php
interface PhabricatorConduitResultInterface
extends PhabricatorPHIDInterface {
public function getFieldSpecificationsForConduit();
public function getFieldValuesForConduit();
public function getConduitSearchAttachments();
}
// TEMPLATE IMPLEMENTATION /////////////////////////////////////////////////////
/* -( PhabricatorConduitResultInterface )---------------------------------- */
/*
public function getFieldSpecificationsForConduit() {
return array(
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('name')
->setType('string')
->setDescription(pht('The name of the object.')),
);
}
public function getFieldValuesForConduit() {
return array(
'name' => $this->getName(),
);
}
public function getConduitSearchAttachments() {
return array();
}
*/

View file

@ -0,0 +1,37 @@
<?php
final class PhabricatorConduitSearchFieldSpecification
extends Phobject {
private $key;
private $type;
private $description;
public function setKey($key) {
$this->key = $key;
return $this;
}
public function getKey() {
return $this->key;
}
public function setType($type) {
$this->type = $type;
return $this;
}
public function getType() {
return $this->type;
}
public function setDescription($description) {
$this->description = $description;
return $this;
}
public function getDescription() {
return $this->description;
}
}

View file

@ -9,6 +9,7 @@ abstract class ConduitAPIMethod
extends Phobject
implements PhabricatorPolicyInterface {
private $viewer;
const METHOD_STATUS_STABLE = 'stable';
const METHOD_STATUS_UNSTABLE = 'unstable';
@ -36,6 +37,10 @@ abstract class ConduitAPIMethod
*/
abstract public function getMethodDescription();
public function getMethodDocumentation() {
return null;
}
abstract protected function defineParamTypes();
abstract protected function defineReturnType();
@ -46,8 +51,6 @@ abstract class ConduitAPIMethod
abstract protected function execute(ConduitAPIRequest $request);
public function __construct() {}
public function getParamTypes() {
$types = $this->defineParamTypes();
@ -110,6 +113,8 @@ abstract class ConduitAPIMethod
}
public function executeMethod(ConduitAPIRequest $request) {
$this->setViewer($request->getUser());
return $this->execute($request);
}
@ -134,6 +139,16 @@ abstract class ConduitAPIMethod
return "{$head}.{$ord}.{$tail}";
}
public static function getMethodStatusMap() {
$map = array(
self::METHOD_STATUS_STABLE => pht('Stable'),
self::METHOD_STATUS_UNSTABLE => pht('Unstable'),
self::METHOD_STATUS_DEPRECATED => pht('Deprecated'),
);
return $map;
}
public function getApplicationName() {
return head(explode('.', $this->getAPIMethodName(), 2));
}
@ -211,6 +226,15 @@ abstract class ConduitAPIMethod
return null;
}
final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
final public function getViewer() {
return $this->viewer;
}
/* -( Paging Results )----------------------------------------------------- */

View file

@ -63,14 +63,6 @@ final class ConduitConnectConduitAPIMethod extends ConduitAPIMethod {
->truncateString($client_description);
$username = (string)$request->getValue('user');
// Log the connection, regardless of the outcome of checks below.
$connection = new PhabricatorConduitConnectionLog();
$connection->setClient($client);
$connection->setClientVersion($client_version);
$connection->setClientDescription($client_description);
$connection->setUsername($username);
$connection->save();
switch ($client) {
case 'arc':
$server_version = 6;
@ -154,7 +146,7 @@ final class ConduitConnectConduitAPIMethod extends ConduitAPIMethod {
}
return array(
'connectionID' => $connection->getID(),
'connectionID' => mt_rand(),
'sessionKey' => $session_key,
'userPHID' => $user->getPHID(),
);

View file

@ -0,0 +1,36 @@
<?php
final class ConduitBoolParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$value = parent::getParameterValue($request, $key);
if (!is_bool($value)) {
$this->raiseValidationException(
$request,
$key,
pht('Expected boolean (true or false), got something else.'));
}
return $value;
}
protected function getParameterTypeName() {
return 'bool';
}
protected function getParameterFormatDescriptions() {
return array(
pht('A boolean.'),
);
}
protected function getParameterExamples() {
return array(
'true',
'false',
);
}
}

View file

@ -0,0 +1,42 @@
<?php
final class ConduitEpochParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$value = parent::getParameterValue($request, $key);
if (!is_int($value)) {
$this->raiseValidationException(
$request,
$key,
pht('Expected epoch timestamp as integer, got something else.'));
}
if ($value <= 0) {
$this->raiseValidationException(
$request,
$key,
pht('Epoch timestamp must be larger than 0, got %d.', $value));
}
return $value;
}
protected function getParameterTypeName() {
return 'epoch';
}
protected function getParameterFormatDescriptions() {
return array(
pht('Epoch timestamp, as an integer.'),
);
}
protected function getParameterExamples() {
return array(
'1450019509',
);
}
}

View file

@ -0,0 +1,40 @@
<?php
final class ConduitIntListParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$list = parent::getParameterValue($request, $key);
foreach ($list as $idx => $item) {
if (!is_int($item)) {
$this->raiseValidationException(
$request,
$key,
pht(
'Expected a list of integers, but item with index "%s" is '.
'not an integer.',
$idx));
}
}
return $list;
}
protected function getParameterTypeName() {
return 'list<int>';
}
protected function getParameterFormatDescriptions() {
return array(
pht('List of integers.'),
);
}
protected function getParameterExamples() {
return array(
'[123, 0, -456]',
);
}
}

View file

@ -0,0 +1,37 @@
<?php
final class ConduitIntParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$value = parent::getParameterValue($request, $key);
if (!is_int($value)) {
$this->raiseValidationException(
$request,
$key,
pht('Expected integer, got something else.'));
}
return $value;
}
protected function getParameterTypeName() {
return 'int';
}
protected function getParameterFormatDescriptions() {
return array(
pht('An integer.'),
);
}
protected function getParameterExamples() {
return array(
'123',
'0',
'-345',
);
}
}

View file

@ -0,0 +1,53 @@
<?php
abstract class ConduitListParameterType
extends ConduitParameterType {
protected function getParameterValue(array $request, $key) {
$value = parent::getParameterValue($request, $key);
if (!is_array($value)) {
$this->raiseValidationException(
$request,
$key,
pht('Expected a list, but value is not a list.'));
}
$actual_keys = array_keys($value);
if ($value) {
$natural_keys = range(0, count($value) - 1);
} else {
$natural_keys = array();
}
if ($actual_keys !== $natural_keys) {
$this->raiseValidationException(
$request,
$key,
pht('Expected a list, but value is an object.'));
}
return $value;
}
protected function validateStringList(array $request, $key, array $list) {
foreach ($list as $idx => $item) {
if (!is_string($item)) {
$this->raiseValidationException(
$request,
$key,
pht(
'Expected a list of strings, but item with index "%s" is '.
'not a string.',
$idx));
}
}
return $list;
}
protected function getParameterDefault() {
return array();
}
}

View file

@ -0,0 +1,27 @@
<?php
final class ConduitPHIDListParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$list = parent::getParameterValue($request, $key);
return $this->validateStringList($request, $key, $list);
}
protected function getParameterTypeName() {
return 'list<phid>';
}
protected function getParameterFormatDescriptions() {
return array(
pht('List of PHIDs.'),
);
}
protected function getParameterExamples() {
return array(
'["PHID-WXYZ-1111", "PHID-WXYZ-2222"]',
);
}
}

View file

@ -0,0 +1,35 @@
<?php
final class ConduitPHIDParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$value = parent::getParameterValue($request, $key);
if (!is_string($value)) {
$this->raiseValidationException(
$request,
$key,
pht('Expected PHID, got something else.'));
}
return $value;
}
protected function getParameterTypeName() {
return 'phid';
}
protected function getParameterFormatDescriptions() {
return array(
pht('A PHID.'),
);
}
protected function getParameterExamples() {
return array(
'"PHID-WXYZ-1111222233334444"',
);
}
}

View file

@ -0,0 +1,97 @@
<?php
/**
* Defines how to read a value from a Conduit request.
*
* This class behaves like @{class:AphrontHTTPParameterType}, but for Conduit.
*/
abstract class ConduitParameterType extends Phobject {
private $viewer;
final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
final public function getViewer() {
if (!$this->viewer) {
throw new PhutilInvalidStateException('setViewer');
}
return $this->viewer;
}
final public function getExists(array $request, $key) {
return $this->getParameterExists($request, $key);
}
final public function getValue(array $request, $key) {
if (!$this->getExists($request, $key)) {
return $this->getParameterDefault();
}
return $this->getParameterValue($request, $key);
}
final public function getDefaultValue() {
return $this->getParameterDefault();
}
final public function getTypeName() {
return $this->getParameterTypeName();
}
final public function getFormatDescriptions() {
return $this->getParameterFormatDescriptions();
}
final public function getExamples() {
return $this->getParameterExamples();
}
protected function raiseValidationException(array $request, $key, $message) {
// TODO: Specialize this so we can give users more tailored messages from
// Conduit.
throw new Exception($message);
}
final public static function getAllTypes() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getTypeName')
->setSortMethod('getTypeName')
->execute();
}
protected function getParameterExists(array $request, $key) {
return array_key_exists($key, $request);
}
protected function getParameterValue(array $request, $key) {
return $request[$key];
}
abstract protected function getParameterTypeName();
abstract protected function getParameterFormatDescriptions();
abstract protected function getParameterExamples();
protected function getParameterDefault() {
return null;
}
}

View file

@ -0,0 +1,34 @@
<?php
final class ConduitProjectListParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$list = parent::getParameterValue($request, $key);
$list = $this->validateStringList($request, $key, $list);
return id(new PhabricatorProjectPHIDResolver())
->setViewer($this->getViewer())
->resolvePHIDs($list);
}
protected function getParameterTypeName() {
return 'list<project>';
}
protected function getParameterFormatDescriptions() {
return array(
pht('List of project PHIDs.'),
pht('List of project tags.'),
pht('List with a mixture of PHIDs and tags.'),
);
}
protected function getParameterExamples() {
return array(
'["PHID-PROJ-1111"]',
'["backend"]',
'["PHID-PROJ-2222", "frontend"]',
);
}
}

View file

@ -0,0 +1,27 @@
<?php
final class ConduitStringListParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$list = parent::getParameterValue($request, $key);
return $this->validateStringList($request, $key, $list);
}
protected function getParameterTypeName() {
return 'list<string>';
}
protected function getParameterFormatDescriptions() {
return array(
pht('List of strings.'),
);
}
protected function getParameterExamples() {
return array(
'["mango", "nectarine"]',
);
}
}

View file

@ -0,0 +1,35 @@
<?php
final class ConduitStringParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$value = parent::getParameterValue($request, $key);
if (!is_string($value)) {
$this->raiseValidationException(
$request,
$key,
pht('Expected string, got something else.'));
}
return $value;
}
protected function getParameterTypeName() {
return 'string';
}
protected function getParameterFormatDescriptions() {
return array(
pht('A string.'),
);
}
protected function getParameterExamples() {
return array(
'"papaya"',
);
}
}

View file

@ -0,0 +1,34 @@
<?php
final class ConduitUserListParameterType
extends ConduitListParameterType {
protected function getParameterValue(array $request, $key) {
$list = parent::getParameterValue($request, $key);
$list = $this->validateStringList($request, $key, $list);
return id(new PhabricatorUserPHIDResolver())
->setViewer($this->getViewer())
->resolvePHIDs($list);
}
protected function getParameterTypeName() {
return 'list<user>';
}
protected function getParameterFormatDescriptions() {
return array(
pht('List of user PHIDs.'),
pht('List of usernames.'),
pht('List with a mixture of PHIDs and usernames.'),
);
}
protected function getParameterExamples() {
return array(
'["PHID-USER-1111"]',
'["alincoln"]',
'["PHID-USER-2222", "alincoln"]',
);
}
}

View file

@ -0,0 +1,22 @@
<?php
final class ConduitWildParameterType
extends ConduitListParameterType {
protected function getParameterTypeName() {
return 'wild';
}
protected function getParameterFormatDescriptions() {
return array(
pht('Any mixed or complex value. Check the documentation for details.'),
);
}
protected function getParameterExamples() {
return array(
pht('(Wildcard)'),
);
}
}

View file

@ -14,6 +14,10 @@ final class ConduitAPIRequest extends Phobject {
return coalesce(idx($this->params, $key), $default);
}
public function getValueExists($key) {
return array_key_exists($key, $this->params);
}
public function getAllParameters() {
return $this->params;
}

View file

@ -0,0 +1,36 @@
<?php
final class ConduitResultSearchEngineExtension
extends PhabricatorSearchEngineExtension {
const EXTENSIONKEY = 'conduit';
public function isExtensionEnabled() {
return true;
}
public function getExtensionOrder() {
return 1500;
}
public function getExtensionName() {
return pht('Support for ConduitResultInterface');
}
public function supportsObject($object) {
return ($object instanceof PhabricatorConduitResultInterface);
}
public function getFieldSpecificationsForConduit($object) {
return $object->getFieldSpecificationsForConduit();
}
public function getFieldValuesForConduit($object) {
return $object->getFieldValuesForConduit();
}
public function getSearchAttachments($object) {
return $object->getConduitSearchAttachments();
}
}

View file

@ -3,40 +3,76 @@
final class PhabricatorConduitLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $callerPHIDs;
private $methods;
private $methodStatuses;
public function withCallerPHIDs(array $phids) {
$this->callerPHIDs = $phids;
return $this;
}
public function withMethods(array $methods) {
$this->methods = $methods;
return $this;
}
protected function loadPage() {
$table = new PhabricatorConduitMethodCallLog();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
public function withMethodStatuses(array $statuses) {
$this->methodStatuses = $statuses;
return $this;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
public function newResultObject() {
return new PhabricatorConduitMethodCallLog();
}
if ($this->methods) {
protected function loadPage() {
return $this->loadStandardPage($this->newResultObject());
}
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
if ($this->callerPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'callerPHID IN (%Ls)',
$this->callerPHIDs);
}
if ($this->methods !== null) {
$where[] = qsprintf(
$conn,
'method IN (%Ls)',
$this->methods);
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
if ($this->methodStatuses !== null) {
$statuses = array_fuse($this->methodStatuses);
$methods = id(new PhabricatorConduitMethodQuery())
->setViewer($this->getViewer())
->execute();
$method_names = array();
foreach ($methods as $method) {
$status = $method->getMethodStatus();
if (isset($statuses[$status])) {
$method_names[] = $method->getAPIMethodName();
}
}
if (!$method_names) {
throw new PhabricatorEmptyQueryException();
}
$where[] = qsprintf(
$conn,
'method IN (%Ls)',
$method_names);
}
return $where;
}
public function getQueryApplicationClass() {

View file

@ -0,0 +1,204 @@
<?php
final class PhabricatorConduitLogSearchEngine
extends PhabricatorApplicationSearchEngine {
public function getResultTypeDescription() {
return pht('Conduit Logs');
}
public function getApplicationClassName() {
return 'PhabricatorConduitApplication';
}
public function newQuery() {
return new PhabricatorConduitLogQuery();
}
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
if ($map['callerPHIDs']) {
$query->withCallerPHIDs($map['callerPHIDs']);
}
if ($map['methods']) {
$query->withMethods($map['methods']);
}
if ($map['statuses']) {
$query->withMethodStatuses($map['statuses']);
}
return $query;
}
protected function buildCustomSearchFields() {
return array(
id(new PhabricatorUsersSearchField())
->setKey('callerPHIDs')
->setLabel(pht('Methods'))
->setAliases(array('caller', 'callers'))
->setDescription(pht('Find calls by specific users.')),
id(new PhabricatorSearchStringListField())
->setKey('methods')
->setLabel(pht('Methods'))
->setDescription(pht('Find calls to specific methods.')),
id(new PhabricatorSearchCheckboxesField())
->setKey('statuses')
->setLabel(pht('Method Status'))
->setAliases(array('status'))
->setDescription(
pht('Find calls to stable, unstable, or deprecated methods.'))
->setOptions(ConduitAPIMethod::getMethodStatusMap()),
);
}
protected function getURI($path) {
return '/conduit/log/'.$path;
}
protected function getBuiltinQueryNames() {
$names = array();
$viewer = $this->requireViewer();
if ($viewer->isLoggedIn()) {
$names['viewer'] = pht('My Calls');
$names['viewerdeprecated'] = pht('My Deprecated Calls');
}
$names['all'] = pht('All Call Logs');
$names['deprecated'] = pht('Deprecated Call Logs');
return $names;
}
public function buildSavedQueryFromBuiltin($query_key) {
$query = $this->newSavedQuery();
$query->setQueryKey($query_key);
$viewer = $this->requireViewer();
$viewer_phid = $viewer->getPHID();
$deprecated = array(
ConduitAPIMethod::METHOD_STATUS_DEPRECATED,
);
switch ($query_key) {
case 'viewer':
return $query
->setParameter('callerPHIDs', array($viewer_phid));
case 'viewerdeprecated':
return $query
->setParameter('callerPHIDs', array($viewer_phid))
->setParameter('statuses', $deprecated);
case 'deprecated':
return $query
->setParameter('statuses', $deprecated);
case 'all':
return $query;
}
return parent::buildSavedQueryFromBuiltin($query_key);
}
protected function renderResultList(
array $logs,
PhabricatorSavedQuery $query,
array $handles) {
assert_instances_of($logs, 'PhabricatorConduitMethodCallLog');
$viewer = $this->requireViewer();
$methods = id(new PhabricatorConduitMethodQuery())
->setViewer($viewer)
->execute();
$methods = mpull($methods, null, 'getAPIMethodName');
Javelin::initBehavior('phabricator-tooltips');
$viewer = $this->requireViewer();
$rows = array();
foreach ($logs as $log) {
$caller_phid = $log->getCallerPHID();
if ($caller_phid) {
$caller = $viewer->renderHandle($caller_phid);
} else {
$caller = null;
}
$method = idx($methods, $log->getMethod());
if ($method) {
$method_status = $method->getMethodStatus();
} else {
$method_status = null;
}
switch ($method_status) {
case ConduitAPIMethod::METHOD_STATUS_STABLE:
$status = null;
break;
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
$status = id(new PHUIIconView())
->setIconFont('fa-exclamation-triangle yellow')
->addSigil('has-tooltip')
->setMetadata(
array(
'tip' => pht('Unstable'),
));
break;
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
$status = id(new PHUIIconView())
->setIconFont('fa-exclamation-triangle red')
->addSigil('has-tooltip')
->setMetadata(
array(
'tip' => pht('Deprecated'),
));
break;
default:
$status = id(new PHUIIconView())
->setIconFont('fa-question-circle')
->addSigil('has-tooltip')
->setMetadata(
array(
'tip' => pht('Unknown ("%s")', $status),
));
break;
}
$rows[] = array(
$status,
$log->getMethod(),
$caller,
$log->getError(),
pht('%s us', new PhutilNumber($log->getDuration())),
phabricator_datetime($log->getDateCreated(), $viewer),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
null,
pht('Method'),
pht('Caller'),
pht('Error'),
pht('Duration'),
pht('Date'),
))
->setColumnClasses(
array(
null,
'pri',
null,
'wide right',
null,
null,
));
return id(new PhabricatorApplicationSearchResultView())
->setTable($table)
->setNoDataString(pht('No matching calls in log.'));
}
}

View file

@ -11,7 +11,7 @@ final class PhabricatorElasticSearchSetupCheck extends PhabricatorSetupCheck {
return;
}
$engine = new PhabricatorElasticSearchEngine();
$engine = new PhabricatorElasticFulltextStorageEngine();
$index_exists = null;
$index_sane = null;
@ -70,8 +70,8 @@ final class PhabricatorElasticSearchSetupCheck extends PhabricatorSetupCheck {
}
protected function shouldUseElasticSearchEngine() {
$search_engine = PhabricatorSearchEngine::loadEngine();
return ($search_engine instanceof PhabricatorElasticSearchEngine);
$search_engine = PhabricatorFulltextStorageEngine::loadEngine();
return ($search_engine instanceof PhabricatorElasticFulltextStorageEngine);
}
}

View file

@ -84,6 +84,8 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
$issue->addPhabricatorConfig($key);
}
}
$this->executeManiphestFieldChecks();
}
/**
@ -300,4 +302,70 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
return $ancient_config;
}
private function executeManiphestFieldChecks() {
$maniphest_appclass = 'PhabricatorManiphestApplication';
if (!PhabricatorApplication::isClassInstalled($maniphest_appclass)) {
return;
}
$capabilities = array(
ManiphestEditAssignCapability::CAPABILITY,
ManiphestEditPoliciesCapability::CAPABILITY,
ManiphestEditPriorityCapability::CAPABILITY,
ManiphestEditProjectsCapability::CAPABILITY,
ManiphestEditStatusCapability::CAPABILITY,
);
// Check for any of these capabilities set to anything other than
// "All Users".
$any_set = false;
$app = new PhabricatorManiphestApplication();
foreach ($capabilities as $capability) {
$setting = $app->getPolicy($capability);
if ($setting != PhabricatorPolicies::POLICY_USER) {
$any_set = true;
break;
}
}
if (!$any_set) {
return;
}
$issue_summary = pht(
'Maniphest is currently configured with deprecated policy settings '.
'which will be removed in a future version of Phabricator.');
$message = pht(
'Some policy settings in Maniphest are now deprecated and will be '.
'removed in a future version of Phabricator. You are currently using '.
'at least one of these settings.'.
"\n\n".
'The deprecated settings are "Can Assign Tasks", '.
'"Can Edit Task Policies", "Can Prioritize Tasks", '.
'"Can Edit Task Projects", and "Can Edit Task Status". You can '.
'find these settings in Applications, or follow the link below.'.
"\n\n".
'You can find discussion of this change (including rationale and '.
'recommendations on how to configure similar features) in the upstream, '.
'at the link below.'.
"\n\n".
'To resolve this issue, set all of these policies to "All Users" after '.
'making any necessary form customization changes.');
$more_href = 'https://secure.phabricator.com/T10003';
$edit_href = '/applications/view/PhabricatorManiphestApplication/';
$issue = $this->newIssue('maniphest.T10003-per-field-policies')
->setShortName(pht('Deprecated Policies'))
->setName(pht('Deprecated Maniphest Field Policies'))
->setSummary($issue_summary)
->setMessage($message)
->addLink($more_href, pht('Learn More: Upstream Discussion'))
->addLink($edit_href, pht('Edit These Settings'));
}
}

View file

@ -366,8 +366,8 @@ final class PhabricatorMySQLSetupCheck extends PhabricatorSetupCheck {
}
protected function shouldUseMySQLSearchEngine() {
$search_engine = PhabricatorSearchEngine::loadEngine();
return $search_engine instanceof PhabricatorMySQLSearchEngine;
$search_engine = PhabricatorFulltextStorageEngine::loadEngine();
return ($search_engine instanceof PhabricatorMySQLFulltextStorageEngine);
}
}

View file

@ -265,7 +265,7 @@ final class PhabricatorConfigWelcomeController
$maniphest_uri = PhabricatorEnv::getURI('/maniphest/');
$maniphest_create_uri = PhabricatorEnv::getURI('/maniphest/task/create/');
$maniphest_create_uri = PhabricatorEnv::getURI('/maniphest/task/edit/');
$maniphest_all_uri = PhabricatorEnv::getURI('/maniphest/query/all/');
$quick[] = $this->newItem(
$request,

Some files were not shown because too many files have changed in this diff Show more