creatoro/jelly — Issue #95: Paranoid behavior and Jelly_builder
Author: ivank
Created: 2011-11-02 09:05:16+00:00
State: open

I'm trying to implement paranoid behavior and I have this problem - I've added an event listener for "builder.before_select" that adds an "is_deleted" where clause, but I have a builder_call_deleted() method that modifies that clause so you can do $builder->desleted("all")->select_all() to get all the records including the deleted ones. The problem is I cannot keep state between the method call and the event Jelly_Builder doesn't provide any arbitrary attributes for this, and I can't read if the builder has set a where for "is_deleted" or not.

So this would be solved if
- somebody has already developed a paranoid behavior
- I can save state in the behavior for each builder
- I can read the current state of the builder from outside the builder class

Here's the current implementation (but it does not work) as I cannot set "_select_deleted" on the Jelly_Builder

```php
field = Arr::get($params, 'field', 'is_deleted');
}

public function initialize(Jelly_Event $event, $model, $name)
{
parent::initialize($event, $model, $name);

Jelly::meta($model)
->field($this->field, Jelly::field('boolean', array('default' => false)));

$event->bind('builder.before_select', array($this, 'before_select'));
$event->bind('model.before_delete', array($this, 'before_delete'));
}

public function before_select(Jelly_Builder $builder, Jelly_Event_Data $data)
{
switch($builder->_select_deleted)
{
case Jelly_Behavior_Paranoid::ALL:
break;

case Jelly_Behavior_Paranoid::DELETED:
$builder->where($this->field, '=', true);
break;

case Jelly_Behavior_Paranoid::NORMAL:
default:
$builder->where($this->field, '=', false);
break;
}
}

public function builder_call_deleted(Jelly_Builder $builder, $type, Jelly_Event_Data $data)
{
if( ! in_array($type, array(Jelly_Behavior_Paranoid::DELETED, Jelly_Behavior_Paranoid::NORMAL, Jelly_Behavior_Paranoid::ALL)))
throw new Kohana_Exception("Deleted type should be Jelly_Behavior_Paranoid::DELETED, Jelly_Behavior_Paranoid::NORMAL or Jelly_Behavior_Paranoid::ALL");

$builder->_select_deleted = $type;
$data->return = $builder;
}

public function before_delete(Jelly_Model $model, Jelly_Event_Data $data)
{
if( ! $model->real_delete)
{
$data->stop = TRUE;
$model->set($this->field, TRUE)->save();
$data->return = false;
}
}

public function model_call_real_delete(Jelly_Model $model, Jelly_Event_Data $data)
{
$model->real_delete = true;
$data->stop = TRUE;
$data->return = $model->delete();
}
}
```