Test Setup Failed
Push — master ( 6ed3f9...7ff8b7 )
by Alex
02:47
created

MetadataTrait::getConnection()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 1
ccs 0
cts 0
cp 0
nc 1
1
<?php
2
namespace AlgoWeb\PODataLaravel\Models;
3
4
use Illuminate\Database\Eloquent\Relations\BelongsTo;
5
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
6
use Illuminate\Database\Eloquent\Relations\MorphMany;
7
use Illuminate\Database\Eloquent\Relations\MorphOne;
8
use Illuminate\Database\Eloquent\Relations\MorphToMany;
9
use Illuminate\Support\Facades\App as App;
10
use Illuminate\Database\Eloquent\Relations\Relation;
11
use POData\Providers\Metadata\ResourceStreamInfo;
12
use POData\Providers\Metadata\Type\EdmPrimitiveType;
13
use Illuminate\Database\Eloquent\Model;
14
15
trait MetadataTrait
16
{
17
    protected static $methodPrimary = [];
18
    protected static $methodAlternate = [];
19
    protected $loadEagerRelations = [];
20
21
    /*
22
     * Array to record mapping between doctrine types and OData types
23
     */
24
    protected $mapping = [
25
        'integer' => EdmPrimitiveType::INT32,
26
        'string' => EdmPrimitiveType::STRING,
27
        'datetime' => EdmPrimitiveType::DATETIME,
28 3
        'float' => EdmPrimitiveType::SINGLE,
29
        'decimal' => EdmPrimitiveType::DECIMAL,
30 3
        'text' => EdmPrimitiveType::STRING,
31
        'boolean' => EdmPrimitiveType::BOOLEAN,
32
        'blob' => "stream"
33 2
    ];
34 2
35
    /*
36 2
     * Retrieve and assemble this model's metadata for OData packaging
37
     */
38 2
    public function metadata()
39 1
    {
40
        assert($this instanceof Model, get_class($this));
41
42 1
        // Break these out separately to enable separate reuse
43 1
        $connect = $this->getConnection();
44 1
        $builder = $connect->getSchemaBuilder();
45
46 1
        $table = $this->getTable();
47
48 1
        if (!$builder->hasTable($table)) {
49 1
            return [];
50 1
        }
51
52 1
        $columns = $builder->getColumnListing($table);
53 1
        $mask = $this->metadataMask();
54 1
        $columns = array_intersect($columns, $mask);
55
56 1
        $tableData = [];
57
58 1
        $rawFoo = $connect->getDoctrineSchemaManager()->listTableColumns($table);
59 1
        $foo = [];
60 1
        $getters = $this->collectGetters();
61 1
62 1
        foreach ($rawFoo as $key => $val) {
63 1
            // Work around glitch in Doctrine when reading from MariaDB which added ` characters to root key value
64 1
            $key = trim($key, '`');
65
            $foo[$key] = $val;
66 1
        }
67
68
        foreach ($columns as $column) {
69
            // Doctrine schema manager returns columns with lowercased names
70
            $rawColumn = $foo[strtolower($column)];
71
            $nullable = !($rawColumn->getNotNull());
72
            $fillable = in_array($column, $this->getFillable());
73 4
            $rawType = $rawColumn->getType();
74
            $type = $rawType->getName();
75 4
            $default = $this->$column;
76
            $tableData[$column] = ['type' => $type,
77 4
                'nullable' => $nullable,
78 4
                'fillable' => $fillable,
79 4
                'default' => $default
80 2
            ];
81 4
        }
82 1
83 1
        foreach ($getters as $get) {
84
            if (isset($tableData[$get])) {
85 4
                continue;
86
            }
87
            $default = $this->$get;
88
            $tableData[$get] = ['type' => 'text', 'nullable' => true, 'fillable' => false, 'default' => $default];
89
        }
90
91 5
        return $tableData;
92
    }
93 5
94 5
    /*
95 1
     * Return the set of fields that are permitted to be in metadata
96
     * - following same visible-trumps-hidden guideline as Laravel
97
     */
98 4
    public function metadataMask()
99
    {
100 4
        $attribs = array_keys($this->getAllAttributes());
101
102 4
        $visible = $this->getVisible();
103 4
        $hidden = $this->getHidden();
104 4
        if (0 < count($visible)) {
105 4
            assert(!empty($visible));
106 4
            $attribs = array_intersect($visible, $attribs);
107 4
        } elseif (0 < count($hidden)) {
108
            assert(!empty($hidden));
109 4
            $attribs = array_diff($attribs, $hidden);
110 1
        }
111 1
112 1
        return $attribs;
113 1
    }
114
115 4
    /*
116 4
     * Get the endpoint name being exposed
117
     *
118 4
     */
119
    public function getEndpointName()
120
    {
121
        $endpoint = isset($this->endpoint) ? $this->endpoint : null;
122
123
        if (!isset($endpoint)) {
124
            $bitter = get_class();
125
            $name = substr($bitter, strrpos($bitter, '\\')+1);
126
            return strtolower($name);
127
        }
128
        return strtolower($endpoint);
129
    }
130
131
    /*
132
     * Assemble this model's OData metadata as xml schema
133
     */
134
    public function getXmlSchema($MetaNamespace = "Data")
135
    {
136
        $raw = $this->metadata();
137
        if ([] == $raw) {
138
            return null;
139
        }
140
141
        $metadata = App::make('metadata');
142
143
        $rf = new \ReflectionClass(get_class($this));
144
        $complex = $metadata->addEntityType($rf, $rf->getShortName(), $MetaNamespace);
145
        $keyName = $this->getKeyName();
146
        if (null != $keyName) {
147
            $metadata->addKeyProperty($complex, $keyName, $this->mapping[$raw[$keyName]['type']]);
148
        }
149
150
        foreach ($raw as $key => $secret) {
151
            if ($key == $keyName) {
152
                continue;
153
            }
154
            if ($secret['type'] == "blob") {
155
                $complex->setMediaLinkEntry(true);
156
                $streamInfo = new ResourceStreamInfo($key);
157
                assert($complex->isMediaLinkEntry());
158
                $complex->addNamedStream($streamInfo);
159
                continue;
160
            }
161
            $nullable = $secret['nullable'];
162
            $default = $secret['default'];
163
            // tag as isBag?
164
            $metadata->addPrimitiveProperty(
165
                $complex,
166
                $key,
167
                $this->mapping[$secret['type']],
168
                false,
169
                $default,
170
                $nullable
171
            );
172
        }
173
174
        return $complex;
175 3
    }
176
177 3
    public function hookUpRelationships($entityTypes, $resourceSets)
178
    {
179 3
        assert(is_array($entityTypes) && is_array($resourceSets), "Both entityTypes and resourceSets must be arrays");
180 3
        $metadata = App::make('metadata');
181 3
        $rel = $this->getRelationshipsFromMethods();
182 3
        $thisClass = get_class($this);
183 3
        $thisInTypes = array_key_exists($thisClass, $entityTypes);
184 3
        $thisInSets = array_key_exists($thisClass, $resourceSets);
185 3
186 3
        if (!($thisInSets && $thisInTypes)) {
187 3
            return $rel;
188 3
        }
189
190 3
        $resourceType = $entityTypes[$thisClass];
191
        // if $r is in $combined keys, then its in keyspaces of both $entityTypes and $resourceSets
192 3
        $combinedKeys = array_intersect(array_keys($entityTypes), array_keys($resourceSets));
193 3 View Code Duplication
        foreach ($rel["HasOne"] as $n => $r) {
194 3
            $r = trim($r, '\\');
195 3
            if (in_array($r, $combinedKeys)) {
196 3
                $targResourceSet = $resourceSets[$r];
197 3
                $metadata->addResourceReferenceProperty($resourceType, $n, $targResourceSet);
198 3
            }
199 3
        }
200 3 View Code Duplication
        foreach ($rel["HasMany"] as $n => $r) {
201 3
            $r = trim($r, '\\');
202
            if (in_array($r, $combinedKeys)) {
203 3
                $targResourceSet = $resourceSets[$r];
204 3
                $metadata->addResourceSetReferenceProperty($resourceType, $n, $targResourceSet);
205 3
            }
206 3
        }
207 3
        return $rel;
208 3
    }
209 3
210 3
    public function getRelationships()
211
    {
212 3
        $hooks = [];
213 3
214 3
        $rels = $this->getRelationshipsFromMethods(true);
215
216 3
        $this->getRelationshipsUnknownPolyMorph($rels, $hooks);
217 3
218 3
        $this->getRelationshipsKnownPolyMorph($rels, $hooks);
219 3
220 3
        $this->getRelationshipsHasOne($rels, $hooks);
221
222 1
        $this->getRelationshipsHasMany($rels, $hooks);
223 3
224
        return $hooks;
225 1
    }
226
227 1
    protected function getAllAttributes()
228
    {
229 1
        // Adapted from http://stackoverflow.com/a/33514981
230
        // $columns = $this->getFillable();
231 3
        // Another option is to get all columns for the table like so:
232 2
        $builder = $this->getConnection()->getSchemaBuilder();
233 2
        $columns = $builder->getColumnListing($this->getTable());
234 3
        // but it's safer to just get the fillable fields
235 3
236 3
        $attributes = $this->getAttributes();
237 3
238 3
        foreach ($columns as $column) {
239 3
            if (!array_key_exists($column, $attributes)) {
240 3
                $attributes[$column] = null;
241
            }
242
        }
243
244
        $methods = $this->collectGetters();
245
246
        foreach ($methods as $method) {
247
            $attributes[$method] = null;
248
        }
249
250
        return $attributes;
251
    }
252
253
    protected function getRelationshipsFromMethods($biDir = false)
254
    {
255
        $model = $this;
256
        $relationships = array(
257
            "HasOne" => array(),
258
            "UnknownPolyMorphSide"=>array(),
259
            "HasMany"=>array(),
260
            "KnownPolyMorphSide"=>array()
261
        );
262
        $methods = get_class_methods($model);
263
        if (!empty($methods)) {
264
            foreach ($methods as $method) {
265
                if (!method_exists('Illuminate\Database\Eloquent\Model', $method)
266
                ) {
267
                    //Use reflection to inspect the code, based on Illuminate/Support/SerializableClosure.php
268
                    $reflection = new \ReflectionMethod($model, $method);
269
270
                    $file = new \SplFileObject($reflection->getFileName());
271
                    $file->seek($reflection->getStartLine()-1);
272
                    $code = '';
273
                    while ($file->key() < $reflection->getEndLine()) {
274
                        $code .= $file->current();
275
                        $file->next();
276
                    }
277
278
                    $code = trim(preg_replace('/\s\s+/', '', $code));
279
                    assert(false !== stripos($code, 'function'), 'Function definition must have keyword \'function\'');
280
                    $begin = strpos($code, 'function(');
281
                    $code = substr($code, $begin, strrpos($code, '}')-$begin+1);
282
                    $lastCode = $code[strlen($code)-1];
283
                    assert("}" == $lastCode, "Final character of function definition must be closing brace");
284
                    foreach (array(
285
                                'hasMany',
286
                                'hasManyThrough',
287
                                'belongsToMany',
288
                                'hasOne',
289
                                'belongsTo',
290
                                'morphOne',
291
                                'morphTo',
292
                                'morphMany',
293
                                'morphToMany',
294
                                'morphedByMany'
295
                                ) as $relation) {
296
                        $search = '$this->'.$relation.'(';
297
                        if ($pos = stripos($code, $search)) {
298
                            //Resolve the relation's model to a Relation object.
299
                            $relationObj = $model->$method();
300
                            if ($relationObj instanceof Relation) {
301
                                $relatedModel = '\\'.get_class($relationObj->getRelated());
302
                                $relations = [
303
                                    'hasManyThrough',
304
                                    'belongsToMany',
305
                                    'hasMany',
306
                                    'morphMany',
307
                                    'morphToMany',
308
                                    'morphedByMany'
309
                                ];
310
                                if (in_array($relation, $relations)) {
311
                                    //Collection or array of models (because Collection is Arrayable)
312
                                    $relationships["HasMany"][$method] = $biDir ? $relationObj : $relatedModel;
313
                                } elseif ($relation === "morphTo") {
314
                                    // Model isn't specified because relation is polymorphic
315
                                    $relationships["UnknownPolyMorphSide"][$method] =
316
                                        $biDir ? $relationObj : '\Illuminate\Database\Eloquent\Model|\Eloquent';
317
                                } else {
318
                                    //Single model is returned
319
                                    $relationships["HasOne"][$method] = $biDir ? $relationObj : $relatedModel;
320
                                }
321
                                if (in_array($relation, ["morphMany", "morphOne", "morphedByMany"])) {
322
                                    $relationships["KnownPolyMorphSide"][$method] =
323
                                        $biDir ? $relationObj : $relatedModel;
324
                                }
325
                                if (in_array($relation, ["morphToMany"])) {
326
                                    $relationships["UnknownPolyMorphSide"][$method] =
327
                                        $biDir ? $relationObj : $relatedModel;
328
                                }
329
                            }
330
                        }
331
                    }
332
                }
333
            }
334
        }
335
        return $relationships;
336
    }
337
338
    /**
339
     * Get the visible attributes for the model.
340
     *
341
     * @return array
342
     */
343
    abstract public function getVisible();
344
345
    /**
346
     * Get the hidden attributes for the model.
347
     *
348
     * @return array
349
     */
350
    abstract public function getHidden();
351
352
    /**
353
     * Get the primary key for the model.
354
     *
355
     * @return string
356
     */
357
    abstract public function getKeyName();
358
359
    /**
360
     * Get the current connection name for the model.
361
     *
362
     * @return string
363
     */
364
    abstract public function getConnectionName();
365
366
    /**
367
     * Get the database connection for the model.
368
     *
369
     * @return \Illuminate\Database\Connection
370
     */
371
    abstract public function getConnection();
372
373
    /**
374
     * Get all of the current attributes on the model.
375
     *
376
     * @return array
377
     */
378
    abstract public function getAttributes();
379
380
    /**
381
     * Get the table associated with the model.
382
     *
383
     * @return string
384
     */
385
    abstract public function getTable();
386
387
    /**
388
     * Get the fillable attributes for the model.
389
     *
390
     * @return array
391
     */
392
    abstract public function getFillable();
393
394
    /**
395
     * Dig up all defined getters on the model
396
     *
397
     * @return array
398
     */
399
    protected function collectGetters()
400
    {
401
        $getterz = [];
402
        $methods = get_class_methods($this);
403
        foreach ($methods as $method) {
404
            if (12 < strlen($method) && 'get' == substr($method, 0, 3)) {
405
                if ('Attribute' == substr($method, -9)) {
406
                    $getterz[] = $method;
407
                }
408
            }
409
        }
410
        $methods = [];
411
412
        foreach ($getterz as $getter) {
413
            $residual = substr($getter, 3);
414
            $residual = substr($residual, 0, -9);
415
            $methods[] = $residual;
416
        }
417
        return $methods;
418
    }
419
420
    /**
421
     * @param $foo
422
     * @return array
423
     */
424
    private function polyglotKeyMethodNames($foo, $condition = false)
425
    {
426
        $fkList = ['getQualifiedForeignKeyName', 'getForeignKey'];
427
        $rkList = ['getQualifiedRelatedKeyName', 'getOtherKey', 'getOwnerKey'];
428
429
        $fkMethodName = null;
430
        $rkMethodName = null;
431 View Code Duplication
        if ($condition) {
432
            if (array_key_exists(get_class($foo), static::$methodPrimary)) {
433
                $line = static::$methodPrimary[get_class($foo)];
434
                $fkMethodName = $line['fk'];
435
                $rkMethodName = $line['rk'];
436
            } else {
437
                $methodList = get_class_methods(get_class($foo));
438
                $fkMethodName = 'getQualifiedForeignPivotKeyName';
439
                foreach ($fkList as $option) {
440
                    if (in_array($option, $methodList)) {
441
                        $fkMethodName = $option;
442
                        break;
443
                    }
444
                }
445
                assert(in_array($fkMethodName, $methodList), "Selected method, ".$fkMethodName.", not in method list");
446
                $rkMethodName = 'getQualifiedRelatedPivotKeyName';
447
                foreach ($rkList as $option) {
448
                    if (in_array($option, $methodList)) {
449
                        $rkMethodName = $option;
450
                        break;
451
                    }
452
                }
453
                assert(in_array($rkMethodName, $methodList), "Selected method, ".$rkMethodName.", not in method list");
454
                $line = ['fk' => $fkMethodName, 'rk' => $rkMethodName];
455
                static::$methodPrimary[get_class($foo)] = $line;
456
            }
457
        }
458
        return array($fkMethodName, $rkMethodName);
459
    }
460
461
    private function polyglotKeyMethodBackupNames($foo, $condition = false)
462
    {
463
        $fkList = ['getForeignKey'];
464
        $rkList = ['getOtherKey'];
465
466
        $fkMethodName = null;
467
        $rkMethodName = null;
468 View Code Duplication
        if ($condition) {
469
            if (array_key_exists(get_class($foo), static::$methodAlternate)) {
470
                $line = static::$methodAlternate[get_class($foo)];
471
                $fkMethodName = $line['fk'];
472
                $rkMethodName = $line['rk'];
473
            } else {
474
                $methodList = get_class_methods(get_class($foo));
475
                $fkMethodName = 'getForeignKeyName';
476
                foreach ($fkList as $option) {
477
                    if (in_array($option, $methodList)) {
478
                        $fkMethodName = $option;
479
                        break;
480
                    }
481
                }
482
                assert(in_array($fkMethodName, $methodList), "Selected method, ".$fkMethodName.", not in method list");
483
                $rkMethodName = 'getQualifiedParentKeyName';
484
                foreach ($rkList as $option) {
485
                    if (in_array($option, $methodList)) {
486
                        $rkMethodName = $option;
487
                        break;
488
                    }
489
                }
490
                assert(in_array($rkMethodName, $methodList), "Selected method, ".$rkMethodName.", not in method list");
491
                $line = ['fk' => $fkMethodName, 'rk' => $rkMethodName];
492
                static::$methodAlternate[get_class($foo)] = $line;
493
            }
494
        }
495
        return array($fkMethodName, $rkMethodName);
496
    }
497
498
    /**
499
     * @param $hooks
500
     * @param $first
501
     * @param $property
502
     * @param $last
503
     * @param $mult
504
     * @param $targ
505
     */
506
    private function addRelationsHook(&$hooks, $first, $property, $last, $mult, $targ)
507
    {
508
        if (!isset($hooks[$first])) {
509
            $hooks[$first] = [];
510
        }
511
        $hooks[$first][$targ] = [
512
            'property' => $property,
513
            'local' => $last,
514
            'multiplicity' => $mult
515
        ];
516
    }
517
518
    /**
519
     * @param $rels
520
     * @param $hooks
521
     */
522
    private function getRelationshipsHasMany($rels, &$hooks)
523
    {
524
        foreach ($rels['HasMany'] as $property => $foo) {
525
            if ($foo instanceof MorphMany || $foo instanceof MorphToMany) {
526
                continue;
527
            }
528
            $isBelong = $foo instanceof BelongsToMany;
529
            $mult = '*';
530
            $targ = get_class($foo->getRelated());
531
532
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodNames($foo, $isBelong);
533
            list($fkMethodAlternate, $rkMethodAlternate) = $this->polyglotKeyMethodBackupNames($foo, !$isBelong);
534
535
            $keyRaw = $isBelong ? $foo->$fkMethodName() : $foo->$fkMethodAlternate();
536
            $keySegments = explode('.', $keyRaw);
537
            $keyName = $keySegments[count($keySegments) - 1];
538
            $localRaw = $isBelong ? $foo->$rkMethodName() : $foo->$rkMethodAlternate();
539
            $localSegments = explode('.', $localRaw);
540
            $localName = $localSegments[count($localSegments) - 1];
541
            $first = $keyName;
542
            $last = $localName;
543
            $this->addRelationsHook($hooks, $first, $property, $last, $mult, $targ);
544
        }
545
    }
546
547
    /**
548
     * @param $rels
549
     * @param $hooks
550
     */
551
    private function getRelationshipsHasOne($rels, &$hooks)
552
    {
553
        foreach ($rels['HasOne'] as $property => $foo) {
554
            if ($foo instanceof MorphOne) {
555
                continue;
556
            }
557
            $isBelong = $foo instanceof BelongsTo;
558
            $mult = $isBelong ? '1' : '0..1';
559
            $targ = get_class($foo->getRelated());
560
561
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodNames($foo, $isBelong);
562
            list($fkMethodAlternate, $rkMethodAlternate) = $this->polyglotKeyMethodBackupNames($foo, !$isBelong);
563
564
            $keyName = $isBelong ? $foo->$fkMethodName() : $foo->$fkMethodAlternate();
565
            $keySegments = explode('.', $keyName);
566
            $keyName = $keySegments[count($keySegments) - 1];
567
            $localRaw = $isBelong ? $foo->$rkMethodName() : $foo->$rkMethodAlternate();
568
            $localSegments = explode('.', $localRaw);
569
            $localName = $localSegments[count($localSegments) - 1];
570
            $first = $isBelong ? $localName : $keyName;
571
            $last = $isBelong ? $keyName : $localName;
572
            $this->addRelationsHook($hooks, $first, $property, $last, $mult, $targ);
573
        }
574
    }
575
576
    /**
577
     * @param $rels
578
     * @param $hooks
579
     */
580
    private function getRelationshipsKnownPolyMorph($rels, &$hooks)
581
    {
582
        foreach ($rels['KnownPolyMorphSide'] as $property => $foo) {
583
            $isMany = $foo instanceof MorphToMany;
584
            $targ = get_class($foo->getRelated());
585
            $mult = $isMany ? '*' : $foo instanceof MorphMany ? '*' : '1';
586
            $mult = $foo instanceof MorphOne ? '0..1' : $mult;
587
588
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodNames($foo, $isMany);
589
            list($fkMethodAlternate, $rkMethodAlternate) = $this->polyglotKeyMethodBackupNames($foo, !$isMany);
590
591
            $keyRaw = $isMany ? $foo->$fkMethodName() : $foo->$fkMethodAlternate();
592
            $keySegments = explode('.', $keyRaw);
593
            $keyName = $keySegments[count($keySegments) - 1];
594
            $localRaw = $isMany ? $foo->$rkMethodName() : $foo->$rkMethodAlternate();
595
            $localSegments = explode('.', $localRaw);
596
            $localName = $localSegments[count($localSegments) - 1];
597
            $first = $isMany ? $keyName : $localName;
598
            $last = $isMany ? $localName : $keyName;
599
            $this->addRelationsHook($hooks, $first, $property, $last, $mult, $targ);
600
        }
601
    }
602
603
    /**
604
     * @param $rels
605
     * @param $hooks
606
     */
607
    private function getRelationshipsUnknownPolyMorph($rels, &$hooks)
608
    {
609
        foreach ($rels['UnknownPolyMorphSide'] as $property => $foo) {
610
            $isMany = $foo instanceof MorphToMany;
611
            $targ = get_class($foo->getRelated());
612
            $mult = $isMany ? '*' : '1';
613
614
            list($fkMethodName, $rkMethodName) = $this->polyglotKeyMethodNames($foo, $isMany);
615
            list($fkMethodAlternate, $rkMethodAlternate) = $this->polyglotKeyMethodBackupNames($foo, !$isMany);
616
617
            $keyRaw = $isMany ? $foo->$fkMethodName() : $foo->$fkMethodAlternate();
618
            $keySegments = explode('.', $keyRaw);
619
            $keyName = $keySegments[count($keySegments) - 1];
620
            $localRaw = $isMany ? $foo->$rkMethodName() : $foo->$rkMethodAlternate();
621
            $localSegments = explode('.', $localRaw);
622
            $localName = $localSegments[count($localSegments) - 1];
623
624
            $first = $keyName;
625
            $last = (isset($localName) && "" != $localName) ? $localName : $foo->getRelated()->getKeyName();
626
            $this->addRelationsHook($hooks, $first, $property, $last, $mult, $targ);
627
        }
628
    }
629
630
    /**
631
     * SUpplemental function to retrieve cast array for Laravel versions that do not supply hasCasts
632
     *
633
     * @return array
634
     */
635
    public function retrieveCasts()
636
    {
637
        return $this->casts;
638
    }
639
640
    /**
641
     * Return list of relations to be eager-loaded by Laravel query provider
642
     *
643
     * @return array
644
     */
645
    public function getEagerLoad()
646
    {
647
        assert(is_array($this->loadEagerRelations));
648
        return $this->loadEagerRelations;
649
    }
650
651
    /**
652
     * Set list of relations to be eager-loaded
653
     *
654
     * @param array $relations
655
     */
656
    public function setEagerLoad(array $relations)
657
    {
658
        $check = array_map('strval', $relations);
659
        assert($relations == $check, "All supplied relations must be resolvable to strings");
660
        $this->loadEagerRelations = $relations;
661
    }
662
}
663