Completed
Push — master ( aa8397...903b4e )
by David
02:53
created

PostDispatch::fillValues()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 28
rs 8.8571
c 2
b 0
f 0
cc 3
eloc 17
nc 3
nop 1
1
<?php
2
/**
3
 * Tag Manager
4
 * Copyright (c) Webmatch GmbH
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 */
16
17
namespace WbmTagManager\Subscriber\Frontend;
18
19
use Enlight\Event\SubscriberInterface;
20
use Shopware\Components\DependencyInjection\Container;
21
use WbmTagManager\Models\Repository;
22
23
/**
24
 * Class PostDispatch
25
 * @package WbmTagManager\Subscriber\Frontend
26
 */
27
class PostDispatch implements SubscriberInterface
28
{
29
30
    /**
31
     * @var Container
32
     */
33
    private $container;
34
35
    /**
36
     * @var mixed
37
     */
38
    private $viewVariables;
39
40
    /**
41
     * @return array
42
     */
43
    public static function getSubscribedEvents()
44
    {
45
        return [
46
            'Enlight_Controller_Action_PostDispatch_Frontend' => 'onPostDispatch',
47
            'Enlight_Controller_Action_PostDispatch_Widgets' => 'onPostDispatch'
48
        ];
49
    }
50
51
    /**
52
     * PostDispatch constructor.
53
     * @param Container $container
54
     */
55
    public function __construct(Container $container)
56
    {
57
        $this->container = $container;
58
    }
59
60
    /**
61
     * @param \Enlight_Controller_ActionEventArgs $args
62
     */
63
    public function onPostDispatch(\Enlight_Controller_ActionEventArgs $args)
64
    {
65
        if (
66
            !$this->container->get('config')->getByNamespace('WbmTagManager', 'wbmTagManagerActive') ||
67
            empty($this->container->get('config')->getByNamespace('WbmTagManager', 'wbmTagManagerContainer'))
68
        ) {
69
            return;
70
        }
71
72
        $controller = $args->getSubject();
73
        $request = $controller->Request();
74
75
        $module = $oModule = join('_', [
76
                strtolower($request->getModuleName()),
77
                strtolower($request->getControllerName()),
78
                strtolower($request->getActionName()),
79
            ]);
80
81
        if ($module == 'frontend_checkout_ajaxcart') {
82
            $module = 'frontend_checkout_' . strtolower($request->getParam('action'));
83
        }
84
85
        $search = [
86
            'widgets_listing_ajaxlisting',
87
            'widgets_listing_listingcount',
88
            'frontend_checkout_ajaxcart',
89
        ];
90
        $replace = [
91
            'frontend_listing_index',
92
            'frontend_listing_index',
93
            'frontend_checkout_cart',
94
        ];
95
        $module = str_replace($search, $replace, $module);
96
97
        /** @var Repository $propertyRepo */
98
        $propertyRepo = $this->container->get('models')->getRepository('WbmTagManager\Models\Property');
99
        $dataLayer = $propertyRepo->getChildrenList(0, $module, true);
100
101
        if (!empty($dataLayer)) {
102
            $this->viewVariables = $controller->View()->getAssign();
103
104
            $dataLayer = $this->fillValues($dataLayer);
105
106
            $this->container->get('wbm_tag_manager.variables')->setVariables($dataLayer);
107
        }
108
109
        // Since SW 5.3 the generic listingCountAction is used for paginated listings.
110
        // Get the response json body, decode it, prepend the dataLayer to the listing key
111
        // and set json encoded markup as response body.
112
        if ($oModule == 'widgets_listing_listingcount') {
113
            /** @var \Enlight_Controller_Response_ResponseHttp $response */
114
            $response = $controller->Response();
115
            $data = json_decode($response->getBody(), true);
116
117
            if (isset($data['listing'])) {
118
                if ($dataLayer = $this->container->get('wbm_tag_manager.variables')->getVariables()) {
119
                    $data['listing'] = FilterRender::prependDataLayer(
120
                        $data['listing'],
121
                        $dataLayer,
122
                        $this->container->get('config')->getByNamespace('WbmTagManager', 'wbmTagManagerJsonPrettyPrint')
123
                    );
124
125
                    $response->setBody(json_encode($data));
126
                }
127
            }
128
        }
129
    }
130
131
    /**
132
     * @param $dataLayer
133
     * @return mixed
134
     */
135
    private function fillValues($dataLayer)
136
    {
137
        $dataLayer = json_encode($dataLayer);
138
139
        $search = ['{\/', ',{"endArrayOf":true}'];
140
        $replace = ['{/', '{/literal}{if !$smarty.foreach.loop.last},{/if}{/foreach}{literal}'];
141
142
        $dataLayer = str_replace($search, $replace, $dataLayer);
143
144
        preg_match('/({"startArrayOf":".*?"},)/i', $dataLayer, $matches);
145
        foreach($matches as $match){
146
            $foreachObj = json_decode(rtrim($match, ','));
147
            if($foreachObj->startArrayOf){
148
                $arguments = explode(' as ', $foreachObj->startArrayOf);
149
                $dataLayer = str_replace(
150
                    $match,
151
                    '{/literal}{foreach from=' . $arguments[0] . ' item=' . ltrim($arguments[1], '$') . ' name=loop}{literal}',
152
                    $dataLayer
153
                );
154
            }
155
        }
156
157
        $dataLayer = '{literal}' . $dataLayer . '{/literal}';
158
159
        $dataLayer = $this->compileString($dataLayer);
160
161
        return json_decode($dataLayer, true);
162
    }
163
164
    /**
165
     * @param $string
166
     * @return string
167
     */
168
    private function compileString($string)
169
    {
170
        $view = new \Enlight_View_Default(
171
            $this->container->get('Template')
172
        );
173
174
        $compiler = new \Shopware_Components_StringCompiler($view->Engine());
175
176
        $compiler->setContext($this->viewVariables);
177
178
        return $compiler->compileString($string);
179
    }
180
}