Passed
Push — master ( 419ad9...31c178 )
by Aimeos
26:11 queued 22:42
created

JQAdm::addComponentDecorators()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 50
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 16
c 1
b 0
f 0
nc 3
nop 3
dl 0
loc 50
rs 9.7333
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2022
6
 * @package Admin
7
 * @subpackage JQAdm
8
 */
9
10
11
namespace Aimeos\Admin;
12
13
14
/**
15
 * Common factory for JQAdm clients
16
 *
17
 * @package Admin
18
 * @subpackage JQAdm
19
 */
20
class JQAdm
21
{
22
	private static $objects = [];
23
24
25
	/**
26
	 * Creates a new client object.
27
	 *
28
	 * @param \Aimeos\MShop\ContextIface $context Shop context instance with necessary objects
29
	 * @param \Aimeos\Bootstrap $aimeos Aimeos object
30
	 * @param string $path Type of the client, e.g 'product' for \Aimeos\Admin\JQAdm\Product\Standard
31
	 * @param string|null $name Admin name (default: "Standard")
32
	 * @return \Aimeos\Admin\JQAdm\Iface admin client implementing \Aimeos\Admin\JQAdm\Iface
33
	 * @throws \Aimeos\Admin\JQAdm\Exception If requested client implementation couldn't be found or initialisation fails
34
	 */
35
	public static function create( \Aimeos\MShop\ContextIface $context, \Aimeos\Bootstrap $aimeos, $path, $name = null )
36
	{
37
		if( empty( $path ) ) {
38
			throw new \Aimeos\Admin\JQAdm\Exception( 'Component path is empty', 400 );
39
		}
40
41
		$view = $context->view();
42
		$config = $context->config();
43
44
		if( $view->access( $config->get( 'admin/jqadm/resource/' . $path . '/groups', [] ) ) !== true ) {
45
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Not allowed to access JQAdm "%1$s" client', $path ), 403 );
46
		}
47
48
		if( empty( $name ) ) {
49
			$name = $config->get( 'admin/jqadm/' . $path . '/name', 'Standard' );
50
		}
51
52
		$interface = '\\Aimeos\\Admin\JQAdm\\Iface';
53
		$classname = '\\Aimeos\\Admin\\JQAdm\\' . str_replace( '/', '\\', ucwords( $path, '/' ) ) . '\\' . $name;
54
55
		if( class_exists( $classname ) === false ) {
56
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" not found', $classname ), 404 );
57
		}
58
59
		$client = self::createComponent( $context, $classname, $interface );
60
		$client = self::addComponentDecorators( $context, $client, $path );
61
62
		return $client->setAimeos( $aimeos )->setView( $view )->setObject( $client );
0 ignored issues
show
Bug introduced by
The method setAimeos() does not exist on Aimeos\Admin\JQAdm\Iface. It seems like you code against a sub-type of said class. However, the method does not exist in Aimeos\Admin\JQAdm\Common\Admin\Factory\Iface or Aimeos\Admin\JQAdm\Common\Decorator\Iface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

62
		return $client->/** @scrutinizer ignore-call */ setAimeos( $aimeos )->setView( $view )->setObject( $client );
Loading history...
63
	}
64
65
66
	/**
67
	 * Injects a client object.
68
	 * The object is returned via create() if an instance of the class
69
	 * with the name name is requested.
70
	 *
71
	 * @param string $classname Full name of the class for which the object should be returned
72
	 * @param \Aimeos\Admin\JQAdm\Iface|null $client ExtJS client object
73
	 */
74
	public static function inject( string $classname, \Aimeos\Admin\JQAdm\Iface $client = null )
75
	{
76
		self::$objects['\\' . ltrim( $classname, '\\' )] = $client;
77
	}
78
79
80
	/**
81
	 * Adds the decorators to the client object.
82
	 *
83
	 * @param \Aimeos\MShop\ContextIface $context Context instance with necessary objects
84
	 * @param \Aimeos\Admin\JQAdm\Iface $client Admin object
85
	 * @param string $path Path of the client in lower case, e.g. "catalog/detail"
86
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
87
	 */
88
	protected static function addComponentDecorators( \Aimeos\MShop\ContextIface $context,
89
		\Aimeos\Admin\JQAdm\Iface $client, string $path ) : \Aimeos\Admin\JQAdm\Iface
90
	{
91
		$localClass = str_replace( '/', '\\', ucwords( $path, '/' ) );
92
		$config = $context->config();
93
94
		/** admin/jqadm/common/decorators/default
95
		 * Configures the list of decorators applied to all jqadm clients
96
		 *
97
		 * Decorators extend the functionality of a class by adding new aspects
98
		 * (e.g. log what is currently done), executing the methods of the underlying
99
		 * class only in certain conditions (e.g. only for logged in users) or
100
		 * modify what is returned to the caller.
101
		 *
102
		 * This option allows you to configure a list of decorator names that should
103
		 * be wrapped around the original instance of all created clients:
104
		 *
105
		 *  admin/jqadm/common/decorators/default = array( 'decorator1', 'decorator2' )
106
		 *
107
		 * This would wrap the decorators named "decorator1" and "decorator2" around
108
		 * all client instances in that order. The decorator classes would be
109
		 * "\Aimeos\Admin\JQAdm\Common\Decorator\Decorator1" and
110
		 * "\Aimeos\Admin\JQAdm\Common\Decorator\Decorator2".
111
		 *
112
		 * @param array List of decorator names
113
		 * @since 2014.03
114
		 * @category Developer
115
		 */
116
		$decorators = $config->get( 'admin/jqadm/common/decorators/default', [] );
117
		$excludes = $config->get( 'admin/jqadm/' . $path . '/decorators/excludes', [] );
118
119
		foreach( $decorators as $key => $name )
120
		{
121
			if( in_array( $name, $excludes ) ) {
122
				unset( $decorators[$key] );
123
			}
124
		}
125
126
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\';
127
		$client = self::addDecorators( $context, $client, $decorators, $classprefix );
128
129
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\';
130
		$decorators = $config->get( 'admin/jqadm/' . $path . '/decorators/global', [] );
131
		$client = self::addDecorators( $context, $client, $decorators, $classprefix );
132
133
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\' . $localClass . '\\Decorator\\';
134
		$decorators = $config->get( 'admin/jqadm/' . $path . '/decorators/local', [] );
135
		$client = self::addDecorators( $context, $client, $decorators, $classprefix );
136
137
		return $client;
138
	}
139
140
141
	/**
142
	 * Adds the decorators to the client object.
143
	 *
144
	 * @param \Aimeos\MShop\ContextIface $context Context instance with necessary objects
145
	 * @param \Aimeos\Admin\JQAdm\Iface $client Admin object
146
	 * @param array $decorators List of decorator name that should be wrapped around the client
147
	 * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Admin\JQAdm\Catalog\Decorator\"
148
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
149
	 */
150
	protected static function addDecorators( \Aimeos\MShop\ContextIface $context,
151
		\Aimeos\Admin\JQAdm\Iface $client, array $decorators, string $classprefix ) : \Aimeos\Admin\JQAdm\Iface
152
	{
153
		foreach( $decorators as $name )
154
		{
155
			$classname = $classprefix . $name;
156
157
			if( ctype_alnum( $name ) === false ) {
158
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Invalid class name "%1$s"', $classname ), 400 );
159
			}
160
161
			if( class_exists( $classname ) === false ) {
162
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" not found', $classname ), 404 );
163
			}
164
165
			$client = new $classname( $client, $context );
166
			$interface = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\Iface';
167
168
			if( !( $client instanceof $interface ) )
169
			{
170
				$msg = sprintf( 'Class "%1$s" does not implement "%2$s"', $classname, $interface );
171
				throw new \Aimeos\Admin\JQAdm\Exception( $msg, 400 );
172
			}
173
		}
174
175
		return $client;
176
	}
177
178
179
	/**
180
	 * Creates a client object.
181
	 *
182
	 * @param \Aimeos\MShop\ContextIface $context Context instance with necessary objects
183
	 * @param string $classname Name of the client class
184
	 * @param string $interface Name of the client interface
185
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
186
	 * @throws \Aimeos\Admin\JQAdm\Exception If client couldn't be found or doesn't implement the interface
187
	 */
188
	protected static function createComponent( \Aimeos\MShop\ContextIface $context,
189
		string $classname, string $interface ) : \Aimeos\Admin\JQAdm\Iface
190
	{
191
		if( isset( self::$objects[$classname] ) ) {
192
			return self::$objects[$classname];
193
		}
194
195
		if( class_exists( $classname ) === false ) {
196
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" not found', $classname ), 404 );
197
		}
198
199
		$client = new $classname( $context );
200
201
		if( !( $client instanceof $interface ) )
202
		{
203
			$msg = 'Class "%1$s" does not implement "%2$s"';
204
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( $msg, $classname, $interface ), 400 );
205
		}
206
207
		return $client;
208
	}
209
}
210