1 <?php
2
3 namespace Docotory\Traits;
4
5 use InvalidArgumentException;
6
7 /**
8 * A helper trait to make your implementation has a factory.
9 *
10 * @author Krisan Alfa Timur <krisanalfa@docotel.co.id>
11 */
12 trait HasFactories
13 {
14 /**
15 * A key / value pair array of your registered factories
16 *
17 * @var array
18 */
19 protected $factories = [];
20
21 /**
22 * A key / value pair array of your resolved factories
23 *
24 * @var array
25 */
26 protected $resolvedFactories = [];
27
28 /**
29 * Resolve a factory. Keep in mind that factory would be resolved via container method.
30 * So make sure if the accessor is an alias, register it on a container by calling:
31 *
32 * ```php
33 * container()->alias('FooClass', 'foo');
34 * ```
35 *
36 * @param string $factory Name of your registered factory
37 *
38 * @return mixed
39 */
40 public function factory($factory)
41 {
42 if ($this->hasFactory($factory)) {
43 if (! $this->factoryHasBeenResolved($factory)) {
44 $this->resolvedFactories[$factory] = container($this->factories[$factory]);
45 }
46
47 return $this->resolvedFactories[$factory];
48 }
49 }
50
51 /**
52 * Determine if a factory has been resolved
53 *
54 * @param string $factory Factory name
55 *
56 * @return bool
57 */
58 protected function factoryHasBeenResolved($factory)
59 {
60 return isset($this->resolvedFactories[$factory]);
61 }
62
63 /**
64 * Determine if your factory has been registered or not.
65 *
66 * @param string $factory Name of your factory
67 *
68 * @return boolean
69 */
70 public function hasFactory($factory)
71 {
72 return isset($this->factories[$factory]);
73 }
74
75 /**
76 * Register your factory
77 *
78 * @param string $factory
79 * @param string $containerAccessor
80 * @param boolean $replace
81 *
82 * @return void
83 */
84 public function registerFactory($factory, $containerAccessor, $replace = false)
85 {
86 if (! $factory or ! $containerAccessor) {
87 throw new InvalidArgumentException("Cannot register factory.");
88 }
89
90 // Don't replace
91 if (! $replace) {
92 // Don't replace if exist
93 if ($this->hasFactory($factory)) {
94 return;
95 }
96 }
97 // If replace, unset the resolved one
98 else {
99 if ($this->factoryHasBeenResolved($factory)) {
100 unset($this->resolvedFactories[$factory]);
101 }
102 }
103
104 $this->factories[$factory] = $containerAccessor;
105 }
106
107 /**
108 * Register your factory from key / value pair array
109 *
110 * @param array $factories
111 * @param boolean $replace
112 *
113 * @return void
114 */
115 public function registerFactories(array $factories, $replace = false)
116 {
117 foreach ($factories as $factory => $containerAccessor) {
118 $this->registerFactory($factory, $containerAccessor, $replace);
119 }
120 }
121
122 /**
123 * Return all registered factories.
124 *
125 * @return array
126 */
127 public function factories()
128 {
129 return $this->factories;
130 }
131 }
132