├── README.md ├── admin ├── controller │ └── feed │ │ └── web_api.php ├── language │ ├── english │ │ └── feed │ │ │ └── web_api.php │ └── russian │ │ └── feed │ │ └── web_api.php └── view │ └── template │ └── feed │ └── web_api.tpl └── catalog └── controller └── feed └── web_api.php /README.md: -------------------------------------------------------------------------------- 1 | Opencart WEB API 2 | ================ 3 | 4 | This is a small module that adds the ability to remotely work with the OpenCart 1.5.3+ via the REST API. 5 | 6 | * Homepage: http://zenwalker.ru/lab/opencart-webapi/ 7 | * Sources: https://github.com/ethernet1/opencart-webapi 8 | * Ddocumentation in Russian: http://zenwalker.ru/lab/opencart-webapi/documentation.html 9 | 10 | Features: 11 | 12 | * [Get categories list](#get-categories) 13 | * [Get category info](#get-category-info) 14 | * [Get products from category](#get-products) 15 | * [Get full info from product](#get-product) 16 | 17 | 18 | Examples 19 | -------- 20 | 21 | ### Get categories 22 | 23 | Request: 24 | 25 | http://example.com/?route=feed/web_api/categories&parent=0&level=2 26 | 27 | 28 | Params: 29 | 30 | * $_GET['parent']: parent category id 31 | * $_GET['level']: depth level 32 | 33 | 34 | Answer: 35 | 36 | { 37 | "success": true, 38 | 39 | categories: 40 | [ 41 | { 42 | "category_id": "1", 43 | "name": "First category", 44 | "parent_id": "0", 45 | "href": "http://example.com/index.php?route=product/category&category_id=1" 46 | "categories": null, 47 | }, 48 | { 49 | "category_id": "2", 50 | "name": "Second category", 51 | "parent_id": "0", 52 | "href": "http://example.com/index.php?route=product/category&category_id=2" 53 | "categories": [ 54 | { 55 | "category_id": "3", 56 | "name": "Inner category", 57 | "parent_id": "2", 58 | "href": "http://example.com/index.php?route=product/category&category_id=3" 59 | "categories": null 60 | }, 61 | { 62 | "category_id": "3", 63 | "name": "Inner category", 64 | "parent_id": "2", 65 | "href": "http://example.com/index.php?route=product/category&category_id=4" 66 | "categories": null 67 | } 68 | ] 69 | } 70 | ] 71 | } 72 | 73 | 74 | ### Get category info 75 | 76 | Request: 77 | 78 | http://example.com/?route=feed/web_api/category&id=1 79 | 80 | 81 | Params: 82 | 83 | * $_GET['id']: category id 84 | 85 | 86 | Answer: 87 | 88 | { 89 | "success":true, 90 | 91 | "category":{ 92 | "id": "1", 93 | "name": "Category name", 94 | "description": "", 95 | "href": "http://example.com/index.php?route=product/category&category_id=1" 96 | } 97 | } 98 | 99 | 100 | 101 | ### Get products 102 | 103 | Request: 104 | 105 | http://example.com/?route=feed/web_api/products&category=1 106 | 107 | 108 | Params: 109 | 110 | * $_GET['category']: parent category id 111 | 112 | 113 | Answer: 114 | 115 | { 116 | "success": true, 117 | 118 | products: [ 119 | { 120 | "id": "6", 121 | "name": "Product name", 122 | "description": "", 123 | "pirce": "$455.00", 124 | "href": "http://example.com/index.php?route=product/product&product_id=6", 125 | "thumb": false, 126 | "special": false, 127 | "rating": 0 128 | }, 129 | { 130 | "id": "7", 131 | "name": "Product name", 132 | "description": "", 133 | "pirce": "$25.00", 134 | "href": "http://example.com/index.php?route=product/product&product_id=7", 135 | "thumb": false, 136 | "special": false, 137 | "rating": 0 138 | } 139 | ] 140 | } 141 | 142 | 143 | 144 | ### Get product 145 | 146 | Request: 147 | 148 | http://example.com/?route=feed/web_api/product&id=1 149 | 150 | Params: 151 | 152 | * $_GET['id']: product id 153 | 154 | Answer: 155 | 156 | { 157 | "success":true, 158 | 159 | "product":{ 160 | "id": "2", 161 | "seo_h1": "", 162 | "name": "Product name", 163 | "manufacturer":null, 164 | "model": "A1", 165 | "reward":null, 166 | "points": "0", 167 | "image": "", 168 | "images":[], 169 | "price": "$10.00", 170 | "special":false, 171 | "discounts":[], 172 | "options":[ 173 | { 174 | "product_option_id": "2", 175 | "option_id": "5", 176 | "name": "Select", 177 | "type": "select", 178 | "option_value":[ 179 | 180 | ], 181 | "required": "1" 182 | }, 183 | { 184 | "product_option_id": "1", 185 | "option_id": "2", 186 | "name": "Checkbox", 187 | "type": "checkbox", 188 | "option_value":[ 189 | { 190 | "product_option_value_id": "1", 191 | "option_value_id": "24", 192 | "name": "Checkbox 2", 193 | "image":null, 194 | "price": "$20.00", 195 | "price_prefix": "+" 196 | } 197 | ], 198 | "required": "1" 199 | } 200 | ], 201 | "minimum": "1", 202 | "rating": 0, 203 | "description": "HTML Description", 204 | "attribute_groups":[ 205 | { 206 | "attribute_group_id": "1", 207 | "name": "Attribute group 1", 208 | "attribute":[ 209 | { 210 | "attribute_id": "10", 211 | "name": "Attribute 1", 212 | "text": "20" 213 | }, 214 | { 215 | "attribute_id": "70", 216 | "name": "Attrubute 2", 217 | "text": "Value" 218 | } 219 | ] 220 | } 221 | ] 222 | } 223 | } 224 | 225 | 226 | 227 | ### Error handling 228 | 229 | Answer: 230 | 231 | { 232 | "success": false, 233 | "code": 20, 234 | "message": "Invalid secret key" 235 | } 236 | 237 | Error codes: 238 | 239 | * 10 - Module disabled 240 | * 20 - Invalid secret key 241 | 242 | 243 | License 244 | ------- 245 | 246 | This software is distributed under the [GNU GPL V3](http://www.gnu.org/licenses/gpl.html) License. -------------------------------------------------------------------------------- /admin/controller/feed/web_api.php: -------------------------------------------------------------------------------- 1 | load->language('feed/web_api'); 7 | $this->load->model('setting/setting'); 8 | 9 | $this->document->setTitle($this->language->get('heading_title')); 10 | 11 | 12 | $this->data = array( 13 | 'version' => '1.0', 14 | 'heading_title' => $this->language->get('heading_title'), 15 | 16 | 'text_enabled' => $this->language->get('text_enabled'), 17 | 'text_disabled' => $this->language->get('text_disabled'), 18 | 'text_homepage' => $this->language->get('text_homepage'), 19 | 'tab_general' => $this->language->get('tab_general'), 20 | 21 | 'entry_status' => $this->language->get('entry_status'), 22 | 'entry_key' => $this->language->get('entry_key'), 23 | 24 | 'button_save' => $this->language->get('button_save'), 25 | 'button_cancel' => $this->language->get('button_cancel'), 26 | 27 | 'action' => $this->url->link('feed/web_api', 'token=' . $this->session->data['token'], 'SSL'), 28 | 'cancel' => $this->url->link('extension/feed', 'token=' . $this->session->data['token'], 'SSL') 29 | ); 30 | 31 | if (($this->request->server['REQUEST_METHOD'] == 'POST')) { 32 | $this->model_setting_setting->editSetting('web_api', $this->request->post); 33 | $this->session->data['success'] = $this->language->get('text_success'); 34 | $this->redirect($this->url->link('extension/feed', 'token=' . $this->session->data['token'], 'SSL')); 35 | } 36 | 37 | $this->data['breadcrumbs'] = array(); 38 | 39 | $this->data['breadcrumbs'][] = array( 40 | 'text' => $this->language->get('text_home'), 41 | 'href' => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'), 42 | 'separator' => false 43 | ); 44 | 45 | $this->data['breadcrumbs'][] = array( 46 | 'text' => $this->language->get('text_feed'), 47 | 'href' => $this->url->link('extension/feed', 'token=' . $this->session->data['token'], 'SSL'), 48 | 'separator' => ' :: ' 49 | ); 50 | 51 | $this->data['breadcrumbs'][] = array( 52 | 'text' => $this->language->get('heading_title'), 53 | 'href' => $this->url->link('feed/web_api', 'token=' . $this->session->data['token'], 'SSL'), 54 | 'separator' => ' :: ' 55 | ); 56 | 57 | if (isset($this->request->post['web_api_status'])) { 58 | $this->data['web_api_status'] = $this->request->post['web_api_status']; 59 | } else { 60 | $this->data['web_api_status'] = $this->config->get('web_api_status'); 61 | } 62 | 63 | if (isset($this->request->post['web_api_key'])) { 64 | $this->data['web_api_key'] = $this->request->post['web_api_key']; 65 | } else { 66 | $this->data['web_api_key'] = $this->config->get('web_api_key'); 67 | } 68 | 69 | 70 | $this->template = 'feed/web_api.tpl'; 71 | 72 | $this->children = array( 73 | 'common/header', 74 | 'common/footer' 75 | ); 76 | 77 | $this->response->setOutput($this->render()); 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /admin/language/english/feed/web_api.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 8 |
9 |
10 |

11 |
12 |
13 |
14 |
15 | 16 |
17 |
18 |
19 | 20 | 21 | 22 | 33 | 34 | 35 | 38 | 41 | 42 |
23 | 32 |
36 | 37 | 39 | 40 |
43 |
44 |
45 |
46 |
47 |
48 | Version: | 49 |
50 |
51 | 52 | 55 | 56 | -------------------------------------------------------------------------------- /catalog/controller/feed/web_api.php: -------------------------------------------------------------------------------- 1 | init(); 10 | $this->load->model('catalog/category'); 11 | $json = array('success' => true); 12 | 13 | # -- $_GET params ------------------------------ 14 | 15 | if (isset($this->request->get['parent'])) { 16 | $parent = $this->request->get['parent']; 17 | } else { 18 | $parent = 0; 19 | } 20 | 21 | if (isset($this->request->get['level'])) { 22 | $level = $this->request->get['level']; 23 | } else { 24 | $level = 1; 25 | } 26 | 27 | # -- End $_GET params -------------------------- 28 | 29 | 30 | $json['categories'] = $this->getCategoriesTree($parent, $level); 31 | 32 | if ($this->debug) { 33 | echo '
';
 34 | 			print_r($json);
 35 | 		} else {
 36 | 			$this->response->setOutput(json_encode($json));
 37 | 		}
 38 | 	}
 39 | 
 40 | 	public function category() {
 41 | 		$this->init();
 42 | 		$this->load->model('catalog/category');
 43 | 		$this->load->model('tool/image');
 44 | 
 45 | 		$json = array('success' => true);
 46 | 
 47 | 		# -- $_GET params ------------------------------
 48 | 		
 49 | 		if (isset($this->request->get['id'])) {
 50 | 			$category_id = $this->request->get['id'];
 51 | 		} else {
 52 | 			$category_id = 0;
 53 | 		}
 54 | 
 55 | 		# -- End $_GET params --------------------------
 56 | 
 57 | 		$category = $this->model_catalog_category->getCategory($category_id);
 58 | 		
 59 | 		$json['category'] = array(
 60 | 			'id'                    => $category['category_id'],
 61 | 			'name'                  => $category['name'],
 62 | 			'description'           => $category['description'],
 63 | 			'href'                  => $this->url->link('product/category', 'category_id=' . $category['category_id'])
 64 | 		);
 65 | 
 66 | 		if ($this->debug) {
 67 | 			echo '
';
 68 | 			print_r($json);
 69 | 		} else {
 70 | 			$this->response->setOutput(json_encode($json));
 71 | 		}
 72 | 	}
 73 | 
 74 | 
 75 | 	public function products() {
 76 | 		$this->init();
 77 | 		$this->load->model('catalog/product');
 78 | 		$this->load->model('tool/image');
 79 | 		$json = array('success' => true, 'products' => array());
 80 | 
 81 | 
 82 | 		# -- $_GET params ------------------------------
 83 | 		
 84 | 		if (isset($this->request->get['category'])) {
 85 | 			$category_id = $this->request->get['category'];
 86 | 		} else {
 87 | 			$category_id = 0;
 88 | 		}
 89 | 
 90 | 		# -- End $_GET params --------------------------
 91 | 
 92 | 		$products = $this->model_catalog_product->getProducts(array(
 93 | 			'filter_category_id'	=> $category_id
 94 | 		));
 95 | 
 96 | 		foreach ($products as $product) {
 97 | 
 98 | 			if ($product['image']) {
 99 | 				$image = $this->model_tool_image->resize($product['image'], $this->config->get('config_image_product_width'), $this->config->get('config_image_product_height'));
100 | 			} else {
101 | 				$image = false;
102 | 			}
103 | 
104 | 			if ((float)$product['special']) {
105 | 				$special = $this->currency->format($this->tax->calculate($product['special'], $product['tax_class_id'], $this->config->get('config_tax')));
106 | 			} else {
107 | 				$special = false;
108 | 			}
109 | 
110 | 			$json['products'][] = array(
111 | 				'id'                    => $product['product_id'],
112 | 				'name'                  => $product['name'],
113 | 				'description'           => $product['description'],
114 | 				'pirce'                 => $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax'))),
115 | 				'href'                  => $this->url->link('product/product', 'product_id=' . $product['product_id']),
116 | 				'thumb'                 => $image,
117 | 				'special'               => $special,
118 | 				'rating'                => $product['rating']
119 | 			);
120 | 		}
121 | 
122 | 		if ($this->debug) {
123 | 			echo '
';
124 | 			print_r($json);
125 | 		} else {
126 | 			$this->response->setOutput(json_encode($json));
127 | 		}
128 | 	}
129 | 
130 | 	public function product() {
131 | 		$this->init();
132 | 		$this->load->model('catalog/product');
133 | 		$this->load->model('tool/image');
134 | 		$json = array('success' => true);
135 | 
136 | 		# -- $_GET params ------------------------------
137 | 		
138 | 		if (isset($this->request->get['id'])) {
139 | 			$product_id = $this->request->get['id'];
140 | 		} else {
141 | 			$product_id = 0;
142 | 		}
143 | 
144 | 		# -- End $_GET params --------------------------
145 | 
146 | 		$product = $this->model_catalog_product->getProduct($product_id);
147 | 
148 | 		# product image
149 | 		if ($product['image']) {
150 | 			$image = $this->model_tool_image->resize($product['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height'));
151 | 		} else {
152 | 			$image = '';
153 | 		}
154 | 
155 | 		#additional images
156 | 		$additional_images = $this->model_catalog_product->getProductImages($product['product_id']);
157 | 		$images = array();
158 | 
159 | 		foreach ($additional_images as $additional_image) {
160 | 			$images[] = $this->model_tool_image->resize($additional_image, $this->config->get('config_image_additional_width'), $this->config->get('config_image_additional_height'));
161 | 		}
162 | 
163 | 		#specal
164 | 		if ((float)$product['special']) {
165 | 			$special = $this->currency->format($this->tax->calculate($product['special'], $product['tax_class_id'], $this->config->get('config_tax')));
166 | 		} else {
167 | 			$special = false;
168 | 		}
169 | 
170 | 		#discounts
171 | 		$discounts = array();
172 | 		$data_discounts =  $this->model_catalog_product->getProductDiscounts($product['product_id']);
173 | 
174 | 		foreach ($data_discounts as $discount) {
175 | 			$discounts[] = array(
176 | 				'quantity' => $discount['quantity'],
177 | 				'price'    => $this->currency->format($this->tax->calculate($discount['price'], $product['tax_class_id'], $this->config->get('config_tax')))
178 | 			);
179 | 		}
180 | 
181 | 		#options
182 | 		$options = array();
183 | 
184 | 		foreach ($this->model_catalog_product->getProductOptions($product['product_id']) as $option) { 
185 | 			if ($option['type'] == 'select' || $option['type'] == 'radio' || $option['type'] == 'checkbox' || $option['type'] == 'image') { 
186 | 				$option_value_data = array();
187 | 				
188 | 				foreach ($option['option_value'] as $option_value) {
189 | 					if (!$option_value['subtract'] || ($option_value['quantity'] > 0)) {
190 | 						if ((($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) && (float)$option_value['price']) {
191 | 							$price = $this->currency->format($this->tax->calculate($option_value['price'], $product['tax_class_id'], $this->config->get('config_tax')));
192 | 						} else {
193 | 							$price = false;
194 | 						}
195 | 						
196 | 						$option_value_data[] = array(
197 | 							'product_option_value_id' => $option_value['product_option_value_id'],
198 | 							'option_value_id'         => $option_value['option_value_id'],
199 | 							'name'                    => $option_value['name'],
200 | 							'image'                   => $this->model_tool_image->resize($option_value['image'], 50, 50),
201 | 							'price'                   => $price,
202 | 							'price_prefix'            => $option_value['price_prefix']
203 | 						);
204 | 					}
205 | 				}
206 | 				
207 | 				$options[] = array(
208 | 					'product_option_id' => $option['product_option_id'],
209 | 					'option_id'         => $option['option_id'],
210 | 					'name'              => $option['name'],
211 | 					'type'              => $option['type'],
212 | 					'option_value'      => $option_value_data,
213 | 					'required'          => $option['required']
214 | 				);					
215 | 			} elseif ($option['type'] == 'text' || $option['type'] == 'textarea' || $option['type'] == 'file' || $option['type'] == 'date' || $option['type'] == 'datetime' || $option['type'] == 'time') {
216 | 				$options[] = array(
217 | 					'product_option_id' => $option['product_option_id'],
218 | 					'option_id'         => $option['option_id'],
219 | 					'name'              => $option['name'],
220 | 					'type'              => $option['type'],
221 | 					'option_value'      => $option['option_value'],
222 | 					'required'          => $option['required']
223 | 				);						
224 | 			}
225 | 		}
226 | 
227 | 		#minimum
228 | 		if ($product['minimum']) {
229 | 			$minimum = $product['minimum'];
230 | 		} else {
231 | 			$minimum = 1;
232 | 		}
233 | 
234 | 		$json['product'] = array(
235 | 			'id'                            => $product['product_id'],
236 | 			'seo_h1'                        => $product['seo_h1'],
237 | 			'name'                          => $product['name'],
238 | 			'manufacturer'                  => $product['manufacturer'],
239 | 			'model'                         => $product['model'],
240 | 			'reward'                        => $product['reward'],
241 | 			'points'                        => $product['points'],
242 | 			'image'                         => $image,
243 | 			'images'                        => $images,
244 | 			'price'                         => $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax'))),
245 | 			'special'                       => $special,
246 | 			'discounts'                     => $discounts,
247 | 			'options'                       => $options,
248 | 			'minimum'                       => $minimum,
249 | 			'rating'                        => (int)$product['rating'],
250 | 			'description'                   => html_entity_decode($product['description'], ENT_QUOTES, 'UTF-8'),
251 | 			'attribute_groups'              => $this->model_catalog_product->getProductAttributes($product['product_id'])
252 | 		);
253 | 
254 | 
255 | 		if ($this->debug) {
256 | 			echo '
';
257 | 			print_r($json);
258 | 		} else {
259 | 			$this->response->setOutput(json_encode($json));
260 | 		}
261 | 	}
262 | 
263 | 
264 | 	/**
265 | 	 * Generation of category tree
266 | 	 * 
267 | 	 * @param  int    $parent  Prarent category id
268 | 	 * @param  int    $level   Depth level
269 | 	 * @return array           Tree
270 | 	 */
271 | 	private function getCategoriesTree($parent = 0, $level = 1) {
272 | 		$this->load->model('catalog/category');
273 | 		$this->load->model('tool/image');
274 | 		
275 | 		$result = array();
276 | 
277 | 		$categories = $this->model_catalog_category->getCategories($parent);
278 | 
279 | 		if ($categories && $level > 0) {
280 | 			$level--;
281 | 
282 | 			foreach ($categories as $category) {
283 | 
284 | 				if ($category['image']) {
285 | 					$image = $this->model_tool_image->resize($category['image'], $this->config->get('config_image_category_width'), $this->config->get('config_image_category_height'));
286 | 				} else {
287 | 					$image = false;
288 | 				}
289 | 
290 | 				$result[] = array(
291 | 					'category_id'   => $category['category_id'],
292 | 					'parent_id'     => $category['parent_id'],
293 | 					'name'          => $category['name'],
294 | 					'image'         => $image,
295 | 					'href'          => $this->url->link('product/category', 'category_id=' . $category['category_id']),
296 | 					'categories'    => $this->getCategoriesTree($category['category_id'], $level)
297 | 				);
298 | 			}
299 | 
300 | 			return $result;
301 | 		}
302 | 	}
303 | 
304 | 	/**
305 | 	 * 
306 | 	 */
307 | 	private function init() {
308 | 
309 | 		$this->response->addHeader('Content-Type: application/json');
310 | 
311 | 		if (!$this->config->get('web_api_status')) {
312 | 			$this->error(10, 'API is disabled');
313 | 		}
314 | 
315 | 		if ($this->config->get('web_api_key') && (!isset($this->request->get['key']) || $this->request->get['key'] != $this->config->get('web_api_key'))) {
316 | 			$this->error(20, 'Invalid secret key');
317 | 		}
318 | 	}
319 | 
320 | 	/**
321 | 	 * Error message responser
322 | 	 *
323 | 	 * @param string $message  Error message
324 | 	 */
325 | 	private function error($code = 0, $message = '') {
326 | 
327 | 		# setOutput() is not called, set headers manually
328 | 		header('Content-Type: application/json');
329 | 
330 | 		$json = array(
331 | 			'success'       => false,
332 | 			'code'          => $code,
333 | 			'message'       => $message
334 | 		);
335 | 
336 | 		if ($this->debug) {
337 | 			echo '
';
338 | 			print_r($json);
339 | 		} else {
340 | 			echo json_encode($json);
341 | 		}
342 | 		
343 | 		exit();
344 | 	}
345 | 
346 | }
347 | 


--------------------------------------------------------------------------------