PageRenderTime 27ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/pogostick/behaviors/CPSRestBehavior.php

http://ps-yii-extensions.googlecode.com/
PHP | 192 lines | 77 code | 24 blank | 91 comment | 18 complexity | a6c86bd45e5acc5113607bb59bfa192f MD5 | raw file
  1. <?php
  2. /*
  3. * CPSRestBehavior.php
  4. *
  5. * Copyright (c) 2010 Jerry Ablan <jablan@pogostick.com>.
  6. * @link http://www.pogostick.com Pogostick, LLC.
  7. * @license http://www.pogostick.com/licensing
  8. *
  9. * This file is part of Pogostick : Yii Extensions.
  10. *
  11. * We share the same open source ideals as does the jQuery team, and
  12. * we love them so much we like to quote their license statement:
  13. *
  14. * You may use our open source libraries under the terms of either the MIT
  15. * License or the Gnu General Public License (GPL) Version 2.
  16. *
  17. * The MIT License is recommended for most projects. It is simple and easy to
  18. * understand, and it places almost no restrictions on what you can do with
  19. * our code.
  20. *
  21. * If the GPL suits your project better, you are also free to use our code
  22. * under that license.
  23. *
  24. * You don’t have to do anything special to choose one license or the other,
  25. * and you don’t have to notify anyone which license you are using.
  26. */
  27. // Include Files
  28. // Constants
  29. // Global Settings
  30. /**
  31. * CPSRestBehavior provides REST behaviors to controllers
  32. *
  33. * @package psYiiExtensions
  34. * @subpackage behaviors
  35. *
  36. * @author Jerry Ablan <jablan@pogostick.com>
  37. * @version SVN $Id: CPSRestBehavior.php 395 2010-07-15 21:34:48Z jerryablan@gmail.com $
  38. * @since v1.1.0
  39. *
  40. * @filesource
  41. */
  42. class CPSRestBehavior extends CPSComponentBehavior
  43. {
  44. //********************************************************************************
  45. //* Member Variables
  46. //********************************************************************************
  47. /**
  48. * The actions we know are for REST
  49. * @var array
  50. */
  51. protected $_restActions = array();
  52. public function getRestActions() { return $this->_restActions; }
  53. public function setRestActions( $restActions ) { $this->_restActions = $restActions; }
  54. //********************************************************************************
  55. //* Public Methods
  56. //********************************************************************************
  57. /***
  58. * Registers an action as a REST action
  59. * @param string $actionName
  60. * @param string $method
  61. * @param mixed $access
  62. */
  63. public function addRestAction( $actionName, $method = 'GET', $access = CPSCRUDController::ACCESS_TO_AUTH )
  64. {
  65. $this->_restActions[ $actionName ] = array(
  66. 'method' => $method,
  67. 'access' => $access,
  68. );
  69. }
  70. /**
  71. * Determines if this behavior knows about a particular action.
  72. * @param string $actionName
  73. * @param string $method
  74. * @return boolean
  75. */
  76. public function hasAction( $actionName, $method = 'GET' )
  77. {
  78. if ( $_action = PS::o( $this->_restActions, $actionName ) )
  79. return ( PS::o( $this->_restActions[$actionName], 'method' ) == $method );
  80. return false;
  81. }
  82. /**
  83. * Creates the action instance based on the action name.
  84. * The action can be either an inline action or an object.
  85. * The latter is created by looking up the action map specified in {@link actions}.
  86. * @param string ID of the action. If empty, the {@link defaultAction default action} will be used.
  87. * @return CAction the action instance, null if the action does not exist.
  88. * @see actions
  89. */
  90. public function createAction( $sActionId )
  91. {
  92. $_sActionId = ( $sActionId === '' ) ? $this->getOwner()->defaultAction : $sActionId;
  93. // Is it a valid request?
  94. if ( ! method_exists( $this->getOwner(), 'get' . $_sActionId ) && ! method_exists( $this->getOwner(), 'post' . $_sActionId ) && ! method_exists( $this->getOwner(), 'request' . $_sActionId ) )
  95. return $this->getOwner()->missingAction( $_sActionId );
  96. return new CPSRESTAction( $this->getOwner(), $_sActionId );
  97. }
  98. //********************************************************************************
  99. //* Private Methods
  100. //********************************************************************************
  101. /**
  102. * Runs the named REST action.
  103. * Filters specified via {@link filters()} will be applied.
  104. * @param string $sActionId Action id
  105. * @throws CHttpException if the action does not exist or the action name is not proper.
  106. * @see filters
  107. * @see createAction
  108. * @see runAction
  109. * @access protected
  110. */
  111. protected function dispatchRequest( CAction $oAction )
  112. {
  113. $_sActionId = $oAction->getId();
  114. $_arParams = $_REQUEST;
  115. $_arUrlParams = array();
  116. $_arOpts = array();
  117. // If additional parameters are specified in the URL, convert to parameters...
  118. $_sUri = Yii::app()->getRequest()->getRequestUri();
  119. if ( null != ( $_sUri = trim( str_ireplace( '/' . $this->getOwner()->getId() . '/' . $_sActionId, '', $_sUri ) ) ) )
  120. {
  121. $_sUri = trim( $_sUri, '/?' );
  122. $_arOpts = ( ! empty( $_sUri ) ? explode( '/', $_sUri ) : array() );
  123. foreach ( $_arOpts as $_sKey => $_oValue )
  124. {
  125. if ( false !== strpos( $_oValue, '=' ) )
  126. {
  127. if ( null != ( $_arTemp = explode( '=', $_oValue ) ) )
  128. $_arOpts[ $_arTemp[0] ] = $_arTemp[1];
  129. unset( $_arOpts[ $_sKey ] );
  130. }
  131. else
  132. $_arOpts[ $_sKey ] = $_oValue;
  133. }
  134. }
  135. // Any query string? (?x=y&...)
  136. if ( null != ( $_sQuery = parse_url( $_sUri, PHP_URL_QUERY ) ) )
  137. $_arOpts = array_merge( explode( '=', $_sQuery ), $_arOpts );
  138. // load into url params
  139. foreach ( $_arOpts as $_sKey => $_sValue )
  140. if ( ! isset( $_arUrlParams[ $_sKey ] ) ) $_arUrlParams[ $_sKey ] = $_sValue;
  141. // Is it a valid request?
  142. $_sType = strtolower( $this->getOwner()->getRequest()->getRequestType() );
  143. $_sMethod = $_sType . ucfirst( $_sActionId );
  144. if ( $_sType == 'post' )
  145. {
  146. foreach ( $_POST as $_sKey => $_oValue )
  147. {
  148. if ( ! is_array( $_oValue ) )
  149. $_arUrlParams[ $_sKey ] = $_oValue;
  150. else
  151. {
  152. foreach ( $_oValue as $_sSubKey => $_oSubValue )
  153. $_arUrlParams[ $_sSubKey ] = $_oSubValue;
  154. }
  155. }
  156. }
  157. if ( ! method_exists( $this->getOwner(), $_sMethod ) )
  158. {
  159. // Is it a valid catchall request?
  160. if ( ! method_exists( $this->getOwner(), 'request' . $_sActionId ) )
  161. // No clue what it is, so must be bogus. Hand off to missing action...
  162. return $this->getOwner()->missingAction( $_sActionId );
  163. $_sMethod = 'request' . $_sActionId;
  164. }
  165. // All rest methods echo their output
  166. echo call_user_func_array( array( $this->getOwner(), $_sMethod ), array_values( $_arUrlParams ) );
  167. }
  168. }