root/trunk/lib/AkActionWebService/AkActionWebServiceApi.php

Revision 285, 8.5 kB (checked in by bermiferrer, 3 years ago)

Reorganizing API packages hierarchy.

Line 
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org                             |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
10
11 /**
12  * @package ActionWebservice
13  * @subpackage Api
14  * @author Bermi Ferrer <bermi a.t akelos c.om>
15  * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16  * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
17  */
18
19 /**
20  * A web service API class specifies the methods that will be available for
21  * invocation for an API. It also contains metadata such as the method type
22  * signature hints.
23  *
24  * It is not intended to be instantiated.
25  *
26  * It is attached to web service implementation classes like
27  * AkActionWebService and AkActionController derivatives by using
28  * <tt>container::web_service_api</tt>, where <tt>container</tt> is an
29  * AkActionController or an AkActionWebService.
30  *
31  * See AkActionWebService/AkDirectContainer.php class methods for an example
32  * of use.
33  */
34 class AkActionWebserviceApi extends AkObject
35 {   
36     /**
37      * Whether to transform the public API method names into camel-cased names
38      */
39     var $inflect_names = true;
40     
41     /**
42      * Whether to localize the API documentation automatically.
43      */
44     var $localize_documentation = true;
45
46     /**
47     * If present, the name of a method to call when the remote caller
48     * tried to call a nonexistent method.
49     */
50     var $default_api_method;
51     
52     var $_api_methods = array();
53     var $_api_public_method_names = array();
54     
55     /**
56     * API methods have a +name+, which must be the PHP method name to use when
57     * performing the invocation on the web service object.
58     *
59     * The signatures for the method input parameters and return value can
60     * by specified in +options+.
61     *
62     * A signature is an array of one or more parameter specifiers.
63     * A parameter specifier can be one of the following:
64     *
65     * * A string representing one of the Action Web Service base types.
66     *   See AkActionWebService/AkSignatureTypes.php for a canonical list of the base types.
67     * * The Class object of the parameter type
68     * * A single-element Array containing one of the two preceding items. This
69     *   will cause Action Web Service to treat the parameter at that position
70     *   as an array containing only values of the given type.
71     * * An Array containing as key the name of the parameter, and as value
72     *   one of the three preceding items
73     *
74     * If no method input parameter or method return value signatures are given,
75     * the method is assumed to take no parameters and/or return no values of
76     * interest, and any values that are received by the server will be
77     * discarded and ignored.
78     *
79     * Valid options:
80     * <tt>expects</tt>             Signature for the method input parameters
81     * <tt>returns</tt>             Signature for the method return value
82     * <tt>expects_and_returns</tt> Signature for both input parameters and return value
83     */
84     function addApiMethod($name, $options = array())
85     {
86         $this->_validateOptions(array('expects', 'returns', 'expects_and_returns', 'documentation'), array_keys($options));
87         if (!empty($options['expects_and_returns'])){
88             $expects = $returns = $options['expects_and_returns'];
89         }else{
90             $expects = @$options['expects'];
91             $returns = @$options['returns'];
92         }
93
94         $public_name = $this->getPublicApiMethodName($name);
95         $method =& new AkActionWebServiceMethod($name, $public_name, $expects, $returns, @$options['documentation'], $this->localize_documentation);
96         $this->_api_methods[$name] =& $method;
97         $this->_api_public_method_names[$public_name] = $name;
98     }
99
100     /**
101     * Whether the given method name is a service method on this API
102     */
103     function hasApiMethod($name)
104     {
105         return !empty($this->_api_methods[$name]);
106     }
107
108     /**
109     * Whether the given public method name has a corresponding service method
110     * on this API
111     */
112     function hasPublicApiMethod($public_name)
113     {
114         return !empty($this->_api_public_method_names[$public_name]);
115     }
116
117     /**
118     * The corresponding public method name for the given service method name
119     */
120     function getPublicApiMethodName($name)
121     {
122         return $this->inflect_names ? AkInflector::camelize($name) : $name;
123     }
124
125     /**
126     * The corresponding service method name for the given public method name
127     */
128     function getApiMethodName($public_name)
129     {
130         return $this->_api_public_method_names[$public_name];
131     }
132     
133     /**
134     * An array containing all service methods on this API, and their
135     * associated metadata.
136     */
137     function &getApiMethods()
138     {
139         return $this->_api_methods;
140     }
141
142     /**
143     * The Method instance for the given public API method name, if any
144     */
145     function &getPublicApiMethodInstance($public_method_name)
146     {
147         return $this->getApiMethodInstance($this->getApiMethodName($public_method_name));
148     }
149
150     /**
151     * The Method instance for the given API method name, if any
152     */
153     function &getApiMethodInstance($method_name)
154     {
155         return $this->_api_methods[$method_name];
156     }
157
158     /**
159     * The Method instance for the default API method, if any
160     */
161     function &getDefaultApiMethodInstance()
162     {
163         if(empty($this->default_api_method)){
164             $false = false;
165             return $false;
166         }
167
168         $name = $this->default_api_method;
169         if(!empty($this->default_api_method_instance->name) && $this->default_api_method_instance->name == $name){
170             return $this->default_api_method_instance;
171         }
172
173         $this->default_api_method_instance =& new AkActionWebServiceMethod($name, $this->getPublicApiMethodName($name), null, null, null);
174         return $this->default_api_method_instance;
175     }
176
177     function _getApiPublicMethodNames()
178     {
179         return array_keys($this->_api_public_method_names);
180     }
181
182     function _validateOptions($valid_option_keys, $supplied_option_keys)
183     {
184         $unknown_option_keys = array_diff($supplied_option_keys, $valid_option_keys);
185         if(!empty($unknown_option_keys)){
186             trigger_error(Ak::t('Unknown options: %options', array('%options'=> var_export($unknown_option_keys,true))), E_USER_ERROR);
187         }
188     }
189 }
190
191
192 /**
193 * Represents an API method and its associated metadata, and provides functionality
194 * to assist in commonly performed API method tasks.
195 */
196 class AkActionWebServiceMethod
197 {
198     var $name;
199     var $public_name;
200     var $expects;
201     var $returns;
202     var $documentation;
203     var $expects_documentation = array();
204     var $returns_documentation = array();
205
206     function AkActionWebServiceMethod($name, $public_name, $expects, $returns, $documentation, $localize_documentation = true)
207     {
208         $this->name = $name;
209         $this->public_name = $public_name;
210         $this->expects = $expects;
211         $this->returns = $returns;
212         $this->documentation = $documentation;
213         $this->localize_documentation = $localize_documentation;
214       
215         $this->_extractDocumentationFromExpects();
216         $this->_extractDocumentationFromReturns();
217     }
218     
219     function _extractDocumentationFromExpects()
220     {
221         return $this->_extractDocumentationFromMethod('expects');
222     }
223     
224     function _extractDocumentationFromReturns()
225     {
226         return $this->_extractDocumentationFromMethod('returns');
227     }
228     
229     function _extractDocumentationFromMethod($expects_or_returns)
230     {
231         if(!in_array($expects_or_returns, array('expects', 'returns'))){
232             trigger_error(Ak::t('Only expects and returns options are valid'), E_USER_ERROR);
233             return false;
234         }
235         $parameters = array();
236         $i = 0;
237         foreach ((array)$this->{$expects_or_returns} as $parameter=>$documentation){
238             
239             if(is_numeric($parameter)){
240                 $parameters[] = $documentation;
241             }else{
242                 $parameters[] = $parameter;
243                 $this->{$expects_or_returns.'_documentation'}[$i] = $documentation;
244             }
245             $i++;
246         }
247         $this->{$expects_or_returns} = $parameters;
248     }
249     
250 }
251
252 ?>
Note: See TracBrowser for help on using the browser.