Changeset View
Changeset View
Standalone View
Standalone View
src/applications/conduit/method/ConduitAPIMethod.php
| Show All 12 Lines | abstract class ConduitAPIMethod | ||||
| const METHOD_STATUS_DEPRECATED = 'deprecated'; | const METHOD_STATUS_DEPRECATED = 'deprecated'; | ||||
| abstract public function getMethodDescription(); | abstract public function getMethodDescription(); | ||||
| abstract public function defineParamTypes(); | abstract public function defineParamTypes(); | ||||
| abstract public function defineReturnType(); | abstract public function defineReturnType(); | ||||
| abstract public function defineErrorTypes(); | abstract public function defineErrorTypes(); | ||||
| abstract protected function execute(ConduitAPIRequest $request); | abstract protected function execute(ConduitAPIRequest $request); | ||||
| public function __construct() { | public function __construct() {} | ||||
| } | |||||
| /** | /** | ||||
| * This is mostly for compatibility with | * This is mostly for compatibility with | ||||
| * @{class:PhabricatorCursorPagedPolicyAwareQuery}. | * @{class:PhabricatorCursorPagedPolicyAwareQuery}. | ||||
| */ | */ | ||||
| public function getID() { | public function getID() { | ||||
| return $this->getAPIMethodName(); | return $this->getAPIMethodName(); | ||||
| } | } | ||||
| Show All 30 Lines | public function getRequiredScope() { | ||||
| // by default, conduit methods are not accessible via OAuth | // by default, conduit methods are not accessible via OAuth | ||||
| return PhabricatorOAuthServerScope::SCOPE_NOT_ACCESSIBLE; | return PhabricatorOAuthServerScope::SCOPE_NOT_ACCESSIBLE; | ||||
| } | } | ||||
| public function executeMethod(ConduitAPIRequest $request) { | public function executeMethod(ConduitAPIRequest $request) { | ||||
| return $this->execute($request); | return $this->execute($request); | ||||
| } | } | ||||
| public function getAPIMethodName() { | public abstract function getAPIMethodName(); | ||||
| return self::getAPIMethodNameFromClassName(get_class($this)); | |||||
| } | |||||
| /** | /** | ||||
| * Return a key which sorts methods by application name, then method status, | * Return a key which sorts methods by application name, then method status, | ||||
| * then method name. | * then method name. | ||||
| */ | */ | ||||
| public function getSortOrder() { | public function getSortOrder() { | ||||
| $name = $this->getAPIMethodName(); | $name = $this->getAPIMethodName(); | ||||
| $map = array( | $map = array( | ||||
| ConduitAPIMethod::METHOD_STATUS_STABLE => 0, | ConduitAPIMethod::METHOD_STATUS_STABLE => 0, | ||||
| ConduitAPIMethod::METHOD_STATUS_UNSTABLE => 1, | ConduitAPIMethod::METHOD_STATUS_UNSTABLE => 1, | ||||
| ConduitAPIMethod::METHOD_STATUS_DEPRECATED => 2, | ConduitAPIMethod::METHOD_STATUS_DEPRECATED => 2, | ||||
| ); | ); | ||||
| $ord = idx($map, $this->getMethodStatus(), 0); | $ord = idx($map, $this->getMethodStatus(), 0); | ||||
| list($head, $tail) = explode('.', $name, 2); | list($head, $tail) = explode('.', $name, 2); | ||||
| return "{$head}.{$ord}.{$tail}"; | return "{$head}.{$ord}.{$tail}"; | ||||
| } | } | ||||
| public function getApplicationName() { | public function getApplicationName() { | ||||
| return head(explode('.', $this->getAPIMethodName(), 2)); | return head(explode('.', $this->getAPIMethodName(), 2)); | ||||
| } | } | ||||
| public static function getClassNameFromAPIMethodName($method_name) { | public static function getConduitMethod($method_name) { | ||||
| $method_fragment = str_replace('.', '_', $method_name); | static $method_map = null; | ||||
| return 'ConduitAPI_'.$method_fragment.'_Method'; | |||||
| if ($method_map === null) { | |||||
| $methods = id(new PhutilSymbolLoader()) | |||||
| ->setAncestorClass(__CLASS__) | |||||
| ->setConcreteOnly(true) | |||||
| ->loadObjects(); | |||||
| foreach ($methods as $method) { | |||||
epriestley: We should check + throw here for duplicates. | |||||
Not Done Inline ActionsYeah I agree. This means that I can't use mpull right? joshuaspence: Yeah I agree. This means that I can't use `mpull` right? | |||||
| $name = $method->getAPIMethodName(); | |||||
| if (empty($method_map[$name])) { | |||||
| $method_map[$name] = $method; | |||||
| continue; | |||||
| } | |||||
| $orig_class = get_class($method_map[$name]); | |||||
| $this_class = get_class($method); | |||||
| throw new Exception( | |||||
| "Two Conduit API method classes ({$orig_class}, {$this_class}) ". | |||||
| "both have the same method name ({$name}). API methods ". | |||||
| "must have unique method names."); | |||||
| } | |||||
| } | |||||
| return idx($method_map, $method_name); | |||||
| } | } | ||||
| public function shouldRequireAuthentication() { | public function shouldRequireAuthentication() { | ||||
| return true; | return true; | ||||
| } | } | ||||
| public function shouldAllowPublic() { | public function shouldAllowPublic() { | ||||
| return false; | return false; | ||||
| Show All 9 Lines | abstract class ConduitAPIMethod | ||||
| * part of. The call will be disabled when the application is uninstalled. | * part of. The call will be disabled when the application is uninstalled. | ||||
| * | * | ||||
| * @return PhabricatorApplication|null Related application. | * @return PhabricatorApplication|null Related application. | ||||
| */ | */ | ||||
| public function getApplication() { | public function getApplication() { | ||||
| return null; | return null; | ||||
| } | } | ||||
| public static function getAPIMethodNameFromClassName($class_name) { | |||||
| $match = null; | |||||
| $is_valid = preg_match( | |||||
| '/^ConduitAPI_(.*)_Method$/', | |||||
| $class_name, | |||||
| $match); | |||||
| if (!$is_valid) { | |||||
| throw new Exception( | |||||
| "Parameter '{$class_name}' is not a valid Conduit API method class."); | |||||
| } | |||||
| $method_fragment = $match[1]; | |||||
| return str_replace('_', '.', $method_fragment); | |||||
| } | |||||
| protected function formatStringConstants($constants) { | protected function formatStringConstants($constants) { | ||||
| foreach ($constants as $key => $value) { | foreach ($constants as $key => $value) { | ||||
| $constants[$key] = '"'.$value.'"'; | $constants[$key] = '"'.$value.'"'; | ||||
| } | } | ||||
| $constants = implode(', ', $constants); | $constants = implode(', ', $constants); | ||||
| return 'string-constant<'.$constants.'>'; | return 'string-constant<'.$constants.'>'; | ||||
| } | } | ||||
| /* -( Paging Results )----------------------------------------------------- */ | /* -( Paging Results )----------------------------------------------------- */ | ||||
| /** | /** | ||||
| * @task pager | * @task pager | ||||
| */ | */ | ||||
| protected function getPagerParamTypes() { | protected function getPagerParamTypes() { | ||||
| return array( | return array( | ||||
| 'before' => 'optional string', | 'before' => 'optional string', | ||||
| 'after' => 'optional string', | 'after' => 'optional string', | ||||
| 'limit' => 'optional int (default = 100)', | 'limit' => 'optional int (default = 100)', | ||||
| ); | ); | ||||
| } | } | ||||
| /** | /** | ||||
| * @task pager | * @task pager | ||||
| */ | */ | ||||
| protected function newPager(ConduitAPIRequest $request) { | protected function newPager(ConduitAPIRequest $request) { | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if ($application) { | ||||
| return $application->getPolicy($capability); | return $application->getPolicy($capability); | ||||
| } | } | ||||
| return PhabricatorPolicies::getMostOpenPolicy(); | return PhabricatorPolicies::getMostOpenPolicy(); | ||||
| } | } | ||||
| public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { | public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { | ||||
| if (!$this->shouldRequireAuthentication()) { | if (!$this->shouldRequireAuthentication()) { | ||||
| // Make unauthenticated methods univerally visible. | // Make unauthenticated methods universally visible. | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| public function describeAutomaticCapability($capability) { | public function describeAutomaticCapability($capability) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| } | } | ||||
We should check + throw here for duplicates.