Completed
Push — master ( b98343...f157ac )
by Aimeos
03:37
created

Base::__call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015
6
 * @package Admin
7
 * @subpackage JQAdm
8
 */
9
10
11
namespace Aimeos\Admin\JQAdm;
12
13
14
/**
15
 * Common abstract class for all admin client classes.
16
 *
17
 * @package Admin
18
 * @subpackage JQAdm
19
 */
20
abstract class Base
21
	implements \Aimeos\Admin\JQAdm\Iface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
22
{
23
	private $view;
24
	private $context;
25
	private $subclients;
26
	private $templatePaths;
27
28
29
	/**
30
	 * Initializes the class instance.
31
	 *
32
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
33
	 * @param array $templatePaths Associative list of the file system paths to the core or the extensions as key
34
	 * 	and a list of relative paths inside the core or the extension as values
35
	 */
36
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths )
37
	{
38
		$this->context = $context;
39
		$this->templatePaths = $templatePaths;
40
	}
41
42
43
	/**
44
	 * Catches unknown methods
45
	 *
46
	 * @param string $name Name of the method
47
	 * @param array $param List of method parameter
48
	 * @return boolean False for every call
49
	 */
50
	public function __call( $name, array $param )
51
	{
52
		return false;
53
	}
54
55
56
	/**
57
	 * Returns the view object that will generate the admin output.
58
	 *
59
	 * @return \Aimeos\MW\View\Iface $view The view object which generates the admin output
60
	 */
61
	public function getView()
62
	{
63
		if( !isset( $this->view ) ) {
64
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'No view available' ) );
65
		}
66
67
		return $this->view;
68
	}
69
70
71
	/**
72
	 * Sets the view object that will generate the admin output.
73
	 *
74
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the admin output
75
	 * @return \Aimeos\Admin\JQAdm\Iface Reference to this object for fluent calls
76
	 */
77
	public function setView( \Aimeos\MW\View\Iface $view )
78
	{
79
		$this->view = $view;
80
		return $this;
81
	}
82
83
84
	/**
85
	 * Deletes a resource
86
	 *
87
	 * @return string|null admin output to display or null for redirecting to the list
88
	 */
89
	public function delete()
90
	{
91
	}
92
93
94
	/**
95
	 * Returns a list of resource according to the conditions
96
	 *
97
	 * @return string admin output to display
98
	 */
99
	public function search()
100
	{
101
	}
102
103
104
	/**
105
	 * Adds the decorators to the client object
106
	 *
107
	 * @param \Aimeos\Admin\JQAdm\Iface $client Admin object
108
	 * @param array $templatePaths List of file system paths where the templates are stored
109
	 * @param array $decorators List of decorator name that should be wrapped around the client
110
	 * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Admin\JQAdm\Catalog\Decorator\"
111
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
112
	 */
113
	protected function addDecorators( \Aimeos\Admin\JQAdm\Iface $client, array $templatePaths,
114
		array $decorators, $classprefix )
115
	{
116
		$iface = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\Iface';
117
118
		foreach( $decorators as $name )
119
		{
120
			if( ctype_alnum( $name ) === false )
121
			{
122
				$classname = is_string( $name ) ? $classprefix . $name : '<not a string>';
123
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Invalid class name "%1$s"', $classname ) );
124
			}
125
126
			$classname = $classprefix . $name;
127
128
			if( class_exists( $classname ) === false ) {
129
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" not found', $classname ) );
130
			}
131
132
			$client = new $classname( $client, $this->context, $this->templatePaths );
133
134
			if( !( $client instanceof $iface ) ) {
135
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" does not implement "%2$s"', $classname, $iface ) );
136
			}
137
		}
138
139
		return $client;
140
	}
141
142
143
	/**
144
	 * Adds the decorators to the client object
145
	 *
146
	 * @param \Aimeos\Admin\JQAdm\Iface $client Admin object
147
	 * @param array $templatePaths List of file system paths where the templates are stored
148
	 * @param string $path Admin string in lower case, e.g. "catalog/detail/basic"
149
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
150
	 */
151
	protected function addClientDecorators( \Aimeos\Admin\JQAdm\Iface $client, array $templatePaths, $path )
152
	{
153
		if( !is_string( $path ) || $path === '' ) {
154
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Invalid domain "%1$s"', $path ) );
155
		}
156
157
		$localClass = str_replace( ' ', '\\', ucwords( str_replace( '/', ' ', $path ) ) );
158
		$config = $this->context->getConfig();
159
160
		$decorators = $config->get( 'admin/jqadm/common/decorators/default', array() );
161
		$excludes = $config->get( 'admin/jqadm/' . $path . '/decorators/excludes', array() );
162
163
		foreach( $decorators as $key => $name )
164
		{
165
			if( in_array( $name, $excludes ) ) {
166
				unset( $decorators[$key] );
167
			}
168
		}
169
170
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\';
171
		$client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
172
173
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\';
174
		$decorators = $config->get( 'admin/jqadm/' . $path . '/decorators/global', array() );
175
		$client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
176
177
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\' . $localClass . '\\Decorator\\';
178
		$decorators = $config->get( 'admin/jqadm/' . $path . '/decorators/local', array() );
179
		$client = $this->addDecorators( $client, $templatePaths, $decorators, $classprefix );
180
181
		return $client;
182
	}
183
184
185
	/**
186
	 * Returns the sub-client given by its name.
187
	 *
188
	 * @param string $path Name of the sub-part in lower case (can contain a path like catalog/filter/tree)
189
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
190
	 * @return \Aimeos\Admin\JQAdm\Iface Sub-part object
191
	 */
192
	protected function createSubClient( $path, $name )
193
	{
194
		$path = strtolower( $path );
195
196
		if( $name === null ) {
197
			$name = $this->context->getConfig()->get( 'admin/jqadm/' . $path . '/name', 'Standard' );
198
		}
199
200
		if( empty( $name ) || ctype_alnum( $name ) === false ) {
201
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Invalid characters in client name "%1$s"', $name ) );
202
		}
203
204
		$subnames = str_replace( ' ', '\\', ucwords( str_replace( '/', ' ', $path ) ) );
205
206
		$classname = '\\Aimeos\\Admin\\JQAdm\\' . $subnames . '\\' . $name;
207
		$interface = '\\Aimeos\\Admin\\JQAdm\\Iface';
208
209
		if( class_exists( $classname ) === false ) {
210
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
211
		}
212
213
		$object = new $classname( $this->context, $this->templatePaths );
214
215
		if( ( $object instanceof $interface ) === false ) {
216
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $interface ) );
217
		}
218
219
		$object = $this->addClientDecorators( $object, $this->templatePaths, $path );
220
		$object->setView( $this->view );
221
222
		return $object;
223
	}
224
225
226
	/**
227
	 * Returns the known client parameters and their values
228
	 *
229
	 * @param array $names List of parameter names
230
	 * @return array Associative list of parameters names as key and their values
231
	 */
232
	protected function getClientParams( $names = array( 'resource', 'site', 'lang', 'fields', 'filter', 'page', 'sort' ) )
233
	{
234
		$list = array();
235
236
		foreach( $names as $name )
237
		{
238
			if( ( $val = $this->view->param( $name ) ) !== null ) {
239
				$list[$name] = $val;
240
			}
241
		}
242
243
		return $list;
244
	}
245
246
247
	/**
248
	 * Returns the context object.
249
	 *
250
	 * @return \Aimeos\MShop\Context\Item\Iface Context object
251
	 */
252
	protected function getContext()
253
	{
254
		return $this->context;
255
	}
256
257
258
	/**
259
	 * Returns the list of sub-client names configured for the client.
260
	 *
261
	 * @return array List of admin client names
262
	 */
263
	abstract protected function getSubClientNames();
264
265
266
	/**
267
	 * Returns the configured sub-clients or the ones named in the default parameter if none are configured.
268
	 *
269
	 * @return array List of sub-clients implementing \Aimeos\Admin\JQAdm\Iface ordered in the same way as the names
270
	 */
271
	protected function getSubClients()
272
	{
273
		if( !isset( $this->subclients ) )
274
		{
275
			$this->subclients = array();
276
277
			foreach( $this->getSubClientNames() as $name ) {
278
				$this->subclients[] = $this->getSubClient( $name );
279
			}
280
		}
281
282
		return $this->subclients;
283
	}
284
285
286
	/**
287
	 * Returns the paths where the layout templates can be found
288
	 *
289
	 * @return array List of template paths
290
	 */
291
	protected function getTemplatePaths()
292
	{
293
		return $this->templatePaths;
294
	}
295
296
297
	/**
298
	 * Initializes the criteria object based on the given parameter
299
	 *
300
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
301
	 * @param array $params List of criteria data with condition, sorting and paging
302
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
303
	 */
304
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params )
305
	{
306
		$this->initCriteriaConditions( $criteria, $params );
307
		$this->initCriteriaSortations( $criteria, $params );
308
		$this->initCriteriaSlice( $criteria, $params );
309
310
		return $criteria;
311
	}
312
313
314
	/**
315
	 * Initializes the criteria object with conditions based on the given parameter
316
	 *
317
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
318
	 * @param array $params List of criteria data with condition, sorting and paging
319
	 */
320
	private function initCriteriaConditions( \Aimeos\MW\Criteria\Iface $criteria, array $params )
321
	{
322
		if( isset( $params['filter'] ) && isset( $params['filter']['key'] ) )
323
		{
324
			$expr = array();
325
			$existing = $criteria->getConditions();
326
327
			foreach( (array) $params['filter']['key'] as $idx => $key )
328
			{
329
				if( $key != '' && isset( $params['filter']['op'][$idx] ) && $params['filter']['op'][$idx] != ''
330
					&& isset( $params['filter']['val'][$idx] )
331
				) {
332
					$expr[] = $criteria->compare( $params['filter']['op'][$idx], $key, $params['filter']['val'][$idx] );
333
				}
334
			}
335
336
			$expr[] = $existing;
337
			$criteria->setConditions( $criteria->combine( '&&', $expr ) );
338
		}
339
	}
340
341
342
	/**
343
	 * Initializes the criteria object with the slice based on the given parameter.
344
	 *
345
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
346
	 * @param array $params List of criteria data with condition, sorting and paging
347
	 */
348
	private function initCriteriaSlice( \Aimeos\MW\Criteria\Iface $criteria, array $params )
349
	{
350
		$start = ( isset( $params['page']['offset'] ) ? $params['page']['offset'] : 0 );
351
		$size = ( isset( $params['page']['limit'] ) ? $params['page']['limit'] : 100 );
352
353
		$criteria->setSlice( $start, $size );
354
	}
355
356
357
	/**
358
	 * Initializes the criteria object with sortations based on the given parameter
359
	 *
360
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
361
	 * @param array $params List of criteria data with condition, sorting and paging
362
	 */
363
	private function initCriteriaSortations( \Aimeos\MW\Criteria\Iface $criteria, array $params )
364
	{
365
		if( !isset( $params['sort'] ) ) {
366
			return;
367
		}
368
369
		$sortation = array();
370
371
		foreach( (array) $params['sort'] as $sort )
372
		{
373
			if( $sort[0] === '-' ) {
374
				$sortation[] = $criteria->sort( '-', substr( $sort, 1 ) );
375
			} else {
376
				$sortation[] = $criteria->sort( '+', $sort ); break;
377
			}
378
		}
379
380
		$criteria->setSortations( $sortation );
381
	}
382
}
383