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 AdminReferrersControllerCore
34 *
35 * @since 1.0.0
36 */
37class AdminReferrersControllerCore extends AdminController
38{
39    /**
40     * AdminReferrersControllerCore constructor.
41     *
42     * @since 1.0.0
43     */
44    public function __construct()
45    {
46        if (!defined('_PS_ADMIN_DIR_')) {
47            define('_PS_ADMIN_DIR_', getcwd().'/..');
48        }
49
50        $this->bootstrap = true;
51        $this->table = 'referrer';
52        $this->className = 'Referrer';
53        $this->fields_list = [
54            'id_referrer'         => [
55                'title' => $this->l('ID'),
56                'width' => 25,
57                'align' => 'center',
58            ],
59            'name'                => [
60                'title' => $this->l('Name'),
61                'width' => 80,
62            ],
63            'cache_visitors'      => [
64                'title' => $this->l('Visitors'),
65                'width' => 30,
66                'align' => 'center',
67            ],
68            'cache_visits'        => [
69                'title' => $this->l('Visits'),
70                'width' => 30,
71                'align' => 'center',
72            ],
73            'cache_pages'         => [
74                'title' => $this->l('Pages'),
75                'width' => 30,
76                'align' => 'center',
77            ],
78            'cache_registrations' => [
79                'title' => $this->l('Reg.'),
80                'width' => 30,
81                'align' => 'center',
82            ],
83            'cache_orders'        => [
84                'title' => $this->l('Orders'),
85                'width' => 30,
86                'align' => 'center',
87            ],
88            'cache_sales'         => [
89                'title'  => $this->l('Sales'),
90                'width'  => 80,
91                'align'  => 'right',
92                'prefix' => '<b>',
93                'suffix' => '</b>',
94                'price'  => true,
95            ],
96            'cart'                => [
97                'title'        => $this->l('Avg. cart'),
98                'width'        => 50,
99                'align'        => 'right',
100                'price'        => true,
101                'havingFilter' => true,
102            ],
103            'cache_reg_rate'      => [
104                'title' => $this->l('Reg. rate'),
105                'width' => 30,
106                'align' => 'center',
107            ],
108            'cache_order_rate'    => [
109                'title' => $this->l('Order rate'),
110                'width' => 30,
111                'align' => 'center',
112            ],
113            'fee0'                => [
114                'title'        => $this->l('Click'),
115                'width'        => 30,
116                'align'        => 'right',
117                'price'        => true,
118                'havingFilter' => true,
119            ],
120            'fee1'                => [
121                'title'        => $this->l('Base'),
122                'width'        => 30,
123                'align'        => 'right',
124                'price'        => true,
125                'havingFilter' => true,
126            ],
127            'fee2'                => [
128                'title'        => $this->l('Percent'),
129                'width'        => 30,
130                'align'        => 'right',
131                'price'        => true,
132                'havingFilter' => true,
133            ],
134        ];
135
136        $this->bulk_actions = [
137            'delete' => [
138                'text'    => $this->l('Delete selected'),
139                'confirm' => $this->l('Delete selected items?'),
140                'icon'    => 'icon-trash',
141            ],
142        ];
143
144        parent::__construct();
145    }
146
147    /**
148     * Display calendar form
149     *
150     * @param      $translations
151     * @param      $token
152     * @param null $action
153     * @param null $table
154     * @param null $identifier
155     * @param null $id
156     *
157     * @return string
158     *
159     * @since 1.0.0
160     */
161    public static function displayCalendarForm($translations, $token, $action = null, $table = null, $identifier = null, $id = null)
162    {
163        $context = Context::getContext();
164        $tpl = $context->controller->createTemplate('calendar.tpl');
165
166        $context->controller->addJqueryUI('ui.datepicker');
167
168        $tpl->assign(
169            [
170                'current'        => static::$currentIndex,
171                'token'          => $token,
172                'action'         => $action,
173                'table'          => $table,
174                'identifier'     => $identifier,
175                'id'             => $id,
176                'translations'   => $translations,
177                'datepickerFrom' => Tools::getValue('datepickerFrom', $context->employee->stats_date_from),
178                'datepickerTo'   => Tools::getValue('datepickerTo', $context->employee->stats_date_to),
179            ]
180        );
181
182        return $tpl->fetch();
183    }
184
185    /**
186     * Set media
187     *
188     * @return void
189     *
190     * @since 1.0.0
191     */
192    public function setMedia()
193    {
194        parent::setMedia();
195        $this->context->controller->addJqueryUI('ui.datepicker');
196    }
197
198    /**
199     * Initialize page header toolbar
200     *
201     * @return void
202     *
203     * @since 1.0.0
204     */
205    public function initPageHeaderToolbar()
206    {
207        if (empty($this->display)) {
208            $this->page_header_toolbar_btn['new_referrer'] = [
209                'href' => static::$currentIndex.'&addreferrer&token='.$this->token,
210                'desc' => $this->l('Add new referrer', null, null, false),
211                'icon' => 'process-icon-new',
212            ];
213        }
214
215        parent::initPageHeaderToolbar();
216    }
217
218    /**
219     * Render list
220     *
221     * @return false|string
222     *
223     * @since 1.0.0
224     */
225    public function renderList()
226    {
227        // Display list Referrers:
228        $this->addRowAction('view');
229        $this->addRowAction('edit');
230        $this->addRowAction('delete');
231
232        $this->_select = 'SUM(sa.cache_visitors) AS cache_visitors, SUM(sa.cache_visits) AS cache_visits, SUM(sa.cache_pages) AS cache_pages,
233							SUM(sa.cache_registrations) AS cache_registrations, SUM(sa.cache_orders) AS cache_orders, SUM(sa.cache_sales) AS cache_sales,
234							IF(sa.cache_orders > 0, ROUND(sa.cache_sales/sa.cache_orders, 2), 0) as cart, (sa.cache_visits*click_fee) as fee0,
235							(sa.cache_orders*base_fee) as fee1, (sa.cache_sales*percent_fee/100) as fee2';
236        $this->_join = '
237			LEFT JOIN `'._DB_PREFIX_.'referrer_shop` sa
238				ON (sa.'.$this->identifier.' = a.'.$this->identifier.' AND sa.id_shop IN ('.implode(', ', Shop::getContextListShopID()).'))';
239
240        $this->_group = 'GROUP BY sa.id_referrer';
241
242        $this->tpl_list_vars = [
243            'enable_calendar' => $this->enableCalendar(),
244            'calendar_form'   => $this->displayCalendar(),
245            'settings_form'   => $this->displaySettings(),
246        ];
247
248        return parent::renderList();
249    }
250
251    /**
252     * Enable calendar
253     *
254     * @return bool
255     *
256     * @since 1.0.0
257     */
258    protected function enableCalendar()
259    {
260        return (!Tools::isSubmit('add'.$this->table) && !Tools::isSubmit('submitAdd'.$this->table) && !Tools::isSubmit('update'.$this->table));
261    }
262
263    /**
264     * @param null $action
265     * @param null $table
266     * @param null $identifier
267     * @param null $id
268     *
269     * @return mixed
270     *
271     * @since 1.0.0
272     */
273    public function displayCalendar($action = null, $table = null, $identifier = null, $id = null)
274    {
275        return static::displayCalendarForm(
276            [
277                'Calendar' => $this->l('Calendar'),
278                'Day'      => $this->l('Today'),
279                'Month'    => $this->l('Month'),
280                'Year'     => $this->l('Year'),
281            ],
282            $this->token,
283            $action,
284            $table,
285            $identifier,
286            $id
287        );
288    }
289
290    /**
291     * Display settings
292     *
293     * @return string
294     *
295     * @since 1.0.0
296     */
297    public function displaySettings()
298    {
299        if (!Tools::isSubmit('viewreferrer')) {
300            $tpl = $this->createTemplate('form_settings.tpl');
301
302            $statsdata = Module::getInstanceByName('statsdata');
303
304            $statsdataName = false;
305            if (Validate::isLoadedObject($statsdata)) {
306                $statsdataName = $statsdata->displayName;
307            }
308            $tpl->assign(
309                [
310                    'statsdata_name' => $statsdataName,
311                    'current'        => static::$currentIndex,
312                    'token'          => $this->token,
313                    'tracking_dt'    => (int) Tools::getValue('tracking_dt', Configuration::get('TRACKING_DIRECT_TRAFFIC')),
314                ]
315            );
316
317            return $tpl->fetch();
318        }
319    }
320
321    /**
322     * Render form
323     *
324     * @return string
325     *
326     * @since 1.0.0
327     */
328    public function renderForm()
329    {
330        $uri = Tools::getHttpHost(true, true).__PS_BASE_URI__;
331
332        $this->fields_form[0] = [
333            'form' => [
334                'legend' => [
335                    'title' => $this->l('Affiliate'),
336                    'icon'  => 'icon-group',
337                ],
338                'input'  => [
339                    [
340                        'type'         => 'text',
341                        'label'        => $this->l('Name'),
342                        'name'         => 'name',
343                        'required'     => true,
344                        'autocomplete' => false,
345                    ],
346                    [
347                        'type'         => 'password',
348                        'label'        => $this->l('Password'),
349                        'name'         => 'passwd',
350                        'desc'         => $this->l('Leave blank if no change.'),
351                        'autocomplete' => false,
352                    ],
353                ],
354                'submit' => ['title' => $this->l('Save')],
355            ],
356        ];
357
358        if (Module::isInstalled('trackingfront')) {
359            $this->fields_form[0]['form']['desc'] = [
360                $this->l('Affiliates can access their data with this name and password.'),
361                $this->l('Front access:').' <a class="btn btn-link" href="'.$uri.'modules/trackingfront/stats.php" onclick="return !window.open(this.href);"><i class="icon-external-link-sign"></i> '.$uri.'modules/trackingfront/stats.php</a>',
362            ];
363        } else {
364            $this->fields_form[0]['form']['desc'] = [
365                sprintf($this->l('Please install the "%s" module in order to give your affiliates access their own statistics.'), Module::getModuleName('trackingfront')),
366            ];
367        }
368
369        $this->fields_form[1] = [
370            'form' => [
371                'legend' => [
372                    'title' => $this->l('Commission plan'),
373                    'icon'  => 'icon-dollar',
374                ],
375                'input'  => [
376                    [
377                        'type'  => 'price',
378                        'label' => $this->l('Click fee'),
379                        'name'  => 'click_fee',
380                        'desc'  => $this->l('Fee given for each visit.'),
381                    ],
382                    [
383                        'type'  => 'price',
384                        'label' => $this->l('Base fee'),
385                        'name'  => 'base_fee',
386                        'desc'  => $this->l('Fee given for each order placed.'),
387                    ],
388                    [
389                        'type'  => 'text',
390                        'label' => $this->l('Percent fee'),
391                        'name'  => 'percent_fee',
392                        'desc'  => $this->l('Percent of the sales.'),
393                    ],
394                ],
395                'submit' => ['title' => $this->l('Save')],
396            ],
397        ];
398
399        if (Shop::isFeatureActive()) {
400            $this->fields_form[1]['form']['input'][] = [
401                'type'  => 'shop',
402                'label' => $this->l('Shop association'),
403                'name'  => 'checkBoxShopAsso',
404            ];
405        }
406
407        $this->fields_form[2] = [
408            'form' => [
409                'legend' => [
410                    'title' => $this->l('Technical information -- Simple mode'),
411                    'icon'  => 'icon-cogs',
412                ],
413                'help'   => true,
414                'input'  => [
415                    [
416                        'type'   => 'textarea',
417                        'label'  => $this->l('Include'),
418                        'name'   => 'http_referer_like',
419                        'cols'   => 40,
420                        'rows'   => 1,
421                        'legend' => $this->l('HTTP referrer'),
422                    ],
423                    [
424                        'type'  => 'textarea',
425                        'label' => $this->l('Exclude'),
426                        'name'  => 'http_referer_like_not',
427                        'cols'  => 40,
428                        'rows'  => 1,
429                    ],
430                    [
431                        'type'   => 'textarea',
432                        'label'  => $this->l('Include'),
433                        'name'   => 'request_uri_like',
434                        'cols'   => 40,
435                        'rows'   => 1,
436                        'legend' => $this->l('Request URI'),
437                    ],
438                    [
439                        'type'  => 'textarea',
440                        'label' => $this->l('Exclude'),
441                        'name'  => 'request_uri_like_not',
442                        'cols'  => 40,
443                        'rows'  => 1,
444                    ],
445                ],
446                'desc'   => $this->l('If you know how to use MySQL regular expressions, you can use the').'
447					<a style="cursor: pointer; font-weight: bold;" onclick="$(\'#tracking_expert\').slideToggle();">'.$this->l('expert mode').'.</a>',
448                'submit' => [
449                    'title' => $this->l('Save'),
450                ],
451            ],
452        ];
453
454        $this->fields_form[3] = [
455            'form' => [
456                'legend' => [
457                    'title' => $this->l('Technical information -- Expert mode'),
458                    'icon'  => 'icon-cogs',
459                ],
460                'input'  => [
461                    [
462                        'type'   => 'textarea',
463                        'label'  => $this->l('Include'),
464                        'name'   => 'http_referer_regexp',
465                        'cols'   => 40,
466                        'rows'   => 1,
467                        'legend' => $this->l('HTTP referrer'),
468                    ],
469                    [
470                        'type'  => 'textarea',
471                        'label' => $this->l('Exclude'),
472                        'name'  => 'http_referer_regexp_not',
473                        'cols'  => 40,
474                        'rows'  => 1,
475                    ],
476                    [
477                        'type'   => 'textarea',
478                        'label'  => $this->l('Include'),
479                        'name'   => 'request_uri_regexp',
480                        'cols'   => 40,
481                        'rows'   => 1,
482                        'legend' => $this->l('Request URI'),
483                    ],
484                    [
485                        'type'  => 'textarea',
486                        'label' => $this->l('Exclude'),
487                        'name'  => 'request_uri_regexp_not',
488                        'cols'  => 40,
489                        'rows'  => 1,
490                    ],
491                ],
492            ],
493        ];
494
495        $this->multiple_fieldsets = true;
496
497        if (!($obj = $this->loadObject(true))) {
498            return '';
499        }
500
501        $this->fields_value = [
502            'click_fee'             =>
503                (float) $this->getFieldValue($obj, 'click_fee'),
504            'base_fee'              =>
505                (float) $this->getFieldValue($obj, 'base_fee'),
506            'percent_fee'           =>
507                (float) $this->getFieldValue($obj, 'percent_fee'),
508            'http_referer_like'     => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'http_referer_like'), ENT_COMPAT, 'UTF-8')),
509            'http_referer_like_not' => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'http_referer_like_not'), ENT_COMPAT, 'UTF-8')),
510            'request_uri_like'      => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'request_uri_like'), ENT_COMPAT, 'UTF-8')),
511            'request_uri_like_not'  => str_replace('\\', '\\\\', htmlentities($this->getFieldValue($obj, 'request_uri_like_not'), ENT_COMPAT, 'UTF-8')),
512        ];
513
514        $this->tpl_form_vars = ['uri' => $uri];
515
516        return parent::renderForm();
517    }
518
519    /**
520     * Post processing
521     *
522     * @return bool
523     *
524     * @since 1.0.0
525     */
526    public function postProcess()
527    {
528        if ($this->enableCalendar()) {
529            // Warning, instantiating a controller here changes the controller in the Context...
530            $calendarTab = new AdminStatsController();
531            $calendarTab->postProcess();
532            // ...so we set it back to the correct one here
533            $this->context->controller = $this;
534        }
535
536        if (Tools::isSubmit('submitSettings')) {
537            if ($this->tabAccess['edit'] === '1') {
538                if (Configuration::updateValue('TRACKING_DIRECT_TRAFFIC', (int) Tools::getValue('tracking_dt'))) {
539                    Tools::redirectAdmin(static::$currentIndex.'&conf=4&token='.Tools::getValue('token'));
540                }
541            }
542        }
543
544        if (ModuleGraph::getDateBetween() != Configuration::get('PS_REFERRERS_CACHE_LIKE') || Tools::isSubmit('submitRefreshCache')) {
545            Referrer::refreshCache();
546        }
547        if (Tools::isSubmit('submitRefreshIndex')) {
548            Referrer::refreshIndex();
549        }
550
551        return parent::postProcess();
552    }
553
554    /**
555     * Render view
556     *
557     * @return string
558     *
559     * @since 1.0.0
560     */
561    public function renderView()
562    {
563        $referrer = new Referrer((int) Tools::getValue('id_referrer'));
564
565        $displayTab = [
566            'uniqs'         => $this->l('Unique visitors'),
567            'visitors'      => $this->l('Visitors'),
568            'visits'        => $this->l('Visits'),
569            'pages'         => $this->l('Pages viewed'),
570            'registrations' => $this->l('Registrations'),
571            'orders'        => $this->l('Orders'),
572            'sales'         => $this->l('Sales'),
573            'reg_rate'      => $this->l('Registration rate'),
574            'order_rate'    => $this->l('Order rate'),
575            'click_fee'     => $this->l('Click fee'),
576            'base_fee'      => $this->l('Base fee'),
577            'percent_fee'   => $this->l('Percent fee'),
578        ];
579
580        $this->tpl_view_vars = [
581            'enable_calendar' => $this->enableCalendar(),
582            'calendar_form'   => $this->displayCalendar($this->action, $this->table, $this->identifier, (int) Tools::getValue($this->identifier)),
583            'referrer'        => $referrer,
584            'display_tab'     => $displayTab,
585            'id_employee'     => (int) $this->context->employee->id,
586            'id_lang'         => (int) $this->context->language->id,
587        ];
588
589        return parent::renderView();
590    }
591}
592