[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/webservice/amf/ -> locallib.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  
  18  /**
  19   * AMF web service implementation classes and methods.
  20   *
  21   * @package    webservice_amf
  22   * @copyright  2009 Petr Skodak
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  require_once("$CFG->dirroot/webservice/lib.php");
  27  require_once( "{$CFG->dirroot}/webservice/amf/introspector.php");
  28  require_once 'Zend/Amf/Server.php';
  29  
  30  /**
  31   * Exception indicating an invalid return value from a function.
  32   *
  33   * Used when an externallib function does not return values of the expected structure.
  34   *
  35   * @package    webservice_amf
  36   * @copyright  2010 Jamie Pratt
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class invalid_return_value_exception extends moodle_exception {
  40  
  41      /**
  42       * Constructor
  43       *
  44       * @param string $debuginfo some detailed information
  45       */
  46      function __construct($debuginfo=null) {
  47          parent::__construct('invalidreturnvalue', 'webservice_amf', '', $debuginfo, $debuginfo);
  48      }
  49  }
  50  
  51  /**
  52   * AMF service server implementation.
  53   *
  54   * @package    webservice_amf
  55   * @copyright  2009 Petr Skodak
  56   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  57   */
  58  class webservice_amf_server extends webservice_zend_server {
  59  
  60      /**
  61       * Contructor
  62       *
  63       * @param integer $authmethod authentication method - one of WEBSERVICE_AUTHMETHOD_*
  64       */
  65      public function __construct($authmethod) {
  66          parent::__construct($authmethod, 'Moodle_Amf_Server');
  67          $this->wsname = 'amf';
  68      }
  69  
  70      /**
  71       * Load virtual class needed for Zend api
  72       */
  73      protected function init_service_class(){
  74          parent::init_service_class();
  75          //allow access to data about methods available.
  76          $this->zend_server->setClass( "MethodDescriptor" );
  77          MethodDescriptor::$classnametointrospect = $this->service_class;
  78      }
  79      
  80      /**
  81       * Get the generated web service function code.
  82       *
  83       * @param stdClass $function contains function name and class name
  84       * @param array $params all the function parameters
  85       * @return string the generate web service function code
  86       */
  87      protected function service_class_method_body($function, $params){
  88          //cast the param from object to array (validate_parameters except array only)
  89          $castingcode = '';
  90          if ($params){
  91              $paramstocast = explode(',', $params);
  92              foreach ($paramstocast as $paramtocast) {
  93                  $paramtocast = trim($paramtocast);
  94                  $castingcode .= $paramtocast .
  95                  '=webservice_zend_server::cast_objects_to_array('.$paramtocast.');';
  96          }
  97  
  98          }
  99  
 100          $externallibcall = $function->classname.'::'.$function->methodname.'('.$params.')';
 101          $descriptionmethod = $function->methodname.'_returns()';
 102          $callforreturnvaluedesc = $function->classname.'::'.$descriptionmethod;
 103          return $castingcode . 
 104  '        return webservice_amf_server::validate_and_cast_values('.$callforreturnvaluedesc.', '.$externallibcall.');';
 105      }
 106  
 107      /**
 108       * Validates submitted value, comparing it to a description. If anything is incorrect
 109       * invalid_return_value_exception is thrown. Also casts the values to the type specified in
 110       * the description.
 111       *
 112       * @param external_description $description description of parameters or null if no return value
 113       * @param mixed $value the actual values
 114       * @return mixed params with added defaults for optional items
 115       * @throws invalid_return_value_exception
 116       */
 117      public static function validate_and_cast_values($description, $value) {
 118          if (is_null($description)){
 119              return;
 120          }
 121          if ($description instanceof external_value) {
 122              if (is_array($value) or is_object($value)) {
 123                  throw new invalid_return_value_exception('Scalar type expected, array or object received.');
 124              }
 125  
 126              if ($description->type == PARAM_BOOL) {
 127                  // special case for PARAM_BOOL - we want true/false instead of the usual 1/0 - we can not be too strict here ;-)
 128                  if (is_bool($value) or $value === 0 or $value === 1 or $value === '0' or $value === '1') {
 129                      return (bool)$value;
 130                  }
 131              }
 132              return validate_param($value, $description->type, $description->allownull, 'Invalid external api parameter');
 133  
 134          } else if ($description instanceof external_single_structure) {
 135              if (!is_array($value)) {
 136                  throw new invalid_return_value_exception('Only arrays accepted.');
 137              }
 138              $result = array();
 139              foreach ($description->keys as $key=>$subdesc) {
 140                  if (!array_key_exists($key, $value)) {
 141                      if ($subdesc->required == VALUE_REQUIRED) {
 142                          throw new invalid_return_value_exception('Missing required key in single structure: '.$key);
 143                      }
 144                      if ($subdesc instanceof external_value) {
 145                              if ($subdesc->required == VALUE_DEFAULT) {
 146                                  $result[$key] = self::validate_and_cast_values($subdesc, $subdesc->default);
 147                              }
 148                      }
 149                  } else {
 150                      $result[$key] = self::validate_and_cast_values($subdesc, $value[$key]);
 151                  }
 152                  unset($value[$key]);
 153              }
 154  
 155              return (object)$result;
 156  
 157          } else if ($description instanceof external_multiple_structure) {
 158              if (!is_array($value)) {
 159                  throw new invalid_return_value_exception('Only arrays accepted.');
 160              }
 161              $result = array();
 162              foreach ($value as $param) {
 163                  $result[] = self::validate_and_cast_values($description->content, $param);
 164              }
 165              return $result;
 166  
 167          } else {
 168              throw new invalid_return_value_exception('Invalid external api description.');
 169          }
 170      }    
 171      
 172      /**
 173       * Set up zend service class
 174       */
 175      protected function init_zend_server() {
 176          parent::init_zend_server();
 177          $this->zend_server->setProduction(false); //set to false for development mode
 178                                                   //(complete error message displayed into your AMF client)
 179      }
 180  }
 181  
 182  /**
 183   * Zend Amf server with a different fault management
 184   *
 185   * @package    webservice_amf
 186   * @copyright  2010 Jamie Pratt
 187   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 188   */
 189  class Moodle_Amf_Server extends Zend_Amf_Server{
 190  
 191      /**
 192       * Raise a server fault
 193       *
 194       * @param string|Exception $fault
 195       * @param int $code fault code
 196       */
 197      public function fault($fault = null, $code = 404)
 198      {
 199          if (!$fault instanceof Exception) {
 200              $fault = new Exception($fault);
 201          }
 202          $request = $this->getRequest();
 203          // Get the object encoding of the request.
 204          $objectEncoding = $request->getObjectEncoding();
 205  
 206          // create a response object to place the output from the services.
 207          $response = $this->getResponse();
 208  
 209          // set response encoding
 210          $response->setObjectEncoding($objectEncoding);
 211          
 212          $responseBody = $request->getAmfBodies();
 213  
 214          foreach($responseBody as $body){
 215              $return = $this->_errorMessage($objectEncoding, $fault->getMessage(), 
 216                  $fault->getMessage(), $fault->getTraceAsString(),$fault->getCode(),  $fault->getLine());
 217              $responseType = Zend_AMF_Constants::STATUS_METHOD;
 218      
 219      
 220              $responseURI = $body->getResponseURI() . $responseType;
 221              $newBody     = new Zend_Amf_Value_MessageBody($responseURI, null, $return);
 222              $response->addAmfBody($newBody);
 223          }
 224          $response->finalize();
 225          echo $response;
 226      }
 227  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1