mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 05:50:55 +01:00
Modernize most Conduit console interfaces
Summary: Ref T603. Ref T2625. Long chain of "doing the right thing" here: I want to clean this up, so I can clean up the Conduit logs, so I can add a setup issue for deprecated method calls, so I can remove deprecated methods, so I can get rid of `DifferentialRevisionListData`, so I can make Differntial policy-aware. Adds modern infrastructure and UI to all of the Conduit interfaces (except only partially for the logs, that will be the next diff). Test Plan: {F48201} {F48202} {F48203} {F48204} {F48206} This will get further updates in the next diff: {F48205} Reviewers: btrahan, chad Reviewed By: chad CC: aran Maniphest Tasks: T603, T2625 Differential Revision: https://secure.phabricator.com/D6331
This commit is contained in:
parent
e4eeff8140
commit
f82e4b0c70
13 changed files with 513 additions and 227 deletions
|
@ -921,6 +921,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitListController' => 'applications/conduit/controller/PhabricatorConduitListController.php',
|
'PhabricatorConduitListController' => 'applications/conduit/controller/PhabricatorConduitListController.php',
|
||||||
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
|
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
|
||||||
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
|
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
|
||||||
|
'PhabricatorConduitMethodQuery' => 'applications/conduit/query/PhabricatorConduitMethodQuery.php',
|
||||||
|
'PhabricatorConduitSearchEngine' => 'applications/conduit/query/PhabricatorConduitSearchEngine.php',
|
||||||
'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
|
'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
|
||||||
'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php',
|
'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php',
|
||||||
'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
|
'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
|
||||||
|
@ -2009,6 +2011,11 @@ phutil_register_library_map(array(
|
||||||
'CelerityResourceController' => 'PhabricatorController',
|
'CelerityResourceController' => 'PhabricatorController',
|
||||||
'CelerityResourceGraph' => 'AbstractDirectedGraph',
|
'CelerityResourceGraph' => 'AbstractDirectedGraph',
|
||||||
'CelerityResourceTransformerTestCase' => 'PhabricatorTestCase',
|
'CelerityResourceTransformerTestCase' => 'PhabricatorTestCase',
|
||||||
|
'ConduitAPIMethod' =>
|
||||||
|
array(
|
||||||
|
0 => 'Phobject',
|
||||||
|
1 => 'PhabricatorPolicyInterface',
|
||||||
|
),
|
||||||
'ConduitAPI_arcanist_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_arcanist_Method' => 'ConduitAPIMethod',
|
||||||
'ConduitAPI_arcanist_projectinfo_Method' => 'ConduitAPI_arcanist_Method',
|
'ConduitAPI_arcanist_projectinfo_Method' => 'ConduitAPI_arcanist_Method',
|
||||||
'ConduitAPI_audit_Method' => 'ConduitAPIMethod',
|
'ConduitAPI_audit_Method' => 'ConduitAPIMethod',
|
||||||
|
@ -2807,9 +2814,15 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
|
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
|
||||||
'PhabricatorConduitController' => 'PhabricatorController',
|
'PhabricatorConduitController' => 'PhabricatorController',
|
||||||
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorConduitListController' => 'PhabricatorConduitController',
|
'PhabricatorConduitListController' =>
|
||||||
|
array(
|
||||||
|
0 => 'PhabricatorConduitController',
|
||||||
|
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
||||||
|
),
|
||||||
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
|
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
|
||||||
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
|
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
|
||||||
|
'PhabricatorConduitMethodQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorConduitSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
|
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
|
||||||
'PhabricatorConfigAllController' => 'PhabricatorConfigController',
|
'PhabricatorConfigAllController' => 'PhabricatorConfigController',
|
||||||
'PhabricatorConfigController' => 'PhabricatorController',
|
'PhabricatorConfigController' => 'PhabricatorController',
|
||||||
|
|
|
@ -38,7 +38,7 @@ final class PhabricatorApplicationConduit extends PhabricatorApplication {
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/conduit/' => array(
|
'/conduit/' => array(
|
||||||
'' => 'PhabricatorConduitListController',
|
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorConduitListController',
|
||||||
'method/(?P<method>[^/]+)/' => 'PhabricatorConduitConsoleController',
|
'method/(?P<method>[^/]+)/' => 'PhabricatorConduitConsoleController',
|
||||||
'log/' => 'PhabricatorConduitLogController',
|
'log/' => 'PhabricatorConduitLogController',
|
||||||
'log/view/(?P<view>[^/]+)/' => 'PhabricatorConduitLogController',
|
'log/view/(?P<view>[^/]+)/' => 'PhabricatorConduitLogController',
|
||||||
|
|
|
@ -354,6 +354,7 @@ final class PhabricatorConduitAPIController
|
||||||
}
|
}
|
||||||
|
|
||||||
$param_table = new AphrontTableView($param_rows);
|
$param_table = new AphrontTableView($param_rows);
|
||||||
|
$param_table->setDeviceReadyTable(true);
|
||||||
$param_table->setColumnClasses(
|
$param_table->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
'header',
|
'header',
|
||||||
|
@ -369,6 +370,7 @@ final class PhabricatorConduitAPIController
|
||||||
}
|
}
|
||||||
|
|
||||||
$result_table = new AphrontTableView($result_rows);
|
$result_table = new AphrontTableView($result_rows);
|
||||||
|
$result_table->setDeviceReadyTable(true);
|
||||||
$result_table->setColumnClasses(
|
$result_table->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
'header',
|
'header',
|
||||||
|
@ -383,13 +385,36 @@ final class PhabricatorConduitAPIController
|
||||||
$result_panel->setHeader('Method Result');
|
$result_panel->setHeader('Method Result');
|
||||||
$result_panel->appendChild($result_table);
|
$result_panel->appendChild($result_table);
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
$param_head = id(new PhabricatorHeaderView())
|
||||||
|
->setHeader(pht('Method Parameters'));
|
||||||
|
|
||||||
|
$result_head = id(new PhabricatorHeaderView())
|
||||||
|
->setHeader(pht('Method Result'));
|
||||||
|
|
||||||
|
$method_uri = $this->getApplicationURI('method/'.$method.'/');
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
$crumbs
|
||||||
|
->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName($method)
|
||||||
|
->setHref($method_uri))
|
||||||
|
->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName(pht('Call')));
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
$param_panel,
|
$crumbs,
|
||||||
$result_panel,
|
$param_head,
|
||||||
|
$param_table,
|
||||||
|
$result_head,
|
||||||
|
$result_table,
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'title' => 'Method Call Result',
|
'title' => 'Method Call Result',
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,18 +15,19 @@ final class PhabricatorConduitConsoleController
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
|
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
$methods = $this->getAllMethods();
|
$method = id(new PhabricatorConduitMethodQuery())
|
||||||
if (empty($methods[$this->method])) {
|
->setViewer($viewer)
|
||||||
|
->withMethods(array($this->method))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if (!$method) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
$this->setFilter('method/'.$this->method);
|
|
||||||
|
|
||||||
$method_class = $methods[$this->method];
|
$status = $method->getMethodStatus();
|
||||||
$method_object = newv($method_class, array());
|
$reason = $method->getMethodStatusDescription();
|
||||||
|
|
||||||
$status = $method_object->getMethodStatus();
|
|
||||||
$reason = $method_object->getMethodStatusDescription();
|
|
||||||
|
|
||||||
$status_view = null;
|
$status_view = null;
|
||||||
if ($status != ConduitAPIMethod::METHOD_STATUS_STABLE) {
|
if ($status != ConduitAPIMethod::METHOD_STATUS_STABLE) {
|
||||||
|
@ -49,7 +50,7 @@ final class PhabricatorConduitConsoleController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$error_types = $method_object->defineErrorTypes();
|
$error_types = $method->defineErrorTypes();
|
||||||
if ($error_types) {
|
if ($error_types) {
|
||||||
$error_description = array();
|
$error_description = array();
|
||||||
foreach ($error_types as $error => $meaning) {
|
foreach ($error_types as $error => $meaning) {
|
||||||
|
@ -68,14 +69,15 @@ final class PhabricatorConduitConsoleController
|
||||||
->setUser($request->getUser())
|
->setUser($request->getUser())
|
||||||
->setAction('/api/'.$this->method)
|
->setAction('/api/'.$this->method)
|
||||||
->addHiddenInput('allowEmptyParams', 1)
|
->addHiddenInput('allowEmptyParams', 1)
|
||||||
|
->setFlexible(true)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
->setLabel('Description')
|
->setLabel('Description')
|
||||||
->setValue($method_object->getMethodDescription()))
|
->setValue($method->getMethodDescription()))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormStaticControl())
|
id(new AphrontFormStaticControl())
|
||||||
->setLabel('Returns')
|
->setLabel('Returns')
|
||||||
->setValue($method_object->defineReturnType()))
|
->setValue($method->defineReturnType()))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormMarkupControl())
|
id(new AphrontFormMarkupControl())
|
||||||
->setLabel('Errors')
|
->setLabel('Errors')
|
||||||
|
@ -85,7 +87,7 @@ final class PhabricatorConduitConsoleController
|
||||||
'<strong>JSON</strong>. For instance, to enter a list, type: '.
|
'<strong>JSON</strong>. For instance, to enter a list, type: '.
|
||||||
'<tt>["apple", "banana", "cherry"]</tt>'));
|
'<tt>["apple", "banana", "cherry"]</tt>'));
|
||||||
|
|
||||||
$params = $method_object->defineParamTypes();
|
$params = $method->defineParamTypes();
|
||||||
foreach ($params as $param => $desc) {
|
foreach ($params as $param => $desc) {
|
||||||
$form->appendChild(
|
$form->appendChild(
|
||||||
id(new AphrontFormTextControl())
|
id(new AphrontFormTextControl())
|
||||||
|
@ -106,30 +108,25 @@ final class PhabricatorConduitConsoleController
|
||||||
)))
|
)))
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormSubmitControl())
|
id(new AphrontFormSubmitControl())
|
||||||
|
->addCancelButton($this->getApplicationURI())
|
||||||
->setValue('Call Method'));
|
->setValue('Call Method'));
|
||||||
|
|
||||||
$panel = new AphrontPanelView();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$panel->setHeader('Conduit API: '.$this->method);
|
$crumbs->addCrumb(
|
||||||
$panel->appendChild($form);
|
id(new PhabricatorCrumbView())
|
||||||
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
|
->setName($method->getAPIMethodName()));
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
|
$crumbs,
|
||||||
$status_view,
|
$status_view,
|
||||||
$panel,
|
$form,
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'title' => 'Conduit Console - '.$this->method,
|
'title' => $method->getAPIMethodName(),
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAllMethods() {
|
|
||||||
$classes = $this->getAllMethodImplementationClasses();
|
|
||||||
$methods = array();
|
|
||||||
foreach ($classes as $class) {
|
|
||||||
$name = ConduitAPIMethod::getAPIMethodNameFromClassName($class);
|
|
||||||
$methods[$name] = $class;
|
|
||||||
}
|
|
||||||
return $methods;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,122 +5,27 @@
|
||||||
*/
|
*/
|
||||||
abstract class PhabricatorConduitController extends PhabricatorController {
|
abstract class PhabricatorConduitController extends PhabricatorController {
|
||||||
|
|
||||||
private $filter;
|
protected function buildSideNavView() {
|
||||||
protected $showSideNav;
|
$viewer = $this->getRequest()->getUser();
|
||||||
|
|
||||||
public function buildStandardPageResponse($view, array $data) {
|
|
||||||
$page = $this->buildStandardPageView();
|
|
||||||
|
|
||||||
$page->setApplicationName('Conduit');
|
|
||||||
$page->setBaseURI('/conduit/');
|
|
||||||
$page->setTitle(idx($data, 'title'));
|
|
||||||
$page->setGlyph("\xE2\x87\xB5");
|
|
||||||
|
|
||||||
if ($this->showSideNav()) {
|
|
||||||
|
|
||||||
$nav = new AphrontSideNavFilterView();
|
$nav = new AphrontSideNavFilterView();
|
||||||
$nav->setBaseURI(new PhutilURI('/conduit/'));
|
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||||
$method_filters = $this->getMethodFilters();
|
|
||||||
foreach ($method_filters as $group => $methods) {
|
|
||||||
$nav->addLabel($group);
|
|
||||||
foreach ($methods as $method) {
|
|
||||||
$method_name = $method['full_name'];
|
|
||||||
|
|
||||||
$display_name = $method_name;
|
id(new PhabricatorConduitSearchEngine())
|
||||||
switch ($method['status']) {
|
->setViewer($viewer)
|
||||||
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
|
->addNavigationItems($nav->getMenu());
|
||||||
$display_name = '('.$display_name.')';
|
|
||||||
break;
|
$nav->addLabel('Logs');
|
||||||
|
$nav->addFilter('log', pht('Call Logs'));
|
||||||
|
|
||||||
|
$nav->selectFilter(null);
|
||||||
|
|
||||||
|
return $nav;
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav->addFilter('method/'.$method_name,
|
protected function buildApplicationMenu() {
|
||||||
$display_name);
|
return $this->buildSideNavView()->getMenu();
|
||||||
}
|
|
||||||
}
|
|
||||||
$nav->selectFilter($this->getFilter());
|
|
||||||
$nav->appendChild($view);
|
|
||||||
$body = $nav;
|
|
||||||
} else {
|
|
||||||
$body = $view;
|
|
||||||
}
|
|
||||||
$page->appendChild($body);
|
|
||||||
|
|
||||||
$response = new AphrontWebpageResponse();
|
|
||||||
return $response->setContent($page->render());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFilter() {
|
|
||||||
return $this->filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function setFilter($filter) {
|
|
||||||
$this->filter = $filter;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function showSideNav() {
|
|
||||||
return $this->showSideNav !== false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function setShowSideNav($show_side_nav) {
|
|
||||||
$this->showSideNav = $show_side_nav;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getAllMethodImplementationClasses() {
|
|
||||||
$classes = id(new PhutilSymbolLoader())
|
|
||||||
->setAncestorClass('ConduitAPIMethod')
|
|
||||||
->setType('class')
|
|
||||||
->setConcreteOnly(true)
|
|
||||||
->selectSymbolsWithoutLoading();
|
|
||||||
|
|
||||||
return array_values(ipull($classes, 'name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getMethodFilters() {
|
|
||||||
$classes = $this->getAllMethodImplementationClasses();
|
|
||||||
$method_names = array();
|
|
||||||
foreach ($classes as $method_class) {
|
|
||||||
$method_name = ConduitAPIMethod::getAPIMethodNameFromClassName(
|
|
||||||
$method_class);
|
|
||||||
$group_name = head(explode('.', $method_name));
|
|
||||||
|
|
||||||
$method_object = newv($method_class, array());
|
|
||||||
|
|
||||||
$application = $method_object->getApplication();
|
|
||||||
if ($application && !$application->isInstalled()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$status = $method_object->getMethodStatus();
|
|
||||||
|
|
||||||
$key = sprintf(
|
|
||||||
'%02d %s %s',
|
|
||||||
$this->getOrderForMethodStatus($status),
|
|
||||||
$group_name,
|
|
||||||
$method_name);
|
|
||||||
|
|
||||||
$method_names[$key] = array(
|
|
||||||
'full_name' => $method_name,
|
|
||||||
'group_name' => $group_name,
|
|
||||||
'status' => $status,
|
|
||||||
'description' => $method_object->getMethodDescription(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ksort($method_names);
|
|
||||||
$method_names = igroup($method_names, 'group_name');
|
|
||||||
ksort($method_names);
|
|
||||||
|
|
||||||
return $method_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getOrderForMethodStatus($status) {
|
|
||||||
$map = array(
|
|
||||||
ConduitAPIMethod::METHOD_STATUS_STABLE => 0,
|
|
||||||
ConduitAPIMethod::METHOD_STATUS_UNSTABLE => 1,
|
|
||||||
ConduitAPIMethod::METHOD_STATUS_DEPRECATED => 2,
|
|
||||||
);
|
|
||||||
return idx($map, $status, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,78 +4,78 @@
|
||||||
* @group conduit
|
* @group conduit
|
||||||
*/
|
*/
|
||||||
final class PhabricatorConduitListController
|
final class PhabricatorConduitListController
|
||||||
extends PhabricatorConduitController {
|
extends PhabricatorConduitController
|
||||||
|
implements PhabricatorApplicationSearchResultsControllerInterface {
|
||||||
|
|
||||||
|
private $queryKey;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->queryKey = idx($data, 'queryKey');
|
||||||
|
}
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$method_groups = $this->getMethodFilters();
|
$request = $this->getRequest();
|
||||||
$rows = array();
|
$controller = id(new PhabricatorApplicationSearchController($request))
|
||||||
foreach ($method_groups as $group => $methods) {
|
->setQueryKey($this->queryKey)
|
||||||
foreach ($methods as $info) {
|
->setSearchEngine(new PhabricatorConduitSearchEngine())
|
||||||
switch ($info['status']) {
|
->setNavigation($this->buildSideNavView());
|
||||||
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
|
return $this->delegateToController($controller);
|
||||||
$status = 'Deprecated';
|
}
|
||||||
|
|
||||||
|
public function renderResultsList(array $methods) {
|
||||||
|
assert_instances_of($methods, 'ConduitAPIMethod');
|
||||||
|
|
||||||
|
$viewer = $this->getRequest()->getUser();
|
||||||
|
|
||||||
|
$out = array();
|
||||||
|
|
||||||
|
$last = null;
|
||||||
|
$list = null;
|
||||||
|
foreach ($methods as $method) {
|
||||||
|
$app = $method->getApplicationName();
|
||||||
|
if ($app !== $last) {
|
||||||
|
$last = $app;
|
||||||
|
if ($list) {
|
||||||
|
$out[] = $list;
|
||||||
|
}
|
||||||
|
$list = id(new PhabricatorObjectItemListView());
|
||||||
|
|
||||||
|
$app_object = $method->getApplication();
|
||||||
|
if ($app_object) {
|
||||||
|
$app_name = $app_object->getName();
|
||||||
|
} else {
|
||||||
|
$app_name = $app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$method_name = $method->getAPIMethodName();
|
||||||
|
|
||||||
|
$item = id(new PhabricatorObjectItemView())
|
||||||
|
->setHeader($method_name)
|
||||||
|
->setHref($this->getApplicationURI('method/'.$method_name.'/'))
|
||||||
|
->addAttribute($method->getMethodDescription());
|
||||||
|
|
||||||
|
switch ($method->getMethodStatus()) {
|
||||||
|
case ConduitAPIMethod::METHOD_STATUS_STABLE:
|
||||||
break;
|
break;
|
||||||
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
|
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
|
||||||
$status = 'Unstable';
|
$item->addIcon('warning-grey', pht('Unstable'));
|
||||||
|
$item->setBarColor('yellow');
|
||||||
break;
|
break;
|
||||||
default:
|
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
|
||||||
$status = null;
|
$item->addIcon('warning', pht('Deprecated'));
|
||||||
|
$item->setBarColor('red');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rows[] = array(
|
$list->addItem($item);
|
||||||
$group,
|
|
||||||
phutil_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => '/conduit/method/'.$info['full_name'],
|
|
||||||
),
|
|
||||||
$info['full_name']),
|
|
||||||
$info['description'],
|
|
||||||
$status,
|
|
||||||
);
|
|
||||||
$group = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$table = new AphrontTableView($rows);
|
if ($list) {
|
||||||
$table->setHeaders(array(
|
$out[] = $list;
|
||||||
'Group',
|
}
|
||||||
'Name',
|
|
||||||
'Description',
|
|
||||||
'Status',
|
|
||||||
));
|
|
||||||
$table->setColumnClasses(array(
|
|
||||||
'pri',
|
|
||||||
'pri',
|
|
||||||
'wide',
|
|
||||||
null,
|
|
||||||
));
|
|
||||||
|
|
||||||
$panel = new AphrontPanelView();
|
return $out;
|
||||||
$panel->setHeader('Conduit Methods');
|
|
||||||
$panel->appendChild($table);
|
|
||||||
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
|
|
||||||
|
|
||||||
$utils = new AphrontPanelView();
|
|
||||||
$utils->setHeader('Utilities');
|
|
||||||
$utils->appendChild(hsprintf(
|
|
||||||
'<ul>'.
|
|
||||||
'<li><a href="/conduit/log/">Log</a> - Conduit Method Calls</li>'.
|
|
||||||
'<li><a href="/conduit/token/">Token</a> - Certificate Install</li>'.
|
|
||||||
'</ul>'));
|
|
||||||
$utils->setWidth(AphrontPanelView::WIDTH_FULL);
|
|
||||||
|
|
||||||
$this->setShowSideNav(false);
|
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
|
||||||
array(
|
|
||||||
$panel,
|
|
||||||
$utils,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'title' => 'Conduit Console',
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,16 @@ final class PhabricatorConduitLogController
|
||||||
$panel->appendChild($table);
|
$panel->appendChild($table);
|
||||||
$panel->appendChild($pager);
|
$panel->appendChild($pager);
|
||||||
|
|
||||||
$this->setShowSideNav(false);
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName(pht('Call Logs')));
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
$panel,
|
$panel,
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'title' => 'Conduit Logs',
|
'title' => 'Conduit Logs',
|
||||||
));
|
));
|
||||||
|
|
|
@ -28,26 +28,40 @@ final class PhabricatorConduitTokenController
|
||||||
->setToken(Filesystem::readRandomCharacters(40))
|
->setToken(Filesystem::readRandomCharacters(40))
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
$panel = new AphrontPanelView();
|
unset($unguarded);
|
||||||
$panel->setHeader('Certificate Install Token');
|
|
||||||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
|
||||||
|
|
||||||
$panel->appendChild(hsprintf(
|
$pre_instructions = pht(
|
||||||
'<p class="aphront-form-instructions">Copy and paste this token into '.
|
'Copy and paste this token into the prompt given to you by '.
|
||||||
'the prompt given to you by "arc install-certificate":</p>'.
|
'`arc install-certificate`');
|
||||||
'<p style="padding: 0 0 1em 4em;">'.
|
|
||||||
'<strong>%s</strong>'.
|
|
||||||
'</p>'.
|
|
||||||
'<p class="aphront-form-instructions">arc will then complete the '.
|
|
||||||
'install process for you.</p>',
|
|
||||||
$token->getToken()));
|
|
||||||
|
|
||||||
$this->setShowSideNav(false);
|
$post_instructions = pht(
|
||||||
|
'After you copy and paste this token, `arc` will complete '.
|
||||||
|
'the certificate install process for you.');
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
$form = id(new AphrontFormView())
|
||||||
$panel,
|
->setUser($user)
|
||||||
|
->appendRemarkupInstructions($pre_instructions)
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextAreaControl())
|
||||||
|
->setLabel(pht('Token'))
|
||||||
|
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
|
||||||
|
->setValue($token->getToken()))
|
||||||
|
->appendRemarkupInstructions($post_instructions);
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
$crumbs->addCrumb(
|
||||||
|
id(new PhabricatorCrumbView())
|
||||||
|
->setName(pht('Install Certificate')));
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
'title' => 'Certificate Install Token',
|
$crumbs,
|
||||||
|
$form,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => pht('Certificate Install Token'),
|
||||||
|
'device' => true,
|
||||||
|
'dust' => true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
* @task status Method Status
|
* @task status Method Status
|
||||||
* @group conduit
|
* @group conduit
|
||||||
*/
|
*/
|
||||||
abstract class ConduitAPIMethod {
|
abstract class ConduitAPIMethod
|
||||||
|
extends Phobject
|
||||||
|
implements PhabricatorPolicyInterface {
|
||||||
|
|
||||||
const METHOD_STATUS_STABLE = 'stable';
|
const METHOD_STATUS_STABLE = 'stable';
|
||||||
const METHOD_STATUS_UNSTABLE = 'unstable';
|
const METHOD_STATUS_UNSTABLE = 'unstable';
|
||||||
|
@ -21,6 +23,14 @@ abstract class ConduitAPIMethod {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is mostly for compatibility with
|
||||||
|
* @{class:AphrontCursorPagedPolicyAwareQuery}.
|
||||||
|
*/
|
||||||
|
public function getID() {
|
||||||
|
return $this->getAPIMethodName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the status for this method (e.g., stable, unstable or deprecated).
|
* Get the status for this method (e.g., stable, unstable or deprecated).
|
||||||
* Should return a METHOD_STATUS_* constant. By default, methods are
|
* Should return a METHOD_STATUS_* constant. By default, methods are
|
||||||
|
@ -62,6 +72,29 @@ abstract class ConduitAPIMethod {
|
||||||
return self::getAPIMethodNameFromClassName(get_class($this));
|
return self::getAPIMethodNameFromClassName(get_class($this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a key which sorts methods by application name, then method status,
|
||||||
|
* then method name.
|
||||||
|
*/
|
||||||
|
public function getSortOrder() {
|
||||||
|
$name = $this->getAPIMethodName();
|
||||||
|
|
||||||
|
$map = array(
|
||||||
|
ConduitAPIMethod::METHOD_STATUS_STABLE => 0,
|
||||||
|
ConduitAPIMethod::METHOD_STATUS_UNSTABLE => 1,
|
||||||
|
ConduitAPIMethod::METHOD_STATUS_DEPRECATED => 2,
|
||||||
|
);
|
||||||
|
$ord = idx($map, $this->getMethodStatus(), 0);
|
||||||
|
|
||||||
|
list($head, $tail) = explode('.', $name, 2);
|
||||||
|
|
||||||
|
return "{$head}.{$ord}.{$tail}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return head(explode('.', $this->getAPIMethodName(), 2));
|
||||||
|
}
|
||||||
|
|
||||||
public static function getClassNameFromAPIMethodName($method_name) {
|
public static function getClassNameFromAPIMethodName($method_name) {
|
||||||
$method_fragment = str_replace('.', '_', $method_name);
|
$method_fragment = str_replace('.', '_', $method_name);
|
||||||
return 'ConduitAPI_'.$method_fragment.'_Method';
|
return 'ConduitAPI_'.$method_fragment.'_Method';
|
||||||
|
@ -129,4 +162,25 @@ abstract class ConduitAPIMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getCapabilities() {
|
||||||
|
return array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPolicy($capability) {
|
||||||
|
return PhabricatorPolicies::POLICY_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
|
// The policy interface on Conduit calls is currently just to let us hook
|
||||||
|
// into ApplicationSearch. Calls are always visible (even to logged out
|
||||||
|
// users).
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
124
src/applications/conduit/query/PhabricatorConduitMethodQuery.php
Normal file
124
src/applications/conduit/query/PhabricatorConduitMethodQuery.php
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorConduitMethodQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $isDeprecated;
|
||||||
|
private $isStable;
|
||||||
|
private $isUnstable;
|
||||||
|
private $applicationNames;
|
||||||
|
private $nameContains;
|
||||||
|
private $methods;
|
||||||
|
|
||||||
|
public function withMethods(array $methods) {
|
||||||
|
$this->methods = $methods;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withNameContains($name_contains) {
|
||||||
|
$this->nameContains = $name_contains;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withApplicationNames(array $application_names) {
|
||||||
|
$this->applicationNames = $application_names;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withIsStable($is_stable) {
|
||||||
|
$this->isStable = $is_stable;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withIsUnstable($is_unstable) {
|
||||||
|
$this->isUnstable = $is_unstable;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withIsDeprecated($is_deprecated) {
|
||||||
|
$this->isDeprecated = $is_deprecated;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadPage() {
|
||||||
|
$methods = $this->getAllMethods();
|
||||||
|
|
||||||
|
$methods = $this->filterMethods($methods);
|
||||||
|
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAllMethods() {
|
||||||
|
static $methods;
|
||||||
|
if ($methods === null) {
|
||||||
|
$methods = id(new PhutilSymbolLoader())
|
||||||
|
->setAncestorClass('ConduitAPIMethod')
|
||||||
|
->loadObjects();
|
||||||
|
$methods = msort($methods, 'getSortOrder');
|
||||||
|
}
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function filterMethods(array $methods) {
|
||||||
|
foreach ($methods as $key => $method) {
|
||||||
|
$application = $method->getApplication();
|
||||||
|
if (!$application) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!$application->isInstalled()) {
|
||||||
|
unset($methods[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = array(
|
||||||
|
ConduitAPIMethod::METHOD_STATUS_STABLE => $this->isStable,
|
||||||
|
ConduitAPIMethod::METHOD_STATUS_DEPRECATED => $this->isDeprecated,
|
||||||
|
ConduitAPIMethod::METHOD_STATUS_UNSTABLE => $this->isUnstable,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Only apply status filters if any of them are set.
|
||||||
|
if (array_filter($status)) {
|
||||||
|
foreach ($methods as $key => $method) {
|
||||||
|
$keep = idx($status, $method->getMethodStatus());
|
||||||
|
if (!$keep) {
|
||||||
|
unset($methods[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->applicationNames) {
|
||||||
|
$map = array_fuse($this->applicationNames);
|
||||||
|
foreach ($methods as $key => $method) {
|
||||||
|
$needle = $method->getApplicationName();
|
||||||
|
$needle = phutil_utf8_strtolower($needle);
|
||||||
|
if (empty($map[$needle])) {
|
||||||
|
unset($methods[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->nameContains) {
|
||||||
|
$needle = phutil_utf8_strtolower($this->nameContains);
|
||||||
|
foreach ($methods as $key => $method) {
|
||||||
|
$haystack = $method->getAPIMethodName();
|
||||||
|
$haystack = phutil_utf8_strtolower($haystack);
|
||||||
|
if (strpos($haystack, $needle) === false) {
|
||||||
|
unset($methods[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->methods) {
|
||||||
|
$map = array_fuse($this->methods);
|
||||||
|
foreach ($methods as $key => $method) {
|
||||||
|
$needle = $method->getAPIMethodName();
|
||||||
|
if (empty($map[$needle])) {
|
||||||
|
unset($methods[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorConduitSearchEngine
|
||||||
|
extends PhabricatorApplicationSearchEngine {
|
||||||
|
|
||||||
|
public function getPageSize(PhabricatorSavedQuery $saved) {
|
||||||
|
return INF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||||
|
$saved = new PhabricatorSavedQuery();
|
||||||
|
|
||||||
|
$saved->setParameter('isStable', $request->getStr('isStable'));
|
||||||
|
$saved->setParameter('isUnstable', $request->getStr('isUnstable'));
|
||||||
|
$saved->setParameter('isDeprecated', $request->getStr('isDeprecated'));
|
||||||
|
|
||||||
|
$saved->setParameter(
|
||||||
|
'applicationNames',
|
||||||
|
$request->getStrList('applicationNames'));
|
||||||
|
|
||||||
|
$saved->setParameter('nameContains', $request->getStr('nameContains'));
|
||||||
|
|
||||||
|
return $saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||||
|
$query = id(new PhabricatorConduitMethodQuery());
|
||||||
|
|
||||||
|
$query->withIsStable($saved->getParameter('isStable'));
|
||||||
|
$query->withIsUnstable($saved->getParameter('isUnstable'));
|
||||||
|
$query->withIsDeprecated($saved->getParameter('isDeprecated'));
|
||||||
|
|
||||||
|
$names = $saved->getParameter('applicationNames', array());
|
||||||
|
if ($names) {
|
||||||
|
$query->withApplicationNames($names);
|
||||||
|
}
|
||||||
|
|
||||||
|
$contains = $saved->getParameter('nameContains');
|
||||||
|
if (strlen($contains)) {
|
||||||
|
$query->withNameContains($contains);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSearchForm(
|
||||||
|
AphrontFormView $form,
|
||||||
|
PhabricatorSavedQuery $saved) {
|
||||||
|
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Name Contains')
|
||||||
|
->setName('nameContains')
|
||||||
|
->setValue($saved->getParameter('nameContains')));
|
||||||
|
|
||||||
|
$names = $saved->getParameter('applicationNames', array());
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Applications')
|
||||||
|
->setName('applicationNames')
|
||||||
|
->setValue(implode(', ', $names))
|
||||||
|
->setCaption(
|
||||||
|
pht('Example: %s', hsprintf('<tt>differential, paste</tt>'))));
|
||||||
|
|
||||||
|
$is_stable = $saved->getParameter('isStable');
|
||||||
|
$is_unstable = $saved->getParameter('isUnstable');
|
||||||
|
$is_deprecated = $saved->getParameter('isDeprecated');
|
||||||
|
$form
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormCheckboxControl())
|
||||||
|
->setLabel('Stability')
|
||||||
|
->addCheckbox(
|
||||||
|
'isStable',
|
||||||
|
1,
|
||||||
|
hsprintf(
|
||||||
|
'<strong>%s</strong>: %s',
|
||||||
|
pht('Stable Methods'),
|
||||||
|
pht('Show established API methods with stable interfaces.')),
|
||||||
|
$is_stable)
|
||||||
|
->addCheckbox(
|
||||||
|
'isUnstable',
|
||||||
|
1,
|
||||||
|
hsprintf(
|
||||||
|
'<strong>%s</strong>: %s',
|
||||||
|
pht('Unstable Methods'),
|
||||||
|
pht('Show new methods which are subject to change.')),
|
||||||
|
$is_unstable)
|
||||||
|
->addCheckbox(
|
||||||
|
'isDeprecated',
|
||||||
|
1,
|
||||||
|
hsprintf(
|
||||||
|
'<strong>%s</strong>: %s',
|
||||||
|
pht('Deprecated Methods'),
|
||||||
|
pht(
|
||||||
|
'Show old methods which will be deleted in a future '.
|
||||||
|
'version of Phabricator.')),
|
||||||
|
$is_deprecated));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getURI($path) {
|
||||||
|
return '/conduit/'.$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBuiltinQueryNames() {
|
||||||
|
$names = array(
|
||||||
|
'modern' => pht('Modern Methods'),
|
||||||
|
'all' => pht('All Methods'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromBuiltin($query_key) {
|
||||||
|
|
||||||
|
$query = $this->newSavedQuery();
|
||||||
|
$query->setQueryKey($query_key);
|
||||||
|
|
||||||
|
switch ($query_key) {
|
||||||
|
case 'modern':
|
||||||
|
return $query
|
||||||
|
->setParameter('isStable', true)
|
||||||
|
->setParameter('isUnstable', true);
|
||||||
|
case 'all':
|
||||||
|
return $query
|
||||||
|
->setParameter('isStable', true)
|
||||||
|
->setParameter('isUnstable', true)
|
||||||
|
->setParameter('isDeprecated', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -173,16 +173,17 @@ final class PhabricatorApplicationSearchController
|
||||||
|
|
||||||
$pager = new AphrontCursorPagerView();
|
$pager = new AphrontCursorPagerView();
|
||||||
$pager->readFromRequest($request);
|
$pager->readFromRequest($request);
|
||||||
|
$pager->setPageSize($engine->getPageSize($saved_query));
|
||||||
$objects = $query->setViewer($request->getUser())
|
$objects = $query->setViewer($request->getUser())
|
||||||
->executeWithCursorPager($pager);
|
->executeWithCursorPager($pager);
|
||||||
|
|
||||||
$list = $parent->renderResultsList($objects);
|
$list = $parent->renderResultsList($objects);
|
||||||
$list->setNoDataString(pht("No results found for this query."));
|
|
||||||
|
|
||||||
$nav->appendChild($list);
|
$nav->appendChild($list);
|
||||||
|
|
||||||
// TODO: This is a bit hacky.
|
// TODO: This is a bit hacky.
|
||||||
if ($list instanceof PhabricatorObjectItemListView) {
|
if ($list instanceof PhabricatorObjectItemListView) {
|
||||||
|
$list->setNoDataString(pht("No results found for this query."));
|
||||||
$list->setPager($pager);
|
$list->setPager($pager);
|
||||||
} else {
|
} else {
|
||||||
$nav->appendChild($pager);
|
$nav->appendChild($pager);
|
||||||
|
|
|
@ -305,4 +305,14 @@ abstract class PhabricatorApplicationSearchEngine {
|
||||||
->setLabel($end_name)
|
->setLabel($end_name)
|
||||||
->setValue($end_str));
|
->setValue($end_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( Pagination )--------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getPageSize(PhabricatorSavedQuery $saved) {
|
||||||
|
return $saved->getParameter('limit', 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue