Position: Positioning object one relative to the others

A record is marked as being positionable if its model define a property "position" in its table definition. A new property "position" is made available to the record with a couple of usefull methods.

Available methods

The position plugin will add a position property to each records marked as positionable (where the model is defined with a "position" property). The "position" property give access to a set of methods used to position the current record relative to other records of the same type.

Exemple

The following exemple illustrace how to define a positionable model (using the class model definition). It also show the usage of the "getPosition", "first" and "after" methods.

class User extends PorteRecord{
	public $config = array(
		'position'
	);
}

$porte->users->update(array('drop'=>true));
$user1 = new User();
$user2 = new User();
$user3 = new User();

// Fields created in Users databse table
assert( array('id','position') === array_keys($porte->users->fields()) );

// Assert user positions
assert( 1 === $user1->save()->getPosition() );
assert( 2 === $user2->save()->getPosition() );
assert( 3 === $user3->save()->getPosition() );

// Move 3rd user at first position
$user3->position->first();
$user3->save();

// Assert user positions
assert( 2 === $user1->getPosition() );
assert( 3 === $user2->getPosition() );
assert( 1 === $user3->getPosition() );

// Move back 3rd user at last position by placing it after 2nd user
$user3->position->after($user2);
$user3->save();

// Assert user positions
assert( 1 === $user1->getPosition() );
assert( 2 === $user2->getPosition() );
assert( 3 === $user3->getPosition() );

Configuration

A record is marked as positionable if its meta_table property contains a key "position". You can set options if the value of the key "position" is an array.

class User extends PorteRecord{
	public $config = array(
		'position'
	);
}

$user = new User();
$user->table->update(array('drop'=>true));
$user->save();

// User position is expected to be first
assert(
	1 === $user->getPosition()
);

class File extends PorteRecord{
	public $config = array(
		'position' => array(
			'property' => 'my_position'
		)
	);
}

$file = new File();
$file->table->update(array('drop'=>true));
$file->save();

// File position is expected to be first
assert(
	1 === $file->getMyPosition()
);

Understanding the internal

The "position" services use the "event" system to plug required database organisation when the current record is saved.

If calling the "reset" or "reload" methods, the "position" action will be canceled.