Completed
Push — master ( bca19f...60fe0a )
by Aimeos
11:40
created

AimeosCommandController   B

Complexity

Total Complexity 21

Size/Duplication

Total Lines 283
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 16
dl 0
loc 283
rs 8.4614
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
B cacheCommand() 0 36 4
B jobsCommand() 0 31 3
B setupCommand() 0 30 4
B getContext() 0 24 1
A getDbConfig() 0 13 3
A getSiteItems() 0 11 2
A injectCache() 0 4 1
A injectObjectManager() 0 4 1
A setOptions() 0 8 2
1
<?php
2
3
/**
4
 * @license LGPLv3, http://www.gnu.org/copyleft/lgpl.html
5
 * @copyright Aimeos (aimeos.org), 2015-2016
6
 * @package flow
7
 * @subpackage Command
8
 */
9
10
11
namespace Aimeos\Shop\Command;
12
13
use Neos\Flow\Annotations as Flow;
14
15
16
/**
17
 * Aimeos CLI controller for cronjobs
18
 *
19
 * @package flow
20
 * @subpackage Command
21
 * @Flow\Scope("singleton")
22
 */
23
class AimeosCommandController extends \Neos\Flow\Cli\CommandController
24
{
25
	/**
26
	 * @var string
27
	 * @Flow\InjectConfiguration(path="http.baseUri", package="Neos.Flow")
28
	 */
29
	protected $baseUri;
30
31
	/**
32
	 * @var \Neos\Cache\Frontend\StringFrontend
33
	 */
34
	protected $cache;
35
36
	/**
37
	 * @var \Neos\Flow\ObjectManagement\ObjectManagerInterface
38
	 */
39
	protected $objectManager;
40
41
42
	/**
43
	 * Clears the content cache
44
	 *
45
	 * @param string $sites List of sites separated by a space character the jobs should be executed for, e.g. "default unittest"
46
	 * @return void
47
	 */
48
	public function cacheCommand( $sites = '' )
49
	{
50
		$context = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\Context' )->get( null, 'command' );
51
		$context->setEditor( 'aimeos:cache' );
52
53
		$config = $context->getConfig();
54
		$name = $config->get( 'flow/cache/name', 'Flow' );
55
56
		$localeManager = \Aimeos\MShop\Locale\Manager\Factory::createManager( $context );
57
58
		foreach( $this->getSiteItems( $context, $sites ) as $siteItem )
59
		{
60
			$localeItem = $localeManager->bootstrap( $siteItem->getCode(), '', '', false );
61
62
			$lcontext = clone $context;
63
			$lcontext->setLocale( $localeItem );
64
65
			switch( $name )
66
			{
67
				case 'None':
68
					$config->set( 'client/html/basket/cache/enable', false );
69
					$cache = \Aimeos\MW\Cache\Factory::createManager( 'None', array(), null );
70
					break;
71
				case 'Flow':
72
					$cache = new \Aimeos\MAdmin\Cache\Proxy\Flow( $lcontext, $this->cache );
73
					break;
74
				default:
75
					$cache = new \Aimeos\MAdmin\Cache\Proxy\Standard( $lcontext );
76
					break;
77
			}
78
79
			$this->outputFormatted( 'Clearing the Aimeos cache for site <b>%s</b>', array( $siteItem->getCode() ) );
80
81
			$cache->clear();
82
		}
83
	}
84
85
86
	/**
87
	 * Executes the Aimeos maintenance jobs
88
	 *
89
	 * The Aimeos shop system needs some maintenance tasks that must be
90
	 * regularly executed. These include
91
	 *
92
	 * - admin/cache (remove expired cache entries once a day)
93
	 * - admin/job (process import/export jobs created in the admin interface every five minutes)
94
	 * - admin/log (archivate and delete old log entries once a day)
95
	 * - customer/email/watch (send customers e-mails if their watched products have changed)
96
	 * - index/rebuild (rebuild the catalog index once a day after midnight)
97
	 * - index/optimize (optimize the catalog index once a day one hour after the rebuild)
98
	 * - order/cleanup/unfinished (remove unfinised orders once a day)
99
	 * - order/cleanup/unfinised (remove unpaid orders once a day)
100
	 * - order/email/delivery (send delivery status update e-mails to the customers every few hours)
101
	 * - order/email/payment (send payment status update e-mails to the customers every few hours)
102
	 * - order/service/async (import batch delivery or payment status updates if necessary)
103
	 * - order/service/delivery (sends paid orders to the ERP system or logistic partner)
104
	 * - order/service/payment (captures authorized payments after the configured amount of time automatically)
105
	 * - product/bought (updates the suggested products based on what other customers bought once a day)
106
	 * - product/export (export products)
107
	 * - product/export/sitemap (generate product sitemaps for search engines)
108
	 * - product/import/csv (import products from CSV files)
109
	 *
110
	 * Each of these maintenance tasks must be executed for all shop instances
111
	 * if you have more than one site in your installation. The sites parameter
112
	 * should contain a list of site codes in this case. If you only have one
113
	 * site named "default" then you don't need to specify the site.
114
	 *
115
	 * @param string $jobs List of job names separated by a space character like "admin/job catalog/index/rebuild"
116
	 * @param string $sites List of sites separated by a space character the jobs should be executed for, e.g. "default unittest"
117
	 * @return void
118
	 */
119
	public function jobsCommand( $jobs, $sites = 'default' )
120
	{
121
		$aimeos = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\Aimeos' )->get();
122
		$context = $this->getContext();
123
		$process = $context->getProcess();
124
125
		$jobs = explode( ' ', $jobs );
126
		$localeManager = \Aimeos\MShop\Factory::createManager( $context, 'locale' );
127
128
		foreach( $this->getSiteItems( $context, $sites ) as $siteItem )
129
		{
130
			$localeItem = $localeManager->bootstrap( $siteItem->getCode(), '', '', false );
131
			$localeItem->setLanguageId( null );
132
			$localeItem->setCurrencyId( null );
133
134
			$context->setLocale( $localeItem );
135
136
			$this->outputFormatted( 'Executing jobs for site <b>%s</b>', array( $siteItem->getCode() ) );
137
138
			foreach( $jobs as $jobname )
139
			{
140
				$fcn = function( $context, $aimeos, $jobname ) {
141
					\Aimeos\Controller\Jobs\Factory::createController( $context, $aimeos, $jobname )->run();
142
				};
143
144
				$process->start( $fcn, [$context, $aimeos, $jobname], true );
145
			}
146
		}
147
148
		$process->wait();
149
	}
150
151
152
	/**
153
	 * Initialize or update the Aimeos database tables
154
	 *
155
	 * After installing and updating the Aimeos package, the database structure
156
	 * must be created or upgraded to the current version. Depending on the size
157
	 * of the database, this may take a while.
158
	 *
159
	 * @param string $site Site for updating database entries
160
	 * @param string $tplsite Template site for creating or updating database entries
161
	 * @param array $option Optional setup configuration, name and value are separated by ":" like "setup/default/demo:1".
162
	 * @param string|null $task Setup task name to execute
163
	 * @param string $action Setup task action, e.g. "migrate", "rollback" or "clean"
164
	 * @return void
165
	 */
166
	public function setupCommand( $site = 'default', $tplsite = 'default', array $option = array(), $task = null, $action = 'migrate' )
167
	{
168
		$context = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\Context' )->get( null, 'command' );
169
		$context->setEditor( 'aimeos:setup' );
170
171
		$config = $context->getConfig();
172
		$config->set( 'setup/site', $site );
173
		$dbconfig = $this->getDbConfig( $config );
174
		$this->setOptions( $config, $option );
175
176
		$taskPaths = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\Aimeos' )->get()->getSetupPaths( $tplsite );
177
		$manager = new \Aimeos\MW\Setup\Manager\Multiple( $context->getDatabaseManager(), $dbconfig, $taskPaths, $context );
178
179
		$this->outputFormatted( 'Initializing or updating the Aimeos database tables for site <b>%s</b>', array( $site ) );
180
181
		switch( $action )
182
		{
183
			case 'migrate':
184
				$manager->migrate( $task );
185
				break;
186
			case 'rollback':
187
				$manager->rollback( $task );
188
				break;
189
			case 'clean':
190
				$manager->clean( $task );
191
				break;
192
			default:
193
				throw new \Exception( sprintf( 'Invalid setup action "%1$s"', $action ) );
194
		}
195
	}
196
197
198
	/**
199
	 * Returns a context object for the jobs command
200
	 *
201
	 * @return \Aimeos\MShop\Context\Item\Standard Context object
202
	 */
203
	protected function getContext()
204
	{
205
		$aimeos = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\Aimeos' )->get();
206
		$context = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\Context' )->get( null, 'command' );
207
		$uriBuilder = $this->objectManager->get( '\\Neos\\Flow\\Mvc\\Routing\\UriBuilder' );
208
209
		$request = \Neos\Flow\Http\Request::createFromEnvironment();
210
		$request->setBaseUri( new \Neos\Flow\Http\Uri( $this->baseUri ) );
211
		$uriBuilder->setRequest( new \Neos\Flow\Mvc\ActionRequest( $request ) );
212
213
		$tmplPaths = $aimeos->getCustomPaths( 'controller/jobs/templates' );
214
215
		$langManager = \Aimeos\MShop\Locale\Manager\Factory::createManager( $context )->getSubManager( 'language' );
216
		$langids = array_keys( $langManager->searchItems( $langManager->createSearch( true ) ) );
217
218
		$i18n = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\I18n' )->get( $langids );
219
		$view = $this->objectManager->get( '\\Aimeos\\Shop\\Base\\View' )->create( $context, $uriBuilder, $tmplPaths );
220
221
		$context->setEditor( 'aimeos:jobs' );
222
		$context->setView( $view );
223
		$context->setI18n( $i18n );
224
225
		return $context;
226
	}
227
228
229
	/**
230
	 * Returns the database configuration from the config object.
231
	 *
232
	 * @param \Aimeos\MW\Config\Iface $conf Config object
233
	 * @return array Multi-dimensional associative list of database configuration parameters
234
	 */
235
	protected function getDbConfig( \Aimeos\MW\Config\Iface $conf )
236
	{
237
		$dbconfig = $conf->get( 'resource', array() );
238
239
		foreach( $dbconfig as $rname => $dbconf )
240
		{
241
			if( strncmp( $rname, 'db', 2 ) !== 0 ) {
242
				unset( $dbconfig[$rname] );
243
			}
244
		}
245
246
		return $dbconfig;
247
	}
248
249
250
	/**
251
	 * Returns the enabled site items which may be limited by the input arguments.
252
	 *
253
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context item object
254
	 * @param string $sites Unique site codes
255
	 * @return \Aimeos\MShop\Locale\Item\Site\Iface[] List of site items
256
	 */
257
	protected function getSiteItems( \Aimeos\MShop\Context\Item\Iface $context, $sites )
258
	{
259
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'locale/site' );
260
		$search = $manager->createSearch();
261
262
		if( $sites !== '' ) {
263
			$search->setConditions( $search->compare( '==', 'locale.site.code', explode( ' ', $sites ) ) );
264
		}
265
266
		return $manager->searchItems( $search );
267
	}
268
269
270
	/**
271
	 * @param \Neos\Cache\Frontend\StringFrontend $cache
272
	 * @return void
273
	 */
274
	public function injectCache( \Neos\Cache\Frontend\StringFrontend $cache )
275
	{
276
		$this->cache = $cache;
277
	}
278
279
280
	/**
281
	 * @param \Neos\Flow\ObjectManagement\ObjectManagerInterface $objectManager
282
	 * @return void
283
	 */
284
	public function injectObjectManager( \Neos\Flow\ObjectManagement\ObjectManagerInterface $objectManager )
285
	{
286
		$this->objectManager = $objectManager;
287
	}
288
289
290
	/**
291
	 * Extracts the configuration options from the input object and updates the configuration values in the config object.
292
	 *
293
	 * @param \Aimeos\MW\Config\Iface $conf Configuration object
294
	 * @param array $options List of option key/value pairs
295
	 * @param array Associative list of database configurations
296
	 */
297
	protected function setOptions( \Aimeos\MW\Config\Iface $conf, array $options )
298
	{
299
		foreach( $options as $option )
300
		{
301
			list( $name, $value ) = explode( ':', $option );
302
			$conf->set( str_replace( '\\', '/', $name ), $value );
303
		}
304
	}
305
}
306