From ff3844e4e189e5abd99ac9dcb9e0978e0e373e26 Mon Sep 17 00:00:00 2001 From: Antoine Aflalo Date: Sat, 8 Apr 2017 04:19:23 -0400 Subject: [PATCH] Implements Nullable (#487) * Add nullable support Fixes #407 * Add nullable to setProperty Better do it like this to still be able to override the base type if wanted * Cleanup nullableColumns between models iterations Also rename it to nullableColumns since it contains multiple columns * Fix formatting --- src/Console/ModelsCommand.php | 61 ++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index 019e5c6..d8e3996 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -56,6 +56,10 @@ class ModelsCommand extends Command protected $write = false; protected $dirs = array(); protected $reset; + /** + * @var bool[string] + */ + protected $nullableColumns = []; /** * @param Filesystem $files @@ -202,8 +206,9 @@ class ModelsCommand extends Command } $this->getPropertiesFromMethods($model); - $output .= $this->createPhpDocs($name); - $ignore[] = $name; + $output .= $this->createPhpDocs($name); + $ignore[] = $name; + $this->nullableColumns = []; } catch (\Exception $e) { $this->error("Exception: " . $e->getMessage() . "\nCould not analyze class $name."); } @@ -361,7 +366,10 @@ class ModelsCommand extends Command } $comment = $column->getComment(); - $this->setProperty($name, $type, true, true, $comment); + if (!$column->getNotnull()) { + $this->nullableColumns[$name] = true; + } + $this->setProperty($name, $type, true, true, $comment, !$column->getNotnull()); if ($this->write_model_magic_where) { $this->setMethod( Str::camel("where_" . $name), @@ -470,7 +478,14 @@ class ModelsCommand extends Command ); } else { //Single model is returned - $this->setProperty($method, $relatedModel, true, null); + $this->setProperty( + $method, + $relatedModel, + true, + null, + '', + $this->isRelationForeignKeyNullable($relationObj) + ); } } } @@ -481,13 +496,33 @@ class ModelsCommand extends Command } /** - * @param string $name - * @param string|null $type - * @param bool|null $read - * @param bool|null $write - * @param string|null $comment + * Check if the foreign key of the relation is nullable + * + * @param Relation $relation + * + * @return bool */ - protected function setProperty($name, $type = null, $read = null, $write = null, $comment = '') + private function isRelationForeignKeyNullable(Relation $relation) + { + $reflectionObj = new \ReflectionObject($relation); + if (!$reflectionObj->hasProperty('foreignKey')) { + return false; + } + $fkProp = $reflectionObj->getProperty('foreignKey'); + $fkProp->setAccessible(true); + + return isset($this->nullableColumns[$fkProp->getValue($relation)]); + } + + /** + * @param string $name + * @param string|null $type + * @param bool|null $read + * @param bool|null $write + * @param string|null $comment + * @param bool $nullable + */ + protected function setProperty($name, $type = null, $read = null, $write = null, $comment = '', $nullable = false) { if (!isset($this->properties[$name])) { $this->properties[$name] = array(); @@ -497,7 +532,11 @@ class ModelsCommand extends Command $this->properties[$name]['comment'] = (string) $comment; } if ($type !== null) { - $this->properties[$name]['type'] = $this->getTypeOverride($type); + $newType = $this->getTypeOverride($type); + if ($nullable) { + $newType .='|null'; + } + $this->properties[$name]['type'] = $newType; } if ($read !== null) { $this->properties[$name]['read'] = $read;