public function __get($propertyName) { if (!$this->defaultsSet) { $this->setDefaultValues(); } // Should any type of magical getter below require that the value is cached for performance // this boolean will be set to true. At the end of the function we pick up on this and do the // caching - instead of having the caching line repeated all over the place. $addToPropertyCache = false; $value = parent::__get($propertyName); if ($value === null) { if (isset($this->propertyCache[$propertyName])) { return $this->propertyCache[$propertyName]; } // Handle the dot operator by passing control to the next object in the chain. if (strpos($propertyName, ".") !== false) { $parts = explode(".", $propertyName, 2); $firstStep = $this[$parts[0]]; if ($firstStep === null || !$firstStep instanceof Model) { // If the next item in the chain is not model object we can't ask it to return // a value can we! return null; } return $firstStep[$parts[1]]; } $this->ensureRelationshipsArePopulated(); if (isset(self::$relationships[$this->modelName][$propertyName])) { $relationship = self::$relationships[$this->modelName][$propertyName]; $value = $relationship->fetchFor($this); if ($value instanceof Model) { $addToPropertyCache = true; } } } if ($addToPropertyCache) { $this->propertyCache[$propertyName] = $value; } if (isset(self::$modelDataTransforms[$this->modelName][$propertyName][0])) { $closure = self::$modelDataTransforms[$this->modelName][$propertyName][0]; $value = $closure($value); } return $value; }