Passed
Push — master ( d7c3ec...93a960 )
by Aimeos
03:37
created

Jobs::createControllers()   B

Complexity

Conditions 8
Paths 5

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 12
c 1
b 0
f 0
nc 5
nop 4
dl 0
loc 24
rs 8.4444
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2022
6
 * @package Controller
7
 * @subpackage Jobs
8
 */
9
10
11
namespace Aimeos\Controller;
12
13
14
/**
15
 * Factory which can create all job controllers
16
 *
17
 * @package Controller
18
 * @subpackage Jobs
19
 */
20
class Jobs
21
{
22
	/**
23
	 * Creates the required controller specified by the given path of controller names.
24
	 *
25
	 * Controllers are created by providing only the domain name, e.g.
26
	 * "stock" for the \Aimeos\Controller\Jobs\Stock\Standard.
27
	 * Please note, that only the default controllers can be created. If you need
28
	 * a specific implementation, you need to use the factory class of the
29
	 * controller to hand over specifc implementation names.
30
	 *
31
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object required by controllers
32
	 * @param \Aimeos\Bootstrap $aimeos \Aimeos\Bootstrap object
33
	 * @param string $path Name of the domain
34
	 * @return \Aimeos\Controller\Jobs\Iface Controller class instance
35
	 * @throws \Aimeos\Controller\Jobs\Exception If the given path is invalid or the controllers wasn't found
36
	 */
37
	public static function create( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\Bootstrap $aimeos, string $path ) : \Aimeos\Controller\Jobs\Iface
38
	{
39
		if( empty( $path ) ) {
40
			throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Controller path is empty' ) );
41
		}
42
43
		$parts = explode( '/', $path );
44
45
		foreach( $parts as $key => $part )
46
		{
47
			if( ctype_alnum( $part ) === false ) {
48
				throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Invalid controller "%1$s" in "%2$s"', $part, $path ) );
49
			}
50
51
			$parts[$key] = ucwords( $part );
52
		}
53
54
		$factory = '\Aimeos\Controller\Jobs\\' . join( '\\', $parts ) . '\Factory';
55
56
		if( class_exists( $factory ) === false ) {
57
			throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Class "%1$s" not found', $factory ) );
58
		}
59
60
		if( ( $controller = call_user_func_array( [$factory, 'create'], [$context, $aimeos] ) ) === false ) {
61
			throw new \Aimeos\Controller\Jobs\Exception( sprintf( 'Invalid factory "%1$s"', $factory ) );
62
		}
63
64
		return $controller;
65
	}
66
67
68
	/**
69
	 * Returns all available controller instances.
70
	 *
71
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object required by controllers
72
	 * @param \Aimeos\Bootstrap $aimeos \Aimeos\Bootstrap object
73
	 * @param array $cntlPaths Associative list of the base path as key and all relative job controller paths (core and extensions)
74
	 * @return \Aimeos\Controller\Jobs\Iface[] Associative list of controller names as values and class instance as values
75
	 */
76
	public static function get( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\Bootstrap $aimeos, array $cntlPaths ) : array
77
	{
78
		$cntlList = [];
79
		$ds = DIRECTORY_SEPARATOR;
80
81
		foreach( $cntlPaths as $path => $list )
82
		{
83
			foreach( $list as $relpath )
84
			{
85
				$path .= $ds . str_replace( '/', $ds, $relpath . '/Controller/Jobs' );
86
87
				if( is_dir( $path ) )
88
				{
89
					$it = new \DirectoryIterator( $path );
90
					$list = self::createControllers( $it, $context, $aimeos );
91
92
					$cntlList = array_merge( $cntlList, $list );
93
				}
94
			}
95
		}
96
97
		ksort( $cntlList );
98
99
		return $cntlList;
100
	}
101
102
103
	/**
104
	 * Instantiates all found factories and stores the controller instances in the class variable.
105
	 *
106
	 * @param \DirectoryIterator $dir Iterator over the (sub-)directory which might contain a factory
107
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object required by controllers
108
	 * @param \Aimeos\Bootstrap $aimeos \Aimeos\Bootstrap object
109
	 * @param string $prefix Part of the class name between "\Aimeos\Controller\Jobs" and "Factory"
110
	 * @return \Aimeos\Controller\Jobs\Iface[] Associative list if prefixes as values and job controller instances as values
111
	 * @throws \Aimeos\Controller\Jobs\Exception If factory name is invalid or if the controller couldn't be instantiated
112
	 */
113
	protected static function createControllers( \DirectoryIterator $dir, \Aimeos\MShop\Context\Item\Iface $context,
114
		\Aimeos\Bootstrap $aimeos, string $prefix = '' ) : array
115
	{
116
		$list = [];
117
118
		foreach( $dir as $entry )
119
		{
120
			if( $entry->getType() === 'dir' && $entry->isDot() === false )
121
			{
122
				$name = strtolower( $entry->getBaseName() );
123
				$it = new \DirectoryIterator( $entry->getPathName() );
124
				$pref = ( $prefix !== '' ? $prefix . '/' : '' ) . $name;
125
				$subList = self::createControllers( $it, $context, $aimeos, $pref );
126
127
				$list = array_merge( $list, $subList );
128
			}
129
			else if( $prefix !== '' && $entry->getType() === 'file'
130
				&& $entry->getBaseName( '.php' ) === 'Factory' )
131
			{
132
				$list[$prefix] = self::create( $context, $aimeos, $prefix );
133
			}
134
		}
135
136
		return $list;
137
	}
138
}
139