BaseFactory   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 20
eloc 51
dl 0
loc 201
ccs 50
cts 50
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A fakeMembers() 0 21 4
A toJson() 0 12 2
A getGenerator() 0 3 1
A fakeValue() 0 20 3
A fakeMemberName() 0 14 5
A addToObject() 0 9 2
A setGenerator() 0 5 1
A addToArray() 0 9 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace VGirol\JsonApiFaker\Factory;
6
7
use Faker\Generator;
8
use VGirol\JsonApiConstant\Members;
9
use VGirol\JsonApiFaker\Contract\FactoryContract;
10
use VGirol\JsonApiFaker\Contract\GeneratorContract;
11
use VGirol\JsonApiFaker\Exception\JsonApiFakerException;
12
use VGirol\JsonApiFaker\Messages;
13
14
/**
15
 * This class implements some methods of the FactoryContract interface.
16
 */
17
abstract class BaseFactory implements FactoryContract
18
{
19
    /**
20
     * The factory generator
21
     *
22
     * @var GeneratorContract
23
     */
24
    protected $generator;
25
26
    abstract public function toArray(): ?array;
27
28
    abstract public function fake();
29
30
    /**
31
     * Set the Generator instance
32
     *
33
     * @param GeneratorContract $generator
34
     *
35
     * @return static
36
     */
37 75
    public function setGenerator(GeneratorContract $generator)
38
    {
39 75
        $this->generator = $generator;
40
41 75
        return $this;
42
    }
43
44
    /**
45
     * Get the Generator instance
46
     *
47
     * @return GeneratorContract|null
48
     */
49 24
    public function getGenerator(): ?GeneratorContract
50
    {
51 24
        return $this->generator;
52
    }
53
54
    /**
55
     * Add a member to an internal object (such as the "attributes" object of a resource).
56
     *
57
     * @param string $object
58
     * @param string $name
59
     * @param mixed $value
60
     *
61
     * @return static
62
     */
63 57
    public function addToObject(string $object, string $name, $value)
64
    {
65 57
        if (!isset($this->{$object})) {
66 57
            $this->{$object} = [];
67
        }
68
69 57
        $this->{$object}[$name] = $value;
70
71 57
        return $this;
72
    }
73
74
    /**
75
     * Add an object to an internal array (such as the "errors" array).
76
     *
77
     * @param string $object
78
     * @param mixed $value
79
     *
80
     * @return static
81
     */
82 9
    public function addToArray(string $object, $value)
83
    {
84 9
        if (!isset($this->{$object})) {
85 6
            $this->{$object} = [];
86
        }
87
88 9
        $this->{$object}[] = $value;
89
90 9
        return $this;
91
    }
92
93
    /**
94
     * Exports the factory as a JSON string.
95
     *
96
     * @param integer $options Bitmask (@see https://www.php.net/manual/en/function.json-encode.php)
97
     *
98
     * @return string
99
     * @throws JsonApiFakerException
100
     */
101 6
    public function toJson($options = 0): string
102
    {
103 6
        $options = $options | JSON_PRESERVE_ZERO_FRACTION;
104 6
        $json = json_encode($this->toArray(), $options);
105
106 6
        if ($json === false) {
107 3
            throw new JsonApiFakerException(
108 3
                sprintf(Messages::JSON_ENCODE_ERROR, json_last_error_msg())
109
            );
110
        }
111
112 3
        return $json;
113
    }
114
115
    /**
116
     * This methods creates some members with fake names and values.
117
     *
118
     * The fake member is filled with the null value :
119
     * $options = [
120
     *      'member name' => null
121
     * ]
122
     *
123
     * The default array of methods is used to fill the fake value :
124
     * $options = [
125
     *      'member name' => []
126
     * ]
127
     *
128
     * Only the provided methods are used to fill the fake value :
129
     * $options = [
130
     *      'member name' => [ array of methods allowed to fake ]
131
     * ]
132
     *
133
     * If no key name is provided, a fake member name is generated :
134
     * $options = [
135
     *      null,
136
     *      [],
137
     *      [ array of methods allowed to fake ]
138
     * ]
139
     *
140
     * @param integer|array $options The number of keys to generate or an array of keys to use.
141
     *
142
     * @return array
143
     */
144 66
    protected function fakeMembers($options): array
145
    {
146 66
        $faker = \Faker\Factory::create();
147
148 66
        if (is_int($options)) {
149 63
            $count = $options;
150 63
            $options = [];
151 63
            for ($i = 0; $i < $count; $i++) {
152 63
                $options[] = [];
153
            }
154
        }
155
156 66
        $values = [];
157 66
        foreach ($options as $key => $providers) {
158 66
            $name = $this->fakeMemberName($faker, $key);
159 66
            $value = $this->fakeValue($faker, $providers);
160
161 66
            $values[$name] = $value;
162
        }
163
164 66
        return $values;
165
    }
166
167
    /**
168
     * Returns a fake member's name.
169
     *
170
     * @param Generator $faker
171
     * @param string|integer|null $name
172
     *
173
     * @return string
174
     */
175 69
    protected function fakeMemberName(Generator $faker, $name = null): string
176
    {
177 69
        if (($name === null) || \is_int($name)) {
178 66
            $forbidden = [Members::ID, Members::TYPE];
179
            do {
180 66
                $name = $faker->unique()->word();
181 66
            } while (in_array($name, $forbidden));
182
        }
183
184 69
        if (\strpos($name, '/') === false) {
185 69
            return $name;
186
        }
187
188 3
        return $faker->unique()->regexify($name);
189
    }
190
191
    /**
192
     * Returns a fake member's value.
193
     *
194
     * @param Generator $faker
195
     * @param array|null $providers
196
     * @return mixed
197
     */
198 69
    protected function fakeValue(Generator $faker, $providers = [])
199
    {
200
        $allowed = [
201 69
            'word',
202
            'sentence',
203
            'boolean',
204
            'randomNumber',
205
            'randomFloat',
206
            'date'
207
        ];
208
209 69
        if ($providers === null) {
210 3
            return null;
211
        }
212
213 69
        $method = $faker->randomElement(
214 69
            empty($providers) ? $allowed : $providers
215
        );
216
217 69
        return $faker->{$method};
218
    }
219
}
220