JQAdm::addComponentDecorators()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 49
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 3
nop 3
dl 0
loc 49
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2025
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,
36
		string $path, ?string $name = null ) : \Aimeos\Admin\JQAdm\Iface
37
	{
38
		if( empty( $path ) ) {
39
			throw new \Aimeos\Admin\JQAdm\Exception( 'Component path is empty', 400 );
40
		}
41
42
		$view = $context->view();
43
		$config = $context->config();
44
45
		if( $view->access( $config->get( 'admin/jqadm/resource/' . $path . '/groups', [] ) ) !== true ) {
46
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Not allowed to access JQAdm "%1$s" client', $path ), 403 );
47
		}
48
49
		if( empty( $name ) ) {
50
			$name = $config->get( 'admin/jqadm/' . $path . '/name', 'Standard' );
51
		}
52
53
		$interface = '\\Aimeos\\Admin\JQAdm\\Iface';
54
		$classname = '\\Aimeos\\Admin\\JQAdm\\' . str_replace( '/', '\\', ucwords( $path, '/' ) ) . '\\' . $name;
55
56
		if( class_exists( $classname ) === false ) {
57
			throw new \LogicException( sprintf( 'Class "%1$s" not found', $classname ), 404 );
58
		}
59
60
		$client = self::createComponent( $context, $classname, $interface, $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
		$config = $context->config();
92
		$localClass = str_replace( '/', '\\', ucwords( $path, '/' ) );
93
94
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\' . $localClass . '\\Decorator\\';
95
		$decorators = array_reverse( $config->get( 'admin/jqadm/' . $path . '/decorators/local', [] ) );
96
		$client = self::addDecorators( $context, $client, $decorators, $classprefix );
97
98
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\';
99
		$decorators = array_reverse( $config->get( 'admin/jqadm/' . $path . '/decorators/global', [] ) );
100
		$client = self::addDecorators( $context, $client, $decorators, $classprefix );
101
102
		/** admin/jqadm/common/decorators/default
103
		 * Configures the list of decorators applied to all jqadm clients
104
		 *
105
		 * Decorators extend the functionality of a class by adding new aspects
106
		 * (e.g. log what is currently done), executing the methods of the underlying
107
		 * class only in certain conditions (e.g. only for logged in users) or
108
		 * modify what is returned to the caller.
109
		 *
110
		 * This option allows you to configure a list of decorator names that should
111
		 * be wrapped around the original instance of all created clients:
112
		 *
113
		 *  admin/jqadm/common/decorators/default = array( 'decorator1', 'decorator2' )
114
		 *
115
		 * This would wrap the decorators named "decorator1" and "decorator2" around
116
		 * all client instances in that order. The decorator classes would be
117
		 * "\Aimeos\Admin\JQAdm\Common\Decorator\Decorator1" and
118
		 * "\Aimeos\Admin\JQAdm\Common\Decorator\Decorator2".
119
		 *
120
		 * @param array List of decorator names
121
		 * @since 2014.03
122
		 */
123
		$decorators = array_reverse( $config->get( 'admin/jqadm/common/decorators/default', [] ) );
124
		$excludes = $config->get( 'admin/jqadm/' . $path . '/decorators/excludes', [] );
125
126
		foreach( $decorators as $key => $name )
127
		{
128
			if( in_array( $name, $excludes ) ) {
129
				unset( $decorators[$key] );
130
			}
131
		}
132
133
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\';
134
		$client = self::addDecorators( $context, $client, $decorators, $classprefix );
135
136
		return $client;
137
	}
138
139
140
	/**
141
	 * Adds the decorators to the client object.
142
	 *
143
	 * @param \Aimeos\MShop\ContextIface $context Context instance with necessary objects
144
	 * @param \Aimeos\Admin\JQAdm\Iface $client Admin object
145
	 * @param array $decorators List of decorator name that should be wrapped around the client
146
	 * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Admin\JQAdm\Catalog\Decorator\"
147
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
148
	 * @throws \LogicException If class can't be instantiated
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
		$interface = \Aimeos\Admin\JQAdm\Common\Decorator\Iface::class;
154
155
		foreach( $decorators as $name )
156
		{
157
			if( ctype_alnum( $name ) === false ) {
158
				throw new \LogicException( sprintf( 'Invalid class name "%1$s"', $name ), 400 );
159
			}
160
161
			$client = \Aimeos\Utils::create( $classprefix . $name, [$client, $context], $interface );
162
		}
163
164
		return $client;
165
	}
166
167
168
	/**
169
	 * Creates a client object.
170
	 *
171
	 * @param \Aimeos\MShop\ContextIface $context Context instance with necessary objects
172
	 * @param string $classname Name of the client class
173
	 * @param string $interface Name of the client interface
174
	 * @param string $path Type of the client, e.g 'product' for \Aimeos\Admin\JQAdm\Product\Standard
175
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
176
	 * @throws \Aimeos\Admin\JQAdm\Exception If client couldn't be found or doesn't implement the interface
177
	 */
178
	protected static function createComponent( \Aimeos\MShop\ContextIface $context,
179
		string $classname, string $interface, string $path ) : \Aimeos\Admin\JQAdm\Iface
180
	{
181
		if( isset( self::$objects[$classname] ) ) {
182
			return self::$objects[$classname];
183
		}
184
185
		$client = \Aimeos\Utils::create( $classname, [$context], $interface );
186
187
		return self::addComponentDecorators( $context, $client, $path );
188
	}
189
}
190