/controllers/admin/AdminShopController.php
PHP | 865 lines | 668 code | 101 blank | 96 comment | 114 complexity | 5d4426de3c249b660475b3ff6ad28db9 MD5 | raw file
1<?php
2/*
3* 2007-2015 PrestaShop
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@prestashop.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 PrestaShop to newer
18* versions in the future. If you wish to customize PrestaShop for your
19* needs please refer to http://www.prestashop.com for more information.
20*
21* @author PrestaShop SA <contact@prestashop.com>
22* @copyright 2007-2015 PrestaShop SA
23* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
24* International Registered Trademark & Property of PrestaShop SA
25*/
26
27/**
28 * @property Shop $object
29 */
30class AdminShopControllerCore extends AdminController
31{
32 public function __construct()
33 {
34 $this->bootstrap = true;
35 $this->context = Context::getContext();
36 $this->table = 'shop';
37 $this->className = 'Shop';
38 $this->multishop_context = Shop::CONTEXT_ALL;
39
40 $this->id_shop_group = (int)Tools::getValue('id_shop_group');
41
42 /* if $_GET['id_shop'] is transmitted, virtual url can be loaded in config.php, so we wether transmit shop_id in herfs */
43 if ($this->id_shop = (int)Tools::getValue('shop_id')) {
44 $_GET['id_shop'] = $this->id_shop;
45 }
46
47 $this->list_skip_actions['delete'] = array((int)Configuration::get('PS_SHOP_DEFAULT'));
48 $this->fields_list = array(
49 'id_shop' => array(
50 'title' => $this->l('Shop ID'),
51 'align' => 'center',
52 'class' => 'fixed-width-xs'
53 ),
54 'name' => array(
55 'title' => $this->l('Shop name'),
56 'filter_key' => 'a!name',
57 'width' => 200,
58 ),
59 'shop_group_name' => array(
60 'title' => $this->l('Shop group'),
61 'width' => 150,
62 'filter_key' => 'gs!name'
63 ),
64 'category_name' => array(
65 'title' => $this->l('Root category'),
66 'width' => 150,
67 'filter_key' => 'cl!name'
68 ),
69 'url' => array(
70 'title' => $this->l('Main URL for this shop'),
71 'havingFilter' => 'url',
72 ),
73 /*'active' => array(
74 'title' => $this->l('Enabled'),
75 'align' => 'center',
76 'active' => 'status',
77 'type' => 'bool',
78 'orderby' => false,
79 'filter_key' => 'active',
80 'width' => 50,
81 )*/
82 );
83
84 parent::__construct();
85 }
86
87 public function viewAccess($disable = false)
88 {
89 return Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE');
90 }
91
92 public function initPageHeaderToolbar()
93 {
94 parent::initPageHeaderToolbar();
95
96 if (!$this->display && $this->id_shop_group) {
97 if ($this->id_object) {
98 $this->loadObject();
99 }
100
101 if (!$this->id_shop_group && $this->object && $this->object->id_shop_group) {
102 $this->id_shop_group = $this->object->id_shop_group;
103 }
104
105 $this->page_header_toolbar_btn['edit'] = array(
106 'desc' => $this->l('Edit this shop group'),
107 'href' => $this->context->link->getAdminLink('AdminShopGroup').'&updateshop_group&id_shop_group='
108 .$this->id_shop_group,
109 );
110
111 $this->page_header_toolbar_btn['new'] = array(
112 'desc' => $this->l('Add new shop'),
113 'href' => $this->context->link->getAdminLink('AdminShop').'&add'.$this->table.'&id_shop_group='
114 .$this->id_shop_group,
115 );
116 }
117 }
118
119 public function initToolbar()
120 {
121 parent::initToolbar();
122
123 if ($this->display != 'edit' && $this->display != 'add') {
124 if ($this->id_object) {
125 $this->loadObject();
126 }
127
128 if (!$this->id_shop_group && $this->object && $this->object->id_shop_group) {
129 $this->id_shop_group = $this->object->id_shop_group;
130 }
131
132 $this->toolbar_btn['new'] = array(
133 'desc' => $this->l('Add new shop'),
134 'href' => $this->context->link->getAdminLink('AdminShop').'&add'.$this->table.'&id_shop_group='
135 .$this->id_shop_group,
136 );
137 }
138 }
139
140 public function initContent()
141 {
142 parent::initContent();
143
144 $this->addJqueryPlugin('cooki-plugin');
145 $data = Shop::getTree();
146
147 foreach ($data as $key_group => &$group) {
148 foreach ($group['shops'] as $key_shop => &$shop) {
149 $current_shop = new Shop($shop['id_shop']);
150 $urls = $current_shop->getUrls();
151
152 foreach ($urls as $key_url => &$url) {
153 $title = $url['domain'].$url['physical_uri'].$url['virtual_uri'];
154 if (strlen($title) > 23) {
155 $title = substr($title, 0, 23).'...';
156 }
157
158 $url['name'] = $title;
159 $shop['urls'][$url['id_shop_url']] = $url;
160 }
161 }
162 }
163
164 $shops_tree = new HelperTreeShops('shops-tree', $this->l('Multistore tree'));
165 $shops_tree->setNodeFolderTemplate('shop_tree_node_folder.tpl')->setNodeItemTemplate('shop_tree_node_item.tpl')
166 ->setHeaderTemplate('shop_tree_header.tpl')->setActions(array(
167 new TreeToolbarLink(
168 'Collapse All',
169 '#',
170 '$(\'#'.$shops_tree->getId().'\').tree(\'collapseAll\'); return false;',
171 'icon-collapse-alt'),
172 new TreeToolbarLink(
173 'Expand All',
174 '#',
175 '$(\'#'.$shops_tree->getId().'\').tree(\'expandAll\'); return false;',
176 'icon-expand-alt')
177 ))
178 ->setAttribute('url_shop_group', $this->context->link->getAdminLink('AdminShopGroup'))
179 ->setAttribute('url_shop', $this->context->link->getAdminLink('AdminShop'))
180 ->setAttribute('url_shop_url', $this->context->link->getAdminLink('AdminShopUrl'))
181 ->setData($data);
182 $shops_tree = $shops_tree->render(null, false, false);
183
184 if ($this->display == 'edit') {
185 $this->toolbar_title[] = $this->object->name;
186 } elseif (!$this->display && $this->id_shop_group) {
187 $group = new ShopGroup($this->id_shop_group);
188 $this->toolbar_title[] = $group->name;
189 }
190
191 $this->context->smarty->assign(array(
192 'toolbar_scroll' => 1,
193 'toolbar_btn' => $this->toolbar_btn,
194 'title' => $this->toolbar_title,
195 'shops_tree' => $shops_tree
196 ));
197 }
198
199 public function renderList()
200 {
201 $this->addRowAction('edit');
202 $this->addRowAction('delete');
203
204 $this->_select = 'gs.name shop_group_name, cl.name category_name, CONCAT(\'http://\', su.domain, su.physical_uri, su.virtual_uri) AS url';
205 $this->_join = '
206 LEFT JOIN `'._DB_PREFIX_.'shop_group` gs
207 ON (a.id_shop_group = gs.id_shop_group)
208 LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
209 ON (a.id_category = cl.id_category AND cl.id_lang='.(int)$this->context->language->id.')
210 LEFT JOIN '._DB_PREFIX_.'shop_url su
211 ON a.id_shop = su.id_shop AND su.main = 1
212 ';
213 $this->_group = 'GROUP BY a.id_shop';
214
215 if ($id_shop_group = (int)Tools::getValue('id_shop_group')) {
216 $this->_where = 'AND a.id_shop_group = '.$id_shop_group;
217 }
218
219 return parent::renderList();
220 }
221
222 public function displayAjaxGetCategoriesFromRootCategory()
223 {
224 if (Tools::isSubmit('id_category')) {
225 $selected_cat = array((int)Tools::getValue('id_category'));
226 $children = Category::getChildren((int)Tools::getValue('id_category'), $this->context->language->id);
227 foreach ($children as $child) {
228 $selected_cat[] = $child['id_category'];
229 }
230
231 $helper = new HelperTreeCategories('categories-tree', null, (int)Tools::getValue('id_category'), null, false);
232 $this->content = $helper->setSelectedCategories($selected_cat)->setUseSearch(true)->setUseCheckBox(true)
233 ->render();
234 }
235 parent::displayAjax();
236 }
237
238 public function postProcess()
239 {
240 if (Tools::isSubmit('id_category_default')) {
241 $_POST['id_category'] = Tools::getValue('id_category_default');
242 }
243 /*if ((Tools::isSubmit('status') ||
244 Tools::isSubmit('status'.$this->table) ||
245 (Tools::isSubmit('submitAdd'.$this->table) && Tools::getValue($this->identifier) && !Tools::getValue('active'))) &&
246 $this->loadObject() && $this->loadObject()->active)
247 {
248 if (Tools::getValue('id_shop') == Configuration::get('PS_SHOP_DEFAULT'))
249 $this->errors[] = Tools::displayError('You cannot disable the default shop.');
250 elseif (Shop::getTotalShops() == 1)
251 $this->errors[] = Tools::displayError('You cannot disable the last shop.');
252 }*/
253
254 if (Tools::isSubmit('submitAddshopAndStay') || Tools::isSubmit('submitAddshop')) {
255 $shop_group = new ShopGroup((int)Tools::getValue('id_shop_group'));
256 if ($shop_group->shopNameExists(Tools::getValue('name'), (int)Tools::getValue('id_shop'))) {
257 $this->errors[] = Tools::displayError('You cannot have two shops with the same name in the same group.');
258 }
259 }
260
261 if (count($this->errors)) {
262 return false;
263 }
264
265 /** @var Shop|bool $result */
266 $result = parent::postProcess();
267
268 if ($result != false && (Tools::isSubmit('submitAddshopAndStay') || Tools::isSubmit('submitAddshop')) && (int)$result->id_category != (int)Configuration::get('PS_HOME_CATEGORY', null, null, (int)$result->id)) {
269 Configuration::updateValue('PS_HOME_CATEGORY', (int)$result->id_category, false, null, (int)$result->id);
270 }
271
272 if ($this->redirect_after) {
273 $this->redirect_after .= '&id_shop_group='.$this->id_shop_group;
274 }
275
276 return $result;
277 }
278
279 public function processDelete()
280 {
281 if (!Validate::isLoadedObject($object = $this->loadObject())) {
282 $this->errors[] = Tools::displayError('Unable to load this shop.');
283 } elseif (!Shop::hasDependency($object->id)) {
284 $result = Category::deleteCategoriesFromShop($object->id) && parent::processDelete();
285 Tools::generateHtaccess();
286 return $result;
287 } else {
288 $this->errors[] = Tools::displayError('You can\'t delete this shop (customer and/or order dependency).');
289 }
290
291 return false;
292 }
293
294 /**
295 * @param Shop $new_shop
296 * @return bool
297 */
298 protected function afterAdd($new_shop)
299 {
300 $import_data = Tools::getValue('importData', array());
301
302 // The root category should be at least imported
303 $new_shop->copyShopData((int)Tools::getValue('importFromShop'), $import_data);
304
305 // copy default data
306 if (!Tools::getValue('useImportData') || (is_array($import_data) && !isset($import_data['group']))) {
307 $sql = 'INSERT INTO `'._DB_PREFIX_.'group_shop` (`id_shop`, `id_group`)
308 VALUES
309 ('.(int)$new_shop->id.', '.(int)Configuration::get('PS_UNIDENTIFIED_GROUP').'),
310 ('.(int)$new_shop->id.', '.(int)Configuration::get('PS_GUEST_GROUP').'),
311 ('.(int)$new_shop->id.', '.(int)Configuration::get('PS_CUSTOMER_GROUP').')
312 ';
313 Db::getInstance()->execute($sql);
314 }
315
316 return parent::afterAdd($new_shop);
317 }
318
319 /**
320 * @param Shop $new_shop
321 * @return bool
322 */
323 protected function afterUpdate($new_shop)
324 {
325 $categories = Tools::getValue('categoryBox');
326
327 if (!is_array($categories)) {
328 $this->errors[] = $this->l('Please create some sub-categories for this root category.');
329 return false;
330 }
331
332 array_unshift($categories, Configuration::get('PS_ROOT_CATEGORY'));
333
334 if (!Category::updateFromShop($categories, $new_shop->id)) {
335 $this->errors[] = $this->l('You need to select at least the root category.');
336 }
337 if (Tools::getValue('useImportData') && ($import_data = Tools::getValue('importData')) && is_array($import_data)) {
338 $new_shop->copyShopData((int)Tools::getValue('importFromShop'), $import_data);
339 }
340
341 if (Tools::isSubmit('submitAddshopAndStay') || Tools::isSubmit('submitAddshop')) {
342 $this->redirect_after = self::$currentIndex.'&shop_id='.(int)$new_shop->id.'&conf=4&token='.$this->token;
343 }
344
345 return parent::afterUpdate($new_shop);
346 }
347
348 public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
349 {
350 if (Shop::getContext() == Shop::CONTEXT_GROUP) {
351 $this->_where .= ' AND a.id_shop_group = '.(int)Shop::getContextShopGroupID();
352 }
353
354 parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
355 $shop_delete_list = array();
356
357 // don't allow to remove shop which have dependencies (customers / orders / ... )
358 foreach ($this->_list as &$shop) {
359 if (Shop::hasDependency($shop['id_shop'])) {
360 $shop_delete_list[] = $shop['id_shop'];
361 }
362 }
363 $this->context->smarty->assign('shops_having_dependencies', $shop_delete_list);
364 }
365
366 public function renderForm()
367 {
368 /** @var Shop $obj */
369 if (!($obj = $this->loadObject(true))) {
370 return;
371 }
372
373 $this->fields_form = array(
374 'legend' => array(
375 'title' => $this->l('Shop'),
376 'icon' => 'icon-shopping-cart'
377 ),
378 'identifier' => 'shop_id',
379 'input' => array(
380 array(
381 'type' => 'text',
382 'label' => $this->l('Shop name'),
383 'desc' => array($this->l('This field does not refer to the shop name visible in the front office.'),
384 sprintf($this->l('Follow %sthis link%s to edit the shop name used on the front office.'), '<a href="'.$this->context->link->getAdminLink('AdminStores').'#store_fieldset_general">', '</a>')),
385 'name' => 'name',
386 'required' => true,
387 )
388 )
389 );
390
391 $display_group_list = true;
392 if ($this->display == 'edit') {
393 $group = new ShopGroup($obj->id_shop_group);
394 if ($group->share_customer || $group->share_order || $group->share_stock) {
395 $display_group_list = false;
396 }
397 }
398
399 if ($display_group_list) {
400 $options = array();
401 foreach (ShopGroup::getShopGroups() as $group) {
402 /** @var ShopGroup $group */
403 if ($this->display == 'edit' && ($group->share_customer || $group->share_order || $group->share_stock) && ShopGroup::hasDependency($group->id)) {
404 continue;
405 }
406
407 $options[] = array(
408 'id_shop_group' => $group->id,
409 'name' => $group->name,
410 );
411 }
412
413 if ($this->display == 'add') {
414 $group_desc = $this->l('Warning: You won\'t be able to change the group of this shop if this shop belongs to a group with one of these options activated: Share Customers, Share Quantities or Share Orders.');
415 } else {
416 $group_desc = $this->l('You can only move your shop to a shop group with all "share" options disabled -- or to a shop group with no customers/orders.');
417 }
418
419 $this->fields_form['input'][] = array(
420 'type' => 'select',
421 'label' => $this->l('Shop group'),
422 'desc' => $group_desc,
423 'name' => 'id_shop_group',
424 'options' => array(
425 'query' => $options,
426 'id' => 'id_shop_group',
427 'name' => 'name',
428 ),
429 );
430 } else {
431 $this->fields_form['input'][] = array(
432 'type' => 'hidden',
433 'name' => 'id_shop_group',
434 'default' => $group->name
435 );
436 $this->fields_form['input'][] = array(
437 'type' => 'textShopGroup',
438 'label' => $this->l('Shop group'),
439 'desc' => $this->l('You can\'t edit the shop group because the current shop belongs to a group with the "share" option enabled.'),
440 'name' => 'id_shop_group',
441 'value' => $group->name
442 );
443 }
444
445 $categories = Category::getRootCategories($this->context->language->id);
446 $this->fields_form['input'][] = array(
447 'type' => 'select',
448 'label' => $this->l('Category root'),
449 'desc' => sprintf($this->l('This is the root category of the store that you\'ve created. To define a new root category for your store, %splease click here%s.'), '<a href="'.$this->context->link->getAdminLink('AdminCategories').'&addcategoryroot" target="_blank">', '</a>'),
450 'name' => 'id_category',
451 'options' => array(
452 'query' => $categories,
453 'id' => 'id_category',
454 'name' => 'name'
455 )
456 );
457
458 if (Tools::isSubmit('id_shop')) {
459 $shop = new Shop((int)Tools::getValue('id_shop'));
460 $id_root = $shop->id_category;
461 } else {
462 $id_root = $categories[0]['id_category'];
463 }
464
465
466 $id_shop = (int)Tools::getValue('id_shop');
467 self::$currentIndex = self::$currentIndex.'&id_shop_group='.(int)(Tools::getValue('id_shop_group') ?
468 Tools::getValue('id_shop_group') : (isset($obj->id_shop_group) ? $obj->id_shop_group : Shop::getContextShopGroupID()));
469 $shop = new Shop($id_shop);
470 $selected_cat = Shop::getCategories($id_shop);
471
472 if (empty($selected_cat)) {
473 // get first category root and preselect all these children
474 $root_categories = Category::getRootCategories();
475 $root_category = new Category($root_categories[0]['id_category']);
476 $children = $root_category->getAllChildren($this->context->language->id);
477 $selected_cat[] = $root_categories[0]['id_category'];
478
479 foreach ($children as $child) {
480 $selected_cat[] = $child->id;
481 }
482 }
483
484 if (Shop::getContext() == Shop::CONTEXT_SHOP && Tools::isSubmit('id_shop')) {
485 $root_category = new Category($shop->id_category);
486 } else {
487 $root_category = new Category($id_root);
488 }
489
490 $this->fields_form['input'][] = array(
491 'type' => 'categories',
492 'name' => 'categoryBox',
493 'label' => $this->l('Associated categories'),
494 'tree' => array(
495 'id' => 'categories-tree',
496 'selected_categories' => $selected_cat,
497 'root_category' => $root_category->id,
498 'use_search' => true,
499 'use_checkbox' => true
500 ),
501 'desc' => $this->l('By selecting associated categories, you are choosing to share the categories between shops. Once associated between shops, any alteration of this category will impact every shop.')
502 );
503 /*$this->fields_form['input'][] = array(
504 'type' => 'switch',
505 'label' => $this->l('Enabled'),
506 'name' => 'active',
507 'required' => true,
508 'is_bool' => true,
509 'values' => array(
510 array(
511 'id' => 'active_on',
512 'value' => 1
513 ),
514 array(
515 'id' => 'active_off',
516 'value' => 0
517 )
518 ),
519 'desc' => $this->l('Enable or disable your store?')
520 );*/
521
522 $themes = Theme::getThemes();
523 if (!isset($obj->id_theme)) {
524 foreach ($themes as $theme) {
525 if (isset($theme->id)) {
526 $id_theme = $theme->id;
527 break;
528 }
529 }
530 }
531
532 $this->fields_form['input'][] = array(
533 'type' => 'theme',
534 'label' => $this->l('Theme'),
535 'name' => 'theme',
536 'values' => $themes
537 );
538
539 $this->fields_form['submit'] = array(
540 'title' => $this->l('Save'),
541 );
542
543 if (Shop::getTotalShops() > 1 && $obj->id) {
544 $disabled = array('active' => false);
545 } else {
546 $disabled = false;
547 }
548
549 $import_data = array(
550 'carrier' => $this->l('Carriers'),
551 'cms' => $this->l('CMS pages'),
552 'contact' => $this->l('Contact information'),
553 'country' => $this->l('Countries'),
554 'currency' => $this->l('Currencies'),
555 'discount' => $this->l('Discount prices'),
556 'employee' => $this->l('Employees'),
557 'image' => $this->l('Images'),
558 'lang' => $this->l('Languages'),
559 'manufacturer' => $this->l('Manufacturers'),
560 'module' => $this->l('Modules'),
561 'hook_module' => $this->l('Module hooks'),
562 'meta_lang' => $this->l('Meta information'),
563 'product' => $this->l('Products'),
564 'product_attribute' => $this->l('Product combinations'),
565 'scene' => $this->l('Scenes'),
566 'stock_available' => $this->l('Available quantities for sale'),
567 'store' => $this->l('Stores'),
568 'warehouse' => $this->l('Warehouses'),
569 'webservice_account' => $this->l('Webservice accounts'),
570 'attribute_group' => $this->l('Attribute groups'),
571 'feature' => $this->l('Features'),
572 'group' => $this->l('Customer groups'),
573 'tax_rules_group' => $this->l('Tax rules groups'),
574 'supplier' => $this->l('Suppliers'),
575 'referrer' => $this->l('Referrers/affiliates'),
576 'zone' => $this->l('Zones'),
577 'cart_rule' => $this->l('Cart rules'),
578 );
579
580 // Hook for duplication of shop data
581 $modules_list = Hook::getHookModuleExecList('actionShopDataDuplication');
582 if (is_array($modules_list) && count($modules_list) > 0) {
583 foreach ($modules_list as $m) {
584 $import_data['Module'.ucfirst($m['module'])] = Module::getModuleName($m['module']);
585 }
586 }
587
588 asort($import_data);
589
590 if (!$this->object->id) {
591 $this->fields_import_form = array(
592 'radio' => array(
593 'type' => 'radio',
594 'label' => $this->l('Import data'),
595 'name' => 'useImportData',
596 'value' => 1
597 ),
598 'select' => array(
599 'type' => 'select',
600 'name' => 'importFromShop',
601 'label' => $this->l('Choose the source shop'),
602 'options' => array(
603 'query' => Shop::getShops(false),
604 'name' => 'name'
605 )
606 ),
607 'allcheckbox' => array(
608 'type' => 'checkbox',
609 'label' => $this->l('Choose data to import'),
610 'values' => $import_data
611 ),
612 'desc' => $this->l('Use this option to associate data (products, modules, etc.) the same way for each selected shop.')
613 );
614 }
615
616 $this->fields_value = array(
617 'id_shop_group' => (Tools::getValue('id_shop_group') ? Tools::getValue('id_shop_group') :
618 (isset($obj->id_shop_group)) ? $obj->id_shop_group : Shop::getContextShopGroupID()),
619 'id_category' => (Tools::getValue('id_category') ? Tools::getValue('id_category') :
620 (isset($obj->id_category)) ? $obj->id_category : (int)Configuration::get('PS_HOME_CATEGORY')),
621 'id_theme_checked' => (isset($obj->id_theme) ? $obj->id_theme : $id_theme)
622 );
623
624 $ids_category = array();
625 $shops = Shop::getShops(false);
626 foreach ($shops as $shop) {
627 $ids_category[$shop['id_shop']] = $shop['id_category'];
628 }
629
630 $this->tpl_form_vars = array(
631 'disabled' => $disabled,
632 'checked' => (Tools::getValue('addshop') !== false) ? true : false,
633 'defaultShop' => (int)Configuration::get('PS_SHOP_DEFAULT'),
634 'ids_category' => $ids_category,
635 );
636 if (isset($this->fields_import_form)) {
637 $this->tpl_form_vars = array_merge($this->tpl_form_vars, array('form_import' => $this->fields_import_form));
638 }
639
640 return parent::renderForm();
641 }
642
643
644 /**
645 * Object creation
646 */
647 public function processAdd()
648 {
649 if (!Tools::getValue('categoryBox') || !in_array(Tools::getValue('id_category'), Tools::getValue('categoryBox'))) {
650 $this->errors[] = $this->l('You need to select at least the root category.');
651 }
652
653 if (Tools::isSubmit('id_category_default')) {
654 $_POST['id_category'] = (int)Tools::getValue('id_category_default');
655 }
656
657 /* Checking fields validity */
658 $this->validateRules();
659
660 if (!count($this->errors)) {
661 /** @var Shop $object */
662 $object = new $this->className();
663 $this->copyFromPost($object, $this->table);
664 $this->beforeAdd($object);
665 if (!$object->add()) {
666 $this->errors[] = Tools::displayError('An error occurred while creating an object.').
667 ' <b>'.$this->table.' ('.Db::getInstance()->getMsgError().')</b>';
668 }
669 /* voluntary do affectation here */
670 elseif (($_POST[$this->identifier] = $object->id) && $this->postImage($object->id) && !count($this->errors) && $this->_redirect) {
671 $parent_id = (int)Tools::getValue('id_parent', 1);
672 $this->afterAdd($object);
673 $this->updateAssoShop($object->id);
674 // Save and stay on same form
675 if (Tools::isSubmit('submitAdd'.$this->table.'AndStay')) {
676 $this->redirect_after = self::$currentIndex.'&shop_id='.(int)$object->id.'&conf=3&update'.$this->table.'&token='.$this->token;
677 }
678 // Save and back to parent
679 if (Tools::isSubmit('submitAdd'.$this->table.'AndBackToParent')) {
680 $this->redirect_after = self::$currentIndex.'&shop_id='.(int)$parent_id.'&conf=3&token='.$this->token;
681 }
682 // Default behavior (save and back)
683 if (empty($this->redirect_after)) {
684 $this->redirect_after = self::$currentIndex.($parent_id ? '&shop_id='.$object->id : '').'&conf=3&token='.$this->token;
685 }
686 }
687 }
688
689 $this->errors = array_unique($this->errors);
690 if (count($this->errors) > 0) {
691 $this->display = 'add';
692 return;
693 }
694
695 $object->associateSuperAdmins();
696
697 $categories = Tools::getValue('categoryBox');
698 array_unshift($categories, Configuration::get('PS_ROOT_CATEGORY'));
699 Category::updateFromShop($categories, $object->id);
700 if (Tools::getValue('useImportData') && ($import_data = Tools::getValue('importData')) && is_array($import_data) && isset($import_data['product'])) {
701 ini_set('max_execution_time', 7200); // like searchcron.php
702 Search::indexation(true);
703 }
704 return $object;
705 }
706
707 public function displayEditLink($token = null, $id, $name = null)
708 {
709 if ($this->tabAccess['edit'] == 1) {
710 $tpl = $this->createTemplate('helpers/list/list_action_edit.tpl');
711 if (!array_key_exists('Edit', self::$cache_lang)) {
712 self::$cache_lang['Edit'] = $this->l('Edit', 'Helper');
713 }
714
715 $tpl->assign(array(
716 'href' => $this->context->link->getAdminLink('AdminShop').'&shop_id='.(int)$id.'&update'.$this->table,
717 'action' => self::$cache_lang['Edit'],
718 'id' => $id
719 ));
720
721 return $tpl->fetch();
722 } else {
723 return;
724 }
725 }
726
727 public function initCategoriesAssociation($id_root = null)
728 {
729 if (is_null($id_root)) {
730 $id_root = Configuration::get('PS_ROOT_CATEGORY');
731 }
732 $id_shop = (int)Tools::getValue('id_shop');
733 $shop = new Shop($id_shop);
734 $selected_cat = Shop::getCategories($id_shop);
735 if (empty($selected_cat)) {
736 // get first category root and preselect all these children
737 $root_categories = Category::getRootCategories();
738 $root_category = new Category($root_categories[0]['id_category']);
739 $children = $root_category->getAllChildren($this->context->language->id);
740 $selected_cat[] = $root_categories[0]['id_category'];
741
742 foreach ($children as $child) {
743 $selected_cat[] = $child->id;
744 }
745 }
746 if (Shop::getContext() == Shop::CONTEXT_SHOP && Tools::isSubmit('id_shop')) {
747 $root_category = new Category($shop->id_category);
748 } else {
749 $root_category = new Category($id_root);
750 }
751 $root_category = array('id_category' => $root_category->id, 'name' => $root_category->name[$this->context->language->id]);
752
753 $helper = new Helper();
754 return $helper->renderCategoryTree($root_category, $selected_cat, 'categoryBox', false, true);
755 }
756
757 public function ajaxProcessTree()
758 {
759 $tree = array();
760 $sql = 'SELECT g.id_shop_group, g.name as group_name, s.id_shop, s.name as shop_name, u.id_shop_url, u.domain, u.physical_uri, u.virtual_uri
761 FROM '._DB_PREFIX_.'shop_group g
762 LEFT JOIN '._DB_PREFIX_.'shop s ON g.id_shop_group = s.id_shop_group
763 LEFT JOIN '._DB_PREFIX_.'shop_url u ON u.id_shop = s.id_shop
764 ORDER BY g.name, s.name, u.domain';
765 $results = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);
766 foreach ($results as $row) {
767 $id_shop_group = $row['id_shop_group'];
768 $id_shop = $row['id_shop'];
769 $id_shop_url = $row['id_shop_url'];
770
771 // Group list
772 if (!isset($tree[$id_shop_group])) {
773 $tree[$id_shop_group] = array(
774 'data' => array(
775 'title' => '<b>'.$this->l('Group').'</b> '.$row['group_name'],
776 'icon' => 'themes/'.$this->context->employee->bo_theme.'/img/tree-multishop-groups.png',
777 'attr' => array(
778 'href' => $this->context->link->getAdminLink('AdminShop').'&id_shop_group='.$id_shop_group,
779 'title' => sprintf($this->l('Click here to display the shops in the %s shop group', 'AdminShop', false, false), $row['group_name']),
780 ),
781 ),
782 'attr' => array(
783 'id' => 'tree-group-'.$id_shop_group,
784 ),
785 'children' => array(),
786 );
787 }
788
789 // Shop list
790 if (!$id_shop) {
791 continue;
792 }
793
794 if (!isset($tree[$id_shop_group]['children'][$id_shop])) {
795 $tree[$id_shop_group]['children'][$id_shop] = array(
796 'data' => array(
797 'title' => $row['shop_name'],
798 'icon' => 'themes/'.$this->context->employee->bo_theme.'/img/tree-multishop-shop.png',
799 'attr' => array(
800 'href' => $this->context->link->getAdminLink('AdminShopUrl').'&shop_id='.(int)$id_shop,
801 'title' => sprintf($this->l('Click here to display the URLs of the %s shop', 'AdminShop', false, false), $row['shop_name']),
802 )
803 ),
804 'attr' => array(
805 'id' => 'tree-shop-'.$id_shop,
806 ),
807 'children' => array(),
808 );
809 }
810 // Url list
811 if (!$id_shop_url) {
812 continue;
813 }
814
815 if (!isset($tree[$id_shop_group]['children'][$id_shop]['children'][$id_shop_url])) {
816 $url = $row['domain'].$row['physical_uri'].$row['virtual_uri'];
817 if (strlen($url) > 23) {
818 $url = substr($url, 0, 23).'...';
819 }
820
821 $tree[$id_shop_group]['children'][$id_shop]['children'][$id_shop_url] = array(
822 'data' => array(
823 'title' => $url,
824 'icon' => 'themes/'.$this->context->employee->bo_theme.'/img/tree-multishop-url.png',
825 'attr' => array(
826 'href' => $this->context->link->getAdminLink('AdminShopUrl').'&updateshop_url&id_shop_url='.$id_shop_url,
827 'title' => $row['domain'].$row['physical_uri'].$row['virtual_uri'],
828 )
829 ),
830 'attr' => array(
831 'id' => 'tree-url-'.$id_shop_url,
832 ),
833 );
834 }
835 }
836
837 // jstree need to have children as array and not object, so we use sort to get clean keys
838 // DO NOT REMOVE this code, even if it seems really strange ;)
839 sort($tree);
840 foreach ($tree as &$groups) {
841 sort($groups['children']);
842 foreach ($groups['children'] as &$shops) {
843 sort($shops['children']);
844 }
845 }
846
847 $tree = array(array(
848 'data' => array(
849 'title' => '<b>'.$this->l('Shop groups list').'</b>',
850 'icon' => 'themes/'.$this->context->employee->bo_theme.'/img/tree-multishop-root.png',
851 'attr' => array(
852 'href' => $this->context->link->getAdminLink('AdminShopGroup'),
853 'title' => $this->l('Click here to display the list of shop groups', 'AdminShop', false, false),
854 )
855 ),
856 'attr' => array(
857 'id' => 'tree-root',
858 ),
859 'state' => 'open',
860 'children' => $tree,
861 ));
862
863 die(Tools::jsonEncode($tree));
864 }
865}