Handling of daylight changes a bit better
[swisdk.git] / modules / inc.data.dbobjectml.php
blob269193980d2e0ea8403212e09c06f14c46d8afea
1 <?php
2 /*
3 * Copyright (c) 2006, Matthias Kestenholz <mk@spinlock.ch>
4 * Distributed under the GNU General Public License.
5 * Read the entire license text here: http://www.gnu.org/licenses/gpl.html
6 */
8 class DBObjectML extends DBObject {
9 protected $class = __CLASS__;
11 /**
12 * translation object class
14 protected $tclass = null;
16 /**
17 * DBObject or DBOContainer with translation objects
19 protected $obj;
21 /**
22 * content DBObject instance
24 protected $content_dbobj;
26 /**
27 * the language id of this DBObjectML or one of the
28 * LANGUAGE_* constants
30 protected $language;
32 public function __clone()
34 if($this->obj)
35 $this->obj = clone $this->obj;
38 public function language()
40 if($this->language == LANGUAGE_DEFAULT)
41 return Swisdk::language();
42 return $this->language;
45 public function set_language($language)
47 if($this->language == LANGUAGE_ALL)
48 SwisdkError::handle(new FatalError(
49 'Cannot assign language to DBObjectML in LANGUAGE_ALL mode'));
50 if($language == LANGUAGE_DEFAULT)
51 $this->language = Swisdk::language();
52 $this->language = $language;
53 $this->dbobj()->language_id = $this->language;
56 /**
57 * @return a DBObject or a DBOContainer depending on the value
58 * of $language above
60 * Creates and initializes the object if it does not exist already
62 public function dbobj()
64 if(!$this->obj) {
65 $tmp = $this->content_dbobj;
66 if($this->language == LANGUAGE_ALL) {
67 if($id = $this->id()) {
68 $this->obj = DBOContainer::find($this->tclass, array(
69 $tmp->name($this->primary).'=' => $id,
70 ':index' => $tmp->name('language_id')));
71 } else
72 $this->obj = DBOContainer::create($this->tclass);
73 } else {
74 $language = $this->language;
75 if($language == LANGUAGE_DEFAULT)
76 $language = Swisdk::language();
78 if($id = $this->id())
79 $this->obj = DBObject::find($this->tclass, array(
80 $tmp->name($this->primary).'=' => $id,
81 $tmp->name('language_id').'=' => $language));
82 if(!$this->obj) {
83 $this->obj = DBObject::create($this->tclass);
84 $this->obj->language_id = $this->language;
87 $this->obj->set_db_connection($this->db_connection_id);
89 return $this->obj;
92 public function &content_dbobj()
94 return $this->content_dbobj;
97 public function translation($language_id)
99 if($this->language!=LANGUAGE_ALL)
100 return null;
102 $container = $this->dbobj();
103 if(!$container->offsetExists($language_id)) {
104 $obj = DBObject::create($this->tclass);
105 $obj->set_owner($this);
106 $obj->language_id = $language_id;
107 $container[$language_id] = $obj;
110 return $container[$language_id];
113 public function translation_by_key($key)
115 return $this->translation(Swisdk::language($key));
118 protected function _setup_dbvars()
120 parent::_setup_dbvars();
121 if($this->tclass===null)
122 $this->tclass = $this->class.'Content';
123 DBObject::has_many($this, $this->tclass);
124 DBObject::has_a($this->tclass, 'Language');
125 $this->content_dbobj = DBObject::create($this->tclass);
128 public function __construct($language = LANGUAGE_DEFAULT, $setup_dbvars = true)
130 $this->language = $language;
131 if($setup_dbvars)
132 $this->_setup_dbvars();
135 public static function create($class, $language = LANGUAGE_DEFAULT)
137 if(class_exists($class))
138 return new $class($language);
140 $obj = new DBObjectML($language, false);
141 $obj->class = $class;
142 $obj->_setup_dbvars();
143 $obj->language = $language;
144 return $obj;
147 public static function create_with_data($class, $data,
148 $language = LANGUAGE_DEFAULT)
150 $obj = DBObjectML::create($class, $language);
152 foreach($data as $k => $v)
153 $obj->set($k, $v);
154 return $obj;
157 public static function find($class, $params, $language = LANGUAGE_DEFAULT)
159 $obj = DBObjectML::create($class, $language);
160 if($obj->_find($params))
161 return $obj;
162 return false;
165 protected function _find($params)
167 if(!parent::_find($params))
168 return false;
169 $this->dbobj();
170 return true;
173 public function refresh()
175 // this is used when freshly initializing a DBObjectML
176 if($this->obj)
177 $this->obj->refresh();
178 return parent::refresh();
181 public function store()
183 if($this->id()>0)
184 return $this->update();
185 else
186 return $this->insert();
189 public function update()
191 DBObject::db_start_transaction($this->db_connection_id);
192 if(parent::update()===false||!$this->obj->store()) {
193 DBObject::db_rollback($this->db_connection_id);
194 return false;
196 DBObject::db_commit($this->db_connection_id);
197 return true;
200 public function insert($force_primary = false)
202 DBObject::db_start_transaction($this->db_connection_id);
203 if(parent::insert($force_primary)===false) {
204 DBObject::db_rollback($this->db_connection_id);
205 return false;
207 $this->obj->unset_primary();
208 $this->obj->{$this->primary} = $this->id();
209 if($this->obj->insert()===false) {
210 DBObject::db_rollback($this->db_connection_id);
211 return false;
213 DBObject::db_commit($this->db_connection_id);
214 return true;
217 public function delete()
219 DBObject::db_start_transaction($this->db_connection_id);
220 if($this->obj->delete()===false || parent::delete()===false) {
221 DBObject::db_rollback($this->db_connection_id);
222 return false;
224 DBObject::db_commit($this->db_connection_id);
225 return true;
229 * the returned array has the following structure:
231 * if $language is null:
232 * array(
233 * 'news_id' => ...,
234 * 'news_author' => ...,
235 * 'translations' => array(
236 * 1 => array(
237 * 'news_content_id' => ...,
238 * 'news_content_language_id' => 1,
239 * 'news_content_title' => ...,
240 * 'news_content_news_id' => ...,
241 * ...
242 * ),
243 * 2 => array(
244 * ...
249 * otherwise:
250 * array(
251 * 'news_id' => ...,
252 * 'news_author' => ...,
253 * 'news_content_id' => ...,
254 * 'news_content_language_id' => ...,
255 * 'news_content_title' => ...
258 public function data()
260 if($this->language == LANGUAGE_ALL)
261 return array_merge(parent::data(),
262 array('translations' => $this->dbobj()->data()));
263 else
264 return array_merge(parent::data(), $this->dbobj()->data());
267 public function set_data($data)
269 $p = $this->content_dbobj->_prefix();
270 $lkey = $p.'language_id';
271 if(isset($data['translations'])) {
272 $this->language = LANGUAGE_ALL;
273 $translations = $data['translations'];
274 unset($data['translations']);
275 parent::set_data($data);
276 $dbobj =& $this->dbobj();
277 foreach($translations as &$t) {
278 $lid = $t[$lkey];
279 if(isset($dbobj[$lid]))
280 $dbobj[$lid]->set_data($t);
281 else
282 $dbobj->add($t);
284 return;
287 if(!isset($data[$lkey])) {
288 parent::set_data($data);
289 return;
292 $this->language = $data[$lkey];
293 $dbobj = $this->dbobj();
294 foreach($data as $k => $v) {
295 if(strpos($k, $p)===0)
296 $dbobj->set($k, $v);
297 else
298 $this->set($k, $v);
302 public function __get($var)
304 if($val = $this->get($this->name($var)))
305 return $val;
306 return $this->dbobj()->$var;
309 public function __set($var, $value)
311 $dbo = $this->dbobj();
312 $fields = $dbo->field_list();
313 if(isset($fields[$name = $dbo->name($var)]))
314 return $dbo->set($name, $value);
315 return $this->set($this->name($var), $value);
318 public function get($var)
320 if($var==$this->primary) {
321 if(isset($this->data[$this->primary]))
322 return $this->data[$this->primary];
323 return null;
325 $dbo = $this->dbobj();
326 $fields = $dbo->field_list();
327 if(isset($fields[$var]))
328 return $dbo->get($var);
330 return parent::get($var);
333 public function set($var, $value)
335 $this->dirty = true;
336 if($var==$this->primary)
337 return ($this->data[$this->primary] = $value);
338 $dbo = $this->dbobj();
339 $fields = $dbo->field_list();
340 if(isset($fields[$var]))
341 return $dbo->set($var, $value);
342 else
343 return $this->data[$var] = $value;
346 public function &_fulltext_fields()
348 if(!isset(DBObject::$_fulltext_fields[$this->db_connection_id]
349 [$this->class])) {
350 $mine = parent::_fulltext_fields();
351 DBObject::$_fulltext_fields[$this->db_connection_id]
352 [$this->class] =
353 array_merge($mine,
354 $this->content_dbobj->_fulltext_fields());
357 return DBObject::$_fulltext_fields[$this->db_connection_id][$this->class];
361 public function _select_sql($joins)
363 $tmp = $this->content_dbobj;
364 $lang_clause = '';
365 if(($lang_id = $this->language())!=LANGUAGE_ALL)
366 $lang_clause = ' AND '.$tmp->name('language_id').'='.$lang_id;
367 return 'SELECT * FROM '.$this->table.' LEFT JOIN '.$tmp->table()
368 .' ON '.$this->table.'.'.$this->primary.'='
369 .$tmp->table().'.'.$tmp->name($this->primary)
370 .$joins.' WHERE 1'.$lang_clause;