Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
19.86% covered (danger)
19.86%
29 / 146
25.00% covered (danger)
25.00%
19 / 76
CRAP
0.00% covered (danger)
0.00%
0 / 1
User
19.86% covered (danger)
19.86%
29 / 146
25.00% covered (danger)
25.00%
19 / 76
4258.54
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setConfig
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 clearCredentials
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 saveCatalogId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 setCredentials
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 saveCredentials
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 saveEmailVerified
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getCatPassword
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 passwordEncryptionEnabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 encryptOrDecrypt
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 changeHomeLibrary
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 checkEmailVerified
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTags
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getListTags
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTagString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 formatTagString
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 getLists
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getSavedData
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 saveResource
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 removeResourcesById
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 libraryCardsEnabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getLibraryCards
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getLibraryCard
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 deleteLibraryCard
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 activateLibraryCard
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 saveLibraryCard
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 updateLibraryCardEntry
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUserCardService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 delete
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
 updateHash
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 updateLastLanguage
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 updateEmail
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRoles
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setUsername
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getUsername
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRawPassword
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getRawPassword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPasswordHash
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getPasswordHash
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setFirstname
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getFirstname
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setLastname
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLastname
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEmail
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getEmail
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPendingEmail
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getPendingEmail
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCatId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getCatId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCatUsername
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCatUsername
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHomeLibrary
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getHomeLibrary
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRawCatPassword
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getRawCatPassword
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCatPassEnc
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCatPassEnc
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCollege
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCollege
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setMajor
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getMajor
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setVerifyHash
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getVerifyHash
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setAuthMethod
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getAuthMethod
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setLastLanguage
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getLastLanguage
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasUserProvidedEmail
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHasUserProvidedEmail
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 setLastLogin
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getLastLogin
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCreated
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getCreated
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setEmailVerified
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getEmailVerified
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3/**
4 * Row Definition for user
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2010.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  Db_Row
25 * @author   Demian Katz <demian.katz@villanova.edu>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org Main Site
28 */
29
30namespace VuFind\Db\Row;
31
32use DateTime;
33use Laminas\Db\Sql\Expression;
34use Laminas\Db\Sql\Select;
35use VuFind\Auth\ILSAuthenticator;
36use VuFind\Config\AccountCapabilities;
37use VuFind\Db\Entity\UserEntityInterface;
38use VuFind\Db\Service\ResourceServiceInterface;
39use VuFind\Db\Service\ResourceTagsService;
40use VuFind\Db\Service\ResourceTagsServiceInterface;
41use VuFind\Db\Service\TagServiceInterface;
42use VuFind\Db\Service\UserCardServiceInterface;
43use VuFind\Db\Service\UserListServiceInterface;
44use VuFind\Db\Service\UserResourceServiceInterface;
45use VuFind\Db\Service\UserServiceInterface;
46use VuFind\Favorites\FavoritesService;
47
48use function count;
49
50/**
51 * Row Definition for user
52 *
53 * @category VuFind
54 * @package  Db_Row
55 * @author   Demian Katz <demian.katz@villanova.edu>
56 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
57 * @link     https://vufind.org Main Site
58 *
59 * @property int     $id
60 * @property ?string $username
61 * @property string  $password
62 * @property ?string $pass_hash
63 * @property string  $firstname
64 * @property string  $lastname
65 * @property string  $email
66 * @property ?string $email_verified
67 * @property string  $pending_email
68 * @property int     $user_provided_email
69 * @property ?string $cat_id
70 * @property ?string $cat_username
71 * @property ?string $cat_password
72 * @property ?string $cat_pass_enc
73 * @property string  $college
74 * @property string  $major
75 * @property ?string $home_library
76 * @property string  $created
77 * @property string  $verify_hash
78 * @property string  $last_login
79 * @property ?string $auth_method
80 * @property string  $last_language
81 */
82class User extends RowGateway implements
83    UserEntityInterface,
84    \VuFind\Db\Service\DbServiceAwareInterface,
85    \VuFind\Db\Table\DbTableAwareInterface,
86    \LmcRbacMvc\Identity\IdentityInterface
87{
88    use \VuFind\Db\Service\DbServiceAwareTrait;
89    use \VuFind\Db\Table\DbTableAwareTrait;
90
91    /**
92     * VuFind configuration
93     *
94     * @var \Laminas\Config\Config
95     */
96    protected $config = null;
97
98    /**
99     * Constructor
100     *
101     * @param \Laminas\Db\Adapter\Adapter $adapter          Database adapter
102     * @param ILSAuthenticator            $ilsAuthenticator ILS authenticator
103     * @param AccountCapabilities         $capabilities     Account capabilities configuration (null for defaults)
104     * @param FavoritesService            $favoritesService Favorites service
105     */
106    public function __construct(
107        $adapter,
108        protected ILSAuthenticator $ilsAuthenticator,
109        protected AccountCapabilities $capabilities,
110        protected FavoritesService $favoritesService,
111    ) {
112        parent::__construct('id', 'user', $adapter);
113    }
114
115    /**
116     * Configuration setter
117     *
118     * @param \Laminas\Config\Config $config VuFind configuration
119     *
120     * @return void
121     *
122     * @deprecated
123     */
124    public function setConfig(\Laminas\Config\Config $config)
125    {
126        $this->config = $config;
127    }
128
129    /**
130     * Reset ILS login credentials.
131     *
132     * @return void
133     *
134     * @deprecated Use setCatUsername(null)->setRawCatPassword(null)->setCatPassEnc(null)
135     */
136    public function clearCredentials()
137    {
138        $this->cat_username = null;
139        $this->cat_password = null;
140        $this->cat_pass_enc = null;
141    }
142
143    /**
144     * Save ILS ID.
145     *
146     * @param string $catId Catalog ID to save.
147     *
148     * @return mixed        The output of the save method.
149     * @throws \VuFind\Exception\PasswordSecurity
150     *
151     * @deprecated Use UserEntityInterface::setCatId() and \VuFind\Db\Service\DbServiceInterface::persistEntity()
152     */
153    public function saveCatalogId($catId)
154    {
155        $this->cat_id = $catId;
156        return $this->save();
157    }
158
159    /**
160     * Set ILS login credentials without saving them.
161     *
162     * @param string  $username Username to save
163     * @param ?string $password Password to save (null for none)
164     *
165     * @return void
166     *
167     * @deprecated Use ILSAuthenticator::setUserCatalogCredentials()
168     */
169    public function setCredentials($username, $password)
170    {
171        $this->ilsAuthenticator->setUserCatalogCredentials($this, $username, $password);
172    }
173
174    /**
175     * Save ILS login credentials.
176     *
177     * @param string $username Username to save
178     * @param string $password Password to save
179     *
180     * @return void
181     * @throws \VuFind\Exception\PasswordSecurity
182     *
183     * @deprecated Use ILSAuthenticator::saveUserCatalogCredentials()
184     */
185    public function saveCredentials($username, $password)
186    {
187        $this->ilsAuthenticator->saveUserCatalogCredentials($this, $username, $password);
188    }
189
190    /**
191     * Save date/time when email address has been verified.
192     *
193     * @param string $datetime optional date/time to save.
194     *
195     * @return mixed           The output of the save method.
196     *
197     * @deprecated Use UserEntityInterface::setEmailVerified() and
198     * \VuFind\Db\Service\DbServiceInterface::persistEntity()
199     */
200    public function saveEmailVerified($datetime = null)
201    {
202        if ($datetime === null) {
203            $datetime = date('Y-m-d H:i:s');
204        }
205
206        $this->email_verified = $datetime;
207        return $this->save();
208    }
209
210    /**
211     * This is a getter for the Catalog Password. It will return a plaintext version
212     * of the password.
213     *
214     * @return string The Catalog password in plain text
215     * @throws \VuFind\Exception\PasswordSecurity
216     *
217     * @deprecated Use ILSAuthenticator::getCatPasswordForUser()
218     */
219    public function getCatPassword()
220    {
221        return $this->ilsAuthenticator->getCatPasswordForUser($this);
222    }
223
224    /**
225     * Is ILS password encryption enabled?
226     *
227     * @return bool
228     *
229     * @deprecated
230     */
231    protected function passwordEncryptionEnabled()
232    {
233        return $this->ilsAuthenticator->passwordEncryptionEnabled();
234    }
235
236    /**
237     * This is a central function for encrypting and decrypting so that
238     * logic is all in one location
239     *
240     * @param string $text    The text to be encrypted or decrypted
241     * @param bool   $encrypt True if we wish to encrypt text, False if we wish to
242     * decrypt text.
243     *
244     * @return string|bool    The encrypted/decrypted string
245     * @throws \VuFind\Exception\PasswordSecurity
246     *
247     * @deprecated Use ILSAuthenticator::encrypt() or ILSAuthenticator::decrypt()
248     */
249    protected function encryptOrDecrypt($text, $encrypt = true)
250    {
251        $method = $encrypt ? 'encrypt' : 'decrypt';
252        return $this->ilsAuthenticator->$method($text);
253    }
254
255    /**
256     * Change home library.
257     *
258     * @param ?string $homeLibrary New home library to store, or null to indicate
259     * that the user does not want a default. An empty string is the default for
260     * backward compatibility and indicates that system's default pick up location is
261     * to be used
262     *
263     * @return mixed               The output of the save method.
264     *
265     * @deprecated Use ILSAuthenticator::updateUserHomeLibrary()
266     */
267    public function changeHomeLibrary($homeLibrary)
268    {
269        return $this->ilsAuthenticator->updateUserHomeLibrary($this, $homeLibrary);
270    }
271
272    /**
273     * Check whether the email address has been verified yet.
274     *
275     * @return bool
276     *
277     * @deprecated Use getEmailVerified()
278     */
279    public function checkEmailVerified()
280    {
281        return !empty($this->email_verified);
282    }
283
284    /**
285     * Get a list of all tags generated by the user in favorites lists. Note that
286     * the returned list WILL NOT include tags attached to records that are not
287     * saved in favorites lists.
288     *
289     * @param string $resourceId Filter for tags tied to a specific resource (null for no filter).
290     * @param int    $listId     Filter for tags tied to a specific list (null for no filter).
291     * @param string $source     Filter for tags tied to a specific record source. (null for no filter).
292     *
293     * @return array
294     *
295     * @deprecated Use TagServiceInterface::getUserTagsFromFavorites()
296     */
297    public function getTags($resourceId = null, $listId = null, $source = null)
298    {
299        return $this->getDbTable('Tags')->getListTagsForUser($this->getId(), $resourceId, $listId, $source);
300    }
301
302    /**
303     * Get tags assigned by the user to a favorite list.
304     *
305     * @param int $listId List id
306     *
307     * @return array
308     *
309     * @deprecated Use TagServiceInterface::getListTags()
310     */
311    public function getListTags($listId)
312    {
313        return $this->getDbTable('Tags')->getForList($listId, $this->getId());
314    }
315
316    /**
317     * Same as getTags(), but returns a string for use in edit mode rather than an
318     * array of tag objects.
319     *
320     * @param string $resourceId Filter for tags tied to a specific resource (null
321     * for no filter).
322     * @param int    $listId     Filter for tags tied to a specific list (null for no
323     * filter).
324     * @param string $source     Filter for tags tied to a specific record source
325     * (null for no filter).
326     *
327     * @return string
328     *
329     * @deprecated Use \VuFind\Favorites\FavoritesService::getTagStringForEditing()
330     */
331    public function getTagString($resourceId = null, $listId = null, $source = null)
332    {
333        return $this->formatTagString($this->getTags($resourceId, $listId, $source));
334    }
335
336    /**
337     * Same as getTagString(), but operates on a list of tags.
338     *
339     * @param array $tags Tags
340     *
341     * @return string
342     *
343     * @deprecated Use \VuFind\Favorites\FavoritesService::formatTagStringForEditing()
344     */
345    public function formatTagString($tags)
346    {
347        $tagStr = '';
348        if (count($tags) > 0) {
349            foreach ($tags as $tag) {
350                if (strstr($tag['tag'], ' ')) {
351                    $tagStr .= "\"{$tag['tag']}\" ";
352                } else {
353                    $tagStr .= "{$tag['tag']} ";
354                }
355            }
356        }
357        return trim($tagStr);
358    }
359
360    /**
361     * Get all of the lists associated with this user.
362     *
363     * @return \Laminas\Db\ResultSet\AbstractResultSet
364     *
365     * @deprecated Use UserListServiceInterface::getUserListsAndCountsByUser()
366     */
367    public function getLists()
368    {
369        $userId = $this->id;
370        $callback = function ($select) use ($userId) {
371            $select->columns(
372                [
373                    Select::SQL_STAR,
374                    'cnt' => new Expression(
375                        'COUNT(DISTINCT(?))',
376                        ['ur.resource_id'],
377                        [Expression::TYPE_IDENTIFIER]
378                    ),
379                ]
380            );
381            $select->join(
382                ['ur' => 'user_resource'],
383                'user_list.id = ur.list_id',
384                [],
385                $select::JOIN_LEFT
386            );
387            $select->where->equalTo('user_list.user_id', $userId);
388            $select->group(
389                [
390                    'user_list.id', 'user_list.user_id', 'title', 'description',
391                    'created', 'public',
392                ]
393            );
394            $select->order(['title']);
395        };
396
397        $table = $this->getDbTable('UserList');
398        return $table->select($callback);
399    }
400
401    /**
402     * Get information saved in a user's favorites for a particular record.
403     *
404     * @param string $resourceId ID of record being checked.
405     * @param int    $listId     Optional list ID (to limit results to a particular
406     * list).
407     * @param string $source     Source of record to look up
408     *
409     * @return array
410     *
411     * @deprecated Use UserResourceServiceInterface::getFavoritesForRecord()
412     */
413    public function getSavedData(
414        $resourceId,
415        $listId = null,
416        $source = DEFAULT_SEARCH_BACKEND
417    ) {
418        $table = $this->getDbTable('UserResource');
419        return $table->getSavedData($resourceId, $source, $listId, $this->id);
420    }
421
422    /**
423     * Add/update a resource in the user's account.
424     *
425     * @param \VuFind\Db\Row\Resource $resource        The resource to add/update
426     * @param \VuFind\Db\Row\UserList $list            The list to store the resource
427     * in.
428     * @param array                   $tagArray        An array of tags to associate
429     * with the resource.
430     * @param string                  $notes           User notes about the resource.
431     * @param bool                    $replaceExisting Whether to replace all
432     * existing tags (true) or append to the existing list (false).
433     *
434     * @return void
435     *
436     * @deprecated Use \VuFind\Favorites\FavoritesService::saveResourceToFavorites()
437     */
438    public function saveResource(
439        $resource,
440        $list,
441        $tagArray,
442        $notes,
443        $replaceExisting = true
444    ) {
445        // Create the resource link if it doesn't exist and update the notes in any case:
446        $this->getDbService(UserResourceServiceInterface::class)->createOrUpdateLink($resource, $this, $list, $notes);
447
448        // If we're replacing existing tags, delete the old ones before adding the
449        // new ones:
450        if ($replaceExisting) {
451            $this->getDbService(ResourceTagsService::class)
452                ->destroyResourceTagsLinksForUser($resource->getId(), $this, $list);
453        }
454
455        // Add the new tags:
456        foreach ($tagArray as $tag) {
457            $resource->addTag($tag, $this, $list->id);
458        }
459    }
460
461    /**
462     * Given an array of item ids, remove them from all lists
463     *
464     * @param array  $ids    IDs to remove from the list
465     * @param string $source Type of resource identified by IDs
466     *
467     * @return void
468     *
469     * @deprecated Use \VuFind\Favorites\FavoritesService::removeUserResourcesById()
470     */
471    public function removeResourcesById($ids, $source = DEFAULT_SEARCH_BACKEND)
472    {
473        // Retrieve a list of resource IDs:
474        $resources = $this->getDbService(ResourceServiceInterface::class)->getResourcesByRecordIds($ids, $source);
475
476        $resourceIDs = [];
477        foreach ($resources as $current) {
478            $resourceIDs[] = $current->getId();
479        }
480
481        // Remove Resource (related tags are also removed implicitly)
482        $userResourceTable = $this->getDbTable('UserResource');
483        // true here makes sure that only tags in lists are deleted
484        $userResourceTable->destroyLinks($resourceIDs, $this->id, true);
485    }
486
487    /**
488     * Whether library cards are enabled
489     *
490     * @return bool
491     *
492     * @deprecated use \VuFind\Config\AccountCapabilities::libraryCardsEnabled()
493     */
494    public function libraryCardsEnabled()
495    {
496        return $this->capabilities->libraryCardsEnabled();
497    }
498
499    /**
500     * Get all library cards associated with the user.
501     *
502     * @return \Laminas\Db\ResultSet\AbstractResultSet
503     * @throws \VuFind\Exception\LibraryCard
504     *
505     * @deprecated Use UserCardServiceInterface::getLibraryCards()
506     */
507    public function getLibraryCards()
508    {
509        if (!$this->capabilities->libraryCardsEnabled()) {
510            return new \Laminas\Db\ResultSet\ResultSet();
511        }
512        $userCard = $this->getDbTable('UserCard');
513        return $userCard->select(['user_id' => $this->id]);
514    }
515
516    /**
517     * Get library card data
518     *
519     * @param int $id Library card ID
520     *
521     * @return UserCard|false Card data if found, false otherwise
522     * @throws \VuFind\Exception\LibraryCard
523     *
524     * @deprecated Use LibraryCardServiceInterface::getOrCreateLibraryCard()
525     */
526    public function getLibraryCard($id = null)
527    {
528        return $this->getUserCardService()->getOrCreateLibraryCard($this, $id);
529    }
530
531    /**
532     * Delete library card
533     *
534     * @param int $id Library card ID
535     *
536     * @return void
537     * @throws \VuFind\Exception\LibraryCard
538     *
539     * @deprecated Use UserCardServiceInterface::deleteLibraryCard()
540     */
541    public function deleteLibraryCard($id)
542    {
543        return $this->getUserCardService()->deleteLibraryCard($this, $id);
544    }
545
546    /**
547     * Activate a library card for the given username
548     *
549     * @param int $id Library card ID
550     *
551     * @return void
552     * @throws \VuFind\Exception\LibraryCard
553     *
554     * @deprecated Use UserCardServiceInterface::activateLibraryCard()
555     */
556    public function activateLibraryCard($id)
557    {
558        return $this->getUserCardService()->activateLibraryCard($this, $id);
559    }
560
561    /**
562     * Save library card with the given information
563     *
564     * @param int    $id       Card ID
565     * @param string $cardName Card name
566     * @param string $username Username
567     * @param string $password Password
568     * @param string $homeLib  Home Library
569     *
570     * @return int Card ID
571     * @throws \VuFind\Exception\LibraryCard
572     *
573     * @deprecated Use UserCardServiceInterface::persistLibraryCardData()
574     */
575    public function saveLibraryCard(
576        $id,
577        $cardName,
578        $username,
579        $password,
580        $homeLib = ''
581    ) {
582        return $this->getUserCardService()
583            ->persistLibraryCardData($this, $id, $cardName, $username, $password, $homeLib)
584            ->getId();
585    }
586
587    /**
588     * Verify that the current card information exists in user's library cards
589     * (if enabled) and is up to date.
590     *
591     * @return void
592     * @throws \VuFind\Exception\PasswordSecurity
593     *
594     * @deprecated Use UserCardServiceInterface::synchronizeUserLibraryCardData()
595     */
596    protected function updateLibraryCardEntry()
597    {
598        $this->getUserCardService()->synchronizeUserLibraryCardData($this);
599    }
600
601    /**
602     * Get a UserCard service object.
603     *
604     * @return UserCardServiceInterface
605     */
606    protected function getUserCardService()
607    {
608        return $this->getDbService(UserCardServiceInterface::class);
609    }
610
611    /**
612     * Destroy the user.
613     *
614     * @param bool $removeComments Whether to remove user's comments
615     * @param bool $removeRatings  Whether to remove user's ratings
616     *
617     * @return int The number of rows deleted.
618     *
619     * @deprecated Use \VuFind\Account\UserAccountService::purgeUserData()
620     */
621    public function delete($removeComments = true, $removeRatings = true)
622    {
623        // Remove all lists owned by the user:
624        $listService = $this->getDbService(UserListServiceInterface::class);
625        foreach ($listService->getUserListsByUser($this) as $current) {
626            $this->favoritesService->destroyList($current, $this, true);
627        }
628        $this->getDbService(ResourceTagsServiceInterface::class)->destroyResourceTagsLinksForUser(null, $this);
629        if ($removeComments) {
630            $comments = $this->getDbService(
631                \VuFind\Db\Service\CommentsServiceInterface::class
632            );
633            $comments->deleteByUser($this->getId());
634        }
635        if ($removeRatings) {
636            $ratings = $this->getDbService(\VuFind\Db\Service\RatingsServiceInterface::class);
637            $ratings->deleteByUser($this);
638        }
639
640        // Remove the user itself:
641        return parent::delete();
642    }
643
644    /**
645     * Update the verification hash for this user
646     *
647     * @return bool save success
648     *
649     * @deprecated Use \VuFind\Auth\Manager::updateUserVerifyHash()
650     */
651    public function updateHash()
652    {
653        $hash = md5($this->username . $this->password . $this->pass_hash . rand());
654        // Make totally sure the timestamp is exactly 10 characters:
655        $time = str_pad(substr((string)time(), 0, 10), 10, '0', STR_PAD_LEFT);
656        $this->verify_hash = $hash . $time;
657        return $this->save();
658    }
659
660    /**
661     * Updated saved language
662     *
663     * @param string $language New language
664     *
665     * @return void
666     *
667     * @deprecated Use \VuFind\Db\Entity\UserEntityInterface::setLastLanguage()
668     * and \VuFind\Db\Service\UserService::persistEntity() instead.
669     */
670    public function updateLastLanguage($language)
671    {
672        $this->last_language = $language;
673        $this->save();
674    }
675
676    /**
677     * Update the user's email address, if appropriate. Note that this does NOT
678     * automatically save the row; it assumes a subsequent call will be made to
679     * persist the data.
680     *
681     * @param string $email        New email address
682     * @param bool   $userProvided Was this email provided by the user (true) or
683     * an automated lookup (false)?
684     *
685     * @return void
686     *
687     * @deprecated Use \VuFind\Db\Service\UserServiceInterface::updateUserEmail()
688     */
689    public function updateEmail($email, $userProvided = false)
690    {
691        $this->getDbService(UserServiceInterface::class)->updateUserEmail($this, $email, $userProvided);
692    }
693
694    /**
695     * Get the list of roles of this identity
696     *
697     * @return string[]|\Rbac\Role\RoleInterface[]
698     */
699    public function getRoles()
700    {
701        return ['loggedin'];
702    }
703
704    /**
705     * Get identifier (returns null for an uninitialized or non-persisted object).
706     *
707     * @return ?int
708     */
709    public function getId(): ?int
710    {
711        return $this->id;
712    }
713
714    /**
715     * Username setter
716     *
717     * @param string $username Username
718     *
719     * @return UserEntityInterface
720     */
721    public function setUsername(string $username): UserEntityInterface
722    {
723        $this->username = $username;
724        return $this;
725    }
726
727    /**
728     * Get username.
729     *
730     * @return string
731     */
732    public function getUsername(): string
733    {
734        return $this->username;
735    }
736
737    /**
738     * Set raw (unhashed) password (if available). This should only be used when hashing is disabled.
739     *
740     * @param string $password Password
741     *
742     * @return UserEntityInterface
743     */
744    public function setRawPassword(string $password): UserEntityInterface
745    {
746        $this->password = $password;
747        return $this;
748    }
749
750    /**
751     * Get raw (unhashed) password (if available). This should only be used when hashing is disabled.
752     *
753     * @return string
754     */
755    public function getRawPassword(): string
756    {
757        return $this->password ?? '';
758    }
759
760    /**
761     * Set hashed password. This should only be used when hashing is enabled.
762     *
763     * @param ?string $hash Password hash
764     *
765     * @return UserEntityInterface
766     */
767    public function setPasswordHash(?string $hash): UserEntityInterface
768    {
769        $this->pass_hash = $hash;
770        return $this;
771    }
772
773    /**
774     * Get hashed password. This should only be used when hashing is enabled.
775     *
776     * @return ?string
777     */
778    public function getPasswordHash(): ?string
779    {
780        return $this->pass_hash ?? null;
781    }
782
783    /**
784     * Set firstname.
785     *
786     * @param string $firstName New first name
787     *
788     * @return UserEntityInterface
789     */
790    public function setFirstname(string $firstName): UserEntityInterface
791    {
792        $this->firstname = $firstName;
793        return $this;
794    }
795
796    /**
797     * Get firstname.
798     *
799     * @return string
800     */
801    public function getFirstname(): string
802    {
803        return $this->firstname;
804    }
805
806    /**
807     * Set lastname.
808     *
809     * @param string $lastName New last name
810     *
811     * @return UserEntityInterface
812     */
813    public function setLastname(string $lastName): UserEntityInterface
814    {
815        $this->lastname = $lastName;
816        return $this;
817    }
818
819    /**
820     * Get lastname.
821     *
822     * @return string
823     */
824    public function getLastname(): string
825    {
826        return $this->lastname;
827    }
828
829    /**
830     * Set email.
831     *
832     * @param string $email Email address
833     *
834     * @return UserEntityInterface
835     */
836    public function setEmail(string $email): UserEntityInterface
837    {
838        $this->email = $email;
839        return $this;
840    }
841
842    /**
843     * Get email.
844     *
845     * @return string
846     */
847    public function getEmail(): string
848    {
849        return $this->email;
850    }
851
852    /**
853     * Set pending email.
854     *
855     * @param string $email New pending email
856     *
857     * @return UserEntityInterface
858     */
859    public function setPendingEmail(string $email): UserEntityInterface
860    {
861        $this->pending_email = $email;
862        return $this;
863    }
864
865    /**
866     * Get pending email.
867     *
868     * @return string
869     */
870    public function getPendingEmail(): string
871    {
872        return $this->pending_email ?? '';
873    }
874
875    /**
876     * Catalog id setter
877     *
878     * @param ?string $catId Catalog id
879     *
880     * @return UserEntityInterface
881     */
882    public function setCatId(?string $catId): UserEntityInterface
883    {
884        $this->cat_id = $catId;
885        return $this;
886    }
887
888    /**
889     * Get catalog id.
890     *
891     * @return ?string
892     */
893    public function getCatId(): ?string
894    {
895        return $this->cat_id;
896    }
897
898    /**
899     * Catalog username setter
900     *
901     * @param ?string $catUsername Catalog username
902     *
903     * @return UserEntityInterface
904     */
905    public function setCatUsername(?string $catUsername): UserEntityInterface
906    {
907        $this->cat_username = $catUsername;
908        return $this;
909    }
910
911    /**
912     * Get catalog username.
913     *
914     * @return ?string
915     */
916    public function getCatUsername(): ?string
917    {
918        return $this->cat_username ?? '';
919    }
920
921    /**
922     * Home library setter
923     *
924     * @param ?string $homeLibrary Home library
925     *
926     * @return UserEntityInterface
927     */
928    public function setHomeLibrary(?string $homeLibrary): UserEntityInterface
929    {
930        $this->home_library = $homeLibrary;
931        return $this;
932    }
933
934    /**
935     * Get home library.
936     *
937     * @return ?string
938     */
939    public function getHomeLibrary(): ?string
940    {
941        return $this->home_library;
942    }
943
944    /**
945     * Raw catalog password setter
946     *
947     * @param ?string $catPassword Cat password
948     *
949     * @return UserEntityInterface
950     */
951    public function setRawCatPassword(?string $catPassword): UserEntityInterface
952    {
953        $this->cat_password = $catPassword;
954        return $this;
955    }
956
957    /**
958     * Get raw catalog password.
959     *
960     * @return ?string
961     */
962    public function getRawCatPassword(): ?string
963    {
964        return $this->cat_password;
965    }
966
967    /**
968     * Encrypted catalog password setter
969     *
970     * @param ?string $passEnc Encrypted password
971     *
972     * @return UserEntityInterface
973     */
974    public function setCatPassEnc(?string $passEnc): UserEntityInterface
975    {
976        $this->cat_pass_enc = $passEnc;
977        return $this;
978    }
979
980    /**
981     * Get encrypted catalog password.
982     *
983     * @return ?string
984     */
985    public function getCatPassEnc(): ?string
986    {
987        return $this->cat_pass_enc;
988    }
989
990    /**
991     * Set college.
992     *
993     * @param string $college College
994     *
995     * @return UserEntityInterface
996     */
997    public function setCollege(string $college): UserEntityInterface
998    {
999        $this->college = $college;
1000        return $this;
1001    }
1002
1003    /**
1004     * Get college.
1005     *
1006     * @return string
1007     */
1008    public function getCollege(): string
1009    {
1010        return $this->college ?? '';
1011    }
1012
1013    /**
1014     * Set major.
1015     *
1016     * @param string $major Major
1017     *
1018     * @return UserEntityInterface
1019     */
1020    public function setMajor(string $major): UserEntityInterface
1021    {
1022        $this->major = $major;
1023        return $this;
1024    }
1025
1026    /**
1027     * Get major.
1028     *
1029     * @return string
1030     */
1031    public function getMajor(): string
1032    {
1033        return $this->major ?? '';
1034    }
1035
1036    /**
1037     * Set verification hash for recovery.
1038     *
1039     * @param string $hash Hash value to save
1040     *
1041     * @return UserEntityInterface
1042     */
1043    public function setVerifyHash(string $hash): UserEntityInterface
1044    {
1045        $this->verify_hash = $hash;
1046        return $this;
1047    }
1048
1049    /**
1050     * Get verification hash for recovery.
1051     *
1052     * @return string
1053     */
1054    public function getVerifyHash(): string
1055    {
1056        return $this->verify_hash ?? '';
1057    }
1058
1059    /**
1060     * Set active authentication method (if any).
1061     *
1062     * @param ?string $authMethod New value (null for none)
1063     *
1064     * @return UserEntityInterface
1065     */
1066    public function setAuthMethod(?string $authMethod): UserEntityInterface
1067    {
1068        $this->auth_method = $authMethod;
1069        return $this;
1070    }
1071
1072    /**
1073     * Get active authentication method (if any).
1074     *
1075     * @return ?string
1076     */
1077    public function getAuthMethod(): ?string
1078    {
1079        return $this->auth_method;
1080    }
1081
1082    /**
1083     * Set last language.
1084     *
1085     * @param string $lang Last language
1086     *
1087     * @return UserEntityInterface
1088     */
1089    public function setLastLanguage(string $lang): UserEntityInterface
1090    {
1091        $this->last_language = $lang;
1092        return $this;
1093    }
1094
1095    /**
1096     * Get last language.
1097     *
1098     * @return string
1099     */
1100    public function getLastLanguage(): string
1101    {
1102        return $this->last_language ?? '';
1103    }
1104
1105    /**
1106     * Does the user have a user-provided (true) vs. automatically looked up (false) email address?
1107     *
1108     * @return bool
1109     */
1110    public function hasUserProvidedEmail(): bool
1111    {
1112        return (bool)($this->user_provided_email ?? false);
1113    }
1114
1115    /**
1116     * Set the flag indicating whether the email address is user-provided.
1117     *
1118     * @param bool $userProvided New value
1119     *
1120     * @return UserEntityInterface
1121     */
1122    public function setHasUserProvidedEmail(bool $userProvided): UserEntityInterface
1123    {
1124        $this->user_provided_email = $userProvided ? 1 : 0;
1125        return $this;
1126    }
1127
1128    /**
1129     * Last login setter.
1130     *
1131     * @param DateTime $dateTime Last login date
1132     *
1133     * @return UserEntityInterface
1134     */
1135    public function setLastLogin(DateTime $dateTime): UserEntityInterface
1136    {
1137        $this->last_login = $dateTime->format('Y-m-d H:i:s');
1138        return $this;
1139    }
1140
1141    /**
1142     * Last login getter
1143     *
1144     * @return DateTime
1145     */
1146    public function getLastLogin(): DateTime
1147    {
1148        return DateTime::createFromFormat('Y-m-d H:i:s', $this->last_login);
1149    }
1150
1151    /**
1152     * Created setter
1153     *
1154     * @param DateTime $dateTime Creation date
1155     *
1156     * @return UserEntityInterface
1157     */
1158    public function setCreated(DateTime $dateTime): UserEntityInterface
1159    {
1160        $this->created = $dateTime->format('Y-m-d H:i:s');
1161        return $this;
1162    }
1163
1164    /**
1165     * Created getter
1166     *
1167     * @return DateTime
1168     */
1169    public function getCreated(): DateTime
1170    {
1171        return DateTime::createFromFormat('Y-m-d H:i:s', $this->created);
1172    }
1173
1174    /**
1175     * Set email verification date (or null for unverified).
1176     *
1177     * @param ?DateTime $dateTime Verification date (or null)
1178     *
1179     * @return UserEntityInterface
1180     */
1181    public function setEmailVerified(?DateTime $dateTime): UserEntityInterface
1182    {
1183        $this->email_verified = $dateTime?->format('Y-m-d H:i:s');
1184        return $this;
1185    }
1186
1187    /**
1188     * Get email verification date (or null for unverified).
1189     *
1190     * @return ?DateTime
1191     */
1192    public function getEmailVerified(): ?DateTime
1193    {
1194        return $this->email_verified ? DateTime::createFromFormat('Y-m-d H:i:s', $this->email_verified) : null;
1195    }
1196}