diff --git a/control/Controller.php b/control/Controller.php index becd21f86..22b4a581d 100644 --- a/control/Controller.php +++ b/control/Controller.php @@ -71,15 +71,6 @@ class Controller extends RequestHandler implements TemplateGlobalProvider { public function init() { if($this->basicAuthEnabled) BasicAuth::protect_site_if_necessary(); - // Directly access the session variable just in case the Group or Member tables don't yet exist - if(Session::get('loggedInAs') && Security::database_is_ready()) { - $member = Member::currentUser(); - if($member) { - DB::query("UPDATE \"Member\" SET \"LastVisited\" = " . DB::getConn()->now() - . " WHERE \"ID\" = $member->ID", null); - } - } - // This is used to test that subordinate controllers are actually calling parent::init() - a common bug $this->baseInitCalled = true; } diff --git a/docs/en/changelogs/rc/3.2.0.md b/docs/en/changelogs/rc/3.2.0.md index afb542352..3e0489ac9 100644 --- a/docs/en/changelogs/rc/3.2.0.md +++ b/docs/en/changelogs/rc/3.2.0.md @@ -139,3 +139,7 @@ the default ones. Injector: FormTemplateHelper: class: FormTemplateHelper_Pre32 + +### Further Changes + + * Removed `Member.LastVisited` and `Member.NumVisits` properties, see [Howto: Track Member Logins](doc.silverstripe.org/framework/en/trunk/howto/track-member-logins) to restore functionality as custom code \ No newline at end of file diff --git a/docs/en/howto/track-member-logins.md b/docs/en/howto/track-member-logins.md new file mode 100644 index 000000000..cf2eaa688 --- /dev/null +++ b/docs/en/howto/track-member-logins.md @@ -0,0 +1,52 @@ +# Howto: Track Member Logins + +Sometimes its good to know how active your users are, +and when they last visited the site (and logged on). +A simple `LastVisited` property on the `Member` record +with some hooks into the login process can achieve this. +In addition, a `NumVisit` property will tell us how +often the member has visited. Or more specifically, +how often he has started a browser session, either through +explicitly logging in or by invoking the "remember me" functionality. + + :::php + 'Datetime', + 'NumVisit' => 'Int', + ); + + public function memberLoggedIn() { + $this->logVisit(); + } + + public function memberAutoLoggedIn() { + $this->logVisit(); + } + + public function updateCMSFields(FieldList $fields) { + $fields->addFieldsToTab('Root.Main', array( + ReadonlyField::create('LastVisited', 'Last visited'), + ReadonlyField::create('NumVisits', 'Number of visits') + )); + } + + protected function logVisit() { + if(!Security::database_is_ready()) return; + + DB::query(sprintf( + 'UPDATE "Member" SET "LastVisited" = %s, "NumVisit" = "NumVisit" + 1 WHERE "ID" = %d', + DB::getConn()->now(), + $this->owner->ID + )); + } + } + +Now you just need to apply this extension through your config: + + :::yml + Member: + extensions: + - MyMemberExtension + diff --git a/docs/en/topics/datamodel.md b/docs/en/topics/datamodel.md index 9a85dfe72..3799df139 100755 --- a/docs/en/topics/datamodel.md +++ b/docs/en/topics/datamodel.md @@ -272,7 +272,7 @@ start with S, who has logged in since 1/1/2011. :::php $members = Member::get()->filter(array( 'FirstName:StartsWith:Not' => 'S' - 'LastVisited:GreaterThan' => '2011-01-01' + 'Birthday:GreaterThan' => '2011-01-01' )); ### Subtract diff --git a/security/Member.php b/security/Member.php index de25557f4..e373a07d3 100644 --- a/security/Member.php +++ b/security/Member.php @@ -13,8 +13,6 @@ class Member extends DataObject implements TemplateGlobalProvider { 'Email' => 'Varchar(256)', // See RFC 5321, Section 4.5.3.1.3. 'Password' => 'Varchar(160)', 'RememberLoginToken' => 'Varchar(160)', // Note: this currently holds a hash, not a token. - 'NumVisit' => 'Int', - 'LastVisited' => 'SS_Datetime', 'AutoLoginHash' => 'Varchar(160)', 'AutoLoginExpired' => 'SS_Datetime', // This is an arbitrary code pointing to a PasswordEncryptor instance, @@ -369,8 +367,6 @@ class Member extends DataObject implements TemplateGlobalProvider { // This lets apache rules detect whether the user has logged in if(Member::config()->login_marker_cookie) Cookie::set(Member::config()->login_marker_cookie, 1, 0); - $this->NumVisit++; - if($remember) { // Store the hash and give the client the cookie with the token. $generator = new RandomGenerator(); @@ -454,8 +450,6 @@ class Member extends DataObject implements TemplateGlobalProvider { $hash = $member->encryptWithUserSettings($token); $member->RememberLoginToken = $hash; Cookie::set('alc_enc', $member->ID . ':' . $token, 90, null, null, false, true); - - $member->NumVisit++; $member->write(); // Audit logging hook @@ -595,8 +589,6 @@ class Member extends DataObject implements TemplateGlobalProvider { )); $fields->removeByName('RememberLoginToken'); - $fields->removeByName('NumVisit'); - $fields->removeByName('LastVisited'); $fields->removeByName('AutoLoginHash'); $fields->removeByName('AutoLoginExpired'); $fields->removeByName('PasswordEncryption'); @@ -1181,9 +1173,6 @@ class Member extends DataObject implements TemplateGlobalProvider { } $mainFields->removeByName('Salt'); - $mainFields->removeByName('NumVisit'); - - $mainFields->makeFieldReadonly('LastVisited'); $fields->removeByName('Subscriptions'); @@ -1279,8 +1268,6 @@ class Member extends DataObject implements TemplateGlobalProvider { $labels['Surname'] = _t('Member.SURNAME', 'Surname'); $labels['Email'] = _t('Member.EMAIL', 'Email'); $labels['Password'] = _t('Member.db_Password', 'Password'); - $labels['NumVisit'] = _t('Member.db_NumVisit', 'Number of Visits'); - $labels['LastVisited'] = _t('Member.db_LastVisited', 'Last Visited Date'); $labels['PasswordExpiry'] = _t('Member.db_PasswordExpiry', 'Password Expiry Date', 'Password expiry date'); $labels['LockedOutUntil'] = _t('Member.db_LockedOutUntil', 'Locked out until', 'Security related date'); $labels['Locale'] = _t('Member.db_Locale', 'Interface Locale');