mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Merge branch 'master' into redesign-2015
This commit is contained in:
commit
7d7e13d79b
50 changed files with 727 additions and 313 deletions
|
@ -8,7 +8,7 @@
|
||||||
return array(
|
return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'core.pkg.css' => '9cbee819',
|
'core.pkg.css' => '9cbee819',
|
||||||
'core.pkg.js' => '41f5edc5',
|
'core.pkg.js' => 'f1e8abd7',
|
||||||
'darkconsole.pkg.js' => 'e7393ebb',
|
'darkconsole.pkg.js' => 'e7393ebb',
|
||||||
'differential.pkg.css' => 'fe951924',
|
'differential.pkg.css' => 'fe951924',
|
||||||
'differential.pkg.js' => 'ebef29b1',
|
'differential.pkg.js' => 'ebef29b1',
|
||||||
|
@ -459,7 +459,7 @@ return array(
|
||||||
'rsrc/js/core/behavior-object-selector.js' => '49b73b36',
|
'rsrc/js/core/behavior-object-selector.js' => '49b73b36',
|
||||||
'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
|
'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
|
||||||
'rsrc/js/core/behavior-phabricator-nav.js' => '56a1ca03',
|
'rsrc/js/core/behavior-phabricator-nav.js' => '56a1ca03',
|
||||||
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '095ed313',
|
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'eeaa9e5a',
|
||||||
'rsrc/js/core/behavior-refresh-csrf.js' => '7814b593',
|
'rsrc/js/core/behavior-refresh-csrf.js' => '7814b593',
|
||||||
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
|
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
|
||||||
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
|
'rsrc/js/core/behavior-reorder-applications.js' => '76b9fc3e',
|
||||||
|
@ -609,7 +609,7 @@ return array(
|
||||||
'javelin-behavior-phabricator-notification-example' => '8ce821c5',
|
'javelin-behavior-phabricator-notification-example' => '8ce821c5',
|
||||||
'javelin-behavior-phabricator-object-selector' => '49b73b36',
|
'javelin-behavior-phabricator-object-selector' => '49b73b36',
|
||||||
'javelin-behavior-phabricator-oncopy' => '2926fff2',
|
'javelin-behavior-phabricator-oncopy' => '2926fff2',
|
||||||
'javelin-behavior-phabricator-remarkup-assist' => '095ed313',
|
'javelin-behavior-phabricator-remarkup-assist' => 'eeaa9e5a',
|
||||||
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
|
'javelin-behavior-phabricator-reveal-content' => '60821bc7',
|
||||||
'javelin-behavior-phabricator-search-typeahead' => '048330fa',
|
'javelin-behavior-phabricator-search-typeahead' => '048330fa',
|
||||||
'javelin-behavior-phabricator-show-older-transactions' => 'dbbf48b6',
|
'javelin-behavior-phabricator-show-older-transactions' => 'dbbf48b6',
|
||||||
|
@ -896,15 +896,6 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-vector',
|
'javelin-vector',
|
||||||
),
|
),
|
||||||
'095ed313' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-dom',
|
|
||||||
'phabricator-phtize',
|
|
||||||
'phabricator-textareautils',
|
|
||||||
'javelin-workflow',
|
|
||||||
'javelin-vector',
|
|
||||||
),
|
|
||||||
'0a3f3021' => array(
|
'0a3f3021' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
|
@ -1951,6 +1942,15 @@ return array(
|
||||||
'phabricator-phtize',
|
'phabricator-phtize',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
|
'eeaa9e5a' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-dom',
|
||||||
|
'phabricator-phtize',
|
||||||
|
'phabricator-textareautils',
|
||||||
|
'javelin-workflow',
|
||||||
|
'javelin-vector',
|
||||||
|
),
|
||||||
'efe49472' => array(
|
'efe49472' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
|
|
5
resources/sql/autopatches/20150616.divinerrepository.sql
Normal file
5
resources/sql/autopatches/20150616.divinerrepository.sql
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_diviner.diviner_livebook
|
||||||
|
ADD COLUMN repositoryPHID VARBINARY(64) AFTER name;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_diviner.diviner_livesymbol
|
||||||
|
ADD COLUMN repositoryPHID VARBINARY(64) AFTER bookPHID;
|
|
@ -3288,7 +3288,6 @@ phutil_register_library_map(array(
|
||||||
'phabricator_format_local_time' => 'view/viewutils.php',
|
'phabricator_format_local_time' => 'view/viewutils.php',
|
||||||
'phabricator_relative_date' => 'view/viewutils.php',
|
'phabricator_relative_date' => 'view/viewutils.php',
|
||||||
'phabricator_time' => 'view/viewutils.php',
|
'phabricator_time' => 'view/viewutils.php',
|
||||||
'phabricator_time_format' => 'view/viewutils.php',
|
|
||||||
'phid_get_subtype' => 'applications/phid/utils.php',
|
'phid_get_subtype' => 'applications/phid/utils.php',
|
||||||
'phid_get_type' => 'applications/phid/utils.php',
|
'phid_get_type' => 'applications/phid/utils.php',
|
||||||
'phid_group_by_type' => 'applications/phid/utils.php',
|
'phid_group_by_type' => 'applications/phid/utils.php',
|
||||||
|
|
|
@ -35,8 +35,10 @@ abstract class AphrontController extends Phobject {
|
||||||
|
|
||||||
throw new PhutilMethodNotImplementedException(
|
throw new PhutilMethodNotImplementedException(
|
||||||
pht(
|
pht(
|
||||||
'Controllers must implement either handleRequest() (recommended) '.
|
'Controllers must implement either %s (recommended) '.
|
||||||
'or processRequest() (deprecated).'));
|
'or %s (deprecated).',
|
||||||
|
'handleRequest()',
|
||||||
|
'processRequest()'));
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function setRequest(AphrontRequest $request) {
|
final public function setRequest(AphrontRequest $request) {
|
||||||
|
@ -46,7 +48,7 @@ abstract class AphrontController extends Phobject {
|
||||||
|
|
||||||
final public function getRequest() {
|
final public function getRequest() {
|
||||||
if (!$this->request) {
|
if (!$this->request) {
|
||||||
throw new Exception(pht('Call setRequest() before getRequest()!'));
|
throw new PhutilInvalidStateException('setRequest');
|
||||||
}
|
}
|
||||||
return $this->request;
|
return $this->request;
|
||||||
}
|
}
|
||||||
|
@ -81,10 +83,12 @@ abstract class AphrontController extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultResourceSource() {
|
public function getDefaultResourceSource() {
|
||||||
throw new Exception(
|
throw new PhutilMethodNotImplementedException(
|
||||||
pht(
|
pht(
|
||||||
'A Controller must implement getDefaultResourceSource() before you '.
|
'A Controller must implement %s before you can invoke %s or %s.',
|
||||||
'can invoke requireResource() or initBehavior().'));
|
'getDefaultResourceSource()',
|
||||||
|
'requireResource()',
|
||||||
|
'initBehavior()'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function requireResource($symbol) {
|
public function requireResource($symbol) {
|
||||||
|
|
|
@ -18,7 +18,7 @@ final class PhabricatorAuthInviteEngine extends Phobject {
|
||||||
|
|
||||||
public function getViewer() {
|
public function getViewer() {
|
||||||
if (!$this->viewer) {
|
if (!$this->viewer) {
|
||||||
throw new Exception(pht('Call setViewer() before getViewer()!'));
|
throw new PhutilInvalidStateException('setViewer');
|
||||||
}
|
}
|
||||||
return $this->viewer;
|
return $this->viewer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,10 +437,11 @@ final class PhabricatorCalendarEventEditController
|
||||||
->setValue($end_disabled);
|
->setValue($end_disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
$description = id(new AphrontFormTextAreaControl())
|
$description = id(new PhabricatorRemarkupControl())
|
||||||
->setLabel(pht('Description'))
|
->setLabel(pht('Description'))
|
||||||
->setName('description')
|
->setName('description')
|
||||||
->setValue($description);
|
->setValue($description)
|
||||||
|
->setUser($viewer);
|
||||||
|
|
||||||
$view_policies = id(new AphrontFormPolicyControl())
|
$view_policies = id(new AphrontFormPolicyControl())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
|
|
|
@ -362,10 +362,19 @@ final class PhabricatorCalendarEventViewController
|
||||||
pht('Icon'),
|
pht('Icon'),
|
||||||
$icon_display);
|
$icon_display);
|
||||||
|
|
||||||
$properties->addSectionHeader(
|
if (strlen($event->getDescription())) {
|
||||||
pht('Description'),
|
|
||||||
PHUIPropertyListView::ICON_SUMMARY);
|
$description = PhabricatorMarkupEngine::renderOneObject(
|
||||||
$properties->addTextContent($event->getDescription());
|
id(new PhabricatorMarkupOneOff())->setContent($event->getDescription()),
|
||||||
|
'default',
|
||||||
|
$viewer);
|
||||||
|
|
||||||
|
$properties->addSectionHeader(
|
||||||
|
pht('Description'),
|
||||||
|
PHUIPropertyListView::ICON_SUMMARY);
|
||||||
|
|
||||||
|
$properties->addTextContent($description);
|
||||||
|
}
|
||||||
|
|
||||||
return $properties;
|
return $properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,15 +126,15 @@ final class PhabricatorCalendarEventSearchEngine
|
||||||
$query->withDateRange($min_range, $max_range);
|
$query->withDateRange($min_range, $max_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
$invited_phids = $saved->getParameter('invitedPHIDs');
|
$invited_phids = $saved->getParameter('invitedPHIDs', array());
|
||||||
|
$invited_phids = $user_datasource->evaluateTokens($invited_phids);
|
||||||
if ($invited_phids) {
|
if ($invited_phids) {
|
||||||
$invited_phids = $user_datasource->evaluateTokens($invited_phids);
|
|
||||||
$query->withInvitedPHIDs($invited_phids);
|
$query->withInvitedPHIDs($invited_phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
$creator_phids = $saved->getParameter('creatorPHIDs');
|
$creator_phids = $saved->getParameter('creatorPHIDs', array());
|
||||||
|
$creator_phids = $user_datasource->evaluateTokens($creator_phids);
|
||||||
if ($creator_phids) {
|
if ($creator_phids) {
|
||||||
$creator_phids = $user_datasource->evaluateTokens($creator_phids);
|
|
||||||
$query->withCreatorPHIDs($creator_phids);
|
$query->withCreatorPHIDs($creator_phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,17 +313,31 @@ final class PhabricatorCalendarEventSearchEngine
|
||||||
$list = new PHUIObjectItemListView();
|
$list = new PHUIObjectItemListView();
|
||||||
foreach ($events as $event) {
|
foreach ($events as $event) {
|
||||||
$from = phabricator_datetime($event->getDateFrom(), $viewer);
|
$from = phabricator_datetime($event->getDateFrom(), $viewer);
|
||||||
$to = phabricator_datetime($event->getDateTo(), $viewer);
|
$duration = '';
|
||||||
$creator_handle = $handles[$event->getUserPHID()];
|
$creator_handle = $handles[$event->getUserPHID()];
|
||||||
|
|
||||||
|
$attendees = array();
|
||||||
|
foreach ($event->getInvitees() as $invitee) {
|
||||||
|
$attendees[] = $invitee->getInviteePHID();
|
||||||
|
}
|
||||||
|
|
||||||
|
$attendees = pht(
|
||||||
|
'Attending: %s',
|
||||||
|
$viewer->renderHandleList($attendees)
|
||||||
|
->setAsInline(1)
|
||||||
|
->render());
|
||||||
|
|
||||||
|
if (strlen($event->getDuration()) > 0) {
|
||||||
|
$duration = pht(
|
||||||
|
'Duration: %s',
|
||||||
|
$event->getDuration());
|
||||||
|
}
|
||||||
|
|
||||||
$item = id(new PHUIObjectItemView())
|
$item = id(new PHUIObjectItemView())
|
||||||
->setHeader($event->getName())
|
->setHeader($viewer->renderHandle($event->getPHID())->render())
|
||||||
->setHref($event->getURI())
|
->addAttribute($attendees)
|
||||||
->addByline(pht('Creator: %s', $creator_handle->renderLink()))
|
->addIcon('none', $from)
|
||||||
->addAttribute(pht('From %s to %s', $from, $to))
|
->addIcon('none', $duration);
|
||||||
->addAttribute(id(new PhutilUTF8StringTruncator())
|
|
||||||
->setMaximumGlyphs(64)
|
|
||||||
->truncateString($event->getDescription()));
|
|
||||||
|
|
||||||
$list->addItem($item);
|
$list->addItem($item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,6 +373,29 @@ final class PhabricatorCalendarEvent extends PhabricatorCalendarDAO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDuration() {
|
||||||
|
$seconds = $this->dateTo - $this->dateFrom;
|
||||||
|
$minutes = round($seconds / 60, 1);
|
||||||
|
$hours = round($minutes / 60, 3);
|
||||||
|
$days = round($hours / 24, 2);
|
||||||
|
|
||||||
|
$duration = '';
|
||||||
|
|
||||||
|
if ($days >= 1) {
|
||||||
|
return pht(
|
||||||
|
'%s day(s)',
|
||||||
|
round($days, 1));
|
||||||
|
} else if ($hours >= 1) {
|
||||||
|
return pht(
|
||||||
|
'%s hour(s)',
|
||||||
|
round($hours, 1));
|
||||||
|
} else if ($minutes >= 1) {
|
||||||
|
return pht(
|
||||||
|
'%s minute(s)',
|
||||||
|
round($minutes, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -( Markup Interface )--------------------------------------------------- */
|
/* -( Markup Interface )--------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ abstract class ConduitAPIMethod
|
||||||
|
|
||||||
$query = $this->newQueryObject();
|
$query = $this->newQueryObject();
|
||||||
if ($query) {
|
if ($query) {
|
||||||
$types['order'] = 'order';
|
$types['order'] = 'optional order';
|
||||||
$types += $this->getPagerParamTypes();
|
$types += $this->getPagerParamTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ final class PhabricatorSyntaxHighlightingConfigOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOptions() {
|
public function getOptions() {
|
||||||
|
|
||||||
$caches_href = PhabricatorEnv::getDocLink('Managing Caches');
|
$caches_href = PhabricatorEnv::getDocLink('Managing Caches');
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
@ -74,31 +73,43 @@ final class PhabricatorSyntaxHighlightingConfigOptions
|
||||||
'c' => 'C',
|
'c' => 'C',
|
||||||
'coffee-script' => 'CoffeeScript',
|
'coffee-script' => 'CoffeeScript',
|
||||||
'cpp' => 'C++',
|
'cpp' => 'C++',
|
||||||
|
'csharp' => 'C#',
|
||||||
'css' => 'CSS',
|
'css' => 'CSS',
|
||||||
'd' => 'D',
|
'd' => 'D',
|
||||||
'diff' => 'Diff',
|
'diff' => 'Diff',
|
||||||
'django' => 'Django Templating',
|
'django' => 'Django Templating',
|
||||||
|
'docker' => 'Docker',
|
||||||
'erb' => 'Embedded Ruby/ERB',
|
'erb' => 'Embedded Ruby/ERB',
|
||||||
'erlang' => 'Erlang',
|
'erlang' => 'Erlang',
|
||||||
'go' => 'Golang',
|
'go' => 'Golang',
|
||||||
'groovy' => 'Groovy',
|
'groovy' => 'Groovy',
|
||||||
'haskell' => 'Haskell',
|
'haskell' => 'Haskell',
|
||||||
'html' => 'HTML',
|
'html' => 'HTML',
|
||||||
|
'http' => 'HTTP',
|
||||||
'invisible' => 'Invisible',
|
'invisible' => 'Invisible',
|
||||||
'java' => 'Java',
|
'java' => 'Java',
|
||||||
'js' => 'Javascript',
|
'js' => 'Javascript',
|
||||||
'json' => 'JSON',
|
'json' => 'JSON',
|
||||||
|
'make' => 'Makefile',
|
||||||
'mysql' => 'MySQL',
|
'mysql' => 'MySQL',
|
||||||
|
'nginx' => 'Nginx Configuration',
|
||||||
'objc' => 'Objective-C',
|
'objc' => 'Objective-C',
|
||||||
'perl' => 'Perl',
|
'perl' => 'Perl',
|
||||||
'php' => 'PHP',
|
'php' => 'PHP',
|
||||||
|
'postgresql' => 'PostgreSQL',
|
||||||
|
'pot' => 'Gettext Catalog',
|
||||||
'puppet' => 'Puppet',
|
'puppet' => 'Puppet',
|
||||||
'rest' => 'reStructuredText',
|
|
||||||
'text' => 'Plain Text',
|
|
||||||
'python' => 'Python',
|
'python' => 'Python',
|
||||||
'rainbow' => 'Rainbow',
|
'rainbow' => 'Rainbow',
|
||||||
'remarkup' => 'Remarkup',
|
'remarkup' => 'Remarkup',
|
||||||
|
'rest' => 'reStructuredText',
|
||||||
|
'robotframework' => 'RobotFramework',
|
||||||
|
'rst' => 'reStructuredText',
|
||||||
'ruby' => 'Ruby',
|
'ruby' => 'Ruby',
|
||||||
|
'sql' => 'SQL',
|
||||||
|
'tex' => 'LaTeX',
|
||||||
|
'text' => 'Plain Text',
|
||||||
|
'twig' => 'Twig',
|
||||||
'xml' => 'XML',
|
'xml' => 'XML',
|
||||||
'yaml' => 'YAML',
|
'yaml' => 'YAML',
|
||||||
))
|
))
|
||||||
|
|
|
@ -64,7 +64,7 @@ final class ConpherenceTransactionView extends AphrontView {
|
||||||
public function render() {
|
public function render() {
|
||||||
$viewer = $this->getUser();
|
$viewer = $this->getUser();
|
||||||
if (!$viewer) {
|
if (!$viewer) {
|
||||||
throw new Exception(pht('Call setUser() before render()!'));
|
throw new PhutilInvalidStateException('setUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
require_celerity_resource('conpherence-transaction-css');
|
require_celerity_resource('conpherence-transaction-css');
|
||||||
|
|
|
@ -127,6 +127,13 @@ final class DarkConsoleCore extends Phobject {
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
} else {
|
} else {
|
||||||
|
// Truncate huge strings. Since the data doesn't really matter much,
|
||||||
|
// just truncate bytes to avoid PhutilUTF8StringTruncator overhead.
|
||||||
|
$length = strlen($data);
|
||||||
|
$max = 4096;
|
||||||
|
if ($length > $max) {
|
||||||
|
$data = substr($data, 0, $max).'...<'.$length.' bytes>...';
|
||||||
|
}
|
||||||
return phutil_utf8ize($data);
|
return phutil_utf8ize($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,9 +283,7 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
||||||
*/
|
*/
|
||||||
private function detectRenderingCycle(PhabricatorDashboardPanel $panel) {
|
private function detectRenderingCycle(PhabricatorDashboardPanel $panel) {
|
||||||
if ($this->parentPanelPHIDs === null) {
|
if ($this->parentPanelPHIDs === null) {
|
||||||
throw new Exception(
|
throw new PhutilInvalidStateException('setParentPanelPHIDs');
|
||||||
pht(
|
|
||||||
'You must call setParentPanelPHIDs() before rendering panels.'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$max_depth = 4;
|
$max_depth = 4;
|
||||||
|
|
|
@ -20,6 +20,8 @@ final class DiffusionFileContentQueryConduitAPIMethod
|
||||||
'path' => 'required string',
|
'path' => 'required string',
|
||||||
'commit' => 'required string',
|
'commit' => 'required string',
|
||||||
'needsBlame' => 'optional bool',
|
'needsBlame' => 'optional bool',
|
||||||
|
'timeout' => 'optional int',
|
||||||
|
'byteLimit' => 'optional int',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,16 +33,30 @@ final class DiffusionFileContentQueryConduitAPIMethod
|
||||||
$file_query
|
$file_query
|
||||||
->setViewer($request->getUser())
|
->setViewer($request->getUser())
|
||||||
->setNeedsBlame($needs_blame);
|
->setNeedsBlame($needs_blame);
|
||||||
|
|
||||||
|
$timeout = $request->getValue('timeout');
|
||||||
|
if ($timeout) {
|
||||||
|
$file_query->setTimeout($timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
$byte_limit = $request->getValue('byteLimit');
|
||||||
|
if ($byte_limit) {
|
||||||
|
$file_query->setByteLimit($byte_limit);
|
||||||
|
}
|
||||||
|
|
||||||
$file_content = $file_query->loadFileContent();
|
$file_content = $file_query->loadFileContent();
|
||||||
|
|
||||||
if ($needs_blame) {
|
if ($needs_blame) {
|
||||||
list($text_list, $rev_list, $blame_dict) = $file_query->getBlameData();
|
list($text_list, $rev_list, $blame_dict) = $file_query->getBlameData();
|
||||||
} else {
|
} else {
|
||||||
$text_list = $rev_list = $blame_dict = array();
|
$text_list = $rev_list = $blame_dict = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_content
|
$file_content
|
||||||
->setBlameDict($blame_dict)
|
->setBlameDict($blame_dict)
|
||||||
->setRevList($rev_list)
|
->setRevList($rev_list)
|
||||||
->setTextList($text_list);
|
->setTextList($text_list);
|
||||||
|
|
||||||
return $file_content->toDictionary();
|
return $file_content->toDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,14 +54,27 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
||||||
$needs_blame = ($show_blame && !$show_color) ||
|
$needs_blame = ($show_blame && !$show_color) ||
|
||||||
($show_blame && $request->isAjax());
|
($show_blame && $request->isAjax());
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
'commit' => $drequest->getCommit(),
|
||||||
|
'path' => $drequest->getPath(),
|
||||||
|
'needsBlame' => $needs_blame,
|
||||||
|
);
|
||||||
|
|
||||||
|
$byte_limit = null;
|
||||||
|
if ($view !== 'raw') {
|
||||||
|
$byte_limit = PhabricatorFileStorageEngine::getChunkThreshold();
|
||||||
|
$time_limit = 10;
|
||||||
|
|
||||||
|
$params += array(
|
||||||
|
'timeout' => $time_limit,
|
||||||
|
'byteLimit' => $byte_limit,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$file_content = DiffusionFileContent::newFromConduit(
|
$file_content = DiffusionFileContent::newFromConduit(
|
||||||
$this->callConduitWithDiffusionRequest(
|
$this->callConduitWithDiffusionRequest(
|
||||||
'diffusion.filecontentquery',
|
'diffusion.filecontentquery',
|
||||||
array(
|
$params));
|
||||||
'commit' => $drequest->getCommit(),
|
|
||||||
'path' => $drequest->getPath(),
|
|
||||||
'needsBlame' => $needs_blame,
|
|
||||||
)));
|
|
||||||
$data = $file_content->getCorpus();
|
$data = $file_content->getCorpus();
|
||||||
|
|
||||||
if ($view === 'raw') {
|
if ($view === 'raw') {
|
||||||
|
@ -71,8 +84,13 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
||||||
$this->loadLintMessages();
|
$this->loadLintMessages();
|
||||||
$this->coverage = $drequest->loadCoverage();
|
$this->coverage = $drequest->loadCoverage();
|
||||||
|
|
||||||
$binary_uri = null;
|
if ($byte_limit && (strlen($data) == $byte_limit)) {
|
||||||
if (ArcanistDiffUtils::isHeuristicBinaryFile($data)) {
|
$corpus = $this->buildErrorCorpus(
|
||||||
|
pht(
|
||||||
|
'This file is larger than %s byte(s), and too large to display '.
|
||||||
|
'in the web UI.',
|
||||||
|
$byte_limit));
|
||||||
|
} else if (ArcanistDiffUtils::isHeuristicBinaryFile($data)) {
|
||||||
$file = $this->loadFileForData($path, $data);
|
$file = $this->loadFileForData($path, $data);
|
||||||
$file_uri = $file->getBestURI();
|
$file_uri = $file->getBestURI();
|
||||||
|
|
||||||
|
@ -80,7 +98,6 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
||||||
$corpus = $this->buildImageCorpus($file_uri);
|
$corpus = $this->buildImageCorpus($file_uri);
|
||||||
} else {
|
} else {
|
||||||
$corpus = $this->buildBinaryCorpus($file_uri, $data);
|
$corpus = $this->buildBinaryCorpus($file_uri, $data);
|
||||||
$binary_uri = $file_uri;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Build the content of the file.
|
// Build the content of the file.
|
||||||
|
@ -940,6 +957,21 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
||||||
return $box;
|
return $box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildErrorCorpus($message) {
|
||||||
|
$text = id(new PHUIBoxView())
|
||||||
|
->addPadding(PHUI::PADDING_LARGE)
|
||||||
|
->appendChild($message);
|
||||||
|
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader(pht('Details'));
|
||||||
|
|
||||||
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeader($header)
|
||||||
|
->appendChild($text);
|
||||||
|
|
||||||
|
return $box;
|
||||||
|
}
|
||||||
|
|
||||||
private function buildBeforeResponse($before) {
|
private function buildBeforeResponse($before) {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$drequest = $this->getDiffusionRequest();
|
$drequest = $this->getDiffusionRequest();
|
||||||
|
|
|
@ -11,6 +11,26 @@ abstract class DiffusionFileContentQuery extends DiffusionQuery {
|
||||||
private $needsBlame;
|
private $needsBlame;
|
||||||
private $fileContent;
|
private $fileContent;
|
||||||
private $viewer;
|
private $viewer;
|
||||||
|
private $timeout;
|
||||||
|
private $byteLimit;
|
||||||
|
|
||||||
|
public function setTimeout($timeout) {
|
||||||
|
$this->timeout = $timeout;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTimeout() {
|
||||||
|
return $this->timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setByteLimit($byte_limit) {
|
||||||
|
$this->byteLimit = $byte_limit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByteLimit() {
|
||||||
|
return $this->byteLimit;
|
||||||
|
}
|
||||||
|
|
||||||
final public static function newFromDiffusionRequest(
|
final public static function newFromDiffusionRequest(
|
||||||
DiffusionRequest $request) {
|
DiffusionRequest $request) {
|
||||||
|
@ -21,7 +41,31 @@ abstract class DiffusionFileContentQuery extends DiffusionQuery {
|
||||||
abstract protected function executeQueryFromFuture(Future $future);
|
abstract protected function executeQueryFromFuture(Future $future);
|
||||||
|
|
||||||
final public function loadFileContentFromFuture(Future $future) {
|
final public function loadFileContentFromFuture(Future $future) {
|
||||||
$this->fileContent = $this->executeQueryFromFuture($future);
|
|
||||||
|
if ($this->timeout) {
|
||||||
|
$future->setTimeout($this->timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getByteLimit()) {
|
||||||
|
$future->setStdoutSizeLimit($this->getByteLimit());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$file_content = $this->executeQueryFromFuture($future);
|
||||||
|
} catch (CommandException $ex) {
|
||||||
|
if (!$future->getWasKilledByTimeout()) {
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = pht(
|
||||||
|
'<Attempt to load this file was terminated after %s second(s).>',
|
||||||
|
$this->timeout);
|
||||||
|
|
||||||
|
$file_content = new DiffusionFileContent();
|
||||||
|
$file_content->setCorpus($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->fileContent = $file_content;
|
||||||
|
|
||||||
$repository = $this->getRequest()->getRepository();
|
$repository = $this->getRequest()->getRepository();
|
||||||
$try_encoding = $repository->getDetail('encoding');
|
$try_encoding = $repository->getDetail('encoding');
|
||||||
|
|
|
@ -84,6 +84,7 @@ final class DivinerAtomController extends DivinerController {
|
||||||
if ($atom) {
|
if ($atom) {
|
||||||
$this->buildDefined($properties, $symbol);
|
$this->buildDefined($properties, $symbol);
|
||||||
$this->buildExtendsAndImplements($properties, $symbol);
|
$this->buildExtendsAndImplements($properties, $symbol);
|
||||||
|
$this->buildRepository($properties, $symbol);
|
||||||
|
|
||||||
$warnings = $atom->getWarnings();
|
$warnings = $atom->getWarnings();
|
||||||
if ($warnings) {
|
if ($warnings) {
|
||||||
|
@ -294,6 +295,15 @@ final class DivinerAtomController extends DivinerController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildRepository(
|
||||||
|
PHUIPropertyListView $view,
|
||||||
|
DivinerLiveSymbol $symbol) {
|
||||||
|
|
||||||
|
$view->addProperty(
|
||||||
|
pht('Repository'),
|
||||||
|
$this->getViewer()->renderHandle($symbol->getRepositoryPHID()));
|
||||||
|
}
|
||||||
|
|
||||||
private function renderAtomTag(DivinerLiveSymbol $symbol) {
|
private function renderAtomTag(DivinerLiveSymbol $symbol) {
|
||||||
return id(new PHUITagView())
|
return id(new PHUITagView())
|
||||||
->setType(PHUITagView::TYPE_OBJECT)
|
->setType(PHUITagView::TYPE_OBJECT)
|
||||||
|
|
|
@ -14,6 +14,7 @@ final class DivinerBookController extends DivinerController {
|
||||||
$book = id(new DivinerBookQuery())
|
$book = id(new DivinerBookQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withNames(array($book_name))
|
->withNames(array($book_name))
|
||||||
|
->needRepositories(true)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
|
||||||
if (!$book) {
|
if (!$book) {
|
||||||
|
@ -43,6 +44,15 @@ final class DivinerBookController extends DivinerController {
|
||||||
->setEpoch($book->getDateModified())
|
->setEpoch($book->getDateModified())
|
||||||
->addActionLink($action_button);
|
->addActionLink($action_button);
|
||||||
|
|
||||||
|
// TODO: This could probably look better.
|
||||||
|
if ($book->getRepositoryPHID()) {
|
||||||
|
$header->addTag(
|
||||||
|
id(new PHUITagView())
|
||||||
|
->setType(PHUITagView::TYPE_STATE)
|
||||||
|
->setBackgroundColor(PHUITagView::COLOR_BLUE)
|
||||||
|
->setName($book->getRepository()->getMonogram()));
|
||||||
|
}
|
||||||
|
|
||||||
$document = new PHUIDocumentView();
|
$document = new PHUIDocumentView();
|
||||||
$document->setHeader($header);
|
$document->setHeader($header);
|
||||||
$document->addClass('diviner-view');
|
$document->addClass('diviner-view');
|
||||||
|
|
|
@ -75,6 +75,16 @@ final class DivinerBookEditController extends DivinerController {
|
||||||
->setName('projectPHIDs')
|
->setName('projectPHIDs')
|
||||||
->setLabel(pht('Projects'))
|
->setLabel(pht('Projects'))
|
||||||
->setValue($book->getProjectPHIDs()))
|
->setValue($book->getProjectPHIDs()))
|
||||||
|
->appendControl(
|
||||||
|
id(new AphrontFormTokenizerControl())
|
||||||
|
->setDatasource(new DiffusionRepositoryDatasource())
|
||||||
|
->setName('repositoryPHIDs')
|
||||||
|
->setLabel(pht('Repository'))
|
||||||
|
->setDisableBehavior(true)
|
||||||
|
->setLimit(1)
|
||||||
|
->setValue($book->getRepositoryPHID()
|
||||||
|
? array($book->getRepositoryPHID())
|
||||||
|
: null))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormPolicyControl())
|
id(new AphrontFormPolicyControl())
|
||||||
->setName('viewPolicy')
|
->setName('viewPolicy')
|
||||||
|
|
|
@ -4,7 +4,7 @@ final class DivinerLivePublisher extends DivinerPublisher {
|
||||||
|
|
||||||
private $book;
|
private $book;
|
||||||
|
|
||||||
private function loadBook() {
|
protected function getBook() {
|
||||||
if (!$this->book) {
|
if (!$this->book) {
|
||||||
$book_name = $this->getConfig('name');
|
$book_name = $this->getConfig('name');
|
||||||
|
|
||||||
|
@ -20,7 +20,24 @@ final class DivinerLivePublisher extends DivinerPublisher {
|
||||||
->save();
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$book->setConfigurationData($this->getConfigurationData())->save();
|
$conn_w = $book->establishConnection('w');
|
||||||
|
$conn_w->openTransaction();
|
||||||
|
|
||||||
|
$book
|
||||||
|
->setRepositoryPHID($this->getRepositoryPHID())
|
||||||
|
->setConfigurationData($this->getConfigurationData())
|
||||||
|
->save();
|
||||||
|
|
||||||
|
// TODO: This is gross. Without this, the repository won't be updated for
|
||||||
|
// atoms which have already been published.
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'UPDATE %T SET repositoryPHID = %s WHERE bookPHID = %s',
|
||||||
|
id(new DivinerLiveSymbol())->getTableName(),
|
||||||
|
$this->getRepositoryPHID(),
|
||||||
|
$book->getPHID());
|
||||||
|
|
||||||
|
$conn_w->saveTransaction();
|
||||||
$this->book = $book;
|
$this->book = $book;
|
||||||
|
|
||||||
id(new PhabricatorSearchIndexer())
|
id(new PhabricatorSearchIndexer())
|
||||||
|
@ -33,7 +50,7 @@ final class DivinerLivePublisher extends DivinerPublisher {
|
||||||
private function loadSymbolForAtom(DivinerAtom $atom) {
|
private function loadSymbolForAtom(DivinerAtom $atom) {
|
||||||
$symbol = id(new DivinerAtomQuery())
|
$symbol = id(new DivinerAtomQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withBookPHIDs(array($this->loadBook()->getPHID()))
|
->withBookPHIDs(array($atom->getBook()))
|
||||||
->withTypes(array($atom->getType()))
|
->withTypes(array($atom->getType()))
|
||||||
->withNames(array($atom->getName()))
|
->withNames(array($atom->getName()))
|
||||||
->withContexts(array($atom->getContext()))
|
->withContexts(array($atom->getContext()))
|
||||||
|
@ -45,7 +62,7 @@ final class DivinerLivePublisher extends DivinerPublisher {
|
||||||
}
|
}
|
||||||
|
|
||||||
return id(new DivinerLiveSymbol())
|
return id(new DivinerLiveSymbol())
|
||||||
->setBookPHID($this->loadBook()->getPHID())
|
->setBookPHID($this->getBook()->getPHID())
|
||||||
->setType($atom->getType())
|
->setType($atom->getType())
|
||||||
->setName($atom->getName())
|
->setName($atom->getName())
|
||||||
->setContext($atom->getContext())
|
->setContext($atom->getContext())
|
||||||
|
@ -68,7 +85,7 @@ final class DivinerLivePublisher extends DivinerPublisher {
|
||||||
protected function loadAllPublishedHashes() {
|
protected function loadAllPublishedHashes() {
|
||||||
$symbols = id(new DivinerAtomQuery())
|
$symbols = id(new DivinerAtomQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withBookPHIDs(array($this->loadBook()->getPHID()))
|
->withBookPHIDs(array($this->getBook()->getPHID()))
|
||||||
->withGhosts(false)
|
->withGhosts(false)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
@ -113,6 +130,7 @@ final class DivinerLivePublisher extends DivinerPublisher {
|
||||||
$is_documentable = $this->shouldGenerateDocumentForAtom($atom);
|
$is_documentable = $this->shouldGenerateDocumentForAtom($atom);
|
||||||
|
|
||||||
$symbol
|
$symbol
|
||||||
|
->setRepositoryPHID($this->getRepositoryPHID())
|
||||||
->setGraphHash($hash)
|
->setGraphHash($hash)
|
||||||
->setIsDocumentable((int)$is_documentable)
|
->setIsDocumentable((int)$is_documentable)
|
||||||
->setTitle($ref->getTitle())
|
->setTitle($ref->getTitle())
|
||||||
|
|
|
@ -9,6 +9,7 @@ abstract class DivinerPublisher extends Phobject {
|
||||||
private $config;
|
private $config;
|
||||||
private $symbolReverseMap;
|
private $symbolReverseMap;
|
||||||
private $dropCaches;
|
private $dropCaches;
|
||||||
|
private $repositoryPHID;
|
||||||
|
|
||||||
final public function setDropCaches($drop_caches) {
|
final public function setDropCaches($drop_caches) {
|
||||||
$this->dropCaches = $drop_caches;
|
$this->dropCaches = $drop_caches;
|
||||||
|
@ -163,4 +164,13 @@ abstract class DivinerPublisher extends Phobject {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final public function getRepositoryPHID() {
|
||||||
|
return $this->repositoryPHID;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setRepositoryPHID($repository_phid) {
|
||||||
|
$this->repositoryPHID = $repository_phid;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,12 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
private $nodeHashes;
|
private $nodeHashes;
|
||||||
private $titles;
|
private $titles;
|
||||||
private $nameContains;
|
private $nameContains;
|
||||||
|
private $repositoryPHIDs;
|
||||||
|
|
||||||
private $needAtoms;
|
private $needAtoms;
|
||||||
private $needExtends;
|
private $needExtends;
|
||||||
private $needChildren;
|
private $needChildren;
|
||||||
|
private $needRepositories;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
$this->ids = $ids;
|
$this->ids = $ids;
|
||||||
|
@ -109,6 +111,16 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withRepositoryPHIDs(array $repository_phids) {
|
||||||
|
$this->repositoryPHIDs = $repository_phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function needRepositories($need_repositories) {
|
||||||
|
$this->needRepositories = $need_repositories;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new DivinerLiveSymbol();
|
$table = new DivinerLiveSymbol();
|
||||||
$conn_r = $table->establishConnection('r');
|
$conn_r = $table->establishConnection('r');
|
||||||
|
@ -125,6 +137,8 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function willFilterPage(array $atoms) {
|
protected function willFilterPage(array $atoms) {
|
||||||
|
assert_instances_of($atoms, 'DivinerLiveSymbol');
|
||||||
|
|
||||||
$books = array_unique(mpull($atoms, 'getBookPHID'));
|
$books = array_unique(mpull($atoms, 'getBookPHID'));
|
||||||
|
|
||||||
$books = id(new DivinerBookQuery())
|
$books = id(new DivinerBookQuery())
|
||||||
|
@ -257,6 +271,31 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
$this->attachAllChildren($atoms, $children, $this->needExtends);
|
$this->attachAllChildren($atoms, $children, $this->needExtends);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->needRepositories) {
|
||||||
|
$repositories = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->withPHIDs(mpull($atoms, 'getRepositoryPHID'))
|
||||||
|
->execute();
|
||||||
|
$repositories = mpull($repositories, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($atoms as $key => $atom) {
|
||||||
|
if ($atom->getRepositoryPHID() === null) {
|
||||||
|
$atom->attachRepository(null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository = idx($repositories, $atom->getRepositoryPHID());
|
||||||
|
|
||||||
|
if (!$repository) {
|
||||||
|
$this->didRejectResult($atom);
|
||||||
|
unset($atom[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$atom->attachRepository($repository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $atoms;
|
return $atoms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,6 +420,13 @@ final class DivinerAtomQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
$this->nameContains);
|
$this->nameContains);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->repositoryPHIDs) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'repositoryPHID IN (%Ls)',
|
||||||
|
$this->repositoryPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
|
@ -13,21 +13,23 @@ final class DivinerAtomSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||||
$saved = new PhabricatorSavedQuery();
|
$saved = new PhabricatorSavedQuery();
|
||||||
|
|
||||||
|
$saved->setParameter(
|
||||||
|
'repositoryPHIDs',
|
||||||
|
$this->readPHIDsFromRequest($request, 'repositoryPHIDs'));
|
||||||
|
$saved->setParameter('name', $request->getStr('name'));
|
||||||
$saved->setParameter(
|
$saved->setParameter(
|
||||||
'types',
|
'types',
|
||||||
$this->readListFromRequest($request, 'types'));
|
$this->readListFromRequest($request, 'types'));
|
||||||
|
|
||||||
$saved->setParameter('name', $request->getStr('name'));
|
|
||||||
|
|
||||||
return $saved;
|
return $saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||||
$query = id(new DivinerAtomQuery());
|
$query = id(new DivinerAtomQuery());
|
||||||
|
|
||||||
$types = $saved->getParameter('types');
|
$repository_phids = $saved->getParameter('repositoryPHIDs');
|
||||||
if ($types) {
|
if ($repository_phids) {
|
||||||
$query->withTypes($types);
|
$query->withRepositoryPHIDs($repository_phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = $saved->getParameter('name');
|
$name = $saved->getParameter('name');
|
||||||
|
@ -35,6 +37,11 @@ final class DivinerAtomSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
$query->withNameContains($name);
|
$query->withNameContains($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$types = $saved->getParameter('types');
|
||||||
|
if ($types) {
|
||||||
|
$query->withTypes($types);
|
||||||
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +49,12 @@ final class DivinerAtomSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
AphrontFormView $form,
|
AphrontFormView $form,
|
||||||
PhabricatorSavedQuery $saved) {
|
PhabricatorSavedQuery $saved) {
|
||||||
|
|
||||||
|
$form->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel(pht('Name Contains'))
|
||||||
|
->setName('name')
|
||||||
|
->setValue($saved->getParameter('name')));
|
||||||
|
|
||||||
$all_types = array();
|
$all_types = array();
|
||||||
foreach (DivinerAtom::getAllTypes() as $type) {
|
foreach (DivinerAtom::getAllTypes() as $type) {
|
||||||
$all_types[$type] = DivinerAtom::getAtomTypeNameString($type);
|
$all_types[$type] = DivinerAtom::getAtomTypeNameString($type);
|
||||||
|
@ -59,14 +72,14 @@ final class DivinerAtomSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
$name,
|
$name,
|
||||||
isset($types[$type]));
|
isset($types[$type]));
|
||||||
}
|
}
|
||||||
|
$form->appendChild($type_control);
|
||||||
|
|
||||||
$form
|
$form->appendControl(
|
||||||
->appendChild(
|
id(new AphrontFormTokenizerControl())
|
||||||
id(new AphrontFormTextControl())
|
->setLabel(pht('Repositories'))
|
||||||
->setLabel(pht('Name Contains'))
|
->setName('repositoryPHIDs')
|
||||||
->setName('name')
|
->setDatasource(new DiffusionRepositoryDatasource())
|
||||||
->setValue($saved->getParameter('name')))
|
->setValue($saved->getParameter('repositoryPHIDs')));
|
||||||
->appendChild($type_control);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getURI($path) {
|
protected function getURI($path) {
|
||||||
|
|
|
@ -5,8 +5,10 @@ final class DivinerBookQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
private $names;
|
private $names;
|
||||||
|
private $repositoryPHIDs;
|
||||||
|
|
||||||
private $needProjectPHIDs;
|
private $needProjectPHIDs;
|
||||||
|
private $needRepositories;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
$this->ids = $ids;
|
$this->ids = $ids;
|
||||||
|
@ -23,11 +25,21 @@ final class DivinerBookQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withRepositoryPHIDs(array $repository_phids) {
|
||||||
|
$this->repositoryPHIDs = $repository_phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function needProjectPHIDs($need_phids) {
|
public function needProjectPHIDs($need_phids) {
|
||||||
$this->needProjectPHIDs = $need_phids;
|
$this->needProjectPHIDs = $need_phids;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function needRepositories($need_repositories) {
|
||||||
|
$this->needRepositories = $need_repositories;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new DivinerLiveBook();
|
$table = new DivinerLiveBook();
|
||||||
$conn_r = $table->establishConnection('r');
|
$conn_r = $table->establishConnection('r');
|
||||||
|
@ -46,6 +58,31 @@ final class DivinerBookQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
protected function didFilterPage(array $books) {
|
protected function didFilterPage(array $books) {
|
||||||
assert_instances_of($books, 'DivinerLiveBook');
|
assert_instances_of($books, 'DivinerLiveBook');
|
||||||
|
|
||||||
|
if ($this->needRepositories) {
|
||||||
|
$repositories = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->withPHIDs(mpull($books, 'getRepositoryPHID'))
|
||||||
|
->execute();
|
||||||
|
$repositories = mpull($repositories, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($books as $key => $book) {
|
||||||
|
if ($book->getRepositoryPHID() === null) {
|
||||||
|
$book->attachRepository(null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository = idx($repositories, $book->getRepositoryPHID());
|
||||||
|
|
||||||
|
if (!$repository) {
|
||||||
|
$this->didRejectResult($book);
|
||||||
|
unset($books[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$book->attachRepository($repository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->needProjectPHIDs) {
|
if ($this->needProjectPHIDs) {
|
||||||
$edge_query = id(new PhabricatorEdgeQuery())
|
$edge_query = id(new PhabricatorEdgeQuery())
|
||||||
->withSourcePHIDs(mpull($books, 'getPHID'))
|
->withSourcePHIDs(mpull($books, 'getPHID'))
|
||||||
|
@ -91,6 +128,13 @@ final class DivinerBookQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
$this->names);
|
$this->names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->repositoryPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'repositoryPHID IN (%Ls)',
|
||||||
|
$this->repositoryPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
|
@ -29,6 +29,12 @@ final class DivinerAtomSearchIndexer extends PhabricatorSearchDocumentIndexer {
|
||||||
DivinerBookPHIDType::TYPECONST,
|
DivinerBookPHIDType::TYPECONST,
|
||||||
PhabricatorTime::getNow());
|
PhabricatorTime::getNow());
|
||||||
|
|
||||||
|
$doc->addRelationship(
|
||||||
|
PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY,
|
||||||
|
$atom->getRepositoryPHID(),
|
||||||
|
PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
|
||||||
|
PhabricatorTime::getNow());
|
||||||
|
|
||||||
$doc->addRelationship(
|
$doc->addRelationship(
|
||||||
$atom->getGraphHash()
|
$atom->getGraphHash()
|
||||||
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
|
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
|
||||||
|
|
|
@ -18,6 +18,12 @@ final class DivinerBookSearchIndexer extends PhabricatorSearchDocumentIndexer {
|
||||||
PhabricatorSearchDocumentFieldType::FIELD_BODY,
|
PhabricatorSearchDocumentFieldType::FIELD_BODY,
|
||||||
$book->getPreface());
|
$book->getPreface());
|
||||||
|
|
||||||
|
$doc->addRelationship(
|
||||||
|
PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY,
|
||||||
|
$book->getRepositoryPHID(),
|
||||||
|
PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
|
||||||
|
$book->getDateCreated());
|
||||||
|
|
||||||
$this->indexTransactions(
|
$this->indexTransactions(
|
||||||
$doc,
|
$doc,
|
||||||
new DivinerLiveBookTransactionQuery(),
|
new DivinerLiveBookTransactionQuery(),
|
||||||
|
|
|
@ -8,11 +8,13 @@ final class DivinerLiveBook extends DivinerDAO
|
||||||
PhabricatorApplicationTransactionInterface {
|
PhabricatorApplicationTransactionInterface {
|
||||||
|
|
||||||
protected $name;
|
protected $name;
|
||||||
|
protected $repositoryPHID;
|
||||||
protected $viewPolicy;
|
protected $viewPolicy;
|
||||||
protected $editPolicy;
|
protected $editPolicy;
|
||||||
protected $configurationData = array();
|
protected $configurationData = array();
|
||||||
|
|
||||||
private $projectPHIDs = self::ATTACHABLE;
|
private $projectPHIDs = self::ATTACHABLE;
|
||||||
|
private $repository = self::ATTACHABLE;
|
||||||
|
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
|
@ -22,6 +24,7 @@ final class DivinerLiveBook extends DivinerDAO
|
||||||
),
|
),
|
||||||
self::CONFIG_COLUMN_SCHEMA => array(
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
'name' => 'text64',
|
'name' => 'text64',
|
||||||
|
'repositoryPHID' => 'phid?',
|
||||||
),
|
),
|
||||||
self::CONFIG_KEY_SCHEMA => array(
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
'key_phid' => null,
|
'key_phid' => null,
|
||||||
|
@ -68,6 +71,15 @@ final class DivinerLiveBook extends DivinerDAO
|
||||||
return idx($spec, 'name', $group);
|
return idx($spec, 'name', $group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function attachRepository(PhabricatorRepository $repository = null) {
|
||||||
|
$this->repository = $repository;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRepository() {
|
||||||
|
return $this->assertAttached($this->repository);
|
||||||
|
}
|
||||||
|
|
||||||
public function attachProjectPHIDs(array $project_phids) {
|
public function attachProjectPHIDs(array $project_phids) {
|
||||||
$this->projectPHIDs = $project_phids;
|
$this->projectPHIDs = $project_phids;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -98,7 +110,7 @@ final class DivinerLiveBook extends DivinerDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class DivinerLiveSymbol extends DivinerDAO
|
||||||
PhabricatorDestructibleInterface {
|
PhabricatorDestructibleInterface {
|
||||||
|
|
||||||
protected $bookPHID;
|
protected $bookPHID;
|
||||||
|
protected $repositoryPHID;
|
||||||
protected $context;
|
protected $context;
|
||||||
protected $type;
|
protected $type;
|
||||||
protected $name;
|
protected $name;
|
||||||
|
@ -22,6 +23,7 @@ final class DivinerLiveSymbol extends DivinerDAO
|
||||||
protected $isDocumentable = 0;
|
protected $isDocumentable = 0;
|
||||||
|
|
||||||
private $book = self::ATTACHABLE;
|
private $book = self::ATTACHABLE;
|
||||||
|
private $repository = self::ATTACHABLE;
|
||||||
private $atom = self::ATTACHABLE;
|
private $atom = self::ATTACHABLE;
|
||||||
private $extends = self::ATTACHABLE;
|
private $extends = self::ATTACHABLE;
|
||||||
private $children = self::ATTACHABLE;
|
private $children = self::ATTACHABLE;
|
||||||
|
@ -43,6 +45,7 @@ final class DivinerLiveSymbol extends DivinerDAO
|
||||||
'summary' => 'text?',
|
'summary' => 'text?',
|
||||||
'isDocumentable' => 'bool',
|
'isDocumentable' => 'bool',
|
||||||
'nodeHash' => 'text64?',
|
'nodeHash' => 'text64?',
|
||||||
|
'repositoryPHID' => 'phid?',
|
||||||
),
|
),
|
||||||
self::CONFIG_KEY_SCHEMA => array(
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
'key_phid' => null,
|
'key_phid' => null,
|
||||||
|
@ -94,6 +97,15 @@ final class DivinerLiveSymbol extends DivinerDAO
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRepository() {
|
||||||
|
return $this->assertAttached($this->repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attachRepository(PhabricatorRepository $repository = null) {
|
||||||
|
$this->repository = $repository;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAtom() {
|
public function getAtom() {
|
||||||
return $this->assertAttached($this->atom);
|
return $this->assertAttached($this->atom);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,11 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
|
||||||
'help' => pht('Specify a subclass of %s.', 'DivinerPublisher'),
|
'help' => pht('Specify a subclass of %s.', 'DivinerPublisher'),
|
||||||
'default' => 'DivinerLivePublisher',
|
'default' => 'DivinerLivePublisher',
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'repository',
|
||||||
|
'param' => 'callsign',
|
||||||
|
'help' => pht('Repository that the documentation belongs to.'),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +192,24 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
|
||||||
}
|
}
|
||||||
$publisher = newv($publisher_class, array());
|
$publisher = newv($publisher_class, array());
|
||||||
|
|
||||||
|
$callsign = $args->getArg('repository');
|
||||||
|
$repository = null;
|
||||||
|
if ($callsign) {
|
||||||
|
$repository = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withCallsigns(array($callsign))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$repository) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
"Repository '%s' does not exist.",
|
||||||
|
$callsign));
|
||||||
|
}
|
||||||
|
|
||||||
|
$publisher->setRepositoryPHID($repository->getPHID());
|
||||||
|
}
|
||||||
|
|
||||||
$this->publishDocumentation($args->getArg('clean'), $publisher);
|
$this->publishDocumentation($args->getArg('clean'), $publisher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,20 +77,7 @@ final class DrydockPreallocatedHostBlueprintImplementation
|
||||||
|
|
||||||
$cmd = $lease->getInterface('command');
|
$cmd = $lease->getInterface('command');
|
||||||
|
|
||||||
if ($v_platform !== 'windows') {
|
$cmd->execx('mkdir %s', $full_path);
|
||||||
$cmd->execx('mkdir %s', $full_path);
|
|
||||||
} else {
|
|
||||||
// Windows is terrible. The mkdir command doesn't even support putting
|
|
||||||
// the path in quotes. IN QUOTES. ARGUHRGHUGHHGG!! Do some terribly
|
|
||||||
// inaccurate sanity checking since we can't safely escape the path.
|
|
||||||
if (preg_match('/^[A-Z]\\:\\\\[a-zA-Z0-9\\\\\\ ]/', $full_path) === 0) {
|
|
||||||
throw new Exception(
|
|
||||||
pht(
|
|
||||||
'Unsafe path detected for Windows platform: "%s".',
|
|
||||||
$full_path));
|
|
||||||
}
|
|
||||||
$cmd->execx('mkdir %C', $full_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lease->setAttribute('path', $full_path);
|
$lease->setAttribute('path', $full_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,46 +42,8 @@ final class DrydockSSHCommandInterface extends DrydockCommandInterface {
|
||||||
$this->openCredentialsIfNotOpen();
|
$this->openCredentialsIfNotOpen();
|
||||||
|
|
||||||
$argv = func_get_args();
|
$argv = func_get_args();
|
||||||
|
$argv = $this->applyWorkingDirectoryToArgv($argv);
|
||||||
if ($this->getConfig('platform') === 'windows') {
|
$full_command = call_user_func_array('csprintf', $argv);
|
||||||
// Handle Windows by executing the command under PowerShell.
|
|
||||||
$command = id(new PhutilCommandString($argv))
|
|
||||||
->setEscapingMode(PhutilCommandString::MODE_POWERSHELL);
|
|
||||||
|
|
||||||
$change_directory = '';
|
|
||||||
if ($this->getWorkingDirectory() !== null) {
|
|
||||||
$change_directory .= 'cd '.$this->getWorkingDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
$script = <<<EOF
|
|
||||||
$change_directory
|
|
||||||
$command
|
|
||||||
if (\$LastExitCode -ne 0) {
|
|
||||||
exit \$LastExitCode
|
|
||||||
}
|
|
||||||
EOF;
|
|
||||||
|
|
||||||
// When Microsoft says "Unicode" they don't mean UTF-8.
|
|
||||||
$script = mb_convert_encoding($script, 'UTF-16LE');
|
|
||||||
|
|
||||||
$script = base64_encode($script);
|
|
||||||
|
|
||||||
$powershell =
|
|
||||||
'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
|
|
||||||
$powershell .=
|
|
||||||
' -ExecutionPolicy Bypass'.
|
|
||||||
' -NonInteractive'.
|
|
||||||
' -InputFormat Text'.
|
|
||||||
' -OutputFormat Text'.
|
|
||||||
' -EncodedCommand '.$script;
|
|
||||||
|
|
||||||
$full_command = $powershell;
|
|
||||||
} else {
|
|
||||||
// Handle UNIX by executing under the native shell.
|
|
||||||
$argv = $this->applyWorkingDirectoryToArgv($argv);
|
|
||||||
|
|
||||||
$full_command = call_user_func_array('csprintf', $argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
$command_timeout = '';
|
$command_timeout = '';
|
||||||
if ($this->connectTimeout !== null) {
|
if ($this->connectTimeout !== null) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class PhabricatorOwnersPackageQuery
|
||||||
private $phids;
|
private $phids;
|
||||||
private $ownerPHIDs;
|
private $ownerPHIDs;
|
||||||
private $repositoryPHIDs;
|
private $repositoryPHIDs;
|
||||||
|
private $namePrefix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Owners are direct owners, and members of owning projects.
|
* Owners are direct owners, and members of owning projects.
|
||||||
|
@ -31,62 +32,59 @@ final class PhabricatorOwnersPackageQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
public function withNamePrefix($prefix) {
|
||||||
$table = new PhabricatorOwnersPackage();
|
$this->namePrefix = $prefix;
|
||||||
$conn_r = $table->establishConnection('r');
|
return $this;
|
||||||
|
|
||||||
$data = queryfx_all(
|
|
||||||
$conn_r,
|
|
||||||
'SELECT p.* FROM %T p %Q %Q %Q %Q',
|
|
||||||
$table->getTableName(),
|
|
||||||
$this->buildJoinClause($conn_r),
|
|
||||||
$this->buildWhereClause($conn_r),
|
|
||||||
$this->buildOrderClause($conn_r),
|
|
||||||
$this->buildLimitClause($conn_r));
|
|
||||||
|
|
||||||
return $table->loadAllFromArray($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) {
|
public function newResultObject() {
|
||||||
$joins = array();
|
return new PhabricatorOwnersPackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadPage() {
|
||||||
|
return $this->loadStandardPage(new PhabricatorOwnersPackage());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
|
$joins = parent::buildJoinClauseParts($conn);
|
||||||
|
|
||||||
if ($this->ownerPHIDs !== null) {
|
if ($this->ownerPHIDs !== null) {
|
||||||
$joins[] = qsprintf(
|
$joins[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'JOIN %T o ON o.packageID = p.id',
|
'JOIN %T o ON o.packageID = p.id',
|
||||||
id(new PhabricatorOwnersOwner())->getTableName());
|
id(new PhabricatorOwnersOwner())->getTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->repositoryPHIDs !== null) {
|
if ($this->repositoryPHIDs !== null) {
|
||||||
$joins[] = qsprintf(
|
$joins[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'JOIN %T rpath ON rpath.packageID = p.id',
|
'JOIN %T rpath ON rpath.packageID = p.id',
|
||||||
id(new PhabricatorOwnersPath())->getTableName());
|
id(new PhabricatorOwnersPath())->getTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return implode(' ', $joins);
|
return $joins;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
$where = array();
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
if ($this->phids !== null) {
|
if ($this->phids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'p.phid IN (%Ls)',
|
'p.phid IN (%Ls)',
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->ids !== null) {
|
if ($this->ids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'p.id IN (%Ld)',
|
'p.id IN (%Ld)',
|
||||||
$this->ids);
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->repositoryPHIDs !== null) {
|
if ($this->repositoryPHIDs !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'rpath.repositoryPHID IN (%Ls)',
|
'rpath.repositoryPHID IN (%Ls)',
|
||||||
$this->repositoryPHIDs);
|
$this->repositoryPHIDs);
|
||||||
}
|
}
|
||||||
|
@ -94,26 +92,79 @@ final class PhabricatorOwnersPackageQuery
|
||||||
if ($this->ownerPHIDs !== null) {
|
if ($this->ownerPHIDs !== null) {
|
||||||
$base_phids = $this->ownerPHIDs;
|
$base_phids = $this->ownerPHIDs;
|
||||||
|
|
||||||
$query = new PhabricatorProjectQuery();
|
$projects = id(new PhabricatorProjectQuery())
|
||||||
$query->setViewer($this->getViewer());
|
->setViewer($this->getViewer())
|
||||||
$query->withMemberPHIDs($base_phids);
|
->withMemberPHIDs($base_phids)
|
||||||
$projects = $query->execute();
|
->execute();
|
||||||
$project_phids = mpull($projects, 'getPHID');
|
$project_phids = mpull($projects, 'getPHID');
|
||||||
|
|
||||||
$all_phids = array_merge($base_phids, $project_phids);
|
$all_phids = array_merge($base_phids, $project_phids);
|
||||||
|
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'o.userPHID IN (%Ls)',
|
'o.userPHID IN (%Ls)',
|
||||||
$all_phids);
|
$all_phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
if (strlen($this->namePrefix)) {
|
||||||
return $this->formatWhereClause($where);
|
// NOTE: This is a hacky mess, but this column is currently case
|
||||||
|
// sensitive and unique.
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'LOWER(p.name) LIKE %>',
|
||||||
|
phutil_utf8_strtolower($this->namePrefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function shouldGroupQueryResultRows() {
|
||||||
|
if ($this->repositoryPHIDs) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->ownerPHIDs) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::shouldGroupQueryResultRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBuiltinOrders() {
|
||||||
|
return array(
|
||||||
|
'name' => array(
|
||||||
|
'vector' => array('name'),
|
||||||
|
'name' => pht('Name'),
|
||||||
|
),
|
||||||
|
) + parent::getBuiltinOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOrderableColumns() {
|
||||||
|
return parent::getOrderableColumns() + array(
|
||||||
|
'name' => array(
|
||||||
|
'table' => $this->getPrimaryTableAlias(),
|
||||||
|
'column' => 'name',
|
||||||
|
'type' => 'string',
|
||||||
|
'unique' => true,
|
||||||
|
'reverse' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPagingValueMap($cursor, array $keys) {
|
||||||
|
$package = $this->loadCursorObject($cursor);
|
||||||
|
return array(
|
||||||
|
'id' => $package->getID(),
|
||||||
|
'name' => $package->getName(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryApplicationClass() {
|
public function getQueryApplicationClass() {
|
||||||
return 'PhabricatorOwnersApplication';
|
return 'PhabricatorOwnersApplication';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getPrimaryTableAlias() {
|
||||||
|
return 'p';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,68 +11,39 @@ final class PhabricatorOwnersPackageSearchEngine
|
||||||
return 'PhabricatorOwnersApplication';
|
return 'PhabricatorOwnersApplication';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
public function newQuery() {
|
||||||
$saved = new PhabricatorSavedQuery();
|
return new PhabricatorOwnersPackageQuery();
|
||||||
|
|
||||||
$saved->setParameter(
|
|
||||||
'ownerPHIDs',
|
|
||||||
$this->readUsersFromRequest(
|
|
||||||
$request,
|
|
||||||
'owners',
|
|
||||||
array(
|
|
||||||
PhabricatorProjectProjectPHIDType::TYPECONST,
|
|
||||||
)));
|
|
||||||
|
|
||||||
$saved->setParameter(
|
|
||||||
'repositoryPHIDs',
|
|
||||||
$this->readPHIDsFromRequest(
|
|
||||||
$request,
|
|
||||||
'repositories',
|
|
||||||
array(
|
|
||||||
PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
|
|
||||||
)));
|
|
||||||
|
|
||||||
return $saved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
protected function buildCustomSearchFields() {
|
||||||
$query = id(new PhabricatorOwnersPackageQuery());
|
return array(
|
||||||
|
id(new PhabricatorSearchDatasourceField())
|
||||||
|
->setLabel(pht('Owners'))
|
||||||
|
->setKey('ownerPHIDs')
|
||||||
|
->setAliases(array('owner', 'owners'))
|
||||||
|
->setDatasource(new PhabricatorProjectOrUserDatasource()),
|
||||||
|
id(new PhabricatorSearchDatasourceField())
|
||||||
|
->setLabel(pht('Repositories'))
|
||||||
|
->setKey('repositoryPHIDs')
|
||||||
|
->setAliases(array('repository', 'repositories'))
|
||||||
|
->setDatasource(new DiffusionRepositoryDatasource()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$owner_phids = $saved->getParameter('ownerPHIDs', array());
|
protected function buildQueryFromParameters(array $map) {
|
||||||
if ($owner_phids) {
|
$query = $this->newQuery();
|
||||||
$query->withOwnerPHIDs($owner_phids);
|
|
||||||
|
if ($map['ownerPHIDs']) {
|
||||||
|
$query->withOwnerPHIDs($map['ownerPHIDs']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
|
if ($map['repositoryPHIDs']) {
|
||||||
if ($repository_phids) {
|
$query->withRepositoryPHIDs($map['repositoryPHIDs']);
|
||||||
$query->withRepositoryPHIDs($repository_phids);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildSearchForm(
|
|
||||||
AphrontFormView $form,
|
|
||||||
PhabricatorSavedQuery $saved) {
|
|
||||||
|
|
||||||
$owner_phids = $saved->getParameter('ownerPHIDs', array());
|
|
||||||
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
|
|
||||||
|
|
||||||
$form
|
|
||||||
->appendControl(
|
|
||||||
id(new AphrontFormTokenizerControl())
|
|
||||||
->setDatasource(new PhabricatorProjectOrUserDatasource())
|
|
||||||
->setName('owners')
|
|
||||||
->setLabel(pht('Owners'))
|
|
||||||
->setValue($owner_phids))
|
|
||||||
->appendControl(
|
|
||||||
id(new AphrontFormTokenizerControl())
|
|
||||||
->setDatasource(new DiffusionRepositoryDatasource())
|
|
||||||
->setName('repositories')
|
|
||||||
->setLabel(pht('Repositories'))
|
|
||||||
->setValue($repository_phids));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getURI($path) {
|
protected function getURI($path) {
|
||||||
return '/owners/'.$path;
|
return '/owners/'.$path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,6 @@
|
||||||
final class PhabricatorOwnersPackageDatasource
|
final class PhabricatorOwnersPackageDatasource
|
||||||
extends PhabricatorTypeaheadDatasource {
|
extends PhabricatorTypeaheadDatasource {
|
||||||
|
|
||||||
public function isBrowsable() {
|
|
||||||
// TODO: Make this browsable.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBrowseTitle() {
|
public function getBrowseTitle() {
|
||||||
return pht('Browse Packages');
|
return pht('Browse Packages');
|
||||||
}
|
}
|
||||||
|
@ -26,10 +21,11 @@ final class PhabricatorOwnersPackageDatasource
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
$packages = id(new PhabricatorOwnersPackageQuery())
|
$query = id(new PhabricatorOwnersPackageQuery())
|
||||||
->setViewer($viewer)
|
->withNamePrefix($raw_query)
|
||||||
->execute();
|
->setOrder('name');
|
||||||
|
|
||||||
|
$packages = $this->executeQuery($query);
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$results[] = id(new PhabricatorTypeaheadResult())
|
$results[] = id(new PhabricatorTypeaheadResult())
|
||||||
->setName($package->getName())
|
->setName($package->getName())
|
||||||
|
@ -37,7 +33,7 @@ final class PhabricatorOwnersPackageDatasource
|
||||||
->setPHID($package->getPHID());
|
->setPHID($package->getPHID());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
return $this->filterResultsAgainstTokens($results);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -738,6 +738,41 @@ final class PhabricatorUser
|
||||||
return new DateTimeZone($this->getTimezoneIdentifier());
|
return new DateTimeZone($this->getTimezoneIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPreference($key) {
|
||||||
|
$preferences = $this->loadPreferences();
|
||||||
|
|
||||||
|
// TODO: After T4103 and T7707 this should eventually be pushed down the
|
||||||
|
// stack into modular preference definitions and role profiles. This is
|
||||||
|
// just fixing T8601 and mildly anticipating those changes.
|
||||||
|
$value = $preferences->getPreference($key);
|
||||||
|
|
||||||
|
$allowed_values = null;
|
||||||
|
switch ($key) {
|
||||||
|
case PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT:
|
||||||
|
$allowed_values = array(
|
||||||
|
'g:i A',
|
||||||
|
'H:i',
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT:
|
||||||
|
$allowed_values = array(
|
||||||
|
'Y-m-d',
|
||||||
|
'n/j/Y',
|
||||||
|
'd-m-Y',
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($allowed_values !== null) {
|
||||||
|
$allowed_values = array_fuse($allowed_values);
|
||||||
|
if (empty($allowed_values[$value])) {
|
||||||
|
$value = head($allowed_values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
public function __toString() {
|
public function __toString() {
|
||||||
return $this->getUsername();
|
return $this->getUsername();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1913,7 +1913,25 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
PhabricatorDestructionEngine $engine) {
|
PhabricatorDestructionEngine $engine) {
|
||||||
|
|
||||||
$this->openTransaction();
|
$this->openTransaction();
|
||||||
$this->delete();
|
|
||||||
|
$this->delete();
|
||||||
|
|
||||||
|
$books = id(new DivinerBookQuery())
|
||||||
|
->setViewer($engine->getViewer())
|
||||||
|
->withRepositoryPHIDs(array($this->getPHID()))
|
||||||
|
->execute();
|
||||||
|
foreach ($books as $book) {
|
||||||
|
$engine->destroyObject($book);
|
||||||
|
}
|
||||||
|
|
||||||
|
$atoms = id(new DivinerAtomQuery())
|
||||||
|
->setViewer($engine->getViewer())
|
||||||
|
->withRepositoryPHIDs(array($this->getPHID()))
|
||||||
|
->execute();
|
||||||
|
foreach ($atoms as $atom) {
|
||||||
|
$engine->destroyObject($atom);
|
||||||
|
}
|
||||||
|
|
||||||
$this->saveTransaction();
|
$this->saveTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,8 @@ abstract class PhabricatorWorker extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
$tasks = id(new PhabricatorWorkerArchiveTaskQuery())
|
$tasks = id(new PhabricatorWorkerArchiveTaskQuery())
|
||||||
->withIDs($task_ids);
|
->withIDs($task_ids)
|
||||||
|
->execute();
|
||||||
|
|
||||||
foreach ($tasks as $task) {
|
foreach ($tasks as $task) {
|
||||||
if ($task->getResult() != PhabricatorWorkerArchiveTask::RESULT_SUCCESS) {
|
if ($task->getResult() != PhabricatorWorkerArchiveTask::RESULT_SUCCESS) {
|
||||||
|
|
|
@ -198,10 +198,7 @@ final class PhabricatorMarkupEngine extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($this->objects[$key]['output'])) {
|
if (!isset($this->objects[$key]['output'])) {
|
||||||
throw new Exception(
|
throw new PhutilInvalidStateException('process');
|
||||||
pht(
|
|
||||||
'Call %s before using results.',
|
|
||||||
'process()'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,34 +45,57 @@ final class PhabricatorStorageManagementProbeWorkflow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$console->writeOut("%s\n", pht('APPROXIMATE TABLE SIZES'));
|
|
||||||
asort($totals);
|
asort($totals);
|
||||||
|
|
||||||
|
$table = id(new PhutilConsoleTable())
|
||||||
|
->setShowHeader(false)
|
||||||
|
->setPadding(2)
|
||||||
|
->addColumn('name', array('title' => pht('Database / Table')))
|
||||||
|
->addColumn('size', array('title' => pht('Size')))
|
||||||
|
->addColumn('percentage', array('title' => pht('Percentage')));
|
||||||
|
|
||||||
foreach ($totals as $db => $size) {
|
foreach ($totals as $db => $size) {
|
||||||
$database_size = $this->formatSize($totals[$db], $overall);
|
list($database_size, $database_percentage) = $this->formatSize(
|
||||||
$console->writeOut(
|
$totals[$db],
|
||||||
"**%s**\n",
|
$overall);
|
||||||
sprintf('%-32.32s %18s', $db, $database_size));
|
|
||||||
|
$table->addRow(array(
|
||||||
|
'name' => phutil_console_format('**%s**', $db),
|
||||||
|
'size' => phutil_console_format('**%s**', $database_size),
|
||||||
|
'percentage' => phutil_console_format('**%s**', $database_percentage),
|
||||||
|
));
|
||||||
$data[$db] = isort($data[$db], '_totalSize');
|
$data[$db] = isort($data[$db], '_totalSize');
|
||||||
foreach ($data[$db] as $table => $info) {
|
foreach ($data[$db] as $table_name => $info) {
|
||||||
$table_size = $this->formatSize($info['_totalSize'], $overall);
|
list($table_size, $table_percentage) = $this->formatSize(
|
||||||
$console->writeOut(
|
$info['_totalSize'],
|
||||||
"%s\n",
|
$overall);
|
||||||
sprintf(' %-28.28s %18s', $table, $table_size));
|
|
||||||
|
$table->addRow(array(
|
||||||
|
'name' => ' '.$table_name,
|
||||||
|
'size' => $table_size,
|
||||||
|
'percentage' => $table_percentage,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$overall_size = $this->formatSize($overall, $overall);
|
|
||||||
$console->writeOut(
|
|
||||||
"**%s**\n",
|
|
||||||
sprintf('%-32.32s %18s', pht('TOTAL'), $overall_size));
|
|
||||||
|
|
||||||
|
list($overall_size, $overall_percentage) = $this->formatSize(
|
||||||
|
$overall,
|
||||||
|
$overall);
|
||||||
|
$table->addRow(array(
|
||||||
|
'name' => phutil_console_format('**%s**', pht('TOTAL')),
|
||||||
|
'size' => phutil_console_format('**%s**', $overall_size),
|
||||||
|
'percentage' => phutil_console_format('**%s**', $overall_percentage),
|
||||||
|
));
|
||||||
|
|
||||||
|
$table->draw();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function formatSize($n, $o) {
|
private function formatSize($n, $o) {
|
||||||
return sprintf(
|
return array(
|
||||||
'%8.8s MB %5.5s%%',
|
sprintf('%8.8s MB', number_format($n / (1024 * 1024), 1)),
|
||||||
number_format($n / (1024 * 1024), 1),
|
sprintf('%3.1f%%', 100 * ($n / $o)),
|
||||||
sprintf('%3.1f', 100 * ($n / $o)));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,19 +137,13 @@ final class AphrontFormDateControl extends AphrontFormControl {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getTimeFormat() {
|
private function getTimeFormat() {
|
||||||
$viewer = $this->getUser();
|
return $this->getUser()
|
||||||
$preferences = $viewer->loadPreferences();
|
->getPreference(PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT);
|
||||||
$pref_time_format = PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT;
|
|
||||||
|
|
||||||
return $preferences->getPreference($pref_time_format, 'g:i A');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDateFormat() {
|
private function getDateFormat() {
|
||||||
$viewer = $this->getUser();
|
return $this->getUser()
|
||||||
$preferences = $viewer->loadPreferences();
|
->getPreference(PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT);
|
||||||
$pref_date_format = PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT;
|
|
||||||
|
|
||||||
return $preferences->getPreference($pref_date_format, 'Y-m-d');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getTimeInputValue() {
|
private function getTimeInputValue() {
|
||||||
|
|
|
@ -10,7 +10,6 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
private $zone;
|
private $zone;
|
||||||
private $optional;
|
private $optional;
|
||||||
|
|
||||||
|
|
||||||
public function getValueDate() {
|
public function getValueDate() {
|
||||||
return $this->valueDate;
|
return $this->valueDate;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +55,10 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
return $this->optional;
|
return $this->optional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getViewer() {
|
||||||
|
return $this->viewer;
|
||||||
|
}
|
||||||
|
|
||||||
public static function newFromParts(
|
public static function newFromParts(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
$year,
|
$year,
|
||||||
|
@ -71,8 +74,7 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
$year,
|
$year,
|
||||||
$month,
|
$month,
|
||||||
$day,
|
$day,
|
||||||
coalesce($time, '12:00 AM'),
|
coalesce($time, '12:00 AM'));
|
||||||
$value);
|
|
||||||
$value->valueEnabled = $enabled;
|
$value->valueEnabled = $enabled;
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
|
@ -85,8 +87,7 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
list($value->valueDate, $value->valueTime) =
|
list($value->valueDate, $value->valueTime) =
|
||||||
$value->getFormattedDateFromDate(
|
$value->getFormattedDateFromDate(
|
||||||
$request->getStr($key.'_d'),
|
$request->getStr($key.'_d'),
|
||||||
$request->getStr($key.'_t'),
|
$request->getStr($key.'_t'));
|
||||||
$value);
|
|
||||||
|
|
||||||
$value->valueEnabled = $request->getStr($key.'_e');
|
$value->valueEnabled = $request->getStr($key.'_e');
|
||||||
return $value;
|
return $value;
|
||||||
|
@ -108,8 +109,7 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
$year,
|
$year,
|
||||||
$month,
|
$month,
|
||||||
$day,
|
$day,
|
||||||
$time,
|
$time);
|
||||||
$value);
|
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,7 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
list($value->valueDate, $value->valueTime) =
|
list($value->valueDate, $value->valueTime) =
|
||||||
$value->getFormattedDateFromDate(
|
$value->getFormattedDateFromDate(
|
||||||
idx($dictionary, 'd'),
|
idx($dictionary, 'd'),
|
||||||
idx($dictionary, 't'),
|
idx($dictionary, 't'));
|
||||||
$value);
|
|
||||||
|
|
||||||
$value->valueEnabled = idx($dictionary, 'e');
|
$value->valueEnabled = idx($dictionary, 'e');
|
||||||
|
|
||||||
|
@ -205,29 +204,25 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getTimeFormat() {
|
private function getTimeFormat() {
|
||||||
$preferences = $this->viewer->loadPreferences();
|
return $this->getViewer()
|
||||||
$pref_time_format = PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT;
|
->getPreference(PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT);
|
||||||
|
|
||||||
return $preferences->getPreference($pref_time_format, 'g:i A');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getDateFormat() {
|
private function getDateFormat() {
|
||||||
$preferences = $this->viewer->loadPreferences();
|
return $this->getViewer()
|
||||||
$pref_date_format = PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT;
|
->getPreference(PhabricatorUserPreferences::PREFERENCE_DATE_FORMAT);
|
||||||
|
|
||||||
return $preferences->getPreference($pref_date_format, 'Y-m-d');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFormattedDateFromDate($date, $time, $value) {
|
private function getFormattedDateFromDate($date, $time) {
|
||||||
$original_input = $date;
|
$original_input = $date;
|
||||||
$zone = $value->getTimezone();
|
$zone = $this->getTimezone();
|
||||||
$separator = $value->getFormatSeparator();
|
$separator = $this->getFormatSeparator();
|
||||||
$parts = preg_split('@[,./:-]@', $date);
|
$parts = preg_split('@[,./:-]@', $date);
|
||||||
$date = implode($separator, $parts);
|
$date = implode($separator, $parts);
|
||||||
$date = id(new DateTime($date, $zone));
|
$date = id(new DateTime($date, $zone));
|
||||||
|
|
||||||
if ($date) {
|
if ($date) {
|
||||||
$date = $date->format($value->getDateFormat());
|
$date = $date->format($this->getDateFormat());
|
||||||
} else {
|
} else {
|
||||||
$date = $original_input;
|
$date = $original_input;
|
||||||
}
|
}
|
||||||
|
@ -235,8 +230,8 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
$date = id(new DateTime("{$date} {$time}", $zone));
|
$date = id(new DateTime("{$date} {$time}", $zone));
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$date->format($value->getDateFormat()),
|
$date->format($this->getDateFormat()),
|
||||||
$date->format($value->getTimeFormat()),
|
$date->format($this->getTimeFormat()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,14 +239,14 @@ final class AphrontFormDateControlValue extends Phobject {
|
||||||
$year,
|
$year,
|
||||||
$month,
|
$month,
|
||||||
$day,
|
$day,
|
||||||
$time,
|
$time) {
|
||||||
$value) {
|
|
||||||
$zone = $value->getTimezone();
|
$zone = $this->getTimezone();
|
||||||
$date_time = id(new DateTime("{$year}-{$month}-{$day} {$time}", $zone));
|
$date_time = id(new DateTime("{$year}-{$month}-{$day} {$time}", $zone));
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$date_time->format($value->getDateFormat()),
|
$date_time->format($this->getDateFormat()),
|
||||||
$date_time->format($value->getTimeFormat()),
|
$date_time->format($this->getTimeFormat()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,10 +162,10 @@ final class AphrontFormPolicyControl extends AphrontFormControl {
|
||||||
|
|
||||||
protected function renderInput() {
|
protected function renderInput() {
|
||||||
if (!$this->object) {
|
if (!$this->object) {
|
||||||
throw new Exception(pht('Call setPolicyObject() before rendering!'));
|
throw new PhutilInvalidStateException('setPolicyObject');
|
||||||
}
|
}
|
||||||
if (!$this->capability) {
|
if (!$this->capability) {
|
||||||
throw new Exception(pht('Call setCapability() before rendering!'));
|
throw new PhutilInvalidStateException('setCapability');
|
||||||
}
|
}
|
||||||
|
|
||||||
$policy = $this->object->getPolicy($this->capability);
|
$policy = $this->object->getPolicy($this->capability);
|
||||||
|
|
|
@ -109,8 +109,11 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
|
||||||
if (!$viewer) {
|
if (!$viewer) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
'Call setUser() before rendering tokenizers. Use appendControl() '.
|
'Call %s before rendering tokenizers. '.
|
||||||
'on AphrontFormView to do this easily.'));
|
'Use %s on %s to do this easily.',
|
||||||
|
'setUser()',
|
||||||
|
'appendControl()',
|
||||||
|
'AphrontFormView'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$values = nonempty($this->getValue(), array());
|
$values = nonempty($this->getValue(), array());
|
||||||
|
|
|
@ -187,10 +187,10 @@ final class AphrontSideNavFilterView extends AphrontView {
|
||||||
public function render() {
|
public function render() {
|
||||||
if ($this->menu->getItems()) {
|
if ($this->menu->getItems()) {
|
||||||
if (!$this->baseURI) {
|
if (!$this->baseURI) {
|
||||||
throw new Exception(pht('Call setBaseURI() before render()!'));
|
throw new PhutilInvalidStateException('setBaseURI');
|
||||||
}
|
}
|
||||||
if ($this->selectedFilter === false) {
|
if ($this->selectedFilter === false) {
|
||||||
throw new Exception(pht('Call selectFilter() before render()!'));
|
throw new PhutilInvalidStateException('selectFilter');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ final class PhabricatorActionListView extends AphrontView {
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
if (!$this->user) {
|
if (!$this->user) {
|
||||||
throw new Exception(pht('Call setUser() before render()!'));
|
throw new PhutilInvalidStateException('setUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
$event = new PhabricatorEvent(
|
$event = new PhabricatorEvent(
|
||||||
|
|
|
@ -144,7 +144,7 @@ final class PHUITagView extends AphrontTagView {
|
||||||
|
|
||||||
protected function getTagContent() {
|
protected function getTagContent() {
|
||||||
if (!$this->type) {
|
if (!$this->type) {
|
||||||
throw new Exception(pht('You must call setType() before render()!'));
|
throw new PhutilInvalidStateException('setType', 'render');
|
||||||
}
|
}
|
||||||
|
|
||||||
$color = null;
|
$color = null;
|
||||||
|
|
|
@ -141,11 +141,8 @@ final class PHUICalendarListView extends AphrontTagView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getEventTooltip(AphrontCalendarEventView $event) {
|
private function getEventTooltip(AphrontCalendarEventView $event) {
|
||||||
$viewer = $this->getUser();
|
$time_pref = $this->getUser()
|
||||||
$preferences = $viewer->loadPreferences();
|
->getPreference(PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT);
|
||||||
$time_pref = $preferences->getPreference(
|
|
||||||
PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT,
|
|
||||||
'g:i A');
|
|
||||||
|
|
||||||
Javelin::initBehavior('phabricator-tooltips');
|
Javelin::initBehavior('phabricator-tooltips');
|
||||||
|
|
||||||
|
|
|
@ -31,32 +31,21 @@ function phabricator_relative_date($epoch, $user, $on = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function phabricator_time($epoch, $user) {
|
function phabricator_time($epoch, $user) {
|
||||||
|
$time_key = PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT;
|
||||||
return phabricator_format_local_time(
|
return phabricator_format_local_time(
|
||||||
$epoch,
|
$epoch,
|
||||||
$user,
|
$user,
|
||||||
phabricator_time_format($user));
|
$user->getPreference($time_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
function phabricator_datetime($epoch, $user) {
|
function phabricator_datetime($epoch, $user) {
|
||||||
|
$time_key = PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT;
|
||||||
return phabricator_format_local_time(
|
return phabricator_format_local_time(
|
||||||
$epoch,
|
$epoch,
|
||||||
$user,
|
$user,
|
||||||
pht('%s, %s',
|
pht('%s, %s',
|
||||||
phutil_date_format($epoch),
|
phutil_date_format($epoch),
|
||||||
phabricator_time_format($user)));
|
$user->getPreference($time_key)));
|
||||||
}
|
|
||||||
|
|
||||||
function phabricator_time_format($user) {
|
|
||||||
$prefs = $user->loadPreferences();
|
|
||||||
|
|
||||||
$pref = $prefs->getPreference(
|
|
||||||
PhabricatorUserPreferences::PREFERENCE_TIME_FORMAT);
|
|
||||||
|
|
||||||
if (strlen($pref)) {
|
|
||||||
return $pref;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pht('g:i A');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -99,8 +99,20 @@ JX.behavior('phabricator-remarkup-assist', function(config) {
|
||||||
} else {
|
} else {
|
||||||
sel = [def];
|
sel = [def];
|
||||||
}
|
}
|
||||||
sel = sel.join('\n' + ch);
|
|
||||||
return sel;
|
if (ch === '>') {
|
||||||
|
for(var i=0; i < sel.length; i++) {
|
||||||
|
if (sel[i][0] === '>') {
|
||||||
|
ch = '>';
|
||||||
|
} else {
|
||||||
|
ch = '> ';
|
||||||
|
}
|
||||||
|
sel[i] = ch + sel[i];
|
||||||
|
}
|
||||||
|
return sel.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sel.join('\n' + ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
function assist(area, action, root) {
|
function assist(area, action, root) {
|
||||||
|
@ -141,9 +153,9 @@ JX.behavior('phabricator-remarkup-assist', function(config) {
|
||||||
update(area, code_prefix + '```\n', sel, '\n```');
|
update(area, code_prefix + '```\n', sel, '\n```');
|
||||||
break;
|
break;
|
||||||
case 'fa-quote-right':
|
case 'fa-quote-right':
|
||||||
ch = '> ';
|
ch = '>';
|
||||||
sel = prepend_char_to_lines(ch, sel, pht('Quoted Text'));
|
sel = prepend_char_to_lines(ch, sel, pht('Quoted Text'));
|
||||||
update(area, ((r.start === 0) ? '' : '\n\n') + ch, sel, '\n\n');
|
update(area, ((r.start === 0) ? '' : '\n\n'), sel, '\n\n');
|
||||||
break;
|
break;
|
||||||
case 'fa-table':
|
case 'fa-table':
|
||||||
var table_prefix = (r.start === 0 ? '' : '\n\n');
|
var table_prefix = (r.start === 0 ? '' : '\n\n');
|
||||||
|
|
Loading…
Reference in a new issue