Completed
Push — dev ( 7ba6b5...ae910b )
by Zach
02:08
created

ModelFactoryBuilder::callClosureAttributes()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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