GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

EbayEnterprise_Catalog_Helper_Data   F
last analyzed

Complexity

Total Complexity 88

Size/Duplication

Total Lines 779
Duplicated Lines 2.7 %

Coupling/Cohesion

Components 4
Dependencies 4
Metric Value
wmc 88
lcom 4
cbo 4
dl 21
loc 779
rs 1.263

48 Methods

Rating   Name   Duplication   Size   Complexity  
A getStoreUrl() 0 4 1
A getDefaultLanguageCode() 0 4 1
A extractNodeVal() 0 4 2
A extractNodeAttributeVal() 0 4 2
A getStoreRootCategoryId() 0 4 1
A getStores() 0 4 1
A nullCoalesce() 0 4 2
A getAllWebsiteIds() 0 4 1
A getDefStoreId() 0 4 1
A getDefStoreRootCatId() 0 4 1
A getDefProdAttSetId() 0 4 1
A getLocaleCode() 0 4 1
A loadWebsiteFilters() 0 18 4
A loadStoreviewFilters() 0 4 1
A getDefaultStoreViewId() 0 4 1
A normalizeSku() 0 10 4
A getProductHtsCodeByCountry() 13 13 4
A __construct() 0 12 1
A checkTypes() 0 7 1
B getProdTplt() 0 29 3
A setCurrentStore() 0 5 1
A getConfigModel() 0 6 1
A hasEavAttr() 0 6 1
A getProductAttributeId() 0 6 1
A hasProdType() 0 5 1
A prepareProductModel() 0 8 2
A createNewProduct() 0 6 1
A applyDummyData() 8 8 3
A loadProductBySku() 0 8 1
A getCustomAttributeCodeSet() 0 12 3
A parseTranslations() 0 10 3
B getConfigurableAttributesData() 0 13 5
A mapPattern() 0 7 2
A generateFileName() 0 7 1
A generateMessageHeader() 0 7 1
A getProcessingDirectory() 0 10 2
A buildErrorFeedFilename() 0 9 1
A getStoreViewLanguage() 0 9 2
A getDefaultParentCategoryId() 0 12 2
A splitDomByXslt() 0 18 2
A appendXslTemplateMatchNode() 0 9 1
A loadStoreviewConfig() 0 12 1
B uniqueSiteFilters() 0 31 4
A getAttributeSetIdByName() 0 9 1
A isValidIsoCountryCode() 0 6 1
A denormalizeSku() 0 5 3
B saveCollectionStubIndexer() 0 36 5
A reregister() 0 9 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EbayEnterprise_Catalog_Helper_Data often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EbayEnterprise_Catalog_Helper_Data, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Copyright (c) 2013-2014 eBay Enterprise, Inc.
4
 *
5
 * NOTICE OF LICENSE
6
 *
7
 * This source file is subject to the Open Software License (OSL 3.0)
8
 * that is bundled with this package in the file LICENSE.md.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * @copyright   Copyright (c) 2013-2014 eBay Enterprise, Inc. (http://www.ebayenterprise.com/)
13
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
14
 */
15
16
class EbayEnterprise_Catalog_Helper_Data extends Mage_Core_Helper_Abstract implements EbayEnterprise_Eb2cCore_Helper_Interface
17
{
18
    /** @var EbayEnterprise_MageLog_Helper_Data */
19
    protected $logger;
20
    /** @var EbayEnterprise_MageLog_Helper_Context */
21
    protected $context;
22
    /** @var Mage_Index_Model_Indexer */
23
    protected $indexerStub;
24
25
    /**
26
     * @param array $args May contain key/value for:
27
     * - logger => EbayEnterprise_MageLog_Helper_Data
28
     * - log_context => EbayEnterprise_MageLog_Helper_Context
29
     * - indexer_stub => Mage_Index_Model_Indexer
30
     */
31
    public function __construct(array $args = [])
32
    {
33
        list(
34
            $this->logger,
35
            $this->context,
36
            $this->indexerStub
37
        ) = $this->checkTypes(
38
            $this->nullCoalesce($args, 'logger', Mage::helper('ebayenterprise_magelog')),
39
            $this->nullCoalesce($args, 'log_context', Mage::helper('ebayenterprise_magelog/context')),
40
            $this->nullCoalesce($args, 'indexer_stub', Mage::getModel('ebayenterprise_catalog/indexer_stub'))
41
        );
42
    }
43
44
    /**
45
     * Enforce type checks on constructor init params.
46
     *
47
     * @param EbayEnterprise_MageLog_Helper_Data
48
     * @param EbayEnterprise_MageLog_Helper_Context
49
     * @param Mage_Index_Model_Indexer
50
     * @return array
51
     */
52
    protected function checkTypes(
0 ignored issues
show
Unused Code introduced by
The method parameter $logger is never used
Loading history...
Unused Code introduced by
The method parameter $logContext is never used
Loading history...
Unused Code introduced by
The method parameter $indexer is never used
Loading history...
53
        EbayEnterprise_MageLog_Helper_Data $logger,
54
        EbayEnterprise_MageLog_Helper_Context $logContext,
55
        Mage_Index_Model_Indexer $indexer
56
    ) {
57
        return func_get_args();
58
    }
59
60
    /**
61
     * Fill in default values.
62
     *
63
     * @param string
64
     * @param array
65
     * @param mixed
66
     * @return mixed
67
     */
68
    protected function nullCoalesce(array $arr, $key, $default)
69
    {
70
        return isset($arr[$key]) ? $arr[$key] : $default;
71
    }
72
73
    /**
74
     * @var int, the default category id
75
     */
76
    protected $defaultParentCategoryId = null;
77
78
    /**
79
     * @see self::getCustomAttributeCodeSet - method
80
     */
81
    protected $customAttributeCodeSets = [];
82
    /**
83
     * @var array boilerplate for initializing a new product with limited information.
84
     */
85
    protected $prodTplt;
86
87
    /**
88
     * @throws EbayEnterprise_Catalog_Model_Config_Exception
89
     * @return array the static defaults for a new product
90
     */
91
    protected function getProdTplt()
92
    {
93
        if (!$this->prodTplt) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->prodTplt of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
94
            $cfg = $this->getConfigModel();
95
            if (!$this->hasProdType($cfg->dummyTypeId)) {
0 ignored issues
show
Documentation introduced by
The property dummyTypeId does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
96
                throw new EbayEnterprise_Catalog_Model_Config_Exception('Config Error: dummy type id is invalid.');
97
            }
98
            $defStockData = [
99
                'is_in_stock' => $cfg->dummyInStockFlag,
0 ignored issues
show
Documentation introduced by
The property dummyInStockFlag does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
100
                'manage_stock' => $cfg->dummyManageStockFlag,
0 ignored issues
show
Documentation introduced by
The property dummyManageStockFlag does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
101
                'qty' => (int) $cfg->dummyStockQuantity,
0 ignored issues
show
Documentation introduced by
The property dummyStockQuantity does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
102
            ];
103
            $this->prodTplt = [
104
                'attribute_set_id' => (int) $this->getDefProdAttSetId(),
105
                'category_ids' => [$this->getDefStoreRootCatId()],
106
                'description' => $cfg->dummyDescription,
0 ignored issues
show
Documentation introduced by
The property dummyDescription does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
107
                'price' => (float) $cfg->dummyPrice,
0 ignored issues
show
Documentation introduced by
The property dummyPrice does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
108
                'short_description' => $cfg->dummyShortDescription,
0 ignored issues
show
Documentation introduced by
The property dummyShortDescription does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
109
                'status' => Mage_Catalog_Model_Product_Status::STATUS_DISABLED,
110
                'stock_data' => $defStockData,
111
                'store_ids' => [$this->getDefStoreId()],
112
                'type_id' => $cfg->dummyTypeId,
0 ignored issues
show
Documentation introduced by
The property dummyTypeId does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
113
                'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE,
114
                'website_ids' => $this->getAllWebsiteIds(),
115
                'weight' => (int) $cfg->dummyWeight,
0 ignored issues
show
Documentation introduced by
The property dummyWeight does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
116
            ];
117
        }
118
        return $this->prodTplt;
119
    }
120
121
    /**
122
     * @return array all website ids
123
     */
124
    protected function getAllWebsiteIds()
125
    {
126
        return (array) Mage::getModel('core/website')->getCollection()->getAllIds();
127
    }
128
    /**
129
     * @return int the default store id
130
     */
131
    protected function getDefStoreId()
132
    {
133
        return (int) Mage::app()->getWebsite()->getDefaultGroup()->getDefaultStoreId();
134
    }
135
    /**
136
     * @return int the root category id for the default store
137
     */
138
    protected function getDefStoreRootCatId()
139
    {
140
        return (int) Mage::app()->getStore()->getRootCategoryId();
141
    }
142
    /**
143
     * @return int the default attribute set id for all products.
144
     */
145
    protected function getDefProdAttSetId()
146
    {
147
        return (int) Mage::getModel('eav/entity_type')->loadByCode('catalog_product')->getDefaultAttributeSetId();
148
    }
149
    /**
150
     * abstracting getting locale code
151
     * @return string, the locale code
0 ignored issues
show
Documentation introduced by
The doc-type string, could not be parsed: Expected "|" or "end of type", but got "," at position 6. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
152
     * @codeCoverageIgnore
153
     */
154
    protected function getLocaleCode()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
155
    {
156
        return Mage::app()->getLocale()->getLocaleCode();
157
    }
158
159
    /**
160
     * Get the base url for a given store
161
     *
162
     * @param $storeId
163
     * @return string the store base url
164
     */
165
    public function getStoreUrl($storeId)
166
    {
167
        return Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
168
    }
169
170
    /**
171
     * Set the current store context
172
     * @param $storeId
173
     * @return self
174
     */
175
    public function setCurrentStore($storeId)
176
    {
177
        Mage::app()->setCurrentStore($storeId);
178
        return $this;
179
    }
180
    /**
181
     * @return string the default locale language code
182
     */
183
    public function getDefaultLanguageCode()
184
    {
185
        return Mage::helper('eb2ccore')->mageToXmlLangFrmt($this->getLocaleCode());
186
    }
187
188
    /**
189
     * @see EbayEnterprise_Eb2cCore_Helper_Interface::getConfigModel
190
     * Get Product config instantiated object.
191
     * @param mixed $store
192
     * @return EbayEnterprise_Eb2cCore_Model_Config_Registry
193
     */
194
    public function getConfigModel($store = null)
195
    {
196
        return Mage::getModel('eb2ccore/config_registry')
197
            ->setStore($store)
198
            ->addConfigModel(Mage::getSingleton('ebayenterprise_catalog/config'));
199
    }
200
201
    /**
202
     * @param $at
203
     * @return bool true if the eav config has at least one instance of the given attribute.
204
     */
205
    public function hasEavAttr($at)
206
    {
207
        return 0 < (int) Mage::getSingleton('eav/config')
208
            ->getAttribute(Mage_Catalog_Model_Product::ENTITY, $at)
209
            ->getId();
210
    }
211
    /**
212
     * Get a catalog product eav attribute id for the attribute identified by
213
     * the given code.
214
     * @param string $attributeCode Attribute code for the product attribute
215
     * @return int id of the attribute
216
     */
217
    public function getProductAttributeId($attributeCode)
218
    {
219
        return Mage::getModel('eav/entity_attribute')
220
            ->loadByCode('catalog_product', $attributeCode)
221
            ->getId();
222
    }
223
    /**
224
     * @return bool true if Magento knows about the product type.
225
     * @param string $type
226
     */
227
    public function hasProdType($type)
228
    {
229
        $types = Mage_Catalog_Model_Product_Type::getTypes();
230
        return isset($types[$type]);
231
    }
232
    /**
233
     * extract node value
234
     * @return string, the extracted content
0 ignored issues
show
Documentation introduced by
The doc-type string, could not be parsed: Expected "|" or "end of type", but got "," at position 6. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
235
     * @param DOMNodeList $nodeList
236
     */
237
    public function extractNodeVal(DOMNodeList $nodeList)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
238
    {
239
        return ($nodeList->length) ? $nodeList->item(0)->nodeValue : null;
240
    }
241
    /**
242
     * extract node attribute value
243
     * @return string, the extracted content
0 ignored issues
show
Documentation introduced by
The doc-type string, could not be parsed: Expected "|" or "end of type", but got "," at position 6. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
244
     * @param DOMNodeList $nodeList
245
     * @param string $attributeName
246
     */
247
    public function extractNodeAttributeVal(DOMNodeList $nodeList, $attributeName)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
248
    {
249
        return ($nodeList->length) ? $nodeList->item(0)->getAttribute($attributeName) : null;
250
    }
251
252
    /**
253
     * get a model loaded with the data for $sku if it exists;
254
     * otherwise, get a new _UNSAVED_ model populated with dummy data.
255
     * @param string $sku
256
     * @param string $name
257
     * @return Mage_Catalog_Model_Product
258
     */
259
    public function prepareProductModel($sku, $name = '')
260
    {
261
        $product = $this->loadProductBySku($sku);
262
        if (!$product->getId()) {
263
            $this->applyDummyData($product, $sku, $name);
264
        }
265
        return $product;
266
    }
267
268
    /**
269
     * instantiate new product object and apply dummy data to it
270
     * @param string $sku
271
     * @param array $additionalData optional
272
     * @return Mage_Catalog_Model_Product
273
     */
274
    public function createNewProduct($sku, array $additionalData = [])
275
    {
276
        /** @var Mage_Catalog_Model_Product $product */
277
        $product = Mage::getModel('catalog/product');
278
        return $this->applyDummyData($product, $sku, $additionalData);
279
    }
280
281
    /**
282
     * Fill a product model with dummy data so that it can be saved and edited later.
283
     * @see http://www.magentocommerce.com/boards/viewthread/289906/
284
     * @param  Mage_Catalog_Model_Product $prod product model to be autofilled
285
     * @param  string $sku the new product's sku
286
     * @param  array $additionalData optional
287
     * @return Mage_Catalog_Model_Product
288
     */
289 View Code Duplication
    protected function applyDummyData(Mage_Catalog_Model_Product $prod, $sku, array $additionalData = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
290
    {
291
        $prodData = array_merge($this->getProdTplt(), $additionalData);
292
        $name = isset($prodData['name']) ? $prodData['name'] : null;
293
        $prodData['name'] = $name ?: "Incomplete Product: $sku";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $sku instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
294
        $prodData['sku'] = $prodData['url_key'] = $sku;
295
        return $prod->addData($prodData);
296
    }
297
    /**
298
     * load product by sku
299
     * @param string $sku product sku
300
     * @param null|string|bool|int|Mage_Core_Model_Store $store magento store
301
     * @return Mage_Catalog_Model_Product
302
     */
303
    public function loadProductBySku($sku, $store = null)
304
    {
305
        return Mage::helper('catalog/product')->getProduct(
306
            $sku,
307
            $store,
308
            'sku'
309
        );
310
    }
311
    /**
312
     * Return an array of attribute_codes
313
     * @param int $attributeSetId
314
     * @return array
315
     */
316
    public function getCustomAttributeCodeSet($attributeSetId)
317
    {
318
        if (empty($this->customAttributeCodeSets[$attributeSetId])) {
319
            $codeSet = [];
320
            $attributeSet = Mage::getModel('catalog/product_attribute_api')->items($attributeSetId);
321
            foreach ($attributeSet as $attribute) {
322
                $codeSet[] = $attribute['code'];
323
            }
324
            $this->customAttributeCodeSets[$attributeSetId] = $codeSet;
325
        }
326
        return $this->customAttributeCodeSets[$attributeSetId];
327
    }
328
    /**
329
     * Flattens translations into arrays keyed by language
330
     * @param array $languageSet
0 ignored issues
show
Documentation introduced by
Should the type for parameter $languageSet not be null|array? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
331
     * @return array in the form a['lang-code'] = 'localized value'; empty array if $languageSet is null
332
     */
333
    public function parseTranslations(array $languageSet = null)
334
    {
335
        $parsedLanguages = [];
336
        if (!empty($languageSet)) {
337
            foreach ($languageSet as $language) {
338
                $parsedLanguages[$language['lang']] = $language['description'];
339
            }
340
        }
341
        return $parsedLanguages;
342
    }
343
    /**
344
     * Sets configurable_attributes_data
345
     * @param string $productTypeId ('configurable', 'simple' etc).
346
     * @param Varien_Object $source the source data field
347
     * @param Mage_Catalog_Model_Product $product the product we are setting
348
     * @return array of configurable_attributes_data
349
     */
350
    public function getConfigurableAttributesData($productTypeId, Varien_Object $source, Mage_Catalog_Model_Product $product)
351
    {
352
        if ($product->getId()
353
                && $product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE
354
                && $productTypeId === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE
355
                && $product->getTypeInstance(true)->getConfigurableAttributesAsArray($product)) {
356
            $logData = ['sku' => $product->getSku()];
357
            $logMessage = 'Cannot change existing configurable attributes; update discarded for SKU "{sku}"';
358
            $this->logger->warning($logMessage, $this->context->getMetaData(__CLASS__, $logData));
359
            return null;
360
        }
361
        return $source->getData('configurable_attributes_data');
362
    }
363
364
    /**
365
     * mapped pattern element with actual values
366
     *
367
     * @param array $keyMap a composite array with map key value
368
     * @param string $pattern the string pattern
369
     * @return array
370
     */
371
    public function mapPattern(array $keyMap, $pattern)
372
    {
373
        return array_reduce(array_keys($keyMap), function ($result, $key) use ($keyMap, $pattern) {
374
            $result = (trim($result) === '')? $pattern : $result;
375
            return str_replace(sprintf('{%s}', $key), $keyMap[$key], $result);
376
        });
377
    }
378
379
    /**
380
     * generate file name by feed type
381
     * @param string $feedType Type of feed to be processed
382
     * @param string $format Filename format string to use to build the filename
383
     * @param array  $overrides use an array to specify the values for the filename.
384
     * @return string the errorconfirmations file name
0 ignored issues
show
Documentation introduced by
Should the return type not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
385
     */
386
    public function generateFileName($feedType, $format, array $overrides = [])
387
    {
388
        return $this->mapPattern(
389
            array_replace(Mage::helper('ebayenterprise_catalog/feed')->getFileNameConfig($feedType), $overrides),
390
            $format
391
        );
392
    }
393
394
    /**
395
     * generate message header by feed type
396
     * @param string $feedType
397
     * @return string message header content xml nodes and child nodes
0 ignored issues
show
Documentation introduced by
Should the return type not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
398
     */
399
    public function generateMessageHeader($feedType)
400
    {
401
        $cfg = Mage::helper('eb2ccore')->getConfigModel(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID);
402
        $map = Mage::helper('ebayenterprise_catalog/feed')->getHeaderConfig($feedType);
403
        $map['event_type'] = $feedType;
404
        return $this->mapPattern($map, $cfg->feedHeaderTemplate);
405
    }
406
407
    /**
408
     * Get the absolute path to the global processing directory set
409
     * in configuration.
410
     *
411
     * @throws EbayEnterprise_Catalog_Exception_Feed_File
412
     * @return string
413
     */
414
    public function getProcessingDirectory()
415
    {
416
        $helper = Mage::helper('eb2ccore');
417
        $path = Mage::getBaseDir('var') . DS . Mage::helper('eb2ccore')->getConfigModel()->feedProcessingDirectory;
418
        $helper->createDir($path);
419
        if (!$helper->isDir($path)) {
420
            throw new EbayEnterprise_Catalog_Exception_Feed_File("Can not create the following directory (${path})");
421
        }
422
        return $path;
423
    }
424
425
    /**
426
     * build the outbound file name by feed type
427
     * @param string $feedType
428
     * @return string
429
     */
430
    public function buildErrorFeedFilename($feedType)
431
    {
432
        return $this->getProcessingDirectory() . DS .
433
            $this->generateFileName(
434
                $feedType,
435
                Mage::helper('eb2ccore')->getConfigModel(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID)
436
                    ->errorFeedFilenameFormat
437
            );
438
    }
439
440
    /**
441
     * get store root category id
442
     * @return int store root category id
443
     * @codeCoverageIgnore
444
     */
445
    public function getStoreRootCategoryId()
446
    {
447
        return Mage::app()->getWebsite(true)->getDefaultStore()->getRootCategoryId();
448
    }
449
450
    /**
451
     * abstracting getting an array of stores
452
     * @return array
453
     * @codeCoverageIgnore
454
     */
455
    public function getStores()
456
    {
457
        return Mage::app()->getStores(true);
458
    }
459
460
    /**
461
     * get the storeview language/country code (en-US, fr-FR)
462
     * @param Mage_Core_Model_Store $store
463
     * @return string|null
464
     */
465
    public function getStoreViewLanguage(Mage_Core_Model_Store $store)
466
    {
467
        $storeCodeParsed = explode('_', $store->getName(), 3);
468
        if (count($storeCodeParsed) > 2) {
469
            return strtolower(Mage::helper('eb2ccore')->mageToXmlLangFrmt($storeCodeParsed[2]));
470
        }
471
472
        return null;
473
    }
474
475
    /**
476
     * get parent default category id
477
     * @return int default parent category id
478
     */
479
    public function getDefaultParentCategoryId()
480
    {
481
        if (is_null($this->defaultParentCategoryId)) {
482
            $this->defaultParentCategoryId = Mage::getResourceModel('catalog/category_collection')
483
                ->addAttributeToSelect('entity_id')
484
                ->addAttributeToFilter('parent_id', ['eq' => 0])
485
                ->setPageSize(1)
486
                ->getFirstItem()
0 ignored issues
show
introduced by
getFirstItem() does not limit the result of collection load to one item.
Loading history...
487
                ->getId();
488
        }
489
        return $this->defaultParentCategoryId;
490
    }
491
492
    /**
493
     * take dom document object and string xslt file template to transform
494
     * whatever the passed in xslt file template transform the new doc to
495
     * @param EbayEnterprise_Dom_Document $doc the document got get the nodelist
496
     * @param string $xsltFilePath the xslt stylesheet template file absolute fulle path
497
     * @param array $params parameters for the xslt
498
     * @param callable $postXsltLoadCall function to be called after loading XSLT, but before Processing it
0 ignored issues
show
Documentation introduced by
Should the type for parameter $postXsltLoadCall not be callable|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
499
     * @param array $websiteFilter
500
     * @return EbayEnterprise_Dom_Document
501
     */
502
    public function splitDomByXslt(EbayEnterprise_Dom_Document $doc, $xsltFilePath, array $params = [], $postXsltLoadCall = null, $websiteFilter = [])
503
    {
504
        $helper = Mage::helper('eb2ccore');
505
        // create a DOMDocument for the xsl
506
        $xslDom = $helper->getNewDomDocument();
507
        $xslDom->load($xsltFilePath);
508
        if (is_callable($postXsltLoadCall)) {
509
            call_user_func($postXsltLoadCall, $xslDom, $websiteFilter);
0 ignored issues
show
introduced by
The use of function call_user_func() is forbidden
Loading history...
510
        }
511
        // load the xsl document into a XSLProcessor
512
        $xslProcessor = $helper->getNewXsltProcessor();
513
        $xslProcessor->importStyleSheet($xslDom);
514
        $xslProcessor->setParameter('', $params);
515
        // create a DOMDocument from the transformed XML
516
        $transformed = $helper->getNewDomDocument();
517
        $transformed->loadXML($xslProcessor->transformToXML($doc));
518
        return $transformed;
519
    }
520
521
    /**
522
     * Appends an <xsl:template match='' /> node to the XSLT DOM.
523
     * XSLT 1.0 won't let us use a variable reference, we have to form the
524
     * xpath as a string, and build a node and insert it.
525
     *
526
     * @param DOMDocument $xslDoc an already loaded DOM
527
     * @param string $xpathExpression to match
528
     * @return bool true (node inserted), or false (node insert failed)
529
     */
530
    function appendXslTemplateMatchNode($xslDoc, $xpathExpression)
531
    {
532
        $templateNode          = $xslDoc->createElement('xsl:template', '', 'http://www.w3.org/1999/XSL/Transform');
533
        $matchAttribute        = $xslDoc->createAttribute('match');
534
        $matchAttribute->value = $xpathExpression;
535
        $templateNode->appendChild($matchAttribute);
536
        $rc = $xslDoc->documentElement->insertBefore($templateNode);
537
        return $rc;
538
    }
539
540
    /**
541
     * Loads a key/ value pair with the relevant config fields of each Magento Web Store which allows us
542
     * to match an incoming feed to that specific destination.
543
     *
544
     * @param $mageStoreId
545
     * @return array of key/value pairs mapping an inbound feed to the given Magento Web Store.
546
     */
547
    protected function loadStoreviewConfig($mageStoreId)
548
    {
549
        $config = Mage::helper('eb2ccore')->getConfigModel($mageStoreId);
550
        return [
551
            'catalog_id'      => $config->catalogId,
552
            'client_id'       => $config->clientId,
553
            'store_id'        => $config->storeId,
554
            'lang_code'       => $config->languageCode,
555
            'mage_store_id'   => $mageStoreId,
556
            'mage_website_id' => Mage::getModel('core/store')->load($mageStoreId)->getWebsiteId(),
557
        ];
558
    }
559
560
    /**
561
     * Loads the relevant config fields of each Magento Web Site that allows us
562
     * to match an incoming feed to the appropriate destination.
563
     *
564
     * @TODO Should this actually return filters for every storeview or should
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
565
     * it just be websites?
566
     *
567
     * @return array of unique key/value pairs mapping an inbound feed to a Magento Web Site.
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<*,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
568
     */
569
    public function loadWebsiteFilters()
570
    {
571
        $allWebsites = [];
572
        // Default Store it has its own special configuration.
573
        $allWebsites[Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID] = $this->loadStoreviewConfig(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID);
574
        foreach (Mage::app()->getWebsites() as $website) {
575
            foreach ($website->getGroups() as $group) {
576
                foreach ($group->getStores() as $store) {
577
578
                    $filter = $this->loadStoreviewConfig($store->getId());
579
                    $this->logger->debug('Adding filter for storeview.', $this->context->getMetaData(__CLASS__, $filter));
580
                    $allWebsites[$store->getId()] = $filter;
581
582
                }
583
            }
584
        }
585
        return $allWebsites;
586
    }
587
588
    /**
589
     * Loads the relevant config fields of each Magento Web Site that allows us
590
     * to match an incoming feed to the appropriate destination. Should only
591
     * return store views that have configuration that is different than the
592
     * configuration of the default store view.
593
     *
594
     * @TODO This method is currently just loadWebsiteFilters with stores containing
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
595
     * the default configuration for feeds removed. I am suspicious of the degree
596
     * of correctness of loadWebsiteFilters, so this method may not always be definable
597
     * as is.
598
     *
599
     * @return array of unique key/value pairs mapping an inbound feed to a Magento Web Site.
600
     */
601
    public function loadStoreviewFilters()
602
    {
603
        return $this->uniqueSiteFilters($this->loadWebsiteFilters());
604
    }
605
606
    /**
607
     * Given a collection of site filters, return only those that represent
608
     * a unique feed configuration, at the lowest level at which that filter
609
     * might apply.
610
     *
611
     * @param array Store view data, keyed by store id, built by loadWebsiteFilters
612
     * @return array
613
     */
614
    protected function uniqueSiteFilters($siteFilters)
615
    {
616
        // Function to create hash of elements of a site filter that we care
617
        // about being unique.
618
        $hashSite = function ($site) {
619
            return sprintf(
620
                '%s|%s|%s|%s',
621
                $site['catalog_id'], $site['client_id'], $site['store_id'], $site['lang_code']
622
            );
623
        };
624
625
        // If there is no default store, no other store can have the same configuration
626
        // as it, so return all site filters.
627
        if (!isset($siteFilters[Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID])) {
628
            return $siteFilters;
629
        }
630
631
        $defaultSite = $siteFilters[Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID];
632
        $defaultSiteHash = $hashSite($defaultSite);
633
        // Always include the default site, which will be filtered out in the
634
        // loop when adding non-default configured sites.
635
        $uniqueSites = [$defaultSite];
636
637
        foreach ($siteFilters as $storeId => $siteFilter) {
638
            if ($hashSite($siteFilter) !== $defaultSiteHash) {
639
                $uniqueSites[$storeId] = $siteFilter;
640
            }
641
        }
642
643
        return $uniqueSites;
644
    }
645
646
    /**
647
     * get attribute set id by attribute set name
648
     * @param string $name the attribute set name
649
     * @return int the entity id of the attribute set or null when not found
650
     */
651
    public function getAttributeSetIdByName($name)
652
    {
653
        return Mage::getModel('eav/entity_attribute_set')
654
            ->getCollection()
655
            ->setEntityTypeFilter(Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId())
656
            ->addFieldToFilter('attribute_set_name', $name)
657
            ->getFirstItem()
0 ignored issues
show
introduced by
getFirstItem() does not limit the result of collection load to one item.
Loading history...
658
            ->getAttributeSetId();
659
    }
660
    /**
661
     * Get the default store view store id
662
     * @return int, the default store view store id
0 ignored issues
show
Documentation introduced by
The doc-type int, could not be parsed: Expected "|" or "end of type", but got "," at position 3. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
663
     */
664
    public function getDefaultStoreViewId()
665
    {
666
        return (int) Mage::app()->getDefaultStoreView()->getId();
667
    }
668
    /**
669
     * check if a string is a valid ISO-3166-1-alpha-2 code.
670
     * @param string $name the string to check if it is a valid ISO Country code.
671
     * @return bool true is valid ISO country code otherwise false.
672
     */
673
    public function isValidIsoCountryCode($name)
674
    {
675
        $collection = Mage::getResourceModel('directory/country_collection')
676
            ->addFieldToFilter('iso2_code', $name);
677
        return ($collection->count() > 0);
0 ignored issues
show
introduced by
Unnecessary loading of a Magento data collection. Use the getSize() method instead.
Loading history...
678
    }
679
    /**
680
     * Ensure the sku/client id/style id matches the same format expected for skus
681
     * {catalogId}-{item_id}
682
     *
683
     * @param  string $itemId    Product item/style/client/whatevs id
684
     * @param  string $catalogId Product catalog id
685
     * @return string            Normalized style id
686
     */
687
    public function normalizeSku($itemId, $catalogId)
688
    {
689
        if (!empty($itemId)) {
690
            $pos = strpos($itemId, $catalogId . '-');
691
            if ($pos === false || $pos !== 0) {
692
                return sprintf('%s-%s', $catalogId, $itemId);
693
            }
694
        }
695
        return $itemId;
696
    }
697
698
    /**
699
     * remove the client id found in a given sku {item_id}
700
     *
701
     * @param  string $itemId    Product item/style/client/whatevs id
702
     * @param  string $catalogId Product catalog id
703
     * @return string            Normalized style id
704
     */
705
    public function denormalizeSku($itemId, $catalogId)
706
    {
707
        return (!empty($itemId) && strpos($itemId, $catalogId . '-') === 0)?
708
            str_replace($catalogId . '-', '', $itemId) : $itemId;
709
    }
710
711
    /**
712
     * given a product object and a country code retrieve the hts_code value for this product
713
     * matching a given country code
714
     *
715
     * @param Mage_Catalog_Model_Product $product
716
     * @param string $countryCode the two letter code for a country (US, CA, DE, etc...)
717
     * @return string | null the htscode matching the country code for that product otherwise null
718
     */
719 View Code Duplication
    public function getProductHtsCodeByCountry(Mage_Catalog_Model_Product $product, $countryCode)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
720
    {
721
        $htsCodes = unserialize($product->getHtsCodes());
722
        if ($htsCodes) {
723
            foreach ($htsCodes as $htsCode) {
724
                if ($countryCode === $htsCode['destination_country']) {
725
                    return $htsCode['hts_code'];
726
                }
727
            }
728
        }
729
730
        return null;
731
    }
732
733
    /**
734
     * Save an EAV collection, disabling the indexer if the collection is
735
     * larger than a configured size.
736
     *
737
     * @param Mage_Eav_Model_Entity_Collection_Abstract
738
     * @return self
739
     */
740
    public function saveCollectionStubIndexer(Mage_Eav_Model_Entity_Collection_Abstract $collection)
741
    {
742
        $config = $this->getConfigModel();
743
        $stubIndexer = $config->maxPartialReindexSkus < $collection->getSize();
0 ignored issues
show
Documentation introduced by
The property maxPartialReindexSkus does not exist on object<EbayEnterprise_Eb..._Model_Config_Registry>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
744
        if ($stubIndexer) {
745
            // Stub the indexer so no indexing can take place during massive saves.
746
            $indexerKey = '_singleton/index/indexer';
747
            $oldIndexer = $this->reregister($indexerKey, $this->indexerStub);
748
        }
749
        $failureCount = 0;
750
        $logData = ['product_count' => $collection->getSize()];
751
        $logMessage = 'Saving {product_count} products with stubbed indexer.';
752
        $this->logger->info($logMessage, $this->context->getMetaData(__CLASS__, $logData));
753
        $failMessage = 'Failed to save product with sku {sku}.';
754
        foreach ($collection as $item) {
755
            try {
756
                $item->save();
0 ignored issues
show
Performance introduced by
Model LSD method save() detected in loop
Loading history...
757
            } catch (Exception $e) {
758
                $failureCount++;
759
                $failLogData = [
760
                    'sku' => $item->getSku(),
761
                    'exception' => $e,
762
                ];
763
                $this->logger
764
                    ->logException($e, $this->context->getMetaData(__CLASS__, $failLogData))
765
                    ->error($failMessage, $this->context->getMetaData(__CLASS__, $failLogData));
766
            }
767
        }
768
        $logMessage = 'Finished saving {product_count} products with {failure_count} failures.';
769
        $logData['failure_count'] = $failureCount;
770
        $this->logger->info($logMessage, $this->context->getMetaData(__CLASS__, $logData));
771
        if ($stubIndexer) {
772
            $this->reregister($indexerKey, $oldIndexer);
0 ignored issues
show
Bug introduced by
The variable $indexerKey does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $oldIndexer does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
773
        }
774
        return $this;
775
    }
776
777
    /**
778
     * Replace a value in the Mage::_registry with a new value.
779
     * If new value is not truthy, just deletes the registry entry.
780
     *
781
     * @param string
782
     * @param mixed
783
     * @return mixed
784
     */
785
    protected function reregister($key, $value=null)
786
    {
787
        $old = Mage::registry($key);
788
        Mage::unregister($key);
789
        if ($value) {
790
            Mage::register($key, $value);
791
        }
792
        return $old;
793
    }
794
}
795