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
|
|
|
} |