Path: blob/master/src/applications/conduit/controller/PhabricatorConduitConsoleController.php
12256 views
<?php12final class PhabricatorConduitConsoleController3extends PhabricatorConduitController {45public function shouldAllowPublic() {6return true;7}89public function handleRequest(AphrontRequest $request) {10$viewer = $this->getViewer();11$method_name = $request->getURIData('method');1213$method = id(new PhabricatorConduitMethodQuery())14->setViewer($viewer)15->withMethods(array($method_name))16->executeOne();17if (!$method) {18return new Aphront404Response();19}2021$method->setViewer($viewer);2223$call_uri = '/api/'.$method->getAPIMethodName();2425$errors = array();2627$form = id(new AphrontFormView())28->setAction($call_uri)29->setUser($request->getUser())30->appendRemarkupInstructions(31pht(32'Enter parameters using **JSON**. For instance, to enter a '.33'list, type: `%s`',34'["apple", "banana", "cherry"]'));3536$params = $method->getParamTypes();37foreach ($params as $param => $desc) {38$form->appendChild(39id(new AphrontFormTextControl())40->setLabel($param)41->setName("params[{$param}]")42->setCaption($desc));43}4445$must_login = !$viewer->isLoggedIn() &&46$method->shouldRequireAuthentication();47if ($must_login) {48$errors[] = pht(49'Login Required: This method requires authentication. You must '.50'log in before you can make calls to it.');51} else {52$form53->appendChild(54id(new AphrontFormSelectControl())55->setLabel(pht('Output Format'))56->setName('output')57->setOptions(58array(59'human' => pht('Human Readable'),60'json' => pht('JSON'),61)))62->appendChild(63id(new AphrontFormSubmitControl())64->addCancelButton($this->getApplicationURI())65->setValue(pht('Call Method')));66}6768$header = id(new PHUIHeaderView())69->setUser($viewer)70->setHeader($method->getAPIMethodName())71->setHeaderIcon('fa-tty');7273$form_box = id(new PHUIObjectBoxView())74->setHeaderText(pht('Call Method'))75->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)76->setForm($form);7778$properties = $this->buildMethodProperties($method);7980$info_box = id(new PHUIObjectBoxView())81->setHeaderText(pht('API Method: %s', $method->getAPIMethodName()))82->setFormErrors($errors)83->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)84->appendChild($properties);8586$crumbs = $this->buildApplicationCrumbs();87$crumbs->addTextCrumb($method->getAPIMethodName());88$crumbs->setBorder(true);8990$documentation_pages = $method->getDocumentationPages($viewer);9192$documentation_view = $this->newDocumentationView(93$method,94$documentation_pages);9596$view = id(new PHUITwoColumnView())97->setHeader($header)98->setFooter(array(99100id(new PhabricatorAnchorView())101->setAnchorName('overview'),102$info_box,103104id(new PhabricatorAnchorView())105->setAnchorName('documentation'),106$documentation_view,107108id(new PhabricatorAnchorView())109->setAnchorName('call'),110$form_box,111112id(new PhabricatorAnchorView())113->setAnchorName('examples'),114$this->renderExampleBox($method, null),115));116117$title = $method->getAPIMethodName();118119$nav = $this->newNavigationView($method, $documentation_pages);120121return $this->newPage()122->setTitle($title)123->setCrumbs($crumbs)124->setNavigation($nav)125->appendChild($view);126}127128private function newDocumentationView(129ConduitAPIMethod $method,130array $documentation_pages) {131assert_instances_of($documentation_pages, 'ConduitAPIDocumentationPage');132133$viewer = $this->getViewer();134135$description_properties = id(new PHUIPropertyListView());136137$description_properties->addTextContent(138new PHUIRemarkupView($viewer, $method->getMethodDescription()));139140$description_box = id(new PHUIObjectBoxView())141->setHeaderText(pht('Method Description'))142->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)143->appendChild($description_properties);144145$view = array();146$view[] = $description_box;147148foreach ($documentation_pages as $page) {149$view[] = $page->newView();150}151152return $view;153}154155private function newNavigationView(156ConduitAPIMethod $method,157array $documentation_pages) {158assert_instances_of($documentation_pages, 'ConduitAPIDocumentationPage');159160$console_uri = urisprintf(161'/method/%s/',162$method->getAPIMethodName());163$console_uri = $this->getApplicationURI($console_uri);164$console_uri = new PhutilURI($console_uri);165166$nav = id(new AphrontSideNavFilterView())167->setBaseURI($console_uri);168169$nav->selectFilter(null);170171$nav->newLink('overview')172->setHref('#overview')173->setName(pht('Overview'))174->setIcon('fa-list');175176$nav->newLink('documentation')177->setHref('#documentation')178->setName(pht('Documentation'))179->setIcon('fa-book');180181foreach ($documentation_pages as $page) {182$nav->newLink($page->getAnchor())183->setHref('#'.$page->getAnchor())184->setName($page->getName())185->setIcon($page->getIconIcon())186->setIndented(true);187}188189$nav->newLink('call')190->setHref('#call')191->setName(pht('Call Method'))192->setIcon('fa-play');193194$nav->newLink('examples')195->setHref('#examples')196->setName(pht('Examples'))197->setIcon('fa-folder-open-o');198199return $nav;200}201202private function buildMethodProperties(ConduitAPIMethod $method) {203$viewer = $this->getViewer();204205$view = id(new PHUIPropertyListView());206207$status = $method->getMethodStatus();208$reason = $method->getMethodStatusDescription();209210switch ($status) {211case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:212$stability_icon = 'fa-exclamation-triangle yellow';213$stability_label = pht('Unstable Method');214$stability_info = nonempty(215$reason,216pht(217'This method is new and unstable. Its interface is subject '.218'to change.'));219break;220case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:221$stability_icon = 'fa-exclamation-triangle red';222$stability_label = pht('Deprecated Method');223$stability_info = nonempty($reason, pht('This method is deprecated.'));224break;225case ConduitAPIMethod::METHOD_STATUS_FROZEN:226$stability_icon = 'fa-archive grey';227$stability_label = pht('Frozen Method');228$stability_info = nonempty(229$reason,230pht('This method is frozen and will eventually be deprecated.'));231break;232default:233$stability_label = null;234break;235}236237if ($stability_label) {238$view->addProperty(239pht('Stability'),240array(241id(new PHUIIconView())->setIcon($stability_icon),242' ',243phutil_tag('strong', array(), $stability_label.':'),244' ',245$stability_info,246));247}248249$view->addProperty(250pht('Returns'),251$method->getReturnType());252253$error_types = $method->getErrorTypes();254$error_types['ERR-CONDUIT-CORE'] = pht('See error message for details.');255$error_description = array();256foreach ($error_types as $error => $meaning) {257$error_description[] = hsprintf(258'<li><strong>%s:</strong> %s</li>',259$error,260$meaning);261}262$error_description = phutil_tag('ul', array(), $error_description);263264$view->addProperty(265pht('Errors'),266$error_description);267268$scope = $method->getRequiredScope();269switch ($scope) {270case ConduitAPIMethod::SCOPE_ALWAYS:271$oauth_icon = 'fa-globe green';272$oauth_description = pht(273'OAuth clients may always call this method.');274break;275case ConduitAPIMethod::SCOPE_NEVER:276$oauth_icon = 'fa-ban red';277$oauth_description = pht(278'OAuth clients may never call this method.');279break;280default:281$oauth_icon = 'fa-unlock-alt blue';282$oauth_description = pht(283'OAuth clients may call this method after requesting access to '.284'the "%s" scope.',285$scope);286break;287}288289$view->addProperty(290pht('OAuth Scope'),291array(292id(new PHUIIconView())->setIcon($oauth_icon),293' ',294$oauth_description,295));296297return $view;298}299300301}302303304