Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  
   3  namespace IMSGlobal\LTI\ToolProvider;
   4  use IMSGlobal\LTI\ToolProvider\DataConnector\DataConnector;
   5  
   6  /**
   7   * Class to represent a tool consumer user
   8   *
   9   * @author  Stephen P Vickers <svickers@imsglobal.org>
  10   * @copyright  IMS Global Learning Consortium Inc
  11   * @date  2016
  12   * @version 3.0.2
  13   * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  14   */
  15  class User
  16  {
  17  
  18  /**
  19   * User's first name.
  20   *
  21   * @var string $firstname
  22   */
  23      public $firstname = '';
  24  /**
  25   * User's last name (surname or family name).
  26   *
  27   * @var string $lastname
  28   */
  29      public $lastname = '';
  30  /**
  31   * User's fullname.
  32   *
  33   * @var string $fullname
  34   */
  35      public $fullname = '';
  36  /**
  37   * User's email address.
  38   *
  39   * @var string $email
  40   */
  41      public $email = '';
  42  /**
  43   * User's image URI.
  44   *
  45   * @var string $image
  46   */
  47      public $image = '';
  48  /**
  49   * Roles for user.
  50   *
  51   * @var array $roles
  52   */
  53      public $roles = array();
  54  /**
  55   * Groups for user.
  56   *
  57   * @var array $groups
  58   */
  59      public $groups = array();
  60  /**
  61   * User's result sourcedid.
  62   *
  63   * @var string $ltiResultSourcedId
  64   */
  65      public $ltiResultSourcedId = null;
  66  /**
  67   * Date/time the record was created.
  68   *
  69   * @var object $created
  70   */
  71      public $created = null;
  72  /**
  73   * Date/time the record was last updated.
  74   *
  75   * @var object $updated
  76   */
  77      public $updated = null;
  78  
  79  /**
  80   * Resource link object.
  81   *
  82   * @var ResourceLink $resourceLink
  83   */
  84      private $resourceLink = null;
  85  /**
  86   * Resource link record ID.
  87   *
  88   * @var int $resourceLinkId
  89   */
  90      private $resourceLinkId = null;
  91  /**
  92   * User record ID value.
  93   *
  94   * @var string $id
  95   */
  96      private $id = null;
  97  /**
  98   * user ID as supplied in the last connection request.
  99   *
 100   * @var string $ltiUserId
 101   */
 102      public $ltiUserId = null;
 103  /**
 104   * Data connector object or string.
 105   *
 106   * @var mixed $dataConnector
 107   */
 108      private $dataConnector = null;
 109  
 110  /**
 111   * Class constructor.
 112   */
 113      public function __construct()
 114      {
 115  
 116          $this->initialize();
 117  
 118      }
 119  
 120  /**
 121   * Initialise the user.
 122   */
 123      public function initialize()
 124      {
 125  
 126          $this->firstname = '';
 127          $this->lastname = '';
 128          $this->fullname = '';
 129          $this->email = '';
 130          $this->image = '';
 131          $this->roles = array();
 132          $this->groups = array();
 133          $this->ltiResultSourcedId = null;
 134          $this->created = null;
 135          $this->updated = null;
 136  
 137      }
 138  
 139  /**
 140   * Initialise the user.
 141   *
 142   * Pseudonym for initialize().
 143   */
 144      public function initialise()
 145      {
 146  
 147          $this->initialize();
 148  
 149      }
 150  
 151  /**
 152   * Save the user to the database.
 153   *
 154   * @return boolean True if the user object was successfully saved
 155   */
 156      public function save()
 157      {
 158  
 159          if (!empty($this->ltiResultSourcedId) && !is_null($this->resourceLinkId)) {
 160              $ok = $this->getDataConnector()->saveUser($this);
 161          } else {
 162              $ok = true;
 163          }
 164  
 165          return $ok;
 166  
 167      }
 168  
 169  /**
 170   * Delete the user from the database.
 171   *
 172   * @return boolean True if the user object was successfully deleted
 173   */
 174      public function delete()
 175      {
 176  
 177          $ok = $this->getDataConnector()->deleteUser($this);
 178  
 179          return $ok;
 180  
 181      }
 182  
 183  /**
 184   * Get resource link.
 185   *
 186   * @return ResourceLink Resource link object
 187   */
 188      public function getResourceLink()
 189      {
 190  
 191          if (is_null($this->resourceLink) && !is_null($this->resourceLinkId)) {
 192              $this->resourceLink = ResourceLink::fromRecordId($this->resourceLinkId, $this->getDataConnector());
 193          }
 194  
 195          return $this->resourceLink;
 196  
 197      }
 198  
 199  /**
 200   * Get record ID of user.
 201   *
 202   * @return int Record ID of user
 203   */
 204      public function getRecordId()
 205      {
 206  
 207          return $this->id;
 208  
 209      }
 210  
 211  /**
 212   * Set record ID of user.
 213   *
 214   * @param int $id  Record ID of user
 215   */
 216      public function setRecordId($id)
 217      {
 218  
 219          $this->id = $id;
 220  
 221      }
 222  
 223  /**
 224   * Set resource link ID of user.
 225   *
 226   * @param int $resourceLinkId  Resource link ID of user
 227   */
 228      public function setResourceLinkId($resourceLinkId)
 229      {
 230  
 231          $this->resourceLinkId = $resourceLinkId;
 232  
 233      }
 234  
 235  /**
 236   * Get the data connector.
 237   *
 238   * @return mixed Data connector object or string
 239   */
 240      public function getDataConnector()
 241      {
 242  
 243          return $this->dataConnector;
 244  
 245      }
 246  
 247  /**
 248   * Get the user ID (which may be a compound of the tool consumer and resource link IDs).
 249   *
 250   * @param int $idScope Scope to use for user ID (optional, default is null for consumer default setting)
 251   *
 252   * @return string User ID value
 253   */
 254      public function getId($idScope = null)
 255      {
 256  
 257          if (empty($idScope)) {
 258              if (!is_null($this->resourceLink)) {
 259                  $idScope = $this->resourceLink->getConsumer()->idScope;
 260              } else {
 261                  $idScope = ToolProvider::ID_SCOPE_ID_ONLY;
 262              }
 263          }
 264          switch ($idScope) {
 265              case ToolProvider::ID_SCOPE_GLOBAL:
 266                  $id = $this->getResourceLink()->getKey() . ToolProvider::ID_SCOPE_SEPARATOR . $this->ltiUserId;
 267                  break;
 268              case ToolProvider::ID_SCOPE_CONTEXT:
 269                  $id = $this->getResourceLink()->getKey();
 270                  if ($this->resourceLink->ltiContextId) {
 271                      $id .= ToolProvider::ID_SCOPE_SEPARATOR . $this->resourceLink->ltiContextId;
 272                  }
 273                  $id .= ToolProvider::ID_SCOPE_SEPARATOR . $this->ltiUserId;
 274                  break;
 275              case ToolProvider::ID_SCOPE_RESOURCE:
 276                  $id = $this->getResourceLink()->getKey();
 277                  if ($this->resourceLink->ltiResourceLinkId) {
 278                      $id .= ToolProvider::ID_SCOPE_SEPARATOR . $this->resourceLink->ltiResourceLinkId;
 279                  }
 280                  $id .= ToolProvider::ID_SCOPE_SEPARATOR . $this->ltiUserId;
 281                  break;
 282              default:
 283                  $id = $this->ltiUserId;
 284                  break;
 285          }
 286  
 287          return $id;
 288  
 289      }
 290  
 291  /**
 292   * Set the user's name.
 293   *
 294   * @param string $firstname User's first name.
 295   * @param string $lastname User's last name.
 296   * @param string $fullname User's full name.
 297   */
 298      public function setNames($firstname, $lastname, $fullname)
 299      {
 300  
 301          $names = array(0 => '', 1 => '');
 302          if (!empty($fullname)) {
 303              $this->fullname = trim($fullname);
 304              $names = preg_split("/[\s]+/", $this->fullname, 2);
 305          }
 306          if (!empty($firstname)) {
 307              $this->firstname = trim($firstname);
 308              $names[0] = $this->firstname;
 309          } else if (!empty($names[0])) {
 310              $this->firstname = $names[0];
 311          } else {
 312              $this->firstname = 'User';
 313          }
 314          if (!empty($lastname)) {
 315              $this->lastname = trim($lastname);
 316              $names[1] = $this->lastname;
 317          } else if (!empty($names[1])) {
 318              $this->lastname = $names[1];
 319          } else {
 320              $this->lastname = $this->ltiUserId;
 321          }
 322          if (empty($this->fullname)) {
 323              $this->fullname = "{$this->firstname} {$this->lastname}";
 324          }
 325  
 326      }
 327  
 328  /**
 329   * Set the user's email address.
 330   *
 331   * @param string $email        Email address value
 332   * @param string $defaultEmail Value to use if no email is provided (optional, default is none)
 333   */
 334      public function setEmail($email, $defaultEmail = null)
 335      {
 336  
 337        if (!empty($email)) {
 338            $this->email = $email;
 339        } else if (!empty($defaultEmail)) {
 340            $this->email = $defaultEmail;
 341            if (substr($this->email, 0, 1) === '@') {
 342                $this->email = $this->getId() . $this->email;
 343            }
 344        } else {
 345            $this->email = '';
 346        }
 347  
 348      }
 349  
 350  /**
 351   * Check if the user is an administrator (at any of the system, institution or context levels).
 352   *
 353   * @return boolean True if the user has a role of administrator
 354   */
 355      public function isAdmin()
 356      {
 357  
 358          return $this->hasRole('Administrator') || $this->hasRole('urn:lti:sysrole:ims/lis/SysAdmin') ||
 359                 $this->hasRole('urn:lti:sysrole:ims/lis/Administrator') || $this->hasRole('urn:lti:instrole:ims/lis/Administrator');
 360  
 361      }
 362  
 363  /**
 364   * Check if the user is staff.
 365   *
 366   * @return boolean True if the user has a role of instructor, contentdeveloper or teachingassistant
 367   */
 368      public function isStaff()
 369      {
 370  
 371          return ($this->hasRole('Instructor') || $this->hasRole('ContentDeveloper') || $this->hasRole('TeachingAssistant'));
 372  
 373      }
 374  
 375  /**
 376   * Check if the user is a learner.
 377   *
 378   * @return boolean True if the user has a role of learner
 379   */
 380      public function isLearner()
 381      {
 382  
 383          return $this->hasRole('Learner');
 384  
 385      }
 386  
 387  /**
 388   * Load the user from the database.
 389   *
 390   * @param int $id     Record ID of user
 391   * @param DataConnector   $dataConnector    Database connection object
 392   *
 393   * @return User  User object
 394   */
 395      public static function fromRecordId($id, $dataConnector)
 396      {
 397  
 398          $user = new User();
 399          $user->dataConnector = $dataConnector;
 400          $user->load($id);
 401  
 402          return $user;
 403  
 404      }
 405  
 406  /**
 407   * Class constructor from resource link.
 408   *
 409   * @param ResourceLink $resourceLink Resource_Link object
 410   * @param string $ltiUserId User ID value
 411   * @return User
 412   */
 413      public static function fromResourceLink($resourceLink, $ltiUserId)
 414      {
 415  
 416          $user = new User();
 417          $user->resourceLink = $resourceLink;
 418          if (!is_null($resourceLink)) {
 419              $user->resourceLinkId = $resourceLink->getRecordId();
 420              $user->dataConnector = $resourceLink->getDataConnector();
 421          }
 422          $user->ltiUserId = $ltiUserId;
 423          if (!empty($ltiUserId)) {
 424              $user->load();
 425          }
 426  
 427          return $user;
 428  
 429      }
 430  
 431  ###
 432  ###  PRIVATE METHODS
 433  ###
 434  
 435  /**
 436   * Check whether the user has a specified role name.
 437   *
 438   * @param string $role Name of role
 439   *
 440   * @return boolean True if the user has the specified role
 441   */
 442      private function hasRole($role) {
 443  
 444          if (substr($role, 0, 4) !== 'urn:')
 445          {
 446              $role = 'urn:lti:role:ims/lis/' . $role;
 447          }
 448  
 449          return in_array($role, $this->roles);
 450  
 451      }
 452  
 453  /**
 454   * Load the user from the database.
 455   *
 456   * @param int $id     Record ID of user (optional, default is null)
 457   *
 458   * @return boolean True if the user object was successfully loaded
 459   */
 460      private function load($id = null)
 461      {
 462  
 463          $this->initialize();
 464          $this->id = $id;
 465          $dataConnector = $this->getDataConnector();
 466          if (!is_null($dataConnector)) {
 467              return $dataConnector->loadUser($this);
 468          }
 469  
 470          return false;
 471      }
 472  
 473  }