44
55use Illuminate \Http \Resources \MergeValue ;
66use Illuminate \Support \Collection ;
7+ use Laravel \Nova \Contracts \RelatableField ;
8+ use Laravel \Nova \Fields \Field ;
79use Laravel \Nova \Fields \FieldCollection ;
810use Laravel \Nova \Http \Controllers \ActionController ;
9- use Laravel \Nova \Http \Controllers \AssociatableController ;
1011use Laravel \Nova \Http \Controllers \CreationFieldController ;
1112use Laravel \Nova \Http \Controllers \FieldController ;
1213use Laravel \Nova \Http \Controllers \MorphableController ;
1314use Laravel \Nova \Http \Controllers \ResourceAttachController ;
15+ use Laravel \Nova \Http \Controllers \ResourceIndexController ;
1416use Laravel \Nova \Http \Controllers \ResourceStoreController ;
1517use Laravel \Nova \Http \Controllers \ResourceUpdateController ;
1618use Laravel \Nova \Http \Controllers \UpdateFieldController ;
@@ -23,7 +25,7 @@ trait HasConditionalContainer
2325 /**
2426 * Get the panels that are available for the given detail request.
2527 *
26- * @param \Laravel\Nova\Http\Requests\ NovaRequest $request
28+ * @param NovaRequest $request
2729 * @return array
2830 */
2931 public function availablePanelsForDetail ($ request )
@@ -37,7 +39,7 @@ public function availablePanelsForDetail($request)
3739 /**
3840 * Get the panels that are available for the given create request.
3941 *
40- * @param \Laravel\Nova\Http\Requests\ NovaRequest $request
42+ * @param NovaRequest $request
4143 * @return array
4244 */
4345 public function availablePanelsForCreate ($ request )
@@ -51,7 +53,7 @@ public function availablePanelsForCreate($request)
5153 /**
5254 * Get the panels that are available for the given update request.
5355 *
54- * @param \Laravel\Nova\Http\Requests\ NovaRequest $request
56+ * @param NovaRequest $request
5557 * @return array
5658 */
5759 public function availablePanelsForUpdate ($ request )
@@ -78,18 +80,30 @@ public function availableFields(NovaRequest $request)
7880
7981 $ controller = $ request ->route ()->controller ;
8082
83+ /**
84+ * Exclude all instance of conditional container from index views
85+ */
86+ if ($ controller instanceof ResourceIndexController) {
87+
88+ return parent ::availableFields ($ request )->filter (function ($ field ) {
89+
90+ return !($ field instanceof ConditionalContainer);
91+
92+ });
93+
94+ }
95+
8196 if ($ controller instanceof CreationFieldController ||
8297 $ controller instanceof UpdateFieldController) {
8398
8499 $ fields = parent ::availableFields ($ request );
85100 $ containers = $ this ->findAllContainers ($ fields );
101+ $ expressionsMap = $ containers ->flatMap ->expressions ;
86102
87103 $ cleanUpMethodName = $ controller instanceof UpdateFieldController ?
88104 'removeNonUpdateFields ' :
89105 'removeNonCreationFields ' ;
90106
91- $ expressionsMap = $ containers ->flatMap ->expressions ;
92-
93107 /**
94108 * @var ConditionalContainer $container
95109 */
@@ -107,7 +121,7 @@ public function availableFields(NovaRequest $request)
107121
108122 }
109123
110- return $ fields ;
124+ return $ this -> preloadRelationships ( $ expressionsMap , $ fields) ;
111125
112126 }
113127
@@ -120,12 +134,56 @@ public function availableFields(NovaRequest $request)
120134
121135 }
122136
123- $ fields = $ this ->flattenDependencies ($ request , $ this ->fields ($ request ));
137+ $ allFields = $ this ->fields ($ request );
138+ $ containers = $ this ->findAllContainers ($ allFields );
139+ $ expressionsMap = $ containers ->flatMap ->expressions ;
140+
141+ $ fields = $ this ->flattenDependencies (
142+ $ request , $ this ->preloadRelationships ($ expressionsMap , $ allFields )
143+ );
124144
125145 return new FieldCollection (array_values ($ this ->filter ($ fields ->toArray ())));
126146
127147 }
128148
149+ private function preloadRelationships (Collection $ expressionsMap , $ fields )
150+ {
151+
152+ $ relations = collect ();
153+
154+ foreach ($ fields as $ field ) {
155+
156+ if ($ field instanceof RelatableField ||
157+ $ field instanceof \NovaAttachMany \AttachMany ||
158+ $ field instanceof \Benjacho \BelongsToManyField \BelongsToManyField) {
159+
160+ $ relations ->push ($ field ->attribute );
161+
162+ }
163+
164+ }
165+
166+ $ expressionsMap = $ expressionsMap ->map (function (string $ expression ) {
167+ return ConditionalContainer::splitLiteral ($ expression )[ 0 ];
168+ });
169+
170+ /**
171+ * Only load the relations that are necessary
172+ */
173+ $ relations = $ relations ->filter (function ($ relation ) use ($ expressionsMap ) {
174+ return $ expressionsMap ->contains ($ relation );
175+ });
176+
177+ if ($ relations ->isNotEmpty ()) {
178+
179+ $ this ->loadMissing ($ relations );
180+
181+ }
182+
183+ return $ fields ;
184+
185+ }
186+
129187 private function flattenDependencies (NovaRequest $ request , array $ fields )
130188 {
131189
@@ -139,7 +197,11 @@ private function flattenDependencies(NovaRequest $request, array $fields)
139197
140198 }
141199
142- return $ fields ->flatMap (function ($ field ) use ($ fields , $ request , $ controller ) {
200+ $ fakeRequest = $ request ->duplicate ();
201+
202+ return $ fields ->flatMap (function ($ field ) use ($ fields , $ fakeRequest , $ controller ) {
203+
204+ $ this ->parseThirdPartyPackageFieldValue ($ field , $ fakeRequest );
143205
144206 if ($ field instanceof ConditionalContainer) {
145207
@@ -157,24 +219,26 @@ private function flattenDependencies(NovaRequest $request, array $fields)
157219 $ controller instanceof ResourceAttachController ||
158220 $ controller instanceof FieldController) {
159221
160- return $ this ->flattenDependencies ($ request , $ field ->fields ->toArray ());
222+ return $ this ->flattenDependencies ($ fakeRequest , $ field ->fields ->toArray ());
161223
162224 }
163225
164226 if ($ controller instanceof ResourceUpdateController ||
165227 $ controller instanceof ResourceStoreController) {
166228
167- return $ this ->flattenDependencies ($ request , $ field ->resolveDependencyFieldUsingRequest ($ this , $ request ));
229+ return $ this ->flattenDependencies (
230+ $ fakeRequest , $ field ->resolveDependencyFieldUsingRequest ($ this , $ fakeRequest )
231+ );
168232
169233 }
170234
171- return $ this ->flattenDependencies ($ request , $ field ->resolveDependencyFieldUsingResource ($ this ));
235+ return $ this ->flattenDependencies ($ fakeRequest , $ field ->resolveDependencyFieldUsingResource ($ this ));
172236
173237 }
174238
175239 if ($ field instanceof MergeValue) {
176240
177- return $ this ->flattenDependencies ($ request , $ field ->data );
241+ return $ this ->flattenDependencies ($ fakeRequest , $ field ->data );
178242
179243 }
180244
@@ -184,6 +248,35 @@ private function flattenDependencies(NovaRequest $request, array $fields)
184248
185249 }
186250
251+ /**
252+ * Intended to minimize the incompatibility with third part package
253+ *
254+ * @param Field $field
255+ * @param NovaRequest $request
256+ */
257+ private function parseThirdPartyPackageFieldValue (Field $ field , NovaRequest $ request )
258+ {
259+
260+ $ value = $ request ->get ($ field ->attribute );
261+
262+ if ($ field instanceof \Benjacho \BelongsToManyField \BelongsToManyField) {
263+
264+ $ request ->offsetSet (
265+ $ field ->attribute , collect (json_decode ($ value , true ))->map ->id
266+ );
267+
268+ }
269+
270+ if ($ field instanceof \NovaAttachMany \AttachMany) {
271+
272+ $ request ->offsetSet (
273+ $ field ->attribute , collect (json_decode ($ value , true ))
274+ );
275+
276+ }
277+
278+ }
279+
187280 private function findAllActiveContainers (Collection $ fields , $ resource ): Collection
188281 {
189282 return $ this ->findAllContainers ($ fields )
@@ -193,9 +286,9 @@ private function findAllActiveContainers(Collection $fields, $resource): Collect
193286 ->values ();
194287 }
195288
196- private function findAllContainers (Collection $ fields ): Collection
289+ private function findAllContainers ($ fields ): Collection
197290 {
198- return $ fields ->flatMap (function ($ field ) {
291+ return collect ( $ fields) ->flatMap (function ($ field ) {
199292
200293 if ($ field instanceof ConditionalContainer) {
201294
@@ -205,7 +298,7 @@ private function findAllContainers(Collection $fields): Collection
205298
206299 if ($ field instanceof MergeValue) {
207300
208- return $ this ->findAllContainers (collect ( $ field ->data ) );
301+ return $ this ->findAllContainers ($ field ->data );
209302
210303 }
211304
0 commit comments