ModelFactoryBuilder   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 160
rs 10
c 0
b 0
f 0
wmc 13
lcom 1
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A make() 0 14 4
A create() 0 18 3
A times() 0 6 1
A makeInstance() 0 17 2
A callClosureAttributes() 0 10 2
1
<?php
2
3
namespace Yarak\DB\Factories;
4
5
use Faker\Generator;
6
use Phalcon\Mvc\Model;
7
use Yarak\Exceptions\FactoryNotFound;
8
9
class ModelFactoryBuilder
10
{
11
    /**
12
     * Name of class.
13
     *
14
     * @var string
15
     */
16
    protected $class;
17
18
    /**
19
     * Definition name.
20
     *
21
     * @var string
22
     */
23
    protected $name;
24
25
    /**
26
     * Array of all definitions.
27
     *
28
     * @var array
29
     */
30
    protected $definitions;
31
32
    /**
33
     * Faker instance.
34
     *
35
     * @var Generator
36
     */
37
    protected $faker;
38
39
    /**
40
     * Number of times to run factory.
41
     *
42
     * @var int|null
43
     */
44
    protected $times;
45
46
    /**
47
     * Construct.
48
     *
49
     * @param string    $class
50
     * @param string    $name
51
     * @param array     $definitions
52
     * @param Generator $faker
53
     */
54
    public function __construct($class, $name, array $definitions, Generator $faker)
55
    {
56
        $this->class = $class;
57
        $this->name = $name;
58
        $this->definitions = $definitions;
59
        $this->faker = $faker;
60
    }
61
62
    /**
63
     * Make an instance of class.
64
     *
65
     * @param array $attributes
66
     *
67
     * @return Phalcon\Mvc\Model|array
68
     */
69
    public function make(array $attributes = [])
70
    {
71
        if ($this->times === null || $this->times < 1) {
72
            return $this->makeInstance($attributes);
73
        }
74
75
        $instances = [];
76
77
        foreach (range(1, $this->times) as $time) {
78
            $instances[] = $this->makeInstance($attributes);
79
        }
80
81
        return $instances;
82
    }
83
84
    /**
85
     * Create an instance of class and persist in database.
86
     *
87
     * @param array $attributes
88
     *
89
     * @return Phalcon\Mvc\Model|array
90
     */
91
    public function create(array $attributes = [])
92
    {
93
        $made = $this->make($attributes);
94
95
        if ($made instanceof Model) {
96
            $made->save();
97
        }
98
99
        if (is_array($made)) {
100
            return array_map(function (Model $model) {
101
                $model->save();
102
103
                return $model;
104
            }, $made);
105
        }
106
107
        return $made;
108
    }
109
110
    /**
111
     * Set the number of times to run the make/create the class.
112
     *
113
     * @param int|null $times
114
     *
115
     * @return $this
116
     */
117
    public function times($times = null)
118
    {
119
        $this->times = $times;
120
121
        return $this;
122
    }
123
124
    /**
125
     * Make an instance of the class with the given attributes.
126
     *
127
     * @param array $attributes
128
     *
129
     * @throws FactoryNotFound
130
     *
131
     * @return Phalcon\Mvc\Model
132
     */
133
    protected function makeInstance(array $attributes = [])
134
    {
135
        if (!isset($this->definitions[$this->class][$this->name])) {
136
            throw FactoryNotFound::factoryDefinitionNotFound(
137
                "Definition for class {$this->class} with name {$this->name} does not exist."
138
            );
139
        }
140
141
        $fakerAttributes = call_user_func(
142
            $this->definitions[$this->class][$this->name],
143
            $this->faker
144
        );
145
146
        $finalAttributes = array_merge($fakerAttributes, $attributes);
147
148
        return new $this->class($this->callClosureAttributes($finalAttributes));
149
    }
150
151
    /**
152
     * Call any closures in attributes.
153
     *
154
     * @param array $attributes
155
     *
156
     * @return array
157
     */
158
    protected function callClosureAttributes(array $attributes)
159
    {
160
        return array_map(function ($attribute) use ($attributes) {
161
            if ($attribute instanceof \Closure) {
162
                return $attribute($attributes);
163
            }
164
165
            return $attribute;
166
        }, $attributes);
167
    }
168
}
169