Completed
Pull Request — master (#36)
by Tim
01:46
created

ClearImageObserver::deleteVarcharAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Category\Observers\ClearImageObserver
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2016 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import-category
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Category\Observers;
22
23
use TechDivision\Import\Utils\StoreViewCodes;
24
use TechDivision\Import\Category\Utils\ColumnKeys;
25
use TechDivision\Import\Category\Utils\MemberNames;
26
27
/**
28
 * Observer that extracts the category's image from a CSV file to be added to image specific CSV file.
29
 *
30
 * @author    Tim Wagner <[email protected]>
31
 * @copyright 2016 TechDivision GmbH <[email protected]>
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      https://github.com/techdivision/import-category
34
 * @link      http://www.techdivision.com
35
 */
36
class ClearImageObserver extends AbstractCategoryImportObserver
37
{
38
39
    /**
40
     * Process the observer's business logic.
41
     *
42
     * @return array The processed row
43
     */
44
    protected function process()
45
    {
46
47
        // initialize the store view code
48
        $this->getSubject()->prepareStoreViewCode();
49
50
        // load the PK
51
        $pk = $this->getValue($this->getPrimaryKeyColumnName());
52
53
        // load the store view - if no store view has been set, we assume the admin
54
        // store view, which will contain the default (fallback) attribute values
55
        $storeViewCode = $this->getSubject()->getStoreViewCode(StoreViewCodes::ADMIN);
56
57
        // query whether or not the row has already been processed
58
        if ($this->storeViewHasBeenProcessed($pk, $storeViewCode)) {
0 ignored issues
show
Bug introduced by
The method storeViewHasBeenProcessed() does not exist on TechDivision\Import\Cate...vers\ClearImageObserver. Did you maybe mean process()?

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...
59
            // log a message
60
            $this->getSystemLogger()->warning(
61
                $this->getSubject()->appendExceptionSuffix(
62
                    sprintf(
63
                        'Attributes for %s "%s" + store view code "%s" has already been processed',
64
                        $this->getPrimaryKeyColumnName(),
65
                        $pk,
66
                        $storeViewCode
67
                    )
68
                )
69
            );
70
71
            // return immediately
72
            return;
73
        }
74
75
        // load the store ID, use the admin store if NO store view code has been set
76
        $storeId = $this->getSubject()->getRowStoreId(StoreViewCodes::ADMIN);
0 ignored issues
show
Bug introduced by
The method getRowStoreId() does not exist on TechDivision\Import\Subjects\SubjectInterface. Did you maybe mean getRow()?

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...
77
78
        // load the image attribute
79
        $attribute = $this->getEavAttributeByAttributeCode('image');
80
81
        // remove the image if one exists
82
        if ($value = $this->loadVarcharAttribute($pk, $attribute[MemberNames::ATTRIBUTE_ID], $storeId)) {
83
            $this->deleteVarcharAttribute(array(MemberNames::VALUE_ID => $value[MemberNames::VALUE_ID]));
84
        }
85
    }
86
87
    /**
88
     * Delete's the varchar attribute with the passed value ID.
89
     *
90
     * @param array       $row  The attributes of the entity to delete
91
     * @param string|null $name The name of the prepared statement that has to be executed
92
     *
93
     * @return void
94
     */
95
    protected function deleteVarcharAttribute(array $row, $name = null)
96
    {
97
        return $this->getCategoryBunchProcessor()->deleteCategoryVarcharAttribute($row, $name);
0 ignored issues
show
Bug introduced by
The method getCategoryBunchProcessor() does not exist on TechDivision\Import\Cate...vers\ClearImageObserver. Did you maybe mean process()?

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...
98
    }
99
100
    /**
101
     * Load's and return's the varchar attribute with the passed entity/attribute/store ID.
102
     *
103
     * @param integer $entityId    The entity ID of the attribute
104
     * @param integer $attributeId The attribute ID of the attribute
105
     * @param integer $storeId     The store ID of the attribute
106
     *
107
     * @return array|null The varchar attribute
108
     */
109
    protected function loadVarcharAttribute($entityId, $attributeId, $storeId)
110
    {
111
        return $this->getCategoryBunchProcessor()->loadCategoryVarcharAttribute($entityId, $attributeId, $storeId);
0 ignored issues
show
Bug introduced by
The method getCategoryBunchProcessor() does not exist on TechDivision\Import\Cate...vers\ClearImageObserver. Did you maybe mean process()?

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...
112
    }
113
114
    /**
115
     * Return's the EAV attribute with the passed attribute code.
116
     *
117
     * @param string $attributeCode The attribute code
118
     *
119
     * @return array The array with the EAV attribute
120
     * @throws \Exception Is thrown if the attribute with the passed code is not available
121
     */
122
    protected function getEavAttributeByAttributeCode($attributeCode)
123
    {
124
        return $this->getSubject()->getEavAttributeByAttributeCode($attributeCode);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method getEavAttributeByAttributeCode() does only exist in the following implementations of said interface: TechDivision\Import\Cate...AbstractCategorySubject, TechDivision\Import\Category\Subjects\BunchSubject, TechDivision\Import\Observers\EntitySubjectImpl, TechDivision\Import\Subjects\AbstractEavSubject.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
125
    }
126
127
    /**
128
     * Return's the category with the passed path.
129
     *
130
     * @param string $path The path of the category to return
131
     *
132
     * @return array The category
133
     */
134
    protected function getCategoryByPath($path)
135
    {
136
        return $this->getSubject()->getCategoryByPath($path);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method getCategoryByPath() does only exist in the following implementations of said interface: TechDivision\Import\Cate...AbstractCategorySubject, TechDivision\Import\Category\Subjects\BunchSubject.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
137
    }
138
139
    /**
140
     * Return's the PK to create the product => attribute relation.
141
     *
142
     * @return integer The PK to create the relation with
143
     */
144
    protected function getPrimaryKey()
145
    {
146
        return $this->getSubject()->getLastEntityId();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface TechDivision\Import\Subjects\SubjectInterface as the method getLastEntityId() does only exist in the following implementations of said interface: TechDivision\Import\Cate...AbstractCategorySubject, TechDivision\Import\Category\Subjects\BunchSubject, TechDivision\Import\Observers\EntitySubjectImpl, TechDivision\Import\Plugins\ExportableSubjectImpl, TechDivision\Import\Subjects\ExportableTraitImpl.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
147
    }
148
149
    /**
150
     * Return's the PK column name to create the product => attribute relation.
151
     *
152
     * @return string The PK column name
153
     */
154
    protected function getPrimaryKeyMemberName()
155
    {
156
        return MemberNames::ENTITY_ID;
157
    }
158
159
    /**
160
     * Return's the column name that contains the primary key.
161
     *
162
     * @return string the column name that contains the primary key
163
     */
164
    protected function getPrimaryKeyColumnName()
165
    {
166
        return ColumnKeys::PATH;
167
    }
168
}
169