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.
Passed
Push — master ( c721cc...3ff35f )
by Ivan
09:59
created

Yml::generate()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 41
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 41
rs 8.439
c 1
b 0
f 0
cc 5
eloc 25
nc 5
nop 0
1
<?php
2
namespace app\modules\shop\components\yml;
3
4
use app\models\ObjectStaticValues;
5
use app\models\Property;
6
use app\models\PropertyStaticValues;
7
use app\modules\shop\events\yml\YmlOffersEvent;
8
use app\modules\shop\helpers\CurrencyHelper;
9
use app\modules\shop\models\Category;
10
use app\modules\shop\models\Currency;
11
use app\modules\shop\models\Product;
12
use devgroup\TagDependencyHelper\ActiveRecordHelper;
13
use Yii;
14
use yii\base\Component;
15
use app\modules\shop\models\Yml as YmlModel;
16
use yii\caching\TagDependency;
17
use yii\db\Query;
18
use yii\helpers\Json;
19
use yii\helpers\Url;
20
use yii\web\View;
21
22
class Yml extends Component
23
{
24
    const PARAM_TYPE_FIELD = 'field';
25
    const PARAM_TYPE_RELATION = 'relation';
26
    const USE_GZIP = 1;
27
    const USE_OFFER_PARAM = 1;
28
    const USE_ADULT = 1;
29
    const USE_STORE = 1;
30
    const USE_PICKUP = 1;
31
    const USE_DELIVERY = 1;
32
33
    const EVENT_PROCESS_OFFER = 'ymlProcessOffer';
34
35
    /**
36
     * @property \app\modules\shop\models\Yml $model
37
     * @property string $viewFile
38
     * @property Currency $currency
39
     */
40
    protected $model = null;
41
    protected $viewFile = null;
42
    protected $currency = null;
43
44
    static public $_noImg = '';
45
    static public $ymlEavProperties = [];
46
    static public $ymlStaticProperties = [];
47
48
    /**
49
     * @inheritdoc
50
     */
51
    public function __construct(YmlModel $model, $config = [])
52
    {
53
        $this->model = $model;
54
        parent::__construct($config);
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60
    public function init()
61
    {
62
        parent::init();
63
64
        if (false === $this->model instanceof YmlModel) {
65
            return false;
66
        }
67
68
        if (null === $this->viewFile) {
69
            $this->viewFile = Yii::$app->getModule('shop')->getViewPath() . '/backend-yml/generate/yml.php';
70
        }
71
72
        /** @var YmlModel $config */
73
        $config = $this->model;
74
        Yii::$app->urlManager->setHostInfo($config->shop_url);
0 ignored issues
show
Documentation introduced by
The property shop_url does not exist on object<app\modules\shop\models\Yml>. 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...
75
        $this->currency = CurrencyHelper::findCurrencyByIso($config->currency_id);
0 ignored issues
show
Documentation introduced by
The property currency_id does not exist on object<app\modules\shop\models\Yml>. 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...
76
77
        if (static::USE_OFFER_PARAM == $config->offer_param) {
0 ignored issues
show
Documentation introduced by
The property offer_param does not exist on object<app\modules\shop\models\Yml>. 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...
78
            $this->prepareProperties();
79
        }
80
81
        static::$_noImg = Yii::$app->getModule('image')->noImageSrc;
82
    }
83
84
    /**
85
     * @return bool
86
     */
87
    public function generate()
88
    {
89
        if (false === $this->model instanceof YmlModel) {
90
            return false;
91
        }
92
93
        /** @var \app\modules\shop\models\Yml $yml */
94
        $config = $this->model;
95
        /** @var View $view */
96
        $view = Yii::$app->getView();
97
98
        $outputParams = [];
99
        $outputParams['shop'] = $this->generateSectionShop($config);
100
        $outputParams['offers'] = [];
101
102
        $eventOffer = new YmlOffersEvent();
103
        $product = Yii::$container->get(Product::class);
104
        /** @var Product $model */
105
        foreach ($product::find()->where(['active' => 1])->batch() as $offers) {
106
            $eventOffer
107
                ->clearHandled()
108
                ->setOffers(array_reduce($offers, function ($r, $i) use ($config) {
109
                    if (null !== $o = $this->generateSingleOffer($config, $i)) {
110
                        $r[] = $o;
111
                    }
112
                    return $r;
113
                }, []));
114
            $this->trigger(static::EVENT_PROCESS_OFFER, $eventOffer);
115
116
            $outputParams['offers'] = array_merge($outputParams['offers'], array_column($eventOffer->getOffers(), 'result'));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 125 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
117
        }
118
119
        $output = $view->renderFile($this->viewFile, $outputParams);
120
121
        $fileName = Yii::getAlias('@webroot') . '/' . $config->general_yml_filename;
0 ignored issues
show
Documentation introduced by
The property general_yml_filename does not exist on object<app\modules\shop\models\Yml>. 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...
122
        $result = static::USE_GZIP === $config->use_gzip
0 ignored issues
show
Documentation introduced by
The property use_gzip does not exist on object<app\modules\shop\models\Yml>. 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...
123
            ? file_put_contents($fileName . '.gz', gzencode($output), 5)
124
            : file_put_contents($fileName, $output);
125
126
        return false !== $result;
127
    }
128
129
    /**
130
     * @param YmlModel $config
131
     * @param string $name
132
     * @param Product $model
133
     * @param string $default
134
     * @return mixed
135
     */
136
    public static function getOfferValue(YmlModel $config, $name, Product $model, $default = '')
137
    {
138
        $param = $config->$name;
139
140
        if (static::PARAM_TYPE_FIELD === $param['type']) {
141
            $field = $param['key'];
142
            $result = $model->$field;
143
        } elseif (static::PARAM_TYPE_RELATION === $param['type']) {
144
            $rel = call_user_func([$model, $param['key']]);
145
            $attr = $param['value'];
146
            $rel = $rel->one();
147
            if (false === empty($rel)) {
148
                $result = $rel->$attr;
149
            }
150
        }
151
152
        return false === empty($result) ? $result : $default;
0 ignored issues
show
Bug introduced by
The variable $result 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...
153
    }
154
155
    /**
156
     *
157
     */
158
    private function prepareProperties()
159
    {
160
        $props = Property::getDb()->cache(function ($db) {
0 ignored issues
show
Unused Code introduced by
The parameter $db is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
161
            return Property::find()->select([
162
                'id',
163
                'name',
164
                'property_handler_id',
165
                'key',
166
                'property_group_id',
167
                'has_static_values',
168
                'is_eav',
169
                'handler_additional_params'
170
            ])->all();
171
        }, 86400, new TagDependency(['tags' => [ActiveRecordHelper::getCommonTag(Property::className()),]]));
172
        foreach ($props as $one) {
173
            $additionalParams = Json::decode($one['handler_additional_params']);
174
            if (false === empty($additionalParams['use_in_file'])) {
175
                if (1 == $one['is_eav'] && false === isset(self::$ymlEavProperties[$one['id']])) {
176
                    self::$ymlEavProperties[$one['id']] = [
177
                        'name' => $one['name'],
178
                        'unit' => empty($additionalParams['unit']) ? '' : $additionalParams['unit'],
179
                        'key' => $one['key'],
180
                        'group_id' => $one['property_group_id'],
181
                        'handler_id' => $one['property_handler_id'],
182
                    ];
183
                } elseif (1 == $one['has_static_values'] && false === isset(self::$ymlStaticProperties[$one['id']])) {
184
                    self::$ymlStaticProperties[$one['id']] = [
185
                        'name' => $one['name'],
186
                        'unit' => empty($additionalParams['unit']) ? '' : $additionalParams['unit'],
187
                    ];
188
                }
189
190
            }
191
        }
192
    }
193
194
    /**
195
     * @param Product $model
196
     * @return array
197
     */
198
    public static function getOfferParams(Product $model)
199
    {
200
        $params = [];
201
        $eav = Yii::$app->getDb()->cache(function ($db) use ($model) {
0 ignored issues
show
Unused Code introduced by
The parameter $db is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
202
            /**
203
             * @var \app\models\Object $object
204
             */
205
            $object = $model->object;
0 ignored issues
show
Documentation introduced by
The property object does not exist on object<app\modules\shop\models\Product>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
206
            return (new Query())
207
                ->from($object->eav_table_name)
208
                ->select(Property::tableName() . '.id, ' . $object->eav_table_name . '.value')
209
                ->innerJoin(
210
                    Property::tableName(),
211
                    Property::tableName() . '.property_group_id = ' . $object->eav_table_name . '.property_group_id'
212
                    . ' AND ' . Property::tableName() . '.key = ' . $object->eav_table_name . '.key'
213
                )
214
                ->where([
215
                    'object_model_id' => $model->id,
216
                    $object->eav_table_name . '.key' => array_column(static::$ymlEavProperties, 'key'),
217
                    $object->eav_table_name . '.property_group_id' => array_column(static::$ymlEavProperties, 'group_id'),
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
218
                    Property::tableName() . '.id' => array_keys(static::$ymlEavProperties),
219
                ])
220
                ->andWhere(['<>','value', ''])
221
                ->all();
222
        });
223
        foreach ($eav as $prop) {
224
            if (false === isset($prop['id'])) {
225
                continue ;
226
            }
227
228
            $val = htmlspecialchars($prop['value']);
229
            switch (static::$ymlEavProperties[$prop['id']]['handler_id']) {
230
                case 3 :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
231
                    $val = $val == 1 ? Yii::t('yii', 'Yes') : Yii::t('yii', 'No');
232
                    break;
233
            }
234
            $_key = static::$ymlEavProperties[$prop['id']]['name'];
235
            $params[htmlspecialchars(trim($_key))] = [
236
                'unit' => false === empty(static::$ymlEavProperties[$prop['id']]['unit'])
237
                    ? htmlspecialchars(trim(static::$ymlEavProperties[$prop['id']]['unit']))
238
                    : null,
239
                'value' => $val,
240
            ];
241
        }
242
243
        $psv = Yii::$app->getDb()->cache(function ($db) use ($model) {
0 ignored issues
show
Unused Code introduced by
The parameter $db is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
244
            return  (new Query())
245
                ->from(PropertyStaticValues::tableName())
246
                ->innerJoin(
247
                    ObjectStaticValues::tableName(),
248
                    ObjectStaticValues::tableName() . '.property_static_value_id = ' . PropertyStaticValues::tableName() . '.id'
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
249
                )
250
                ->where([
251
                    'object_model_id' => $model->id,
252
                    'object_id' => $model->object->id,
0 ignored issues
show
Documentation introduced by
The property object does not exist on object<app\modules\shop\models\Product>. 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...
253
                    'property_id' => array_keys(static::$ymlStaticProperties)
254
                ])
255
                ->andWhere(['<>','value', ''])
256
                ->all();
257
        });
258
        foreach ($psv as $prop) {
259
            if (false === isset($prop['property_id'])) {
260
                continue ;
261
            }
262
263
            $_key = static::$ymlStaticProperties[$prop['property_id']]['name'];
264
            $params[htmlspecialchars(trim($_key))] = [
265
                'unit' => false === empty(static::$ymlStaticProperties[$prop['property_id']]['unit'])
266
                    ? htmlspecialchars(trim(static::$ymlStaticProperties[$prop['property_id']]['unit']))
267
                    : null,
268
                'value' => htmlspecialchars(trim($prop['value'])),
269
            ];
270
        }
271
272
        return $params;
273
    }
274
275
    /**
276
     * @param YmlModel $config
277
     * @return array
278
     */
279
    private function generateSectionShop(YmlModel $config)
280
    {
281
        return [
282
            'name' => $config->shop_name,
0 ignored issues
show
Documentation introduced by
The property shop_name does not exist on object<app\modules\shop\models\Yml>. 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...
283
            'company' => $config->shop_company,
0 ignored issues
show
Documentation introduced by
The property shop_company does not exist on object<app\modules\shop\models\Yml>. 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...
284
            'url' => $config->shop_url,
0 ignored issues
show
Documentation introduced by
The property shop_url does not exist on object<app\modules\shop\models\Yml>. 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...
285
            'currency' => $this->currency->iso_code,
286
            'categories' => Category::find()->where(['active' => 1])->asArray(),
287
            'store' => static::USE_STORE == $config->shop_store ? 'true' : 'false',
0 ignored issues
show
Documentation introduced by
The property shop_store does not exist on object<app\modules\shop\models\Yml>. 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...
288
            'pickup' => static::USE_PICKUP == $config->shop_pickup ? 'true' : 'false',
0 ignored issues
show
Documentation introduced by
The property shop_pickup does not exist on object<app\modules\shop\models\Yml>. 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...
289
            'delivery' => static::USE_DELIVERY == $config->shop_delivery ? 'true' : 'false',
0 ignored issues
show
Documentation introduced by
The property shop_delivery does not exist on object<app\modules\shop\models\Yml>. 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...
290
            'local_delivery_cost' => $config->shop_local_delivery_cost,
0 ignored issues
show
Documentation introduced by
The property shop_local_delivery_cost does not exist on object<app\modules\shop\models\Yml>. 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...
291
            'adult' => static::USE_ADULT == $config->shop_adult ? 'true' : 'false',
0 ignored issues
show
Documentation introduced by
The property shop_adult does not exist on object<app\modules\shop\models\Yml>. 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...
292
        ];
293
    }
294
295
    /**
296
     * @param YmlModel $config
297
     * @param Product $model
298
     * @return null|array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use null|array<string,Product|OfferTag>.

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...
299
     */
300
    private function generateSingleOffer(YmlModel $config, Product $model)
301
    {
302
        $result = $this->offerSimplified($config, $model);
303
        if (null === $result) {
304
            return null;
305
        }
306
307
        return [
308
            'model' => $model,
309
            'result' => $result,
310
        ];
311
    }
312
313
    /**
314
     * @param YmlModel $config
315
     * @param Product $model
316
     * @return OfferTag|null
317
     */
318
    private function offerSimplified(YmlModel $config, Product $model)
319
    {
320
        $offer = new OfferTag('offer', [], ['id' => $model->id, 'available' => 'true',]);
0 ignored issues
show
Documentation introduced by
array() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
321
322
        $price = static::getOfferValue($config, 'offer_price', $model, 0);
323
        $price = CurrencyHelper::convertCurrencies($price, $model->currency, $this->currency);
0 ignored issues
show
Bug introduced by
The property currency does not seem to exist. Did you mean currency_id?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
324
        if ($price <= 0 || $price >= 1000000000) {
325
            return null;
326
        }
327
328
        $values = [];
329
330
        $name = static::getOfferValue($config, 'offer_name', $model, null);
331
        if (true === empty($name)) {
332
            return null;
333
        }
334 View Code Duplication
        if (mb_strlen($name) > 120) {
335
            $name = mb_substr($name, 0, 120);
336
            $name = mb_substr($name, 0, mb_strrpos($name, ' '));
337
        }
338
        $values[] = new OfferTag('name', htmlspecialchars(trim(strip_tags($name))));
339
        $values[] = new OfferTag('price', $price);
340
        $values[] = new OfferTag('currencyId', $this->currency->iso_code);
341
342
        /** @var Category $category */
343
        if (null === $category = $model->category) {
344
            return null;
345
        }
346
        $values[] = new OfferTag('categoryId', $category->id);
347
        $values[] = new OfferTag('url', Url::toRoute([
348
            '@product',
349
            'model' => $model,
350
            'category_group_id' => $category->category_group_id,
351
        ], true));
352
353
        $picture = static::getOfferValue($config, 'offer_picture', $model, static::$_noImg);
354
        if (static::$_noImg !== $picture) {
355
            $picture = htmlspecialchars(trim($picture, '/'));
356
            $picture = implode('/', array_map('rawurlencode', explode('/', $picture)));
357
            $values[] = new OfferTag('picture', trim($config->shop_url, '/') . '/' . $picture);
0 ignored issues
show
Documentation introduced by
The property shop_url does not exist on object<app\modules\shop\models\Yml>. 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...
358
        }
359
360
        $description = static::getOfferValue($config, 'offer_description', $model, null);
361
362
        if (false === empty($description)) {
363
            $description = preg_replace("/([\r\n\t])/", ' ', $description);
364
            $description = preg_replace("/[ ]{2,}/", '', $description);
365
            $description = htmlspecialchars(trim(strip_tags($description)));
366
367 View Code Duplication
            if (mb_strlen($description) > 175) {
368
                $description = mb_substr($description, 0, 175);
369
                $description = mb_substr($description, 0, mb_strrpos($description, ' '));
370
            }
371
372
            $values[] = new OfferTag('description', $description);
373
        }
374
375
        if (static::USE_OFFER_PARAM == $config->offer_param) {
0 ignored issues
show
Documentation introduced by
The property offer_param does not exist on object<app\modules\shop\models\Yml>. 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...
376
            foreach (static::getOfferParams($model) as $k => $v) {
377
                $values[] = new OfferTag('param', $v['value'], ['name' => $k, 'unit' => $v['unit']]);
378
            }
379
        }
380
381
        return $offer->setValue($values);
382
    }
383
}
384