PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 541 lines | 332 code | 70 blank | 139 comment | 79 complexity | d043c5370f274cc05bdeb1ea4b61a312 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Api
  23. * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Webservice default handler
  28. *
  29. * @category Mage
  30. * @package Mage_Api
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. abstract class Mage_Api_Model_Server_Handler_Abstract
  34. {
  35. protected $_resourceSuffix = null;
  36. public function __construct()
  37. {
  38. set_error_handler(array($this, 'handlePhpError'), E_ALL);
  39. }
  40. public function handlePhpError($errorCode, $errorMessage, $errorFile)
  41. {
  42. Mage::log($errorMessage . $errorFile);
  43. if (in_array($errorCode, array(E_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR))) {
  44. $this->_fault('internal');
  45. }
  46. return true;
  47. }
  48. /**
  49. * Retrive webservice session
  50. *
  51. * @return Mage_Api_Model_Session
  52. */
  53. protected function _getSession()
  54. {
  55. return Mage::getSingleton('api/session');
  56. }
  57. /**
  58. * Retrive webservice configuration
  59. *
  60. * @return Mage_Api_Model_Config
  61. */
  62. protected function _getConfig()
  63. {
  64. return Mage::getSingleton('api/config');
  65. }
  66. /**
  67. * Retrive webservice server
  68. *
  69. * @return Mage_Api_Model_Server
  70. */
  71. protected function _getServer()
  72. {
  73. return Mage::getSingleton('api/server');
  74. }
  75. /**
  76. * Start webservice session
  77. *
  78. * @param string $sessionId
  79. * @return Mage_Api_Model_Server_Handler_Abstract
  80. */
  81. protected function _startSession($sessionId=null)
  82. {
  83. $this->_getSession()->setSessionId($sessionId);
  84. $this->_getSession()->init('api', 'api');
  85. return $this;
  86. }
  87. /**
  88. * Check current user permission on resource and privilege
  89. *
  90. *
  91. * @param string $resource
  92. * @param string $privilege
  93. * @return bool
  94. */
  95. protected function _isAllowed($resource, $privilege=null)
  96. {
  97. return $this->_getSession()->isAllowed($resource, $privilege);
  98. }
  99. /**
  100. * Check session expiration
  101. *
  102. * @return boolean
  103. */
  104. protected function _isSessionExpired ()
  105. {
  106. return $this->_getSession()->isSessionExpired();
  107. }
  108. /**
  109. * Dispatch webservice fault
  110. *
  111. * @param string $faultName
  112. * @param string $resourceName
  113. * @param string $customMessage
  114. */
  115. protected function _fault($faultName, $resourceName=null, $customMessage=null)
  116. {
  117. $faults = $this->_getConfig()->getFaults($resourceName);
  118. if (!isset($faults[$faultName]) && !is_null($resourceName)) {
  119. $this->_fault($faultName);
  120. return;
  121. } elseif (!isset($faults[$faultName])) {
  122. $this->_fault('unknown');
  123. return;
  124. }
  125. $this->_getServer()->getAdapter()->fault(
  126. $faults[$faultName]['code'],
  127. (is_null($customMessage) ? $faults[$faultName]['message'] : $customMessage)
  128. );
  129. }
  130. /**
  131. * Retrive webservice fault as array
  132. *
  133. * @param string $faultName
  134. * @param string $resourceName
  135. * @param string $customMessage
  136. * @return array
  137. */
  138. protected function _faultAsArray($faultName, $resourceName=null, $customMessage=null)
  139. {
  140. $faults = $this->_getConfig()->getFaults($resourceName);
  141. if (!isset($faults[$faultName]) && !is_null($resourceName)) {
  142. return $this->_faultAsArray($faultName);
  143. } elseif (!isset($faults[$faultName])) {
  144. return $this->_faultAsArray('unknown');
  145. }
  146. return array(
  147. 'isFault' => true,
  148. 'faultCode' => $faults[$faultName]['code'],
  149. 'faultMessage' => (is_null($customMessage) ? $faults[$faultName]['message'] : $customMessage)
  150. );
  151. }
  152. /**
  153. * Start web service session
  154. *
  155. * @return string
  156. */
  157. public function startSession()
  158. {
  159. $this->_startSession();
  160. return $this->_getSession()->getSessionId();
  161. }
  162. /**
  163. * End web service session
  164. *
  165. * @param string $sessionId
  166. * @return boolean
  167. */
  168. public function endSession($sessionId)
  169. {
  170. $this->_startSession($sessionId);
  171. $this->_getSession()->clear();
  172. return true;
  173. }
  174. /**
  175. * Enter description here...
  176. *
  177. * @param string $resource
  178. * @return string
  179. */
  180. protected function _prepareResourceModelName($resource)
  181. {
  182. if (null !== $this->_resourceSuffix) {
  183. return $resource . $this->_resourceSuffix;
  184. }
  185. return $resource;
  186. }
  187. /**
  188. * Login user and Retrieve session id
  189. *
  190. * @param string $username
  191. * @param string $apiKey
  192. * @return string
  193. */
  194. public function login($username, $apiKey)
  195. {
  196. $this->_startSession();
  197. try {
  198. $this->_getSession()->login($username, $apiKey);
  199. } catch (Exception $e) {
  200. return $this->_fault('access_denied');
  201. }
  202. return $this->_getSession()->getSessionId();
  203. }
  204. /**
  205. * Call resource functionality
  206. *
  207. * @param string $sessionId
  208. * @param string $resourcePath
  209. * @param array $args
  210. * @return mixed
  211. */
  212. public function call($sessionId, $apiPath, $args = array())
  213. {
  214. $this->_startSession($sessionId);
  215. if (!$this->_getSession()->isLoggedIn($sessionId)) {
  216. return $this->_fault('session_expired');
  217. }
  218. list($resourceName, $methodName) = explode('.', $apiPath);
  219. if (empty($resourceName) || empty($methodName)) {
  220. return $this->_fault('resource_path_invalid');
  221. }
  222. $resourcesAlias = $this->_getConfig()->getResourcesAlias();
  223. $resources = $this->_getConfig()->getResources();
  224. if (isset($resourcesAlias->$resourceName)) {
  225. $resourceName = (string) $resourcesAlias->$resourceName;
  226. }
  227. if (!isset($resources->$resourceName)
  228. || !isset($resources->$resourceName->methods->$methodName)) {
  229. return $this->_fault('resource_path_invalid');
  230. }
  231. if (!isset($resources->$resourceName->public)
  232. && isset($resources->$resourceName->acl)
  233. && !$this->_isAllowed((string)$resources->$resourceName->acl)) {
  234. return $this->_fault('access_denied');
  235. }
  236. if (!isset($resources->$resourceName->methods->$methodName->public)
  237. && isset($resources->$resourceName->methods->$methodName->acl)
  238. && !$this->_isAllowed((string)$resources->$resourceName->methods->$methodName->acl)) {
  239. return $this->_fault('access_denied');
  240. }
  241. $methodInfo = $resources->$resourceName->methods->$methodName;
  242. try {
  243. $method = (isset($methodInfo->method) ? (string) $methodInfo->method : $methodName);
  244. $modelName = $this->_prepareResourceModelName((string) $resources->$resourceName->model);
  245. try {
  246. $model = Mage::getModel($modelName);
  247. if ($model instanceof Mage_Api_Model_Resource_Abstract) {
  248. $model->setResourceConfig($resources->$resourceName);
  249. }
  250. } catch (Exception $e) {
  251. throw new Mage_Api_Exception('resource_path_not_callable');
  252. }
  253. if (is_callable(array(&$model, $method))) {
  254. if (isset($methodInfo->arguments) && ((string)$methodInfo->arguments) == 'array') {
  255. return $model->$method((is_array($args) ? $args : array($args)));
  256. } elseif (!is_array($args)) {
  257. return $model->$method($args);
  258. } else {
  259. return call_user_func_array(array(&$model, $method), $args);
  260. }
  261. } else {
  262. throw new Mage_Api_Exception('resource_path_not_callable');
  263. }
  264. } catch (Mage_Api_Exception $e) {
  265. return $this->_fault($e->getMessage(), $resourceName, $e->getCustomMessage());
  266. } catch (Exception $e) {
  267. Mage::logException($e);
  268. return $this->_fault('internal', null, $e->getMessage());
  269. }
  270. }
  271. /**
  272. * Multiple calls of resource functionality
  273. *
  274. * @param string $sessionId
  275. * @param array $calls
  276. * @param array $options
  277. * @return array
  278. */
  279. public function multiCall($sessionId, array $calls = array(), $options = array())
  280. {
  281. $this->_startSession($sessionId);
  282. if (!$this->_getSession()->isLoggedIn($sessionId)) {
  283. return $this->_fault('session_expired');
  284. }
  285. $result = array();
  286. $resourcesAlias = $this->_getConfig()->getResourcesAlias();
  287. $resources = $this->_getConfig()->getResources();
  288. foreach ($calls as $call) {
  289. if (!isset($call[0])) {
  290. $result[] = $this->_faultAsArray('resource_path_invalid');
  291. if (isset($options['break']) && $options['break']==1) {
  292. break;
  293. } else {
  294. continue;
  295. }
  296. }
  297. $apiPath = $call[0];
  298. $args = (isset($call[1]) ? $call[1] : array());
  299. list($resourceName, $methodName) = explode('.', $apiPath);
  300. if (empty($resourceName) || empty($methodName)) {
  301. $result[] = $this->_faultAsArray('resource_path_invalid');
  302. if (isset($options['break']) && $options['break']==1) {
  303. break;
  304. } else {
  305. continue;
  306. }
  307. }
  308. if (isset($resourcesAlias->$resourceName)) {
  309. $resourceName = (string) $resourcesAlias->$resourceName;
  310. }
  311. if (!isset($resources->$resourceName)
  312. || !isset($resources->$resourceName->methods->$methodName)) {
  313. $result[] = $this->_faultAsArray('resource_path_invalid');
  314. if (isset($options['break']) && $options['break']==1) {
  315. break;
  316. } else {
  317. continue;
  318. }
  319. }
  320. if (!isset($resources->$resourceName->public)
  321. && isset($resources->$resourceName->acl)
  322. && !$this->_isAllowed((string)$resources->$resourceName->acl)) {
  323. $result[] = $this->_faultAsArray('access_denied');
  324. if (isset($options['break']) && $options['break']==1) {
  325. break;
  326. } else {
  327. continue;
  328. }
  329. }
  330. if (!isset($resources->$resourceName->methods->$methodName->public)
  331. && isset($resources->$resourceName->methods->$methodName->acl)
  332. && !$this->_isAllowed((string)$resources->$resourceName->methods->$methodName->acl)) {
  333. $result[] = $this->_faultAsArray('access_denied');
  334. if (isset($options['break']) && $options['break']==1) {
  335. break;
  336. } else {
  337. continue;
  338. }
  339. }
  340. $methodInfo = $resources->$resourceName->methods->$methodName;
  341. try {
  342. $method = (isset($methodInfo->method) ? (string) $methodInfo->method : $methodName);
  343. $modelName = $this->_prepareResourceModelName((string) $resources->$resourceName->model);
  344. try {
  345. $model = Mage::getModel($modelName);
  346. } catch (Exception $e) {
  347. throw new Mage_Api_Exception('resource_path_not_callable');
  348. }
  349. if (is_callable(array(&$model, $method))) {
  350. if (isset($methodInfo->arguments) && ((string)$methodInfo->arguments) == 'array') {
  351. $result[] = $model->$method((is_array($args) ? $args : array($args)));
  352. } elseif (!is_array($args)) {
  353. $result[] = $model->$method($args);
  354. } else {
  355. $result[] = call_user_func_array(array(&$model, $method), $args);
  356. }
  357. } else {
  358. throw new Mage_Api_Exception('resource_path_not_callable');
  359. }
  360. } catch (Mage_Api_Exception $e) {
  361. $result[] = $this->_faultAsArray($e->getMessage(), $resourceName, $e->getCustomMessage());
  362. if (isset($options['break']) && $options['break']==1) {
  363. break;
  364. } else {
  365. continue;
  366. }
  367. } catch (Exception $e) {
  368. Mage::logException($e);
  369. $result[] = $this->_faultAsArray('internal');
  370. if (isset($options['break']) && $options['break']==1) {
  371. break;
  372. } else {
  373. continue;
  374. }
  375. }
  376. }
  377. return $result;
  378. }
  379. /**
  380. * List of available resources
  381. *
  382. * @param string $sessionId
  383. * @return array
  384. */
  385. public function resources($sessionId)
  386. {
  387. $this->_startSession($sessionId);
  388. if (!$this->_getSession()->isLoggedIn($sessionId)) {
  389. return $this->_fault('session_expired');
  390. }
  391. $resources = array();
  392. $resourcesAlias = array();
  393. foreach ($this->_getConfig()->getResourcesAlias() as $alias => $resourceName) {
  394. $resourcesAlias[(string) $resourceName][] = $alias;
  395. }
  396. foreach ($this->_getConfig()->getResources() as $resourceName => $resource) {
  397. if (isset($resource->acl) && !$this->_isAllowed((string) $resource->acl)) {
  398. continue;
  399. }
  400. $methods = array();
  401. foreach ($resource->methods->children() as $methodName => $method) {
  402. if (isset($method->acl) && !$this->_isAllowed((string) $method->acl)) {
  403. continue;
  404. }
  405. $methodAliases = array();
  406. if (isset($resourcesAlias[$resourceName])) {
  407. foreach ($resourcesAlias[$resourceName] as $alias) {
  408. $methodAliases[] = $alias . '.' . $methodName;
  409. }
  410. }
  411. $methods[] = array(
  412. 'title' => (string) $method->title,
  413. 'description' => (isset($method->description) ? (string)$method->description : null),
  414. 'path' => $resourceName . '.' . $methodName,
  415. 'name' => $methodName,
  416. 'aliases' => $methodAliases
  417. );
  418. }
  419. if (count($methods) == 0) {
  420. continue;
  421. }
  422. $resources[] = array(
  423. 'title' => (string) $resource->title,
  424. 'description' => (isset($resource->description) ? (string)$resource->description : null),
  425. 'name' => $resourceName,
  426. 'aliases' => (isset($resourcesAlias[$resourceName]) ? $resourcesAlias[$resourceName] : array()),
  427. 'methods' => $methods
  428. );
  429. }
  430. return $resources;
  431. }
  432. /**
  433. * List of resource faults
  434. *
  435. * @param string $sessionId
  436. * @param string $resourceName
  437. * @return array
  438. */
  439. public function resourceFaults($sessionId, $resourceName)
  440. {
  441. $this->_startSession($sessionId);
  442. if (!$this->_getSession()->isLoggedIn($sessionId)) {
  443. return $this->_fault('session_expired');
  444. }
  445. $resourcesAlias = $this->_getConfig()->getResourcesAlias();
  446. $resources = $this->_getConfig()->getResources();
  447. if (isset($resourcesAlias->$resourceName)) {
  448. $resourceName = (string) $resourcesAlias->$resourceName;
  449. }
  450. if (empty($resourceName)
  451. || !isset($resources->$resourceName)) {
  452. return $this->_fault('resource_path_invalid');
  453. }
  454. if (isset($resources->$resourceName->acl)
  455. && !$this->_isAllowed((string)$resources->$resourceName->acl)) {
  456. return $this->_fault('access_denied');
  457. }
  458. return array_values($this->_getConfig()->getFaults($resourceName));
  459. }
  460. /**
  461. * List of global faults
  462. *
  463. * @param string $sessionId
  464. * @return array
  465. */
  466. public function globalFaults($sessionId)
  467. {
  468. $this->_startSession($sessionId);
  469. return array_values($this->_getConfig()->getFaults());
  470. }
  471. } // Class Mage_Api_Model_Server_Handler_Abstract End