PageRenderTime 71ms CodeModel.GetById 12ms app.highlight 50ms RepoModel.GetById 0ms app.codeStats 1ms

/controllers/admin/AdminShopController.php

https://gitlab.com/staging06/myproject
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}