1<?php
2/**
3 * 2007-2016 PrestaShop
4 *
5 * thirty bees is an extension to the PrestaShop e-commerce software developed by PrestaShop SA
6 * Copyright (C) 2017-2018 thirty bees
7 *
8 * NOTICE OF LICENSE
9 *
10 * This source file is subject to the Open Software License (OSL 3.0)
11 * that is bundled with this package in the file LICENSE.txt.
12 * It is also available through the world-wide-web at this URL:
13 * http://opensource.org/licenses/osl-3.0.php
14 * If you did not receive a copy of the license and are unable to
15 * obtain it through the world-wide-web, please send an email
16 * to license@thirtybees.com so we can send you a copy immediately.
17 *
18 * DISCLAIMER
19 *
20 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
21 * versions in the future. If you wish to customize PrestaShop for your
22 * needs please refer to https://www.thirtybees.com for more information.
23 *
24 * @author    thirty bees <contact@thirtybees.com>
25 * @author    PrestaShop SA <contact@prestashop.com>
26 * @copyright 2017-2018 thirty bees
27 * @copyright 2007-2016 PrestaShop SA
28 * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
29 *  PrestaShop is an internationally registered trademark & property of PrestaShop SA
30 */
31
32/**
33 * Class AdminSearchControllerCore
34 *
35 * @since 1.0.0
36 */
37class AdminSearchControllerCore extends AdminController
38{
39    /**
40     * AdminSearchControllerCore constructor.
41     *
42     * @since 1.0.0
43     */
44    public function __construct()
45    {
46        $this->bootstrap = true;
47        parent::__construct();
48    }
49
50    /**
51     * Post processing
52     *
53     * @return void
54     *
55     * @since 1.0.0
56     */
57    public function postProcess()
58    {
59        $this->query = trim(Tools::getValue('bo_query'));
60        $searchType = (int) Tools::getValue('bo_search_type');
61        /* Handle empty search field */
62        if (!empty($this->query)) {
63            if (!$searchType && strlen($this->query) > 1) {
64                $this->searchFeatures();
65            }
66
67            /* Product research */
68            if (!$searchType || $searchType == 1) {
69                /* Handle product ID */
70                if ($searchType == 1 && (int) $this->query && Validate::isUnsignedInt((int) $this->query)) {
71                    if (($product = new Product($this->query)) && Validate::isLoadedObject($product)) {
72                        Tools::redirectAdmin('index.php?tab=AdminProducts&id_product='.(int) ($product->id).'&token='.Tools::getAdminTokenLite('AdminProducts'));
73                    }
74                }
75
76                /* Normal catalog search */
77                $this->searchCatalog();
78            }
79
80            /* Customer */
81            if (!$searchType || $searchType == 2 || $searchType == 6) {
82                if (!$searchType || $searchType == 2) {
83                    /* Handle customer ID */
84                    if ($searchType && (int) $this->query && Validate::isUnsignedInt((int) $this->query)) {
85                        if (($customer = new Customer($this->query)) && Validate::isLoadedObject($customer)) {
86                            Tools::redirectAdmin('index.php?tab=AdminCustomers&id_customer='.(int) $customer->id.'&viewcustomer'.'&token='.Tools::getAdminToken('AdminCustomers'.(int) Tab::getIdFromClassName('AdminCustomers').(int) $this->context->employee->id));
87                        }
88                    }
89
90                    /* Normal customer search */
91                    $this->searchCustomer();
92                }
93
94                if ($searchType == 6) {
95                    $this->searchIP();
96                }
97            }
98
99            /* Order */
100            if (!$searchType || $searchType == 3) {
101                if (Validate::isUnsignedInt(trim($this->query)) && (int) $this->query && ($order = new Order((int) $this->query)) && Validate::isLoadedObject($order)) {
102                    if ($searchType == 3) {
103                        Tools::redirectAdmin('index.php?tab=AdminOrders&id_order='.(int) $order->id.'&vieworder'.'&token='.Tools::getAdminTokenLite('AdminOrders'));
104                    } else {
105                        $row = get_object_vars($order);
106                        $row['id_order'] = $row['id'];
107                        $customer = $order->getCustomer();
108                        $row['customer'] = $customer->firstname.' '.$customer->lastname;
109                        $orderState = $order->getCurrentOrderState();
110                        $row['osname'] = $orderState->name[$this->context->language->id];
111                        $this->_list['orders'] = [$row];
112                    }
113                } else {
114                    $orders = Order::getByReference($this->query);
115                    $nbOrders = count($orders);
116                    if ($nbOrders == 1 && $searchType == 3) {
117                        Tools::redirectAdmin('index.php?tab=AdminOrders&id_order='.(int) $orders[0]->id.'&vieworder'.'&token='.Tools::getAdminTokenLite('AdminOrders'));
118                    } elseif ($nbOrders) {
119                        $this->_list['orders'] = [];
120                        foreach ($orders as $order) {
121                            /** @var Order $order */
122                            $row = get_object_vars($order);
123                            $row['id_order'] = $row['id'];
124                            $customer = $order->getCustomer();
125                            $row['customer'] = $customer->firstname.' '.$customer->lastname;
126                            $orderState = $order->getCurrentOrderState();
127                            $row['osname'] = $orderState->name[$this->context->language->id];
128                            $this->_list['orders'][] = $row;
129                        }
130                    } elseif ($searchType == 3) {
131                        $this->errors[] = Tools::displayError('No order was found with this ID:').' '.Tools::htmlentitiesUTF8($this->query);
132                    }
133                }
134            }
135
136            /* Invoices */
137            if ($searchType == 4) {
138                if (Validate::isOrderInvoiceNumber($this->query) && ($invoice = OrderInvoice::getInvoiceByNumber($this->query))) {
139                    Tools::redirectAdmin($this->context->link->getAdminLink('AdminPdf').'&submitAction=generateInvoicePDF&id_order='.(int) ($invoice->id_order));
140                }
141                $this->errors[] = Tools::displayError('No invoice was found with this ID:').' '.Tools::htmlentitiesUTF8($this->query);
142            }
143
144            /* Cart */
145            if ($searchType == 5) {
146                if ((int) $this->query && Validate::isUnsignedInt((int) $this->query) && ($cart = new Cart($this->query)) && Validate::isLoadedObject($cart)) {
147                    Tools::redirectAdmin('index.php?tab=AdminCarts&id_cart='.(int) ($cart->id).'&viewcart'.'&token='.Tools::getAdminToken('AdminCarts'.(int) (Tab::getIdFromClassName('AdminCarts')).(int) $this->context->employee->id));
148                }
149                $this->errors[] = Tools::displayError('No cart was found with this ID:').' '.Tools::htmlentitiesUTF8($this->query);
150            }
151            /* IP */
152            // 6 - but it is included in the customer block
153
154            /* Module search */
155            if (!$searchType || $searchType == 7) {
156                /* Handle module name */
157                if ($searchType == 7 && Validate::isModuleName($this->query) and ($module = Module::getInstanceByName($this->query)) && Validate::isLoadedObject($module)) {
158                    Tools::redirectAdmin('index.php?tab=AdminModules&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor='.ucfirst($module->name).'&token='.Tools::getAdminTokenLite('AdminModules'));
159                }
160
161                /* Normal catalog search */
162                $this->searchModule();
163            }
164        }
165        $this->display = 'view';
166    }
167
168    /**
169     * Search a feature in all store
170     *
171     * @params string $query String to find in the catalog
172     *
173     * @return void
174     *
175     * @since 1.0.0
176     */
177    public function searchFeatures()
178    {
179        $this->_list['features'] = [];
180
181        global $_LANGADM;
182        if ($_LANGADM === null) {
183            return;
184        }
185
186        $tabs = [];
187        $keyMatch = [];
188        $result = Db::getInstance()->executeS(
189            '
190		SELECT class_name, name
191		FROM '._DB_PREFIX_.'tab t
192		INNER JOIN '._DB_PREFIX_.'tab_lang tl ON (t.id_tab = tl.id_tab AND tl.id_lang = '.(int) $this->context->employee->id_lang.')
193		LEFT JOIN '._DB_PREFIX_.'access a ON (a.id_tab = t.id_tab AND a.id_profile = '.(int) $this->context->employee->id_profile.')
194		WHERE active = 1
195		'.($this->context->employee->id_profile != 1 ? 'AND view = 1' : '').
196            (defined('_PS_HOST_MODE_') ? ' AND t.`hide_host_mode` = 0' : '')
197        );
198        foreach ($result as $row) {
199            $tabs[strtolower($row['class_name'])] = $row['name'];
200            $keyMatch[strtolower($row['class_name'])] = $row['class_name'];
201        }
202        foreach (AdminTab::$tabParenting as $key => $value) {
203            $value = stripslashes($value);
204            if (!isset($tabs[strtolower($key)]) || !isset($tabs[strtolower($value)])) {
205                continue;
206            }
207            $tabs[strtolower($key)] = $tabs[strtolower($value)];
208            $keyMatch[strtolower($key)] = $key;
209        }
210
211        $this->_list['features'] = [];
212        foreach ($_LANGADM as $key => $value) {
213            if (stripos($value, $this->query) !== false) {
214                $value = stripslashes($value);
215                $key = strtolower(substr($key, 0, -32));
216                if (in_array($key, ['AdminTab', 'index'])) {
217                    continue;
218                }
219                // if class name doesn't exists, just ignore it
220                if (!isset($tabs[$key])) {
221                    continue;
222                }
223                if (!isset($this->_list['features'][$tabs[$key]])) {
224                    $this->_list['features'][$tabs[$key]] = [];
225                }
226                $this->_list['features'][$tabs[$key]][] = ['link' => $this->context->link->getAdminLink($keyMatch[$key]), 'value' => Tools::safeOutput($value)];
227            }
228        }
229    }
230
231    /**
232     * Search a specific string in the products and categories
233     *
234     * @params string $query String to find in the catalog
235     *
236     *
237     * @return void
238     * @since 1.0.0
239     *
240     *
241     */
242    public function searchCatalog()
243    {
244        $this->_list['products'] = Product::searchByName($this->context->language->id, $this->query);
245        $this->_list['categories'] = Category::searchByName($this->context->language->id, $this->query);
246    }
247
248    /**
249     * Search a specific name in the customers
250     *
251     * @params string $query String to find in the catalog
252     *
253     * @return void
254     *
255     * @since 1.0.0
256     */
257    public function searchCustomer()
258    {
259        $this->_list['customers'] = Customer::searchByName($this->query);
260    }
261
262    /**
263     * Search by ip
264     *
265     * @return void
266     *
267     * @since 1.0.0
268     */
269    public function searchIP()
270    {
271        if (!ip2long(trim($this->query))) {
272            $this->errors[] = Tools::displayError('This is not a valid IP address:').' '.Tools::htmlentitiesUTF8($this->query);
273
274            return;
275        }
276        $this->_list['customers'] = Customer::searchByIp($this->query);
277    }
278
279    /**
280     * @return void
281     *
282     * @since 1.0.0
283     */
284    public function searchModule()
285    {
286        $this->_list['modules'] = [];
287        $allModules = Module::getModulesOnDisk(true, true, $this->context->employee->id);
288        foreach ($allModules as $module) {
289            if (stripos($module->name, $this->query) !== false || stripos($module->displayName, $this->query) !== false || stripos($module->description, $this->query) !== false) {
290                $module->linkto = 'index.php?tab=AdminModules&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor='.ucfirst($module->name).'&token='.Tools::getAdminTokenLite('AdminModules');
291                $this->_list['modules'][] = $module;
292            }
293        }
294    }
295
296    /**
297     * Set media
298     *
299     * @return void
300     *
301     * @since 1.0.0
302     */
303    public function setMedia()
304    {
305        parent::setMedia();
306        $this->addJqueryPlugin('highlight');
307    }
308
309    /**
310     * Initialize toolbar
311     *
312     * @return void
313     *
314     * @since 1.0.0
315     */
316    public function initToolbar()
317    {
318    }
319
320    /**
321     * Initialize toolbar title
322     *
323     * @return void
324     *
325     * @since 1.0.0
326     */
327    public function initToolbarTitle()
328    {
329        $this->toolbar_title = $this->l('Search results', null, null, false);
330    }
331
332    /**
333     * Render view
334     *
335     * @return string
336     *
337     * @since 1.0.0
338     */
339    public function renderView()
340    {
341        $this->tpl_view_vars['query'] = Tools::safeOutput($this->query);
342        $this->tpl_view_vars['show_toolbar'] = true;
343
344        if ($this->errors) {
345            return parent::renderView();
346        } else {
347            $nbResults = 0;
348            foreach ($this->_list as $list) {
349                if ($list != false) {
350                    $nbResults += count($list);
351                }
352            }
353            $this->tpl_view_vars['nb_results'] = $nbResults;
354
355            if (isset($this->_list['features']) && $this->_list['features']) {
356                $this->tpl_view_vars['features'] = $this->_list['features'];
357            }
358            if (isset($this->_list['categories']) && $this->_list['categories']) {
359                $categories = [];
360                foreach ($this->_list['categories'] as $category) {
361                    $categories[] = getPath($this->context->link->getAdminLink('AdminCategories', false), $category['id_category']);
362                }
363                $this->tpl_view_vars['categories'] = $categories;
364            }
365            if (isset($this->_list['products']) && $this->_list['products']) {
366                $view = '';
367                $this->initProductList();
368
369                $helper = new HelperList();
370                $helper->shopLinkType = '';
371                $helper->simple_header = true;
372                $helper->identifier = 'id_product';
373                $helper->actions = ['edit'];
374                $helper->show_toolbar = false;
375                $helper->table = 'product';
376                $helper->currentIndex = $this->context->link->getAdminLink('AdminProducts', false);
377
378                $query = trim(Tools::getValue('bo_query'));
379                $searchType = (int) Tools::getValue('bo_search_type');
380
381                if ($query) {
382                    $helper->currentIndex .= '&bo_query='.$query.'&bo_search_type='.$searchType;
383                }
384
385                $helper->token = Tools::getAdminTokenLite('AdminProducts');
386
387                if ($this->_list['products']) {
388                    $view = $helper->generateList($this->_list['products'], $this->fields_list['products']);
389                }
390
391                $this->tpl_view_vars['products'] = $view;
392            }
393            if (isset($this->_list['customers']) && $this->_list['customers']) {
394                $view = '';
395                $this->initCustomerList();
396
397                $helper = new HelperList();
398                $helper->shopLinkType = '';
399                $helper->simple_header = true;
400                $helper->identifier = 'id_customer';
401                $helper->actions = ['edit', 'view'];
402                $helper->show_toolbar = false;
403                $helper->table = 'customer';
404                $helper->currentIndex = $this->context->link->getAdminLink('AdminCustomers', false);
405                $helper->token = Tools::getAdminTokenLite('AdminCustomers');
406
407                if ($this->_list['customers']) {
408                    foreach ($this->_list['customers'] as $key => $val) {
409                        $this->_list['customers'][$key]['orders'] = Order::getCustomerNbOrders((int) $val['id_customer']);
410                    }
411                    $view = $helper->generateList($this->_list['customers'], $this->fields_list['customers']);
412                }
413                $this->tpl_view_vars['customers'] = $view;
414            }
415            if (isset($this->_list['orders']) && $this->_list['orders']) {
416                $view = '';
417                $this->initOrderList();
418
419                $helper = new HelperList();
420                $helper->shopLinkType = '';
421                $helper->simple_header = true;
422                $helper->identifier = 'id_order';
423                $helper->actions = ['view'];
424                $helper->show_toolbar = false;
425                $helper->table = 'order';
426                $helper->currentIndex = $this->context->link->getAdminLink('AdminOrders', false);
427                $helper->token = Tools::getAdminTokenLite('AdminOrders');
428
429                if ($this->_list['orders']) {
430                    $view = $helper->generateList($this->_list['orders'], $this->fields_list['orders']);
431                }
432                $this->tpl_view_vars['orders'] = $view;
433            }
434
435            if (isset($this->_list['modules']) && $this->_list['modules']) {
436                $this->tpl_view_vars['modules'] = $this->_list['modules'];
437            }
438            if (isset($this->_list['addons']) && $this->_list['addons']) {
439                $this->tpl_view_vars['addons'] = $this->_list['addons'];
440            }
441
442            return parent::renderView();
443        }
444    }
445
446    /**
447     * Extend this to remove buttons
448     *
449     * @return void
450     *
451     * @since 1.0.0
452     */
453    protected function initProductList()
454    {
455        $this->show_toolbar = false;
456        $this->fields_list['products'] = [
457            'id_product'        => ['title' => $this->l('ID'), 'width' => 25],
458            'manufacturer_name' => ['title' => $this->l('Manufacturer'), 'align' => 'center', 'width' => 200],
459            'reference'         => ['title' => $this->l('Reference'), 'align' => 'center', 'width' => 150],
460            'name'              => ['title' => $this->l('Name'), 'width' => 'auto'],
461            'price_tax_excl'    => ['title' => $this->l('Price (tax excl.)'), 'align' => 'right', 'type' => 'price', 'width' => 60],
462            'price_tax_incl'    => ['title' => $this->l('Price (tax incl.)'), 'align' => 'right', 'type' => 'price', 'width' => 60],
463            'active'            => ['title' => $this->l('Active'), 'width' => 70, 'active' => 'status', 'align' => 'center', 'type' => 'bool'],
464        ];
465    }
466
467    /**
468     * Initialize customer list
469     *
470     * @return void
471     *
472     * @since 1.0.0
473     */
474    protected function initCustomerList()
475    {
476        $gendersIcon = ['default' => 'unknown.gif'];
477        $genders = [0 => $this->l('?')];
478        foreach (Gender::getGenders() as $gender) {
479            /** @var Gender $gender */
480            $gendersIcon[$gender->id] = '../genders/'.(int) $gender->id.'.jpg';
481            $genders[$gender->id] = $gender->name;
482        }
483        $this->fields_list['customers'] = ([
484            'id_customer' => ['title' => $this->l('ID'), 'align' => 'center', 'width' => 25],
485            'id_gender'   => ['title' => $this->l('Social title'), 'align' => 'center', 'icon' => $gendersIcon, 'list' => $genders, 'width' => 25],
486            'firstname'   => ['title' => $this->l('First Name'), 'align' => 'left', 'width' => 150],
487            'lastname'    => ['title' => $this->l('Name'), 'align' => 'left', 'width' => 'auto'],
488            'email'       => ['title' => $this->l('Email address'), 'align' => 'left', 'width' => 250],
489            'birthday'    => ['title' => $this->l('Birth date'), 'align' => 'center', 'type' => 'date', 'width' => 75],
490            'date_add'    => ['title' => $this->l('Registration date'), 'align' => 'center', 'type' => 'date', 'width' => 75],
491            'orders'      => ['title' => $this->l('Orders'), 'align' => 'center', 'width' => 50],
492            'active'      => ['title' => $this->l('Enabled'), 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'width' => 25],
493        ]);
494    }
495
496    /**
497     * Initialize order list
498     *
499     * @return void
500     *
501     * @since 1.0.0
502     */
503    protected function initOrderList()
504    {
505        $this->fields_list['orders'] = [
506            'reference'           => ['title' => $this->l('Reference'), 'align' => 'center', 'width' => 65],
507            'id_order'            => ['title' => $this->l('ID'), 'align' => 'center', 'width' => 25],
508            'customer'            => ['title' => $this->l('Customer')],
509            'total_paid_tax_incl' => ['title' => $this->l('Total'), 'width' => 70, 'align' => 'right', 'type' => 'price', 'currency' => true],
510            'payment'             => ['title' => $this->l('Payment'), 'width' => 100],
511            'osname'              => ['title' => $this->l('Status'), 'width' => 280],
512            'date_add'            => ['title' => $this->l('Date'), 'width' => 130, 'align' => 'right', 'type' => 'datetime'],
513        ];
514    }
515}
516