TestingClass::methodRules()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
namespace carono\exchange1c\models;
5
6
7
use carono\exchange1c\helpers\ClassHelper;
8
use carono\exchange1c\helpers\ModuleHelper;
9
use yii\db\ActiveRecord;
10
use yii\helpers\ArrayHelper;
11
use yii\helpers\StringHelper;
12
use Zenwalker\CommerceML\CommerceML;
13
14
/**
15
 * Class TestingClass
16
 *
17
 * @package carono\exchange1c\models
18
 * @property mixed $result
19
 */
20
abstract class TestingClass extends Testing
21
{
22
    public $caption;
23
    protected static $property;
24
    protected static $required = false;
25
    public $expect;
26
27
    const RETURN_STRING = 'string';
28
    const RETURN_INTERFACE = 'interface';
29
30
    /**
31
     * [['name'], 'return' => 'array|string|interface']
32
     * [['name'], 'return' => 'interface', 'value'=>'']
33
     *
34
     *
35
     * @return array
36
     */
37
    protected static function methodRules()
38
    {
39
        return [];
40
    }
41
42
    /**
43
     * @param $result
44
     * @return mixed
45
     */
46
    protected function saveResult($result)
47
    {
48
        if (\Yii::$app->cache) {
49
            \Yii::$app->cache->set([$this->method, self::getPropertyClass()], $result);
50
        }
51
        return $result;
52
    }
53
54
    /**
55
     * @return mixed|null
56
     */
57
    protected function getSavedResult()
58
    {
59
        if (\Yii::$app->cache) {
60
            return \Yii::$app->cache->get([$this->method, self::getPropertyClass()]);
61
        }
62
        return null;
63
    }
64
65
    /**
66
     * @param $params
67
     * @return array
68
     */
69
    protected static function getParams($params)
70
    {
71
        $values = [];
72
        foreach ($params as $param) {
73
            $value = null;
74
            $cml = new CommerceML();
75
            $cml->loadImportXml(\Yii::getAlias('@vendor/carono/yii2-1c-exchange/files/xml/import.xml'));
76
            $cml->loadOffersXml(\Yii::getAlias('@vendor/carono/yii2-1c-exchange/files/xml/offers.xml'));
77
            if ($param instanceof \Closure) {
78
                $values[] = call_user_func($param);
79
            } elseif (StringHelper::startsWith($param, 'cml.')) {
80
                $value = ArrayHelper::getValue($cml, substr($param, 4));
81
            } else {
82
                $value = $param;
83
            }
84
            $values[] = $value;
85
        }
86
        return $values;
87
    }
88
89
    /**
90
     * @return ActiveRecord|mixed
91
     */
92
    protected static function getPropertyClass()
93
    {
94
        return self::module()->{static::$property};
95
    }
96
97
    /**
98
     * @param $method
99
     * @param $params
100
     * @return mixed|null
101
     */
102
    protected static function getMethodResult($method, $params)
103
    {
104
        $class = self::getPropertyClass();
105
        $methodResult = null;
106
        if (method_exists($class, $method)) {
107
            $reflectionMethod = new \ReflectionMethod($class, $method);
108
            $params = self::getParams($params);
109
            try {
110
                if ($reflectionMethod->isStatic()) {
111
                    $methodResult = call_user_func_array("$class::$method", $params);
112
                } elseif (!$context = static::getContext()) {
113
                    return null;
114
                } else {
115
                    $methodResult = call_user_func_array([$context, $method], $params);
116
                }
117
            } catch (\Exception $e) {
118
                return null;
119
            }
120
        }
121
        return $methodResult;
122
    }
123
124
    /**
125
     * @param Testing $test
126
     * @param $method
127
     * @param $rule
128
     */
129
    private static function validateMethodRule($test, $method, $rule)
130
    {
131
132
    }
133
134
    public static function findAll()
135
    {
136
        $result = parent::findAll();
137
        foreach (static::methodRules() as $method => $rule) {
138
            $test = new static();
139
            $test->name = "Результат '$method'";
140
            $test->method = $method;
141
            $test->expect = ArrayHelper::getValue($rule, 'return', false) ?: 'VOID';
142
            $result[] = $test;
143
        }
144
        return $result;
145
    }
146
147
    protected static function getContext()
148
    {
149
        $class = \Yii::$app->controller->module->{static::$property};
150
        return InterfaceTest::findByClass($class)->getModel();
151
    }
152
153
    public static function testPropertyIsSet()
154
    {
155
        $property = static::$property;
156
        $test = new static();
157
        $test->name = ModuleHelper::getModuleNameByClass() . "->{$property}";
158
        if (!self::module()->{$property}) {
159
            $test->result = false;
160
            $test->comment = "Необходимо прописать '$property' в модуле '" . ModuleHelper::getModuleNameByClass() . "'";
161
        }
162
        return $test;
163
    }
164
165
    public function hasResult()
166
    {
167
        return $this->_result;
168
    }
169
170
    public function getResult($force = false)
171
    {
172
        if (!$force && ($cache = $this->getSavedResult())) {
173
            return $cache;
174
        }
175
        try {
176
            return $this->saveResult($this->prepareResult());
177
        } catch (\Exception $e) {
178
            return $e->getMessage();
179
        }
180
    }
181
182
    public function prepareResult()
183
    {
184
        if ($method = $this->method) {
185
            $methodName = "getResult" . ucfirst($method);
186
            if (method_exists($this, $methodName)) {
187
                $result = call_user_func([$this, $methodName]);
188
                return $this->_result = $result;
189
            } else {
190
                $params = ArrayHelper::getValue(static::methodRules(), $method . '.params', []);
191
                return $this->_result = static::getMethodResult($method, $params);
192
            }
193
        } else {
194
            return null;
195
        }
196
    }
197
198
    public static function testImplementsClass()
199
    {
200
        $property = static::$property;
201
        $test = new static();
202
        $test->name = "Реализация интерфейсов $property (" . self::module()->{$property} . ")";
203
        $propertyValue = self::module()->{$property};
204
        $propertyDoc = ModuleHelper::getPhpDocInterfaceProperty($property);
205
        $implements = ClassHelper::getImplementedMethods($propertyValue, $propertyDoc);
206
        $implements = array_filter($implements, function ($data) {
207
            return !$data;
208
        });
209
        if (!empty($implements)) {
210
            $comment = [];
211
            foreach ($implements as $class => $value) {
212
                $comment[] = $class;
213
                $test->addError('', 'Need implement: ' . $class);
214
            }
215
            $test->comment = "Не реализованы:<br>" . join("<br>", $comment);
216
        }
217
        return $test;
218
    }
219
220
    public static function getMethodRule($method)
221
    {
222
        return ArrayHelper::getValue(static::methodRules(), $method, []);
223
    }
224
225
    public function isAutoTest()
226
    {
227
        return ArrayHelper::getValue(self::getMethodRule($this->method), 'auto') == true;
228
    }
229
230
    public function validateMethod()
231
    {
232
        return false;
233
    }
234
235
    public function testing()
236
    {
237
        if (!$rule = self::getMethodRule($this->method)) {
238
            return parent::testing();
239
        }
240
        $result = $this->isAutoTest() ? $this->getResult() : $this->getSavedResult();
241
        $validateMethod = 'validateMethod' . ucfirst($this->method);
242
        if (method_exists($this, $validateMethod)) {
243
            $params = self::getParams($rule['params']);
244
            $params[] = $result;
245
            return call_user_func_array([$this, $validateMethod], $params);
246
        }
247
        switch ($rule['return']) {
248
            case 'string':
249
                return is_string($result);
250
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
251
            case 'interface';
252
                return $result instanceof $rule['value'];
253
                break;
254
        }
255
    }
256
}