1 <?php
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 class P3MetaDataBehavior extends CActiveRecordBehavior
41 {
42
43 44 45 46
47 public $metaDataRelation;
48
49 50 51 52
53 public $contentRelation;
54
55 56 57 58
59 public $parentRelation;
60
61 62 63 64
65 public $childrenRelation;
66
67 const STATUS_DELETED = 0;
68 const STATUS_DRAFT = 10;
69 const STATUS_PENDING = 20;
70 const STATUS_ACTIVE = 30;
71 const STATUS_LOCKED = 40;
72 const STATUS_HIDDEN = 50;
73 const STATUS_ARCHIVE = 60;
74
75 public function getChildren()
76 {
77 $return = array();
78
79
80 $model = $this->resolveMetaDataModel();
81 if ($model === null) {
82 Yii::log('Record #' . $this->owner->id . ' has no Meta Data model.');
83 return array();
84 }
85
86
87 $criteria = new CDbCriteria;
88 $criteria->condition = 'treeParent_id = ' . $this->owner->id;
89 $criteria->order = "treePosition ASC";
90 $children = $model->findAll($criteria);
91
92 if ($children !== array()) {
93 foreach ($children AS $metaModel) {
94 if ($this->metaDataRelation == '_self_') {
95 $return[] = $metaModel;
96 }
97 else {
98 $return[] = $metaModel->{$this->contentRelation};
99 }
100 }
101 }
102 return $return;
103 }
104
105 public function getParent()
106 {
107 $model = $this->resolveMetaDataModel();
108 $result = $model->findByAttributes(array('id' => $this->owner->{$this->metaDataRelation}->treeParent_id));
109 if ($this->metaDataRelation == '_self_') {
110 return $result;
111 }
112 else {
113 if ($result !== null) {
114 return $result->{$this->contentRelation};
115 } else {
116 return $result;
117 }
118 }
119
120 }
121
122 public function beforeFind($event)
123 {
124 parent::beforeFind($event);
125
126
127 if (Yii::app() instanceof CConsoleApplication) {
128 Yii::log('Meta Data behavior omitted in console application.', CLogger::LEVEL_INFO);
129 return true;
130 }
131
132
133 $criteria = $this->createReadAccessCriteria();
134 $this->owner->applyScopes($criteria);
135 $this->owner->setDbCriteria($criteria);
136 }
137
138 139 140 141 142
143 public function beforeDelete($event)
144 {
145 parent::beforeDelete($event);
146 if ($this->resolveMetaDataModel() !== null) {
147 if ($this->resolveMetaDataModel()->checkAccessDelete && Yii::app()->user->checkAccess($this->resolveMetaDataModel()->checkAccessDelete) === false) {
148 throw new CHttpException(403, "You are not authorized to perform this action. Access restricted by P3MetaDataBehavior.");
149 return false;
150 }
151 else {
152 if ($this->metaDataRelation !== "_self_") {
153 $this->resolveMetaDataModel()->delete();
154 }
155 }
156 }
157 return true;
158 }
159
160 161 162 163 164
165 public function beforeSave($event)
166 {
167 parent::beforeSave($event);
168
169
170 if (Yii::app() instanceof CConsoleApplication) {
171 Yii::log('Meta Data behavior omitted in console application.', CLogger::LEVEL_INFO);
172 return true;
173 }
174
175 if ($this->resolveMetaDataModel() !== null && $this->resolveMetaDataModel()->checkAccessUpdate) {
176 if (Yii::app()->user->checkAccess($this->resolveMetaDataModel()->checkAccessUpdate) === false) {
177 throw new CHttpException(403, "You are not authorized to perform this action. Access restricted by P3MetaDataBehavior.");
178 return false;
179 }
180 }
181 return true;
182 }
183
184 185 186 187 188
189 public function afterSave($event)
190 {
191 parent::afterSave($event);
192
193
194 if ($this->metaDataRelation == '_self_') {
195 return true;
196 }
197
198
199 if (Yii::app() instanceof CConsoleApplication) {
200 Yii::log('Meta Data behavior omitted in console application.', CLogger::LEVEL_INFO);
201 $userId = 1;
202 $primaryRole = null;
203 } else {
204 $userId = Yii::app()->user->id;
205 $primaryRole = key(Yii::app()->authManager->getRoles(Yii::app()->user->id));
206 }
207
208
209 if ($this->resolveMetaDataModel() === null) {
210 $metaClassName = $this->owner->getActiveRelation($this->metaDataRelation)->className;
211 $metaModel = new $metaClassName;
212 $metaModel->id = $this->owner->id;
213 $metaModel->status = self::STATUS_ACTIVE;
214
215 $metaModel->language = '_ALL';
216 $metaModel->owner = $userId;
217
218
219 $metaModel->createdAt = date('Y-m-d H:i:s');
220 $metaModel->createdBy = $userId;
221 $metaModel->guid = sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
222 $metaModel->model = get_class($this->owner);
223 }
224 else {
225 $metaModel = $this->resolveMetaDataModel();
226 $metaModel->modifiedAt = date('Y-m-d H:i:s');
227 $metaModel->modifiedBy = $userId;
228 }
229 $metaModel->save();
230 return true;
231 }
232
233 234 235 236 237
238 private function resolveMetaDataModel()
239 {
240 if (!$this->metaDataRelation) {
241 throw new CException("Attribute 'metaDataRelation' for model '" . get_class($this->owner) . "' not set.");
242 }
243 elseif ($this->metaDataRelation == "_self_") {
244
245 return $this->owner;
246 }
247 elseif (strpos($this->metaDataRelation, ".")) {
248
249 $parts = explode(".", $this->metaDataRelation);
250 $return = $this->owner;
251 foreach ($parts AS $part) {
252 $return = $return->$part;
253 }
254 return $return;
255 }
256 else {
257
258 return $this->owner->{$this->metaDataRelation};
259 }
260 }
261
262 263 264 265
266 private function createReadAccessCriteria()
267 {
268 $criteria = new CDbCriteria;
269
270
271 if (!Yii::app()->user->isSuperuser) {
272 if ($this->owner->metaDataRelation != "_self_") {
273 $criteria->with = $this->owner->metaDataRelation;
274 $tablePrefix = $this->owner->metaDataRelation;
275 } else {
276 $tablePrefix = $this->owner->getTableAlias();
277 }
278
279 $checkAccessRoles = "";
280 if (!Yii::app()->user->isGuest) {
281 foreach (Yii::app()->authManager->getRoles(Yii::app()->user->id) AS $role) {
282 $checkAccessRoles .= $tablePrefix.".checkAccessRead = '" . $role->name . "' OR ";
283 }
284 }
285 else {
286 $checkAccessRoles .= $tablePrefix.".checkAccessRead = 'Guest' OR ";
287 }
288 $criteria->condition = $checkAccessRoles . " " . $tablePrefix.".checkAccessRead IS NULL";
289 }
290 return $criteria;
291 }
292
293 }
294
295 ?>