[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/conduit/method/ -> ConduitAPIMethod.php (source)

   1  <?php
   2  
   3  /**
   4   * @task  status  Method Status
   5   * @task  pager   Paging Results
   6   */
   7  abstract class ConduitAPIMethod
   8    extends Phobject
   9    implements PhabricatorPolicyInterface {
  10  
  11    const METHOD_STATUS_STABLE      = 'stable';
  12    const METHOD_STATUS_UNSTABLE    = 'unstable';
  13    const METHOD_STATUS_DEPRECATED  = 'deprecated';
  14  
  15    abstract public function getMethodDescription();
  16    abstract public function defineParamTypes();
  17    abstract public function defineReturnType();
  18    abstract public function defineErrorTypes();
  19    abstract protected function execute(ConduitAPIRequest $request);
  20  
  21    public function __construct() {}
  22  
  23    /**
  24     * This is mostly for compatibility with
  25     * @{class:PhabricatorCursorPagedPolicyAwareQuery}.
  26     */
  27    public function getID() {
  28      return $this->getAPIMethodName();
  29    }
  30  
  31    /**
  32     * Get the status for this method (e.g., stable, unstable or deprecated).
  33     * Should return a METHOD_STATUS_* constant. By default, methods are
  34     * "stable".
  35     *
  36     * @return const  METHOD_STATUS_* constant.
  37     * @task status
  38     */
  39    public function getMethodStatus() {
  40      return self::METHOD_STATUS_STABLE;
  41    }
  42  
  43    /**
  44     * Optional description to supplement the method status. In particular, if
  45     * a method is deprecated, you can return a string here describing the reason
  46     * for deprecation and stable alternatives.
  47     *
  48     * @return string|null  Description of the method status, if available.
  49     * @task status
  50     */
  51    public function getMethodStatusDescription() {
  52      return null;
  53    }
  54  
  55    public function getErrorDescription($error_code) {
  56      return idx($this->defineErrorTypes(), $error_code, 'Unknown Error');
  57    }
  58  
  59    public function getRequiredScope() {
  60      // by default, conduit methods are not accessible via OAuth
  61      return PhabricatorOAuthServerScope::SCOPE_NOT_ACCESSIBLE;
  62    }
  63  
  64    public function executeMethod(ConduitAPIRequest $request) {
  65      return $this->execute($request);
  66    }
  67  
  68    public abstract function getAPIMethodName();
  69  
  70    /**
  71     * Return a key which sorts methods by application name, then method status,
  72     * then method name.
  73     */
  74    public function getSortOrder() {
  75      $name = $this->getAPIMethodName();
  76  
  77      $map = array(
  78        ConduitAPIMethod::METHOD_STATUS_STABLE      => 0,
  79        ConduitAPIMethod::METHOD_STATUS_UNSTABLE    => 1,
  80        ConduitAPIMethod::METHOD_STATUS_DEPRECATED  => 2,
  81      );
  82      $ord = idx($map, $this->getMethodStatus(), 0);
  83  
  84      list($head, $tail) = explode('.', $name, 2);
  85  
  86      return "{$head}.{$ord}.{$tail}";
  87    }
  88  
  89    public function getApplicationName() {
  90      return head(explode('.', $this->getAPIMethodName(), 2));
  91    }
  92  
  93    public static function getConduitMethod($method_name) {
  94      static $method_map = null;
  95  
  96      if ($method_map === null) {
  97        $methods = id(new PhutilSymbolLoader())
  98          ->setAncestorClass(__CLASS__)
  99          ->loadObjects();
 100  
 101        foreach ($methods as $method) {
 102          $name = $method->getAPIMethodName();
 103  
 104          if (empty($method_map[$name])) {
 105            $method_map[$name] = $method;
 106            continue;
 107          }
 108  
 109          $orig_class = get_class($method_map[$name]);
 110          $this_class = get_class($method);
 111          throw new Exception(
 112            "Two Conduit API method classes ({$orig_class}, {$this_class}) ".
 113            "both have the same method name ({$name}). API methods ".
 114            "must have unique method names.");
 115        }
 116      }
 117  
 118      return idx($method_map, $method_name);
 119    }
 120  
 121    public function shouldRequireAuthentication() {
 122      return true;
 123    }
 124  
 125    public function shouldAllowPublic() {
 126      return false;
 127    }
 128  
 129    public function shouldAllowUnguardedWrites() {
 130      return false;
 131    }
 132  
 133  
 134    /**
 135     * Optionally, return a @{class:PhabricatorApplication} which this call is
 136     * part of. The call will be disabled when the application is uninstalled.
 137     *
 138     * @return PhabricatorApplication|null  Related application.
 139     */
 140    public function getApplication() {
 141      return null;
 142    }
 143  
 144    protected function formatStringConstants($constants) {
 145      foreach ($constants as $key => $value) {
 146        $constants[$key] = '"'.$value.'"';
 147      }
 148      $constants = implode(', ', $constants);
 149      return 'string-constant<'.$constants.'>';
 150    }
 151  
 152  
 153  /* -(  Paging Results  )----------------------------------------------------- */
 154  
 155  
 156    /**
 157     * @task pager
 158     */
 159    protected function getPagerParamTypes() {
 160      return array(
 161        'before' => 'optional string',
 162        'after'  => 'optional string',
 163        'limit'  => 'optional int (default = 100)',
 164      );
 165    }
 166  
 167  
 168    /**
 169     * @task pager
 170     */
 171    protected function newPager(ConduitAPIRequest $request) {
 172      $limit = $request->getValue('limit', 100);
 173      $limit = min(1000, $limit);
 174      $limit = max(1, $limit);
 175  
 176      $pager = id(new AphrontCursorPagerView())
 177        ->setPageSize($limit);
 178  
 179      $before_id = $request->getValue('before');
 180      if ($before_id !== null) {
 181        $pager->setBeforeID($before_id);
 182      }
 183  
 184      $after_id = $request->getValue('after');
 185      if ($after_id !== null) {
 186        $pager->setAfterID($after_id);
 187      }
 188  
 189      return $pager;
 190    }
 191  
 192  
 193    /**
 194     * @task pager
 195     */
 196    protected function addPagerResults(
 197      array $results,
 198      AphrontCursorPagerView $pager) {
 199  
 200      $results['cursor'] = array(
 201        'limit' => $pager->getPageSize(),
 202        'after' => $pager->getNextPageID(),
 203        'before' => $pager->getPrevPageID(),
 204      );
 205  
 206      return $results;
 207    }
 208  
 209  
 210  /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 211  
 212  
 213    public function getPHID() {
 214      return null;
 215    }
 216  
 217    public function getCapabilities() {
 218      return array(
 219        PhabricatorPolicyCapability::CAN_VIEW,
 220      );
 221    }
 222  
 223    public function getPolicy($capability) {
 224      // Application methods get application visibility; other methods get open
 225      // visibility.
 226  
 227      $application = $this->getApplication();
 228      if ($application) {
 229        return $application->getPolicy($capability);
 230      }
 231  
 232      return PhabricatorPolicies::getMostOpenPolicy();
 233    }
 234  
 235    public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
 236      if (!$this->shouldRequireAuthentication()) {
 237        // Make unauthenticated methods universally visible.
 238        return true;
 239      }
 240  
 241      return false;
 242    }
 243  
 244    public function describeAutomaticCapability($capability) {
 245      return null;
 246    }
 247  
 248    protected function hasApplicationCapability(
 249      $capability,
 250      PhabricatorUser $viewer) {
 251  
 252      $application = $this->getApplication();
 253  
 254      if (!$application) {
 255        return false;
 256      }
 257  
 258      return PhabricatorPolicyFilter::hasCapability(
 259        $viewer,
 260        $application,
 261        $capability);
 262    }
 263  
 264    protected function requireApplicationCapability(
 265      $capability,
 266      PhabricatorUser $viewer) {
 267  
 268      $application = $this->getApplication();
 269      if (!$application) {
 270        return;
 271      }
 272  
 273      PhabricatorPolicyFilter::requireCapability(
 274        $viewer,
 275        $this->getApplication(),
 276        $capability);
 277    }
 278  
 279  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1