Model   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 54
c 1
b 0
f 0
dl 0
loc 172
rs 10
wmc 26

10 Methods

Rating   Name   Duplication   Size   Complexity  
A types() 0 3 1
A sources() 0 3 1
A rules() 0 3 1
A labels() 0 3 1
A __construct() 0 5 1
A getAllProperties() 0 12 3
A clearProperties() 0 5 3
A getValidationRule() 0 20 6
B validate() 0 44 8
A before() 0 2 1
1
<?php
2
3
namespace Ffcms\Core\Arch;
4
5
use Dflydev\DotAccessData\Data as DotData;
6
use Ffcms\Core\App;
7
use Ffcms\Core\Exception\SyntaxException;
8
use Ffcms\Core\Helper\Type\Any;
9
use Ffcms\Core\Helper\Type\Str;
10
use Ffcms\Core\Interfaces\iModel;
11
use Ffcms\Core\Traits\ModelValidator;
12
use Ffcms\Templex\Helper\Html\Form\ModelInterface;
0 ignored issues
show
Bug introduced by
The type Ffcms\Templex\Helper\Html\Form\ModelInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Ffcms\Templex\Helper\Html\Form\Model as TemplexModel;
0 ignored issues
show
Bug introduced by
The type Ffcms\Templex\Helper\Html\Form\Model was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
15
/**
16
 * Class Model. Classic constructor of models in MVC architecture with algorithm of passing attributes from user input data.
17
 * @package Ffcms\Core\Arch
18
 */
19
abstract class Model extends TemplexModel implements iModel, ModelInterface
20
{
21
    use ModelValidator {
22
        ModelValidator::initialize as private validatorConstructor;
23
    }
24
25
    public $_csrf_token;
26
27
    /**
28
     * Model constructor. Initialize before() method for extended objects and run validator initialization
29
     * @param bool $csrf
30
     */
31
    public function __construct($csrf = false)
32
    {
33
        parent::__construct();
34
        $this->before();
35
        $this->validatorConstructor($csrf);
36
    }
37
38
    /**
39
     * Make any things before model is initialized
40
     */
41
    public function before()
42
    {
43
    }
44
45
    /**
46
     * Set attribute labels for model variables
47
     * @return array
48
     */
49
    public function labels(): array
50
    {
51
        return [];
52
    }
53
54
    /**
55
     * Set of model validation rules
56
     * @return array
57
     */
58
    public function rules(): array
59
    {
60
        return [];
61
    }
62
63
    /**
64
     * Set model data sources for input data
65
     * Allowed sources: get, post, file
66
     * @return array
67
     */
68
    public function sources(): array
69
    {
70
        return [];
71
    }
72
73
    /**
74
     * Set model property types to advanced filtering
75
     * Allowed types: text, html, !secure
76
     * Ex: ['property1' => 'text', 'property2' => 'html']
77
     * @return array
78
     */
79
    public function types(): array
80
    {
81
        return [];
82
    }
83
84
    /**
85
     * Validate defined rules in app
86
     * @return bool
87
     * @throws SyntaxException
88
     */
89
    final public function validate(): bool
90
    {
91
        // validate csrf token if required
92
        if ($this->_tokenRequired && !$this->_tokenOk) {
93
            App::$Session->getFlashBag()->add('warning', __('Hack attention: security token is wrong!'));
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

93
            App::$Session->getFlashBag()->add('warning', /** @scrutinizer ignore-call */ __('Hack attention: security token is wrong!'));
Loading history...
94
            return false;
95
        }
96
        // get all rules as array from method rules()
97
        $rules = $this->rules();
98
        // get default values of attributes
99
        $defaultAttr = $this->getAllProperties();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $defaultAttr is correct as $this->getAllProperties() targeting Ffcms\Core\Arch\Model::getAllProperties() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
100
101
        // start validation: on this step class attribute values will be changed to input data if it valid
102
        $success = $this->runValidate($rules);
103
104
        // get not-passed validation fields as array
105
        $badAttributes = $this->getBadAttributes();
106
        // prevent warnings
107
        if (Any::isArray($badAttributes) && count($badAttributes) > 0) {
108
            foreach ($badAttributes as $attr) {
109
                if (Str::contains('.', $attr)) { // sounds like dot-separated array attr
110
                    $attrName = strstr($attr, '.', true); // get attr name
111
                    $attrArray = trim(strstr($attr, '.'), '.'); // get dot-based array path
112
113
                    $defaultValue = new DotData($defaultAttr); // load default attr
114
115
                    $dotData = new DotData($this->{$attrName}); // load local attr variable
116
                    $dotData->set($attrArray, $defaultValue->get($attr)); // set to local prop. variable default value
117
118
                    $this->{$attrName} = $dotData->export(); // export to model
119
                } else {
120
                    $this->{$attr} = $defaultAttr[$attr]; // just set ;)
121
                }
122
                // add message about wrong attribute to session holder, later display it
123
                $attrLabel = $attr;
124
                if ($this->getLabel($attr) !== null) {
125
                    $attrLabel = $this->getLabel($attr);
126
                }
127
128
                App::$Session->getFlashBag()->add('warning', __('Field "%field%" is incorrect', ['field' => $attrLabel]));
129
            }
130
        }
131
132
        return $success;
133
    }
134
135
    /**
136
     * Get all properties for current model in key=>value array
137
     * @return array|null
138
     */
139
    public function getAllProperties(): ?array
140
    {
141
        $properties = null;
142
        // list all properties here, array_walk sucks on performance!
143
        foreach ($this as $property => $value) {
144
            if (Str::startsWith('_', $property)) {
145
                continue;
146
            }
147
148
            $properties[$property] = $value;
149
        }
150
        return $properties;
151
    }
152
153
    /**
154
     * Cleanup all public model properties
155
     * @return void
156
     */
157
    public function clearProperties(): void
158
    {
159
        foreach ($this as $property => $value) {
160
            if (!Str::startsWith('_', $property)) {
161
                $this->{$property} = null;
162
            }
163
        }
164
    }
165
166
    /**
167
     * Get validation rules for field
168
     * @param string $field
169
     * @return array
170
     */
171
    final public function getValidationRule($field): array
172
    {
173
        $rules = $this->rules();
174
        $response = [];
175
176
        foreach ($rules as $rule) {
177
            if (Any::isArray($rule[0])) { // 2 or more rules [['field1', 'field2'], 'filter', 'filter_argv']
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
178
                foreach ($rule[0] as $tfield) {
179
                    if ($tfield == $field) {
180
                        $response[$rule[1]] = $rule[2];
181
                    } // ['min_length' => 1, 'required' => null]
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
182
                }
183
            } else { // 1 rule ['field1', 'filter', 'filter_argv']
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
184
                if ($rule[0] === $field) {
185
                    $response[$rule[1]] = $rule[2];
186
                }
187
            }
188
        }
189
190
        return $response;
191
    }
192
}
193