Overview

Namespaces

  • Flea
  • None

Classes

  • Flea
  • Flea\BuildUtil
  • Flea\Cache
  • Flea\DataBase
  • Flea\DataBaseCRUD
  • Flea\DataList
  • Flea\DataUtil
  • Flea\Debug
  • Flea\FileUtil
  • Flea\General
  • Flea\Header
  • Flea\InitUtil
  • Flea\LangList
  • Flea\Login
  • Flea\LoginFormHelper
  • Flea\LoginTableName
  • Flea\LoginUser
  • Flea\Page
  • Flea\PageList
  • Flea\PageListCreate
  • Flea\SqlQuery
  • Flea\TagUtil
  • Flea\UrlUtil
  • Flea\ValueObject
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /*
  4:  * The MIT License
  5:  *
  6:  * Copyright 2014 Damien Doussaud (namide.com)
  7:  *
  8:  * Permission is hereby granted, free of charge, to any person obtaining a copy
  9:  * of this software and associated documentation files (the "Software"), to deal
 10:  * in the Software without restriction, including without limitation the rights
 11:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12:  * copies of the Software, and to permit persons to whom the Software is
 13:  * furnished to do so, subject to the following conditions:
 14:  *
 15:  * The above copyright notice and this permission notice shall be included in
 16:  * all copies or substantial portions of the Software.
 17:  *
 18:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24:  * THE SOFTWARE.
 25:  */
 26: 
 27: namespace Flea;
 28: 
 29: /**
 30:  * Flags for the names of the table used by the Login class.
 31:  * 
 32:  * @author Namide
 33:  */
 34: class LoginTableName {
 35: 
 36:     /**
 37:      * Name of the table of the datas of users.
 38:      * Datas are optionnal and unlimited.
 39:      * @var string 
 40:      */
 41:     public static $TABLE_NAME_DATAS = 'login_datas';
 42: 
 43:     /**
 44:      * Name of the table of users (email, password...).
 45:      * @var string
 46:      */
 47:     public static $TABLE_NAME_USERS = 'login_users';
 48: 
 49:     /**
 50:      * Name of the table of logs of users.
 51:      * @var string 
 52:      */
 53:     public static $TABLE_NAME_LOGS = 'login_logs';
 54: 
 55: }
 56: 
 57: /**
 58:  * User's variables used by the Login class.
 59:  * 
 60:  * @author Namide
 61:  */
 62: class LoginUser {
 63: 
 64:     /**
 65:      * Role of the user. Basic user is authorized to less informations.
 66:      * 
 67:      * @var int
 68:      */
 69:     public static $ROLE_BASIC = 1;
 70: 
 71:     /**
 72:      * Role of the user. Admin is authorized to more informations.
 73:      * 
 74:      * @var int
 75:      */
 76:     public static $ROLE_ADMIN = 2;
 77:     private $_db;
 78:     private $_email;
 79: 
 80:     /**
 81:      * Email of the user
 82:      * 
 83:      * @return string
 84:      */
 85:     public function getEmail() {
 86:         return $this->_email;
 87:     }
 88: 
 89:     private $_token;
 90: 
 91:     /**
 92:      * Token is used for security
 93:      * 
 94:      * @return string
 95:      */
 96:     public function getToken() {
 97:         return $this->_token;
 98:     }
 99: 
100:     private $_role;
101: 
102:     /**
103:      * Role of the user: LoginUser::$ROLE_BASIC or LoginUser::$ROLE_ADMIN
104:      * 
105:      * @return int
106:      */
107:     public function getRole() {
108:         return $this->_role;
109:     }
110: 
111:     /**
112:      * Init the user.
113:      * 
114:      * @param DataBase $db      DataBase used to this user
115:      */
116:     public function __construct($db) {
117:         $this->_db = $db;
118:     }
119: 
120:     /**
121:      * Initialize user's datas
122:      * 
123:      * @param type $email   Email of the user   
124:      * @param type $token   Token of the current conection of the user
125:      * @param type $role    Role of the user
126:      */
127:     public function init($email, $token, $role = 1) {
128:         $this->_email = $email;
129:         $this->_token = $token;
130:         $this->_role = $role;
131:     }
132: 
133:     private $_datas;
134: 
135:     /**
136:      * A data is a pair with key and value.
137:      * 
138:      * @return DataList     Data of the user
139:      */
140:     public function getDatas() {
141:         if ($this->_datas === null) {
142:             $this->_datas = new DataList(true);
143: 
144:             $query = SqlQuery::getTemp(SqlQuery::$TYPE_SELECT);
145:             $where = array('user_email' => $this->getEmail());
146:             $query->initSelect('key, value', '`' . LoginTableName::$TABLE_NAME_DATAS . '`', $where);
147: 
148:             foreach ($this->_db->fetchAll($query) as $row) {
149:                 $this->_datas->add($row['value'], $row['key']);
150:             }
151:         }
152:         return $this->_datas;
153:     }
154: 
155: }
156: 
157: /**
158:  * Class to manipulate Users (connect, disconnect, add...)
159:  * 
160:  * @author Namide
161:  */
162: class Login {
163: 
164:     private static $_INSTANCE = array();
165:     private static $_HASH_ALGO = 'whirlpool';
166:     private static $_IS_SESSION_STARTED = false;
167: 
168:     /**
169:      * @var DataBase
170:      */
171:     private $_db;
172:     private $_loginFormHelper = null;
173:     private $_user = null;
174: 
175:     /**
176:      * Test if this user is connected (with Session).
177:      * 
178:      * @return boolean      Is connected
179:      */
180:     public function isConnected() {
181:         if (isset($_SESSION['login_token'])) {
182:             if ($this->_user === null) {
183:                 $where = array('token' => $_SESSION['login_token']);
184:                 $query = SqlQuery::getTemp(SqlQuery::$TYPE_SELECT);
185:                 $query->initSelect('*', LoginTableName::$TABLE_NAME_USERS, $where);
186:                 $rows = $this->_db->fetchAll($query);
187:                 if (count($rows) < 1) {
188:                     return false;
189:                 }
190:             }
191:             return true;
192:         }
193:         return false;
194:     }
195: 
196:     /**
197:      * User connected.
198:      * 
199:      * @return ValueObject
200:      */
201:     public function getUserConnected() {
202:         if (!$this->isConnected()) {
203:             //if ( _DEBUG ) Debug::getInstance()->addError ('User is\'n connected');
204:             return new ValueObject(null, true, array('You are don\'t connected'));
205:         }
206: 
207:         if ($this->_user == null) {
208:             $query = SqlQuery::getTemp();
209:             $where = array('token' => $_SESSION['login_token']);
210:             $query->initSelect('*', LoginTableName::$TABLE_NAME_USERS, $where);
211:             $rows = $this->_db->fetchAll($query);
212:             if (count($rows) < 1) {
213:                 return new ValueObject(null, true, array('Connection data corrupted'));
214:             }
215: 
216:             $this->_user = new LoginUser($this->_db);
217:             $this->_user->init($rows[0]['email'], $rows[0]['token'], $rows[0]['role']);
218:         }
219: 
220:         return new ValueObject($this->_user);
221:         ;
222:     }
223: 
224:     /**
225:      * An helper to make formularies of the login page.
226:      * 
227:      * @return LoginFormHelper
228:      */
229:     public function getLoginFormHelper() {
230:         if ($this->_loginFormHelper === null) {
231:             include_once _SYSTEM_DIRECTORY . 'helpers/miscellaneous/LoginFormHelper.php';
232:             $this->_loginFormHelper = new LoginFormHelper($this);
233:         }
234:         return $this->_loginFormHelper;
235:     }
236: 
237:     /**
238:      * Crypt the password.
239:      * 
240:      * @param string $realPass      Password not crypted
241:      * @param string $email         Email of the user (for the saltz)
242:      * @return string               Password crypted
243:      */
244:     public function passEncrypt($realPass, $email) {
245:         return hash(self::$_HASH_ALGO, $realPass . $email);
246:     }
247: 
248:     /**
249:      * Test if the data base has 1 or more users.
250:      * 
251:      * @return bool     True is it has 1 or more users in the data base
252:      */
253:     public function hasUsersInList() {
254:         $query = SqlQuery::getTemp(SqlQuery::$TYPE_SELECT);
255:         $query->initSelect('COUNT(*)', LoginTableName::$TABLE_NAME_USERS);
256:         return $this->_db->count($query) > 0;
257:     }
258: 
259:     /**
260:      * Found and return a ValueObject with the user
261:      * (error if no user connected or email not found or
262:      * if the user don't have authorizations).
263:      * Work only if your are admin and connected
264:      * 
265:      * @param string $email     Mail of the user
266:      * @return ValueObject      <code>getUserByEMail( $email )->content</code>;
267:      */
268:     public function getUserByEMail($email) {
269:         $userConnectedVO = $this->getUserConnected();
270:         if ($userConnectedVO->error) {
271:             return new ValueObject(null, true, $userConnectedVO->errorList);
272:         } else if ($userConnectedVO->content->getRole() != LoginUser::$ROLE_ADMIN) {
273:             return new ValueObject(null, true, array('Only admin can see others user with her email'));
274:         }
275: 
276:         $tnu = LoginTableName::$TABLE_NAME_USERS;
277: 
278:         $query = SqlQuery::getTemp(SqlQuery::$TYPE_SELECT);
279:         $query->initSelect('email, role', $tnu, array('email' => $email));
280:         $rows = $this->_db->fetchAll($query);
281:         if (count($rows) < 1) {
282:             return new ValueObject(null, true, array('No users have this email'));
283:         }
284: 
285:         $user = new LoginUser($this->_db);
286:         $user->init($rows[0]['email'], 'null', $rows[0]['role']);
287:         return new ValueObject($user);
288:     }
289: 
290:     /**
291:      * List of the users.
292:      * Only if your are admin and connected
293:      * <br>Example of getUserList() in <code>en.php</code>
294:      * <pre>
295:      * $vo = $login->getUserList('group', 'admin');
296:      * $list = $vo->content;
297:      * $output = '';
298:      * if ( !$vo->error )
299:      * {
300:      *   foreach ($list as $userMail => $userDatas)
301:      *   {
302:      *     $output .= $userMail.'<br>-role: '.$userDatas['role'].'<br>';
303:      *     foreach ($userDatas['datas'] as $dataKey => $dataValue )
304:      *     {
305:      *       $output .= '-'.$dataKey.': '.$dataValue.'<br>';
306:      *     }
307:      *   }
308:      * }
309:      * else if ( count($vo->errorList)>0 )
310:      * {
311:      *   foreach ($vo->errorList as $errorInfo)
312:      *   {
313:      *     $output .= $errorInfo;
314:      *   }
315:      * }
316:      * echo $output;
317:      * </pre>
318:      * 
319:      * @param string $dataKey               Key for the filter (example: group)
320:      * @param string $dataValue             Value for the filter (example: gamer)
321:      * @return ValueObject                  List of the users with $dataKey = $dataValue
322:      */
323:     public function getUserList($dataKey = null, $dataValue = null) {
324:         $list = array();
325: 
326:         $userConnectedVO = $this->getUserConnected();
327:         if ($userConnectedVO->error) {
328:             return new ValueObject($list, true, $userConnectedVO->errorList);
329:         } else if ($userConnectedVO->content->getRole() != LoginUser::$ROLE_ADMIN) {
330:             return new ValueObject($list, true, array('Only admin can see others user with her email'));
331:         }
332: 
333:         $tnu = LoginTableName::$TABLE_NAME_USERS;
334:         $tnd = LoginTableName::$TABLE_NAME_DATAS;
335: 
336:         $query = SqlQuery::getTemp(SqlQuery::$TYPE_SELECT);
337:         $query->initSelect('email, role', $tnu);
338:         if ($dataKey !== null && $dataValue !== null) {
339:             $query->setFrom('`' . $tnu . '` '
340:                     . 'LEFT JOIN ' . $tnd . ' '
341:                     . 'ON ' . $tnu . '.email = ' . $tnd . '.user_email');
342:             $query->setWhere($tnd . '.key = \'' . $dataKey . '\' AND ' . $tnd . '.value = \'' . $dataValue . '\'');
343:         }
344: 
345:         foreach ($this->_db->fetchAll($query) as $user) {
346:             $list[$user['email']] = new LoginUser($this->_db);
347:             $list[$user['email']]->init($user['email'], 'null', $user['role']);
348:         }
349: 
350:         return new ValueObject($list);
351:     }
352: 
353:     /**
354:      * Add a new user.
355:      * Only if your are admin and connected.<br>
356:      * <br>Example of addUser() in <code>en.php</code>
357:      * <pre>
358:      * $build = Flea::getBuildUtil();
359:      * $gen = Flea::getGeneral();
360:      * $post = $gen->getCurrentPostUrl();
361:      * if ( isset($post['addUserEmail']) &&
362:      *      isset($post['addUserPass']) )
363:      * {
364:      *  $login->addUser( $post['addUserEmail'],
365:      *              $post['addUserPass'] );
366:      * }
367:      * $currentUrl = $build->getAbsUrl( $gen->getCurrentPage()->getName() );
368:      * $form = '<form method="post" action="'.$currentUrl.'">
369:      *      <input class="field" 
370:      *              type="text"
371:      *              name="addUserEmail"
372:      *              placeholder="E-mail"
373:      *              value=""
374:      *              required="required"
375:      *              pattern="^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$"/>
376:      *      <input class="field"
377:      *              type="password"
378:      *              name="addUserPass"
379:      *              placeholder="Password"
380:      *              value=""
381:      *              required="required"/>
382:      *      <input type="submit"
383:      *              name="add"
384:      *              value="add">
385:      *  </form>';
386:      * echo $form;
387:      * </pre>
388:      * 
389:      * @param type $email       Email of the new user
390:      * @param type $realPass    Password of the new user
391:      * @param type $role        Role of the new user
392:      * @return ValueObject      Content is true if the user is added
393:      */
394:     public function addUser($email, $realPass, $role = 1) {
395:         $userConnectedVO = $this->getUserConnected();
396:         if ($userConnectedVO->error) {
397:             return new ValueObject(false, true, $userConnectedVO->errorList);
398:         } else if ($userConnectedVO->content->getRole() != LoginUser::$ROLE_ADMIN) {
399:             return new ValueObject(false, true, array('Only admin can add a user.'));
400:         }
401: 
402:         return registerUser($email, $realPass, $role);
403:     }
404: 
405:     /**
406:      * Register a new user
407:      * 
408:      * @param type $email       Email of the new user
409:      * @param type $realPass    Password of the new user
410:      * @param type $role        Role of the new user
411:      * @return ValueObject      ValueObject with datas : content = true if the user is added
412:      */
413:     public function registerUser($email, $realPass, $role = 1) {
414:         $sameEmail = $this->getUserByEMail($email);
415:         if (!$sameEmail->error && $sameEmail->content !== null) {
416:             return new ValueObject(false, true, array('An user with the same email already exist.'));
417:         }
418: 
419:         $query = SqlQuery::getTemp(SqlQuery::$TYPE_INSERT);
420:         $values = array();
421:         $values['email'] = $email;
422:         $values['pass'] = $this->passEncrypt($realPass, $email);
423:         $values['role'] = $role;
424:         $values['token'] = $this->generateToken();
425:         $insert = LoginTableName::$TABLE_NAME_USERS;
426:         $query->initInsertValues($insert, $values);
427:         $this->_db->execute($query);
428: 
429:         return new ValueObject(true);
430:     }
431: 
432:     /**
433:      * Add informations to a user.
434:      * Only if your are admin and connected
435:      * 
436:      * @param type $userEmail       Email of the user
437:      * @param type $dataKey         Label of the data (example: group)
438:      * @param type $dataValue       Value of the data (example: gamer)
439:      * @return ValueObject          ValueObject, $vo->content = true if the data is added
440:      */
441:     public function addDataToUser($userEmail, $dataKey, $dataValue) {
442:         $userConnectedVO = $this->getUserConnected();
443:         if ($userConnectedVO->error) {
444:             return new ValueObject(false, true, $userConnectedVO->errorList);
445:         } else if ($userConnectedVO->content->getRole() != LoginUser::$ROLE_ADMIN ||
446:                 $userConnectedVO->content->getEmail() == $userEmail) {
447:             return new ValueObject(false, true, array('Only admin or the user can add data.'));
448:         }
449: 
450:         if ($this->_db->exist(LoginTableName::$TABLE_NAME_DATAS)) {
451:             $query = SqlQuery::getTemp(SqlQuery::$TYPE_INSERT);
452:             $values = array();
453:             $values['user_email'] = $userEmail;
454:             $values['key'] = $dataKey;
455:             $values['value'] = $dataValue;
456:             $insert = LoginTableName::$TABLE_NAME_DATAS;
457:             $query->initInsertValues($insert, $values);
458: 
459:             $added = $this->_db->execute($query);
460:             if ($added) {
461:                 return new ValueObject(true);
462:             } else {
463:                 return new ValueObject(false, true, array('An error as occured in the data base.'));
464:             }
465:         }
466: 
467:         return new ValueObject(false, true, array('This table does not exist in the database'));
468:     }
469: 
470:     /**
471:      * Connect the user.
472:      * After this state a token will be storage in the session
473:      * <br>Example of connect() in <code>en.php</code>
474:      * <pre>
475:      * $build = Flea::getBuildUtil();
476:      * $gen = \Flea\General::getInstance();
477:      * $post = $gen->getCurrentPostUrl();
478:      * if ( isset($post['connectUserEmail']) &&
479:      *      isset($post['connectUserPass']) )
480:      * {
481:      *  $login->connect( $post['connectUserEmail'], 
482:      *          $post['connectUserPass'] );
483:      * }
484:      * $currentUrl = $build->getAbsUrl( $gen->getCurrentPage()->getName() );
485:      * $form = '<form method="post" action="'.$currentUrl.'">
486:      *      <input class="field"
487:      *          type="text" 
488:      *          name="connectUserEmail" 
489:      *          placeholder="E-mail" 
490:      *          value="" 
491:      *          required="required"/>
492:      *      <input class="field" 
493:      *          type="password" 
494:      *          name="connectUserPass" 
495:      *          placeholder="Password" 
496:      *          value="" required="required"/>
497:      *      <input type="submit" 
498:      *          name="connect" 
499:      *          value="connect">
500:      *      </form>';
501:      * echo $form;
502:      * </pre>
503:      * 
504:      * @param string $email         Email of the user
505:      * @param string $realPass      Password of the user
506:      * @return ValueObject          It is connected
507:      */
508:     public function connect($email, $realPass) {
509:         $time = time();
510: 
511:         // anti-brute-force -->
512:         $query = SqlQuery::getTemp(SqlQuery::$TYPE_INSERT);
513:         $datas = array();
514:         //$datas['id'] = null;
515:         $datas['user_email'] = $email;
516:         $datas['time'] = $time;
517:         $datas['ip'] = $_SERVER["REMOTE_ADDR"];
518:         $query->initInsertValues(LoginTableName::$TABLE_NAME_LOGS, $datas);
519:         $this->_db->execute($query);
520: 
521:         $query2 = SqlQuery::getTemp();
522:         $query2->initCount(LoginTableName::$TABLE_NAME_LOGS, array('user_email' => $email, 'time' => ($time - 2)), array('=', '>'));
523:         if ($this->_db->count($query2) > 1) {
524:             return new ValueObject(false, true, array('The server has detected an attack by brute forcing.'));
525:         }
526:         // <-- anti-brute-force
527: 
528:         $cryptedPass = $this->passEncrypt($realPass, $email);
529:         $where3 = array('email' => $email, 'pass' => $cryptedPass);
530:         $query3 = SqlQuery::getTemp();
531:         $query3->initSelect('*', LoginTableName::$TABLE_NAME_USERS, $where3);
532:         $rows = $this->_db->fetchAll($query3);
533:         if (count($rows) < 1) {
534:             return new ValueObject(false, true, array('No password matches this email.'));
535:         }
536: 
537:         $token = $this->generateToken();
538:         $query4 = SqlQuery::getTemp(SqlQuery::$TYPE_UPDATE);
539:         $query4->setUpdate(LoginTableName::$TABLE_NAME_USERS);
540:         $query4->setSet('token = \'' . $token . '\'');
541:         $query4->setWhere('email = \'' . $rows[0]['email'] . '\'');
542: 
543:         if ($this->_db->execute($query4)) {
544:             $_SESSION['login_token'] = $token;
545:             return new ValueObject(true);
546:         } else {
547:             return new ValueObject(false, true, array('An error in the data base has occurred.'));
548:         }
549:     }
550: 
551:     /**
552:      * Disconnect the current connected user.
553:      * <br>Example of connect() in <code>en.php</code>
554:      * <pre>
555:      * $buil = Flea::getBuildUtil();
556:      * $gen = \Flea\General::getInstance();
557:      * $post = $gen->getCurrentPostUrl();
558:      * if ( isset($post['disconnectUser']) )
559:      * {
560:      *   $login->disconnect();
561:      * }
562:      * $currentUrl = $buil->getAbsUrl( $gen->getCurrentPage()->getName() );
563:      * $form = '<form method="post" action="'.$currentUrl.'">
564:      *          <input type="hidden" name="disconnectUser" value="1">
565:      *          <input type="submit" name="disconnect" value="disconnect">
566:      *      </form>';
567:      * echo $form;
568:      * </pre>
569:      * 
570:      * @return boolean
571:      */
572:     public function disconnect() {
573:         $vo = $this->getUserConnected();
574:         if (!$vo->error) {
575:             $user = $vo->content;
576: 
577:             $token = $this->generateToken();
578:             $query = SqlQuery::getTemp(SqlQuery::$TYPE_UPDATE);
579:             $query->setUpdate(LoginTableName::$TABLE_NAME_USERS);
580:             $query->setSet('token = \'' . $token . '\'');
581:             $query->setWhere('email = \'' . $user->getEmail() . '\'');
582:             $this->_db->execute($query);
583:         }
584: 
585:         $this->_user = null;
586: 
587:         session_unset();
588:         session_destroy();
589:         return true;
590:     }
591: 
592:     private function generateToken() {
593:         return md5(rand(0, 9999) . microtime());
594:     }
595: 
596:     /**
597:      * Create the table of the users.
598:      */
599:     private function create() {
600:         $req1 = SqlQuery::getTemp(SqlQuery::$TYPE_CREATE);
601:         $create1 = 'TABLE IF NOT EXISTS `' . LoginTableName::$TABLE_NAME_USERS . '` ( '
602:                 . 'email TEXT UNIQUE, '
603:                 . 'pass TEXT, '
604:                 . 'role INT DEFAULT 0, '
605:                 . 'token TEXT DEFAULT \'' . $this->generateToken() . '\' '
606:                 . ');';
607:         $req1->setCreate($create1);
608:         $this->_db->execute($req1);
609: 
610:         $req2 = SqlQuery::getTemp(SqlQuery::$TYPE_CREATE);
611:         $create2 = 'TABLE IF NOT EXISTS `' . LoginTableName::$TABLE_NAME_LOGS . '` ( '
612:                 . 'user_email TEXT, '
613:                 . 'time INT, '
614:                 . 'ip TEXT );';
615:         $req2->setCreate($create2);
616:         $this->_db->execute($req2);
617: 
618:         $req3 = SqlQuery::getTemp(SqlQuery::$TYPE_CREATE);
619:         $create3 = 'TABLE IF NOT EXISTS `' . LoginTableName::$TABLE_NAME_DATAS . '` ( '
620:                 . 'user_email TEXT, '
621:                 . 'key INT, '
622:                 . 'value TEXT );';
623:         $req3->setCreate($create3);
624:         $this->_db->execute($req3);
625:     }
626: 
627:     /**
628:      * Test if the table of the user exist.
629:      * 
630:      * @return Bool         True if the table exist 
631:      */
632:     private function isDbInitialized() {
633:         return $this->_db->exist(LoginTableName::$TABLE_NAME_USERS);
634:     }
635: 
636:     private function __construct($dbDsn) {
637:         if (!self::$_IS_SESSION_STARTED) {
638:             session_start();
639:             self::$_IS_SESSION_STARTED = true;
640:         }
641: 
642:         $this->_db = DataBase::getInstance($dbDsn);
643: 
644:         if (!$this->isDbInitialized()) {
645:             $this->create();
646:         }
647:     }
648: 
649:     /**
650:      * Get the Login manager
651:      * 
652:      * @param string $dbDsn     Data Source Name of the data base
653:      * @return Login            Login corresponding at the data base
654:      */
655:     public static function getInstance($dbDsn) {
656:         if (!isset(self::$_INSTANCE[$dbDsn])) {
657:             self::$_INSTANCE[$dbDsn] = new Login($dbDsn);
658:         }
659:         return self::$_INSTANCE[$dbDsn];
660:     }
661: 
662:     final private function __clone() {
663:         if (_DEBUG) {
664:             Debug::getInstance()->addError('You can\'t clone a multiton');
665:         }
666:     }
667: 
668: }
669: 
Flea API documentation generated by ApiGen