public static function from_query( array $attributes = array() ) {

		$instance = new static( new \stdClass() );
		$instance->set_raw_attributes( $attributes, true );
		$instance->_exists = true;

		if ( static::$_cache && ! static::is_data_cached( $instance->get_pk() ) ) {
			Cache::update( $instance );
		}

		return $instance;
	}

public static function from_query ( array $ attributes = array ( ) ) { $ instance = new static ( new \ stdClass ( ) ) ; $ instance -> set_raw_attributes ( $ attributes , true ) ; $ instance -> _exists = true ; if ( static :: $ _cache && ! static :: is_data_cached ( $ instance -> get_pk ( ) ) ) { Cache :: update ( $ instance ) ; } return $ instance ; }

Create a new object from a query builder.

This is used to bypass guarding when retrieve model data from the database.

@since 2.0

@param array $attributes

@return static

Create a new object from a query builder .


protected static function get_data_from_pk( $pk ) {

		$data = static::$_cache ? Cache::get( $pk, static::get_cache_group() ) : null;

		if ( ! $data ) {
			$query = new FluentQuery( static::table() );
			$data  = $query->where( static::table()->get_primary_key(), '=', $pk )->first();
		}

		return $data ? (object) $data : null;
	}

protected static function get_data_from_pk ( $ pk ) { $ data = static :: $ _cache ? Cache :: get ( $ pk , static :: get_cache_group ( ) ) : null ; if ( ! $ data ) { $ query = new FluentQuery ( static :: table ( ) ) ; $ data = $ query -> where ( static :: table ( ) -> get_primary_key ( ) , '=' , $ pk ) -> first ( ) ; } return $ data ? ( object ) $ data : null ; }

Get data for a primary key.

@since 1.0

@param int|string $pk Primary key for this record.

@return \stdClass|null


protected static function is_data_cached( $pk ) {

		if ( ! static::$_cache ) {
			return false;
		}

		$data = Cache::get( $pk, static::get_cache_group() );

		return ! empty( $data );
	}

protected static function is_data_cached ( $ pk ) { if ( ! static :: $ _cache ) { return false ; } $ data = Cache :: get ( $ pk , static :: get_cache_group ( ) ) ; return ! empty ( $ data ) ; }

Check if data is cached.

@since 1.0

@param int|string $pk Primary key for this record.

@return bool


protected function update( $key, $value ) {

		$columns = static::table()->get_columns();

		$data = array(
			$key => $columns[ $key ]->prepare_for_storage( $value )
		);

		$res = static::make_query_object()->update( $this->get_pk(), $data );

		if ( $res && static::$_cache ) {
			Cache::update( $this );
		}

		return $res;
	}

protected function update ( $ key , $ value ) { $ columns = static :: table ( ) -> get_columns ( ) ; $ data = array ( $ key => $ columns [ $ key ] -> prepare_for_storage ( $ value ) ) ; $ res = static :: make_query_object ( ) -> update ( $ this -> get_pk ( ) , $ data ) ; if ( $ res && static :: $ _cache ) { Cache :: update ( $ this ) ; } return $ res ; }

Update a certain value.

@deprecated 2.0 This bypasses the attributes layer and as such is deprecated in 2.0.

@since      1.0

@param string $key   DB column to update.
@param mixed  $value New value.

@return bool


public function save( array $options = array() ) {

		if ( isset( $options['exclude_relations'] ) && ! is_array( $options['exclude_relations'] ) ) {
			$options['exclude_relations'] = (array) $options['exclude_relations'];
		}

		$columns = static::table()->get_columns();

		$options = wp_parse_args( $options, array(
			'exclude_relations' => array_filter( $this->get_all_relations(), function ( $attribute ) use ( $columns ) {
				return array_key_exists( $attribute, $columns );
			} )
		) );

		$this->fire_model_event( 'saving' );

		$this->save_has_foreign_relations();

		if ( $this->exists() ) {
			$saved = $this->do_save_as_update();
		} else {
			$saved = $this->do_save_as_insert();
		}

		$this->save_loaded_relations( $options['exclude_relations'] );

		if ( $saved ) {
			$this->finish_save();
		}

		return $saved;
	}

public function save ( array $ options = array ( ) ) { if ( isset ( $ options [ 'exclude_relations' ] ) && ! is_array ( $ options [ 'exclude_relations' ] ) ) { $ options [ 'exclude_relations' ] = ( array ) $ options [ 'exclude_relations' ] ; } $ columns = static :: table ( ) -> get_columns ( ) ; $ options = wp_parse_args ( $ options , array ( 'exclude_relations' => array_filter ( $ this -> get_all_relations ( ) , function ( $ attribute ) use ( $ columns ) { return array_key_exists ( $ attribute , $ columns ) ; } ) ) ) ; $ this -> fire_model_event ( 'saving' ) ; $ this -> save_has_foreign_relations ( ) ; if ( $ this -> exists ( ) ) { $ saved = $ this -> do_save_as_update ( ) ; } else { $ saved = $ this -> do_save_as_insert ( ) ; } $ this -> save_loaded_relations ( $ options [ 'exclude_relations' ] ) ; if ( $ saved ) { $ this -> finish_save ( ) ; } return $ saved ; }

Persist this model's changes to the database.

This will save all savable attributes like WP_Post objects or Models,
and persist any loaded relations.

The `saving` and `saved` events will be fired. If this model does not yet exist, the `creating` and `created`
events will fire as well. Otherwise, the `updating` and `updated` events will fire.

@since 2.0

@param array $options Configure how the saving should be performed.
Accepts 'exclude_relations' to allow for given relations to be excluded from persistence.

@return bool

@throws Exception

Persist this model s changes to the database .


protected function save_has_foreign_relations() {

		foreach ( $this->_relations as $attribute => $value ) {
			$relation = $this->get_relation( $attribute );

			if ( $relation instanceof HasForeign && $value ) {

				$value = $relation->persist( $value );
				$pk    = $relation->get_pk_for_value( $value );

				$this->set_raw_attribute( $attribute, $pk );
				$this->_relations[ $attribute ] = $value;
			}
		}
	}

protected function save_has_foreign_relations ( ) { foreach ( $ this -> _relations as $ attribute => $ value ) { $ relation = $ this -> get_relation ( $ attribute ) ; if ( $ relation instanceof HasForeign && $ value ) { $ value = $ relation -> persist ( $ value ) ; $ pk = $ relation -> get_pk_for_value ( $ value ) ; $ this -> set_raw_attribute ( $ attribute , $ pk ) ; $ this -> _relations [ $ attribute ] = $ value ; } } }

Save the has foreign relations.

These need to be saved early because otherwise they will be persisted to both
the attribute value cache, and the relation cache.

@since 2.0


protected function save_loaded_relations( array $exclude = array() ) {
		foreach ( $this->_relations as $relation => $values ) {

			if ( in_array( $relation, $exclude ) ) {
				continue;
			}

			$relation_controller = $this->get_relation( $relation );
			$relation_controller->persist( $values );
		}
	}

protected function save_loaded_relations ( array $ exclude = array ( ) ) { foreach ( $ this -> _relations as $ relation => $ values ) { if ( in_array ( $ relation , $ exclude ) ) { continue ; } $ relation_controller = $ this -> get_relation ( $ relation ) ; $ relation_controller -> persist ( $ values ) ; } }

Save loaded relations.

@since 2.0

@param array $exclude Relations to exclude from being saved.


protected function do_save_as_insert() {

		if ( static::table() instanceof TimestampedTable ) {
			$time = $this->fresh_timestamp();

			$this->set_attribute( static::table()->get_created_at_column(), $time );
			$this->set_attribute( static::table()->get_updated_at_column(), $time );
		}

		$this->fire_model_event( 'creating' );

		$columns = static::table()->get_columns();
		$insert  = array();

		foreach ( $this->get_raw_attributes() as $attribute => $value ) {
			$insert[ $attribute ] = $columns[ $attribute ]->prepare_for_storage( $value );
		}

		$insert_id = static::make_query_object()->insert( $insert );

		if ( $insert_id ) {
			$this->set_raw_attribute( static::table()->get_primary_key(), $insert_id );
		}

		$default_columns_to_fill = array();

		foreach ( static::table()->get_columns() as $name => $column ) {

			if ( ! array_key_exists( $name, $this->get_raw_attributes() ) ) {
				$default_columns_to_fill[] = $name;
			}
		}

		if ( $default_columns_to_fill ) {

			$query          = new FluentQuery( static::table() );
			$default_values = $query->where( static::table()->get_primary_key(), '=', $this->get_pk() )
			                        ->select( $default_columns_to_fill )->first();

			if ( $default_values ) {
				foreach ( $default_values as $column => $value ) {
					$this->set_raw_attribute( $column, $value );
				}
			}
		}

		$this->_exists = true;

		if ( static::$_cache ) {
			Cache::update( $this );
		}

		$this->fire_model_event( 'created' );

		return true;
	}

protected function do_save_as_insert ( ) { if ( static :: table ( ) instanceof TimestampedTable ) { $ time = $ this -> fresh_timestamp ( ) ; $ this -> set_attribute ( static :: table ( ) -> get_created_at_column ( ) , $ time ) ; $ this -> set_attribute ( static :: table ( ) -> get_updated_at_column ( ) , $ time ) ; } $ this -> fire_model_event ( 'creating' ) ; $ columns = static :: table ( ) -> get_columns ( ) ; $ insert = array ( ) ; foreach ( $ this -> get_raw_attributes ( ) as $ attribute => $ value ) { $ insert [ $ attribute ] = $ columns [ $ attribute ] -> prepare_for_storage ( $ value ) ; } $ insert_id = static :: make_query_object ( ) -> insert ( $ insert ) ; if ( $ insert_id ) { $ this -> set_raw_attribute ( static :: table ( ) -> get_primary_key ( ) , $ insert_id ) ; } $ default_columns_to_fill = array ( ) ; foreach ( static :: table ( ) -> get_columns ( ) as $ name => $ column ) { if ( ! array_key_exists ( $ name , $ this -> get_raw_attributes ( ) ) ) { $ default_columns_to_fill [ ] = $ name ; } } if ( $ default_columns_to_fill ) { $ query = new FluentQuery ( static :: table ( ) ) ; $ default_values = $ query -> where ( static :: table ( ) -> get_primary_key ( ) , '=' , $ this -> get_pk ( ) ) -> select ( $ default_columns_to_fill ) -> first ( ) ; if ( $ default_values ) { foreach ( $ default_values as $ column => $ value ) { $ this -> set_raw_attribute ( $ column , $ value ) ; } } } $ this -> _exists = true ; if ( static :: $ _cache ) { Cache :: update ( $ this ) ; } $ this -> fire_model_event ( 'created' ) ; return true ; }

Save model as an insert query.

@since 2.0

@return bool

@throws Exception


protected function do_save_as_update() {

		$dirty = $this->get_dirty();

		if ( ! $dirty ) {
			return true;
		}

		if ( static::table() instanceof TimestampedTable ) {
			$this->set_attribute( static::table()->get_updated_at_column(), $this->fresh_timestamp() );
			$dirty = $this->get_dirty();
		}

		$columns = static::table()->get_columns();

		$previous = array();
		$update   = array();

		foreach ( $dirty as $column => $value ) {

			if ( array_key_exists( $column, $this->_original ) ) {
				$previous[ $column ] = $this->_original[ $column ];
			}

			$update[ $column ] = $columns[ $column ]->prepare_for_storage( $value );
		}

		$this->fire_model_event( 'updating', array(
			'changed' => $dirty,
			'from'    => $previous
		) );

		$result = static::make_query_object()->update( $this->get_pk(), $update );

		if ( $result ) {

			if ( static::$_cache ) {
				Cache::update( $this );
			}

			$this->fire_model_event( 'updated', array(
				'changed' => $dirty,
				'from'    => $previous
			) );
		}

		return $result;
	}

protected function do_save_as_update ( ) { $ dirty = $ this -> get_dirty ( ) ; if ( ! $ dirty ) { return true ; } if ( static :: table ( ) instanceof TimestampedTable ) { $ this -> set_attribute ( static :: table ( ) -> get_updated_at_column ( ) , $ this -> fresh_timestamp ( ) ) ; $ dirty = $ this -> get_dirty ( ) ; } $ columns = static :: table ( ) -> get_columns ( ) ; $ previous = array ( ) ; $ update = array ( ) ; foreach ( $ dirty as $ column => $ value ) { if ( array_key_exists ( $ column , $ this -> _original ) ) { $ previous [ $ column ] = $ this -> _original [ $ column ] ; } $ update [ $ column ] = $ columns [ $ column ] -> prepare_for_storage ( $ value ) ; } $ this -> fire_model_event ( 'updating' , array ( 'changed' => $ dirty , 'from' => $ previous ) ) ; $ result = static :: make_query_object ( ) -> update ( $ this -> get_pk ( ) , $ update ) ; if ( $ result ) { if ( static :: $ _cache ) { Cache :: update ( $ this ) ; } $ this -> fire_model_event ( 'updated' , array ( 'changed' => $ dirty , 'from' => $ previous ) ) ; } return $ result ; }

Save this model as an update query.

@since 2.0

@return bool

@throws Exception


protected function finish_save() {

		$this->fire_model_event( 'saved' );

		foreach ( $this->_relations as $attribute => $relation ) {
			if ( $relation instanceof Collection ) {
				$relation->clear_memory();
			}
		}

		$this->sync_original();
	}

protected function finish_save ( ) { $ this -> fire_model_event ( 'saved' ) ; foreach ( $ this -> _relations as $ attribute => $ relation ) { if ( $ relation instanceof Collection ) { $ relation -> clear_memory ( ) ; } } $ this -> sync_original ( ) ; }

Perform cleanup after a save has occurred.

@since 2.0

Perform cleanup after a save has occurred .


public function delete() {

		$this->fire_model_event( 'deleting' );

		foreach ( $this->get_all_relations() as $relation ) {
			$this->get_relation( $relation )->on_delete( $this );
		}

		static::make_query_object()->delete( $this->get_pk() );

		if ( static::$_cache ) {
			Cache::delete( $this );
		}

		$this->_exists = false;

		$this->fire_model_event( 'deleted' );
	}

public function delete ( ) { $ this -> fire_model_event ( 'deleting' ) ; foreach ( $ this -> get_all_relations ( ) as $ relation ) { $ this -> get_relation ( $ relation ) -> on_delete ( $ this ) ; } static :: make_query_object ( ) -> delete ( $ this -> get_pk ( ) ) ; if ( static :: $ _cache ) { Cache :: delete ( $ this ) ; } $ this -> _exists = false ; $ this -> fire_model_event ( 'deleted' ) ; }

Delete this object from the database.

Will fire `deleting` and `deleted` events.

@since 1.0

@throws Exception


public static function create_many( array $to_insert ) {

		$models = array();
		$data   = array();

		foreach ( $to_insert as $model ) {
			$model = $model instanceof static ? $model : new static ( $model );
			$model->fire_model_event( 'saving' );
			$model->fire_model_event( 'creating' );

			$models[] = $model;
			$data[]   = $model->get_raw_attributes();
		}

		$rows = static::make_query_object()->insert_many( $data );

		foreach ( $rows as $i => $row ) {
			$model = $models[ $i ];

			$model->set_raw_attributes( $row );
			$model->fire_model_event( 'created' );
			$model->fire_model_event( 'saved' );
			$model->sync_original();
		}

		return $models;
	}

public static function create_many ( array $ to_insert ) { $ models = array ( ) ; $ data = array ( ) ; foreach ( $ to_insert as $ model ) { $ model = $ model instanceof static ? $ model : new static ( $ model ) ; $ model -> fire_model_event ( 'saving' ) ; $ model -> fire_model_event ( 'creating' ) ; $ models [ ] = $ model ; $ data [ ] = $ model -> get_raw_attributes ( ) ; } $ rows = static :: make_query_object ( ) -> insert_many ( $ data ) ; foreach ( $ rows as $ i => $ row ) { $ model = $ models [ $ i ] ; $ model -> set_raw_attributes ( $ row ) ; $ model -> fire_model_event ( 'created' ) ; $ model -> fire_model_event ( 'saved' ) ; $ model -> sync_original ( ) ; } return $ models ; }

Create multiple models at once.

@since 2.0.0

@param array[]|static[] $to_insert Records to be inserted.

@return static[]

@throws \IronBound\DB\Exception


protected function fire_model_event( $event, $arguments = array() ) {

		if ( ! static::$_event_dispatcher ) {
			return;
		}

		$event = static::table()->get_slug() . ".$event";

		static::$_event_dispatcher->dispatch( $event, new GenericEvent( $this, $arguments ) );
	}

protected function fire_model_event ( $ event , $ arguments = array ( ) ) { if ( ! static :: $ _event_dispatcher ) { return ; } $ event = static :: table ( ) -> get_slug ( ) . ".$event" ; static :: $ _event_dispatcher -> dispatch ( $ event , new GenericEvent ( $ this , $ arguments ) ) ; }

Fire a model event.

Will bail early if no event dispatcher is available.

@since 2.0

@param string $event     Event name.
@param array  $arguments Additional arguments passed to the GenericEvent object.


public static function register_model_event( $event, $callback, $priority = 10, $accepted_args = 3 ) {

		if ( isset( static::$_event_dispatcher ) ) {
			$event = static::table()->get_slug() . ".$event";

			static::$_event_dispatcher->add_listener( $event, $callback, $priority, $accepted_args );
		}
	}

public static function register_model_event ( $ event , $ callback , $ priority = 10 , $ accepted_args = 3 ) { if ( isset ( static :: $ _event_dispatcher ) ) { $ event = static :: table ( ) -> get_slug ( ) . ".$event" ; static :: $ _event_dispatcher -> add_listener ( $ event , $ callback , $ priority , $ accepted_args ) ; } }

Register a model event listener.

@since 2.0

@param string   $event
@param callable $callback
@param int      $priority
@param int      $accepted_args


public function get_data_to_cache() {

		$data = $this->get_raw_attributes();

		$columns = static::table()->get_columns();

		foreach ( $data as $column => $value ) {
			if ( isset( $columns[ $column ] ) ) {
				$data[ $column ] = $columns[ $column ]->prepare_for_storage( $value );
			}
		}

		return $data;
	}

public function get_data_to_cache ( ) { $ data = $ this -> get_raw_attributes ( ) ; $ columns = static :: table ( ) -> get_columns ( ) ; foreach ( $ data as $ column => $ value ) { if ( isset ( $ columns [ $ column ] ) ) { $ data [ $ column ] = $ columns [ $ column ] -> prepare_for_storage ( $ value ) ; } } return $ data ; }

Get the data we'd like to cache.

This is a bit magical. It iterates through all of the table columns,
and checks if a getter for that method exists. If so, it pulls in that
value. Otherwise, it will pull in the default value. If you'd like to
customize this you should override this function in your child model
class.

@since 1.0

@return array


public static function register_global_scope( $scope_or_identifier, Closure $closure = null ) {

		if ( $scope_or_identifier instanceof Scope ) {
			self::$_scopes[ get_called_class() ][ get_class( $scope_or_identifier ) ] = $scope_or_identifier;
		} elseif ( is_string( $scope_or_identifier ) && $closure ) {
			self::$_scopes[ get_called_class() ][ $scope_or_identifier ] = $closure;
		} else {
			throw new \InvalidArgumentException();
		}
	}

public static function register_global_scope ( $ scope_or_identifier , Closure $ closure = null ) { if ( $ scope_or_identifier instanceof Scope ) { self :: $ _scopes [ get_called_class ( ) ] [ get_class ( $ scope_or_identifier ) ] = $ scope_or_identifier ; } elseif ( is_string ( $ scope_or_identifier ) && $ closure ) { self :: $ _scopes [ get_called_class ( ) ] [ $ scope_or_identifier ] = $ closure ; } else { throw new \ InvalidArgumentException ( ) ; } }

Register a global query scope.

Global query scopes are automatically applied whenever the query() method is called.

@since 2.0

@param Scope|string $scope_or_identifier Either a Scope object or an identifier for an accompanying closure.
@param Closure|null $closure             When not using a Scope object, an implementation for the scope.

@throws \InvalidArgumentException


public static function without_global_scopes( array $scopes ) {

		$query = static::query_with_no_global_scopes();

		foreach ( static::get_global_scopes() as $id => $scope ) {

			if ( in_array( $id, $scopes ) ) {
				continue;
			}

			if ( $scope instanceof Scope ) {
				$scope->apply( $query );
			} else {
				$scope( $query );
			}
		}

		return $query;
	}

public static function without_global_scopes ( array $ scopes ) { $ query = static :: query_with_no_global_scopes ( ) ; foreach ( static :: get_global_scopes ( ) as $ id => $ scope ) { if ( in_array ( $ id , $ scopes ) ) { continue ; } if ( $ scope instanceof Scope ) { $ scope -> apply ( $ query ) ; } else { $ scope ( $ query ) ; } } return $ query ; }

Create a new query builder without certain global scopes applied.

@since 2.0

@param array $scopes

@return FluentQuery

Create a new query builder without certain global scopes applied .


public static function with( $relations ) {

		$query = FluentQuery::from_model( get_called_class() );

		call_user_func_array( array( $query, 'with' ), func_get_args() );

		return $query;
	}

public static function with ( $ relations ) { $ query = FluentQuery :: from_model ( get_called_class ( ) ) ; call_user_func_array ( array ( $ query , 'with' ) , func_get_args ( ) ) ; return $ query ; }

Perform a query with a given set of relations.

@since 2.0

@param $relations,...

@return FluentQuery

Perform a query with a given set of relations .


public function to_array() {

		$attributes = array();

		foreach ( static::table()->get_columns() as $attribute => $column ) {
			$attributes[ $attribute ] = $this->get_attribute( $attribute );
		}

		return $attributes;
	}

public function to_array ( ) { $ attributes = array ( ) ; foreach ( static :: table ( ) -> get_columns ( ) as $ attribute => $ column ) { $ attributes [ $ attribute ] = $ this -> get_attribute ( $ attribute ) ; } return $ attributes ; }

Convert the model to an array.

@since 2.0

@return array


protected function get_comparison() {

		if ( ! $this->column ) {
			return '';
		}

		$query = "{$this->column} ";

		if ( is_array( $this->value ) ) {
			$values = $this->implode( $this->value );

			if ( $this->operator ) {
				$query .= "IN ($values)";
			} else {
				$query .= "NOT IN ($values)";
			}
		} elseif ( $this->value === null ) {

			if ( $this->operator === true || $this->operator === '=' ) {
				$query .= 'IS NULL';
			} else {
				$query .= 'IS NOT NULL';
			}

		} else {

			if ( is_bool( $this->operator ) ) {
				$operator = $this->operator ? '=' : '!=';
			} else {
				$operator = $this->operator;
			}

			$query .= "$operator '{$this->value}'";
		}

		return $query;
	}

protected
function
get_comparison
(
)
{
if
(
!
$
this
->
column
)
{
return
''
;
}
$
query
=
"{$this->column} "
;
if
(
is_array
(
$
this
->
value
)
)
{
$
values
=
$
this
->
implode
(
$
this
->
value
)
;
if
(
$
this
->
operator
)
{
$
query
.=
"IN ($values)"
;
}
else
{
$
query
.=
"NOT IN ($values)"
;
}
}
elseif
(
$
this
->
value
===
)
{
if
(
$
this
->
operator
===
true
||
$
this
->
operator
===
'='
)
{
$
query
.=
'IS NULL'
;
}
else
{
$
query
.=
'IS NOT NULL'
;
}
}
else
{
if
(
is_bool
(
$
this
->
operator
)
)
{
$
operator
=
$
this
->
operator
'='
:
'!='
;
}
else
{
$
operator
=
$
this
->
operator
;
}
$
query
.=
"$operator '{$this->value}'"
;
}
return
$
query
;
}

Get the actual comparison value to be checked.

@since 1.0

@return string

Get the actual comparison value to be checked .


protected function get_value() {

		$query = $this->for_clause ? '(' : $this->get_comparison();

		if ( ! empty( $this->clauses ) ) {
			foreach ( $this->clauses as $i => $clause ) {

				// We don't want to add the connector if this is the first clause and there is no comparison.
				if ( strlen( $query ) > 1 ) {
					$query .= ' ' . $clause['type'] . ' ';
				}

				/** @var Where $where */
				$where = $clause['clause'];

				if ( ! $where->is_for_clause() ) {
					$query .= '(';
				}

				$query .= $where->get_value();

				if ( ! $where->is_for_clause() ) {
					$query .= ')';
				}
			}
		}

		if ( $this->for_clause ) {
			$query .= ')';
		}

		return $query;
	}

Override the value method. Handles recursion of nested Where clauses.

@since 1.0

@return string

Override the value method . Handles recursion of nested Where clauses .


public function get( $row_key, $columns = '*' ) {
		return $this->get_by( $this->table->get_primary_key(), $row_key, $columns );
	}

public function get ( $ row_key , $ columns = '*' ) { return $ this -> get_by ( $ this -> table -> get_primary_key ( ) , $ row_key , $ columns ) ; }

Retrieve a row by the primary key

@since 1.0

@param string       $row_key
@param array|string $columns

@return object

@throws Exception


public function get_column( $column, $row_key ) {
		return $this->get_column_by( $column, $this->table->get_primary_key(), $row_key );
	}

public function get_column ( $ column , $ row_key ) { return $ this -> get_column_by ( $ column , $ this -> table -> get_primary_key ( ) , $ row_key ) ; }

Retrieve a specific column's value by the primary key

@since 1.0

@param string $column
@param string $row_key

@return string

@throws Exception

Retrieve a specific column s value by the primary key


protected function get_by_or_many_by_helper( $column, $value, $columns = '*', $method ) {

		$builder = new Builder();

		$allowed_columns = $this->table->get_columns();

		if ( is_array( $columns ) ) {

			$select = new Select( null );

			foreach ( $columns as $col ) {

				if ( ! isset( $allowed_columns[ $col ] ) ) {
					throw new InvalidColumnException( "Invalid column." );
				}

				$select->also( "`$col`" );
			}
		} elseif ( $columns == Select::ALL ) {
			$select = new Select( $columns );
		} else {
			if ( ! isset( $allowed_columns[ $columns ] ) ) {
				throw new InvalidColumnException( "Invalid column" );
			}

			$select = new Select( "`$columns`" );
		}

		$builder->append( $select );
		$builder->append( new From( $this->table->get_table_name( $this->wpdb ) ) );
		$builder->append( new Where( "`$column`", true, $this->escape_value( $column, $value ) ) );

		return $this->wpdb->{$method}( trim( $builder->build() ) );
	}

protected
function
get_by_or_many_by_helper
(
$
column
,
$
value
,
$
columns
=
'*'
,
$
method
)
{
$
builder
=
new
Builder
(
)
;
$
allowed_columns
=
$
this
->
table
->
get_columns
(
)
;
if
(
is_array
(
$
columns
)
)
{
$
select
=
new
Select
(
)
;
foreach
(
$
columns
as
$
col
)
{
if
(
!
isset
(
$
allowed_columns
[
$
col
]
)
)
{
throw
new
InvalidColumnException
(
"Invalid column."
)
;
}
$
select
->
also
(
"`$col`"
)
;
}
}
elseif
(
$
columns
==
Select
::
ALL
)
{
$
select
=
new
Select
(
$
columns
)
;
}
else
{
if
(
!
isset
(
$
allowed_columns
[
$
columns
]
)
)
{
throw
new
InvalidColumnException
(
"Invalid column"
)
;
}
$
select
=
new
Select
(
"`$columns`"
)
;
}
$
builder
->
append
(
$
select
)
;
$
builder
->
append
(
new
From
(
$
this
->
table
->
get_table_name
(
$
this
->
wpdb
)
)
)
;
$
builder
->
append
(
new
Where
(
"`$column`"
,
true
,
$
this
->
escape_value
(
$
column
,
$
value
)
)
)
;
return
$
this
->
wpdb
->
{
$
method
}
(
trim
(
$
builder
->
build
(
)
)
)
;
}

Helper function for get_by and get_many_by methods.

@param string $column
@param mixed  $value
@param string $columns
@param string $method

@return mixed
@throws InvalidColumnException

Helper function for get_by and get_many_by methods .


public function count( $wheres = array() ) {

		$builder = new Builder();

		$select = new Select( null );
		$select->expression( 'COUNT', '*' );
		$builder->append( $select );

		$builder->append( new From( $this->table->get_table_name( $this->wpdb ) ) );

		if ( ! empty( $wheres ) ) {

			foreach ( $wheres as $column => $value ) {
				if ( ! isset( $where ) ) {
					$where = new Where( "`$column`", true, $this->escape_value( $column, $value ) );
				} else {
					$where->qAnd( new Where( "`$column`", true, $this->escape_value( $column, $value ) ) );
				}
			}

			$builder->append( $where );
		}

		return (int) $this->wpdb->get_var( trim( $builder->build() ) );
	}

public function count ( $ wheres = array ( ) ) { $ builder = new Builder ( ) ; $ select = new Select ( null ) ; $ select -> expression ( 'COUNT' , '*' ) ; $ builder -> append ( $ select ) ; $ builder -> append ( new From ( $ this -> table -> get_table_name ( $ this -> wpdb ) ) ) ; if ( ! empty ( $ wheres ) ) { foreach ( $ wheres as $ column => $ value ) { if ( ! isset ( $ where ) ) { $ where = new Where ( "`$column`" , true , $ this -> escape_value ( $ column , $ value ) ) ; } else { $ where -> qAnd ( new Where ( "`$column`" , true , $ this -> escape_value ( $ column , $ value ) ) ) ; } } $ builder -> append ( $ where ) ; } return ( int ) $ this -> wpdb -> get_var ( trim ( $ builder -> build ( ) ) ) ; }

Retrieve the number of rows matching a certain where clause

@since 1.0

@param array $wheres

@return int


public function insert( $data ) {

		// Set default values
		$data = wp_parse_args( $data, $this->table->get_column_defaults() );

		$columns = $this->table->get_columns();

		// White list columns
		$data = array_intersect_key( $data, $columns );

		$null_columns = array();

		foreach ( $data as $col => $val ) {

			if ( $val === null ) {
				$null_columns[] = $col;
			}
		}

		foreach ( $null_columns as $null_column ) {
			unset( $data[ $null_column ] );
		}

		foreach ( $data as $name => $value ) {
			$data[ $name ] = $this->prepare_for_storage( $name, $value );
		}

		$formats = array_fill( 0, count( $data ), '%s' );

		$prev = $this->wpdb->show_errors( false );
		$this->wpdb->insert( $this->table->get_table_name( $this->wpdb ), $data, $formats );
		$this->wpdb->show_errors( $prev );

		if ( $this->wpdb->last_error ) {
			throw $this->generate_exception_from_db_error();
		}

		return $this->wpdb->insert_id;
	}

public
function
insert
(
$
data
)
{
// Set default values
$
data
=
wp_parse_args
(
$
data
,
$
this
->
table
->
get_column_defaults
(
)
)
;
$
columns
=
$
this
->
table
->
get_columns
(
)
;
// White list columns
$
data
=
array_intersect_key
(
$
data
,
$
columns
)
;
$
null_columns
=
array
(
)
;
foreach
(
$
data
as
$
col
=>
$
val
)
{
if
(
$
val
===
)
{
$
null_columns
[
]
=
$
col
;
}
}
foreach
(
$
null_columns
as
$
null_column
)
{
unset
(
$
data
[
$
null_column
]
)
;
}
foreach
(
$
data
as
$
name
=>
$
value
)
{
$
data
[
$
name
]
=
$
this
->
prepare_for_storage
(
$
name
,
$
value
)
;
}
$
formats
=
array_fill
(
0
,
count
(
$
data
)
,
'%s'
)
;
$
prev
=
$
this
->
wpdb
->
show_errors
(
false
)
;
$
this
->
wpdb
->
insert
(
$
this
->
table
->
get_table_name
(
$
this
->
wpdb
)
,
$
data
,
$
formats
)
;
$
this
->
wpdb
->
show_errors
(
$
prev
)
;
if
(
$
this
->
wpdb
->
last_error
)
{
throw
$
this
->
generate_exception_from_db_error
(
)
;
}
return
$
this
->
wpdb
->
insert_id
;
}

Insert a new row

@since 1.0

@param array $data

@return mixed Insert ID

@throws Exception


public function update( $row_key, $data, $where = array() ) {

		if ( empty( $row_key ) ) {
			return false;
		}

		if ( empty( $where ) ) {
			$where = array( $this->table->get_primary_key() => $row_key );
		}

		$columns = $this->table->get_columns();

		// White list columns
		$data = array_intersect_key( $data, $columns );

		foreach ( $data as $name => $value ) {
			$data[ $name ] = $this->prepare_for_storage( $name, $value );
		}

		$formats      = array_fill( 0, count( $data ), '%s' );
		$where_format = array_fill( 0, count( $where ), '%s' );

		$prev   = $this->wpdb->show_errors( false );
		$result = $this->wpdb->update( $this->table->get_table_name( $this->wpdb ), $data, $where, $formats, $where_format );
		$this->wpdb->show_errors( $prev );

		if ( $this->wpdb->last_error ) {
			throw $this->generate_exception_from_db_error();
		}

		return (bool) $result;
	}

public
function
update
(
$
row_key
,
$
data
,
$
where
=
array
(
)
)
{
if
(
empty
(
$
row_key
)
)
{
return
false
;
}
if
(
empty
(
$
where
)
)
{
$
where
=
array
(
$
this
->
table
->
get_primary_key
(
)
=>
$
row_key
)
;
}
$
columns
=
$
this
->
table
->
get_columns
(
)
;
// White list columns
$
data
=
array_intersect_key
(
$
data
,
$
columns
)
;
foreach
(
$
data
as
$
name
=>
$
value
)
{
$
data
[
$
name
]
=
$
this
->
prepare_for_storage
(
$
name
,
$
value
)
;
}
$
formats
=
array_fill
(
0
,
count
(
$
data
)
,
'%s'
)
;
$
where_format
=
array_fill
(
0
,
count
(
$
where
)
,
'%s'
)
;
$
prev
=
$
this
->
wpdb
->
show_errors
(
false
)
;
$
result
=
$
this
->
wpdb
->
update
(
$
this
->
table
->
get_table_name
(
$
this
->
wpdb
)
,
$
data
,
$
where
,
$
formats
,
$
where_format
)
;
$
this
->
wpdb
->
show_errors
(
$
prev
)
;
if
(
$
this
->
wpdb
->
last_error
)
{
throw
$
this
->
generate_exception_from_db_error
(
)
;
}
return
(
bool
)
$
result
;
}

Update a row

@since 1.0

@param string $row_key
@param array  $data
@param array  $where

@return  bool

@throws Exception


public function delete( $row_key ) {

		if ( empty( $row_key ) ) {
			return false;
		}

		$row_key = $this->escape_value( $this->table->get_primary_key(), $row_key );

		$prev   = $this->wpdb->show_errors( false );
		$result = $this->wpdb->delete( $this->table->get_table_name( $this->wpdb ), array(
			$this->table->get_primary_key() => $row_key
		), '%s' );
		$this->wpdb->show_errors( $prev );

		if ( $this->wpdb->last_error ) {
			throw $this->generate_exception_from_db_error();
		}

		return (bool) $result;
	}

public function delete ( $ row_key ) { if ( empty ( $ row_key ) ) { return false ; } $ row_key = $ this -> escape_value ( $ this -> table -> get_primary_key ( ) , $ row_key ) ; $ prev = $ this -> wpdb -> show_errors ( false ) ; $ result = $ this -> wpdb -> delete ( $ this -> table -> get_table_name ( $ this -> wpdb ) , array ( $ this -> table -> get_primary_key ( ) => $ row_key ) , '%s' ) ; $ this -> wpdb -> show_errors ( $ prev ) ; if ( $ this -> wpdb -> last_error ) { throw $ this -> generate_exception_from_db_error ( ) ; } return ( bool ) $ result ; }

Delete a row identified by the primary key

@since 1.0

@param string $row_key

@return  bool

@throws Exception


public function delete_many( $wheres ) {

		$format = array_fill( 0, count( $wheres ), '%s' );
		$prev   = $this->wpdb->show_errors( false );
		$result = $this->wpdb->delete( $this->table->get_table_name( $this->wpdb ), $wheres, $format );
		$this->wpdb->show_errors( $prev );

		if ( $this->wpdb->last_error ) {
			throw $this->generate_exception_from_db_error();
		}

		return (bool) $result;
	}

public function delete_many ( $ wheres ) { $ format = array_fill ( 0 , count ( $ wheres ) , '%s' ) ; $ prev = $ this -> wpdb -> show_errors ( false ) ; $ result = $ this -> wpdb -> delete ( $ this -> table -> get_table_name ( $ this -> wpdb ) , $ wheres , $ format ) ; $ this -> wpdb -> show_errors ( $ prev ) ; if ( $ this -> wpdb -> last_error ) { throw $ this -> generate_exception_from_db_error ( ) ; } return ( bool ) $ result ; }

Delete many rows.

@since 1.0

@param $wheres array

@return bool

@throws Exception


protected function generate_exception_from_db_error() {

		if ( ! $this->wpdb->last_error ) {
			return null;
		}

		if ( $this->is_mysqli() ) {
			$error_number = mysqli_errno( $this->get_dbh() );
		} else {
			$error_number = mysql_errno( $this->get_dbh() );
		}

		return new Exception( $this->wpdb->last_error, $error_number );
	}

protected function generate_exception_from_db_error ( ) { if ( ! $ this -> wpdb -> last_error ) { return null ; } if ( $ this -> is_mysqli ( ) ) { $ error_number = mysqli_errno ( $ this -> get_dbh ( ) ) ; } else { $ error_number = mysql_errno ( $ this -> get_dbh ( ) ) ; } return new Exception ( $ this -> wpdb -> last_error , $ error_number ) ; }

Generate an Exception object from a DB error.

@return Exception

Generate an Exception object from a DB error .


protected function do_save( $term ) {

		if ( ! $term->term_id ) {
			$ids = wp_insert_term( wp_slash( $term->name ), $term->taxonomy, array(
				'description' => wp_slash( $term->description ),
				'parent'      => $term->parent,
				'slug'        => $term->slug
			) );
		} else {
			$ids = wp_update_term( $term->term_id, $term->taxonomy, array(
				'name'        => wp_slash( $term->name ),
				'description' => wp_slash( $term->description ),
				'parent'      => $term->parent,
				'slug'        => $term->slug
			) );
		}

		if ( is_wp_error( $ids ) ) {
			throw new \InvalidArgumentException( 'Error encountered while saving WP_Term: ' . $ids->get_error_message() );
		}

		$term = get_term( $ids['term_id'], $term->taxonomy );

		if ( is_wp_error( $term ) ) {
			throw new \UnexpectedValueException( $term->get_error_message() );
		}

		return $term;
	}

Do the saving for a term.

@since 2.0

@param \WP_Term $term

@return \WP_Term


protected function make_query_object( $model_class = false ) {

		$query = call_user_func( array( $this->related_model, 'query_with_no_global_scopes' ) );

		if ( ! $model_class ) {
			$query->set_model_class( null );
		}

		return $query;
	}

protected function make_query_object ( $ model_class = false ) { $ query = call_user_func ( array ( $ this -> related_model , 'query_with_no_global_scopes' ) ) ; if ( ! $ model_class ) { $ query -> set_model_class ( null ) ; } return $ query ; }

Make a FluentQuery object.

@since 2.0

@param bool $model_class Set the Model class if possible.

@return FluentQuery


protected function fetch_results_for_eager_load( $primary_keys ) {

		if ( ! $primary_keys ) {
			return new Collection( array(), false, $this->saver );
		}

		$query = $this->make_query_object( true );
		$query->where( $this->related_primary_key_column, true, $primary_keys );

		return $query->results( $this->saver );
	}

protected function fetch_results_for_eager_load ( $ primary_keys ) { if ( ! $ primary_keys ) { return new Collection ( array ( ) , false , $ this -> saver ) ; } $ query = $ this -> make_query_object ( true ) ; $ query -> where ( $ this -> related_primary_key_column , true , $ primary_keys ) ; return $ query -> results ( $ this -> saver ) ; }

Fetch results for an eager loading query.

@since 2.0

@param array $primary_keys

@return \Doctrine\Common\Collections\Collection|\IronBound\DB\Collection

Fetch results for an eager loading query .


public function newValues($nameParams, $val)
    {
        // store value buffer data
        if (count($this->_lastInsertValues) > 0) {
            $this->_insertValues[] = $this->_lastInsertValues;
        }

        // set new value in insert buffer
        $this->_lastInsertValues = array($nameParams => $val);

        return $this;
    }

public
function
newValues
(
$
nameParams
,
$
val
)
{
// store value buffer data
if
(
count
(
$
this
->
_lastInsertValues
)
>
0
)
{
$
this
->
_insertValues
[
]
=
$
this
->
_lastInsertValues
;
}
// set new value in insert buffer
$
this
->
_lastInsertValues
=
array
(
$
nameParams
=>
$
val
)
;
return
$
this
;
}

Create new values set for multiple insert query

@param $nameParams - field name
@param $val        - field value

@return $this


public function set($nameParams, $val)
    {
        $this->_setName[] = $nameParams;
        $this->_setVal[]  = $val;

        return $this;
    }

public function set ( $ nameParams , $ val ) { $ this -> _setName [ ] = $ nameParams ; $ this -> _setVal [ ] = $ val ; return $ this ; }

Set values for update query

@alias values

@param $nameParams
@param $val

@return $this


public function select($field)
    {
        $this->_queryType = self :: SELECT;
        if (!is_array($field)) {
            $field = array($field);
        }
        $this->_select = array_merge($this->_select, $field);

        return $this;
    }

public function select ( $ field ) { $ this -> _queryType = self :: SELECT ; if ( ! is_array ( $ field ) ) { $ field = array ( $ field ) ; } $ this -> _select = array_merge ( $ this -> _select , $ field ) ; return $ this ; }

Add field to select

@param $field

@return $this


public function resetSelect($field = null)
    {
        $this->_select = array();
        if ($field !== null) {
            $this->select($field);
        }

        return $this;
    }

public function resetSelect ( $ field = null ) { $ this -> _select = array ( ) ; if ( $ field !== null ) { $ this -> select ( $ field ) ; } return $ this ; }

Reset select and add a new field

@param $field

@return $this


public function update($tableName)
    {
        $this->_queryType = self :: UPDATE;
        $this->_update    = $tableName;

        return $this;
    }

public function update ( $ tableName ) { $ this -> _queryType = self :: UPDATE ; $ this -> _update = $ tableName ; return $ this ; }

Configure object for UPDATE query
and set the main table name

@param $tableName

@return $this


public function delete($tableName)
    {
        $this->_queryType = self :: DELETE;
        $this->_delete    = $tableName;

        return $this;
    }

public function delete ( $ tableName ) { $ this -> _queryType = self :: DELETE ; $ this -> _delete = $ tableName ; return $ this ; }

Configure object for DELETE query
and set the main table name

@param $tableName

@return $this


public function insertInto($tableName)
    {
        $this->_queryType = self :: INSERT;
        $this->_insert    = $tableName;

        return $this;
    }

public function insertInto ( $ tableName ) { $ this -> _queryType = self :: INSERT ; $ this -> _insert = $ tableName ; return $ this ; }

Configure object for INSERT query
and set the main table name

@param $tableName

@return $this


public function from($tableName, $aliasTable = null)
    {
        $this->_from = sprintf('%s %s', $tableName, $aliasTable);

        return $this;
    }

public
function
from
(
$
tableName
,
$
aliasTable
=
)
{
$
this
->
_from
=
sprintf
(
'%s %s'
,
$
tableName
,
$
aliasTable
)
;
return
$
this
;
}

Add FROM clause with table name and optional alias

@param      $tableName
@param null $aliasTable

@return $this


public function join($mode, $table, $on)
    {
        $this->_join[] = sprintf('%s JOIN %s ON %s', $mode, $table, $on);

        return $this;
    }

public
function
join
(
$
mode
,
$
table
,
$
on
)
{
$
this
->
_join
[
]
=
sprintf
(
'%s JOIN %s ON %s'
,
$
mode
,
$
table
,
$
on
)
;
return
$
this
;
}

Add JOIN clause

@param $mode     string    INNER|LEFT|RIGHT or other mysql join possibilities
@param $table    string    table name
@param $on       string    join condition

@return $this


public function andWhere($field, $comparisonOperator, $value)
    {
        $this->where($field, $comparisonOperator, $value, 'AND');

        return $this;
    }

public function andWhere ( $ field , $ comparisonOperator , $ value ) { $ this -> where ( $ field , $ comparisonOperator , $ value , 'AND' ) ; return $ this ; }

Alias to add WHERE clause with AND operator

@param $field
@param $comparisonOperator
@param $value

@return $this


public function orWhere($field, $comparisonOperator, $value)
    {
        $this->where($field, $comparisonOperator, $value, 'OR');

        return $this;
    }

public function orWhere ( $ field , $ comparisonOperator , $ value ) { $ this -> where ( $ field , $ comparisonOperator , $ value , 'OR' ) ; return $ this ; }

Alias to add WHERE clause with OR

@param $field
@param $comparisonOperator
@param $value

@return $this


public function resetOrderBy($orderName = null, $orderVal = '')
    {
        $this->_orderBy = array();
        if ($orderName !== null) {
            $this->orderBy($orderName, $orderVal);
        }

        return $this;
    }

public function resetOrderBy ( $ orderName = null , $ orderVal = '' ) { $ this -> _orderBy = array ( ) ; if ( $ orderName !== null ) { $ this -> orderBy ( $ orderName , $ orderVal ) ; } return $ this ; }

Reset the order clause from query

@param null   $orderName
@param string $orderVal

@return $this


public function limit($limitStart = null, $limitEnd = null)
    {
        if ($limitStart === null) {
            return $this;
        }

        if ($limitEnd === null) {
            $this->_limit = sprintf('LIMIT %d', $limitStart);
        } else {
            $this->_limit = sprintf('LIMIT %d, %d', $limitStart, $limitEnd);
        }

        return $this;
    }

public
function
limit
(
$
limitStart
=
,
$
limitEnd
=
)
{
if
(
$
limitStart
===
)
{
return
$
this
;
}
if
(
$
limitEnd
===
)
{
$
this
->
_limit
=
sprintf
(
'LIMIT %d'
,
$
limitStart
)
;
}
else
{
$
this
->
_limit
=
sprintf
(
'LIMIT %d, %d'
,
$
limitStart
,
$
limitEnd
)
;
}
return
$
this
;
}

Set LIMIT clause

@param      $limitStart
@param null $limitEnd

@return $this


public function resetLimit($limitStart = null, $limitEnd = null)
    {
        $this->_limit = '';
        if ($limitStart !== null) {
            $this->limit($limitStart, $limitEnd);
        }

        return $this;
    }

public function resetLimit ( $ limitStart = null , $ limitEnd = null ) { $ this -> _limit = '' ; if ( $ limitStart !== null ) { $ this -> limit ( $ limitStart , $ limitEnd ) ; } return $ this ; }

Delete the limit clause from query

@param null $limitStart
@param null $limitEnd

@return $this


public static function boot_TrashSupport() {

		$table = static::table();

		if ( ! $table instanceof TrashTable ) {
			throw new \UnexpectedValueException( sprintf( "%s model's table must implement TrashTable." ), get_called_class() );
		}

		static::register_global_scope( 'trash', function ( FluentQuery $query ) use ( $table ) {
			$query->and_where( $table->get_deleted_at_column(), true, null );
		} );
	}

Initialize the TrashSupport trait.

@since 2.0


public function get_results() {

		if ( ( $results = $this->load_from_cache( $this->parent ) ) === null ) {
			$results = $this->fetch_results();

			if ( $this->cache ) {
				$this->cache_results( $results, $this->parent );
				$this->maybe_register_cache_events();
			}
		}

		if ( $this->keep_synced && $results instanceof Collection ) {
			$this->register_events( $results );
		}

		return $results;
	}

public function get_results ( ) { if ( ( $ results = $ this -> load_from_cache ( $ this -> parent ) ) === null ) { $ results = $ this -> fetch_results ( ) ; if ( $ this -> cache ) { $ this -> cache_results ( $ results , $ this -> parent ) ; $ this -> maybe_register_cache_events ( ) ; } } if ( $ this -> keep_synced && $ results instanceof Collection ) { $ this -> register_events ( $ results ) ; } return $ results ; }

Get the results of the relation.

@since 2.0

@return Collection|Model|mixed


protected function load_from_cache( Model $model ) {

		$cached = wp_cache_get( $model->get_pk(), $this->get_cache_group() );

		if ( $cached === false ) {
			return null;
		}

		if ( is_array( $cached ) ) {
			return $this->load_collection_from_cache( $cached, $model );
		} else {
			return $this->load_single_from_cache( $cached );
		}
	}

protected function load_from_cache ( Model $ model ) { $ cached = wp_cache_get ( $ model -> get_pk ( ) , $ this -> get_cache_group ( ) ) ; if ( $ cached === false ) { return null ; } if ( is_array ( $ cached ) ) { return $ this -> load_collection_from_cache ( $ cached , $ model ) ; } else { return $ this -> load_single_from_cache ( $ cached ) ; } }

Load the results of a relation from the cache.

@since 2.0

@param Model $model

@return Collection|Model|mixed|null

Load the results of a relation from the cache .


protected function load_collection_from_cache( array $cached, Model $for ) {

		$models  = array();
		$removed = array();

		foreach ( $cached as $id ) {
			$model = $this->saver->get_model( $id );

			if ( $model ) {
				$models[ $id ] = $model;
			} else {
				$removed[] = $id;
			}
		}

		$diff = array_diff( $cached, $removed );
		wp_cache_set( $for->get_pk(), $diff, $this->get_cache_group() );

		return new Collection( $models, false, $this->saver );
	}

protected function load_collection_from_cache ( array $ cached , Model $ for ) { $ models = array ( ) ; $ removed = array ( ) ; foreach ( $ cached as $ id ) { $ model = $ this -> saver -> get_model ( $ id ) ; if ( $ model ) { $ models [ $ id ] = $ model ; } else { $ removed [ ] = $ id ; } } $ diff = array_diff ( $ cached , $ removed ) ; wp_cache_set ( $ for -> get_pk ( ) , $ diff , $ this -> get_cache_group ( ) ) ; return new Collection ( $ models , false , $ this -> saver ) ; }

Load a collection of models from the cache.

@since 2.0

@param int[]|string[] $cached
@param Model          $for

@return Collection

Load a collection of models from the cache .


protected function cache_results( $results, Model $model ) {

		if ( $results instanceof Collection ) {
			$this->cache_collection( $results, $model );
		} elseif ( is_object( $results ) ) {
			$this->cache_single( $results, $model );
		}
	}

protected function cache_results ( $ results , Model $ model ) { if ( $ results instanceof Collection ) { $ this -> cache_collection ( $ results , $ model ) ; } elseif ( is_object ( $ results ) ) { $ this -> cache_single ( $ results , $ model ) ; } }

Cache the results of a relation.

@since 2.0

@param Collection|Model|mixed $results
@param Model                  $model


protected function cache_collection( Collection $collection, Model $model ) {

		$ids = array_map( function ( $e ) use ( $collection ) {
			return $collection->get_saver()->get_pk( $e );
		}, $collection->toArray() );

		wp_cache_set( $model->get_pk(), $ids, $this->get_cache_group() );
	}

protected function cache_collection ( Collection $ collection , Model $ model ) { $ ids = array_map ( function ( $ e ) use ( $ collection ) { return $ collection -> get_saver ( ) -> get_pk ( $ e ) ; } , $ collection -> toArray ( ) ) ; wp_cache_set ( $ model -> get_pk ( ) , $ ids , $ this -> get_cache_group ( ) ) ; }

Cache a collection of results.

@since 2.0

@param Collection $collection
@param Model      $model


protected function cache_single( $result, Model $model ) {

		$id = $this->saver->get_pk( $result );

		wp_cache_set( $model->get_pk(), $id, $this->get_cache_group() );
	}

protected function cache_single ( $ result , Model $ model ) { $ id = $ this -> saver -> get_pk ( $ result ) ; wp_cache_set ( $ model -> get_pk ( ) , $ id , $ this -> get_cache_group ( ) ) ; }

Cache a single result.

@since 2.0

@param Model|mixed $result
@param Model       $model


private function maybe_register_cache_events() {

		$key = get_class( $this );
		$key .= "-{$this->attribute}";

		if ( isset( $this->registered_cache_events[ $key ] ) ) {
			return;
		}

		$this->register_cache_events();

		$this->registered_cache_events[ $key ] = true;
	}

private function maybe_register_cache_events ( ) { $ key = get_class ( $ this ) ; $ key .= "-{$this->attribute}" ; if ( isset ( $ this -> registered_cache_events [ $ key ] ) ) { return ; } $ this -> register_cache_events ( ) ; $ this -> registered_cache_events [ $ key ] = true ; }

Maybe register cache events.

Cache events should only be registered once per relation.

@since 2.o


protected function do_save( \WP_User $user ) {

		if ( ! $user->exists() ) {

			if ( empty( $user->user_pass ) ) {
				$user->user_pass = wp_generate_password( 24 );
			}

			$id = wp_insert_user( wp_slash( $user->to_array() ) );
		} else {
			$id = wp_update_user( wp_slash( $user->to_array() ) );
		}

		if ( is_wp_error( $id ) ) {
			throw new \InvalidArgumentException( 'Error encountered while saving WP_User: ' . $id->get_error_message() );
		}

		return get_user_by( 'id', $id );
	}

Do the saving for a user.

@since 2.0

@param \WP_User $user

@return \WP_User


private function set_last_updated_at() {

		if ( ! static::get_table() instanceof TimestampedTable ) {
			return;
		}

		$dirty = $this->is_dirty();

		$this->set_attribute( static::get_table()->get_updated_at_column(), $this->fresh_timestamp() );

		// If the model is dirty, we don't want to commit our save since the user should already be calling save.
		if ( ! $dirty ) {
			$this->save();
		}
	}

Set the model's last updated date whenever meta changes.

Set the model s last updated date whenever meta changes .


public function getContainerParameters(): array
    {
        $result = array(
            'app.name' => $this->getName(),
            'app.version' => $this->getVersion(),
            'app.environment' => $this->getEnvironment(),
            'app.sub_environment' => $this->getSubEnvironment(),
            'app.debug' => $this->isDebug(),
            'app.charset' => $this->getCharset(),
            'app.path' => $this->getAppPath(),
            'app.config_path' => $this->getConfigPath(),
            'app.base_path' => $this->getBasePath(),
            'app.storage_path' => $this->getStoragePath(),
            'app.log_path' => $this->getLogPath(),
            'app.cache_path' => $this->getCachePath(),
            'app.src_path' => $this->getSrcPath(),
        );

        return $result;
    }

public function getContainerParameters ( ) : array { $ result = array ( 'app.name' => $ this -> getName ( ) , 'app.version' => $ this -> getVersion ( ) , 'app.environment' => $ this -> getEnvironment ( ) , 'app.sub_environment' => $ this -> getSubEnvironment ( ) , 'app.debug' => $ this -> isDebug ( ) , 'app.charset' => $ this -> getCharset ( ) , 'app.path' => $ this -> getAppPath ( ) , 'app.config_path' => $ this -> getConfigPath ( ) , 'app.base_path' => $ this -> getBasePath ( ) , 'app.storage_path' => $ this -> getStoragePath ( ) , 'app.log_path' => $ this -> getLogPath ( ) , 'app.cache_path' => $ this -> getCachePath ( ) , 'app.src_path' => $ this -> getSrcPath ( ) , ) ; return $ result ; }

Returns app config parameters like app.name, app.version and app.base_path as array

@return array

Returns app config parameters like app . name app . version and app . base_path as array


public function containerIsCacheable(): bool
    {
        $result = true; // container is cacheable by default

        if ($this->container->hasParameter('container.cache')) {
            $result = (bool)$this->container->getParameter('container.cache');
        }

        return $result;
    }

public
function
containerIsCacheable
(
)
:
bool
{
$
result
=
true
;
// container is cacheable by default
if
(
$
this
->
container
->
hasParameter
(
'container.cache'
)
)
{
$
result
=
(
bool
)
$
this
->
container
->
getParameter
(
'container.cache'
)
;
}
return
$
result
;
}

Returns true, if the container.cache parameter does not exist or is false

@return bool

Returns true if the container . cache parameter does not exist or is false


protected function boot()
    {
        if ($this->hasBooted()) return; // Nothing to do

        if ($this->debug) {
            $this->setContainer(new ContainerBuilder(new EnvPlaceholderParameterBag($this->getContainerParameters())));
            $this->loadContainerConfiguration();
            $this->container->compile(true);
        } else {
            $filename = $this->getContainerCacheFilename();

            if (file_exists($filename)) {
                require_once($filename);
                $this->setContainer(new CachedContainer());
            } else {
                $this->setContainer(new ContainerBuilder(new EnvPlaceholderParameterBag($this->getContainerParameters())));
                $this->loadContainerConfiguration();
                $this->container->compile(true);

                if ($this->containerIsCacheable()) {
                    $dumper = new PhpDumper($this->container);
                    file_put_contents($filename, $dumper->dump());
                }
            }
        }
    }

protected
function
boot
(
)
{
if
(
$
this
->
hasBooted
(
)
)
return
;
// Nothing to do
if
(
$
this
->
debug
)
{
$
this
->
setContainer
(
new
ContainerBuilder
(
new
EnvPlaceholderParameterBag
(
$
this
->
getContainerParameters
(
)
)
)
)
;
$
this
->
loadContainerConfiguration
(
)
;
$
this
->
container
->
compile
(
true
)
;
}
else
{
$
filename
=
$
this
->
getContainerCacheFilename
(
)
;
if
(
file_exists
(
$
filename
)
)
{
require_once
(
$
filename
)
;
$
this
->
setContainer
(
new
CachedContainer
(
)
)
;
}
else
{
$
this
->
setContainer
(
new
ContainerBuilder
(
new
EnvPlaceholderParameterBag
(
$
this
->
getContainerParameters
(
)
)
)
)
;
$
this
->
loadContainerConfiguration
(
)
;
$
this
->
container
->
compile
(
true
)
;
if
(
$
this
->
containerIsCacheable
(
)
)
{
$
dumper
=
new
PhpDumper
(
$
this
->
container
)
;
file_put_contents
(
$
filename
,
$
dumper
->
dump
(
)
)
;
}
}
}
}


protected function loadContainerConfiguration()
    {
        $configPath = $this->getConfigPath();
        $environment = $this->getEnvironment();

        $loader = new YamlFileLoader($this->container, new FileLocator($configPath));

        if (file_exists($configPath . '/' . $environment . '.yml')) {
            $loader->load($environment . '.yml');
        }

        $subEnvironment = $this->getSubEnvironment();

        if (file_exists($configPath . '/' . $environment . '.' . $subEnvironment . '.yml')) {
            $loader->load($environment . '.' . $subEnvironment . '.yml');
        }
    }

protected function loadContainerConfiguration ( ) { $ configPath = $ this -> getConfigPath ( ) ; $ environment = $ this -> getEnvironment ( ) ; $ loader = new YamlFileLoader ( $ this -> container , new FileLocator ( $ configPath ) ) ; if ( file_exists ( $ configPath . '/' . $ environment . '.yml' ) ) { $ loader -> load ( $ environment . '.yml' ) ; } $ subEnvironment = $ this -> getSubEnvironment ( ) ; if ( file_exists ( $ configPath . '/' . $ environment . '.' . $ subEnvironment . '.yml' ) ) { $ loader -> load ( $ environment . '.' . $ subEnvironment . '.yml' ) ; } }

Loads the container config from YAML files in the config directory


protected function build_column_name_for_table( Table $table ) {

		$basename  = $this->class_basename( $table );
		$tableized = Inflector::tableize( $basename );

		$parts         = explode( '_', $tableized );
		$last_plural   = array_pop( $parts );
		$last_singular = Inflector::singularize( $last_plural );
		$parts[]       = $last_singular;

		$column_name = implode( '_', $parts );
		$column_name .= '_' . $table->get_primary_key();

		return $column_name;
	}

protected function build_column_name_for_table ( Table $ table ) { $ basename = $ this -> class_basename ( $ table ) ; $ tableized = Inflector :: tableize ( $ basename ) ; $ parts = explode ( '_' , $ tableized ) ; $ last_plural = array_pop ( $ parts ) ; $ last_singular = Inflector :: singularize ( $ last_plural ) ; $ parts [ ] = $ last_singular ; $ column_name = implode ( '_' , $ parts ) ; $ column_name .= '_' . $ table -> get_primary_key ( ) ; return $ column_name ; }

Build the column name for a table.

@since 2.0

@param Table $table

@return string


protected function persist_do_save( Collection $values ) {

		$added = array();

		foreach ( $values as $value ) {

			$new = ! $this->saver->get_pk( $value );

			// prevent recursion by excluding the relation that references this from being saved.
			$saved = $this->saver->save( $value, array( 'exclude_relations' => $this->other_attribute ) );
			$pk    = $this->saver->get_pk( $saved );

			if ( $new && $pk ) {
				$added[ $pk ] = $saved;

				$values->removeElement( $value );
			}

			$values->dont_remember( function ( Collection $collection ) use ( $saved, $pk ) {
				if ( ! $collection->contains( $saved ) ) {
					$collection->add( $saved );
				}
			} );
		}

		return $added;
	}

Save all models that are being persisted.

@since 2.0

@param Collection $values

@return array Models that have been newly created, not updated.

Save all models that are being persisted .


protected function persist_removed( $removed ) {

		$cached = wp_cache_get( $this->parent->get_pk(), $this->get_cache_group() ) ?: array();

		global $wpdb;

		$where = new Where( 1, false, 1 );

		foreach ( $removed as $model ) {

			$i = array_search( $this->saver->get_pk( $model ), $cached );

			if ( $i !== false ) {
				unset( $cached[ $i ] );
			}

			$remove_where = new Where( $this->other_column, true, esc_sql( $this->parent->get_pk() ) );
			$remove_where->qAnd(
				new Where( $this->primary_column, true, esc_sql( $this->saver->get_pk( $model ) ) )
			);

			$where->qOr( $remove_where );
		}

		wp_cache_set( $this->parent->get_pk(), $cached, $this->get_cache_group() );

		$wpdb->query( "DELETE FROM `{$this->association->get_table_name( $wpdb )}` $where" );
	}

Persist the removed models.

@since 2.0

@param DoctrineCollection $removed


protected function persist_added( $added ) {

		$cached = wp_cache_get( $this->parent->get_pk(), $this->get_cache_group() ) ?: array();

		global $wpdb;

		$insert = array();

		$parent = esc_sql( $this->parent->get_pk() );

		foreach ( $added as $model ) {
			$pk = esc_sql( $this->saver->get_pk( $model ) );

			if ( $pk ) {
				$insert[] = "({$parent},{$pk})";
				$cached[] = $pk;
			}
		}

		if ( empty( $insert ) ) {
			return;
		}

		wp_cache_set( $this->parent->get_pk(), $cached, $this->get_cache_group() );

		$insert = implode( ',', $insert );

		$sql = "INSERT IGNORE INTO `{$this->association->get_table_name( $wpdb )}` ";
		$sql .= "({$this->other_column},{$this->primary_column}) VALUES $insert";

		$wpdb->query( $sql );
	}

Persist the added models.

@since 2.0

@param DoctrineCollection $added


public function create($attributes) {
        if (!isset($attributes['uuid'])) { $attributes['uuid'] = Uuid::uuid4()->toString(); }
        return parent::create($attributes);
    }

public function create ( $ attributes ) { if ( ! isset ( $ attributes [ 'uuid' ] ) ) { $ attributes [ 'uuid' ] = Uuid :: uuid4 ( ) -> toString ( ) ; } return parent :: create ( $ attributes ) ; }


protected function initAuthenticator() {
        $auth = $this->auth;
        $this->hmac_validator  = new \Tokenly\HmacAuth\Validator(function($api_token) use ($auth) {
            // lookup the API secrect by $api_token using $this->auth
            $user = $this->user_repository->findByAPIToken($api_token);
            if (!$user) { return null; }

            // populate Guard with the $user
            $auth->setUser($user);

            // the purpose of this function is to look up the secret
            $api_secret = $user->getApiSecretKey();
            return $api_secret;
        });

        $substitions = Config::get('protectedApi.allowedSubstitutions');
        if ($substitions) {
            $this->hmac_validator->setSignedURLValidationFunction(function($actual_url, $signed_url) use ($substitions) {
                return $this->validateSignedURL($actual_url, $signed_url, $substitions);
            });
        }
    }

Create a new filter instance.

@param  Guard  $auth
@return void


public function create($attributes) {
        $attributes = $this->modifyAttributesBeforeCreate($attributes);

        $model = $this->prototype_model->create($attributes);

        // broadcast create event
        if ($this->usesTrait(BroadcastsRepositoryEvents::class)) {
            $this->broadcastRepositoryEvent(new ModelCreated($model, $attributes));
        }

        return $model;
    }

public
function
create
(
$
attributes
)
{
$
attributes
=
$
this
->
modifyAttributesBeforeCreate
(
$
attributes
)
;
$
model
=
$
this
->
prototype_model
->
create
(
$
attributes
)
;
// broadcast create event
if
(
$
this
->
usesTrait
(
BroadcastsRepositoryEvents
::
class
)
)
{
$
this
->
broadcastRepositoryEvent
(
new
ModelCreated
(
$
model
,
$
attributes
)
)
;
}
return
$
model
;
}


public function convert($asset, $basePath)
    {
        if (($dotPos = strrpos($asset, '.')) === false)
            return $asset;

        if (($ext = substr($asset, $dotPos + 1)) !== self::INPUT_EXT)
            return parent::convert($asset, $basePath);

        $assetFilemtime = @filemtime("$basePath/$asset");
        $result = $this->buildResult($asset, $dotPos, ($this->cacheSuffix === true) ? $assetFilemtime : null);
        $resultFilemtime = @filemtime("$basePath/$result");

        if ($resultFilemtime < $assetFilemtime) {
            $this->parseLess($basePath, $asset, $result);
        }

        return $result;
    }

public function convert ( $ asset , $ basePath ) { if ( ( $ dotPos = strrpos ( $ asset , '.' ) ) === false ) return $ asset ; if ( ( $ ext = substr ( $ asset , $ dotPos + 1 ) ) !== self :: INPUT_EXT ) return parent :: convert ( $ asset , $ basePath ) ; $ assetFilemtime = @ filemtime ( "$basePath/$asset" ) ; $ result = $ this -> buildResult ( $ asset , $ dotPos , ( $ this -> cacheSuffix === true ) ? $ assetFilemtime : null ) ; $ resultFilemtime = @ filemtime ( "$basePath/$result" ) ; if ( $ resultFilemtime < $ assetFilemtime ) { $ this -> parseLess ( $ basePath , $ asset , $ result ) ; } return $ result ; }

Converts a given LESS assets file into a CSS

@param string $asset the asset file path, relative to $basePath
@param string $basePath the directory the $asset is relative to.
@return string the converted asset file path, relative to $basePath.


protected function buildResult($asset, $dotPos = null, $resultSuffix = null)
    {
        if ($dotPos === null) {
            if (($dotPos = strrpos($asset, '.')) === false) {
                return $asset;
            }
        }

        $divider = ($this->compress === true) ? '-m' : '-';
        $suffix = ($resultSuffix !== null) ? $divider . (string)$resultSuffix . '.' . self::OUTPUT_EXT : '.' . self::OUTPUT_EXT;

        return substr($asset, 0, $dotPos) . $suffix;
    }

protected function buildResult ( $ asset , $ dotPos = null , $ resultSuffix = null ) { if ( $ dotPos === null ) { if ( ( $ dotPos = strrpos ( $ asset , '.' ) ) === false ) { return $ asset ; } } $ divider = ( $ this -> compress === true ) ? '-m' : '-' ; $ suffix = ( $ resultSuffix !== null ) ? $ divider . ( string ) $ resultSuffix . '.' . self :: OUTPUT_EXT : '.' . self :: OUTPUT_EXT ; return substr ( $ asset , 0 , $ dotPos ) . $ suffix ; }

Builds the result file name

@param string $asset the asset file path, relative to $basePath
@param int $dotPos the strrpos position of filename-extension dot
@param mixed $resultSuffix Suffix result css filename
@return string the converted asset file path, relative to $basePath.


protected function parseLess($basePath, $asset, $result)
    {
        $parser = new \Less_Parser([
            'compress' => ($this->compress === true) ? true : false,
            'cache_dir' => ($this->useCache === true) ? ($this->cacheDir !== null && is_dir($this->cacheDir)) ? $this->cacheDir : __DIR__ . DIRECTORY_SEPARATOR . 'cache' : false,
        ]);

        $parser->parseFile($basePath . DIRECTORY_SEPARATOR . $asset);

        if ((!$css = $parser->getCss()) || empty($css))
            return false;

        Yii::trace("Converted $asset into $result", __METHOD__);

        return file_put_contents($basePath . DIRECTORY_SEPARATOR . $result, $css, LOCK_EX);
    }

protected
function
parseLess
(
$
basePath
,
$
asset
,
$
result
)
{
$
parser
=
new
\
Less_Parser
(
[
'compress'
=>
(
$
this
->
compress
===
true
)
true
:
false
,
'cache_dir'
=>
(
$
this
->
useCache
===
true
)
(
$
this
->
cacheDir
!==
&&
is_dir
(
$
this
->
cacheDir
)
)
$
this
->
cacheDir
:
__DIR__
.
DIRECTORY_SEPARATOR
.
'cache'
:
false
,
]
)
;
$
parser
->
parseFile
(
$
basePath
.
DIRECTORY_SEPARATOR
.
$
asset
)
;
if
(
(
!
$
css
=
$
parser
->
getCss
(
)
)
||
empty
(
$
css
)
)
return
false
;
Yii
::
trace
(
"Converted $asset into $result"
,
__METHOD__
)
;
return
file_put_contents
(
$
basePath
.
DIRECTORY_SEPARATOR
.
$
result
,
$
css
,
LOCK_EX
)
;
}

Parsing Less File

@param string $basePath asset base path and command working directory
@param string $asset the name of the asset file
@param string $result the name of the file to be generated by the converter command
@return boolean true on success, false on failure. Failures will be logged.
@throws Less_Exception_Parser when the command fails


public function send( $message, array $options = [] ) {
		$options[Options::TOKEN]   = $this->token;
		$options[Options::USER]    = $this->user;
		$options[Options::MESSAGE] = $message;

		$opts = [ 'http' => [
			'method'  => 'POST',
			'header'  => 'Content-Type: application/x-www-form-urlencoded',
			'content' => http_build_query($options),
		] ];

		$context = stream_context_create($opts);

		if( $result = @file_get_contents($this->apiUrl, false, $context) ) {
			if( $final = @json_decode($result, true) ) {
				return $final;
			}
		}

		return false;
	}

Send the pushover message

@see    https://pushover.net/api

@param  string $message The message to send
@param  array  $options Optional configuration settings
@return bool|array       Returns false on failure, or a data array on success


final public function get(array $query, array $options = []) : array
    {
        $completeQuery = $this->buildPayloadQuery(
            ['earliestGet' => ['$lte' => new UTCDateTime((int)(microtime(true) * 1000))]],
            $query
        );

        $options += self::DEFAULT_GET_OPTIONS;
        $update = ['$set' => ['earliestGet' => $this->calculateEarliestGet($options['runningResetDuration'])]];
        $end = $this->calculateEndTime($options['waitDurationInMillis']);
        $sleepTime = $this->calculateSleepTime($options['pollDurationInMillis']);
        $messages = new ArrayObject();
        while (count($messages) < $options['maxNumberOfMessages']) {
            if ($this->tryFindOneAndUpdate($completeQuery, $update, $messages)) {
                continue;
            }

            if (microtime(true) < $end) {
                usleep($sleepTime);
            }

            break;
        }

        return $messages->getArrayCopy();
    }

final public function get ( array $ query , array $ options = [ ] ) : array { $ completeQuery = $ this -> buildPayloadQuery ( [ 'earliestGet' => [ '$lte' => new UTCDateTime ( ( int ) ( microtime ( true ) * 1000 ) ) ] ] , $ query ) ; $ options += self :: DEFAULT_GET_OPTIONS ; $ update = [ '$set' => [ 'earliestGet' => $ this -> calculateEarliestGet ( $ options [ 'runningResetDuration' ] ) ] ] ; $ end = $ this -> calculateEndTime ( $ options [ 'waitDurationInMillis' ] ) ; $ sleepTime = $ this -> calculateSleepTime ( $ options [ 'pollDurationInMillis' ] ) ; $ messages = new ArrayObject ( ) ; while ( count ( $ messages ) < $ options [ 'maxNumberOfMessages' ] ) { if ( $ this -> tryFindOneAndUpdate ( $ completeQuery , $ update , $ messages ) ) { continue ; } if ( microtime ( true ) < $ end ) { usleep ( $ sleepTime ) ; } break ; } return $ messages -> getArrayCopy ( ) ; }

Get a non running message from the queue.

@param array $query in same format as \MongoDB\Collection::find() where top level fields do not contain
operators. Lower level fields can however. eg: valid {a: {$gt: 1}, "b.c": 3},
invalid {$and: [{...}, {...}]}
@param array $options Associative array of get options.
runningResetDuration => integer
The duration (in miiliseconds) that the received messages are hidden from
subsequent retrieve requests after being retrieved by a get() request.
waitDurationInMillis => integer
The duration (in milliseconds) for which the call will wait for a message to
arrive in the queue before returning. If a message is available, the call will
return sooner than WaitTimeSeconds.
pollDurationInMillis => integer
The millisecond duration to wait between polls.
maxNumberOfMessages => integer
The maximum number of messages to return with get(). All of the messages are not
necessarily returned.

@return array Array of messages.

@throws \InvalidArgumentException key in $query was not a string

Get a non running message from the queue .


final public function count(array $query, bool $running = null) : int
    {
        $totalQuery = [];

        if ($running === true || $running === false) {
            $key = $running ? '$gt' : '$lte';
            $totalQuery['earliestGet'] = [$key => new UTCDateTime((int)(microtime(true) * 1000))];
        }

        return $this->collection->count($this->buildPayloadQuery($totalQuery, $query));
    }

final public function count ( array $ query , bool $ running = null ) : int { $ totalQuery = [ ] ; if ( $ running === true || $ running === false ) { $ key = $ running ? '$gt' : '$lte' ; $ totalQuery [ 'earliestGet' ] = [ $ key => new UTCDateTime ( ( int ) ( microtime ( true ) * 1000 ) ) ] ; } return $ this -> collection -> count ( $ this -> buildPayloadQuery ( $ totalQuery , $ query ) ) ; }

Count queue messages.

@param array $query in same format as \MongoDB\Collection::find() where top level fields do not contain
operators. Lower level fields can however. eg: valid {a: {$gt: 1}, "b.c": 3},
invalid {$and: [{...}, {...}]}
@param bool|null $running query a running message or not or all

@return int the count

@throws \InvalidArgumentException key in $query was not a string


final public function requeue(Message $message)
    {
        $set = [
            'payload' => $message->getPayload(),
            'earliestGet' => $message->getEarliestGet(),
            'priority' => $message->getPriority(),
            'created' => new UTCDateTime(),
        ];

        $this->collection->updateOne(['_id' => $message->getId()], ['$set' => $set], ['upsert' => true]);
    }

final public function requeue ( Message $ message ) { $ set = [ 'payload' => $ message -> getPayload ( ) , 'earliestGet' => $ message -> getEarliestGet ( ) , 'priority' => $ message -> getPriority ( ) , 'created' => new UTCDateTime ( ) , ] ; $ this -> collection -> updateOne ( [ '_id' => $ message -> getId ( ) ] , [ '$set' => $ set ] , [ 'upsert' => true ] ) ; }

Atomically acknowledge and send a message to the queue.

@param Message $message message received from get().

@return void

Atomically acknowledge and send a message to the queue .


final public function send(Message $message)
    {
        $document = [
            '_id' => $message->getId(),
            'payload' => $message->getPayload(),
            'earliestGet' => $message->getEarliestGet(),
            'priority' => $message->getPriority(),
            'created' => new UTCDateTime(),
        ];

        $this->collection->insertOne($document);
    }

final public function send ( Message $ message ) { $ document = [ '_id' => $ message -> getId ( ) , 'payload' => $ message -> getPayload ( ) , 'earliestGet' => $ message -> getEarliestGet ( ) , 'priority' => $ message -> getPriority ( ) , 'created' => new UTCDateTime ( ) , ] ; $ this -> collection -> insertOne ( $ document ) ; }

Send a message to the queue.

@param Message $message The message to send.

@return void


final private function verifySort(array $sort, string $label, array &$completeFields)
    {
        foreach ($sort as $key => $value) {
            $this->throwIfTrue(!is_string($key), "key in \${$label} was not a string");
            $this->throwIfTrue(
                $value !== 1 && $value !== -1,
                "value of \${$label} is not 1 or -1 for ascending and descending"
            );

            $completeFields["payload.{$key}"] = $value;
        }
    }

Helper method to validate keys and values for the given sort array

@param array  $sort             The proposed sort for a mongo index.
@param string $label            The name of the variable given to the public ensureXIndex method.
@param array  &$completedFields The final index array with payload. prefix added to fields.

@return void


public function add(string $type, string $message)
    {
        $this->messages($type)->add($message);
    }

public function add ( string $ type , string $ message ) { $ this -> messages ( $ type ) -> add ( $ message ) ; }

Short cut to append a message string into the message collection
@param string $type
@param string $message
@return void


public function messages(string $type)
    {
        if ('' === $type) {
            throw new \InvalidArgumentException('The type of messages must be a non-empty string');
        }
        if (! array_key_exists($type, $this->messages)) {
            $this->messages[$type] = new Messages();
        }
        return $this->messages[$type];
    }

Return a message collection of the selected type
If the type does not exists the object is created
@param string $type
@return Messages


public function import(self $issues)
    {
        foreach ($issues->types() as $type) {
            $source = $issues->messages($type);
            $destination = $this->messages($type);
            foreach ($source as $message) {
                $destination->add($message);
            }
        }
    }

public function import ( self $ issues ) { foreach ( $ issues -> types ( ) as $ type ) { $ source = $ issues -> messages ( $ type ) ; $ destination = $ this -> messages ( $ type ) ; foreach ( $ source as $ message ) { $ destination -> add ( $ message ) ; } } }

Copy all messages from source to this object
@param Issues $issues
@return void


public function offsetGet($id)
    {
        if ($this->hasAlias($id)) {
            $id = $this->getAlias($id);
        }

        if (!$this->has($id) && class_exists($id)) {
            return $this->build($id);
        }

        if (!isset($this->keys[$id])) {
            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
        }

        if (
            isset($this->raw[$id])
            || !is_object($this->values[$id])
            || isset($this->protected[$this->values[$id]])
            || !method_exists($this->values[$id], '__invoke')
        ) {
            return $this->values[$id];
        }

        if (isset($this->factories[$this->values[$id]])) {
            return $this->values[$id]($this);
        }

        $raw = $this->values[$id];
        $val = $this->values[$id] = $raw($this);
        $this->raw[$id] = $raw;

        $this->frozen[$id] = true;

        return $val;
    }

public
function
offsetGet
(
$
id
)
{
if
(
$
this
->
hasAlias
(
$
id
)
)
{
$
id
=
$
this
->
getAlias
(
$
id
)
;
}
if
(
!
$
this
->
has
(
$
id
)
&&
class_exists
(
$
id
)
)
{
return
$
this
->
build
(
$
id
)
;
}
if
(
!
isset
(
$
this
->
keys
[
$
id
]
)
)
{
throw
new
\
InvalidArgumentException
(
sprintf
(
'Identifier "%s" is not defined.'
,
$
id
)
)
;
}
if
(
isset
(
$
this
->
raw
[
$
id
]
)
||
!
is_object
(
$
this
->
values
[
$
id
]
)
||
isset
(
$
this
->
protected
[
$
this
->
values
[
$
id
]
]
)
||
!
method_exists
(
$
this
->
values
[
$
id
]
,
'__invoke'
)
)
{
return
$
this
->
values
[
$
id
]
;
}
if
(
isset
(
$
this
->
factories
[
$
this
->
values
[
$
id
]
]
)
)
{
return
$
this
->
values
[
$
id
]
(
$
this
)
;
}
$
raw
=
$
this
->
values
[
$
id
]
;
$
val
=
$
this
->
values
[
$
id
]
=
$
raw
(
$
this
)
;
$
this
->
raw
[
$
id
]
=
$
raw
;
$
this
->
frozen
[
$
id
]
=
true
;
return
$
val
;
}

Gets a parameter or an object.

@param string $id The unique identifier for the parameter or object

@return mixed The value of the parameter or an object

@throws \InvalidArgumentException if the identifier is not defined


public function offsetExists($id)
    {
        if ($this->hasAlias($id)) {
            $id = $this->getAlias($id);
        }

        return isset($this->keys[$id]);
    }

public function offsetExists ( $ id ) { if ( $ this -> hasAlias ( $ id ) ) { $ id = $ this -> getAlias ( $ id ) ; } return isset ( $ this -> keys [ $ id ] ) ; }

Checks if a parameter or an object is set.

@param string $id The unique identifier for the parameter or object

@return bool

Checks if a parameter or an object is set .


public function extend($id, $callable)
    {
        if ( ! isset($this->keys[$id])) {
            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
        }

        if ( ! is_object($this->values[$id]) || ! method_exists($this->values[$id], '__invoke')) {
            throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
        }

        if ( ! is_object($callable) || ! method_exists($callable, '__invoke')) {
            throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
        }

        $factory = $this->values[$id];

        $extended = function ($c) use ($callable, $factory) {
            /** @var \Closure|string $callable */
            return $callable($factory($c), $c);
        };

        if (isset($this->factories[$factory])) {
            $this->factories->detach($factory);
            $this->factories->attach($extended);
        }

        return $this[$id] = $extended;
    }

Extends an object definition.

Useful when you want to extend an existing object definition,
without necessarily loading that object.

@param string   $id       The unique identifier for the object
@param callable $callable A service definition to extend the original

@return callable The wrapped callable

@throws \InvalidArgumentException if the identifier is not defined or not a service definition


public function register(ServiceProviderInterface $provider, array $values = [])
    {
        $provider->register($this);

        foreach ($values as $key => $value) {
            $this[$key] = $value;
        }

        return $this;
    }

public function register ( ServiceProviderInterface $ provider , array $ values = [ ] ) { $ provider -> register ( $ this ) ; foreach ( $ values as $ key => $ value ) { $ this [ $ key ] = $ value ; } return $ this ; }

Registers a service provider.

@param ServiceProviderInterface $provider A ServiceProviderInterface instance
@param array                    $values   An array of values that customizes the provider

@return static


public function tag($id, $tag)
    {
        if ( ! isset($this->serviceTags[$id])) {
            $this->serviceTags[$id] = [];
        }

        $this->serviceTags[$id][] = $tag;
        return $this;
    }

public function tag ( $ id , $ tag ) { if ( ! isset ( $ this -> serviceTags [ $ id ] ) ) { $ this -> serviceTags [ $ id ] = [ ] ; } $ this -> serviceTags [ $ id ] [ ] = $ tag ; return $ this ; }

Tag a service

@param string $id
@param string $tag
@return $this


public function findTaggedServiceIds($tag)
    {
        $ids = [];

        foreach ($this->serviceTags as $id => $tags) {
            if (in_array($tag, $tags)) {
                $ids[] = $id;
            }
        }

        return $ids;
    }

public function findTaggedServiceIds ( $ tag ) { $ ids = [ ] ; foreach ( $ this -> serviceTags as $ id => $ tags ) { if ( in_array ( $ tag , $ tags ) ) { $ ids [ ] = $ id ; } } return $ ids ; }

Find all service ids with a given tag

@param string $tag
@return array


public function boot()
    {
        if (true === $this->booted) {
            return;
        }

        // init container
        $this->initializeContainer();

        // init bundles
        $this->initializeBundles();

        foreach ($this->getBundles() as $bundle) {
            if ($bundle instanceof ContainerAwareInterface) {
                $bundle->setContainer($this->container);
            }

            $bundle->boot();
        }

        $this->booted = true;

        // Load routes from bundles
        $this->loadRoutes();

        // Register events from Bundles
        $this->registerEvents();
    }

public
function
boot
(
)
{
if
(
true
===
$
this
->
booted
)
{
return
;
}
// init container
$
this
->
initializeContainer
(
)
;
// init bundles
$
this
->
initializeBundles
(
)
;
foreach
(
$
this
->
getBundles
(
)
as
$
bundle
)
{
if
(
$
bundle
instanceof
ContainerAwareInterface
)
{
$
bundle
->
setContainer
(
$
this
->
container
)
;
}
$
bundle
->
boot
(
)
;
}
$
this
->
booted
=
true
;
// Load routes from bundles
$
this
->
loadRoutes
(
)
;
// Register events from Bundles
$
this
->
registerEvents
(
)
;
}


protected function initializeBundles()
    {
        // init bundles
        $this->bundles = array();
        $topMostBundles = array();
        $directChildren = array();

        foreach ($this->registerBundles() as $bundle) {
            $name = $bundle->getName();
            if (isset($this->bundles[$name])) {
                throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name));
            }
            $this->bundles[$name] = $bundle;

            if ($parentName = $bundle->getParent()) {
                if (isset($directChildren[$parentName])) {
                    throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName]));
                }
                if ($parentName == $name) {
                    throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name));
                }
                $directChildren[$parentName] = $name;
            } else {
                $topMostBundles[$name] = $bundle;
            }
        }

        // look for orphans
        if (!empty($directChildren) && count($diff = array_diff_key($directChildren, $this->bundles))) {
            $diff = array_keys($diff);

            throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0]));
        }

        // inheritance
        $this->bundleMap = array();
        foreach ($topMostBundles as $name => $bundle) {
            $bundleMap = array($bundle);
            $hierarchy = array($name);

            while (isset($directChildren[$name])) {
                $name = $directChildren[$name];
                array_unshift($bundleMap, $this->bundles[$name]);
                $hierarchy[] = $name;
            }

            foreach ($hierarchy as $bundle) {
                $this->bundleMap[$bundle] = $bundleMap;
                array_pop($bundleMap);
            }
        }

    }

Initializes the data structures related to the bundle management.

- the bundles property maps a bundle name to the bundle instance,
- the bundleMap property maps a bundle name to the bundle inheritance hierarchy (most derived bundle first).

@throws \LogicException if two bundles share a common name
@throws \LogicException if a bundle tries to extend a non-registered bundle
@throws \LogicException if a bundle tries to extend itself
@throws \LogicException if two bundles extend the same ancestor

Initializes the data structures related to the bundle management .


protected function getKernelParameters()
    {
        $bundles = array();
        foreach ($this->bundles as $name => $bundle) {
            $bundles[$name] = get_class($bundle);
        }

        return array_merge(
            array(
                'kernel.root_dir'        => $this->rootDir,
                'kernel.environment'     => $this->environment,
                'kernel.debug'           => $this->debug,
                'kernel.name'            => $this->name,
                'kernel.cache_dir'       => $this->getCacheDir(),
                'kernel.logs_dir'        => $this->getLogDir(),
                'kernel.bundles'         => $bundles,
                'kernel.charset'         => $this->getCharset()
            ),
            $this->getEnvParameters()
        );
    }

protected function getKernelParameters ( ) { $ bundles = array ( ) ; foreach ( $ this -> bundles as $ name => $ bundle ) { $ bundles [ $ name ] = get_class ( $ bundle ) ; } return array_merge ( array ( 'kernel.root_dir' => $ this -> rootDir , 'kernel.environment' => $ this -> environment , 'kernel.debug' => $ this -> debug , 'kernel.name' => $ this -> name , 'kernel.cache_dir' => $ this -> getCacheDir ( ) , 'kernel.logs_dir' => $ this -> getLogDir ( ) , 'kernel.bundles' => $ bundles , 'kernel.charset' => $ this -> getCharset ( ) ) , $ this -> getEnvParameters ( ) ) ; }

Returns the kernel parameters.

@return array An array of kernel parameters


public function validate(string $content)
    {
        if ($this->hasRetriever()) {
            $this->validateWithRetriever($content);
        } else {
            $this->validateWithoutRetriever($content);
        }
    }

public function validate ( string $ content ) { if ( $ this -> hasRetriever ( ) ) { $ this -> validateWithRetriever ( $ content ) ; } else { $ this -> validateWithoutRetriever ( $ content ) ; } }

Validate according to the current retriever.
If retriever is set then it will use validateWithRetriever,
otherwise it will use validateWithoutRetriever.

@see validateWithRetriever
@see validateWithoutRetriever

@param string $content
@throws \RuntimeException on validation errors

Validate according to the current retriever . If retriever is set then it will use validateWithRetriever otherwise it will use validateWithoutRetriever .


public function validateWithRetriever(string $content)
    {
        // obtain the retriever, throw its own exception if non set
        $retriever = $this->getRetriever();
        // create the schema validator object
        $validator = new SchemaValidator($content);
        // obtain the list of schemas
        $schemas = $validator->buildSchemas();
        // replace with the local path
        foreach ($schemas as $schema) {
            /** @var \XmlSchemaValidator\Schema $schema */
            $location = $schema->getLocation();
            $localPath = $retriever->buildPath($location);
            if (! file_exists($localPath)) {
                $retriever->retrieve($location);
            }
            $schemas->create($schema->getNamespace(), $localPath);
        }
        // validate using the modified schemas
        $validator->validateWithSchemas($schemas);
    }

Validate changing the namespaces locations to local resources and downloading them
if they does not exists

@param string $content
@throws \RuntimeException on validation errors


public function validateWithoutRetriever($content)
    {
        // create the schema validator object
        $validator = new SchemaValidator($content);
        if (! $validator->validate()) {
            throw new \RuntimeException('XSD error found: ' . $validator->getLastError());
        }
    }

public
function
validateWithoutRetriever
(
$
content
)
{
// create the schema validator object
$
validator
=
new
SchemaValidator
(
$
content
)
;
if
(
!
$
validator
->
validate
(
)
)
{
throw
new
\
RuntimeException
(
'XSD error found: '
.
$
validator
->
getLastError
(
)
)
;
}
}

Validate just using the SchemaValidator, it will not retrieve any resource
and perform all validations using internet

@param string $content
@throws \RuntimeException on validation errors

Validate just using the SchemaValidator it will not retrieve any resource and perform all validations using internet


public function container($name = 'default')
    {
        if (isset($this->containers[$name])) {
            return $this->containers[$name];
        }

        return $this->containers[$name] = new AssetContainer($name);
    }

public function container ( $ name = 'default' ) { if ( isset ( $ this -> containers [ $ name ] ) ) { return $ this -> containers [ $ name ] ; } return $ this -> containers [ $ name ] = new AssetContainer ( $ name ) ; }

Get container, if it doesn't exist create it

@param string $name
@return AssetContainer

Get container if it doesn t exist create it


public function outputJs($container = 'default')
    {
        $assets = $this->getAssets($container, 'js');

        $html = [];

        foreach ($assets as $asset) {
            $source = $this->url ? $this->url->asset($asset['source']): $asset['source'];
            $html[] = $this->html->script($source, $asset['attributes']);
        }

        return trim(implode(PHP_EOL, $html));
    }

public function outputJs ( $ container = 'default' ) { $ assets = $ this -> getAssets ( $ container , 'js' ) ; $ html = [ ] ; foreach ( $ assets as $ asset ) { $ source = $ this -> url ? $ this -> url -> asset ( $ asset [ 'source' ] ) : $ asset [ 'source' ] ; $ html [ ] = $ this -> html -> script ( $ source , $ asset [ 'attributes' ] ) ; } return trim ( implode ( PHP_EOL , $ html ) ) ; }

Output a JS asset from the container

@param string $container
@return string


public function outputCss($container = 'default')
    {
        $assets = $this->getAssets($container, 'css');

        $html = [];

        foreach ($assets as $asset) {
            $source = $this->url ? $this->url->asset($asset['source']): $asset['source'];
            $html[] = $this->html->style($source, $asset['attributes']);
        }

        return trim(implode(PHP_EOL, $html));
    }

public function outputCss ( $ container = 'default' ) { $ assets = $ this -> getAssets ( $ container , 'css' ) ; $ html = [ ] ; foreach ( $ assets as $ asset ) { $ source = $ this -> url ? $ this -> url -> asset ( $ asset [ 'source' ] ) : $ asset [ 'source' ] ; $ html [ ] = $ this -> html -> style ( $ source , $ asset [ 'attributes' ] ) ; } return trim ( implode ( PHP_EOL , $ html ) ) ; }

Output a CSS asset from the container

@param string $container
@return string


protected function getAssets($container, $type)
    {
        if ( ! isset($this->containers[$container])) {
            return [];
        }

        $container = $this->containers[$container];

        if ( ! isset($container->assets[$type]) || 0 === count($container->assets[$type])) {
            return [];
        }

        $assets = $container->assets[$type];

        $assets = $this->arrange($assets);

        return $assets;
    }

protected function getAssets ( $ container , $ type ) { if ( ! isset ( $ this -> containers [ $ container ] ) ) { return [ ] ; } $ container = $ this -> containers [ $ container ] ; if ( ! isset ( $ container -> assets [ $ type ] ) || 0 === count ( $ container -> assets [ $ type ] ) ) { return [ ] ; } $ assets = $ container -> assets [ $ type ] ; $ assets = $ this -> arrange ( $ assets ) ; return $ assets ; }

Get all assets of a given type from a given container

@param $container
@param $type
@return array


protected function arrange(array $assets)
    {
        list($original, $sorted) = array($assets, []);

        while (count($assets) > 0) {
            foreach ($assets as $asset => $value) {
                $this->evaluateAsset($asset, $value, $original, $sorted, $assets);
            }
        }

        return $sorted;
    }

protected function arrange ( array $ assets ) { list ( $ original , $ sorted ) = array ( $ assets , [ ] ) ; while ( count ( $ assets ) > 0 ) { foreach ( $ assets as $ asset => $ value ) { $ this -> evaluateAsset ( $ asset , $ value , $ original , $ sorted , $ assets ) ; } } return $ sorted ; }

Sort and retrieve assets based on their dependencies

@param   array  $assets
@return  array


protected function dependencyIsValid($asset, $dependency, $original, $assets)
    {
        if ( ! isset($original[$dependency])) {
            return false;
        }
        else if ($dependency === $asset) {
            throw new SelfDependencyException(sprintf('Asset "%" is dependent on itself.', $asset));
        }
        else if (isset($assets[$dependency]) && in_array($asset, $assets[$dependency]['dependencies'])) {
            throw new CircularDependencyException(sprintf('Assets "%s" and "%s" have a circular dependency.', $asset, $dependency));
        }

        return true;
    }

Verify that an asset's dependency is valid.

A dependency is considered valid if it exists, is not a circular reference, and is
not a reference to the owning asset itself. If the dependency doesn't exist, no
error or warning will be given. For the other cases, an exception is thrown.

@param  string $asset
@param  string $dependency
@param  array $original
@param  array $assets
@throws SelfDependencyException
@throws CircularDependencyException
@return bool

Verify that an asset s dependency is valid .


public function newPostValidator(): PostValidator
    {
        $postvalidator = new PostValidator();
        $postvalidator->validators->append(new Validators\TFDVersions());
        $postvalidator->validators->append(new Validators\Impuestos());
        $postvalidator->validators->append(new Validators\Fechas());
        $postvalidator->validators->append(new Validators\Conceptos());
        $postvalidator->validators->append(new Validators\Totales());
        $postvalidator->validators->append($this->newCertificadoValidator());
        return $postvalidator;
    }

public function newPostValidator ( ) : PostValidator { $ postvalidator = new PostValidator ( ) ; $ postvalidator -> validators -> append ( new Validators \ TFDVersions ( ) ) ; $ postvalidator -> validators -> append ( new Validators \ Impuestos ( ) ) ; $ postvalidator -> validators -> append ( new Validators \ Fechas ( ) ) ; $ postvalidator -> validators -> append ( new Validators \ Conceptos ( ) ) ; $ postvalidator -> validators -> append ( new Validators \ Totales ( ) ) ; $ postvalidator -> validators -> append ( $ this -> newCertificadoValidator ( ) ) ; return $ postvalidator ; }

Return an object with default validators included in the PostValidator object

@return PostValidator


public function newRetriever(DownloaderInterface $downloader = null)
    {
        $localResourcesPath = $this->getLocalResourcesPath();
        if ('' === $localResourcesPath) {
            return null;
        }
        return new XsdRetriever($localResourcesPath, $downloader);
    }

public function newRetriever ( DownloaderInterface $ downloader = null ) { $ localResourcesPath = $ this -> getLocalResourcesPath ( ) ; if ( '' === $ localResourcesPath ) { return null ; } return new XsdRetriever ( $ localResourcesPath , $ downloader ) ; }

Return a new instance of an XsdRetriever depending on the
property localResourcesPath.

@param DownloaderInterface|null $downloader
@return null|XsdRetriever

Return a new instance of an XsdRetriever depending on the property localResourcesPath .


public function newXsltRetriever(DownloaderInterface $downloader = null)
    {
        $localResourcesPath = $this->getLocalResourcesPath();
        if ('' === $localResourcesPath) {
            return null;
        }
        return new XsltRetriever($localResourcesPath, $downloader);
    }

public function newXsltRetriever ( DownloaderInterface $ downloader = null ) { $ localResourcesPath = $ this -> getLocalResourcesPath ( ) ; if ( '' === $ localResourcesPath ) { return null ; } return new XsltRetriever ( $ localResourcesPath , $ downloader ) ; }

Return a new instance of an XsltRetriever depending on the
property localResourcesPath.

@param DownloaderInterface|null $downloader
@return null|XsltRetriever

Return a new instance of an XsltRetriever depending on the property localResourcesPath .


public function newCertificadoValidator(): CertificadoValidator
    {
        $validator = new CertificadoValidator();
        $validator->setCadenaOrigen($this->newCadenaOrigen());
        $validator->setXsltRetriever($this->newXsltRetriever());
        return $validator;
    }

public function newCertificadoValidator ( ) : CertificadoValidator { $ validator = new CertificadoValidator ( ) ; $ validator -> setCadenaOrigen ( $ this -> newCadenaOrigen ( ) ) ; $ validator -> setXsltRetriever ( $ this -> newXsltRetriever ( ) ) ; return $ validator ; }

Return a CertificadoValidator with the CadenaOrigen property set
to the value of the newCadenaOrigen method

@return CertificadoValidator