Source for file basicclass.php

Documentation is available at basicclass.php


1 <?php
2 /**
3 * @author Jan H. Andersen <jha@ipwsystems.dk>
4 * @author Martin R. Larsen <mrl@ipwsystems.dk>
5 * @author Jesper Laursen <jl@ipwsystems.dk>
6 * @copyright {@link http://www.ipwsystems.dk/ IPW Systems a.s}
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
8 * @package METAjour
9 * @subpackage core
10 * $Id: basicclass.php,v 1.43 2005/02/16 05:05:09 jan Exp $
11 */
12
13 define('UI_STRING', 0);
14 define('UI_STRING_LITERAL', 8);
15 define('UI_TEXT', 1);
16 define('UI_TEXT_LITERAL', 9);
17 define('UI_TEXT_WRAP', 10);
18 define('UI_TEXT_LITERAL_WRAP', 11);
19 define('UI_DECIMAL', 12);
20 define('UI_PASSWORD', 2);
21 define('UI_IMAGE', 3);
22 define('UI_HIDDEN', 4);
23 define('UI_CHECKBOX', 5);
24 define('UI_FILEUPLOAD', 6);
25 define('UI_FILE', 7);
26 define('UI_BINFILE', 13);
27 define('UI_BINFILE_THUMB', 14);
28 define('UI_LANGUAGE', 50);
29 define('UI_COUNTRY', 51);
30 define('UI_READONLY',60);
31 define('UI_LISTDIALOG',61);
32 define('UI_LISTDIALOG_STRING',62);
33 define('UI_DATE', 70);
34 define('UI_USERGROUP', 902);
35 define('UI_CLASS', 903);
36 define('UI_COMPONENT', 904);
37 define('UI_COMBO', 905);
38 define('UI_COMBO_MULTIPLE', 906);
39 define('UI_USERSGROUPS', 907);
40 define('UI_USERSGROUPS_MULTIPLE', 908);
41 define('UI_APP', 909);
42 define('UI_APP_MULTIPLE', 910);
43 define('UI_RELATION', 1000);
44 define('UI_RELATION_MULTIPLE', 1002);
45 define('UI_RELATION_NODEFAULT', 1001);
46 define('UI_NOTHING', 2000);
47 define('UI_PHONE', 666);
48
49 define('ACCESS_ANONYMOUS', 0);
50 define('ACCESS_USER', 10);
51 define('ACCESS_EDITOR', 20);
52 define('ACCESS_MANAGER', 30);
53 define('ACCESS_ADMINISTRATOR', 40);
54
55 define('INDEX_NORMAL', 0);
56 define('INDEX_PARENT', 1);
57 define('INDEX_OBJECT', 2);
58
59 define('LIKE',0);
60 define('LIKESTART',2);
61 define('LIKEEND',3);
62 define('GREATER',4);
63 define('GREATEREQUAL',5);
64 define('LESS',6);
65 define('LESSEQUAL',7);
66 define('EQUAL',8);
67 define('NOTEQUAL',9);
68 define('SOUNDSLIKE',10);
69 define('NOTSOUNDSLIKE',11);
70
71 require_once($system_path.'adodb.php');
72 require_once($system_path.'basic_error.php');
73 require_once($system_path.'basic_event.php');
74 require_once($system_path.'basic_user.php');
75
76 /**
77 * Baseclass for all core classes
78 * @abstract
79 * @package METAjour
80 * @subpackage core
81 * @author Jan H. Andersen <jha@ipwsystems.dk>
82 * @author Martin R. Larsen <mrl@ipwsystems.dk>
83 * @copyright {@link http://www.ipwsystems.dk/ IPW Systems a.s}
84 */
85
86 class basic {
87 /**
88 * An array with all data abstractlistobjects.
89 * @access public
90 * @var array
91 * @see abstractlistobjects()
92 */
93 var $elements;
94
95 /**
96 * The number of elements in $elements.
97 * @var integer
98 * @see elements
99 * @access public
100 */
101 var $elementscount;
102
103 /**
104 * @todo Create phpdoc
105 * @access private
106 * @var array
107 */
108 var $prv_options;
109
110 # INIT MISC. INTERNAL CLASS VARIABLES
111 var $errorhandler;
112 var $userhandler;
113 var $eventhandler;
114 var $readerror = 0; # Latest _getObjects error code
115 var $allowduplicate = TRUE; # Can two objects of the same type have identical name values
116 var $allownoname = TRUE; #
117 var $supertype = ''; # Name of parent class
118 var $subtype = ''; # Name of child class
119 var $issubtype = FALSE; # Is this class a subtype of another class
120 var $hassubtype = FALSE; # Does this class have a subtype
121 var $_removeelement = false;
122
123 /**
124 * The name of the primary table containing the data for this datatype
125 * Automatically set to current classname in constructor
126 * @var string
127 * @access private
128 */
129 var $objecttable = '';
130
131 /**
132 * The name of the datatype (and class)
133 * Automatically set to current classname in constructor
134 * @var string
135 * @access private
136 */
137 var $type = '';
138 var $filter_variant = FALSE;
139 var $filter_future = FALSE;
140 var $filter_history = FALSE;
141 var $filter_category = FALSE;
142 var $filter_deleted = FALSE;
143 var $filter_data = FALSE;
144 var $filter_datavalue = FALSE;
145 var $filter_name = FALSE;
146 var $filter_exactname = FALSE;
147 var $filter_approved = -1;
148 var $filter_limit = FALSE;
149 var $sort_colname = FALSE;
150 var $sort_way = 'ASC';
151 var $filter_getname = FALSE;
152 var $filter_searchcolname = array();
153 var $filter_searchvalue = array();
154 var $filter_searchtype = array();
155 var $filter_advsearchcolname = array();
156 var $filter_advsearchvalue = array();
157 var $filter_advsearchtype = array();
158 var $listaccess = FALSE;
159 /**
160 * Indicates use of UI_RELATION_MULTIPLE or UI_COMBO_MULTIPLE
161 * Automatically set by addColumn
162 * @var bool
163 * @access private
164 */
165 var $_hasmultiple = FALSE; #
166 var $_hasrelatedfields = FALSE; #
167 var $_view = array();
168 var $_relationdatatypes = array();
169 var $_childdatatypes = array();
170 var $_useapp = FALSE;
171 var $prv_column = array();
172 var $_columnidx = array();
173
174 function basic() {
175 $this->errorhandler =& getErrorHandler();
176 $this->eventhandler =& getEventHandler();
177 $this->userhandler =& getUserHandler();
178 $userhandler =& $this->userhandler;
179 $this->site = $userhandler->getSite();
180 $this->system_url = $userhandler->getSystemUrl();
181 $this->system_path = $userhandler->getSystemPath();
182 $this->viewer_url = $userhandler->getViewerUrl();
183 $this->viewer_path = $userhandler->getViewerPath();
184 $this->webuser = $userhandler->getWebuser();
185
186 $this->_adodb =& getDbConn();
187 $this->_view = array();
188 $this->initViews();
189 $this->setobjecttype(get_class($this));
190 $this->setobjecttable(get_class($this));
191 }
192
193
194 #########################################################################################
195 #
196 # CLASS CONSTRUCTION
197 #
198 #########################################################################################
199
200 function setUseApp($value) {
201 $this->_useapp = $value;
202 }
203
204 function getViews() {
205 return $this->_view;
206 }
207
208 function allowed($name) {
209 return in_array($name, $this->_view) && ($this->userhandler->GetLevel() >= 40 || $this->userhandler->GetProfileView($this->type,$name));
210 }
211
212 function addView($name) {
213 $this->_view[] = $name;
214 }
215
216 function removeView($name) {
217 $i = array_search($name,$this->_view);
218 if ($i !== false) unset($this->_view[$i]);
219 }
220
221 function initViews() {
222 #defines all the default views usually available
223 #apply additional views with addview
224 #remove views with removeview
225 $this->addview('menu');
226 $this->addview('list');
227 $this->addview('tree');
228 $this->addview('view');
229 $this->addview('create');
230 $this->addview('edit');
231 $this->addview('delete');
232 $this->addview('move');
233 $this->addview('properties');
234
235 $this->addview('createdby');
236 $this->addview('changedby');
237 $this->addview('checkedby');
238 $this->addview('created');
239 $this->addview('changed');
240 $this->addview('checked');
241 $this->addview('language');
242 $this->addview('publish');
243 $this->addview('access');
244 $this->addview('active');
245 $this->addview('approved');
246 $this->addview('category');
247 $this->addview('readonly');
248
249 $this->addview('createcopy');
250 $this->addview('createvariant');
251 # $this->addview('createfuture');
252 # $this->addview('approvepublish');
253 # $this->addview('requestapproval');
254 }
255
256 function setObjectType($name) {
257 $this->type = $name;
258 }
259
260 /**
261 * @return int index key of value $name in the $this->prv_column array
262 */
263 function getColumnIdx($name) {
264 return $this->_columnidx[$name];
265 }
266
267 function initLayout() {
268 $this->addChildDatatype('note');
269 #$this->addChildDatatype('message');
270 $this->addChildDatatype('binfile');
271 }
272
273 function addColumn($name, $coltype=0, $inputtype=0, $relation='', $validate='') {
274 $this->prv_column[] = array('name' => $name, 'type' => $coltype, 'inputtype' => $inputtype, 'relation' => $relation, 'validate' => $validate);
275 if ($inputtype == UI_RELATION_MULTIPLE || $inputtype == UI_COMBO_MULTIPLE || $inputtype == UI_USERSGROUPS_MULTIPLE || $inputtype == UI_APP_MULTIPLE) $this->_hasmultiple = true;
276 $this->_columnidx[$name] = sizeof($this->prv_column)-1;
277 }
278
279 function getColumns() {
280 return $this->prv_column;
281 }
282
283 function stdListCol() {
284 $arr = array();
285 $arr[] = 'name';
286 $arr[] = 'createdbyname';
287 $arr[] = 'changed';
288 $arr[] = 'language';
289 $arr[] = 'objectid';
290 return $arr;
291 }
292
293 function stdListInfocol() {
294 $arr = array();
295 if ($this->allowed('default')) $arr[] = 'default';
296 $arr[] = 'active';
297 $arr[] = 'permission';
298 $arr[] = 'variant';
299 return $arr;
300 }
301
302 function addColumnStyle($name, $style) {
303 $this->prv_column[$this->_columnidx[$name]] = array_merge($this->prv_column[$this->_columnidx[$name]], array('style' => $style));
304 }
305
306 function addFieldsetStyle($name, $style) {
307 $this->prv_column[$this->_columnidx[$name]] = array_merge($this->prv_column[$this->_columnidx[$name]], array('fieldsetstyle' => $style));
308 }
309
310 function addLabelStyle($name, $style) {
311 $this->prv_column[$this->_columnidx[$name]] = array_merge($this->prv_column[$this->_columnidx[$name]], array('labelstyle' => $style));
312 }
313
314 function addFieldStyle($name, $style) {
315 $this->prv_column[$this->_columnidx[$name]] = array_merge($this->prv_column[$this->_columnidx[$name]], array('fieldstyle' => $style));
316 }
317
318 function combineFields($name1, $name2) {
319 $this->prv_column[$this->_columnidx[$name1]] = array_merge($this->prv_column[$this->_columnidx[$name1]], array('skipend' => "1"));
320 $this->prv_column[$this->_columnidx[$name2]] = array_merge($this->prv_column[$this->_columnidx[$name2]], array('skipstart' => "1"));
321 }
322
323 function byside2($name1, $name2) {
324 $this->combineFields($name1,$name2);
325 }
326
327 function byside3($name1, $name2, $name3) {
328 $this->combineFields($name1,$name2);
329 $this->combineFields($name2,$name3);
330 }
331
332 function byside4($name1, $name2, $name3, $name4) {
333 $this->combineFields($name1,$name2);
334 $this->combineFields($name2,$name3);
335 $this->combineFields($name3,$name4);
336 }
337
338 function clearRelationDatatypes() {
339 $this->_relationdatatypes = array();
340 }
341
342 function addRelationDatatype($datatype,$column,$foreigncolumn) {
343 $arr['datatype'] = $datatype;
344 $arr['column'] = $column;
345 $arr['foreigncolumn'] = $foreigncolumn;
346 $this->_relationdatatypes[] = $arr;
347 }
348
349 function relateFields($masterfield, $detailfield, $foreigncolumn) {
350 $this->_hasrelatedfields = TRUE;
351 $this->prv_column[$this->_columnidx[$masterfield]]['detailfield'] = $detailfield;
352 $this->prv_column[$this->_columnidx[$masterfield]]['foreigncolumn'] = $foreigncolumn;
353
354 // this information tells UI_LISTDIALOG where to look for
355 // information about which datatype and field that should limit the
356 // dialog-window. Same principle as for addRelationDatatype
357 // in a completely different way.
358 $this->prv_column[$this->_columnidx[$detailfield]]['masterfield'] = $masterfield;
359 $this->prv_column[$this->_columnidx[$detailfield]]['foreigncolumn'] = $foreigncolumn;
360 }
361
362 function getRelationDatatypes() {
363 return $this->_relationdatatypes;
364 }
365
366 function clearChildDatatypes() {
367 $this->_childdatatypes = array();
368 }
369
370 function addChildDatatype($datatype) {
371 $this->_childdatatypes[] = $datatype;
372 }
373
374 function getChildDatatypes() {
375 return $this->_childdatatypes;
376 }
377
378 function setSubtype($name) {
379 $this->subtype = $name;
380 $this->hassubtype = TRUE;
381 }
382
383 function setSupertype($name) {
384 $this->supertype = $name;
385 $this->issubtype = TRUE;
386 }
387
388 /**
389 * @return string objecttype of child class (not child object!)
390 */
391 function getSubtype() {
392 return $this->subtype;
393 }
394
395 /**
396 * @return string objecttype of parent class (not parent object!)
397 */
398 function getSupertype() {
399 return $this->supertype;
400 }
401
402 function setObjectTable($name) {
403 $this->objecttable = $name;
404 }
405
406 #########################################################################################
407 #
408 # ACCESS CONTROL
409 #
410 #########################################################################################
411
412 function setListAccess($value) {
413 $this->listaccess = $value;
414 }
415
416
417 function canTouch() {
418 if (!$this->userhandler->GetRestrictLanguage()) return true;
419 $res = $this->_adodb->getOne("select count(*) from object where objectid = ".$this->getObjectId()." and language="
420 . $this->_adodb->qstr($this->userhandler->GetObjectLanguage()));
421 return ($res > 0) ? true : false;
422 }
423
424 /**
425 * Used to check if the current user has access to the current object
426 *
427 * Administrator has always access.
428 * Other users depend on the objects permissions
429 * @return boolean true if the user has access, false otherwise
430 */
431 function hasAccess() {
432 if ($this->userhandler->GetLevel() >= ACCESS_MANAGER) return true;
433 if ($this->userhandler->getUnlimitedAccess()) return true;
434 if (!$this->webuser && $this->listaccess) return true;
435
436 if ($this->webuser) {
437 $res = true;
438 } else {
439 if ($this->prv_options['createdby'] == $this->userhandler->GetObjectid())
440 $res = true;
441 }
442
443 if (isset($this->prv_options['access'])) {
444 $total = sizeof($this->prv_options['access']);
445 } else {
446 $total = 0;
447 }
448 if ($total > 0) {
449
450 if ($this->webuser) $res = false;
451
452 if ($this->userhandler->LoggedIn()) {
453 if ($this->webuser) {
454 $x = 0;
455 $anyatall = false;
456 while ($x < $total) {
457 if ($this->prv_options['access'][$x]['user_read'] == $this->userhandler->GetObjectId()) {
458 return true;
459 }
460
461 if ($this->prv_options['access'][$x]['user_read'] != 0) $anyatall = true;
462
463 if (is_array($this->userhandler->GetGroups())) {
464 if (in_array($this->prv_options['access'][$x]['group_read'], $this->userhandler->GetGroups())) return true;
465 }
466
467 if ($this->prv_options['access'][$x]['group_read'] != 0) $anyatall = true;
468 $x++;
469 }
470
471 if (!$anyatall) $res = true;
472
473 } else {
474 $x = 0;
475 while ($x < $total) {
476 if ($this->prv_options['access'][$x]['user_write'] == $this->userhandler->GetObjectId()) {
477 return true;
478 }
479
480 if (is_array($this->userhandler->GetGroups())) {
481 if (in_array($this->prv_options['access'][$x]['group_write'], $this->userhandler->GetGroups())) return true;
482 }
483
484 $x++;
485 }
486 }
487 }
488 }
489
490 return $res;
491 }
492
493 function setAccess($readaccess, $writeaccess) {
494 if (!$this->cantouch()) return false;
495
496 $this->_adodb->execute("delete from object_access where objectid = ".$this->getObjectId());
497
498 $haspermission = false;
499 if (is_array($readaccess)) {
500 foreach ($readaccess as $val) {
501 if ($val != '') {
502 if ($val < 0) {
503 $this->_adodb->execute("insert into object_access (objectid, group_read) values (".$this->getObjectId().", " . abs($val) . ")");
504 } else {
505 $this->_adodb->execute("insert into object_access (objectid, user_read) values (".$this->getObjectId().", " . $val . ")");
506 }
507 $haspermission = true;
508 }
509 }
510 }
511 if (is_array($writeaccess)) {
512 foreach ($writeaccess as $val) {
513 if ($val != '') {
514 if ($val < 0) {
515 $this->_adodb->execute("insert into object_access (objectid, group_write) values (".$this->getObjectId().", " . abs($val) . ")");
516 } else {
517 $this->_adodb->execute("insert into object_access (objectid, user_write) values (".$this->getObjectId().", " . $val . ")");
518 }
519 $haspermission = true;
520 }
521 }
522 }
523
524 if ($haspermission) {
525 $this->_setOption('haspermission', '1');
526 } else {
527 $this->_setOption('haspermission', '0');
528 }
529 return true;
530 }
531
532 /**
533 * @return Array with objectids for users which have access to the current object
534 */
535 function resolveAccess() {
536 // If we don't get passed an objectid we use the id for the current object
537 $objectid = $this->getobjectid();
538 $result = array();
539 if ($this->webuser) {
540 owget($objectid, $obj);
541 $obj->readobject($objectid);
542 $obj->webuser = $this->webuser;
543
544 $total = (isset($obj->prv_options['access'])) ? sizeof($obj ->prv_options['access']) : 0;
545
546 $ug = owNew('usergroup');
547 if ($this->webuser) {
548 $x = 0;
549 while ($x < $total) {
550 $result[] = $obj->prv_options['access'][$x]['user_read'];
551
552 if ($obj->prv_options['access'][$x]['group_read'] != 0) {
553 $ug->readobject($obj->prv_options['access'][$x]['group_read']);
554 $members = $ug->getmembers();
555 if (is_array($members)) {
556 foreach($members as $member) {
557 $result[] = $member['id'];
558 }
559 }
560 }
561 $x++;
562 }
563
564 if (count($result) == 0) {
565 // No permissions found. Defaults to all users
566 $users = owNew('user');
567 $users->listobjects();
568 foreach($users->elements as $element) {
569 $result[] = $element['object']['objectid'];
570 }
571 }
572
573 $ug = owNew('usergroup');
574 $ug->readobject($ug->getsystemgroup(ACCESS_ADMINISTRATOR));
575 $members = $ug->getmembers();
576 if (is_array($members)) {
577 foreach ($members as $member) {
578 $result[] = $member['id'];
579 }
580 }
581 owget($objectid, $obj);
582 $obj->readobject($objectid);
583 // Owner always has access
584 $result[] = $obj->getcreatedby();
585 }
586
587 } else {
588
589 // Administrators always has access
590 $ug = owNew('usergroup');
591 $ug->readobject($ug->getsystemgroup(ACCESS_ADMINISTRATOR));
592 $members = $ug->getmembers();
593 if (is_array($members)) {
594 foreach ($members as $member) {
595 $result[] = $member['id'];
596 }
597 }
598
599 owget($objectid, $obj);
600 $obj->readobject($objectid);
601 // Owner always has access
602 $result[] = $obj->getcreatedby();
603
604 $total = (isset($obj->prv_options['access'])) ? sizeof($obj ->prv_options['access']) : 0;
605
606 $x = 0;
607 while ($x < $total) {
608 $result[] = $obj->prv_options['access'][$x]['user_write'];
609
610 if ($obj->prv_options['access'][$x]['group_write'] != 0) {
611 $ug = new usergroup;
612 $ug->readobject($obj