| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace Backpack\Base\app\Models\Traits; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use Illuminate\Support\Str; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use ReflectionClass; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  * This trait helps a child model (ex: BackpackUser) inherit all relationships of its parent model (ex: User). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  * Laravel by default doesn't do that, so packages like Backpack\PermissionManager can't see relationships | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  * on the BackpackUser model, because they haven't been inherited from User. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  * The code below has been copy-pasted from https://github.com/tightenco/parental on Feb 27th 2019. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  * When they provide support for Laravel 5.8, this entire trait could go away (or load their trait). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | trait InheritsRelationsFromParentModel | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     public $hasParent = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     public static function bootHasParent() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |         static::creating(function ($model) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |             if ($model->parentHasHasChildrenTrait()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |                 $model->forceFill( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |                     [$model->getInheritanceColumn() => $model->classToAlias(get_class($model))] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |         }); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |         static::addGlobalScope(function ($query) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |             $instance = new static(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |             if ($instance->parentHasHasChildrenTrait()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |                 $query->where($instance->getInheritanceColumn(), $instance->classToAlias(get_class($instance))); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                            
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         }); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |     public function parentHasHasChildrenTrait() | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |         return $this->hasChildren ?? false; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |     public function getTable() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |         if (!isset($this->table)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |             return str_replace('\\', '', Str::snake(Str::plural(class_basename($this->getParentClass())))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |         return $this->table; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     public function getForeignKey() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |         return Str::snake(class_basename($this->getParentClass())).'_'.$this->primaryKey; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     public function joiningTable($related, $instance = null) | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |         $relatedClassName = method_exists((new $related()), 'getClassNameForRelationships') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |             ? (new $related())->getClassNameForRelationships() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |             : class_basename($related); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         $models = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |             Str::snake($relatedClassName), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |             Str::snake($this->getClassNameForRelationships()), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |         sort($models); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |         return strtolower(implode('_', $models)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |     public function getClassNameForRelationships() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         return class_basename($this->getParentClass()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |     public function getMorphClass() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         if ($this->parentHasHasChildrenTrait()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |             $parentClass = $this->getParentClass(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |             return (new $parentClass())->getMorphClass(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |         return parent::getMorphClass(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |     protected function getParentClass() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |         static $parentClassName; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |         return $parentClassName ?: $parentClassName = (new ReflectionClass($this))->getParentClass()->getName(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 92 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 93 |  |  |  | 
            
                        
This check looks for methods that are used by a trait but not required by it.
To illustrate, let’s look at the following code example
The trait
Idableprovides a methodequalsIdthat in turn relies on the methodgetId(). If this method does not exist on a class mixing in this trait, the method will fail.Adding the
getId()as an abstract method to the trait will make sure it is available.