1 <?php
2 /* --------------------------------------------------------------
3 AddressesApiV2Controller.inc.php 2016-03-07
4 Gambio GmbH
5 http://www.gambio.de
6 Copyright (c) 2016 Gambio GmbH
7 Released under the GNU General Public License (Version 2)
8 [http://www.gnu.org/licenses/gpl-2.0.html]
9 --------------------------------------------------------------
10 */
11
12 MainFactory::load_class('HttpApiV2Controller');
13
14 /**
15 * Class AddressesApiV2Controller
16 *
17 * Provides a gateway to the AddressBookService which handles the shop address resources.
18 *
19 * @category System
20 * @package ApiV2Controllers
21 */
22 class AddressesApiV2Controller extends HttpApiV2Controller
23 {
24 /**
25 * @var AddressBookServiceInterface
26 */
27 protected $addressService;
28
29 /**
30 * @var AddressJsonSerializer
31 */
32 protected $addressSerializer;
33
34
35 /**
36 * Initializes API Controller
37 */
38 protected function __initialize()
39 {
40 $this->addressService = StaticGXCoreLoader::getService('AddressBook');
41 $this->addressSerializer = MainFactory::create('AddressJsonSerializer');
42 }
43
44
45 /**
46 * @api {post} /addresses Create Address
47 * @apiVersion 2.1.0
48 * @apiName CreateAddress
49 * @apiGroup Addresses
50 *
51 * @apiParamExample {json} Request-Body
52 * {
53 * "customerId": 1,
54 * "gender": "m",
55 * "company": "Test Company",
56 * "firstname": "John",
57 * "lastname": "Doe",
58 * "street": "Test Street 1",
59 * "suburb": "Test Suburb",
60 * "postcode": "23983",
61 * "city": "Test City",
62 * "countryId": 81,
63 * "zoneId": 84,
64 * "class": null,
65 * "b2bStatus": false
66 * }
67 *
68 * @apiParam {int} customerId The customer's record ID to whom the address belong.
69 * @apiParam {string} gender Provide either "m" or "f" for male and female.
70 * @apiParam {string} company The address company name.
71 * @apiParam {string} firstname The address firstname.
72 * @apiParam {string} lastname The address lastname.
73 * @apiParam {string} street The address street.
74 * @apiParam {string} suburb The address suburb.
75 * @apiParam {string} postcode The address postcode.
76 * @apiParam {string} city The address city.
77 * @apiParam {int} countryId Provide an existing "countryId", if it does not exist create it through the
78 * "countries" API methods.
79 * @apiParam {int} zoneId Provide an existing "countryId", if it does not exist create it through the "zones" API
80 * methods.
81 * @apiParam {string} class The address class can be any string used for distinguishing the address from other
82 * records.
83 * @apiParam {bool} b2bStatus Defines the Business-to-Business status of the address.
84 *
85 * @apiSuccess (Success 201) Response-Body If successful, this method returns a complete Customers resource in
86 * the response body.
87 *
88 * @apiError 400-BadRequest Address data were not provided.
89 *
90 * @apiErrorExample Error-Response
91 * HTTP/1.1 400 Bad Request
92 * {
93 * "code": 400,
94 * "status": "error",
95 * "message": "Address data were not provided."
96 * }
97 */
98 public function post()
99 {
100 // Validate Request Data
101 $addressJsonString = $this->api->request->getBody();
102
103 if(empty($addressJsonString))
104 {
105 throw new HttpApiV2Exception('Address data were not provided.', 400);
106 }
107
108 // Make sure that the address ID is not included in the request body (post method is used for new records).
109 $tmpEncodedAddress = json_decode($addressJsonString);
110 unset($tmpEncodedAddress->id);
111 $addressJsonString = json_encode($tmpEncodedAddress);
112
113 // Store the address to the database.
114 $address = $this->addressSerializer->deserialize($addressJsonString);
115 $this->addressService->updateCustomerAddress($address);
116
117 // Prepare client response with links.
118 $response = $this->addressSerializer->serialize($address, false);
119 $this->_linkResponse($response);
120 $this->_locateResource('addresses', (string)$address->getId());
121 $this->_writeResponse($response, 201);
122 }
123
124
125 /**
126 * @api {put} /addresses/:id Update Address
127 * @apiVersion 2.1.0
128 * @apiName UpdateAddress
129 * @apiGroup Addresses
130 *
131 * @apiDescription
132 * Update an existing address record by providing new data. You do not have to provide the full
133 * presentation of the address in the JSON string of the request, rather just the fields to be
134 * updated. The address ID will be taken from the URI of the request so it is not required that
135 * it is included withing the request JSON.
136 *
137 * @apiExample {json} Request-Body
138 * {
139 * "company": "Test Company - UPDATED",
140 * "firstname": "John - UPDATED",
141 * "lastname": "Doe - UPDATED",
142 * "street": "Test Street - UPDATED",
143 * "suburb": "Test Suburb - UPDATED",
144 * "city": "Test City - UPDATED"
145 * }
146 *
147 * @apiSuccess Response-Body If successful, this method returns the updated address resource in the response body.
148 */
149 public function put()
150 {
151 // Validate Request Data
152 if(!isset($this->uri[1]) || !is_numeric($this->uri[1]))
153 {
154 throw new HttpApiV2Exception('Address record id was not provided or is invalid: ' . gettype($this->uri[1]),
155 400);
156 }
157
158 $addressJsonString = $this->api->request->getBody();
159
160 if(empty($addressJsonString))
161 {
162 throw new HttpApiV2Exception('Address data were not provided.', 400);
163 }
164
165 // Update existing address record.
166 $addressId = new IdType((int)$this->uri[1]);
167 $baseObject = $this->addressService->findAddressById($addressId);
168
169 // Ensure that the address has the correct address id of the request url
170 $addressJsonString = $this->_setJsonValue($addressJsonString, 'id', $addressId->asInt());
171
172 $address = $this->addressSerializer->deserialize($addressJsonString, $baseObject);
173 $address->setId($addressId); // ensure that the address has the correct ID
174 $this->addressService->updateCustomerAddress($address);
175
176 // Prepare client response with links.
177 $response = $this->addressSerializer->serialize($address, false);
178 $this->_linkResponse($response);
179 $this->_writeResponse($response);
180 }
181
182
183 /**
184 * @api {delete} /addresses/:id Delete Address
185 * @apiVersion 2.1.0
186 * @apiName DeleteAddress
187 * @apiGroup Addresses
188 *
189 * @apiDescription
190 * Remove an address record from the system. This method will always return success even if the address record
191 * does not exist (due to internal architecture decisions, which strive to avoid unnecessary failures).
192 *
193 * @apiExample {curl} Delete Address with ID = 811
194 * curl -X DELETE --user admin@shop.de:12345 http://shop.de/api.php/v2/addresses/811
195 *
196 * @apiSuccessExample {json} Success-Response
197 * {
198 * "code": 200,
199 * "status": "success",
200 * "action": "delete",
201 * "addressId": 811
202 * }
203 *
204 * @apiError 400-BadRequest Address record ID was not provided in the resource URL.
205 *
206 * @apiErrorExample Error-Response
207 * HTTP/1.1 400 Bad Request
208 * {
209 * "code": 400,
210 * "status": "error",
211 * "message": "Address record ID was not provided in the resource URL."
212 * }
213 */
214 public function delete()
215 {
216 // Validate Request Data
217 if(!isset($this->uri[1]) || !is_numeric($this->uri[1]))
218 {
219 throw new HttpApiV2Exception('Address record id was not provided or is invalid: ' . gettype($this->uri[1]),
220 400);
221 }
222
223 $addressId = new IdType((int)$this->uri[1]);
224 $address = $this->addressService->findAddressById($addressId);
225
226 if($address !== null)
227 {
228 $this->addressService->deleteAddress($address);
229 }
230
231 $response = array(
232 'code' => 200,
233 'status' => 'success',
234 'action' => 'delete',
235 'addressId' => (int)$this->uri[1]
236 );
237
238 $this->_writeResponse($response);
239 }
240
241
242 /**
243 * @api {get} /addresses/:id Get Address
244 * @apiVersion 2.1.0
245 * @apiName GetAddress
246 * @apiGroup Addresses
247 *
248 * @apiDescription
249 * Get multiple or a single address records through a GET requets. This method supports all the GET parameters
250 * that are mentioned in the "Introduction" section of this documentation.
251 *
252 * @apiExample {curl} Delete Address with ID = 243
253 * curl --user admin@shop.de:12345 http://shop.de/api.php/v2/addresses/243
254 *
255 * @apiSuccess Response-Body If successful, this method will return the address resource in JSON format.
256 */
257 public function get()
258 {
259 if(isset($this->uri[1]) && is_numeric($this->uri[1])) // single record
260 {
261 $address = $this->addressService->findAddressById(new IdType((int)$this->uri[1]));
262
263 if($address === null)
264 {
265 throw new HttpApiV2Exception('Record could not be found.', 404);
266 }
267
268 $response = $this->addressSerializer->serialize($address, false);
269 }
270 else // multiple records
271 {
272 $addresses = ($this->api->request->get('q')) ? $this->addressService->filterAddresses($this->api->request->get('q')) : $this->addressService->getAllAddresses();
273 $response = array();
274 foreach($addresses as $address)
275 {
276 $response[] = $this->addressSerializer->serialize($address, false);
277 }
278
279 $this->_sortResponse($response);
280 $this->_paginateResponse($response);
281 }
282
283 $this->_minimizeResponse($response);
284 $this->_linkResponse($response);
285 $this->_writeResponse($response);
286 }
287 }