Passed
Push — master ( d7c3ec...93a960 )
by Aimeos
03:37
created

Base::addControllerDecorators()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 54
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
eloc 18
c 2
b 0
f 0
nc 4
nop 4
dl 0
loc 54
rs 9.3554

How to fix   Long Method   

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
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2013
6
 * @copyright Aimeos (aimeos.org), 2015-2022
7
 * @package Controller
8
 * @subpackage Jobs
9
 */
10
11
12
namespace Aimeos\Controller\Jobs\Common\Factory;
13
14
15
/**
16
 * Common methods for all controller factories.
17
 *
18
 * @package Controller
19
 * @subpackage Jobs
20
 */
21
abstract class Base
22
{
23
	private static $objects = [];
24
25
26
	/**
27
	 * Injects a controller object.
28
	 *
29
	 * @param string $classname Full name of the class for which the object should be returned
30
	 * @param \Aimeos\Controller\Jobs\Iface|null $controller Frontend controller object
31
	 */
32
	public static function injectController( string $classname, \Aimeos\Controller\Jobs\Iface $controller = null )
33
	{
34
		self::$objects[$classname] = $controller;
35
	}
36
37
38
	/**
39
	 * Adds the decorators to the controller object.
40
	 *
41
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context instance with necessary objects
42
	 * @param \Aimeos\Bootstrap $aimeos Aimeos Bootstrap object
43
	 * @param \Aimeos\Controller\Jobs\Iface $controller Controller object
44
	 * @param array $decorators List of decorator names that should be wrapped around the controller object
45
	 * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Controller\Jobs\Attribute\Decorator\"
46
	 * @return \Aimeos\Controller\Jobs\Iface Controller object
47
	 */
48
	protected static function addDecorators( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\Bootstrap $aimeos,
49
		\Aimeos\Controller\Jobs\Iface $controller, array $decorators, string $classprefix ) : \Aimeos\Controller\Jobs\Iface
50
	{
51
		$iface = \Aimeos\Controller\Jobs\Common\Decorator\Iface::class;
52
53
		foreach( $decorators as $name )
54
		{
55
			if( ctype_alnum( $name ) === false )
56
			{
57
				$classname = is_string( $name ) ? $classprefix . $name : '<not a string>';
58
				throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
59
			}
60
61
			$classname = $classprefix . $name;
62
63
			if( class_exists( $classname ) === false ) {
64
				throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
65
			}
66
67
			$controller = new $classname( $controller, $context, $aimeos );
68
69
			if( !( $controller instanceof $iface ) ) {
70
				throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $iface ) );
71
			}
72
		}
73
74
		return $controller;
75
	}
76
77
78
	/**
79
	 * Adds the decorators to the controller object.
80
	 *
81
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context instance with necessary objects
82
	 * @param \Aimeos\Bootstrap $aimeos \Aimeos\Bootstrap object
83
	 * @param \Aimeos\Controller\Jobs\Iface $controller Controller object
84
	 * @param string $domain Domain name in lower case, e.g. "product"
85
	 * @return \Aimeos\Controller\Jobs\Iface Controller object
86
	 */
87
	protected static function addControllerDecorators( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\Bootstrap $aimeos,
88
		\Aimeos\Controller\Jobs\Iface $controller, string $domain ) : \Aimeos\Controller\Jobs\Iface
89
	{
90
		if( !is_string( $domain ) || $domain === '' ) {
0 ignored issues
show
introduced by
The condition is_string($domain) is always true.
Loading history...
91
			throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Invalid domain "%1$s"', $domain ) );
92
		}
93
94
		$localClass = str_replace( '/', '\\', ucwords( $domain, '/' ) );
95
		$config = $context->config();
96
97
		/** controller/jobs/common/decorators/default
98
		 * Configures the list of decorators applied to all job controllers
99
		 *
100
		 * Decorators extend the functionality of a class by adding new aspects
101
		 * (e.g. log what is currently done), executing the methods of the underlying
102
		 * class only in certain conditions (e.g. only for logged in users) or
103
		 * modify what is returned to the caller.
104
		 *
105
		 * This option allows you to configure a list of decorator names that should
106
		 * be wrapped around the original instance of all created controllers:
107
		 *
108
		 *  controller/jobs/common/decorators/default = array( 'decorator1', 'decorator2' )
109
		 *
110
		 * This would wrap the decorators named "decorator1" and "decorator2" around
111
		 * all controller instances in that order. The decorator classes would be
112
		 * "\Aimeos\Controller\Jobs\Common\Decorator\Decorator1" and
113
		 * "\Aimeos\Controller\Jobs\Common\Decorator\Decorator2".
114
		 *
115
		 * @param array List of decorator names
116
		 * @since 2014.03
117
		 * @category Developer
118
		 */
119
		$decorators = $config->get( 'controller/jobs/common/decorators/default', [] );
120
		$excludes = $config->get( 'controller/jobs/' . $domain . '/decorators/excludes', [] );
121
122
		foreach( $decorators as $key => $name )
123
		{
124
			if( in_array( $name, $excludes ) ) {
125
				unset( $decorators[$key] );
126
			}
127
		}
128
129
		$classprefix = '\Aimeos\Controller\Jobs\Common\Decorator\\';
130
		$controller = self::addDecorators( $context, $aimeos, $controller, $decorators, $classprefix );
131
132
		$classprefix = '\Aimeos\Controller\Jobs\Common\Decorator\\';
133
		$decorators = $config->get( 'controller/jobs/' . $domain . '/decorators/global', [] );
134
		$controller = self::addDecorators( $context, $aimeos, $controller, $decorators, $classprefix );
135
136
		$classprefix = '\Aimeos\Controller\Jobs\\' . ucfirst( $localClass ) . '\Decorator\\';
137
		$decorators = $config->get( 'controller/jobs/' . $domain . '/decorators/local', [] );
138
		$controller = self::addDecorators( $context, $aimeos, $controller, $decorators, $classprefix );
139
140
		return $controller;
141
	}
142
143
144
	/**
145
	 * Creates a controller object.
146
	 *
147
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context instance with necessary objects
148
	 * @param \Aimeos\Bootstrap $aimeos \Aimeos\Bootstrap object
149
	 * @param string $classname Name of the controller class
150
	 * @param string $interface Name of the controller interface
151
	 * @return \Aimeos\Controller\Jobs\Iface Controller object
152
	 */
153
	protected static function createController( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\Bootstrap $aimeos,
154
		string $classname, string $interface ) : \Aimeos\Controller\Jobs\Iface
155
	{
156
		if( isset( self::$objects[$classname] ) ) {
157
			return self::$objects[$classname];
158
		}
159
160
		if( class_exists( $classname ) === false ) {
161
			throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
162
		}
163
164
		$controller = new $classname( $context, $aimeos );
165
166
		if( !( $controller instanceof $interface ) ) {
167
			throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $interface ) );
168
		}
169
170
		return $controller;
171
	}
172
}
173