Theme   B
last analyzed

Complexity

Total Complexity 41

Size/Duplication

Total Lines 301
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

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

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A setThemeName() 0 8 2
A getCurrentThemeInfoFile() 0 13 3
A getThemeInfoFile() 0 10 2
A getName() 0 4 1
A getFullName() 0 4 1
A getAuthor() 0 4 1
A getVersion() 0 4 1
A getRequiredVersion() 0 4 1
A getDate() 0 4 1
A getLayout() 0 4 1
A getCss() 0 4 1
A getLayoutFile() 0 18 4
A getRenderEngine() 0 4 1
A isBackendTheme() 0 4 1
A isFrontendTheme() 0 4 2
A getArray() 0 4 1
B getPath() 0 22 5
A getWebPath() 0 16 4
A getInfoArray() 0 11 1
A getThemeDirectories() 0 7 1
B iterateDir() 0 46 5

How to fix   Complexity   

Complex Class

Complex classes like Theme 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 Theme, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Koch Framework
5
 * Jens-André Koch © 2005 - onwards.
6
 *
7
 * This file is part of "Koch Framework".
8
 *
9
 * License: GNU/GPL v2 or any later version, see LICENSE file.
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
 */
24
25
namespace Koch\View\Helper;
26
27
use Koch\View\AbstractRenderer;
28
29
/**
30
 * Koch Framework - Class for handling of Themes.
31
 *
32
 * This class provides abstracted (object) access to a theme's theme_info.xml file.
33
 */
34
class Theme
35
{
36
    public $theme      = '';
37
    public $theme_info = [];
0 ignored issues
show
Coding Style introduced by
$theme_info does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
38
39
    /**
40
     * Constructor, or what ;).
41
     *
42
     * @param string $theme Name of the Theme.
43
     *
44
     * @return \Koch\View\Helper\Theme
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
45
     */
46
    public function __construct($theme)
47
    {
48
        $this->setThemeName($theme);
49
50
        $this->getInfoArray($theme);
51
52
        return $this;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
53
    }
54
55
    /**
56
     * @param string $theme
57
     */
58
    public function setThemeName($theme)
59
    {
60
        if ($theme === null) {
61
            throw new \InvalidArgumentException('Please  provide a theme name.');
62
        }
63
64
        $this->theme = $theme;
65
    }
66
67
    /**
68
     * Getter for the "theme_info.xml" file of the currently activated theme.
69
     *
70
     * @return string Filepath to "theme_info.xml" of the currently activated theme.
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
71
     */
72
    public function getCurrentThemeInfoFile()
73
    {
74
        // get array for frontend or backend theme
75
        $paths = AbstractRenderer::getThemeTemplatePaths();
0 ignored issues
show
Bug introduced by
The method getThemeTemplatePaths() does not exist on Koch\View\AbstractRenderer. Did you maybe mean getTheme()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
76
77
        foreach ($paths as $path) {
78
            $file = $path . DIRECTORY_SEPARATOR . 'theme_info.xml';
79
80
            if (is_file($file)) {
81
                return $file;
82
            }
83
        }
84
    }
85
86
    /**
87
     * Looks for the requested theme in the frontend and backend theme folder
88
     * and returns the theme path.
89
     *
90
     * @param string $theme Theme name.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $theme not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
91
     *
92
     * @return string Path to theme.
0 ignored issues
show
Documentation introduced by
Should the return type not be string|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
93
     */
94
    public function getPath($theme = null)
95
    {
96
        if ($theme === null) {
97
            $theme = $this->getName();
98
        }
99
100
        if (is_dir(APPLICATION_PATH . 'Themes') === false) {
101
            throw new \RuntimeException('The application themes folder was not found.');
102
        }
103
104
        $frontend = APPLICATION_PATH . 'Themes/frontend/' . $theme . DIRECTORY_SEPARATOR;
105
        if (is_dir($frontend)) {
106
            return $frontend;
107
        }
108
109
        $backend = APPLICATION_PATH . 'Themes/backend/' . $theme . DIRECTORY_SEPARATOR;
110
        if (is_dir($backend)) {
111
            return $backend;
112
        }
113
114
        return false;
115
    }
116
117
    /**
118
     * Looks for the requested theme in the frontend and backend theme folder
119
     * and returns the web path of the theme.
120
     *
121
     * @param string $theme Theme name.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $theme not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
122
     *
123
     * @return string Webpath of theme (for usage in templates).
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
124
     */
125
    public function getWebPath($theme = null)
126
    {
127
        if ($theme === null) {
128
            $theme = $this->getName();
129
        }
130
131
        // check absolute, return www
132
        if (is_dir(APPLICATION_PATH . 'Themes/frontend/' . $theme)) {
133
            return WWW_ROOT_THEMES_FRONTEND . $theme . '/';
134
        }
135
136
        // check absolute, return www
137
        if (is_dir(APPLICATION_PATH . 'Themes/backend/' . $theme)) {
138
            return WWW_ROOT_THEMES_BACKEND . $theme . '/';
139
        }
140
    }
141
142
    /**
143
     * Returns "theme_info.xml" for the requested theme.
144
     *
145
     * @param string $theme Theme name.
146
     *
147
     * @return string File path to "theme_info.xml" file.
148
     *
149
     * @throws \Koch\Exception\Exception
150
     */
151
    public function getThemeInfoFile($theme)
152
    {
153
        $file = $this->getPath($theme) . 'theme_info.xml';
154
155
        if (is_file($file)) {
156
            return $file;
157
        }
158
159
        throw new \Exception('The Theme "' . $theme . '" has no "theme_info.xml" file.');
160
    }
161
162
    /**
163
     * Returns Theme Infos as array.
164
     *
165
     * @param string $theme Name of the Theme.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $theme not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
166
     *
167
     * @return array Theme_Info.xml as Array.
168
     */
169
    public function getInfoArray($theme = null)
170
    {
171
        $file = $this->getThemeInfoFile($theme);
172
173
        $array = \Koch\Config\Adapter\XML::read($file);
174
175
        // when setting array as object property remove the inner theme array
176
        $this->theme_info = $array['theme'];
177
178
        return $this->theme_info;
179
    }
180
181
    /**
182
     * --------------------------------------------------------------------------------------------
183
     *  GETTERS
184
     * --------------------------------------------------------------------------------------------.
185
     */
186
187
    /**
188
     * Gets shortname or folder name.
189
     *
190
     * @return string short name / folder name.
191
     */
192
    public function getName()
193
    {
194
        return $this->theme;
195
    }
196
197
    public function getFullName()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
198
    {
199
        return $this->theme_info['name'];
200
    }
201
202
    public function getAuthor()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
203
    {
204
        return $this->theme_info['authors'];
205
    }
206
207
    public function getVersion()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
208
    {
209
        return $this->theme_info['theme_version'];
210
    }
211
212
    public function getRequiredVersion()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
213
    {
214
        return $this->theme_info['required_version'];
215
    }
216
217
    public function getDate()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
218
    {
219
        return $this->theme_info['date'];
220
    }
221
222
    public function getLayout()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
223
    {
224
        return $this->theme_info['layout'];
225
    }
226
227
    public function getCss()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
228
    {
229
        return $this->theme_info['css'];
230
    }
231
232
    public function getLayoutFile()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
233
    {
234
        if ($this->theme_info['layout']['mainfile'] !== null) {
235
            #return $this->getPath() . $this->theme_info['layout']['mainfile'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
236
237
            return $this->theme_info['layout']['mainfile'];
238
        } elseif (false === isset($this->theme_info['layout']['mainfile'])) {
239
            // maybe we have a main template css file named after the theme
240
            // $layout_file = $this->getPath() . $this->getName() . '.tpl';
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
241
            $layout_file = $this->getName() . '.tpl';
0 ignored issues
show
Coding Style introduced by
$layout_file does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
242
243
            if (is_file($layout_file)) {
0 ignored issues
show
Coding Style introduced by
$layout_file does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
244
                return $layout_file;
0 ignored issues
show
Coding Style introduced by
$layout_file does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
245
            }
246
        } else { // no main layout found !
247
            throw new \Exception('No Layout File defined. Check ThemeInfo File of ' . $this->getName(), 9090);
248
        }
249
    }
250
251
    public function getRenderEngine()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
252
    {
253
        return $this->theme_info['renderengine'];
254
    }
255
256
    public function isBackendTheme()
257
    {
258
        return (bool) $this->theme_info['backendtheme'];
259
    }
260
261
    public function isFrontendTheme()
262
    {
263
        return (bool) $this->theme_info['backendtheme'] === true ? false : true;
264
    }
265
266
    public function getArray()
267
    {
268
        return $this->theme_info;
269
    }
270
271
    public static function getThemeDirectories()
272
    {
273
        return array_merge(
274
            self::iterateDir(APPLICATION_PATH . 'themes/frontend/', 'frontend'),
275
            self::iterateDir(APPLICATION_PATH . 'themes/backend/', 'backend')
276
        );
277
    }
278
279
    /**
280
     * Iterates over a theme dir (backend / frontend) and fetches some data.
281
     *
282
     * @param string $dir             APPLICATION_FRONTEND_THEMES_PATH, APPLICATION_BACKEND_THEMES_PATH
283
     * @param string $type            'frontend' or 'backend'
284
     * @param bool   $only_index_name
285
     *
286
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
287
     */
288
    protected static function iterateDir($dir, $type, $only_index_name = true)
0 ignored issues
show
Coding Style introduced by
$only_index_name does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
289
    {
290
        $dirs    = '';
0 ignored issues
show
Unused Code introduced by
$dirs is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
291
        $dir_tmp = '';
0 ignored issues
show
Coding Style introduced by
$dir_tmp does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
292
        $i       = 0;
293
        $themes  = [];
294
295
        $dirs = new \DirectoryIterator($dir);
296
297
        foreach ($dirs as $dir) {
298
            /*
299
             * Skip early on dots, like "." or ".." or ".svn", by cheching the first char.
300
             * we can not use DirectoryIterator::isDot() here, because it only checks "." and "..".
301
             */
302
            $dir_tmp = $dir->getFilename();
0 ignored issues
show
Coding Style introduced by
$dir_tmp does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
303
304
            if ($dir_tmp{0} === '.') {
0 ignored issues
show
Coding Style introduced by
$dir_tmp does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
305
                continue;
306
            }
307
308
            /*
309
             * take only directories in account, which contain a "theme_info.xml" file
310
             */
311
            if (is_file($dir->getPathName() . DIRECTORY_SEPARATOR . 'theme_info.xml')) {
312
                $i = $i + 1;
313
314
                if ($only_index_name === false) {
0 ignored issues
show
Coding Style introduced by
$only_index_name does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
315
                    // add fullpath
316
                    $themes[$i]['path'] = $dir->getPathName();
317
318
                    // set frontend as type
319
                    $themes[$i]['type'] = $type;
320
321
                    // add dirname
322
                    $themes[$i]['name'] = $type . DIRECTORY_SEPARATOR . (string) $dir;
323
                } else {
324
                    // add dirname
325
                    $themes[$i] = $type . DIRECTORY_SEPARATOR . (string) $dir;
326
                }
327
            }
328
        }
329
330
        unset($i, $dirs, $dir_tmp);
0 ignored issues
show
Coding Style introduced by
$dir_tmp does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
331
332
        return $themes;
333
    }
334
}
335