File indexing completed on 2024-12-22 05:36:48

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Json
0017  * @subpackage Server
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @category   Zend
0025  * @package    Zend_Json
0026  * @subpackage Server
0027  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0028  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0029  */
0030 class Zend_Json_Server_Smd
0031 {
0032     const ENV_JSONRPC_1 = 'JSON-RPC-1.0';
0033     const ENV_JSONRPC_2 = 'JSON-RPC-2.0';
0034     const SMD_VERSION   = '2.0';
0035 
0036     /**
0037      * Content type
0038      * @var string
0039      */
0040     protected $_contentType = 'application/json';
0041 
0042     /**
0043      * Content type regex
0044      * @var string
0045      */
0046     protected $_contentTypeRegex = '#[a-z]+/[a-z][a-z-]+#i';
0047 
0048     /**
0049      * Service description
0050      * @var string
0051      */
0052     protected $_description;
0053 
0054     /**
0055      * Generate Dojo-compatible SMD
0056      * @var bool
0057      */
0058     protected $_dojoCompatible = false;
0059 
0060     /**
0061      * Current envelope
0062      * @var string
0063      */
0064     protected $_envelope = self::ENV_JSONRPC_1;
0065 
0066     /**
0067      * Allowed envelope types
0068      * @var array
0069      */
0070     protected $_envelopeTypes = array(
0071         self::ENV_JSONRPC_1,
0072         self::ENV_JSONRPC_2,
0073     );
0074 
0075     /**
0076      * Service id
0077      * @var string
0078      */
0079     protected $_id;
0080 
0081     /**
0082      * Services offerred
0083      * @var array
0084      */
0085     protected $_services = array();
0086 
0087     /**
0088      * Service target
0089      * @var string
0090      */
0091     protected $_target;
0092 
0093     /**
0094      * Global transport
0095      * @var string
0096      */
0097     protected $_transport = 'POST';
0098 
0099     /**
0100      * Allowed transport types
0101      * @var array
0102      */
0103     protected $_transportTypes = array('POST');
0104 
0105     /**
0106      * Set object state via options
0107      *
0108      * @param  array $options
0109      * @return Zend_Json_Server_Smd
0110      */
0111     public function setOptions(array $options)
0112     {
0113         $methods = get_class_methods($this);
0114         foreach ($options as $key => $value) {
0115             $method = 'set' . ucfirst($key);
0116             if (in_array($method, $methods)) {
0117                 $this->$method($value);
0118             }
0119         }
0120         return $this;
0121     }
0122 
0123     /**
0124      * Set transport
0125      *
0126      * @param  string $transport
0127      * @return Zend_Json_Server_Smd
0128      */
0129     public function setTransport($transport)
0130     {
0131         if (!in_array($transport, $this->_transportTypes)) {
0132             // require_once 'Zend/Json/Server/Exception.php';
0133             throw new Zend_Json_Server_Exception(sprintf('Invalid transport "%s" specified', $transport));
0134         }
0135         $this->_transport = $transport;
0136         return $this;
0137     }
0138 
0139     /**
0140      * Get transport
0141      *
0142      * @return string
0143      */
0144     public function getTransport()
0145     {
0146         return $this->_transport;
0147     }
0148 
0149     /**
0150      * Set envelope
0151      *
0152      * @param  string $envelopeType
0153      * @return Zend_Json_Server_Smd
0154      */
0155     public function setEnvelope($envelopeType)
0156     {
0157         if (!in_array($envelopeType, $this->_envelopeTypes)) {
0158             // require_once 'Zend/Json/Server/Exception.php';
0159             throw new Zend_Json_Server_Exception(sprintf('Invalid envelope type "%s"', $envelopeType));
0160         }
0161         $this->_envelope = $envelopeType;
0162         return $this;
0163     }
0164 
0165     /**
0166      * Retrieve envelope
0167      *
0168      * @return string
0169      */
0170     public function getEnvelope()
0171     {
0172         return $this->_envelope;
0173     }
0174 
0175     // Content-Type of response; default to application/json
0176     /**
0177      * Set content type
0178      *
0179      * @param  string $type
0180      * @return Zend_Json_Server_Smd
0181      */
0182     public function setContentType($type)
0183     {
0184         if (!preg_match($this->_contentTypeRegex, $type)) {
0185             // require_once 'Zend/Json/Server/Exception.php';
0186             throw new Zend_Json_Server_Exception(sprintf('Invalid content type "%s" specified', $type));
0187         }
0188         $this->_contentType = $type;
0189         return $this;
0190     }
0191 
0192     /**
0193      * Retrieve content type
0194      *
0195      * @return string
0196      */
0197     public function getContentType()
0198     {
0199         return $this->_contentType;
0200     }
0201 
0202     /**
0203      * Set service target
0204      *
0205      * @param  string $target
0206      * @return Zend_Json_Server_Smd
0207      */
0208     public function setTarget($target)
0209     {
0210         $this->_target = (string) $target;
0211         return $this;
0212     }
0213 
0214     /**
0215      * Retrieve service target
0216      *
0217      * @return string
0218      */
0219     public function getTarget()
0220     {
0221         return $this->_target;
0222     }
0223 
0224     /**
0225      * Set service ID
0226      *
0227      * @param  string $Id
0228      * @return Zend_Json_Server_Smd
0229      */
0230     public function setId($id)
0231     {
0232         $this->_id = (string) $id;
0233         return $this->_id;
0234     }
0235 
0236     /**
0237      * Get service id
0238      *
0239      * @return string
0240      */
0241     public function getId()
0242     {
0243         return $this->_id;
0244     }
0245 
0246     /**
0247      * Set service description
0248      *
0249      * @param  string $description
0250      * @return Zend_Json_Server_Smd
0251      */
0252     public function setDescription($description)
0253     {
0254         $this->_description = (string) $description;
0255         return $this->_description;
0256     }
0257 
0258     /**
0259      * Get service description
0260      *
0261      * @return string
0262      */
0263     public function getDescription()
0264     {
0265         return $this->_description;
0266     }
0267 
0268     /**
0269      * Indicate whether or not to generate Dojo-compatible SMD
0270      *
0271      * @param  bool $flag
0272      * @return Zend_Json_Server_Smd
0273      */
0274     public function setDojoCompatible($flag)
0275     {
0276         $this->_dojoCompatible = (bool) $flag;
0277         return $this;
0278     }
0279 
0280     /**
0281      * Is this a Dojo compatible SMD?
0282      *
0283      * @return bool
0284      */
0285     public function isDojoCompatible()
0286     {
0287         return $this->_dojoCompatible;
0288     }
0289 
0290     /**
0291      * Add Service
0292      *
0293      * @param Zend_Json_Server_Smd_Service|array $service
0294      * @return void
0295      */
0296     public function addService($service)
0297     {
0298         // require_once 'Zend/Json/Server/Smd/Service.php';
0299 
0300         if ($service instanceof Zend_Json_Server_Smd_Service) {
0301             $name = $service->getName();
0302         } elseif (is_array($service)) {
0303             $service = new Zend_Json_Server_Smd_Service($service);
0304             $name = $service->getName();
0305         } else {
0306             // require_once 'Zend/Json/Server/Exception.php';
0307             throw new Zend_Json_Server_Exception('Invalid service passed to addService()');
0308         }
0309 
0310         if (array_key_exists($name, $this->_services)) {
0311             // require_once 'Zend/Json/Server/Exception.php';
0312             throw new Zend_Json_Server_Exception('Attempt to register a service already registered detected');
0313         }
0314         $this->_services[$name] = $service;
0315         return $this;
0316     }
0317 
0318     /**
0319      * Add many services
0320      *
0321      * @param  array $services
0322      * @return Zend_Json_Server_Smd
0323      */
0324     public function addServices(array $services)
0325     {
0326         foreach ($services as $service) {
0327             $this->addService($service);
0328         }
0329         return $this;
0330     }
0331 
0332     /**
0333      * Overwrite existing services with new ones
0334      *
0335      * @param  array $services
0336      * @return Zend_Json_Server_Smd
0337      */
0338     public function setServices(array $services)
0339     {
0340         $this->_services = array();
0341         return $this->addServices($services);
0342     }
0343 
0344     /**
0345      * Get service object
0346      *
0347      * @param  string $name
0348      * @return false|Zend_Json_Server_Smd_Service
0349      */
0350     public function getService($name)
0351     {
0352         if (array_key_exists($name, $this->_services)) {
0353             return $this->_services[$name];
0354         }
0355         return false;
0356     }
0357 
0358     /**
0359      * Return services
0360      *
0361      * @return array
0362      */
0363     public function getServices()
0364     {
0365         return $this->_services;
0366     }
0367 
0368     /**
0369      * Remove service
0370      *
0371      * @param  string $name
0372      * @return boolean
0373      */
0374     public function removeService($name)
0375     {
0376         if (array_key_exists($name, $this->_services)) {
0377             unset($this->_services[$name]);
0378             return true;
0379         }
0380         return false;
0381     }
0382 
0383     /**
0384      * Cast to array
0385      *
0386      * @return array
0387      */
0388     public function toArray()
0389     {
0390         if ($this->isDojoCompatible()) {
0391             return $this->toDojoArray();
0392         }
0393 
0394         $transport   = $this->getTransport();
0395         $envelope    = $this->getEnvelope();
0396         $contentType = $this->getContentType();
0397         $SMDVersion  = self::SMD_VERSION;
0398         $service = compact('transport', 'envelope', 'contentType', 'SMDVersion');
0399 
0400         if (null !== ($target = $this->getTarget())) {
0401             $service['target']     = $target;
0402         }
0403         if (null !== ($id = $this->getId())) {
0404             $service['id'] = $id;
0405         }
0406 
0407         $services = $this->getServices();
0408         if (!empty($services)) {
0409             $service['services'] = array();
0410             foreach ($services as $name => $svc) {
0411                 $svc->setEnvelope($envelope);
0412                 $service['services'][$name] = $svc->toArray();
0413             }
0414             $service['methods'] = $service['services'];
0415         }
0416 
0417         return $service;
0418     }
0419 
0420     /**
0421      * Export to DOJO-compatible SMD array
0422      *
0423      * @return array
0424      */
0425     public function toDojoArray()
0426     {
0427         $SMDVersion  = '.1';
0428         $serviceType = 'JSON-RPC';
0429         $service = compact('SMDVersion', 'serviceType');
0430 
0431         $target = $this->getTarget();
0432 
0433         $services = $this->getServices();
0434         if (!empty($services)) {
0435             $service['methods'] = array();
0436             foreach ($services as $name => $svc) {
0437                 $method = array(
0438                     'name'       => $name,
0439                     'serviceURL' => $target,
0440                 );
0441                 $params = array();
0442                 foreach ($svc->getParams() as $param) {
0443                     $paramName = array_key_exists('name', $param) ? $param['name'] : $param['type'];
0444                     $params[] = array(
0445                         'name' => $paramName,
0446                         'type' => $param['type'],
0447                     );
0448                 }
0449                 if (!empty($params)) {
0450                     $method['parameters'] = $params;
0451                 }
0452                 $service['methods'][] = $method;
0453             }
0454         }
0455 
0456         return $service;
0457     }
0458 
0459     /**
0460      * Cast to JSON
0461      *
0462      * @return string
0463      */
0464     public function toJson()
0465     {
0466         // require_once 'Zend/Json.php';
0467         return Zend_Json::encode($this->toArray());
0468     }
0469 
0470     /**
0471      * Cast to string (JSON)
0472      *
0473      * @return string
0474      */
0475     public function __toString()
0476     {
0477         return $this->toJson();
0478     }
0479 }
0480