|
6 | 6 | use App\Forms\ProcurementForm;
|
7 | 7 | use App\Forms\UserProfileForm;
|
8 | 8 | use App\Services\ModulesService;
|
| 9 | +use Exception; |
| 10 | +use Illuminate\Database\Eloquent\Model; |
9 | 11 | use Illuminate\Support\ServiceProvider;
|
10 | 12 | use Illuminate\Support\Str;
|
11 | 13 | use ReflectionClass;
|
| 14 | +use ReflectionParameter; |
12 | 15 | use TorMorten\Eventy\Facades\Events as Hook;
|
13 | 16 |
|
14 | 17 | class FormsProvider extends ServiceProvider
|
@@ -89,16 +92,86 @@ private function autoloadFields( $path, $classRoot )
|
89 | 92 | $field = str_replace( '.php', '', $field );
|
90 | 93 | $field = $classRoot . $field;
|
91 | 94 |
|
92 |
| - $reflection = new ReflectionClass( $field ); |
| 95 | + if ( class_exists( $field ) ) { |
| 96 | + /** |
| 97 | + * We'll initialize a reflection class |
| 98 | + * to perform a verification on the constructor. |
| 99 | + */ |
| 100 | + $reflection = new ReflectionClass( $field ); |
93 | 101 |
|
94 |
| - if ( class_exists( $field ) && $reflection->hasConstant( 'AUTOLOAD' ) && $field::AUTOLOAD && $reflection->hasConstant( 'IDENTIFIER' ) ) { |
95 |
| - Hook::addFilter( 'ns.fields', function ( $identifier ) use ( $field ) { |
96 |
| - if ( $identifier === $field::IDENTIFIER ) { |
97 |
| - return new $field; |
| 102 | + if ( $reflection->hasConstant( 'AUTOLOAD' ) && $field::AUTOLOAD && $reflection->hasConstant( 'IDENTIFIER' ) ) { |
| 103 | + |
| 104 | + $constructor = $reflection->getConstructor(); |
| 105 | + |
| 106 | + $params = collect(); |
| 107 | + |
| 108 | + if ( $constructor ) { |
| 109 | + $parameters = $constructor ? $constructor->getParameters() : []; |
| 110 | + |
| 111 | + $params = collect( $parameters )->map( function( ReflectionParameter $param ) { |
| 112 | + return [ |
| 113 | + 'name' => $param->getName(), |
| 114 | + 'type' => $param->getType() ? $param->getType()->getName() : null, |
| 115 | + 'isOptional' => $param->isOptional(), |
| 116 | + 'isBuiltin' => $param->getType()->isBuiltin(), |
| 117 | + 'default' => $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, |
| 118 | + ]; |
| 119 | + }); |
98 | 120 | }
|
99 | 121 |
|
100 |
| - return $identifier; |
101 |
| - } ); |
| 122 | + /** |
| 123 | + * While loading the relevant field class, we'll attempt to resolve it's dependencies |
| 124 | + * especially if those are subchild of the Illuminate\Database\Eloquent\Model::class |
| 125 | + */ |
| 126 | + Hook::addFilter( 'ns.fields', function ( $identifier, $resource = null ) use ( $field, $params ) { |
| 127 | + if ( $identifier === $field::IDENTIFIER ) { |
| 128 | + $resolved = collect( $params )->map( function( $param ) use ( $resource, $field ) { |
| 129 | + $isBuiltin = $param[ 'isBuiltin' ]; |
| 130 | + |
| 131 | + /** |
| 132 | + * We strickly want to integrate a D.I of models |
| 133 | + * other non-builtin will be resolved using app()->make(). |
| 134 | + */ |
| 135 | + if ( ! $isBuiltin ) { |
| 136 | + if ( is_subclass_of( $param[ 'type' ], Model::class ) ) { |
| 137 | + $model = $param[ 'type' ]; |
| 138 | + $instance = $model::find( $resource ); |
| 139 | + |
| 140 | + /** |
| 141 | + * if the param is not optional, we must have a valid instance. |
| 142 | + */ |
| 143 | + if ( ! $instance instanceof $model && ! $param[ 'isOptional' ] ) { |
| 144 | + throw new Exception( sprintf( |
| 145 | + __( 'Unable to resolve the dependency %s (%s) for the class %s' ), |
| 146 | + $resource, |
| 147 | + $model, |
| 148 | + $field |
| 149 | + ) ); |
| 150 | + } |
| 151 | + |
| 152 | + return $instance; |
| 153 | + } else { |
| 154 | + return app()->make( $param[ 'type' ] ); |
| 155 | + } |
| 156 | + } |
| 157 | + |
| 158 | + return false; |
| 159 | + })->filter(); |
| 160 | + |
| 161 | + /** |
| 162 | + * If no dependencies were resolved, we can create a new instance |
| 163 | + * of the field class. |
| 164 | + */ |
| 165 | + if ( $resolved->isEmpty() ) { |
| 166 | + return new $field; |
| 167 | + } |
| 168 | + |
| 169 | + return call_user_func_array( [ $field, '__construct' ], $resolved->toArray() ); |
| 170 | + } |
| 171 | + |
| 172 | + return $identifier; |
| 173 | + }); |
| 174 | + } |
102 | 175 | }
|
103 | 176 | }
|
104 | 177 | }
|
|
0 commit comments