Skip to content

Commit 4b08e2c

Browse files
author
Marcel Pociot
committed
Support belongsTo relationships
1 parent 156f4d9 commit 4b08e2c

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

src/Console/GenerateCommand.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Illuminate\Contracts\Filesystem\FileNotFoundException;
77
use Illuminate\Database\Eloquent\Relations\Relation;
88
use Illuminate\Filesystem\Filesystem;
9+
use Illuminate\Support\Str;
910
use Symfony\Component\Console\Input\InputOption;
1011
use Symfony\Component\Console\Input\InputArgument;
1112
use Symfony\Component\Console\Output\OutputInterface;
@@ -185,6 +186,8 @@ protected function generateFactories($loadModels, $ignore = '')
185186

186187
$this->getPropertiesFromTable($model);
187188

189+
$this->getPropertiesFromMethods($model);
190+
188191
$output .= $this->createFactory($name);
189192
$ignore[] = $name;
190193
} catch (\Exception $e) {
@@ -256,6 +259,49 @@ protected function getPropertiesFromTable($model)
256259
}
257260
}
258261

262+
263+
/**
264+
* @param \Illuminate\Database\Eloquent\Model $model
265+
*/
266+
protected function getPropertiesFromMethods($model)
267+
{
268+
$methods = get_class_methods($model);
269+
if ($methods) {
270+
foreach ($methods as $method) {
271+
if (!method_exists('Illuminate\Database\Eloquent\Model', $method) && !Str::startsWith($method, 'get')) {
272+
//Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
273+
$reflection = new \ReflectionMethod($model, $method);
274+
$file = new \SplFileObject($reflection->getFileName());
275+
$file->seek($reflection->getStartLine() - 1);
276+
$code = '';
277+
while ($file->key() < $reflection->getEndLine()) {
278+
$code .= $file->current();
279+
$file->next();
280+
}
281+
$code = trim(preg_replace('/\s\s+/', '', $code));
282+
$begin = strpos($code, 'function(');
283+
$code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
284+
foreach (array(
285+
'belongsTo',
286+
) as $relation) {
287+
$search = '$this->' . $relation . '(';
288+
if ($pos = stripos($code, $search)) {
289+
//Resolve the relation's model to a Relation object.
290+
$relationObj = $model->$method();
291+
if ($relationObj instanceof Relation) {
292+
$relatedModel = '\\' . get_class($relationObj->getRelated());
293+
$relatedObj = new $relatedModel;
294+
295+
$property = $relationObj->getForeignKey();
296+
$this->setProperty($property,'factory('.get_class($relationObj->getRelated()).'::class)->create()->'.$relatedObj->getKeyName());
297+
}
298+
}
299+
}
300+
}
301+
}
302+
}
303+
}
304+
259305
/**
260306
* @param string $name
261307
* @param string|null $type
@@ -271,6 +317,10 @@ protected function setProperty($name, $type = null)
271317
$this->properties[$name]['type'] = $type;
272318
}
273319

320+
if (Str::startsWith($type,'factory(')) {
321+
$this->properties[$name]['faker'] = true;
322+
}
323+
274324
$fakeableTypes = [
275325
'string' => '$faker->word',
276326
'text' => '$faker->text',

0 commit comments

Comments
 (0)