• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

phpolar / model / 5449748827

pending completion
5449748827

Pull #12

github

web-flow
Merge 068a00ea6 into 190d9e203
Pull Request #12: refactor: use renamed core library

263 of 287 relevant lines covered (91.64%)

7.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.45
/src/FieldErrorMessageTrait.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Phpolar\Model;
6

7
use Phpolar\Validator\MessageGetterInterface;
8
use ReflectionAttribute;
9
use ReflectionObject;
10
use ReflectionProperty;
11
use Stringable;
12

13
/**
14
 * Provides support for displaying form field error messages.
15
 */
16
trait FieldErrorMessageTrait
17
{
18
    /**
19
     * Stores error messages.
20
     *
21
     * @var array<string,string>
22
     */
23
    private array $errorMessages;
24

25
    /**
26
     * Make sure the properties are
27
     * checked only once.
28
     *
29
     * Do not initialize this.
30
     * Otherwise, this property
31
     * will appear when iterating
32
     * the objects that use this
33
     * trait.
34
     */
35
    protected bool $checked;
36

37
    /**
38
     * Validation is usually only desired
39
     * when the user attempts to
40
     * create or edit a model.
41
     */
42
    protected bool $shouldValidate = false;
43

44
    /**
45
     * Provides an interface for
46
     * retrieving a fields error message.
47
     */
48
    public function getFieldErrorMessage(string $fieldName, string $stringToAppend = ""): string
49
    {
50
        $this->setErrorMsgsOnce();
6✔
51
        return $this->hasError($fieldName) === true ? ($this->errorMessages[$fieldName] . $stringToAppend) : "";
6✔
52
    }
53

54
    /**
55
     * Determines if a property is not valid.
56
     */
57
    public function hasError(string $fieldName): bool
58
    {
59
        if ($this->shouldValidate === false) {
12✔
60
            return false;
4✔
61
        }
62
        $this->setErrorMsgsOnce();
8✔
63
        return isset($this->errorMessages[$fieldName]);
8✔
64
    }
65

66
    /**
67
     * Changes the posted state of the model.
68
     */
69
    public function isPosted(): void
70
    {
71
        $this->shouldValidate = true;
8✔
72
    }
73

74
    /**
75
     * Selects one of the provided validation
76
     * strings based on the state of the model
77
     *
78
     * @param string $invalidAttr The HTML attribute that denotes invalid state
79
     * @param string $validAttr The HTML attribute that denotes valid state
80
     *
81
     * @return string The selected HTML attribute that corresponds with the state of the model
82
     */
83
    public function selectValAttr(string $propName, string $invalidAttr, string $validAttr): string
84
    {
85
        return $this->shouldValidate === false ? "" : ($this->hasError($propName) === true ? $invalidAttr : $validAttr);
2✔
86
    }
87

88

89
    private function setErrorMsgsOnce(): void
90
    {
91
        if (
92
            (new ReflectionProperty($this, "checked"))->isInitialized($this) === true &&
10✔
93
            $this->checked === true
10✔
94
        ) {
95
            return;
4✔
96
        }
97
        $this->checked = true;
10✔
98
        $props = (new ReflectionObject($this))->getProperties(ReflectionProperty::IS_PUBLIC);
10✔
99
        array_walk(
10✔
100
            $props,
10✔
101
            function (ReflectionProperty $prop): void {
10✔
102
                $errorMessages = self::getErrorsFromAttributes(
10✔
103
                    $this->getMessageGetters($prop),
10✔
104
                );
10✔
105
                array_walk(
10✔
106
                    $errorMessages,
10✔
107
                    function (string | Stringable $err) use ($prop): void {
10✔
108
                        $this->errorMessages[$prop->getName()] = (string) $err;
6✔
109
                    }
10✔
110
                );
10✔
111
            }
10✔
112
        );
10✔
113
    }
114

115
    /**
116
     * Provides a way of retrieving only the validator attributes of a property.
117
     *
118
     * Returns only validation attributes.
119
     *
120
     * @return MessageGetterInterface[]
121
     */
122
    private function getMessageGetters(ReflectionProperty $prop): array
123
    {
124
        return array_map(
10✔
125
            function (ReflectionAttribute $attr) use ($prop): MessageGetterInterface {
10✔
126
                $instance = $attr->newInstance();
10✔
127
                if (method_exists($instance, "withRequiredPropVal") === true) {
10✔
128
                    return $instance->withRequiredPropVal($prop, $this);
×
129
                }
130
                if (property_exists($instance, "propVal") === true) {
10✔
131
                    $instance->propVal = $prop->isInitialized($this) === true ? $prop->getValue($this) : $prop->getDefaultValue();
×
132
                }
133
                return $instance;
10✔
134
            },
10✔
135
            $prop->getAttributes(MessageGetterInterface::class, ReflectionAttribute::IS_INSTANCEOF),
10✔
136
        );
10✔
137
    }
138

139
    /**
140
     * Provides a way of retrieving errors from the invalid validation attributes of a property.
141
     *
142
     * Returns errors from invalid validators.
143
     *
144
     * @param MessageGetterInterface[] $attrs
145
     * @return (string|Stringable)[]
146
     */
147
    private static function getErrorsFromAttributes(array $attrs): array
148
    {
149
        return array_merge(
10✔
150
            ...array_map(
10✔
151
                static fn (MessageGetterInterface $attr) => $attr->getMessages(),
10✔
152
                $attrs
10✔
153
            )
10✔
154
        );
10✔
155
    }
156
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc