Completed
Push — development ( ef9e73...b2c3e4 )
by Andrij
20:27
created

TemplateManager::updateImageSizes()   C

Complexity

Conditions 14
Paths 16

Size

Total Lines 35
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 21
c 1
b 0
f 0
nc 16
nop 1
dl 0
loc 35
rs 5.0864

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace template_manager\classes;
4
5
use CMSFactory\Events;
6
use Exception;
7
use libraries\Backup;
8
use RecursiveDirectoryIterator;
9
use RecursiveIteratorIterator;
10
use template_manager\installer\DemodataDirector;
11
use template_manager\installer\DependenceDirector;
12
13
class TemplateManager
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
14
{
0 ignored issues
show
introduced by
Opening brace of a class must be on the same line as the definition
Loading history...
15
16
    const REMORE_UPDATE_INTERVAL = 7200; // 3 hours
17
    const EVENT_DEMODATA_INSTALLED = 'demodata:installed';
18
    const EVENT_DEMODATA_PRE_INSTALLED = 'demodata:preInstalled';
19
20
    /**
21
     *
22
     * @var TemplateManager
23
     */
24
    private static $instance;
25
26
    /**
27
     *
28
     * @var array
29
     */
30
    public $defaultComponents = [];
31
32
    /**
33
     * May have messages
34
     * @var array|string
35
     */
36
    public $messages = [];
37
38
    /**
39
     * Current template
40
     * @var Template
41
     */
42
    private $currentTemplate;
43
44
    /**
45
     *
46
     * @var string
47
     */
48
    private static $ImageCMSRepositoryURL = 'http://www.imagecms.net/addons/shop/templates_xml';
49
50
    /**
51
     *
52
     * @var array
53
     */
54
    public $loadedComponents = [];
55
56
    /**
57
     * Folders that not be included in local templates list
58
     * @var array
59
     */
60
    public $ignoreTemplates = ['administrator'];
61
62
    public $current_template_components;
63
64
    /**
65
     *
66
     * @var array
67
     */
68
    private $allowedDemodataTables = [];
0 ignored issues
show
Unused Code introduced by
The property $allowedDemodataTables is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
69
70
    /**
71
     *
72
     * @return TemplateManager
73
     */
74
    public static function getInstance() {
75
        self::$instance = self::$instance ?: new self;
0 ignored issues
show
Coding Style introduced by
Instantiating objects should always be done with parentheses.

The object instantiation should always have parentheses even if no arguments are passed:

new DateTime; // Bad
new DateTime(); // Good
Loading history...
76
        return self::$instance;
77
    }
78
79
    /**
80
     * Getting core components
81
     */
82
    private function __construct() {
83
        if (SHOP_INSTALLED) {
84
            self::$ImageCMSRepositoryURL = self::$ImageCMSRepositoryURL . '/Shop';
85
        } else {
86
            self::$ImageCMSRepositoryURL = self::$ImageCMSRepositoryURL . '/Corporate';
87
        }
88
    }
89
90
    public function loadDefaultComponents(array $except = []) {
91
        if (count($this->defaultComponents) > 0) {
92
            return;
93
        }
94
        $componentsPath = __DIR__ . '/../components/';
95
96
        if ($handle = opendir($componentsPath)) {
97
            while (false !== ($componentName = readdir($handle))) {
98
                if ($componentName != '.' && $componentName != '..' && !in_array($componentName, $except)) {
99
                    include_once $componentsPath . "$componentName/$componentName" . EXT;
100
                    $this->defaultComponents[$componentName] = new $componentName;
0 ignored issues
show
Coding Style introduced by
Instantiating objects should always be done with parentheses.

The object instantiation should always have parentheses even if no arguments are passed:

new DateTime; // Bad
new DateTime(); // Good
Loading history...
101
                }
102
            }
103
            closedir($handle);
104
        }
105
    }
106
107
    /**
0 ignored issues
show
introduced by
Doc comment is empty
Loading history...
108
     *
109
     */
110
    public static function getTemplateToPay() {
111
        if (MAINSITE) {
112
113
            preg_match('/\/var\/www\/[a-zA-Z\d]+\/data\/www\/([a-zA-Z\d\.\-]+)\//', \CI::$APP->input->server('SCRIPT_FILENAME'), $matches);
114
            $dirToPay = MAINSITE . '/application/config/' . $matches[1] . '/payments/template';
115
            if ($handle = opendir($dirToPay)) {
116
                $templateList = [];
117
                while (false !== ($template = readdir($handle))) {
118
                    if ($template != '.' && $template != '..') {
119
                        $templateList[$template] = file_get_contents($dirToPay . '/' . $template);
120
                    }
121
                }
122
                return $templateList;
123
            }
124
            return false;
125
        } else {
126
            return false;
127
        }
128
    }
129
130
    /**
131
     * Fires event "postTemplateInstall"
132
     *
133
     * @param Template $template
134
     * @param bool $installDemodata
135
     * @param bool $installDemoArchive
136
     * @return bool|null
0 ignored issues
show
introduced by
@return doc comment specified, but function has no return statement
Loading history...
137
     * @throws Exception
0 ignored issues
show
introduced by
Comment missing or not on the next line for @throws tag in function comment
Loading history...
138
     */
139
    public function setTemplate(Template $template, $installDemodata = FALSE, $installDemoArchive = FALSE) {
0 ignored issues
show
Unused Code introduced by
The parameter $installDemoArchive is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
140
        if ($this->currentTemplate->name == $template->name) {
141
            throw new Exception(lang('Current installed template can not be installed again', 'template_manager'));
142
        }
143
144
        //Install template demodata
145 View Code Duplication
        if (isset($template->xml->demodata)) {
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
146
            $demodataDirector = new DemodataDirector($template->xml->demodata);
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
147
            $res = $demodataDirector->install();
148
            $this->massages = $demodataDirector->getMessages();
0 ignored issues
show
Bug introduced by
The property massages does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
149
            if (FALSE == $res) {
150
                throw new Exception(lang('One or more dependency error', 'template_manager'));
151
            }
152
        }
153
154
        $this->copyUploads($template->name);
155
156
        // Truncate table template_settings
157
        \CI::$APP->db->truncate('template_settings');
158
159
        foreach ($template->xml->components->component as $component) {
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
160
            $attributes = $component->attributes();
161
            $handler = (string) $attributes['handler'];
162
            $instance = $template->getComponent($handler);
163
            $instance->setParamsXml($component);
164
        }
165
166
        \CI::$APP->db->where('name', 'systemTemplatePath')->update('shop_settings', ['value' => './templates/' . $template->name . '/shop/']);
167
        \CI::$APP->db->update('settings', ['site_template' => $template->name]);
168
169
        $this->currentTemplate = $template;
170
171
        // processing all dependencies
172
        if (isset($template->xml->dependencies)) {
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
173 View Code Duplication
            if (isset($template->xml->dependencies->dependence)) {
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
174
                $dependenceDirector = new DependenceDirector($template->xml->dependencies->dependence);
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
175
                $res = $dependenceDirector->verify($installDemodata);
176
                $this->massages = $dependenceDirector->getMessages();
177
                if (FALSE == $res) {
178
                    throw new Exception(lang('One or more dependency error', 'template_manager'));
179
                }
180
            }
181
        }
182
183
        if (isset($template->xml->imageSizes)) {
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
184
            $this->updateImageSizes($template->xml->imageSizes);
0 ignored issues
show
Documentation introduced by
The property $xml is declared private in template_manager\classes\Template. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
185
        }
186
187
        Events::create()->registerEvent($template, 'postTemplateInstall');
188
        Events::runFactory();
189
    }
190
191
    /**
192
     * @param \SimpleXMLElement $imageSizes
193
     */
194
    private function updateImageSizes($imageSizes) {
195
        $sizes = [];
196
        foreach ($imageSizes->size as $size) {
197
            if (isset($size['name']) && isset($size['width']) && isset($size['height'])) {
198
                if (is_numeric((string) $size['width']) && is_numeric((string) $size['height'])) {
199
                    $sizes[(string) $size['name']] = [
200
                                                      'name'   => (string) $size['name'],
201
                                                      'width'  => (string) $size['width'],
202
                                                      'height' => (string) $size['height'],
203
                                                     ];
204
                }
205
            };
206
207
        }
208
        if (isset($imageSizes->additional)) {
209
            foreach ($imageSizes->additional->size as $size) {
210
                $additionalSizes = [
211
                                    'image' => 'additionalImage',
212
                                    'thumb' => 'thumbImage',
213
                                   ];
214
                if (is_numeric((string) $size['width']) && is_numeric((string) $size['height'])) {
215
                    foreach ($additionalSizes as $sizeName => $dataBaseValue) {
216
                        if ((string) $size['name'] == $sizeName) {
217
                            \CI::$APP->db->where('name', $dataBaseValue . 'Width')->update('shop_settings', ['value' => (string) $size['width']]);
218
                            \CI::$APP->db->where('name', $dataBaseValue . 'Height')->update('shop_settings', ['value' => (string) $size['height']]);
219
                        }
220
                    }
221
                }
222
            }
223
        }
224
225
        if (count($sizes) > 0) {
226
            \CI::$APP->db->where('name', 'imageSizesBlock')->update('shop_settings', ['value' => serialize($sizes)]);
227
        }
228
    }
229
230
    /**
231
     * @param string $template_name
232
     * @return bool
233
     */
234
    public function installDemoArchive($template_name) {
235
        try {
236
            Events::create()->raiseEvent(['templateName' => $template_name], self::EVENT_DEMODATA_PRE_INSTALLED);
237
238
            $demodata_atchive = realpath('templates/' . $template_name . '/demodata/uploads.zip');
239
240
            if ($demodata_atchive) {
241
                $uploads_folder = realpath('uploads');
242
                if ($uploads_folder) {
243
                    chmod($uploads_folder, 0777);
244
                    $backUpFolderName = $uploads_folder . '_backup_' . time();
245
                    rename($uploads_folder, $backUpFolderName);
246
                }
247
248
                $zip = new \ZipArchive();
249
                $zip->open($demodata_atchive);
250
251
                if (strstr($zip->getNameIndex(0), 'uploads')) {
252
                    $zip->extractTo('.');
253
                } else {
254
                    mkdir('./uploads');
255
                    chmod('./uploads', 0777);
256
                    $zip->extractTo(realpath('uploads'));
257
                }
258
                $zip->close();
259
260
                $changedDir = [];
261
                $uploads_folder = realpath('uploads');
262
                foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($uploads_folder)) as $entity) {
263
                    $directory = dirname($entity->getPathname());
264
                    if (!in_array($directory, $changedDir)) {
265
                        chmod($directory, 0777);
266
                        $changedDir[] = dirname($entity->getPathname());
267
                    }
268
                    chmod($entity->getPathname(), 0777);
269
                }
270
                chmod($uploads_folder, 0777);
271
                //move academy images to new uploads path
272
                $academyImages = $backUpFolderName . '/images/academy';
273
                chmod($academyImages, 0777);
274
                rename($academyImages, UPLOADSPATH . 'images/academy');
275
            }
276
277
            $demodata_db = realpath('templates/' . $template_name . '/demodata/database.sql');
278
279
            if ($demodata_db) {
280
                $this->db_backup();
281
282
                $db_file_content = file_get_contents($demodata_db);
283
                $this->query_from_file($db_file_content);
284
            }
285
286
            Events::create()->raiseEvent(['templateName' => $template_name], self::EVENT_DEMODATA_INSTALLED);
287
288
            return TRUE;
289
        } catch (Exception $exc) {
290
            $this->messages = $exc->getMessage();
291
            return FALSE;
292
        }
293
    }
294
295
    public function db_backup() {
296
        if (!is_dir(BACKUPFOLDER)) {
297
            mkdir(BACKUPFOLDER);
298
            chmod(BACKUPFOLDER, 0777);
299
        }
300
301 View Code Duplication
        if (is_really_writable(BACKUPFOLDER)) {
302
            \CI::$APP->load->dbutil();
303
            $filePath = Backup::create()->createBackup('sql', 'backup_template_manager', TRUE);
304
            chmod(BACKUPFOLDER . 'backup_template_manager.sql', 0777);
305
            return pathinfo($filePath, PATHINFO_BASENAME);
306
        }
307
        return FALSE;
308
    }
309
310
    /**
311
     * @param $sqlString
0 ignored issues
show
introduced by
Missing parameter type
Loading history...
312
     */
313
    public function query_from_file($sqlString) {
314
315
        $allowedTables = \CI::$APP->load
316
            ->module('template_manager')
317
            ->config
318
            ->item('allowedDemodataTables');
319
320
        $queries = new DemoDataSQLFilter($allowedTables);
321
        $queries->parse($sqlString);
322
323
        $truncated = [];
324
        foreach ($queries as $query) {
325
            $table = $queries->getCurrentTable();
326
            if (\CI::$APP->db->table_exists($table)) {
327
328
                //sql dump may have more then one insert query for same table
329
                if (!in_array($table, $truncated)) {
330
                    \CI::$APP->db->truncate($table);
331
                    array_push($truncated, $table);
332
                }
333
334
                \CI::$APP->db->query($query);
335
                //todo: $result = \CI::$APP->db->query($query); if (!$result) log error $table - \CI::$APP->db->_error_message()
336
            }
337
        }
338
    }
339
340
    /**
341
     * @param string $templateName
342
     */
343
    private function copyUploads($templateName) {
344
        $templateUploadsFolder = "./templates/{$templateName}/uploads";
345
346
        if (is_dir($templateUploadsFolder)) {
347
            foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($templateUploadsFolder)) as $entity) {
348
                if ($entity->getFilename() != '.' && $entity->getFilename() != '..' && !strstr($entity->getPathname(), '/.')) {
349
                    preg_match('/uploads.*/', $entity->getPathname(), $matches);
350
351
                    $copyPath = './' . $matches[0];
352
                    $directoryName = dirname($copyPath);
353
                    $directories = explode('/', $directoryName);
354
355
                    $main_dir = './uploads';
356
                    foreach ($directories as $directory) {
357
                        if ($directory != '.' && $directory != 'uploads') {
358
                            $main_dir .= '/' . $directory;
359
                            if (!file_exists($main_dir)) {
360
                                mkdir($main_dir, 0777);
361
                            }
362
                        }
363
                    }
364
365
                    copy($entity->getPathname(), $copyPath);
366
                }
367
            }
368
        }
369
    }
370
371
    /**
372
     * Returns the current set template
373
     * @return Template
374
     */
375
    public function getCurentTemplate() {
376
        if ($this->currentTemplate === null) {
377
            $currentTemplateName = \CI::$APP->db->get('settings')->row()->site_template;
378
            $this->currentTemplate = new Template($currentTemplateName);
379
        }
380
        return $this->currentTemplate;
381
    }
382
383
    /**
384
     * @return array
385
     */
386
    public function getCurrentTemplateComponents() {
387
        if ($this->current_template_components === null) {
388
            $this->current_template_components = $this->getCurentTemplate()
389
                ->getComponents();
390
        }
391
        return $this->current_template_components;
392
    }
393
394
    /**
395
     * Templates from ./templates directory
396
     * @param boolean $validOnly (optional, default TRUE) if false all
397
     * templates will be shown, if true only those wich have all needed files
0 ignored issues
show
introduced by
Parameter comment must start with a capital letter
Loading history...
introduced by
Parameter comment must end with a full stop
Loading history...
398
     * @return array array of Template objects
399
     */
400
    public function listLocal($validOnly = TRUE) {
0 ignored issues
show
Unused Code introduced by
The parameter $validOnly is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
401
        $templates = [];
402
        foreach (get_templates() as $templateName) {
0 ignored issues
show
Bug introduced by
The expression get_templates() of type array|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
403
            $templates[] = new Template($templateName);
404
        }
405
406
        usort(
407
            $templates,
408
            function ($t1, $t2) {
409
                $names1 = [
410
                           $t1->name,
411
                           $t2->name,
412
                          ];
413
                $names2 = $names1;
414
                sort($names1);
415
                return ($names1 === $names2) ? -1 : 1;
416
            }
417
        );
418
419
        return $templates;
420
    }
421
422
    /**
423
     * Gets data from remote feed with templates
424
     * @param string $sourceUrl url of remote xml file with template data
425
     * @return array of Template
426
     */
427
    public function listRemote($sourceUrl = '') {
428
        if (!$sourceUrl) {
429
            $sourceUrl = self::$ImageCMSRepositoryURL;
430
        }
431
432
        $pathToCachedFile = FCPATH . '/uploads/templates/' . md5($sourceUrl);
433
        if (file_exists($pathToCachedFile) && time() < (filemtime($pathToCachedFile) + self::REMORE_UPDATE_INTERVAL)) {
434
            $templatesXML = file_get_contents($pathToCachedFile);
435
        } else {
436
            $templatesXML = $this->getContents($sourceUrl);
437
            if (empty($templatesXML)) {
438
                if (file_exists($pathToCachedFile)) {
439
                    $templatesXML = file_get_contents($pathToCachedFile);
440
                }
441
            } else {
442
                file_put_contents($pathToCachedFile, $templatesXML);
443
            }
444
        }
445
        $xml = simplexml_load_string($templatesXML);
446
        $json = json_encode($xml);
447
        $array = json_decode($json, TRUE);
448
        return $array;
449
    }
450
451
    /**
452
     * @param string $url
453
     * @return mixed
454
     */
455
    protected function getContents($url) {
456
        $ch = curl_init($url);
457
        curl_setopt($ch, CURLOPT_HEADER, 0);
458
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
459
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
460
        curl_setopt($ch, CURLOPT_TIMEOUT, 4);
461
        $content = curl_exec($ch);
462
        curl_close($ch);
463
        return $content;
464
    }
465
466
}