Completed
Branch master (49dc1a)
by Yaro
01:42
created

AbstractField   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 13

Test Coverage

Coverage 89.71%

Importance

Changes 0
Metric Value
wmc 30
lcom 2
cbo 13
dl 0
loc 176
ccs 61
cts 68
cp 0.8971
rs 10
c 0
b 0
f 0

26 Methods

Rating   Name   Duplication   Size   Complexity  
A afterStore() 0 4 1
A afterUpdate() 0 4 1
A make() 0 13 2
A value() 0 9 3
A shouldSkip() 0 4 1
A beforeUpdate() 0 4 1
A isInline() 0 4 1
A isRelationField() 0 4 1
A isMultiple() 0 4 1
A isEncode() 0 4 1
A isMarkupRow() 0 4 1
A isOrderable() 0 4 1
A isAjax() 0 4 1
A isNullable() 0 4 1
A hasTooltip() 0 4 1
A hasClipboardButton() 0 4 1
A isTranslatable() 0 4 1
A isMaskable() 0 4 1
A getPlaceholder() 0 4 1
A hasMaxlength() 0 4 1
A getHistoryView() 0 6 1
getListView() 0 1 ?
getEditFormView() 0 1 ?
getCreateFormView() 0 1 ?
A prepare() 0 23 5
A crud() 0 4 1
1
<?php
2
3
namespace Yaro\Jarboe\Table\Fields;
4
5
use Illuminate\Http\Request;
6
use Yaro\Jarboe\Table\CRUD;
7
use Yaro\Jarboe\Table\Fields\Interfaces\FieldPropsInterface;
8
use Yaro\Jarboe\Table\Fields\Traits\Column;
9
use Yaro\Jarboe\Table\Fields\Traits\DefaultTrait;
10
use Yaro\Jarboe\Table\Fields\Traits\Filter;
11
use Yaro\Jarboe\Table\Fields\Traits\Hidden;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Yaro\Jarboe\Table\Fields\Hidden.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
12
use Yaro\Jarboe\Table\Fields\Traits\Model;
13
use Yaro\Jarboe\Table\Fields\Traits\Name;
14
use Yaro\Jarboe\Table\Fields\Traits\OldAndAttribute;
15
use Yaro\Jarboe\Table\Fields\Traits\Readonly;
16
use Yaro\Jarboe\Table\Fields\Traits\Tab;
17
use Yaro\Jarboe\Table\Fields\Traits\Title;
18
use Yaro\Jarboe\Table\Fields\Traits\Width;
19
20
abstract class AbstractField implements FieldPropsInterface
21
{
22
    use Hidden;
23
    use Width;
24
    use Column;
25
    use Tab;
26
    use Readonly;
27
    use DefaultTrait;
28
    use Title;
29
    use Name;
30
    use OldAndAttribute;
31
    use Model;
32
    use Filter;
33
34
    const DEFAULT_TAB_IDENT = '[extra]';
35
36
    private $crud;
37
    public static $repeaterAdapterClass;
38
39 1002
    public static function make($name = '', $title = '')
40
    {
41 1002
        $field = new static;
42
43 1002
        if (!$title) {
44 951
            $title = preg_replace('~_~', ' ', ucfirst($name));
45
        }
46 1002
        $field->title($title);
47 1002
        $field->name($name);
48 1002
        $field->tab(self::DEFAULT_TAB_IDENT);
49
50 1002
        return $field;
51
    }
52
53 19
    public function value(Request $request)
54
    {
55 19
        $value = $request->get($this->name());
56 19
        if (!$value && $this->isNullable()) {
57 3
            return null;
58
        }
59
60 19
        return $value;
61
    }
62
63 14
    public function shouldSkip(Request $request)
64
    {
65 14
        return false;
66
    }
67
68 1
    public function afterStore($model, Request $request)
69
    {
70
        // dummy
71 1
    }
72
73 2
    public function afterUpdate($model, Request $request)
74
    {
75
        // dummy
76 2
    }
77
78 1
    public function beforeUpdate($model)
79
    {
80
        // dummy
81 1
    }
82
83 12
    public function isInline()
84
    {
85 12
        return false;
86
    }
87
88 19
    public function isRelationField()
89
    {
90 19
        return false;
91
    }
92
93 16
    public function isMultiple()
94
    {
95 16
        return false;
96
    }
97
98 17
    public function isEncode()
99
    {
100 17
        return false;
101
    }
102
103 74
    public function isMarkupRow()
104
    {
105 74
        return false;
106
    }
107
108 4
    public function isOrderable()
109
    {
110 4
        return false;
111
    }
112
113 17
    public function isAjax()
114
    {
115 17
        return false;
116
    }
117
118 3
    public function isNullable()
119
    {
120 3
        return false;
121
    }
122
123 13
    public function hasTooltip()
124
    {
125 13
        return false;
126
    }
127
128 14
    public function hasClipboardButton()
129
    {
130 14
        return false;
131
    }
132
133 70
    public function isTranslatable()
134
    {
135 70
        return false;
136
    }
137
138 16
    public function isMaskable()
139
    {
140 16
        return false;
141
    }
142
143 8
    public function getPlaceholder()
144
    {
145 8
        return null;
146
    }
147
148 15
    public function hasMaxlength(): bool
149
    {
150 15
        return false;
151
    }
152
153 1
    public function getHistoryView($value)
154
    {
155 1
        return view('jarboe::crud.fields.abstract.history', [
156 1
            'value' => $value,
157
        ]);
158
    }
159
160
    abstract public function getListView($model);
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
161
162
    abstract public function getEditFormView($model);
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
163
164
    abstract public function getCreateFormView();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
165
166
    // TODO: interface type-hinting
167 58
    public function prepare(CRUD $crud)
168
    {
169 58
        $this->crud = $crud;
170
171 58
        if ($this->filter()) {
172
            $this->filter()->value(
173
                $this->filter()->getValue($crud->tableIdentifier())
174
            );
175
        }
176
177 58
        $this->setModel($crud->getModel());
178
179 58
        if (method_exists($this, 'setRelationSearchUrl')) {
180
            $this->setRelationSearchUrl($crud->relationSearchUrl());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Yaro\Jarboe\Table\Fields\AbstractField as the method setRelationSearchUrl() does only exist in the following sub-classes of Yaro\Jarboe\Table\Fields\AbstractField: Yaro\Jarboe\Etc\CustomFields\PermissionField, Yaro\Jarboe\Etc\CustomFields\RoleField, Yaro\Jarboe\Table\Fields\Radio, Yaro\Jarboe\Table\Fields\Select, Yaro\Jarboe\Table\Fields\Tags. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
181
        }
182 58
        if (method_exists($this, 'setInlineUrl')) {
183 58
            $this->setInlineUrl($crud->inlineUrl());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Yaro\Jarboe\Table\Fields\AbstractField as the method setInlineUrl() does only exist in the following sub-classes of Yaro\Jarboe\Table\Fields\AbstractField: Yaro\Jarboe\Table\Fields\Checkbox, Yaro\Jarboe\Table\Fields\Date, Yaro\Jarboe\Table\Fields\Number, Yaro\Jarboe\Table\Fields\Text, Yaro\Jarboe\Table\Fields\Textarea. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
184
        }
185 58
        if ($this->isTranslatable()) {
186
            $this->locales($crud->getLocales());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Yaro\Jarboe\Table\Fields\AbstractField as the method locales() does only exist in the following sub-classes of Yaro\Jarboe\Table\Fields\AbstractField: Yaro\Jarboe\Table\Fields\Repeater, Yaro\Jarboe\Table\Fields\Text, Yaro\Jarboe\Table\Fields\Textarea, Yaro\Jarboe\Table\Fields\Wysiwyg. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
187
            $this->setCurrentLocale($crud->getCurrentLocale());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Yaro\Jarboe\Table\Fields\AbstractField as the method setCurrentLocale() does only exist in the following sub-classes of Yaro\Jarboe\Table\Fields\AbstractField: Yaro\Jarboe\Table\Fields\Repeater, Yaro\Jarboe\Table\Fields\Text, Yaro\Jarboe\Table\Fields\Textarea, Yaro\Jarboe\Table\Fields\Wysiwyg. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
188
        }
189 58
    }
190
191
    protected function crud(): CRUD
192
    {
193
        return $this->crud;
194
    }
195
}
196