Completed
Push — master ( fbc717...7baaae )
by Aimeos
09:41
created

Base::getProvider()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 84
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 22
nc 6
nop 1
dl 0
loc 84
rs 8.35
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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-2016
7
 * @package MShop
8
 * @subpackage Service
9
 */
10
11
12
namespace Aimeos\MShop\Service\Manager;
13
14
15
/**
16
 * Abstract class for service managers.
17
 *
18
 * @package MShop
19
 * @subpackage Service
20
 */
21
abstract class Base
22
	extends \Aimeos\MShop\Common\Manager\ListRef\Base
23
{
24
	/**
25
	 * Returns the service provider which is responsible for the service item.
26
	 *
27
	 * @param \Aimeos\MShop\Service\Item\Iface $item Delivery or payment service item object
28
	 * @return \Aimeos\MShop\Service\Provider\Iface Returns a service provider implementing \Aimeos\MShop\Service\Provider\Iface
29
	 * @throws \Aimeos\MShop\Service\Exception If provider couldn't be found
30
	 */
31
	public function getProvider( \Aimeos\MShop\Service\Item\Iface $item )
32
	{
33
		$type = ucwords( $item->getType() );
34
		$names = explode( ',', $item->getProvider() );
35
36
		if( ctype_alnum( $type ) === false ) {
37
			throw new \Aimeos\MShop\Service\Exception( sprintf( 'Invalid characters in type name "%1$s"', $type ) );
38
		}
39
40
		if( ( $provider = array_shift( $names ) ) === null ) {
41
			throw new \Aimeos\MShop\Service\Exception( sprintf( 'Provider in "%1$s" not available', $item->getProvider() ) );
42
		}
43
44
		if( ctype_alnum( $provider ) === false ) {
45
			throw new \Aimeos\MShop\Service\Exception( sprintf( 'Invalid characters in provider name "%1$s"', $provider ) );
46
		}
47
48
		$interface = '\\Aimeos\\MShop\\Service\\Provider\\Factory\\Iface';
49
		$classname = '\\Aimeos\\MShop\\Service\\Provider\\' . $type . '\\' . $provider;
50
51
		if( class_exists( $classname ) === false ) {
52
			throw new \Aimeos\MShop\Service\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
53
		}
54
55
		$context = $this->getContext();
56
		$config = $context->getConfig();
57
		$provider = new $classname( $context, $item );
58
59
		if( ( $provider instanceof $interface ) === false )
60
		{
61
			$msg = sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $interface );
62
			throw new \Aimeos\MShop\Service\Exception( $msg );
63
		}
64
65
		/** mshop/service/provider/delivery/decorators
66
		 * Adds a list of decorators to all delivery provider objects automatcally
67
		 *
68
		 * Decorators extend the functionality of a class by adding new aspects
69
		 * (e.g. log what is currently done), executing the methods of the underlying
70
		 * class only in certain conditions (e.g. only for logged in users) or
71
		 * modify what is returned to the caller.
72
		 *
73
		 * This option allows you to wrap decorators
74
		 * ("\Aimeos\MShop\Service\Provider\Decorator\*") around the delivery provider.
75
		 *
76
		 *  mshop/service/provider/delivery/decorators = array( 'decorator1' )
77
		 *
78
		 * This would add the decorator named "decorator1" defined by
79
		 * "\Aimeos\MShop\Service\Provider\Decorator\Decorator1" to all delivery provider
80
		 * objects.
81
		 *
82
		 * @param array List of decorator names
83
		 * @since 2014.03
84
		 * @category Developer
85
		 * @see mshop/service/provider/payment/decorators
86
		 */
87
88
		/** mshop/service/provider/payment/decorators
89
		 * Adds a list of decorators to all payment provider objects automatcally
90
		 *
91
		 * Decorators extend the functionality of a class by adding new aspects
92
		 * (e.g. log what is currently done), executing the methods of the underlying
93
		 * class only in certain conditions (e.g. only for logged in users) or
94
		 * modify what is returned to the caller.
95
		 *
96
		 * This option allows you to wrap decorators
97
		 * ("\Aimeos\MShop\Service\Provider\Decorator\*") around the payment provider.
98
		 *
99
		 *  mshop/service/provider/payment/decorators = array( 'decorator1' )
100
		 *
101
		 * This would add the decorator named "decorator1" defined by
102
		 * "\Aimeos\MShop\Service\Provider\Decorator\Decorator1" to all payment provider
103
		 * objects.
104
		 *
105
		 * @param array List of decorator names
106
		 * @since 2014.03
107
		 * @category Developer
108
		 * @see mshop/service/provider/delivery/decorators
109
		 */
110
		$decorators = $config->get( 'mshop/service/provider/' . $item->getType() . '/decorators', [] );
111
112
		$provider = $this->addServiceDecorators( $item, $provider, $names );
113
		return $this->addServiceDecorators( $item, $provider, $decorators );
114
	}
115
116
117
	/**
118
	 * Wraps the named service decorators around the service provider.
119
	 *
120
	 * @param \Aimeos\MShop\Service\Item\Iface $serviceItem Service item object
121
	 * @param \Aimeos\MShop\Service\Provider\Iface $provider Service provider object
122
	 * @param array $names List of decorator names that should be wrapped around the provider object
123
	 * @return \Aimeos\MShop\Service\Provider\Iface
124
	 */
125
	protected function addServiceDecorators( \Aimeos\MShop\Service\Item\Iface $serviceItem,
126
		\Aimeos\MShop\Service\Provider\Iface $provider, array $names )
127
	{
128
		$iface = '\\Aimeos\\MShop\\Service\\Provider\\Decorator\\Iface';
129
		$classprefix = '\\Aimeos\\MShop\\Service\\Provider\\Decorator\\';
130
131
		foreach( $names as $name )
132
		{
133
			if( ctype_alnum( $name ) === false ) {
134
				throw new \Aimeos\MShop\Service\Exception( sprintf( 'Invalid characters in class name "%1$s"', $name ) );
135
			}
136
137
			$classname = $classprefix . $name;
138
139
			if( class_exists( $classname ) === false ) {
140
				throw new \Aimeos\MShop\Service\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
141
			}
142
143
			$provider = new $classname( $provider, $this->getContext(), $serviceItem );
144
145
			if( ( $provider instanceof $iface ) === false ) {
146
				$msg = sprintf( 'Class "%1$s" does not implement interface "%2$s"', $classname, $iface );
147
				throw new \Aimeos\MShop\Service\Exception( $msg );
148
			}
149
		}
150
151
		return $provider;
152
	}
153
}