1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33:
34: class Mage_Api2_Model_Multicall
35: {
36:
37: 38: 39:
40: protected $_parentCallRequest;
41:
42: 43: 44:
45: protected $_parentResourceId;
46:
47: 48: 49: 50: 51: 52: 53: 54:
55: public function call($parentResourceId, $parentResourceName, Mage_Api2_Model_Request $parentCallRequest)
56: {
57: $this->_parentResourceId = $parentResourceId;
58: $this->_parentCallRequest = $parentCallRequest;
59: $subresources = $this->_getDeclaredSubresources($parentResourceName);
60: foreach ($subresources as $subresource) {
61: $this->_callSubresource($subresource);
62: }
63:
64: return $this->_getResponse();
65: }
66:
67: 68: 69: 70: 71: 72:
73: protected function _callSubresource($subresource)
74: {
75: $bodyParams = $this->_getRequest()->getBodyParams();
76:
77: $requestParamName = (string)$subresource->request_param_name;
78: if (!(is_array($bodyParams) && array_key_exists($requestParamName, $bodyParams)
79: && is_array($bodyParams[$requestParamName]))
80: ) {
81: return $this;
82: }
83:
84: $subresourceType = (string)$subresource->type;
85: $requestData = $bodyParams[$requestParamName];
86: switch ($subresourceType) {
87: case 'collection':
88: foreach ($requestData as $subresourceData) {
89: $this->_internalCall($subresource, $subresourceData);
90: }
91: break;
92: case 'instance':
93: default:
94: $this->_internalCall($subresource, $requestData);
95: break;
96: }
97: return $this;
98: }
99:
100: 101: 102: 103: 104: 105: 106: 107:
108: protected function _internalCall($subresource, $requestData)
109: {
110: try {
111: if (!is_array($requestData)) {
112: throw new Mage_Api2_Exception('Invalid data format', Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
113: }
114: $subresourceIdKey = (string)$subresource->id_param_name;
115:
116: $server = Mage::getSingleton('api2/server');
117:
118:
119: if (!array_key_exists($subresourceIdKey, $requestData)) {
120: $subresourceCreateResourceName = (string)$subresource->create_resource_name;
121: $internalRequest = $this->_prepareRequest($subresourceCreateResourceName, $requestData);
122:
123: $internalCreateResponse = Mage::getModel('api2/response');
124: $server->internalCall($internalRequest, $internalCreateResponse);
125: $createdSubresourceInstanceId = $this->_getCreatedResourceId($internalCreateResponse);
126: if (empty($createdSubresourceInstanceId)) {
127: throw new Mage_Api2_Exception('Error during subresource creation',
128: Mage_Api2_Model_Server::HTTP_INTERNAL_ERROR);
129: }
130: $requestData[$subresourceIdKey] = $createdSubresourceInstanceId;
131: }
132:
133:
134: $subresourceName = (string)$subresource->name;
135: $parentResourceIdFieldName = (string)$subresource->parent_resource_id_field_name;
136: $internalRequest = $this->_prepareRequest($subresourceName, $requestData, $parentResourceIdFieldName);
137:
138:
139: $internalResponse = Mage::getModel('api2/response');
140: $server->internalCall($internalRequest, $internalResponse);
141: } catch (Exception $e) {
142:
143: Mage::logException($e);
144: $this->_getResponse()->setException($e);
145:
146: $this->_getResponse()->setHttpResponseCode(Mage_Api2_Model_Server::HTTP_CREATED);
147: }
148:
149: if (isset($internalCreateResponse)) {
150: $this->_aggregateResponse($internalCreateResponse);
151: }
152: if (isset($internalResponse)) {
153: $this->_aggregateResponse($internalResponse);
154: }
155:
156: return $this;
157: }
158:
159: 160: 161: 162: 163: 164: 165: 166:
167: protected function _prepareRequest($subresourceName, $data, $parentResourceIdFieldName = null)
168: {
169: $subresourceUri = $this->_createSubresourceUri($subresourceName, $parentResourceIdFieldName);
170:
171: $internalRequest = Mage::getModel('api2/request_internal');
172: $internalRequest->setRequestUri($subresourceUri);
173: $internalRequest->setBodyParams($data);
174: $internalRequest->setMethod('POST');
175: return $internalRequest;
176: }
177:
178: 179: 180: 181: 182: 183: 184:
185: protected function _createSubresourceUri($subresourceName, $parentResourceIdFieldName = null)
186: {
187:
188: $apiTypeRoute = Mage::getModel('api2/route_apiType');
189:
190: $chain = $apiTypeRoute->chain(
191: new Zend_Controller_Router_Route($this->_getConfig()->getMainRoute($subresourceName))
192: );
193: $params = array();
194: $params['api_type'] = 'rest';
195: if (null !== $parentResourceIdFieldName) {
196: $params[$parentResourceIdFieldName] = $this->_parentResourceId;
197: }
198: $uri = $chain->assemble($params);
199:
200: return '/' . $uri;
201: }
202:
203: 204: 205: 206: 207: 208:
209: protected function _getDeclaredSubresources($parentResourceName)
210: {
211: return $this->_getConfig()->getResourceSubresources($parentResourceName);
212: }
213:
214: 215: 216: 217: 218:
219: protected function _getConfig()
220: {
221: return Mage::getSingleton('api2/config');
222: }
223:
224: 225: 226: 227: 228:
229: protected function _getResponse()
230: {
231: return Mage::getSingleton('api2/response');
232: }
233:
234: 235: 236: 237: 238:
239: protected function _getRequest()
240: {
241: return $this->_parentCallRequest;
242: }
243:
244: 245: 246: 247: 248:
249: protected function _aggregateResponse(Mage_Api2_Model_Response $response)
250: {
251: if ($response->isException()) {
252: $errors = $response->getException();
253:
254: foreach ($errors as $error) {
255: $this->_getResponse()->setException($error);
256: }
257: }
258: }
259:
260: 261: 262: 263: 264: 265:
266: protected function _getCreatedResourceId($response)
267: {
268: $resourceId = 0;
269: $headers = $response->getHeaders();
270: foreach ($headers as $header) {
271: if ($header['name'] == 'Location') {
272: list($resourceId) = array_reverse(explode('/', $header['value']));
273: break;
274: }
275: }
276: return $resourceId;
277: }
278: }
279: