diff options
Diffstat (limited to 'engine/classes/ElggAttributeLoader.php')
| -rw-r--r-- | engine/classes/ElggAttributeLoader.php | 77 | 
1 files changed, 63 insertions, 14 deletions
| diff --git a/engine/classes/ElggAttributeLoader.php b/engine/classes/ElggAttributeLoader.php index 602bb8bae..ffc80b02d 100644 --- a/engine/classes/ElggAttributeLoader.php +++ b/engine/classes/ElggAttributeLoader.php @@ -4,6 +4,9 @@   * Loads ElggEntity attributes from DB or validates those passed in via constructor   *   * @access private + * + * @package    Elgg.Core + * @subpackage DataModel   */  class ElggAttributeLoader { @@ -21,7 +24,7 @@ class ElggAttributeLoader {  		'time_created',  		'time_updated',  		'last_action', -		'enabled' +		'enabled',  	);  	/** @@ -65,9 +68,11 @@ class ElggAttributeLoader {  	public $full_loader = '';  	/** -	 * @param string $class class of object being loaded -	 * @param string $required_type entity type this is being used to populate -	 * @param array $initialized_attrs attributes after initializeAttributes() has been run +	 * Constructor +	 * +	 * @param string $class             class of object being loaded +	 * @param string $required_type     entity type this is being used to populate +	 * @param array  $initialized_attrs attributes after initializeAttributes() has been run  	 * @throws InvalidArgumentException  	 */  	public function __construct($class, $required_type, array $initialized_attrs) { @@ -87,14 +92,33 @@ class ElggAttributeLoader {  		$this->secondary_attr_names = array_diff($all_attr_names, self::$primary_attr_names);  	} +	/** +	 * Get primary attributes missing that are missing +	 * +	 * @param stdClass $row Database row +	 * @return array +	 */  	protected function isMissingPrimaries($row) {  		return array_diff(self::$primary_attr_names, array_keys($row)) !== array();  	} +	/** +	 * Get secondary attributes that are missing +	 * +	 * @param stdClass $row Database row +	 * @return array +	 */  	protected function isMissingSecondaries($row) {  		return array_diff($this->secondary_attr_names, array_keys($row)) !== array();  	} +	/** +	 * Check that the type is correct +	 * +	 * @param stdClass $row Database row +	 * @return void +	 * @throws InvalidClassException +	 */  	protected function checkType($row) {  		if ($row['type'] !== $this->required_type) {  			$msg = elgg_echo('InvalidClassException:NotValidElggStar', array($row['guid'], $this->class)); @@ -148,11 +172,11 @@ class ElggAttributeLoader {  				if (!is_callable($this->primary_loader)) {  					throw new LogicException('Primary attribute loader must be callable');  				} -				if (!$this->requires_access_control) { +				if ($this->requires_access_control) { +					$fetched = (array) call_user_func($this->primary_loader, $row['guid']); +				} else {  					$ignoring_access = elgg_set_ignore_access(); -				} -				$fetched = (array) call_user_func($this->primary_loader, $row['guid']); -				if (!$this->requires_access_control) { +					$fetched = (array) call_user_func($this->primary_loader, $row['guid']);  					elgg_set_ignore_access($ignoring_access);  				}  				if (!$fetched) { @@ -176,6 +200,8 @@ class ElggAttributeLoader {  						// saved, these are stored w/ type "site", but with no sites_entity row. These  						// are probably only created in the unit tests.  						// @todo Don't save vanilla ElggEntities with type "site" + +						$row = $this->filterAddedColumns($row);  						$row['guid'] = (int) $row['guid'];  						return $row;  					} @@ -185,15 +211,38 @@ class ElggAttributeLoader {  			}  		} -		// loading complete: re-check missing and check type -		if (($was_missing_primaries && $this->isMissingPrimaries($row)) -				|| ($was_missing_secondaries && $this->isMissingSecondaries($row))) { -			throw new LogicException('Attribute loaders failed to return proper attributes'); -		} +		$row = $this->filterAddedColumns($row); + +		// Note: If there are still missing attributes, we're running on a 1.7 or earlier schema. We let +		// this pass so the upgrades can run. -		// guid needs to be an int  http://trac.elgg.org/ticket/4111 +		// guid needs to be an int  https://github.com/elgg/elgg/issues/4111  		$row['guid'] = (int) $row['guid'];  		return $row;  	} + +	/** +	 * Filter out keys returned by the query which should not appear in the entity's attributes +	 * +	 * @param array $row All columns from the query +	 * @return array Columns acceptable for the entity's attributes +	 */ +	protected function filterAddedColumns($row) { +		// make an array with keys as acceptable attribute names +		$acceptable_attrs = self::$primary_attr_names; +		array_splice($acceptable_attrs, count($acceptable_attrs), 0, $this->secondary_attr_names); +		$acceptable_attrs = array_combine($acceptable_attrs, $acceptable_attrs); + +		// @todo remove these when #4584 is in place +		$acceptable_attrs['tables_split'] = true; +		$acceptable_attrs['tables_loaded'] = true; + +		foreach ($row as $key => $val) { +			if (!isset($acceptable_attrs[$key])) { +				unset($row[$key]); +			} +		} +		return $row; +	}  } | 
