2015-08-17 17:00:26 -07:00
< ? php
namespace Drupal\migrate ;
use Drupal\Component\Utility\NestedArray ;
use Drupal\migrate\Plugin\MigrateIdMapInterface ;
/**
* Stores a row .
*/
class Row {
/**
* The actual values of the source row .
*
* @ var array
*/
2017-04-13 15:53:35 +01:00
protected $source = [];
2015-08-17 17:00:26 -07:00
/**
* The source identifiers .
*
* @ var array
*/
2017-04-13 15:53:35 +01:00
protected $sourceIds = [];
2015-08-17 17:00:26 -07:00
/**
* The destination values .
*
* @ var array
*/
2017-04-13 15:53:35 +01:00
protected $destination = [];
2015-08-17 17:00:26 -07:00
/**
* Level separator of destination and source properties .
*/
const PROPERTY_SEPARATOR = '/' ;
/**
* The mapping between source and destination identifiers .
*
* @ var array
*/
2017-04-13 15:53:35 +01:00
protected $idMap = [
2015-08-17 17:00:26 -07:00
'original_hash' => '' ,
'hash' => '' ,
'source_row_status' => MigrateIdMapInterface :: STATUS_NEEDS_UPDATE ,
2017-04-13 15:53:35 +01:00
];
2015-08-17 17:00:26 -07:00
/**
* Whether the source has been frozen already .
*
* Once frozen the source can not be changed any more .
*
* @ var bool
*/
protected $frozen = FALSE ;
/**
* The raw destination properties .
*
* Unlike $destination which is set by using
* \Drupal\Component\Utility\NestedArray :: setValue () this array contains
* the destination as setDestinationProperty was called .
*
* @ var array
* The raw destination .
*
* @ see getRawDestination ()
*/
2015-11-17 13:42:33 -08:00
protected $rawDestination = [];
2015-08-17 17:00:26 -07:00
/**
* TRUE when this row is a stub .
*
* @ var bool
*/
protected $isStub = FALSE ;
2018-11-23 12:29:20 +00:00
/**
* The empty destination properties .
*
* @ var array
*/
protected $emptyDestinationProperties = [];
2015-08-17 17:00:26 -07:00
/**
* Constructs a \Drupal\Migrate\Row object .
*
* @ param array $values
* An array of values to add as properties on the object .
* @ param array $source_ids
* An array containing the IDs of the source using the keys as the field
* names .
* @ param bool $is_stub
* TRUE if the row being created is a stub .
*
* @ throws \InvalidArgumentException
* Thrown when a source ID property does not exist .
*/
2016-11-02 11:43:31 -07:00
public function __construct ( array $values = [], array $source_ids = [], $is_stub = FALSE ) {
2015-08-17 17:00:26 -07:00
$this -> source = $values ;
$this -> sourceIds = $source_ids ;
$this -> isStub = $is_stub ;
foreach ( array_keys ( $source_ids ) as $id ) {
if ( ! $this -> hasSourceProperty ( $id )) {
2018-11-23 12:29:20 +00:00
throw new \InvalidArgumentException ( " $id is defined as a source ID but has no value. " );
2015-08-17 17:00:26 -07:00
}
}
}
/**
* Retrieves the values of the source identifiers .
*
* @ return array
2017-07-03 16:47:07 +01:00
* An array containing the values of the source identifiers . Returns values
* in the same order as defined in $this -> sourceIds .
2015-08-17 17:00:26 -07:00
*/
public function getSourceIdValues () {
2017-07-03 16:47:07 +01:00
return array_merge ( $this -> sourceIds , array_intersect_key ( $this -> source , $this -> sourceIds ));
2015-08-17 17:00:26 -07:00
}
/**
* Determines whether a source has a property .
*
* @ param string $property
* A property on the source .
*
* @ return bool
* TRUE if the source has property ; FALSE otherwise .
*/
public function hasSourceProperty ( $property ) {
return NestedArray :: keyExists ( $this -> source , explode ( static :: PROPERTY_SEPARATOR , $property ));
}
/**
* Retrieves a source property .
*
* @ param string $property
* A property on the source .
*
* @ return mixed | null
* The found returned property or NULL if not found .
*/
public function getSourceProperty ( $property ) {
$return = NestedArray :: getValue ( $this -> source , explode ( static :: PROPERTY_SEPARATOR , $property ), $key_exists );
if ( $key_exists ) {
return $return ;
}
}
/**
* Returns the whole source array .
*
* @ return array
* An array of source plugins .
*/
public function getSource () {
return $this -> source ;
}
/**
* Sets a source property .
*
* This can only be called from the source plugin .
*
* @ param string $property
* A property on the source .
* @ param mixed $data
* The property value to set on the source .
*
* @ throws \Exception
*/
public function setSourceProperty ( $property , $data ) {
if ( $this -> frozen ) {
throw new \Exception ( " The source is frozen and can't be changed any more " );
}
else {
NestedArray :: setValue ( $this -> source , explode ( static :: PROPERTY_SEPARATOR , $property ), $data , TRUE );
}
}
/**
* Freezes the source .
*
* @ return $this
*/
public function freezeSource () {
$this -> frozen = TRUE ;
return $this ;
}
2015-10-21 21:44:50 -07:00
/**
* Clones the row with an empty set of destination values .
*
* @ return static
*/
public function cloneWithoutDestination () {
return ( new static ( $this -> getSource (), $this -> sourceIds , $this -> isStub ())) -> freezeSource ();
}
2015-08-17 17:00:26 -07:00
/**
* Tests if destination property exists .
*
* @ param array | string $property
* An array of properties on the destination .
*
* @ return bool
* TRUE if the destination property exists .
*/
public function hasDestinationProperty ( $property ) {
return NestedArray :: keyExists ( $this -> destination , explode ( static :: PROPERTY_SEPARATOR , $property ));
}
/**
* Sets destination properties .
*
* @ param string $property
* The name of the destination property .
* @ param mixed $value
* The property value to set on the destination .
*/
public function setDestinationProperty ( $property , $value ) {
$this -> rawDestination [ $property ] = $value ;
NestedArray :: setValue ( $this -> destination , explode ( static :: PROPERTY_SEPARATOR , $property ), $value , TRUE );
}
2015-11-17 13:42:33 -08:00
/**
* Removes destination property .
*
* @ param string $property
* The name of the destination property .
*/
public function removeDestinationProperty ( $property ) {
unset ( $this -> rawDestination [ $property ]);
NestedArray :: unsetValue ( $this -> destination , explode ( static :: PROPERTY_SEPARATOR , $property ));
}
2018-11-23 12:29:20 +00:00
/**
* Sets a destination to be empty .
*
* @ param string $property
* The destination property .
*/
public function setEmptyDestinationProperty ( $property ) {
$this -> emptyDestinationProperties [] = $property ;
}
/**
* Gets the empty destination properties .
*
* @ return array
* An array of destination properties .
*/
public function getEmptyDestinationProperties () {
return $this -> emptyDestinationProperties ;
}
2015-08-17 17:00:26 -07:00
/**
* Returns the whole destination array .
*
* @ return array
* An array of destination values .
*/
public function getDestination () {
return $this -> destination ;
}
/**
* Returns the raw destination . Rarely necessary .
*
* For example calling setDestination ( 'foo/bar' , 'baz' ) results in
* @ code
* $this -> destination [ 'foo' ][ 'bar' ] = 'baz' ;
* $this -> rawDestination [ 'foo/bar' ] = 'baz' ;
* @ endcode
*
* @ return array
* The raw destination values .
*/
public function getRawDestination () {
return $this -> rawDestination ;
}
/**
* Returns the value of a destination property .
*
* @ param string $property
* The name of a property on the destination .
*
* @ return mixed
* The destination value .
*/
public function getDestinationProperty ( $property ) {
return NestedArray :: getValue ( $this -> destination , explode ( static :: PROPERTY_SEPARATOR , $property ));
}
/**
* Sets the Migrate ID mappings .
*
* @ param array $id_map
* An array of mappings between source ID and destination ID .
*/
public function setIdMap ( array $id_map ) {
$this -> idMap = $id_map ;
}
/**
* Retrieves the Migrate ID mappings .
*
* @ return array
* An array of mapping between source and destination identifiers .
*/
public function getIdMap () {
return $this -> idMap ;
}
/**
* Recalculates the hash for the row .
*/
public function rehash () {
$this -> idMap [ 'original_hash' ] = $this -> idMap [ 'hash' ];
$this -> idMap [ 'hash' ] = hash ( 'sha256' , serialize ( $this -> source ));
}
/**
* Checks whether the row has changed compared to the original ID map .
*
* @ return bool
* TRUE if the row has changed , FALSE otherwise . If setIdMap () was not
* called , this always returns FALSE .
*/
public function changed () {
return $this -> idMap [ 'original_hash' ] != $this -> idMap [ 'hash' ];
}
/**
* Returns if this row needs an update .
*
* @ return bool
* TRUE if the row needs updating , FALSE otherwise .
*/
public function needsUpdate () {
return $this -> idMap [ 'source_row_status' ] == MigrateIdMapInterface :: STATUS_NEEDS_UPDATE ;
}
/**
* Returns the hash for the source values ..
*
* @ return mixed
* The hash of the source values .
*/
public function getHash () {
return $this -> idMap [ 'hash' ];
}
/**
* Reports whether this row is a stub .
*
* @ return bool
* The current stub value .
*/
public function isStub () {
return $this -> isStub ;
}
2016-06-02 15:56:09 -07:00
2015-08-17 17:00:26 -07:00
}