Completed
Push — master ( 32337a...5c15c9 )
by Aimeos
10:07
created

Base::register()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 5
nop 2
dl 0
loc 25
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2017
7
 * @package MShop
8
 * @subpackage Plugin
9
 */
10
11
12
namespace Aimeos\MShop\Plugin\Manager;
13
14
15
/**
16
 * Abstract class for plugin managers.
17
 *
18
 * @package MShop
19
 * @subpackage Service
20
 */
21
abstract class Base
22
	extends \Aimeos\MShop\Common\Manager\Base
23
{
24
	private $plugins = [];
25
26
	/**
27
	 * Returns the plugin provider which is responsible for the plugin item.
28
	 *
29
	 * @param \Aimeos\MShop\Plugin\Item\Iface $item Plugin item object
30
	 * @param string $type Plugin type code
31
	 * @return \Aimeos\MShop\Plugin\Provider\Iface Returns the decoratad plugin provider object
32
	 * @throws \Aimeos\MShop\Plugin\Exception If provider couldn't be found
33
	 */
34
	public function getProvider( \Aimeos\MShop\Plugin\Item\Iface $item, $type )
35
	{
36
		$type = ucwords( $type );
37
		$names = explode( ',', $item->getProvider() );
38
39
		if( ctype_alnum( $type ) === false ) {
40
			throw new \Aimeos\MShop\Plugin\Exception( sprintf( 'Invalid characters in type name "%1$s"', $type ) );
41
		}
42
43
		if( ( $provider = array_shift( $names ) ) === null ) {
44
			throw new \Aimeos\MShop\Plugin\Exception( sprintf( 'Provider in "%1$s" not available', $item->getProvider() ) );
45
		}
46
47
		if( ctype_alnum( $provider ) === false ) {
48
			throw new \Aimeos\MShop\Plugin\Exception( sprintf( 'Invalid characters in provider name "%1$s"', $provider ) );
49
		}
50
51
		$interface = '\\Aimeos\\MShop\\Plugin\\Provider\\Factory\\Iface';
52
		$classname = '\\Aimeos\\MShop\\Plugin\\Provider\\' . $type . '\\' . $provider;
53
54
		if( class_exists( $classname ) === false ) {
55
			throw new \Aimeos\MShop\Plugin\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
56
		}
57
58
		$context = $this->getContext();
59
		$config = $context->getConfig();
60
		$provider = new $classname( $context, $item );
61
62
		if( ( $provider instanceof $interface ) === false )
63
		{
64
			$msg = sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $interface );
65
			throw new \Aimeos\MShop\Plugin\Exception( $msg );
66
		}
67
68
		/** mshop/plugin/provider/order/decorators
69
		 * Adds a list of decorators to all order plugin provider objects automatcally
70
		 *
71
		 * Decorators extend the functionality of a class by adding new aspects
72
		 * (e.g. log what is currently done), executing the methods of the underlying
73
		 * class only in certain conditions (e.g. only for logged in users) or
74
		 * modify what is returned to the caller.
75
		 *
76
		 * This option allows you to wrap decorators
77
		 * ("\Aimeos\MShop\Plugin\Provider\Decorator\*") around the order provider.
78
		 *
79
		 *  mshop/plugin/provider/order/decorators = array( 'decorator1' )
80
		 *
81
		 * This would add the decorator named "decorator1" defined by
82
		 * "\Aimeos\MShop\Plugin\Provider\Decorator\Decorator1" to all order provider
83
		 * objects.
84
		 *
85
		 * @param array List of decorator names
86
		 * @since 2014.03
87
		 * @category Developer
88
		 * @see mshop/plugin/provider/order/decorators
89
		 */
90
		$decorators = $config->get( 'mshop/plugin/provider/' . $item->getType() . '/decorators', [] );
91
92
		$provider = $this->addPluginDecorators( $item, $provider, $names );
93
		$provider = $this->addPluginDecorators( $item, $provider, $decorators );
94
95
		return $provider->setObject( $provider );
96
	}
97
98
99
	/**
100
	 * Registers plugins to the given publisher.
101
	 *
102
	 * @param \Aimeos\MW\Observer\Publisher\Iface $publisher Publisher object
103
	 * @param string $type Unique plugin type code
104
	 */
105
	public function register( \Aimeos\MW\Observer\Publisher\Iface $publisher, $type )
106
	{
107
		if( !isset( $this->plugins[$type] ) )
108
		{
109
			$search = $this->getObject()->createSearch( true );
110
111
			$expr = array(
112
				$search->compare( '==', 'plugin.type.code', $type ),
113
				$search->getConditions(),
114
			);
115
116
			$search->setConditions( $search->combine( '&&', $expr ) );
117
			$search->setSortations( array( $search->sort( '+', 'plugin.position' ) ) );
118
119
			$this->plugins[$type] = [];
120
121
			foreach( $this->getObject()->searchItems( $search ) as $item ) {
122
				$this->plugins[$type][$item->getId()] = $this->getProvider( $item, $type );
123
			}
124
		}
125
126
		foreach( $this->plugins[$type] as $plugin ) {
127
			$plugin->register( $publisher );
128
		}
129
	}
130
131
132
	/**
133
	 *
134
	 * @param \Aimeos\MShop\Plugin\Item\Iface $pluginItem Plugin item object
135
	 * @param \Aimeos\MShop\Plugin\Provider\Iface $provider Plugin provider object
136
	 * @param array $names List of decorator names that should be wrapped around the plugin provider object
137
	 * @return \Aimeos\MShop\Plugin\Provider\Iface Plugin provider object
138
	 */
139
	protected function addPluginDecorators( \Aimeos\MShop\Plugin\Item\Iface $pluginItem,
140
		\Aimeos\MShop\Plugin\Provider\Iface $provider, array $names )
141
	{
142
		$iface = '\\Aimeos\\MShop\\Plugin\\Provider\\Decorator\\Iface';
143
		$classprefix = '\\Aimeos\\MShop\\Plugin\\Provider\\Decorator\\';
144
145
		foreach( $names as $name )
146
		{
147
			if( ctype_alnum( $name ) === false ) {
148
				throw new \Aimeos\MShop\Plugin\Exception( sprintf( 'Invalid characters in class name "%1$s"', $name ) );
149
			}
150
151
			$classname = $classprefix . $name;
152
153
			if( class_exists( $classname ) === false ) {
154
				throw new \Aimeos\MShop\Plugin\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
155
			}
156
157
			$provider = new $classname( $this->getContext(), $pluginItem, $provider );
158
159
			if( ( $provider instanceof $iface ) === false ) {
160
				$msg = sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $iface );
161
				throw new \Aimeos\MShop\Plugin\Exception( $msg );
162
			}
163
		}
164
165
		return $provider;
166
	}
167
}