Open Monograph Press  3.3.0
UserDAO.inc.php
1 <?php
2 
17 import('lib.pkp.classes.user.User');
18 
19 /* These constants are used user-selectable search fields. */
20 define('USER_FIELD_USERID', 'user_id');
21 define('USER_FIELD_USERNAME', 'username');
22 define('USER_FIELD_EMAIL', 'email');
23 define('USER_FIELD_URL', 'url');
24 define('USER_FIELD_INTERESTS', 'interests');
25 define('USER_FIELD_AFFILIATION', 'affiliation');
26 define('USER_FIELD_NONE', null);
27 
28 class UserDAO extends DAO {
29 
34  function newDataObject() {
35  return new User();
36  }
37 
44  function getById($userId, $allowDisabled = true) {
45  $result = $this->retrieve(
46  'SELECT * FROM users WHERE user_id = ?' . ($allowDisabled?'':' AND disabled = 0'),
47  array((int) $userId)
48  );
49 
50  $user = null;
51  if ($result->RecordCount() != 0) {
52  $user = $this->_returnUserFromRowWithData($result->GetRowAssoc(false));
53  }
54  $result->Close();
55  return $user;
56  }
57 
64  function getByUsername($username, $allowDisabled = true) {
65  $result = $this->retrieve(
66  'SELECT * FROM users WHERE username = ?' . ($allowDisabled?'':' AND disabled = 0'),
67  array($username)
68  );
69 
70  $user = null;
71  if ($result->RecordCount() != 0) {
72  $user = $this->_returnUserFromRowWithData($result->GetRowAssoc(false));
73  }
74  $result->Close();
75  return $user;
76  }
77 
85  function getBySetting($settingName, $settingValue, $allowDisabled = true) {
86  $result = $this->retrieve(
87  'SELECT u.* FROM users u JOIN user_settings us ON (u.user_id = us.user_id) WHERE us.setting_name = ? AND us.setting_value = ?' . ($allowDisabled?'':' AND u.disabled = 0'),
88  array($settingName, $settingValue)
89  );
90 
91  $user = null;
92  if ($result->RecordCount() != 0) {
93  $user = $this->_returnUserFromRowWithData($result->GetRowAssoc(false));
94  }
95  $result->Close();
96  return $user;
97  }
98 
105  function getUserByAuthStr($authstr, $allowDisabled = true) {
106  $result = $this->retrieve(
107  'SELECT * FROM users WHERE auth_str = ?' . ($allowDisabled?'':' AND disabled = 0'),
108  array($authstr)
109  );
110 
111  $user = null;
112  if ($result->RecordCount() != 0) {
113  $user = $this->_returnUserFromRowWithData($result->GetRowAssoc(false));
114  }
115  $result->Close();
116  return $user;
117  }
118 
125  function getUserByEmail($email, $allowDisabled = true) {
126  $result = $this->retrieve(
127  'SELECT * FROM users WHERE email = ?' . ($allowDisabled?'':' AND disabled = 0'),
128  array($email)
129  );
130 
131  $user = null;
132  if ($result->RecordCount() != 0) {
133  $user = $this->_returnUserFromRowWithData($result->GetRowAssoc(false));
134  }
135  $result->Close();
136  return $user;
137  }
138 
146  function getUserByCredentials($username, $password, $allowDisabled = true) {
147  $result = $this->retrieve(
148  'SELECT * FROM users WHERE username = ? AND password = ?' . ($allowDisabled?'':' AND disabled = 0'),
149  array($username, $password)
150  );
151 
152  $user = null;
153  if ($result->RecordCount() != 0) {
154  $user = $this->_returnUserFromRowWithData($result->GetRowAssoc(false));
155  }
156  $result->Close();
157  return $user;
158  }
159 
167  function getReviewersForSubmission($contextId, $submissionId, $round) {
168  $params = array(
169  (int) $contextId,
170  ROLE_ID_REVIEWER,
171  (int) $submissionId,
172  (int) $round
173  );
174  $params = array_merge($this->getFetchParameters(), $params);
175 
176  $result = $this->retrieve(
177  'SELECT u.* ,
178  ' . $this->getFetchColumns() . '
179  FROM users u
180  LEFT JOIN user_user_groups uug ON (uug.user_id = u.user_id)
181  LEFT JOIN user_groups ug ON (ug.user_group_id = uug.user_group_id)
182  LEFT JOIN review_assignments r ON (r.reviewer_id = u.user_id)
183  ' . $this->getFetchJoins() . '
184  WHERE ug.context_id = ? AND
185  ug.role_id = ? AND
186  r.submission_id = ? AND
187  r.round = ?
188  ' . $this->getOrderBy(),
189  $params
190  );
191 
192  return new DAOResultFactory($result, $this, '_returnUserFromRowWithData');
193  }
194 
203  function getReviewersNotAssignedToSubmission($contextId, $submissionId, &$reviewRound, $name = '') {
204  $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /* @var $reviewAssignmentDao ReviewAssignmentDAO */
205 
206  $params = array(
207  (int) $contextId,
208  ROLE_ID_REVIEWER,
209  (int) $reviewRound->getStageId(),
210  );
211  $params = array_merge($params, $this->getFetchParameters());
212  $params[] = (int) $submissionId;
213  $params[] = (int) $reviewRound->getId();
214  if (!empty($name)) {
215  $nameSearchJoins = 'LEFT JOIN user_settings usgs ON (u.user_id = usgs.user_id AND usgs.setting_name = \'' . IDENTITY_SETTING_GIVENNAME .'\')
216  LEFT JOIN user_settings usfs ON (u.user_id = usfs.user_id AND usfs.setting_name = \'' . IDENTITY_SETTING_FAMILYNAME .'\')';
217  $params[] = $params[] = $params[] = $params[] = "%$name%";
218  }
219 
220  $result = $this->retrieve(
221  'SELECT DISTINCT u.*,
222  ' . $this->getFetchColumns() .'
223  FROM users u
224  JOIN user_user_groups uug ON (uug.user_id = u.user_id)
225  JOIN user_groups ug ON (ug.user_group_id = uug.user_group_id AND ug.context_id = ? AND ug.role_id = ?)
226  JOIN user_group_stage ugs ON (ugs.user_group_id = ug.user_group_id AND ugs.stage_id = ?)' .
227  (!empty($name) ? $nameSearchJoins : '') .'
228  ' . $this->getFetchJoins() . '
229  WHERE 0=(SELECT COUNT(r.reviewer_id)
230  FROM review_assignments r
231  WHERE r.submission_id = ? AND r.reviewer_id = u.user_id AND r.review_round_id = ?)' .
232  (!empty($name) ?' AND (usgs.setting_value LIKE ? OR usfs.setting_value LIKE ? OR username LIKE ? OR email LIKE ?)' : '') .'
233  ' .$this->getOrderBy(),
234  $params
235  );
236  return new DAOResultFactory($result, $this, '_returnUserFromRowWithData');
237  }
238 
245  function _returnUserFromRowWithReviewerStats($row) {
246  $user = $this->_returnUserFromRowWithData($row, false);
247  $user->setData('lastAssigned', $row['last_assigned']);
248  $user->setData('incompleteCount', (int) $row['incomplete_count']);
249  $user->setData('completeCount', (int) $row['complete_count']);
250  $user->setData('declinedCount', (int) $row['declined_count']);
251  $user->setData('cancelledCount', (int) $row['cancelled_count']);
252  $user->setData('averageTime', (int) $row['average_time']);
253 
254  // 0 values should return null. They represent a reviewer with no ratings
255  if ($row['reviewer_rating']) {
256  $user->setData('reviewerRating', max(1, round($row['reviewer_rating'])));
257  }
258 
259  HookRegistry::call('UserDAO::_returnUserFromRowWithReviewerStats', array(&$user, &$row));
260 
261  return $user;
262  }
263 
270  function _returnUserFromRowWithData($row, $callHook = true) {
271  $user = $this->_returnUserFromRow($row, false);
272  $this->getDataObjectSettings('user_settings', 'user_id', $row['user_id'], $user);
273 
274  if (isset($row['review_id'])) $user->review_id = $row['review_id'];
275  HookRegistry::call('UserDAO::_returnUserFromRowWithData', array(&$user, &$row));
276 
277  return $user;
278  }
279 
286  function _returnUserFromRow($row, $callHook = true) {
287  $user = $this->newDataObject();
288  $user->setId($row['user_id']);
289  $user->setUsername($row['username']);
290  $user->setPassword($row['password']);
291  $user->setEmail($row['email']);
292  $user->setUrl($row['url']);
293  $user->setPhone($row['phone']);
294  $user->setMailingAddress($row['mailing_address']);
295  $user->setBillingAddress($row['billing_address']);
296  $user->setCountry($row['country']);
297  $user->setLocales(isset($row['locales']) && !empty($row['locales']) ? explode(':', $row['locales']) : array());
298  $user->setDateLastEmail($this->datetimeFromDB($row['date_last_email']));
299  $user->setDateRegistered($this->datetimeFromDB($row['date_registered']));
300  $user->setDateValidated($this->datetimeFromDB($row['date_validated']));
301  $user->setDateLastLogin($this->datetimeFromDB($row['date_last_login']));
302  $user->setMustChangePassword($row['must_change_password']);
303  $user->setDisabled($row['disabled']);
304  $user->setDisabledReason($row['disabled_reason']);
305  $user->setAuthId($row['auth_id']);
306  $user->setAuthStr($row['auth_str']);
307  $user->setInlineHelp($row['inline_help']);
308  $user->setGossip($row['gossip']);
309 
310  if ($callHook) HookRegistry::call('UserDAO::_returnUserFromRow', array(&$user, &$row));
311 
312  return $user;
313  }
314 
319  function insertObject($user) {
320  if ($user->getDateRegistered() == null) {
321  $user->setDateRegistered(Core::getCurrentDate());
322  }
323  if ($user->getDateLastLogin() == null) {
324  $user->setDateLastLogin(Core::getCurrentDate());
325  }
326  $this->update(
327  sprintf('INSERT INTO users
328  (username, password, email, url, phone, mailing_address, billing_address, country, locales, date_last_email, date_registered, date_validated, date_last_login, must_change_password, disabled, disabled_reason, auth_id, auth_str, inline_help, gossip)
329  VALUES
330  (?, ?, ?, ?, ?, ?, ?, ?, ?, %s, %s, %s, %s, ?, ?, ?, ?, ?, ?, ?)',
331  $this->datetimeToDB($user->getDateLastEmail()), $this->datetimeToDB($user->getDateRegistered()), $this->datetimeToDB($user->getDateValidated()), $this->datetimeToDB($user->getDateLastLogin())),
332  array(
333  $user->getUsername(),
334  $user->getPassword(),
335  $user->getEmail(),
336  $user->getUrl(),
337  $user->getPhone(),
338  $user->getMailingAddress(),
339  $user->getBillingAddress(),
340  $user->getCountry(),
341  join(':', $user->getLocales()),
342  $user->getMustChangePassword() ? 1 : 0,
343  $user->getDisabled() ? 1 : 0,
344  $user->getDisabledReason(),
345  $user->getAuthId()=='' ? null : (int) $user->getAuthId(),
346  $user->getAuthStr(),
347  (int) $user->getInlineHelp(),
348  $user->getGossip(),
349  )
350  );
351 
352  $user->setId($this->getInsertId());
353  $this->updateLocaleFields($user);
354  return $user->getId();
355  }
356 
360  function getLocaleFieldNames() {
361  return array('biography', 'signature', 'affiliation',
362  IDENTITY_SETTING_GIVENNAME, IDENTITY_SETTING_FAMILYNAME, 'preferredPublicName');
363  }
364 
368  function getAdditionalFieldNames() {
369  return array_merge(parent::getAdditionalFieldNames(), array(
370  'orcid',
371  'apiKey',
372  'apiKeyEnabled',
373  ));
374  }
375 
379  function updateLocaleFields($user) {
380  $this->updateDataObjectSettings('user_settings', $user, array(
381  'user_id' => (int) $user->getId()
382  ));
383  }
384 
389  function updateObject($user) {
390  if ($user->getDateLastLogin() == null) {
391  $user->setDateLastLogin(Core::getCurrentDate());
392  }
393 
394  $this->updateLocaleFields($user);
395 
396  return $this->update(
397  sprintf('UPDATE users
398  SET username = ?,
399  password = ?,
400  email = ?,
401  url = ?,
402  phone = ?,
403  mailing_address = ?,
404  billing_address = ?,
405  country = ?,
406  locales = ?,
407  date_last_email = %s,
408  date_validated = %s,
409  date_last_login = %s,
410  must_change_password = ?,
411  disabled = ?,
412  disabled_reason = ?,
413  auth_id = ?,
414  auth_str = ?,
415  inline_help = ?,
416  gossip = ?
417  WHERE user_id = ?',
418  $this->datetimeToDB($user->getDateLastEmail()), $this->datetimeToDB($user->getDateValidated()), $this->datetimeToDB($user->getDateLastLogin())),
419  array(
420  $user->getUsername(),
421  $user->getPassword(),
422  $user->getEmail(),
423  $user->getUrl(),
424  $user->getPhone(),
425  $user->getMailingAddress(),
426  $user->getBillingAddress(),
427  $user->getCountry(),
428  join(':', $user->getLocales()),
429  $user->getMustChangePassword() ? 1 : 0,
430  $user->getDisabled() ? 1 : 0,
431  $user->getDisabledReason(),
432  $user->getAuthId()=='' ? null : (int) $user->getAuthId(),
433  $user->getAuthStr(),
434  (int) $user->getInlineHelp(),
435  $user->getGossip(),
436  (int) $user->getId(),
437  )
438  );
439  }
440 
445  function deleteObject($user) {
446  $this->deleteUserById($user->getId());
447  }
448 
453  function deleteUserById($userId) {
454  $this->update('DELETE FROM user_settings WHERE user_id = ?', array((int) $userId));
455  $this->update('DELETE FROM users WHERE user_id = ?', array((int) $userId));
456  }
457 
464  function getUserFullName($userId, $allowDisabled = true) {
465  $user = $this->getById($userId, $allowDisabled);
466  return $user?$user->getFullName():null;
467  }
468 
475  function getUserEmail($userId, $allowDisabled = true) {
476  $result = $this->retrieve(
477  'SELECT email FROM users WHERE user_id = ?' . ($allowDisabled?'':' AND disabled = 0'),
478  array((int) $userId)
479  );
480 
481  $email = false;
482  if ($result->RecordCount()) {
483  $email = $result->fields[0];
484  }
485 
486  $result->Close();
487  return $email;
488  }
489 
496  function getUsersWithNoRole($allowDisabled = true, $dbResultRange = null) {
497  $sql = 'SELECT u.*,
498  ' . $this->getFetchColumns() . '
499  FROM users u
500  ' . $this->getFetchJoins() . '
501  LEFT JOIN roles r ON u.user_id=r.user_id
502  WHERE r.role_id IS NULL';
503 
504  $orderSql = $this->getOrderBy(); // FIXME Add "sort field" parameter?
505  $params = $this->getFetchParameters();
506  $result = $this->retrieveRange($sql . ($allowDisabled?'':' AND u.disabled = 0') . $orderSql, $params, $dbResultRange);
507 
508  return new DAOResultFactory($result, $this, '_returnUserFromRowWithData');
509  }
510 
517  function userExistsById($userId, $allowDisabled = true) {
518  $result = $this->retrieve(
519  'SELECT COUNT(*) FROM users WHERE user_id = ?' . ($allowDisabled?'':' AND disabled = 0'),
520  array((int) $userId)
521  );
522  $userExists = isset($result->fields[0]) && $result->fields[0] != 0;
523 
524  $result->Close();
525  return $userExists;
526  }
527 
535  function userExistsByUsername($username, $userId = null, $allowDisabled = true) {
536  $result = $this->retrieve(
537  'SELECT COUNT(*) FROM users WHERE username = ?' . (isset($userId) ? ' AND user_id != ?' : '') . ($allowDisabled?'':' AND disabled = 0'),
538  isset($userId) ? array($username, (int) $userId) : array($username)
539  );
540  $userExists = isset($result->fields[0]) && $result->fields[0] == 1;
541 
542  $result->Close();
543  return $userExists;
544  }
545 
553  function userExistsByEmail($email, $userId = null, $allowDisabled = true) {
554  $result = $this->retrieve(
555  'SELECT COUNT(*) FROM users WHERE email = ?' . (isset($userId) ? ' AND user_id != ?' : '') . ($allowDisabled?'':' AND disabled = 0'),
556  isset($userId) ? array($email, (int) $userId) : array($email)
557  );
558  $userExists = isset($result->fields[0]) && $result->fields[0] == 1;
559 
560  $result->Close();
561  return $userExists;
562  }
563 
569  function changeSitePrimaryLocale($oldLocale, $newLocale) {
570  // remove all empty user names in the new locale
571  // so that we do not have to take care if we should insert or update them -- we can then only insert them if needed
572  $settingNames = array(IDENTITY_SETTING_GIVENNAME, IDENTITY_SETTING_FAMILYNAME, 'preferredPublicName');
573  foreach ($settingNames as $settingName) {
574  $params = array($newLocale, $settingName);
575  $this->update(
576  "DELETE from user_settings
577  WHERE locale = ? AND setting_name = ? AND setting_value = ''",
578  $params
579  );
580  }
581  // get all names of all users in the new locale
582  $params = array($newLocale, IDENTITY_SETTING_GIVENNAME, $newLocale, IDENTITY_SETTING_FAMILYNAME, $newLocale, 'preferredPublicName');
583  $result = $this->retrieve(
584  "SELECT DISTINCT us.user_id, usg.setting_value AS given_name, usf.setting_value AS family_name, usp.setting_value AS preferred_public_name
585  FROM user_settings us
586  LEFT JOIN user_settings usg ON (usg.user_id = us.user_id AND usg.locale = ? AND usg.setting_name = ?)
587  LEFT JOIN user_settings usf ON (usf.user_id = us.user_id AND usf.locale = ? AND usf.setting_name = ?)
588  LEFT JOIN user_settings usp ON (usp.user_id = us.user_id AND usp.locale = ? AND usp.setting_name = ?)",
589  $params
590  );
591  while (!$result->EOF) {
592  $row = $result->GetRowAssoc(false);
593  $userId = $row['user_id'];
594  if (empty($row['given_name']) && empty($row['family_name']) && empty($row['preferred_public_name'])) {
595  // if no user name exists in the new locale, insert them all
596  foreach ($settingNames as $settingName) {
597  $params = array($newLocale, $settingName, $settingName, $oldLocale, $userId);
598  $this->update(
599  "INSERT INTO user_settings (user_id, locale, setting_name, setting_value, setting_type)
600  SELECT DISTINCT us.user_id, ?, ?, us.setting_value, 'string'
601  FROM user_settings us
602  WHERE us.setting_name = ? AND us.locale = ? AND us.user_id = ?",
603  $params
604  );
605  }
606  } elseif (empty($row['given_name'])) {
607  // if the given name does not exist in the new locale (but one of the other names do exist), insert it
608  $params = array($newLocale, IDENTITY_SETTING_GIVENNAME, IDENTITY_SETTING_GIVENNAME, $oldLocale, $userId);
609  $this->update(
610  "INSERT INTO user_settings (user_id, locale, setting_name, setting_value, setting_type)
611  SELECT DISTINCT us.user_id, ?, ?, us.setting_value, 'string'
612  FROM user_settings us
613  WHERE us.setting_name = ? AND us.locale = ? AND us.user_id = ?",
614  $params
615  );
616  }
617  $result->MoveNext();
618  }
619  $result->Close();
620  }
621 
626  function getInsertId() {
627  return $this->_getInsertId('users', 'user_id');
628  }
629 
634  function getFetchParameters() {
635  $locale = AppLocale::getLocale();
636  // the users register for the site, thus
637  // the site primary locale should be the default locale
638  $site = Application::get()->getRequest()->getSite();
639  $primaryLocale = $site->getPrimaryLocale();
640  return array(
641  IDENTITY_SETTING_GIVENNAME, $locale,
642  IDENTITY_SETTING_GIVENNAME, $primaryLocale,
643  IDENTITY_SETTING_FAMILYNAME, $locale,
644  IDENTITY_SETTING_FAMILYNAME, $primaryLocale,
645  );
646  }
647 
652  function getFetchColumns() {
653  return 'COALESCE(ugl.setting_value, ugpl.setting_value) AS user_given,
654  CASE WHEN ugl.setting_value <> \'\' THEN ufl.setting_value ELSE ufpl.setting_value END AS user_family';
655  }
656 
661  function getFetchJoins() {
662  return 'LEFT JOIN user_settings ugl ON (u.user_id = ugl.user_id AND ugl.setting_name = ? AND ugl.locale = ?)
663  LEFT JOIN user_settings ugpl ON (u.user_id = ugpl.user_id AND ugpl.setting_name = ? AND ugpl.locale = ?)
664  LEFT JOIN user_settings ufl ON (u.user_id = ufl.user_id AND ufl.setting_name = ? AND ufl.locale = ?)
665  LEFT JOIN user_settings ufpl ON (u.user_id = ufpl.user_id AND ufpl.setting_name = ? AND ufpl.locale = ?)';
666  }
667 
672  function getOrderBy() {
673  return 'ORDER BY user_family, user_given';
674  }
675 }
676 
UserDAO\_returnUserFromRow
_returnUserFromRow($row, $callHook=true)
Definition: UserDAO.inc.php:286
UserDAO\getByUsername
getByUsername($username, $allowDisabled=true)
Definition: UserDAO.inc.php:64
DAOResultFactory
Wrapper around ADORecordSet providing "factory" features for generating objects from DAOs.
Definition: DAOResultFactory.inc.php:21
UserDAO\getUserByEmail
getUserByEmail($email, $allowDisabled=true)
Definition: UserDAO.inc.php:125
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
UserDAO\getById
getById($userId, $allowDisabled=true)
Definition: UserDAO.inc.php:44
UserDAO\newDataObject
newDataObject()
Definition: UserDAO.inc.php:34
DAO\retrieve
& retrieve($sql, $params=false, $callHooks=true)
Definition: DAO.inc.php:85
UserDAO\_returnUserFromRowWithReviewerStats
_returnUserFromRowWithReviewerStats($row)
Definition: UserDAO.inc.php:245
UserDAO\userExistsByUsername
userExistsByUsername($username, $userId=null, $allowDisabled=true)
Definition: UserDAO.inc.php:535
UserDAO\getReviewersNotAssignedToSubmission
getReviewersNotAssignedToSubmission($contextId, $submissionId, &$reviewRound, $name='')
Definition: UserDAO.inc.php:203
UserDAO\getInsertId
getInsertId()
Definition: UserDAO.inc.php:626
DAO\update
update($sql, $params=false, $callHooks=true, $dieOnError=true)
Definition: DAO.inc.php:214
DAO\_getInsertId
_getInsertId($table='', $id='')
Definition: DAO.inc.php:255
UserDAO\getReviewersForSubmission
getReviewersForSubmission($contextId, $submissionId, $round)
Definition: UserDAO.inc.php:167
UserDAO\getBySetting
getBySetting($settingName, $settingValue, $allowDisabled=true)
Definition: UserDAO.inc.php:85
PKPApplication\get
static get()
Definition: PKPApplication.inc.php:235
UserDAO\getUserByCredentials
getUserByCredentials($username, $password, $allowDisabled=true)
Definition: UserDAO.inc.php:146
UserDAO\_returnUserFromRowWithData
_returnUserFromRowWithData($row, $callHook=true)
Definition: UserDAO.inc.php:270
UserDAO\getFetchColumns
getFetchColumns()
Definition: UserDAO.inc.php:652
UserDAO\getFetchParameters
getFetchParameters()
Definition: UserDAO.inc.php:634
AppLocale\getLocale
static getLocale()
Definition: env1/MockAppLocale.inc.php:40
UserDAO\getFetchJoins
getFetchJoins()
Definition: UserDAO.inc.php:661
DAO
Operations for retrieving and modifying objects from a database.
Definition: DAO.inc.php:31
UserDAO\changeSitePrimaryLocale
changeSitePrimaryLocale($oldLocale, $newLocale)
Definition: UserDAO.inc.php:569
User
Basic class describing users existing in the system.
Definition: User.inc.php:23
UserDAO
Operations for retrieving and modifying User objects.
Definition: UserDAO.inc.php:28
UserDAO\getOrderBy
getOrderBy()
Definition: UserDAO.inc.php:672
UserDAO\getUserByAuthStr
getUserByAuthStr($authstr, $allowDisabled=true)
Definition: UserDAO.inc.php:105
UserDAO\userExistsByEmail
userExistsByEmail($email, $userId=null, $allowDisabled=true)
Definition: UserDAO.inc.php:553