Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

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