Completed
Push — master ( 5333a1...a1df86 )
by Aimeos
06:43
created

Factory::createClientNew()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 153
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 153
rs 5.2676
c 0
b 0
f 0
cc 8
eloc 21
nc 10
nop 4

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, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2016
6
 * @package Admin
7
 * @subpackage JsonAdm
8
 */
9
10
11
namespace Aimeos\Admin\JsonAdm;
12
13
14
/**
15
 * Factory which can create all JSON API clients
16
 *
17
 * @package Admin
18
 * @subpackage JsonAdm
19
 */
20
class Factory
21
	extends \Aimeos\Admin\JsonAdm\Common\Factory\Base
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
22
	implements \Aimeos\Admin\JsonAdm\Common\Factory\Iface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
23
{
24
	static private $cache = true;
25
	static private $clients = [];
26
27
28
	/**
29
	 * Removes the client objects from the cache.
30
	 *
31
	 * If neither a context ID nor a path is given, the complete cache will be pruned.
32
	 *
33
	 * @param integer $id Context ID the objects have been created with (string of \Aimeos\MShop\Context\Item\Iface)
34
	 * @param string $path Path describing the client to clear, e.g. "product/lists/type"
35
	 */
36
	static public function clear( $id = null, $path = null )
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
37
	{
38
		if( $id !== null )
39
		{
40
			if( $path !== null ) {
41
				self::$clients[$id][$path] = null;
42
			} else {
43
				self::$clients[$id] = [];
44
			}
45
46
			return;
47
		}
48
49
		self::$clients = [];
50
	}
51
52
53
	/**
54
	 * Creates the required client specified by the given path of client names.
55
	 *
56
	 * Clients are created by providing only the domain name, e.g. "product"
57
	 *  for the \Aimeos\Admin\JsonAdm\Product\Standard or a path of names to
58
	 * retrieve a specific sub-client, e.g. "product/type" for the
59
	 * \Aimeos\Admin\JsonAdm\Product\Type\Standard client.
60
	 *
61
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object required by clients
62
	 * @param array $templatePaths List of file system paths where the templates are stored
63
	 * @param string $path Name of the client separated by slashes, e.g "product/stock"
64
	 * @param string|null $name Name of the client implementation ("Standard" if null)
65
	 * @return \Aimeos\Admin\JsonAdm\Iface JSON admin instance
66
	 * @throws \Aimeos\Admin\JsonAdm\Exception If the given path is invalid
67
	 */
68
	static public function createClient( \Aimeos\MShop\Context\Item\Iface $context,
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
69
		array $templatePaths, $path, $name = null )
70
	{
71
		$path = strtolower( trim( $path, "/ \n\t\r\0\x0B" ) );
72
		$id = (string) $context;
73
74
		if( self::$cache === false || !isset( self::$clients[$id][$path] ) ) {
75
			self::$clients[$id][$path] = self::createClientNew( $context, $templatePaths, $path, $name );
76
		}
77
78
		return self::$clients[$id][$path];
79
	}
80
81
82
	/**
83
	 * Enables or disables caching of class instances.
84
	 *
85
	 * @param boolean $value True to enable caching, false to disable it.
86
	 * @return boolean Previous cache setting
87
	 */
88
	static public function setCache( $value )
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
89
	{
90
		$old = self::$cache;
91
		self::$cache = (boolean) $value;
92
93
		return $old;
94
	}
95
96
97
	/**
98
	 * Creates a new client specified by the given path of client names.
99
	 *
100
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object required by clients
101
	 * @param array $templatePaths List of file system paths where the templates are stored
102
	 * @param string $path Name of the client separated by slashes, e.g "product/stock"
103
	 * @param string|null $name Name of the client implementation ("Standard" if null)
104
	 * @return \Aimeos\Admin\JsonAdm\Iface JSON admin instance
105
	 * @throws \Aimeos\Admin\JsonAdm\Exception If the given path is invalid
106
	 */
107
	protected static function createClientNew( \Aimeos\MShop\Context\Item\Iface $context,
108
		array $templatePaths, $path, $name )
109
	{
110
		if( !empty( $path ) )
111
		{
112
			$parts = explode( '/', $path );
113
114
			foreach( $parts as $key => $part )
115
			{
116
				if( ctype_alnum( $part ) === false )
117
				{
118
					$msg = sprintf( 'Invalid client "%1$s" in "%2$s"', $part, $path );
119
					throw new \Aimeos\Admin\JsonAdm\Exception( $msg, 400 );
120
				}
121
122
				$parts[$key] = ucwords( $part );
123
			}
124
125
			$name = ( $name ?: $context->getConfig()->get( 'admin/jsonadm/' . $path . '/name', 'Standard' ) );
126
			$classname = '\\Aimeos\\Admin\\JsonAdm\\' . join( '\\', $parts ) . '\\' . $name;
127
		}
128
		else
129
		{
130
			/** admin/jsonadm/name
131
			 * Class name of the used JSON API client implementation
132
			 *
133
			 * Each default JSON API client can be replace by an alternative imlementation.
134
			 * To use this implementation, you have to set the last part of the class
135
			 * name as configuration value so the client factory knows which class it
136
			 * has to instantiate.
137
			 *
138
			 * For example, if the name of the default class is
139
			 *
140
			 *  \Aimeos\Admin\JsonAdm\Standard
141
			 *
142
			 * and you want to replace it with your own version named
143
			 *
144
			 *  \Aimeos\Admin\JsonAdm\Mycntl
145
			 *
146
			 * then you have to set the this configuration option:
147
			 *
148
			 *  admin/jsonadm/name = Mycntl
149
			 *
150
			 * The value is the last part of your own class name and it's case sensitive,
151
			 * so take care that the configuration value is exactly named like the last
152
			 * part of the class name.
153
			 *
154
			 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
155
			 * characters are possible! You should always start the last part of the class
156
			 * name with an upper case character and continue only with lower case characters
157
			 * or numbers. Avoid chamel case names like "MyCntl"!
158
			 *
159
			 * @param string Last part of the class name
160
			 * @since 2015.12
161
			 * @category Developer
162
			 */
163
164
			$name = ( $name ?: $context->getConfig()->get( 'admin/jsonadm/name', 'Standard' ) );
165
			$classname = '\\Aimeos\\Admin\\JsonAdm\\' . $name;
166
		}
167
168
169
		if( ctype_alnum( $name ) === false )
170
		{
171
			$classname = is_string( $name ) ? $classname : '<not a string>';
172
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Invalid class name "%1$s"', $classname ) );
173
		}
174
175
		$view = $context->getView();
176
		$iface = '\\Aimeos\\Admin\\JsonAdm\\Iface';
177
178
		$client = self::createClientBase( $classname, $iface, $context, $view, $templatePaths, $path );
179
180
		/** admin/jsonadm/decorators/excludes
181
		 * Excludes decorators added by the "common" option from the JSON API clients
182
		 *
183
		 * Decorators extend the functionality of a class by adding new aspects
184
		 * (e.g. log what is currently done), executing the methods of the underlying
185
		 * class only in certain conditions (e.g. only for logged in users) or
186
		 * modify what is returned to the caller.
187
		 *
188
		 * This option allows you to remove a decorator added via
189
		 * "admin/jsonadm/common/decorators/default" before they are wrapped
190
		 * around the Jsonadm client.
191
		 *
192
		 *  admin/jsonadm/decorators/excludes = array( 'decorator1' )
193
		 *
194
		 * This would remove the decorator named "decorator1" from the list of
195
		 * common decorators ("\Aimeos\Admin\JsonAdm\Common\Decorator\*") added via
196
		 * "admin/jsonadm/common/decorators/default" for the JSON API client.
197
		 *
198
		 * @param array List of decorator names
199
		 * @since 2016.01
200
		 * @category Developer
201
		 * @see admin/jsonadm/common/decorators/default
202
		 * @see admin/jsonadm/decorators/global
203
		 * @see admin/jsonadm/decorators/local
204
		 */
205
206
		/** admin/jsonadm/decorators/global
207
		 * Adds a list of globally available decorators only to the Jsonadm client
208
		 *
209
		 * Decorators extend the functionality of a class by adding new aspects
210
		 * (e.g. log what is currently done), executing the methods of the underlying
211
		 * class only in certain conditions (e.g. only for logged in users) or
212
		 * modify what is returned to the caller.
213
		 *
214
		 * This option allows you to wrap global decorators
215
		 * ("\Aimeos\Admin\Jsonadm\Common\Decorator\*") around the Jsonadm
216
		 * client.
217
		 *
218
		 *  admin/jsonadm/product/decorators/global = array( 'decorator1' )
219
		 *
220
		 * This would add the decorator named "decorator1" defined by
221
		 * "\Aimeos\Admin\Jsonadm\Common\Decorator\Decorator1" only to the
222
		 * "product" Jsonadm client.
223
		 *
224
		 * @param array List of decorator names
225
		 * @since 2016.01
226
		 * @category Developer
227
		 * @see admin/jsonadm/common/decorators/default
228
		 * @see admin/jsonadm/decorators/excludes
229
		 * @see admin/jsonadm/decorators/local
230
		 */
231
232
		/** admin/jsonadm/decorators/local
233
		 * Adds a list of local decorators only to the Jsonadm client
234
		 *
235
		 * Decorators extend the functionality of a class by adding new aspects
236
		 * (e.g. log what is currently done), executing the methods of the underlying
237
		 * class only in certain conditions (e.g. only for logged in users) or
238
		 * modify what is returned to the caller.
239
		 *
240
		 * This option allows you to wrap local decorators
241
		 * ("\Aimeos\Admin\Jsonadm\Product\Decorator\*") around the Jsonadm
242
		 * client.
243
		 *
244
		 *  admin/jsonadm/product/decorators/local = array( 'decorator2' )
245
		 *
246
		 * This would add the decorator named "decorator2" defined by
247
		 * "\Aimeos\Admin\Jsonadm\Product\Decorator\Decorator2" only to the
248
		 * "product" Jsonadm client.
249
		 *
250
		 * @param array List of decorator names
251
		 * @since 2016.01
252
		 * @category Developer
253
		 * @see admin/jsonadm/common/decorators/default
254
		 * @see admin/jsonadm/decorators/excludes
255
		 * @see admin/jsonadm/decorators/global
256
		 */
257
258
		return self::addClientDecorators( $client, $context, $view, $templatePaths, $path );
259
	}
260
}
261