Completed
Push — master ( a9b00f...475749 )
by Aimeos
02:16
created

Standard::__construct()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 57
rs 8.9381
c 0
b 0
f 0
cc 4
nc 4
nop 3

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 Aimeos (aimeos.org), 2015-2018
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Common\Product\Import\Csv\Processor\Attribute;
12
13
14
/**
15
 * Attribute processor for CSV imports
16
 *
17
 * @package Controller
18
 * @subpackage Common
19
 */
20
class Standard
21
	extends \Aimeos\Controller\Common\Product\Import\Csv\Processor\Base
22
	implements \Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface
23
{
24
	/** controller/common/product/import/csv/processor/attribute/name
25
	 * Name of the attribute processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\Common\Product\Import\Csv\Processor\Attribute\Myname".
28
	 * The name is case-sensitive and you should avoid camel case names like "MyName".
29
	 *
30
	 * @param string Last part of the processor class name
31
	 * @since 2015.10
32
	 * @category Developer
33
	 */
34
35
	private $cache;
36
	private $listTypes;
37
	private $types = [];
38
39
40
	/**
41
	 * Initializes the object
42
	 *
43
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
44
	 * @param array $mapping Associative list of field position in CSV as key and domain item key as value
45
	 * @param \Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface $object Decorated processor
46
	 */
47
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $mapping,
48
		\Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface $object = null )
49
	{
50
		parent::__construct( $context, $mapping, $object );
51
52
		/** controller/common/product/import/csv/processor/attribute/listtypes
53
		 * Names of the product list types for attributes that are updated or removed
54
		 *
55
		 * If you want to associate attribute items manually via the administration
56
		 * interface to products and don't want these to be touched during the
57
		 * import, you can specify the product list types for these attributes
58
		 * that shouldn't be updated or removed.
59
		 *
60
		 * @param array|null List of product list type names or null for all
61
		 * @since 2015.05
62
		 * @category Developer
63
		 * @category User
64
		 * @see controller/common/product/import/csv/domains
65
		 * @see controller/common/product/import/csv/processor/catalog/listtypes
66
		 * @see controller/common/product/import/csv/processor/media/listtypes
67
		 * @see controller/common/product/import/csv/processor/product/listtypes
68
		 * @see controller/common/product/import/csv/processor/price/listtypes
69
		 * @see controller/common/product/import/csv/processor/text/listtypes
70
		 */
71
		$key = 'controller/common/product/import/csv/processor/attribute/listtypes';
72
		$this->listTypes = $context->getConfig()->get( $key );
73
74
		if( $this->listTypes === null )
75
		{
76
			$this->listTypes = [];
77
			$manager = \Aimeos\MShop\Factory::createManager( $context, 'product/lists/type' );
78
79
			$search = $manager->createSearch()->setSlice( 0, 0x7fffffff );
80
			$search->setConditions( $search->compare( '==', 'product.lists.type.domain', 'attribute' ) );
81
82
			foreach( $manager->searchItems( $search ) as $item ) {
83
				$this->listTypes[$item->getCode()] = $item->getCode();
84
			}
85
		}
86
		else
87
		{
88
			$this->listTypes = array_flip( $this->listTypes );
89
		}
90
91
92
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'attribute/type' );
93
94
		$search = $manager->createSearch()->setSlice( 0, 0x7fffffff );
95
		$search->setConditions( $search->compare( '==', 'attribute.type.domain', 'product' ) );
96
97
		foreach( $manager->searchItems( $search ) as $item ) {
98
			$this->types[$item->getCode()] = $item->getCode();
99
		}
100
101
102
		$this->cache = $this->getCache( 'attribute' );
103
	}
104
105
106
	/**
107
	 * Saves the attribute related data to the storage
108
	 *
109
	 * @param \Aimeos\MShop\Product\Item\Iface $product Product item with associated items
110
	 * @param array $data List of CSV fields with position as key and data as value
111
	 * @return array List of data which hasn't been imported
112
	 */
113
	public function process( \Aimeos\MShop\Product\Item\Iface $product, array $data )
114
	{
115
		$context = $this->getContext();
116
		$listManager = \Aimeos\MShop\Factory::createManager( $context, 'product/lists' );
117
		$separator = $context->getConfig()->get( 'controller/common/product/import/csv/separator', "\n" );
118
119
		$listMap = [];
120
		$map = $this->getMappedChunk( $data, $this->getMapping() );
121
		$listItems = $product->getListItems( 'attribute', $this->listTypes );
122
123
		foreach( $listItems as $listItem )
124
		{
125
			if( ( $refItem = $listItem->getRefItem() ) !== null ) {
126
				$listMap[ $refItem->getCode() ][ $listItem->getType() ] = $listItem;
127
			}
128
		}
129
130
		foreach( $map as $pos => $list )
131
		{
132
			if( $this->checkEntry( $list ) === false ) {
133
				continue;
134
			}
135
136
			$codes = explode( $separator, $this->getValue( $list, 'attribute.code', '' ) );
0 ignored issues
show
Documentation Bug introduced by
The method getValue does not exist on object<Aimeos\Controller...sor\Attribute\Standard>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
137
138
			foreach( $codes as $code )
139
			{
140
				$code = trim( $code );
141
				$typecode = $this->getValue( $list, 'product.lists.type', 'default' );
0 ignored issues
show
Documentation Bug introduced by
The method getValue does not exist on object<Aimeos\Controller...sor\Attribute\Standard>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
142
143
				if( isset( $listMap[$code][$typecode] ) )
144
				{
145
					$listItem = $listMap[$code][$typecode];
146
					unset( $listItems[ $listItem->getId() ] );
147
				}
148
				else
149
				{
150
					$listItem = $listManager->createItem( $typecode, 'attribute' );
0 ignored issues
show
Unused Code introduced by
The call to Iface::createItem() has too many arguments starting with $typecode.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
151
				}
152
153
				$attrItem = $this->getAttributeItem( $code, $this->getValue( $list, 'attribute.type' ) );
0 ignored issues
show
Documentation Bug introduced by
The method getValue does not exist on object<Aimeos\Controller...sor\Attribute\Standard>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
154
				$attrItem->fromArray( $list );
155
				$attrItem->setCode( $code );
156
157
				$listItem->fromArray( $this->addListItemDefaults( $list, $pos ) );
158
159
				$product->addListItem( 'attribute', $listItem, $attrItem );
160
			}
161
		}
162
163
		$product->deleteListItems( $listItems );
164
165
		return $this->getObject()->process( $product, $data );
166
	}
167
168
169
	/**
170
	 * Checks if the entry from the mapped data is valid
171
	 *
172
	 * @param array $list Associative list of key/value pairs from the mapped data
173
	 * @return boolean True if the entry is valid, false if not
174
	 */
175
	protected function checkEntry( array $list )
176
	{
177
		if( $this->getValue( $list, 'attribute.code' ) === null ) {
0 ignored issues
show
Documentation Bug introduced by
The method getValue does not exist on object<Aimeos\Controller...sor\Attribute\Standard>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
178
			return false;
179
		}
180
181
		if( ( $type = $this->getValue( $list, 'product.lists.type' ) ) && !isset( $this->listTypes[$type] ) )
0 ignored issues
show
Documentation Bug introduced by
The method getValue does not exist on object<Aimeos\Controller...sor\Attribute\Standard>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
182
		{
183
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'product list' );
184
			throw new \Aimeos\Controller\Common\Exception( $msg );
185
		}
186
187
		if( ( $type = $this->getValue( $list, 'attribute.type' ) ) && !isset( $this->types[$type] ) )
0 ignored issues
show
Documentation Bug introduced by
The method getValue does not exist on object<Aimeos\Controller...sor\Attribute\Standard>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
188
		{
189
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'attribute' );
190
			throw new \Aimeos\Controller\Common\Exception( $msg );
191
		}
192
193
		return true;
194
	}
195
196
197
	/**
198
	 * Returns the attribute item for the given code and type
199
	 *
200
	 * @param string $code Attribute code
201
	 * @param string $type Attribute type
202
	 * @return \Aimeos\MShop\Attribute\Item\Iface Attribute item object
203
	 */
204
	protected function getAttributeItem( $code, $type )
205
	{
206
		if( ( $item = $this->cache->get( $code, $type ) ) === null )
207
		{
208
			$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'attribute' );
209
210
			$item = $manager->createItem();
211
			$item->setType( $type );
0 ignored issues
show
Bug introduced by
The method setType() does not exist on Aimeos\MShop\Attribute\Item\Iface. Did you maybe mean setTypeId()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
212
			$item->setDomain( 'product' );
213
			$item->setLabel( $code );
214
			$item->setCode( $code );
215
			$item->setStatus( 1 );
216
217
			$item = $manager->saveItem( $item );
218
219
			$this->cache->set( $item );
220
		}
221
222
		return $item;
223
	}
224
}
225