- Fixed #16160: Call to undefined function ezi18n()
[tinyz:tinyz.git] / kernel / classes / datatypes / ezuser / ezusertype.php
1 <?php
2 //
3 // Definition of eZUserType class
4 //
5 // Created on: <30-Apr-2002 13:06:21 bf>
6 //
7 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
8 // SOFTWARE NAME: eZ Publish
9 // SOFTWARE RELEASE: 4.1.x
10 // COPYRIGHT NOTICE: Copyright (C) 1999-2010 eZ Systems AS
11 // SOFTWARE LICENSE: GNU General Public License v2.0
12 // NOTICE: >
13 //   This program is free software; you can redistribute it and/or
14 //   modify it under the terms of version 2.0  of the GNU General
15 //   Public License as published by the Free Software Foundation.
16 //
17 //   This program is distributed in the hope that it will be useful,
18 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 //   GNU General Public License for more details.
21 //
22 //   You should have received a copy of version 2.0 of the GNU General
23 //   Public License along with this program; if not, write to the Free
24 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 //   MA 02110-1301, USA.
26 //
27 //
28 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
29 //
30
31 /*!
32   \class eZUserType ezusertype.php
33   \brief The class eZUserType handles user accounts and association with content objects
34   \ingroup eZDatatype
35
36 */
37
38 class eZUserType extends eZDataType
39 {
40     const DATA_TYPE_STRING = "ezuser";
41
42     function eZUserType( )
43     {
44         $this->eZDataType( self::DATA_TYPE_STRING, ezpI18n::translate( 'kernel/classes/datatypes', "User account", 'Datatype name' ),
45                            array( 'translation_allowed' => false,
46                                   'serialize_supported' => true ) );
47     }
48
49     /*!
50      Delete stored object attribute
51     */
52     function deleteStoredObjectAttribute( $contentObjectAttribute, $version = null )
53     {
54         $db = eZDB::instance();
55         $userID = $contentObjectAttribute->attribute( "contentobject_id" );
56
57         $res = $db->arrayQuery( "SELECT COUNT(*) AS version_count FROM ezcontentobject_version WHERE contentobject_id = $userID" );
58         $versionCount = $res[0]['version_count'];
59
60         if ( $version == null || $versionCount <= 1 )
61         {
62             eZUser::removeUser( $userID );
63             $db->query( "DELETE FROM ezuser_role WHERE contentobject_id = '$userID'" );
64         }
65     }
66
67     /*!
68      Validates the input and returns true if the input was
69      valid for this datatype.
70     */
71     function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
72     {
73         if ( $http->hasPostVariable( $base . "_data_user_login_" . $contentObjectAttribute->attribute( "id" ) ) &&
74              $http->hasPostVariable( $base . "_data_user_login_" . $contentObjectAttribute->attribute( "id" ) ) &&
75              $http->hasPostVariable( $base . "_data_user_email_" . $contentObjectAttribute->attribute( "id" ) ) &&
76              $http->hasPostVariable( $base . "_data_user_password_" . $contentObjectAttribute->attribute( "id" ) ) &&
77              $http->hasPostVariable( $base . "_data_user_password_confirm_" . $contentObjectAttribute->attribute( "id" ) ) )
78         {
79             $classAttribute = $contentObjectAttribute->contentClassAttribute();
80             $loginName = $http->postVariable( $base . "_data_user_login_" . $contentObjectAttribute->attribute( "id" ) );
81             $email = $http->postVariable( $base . "_data_user_email_" . $contentObjectAttribute->attribute( "id" ) );
82             $password = $http->postVariable( $base . "_data_user_password_" . $contentObjectAttribute->attribute( "id" ) );
83             $passwordConfirm = $http->postVariable( $base . "_data_user_password_confirm_" . $contentObjectAttribute->attribute( "id" ) );
84             if ( trim( $loginName ) == '' )
85             {
86                 if ( $contentObjectAttribute->validateIsRequired() || trim( $email ) != '' )
87                 {
88                     $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
89                                                                          'The username must be specified.' ) );
90                     return eZInputValidator::STATE_INVALID;
91                 }
92             }
93             else
94             {
95                 $existUser = eZUser::fetchByName( $loginName );
96                 if ( $existUser != null )
97                 {
98                     $userID = $existUser->attribute( 'contentobject_id' );
99                     if ( $userID !=  $contentObjectAttribute->attribute( "contentobject_id" ) )
100                     {
101                         $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
102                                                                              'The username already exists, please choose another one.' ) );
103                         return eZInputValidator::STATE_INVALID;
104                     }
105                 }
106                 // validate user email
107                 $isValidate = eZMail::validate( $email );
108                 if ( !$isValidate )
109                 {
110                     $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
111                                                                          'The email address is not valid.' ) );
112                     return eZInputValidator::STATE_INVALID;
113                 }
114                 $authenticationMatch = eZUser::authenticationMatch();
115                 if ( $authenticationMatch & eZUser::AUTHENTICATE_EMAIL )
116                 {
117                     if ( eZUser::requireUniqueEmail() )
118                     {
119                         $userByEmail = eZUser::fetchByEmail( $email );
120                         if ( $userByEmail != null )
121                         {
122                             $userID = $userByEmail->attribute( 'contentobject_id' );
123                             if ( $userID !=  $contentObjectAttribute->attribute( "contentobject_id" ) )
124                             {
125                                 $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
126                                                                                      'A user with this email already exists.' ) );
127                                 return eZInputValidator::STATE_INVALID;
128                             }
129                         }
130                     }
131                 }
132                 // validate user name
133                 if ( !eZUser::validateLoginName( $loginName, $errorText ) )
134                 {
135                     $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
136                                                                          $errorText ) );
137                     return eZInputValidator::STATE_INVALID;
138                 }
139                 // validate user password
140                 $ini = eZINI::instance();
141                 $generatePasswordIfEmpty = $ini->variable( "UserSettings", "GeneratePasswordIfEmpty" ) == 'true';
142                 if ( !$generatePasswordIfEmpty || ( $password != "" ) )
143                 {
144                     if ( $password == "" )
145                     {
146                         $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
147                                                                              'The password cannot be empty.',
148                                                                              'eZUserType' ) );
149                         return eZInputValidator::STATE_INVALID;
150                     }
151                     if ( $password != $passwordConfirm )
152                     {
153                         $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
154                                                                              'The passwords do not match.',
155                                                                              'eZUserType' ) );
156                         return eZInputValidator::STATE_INVALID;
157                     }
158                     if ( !eZUser::validatePassword( $password ) )
159                     {
160                         $minPasswordLength = $ini->hasVariable( 'UserSettings', 'MinPasswordLength' ) ? $ini->variable( 'UserSettings', 'MinPasswordLength' ) : 3;
161                         $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
162                                                                              'The password must be at least %1 characters long.', null, array( $minPasswordLength ) ) );
163                         return eZInputValidator::STATE_INVALID;
164                     }
165                     if ( strtolower( $password ) == 'password' )
166                     {
167                         $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes',
168                                                                              'The password must not be "password".' ) );
169                         return eZInputValidator::STATE_INVALID;
170                     }
171                 }
172             }
173         }
174         else if ( $contentObjectAttribute->validateIsRequired() )
175         {
176             $contentObjectAttribute->setValidationError( ezpI18n::translate( 'kernel/classes/datatypes', 'Input required.' ) );
177             return eZInputValidator::STATE_INVALID;
178         }
179         return eZInputValidator::STATE_ACCEPTED;
180     }
181
182     /*!
183      Fetches the http post var integer input and stores it in the data instance.
184     */
185     function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
186     {
187         if ( $http->hasPostVariable( $base . "_data_user_login_" . $contentObjectAttribute->attribute( "id" ) ) )
188         {
189             $login = $http->postVariable( $base . "_data_user_login_" . $contentObjectAttribute->attribute( "id" ) );
190             $email = $http->hasPostVariable( $base . "_data_user_email_" . $contentObjectAttribute->attribute( "id" ) ) ? $http->postVariable( $base . "_data_user_email_" . $contentObjectAttribute->attribute( "id" ) ) : '';
191             $password = $http->hasPostVariable( $base . "_data_user_password_" . $contentObjectAttribute->attribute( "id" ) ) ? $http->postVariable( $base . "_data_user_password_" . $contentObjectAttribute->attribute( "id" ) ) : '';
192             $passwordConfirm = $http->hasPostVariable( $base . "_data_user_password_confirm_" . $contentObjectAttribute->attribute( "id" ) ) ? $http->postVariable( $base . "_data_user_password_confirm_" . $contentObjectAttribute->attribute( "id" ) ) : '';
193
194             $contentObjectID = $contentObjectAttribute->attribute( "contentobject_id" );
195
196             $user = $contentObjectAttribute->content();
197             if ( $user === null )
198             {
199                 $user = eZUser::create( $contentObjectID );
200             }
201
202             $ini = eZINI::instance();
203             $generatePasswordIfEmpty = $ini->variable( "UserSettings", "GeneratePasswordIfEmpty" );
204             if ( $password == "" )
205             {
206                 if ( $generatePasswordIfEmpty == 'true' )
207                 {
208                     $passwordLength = $ini->variable( "UserSettings", "GeneratePasswordLength" );
209                     $password = $user->createPassword( $passwordLength );
210                     $passwordConfirm = $password;
211                     $http->setSessionVariable( "GeneratedPassword", $password );
212                 }
213                 else
214                 {
215                     $password = null;
216                 }
217             }
218
219             eZDebugSetting::writeDebug( 'kernel-user', $password, "password" );
220             eZDebugSetting::writeDebug( 'kernel-user', $passwordConfirm, "passwordConfirm" );
221             eZDebugSetting::writeDebug( 'kernel-user', $login, "login" );
222             eZDebugSetting::writeDebug( 'kernel-user', $email, "email" );
223             eZDebugSetting::writeDebug( 'kernel-user', $contentObjectID, "contentObjectID" );
224             if ( $password == "_ezpassword" )
225             {
226                 $password = false;
227                 $passwordConfirm = false;
228             }
229             else
230                 $http->setSessionVariable( "GeneratedPassword", $password );
231
232             eZDebugSetting::writeDebug( 'kernel-user', "setInformation run", "ezusertype" );
233             $user->setInformation( $contentObjectID, $login, $email, $password, $passwordConfirm );
234             $contentObjectAttribute->setContent( $user );
235             return true;
236         }
237         return false;
238     }
239
240     function storeObjectAttribute( $contentObjectAttribute )
241     {
242         $user = $contentObjectAttribute->content();
243         if ( !( $user instanceof eZUser ) )
244         {
245             // create a default user account
246             $user = eZUser::create( $contentObjectAttribute->attribute( "contentobject_id" ) );
247             $userID = $contentObjectAttribute->attribute( "contentobject_id" );
248             $isEnabled = 1;
249             $userSetting = eZUserSetting::create( $userID, $isEnabled );
250             $userSetting->store();
251         }
252         $user->store();
253         $contentObjectAttribute->setContent( $user );
254     }
255
256     /*!
257      Returns the object title.
258     */
259     function title( $contentObjectAttribute, $name = "login" )
260     {
261         $user = $this->objectAttributeContent( $contentObjectAttribute );
262
263         $value = $user->attribute( $name );
264
265         return $value;
266     }
267
268     function hasObjectAttributeContent( $contentObjectAttribute )
269     {
270         $user = $this->objectAttributeContent( $contentObjectAttribute );
271         if ( is_object( $user ) and
272              $user->isEnabled() )
273             return true;
274         return false;
275     }
276
277     /*!
278      Returns the user object.
279     */
280     function objectAttributeContent( $contentObjectAttribute )
281     {
282         $userID = $contentObjectAttribute->attribute( "contentobject_id" );
283         if ( empty( $GLOBALS['eZUserObject_' . $userID] ) )
284         {
285             $GLOBALS['eZUserObject_' . $userID] = eZUser::fetch( $userID );
286         }
287         $user = eZUser::fetch( $userID );
288         eZDebugSetting::writeDebug( 'kernel-user', $user, 'user' );
289         return $user;
290     }
291
292     function isIndexable()
293     {
294         return true;
295     }
296
297     /*!
298      We can only remove the user attribute if:
299      - The current user, anonymous user and administrator user is not using this class
300      - There are more classes with the ezuser datatype
301     */
302     function classAttributeRemovableInformation( $contentClassAttribute, $includeAll = true )
303     {
304         $result  = array( 'text' => ezpI18n::translate( 'kernel/classes/datatypes',
305                                             "Cannot remove the account:" ),
306                           'list' => array() );
307         $currentUser = eZUser::currentUser();
308         $userObject  = $currentUser->attribute( 'contentobject' );
309         $ini         = eZINI::instance();
310         $anonID      = (int)$ini->variable( 'UserSettings', 'AnonymousUserID' );
311         $classID     = (int)$contentClassAttribute->attribute( 'contentclass_id' );
312         $db          = eZDB::instance();
313
314         if ( $classID == $userObject->attribute( 'contentclass_id' ) )
315         {
316             $result['list'][] = array( 'text' => ezpI18n::translate( 'kernel/classes/datatypes',
317                                                          "The account owner is currently logged in." ) );
318             if ( !$includeAll )
319                 return $result;
320         }
321
322         $sql = "SELECT id FROM ezcontentobject WHERE id = $anonID AND contentclass_id = $classID";
323         $rows = $db->arrayQuery( $sql );
324         if ( count( $rows ) > 0 )
325         {
326             $result['list'][] = array( 'text' => ezpI18n::translate( 'kernel/classes/datatypes',
327                                                          "The account is currently used by the anonymous user." ) );
328             if ( !$includeAll )
329                 return $result;
330         }
331
332         $sql = "SELECT ezco.id FROM ezcontentobject ezco, ezuser
333  WHERE ezco.contentclass_id = $classID AND
334        ezuser.login = 'admin' AND
335        ezco.id = ezuser.contentobject_id ";
336         $rows = $db->arrayQuery( $sql );
337         if ( count( $rows ) > 0 )
338         {
339             $result['list'][] = array( 'text' => ezpI18n::translate( 'kernel/classes/datatypes',
340                                                          "The account is currently used the administrator user." ) );
341             if ( !$includeAll )
342                 return $result;
343         }
344
345         $sql = "SELECT count( ezcc.id ) AS count FROM ezcontentclass ezcc, ezcontentclass_attribute ezcca
346  WHERE ezcc.id != $classID AND
347        ezcca.data_type_string = 'ezuser' AND
348        ezcc.id = ezcca.contentclass_id ";
349         $rows = $db->arrayQuery( $sql );
350         if ( $rows[0]['count'] == 0 )
351         {
352             $result['list'][] = array( 'text' => ezpI18n::translate( 'kernel/classes/datatypes',
353                                                          "You cannot remove the last class holding user accounts." ) );
354             if ( !$includeAll )
355                 return $result;
356         }
357
358         return $result;
359     }
360
361     /*!
362      Returns the meta data used for storing search indeces.
363     */
364     function metaData( $contentObjectAttribute )
365     {
366         $metaString = "";
367         $user = $contentObjectAttribute->content();
368
369         if ( $user instanceof eZUser )
370         {
371             // create a default user account
372             $metaString .= $user->attribute( 'login' ) . " ";
373             $metaString .= $user->attribute( 'email' ) . " ";
374         }
375         return $metaString;
376     }
377
378     function toString( $contentObjectAttribute )
379     {
380         $userID = $contentObjectAttribute->attribute( "contentobject_id" );
381         if ( empty( $GLOBALS['eZUserObject_' . $userID] ) )
382         {
383             $GLOBALS['eZUserObject_' . $userID] = eZUser::fetch( $userID );
384         }
385         $user = $GLOBALS['eZUserObject_' . $userID];
386
387         return implode( '|', array( $user->attribute( 'login' ),
388                                     $user->attribute( 'email' ),
389                                     $user->attribute( 'password_hash' ),
390                                     eZUser::passwordHashTypeName( $user->attribute( 'password_hash_type' ) )  ) );
391     }
392
393
394     function fromString( $contentObjectAttribute, $string )
395     {
396         if ( $string == '' )
397             return true;
398         $userData = explode( '|', $string );
399         if( count( $userData ) < 2 )
400             return false;
401         $login = $userData[0];
402         $email = $userData[1];
403
404         if ( eZUser::fetchByName( $login ) || eZUser::fetchByEmail( $email ) )
405             return false;
406
407         $user = eZUser::create( $contentObjectAttribute->attribute( 'contentobject_id' ) );
408
409         $user->setAttribute( 'login', $login );
410         $user->setAttribute( 'email', $email );
411         if ( isset( $userData[2] ) )
412             $user->setAttribute( 'password_hash', $userData[2] );
413
414         if ( isset( $userData[3] ) )
415             $user->setAttribute( 'password_hash_type', eZUser::passwordHashTypeID( $userData[3] ) );
416         $user->store();
417         return $user;
418     }
419
420     /*!
421      \param package
422      \param content attribute
423
424      \return a DOM representation of the content object attribute
425     */
426     function serializeContentObjectAttribute( $package, $objectAttribute )
427     {
428         $node = $this->createContentObjectAttributeDOMNode( $objectAttribute );
429         $userID = $objectAttribute->attribute( "contentobject_id" );
430         $user = eZUser::fetch( $userID );
431         if ( is_object( $user ) )
432         {
433             $userNode = $node->ownerDocument->createElement( 'account' );
434             $userNode->setAttribute( 'login', $user->attribute( 'login' ) );
435             $userNode->setAttribute( 'email', $user->attribute( 'email' ) );
436             $userNode->setAttribute( 'password_hash', $user->attribute( 'password_hash' ) );
437             $userNode->setAttribute( 'password_hash_type', eZUser::passwordHashTypeName( $user->attribute( 'password_hash_type' ) ) );
438             $node->appendChild( $userNode );
439         }
440
441         return $node;
442     }
443
444     /*!
445      \param package
446      \param contentobject attribute object
447      \param ezdomnode object
448     */
449     function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode )
450     {
451         $userNode = $attributeNode->getElementsByTagName( 'account' )->item( 0 );
452         if ( is_object( $userNode ) )
453         {
454             $userID = $objectAttribute->attribute( 'contentobject_id' );
455             $user = eZUser::fetch( $userID );
456             if ( !is_object( $user ) )
457             {
458                 $user = eZUser::create( $userID );
459             }
460             $user->setAttribute( 'login', $userNode->getAttribute( 'login' ) );
461             $user->setAttribute( 'email', $userNode->getAttribute( 'email' ) );
462             $user->setAttribute( 'password_hash', $userNode->getAttribute( 'password_hash' ) );
463             $user->setAttribute( 'password_hash_type', eZUser::passwordHashTypeID( $userNode->getAttribute( 'password_hash_type' ) ) );
464             $user->store();
465         }
466     }
467 }
468
469 eZDataType::register( eZUserType::DATA_TYPE_STRING, "eZUserType" );
470
471 ?>