1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Icybee\ActiveRecord\Model;
13
14 use ICanBoogie\ActiveRecord\Query;
15 use ICanBoogie\ActiveRecord\RecordNotFound;
16
17 18 19 20 21
22 class Constructor extends \ICanBoogie\ActiveRecord\Model
23 {
24 const T_CONSTRUCTOR = 'constructor';
25
26 protected $constructor;
27
28 public function __construct(array $attributes)
29 {
30 if (empty($attributes[self::T_CONSTRUCTOR]))
31 {
32 throw new \Exception('The T_CONSTRUCTOR tag is required');
33 }
34
35 $this->constructor = $attributes[self::T_CONSTRUCTOR];
36
37 parent::__construct($attributes);
38 }
39
40 41 42
43 public function save(array $properties, $key=null, array $options=array())
44 {
45 if (!$key && empty($properties[self::T_CONSTRUCTOR]))
46 {
47 $properties[self::T_CONSTRUCTOR] = $this->constructor;
48 }
49
50 return parent::save($properties, $key, $options);
51 }
52
53 54 55
56 public function find($key)
57 {
58 $record = call_user_func_array('parent::' . __FUNCTION__, func_get_args());
59
60 if ($record instanceof \ICanBoogie\ActiveRecord)
61 {
62 $record_model = \ICanBoogie\ActiveRecord\get_model($record->constructor);
63
64 if ($this !== $record_model)
65 {
66 $record = $record_model[$key];
67 }
68 }
69
70 return $record;
71 }
72
73 74 75 76 77 78 79 80 81 82 83 84 85 86
87 public function find_using_constructor(array $keys)
88 {
89 if (!$keys)
90 {
91 return array();
92 }
93
94 $records = array_combine($keys, array_fill(0, count($keys), null));
95 $missing = $records;
96
97 $constructors = $this
98 ->select('constructor, {primary}')
99 ->where(array('{primary}' => $keys))
100 ->all(\PDO::FETCH_COLUMN | \PDO::FETCH_GROUP);
101
102 foreach ($constructors as $constructor => $constructor_keys)
103 {
104 try
105 {
106 $constructor_records = \ICanBoogie\ActiveRecord\get_model($constructor)->find($constructor_keys);
107
108 foreach ($constructor_records as $key => $record)
109 {
110 $records[$key] = $record;
111 unset($missing[$key]);
112 }
113 }
114 catch (RecordNotFound $e)
115 {
116 foreach ($e->records as $key => $record)
117 {
118 if ($record === null)
119 {
120 continue;
121 }
122
123 $records[$key] = $record;
124 unset($missing[$key]);
125 }
126 }
127 }
128
129 if ($missing)
130 {
131 if (count($missing) > 1)
132 {
133 throw new RecordNotFound
134 (
135 "Records " . implode(', ', array_keys($missing)) . " do not exists.", $records
136 );
137 }
138 else
139 {
140 $key = array_keys($missing);
141 $key = array_shift($key);
142
143 throw new RecordNotFound
144 (
145 "Record <q>{$key}</q> does not exists.", $records
146 );
147 }
148 }
149
150 return $records;
151 }
152
153 154 155 156 157 158 159
160 protected function scope_own(Query $query)
161 {
162 return $query->filter_by_constructor($this->constructor);
163 }
164 }