root/trunk/lib/model/PluginsfGuardUser.php

Revision 74, 18.1 kB (checked in by nperriault, 3 months ago)

Forthport of r73: Fixed user model class incorrectly calculates the age of a member (thanks to Russ)

<
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  *
13  * @package    symfony
14  * @subpackage plugin
15  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
16  * @version    SVN: $Id: PluginsfGuardUser.php 7995 2008-03-20 06:58:43Z fabien $
17  */
18 class PluginsfGuardUser extends BasesfGuardUser
19 {
20   protected
21     $profile        = null,
22     $groups         = null,
23     $permissions    = null,
24     $allPermissions = null;
25
26   /**
27    * Human readable string representation for current object instance
28    *
29    * @return string
30    */
31   public function __toString()
32   {
33     return $this->getDisplayName();
34   }
35
36   /**
37    * Adds a skill tag to current person
38    *
39    * @param  mixed  $skills
40    */
41   public function addSkill($skills)
42   {
43     return $this->addTag($skills);
44   }
45
46   /**
47    * Retrieves calculated user age
48    *
49    * @return int
50    */
51   public function getAge()
52   {
53     $age = null;
54
55     if ($this->getBirthdate())
56     {
57       $age   = date("Y") - (int) $this->getBirthdate('Y');
58       $month = (int) $this->getBirthdate('m');
59       $day   = (int) $this->getBirthdate('d');
60
61       if (date("m") < $month || (date("m") == $month && date("d") < $day))
62       {
63         --$age;
64       }
65     }
66
67     return $age;
68   }
69
70   /**
71    * Check if user allow to be contacted. If he published a job offer in its own
72    * name, we override his settings
73    *
74    * @param  boolean  $check_jobs  Check if user has submitted a job in his name
75    * @return boolean
76    */
77   public function getAllowContact($check_jobs = false)
78   {
79     $allow = parent::getAllowContact();
80
81     if ($check_jobs && $this->countJobs(new Criteria) > 0)
82     {
83       $allow = true;
84     }
85
86     return $allow;
87   }
88
89   /**
90    * Retrieves companies associated with current user
91    *
92    * @param  string  $type  Filter type (submitted, related, all)
93    * @return array
94    */
95   public function getCompanies($type = 'submitted')
96   {
97     $c = new Criteria();
98     $c->add(CompanyPeer::IS_ACTIVE, true);
99     $c->addAscendingOrderByColumn(CompanyPeer::NAME);
100     switch ($type)
101     {
102       case 'all':
103         $companies = CompanyPeer::doSelect($c);
104       break;
105       case 'related':
106         $c->addJoin(CompanyPersonPeer::COMPANY_ID, CompanyPeer::ID);
107         $c->add(CompanyPersonPeer::USER_ID, $this->getId());
108         $companies = CompanyPeer::doSelect($c);
109       break;
110       case 'submitted':
111       default:
112         $companies = $this->getCompanys($c);
113       break;
114     }
115     return $companies;
116   }
117
118   /**
119    * Retrieves simple hash of related companies. Useful for populating a select
120    * html tag
121    *
122    * @param  string  $type  Filter type (submitted, related, all)
123    * @return array
124    */
125   public function getCompaniesArray($type = 'submitted')
126   {
127     $companies = array();
128     foreach ($this->getCompanies($type) as $company)
129     {
130       $companies[$company->getId()] = $company->getName();
131     }
132     return $companies;
133   }
134
135   /**
136    * Returns related companies string
137    *
138    * @param  string  $separator
139    * @return string
140    */
141   public function getCompaniesString($separator = ', ')
142   {
143     $companies = array();
144     foreach ($this->getCompanies('related') as $company)
145     {
146       $companies[] = $company->getName();
147     }
148     return implode($separator, $companies);
149   }
150
151   /**
152    * Retrieves country name
153    *
154    * @return string
155    */
156   public function getCountryName()
157   {
158     if ($this->getCountry())
159     {
160       sfLoader::loadHelpers('I18N');
161       return format_country($this->getCountry());
162     }
163   }
164
165   /**
166    * Retrieves user display name
167    *
168    * @return string
169    */
170   public function getDisplayName()
171   {
172     $display_name = parent::getDisplayName();
173     if (!is_null($display_name) && trim($display_name))
174     {
175       return $display_name;
176     }
177     else
178     {
179       return parent::getUsername();
180     }
181   }
182
183   /**
184    * Retrieves related applications
185    *
186    * @param  Criteria  $c
187    * @return array
188    */
189   public function getRelatedApplications(Criteria $c = null)
190   {
191     if (!$c instanceof Criteria)
192     {
193       $c = new Criteria;
194     }
195     $c->addJoin(ApplicationDeveloperPeer::APPLICATION_ID, ApplicationPeer::ID);
196     $c->addJoin(ApplicationDeveloperPeer::DEVELOPER_ID, sfGuardUserPeer::ID);
197     $c->add(sfGuardUserPeer::ID, $this->getId());
198     return ApplicationPeer::doSelect($c);
199   }
200
201   /**
202    * Retrieves related applications and return their names in a string
203    *
204    * @param  string  $separator
205    * @return string
206    */
207   public function getRelatedApplicationsString(Criteria $c = null, $separator = ', ')
208   {
209     if (!$c instanceof Criteria)
210     {
211       $c = new Criteria;
212     }
213     $applications = array();
214     foreach ($this->getRelatedApplications($c) as $application)
215     {
216      $applications[] = $application->getName();
217     }
218     return implode($separator, $applications);
219   }
220
221   /**
222    * Retrieves related companies
223    *
224    * @param  Criteria  $c
225    * @return array
226    */
227   public function getRelatedCompanies(Criteria $c = null)
228   {
229     if (!$c instanceof Criteria)
230     {
231       $c = new Criteria;
232     }
233     $c->addJoin(CompanyPersonPeer::COMPANY_ID, CompanyPeer::ID);
234     $c->addJoin(CompanyPersonPeer::USER_ID, sfGuardUserPeer::ID);
235     $c->add(sfGuardUserPeer::ID, $this->getId());
236     return CompanyPeer::doSelect($c);
237   }
238
239   /**
240    * Retrieves mail sender address, in the form "Firstname Lastname" <name@isp.tld>
241    *
242    * @return string
243    */
244   public function getEmailSender()
245   {
246     return sprintf('"%s" <%s>', $this->getDisplayName(), $this->getEmail());
247   }
248
249   /**
250    * Retrieves complete user geographical address in one line. This method is
251    * mainly used for google maps links.
252    *
253    * @return string
254    */
255   public function getFullAddress()
256   {
257     sfLoader::loadHelpers('I18N');
258     $address = sprintf('%s %s %s %s, %s (%s)',
259                       $this->getAddress(),
260                       $this->getZip(),
261                       $this->getCity(),
262                       $this->getState(),
263                       format_country($this->getCountry()),
264                       $this->getDisplayName());
265     return SymfoniansToolkit::onelinize($address);
266   }
267
268   /**
269    * Retrieves user location
270    *
271    * @return string
272    */
273   public function getLocation()
274   {
275     sfLoader::loadHelpers('I18N');
276     $address = sprintf('%s %s %s %s, %s',
277                       $this->getAddress(),
278                       $this->getZip(),
279                       $this->getCity(),
280                       $this->getState(),
281                       format_country($this->getCountry()));
282     return SymfoniansToolkit::onelinize($address);
283   }
284
285   /**
286    * Return avatar path, with optional stored format
287    *
288    * @param  string  $format (small16, small48, standard)
289    * @return string
290    */
291   public function getAvatarPath($format = 'standard')
292   {
293     if (!parent::getAvatarPath())
294     {
295       return null;
296     }
297
298     return sprintf('/%s/%s', $format, parent::getAvatarPath());
299   }
300
301   /**
302    * Checks if a user has entered an address
303    *
304    * @return boolean
305    */
306   public function hasAddress()
307   {
308     return $this->getCountry() && $this->getCity();
309   }
310
311   /**
312    * Checks if a user has been recommended by another given user
313    *
314    * @param sfGuardUser $user
315    * @return boolean
316    */
317   public function hasBeenRecommendedBy($user)
318   {
319     if ($user instanceof sfOutputEscaperObjectDecorator)
320     {
321       $user = $user->getRawValue();
322     }
323
324     if ($user instanceof sfGuardUser)
325     {
326       $user = $user->getId();
327     }
328
329     $c = new Criteria();
330     $c->add(RecommendationPeer::RECOMMENDED_ID, $this->getId());
331     $c->add(RecommendationPeer::RECOMMENDER_ID, $user);
332
333     return (RecommendationPeer::doCount($c) > 0);
334   }
335
336   /**
337    * Check if current user has given skill name
338    *
339    * @param  string  $skill
340    * @return boolean
341    */
342   public function hasSkill($skill)
343   {
344     return $this->hasTag($skill);
345   }
346
347   /**
348    * Set user passord
349    *
350    * @param string $password
351    */
352   public function setPassword($password)
353   {
354     if (!$password)
355     {
356       return;
357     }
358
359     $salt = md5(rand(100000, 999999).$this->getUsername());
360     $this->setSalt($salt);
361     $algorithm = sfConfig::get('app_sf_guard_plugin_algorithm_callable', 'sha1');
362     $algorithmAsStr = is_array($algorithm) ? $algorithm[0].'::'.$algorithm[1] : $algorithm;
363     if (!is_callable($algorithm))
364     {
365       throw new sfException(sprintf('The algorithm callable "%s" is not callable.', $algorithmAsStr));
366     }
367     $this->setAlgorithm($algorithmAsStr);
368
369     parent::setPassword(call_user_func_array($algorithm, array($salt.$password)));
370   }
371
372   public function setPasswordBis($password)
373   {
374   }
375
376   public function setPasswordHash($v)
377   {
378     if (!is_null($v) && !is_string($v))
379     {
380       $v = (string) $v;
381     }
382
383     if ($this->password !== $v)
384     {
385       $this->password = $v;
386       $this->modifiedColumns[] = sfGuardUserPeer::PASSWORD;
387     }
388   }
389
390   /**
391    * Checks if given password matches current user one
392    *
393    * @param string $password
394    * @return boolean
395    */
396   public function checkPassword($password)
397   {
398     if ($callable = sfConfig::get('app_sf_guard_plugin_check_password_callable'))
399     {
400       return call_user_func_array($callable, array($this->getUsername(), $password));
401     }
402     else
403     {
404       return $this->checkPasswordByGuard($password);
405     }
406   }
407
408   /**
409    * Checks password
410    *
411    * @param string $password
412    * @return boolean
413    */
414   public function checkPasswordByGuard($password)
415   {
416     $algorithm = $this->getAlgorithm();
417
418     if (false !== $pos = strpos($algorithm, '::'))
419     {
420       $algorithm = array(substr($algorithm, 0, $pos), substr($algorithm, $pos + 2));
421     }
422
423     if (!is_callable($algorithm))
424     {
425       throw new sfException(sprintf('The algorithm callable "%s" is not callable.', $algorithm));
426     }
427
428     return $this->getPassword() == call_user_func_array($algorithm, array($this->getSalt().$password));
429   }
430
431   public function getProfile()
432   {
433     if (!is_null($this->profile))
434     {
435       return $this->profile;
436     }
437
438     $profileClass = sfConfig::get('app_sf_guard_plugin_profile_class', 'sfGuardUserProfile');
439     if (!class_exists($profileClass))
440     {
441       throw new sfException(sprintf('The user profile class "%s" does not exist.', $profileClass));
442     }
443
444     $fieldName = sfConfig::get('app_sf_guard_plugin_profile_field_name', 'user_id');
445     $profilePeerClass $profileClass.'Peer';
446
447     // to avoid php segmentation fault
448     class_exists($profilePeerClass);
449
450     $foreignKeyColumn = call_user_func_array(array($profilePeerClass, 'translateFieldName'), array($fieldName, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME));
451
452     if (!$foreignKeyColumn)
453     {
454       throw new sfException(sprintf('The user profile class "%s" does not contain a "%s" column.', $profileClass, $fieldName));
455     }
456
457     $c = new Criteria();
458     $c->add($foreignKeyColumn, $this->getId());
459
460     $this->profile = call_user_func_array(array($profileClass.'Peer', 'doSelectOne'), array($c));
461
462     if (!$this->profile)
463     {
464       $this->profile = new $profileClass();
465       if (method_exists($this->profile, 'setsfGuardUser'))
466       {
467         $this->profile->setsfGuardUser($this);
468       }
469       else
470       {
471         $method = 'set'.call_user_func_array(array($profilePeerClass, 'translateFieldName'), array($fieldName, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME));
472         $this->profile->$method($this->getId());
473       }
474     }
475
476     return $this->profile;
477   }
478
479   public function getPlace()
480   {
481     sfLoader::loadHelpers('I18N');
482     $address = sprintf('%s %s %s %s %s',
483                       $this->getAddress(),
484                       $this->getZip(),
485                       $this->getCity(),
486                       $this->getState(),
487                       format_country($this->getCountry()));
488     return SymfoniansToolkit::onelinize($address);
489   }
490
491   /**
492    * Retrieves all recommendations received by current user. Mainly a proxy to
493    * the ugly named "getRecommendationsRelatedByRecommendedId" method.
494    *
495    * @param  Criteria   $c
496    * @param  Connection $con
497    * @return array
498    */
499   public function getReceivedRecommendations(Criteria $c = null, $con = null)
500   {
501     if (!$c instanceof Criteria)
502     {
503       $c = new Criteria;
504     }
505     $c->addDescendingOrderByColumn(RecommendationPeer::UPDATED_AT);
506     return $this->getRecommendationsRelatedByRecommendedId($c, $con);
507   }
508
509   /**
510    * Retrieves all recommendations sent by current user. Mainly a proxy to the
511    * ugly named "getRecommendationsRelatedByRecommenderId" method.
512    *
513    * @param  Criteria   $c
514    * @param  Connection $con
515    * @return array
516    */
517   public function getSentRecommendations(Criteria $c = null, $con = null)
518   {
519     if (!$c instanceof Criteria)
520     {
521       $c = new Criteria;
522     }
523     $c->addDescendingOrderByColumn(RecommendationPeer::UPDATED_AT);
524     return $this->getRecommendationsRelatedByRecommenderId($c, $con);
525   }
526
527   /**
528    * Get user skill tags
529    *
530    * @return array
531    */
532   public function getSkills()
533   {
534     return $this->getTags();
535   }
536
537   /**
538    * Get user skill tags string
539    *
540    * @return string
541    */
542   public function getSkillsString($separator = ', ')
543   {
544     return implode($separator, $this->getSkills());
545   }
546
547   public function addGroupByName($name, $con = null)
548   {
549     $group = sfGuardGroupPeer::retrieveByName($name);
550     if (!$group)
551     {
552       throw new Exception(sprintf('The group "%s" does not exist.', $name));
553     }
554
555     $ug = new sfGuardUserGroup();
556     $ug->setsfGuardUser($this);
557     $ug->setGroupId($group->getId());
558
559     $ug->save($con);
560   }
561
562   public function addPermissionByName($name, $con = null)
563   {
564     $permission = sfGuardPermissionPeer::retrieveByName($name);
565     if (!$permission)
566     {
567       throw new Exception(sprintf('The permission "%s" does not exist.', $name));
568     }
569
570     $up = new sfGuardUserPermission();
571     $up->setsfGuardUser($this);
572     $up->setPermissionId($permission->getId());
573
574     $up->save($con);
575   }
576
577   public function hasGroup($name)
578   {
579     if (!$this->groups)
580     {
581       $this->getGroups();
582     }
583
584     return isset($this->groups[$name]);
585   }
586
587   public function getGroups()
588   {
589     if (!$this->groups)
590     {
591       $this->groups = array();
592
593       $c = new Criteria();
594       $c->add(sfGuardUserGroupPeer::USER_ID, $this->getId());
595       $ugs = sfGuardUserGroupPeer::doSelectJoinsfGuardGroup($c);
596
597       foreach ($ugs as $ug)
598       {
599         $group = $ug->getsfGuardGroup();
600         $this->groups[$group->getName()] = $group;
601       }
602     }
603
604     return $this->groups;
605   }
606
607   public function getGroupNames()
608   {
609     return array_keys($this->getGroups());
610   }
611
612   public function hasPermission($name)
613   {