$data, 'model'=>$model, 'name'=>$name, 'alias'=>$alias ]); } protected function __construct(array $data){ parent::__construct($data['data']); $this->model = $data['model']; $this->name = $data['name']; $this->alias = $data['alias']; if(isset($this->alias['through'])){ $this->table = $this->model->pdo->table($this->alias['through']); } $self = $this; $this ->on('set', function(&$offset, &$value) use($self){ $self->added = array_merge($self->added, [$value]); $self->removed = array_diff($self->removed, [$value]); })->on('unset', function($offset, $value) use($self){ $self->removed = array_merge($self->removed, [$value]); $self->added = array_diff($self->added, [$value]); }); } public function add(ORM $model){ $this[$model->id] = $model; return $this; } public function remove(ORM $model){ $index = $this->index($model); if($index !== false){ unset($this->data[$index]); } return $this; } public function has(ORM $model){ return $this->index($model) !== false; } public function index(ORM $model){ return array_search($model, $this->data); } public function dirty(){ return count($this->removed) + count($this->added) > 0; } public function reset(){ foreach($this->added as $model){ $index = array_search($model, $this->data); if($index !== false){ unset($this->data[$index]); } } $this->added = []; foreach($this->removed as $model){ $this->data = array_merge($this->data, [$model]); } $this->removed = []; } public function save(){ if($this->dirty()){ $model = $this->model; $alias = $this->alias; $name = $this->name; $class = "\\Models\\{$alias['model']}"; if(!isset($model->has_many[$name])){ throw new \Exception("Invalid relationship {$name}"); } $rem_args = []; if(isset($alias['through'])){ $key = $class::table_name().$class::foreign_key_suffix(); $filter = [ $alias['foreign_key']=> $model->id ]; foreach($this->removed as $item){ $filter[$key] = $item->id; $this->table->delete($filter); } foreach($this->added as $item){ $filter[$key] = $item->id; $this->table->insert($filter); } }else{ $table = $model->pdo->table($alias['model']); $key = $class::primary_key(); $data = [ $alias['foreign_key']=> null ]; foreach($this->removed as $item){ $table->update($data, [ $key=> $item->id ]); } $data = [ $alias['foreign_key']=> $model->id ]; foreach($this->added as $item){ $table->update($data, [ $key=> $item->id ]); } } $this->removed = []; $this->added = []; } } public function offsetSet($offset, $value){ $this->fire('set', $value->id, $value); $this->data[$value->id] = $value; } public function filter(array $filter){ $items = []; foreach($this->data as $item){ $item->load(); foreach($filter as $key => $value){ $val = $item[$key]; if($val !== $value){ unset($item); break; } } if(isset($item)){ $items[$item->id] = $item; } } unset($item); return $items; } } ?>