Passed
Push — master ( 5b947d...494d83 )
by Aimeos
14:32
created

Base::getListConfig()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2018-2023
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Common\Catalog\Import\Csv;
12
13
14
/**
15
 * Common class for CSV catalog import job controllers and processors.
16
 *
17
 * @package Controller
18
 * @subpackage Common
19
 */
20
class Base
21
	extends \Aimeos\Controller\Jobs\Base
22
{
23
	/**
24
	 * Returns the cache object for the given type
25
	 *
26
	 * @param string $type Type of the cached data
27
	 * @param string|null $name Name of the cache implementation
28
	 * @return \Aimeos\Controller\Common\Catalog\Import\Csv\Cache\Iface Cache object
29
	 * @throws \LogicException If class can't be instantiated
30
	 */
31
	protected function getCache( string $type, $name = null ) : \Aimeos\Controller\Common\Catalog\Import\Csv\Cache\Iface
32
	{
33
		$context = $this->context();
34
		$config = $context->config();
35
36
		if( ctype_alnum( $type ) === false ) {
37
			throw new \LogicException( sprintf( 'Invalid characters in class name "%1$s"', $type ), 400 );
38
		}
39
40
		if( $name === null ) {
41
			$name = $config->get( 'controller/common/catalog/import/csv/cache/' . $type . '/name', 'Standard' );
42
		}
43
44
		if( ctype_alnum( $name ) === false ) {
45
			throw new \LogicException( sprintf( 'Invalid characters in class name "%1$s"', $name ), 400 );
46
		}
47
48
		$classname = '\\Aimeos\\Controller\\Common\\Catalog\\Import\\Csv\\Cache\\' . ucfirst( $type ) . '\\' . $name;
49
		$interface = \Aimeos\Controller\Common\Catalog\Import\Csv\Cache\Iface::class;
50
51
		return \Aimeos\Utils::create( $classname, [$context], $interface );
52
	}
53
54
55
	/**
56
	 * Returns the rows from the CSV file up to the maximum count
57
	 *
58
	 * @param resource $fh File handle to CSV file
59
	 * @param int $maxcnt Maximum number of rows that should be retrieved at once
60
	 * @param int $codePos Column position which contains the unique product code (starting from 0)
61
	 * @return array List of arrays with product codes as keys and list of values from the CSV file
62
	 */
63
	protected function getData( $fh, int $maxcnt, int $codePos ) : array
64
	{
65
		$data = [];
66
		$count = 0;
67
68
		while( ( $row = fgetcsv( $fh ) ) !== false && $count++ < $maxcnt ) {
69
			$data[$row[$codePos]] = $row;
70
		}
71
72
		return $data;
73
	}
74
75
76
	/**
77
	 * Returns the default mapping for the CSV fields to the domain item keys
78
	 *
79
	 * Example:
80
	 *  'item' => array(
81
	 *  	0 => 'catalog.code', // e.g. unique EAN code
82
	 *		1 => 'catalog.parent', // Code of parent catalog node
83
	 *  	2 => 'catalog.label', // UTF-8 encoded text, also used as catalog name
84
	 *		3 => 'catalog.status', // If category should be shown in the frontend
85
	 *  ),
86
	 *  'text' => array(
87
	 *  	3 => 'text.type', // e.g. "short" for short description
88
	 *  	4 => 'text.content', // UTF-8 encoded text
89
	 *  ),
90
	 *  'media' => array(
91
	 *  	5 => 'media.url', // relative URL of the catalog image on the server
92
	 *  ),
93
	 *
94
	 * @return array Associative list of domains as keys ("item" is special for the catalog itself) and a list of
95
	 * 	positions and the domain item keys as values.
96
	 */
97
	protected function getDefaultMapping() : array
98
	{
99
		return array(
100
			'item' => array(
101
				0 => 'catalog.code',
102
				1 => 'catalog.parent',
103
				2 => 'catalog.label',
104
				3 => 'catalog.status',
105
			),
106
			'text' => array(
107
				4 => 'text.type',
108
				5 => 'text.content',
109
			),
110
			'media' => array(
111
				6 => 'media.url',
112
			),
113
		);
114
	}
115
116
117
	/**
118
	 * Returns the configuration for the given string
119
	 *
120
	 * @param string $value Configuration string
121
	 * @return array Configuration settings
122
	 */
123
	protected function getListConfig( string $value ) : array
124
	{
125
		$config = [];
126
127
		foreach( array_filter( explode( "\n", $value ) ) as $line )
128
		{
129
			list( $key, $val ) = explode( ':', $line );
130
			$config[$key] = $val;
131
		}
132
133
		return $config;
134
	}
135
136
137
	/**
138
	 * Returns the mapped data from the CSV line
139
	 *
140
	 * @param array $data List of CSV fields with position as key and domain item key as value (mapped data is removed)
141
	 * @param array $mapping List of domain item keys with the CSV field position as key
142
	 * @return array List of associative arrays containing the chunked properties
143
	 */
144
	protected function getMappedChunk( array &$data, array $mapping ) : array
145
	{
146
		$idx = 0;
147
		$map = [];
148
149
		foreach( $mapping as $pos => $key )
150
		{
151
			if( isset( $map[$idx][$key] ) ) {
152
				$idx++;
153
			}
154
155
			if( isset( $data[$pos] ) )
156
			{
157
				$map[$idx][$key] = $data[$pos];
158
				unset( $data[$pos] );
159
			}
160
		}
161
162
		return $map;
163
	}
164
165
166
	/**
167
	 * Returns the processor object for saving the catalog related information
168
	 *
169
	 * @param array $mappings Associative list of processor types as keys and index/data mappings as values
170
	 * @return \Aimeos\Controller\Common\Catalog\Import\Csv\Processor\Iface Processor object
171
	 * @throws \LogicException If class can't be instantiated
172
	 */
173
	protected function getProcessors( array $mappings ) : \Aimeos\Controller\Common\Catalog\Import\Csv\Processor\Iface
174
	{
175
		unset( $mappings['item'] );
176
177
		$context = $this->context();
178
		$config = $context->config();
179
180
		$interface = \Aimeos\Controller\Common\Catalog\Import\Csv\Processor\Iface::class;
181
		$object = new \Aimeos\Controller\Common\Catalog\Import\Csv\Processor\Done( $context, [] );
182
183
		foreach( $mappings as $type => $mapping )
184
		{
185
			if( ctype_alnum( $type ) === false ) {
186
				throw new \LogicException( sprintf( 'Invalid characters in class name "%1$s"', $type ), 400 );
187
			}
188
189
			$name = $config->get( 'controller/common/catalog/import/csv/processor/' . $type . '/name', 'Standard' );
190
191
			if( ctype_alnum( $name ) === false ) {
192
				throw new \LogicException( sprintf( 'Invalid characters in class name "%1$s"', $name ), 400 );
193
			}
194
195
			$classname = '\\Aimeos\\Controller\\Common\\Catalog\\Import\\Csv\\Processor\\' . ucfirst( $type ) . '\\' . $name;
196
197
			$object = \Aimeos\Utils::create( $classname, [$context, $mapping, $object], $interface );
198
		}
199
200
		return $object;
201
	}
202
}
203