Factory.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. namespace Illuminate\Database\Eloquent;
  3. use ArrayAccess;
  4. use Faker\Generator as Faker;
  5. use Symfony\Component\Finder\Finder;
  6. class Factory implements ArrayAccess
  7. {
  8. /**
  9. * The model definitions in the container.
  10. *
  11. * @var array
  12. */
  13. protected $definitions = [];
  14. /**
  15. * The registered model states.
  16. *
  17. * @var array
  18. */
  19. protected $states = [];
  20. /**
  21. * The Faker instance for the builder.
  22. *
  23. * @var \Faker\Generator
  24. */
  25. protected $faker;
  26. /**
  27. * Create a new factory instance.
  28. *
  29. * @param \Faker\Generator $faker
  30. * @return void
  31. */
  32. public function __construct(Faker $faker)
  33. {
  34. $this->faker = $faker;
  35. }
  36. /**
  37. * Create a new factory container.
  38. *
  39. * @param \Faker\Generator $faker
  40. * @param string|null $pathToFactories
  41. * @return static
  42. */
  43. public static function construct(Faker $faker, $pathToFactories = null)
  44. {
  45. $pathToFactories = $pathToFactories ?: database_path('factories');
  46. return (new static($faker))->load($pathToFactories);
  47. }
  48. /**
  49. * Define a class with a given short-name.
  50. *
  51. * @param string $class
  52. * @param string $name
  53. * @param callable $attributes
  54. * @return $this
  55. */
  56. public function defineAs($class, $name, callable $attributes)
  57. {
  58. return $this->define($class, $attributes, $name);
  59. }
  60. /**
  61. * Define a class with a given set of attributes.
  62. *
  63. * @param string $class
  64. * @param callable $attributes
  65. * @param string $name
  66. * @return $this
  67. */
  68. public function define($class, callable $attributes, $name = 'default')
  69. {
  70. $this->definitions[$class][$name] = $attributes;
  71. return $this;
  72. }
  73. /**
  74. * Define a state with a given set of attributes.
  75. *
  76. * @param string $class
  77. * @param string $state
  78. * @param callable|array $attributes
  79. * @return $this
  80. */
  81. public function state($class, $state, $attributes)
  82. {
  83. $this->states[$class][$state] = $attributes;
  84. return $this;
  85. }
  86. /**
  87. * Create an instance of the given model and persist it to the database.
  88. *
  89. * @param string $class
  90. * @param array $attributes
  91. * @return mixed
  92. */
  93. public function create($class, array $attributes = [])
  94. {
  95. return $this->of($class)->create($attributes);
  96. }
  97. /**
  98. * Create an instance of the given model and type and persist it to the database.
  99. *
  100. * @param string $class
  101. * @param string $name
  102. * @param array $attributes
  103. * @return mixed
  104. */
  105. public function createAs($class, $name, array $attributes = [])
  106. {
  107. return $this->of($class, $name)->create($attributes);
  108. }
  109. /**
  110. * Create an instance of the given model.
  111. *
  112. * @param string $class
  113. * @param array $attributes
  114. * @return mixed
  115. */
  116. public function make($class, array $attributes = [])
  117. {
  118. return $this->of($class)->make($attributes);
  119. }
  120. /**
  121. * Create an instance of the given model and type.
  122. *
  123. * @param string $class
  124. * @param string $name
  125. * @param array $attributes
  126. * @return mixed
  127. */
  128. public function makeAs($class, $name, array $attributes = [])
  129. {
  130. return $this->of($class, $name)->make($attributes);
  131. }
  132. /**
  133. * Get the raw attribute array for a given named model.
  134. *
  135. * @param string $class
  136. * @param string $name
  137. * @param array $attributes
  138. * @return array
  139. */
  140. public function rawOf($class, $name, array $attributes = [])
  141. {
  142. return $this->raw($class, $attributes, $name);
  143. }
  144. /**
  145. * Get the raw attribute array for a given model.
  146. *
  147. * @param string $class
  148. * @param array $attributes
  149. * @param string $name
  150. * @return array
  151. */
  152. public function raw($class, array $attributes = [], $name = 'default')
  153. {
  154. return array_merge(
  155. call_user_func($this->definitions[$class][$name], $this->faker), $attributes
  156. );
  157. }
  158. /**
  159. * Create a builder for the given model.
  160. *
  161. * @param string $class
  162. * @param string $name
  163. * @return \Illuminate\Database\Eloquent\FactoryBuilder
  164. */
  165. public function of($class, $name = 'default')
  166. {
  167. return new FactoryBuilder($class, $name, $this->definitions, $this->states, $this->faker);
  168. }
  169. /**
  170. * Load factories from path.
  171. *
  172. * @param string $path
  173. * @return $this
  174. */
  175. public function load($path)
  176. {
  177. $factory = $this;
  178. if (is_dir($path)) {
  179. foreach (Finder::create()->files()->name('*.php')->in($path) as $file) {
  180. require $file->getRealPath();
  181. }
  182. }
  183. return $factory;
  184. }
  185. /**
  186. * Determine if the given offset exists.
  187. *
  188. * @param string $offset
  189. * @return bool
  190. */
  191. public function offsetExists($offset)
  192. {
  193. return isset($this->definitions[$offset]);
  194. }
  195. /**
  196. * Get the value of the given offset.
  197. *
  198. * @param string $offset
  199. * @return mixed
  200. */
  201. public function offsetGet($offset)
  202. {
  203. return $this->make($offset);
  204. }
  205. /**
  206. * Set the given offset to the given value.
  207. *
  208. * @param string $offset
  209. * @param callable $value
  210. * @return void
  211. */
  212. public function offsetSet($offset, $value)
  213. {
  214. return $this->define($offset, $value);
  215. }
  216. /**
  217. * Unset the value at the given offset.
  218. *
  219. * @param string $offset
  220. * @return void
  221. */
  222. public function offsetUnset($offset)
  223. {
  224. unset($this->definitions[$offset]);
  225. }
  226. }