· 8 years ago · May 01, 2018, 10:48 AM
1<?php
2/**
3 * @version $Id: user.php 10456 2008-06-26 17:24:13Z willebil $
4 * @package Joomla.Framework
5 * @subpackage User
6 * @copyright Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
7 * @license GNU/GPL, see LICENSE.php
8 * Joomla! is free software. This version may have been modified pursuant to the
9 * GNU General Public License, and as distributed it includes or is derivative
10 * of works licensed under the GNU General Public License or other free or open
11 * source software licenses. See COPYRIGHT.php for copyright notices and
12 * details.
13 */
14
15// Check to ensure this file is within the rest of the framework
16defined('JPATH_BASE') or die();
17
18jimport( 'joomla.html.parameter');
19
20
21/**
22 * User class. Handles all application interaction with a user
23 *
24 * @author Louis Landry <louis.landry@joomla.org>
25 * @package Joomla.Framework
26 * @subpackage User
27 * @since 1.5
28 */
29class JUser extends JObject
30{
31 /**
32 * Unique id
33 * @var int
34 */
35 var $id = null;
36
37 /**
38 * The users real name (or nickname)
39 * @var string
40 */
41 var $name = null;
42
43 /**
44 * The login name
45 * @var string
46 */
47 var $username = null;
48
49 /**
50 * The users agency name
51 * @var string
52 */
53 var $agency = null;
54
55 /**
56 * The email
57 * @var string
58 */
59 var $email = null;
60
61 /**
62 * MD5 encrypted password
63 * @var string
64 */
65 var $password = null;
66
67 /**
68 * Clear password, only available when a new password is set for a user
69 * @var string
70 */
71 var $password_clear = '';
72
73 /**
74 * Description
75 * @var string
76 */
77 var $usertype = null;
78
79 /**
80 * Description
81 * @var int
82 */
83 var $block = null;
84
85 /**
86 * Description
87 * @var int
88 */
89 var $sendEmail = null;
90
91 /**
92 * The group id number
93 * @var int
94 */
95 var $gid = null;
96
97 /**
98 * Description
99 * @var datetime
100 */
101 var $registerDate = null;
102
103 /**
104 * Description
105 * @var datetime
106 */
107 var $lastvisitDate = null;
108
109 /**
110 * Description
111 * @var string activation hash
112 */
113 var $activation = null;
114
115 /**
116 * Description
117 * @var string
118 */
119 var $params = null;
120
121 /**
122 * Description
123 * @var string integer
124 */
125 var $aid = null;
126
127 /**
128 * Description
129 * @var boolean
130 */
131 var $guest = null;
132
133 /**
134 * User parameters
135 * @var object
136 */
137 var $_params = null;
138
139 /**
140 * Error message
141 * @var string
142 */
143 var $_errorMsg = null;
144
145
146 /**
147 * Constructor activating the default information of the language
148 *
149 * @access protected
150 */
151 function __construct($identifier = 0)
152 {
153 // Create the user parameters object
154 $this->_params = new JParameter( '' );
155
156 // Load the user if it exists
157 if (!empty($identifier)) {
158 $this->load($identifier);
159 }
160 else
161 {
162 //initialise
163 $this->id = 0;
164 $this->gid = 0;
165 $this->sendEmail = 0;
166 $this->aid = 0;
167 $this->guest = 1;
168 }
169 }
170
171 /**
172 * Returns a reference to the global User object, only creating it if it
173 * doesn't already exist.
174 *
175 * This method must be invoked as:
176 * <pre> $user =& JUser::getInstance($id);</pre>
177 *
178 * @access public
179 * @param int $id The user to load - Can be an integer or string - If string, it is converted to ID automatically.
180 * @return JUser The User object.
181 * @since 1.5
182 */
183 function &getInstance($id = 0)
184 {
185 static $instances;
186
187 if (!isset ($instances)) {
188 $instances = array ();
189 }
190
191 // Find the user id
192 if(!is_numeric($id))
193 {
194 jimport('joomla.user.helper');
195 if (!$id = JUserHelper::getUserId($id)) {
196 JError::raiseWarning( 'SOME_ERROR_CODE', 'JUser::_load: User '.$id.' does not exist' );
197 $retval = false;
198 return $retval;
199 }
200 }
201
202 if (empty($instances[$id])) {
203 $user = new JUser($id);
204 $instances[$id] = $user;
205 }
206
207 return $instances[$id];
208 }
209
210 /**
211 * Method to get a parameter value
212 *
213 * @access public
214 * @param string $key Parameter key
215 * @param mixed $default Parameter default value
216 * @return mixed The value or the default if it did not exist
217 * @since 1.5
218 */
219 function getParam( $key, $default = null )
220 {
221 return $this->_params->get( $key, $default );
222 }
223
224 /**
225 * Method to set a parameter
226 *
227 * @access public
228 * @param string $key Parameter key
229 * @param mixed $value Parameter value
230 * @return mixed Set parameter value
231 * @since 1.5
232 */
233 function setParam( $key, $value )
234 {
235 return $this->_params->set( $key, $value );
236 }
237
238 /**
239 * Method to set a default parameter if it does not exist
240 *
241 * @access public
242 * @param string $key Parameter key
243 * @param mixed $value Parameter value
244 * @return mixed Set parameter value
245 * @since 1.5
246 */
247 function defParam( $key, $value )
248 {
249 return $this->_params->def( $key, $value );
250 }
251
252 /**
253 * Method to check JUser object authorization against an access control
254 * object and optionally an access extension object
255 *
256 * @access public
257 * @param string $acoSection The ACO section value
258 * @param string $aco The ACO value
259 * @param string $axoSection The AXO section value [optional]
260 * @param string $axo The AXO value [optional]
261 * @return boolean True if authorized
262 * @since 1.5
263 */
264 function authorize( $acoSection, $aco, $axoSection = null, $axo = null )
265 {
266 // the native calls (Check Mode 1) work on the user id, not the user type
267 $acl = & JFactory::getACL();
268 $value = $acl->getCheckMode() == 1 ? $this->id : $this->usertype;
269
270 return $acl->acl_check( $acoSection, $aco, 'users', $value, $axoSection, $axo );
271 }
272
273 /**
274 * Pass through method to the table for setting the last visit date
275 *
276 * @access public
277 * @param int $timestamp The timestamp, defaults to 'now'
278 * @return boolean True on success
279 * @since 1.5
280 */
281 function setLastVisit($timestamp=null)
282 {
283 // Create the user table object
284 $table =& $this->getTable();
285 $table->load($this->id);
286
287 return $table->setLastVisit($timestamp);
288 }
289
290 /**
291 * Method to get the user parameters
292 *
293 * This function tries to load an xml file based on the users usertype. The filename of the xml
294 * file is the same as the usertype. The functionals has a static variable to store the parameters
295 * setup file base path. You can call this function statically to set the base path if needed.
296 *
297 * @access public
298 * @param boolean If true, loads the parameters setup file. Default is false.
299 * @param path Set the parameters setup file base path to be used to load the user parameters.
300 * @return object The user parameters object
301 * @since 1.5
302 */
303 function &getParameters($loadsetupfile = false, $path = null)
304 {
305 static $parampath;
306
307 // Set a custom parampath if defined
308 if( isset($path) ) {
309 $parampath = $path;
310 }
311
312 // Set the default parampath if not set already
313 if( !isset($parampath) ) {
314 $parampath = JPATH_ADMINISTRATOR.DS.'components'.DS.'com_users'.DS.'models';
315 }
316
317 if($loadsetupfile)
318 {
319 $type = str_replace(' ', '_', strtolower($this->usertype));
320
321 $file = $parampath.DS.$type.'.xml';
322 if(!file_exists($file)) {
323 $file = $parampath.DS.'user.xml';
324 }
325
326 $this->_params->loadSetupFile($file);
327 }
328 return $this->_params;
329 }
330
331 /**
332 * Method to get the user parameters
333 *
334 * @access public
335 * @param object The user parameters object
336 * @since 1.5
337 */
338 function setParameters($params )
339 {
340 $this->_params = $params;
341 }
342
343 /**
344 * Method to get the user table object
345 *
346 * This function uses a static variable to store the table name of the user table to
347 * it instantiates. You can call this function statically to set the table name if
348 * needed.
349 *
350 * @access public
351 * @param string The user table name to be used
352 * @param string The user table prefix to be used
353 * @return object The user table object
354 * @since 1.5
355 */
356 function &getTable( $type = null, $prefix = 'JTable' )
357 {
358 static $tabletype;
359
360 //Set the default tabletype;
361 if(!isset($tabletype)) {
362 $tabletype['name'] = 'user';
363 $tabletype['prefix'] = 'JTable';
364 }
365
366 //Set a custom table type is defined
367 if(isset($type)) {
368 $tabletype['name'] = $type;
369 $tabletype['prefix'] = $prefix;
370 }
371
372 // Create the user table object
373 $table =& JTable::getInstance( $tabletype['name'], $tabletype['prefix'] );
374 return $table;
375 }
376
377 /**
378 * Method to bind an associative array of data to a user object
379 *
380 * @access public
381 * @param array $array The associative array to bind to the object
382 * @return boolean True on success
383 * @since 1.5
384 */
385 function bind(& $array)
386 {
387 jimport('joomla.user.helper');
388
389 // Lets check to see if the user is new or not
390 if (empty($this->id))
391 {
392 // Check the password and create the crypted password
393 if (empty($array['password'])) {
394 $array['password'] = JUserHelper::genRandomPassword();
395 $array['password2'] = $array['password'];
396 }
397
398 if ($array['password'] != $array['password2']) {
399 $this->setError( JText::_( 'PASSWORD DO NOT MATCH.' ) );
400 return false;
401 }
402
403 $this->password_clear = JArrayHelper::getValue( $array, 'password', '', 'string' );
404
405 $salt = JUserHelper::genRandomPassword(32);
406 $crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
407 $array['password'] = $crypt.':'.$salt;
408
409 // Set the registration timestamp
410
411 $now =& JFactory::getDate();
412 $this->set( 'registerDate', $now->toMySQL() );
413
414 // Check that username is not greater than 25 characters
415 $username = $this->get( 'username' );
416 if ( strlen($username) > 150 )
417 {
418 $username = substr( $username, 0, 150 );
419 $this->set( 'username', $username );
420 }
421
422 // Check that password is not greater than 50 characters
423 $password = $this->get( 'password' );
424 if ( strlen($password) > 100 )
425 {
426 $password = substr( $password, 0, 100 );
427 $this->set( 'password', $password );
428 }
429
430 // Check that agency is not greater than 50 characters
431 $agency = $this->get( 'agency' );
432 if ( strlen($agency) > 100 )
433 {
434 $agency = substr( $agency, 0, 100 );
435 $this->set( 'agency', $agency );
436 }
437 }
438 else
439 {
440 // Updating an existing user
441 if (!empty($array['password']))
442 {
443 if ( $array['password'] != $array['password2'] ) {
444 $this->setError( JText::_( 'PASSWORD DO NOT MATCH.' ) );
445 return false;
446 }
447
448 $this->password_clear = JArrayHelper::getValue( $array, 'password', '', 'string' );
449
450 $salt = JUserHelper::genRandomPassword(32);
451 $crypt = JUserHelper::getCryptedPassword($array['password'], $salt);
452 $array['password'] = $crypt.':'.$salt;
453 }
454 else
455 {
456 $array['password'] = $this->password;
457 }
458 }
459
460 // TODO: this will be deprecated as of the ACL implementation
461 $db =& JFactory::getDBO();
462
463 $gid = array_key_exists('gid', $array ) ? $array['gid'] : $this->get('gid');
464
465 $query = 'SELECT name'
466 . ' FROM #__core_acl_aro_groups'
467 . ' WHERE id = ' . (int) $gid
468 ;
469 $db->setQuery( $query );
470 $this->set( 'usertype', $db->loadResult());
471
472 if ( array_key_exists('params', $array) )
473 {
474 $params = '';
475 $this->_params->bind($array['params']);
476 if ( is_array($array['params']) ) {
477 $params = $this->_params->toString();
478 } else {
479 $params = $array['params'];
480 }
481
482 $this->params = $params;
483 }
484
485 // Bind the array
486 if (!$this->setProperties($array)) {
487 $this->setError("Unable to bind array to user object");
488 return false;
489 }
490
491 // Make sure its an integer
492 $this->id = (int) $this->id;
493
494 return true;
495 }
496
497 /**
498 * Method to save the JUser object to the database
499 *
500 * @access public
501 * @param boolean $updateOnly Save the object only if not a new user
502 * @return boolean True on success
503 * @since 1.5
504 */
505 function save( $updateOnly = false )
506 {
507 // Create the user table object
508 $table =& $this->getTable();
509 $this->params = $this->_params->toString();
510 $table->bind($this->getProperties());
511
512 // Check and store the object.
513 if (!$table->check()) {
514 $this->setError($table->getError());
515 return false;
516 }
517
518 // If user is made a Super Admin group and user is NOT a Super Admin
519 $my =& JFactory::getUser();
520 if ( $this->get('gid') == 25 && $my->get('gid') != 25 )
521 {
522 // disallow creation of Super Admin by non Super Admin users
523 $this->setError(JText::_( 'WARNSUPERADMINCREATE' ));
524 return false;
525 }
526
527 // If user is made an Admin group and user is NOT a Super Admin
528 if ($this->get('gid') == 24 && !($my->get('gid') == 25 || ($this->get('id') == $my->id && $my->get('gid') == 24)))
529 {
530 // disallow creation of Admin by non Super Admin users
531 $this->setError(JText::_( 'WARNSUPERADMINCREATE' ));
532 return false;
533 }
534
535 //are we creating a new user
536 $isnew = !$this->id;
537
538 // If we aren't allowed to create new users return
539 if ($isnew && $updateOnly) {
540 return true;
541 }
542
543 // Get the old user
544 $old = new JUser($this->id);
545
546 // Fire the onBeforeStoreUser event.
547 JPluginHelper::importPlugin( 'user' );
548 $dispatcher =& JDispatcher::getInstance();
549 $dispatcher->trigger( 'onBeforeStoreUser', array( $old->getProperties(), $isnew ) );
550
551 //Store the user data in the database
552 if (!$result = $table->store()) {
553 $this->setError($table->getError());
554 }
555
556 // Set the id for the JUser object in case we created a new user.
557 if (empty($this->id)) {
558 $this->id = $table->get( 'id' );
559 }
560
561 // Fire the onAftereStoreUser event
562 $dispatcher->trigger( 'onAfterStoreUser', array( $this->getProperties(), $isnew, $result, $this->getError() ) );
563
564 return $result;
565 }
566
567 /**
568 * Method to delete the JUser object from the database
569 *
570 * @access public
571 * @param boolean $updateOnly Save the object only if not a new user
572 * @return boolean True on success
573 * @since 1.5
574 */
575 function delete( )
576 {
577 JPluginHelper::importPlugin( 'user' );
578
579 //trigger the onBeforeDeleteUser event
580 $dispatcher =& JDispatcher::getInstance();
581 $dispatcher->trigger( 'onBeforeDeleteUser', array( $this->getProperties() ) );
582
583 // Create the user table object
584 $table =& $this->getTable();
585
586 $result = false;
587 if (!$result = $table->delete($this->id)) {
588 $this->setError($table->getError());
589 }
590
591 //trigger the onAfterDeleteUser event
592 $dispatcher->trigger( 'onAfterDeleteUser', array( $this->getProperties(), $result, $this->getError()) );
593 return $result;
594
595 }
596
597 /**
598 * Method to load a JUser object by user id number
599 *
600 * @access public
601 * @param mixed $identifier The user id of the user to load
602 * @param string $path Path to a parameters xml file
603 * @return boolean True on success
604 * @since 1.5
605 */
606 function load($id)
607 {
608 // Create the user table object
609 $table =& $this->getTable();
610
611 // Load the JUserModel object based on the user id or throw a warning.
612 if(!$table->load($id)) {
613 JError::raiseWarning( 'SOME_ERROR_CODE', 'JUser::_load: Unable to load user with id: '.$id );
614 return false;
615 }
616
617 /*
618 * Set the user parameters using the default xml file. We might want to
619 * extend this in the future to allow for the ability to have custom
620 * user parameters, but for right now we'll leave it how it is.
621 */
622 $this->_params->loadINI($table->params);
623
624 // Assuming all is well at this point lets bind the data
625 $this->setProperties($table->getProperties());
626
627 return true;
628 }
629}