/** * Widget to display some of the newest registrations, (if any). */ public function newestSignups(){ if(!\Core\user()->checkAccess('p:/user/users/manage')){ return ''; } // How far back do I want to search for? // 1 month sounds good! $date = new CoreDateTime(); $date->modify('-1 month'); $searches = UserModel::Find(['created > ' . $date->getFormatted('U')], 10, 'created DESC'); // No results? No problem :) if(!sizeof($searches)) return ''; $view = $this->getView(); $view->assign('enableavatar', (\ConfigHandler::Get('/user/enableavatar'))); $view->assign('users', $searches); }
public function wpadmin() { $view = $this->getView(); $request = $this->getPageRequest(); if ($request->isPost()) { // Did they actually try to submit this form?...... silly bot ;) SystemLogModel::LogSecurityEvent('/wp-admin Honeypot POST', 'POST submission to /wp-admin detected!', print_r($_POST, true)); $expireback = new CoreDateTime(); $expireback->modify('+2 days'); $block = IpBlacklistModel::Find(['ip_addr = ' . REMOTE_IP . '/32'], 1); if (!$block) { $block = new IpBlacklistModel(); $block->set('ip_addr', REMOTE_IP . '/32'); } $block->setFromArray(['expires' => $expireback->getFormatted('U', Time::TIMEZONE_GMT), 'message' => 'You tried to submit a wp-admin page.... this is not a WP site!', 'comment' => 'Bot or user submitted to wp-admin']); $block->save(); } else { // Just record the hit. SystemLogModel::LogSecurityEvent('/wp-admin Honeypot GET', 'GET request to /wp-admin detected!'); } $view->templatename = 'pages/wphoneypot/wpadmin.phtml'; $view->mastertemplate = false; }
/** * The hook catch for the "/core/admin/view" hook. */ public static function AdminHook() { // If this user doesn't have access to manage crons, just continue. if (!\Core\user()->checkAccess('p:/cron/viewlog')) { return; } $suffixtext = 'This could be a problem if you have scripts relying on it! <a href="' . \Core\resolve_link('/cron/howto') . '">Read how to resolve this issue</a>.'; // Lookup and make sure that the cron hooks have ran recently enough! $checks = [['cron' => 'hourly', 'modify' => '-1 hour', 'label' => 'hour'], ['cron' => 'daily', 'modify' => '-1 day', 'label' => 'day'], ['cron' => 'weekly', 'modify' => '-1 week', 'label' => 'week'], ['cron' => 'monthly', 'modify' => '-1 month', 'label' => 'month']]; foreach ($checks as $check) { $time = new CoreDateTime(); $cronfac = new ModelFactory('CronLogModel'); $cronfac->where('cron = ' . $check['cron']); $time->modify($check['modify']); $cronfac->where('created >= ' . $time->getFormatted('U', Time::TIMEZONE_GMT)); $count = $cronfac->count(); if ($count == 0) { \Core\set_message('Your ' . $check['cron'] . ' cron has not run in the last ' . $check['label'] . '! ' . $suffixtext, 'error'); // Only complain to the admin once per view. return; } } }
/** * @param Form $form * @return false|string */ public static function SaveBlacklistIp(Form $form) { try { $ban = $form->getModel('model'); // First thing... check and make sure that this directive won't block out the current user! $longip = ip2long(REMOTE_IP); for ($i = 32; $i > 0; $i--) { $mask = ~((1 << 32 - $i) - 1); $join = long2ip($longip & $mask) . '/' . $i; if ($join == $ban->get('ip_addr')) { \Core\set_message('Corwardly refusing to ban an IP range that will blacklist your current connection!', 'error'); return false; } } // The expires value will probably come in as a date string :/ if ($ban->get('expires')) { $date = new CoreDateTime($ban->get('expires')); $ban->set('expires', $date->getFormatted('U', Time::TIMEZONE_GMT)); } $ban->save(); \Core\set_message('Banned IP range ' . $ban->get('ip_addr'), 'success'); return 'back'; } catch (Exception $e) { \Core\set_message($e->getMessage()); return false; } }
public function setValue($value){ $timezone = isset($this->_attributes['savetimezone']) ? $this->_attributes['savetimezone'] : Time::TIMEZONE_GMT; if($value === '' || $value === NULL){ // Allow empty values to be entered without manipulation. // This is to prevent an empty value from tripping up the !is_numeric check below and // getting set to an empty date string, which evaluates to the current date/time. return parent::setValue($value); } elseif(isset($this->_attributes['saveformat']) && !is_numeric($value)){ // Set value succeeded, now I can convert the string to an int, (if requested). $dt = new CoreDateTime($value); $value = $dt->getFormatted($this->_attributes['saveformat'], $timezone); return parent::setValue($value); } else{ return parent::setValue($value); } }
/** * Method to purge the user activity cron. * * This is useful because on an extremely busy site, this table can grow to several gigs within not much time. */ public static function PurgeUserActivityCron() { $opt = \ConfigHandler::Get('/user/activity/keephistory'); if($opt == 'all' || !$opt){ echo 'Not purging any user activity.' . "\n"; return true; } // Convert the key to a datestring value. $date = new \CoreDateTime(); switch($opt){ case '1-week': $date->modify('-1 week'); break; case '1-month': $date->modify('-1 month'); break; case '2-months': $date->modify('-2 month'); break; case '3-months': $date->modify('-3 month'); break; case '6-months': $date->modify('-6 month'); break; case '12-months': $date->modify('-12 month'); break; case '24-months': $date->modify('-24 month'); break; case '36-months': $date->modify('-36 month'); break; default: echo 'Invalid value for /user/activity/keephistory: [' . $opt . ']'; return false; } // And delete any activity older than this date. echo 'Purging user activity older than ' . $date->getFormatted('r') . "...\n"; $ds = new \Core\Datamodel\Dataset(); $ds->delete()->table('user_activity')->where('datetime < ' . $date->getFormatted('U', \TIME::TIMEZONE_GMT))->execute(); echo 'Removed ' . $ds->num_rows . ' record(s).' . "\n"; return true; }
/** * Given all the user defined filter, sort, and what not, apply those values to the ModelFactory if possible. * * @since 2.4.0 * @param ModelFactory $factory */ public function applyToFactory(ModelFactory $factory){ if($this->hassort){ $factory->order($this->getOrder()); } if($this->haspagination){ // Determine the starting count if the page is requested. if($this->_currentpage > 1){ $startat = $this->_limit * ($this->_currentpage - 1); $factory->limit($startat . ', ' . $this->_limit); } else{ $factory->limit($this->_limit); } } foreach($this->_elements as $el){ /** @var $el FormElement */ $name = $el->get('name'); $idxname = $name; if(strpos($name, 'filter[') === 0){ $name = substr($name, 7, -1); } // If this element is not in the index of elements, skip to the next element. if(!isset($this->_elementindexes[$idxname])){ continue; } // If this doesn't have a link attribute, just skip. if(!$el->get('link')){ continue; } // No value, just skip. if($el->get('value') === '' || $el->get('value') === null){ continue; } // If there is a "" option, interpret that as empty and allow "0" to be used. if($el->get('value') === '0'){ if($el->get('options') && isset($el->get('options')[''])){ // '' is set... proceed. } else{ continue; } } $value = $el->get('value'); // Was there a prefix and/or suffix requested? if($el->get('linkvalueprefix')){ $value = $el->get('linkvalueprefix') . $value; } if($el->get('linkvaluesuffix')){ $value = $value . $el->get('linkvaluesuffix'); } // If this link is a date object, convert a date string to its unix timestamp representation. if($el instanceof FormDateInput || $el->get('dateformat')){ // Default to a unix timestamp, but allow the user to override this. // This is useful for saving a date in the datastore as a human-readable format. $format = $el->get('dateformat') ? $el->get('dateformat') : 'U'; $date = new CoreDateTime($value); $value = $date->getFormatted($format, Time::TIMEZONE_GMT); } if($el->get('linkname')){ $name = $el->get('linkname'); } // New support for multiple link names! if(!is_array($name)){ $name = [$name]; } $statements = []; foreach($name as $n){ switch($el->get('link')){ case FilterForm::LINK_TYPE_STANDARD: case FilterForm::LINK_TYPE_GT: case FilterForm::LINK_TYPE_GE: case FilterForm::LINK_TYPE_LT: case FilterForm::LINK_TYPE_LE: $statements[] = $n . $el->get('link') . $value; break; case FilterForm::LINK_TYPE_STARTSWITH: $statements[] = $n . ' LIKE ' . $value . '%'; break; case FilterForm::LINK_TYPE_CONTAINS: $statements[] = $n . ' LIKE %' . $value . '%'; break; } } if(sizeof($statements) > 1){ // Create a sub where clause for these. $subwhere = new \Core\Datamodel\DatasetWhereClause(); $subwhere->setSeparator('OR'); foreach($statements as $s){ $subwhere->addWhere($s); } // Add this sub clause to the main where clause. $factory->where($subwhere); } else{ // A single command just gets added to the main clause. $factory->where($statements[0]); } } // Might as well update the count now, it can always be updated later. $this->setTotalCount($factory->count()); }
/** * Method to cleanup expired IP addresses from the database. * * @return bool */ public static function CleanupHook() { $factory = new \ModelFactory('IpBlacklistModel'); $factory->where('expires > 0'); // If they're set not to be deleted, don't purge them... $factory->where('expires <= ' . \CoreDateTime::Now('U', \Time::TIMEZONE_GMT)); // DELETE! $count = $factory->count(); if (!$count) { echo 'No records purged.'; return true; } foreach ($factory->get() as $record) { /** @var $record \IpBlacklistModel */ $record->delete(); } echo "Purged " . $count . ' record' . ($count > 1 ? 's' : '') . ' successfully.'; return true; }
/** * Method to archive a given log file. * * Will rename it and optionally compress if configured to do so. * * @throws \Exception */ public function archive(){ if($this->isArchived()){ throw new \Exception($this->getFilename('') . ' is already archived, unable to re-archive!'); } if(!$this->exists()){ throw new \Exception($this->getFilename('') . ' does not appear to exist!'); } if(!is_writable($this->getDirectoryName())){ throw new \Exception('Unable to write to directory ' . $this->getDirectoryName() . ', archive unsuccessful!'); } $this->archivedate = \CoreDateTime::Now('YmdHi'); $newfilename = $this->base . '.log.' . $this->archivedate; if(!$this->rename($newfilename)){ throw new \Exception('Unable to move log to ' . $newfilename); } if(\ConfigHandler::Get('/core/logs/rotate/compress')){ // Compression is requested too. $arg = escapeshellarg($this->getFilename()); $output = null; // I don't actually care about this. exec('gzip ' . $arg, $output, $ret); if($ret != 0){ throw new \Exception('Unable to compress archived file!'); } // Gzip appends the gz extension to the file, so follow suit! $this->_filename .= '.gz'; } }
/** * Shortcut function for getting the time now. * * @param string $format * @param int $timezone * * @return string */ public static function Now($format = 'Y-m-d', $timezone = Time::TIMEZONE_DEFAULT){ $d = new CoreDateTime(); return $d->getFormatted($format, $timezone); }
/** * Form Handler for logging in. * * @static * * @param \Form $form * * @return bool|null|string */ public static function LoginHandler(\Form $form){ /** @var \FormElement $e */ $e = $form->getElement('email'); /** @var \FormElement $p */ $p = $form->getElement('pass'); /** @var \UserModel $u */ $u = \UserModel::Find(array('email' => $e->get('value')), 1); if(!$u){ // Log this as a login attempt! $logmsg = 'Failed Login. Email not registered' . "\n" . 'Email: ' . $e->get('value') . "\n"; \SystemLogModel::LogSecurityEvent('/user/login', $logmsg); $e->setError('t:MESSAGE_ERROR_USER_LOGIN_EMAIL_NOT_FOUND'); return false; } if($u->get('active') == 0){ // The model provides a quick cut-off for active/inactive users. // This is the control managed with in the admin. $logmsg = 'Failed Login. User tried to login before account activation' . "\n" . 'User: '******'email') . "\n"; \SystemLogModel::LogSecurityEvent('/user/login', $logmsg, null, $u->get('id')); $e->setError('t:MESSAGE_ERROR_USER_LOGIN_ACCOUNT_NOT_ACTIVE'); return false; } elseif($u->get('active') == -1){ // The model provides a quick cut-off for active/inactive users. // This is the control managed with in the admin. $logmsg = 'Failed Login. User tried to login after account deactivation.' . "\n" . 'User: '******'email') . "\n"; \SystemLogModel::LogSecurityEvent('/user/login', $logmsg, null, $u->get('id')); $e->setError('t:MESSAGE_ERROR_USER_LOGIN_ACCOUNT_DEACTIVATED'); return false; } try{ /** @var \Core\User\AuthDrivers\datastore $auth */ $auth = $u->getAuthDriver('datastore'); } catch(Exception $e){ $e->setError('t:MESSAGE_ERROR_USER_LOGIN_PASSWORD_AUTH_DISABLED'); return false; } // This is a special case if the password isn't set yet. // It can happen with imported users or if a password is invalidated. if($u->get('password') == ''){ // Use the Nonce system to generate a one-time key with this user's data. $nonce = \NonceModel::Generate( '20 minutes', ['type' => 'password-reset', 'user' => $u->get('id')] ); $link = '/datastoreauth/forgotpassword?e=' . urlencode($u->get('email')) . '&n=' . $nonce; $email = new \Email(); $email->setSubject('Initial Password Request'); $email->to($u->get('email')); $email->assign('link', \Core\resolve_link($link)); $email->assign('ip', REMOTE_IP); $email->templatename = 'emails/user/initialpassword.tpl'; try{ $email->send(); \SystemLogModel::LogSecurityEvent('/user/initialpassword/send', 'Initial password request sent successfully', null, $u->get('id')); \Core\set_message('t:MESSAGE_INFO_USER_LOGIN_MUST_SET_NEW_PASSWORD_INSTRUCTIONS_HAVE_BEEN_EMAILED'); return true; } catch(\Exception $e){ \Core\ErrorManagement\exception_handler($e); \Core\set_message('t:MESSAGE_ERROR_USER_LOGIN_MUST_SET_NEW_PASSWORD_UNABLE_TO_SEND_EMAIL'); return false; } } if(!$auth->checkPassword($p->get('value'))){ // Log this as a login attempt! $logmsg = 'Failed Login. Invalid password' . "\n" . 'Email: ' . $e->get('value') . "\n"; \SystemLogModel::LogSecurityEvent('/user/login/failed_password', $logmsg, null, $u->get('id')); // Also, I want to look up and see how many login attempts there have been in the past couple minutes. // If there are too many, I need to start slowing the attempts. $time = new \CoreDateTime(); $time->modify('-5 minutes'); $securityfactory = new \ModelFactory('SystemLogModel'); $securityfactory->where('code = /user/login/failed_password'); $securityfactory->where('datetime > ' . $time->getFormatted(\Time::FORMAT_EPOCH, \Time::TIMEZONE_GMT)); $securityfactory->where('ip_addr = ' . REMOTE_IP); $attempts = $securityfactory->count(); if($attempts > 4){ // Start slowing down the response. This should help deter brute force attempts. // (x+((x-7)/4)^3)-4 sleep( ($attempts+(($attempts-7)/4)^3)-4 ); // This makes a nice little curve with the following delays: // 5th attempt: 0.85 // 6th attempt: 2.05 // 7th attempt: 3.02 // 8th attempt: 4.05 // 9th attempt: 5.15 // 10th attempt: 6.52 // 11th attempt: 8.10 // 12th attempt: 10.05 } $e->setError('t:MESSAGE_ERROR_USER_LOGIN_INCORRECT_PASSWORD'); $p->set('value', ''); return false; } if($form->getElementValue('redirect')){ // The page was set via client-side javascript on the login page. // This is the most reliable option. $url = $form->getElementValue('redirect'); } elseif(REL_REQUEST_PATH == '/user/login'){ // If the user came from the registration page, get the page before that. $url = $form->referrer; } else{ // else the registration link is now on the same page as the 403 handler. $url = REL_REQUEST_PATH; } // Well, record this too! \SystemLogModel::LogSecurityEvent('/user/login', 'Login successful (via password)', null, $u->get('id')); // yay... $u->set('last_login', \CoreDateTime::Now('U', \Time::TIMEZONE_GMT)); $u->save(); \Core\Session::SetUser($u); // Allow an external script to override the redirecting URL. $overrideurl = \HookHandler::DispatchHook('/user/postlogin/getredirecturl'); if($overrideurl){ $url = $overrideurl; } return $url; }
/** * Function to cleanup expired nonce keys and data. * This is meant to be called in a cron, be it hourly, daily, etc. * * @return bool Exit status */ public static function Cleanup() { $date = new CoreDateTime(); $expired = self::Find(['expires > 0', 'expires <= ' . $date->getFormatted('U', Time::TIMEZONE_GMT)]); foreach ($expired as $e) { $e->delete(); } return true; }
/** * Page to enable Facebook logins for user accounts. * * @return int|null|string */ public function enable() { $request = $this->getPageRequest(); $auths = \Core\User\Helper::GetEnabledAuthDrivers(); if (!isset($auths['facebook'])) { // Facebook isn't enabled, simply redirect to the home page. \Core\redirect('/'); } if (!FACEBOOK_APP_ID) { \Core\redirect('/'); } if (!FACEBOOK_APP_SECRET) { \Core\redirect('/'); } // If it was a POST, then it should be the first page. if ($request->isPost()) { $facebook = new Facebook(['appId' => FACEBOOK_APP_ID, 'secret' => FACEBOOK_APP_SECRET]); // Did the user submit the facebook login request? if (isset($_POST['login-method']) && $_POST['login-method'] == 'facebook' && $_POST['access-token']) { try { $facebook->setAccessToken($_POST['access-token']); /** @var int $fbid The user ID from facebook */ $fbid = $facebook->getUser(); /** @var array $user_profile The array of user data from Facebook */ $user_profile = $facebook->api('/me'); } catch (Exception $e) { \Core\set_message($e->getMessage(), 'error'); \Core\go_back(); return null; } // If the user is logged in, then the verification logic is slightly different. if (\Core\user()->exists()) { // Logged in users, the email must match. if (\Core\user()->get('email') != $user_profile['email']) { \Core\set_message('Your Facebook email is ' . $user_profile['email'] . ', which does not match your account email! Unable to link accounts.', 'error'); \Core\go_back(); return null; } $user = \Core\user(); } else { /** @var \UserModel|null $user */ $user = UserModel::Find(['email' => $user_profile['email']], 1); if (!$user) { \Core\set_message('No local account found with the email ' . $user_profile['email'] . ', please <a href="' . \Core\resolve_link('/user/register') . '"create an account</a> instead.', 'error'); \Core\go_back(); return null; } } // Send an email with a nonce link that will do the actual activation. // This is a security feature so just anyone can't link another user's account. $nonce = NonceModel::Generate('20 minutes', null, ['user' => $user, 'access_token' => $_POST['access-token']]); $email = new Email(); $email->to($user->get('email')); $email->setSubject('Facebook Activation Request'); $email->templatename = 'emails/facebook/enable_confirmation.tpl'; $email->assign('link', \Core\resolve_link('/facebook/enable/' . $nonce)); if ($email->send()) { \Core\set_message('An email has been sent to your account with a link enclosed. Please click on that to complete activation within twenty minutes.', 'success'); \Core\go_back(); return null; } else { \Core\set_message('Unable to send a confirmation email, please try again later.', 'error'); \Core\go_back(); return null; } } } // If there is a nonce enclosed, then it should be the second confirmation page. // This is the one that actually performs the action. if ($request->getParameter(0)) { /** @var NonceModel $nonce */ $nonce = NonceModel::Construct($request->getParameter(0)); if (!$nonce->isValid()) { \Core\set_message('Invalid key requested.', 'error'); \Core\redirect('/'); return null; } $nonce->decryptData(); $data = $nonce->get('data'); /** @var UserModel $user */ $user = $data['user']; try { $facebook = new Facebook(['appId' => FACEBOOK_APP_ID, 'secret' => FACEBOOK_APP_SECRET]); $facebook->setAccessToken($data['access_token']); $facebook->getUser(); $facebook->api('/me'); } catch (Exception $e) { \Core\set_message($e->getMessage(), 'error'); \Core\redirect('/'); return null; } $user->enableAuthDriver('facebook'); /** @var \Facebook\UserAuth $auth */ $auth = $user->getAuthDriver('facebook'); $auth->syncUser($data['access_token']); \Core\set_message('Linked Facebook successfully!', 'success'); // And log the user in! if (!\Core\user()->exists()) { $user->set('last_login', \CoreDateTime::Now('U', \Time::TIMEZONE_GMT)); $user->save(); \Core\Session::SetUser($user); } \Core\redirect('/'); return null; } }
/** * Get if this article is published AND not set to a future published date. * * @return bool */ public function isPublished() { return $this->get('status') == 'published' && $this->get('published') <= CoreDateTime::Now('U', Time::TIMEZONE_GMT); }
private function _viewBlogArticle(BlogModel $blog, BlogArticleModel $article) { $view = $this->getView(); /** @var $page PageModel */ $page = $article->getLink('Page'); //$articles = $blog->getLink('BlogArticle'); $manager = \Core\user()->checkAccess('p:/blog/manage_all'); $editor = \Core\user()->checkAccess($blog->get('manage_articles_permission ')) || $manager; $author = UserModel::Construct($article->get('authorid')); //$authorid = $author->get('id'); //var_dump($page->getMeta('keywords')); die(); if (!$article->isPublished()) { // Is it actually not published, or just marked for a future publish date? if ($article->get('status') == 'published') { $publishdate = new CoreDateTime($article->get('published')); Core::SetMessage('Article is set to be published on ' . $publishdate->getFormatted('F jS, Y \\a\\t h:ia'), 'info'); } else { Core::SetMessage('Article not published yet!', 'info'); } } //$view->templatename = $page->get('page_template') ? $page->get('page_template') : 'pages/blog/article_view.tpl'; $view->templatename = 'pages/blog/article_view.tpl'; //$view->addBreadcrumb($blog->get('title'), $blog->get('rewriteurl')); $view->title = $article->get('title'); $view->meta['title'] = $article->get('title'); $view->updated = $article->get('updated'); $view->canonicalurl = \Core\resolve_link($article->get('rewriteurl')); $view->meta['og:type'] = 'article'; if ($article->get('image')) { $image = \Core\Filestore\Factory::File($article->get('image')); $view->meta['og:image'] = $image->getPreviewURL('200x200'); } //if($author){ // /** @var $author User */ // //$view->meta['author'] = $author->getDisplayName(); // $view->meta['author'] = $author; //} $view->meta['description'] = $article->getTeaser(); $view->assign('author', $author->exists() ? $author : null); $view->assign('article', $article); $view->assign('body', \Core\parse_html($article->get('body'))); if ($editor) { $view->addControl('Edit Article', '/blog/article/update/' . $article->get('id'), 'edit'); if ($article->get('status') == 'draft') { $view->addControl(['title' => 'Publish Article', 'link' => '/blog/article/publish/' . $blog->get('id') . '/' . $article->get('id'), 'icon' => 'arrow-up', 'confirm' => 'Publish article?']); } $view->addControl(array('title' => 'Delete Article', 'link' => '/blog/article/delete/' . $article->get('id'), 'icon' => 'remove', 'confirm' => 'Remove blog article?')); } // Add the extra view types for this page $view->addHead('<link rel="alternate" type="application/atom+xml" title="' . $page->get('title') . ' Atom Feed" href="' . \Core\resolve_link($blog->get('baseurl')) . '.atom"/>'); $view->addHead('<link rel="alternate" type="application/rss+xml" title="' . $page->get('title') . ' RSS Feed" href="' . \Core\resolve_link($blog->get('baseurl')) . '.rss"/>'); $view->addControl('RSS Feed', \Core\resolve_link($blog->get('baseurl')) . '.rss', 'rss'); }
/** * The actual Core registration page. * * This renders all the user's configurable options at registration. */ public function register2(){ $view = $this->getView(); $request = $this->getPageRequest(); $manager = \Core\user()->checkAccess('p:/user/users/manage'); // Current user an admin? // Anonymous users should have access to this if it's allow public. if(!\Core\user()->exists() && !ConfigHandler::Get('/user/register/allowpublic')){ return View::ERROR_BADREQUEST; } // Authenticated users must check the permission to manage users. if(\Core\user()->exists() && !$manager){ return View::ERROR_ACCESSDENIED; } /** @var NonceModel $nonce */ $nonce = NonceModel::Construct($request->getParameter(0)); if(!$nonce->isValid()){ \Core\set_message('Invalid nonce token, please try again.', 'error'); \Core\go_back(); } $nonce->decryptData(); $data = $nonce->get('data'); if(!isset($data['user']) || !($data['user'] instanceof UserModel)){ if(DEVELOPMENT_MODE){ \Core\set_message('Your nonce does not include a "user" key. Please ensure that this is set to a non-existent UserModel object!', 'error'); } else{ \Core\set_message('Invalid login type, please try again later.', 'error'); } \Core\go_back(); } /** @var UserModel $user */ $user = $data['user']; $form = \Core\User\Helper::GetForm($user); // If the total number of form elements here are only 2, then only the user object and submit button are present. // Instead of showing the form, auto-submit to that destination. if(sizeof($form->getElements()) <= 2){ $user->setDefaultGroups(); $user->setDefaultMetaFields(); $user->setDefaultActiveStatuses(); $user->generateNewApiKey(); $user->save(); // User created... make a log of this! \SystemLogModel::LogSecurityEvent('/user/register', 'User registration successful', null, $user->get('id')); // Send a thank you for registering email to the user. try{ $user->sendWelcomeEmail(); } catch(\Exception $e){ \Core\ErrorManagement\exception_handler($e); \Core\set_message('t:MESSAGE_ERROR_CANNOT_SEND_WELCOME_EMAIL'); } // "login" this user if not already logged in. if(!\Core\user()->exists()){ if($user->get('active')){ $user->set('last_login', \CoreDateTime::Now('U', \Time::TIMEZONE_GMT)); $user->save(); \Core\Session::SetUser($user); } \Core\set_message('t:MESSAGE_SUCCESS_CREATED_USER_ACCOUNT'); if(($overrideurl = \HookHandler::DispatchHook('/user/postlogin/getredirecturl'))){ // Allow an external script to override the redirecting URL. $url = $overrideurl; } elseif($form->getElementValue('redirect')){ // The preferred default redirect method. // This is set from /user/register2, which is in turn passed in, (hopefully), by the original callee registration page. $url = $form->getElementValue('redirect'); } elseif(strpos(REL_REQUEST_PATH, '/user/register') === 0){ // If the user came from the registration page, get the page before that. $url = '/'; } else{ // else the registration link is now on the same page as the 403 handler. $url = REL_REQUEST_PATH; } \Core\redirect($url); } // It was created administratively; redirect there instead. else{ \Core\set_message('t:MESSAGE_SUCCESS_CREATED_USER_ACCOUNT'); \Core\redirect('/user/admin'); } } $form->addElement('hidden', ['name' => 'redirect', 'value' => $data['redirect']]); $view->title = 'Complete Registration'; $view->assign('form', $form); }