This repository has been archived by the owner on May 14, 2019. It is now read-only.
forked from bermi/akelos
-
Notifications
You must be signed in to change notification settings - Fork 10
/
table_inheritance.php
75 lines (68 loc) · 3.5 KB
/
table_inheritance.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
# This file is part of the Akelos Framework
# (Copyright) 2004-2010 Bermi Ferrer bermi a t bermilabs com
# See LICENSE and CREDITS for details
/**
* == Single table inheritance ==
*
* Active Record allows inheritance by storing the name of the class in a column that by default is called "type" (can be changed
* by overwriting <tt>AkActiveRecord->_inheritanceColumn</tt>). This means that an inheritance looking like this:
*
* <code>
* class Company extends ActiveRecord{}
* class Firm extends Company{}
* class Client extends Company{}
* class PriorityClient extends Client{}
* </code>
*
* When you do $Firm->create('name =>', "akelos"), this record will be saved in the companies table with type = "Firm". You can then
* fetch this row again using $Company->find('first', "name = '37signals'") and it will return a Firm object.
*
* If you don't have a type column defined in your table, single-table inheritance won't be triggered. In that case, it'll work just
* like normal subclasses with no special magic for differentiating between them or reloading the right type with find.
*
* Note, all the attributes for all the cases are kept in the same table. Read more:
* http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
*/
class AkActiveRecordTableInheritance extends AkActiveRecordExtenssion
{
/**
* Defines the column name for use with single table inheritance. Can be overridden in subclasses.
*/
public function setInheritanceColumn($column_name) {
if(!$this->_ActiveRecord->hasColumn($column_name)){
trigger_error(Ak::t('Could not set "%column_name" as the inheritance column as this column is not available on the database.',array('%column_name'=>$column_name)).' '.Ak::getFileAndNumberTextForError(1), E_USER_NOTICE);
return false;
}elseif($this->_ActiveRecord->getColumnType($column_name) != 'string'){
trigger_error(Ak::t('Could not set %column_name as the inheritance column as this column type is "%column_type" instead of "string".',array('%column_name'=>$column_name,'%column_type'=>$this->_ActiveRecord->getColumnType($column_name))).' '.Ak::getFileAndNumberTextForError(1), E_USER_NOTICE);
return false;
}else{
$this->_ActiveRecord->_inheritanceColumn = $column_name;
return true;
}
}
public function getSubclasses() {
$current_class = get_class($this->_ActiveRecord);
$subclasses = array();
$classes = get_declared_classes();
while ($class = array_shift($classes)) {
$parent_class = get_parent_class($class);
if($parent_class == $current_class || in_array($parent_class, $subclasses)){
$subclasses[] = $class;
}elseif(!empty($parent_class)){
$classes[] = $parent_class;
}
}
return $subclasses;
}
public function typeCondition($table_alias = null) {
$inheritance_column = $this->_ActiveRecord->getInheritanceColumn();
$type_condition = array();
$table_name = $this->_ActiveRecord->getTableName();
$available_types = array_merge(array($this->_ActiveRecord->getModelName()), $this->getSubclasses());
foreach ($available_types as $subclass){
$type_condition[] = ' '.($table_alias != null ? $table_alias : $table_name).'.'.$inheritance_column.' = \''.AkInflector::humanize(AkInflector::underscore($subclass)).'\' ';
}
return empty($type_condition) ? '' : '('.join('OR',$type_condition).') ';
}
}