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.
- after
Place the current record after the provided record. Changes will take effect after calling the "save" method.$recordA->position->after($recordB)->save(); - before
Place the current record before the provided record. Changes will take effect after calling the "save" method.$recordA->position->before($recordB)->save(); - first
Place the current record af the first record. Its position value will be set to 1. Changes will take effect after calling the "save" method.$recordA->position->first()->save(); - last
Place the current record af the last record. Its position value should be equal to the value returned by the "count" method. Changes will take effect after calling the "save" method.$recordA->position->last()->save(); - Method "previous"
Place the current record one or more step before. Changes will take effect after calling the "save" method.$recordA->position->previous()->save(); $recordA->position->previous(2)->save(); - next
Place the current record one or more step forward. Changes will take effect after calling the "save" method.$recordA->position->next()->save(); $recordA->position->next(2)->save(); - max
Return the greatest position value. It is equals to the value returned by the "count" method of the record.$recordA->position->max(); - current
Return the current position value.$recordA->position->current(); - get{PositionField}
Return the same value as the method "current". By default, Porte use a property "position" so the available method is "getPosition".$recordA->getPosition(); $recordA->position->getPosition();
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.