Example #1
0
 /**
  * Set the field values
  *
  * @param  array $values
  * @return UserEmail
  */
 public function setFieldValues(array $values = null)
 {
     parent::setFieldValues($values);
     if ($_POST && null !== $this->email) {
         // Check for dupe email
         $user = null;
         $email = null;
         if (null !== $this->email) {
             $user = Table\Users::findBy(['username' => $this->email]);
             if (isset($user->id) && $this->id != $user->id) {
                 $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'That email already exists.'));
             } else {
                 $email = Table\Users::findBy(['email' => $this->email]);
                 if (isset($email->id) && $this->id != $email->id) {
                     $this->getElement('email')->addValidator(new Validator\NotEqual($this->email1, 'That email already exists.'));
                 }
             }
         }
         // If existing user
         if ((int) $_POST['id'] > 0) {
             if (!empty($this->password1)) {
                 $this->getElement('password2')->setRequired(true)->addValidator(new Validator\Equal($this->password1, 'The passwords do not match.'));
             }
             // Else, if new user, check email and password matches
         } else {
             $this->getElement('password2')->setRequired(true)->addValidator(new Validator\Equal($this->password1, 'The passwords do not match.'));
         }
     }
     return $this;
 }
Example #2
0
 /**
  * Config the auth object
  *
  * @param  \Phire\Table\UserTypes $type
  * @param  string                 $username
  * @param  array                  $options
  * @return \Phire\Auth\Auth
  */
 public function config($type, $username = null, $options = array())
 {
     // Set the password encryption and salt
     $this->setEncryption((int) $type->password_encryption);
     $this->setEncryptionOptions($options);
     // Set attempt limit
     $this->setAttemptLimit((int) $type->allowed_attempts);
     // Set allowed IPs
     if (!empty($type->ip_allowed)) {
         $allowed = explode(',', $type->ip_allowed);
         $this->setAllowedIps($allowed);
         $this->setAllowedSubnets($allowed);
     }
     // Set blocked IPs
     if (!empty($type->ip_blocked)) {
         $blocked = explode(',', $type->ip_blocked);
         $this->setBlockedIps($blocked);
         $this->setBlockedSubnets($blocked);
     }
     // Set failed attempts
     if (null !== $username) {
         $user = Table\Users::findBy(array('username' => $username));
         if (isset($user->id)) {
             $this->setAttempts((int) $user->failed_attempts);
         }
     }
     return $this;
 }
Example #3
0
 /**
  * Set the field values
  *
  * @param  array                  $values
  * @param  array                  $filters
  * @param  \Phire\Auth\Auth       $auth
  * @param  \Phire\Table\UserTypes $type
  * @param  \Phire\Model\User      $user
  * @return \Pop\Form\Form
  */
 public function setFieldValues(array $values = null, $filters = null, $auth = null, $type = null, $user = null)
 {
     parent::setFieldValues($values, $filters);
     if ($_POST) {
         // Authenticate and get the auth result
         $auth->authenticate($this->username, $this->password);
         $result = $auth->getAuthResult($type, $this->username);
         if (null !== $result) {
             $user->login($this->username, $type, false);
             if ($auth->getResult() == \Pop\Auth\Auth::PASSWORD_INCORRECT) {
                 $this->getElement('password')->addValidator(new Validator\NotEqual($this->password, $result));
             } else {
                 $this->getElement('username')->addValidator(new Validator\NotEqual($this->username, $result));
             }
         }
         // Check the user's allowed sites
         if (strtolower($type->type) != 'user') {
             $u = Table\Users::findBy(array('username' => $this->username));
             if (isset($u->id)) {
                 $siteIds = unserialize($u->site_ids);
                 $site = Table\Sites::findBy(array('document_root' => $_SERVER['DOCUMENT_ROOT']));
                 $siteId = isset($site->id) ? $site->id : '0';
                 if (!in_array($siteId, $siteIds)) {
                     $this->getElement('username')->addValidator(new Validator\NotEqual($this->username, $this->i18n->__('That user is not allowed on this site.')));
                 }
             }
         }
     }
     return $this;
 }
Example #4
0
 /**
  * Set the field values
  *
  * @param  array $values
  * @return Unsubscribe
  */
 public function setFieldValues(array $values = null)
 {
     parent::setFieldValues($values);
     if ($_POST && null !== $this->email) {
         $member = Table\Users::findBy(['email' => $this->email]);
         if (!isset($member->id)) {
             $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'That email does not exist.'));
         } else {
             if (null !== $member->role_id) {
                 $sess = \Pop\Web\Session::getInstance();
                 $requireLogin = true;
                 $role = Table\Roles::findById($member->role_id);
                 if (isset($role->id) && null !== $role->permissions) {
                     $permissions = unserialize($role->permissions);
                     if (isset($permissions['deny'])) {
                         foreach ($permissions['deny'] as $deny) {
                             if ($deny['resource'] == 'member-login') {
                                 $requireLogin = false;
                             }
                         }
                     }
                 }
                 if ($requireLogin) {
                     if (!isset($sess->member) || isset($sess->member) && $sess->member->id != $member->id) {
                         $memberAdmin = new \Phire\Members\Model\MembersAdmin();
                         $memberAdmin->getByRoleId($member->role_id);
                         $memberUri = isset($memberAdmin->uri) ? $memberAdmin->uri : APP_URI;
                         $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'You must <a href="' . BASE_PATH . $memberUri . '/login">log in</a> to unsubscribe.'));
                     }
                 }
             }
         }
     }
     return $this;
 }
 /**
  * Set the field values
  *
  * @param  array $values
  * @param  array $filters
  * @return \Pop\Form\Form
  */
 public function setFieldValues(array $values = null, $filters = null)
 {
     parent::setFieldValues($values, $filters);
     if ($_POST) {
         if (Validator\Email::factory()->evaluate($this->email)) {
             $user = Table\Users::findBy(array('email' => $this->email));
             if (!isset($user->id)) {
                 $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, $this->i18n->__('That email does not exist.')));
             }
         }
     }
     return $this;
 }
 /**
  * Add action method
  *
  * @return void
  */
 public function add()
 {
     $roleId = $this->getRoleId();
     $username = '';
     $email = null;
     $role = new Model\Role();
     $role->getById($roleId);
     $this->console->write();
     $dupeUser = Table\Users::findBy(['username' => $username]);
     while ($username == '' || isset($dupeUser->id)) {
         if (isset($dupeUser->id)) {
             $this->console->write($this->console->colorize('That username already exists.', Console::BOLD_RED));
             $username = '';
         }
         if ($role->email_as_username) {
             while (!(new Email())->evaluate($username)) {
                 $username = $this->console->prompt($this->console->getIndent() . 'Enter Email: ');
             }
             $email = $username;
         } else {
             while ($username == '') {
                 $username = $this->console->prompt($this->console->getIndent() . 'Enter Username: '******'';
                 while (!(new Email())->evaluate($email)) {
                     $email = $this->console->prompt($this->console->getIndent() . 'Enter Email: ');
                 }
             }
         }
         $dupeUser = Table\Users::findBy(['username' => $username]);
     }
     $password = '';
     while ($password == '') {
         $password = $this->console->prompt($this->console->getIndent() . 'Enter Password: '******'';
     while (strtolower($active) != 'y' && strtolower($active) != 'n') {
         $active = $this->console->prompt($this->console->getIndent() . 'Active? (Y/N): ');
     }
     $verified = '';
     while (strtolower($verified) != 'y' && strtolower($verified) != 'n') {
         $verified = $this->console->prompt($this->console->getIndent() . 'Verified? (Y/N): ');
     }
     $fields = ['role_id' => $roleId, 'username' => $username, 'password1' => $password, 'email' => $email, 'active' => strtolower($active) == 'y' ? 1 : 0, 'verified' => strtolower($verified) == 'y' ? 1 : 0];
     $user = new Model\User();
     $user->save($fields);
     $this->console->write();
     $this->console->write($this->console->colorize('User Added!', Console::BOLD_GREEN));
 }
Example #7
0
 /**
  * Set the field values
  *
  * @param  array $values
  * @return Forgot
  */
 public function setFieldValues(array $values = null)
 {
     parent::setFieldValues($values);
     if ($_POST && null !== $this->email) {
         $user = Table\Users::findBy(['email' => $this->email]);
         if (!isset($user->id)) {
             $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'That email does not exist.'));
         } else {
             $role = new Model\Role();
             if (!$role->canSendReminder($user->role_id)) {
                 $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'That request cannot be processed.'));
             }
         }
     }
     return $this;
 }
Example #8
0
 /**
  * Get user session data
  *
  * @param  int $id
  * @return array
  */
 public function getUserData($id)
 {
     $user = \Phire\Table\Users::findById($id);
     $userData = Table\UserSessionData::findById($id);
     if (isset($userData->user_id)) {
         $data = $userData->getColumns();
         if (null !== $data['logins']) {
             $this->data['logins'] = unserialize($data['logins']);
             krsort($this->data['logins']);
         }
         $this->data['total_logins'] = (int) $data['total_logins'];
         $this->data['failed_attempts'] = $data['failed_attempts'];
     } else {
         $this->data['logins'] = [];
         $this->data['total_logins'] = 0;
         $this->data['failed_attempts'] = 0;
     }
     $this->data['username'] = $user->username;
     $this->data['user_id'] = $id;
 }
Example #9
0
 /**
  * Set the field values
  *
  * @param  array $values
  * @return RegisterEmail
  */
 public function setFieldValues(array $values = null)
 {
     parent::setFieldValues($values);
     if ($_POST && null !== $this->email) {
         // Check for dupe email
         if (null !== $this->email) {
             $user = Table\Users::findBy(['username' => $this->email]);
             if (isset($user->id)) {
                 $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'That username is not allowed.'));
             } else {
                 $email = Table\Users::findBy(['email' => $this->email]);
                 if (isset($email->id)) {
                     $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'That email is not allowed.'));
                 }
             }
         }
         // Check password matches
         $this->getElement('password2')->addValidator(new Validator\Equal($this->password1, 'The passwords do not match.'));
     }
     return $this;
 }
Example #10
0
 /**
  * Set the field values
  *
  * @param  array $values
  * @return Profile
  */
 public function setFieldValues(array $values = null)
 {
     parent::setFieldValues($values);
     if ($_POST && null !== $this->username) {
         // Check for dupe username
         $user = null;
         if (null !== $this->username) {
             $user = Table\Users::findBy(['username' => $this->username]);
             if (isset($user->id) && $this->id != $user->id) {
                 $this->getElement('username')->addValidator(new Validator\NotEqual($this->username, 'That username is not allowed.'));
             }
         }
         // Check for dupe email
         $email = Table\Users::findBy(['email' => $this->email]);
         if (isset($email->id) && $this->id != $email->id) {
             $this->getElement('email')->addValidator(new Validator\NotEqual($this->email, 'That email is not allowed.'));
         }
         // Check password matches
         if (!empty($this->password1)) {
             $this->getElement('password2')->setRequired(true)->addValidator(new Validator\Equal($this->password1, 'The passwords do not match.'));
         }
     }
     return $this;
 }
 /**
  * Install initial user method
  *
  * @return void
  */
 public function user()
 {
     // If the system is installed
     if (DB_INTERFACE != '' && DB_NAME != '' && !isset($this->sess->config)) {
         Response::redirect(BASE_PATH . APP_URI);
         // Else, if the initial install screen or config isn't complete
     } else {
         if (DB_INTERFACE == '' && DB_NAME == '') {
             if (isset($this->sess->config)) {
                 Response::redirect(BASE_PATH . (isset($this->sess->app_uri) ? $this->sess->app_uri : APP_URI) . '/install/config?lang=' . $_GET['lang']);
             } else {
                 Response::redirect(BASE_PATH . (isset($this->sess->app_uri) ? $this->sess->app_uri : APP_URI) . '/install?lang=' . $_GET['lang']);
             }
             // Else, install the first system user
         } else {
             $user = new Model\User(array('title' => $this->i18n->__('User Setup')));
             $form = new Form\User($this->request->getBasePath() . $this->request->getRequestUri() . '?lang=' . $this->i18n->getLanguage() . '_' . $this->i18n->getLocale(), 'post', 2001, true);
             if ($this->request->isPost()) {
                 $form->setFieldValues($this->request->getPost(), array('strip_tags' => null, 'htmlentities' => array(ENT_QUOTES, 'UTF-8')));
                 if ($form->isValid()) {
                     $user->save($form, $this->project->module('Phire'));
                     $newUser = Table\Users::findById($user->id);
                     if (isset($newUser->id)) {
                         $newUser->site_ids = serialize(array(0));
                         $newUser->created = date('Y-m-d H:i:s');
                         $newUser->update();
                     }
                     $ext = new Model\Extension(array('acl' => $this->project->getService('acl')));
                     $ext->getModules($this->project);
                     if (count($ext->new) > 0) {
                         $ext->installModules();
                     }
                     $user->set('form', '        <p style="text-align: center; margin: 50px 0 0 0; line-height: 1.8em; font-size: 1.2em;">' . $this->i18n->__('Thank you. The system has been successfully installed.') . '<br />' . $this->i18n->__('You can now log in %1here%2 or view the home page %3here%4.', array('<a href="' . BASE_PATH . APP_URI . '/login">', '</a>', '<a href="' . BASE_PATH . '/" target="_blank">', '</a>')) . '</p>' . PHP_EOL);
                     Model\Install::send($form);
                     unset($this->sess->config);
                     unset($this->sess->app_uri);
                     $this->view = View::factory($this->viewPath . '/user.phtml', $user->getData());
                     $this->view->set('i18n', $this->i18n);
                     $this->send();
                 } else {
                     $user->set('form', $form);
                     $this->view = View::factory($this->viewPath . '/user.phtml', $user->getData());
                     $this->view->set('i18n', $this->i18n);
                     $this->send();
                 }
             } else {
                 $user->set('form', $form);
                 $this->view = View::factory($this->viewPath . '/user.phtml', $user->getData());
                 $this->view->set('i18n', $this->i18n);
                 $this->send();
             }
         }
     }
 }
Example #12
0
 /**
  * Send password reminder to user
  *
  * @param  string      $email
  * @param  \Pop\Config $config
  * @return void
  */
 public function sendReminder($email, $config)
 {
     $encOptions = $config->encryptionOptions->asArray();
     $user = Table\Users::findBy(array('email' => $email));
     if (isset($user->id)) {
         $type = Table\UserTypes::findById($user->type_id);
         if ($type->password_encryption == Auth\Auth::ENCRYPT_NONE) {
             $newPassword = $this->password;
             $newEncPassword = $newPassword;
             $msg = $this->i18n->__('Your username and password is:');
         } else {
             $newPassword = (string) String::random(8, String::ALPHANUM);
             $newEncPassword = self::encryptPassword($newPassword, $type->password_encryption, $encOptions);
             $msg = $this->i18n->__('Your password has been reset for security reasons. Your username and new password is:');
         }
         // Save new password
         $user->password = $newEncPassword;
         $user->save();
         // Get base path and domain
         $basePath = strtolower($type->type) != 'user' ? BASE_PATH . '/' . strtolower($type->type) : BASE_PATH . APP_URI;
         $domain = str_replace('www.', '', $_SERVER['HTTP_HOST']);
         // Set recipient
         $rcpt = array('name' => $user->username, 'email' => $user->email, 'username' => $user->username, 'password' => $newPassword, 'login' => 'http://' . $_SERVER['HTTP_HOST'] . $basePath . '/login', 'domain' => $domain, 'message' => $msg);
         if (file_exists($_SERVER['DOCUMENT_ROOT'] . BASE_PATH . CONTENT_PATH . '/extensions/themes/phire/mail/forgot.txt')) {
             $mailTmpl = file_get_contents($_SERVER['DOCUMENT_ROOT'] . BASE_PATH . CONTENT_PATH . '/extensions/themes/phire/mail/forgot.txt');
         } else {
             $mailTmpl = file_get_contents(__DIR__ . '/../../../view/phire/mail/forgot.txt');
         }
         $mailTmpl = str_replace(array('Dear', 'Here is your password for', 'You can login at:', 'Thank You'), array($this->i18n->__('Dear'), $this->i18n->__('Here is your password for'), $this->i18n->__('You can login at:'), $this->i18n->__('Thank You')), $mailTmpl);
         // Send reminder
         $mail = new Mail($domain . ' - ' . $this->i18n->__('Password Reset'), $rcpt);
         $mail->from(Table\Config::findById('reply_email')->value);
         $mail->setText($mailTmpl);
         $mail->send();
     }
 }
Example #13
0
 /**
  * Set the field values
  *
  * @param  array       $values
  * @param  array       $filters
  * @param  \Pop\Config $config
  * @return \Pop\Form\Form
  */
 public function setFieldValues(array $values = null, $filters = null, $config = null)
 {
     parent::setFieldValues($values, $filters);
     if ($this->id != 0) {
         if (null !== $this->getElement('email2')) {
             $this->getElement('email2')->setRequired(false);
         }
         if (null !== $this->getElement('password1') && null === $this->reset_pwd) {
             $this->getElement('password1')->setRequired(false);
             $this->getElement('password2')->setRequired(false);
         }
     }
     // Add validators for checking dupe usernames
     // and matching the emails and passwords
     if ($_POST && isset($_POST['id'])) {
         if (isset($this->fields['username'])) {
             $username = $this->username;
             $usernameField = 'username';
         } else {
             $username = $this->email1;
             $usernameField = 'email1';
         }
         $user = Table\Users::findBy(array('username' => $username));
         if (isset($user->id) && $this->id != $user->id) {
             $this->getElement($usernameField)->addValidator(new Validator\NotEqual($username, $this->i18n->__('That user already exists.')));
         }
         $email = Table\Users::findBy(array('email' => $this->email1));
         if (isset($email->id) && $this->id != $email->id) {
             $this->getElement('email1')->addValidator(new Validator\NotEqual($this->email1, $this->i18n->__('That email already exists.')));
         }
         if (null !== $this->getElement('email2')) {
             $this->getElement('email2')->addValidator(new Validator\Equal($this->email1, $this->i18n->__('The emails do not match.')));
         }
         // If the password fields are set, check them for a match
         if (isset($this->password2)) {
             $this->getElement('password2')->addValidator(new Validator\Equal($this->password1, $this->i18n->__('The passwords do not match.')));
         }
         if ($this->reset_pwd) {
             $user = Table\Users::findById($this->id);
             if (isset($user->id)) {
                 $curPassword = $user->password;
                 $type = Table\UserTypes::findById($user->type_id);
                 if (isset($type->id)) {
                     $encOptions = $config->encryptionOptions->asArray();
                     $auth = new \Pop\Auth\Adapter\Table('Phire\\Table\\Users');
                     $result = $auth->authenticate($this->username, $this->password2, $type->password_encryption, $encOptions);
                     if ($result != \Pop\Auth\Auth::PASSWORD_INCORRECT) {
                         $this->getElement('password2')->addValidator(new Validator\Equal($curPassword, $this->i18n->__('The new password cannot be the same.')));
                     }
                 }
             }
         }
     }
     $this->checkFiles();
     return $this;
 }
 /**
  * User logins method
  *
  * @return void
  */
 public function logins()
 {
     if (null === $this->request->getPath(1)) {
         Response::redirect($this->request->getBasePath());
     } else {
         if ($this->request->isPost()) {
             $user = Table\Users::findById($this->request->getPath(1));
             if (isset($user->id)) {
                 $user->logins = null;
                 $user->update();
             }
             $typeId = null !== $this->request->getQuery('type_id') ? '/index/' . $this->request->getQuery('type_id') : null;
             Response::redirect($this->request->getBasePath() . $typeId);
         } else {
             $this->prepareView('logins.phtml', array('assets' => $this->project->getAssets(), 'acl' => $this->project->getService('acl'), 'phireNav' => $this->project->getService('phireNav')));
             $user = new Model\User();
             $user->getLoginsById($this->request->getPath(1));
             $this->view->set('title', $this->view->i18n->__('Users') . ' ' . $this->view->separator . ' ' . $user->type_name . ' ' . $this->view->separator . ' ' . $this->view->i18n->__('Logins') . ' ' . $this->view->separator . ' ' . $user->username)->set('typeId', $user->type_id)->set('table', $user->table);
             $this->send();
         }
     }
 }
Example #15
0
 /**
  * Remove sites
  *
  * @param array $post
  * @return void
  */
 public function remove(array $post)
 {
     if (isset($post['remove_sites'])) {
         foreach ($post['remove_sites'] as $id) {
             $site = Table\Sites::findById($id);
             if (isset($site->id)) {
                 $users = Table\Users::findAll();
                 foreach ($users->rows as $user) {
                     $siteIds = unserialize($user->site_ids);
                     if (in_array($site->id, $siteIds)) {
                         $key = array_search($site->id, $siteIds);
                         unset($siteIds[$key]);
                         $u = Table\Users::findById($user->id);
                         if (isset($u->id)) {
                             $u->site_ids = serialize($siteIds);
                             $u->update();
                         }
                     }
                 }
                 $site->delete();
             }
         }
     }
 }
Example #16
0
 /**
  * Get content
  *
  * @param  array $data
  * @return array
  */
 protected function setContent(array $data)
 {
     $type = new ContentType();
     $type->getById($data['type_id']);
     $data['content_type'] = $type->content_type;
     $data['content_type_force_ssl'] = $type->force_ssl;
     $data['strict_publishing'] = $type->strict_publishing;
     if (!empty($data['publish'])) {
         $publish = explode(' ', $data['publish']);
         $data['publish_date'] = $publish[0];
         $data['publish_time'] = $publish[1];
         if (isset($this->date_format)) {
             $data['publish_date'] = date($this->date_format, strtotime($data['publish_date']));
         }
         if (isset($this->time_format)) {
             $data['publish_time'] = date($this->time_format, strtotime($data['publish_time']));
         }
     }
     if (!empty($data['expire'])) {
         $expire = explode(' ', $data['expire']);
         $data['expire_date'] = $expire[0];
         $data['expire_time'] = $expire[1];
         if (isset($this->date_format)) {
             $data['expire_date'] = date($this->date_format, strtotime($data['expire_date']));
         }
         if (isset($this->time_format)) {
             $data['expire_time'] = date($this->time_format, strtotime($data['expire_time']));
         }
     }
     if (!empty($content->created_by)) {
         $createdBy = \Phire\Table\Users::findById($content->created_by);
         if (isset($createdBy->id)) {
             $data['created_by_username'] = $createdBy->username;
         }
     }
     if (!empty($content->updated_by)) {
         $updatedBy = \Phire\Table\Users::findById($content->updated_by);
         if (isset($updatedBy->id)) {
             $data['updated_by_username'] = $updatedBy->username;
         }
     }
     $data['content_parent_id'] = $data['parent_id'];
     $data['content_status'] = $data['status'];
     $data['content_template'] = $data['template'];
     $data['breadcrumb'] = $this->getBreadcrumb($data['id'], null !== $this->separator ? $this->separator : '&gt;');
     $data['breadcrumb_text'] = strip_tags($data['breadcrumb'], 'span');
     if (!is_array($data['roles']) && is_string($data['roles'])) {
         $data['roles'] = unserialize($data['roles']);
     }
     $this->data = array_merge($this->data, $data);
     return $this->data;
 }
Example #17
0
 /**
  * Send user password reminder notification
  *
  * @param  Table\Users $user
  * @return void
  */
 protected function sendReminder(Table\Users $user)
 {
     $host = Table\Config::findById('domain')->value;
     $domain = str_replace('www.', '', $host);
     $newPassword = Random::create(8, Random::ALPHANUM | Random::LOWERCASE);
     $user->password = (new Bcrypt())->create($newPassword);
     $user->save();
     // Set the recipient
     $rcpt = ['name' => $user->username, 'email' => $user->email, 'domain' => $domain, 'username' => $user->username, 'password' => $newPassword];
     // Check for an override template
     $mailTemplate = file_exists(CONTENT_ABS_PATH . '/phire/view/phire/mail/forgot.txt') ? CONTENT_ABS_PATH . '/phire/view/phire/mail/forgot.txt' : __DIR__ . '/../../view/phire/mail/forgot.txt';
     // Send email verification
     $mail = new Mail($domain . ' - Forgot Password', $rcpt);
     $mail->from('noreply@' . $domain);
     $mail->setText(file_get_contents($mailTemplate));
     $mail->send();
 }
Example #18
0
 /**
  * Login and track session
  *
  * @param  AbstractController $controller
  * @param  Application        $application
  * @return void
  */
 public static function login(AbstractController $controller, Application $application)
 {
     $sess = $application->getService('session');
     $userUri = APP_URI;
     $key = 'user';
     if (isset($sess->member) && $application->isRegistered('phire-members')) {
         $key = 'member';
         $memberAdmin = new \Phire\Members\Model\MembersAdmin();
         $memberAdmin->getByRoleId($sess->member->role_id);
         if (isset($memberAdmin->uri)) {
             $userUri = $memberAdmin->uri;
         }
     }
     $path = BASE_PATH . $userUri;
     if ($path == '') {
         $path = '/';
     }
     $cookie = Cookie::getInstance(['path' => $path]);
     $cookie->delete('phire_session_timeout');
     $cookie->delete('phire_session_path');
     // If login, validate and start new session
     if ($controller->request()->isPost() && substr($controller->request()->getRequestUri(), -6) == '/login') {
         // If the user successfully logged in
         if (isset($sess[$key])) {
             $config = Table\UserSessionConfig::findById($sess[$key]->role_id);
             $data = Table\UserSessionData::findById($sess[$key]->id);
             if (isset($config->role_id)) {
                 if (!self::validate($config, $sess[$key], $data)) {
                     if (isset($data->user_id)) {
                         $data->failed_attempts++;
                         $data->save();
                     } else {
                         $data = new Table\UserSessionData(['user_id' => $sess[$key]->id, 'logins' => null, 'failed_attempts' => 1]);
                         $data->save();
                     }
                     if (isset($config->role_id) && (int) $config->log_type > 0 && null !== $config->log_emails) {
                         self::log($config, $sess[$key], false);
                     }
                     $sess->kill();
                     Response::redirect(BASE_PATH . $userUri . '/login?failed=' . $data->failed_attempts);
                     exit;
                 } else {
                     if (isset($data->user_id)) {
                         $limit = (int) $application->module('phire-sessions')['login_limit'];
                         $logins = unserialize($data->logins);
                         if ($limit > 0 && count($logins) >= $limit) {
                             reset($logins);
                             unset($logins[key($logins)]);
                         }
                         $logins[time()] = ['ua' => $_SERVER['HTTP_USER_AGENT'], 'ip' => $_SERVER['REMOTE_ADDR']];
                         $data->total_logins++;
                         $data->failed_attempts = 0;
                         $data->logins = serialize($logins);
                         $data->save();
                     } else {
                         $data = new Table\UserSessionData(['user_id' => $sess[$key]->id, 'logins' => serialize([time() => ['ua' => $_SERVER['HTTP_USER_AGENT'], 'ip' => $_SERVER['REMOTE_ADDR']]]), 'total_logins' => 1, 'failed_attempts' => 0]);
                         $data->save();
                     }
                 }
                 $expire = (int) $config->session_expiration > 0 ? (int) $config->session_expiration : null;
                 $timeout = (int) $config->timeout_warning;
             } else {
                 $expire = null;
                 $timeout = false;
             }
             $lastLogin = null;
             $lastIp = null;
             // Check for the last login
             $data = Table\UserSessionData::findById($sess[$key]->id);
             if (isset($data->user_id)) {
                 $logins = null !== $data->logins ? unserialize($data->logins) : [];
                 if (count($logins) > 1) {
                     $keys = array_keys($logins);
                     $timestamp = isset($keys[count($keys) - 2]) ? $keys[count($keys) - 2] : null;
                     if (null !== $timestamp && isset($logins[$timestamp])) {
                         $lastLogin = $timestamp;
                         $lastIp = $logins[$timestamp]['ip'];
                     }
                 }
             }
             // Clear old sessions
             $clear = (int) $application->module('phire-sessions')['clear_sessions'];
             if ($clear > 0) {
                 $clear = time() - $clear;
                 $sql = Table\UserSessions::sql();
                 $sql->delete()->where(['start <= :start']);
                 Table\UserSessions::execute((string) $sql, ['start' => $clear]);
             }
             $session = new Table\UserSessions(['user_id' => $sess[$key]->id, 'ip' => $_SERVER['REMOTE_ADDR'], 'ua' => $_SERVER['HTTP_USER_AGENT'], 'start' => time()]);
             $session->save();
             $sess[$key]->session = new \ArrayObject(['id' => $session->id, 'start' => $session->start, 'last' => $session->start, 'expire' => $expire, 'timeout' => $timeout, 'last_login' => $lastLogin, 'last_ip' => $lastIp], \ArrayObject::ARRAY_AS_PROPS);
             if (isset($config->role_id) && (int) $config->log_type > 0 && null !== $config->log_emails) {
                 self::log($config, $sess[$key], true);
             }
             // Else, if the user login failed
         } else {
             if (null !== $controller->view()->form && $controller->view()->form !== false && null !== $controller->view()->form->username) {
                 $user = \Phire\Table\Users::findBy(['username' => $controller->view()->form->username]);
                 $config = Table\UserSessionConfig::findById($user->role_id);
                 if (isset($user->id)) {
                     $data = Table\UserSessionData::findById($user->id);
                     if (isset($data->user_id)) {
                         $data->failed_attempts++;
                         $data->save();
                     } else {
                         $data = new Table\UserSessionData(['user_id' => $user->id, 'logins' => null, 'failed_attempts' => 1]);
                         $data->save();
                     }
                     if (isset($config->role_id) && (int) $config->log_type > 0 && null !== $config->log_emails) {
                         self::log($config, $user, false);
                     }
                 }
             }
         }
         // Check existing session
     } else {
         if (isset($sess[$key]) && isset($sess[$key]->session)) {
             if (!isset(Table\UserSessions::findById((int) $sess[$key]->session->id)->id) || null !== $sess[$key]->session->expire && time() - $sess[$key]->session->last >= $sess[$key]->session->expire) {
                 $session = Table\UserSessions::findById((int) $sess[$key]->session->id);
                 if (isset($session->id)) {
                     $session->delete();
                 }
                 $sess->kill();
                 Response::redirect(BASE_PATH . $userUri . '/login?expired=1');
                 exit;
             } else {
                 if ($sess[$key]->session->timeout && null !== $sess[$key]->session->expire) {
                     $cookie->set('phire_session_timeout', $sess[$key]->session->expire - 30);
                     $cookie->set('phire_session_path', BASE_PATH . $userUri);
                 }
                 $sess[$key]->session->last = time();
             }
         }
     }
 }