_a['table'] = 'idf_gconf'; $this->_a['model'] = __CLASS__; $this->_a['cols'] = array( // It is mandatory to have an "id" column. 'id' => array( 'type' => 'Pluf_DB_Field_Sequence', //It is automatically added. 'blank' => true, ), 'model_class' => array( 'type' => 'Pluf_DB_Field_Varchar', 'blank' => false, 'size' => 150, 'verbose' => __('model class'), ), 'model_id' => array( 'type' => 'Pluf_DB_Field_Integer', 'blank' => false, 'verbose' => __('model id'), ), 'vkey' => array( 'type' => 'Pluf_DB_Field_Varchar', 'blank' => false, 'size' => 50, 'verbose' => __('key'), ), 'vdesc' => array( 'type' => 'Pluf_DB_Field_Text', 'blank' => false, 'verbose' => __('value'), ), ); $this->_a['idx'] = array('model_vkey_idx' => array( 'col' => 'model_class, model_id, vkey', 'type' => 'unique', ), ); $this->f = new IDF_Config_DataProxy($this); } function setModel($model) { $this->datacache = null; $this->_mod = $model; } function initCache() { $this->datacache = array(); $this->dirty = array(); $sql = new Pluf_SQL('model_class=%s AND model_id=%s', array($this->_mod->_model, $this->_mod->id)); foreach ($this->getList(array('filter' => $sql->gen())) as $val) { $this->datacache[$val->vkey] = ($this->serialize) ? unserialize($val->vdesc) : $val->vdesc; $this->dirty[$val->vkey] = $val->id; } } /** * FIXME: This is not efficient when setting a large number of * values in a loop. */ function setVal($key, $value) { if (!is_null($this->getVal($key, null)) and $value == $this->getVal($key)) { return; } $svalue = ($this->serialize) ? serialize($value) : $value; if (isset($this->dirty[$key])) { // we get to check if deleted by other process + update $conf = new IDF_Gconf($this->dirty[$key]); if ($conf->id == $this->dirty[$key]) { $conf->vdesc = $svalue; $conf->update(); $this->datacache[$key] = $value; return; } } // we insert $conf = new IDF_Gconf(); $conf->model_class = $this->_mod->_model; $conf->model_id = $this->_mod->id; $conf->vkey = $key; $conf->vdesc = $svalue; $conf->create(); $this->datacache[$key] = $value; $this->dirty[$key] = $conf->id; } function getVal($key, $default='') { if ($this->datacache === null) { $this->initCache(); } return (isset($this->datacache[$key])) ? $this->datacache[$key] : $default; } function delVal($key, $initcache=true) { $gconf = new IDF_Gconf(); $sql = new Pluf_SQL('vkey=%s AND model_class=%s AND model_id=%s', array($key, $this->_mod->_model, $this->_mod->id)); foreach ($gconf->getList(array('filter' => $sql->gen())) as $c) { $c->delete(); } if ($initcache) { $this->initCache(); } } /** * Collection selection. * * Suppose you have 5 objects with associated meta data in the * Gconf storage, if you load the data independently for each * object, you end up with 5 SELECT queries. With 25 objects, 25 * SELECT. You can select with one query all the data and merge in * the code. It is faster. The collection selection get a * model_class and a list of ids and returns an id indexed array * of associative array data. This is for read only access as you * do not get a series of Gconf objects. */ public static function collect($class, $ids) { $gconf = new IDF_Gconf(); $stmpl = sprintf('model_class=%%s AND model_id IN (%s)', implode(',' , $ids)); $sql = new Pluf_SQL($stmpl, array($class)); $out = array_fill_keys($ids, array()); foreach ($gconf->getList(array('filter' => $sql->gen())) as $c) { $out[$c->model_id][$c->vkey] = $c->vdesc; } return $out; } /** * Drop the conf of a model. * * If your model is using this table, just add the following line * in your preDelete() method: * * IDF_Gconf::dropForModel($this) * * It will take care of the cleaning. */ static public function dropForModel($model) { $table = Pluf::factory(__CLASS__)->getSqlTable(); $sql = new Pluf_SQL('model_class=%s AND model_id=%s', array($model->_model, $model->id)); $db = &Pluf::db(); $db->execute('DELETE FROM '.$table.' WHERE '.$sql->gen()); } static public function dropUser($signal, &$params) { self::dropForModel($params['user']); } }