Completed
Push — master ( 60b053...61ce86 )
by Marcus
02:08
created

Helper   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 269
Duplicated Lines 3.35 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 41
lcom 1
cbo 9
dl 9
loc 269
rs 8.2769
c 2
b 1
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 9 9 1
A redirectToPage() 0 9 2
A terminateScript() 0 4 1
B getSignedGlideURL() 0 20 7
C mailWrapper() 0 48 13
A reachThrough() 0 3 1
A returnEmptyString() 0 3 1
A getDebug() 0 13 4
C getPurifier() 0 34 7
A twigCallback() 0 13 2
A autoInsert() 0 16 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Helper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Helper, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
    HCSF - A multilingual CMS and Shopsystem
5
    Copyright (C) 2014  Marcus Haase - [email protected]
6
7
    This program is free software: you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation, either version 3 of the License, or
10
    (at your option) any later version.
11
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
17
    You should have received a copy of the GNU General Public License
18
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
namespace HaaseIT\HCSF;
22
23
use HaaseIT\Toolbox\Tools;
24
use Zend\ServiceManager\ServiceManager;
25
26
/**
27
 * Class Helper
28
 * @package HaaseIT\HCSF
29
 */
30
class Helper
31
{
32
    /**
33
     * @var ServiceManager
34
     */
35
    protected $serviceManager;
36
37
    /**
38
     * @var \HaaseIT\HCSF\HelperConfig
39
     */
40
    protected $config;
41
42
    /**
43
     * @var array
44
     */
45
    protected $core = [];
46
47
    /**
48
     * @var array
49
     */
50
    protected $secrets = [];
51
52
    /**
53
     * @var array
54
     */
55
    protected $shop = [];
56
57
    /**
58
     * @var \HaaseIT\HCSF\Shop\Helper
59
     */
60
    protected $helperShop;
61
62
    /**
63
     * Helper constructor.
64
     * @param ServiceManager $serviceManager
65
     */
66 View Code Duplication
    public function __construct(ServiceManager $serviceManager)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
67
    {
68
        $this->serviceManager = $serviceManager;
69
        $this->config = $serviceManager->get('config');
70
        $this->secrets = $this->config->getSecret();
71
        $this->core = $this->config->getCore();
72
        $this->shop = $this->config->getShop();
73
        $this->helperShop = $serviceManager->get('helpershop');
74
    }
75
76
    /**
77
     * @param string $target
78
     * @param bool $replace
79
     * @param int $http_response_header
80
     * @return void|false
81
     */
82
    public function redirectToPage($target = '', $replace = false, $http_response_header = 302)
83
    {
84
        if (empty($target)) {
85
            return false;
86
        }
87
88
        header('Location: '.$target, $replace, $http_response_header);
89
        $this->terminateScript();
90
    }
91
92
    /**
93
     * @param string $message
94
     */
95
    public function terminateScript($message = '')
96
    {
97
        die($message);
0 ignored issues
show
Coding Style Compatibility introduced by
The method terminateScript() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
98
    }
99
100
    /**
101
     * @param $file
102
     * @param int $width
103
     * @param int $height
104
     * @return bool|string
105
     */
106
    public function getSignedGlideURL($file, $width = 0, $height = 0)
107
    {
108
        $urlBuilder = \League\Glide\Urls\UrlBuilderFactory::create('', $this->secrets['glide_signkey']);
109
110
        $param = [];
111
        if ($width == 0 && $height == 0) {
112
            return false;
113
        }
114
        if ($width != 0) {
115
            $param['w'] = $width;
116
        }
117
        if ($height != 0) {
118
            $param['h'] = $height;
119
        }
120
        if ($width != 0 && $height != 0) {
121
            $param['fit'] = 'stretch';
122
        }
123
124
        return $urlBuilder->getUrl($file, $param);
125
    }
126
127
    /**
128
     * @param $to
129
     * @param string $subject
130
     * @param string $message
131
     * @param array $aImagesToEmbed
132
     * @param array $aFilesToAttach
133
     * @return bool
134
     */
135
    public function mailWrapper($to, $subject = '(No subject)', $message = '', $aImagesToEmbed = [], $aFilesToAttach = []) {
136
        $mail = new \PHPMailer;
137
        $mail->CharSet = 'UTF-8';
138
139
        $mail->isMail();
140
        if ($this->core['mail_method'] === 'sendmail') {
141
            $mail->isSendmail();
142
        } elseif ($this->core['mail_method'] === 'smtp') {
143
            $mail->isSMTP();
144
            $mail->Host = $this->secrets['mail_smtp_server'];
145
            $mail->Port = $this->secrets['mail_smtp_port'];
146
            if ($this->secrets['mail_smtp_auth'] === true) {
147
                $mail->SMTPAuth = true;
148
                $mail->Username = $this->secrets['mail_smtp_auth_user'];
149
                $mail->Password = $this->secrets['mail_smtp_auth_pwd'];
150
                if ($this->secrets['mail_smtp_secure']) {
151
                    $mail->SMTPSecure = 'tls';
152
                    if ($this->secrets['mail_smtp_secure_method'] === 'ssl') {
153
                        $mail->SMTPSecure = 'ssl';
154
                    }
155
                }
156
            }
157
        }
158
159
        $mail->From = $this->core['email_sender'];
160
        $mail->FromName = $this->core['email_sendername'];
161
        $mail->addAddress($to);
162
        $mail->isHTML(true);
163
        $mail->Subject = $subject;
164
        $mail->Body = $message;
165
166
        if (is_array($aImagesToEmbed) && count($aImagesToEmbed)) {
167
            foreach ($aImagesToEmbed as $sKey => $imgdata) {
168
                $imginfo = getimagesizefromstring($imgdata['binimg']);
169
                $mail->addStringEmbeddedImage($imgdata['binimg'], $sKey, $sKey, 'base64', $imginfo['mime']);
170
            }
171
        }
172
173
        if (is_array($aFilesToAttach) && count($aFilesToAttach)) {
174
            foreach ($aFilesToAttach as $sValue) {
175
                if (file_exists($sValue)) {
176
                    $mail->addAttachment($sValue);
177
                }
178
            }
179
        }
180
181
        return $mail->send();
182
    }
183
184
    // don't remove this, this is the fallback for unavailable twig functions
185
    /**
186
     * @param $string
187
     * @return mixed
188
     */
189
    public function reachThrough($string) {
190
        return $string;
191
    }
192
    // don't remove this, this is the fallback for unavailable twig functions
193
    /**
194
     * @return string
195
     */
196
    public function returnEmptyString() {
197
        return '';
198
    }
199
200
    /**
201
     * @param array $aP
202
     * @param Page $P
203
     */
204
    public function getDebug($aP, $P)
0 ignored issues
show
Coding Style introduced by
getDebug uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getDebug uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getDebug uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
205
    {
206
        if (!empty($_POST)) {
207
            Tools::debug($_POST, '$_POST');
208
        } elseif (!empty($_REQUEST)) {
209
            Tools::debug($_REQUEST, '$_REQUEST');
210
        }
211
        if (!empty($_SESSION)) {
212
            Tools::debug($_SESSION, '$_SESSION');
213
        }
214
        Tools::debug($aP, '$aP');
215
        Tools::debug($P, '$P');
216
    }
217
218
    /**
219
     * @param string $purpose
220
     * @return bool|\HTMLPurifier
221
     */
222
    public function getPurifier($purpose)
223
    {
224
        $purifier_config = \HTMLPurifier_Config::createDefault();
225
        $purifier_config->set('Core.Encoding', 'UTF-8');
226
        $purifier_config->set('Cache.SerializerPath', PATH_PURIFIERCACHE);
227
        $purifier_config->set('HTML.Doctype', $this->core['purifier_doctype']);
228
229
        if ($purpose === 'textcat') {
230
            $configkey = 'textcat';
231
            $configsection = 'core';
232
        } elseif ($purpose === 'page') {
233
            $configkey = 'pagetext';
234
            $configsection = 'core';
235
        } elseif ($purpose === 'item') {
236
            $configkey = 'itemtext';
237
            $configsection = 'shop';
238
        } elseif ($purpose === 'itemgroup') {
239
            $configkey = 'itemgrouptext';
240
            $configsection = 'shop';
241
        } else {
242
            return false;
243
        }
244
245
        if (!empty($this->{$configsection}[$configkey.'_unsafe_html_whitelist'])) {
246
            $purifier_config->set('HTML.Allowed', $this->{$configsection}[$configkey.'_unsafe_html_whitelist']);
247
        }
248
        if (!empty($this->{$configsection}[$configkey.'_loose_filtering'])) {
249
            $purifier_config->set('HTML.Trusted', true);
250
            $purifier_config->set('Attr.EnableID', true);
251
            $purifier_config->set('Attr.AllowedFrameTargets', ['_blank', '_self', '_parent', '_top']);
252
        }
253
254
        return new \HTMLPurifier($purifier_config);
255
    }
256
257
    /**
258
     * @param $callback
259
     * @param $parameters
260
     * @return bool|mixed
261
     */
262
    public function twigCallback($callback, $parameters)
263
    {
264
        $callbacks = [
265
            'renderItemStatusIcon' => [$this->helperShop, 'renderItemStatusIcon'],
266
            'shopadminMakeCheckbox' => [$this->helperShop, 'shopadminMakeCheckbox'],
267
        ];
268
269
        if (!isset($callbacks[$callback])) {
270
            return false;
271
        }
272
        
273
        return call_user_func($callbacks[$callback], $parameters);
274
    }
275
276
    /**
277
     * @param \Doctrine\DBAL\Connection $dbal
278
     * @param string $table
279
     * @param array $data
280
     * @return string
281
     */
282
    public function autoInsert(\Doctrine\DBAL\Connection $dbal, $table, array $data)
283
    {
284
        /** @var \Doctrine\DBAL\Query\QueryBuilder $querybuilder */
285
        $querybuilder = $dbal->createQueryBuilder();
286
        $querybuilder->insert($table);
287
288
        foreach ($data as $colname => $col) {
289
            $querybuilder
290
                ->setValue($colname, ':'.$colname)
291
                ->setParameter(':'.$colname, $col);
292
        }
293
294
        $querybuilder->execute();
295
296
        return $dbal->lastInsertId();
297
    }
298
}
299