3 * Table Definition for Person
5 require_once 'DB/DataObject.php';
7 class Pman_Core_DataObjects_Person extends DB_DataObject
10 /* the code below is auto generated do not remove the above tag */
12 public $__table = 'Person'; // table name
13 public $id; // int(11) not_null primary_key auto_increment
14 public $email; // string(128) not_null
16 public $company_id; // int(11)
17 public $office_id; // int(11)
19 public $name; // string(128) not_null
20 public $firstname; // string(128) not_null
21 public $lastname; // string(128) not_null
22 public $phone; // string(32) not_null
23 public $fax; // string(32) not_null
25 public $role; // string(32) not_null
26 public $active; // int(11) not_null
27 public $remarks; // blob(65535) not_null blob
28 public $passwd; // string(64) not_null
29 public $owner_id; // int(11) not_null
30 public $lang; // string(8)
31 public $no_reset_sent; // int(11)
32 public $action_type; // string(32)
33 public $project_id; // int(11)
34 public $deleted_by; // int(11) not_null
35 public $deleted_dt; // datetime(19) binary
38 /* the code above is auto generated do not remove the tag below */
42 * @param {String} $templateFile (mail/XXXXXXX.txt) exclude the mail and .txt bit.
43 * @param {Array|Object} $args data to send out..
44 * @return {Array|PEAR_Error} array of $recipents, $header, $body
46 function buildMail($templateFile, $args)
49 $args = (array) $args;
50 $content = clone($this);
52 foreach((array)$args as $k=>$v) {
56 $ff = HTML_FlexyFramework::get();
59 //?? is this really the place for this???
62 empty($args['no_auth']) &&
63 !in_array($templateFile, array(
64 // templates that can be sent without authentication.
70 $content->authUser = $this->getAuthUser();
71 if (!$content->authUser) {
72 return PEAR::raiseError("Not authenticated");
76 // should handle x-forwarded...
78 $content->HTTP_HOST = isset($_SERVER["HTTP_HOST"]) ?
79 $_SERVER["HTTP_HOST"] :
80 (isset($ff->HTTP_HOST) ? $ff->HTTP_HOST : 'localhost');
82 /* use the regex compiler, as it doesnt parse <tags */
83 require_once 'HTML/Template/Flexy.php';
84 $template = new HTML_Template_Flexy( array(
85 'compiler' => 'Flexy',
87 'filters' => array('SimpleTags','Mail'),
94 $template->compile("mail/$templateFile.txt");
96 /* use variables from this object to ouput data. */
97 $mailtext = $template->bufferedOutputObject($content);
98 //echo "<PRE>";print_R($mailtext);
99 //print_R($mailtext);exit;
100 /* With the output try and send an email, using a few tricks in Mail_MimeDecode. */
101 require_once 'Mail/mimeDecode.php';
102 require_once 'Mail.php';
104 $decoder = new Mail_mimeDecode($mailtext);
105 $parts = $decoder->getSendArray();
106 if (PEAR::isError($parts)) {
108 //echo "PROBLEM: {$parts->message}";
111 list($recipents,$headers,$body) = $parts;
112 $recipents = array($this->email);
113 if (!empty($content->bcc) && is_array($content->bcc)) {
114 $recipents =array_merge($recipents, $content->bcc);
116 $headers['Date'] = date('r');
119 'recipients' => $recipents,
120 'headers' => $headers,
130 * - user must be authenticate or args[no_auth] = true
131 * or template = password_[reset|welcome]
134 function sendTemplate($templateFile, $args)
137 $ar = $this->buildMail($templateFile, $args);
140 //print_r($recipents);exit;
141 $mailOptions = PEAR::getStaticProperty('Mail','options');
142 $mail = Mail::factory("SMTP",$mailOptions);
144 if (PEAR::isError($mail)) {
147 $oe = error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
148 $ret = $mail->send($ar['recipients'],$ar['headers'],$ar['body']);
149 error_reporting($oe);
158 function getEmailFrom()
160 return '"' . addslashes($this->name) . '" <' . $this->email . '>';
162 function toEventString()
164 return empty($this->name) ? $this->email : $this->name;
166 function verifyAuth()
168 $ff= HTML_FlexyFramework::get();
169 if (!empty($ff->Pman['auth_comptype']) && $ff->Pman['auth_comptype'] != $this->company()->comptype) {
170 $ff->page->jerr("Login not permited to outside companies");
177 // ---------------- authentication / passwords and keys stuff ----------------
180 $db = $this->getDatabaseConnection();
181 // we combine db + project names,
182 // otherwise if projects use different 'auth' objects
183 // then we get unserialize issues.
184 $sesPrefix = get_class($this) .'-'.$db->dsn['database'] ;
188 if (!empty($_SESSION[__CLASS__][$sesPrefix .'-auth'])) {
190 $a = unserialize($_SESSION[__CLASS__][$sesPrefix .'-auth']);
192 $u = DB_DataObject::factory('Person');
193 if ($u->get($a->id)) { //&& strlen($u->passwd)) {
199 $_SESSION[__CLASS__][$sesPrefix .'-auth'] = '';
203 $u = DB_DataObject::factory('Person');
204 $ff = HTML_FlexyFramework::get();
205 if (!empty($ff->Pman['local_autoauth']) &&
206 (!empty($_SERVER['SERVER_ADDR'])) &&
207 ($_SERVER['SERVER_ADDR'] == '127.0.0.1') &&
208 ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') &&
209 $u->get('email', $ff->Pman['local_autoauth'])
211 $_SESSION[__CLASS__][$sesPrefix .'-auth'] = serialize($u);
216 $u = DB_DataObject::factory('Person');
218 if (!empty($_SERVER['PHP_AUTH_USER'])
220 !empty($_SERVER['PHP_AUTH_PW'])
222 $u->get('email', $_SERVER['PHP_AUTH_USER'])
224 $u->checkPassword($_SERVER['PHP_AUTH_PW'])
226 $_SESSION[__CLASS__][$sesPrefix .'-auth'] = serialize($u);
233 // not in session or not matched...
234 $u = DB_DataObject::factory('Person');
235 $u->whereAdd(' LENGTH(passwd) > 0');
237 $error = PEAR::getStaticProperty('DB_DataObject','lastError');
239 die($error->toString()); // not really a good thing to do...
241 if (!$n){ // authenticated as there are no users in the system...
248 function getAuthUser()
250 if (!$this->isAuth()) {
253 $db = $this->getDatabaseConnection();
254 $sesPrefix = get_class($this) .'-'.$db->dsn['database'] ;
256 if (!empty($_SESSION[__CLASS__][$sesPrefix .'-auth'])) {
257 $a = unserialize($_SESSION[__CLASS__][$sesPrefix .'-auth']);
259 $u = DB_DataObject::factory('Person');
260 if ($u->get($a->id)) { /// && strlen($u->passwd)) {
266 $u = DB_DataObject::factory('Person');
267 $u->whereAdd(' LENGTH(passwd) > 0');
269 $u = DB_DataObject::factory('Person');
278 $this->isAuth(); // force session start..
280 $db = $this->getDatabaseConnection();
281 // refresh admin group if we are logged in as one..
282 //DB_DataObject::debugLevel(1);
283 $g = DB_DataObject::factory('Groups');
285 $g->get('name', 'Administrators');
286 $gm = DB_DataObject::Factory('Group_Members');
287 if (in_array($g->id,$gm->listGroupMembership($this))) {
288 // refresh admin groups.
289 $gr = DB_DataObject::Factory('Group_Rights');
290 $gr->applyDefs($g, 0);
293 $sesPrefix = get_class($this) .'-'.$db->dsn['database'] ;
294 $_SESSION[__CLASS__][$sesPrefix .'-auth'] = serialize($this);
299 $this->isAuth(); // force session start..
300 $db = $this->getDatabaseConnection();
301 $sesPrefix = get_class($this) .'-'.$db->dsn['database'] ;
302 $_SESSION[__CLASS__][$sesPrefix .'-auth'] = "";
305 function genPassKey ($t)
307 return md5($this->email . $t. $this->passwd);
309 function simpleAuthKey($m = 0)
311 $month = $m > -1 ? date('Y-m') : date('Y-m', strtotime('LAST MONTH'));
313 return md5(implode(',' , array($month, $this->email , $this->passwd, $this->id)));
315 function checkPassword($val)
318 if (substr($this->passwd,0,1) == '$') {
319 return crypt($val,$this->passwd) == $this->passwd ;
321 // old style md5 passwords...- cant be used with courier....
322 return md5($val) == $this->passwd;
324 function setPassword($value)
327 while(strlen($salt)<9) {
328 $salt.=chr(rand(64,126));
329 //php -r var_dump(crypt('testpassword', '$1$'. (rand(64,126)). '$'));
331 $this->passwd = crypt($value, '$1$'. $salt. '$');
338 $x = DB_DataObject::factory('Companies');
339 $x->get($this->company_id);
342 function loadCompany()
344 $this->company = $this->company();
349 return $this->active;
351 function authUserName($n) // set username prior to acheck user exists query.
354 $this->whereAdd('LENGTH(passwd) > 1');
359 if ($val == $this->lang) {
369 function authUserArray()
372 $aur = $this->toArray();
379 //DB_DataObject::debugLevel(1);
380 $c = DB_Dataobject::factory('Companies');
381 $im = DB_Dataobject::factory('Images');
382 $c->joinAdd($im, 'LEFT');
384 $c->selectAs($c, 'company_id_%s');
385 $c->selectAs($im, 'company_id_logo_id_%s');
386 $c->id = $this->company_id;
390 $aur = array_merge( $c->toArray(),$aur);
392 if (empty($c->company_id_logo_id_id)) {
394 $im = DB_Dataobject::factory('Images');
395 $im->ontable = 'Companies';
397 $im->imgtype = 'LOGO';
400 $im->selectAs($im, 'company_id_logo_id_%s');
401 if ($im->find(true)) {
403 foreach($im->toArray() as $k=>$v) {
410 $aur['perms'] = $this->getPerms();
411 $g = DB_DataObject::Factory('Group_Members');
412 $aur['groups'] = $g->listGroupMembership($this, 'name');
415 $aur['dailykey'] = '';
422 // ----------PERMS------ ----------------
425 //DB_DataObject::debugLevel(1);
426 // find out all the groups they are a member of.. + Default..
428 // ------ INIITIALIZE IF NO GROUPS ARE SET UP.
430 $g = DB_DataObject::Factory('Group_Rights');
436 return $g->adminRights(); // system is not set up - so they get full rights.
438 //DB_DataObject::debugLevel(1);
439 $g = DB_DataObject::Factory('Group_Members');
440 $g->whereAdd('group_id is NOT NULL AND user_id IS NOT NULL');
442 // add the current user to the admin group..
443 $g = DB_DataObject::Factory('Groups');
444 if ($g->get('name', 'Administrators')) {
445 $gm = DB_DataObject::Factory('Group_Members');
446 $gm->group_id = $g->id;
447 $gm->user_id = $this->id;
453 // ------ STANDARD PERMISSION HANDLING.
455 $g = DB_DataObject::Factory('Group_Members');
456 $grps = $g->listGroupMembership($this);
458 $isAdmin = $g->inAdmin;
459 //echo '<PRE>'; print_r($grps);var_dump($isAdmin);
460 // the load all the perms for those groups, and add them all together..
461 // then load all those
462 $g = DB_DataObject::Factory('Group_Rights');
463 $ret = $g->listPermsFromGroupIds($grps, $isAdmin);
464 //echo '<PRE>';print_r($ret);
470 *Basic group fetching - probably needs to filter by type eventually.
472 *@param String $what - fetchall() argument - eg. 'name' returns names of all groups that they are members of.
475 function groups($what=false)
477 $g = DB_DataObject::Factory('Group_Members');
478 $grps = $g->listGroupMembership($this);
479 $g = DB_DataObject::Factory('Groups');
480 $g->whereAddIn('id', $grps, 'int');
481 return $g->fetchAll($what);
485 function hasPerm($name, $lvl)
487 static $pcache = array();
489 if (!isset($pcache[$this->id])) {
490 $pcache[$this->id] = $this->getPerms();
492 // echo "<PRE>";print_r($pcache[$au->id]);
493 // var_dump($pcache[$au->id]);
494 if (empty($pcache[$this->id][$name])) {
498 return strpos($pcache[$this->id][$name], $lvl) > -1;
502 // ------------ROO HOOKS------------------------------------
503 function applyFilters($q, $au, $roo)
505 //DB_DataObject::DebugLevel(1);
506 if (!empty($q['query']['person_not_internal'])) {
507 $this->whereAdd(" join_company_id_id.isOwner = 0 ");
511 if (!empty($q['query']['person_internal_only_all'])) {
514 // must be internal and not current user (need for distribution list)
515 // user has a projectdirectory entry and role is not blank.
516 //DB_DataObject::DebugLevel(1);
517 $pd = DB_DataObject::factory('ProjectDirectory');
518 $pd->whereAdd("role != ''");
520 $pd->selectAdd('distinct(person_id) as person_id');
521 $roled = $pd->fetchAll('person_id');
523 {$this->tableName()}.id IN (".implode(',', $roled) . ")
525 $this->whereAdd(" join_company_id_id.comptype = 'OWNER' $rs ");
528 // -- for distribution
529 if (!empty($q['query']['person_internal_only'])) {
530 // must be internal and not current user (need for distribution list)
531 $this->whereAdd(" join_company_id_id.comptype = 'OWNER'");
533 //$this->whereAdd(($this->tableName() == 'Person' ? 'Person' : "join_person_id_id") .
534 // ".id != ".$au->id);
535 $this->whereAdd("Person.id != {$au->id}");
538 if (!empty($q['query']['comptype_or_company_id'])) {
539 // DB_DataObject::debugLevel(1);
540 $bits = explode(',', $q['query']['comptype_or_company_id']);
541 $id = (int) array_pop($bits);
542 $ct = $this->escape($bits[0]);
544 $this->whereAdd(" join_company_id_id.comptype = '$ct' OR Person.company_id = $id");
550 if (!empty($q['query']['person_inactive'])) {
551 // DB_Dataobject::debugLevel(1);
554 $tn_p = $this->tableName();
555 $tn_gm = DB_DataObject::Factory('Group_Members')->tableName();
556 $tn_g = DB_DataObject::Factory('Groups')->tableName();
558 ///---------------- Group views --------
559 if (!empty($q['query']['in_group'])) {
560 // DB_DataObject::debugLevel(1);
561 $ing = (int) $q['query']['in_group'];
562 if ($q['query']['in_group'] == -1) {
564 // list all staff who are not in a group.
565 $this->whereAdd("Person.id NOT IN (
566 SELECT distinct(user_id) FROM $tn_gm LEFT JOIN
567 $tn_g ON $tn_g.id = $tn_gm.group_id
568 WHERE $tn_g.type = ".$q['query']['type']."
574 $this->whereAdd("$tn_p.id IN (
575 SELECT distinct(user_id) FROM $tn_gm
576 WHERE group_id = $ing
582 if (!empty($q['query']['not_in_directory'])) {
583 // it's a Person list..
584 // DB_DATaobjecT::debugLevel(1);
586 // specific to project directory which is single comp. login
588 $owncomp = DB_DataObject::Factory('Companies');
589 $owncomp->get('comptype', 'OWNER');
590 if ($q['company_id'] == $owncomp->id) {
596 if ( $q['query']['not_in_directory'] > -1) {
597 $tn_pd = DB_DataObject::Factory('ProjectDirectory')->tableName();
598 // can list current - so that it does not break!!!
599 $this->whereAdd("$tn_p.id NOT IN
600 ( SELECT distinct person_id FROM $tn_pd WHERE
601 project_id = " . $q['query']['not_in_directory'] . " AND
602 company_id = " . $this->company_id . ')');
606 if (!empty($q['query']['role'])) {
607 // it's a Person list..
608 // DB_DATaobjecT::debugLevel(1);
610 // specific to project directory which is single comp. login
612 $tn_pd = DB_DataObject::Factory('ProjectDirectory')->tableName();
613 // can list current - so that it does not break!!!
614 $this->whereAdd("$tn_p.id IN
615 ( SELECT distinct person_id FROM $tn_pd WHERE
616 role = '". $this->escape($q['query']['role']) ."'
622 if (!empty($q['query']['project_member_of'])) {
623 // this is also a flag to return if they are a member..
624 //DB_DataObject::debugLevel(1);
625 $do = DB_DataObject::factory('ProjectDirectory');
626 $do->project_id = $q['query']['project_member_of'];
627 $tn_pd = DB_DataObject::Factory('ProjectDirectory')->tableName();
628 $this->joinAdd($do,array('joinType' => 'LEFT', 'useWhereAsOn' => true));
629 $this->selectAdd("IF($tn_pd.id IS NULL, 0, $tn_pd.id ) as is_member");
632 if (!empty($q['query']['project_member_filter'])) {
633 $this->having('is_member !=0');
640 if (!empty($q['query']['search'])) {
641 $s = $this->escape($q['query']['search']);
643 $tn_p.name LIKE '%$s%' OR
644 $tn_p.email LIKE '%$s%' OR
645 $tn_p.role LIKE '%$s%' OR
646 $tn_p.remarks LIKE '%$s%'
653 function setFromRoo($ar, $roo)
656 if (!empty($ar['passwd1'])) {
657 $this->setPassword($ar['passwd1']);
662 ($this->email == $roo->old->email)&&
663 ($this->company_id == $roo->old->company_id)
667 if (empty($this->email)) {
670 $xx = DB_Dataobject::factory('Person');
672 'email' => $this->email,
673 // 'company_id' => $x->company_id
677 return "Duplicate Email found";
683 * before Delete - delete significant dependancies..
684 * this is called after checkPerm..
687 function beforeDelete()
690 $e = DB_DataObject::Factory('Events');
691 $e->whereAdd('person_id = ' . $this->id);
700 * Check if the a user has access to modify this item.
701 * @param String $lvl Level (eg. Core.Projects)
702 * @param Pman_Core_DataObjects_Person $au The authenticated user.
703 * @param boolean $changes alllow changes???
705 * @return false if no access..
707 function checkPerm($lvl, $au, $changes=false) //heck who is trying to access this. false == access denied..
710 // do we have an empty system..
711 if ($au && $au->id == -1) {
715 // determine if it's staff!!!
717 if ($au->company()->comptype != 'OWNER') {
719 // - can not change company!!!
721 isset($changes['company_id']) &&
722 $changes['company_id'] != $au->company_id) {
725 // can only set new emails..
727 !empty($this->email) &&
728 isset($changes['email']) &&
729 $changes['email'] != $this->email) {
733 // edit self... - what about other staff members...
735 return $this->company_id == $au->company_id;
739 // yes, only owner company can mess with this...
740 $owncomp = DB_DataObject::Factory('Companies');
741 $owncomp->get('comptype', 'OWNER');
743 $isStaff = ($this->company_id == $owncomp->id);
747 // extra case change passwod?
748 case 'P': //??? password
749 // standard perms -- for editing + if the user is dowing them selves..
750 $ret = $isStaff ? $au->hasPerm("Core.Staff", "E") : $au->hasPerm("Core.Person", "E");
751 return $ret || $au->id == $this->id;
754 return $isStaff ? $au->hasPerm("Core.Staff", $lvl) : $au->hasPerm("Core.Person", $lvl);
759 function onInsert($req, $roo)
762 if ($roo->authUser->id < 0) {
763 $g = DB_DataObject::factory('Groups');
765 $g->get('name', 'Administrators');
767 $p = DB_DataObject::factory('Group_Members');
768 $p->group_id = $g->id;
769 $p->user_id = $this->id;
772 $roo->addEvent("ADD", $p, $g->toEventString(). " Added " . $this->toEventString());
776 if (!empty($req['project_id_addto'])) {
777 $pd = DB_DataObject::factory('ProjectDirectory');
778 $pd->project_id = $req['project_id_addto'];
779 $pd->person_id = $this->id;
781 $pd->office_id = $this->office_id;
782 $pd->company_id = $this->company_id;