Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKate Butler <kate@innocraft.com>2019-08-14 02:48:36 +0300
committerThomas Steur <tsteur@users.noreply.github.com>2019-08-14 02:48:36 +0300
commit5f96a27e860de0da9cc86db8736e08a9573fbec8 (patch)
tree488de6bbcbc5dbe2ec735e3a27d968dc08a95e1b /plugins/UsersManager
parent85932196aa30e93cc0c28d4445b081b7f710c8ae (diff)
Add newsletter signup button to user settings page (#14466)
* Add newsletter signup button to user settings page * UI tests for newsletter signup on user settings page * Move UI tests for user settings out of UIIntegrationTest * Fix screenshots for UI tests * Move newsletter signup logic out of API * PR changes * Require token to sign users up to newsletter * Add privacy notice and checkbox to newsletter signup * Update UI tests * Fix UI test * do things the angular way * Update userSettings.twig * PR changes * Update reference screenshots * Fix UI test to work with new piwik form elements; remove duplicate test * Capture notification container in screenshot * fix ui tests
Diffstat (limited to 'plugins/UsersManager')
-rw-r--r--plugins/UsersManager/API.php13
-rw-r--r--plugins/UsersManager/Controller.php5
-rw-r--r--plugins/UsersManager/Model.php6
-rw-r--r--plugins/UsersManager/NewsletterSignup.php53
-rw-r--r--plugins/UsersManager/UsersManager.php4
-rw-r--r--plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js35
-rw-r--r--plugins/UsersManager/lang/en.json6
-rw-r--r--plugins/UsersManager/templates/userSettings.twig23
-rw-r--r--plugins/UsersManager/tests/Integration/UsersManagerTest.php14
-rw-r--r--plugins/UsersManager/tests/UI/UserSettings_spec.js61
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_already_signed_up.png3
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_asks_confirmation.png3
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_load.png3
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_signup_success.png3
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_wrong_password_confirmed.png3
15 files changed, 232 insertions, 3 deletions
diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php
index b25a1d6f79..fac5b6178d 100644
--- a/plugins/UsersManager/API.php
+++ b/plugins/UsersManager/API.php
@@ -969,6 +969,7 @@ class API extends \Piwik\Plugin\API
}
$this->model->deleteUserOnly($userLogin);
+ $this->model->deleteUserOptions($userLogin);
$this->model->deleteUserAccess($userLogin);
Cache::deleteTrackerCache();
@@ -1362,6 +1363,18 @@ class API extends \Piwik\Plugin\API
return $user['token_auth'];
}
+ public function newsletterSignup()
+ {
+ Piwik::checkUserIsNotAnonymous();
+
+ $userLogin = Piwik::getCurrentUserLogin();
+ $email = Piwik::getCurrentUserEmail();
+
+ $success = NewsletterSignup::signupForNewsletter($userLogin, $email, true);
+ $result = $success ? array('success' => true) : array('error' => true);
+ return $result;
+ }
+
private function isUserHasAdminAccessTo($idSite)
{
try {
diff --git a/plugins/UsersManager/Controller.php b/plugins/UsersManager/Controller.php
index 9b0c9b475a..a9e2ffcf5b 100644
--- a/plugins/UsersManager/Controller.php
+++ b/plugins/UsersManager/Controller.php
@@ -13,6 +13,7 @@ use Piwik\API\Request;
use Piwik\API\ResponseBuilder;
use Piwik\Common;
use Piwik\Container\StaticContainer;
+use Piwik\Option;
use Piwik\Piwik;
use Piwik\Plugin\ControllerAdmin;
use Piwik\Plugins\LanguagesManager\API as APILanguagesManager;
@@ -183,6 +184,10 @@ class Controller extends ControllerAdmin
$view->userTokenAuth = Piwik::getCurrentUserTokenAuth();
$view->ignoreSalt = $this->getIgnoreCookieSalt();
+ $newsletterSignupOptionKey = NewsletterSignup::NEWSLETTER_SIGNUP_OPTION . $userLogin;
+ $view->showNewsletterSignup = Option::get($newsletterSignupOptionKey) === false
+ && SettingsPiwik::isInternetEnabled();
+
$userPreferences = new UserPreferences();
$defaultReport = $userPreferences->getDefaultReport();
diff --git a/plugins/UsersManager/Model.php b/plugins/UsersManager/Model.php
index 22d7413ccb..839fdbd578 100644
--- a/plugins/UsersManager/Model.php
+++ b/plugins/UsersManager/Model.php
@@ -12,6 +12,7 @@ use Piwik\Auth\Password;
use Piwik\Common;
use Piwik\Date;
use Piwik\Db;
+use Piwik\Option;
use Piwik\Piwik;
use Piwik\Plugins\SitesManager\SitesManager;
use Piwik\Plugins\UsersManager\Sql\SiteAccessFilter;
@@ -392,6 +393,11 @@ class Model
Piwik::postEvent('UsersManager.deleteUser', array($userLogin));
}
+ public function deleteUserOptions($userLogin)
+ {
+ Option::deleteLike('UsersManager.%.' . $userLogin);
+ }
+
/**
* @param string $userLogin
*/
diff --git a/plugins/UsersManager/NewsletterSignup.php b/plugins/UsersManager/NewsletterSignup.php
new file mode 100644
index 0000000000..af489f5562
--- /dev/null
+++ b/plugins/UsersManager/NewsletterSignup.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Matomo - free/libre analytics platform
+ *
+ * @link http://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\UsersManager;
+
+use Exception;
+use Piwik\Config;
+use Piwik\Container\StaticContainer;
+use Piwik\Http;
+use Piwik\Option;
+use Piwik\SettingsPiwik;
+use Piwik\Url;
+
+class NewsletterSignup
+{
+ const NEWSLETTER_SIGNUP_OPTION = 'UsersManager.newsletterSignup.';
+
+ public static function signupForNewsletter($userLogin, $email, $matomoOrg = false, $professionalServices = false)
+ {
+ // Don't bother if they aren't signing up for at least one newsletter, or if we don't have internet access
+ $doSignup = ($matomoOrg || $professionalServices) && SettingsPiwik::isInternetEnabled();
+ if (!$doSignup) {
+ return false;
+ }
+
+ $url = Config::getInstance()->General['api_service_url'];
+ $url .= '/1.0/subscribeNewsletter/';
+
+ $params = array(
+ 'email' => $email,
+ 'piwikorg' => (int)$matomoOrg,
+ 'piwikpro' => (int)$professionalServices,
+ 'url' => Url::getCurrentUrlWithoutQueryString(),
+ 'language' => StaticContainer::get('Piwik\Translation\Translator')->getCurrentLanguage(),
+ );
+
+ $url .= '?' . Http::buildQuery($params);
+ try {
+ Http::sendHttpRequest($url, $timeout = 2);
+ $optionKey = self::NEWSLETTER_SIGNUP_OPTION . $userLogin;
+ Option::set($optionKey, 1);
+ return true;
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/UsersManager/UsersManager.php b/plugins/UsersManager/UsersManager.php
index a844aee258..7e3f6de428 100644
--- a/plugins/UsersManager/UsersManager.php
+++ b/plugins/UsersManager/UsersManager.php
@@ -239,6 +239,7 @@ class UsersManager extends \Piwik\Plugin
$translationKeys[] = "General_Save";
$translationKeys[] = "General_Done";
$translationKeys[] = "General_Pagination";
+ $translationKeys[] = "General_PleaseTryAgain";
$translationKeys[] = "UsersManager_DeleteConfirm";
$translationKeys[] = "UsersManager_ConfirmGrantSuperUserAccess";
$translationKeys[] = "UsersManager_ConfirmProhibitOtherUsersSuperUserAccess";
@@ -314,6 +315,7 @@ class UsersManager extends \Piwik\Plugin
$translationKeys[] = 'General_Warning';
$translationKeys[] = 'General_Add';
$translationKeys[] = 'General_Note';
+ $translationKeys[] = 'General_Yes';
$translationKeys[] = 'UsersManager_FilterByWebsite';
$translationKeys[] = 'UsersManager_GiveAccessToAll';
$translationKeys[] = 'UsersManager_OrManageIndividually';
@@ -324,5 +326,7 @@ class UsersManager extends \Piwik\Plugin
$translationKeys[] = 'UsersManager_AreYouSureAddCapability';
$translationKeys[] = 'UsersManager_AreYouSureRemoveCapability';
$translationKeys[] = 'UsersManager_IncludedInUsersRole';
+ $translationKeys[] = 'UsersManager_NewsletterSignupFailureMessage';
+ $translationKeys[] = 'UsersManager_NewsletterSignupSuccessMessage';
}
}
diff --git a/plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js b/plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js
index 31f9f02f7e..635d6e93db 100644
--- a/plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js
+++ b/plugins/UsersManager/angularjs/personal-settings/personal-settings.controller.js
@@ -7,14 +7,18 @@
(function () {
angular.module('piwikApp').controller('PersonalSettingsController', PersonalSettingsController);
- PersonalSettingsController.$inject = ['piwikApi', '$window', 'piwik'];
+ PersonalSettingsController.$inject = ['piwikApi', '$filter', '$window', 'piwik'];
- function PersonalSettingsController(piwikApi, $window, piwik) {
+ function PersonalSettingsController(piwikApi, $filter, $window, piwik) {
// remember to keep controller very simple. Create a service/factory (model) if needed
+ var translate = $filter('translate');
+
var self = this;
+ this.newsletterSignupButtonTitle = translate('General_Save');
this.doesRequirePasswordConfirmation = false;
+ this.showNewsletterSignup = true;
function updateSettings(postParams)
{
@@ -43,6 +47,33 @@
this.doesRequirePasswordConfirmation = true;
};
+ this.signupForNewsletter = function () {
+ var signupBtn = $('#newsletterSignupBtn');
+ signupBtn.html(translate('General_Loading'));
+ this.isProcessingNewsletterSignup = true;
+
+ piwikApi.withTokenInUrl();
+ piwikApi.fetch({module: 'API', method: 'UsersManager.newsletterSignup'}).then(function () {
+ self.isProcessingNewsletterSignup = false;
+ self.showNewsletterSignup = false;
+
+ var UI = require('piwik/UI');
+ var notification = new UI.Notification();
+ notification.show(translate('UsersManager_NewsletterSignupSuccessMessage'), { id: 'newslettersignup', context: 'success'});
+ notification.scrollToNotification();
+
+ }, function () {
+ self.isProcessingNewsletterSignup = false;
+
+ var UI = require('piwik/UI');
+ var notification = new UI.Notification();
+ notification.show(translate('UsersManager_NewsletterSignupFailureMessage'), { id: 'newslettersignup', context: 'error' });
+ notification.scrollToNotification();
+
+ self.newsletterSignupButtonTitle = translate('General_PleaseTryAgain');
+ });
+ };
+
this.regenerateTokenAuth = function () {
var parameters = { userLogin: piwik.userLogin };
diff --git a/plugins/UsersManager/lang/en.json b/plugins/UsersManager/lang/en.json
index 866b52567a..c8f7e4de47 100644
--- a/plugins/UsersManager/lang/en.json
+++ b/plugins/UsersManager/lang/en.json
@@ -161,6 +161,10 @@
"EmailChangedEmail2": "This change was initiated from the following device: %1$s (IP address = %2$s).",
"IfThisWasYouIgnoreIfNot": "If this was you, feel free to ignore this email. If this was not you, please login, correct your email address, change your password and contact your Matomo administrator.",
"PasswordChangeNotificationSubject": "Your Matomo account's password has just been changed",
- "PasswordChangedEmail": "Your password has just been changed. The change was initiated from the following device: %1$s (IP address = %2$s)."
+ "PasswordChangedEmail": "Your password has just been changed. The change was initiated from the following device: %1$s (IP address = %2$s).",
+ "NewsletterSignupTitle": "Newsletter Signup",
+ "NewsletterSignupMessage": "Subscribe to our newsletter to receive regular information about Matomo. You can unsubscribe from it any time. This service uses MadMimi. Learn more about it on our %1$sPrivacy Policy page%2$s.",
+ "NewsletterSignupFailureMessage": "Whoops, something went wrong. We weren't able to sign you up for the newsletter.",
+ "NewsletterSignupSuccessMessage": "Super, you're all signed up! We'll be in touch soon."
}
}
diff --git a/plugins/UsersManager/templates/userSettings.twig b/plugins/UsersManager/templates/userSettings.twig
index 72ac592a29..567cac4984 100644
--- a/plugins/UsersManager/templates/userSettings.twig
+++ b/plugins/UsersManager/templates/userSettings.twig
@@ -120,6 +120,29 @@
</form>
</div>
+{% if showNewsletterSignup %}
+<div ng-controller="PersonalSettingsController as personalSettings">
+ <div piwik-content-block id="newsletterSignup"
+ ng-show="personalSettings.showNewsletterSignup"
+ content-title="{{ 'UsersManager_NewsletterSignupTitle'|translate|e('html_attr') }}">
+
+ <div piwik-field uicontrol="checkbox" name="newsletterSignupCheckbox"
+ ng-model="personalSettings.newsletterSignupCheckbox"
+ full-width="true"
+ data-title="{{ 'UsersManager_NewsletterSignupMessage'|translate('<a href="https://matomo.org/privacy-policy/" target="_blank">', '</a>')|e('html_attr') }}"
+ >
+ </div>
+
+ <div piwik-save-button id="newsletterSignupBtn"
+ onconfirm="personalSettings.signupForNewsletter()"
+ data-disabled="!personalSettings.newsletterSignupCheckbox"
+ value="{{ '{{ personalSettings.newsletterSignupButtonTitle }}'|raw }}"
+ saving="personalSettings.isProcessingNewsletterSignup">
+ </div>
+ </div>
+</div>
+{% endif %}
+
<div piwik-content-block
content-title="{{ 'UsersManager_TokenAuth'|translate|e('html_attr') }}">
<pre piwik-select-on-focus id="token_auth_user" piwik-show-sensitive-data="{{ userTokenAuth }}"></pre>
diff --git a/plugins/UsersManager/tests/Integration/UsersManagerTest.php b/plugins/UsersManager/tests/Integration/UsersManagerTest.php
index 2d6fc410f7..15f2124ab6 100644
--- a/plugins/UsersManager/tests/Integration/UsersManagerTest.php
+++ b/plugins/UsersManager/tests/Integration/UsersManagerTest.php
@@ -11,9 +11,11 @@ namespace Piwik\Plugins\UsersManager\tests\Integration;
use Piwik\Access;
use Piwik\Auth\Password;
use Piwik\Common;
+use Piwik\Option;
use Piwik\Plugins\SitesManager\API as APISitesManager;
use Piwik\Plugins\UsersManager\API;
use Piwik\Plugins\UsersManager\Model;
+use Piwik\Plugins\UsersManager\NewsletterSignup;
use Piwik\Plugins\UsersManager\UsersManager;
use Piwik\Plugins\UsersManager\UserUpdater;
use Piwik\Tests\Framework\Fixture;
@@ -425,6 +427,18 @@ class UsersManagerTest extends IntegrationTestCase
$this->assertEquals(array(), $this->api->getSitesAccessFromUser("geggeqgeqag"));
}
+ public function testDeleteUser_deletesUserOptions()
+ {
+ Fixture::createSuperUser();
+ $this->api->addUser("geggeqgeqag", "geqgeagae", "test@test.com", "alias");
+ Option::set(NewsletterSignup::NEWSLETTER_SIGNUP_OPTION . 'geggeqgeqag', 'yes');
+
+ $this->api->deleteUser("geggeqgeqag");
+
+ $option = Option::get(NewsletterSignup::NEWSLETTER_SIGNUP_OPTION . 'geggeqgeqag');
+ $this->assertFalse($option);
+ }
+
/**
* @expectedException \Exception
* @expectedExceptionMessage UsersManager_ExceptionUserDoesNotExist
diff --git a/plugins/UsersManager/tests/UI/UserSettings_spec.js b/plugins/UsersManager/tests/UI/UserSettings_spec.js
new file mode 100644
index 0000000000..190673c6ca
--- /dev/null
+++ b/plugins/UsersManager/tests/UI/UserSettings_spec.js
@@ -0,0 +1,61 @@
+/*!
+ * Matomo - free/libre analytics platform
+ *
+ * UsersManager screenshot tests.
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+describe("UserSettings", function () {
+ this.timeout(0);
+ this.fixture = "Piwik\\Plugins\\UsersManager\\tests\\Fixtures\\ManyUsers";
+
+ var url = "?module=UsersManager&action=userSettings";
+
+ before(async function() {
+ await page.webpage.setViewport({
+ width: 1250,
+ height: 768
+ });
+ });
+
+ it('should show user settings page', async function () {
+ await page.goto(url);
+ expect(await page.screenshotSelector('.admin')).to.matchImage('load');
+ });
+
+ it('should allow user to subscribe to newsletter', async function () {
+ await page.click('#newsletterSignup label');
+ await page.click('#newsletterSignupBtn input');
+ await page.waitForNetworkIdle();
+ expect(await page.screenshotSelector('.pageWrap')).to.matchImage('signup_success');
+ });
+
+ it('should not prompt user to subscribe to newsletter again', async function () {
+ // Assumes previous test has clicked on the signup button - so we shouldn't see it this time
+ await page.goto(url);
+ expect(await page.screenshotSelector('.admin')).to.matchImage('already_signed_up');
+ });
+
+ it('should ask for password confirmation when changing email', async function () {
+ await page.evaluate(function () {
+ $('#userSettingsTable input#email').val('testlogin123@example.com').change();
+ });
+ await page.click('#userSettingsTable [piwik-save-button] .btn');
+ await page.waitFor(500); // wait for animation
+
+ let pageWrap = await page.$('.modal.open');
+ expect(await pageWrap.screenshot()).to.matchImage('asks_confirmation');
+ });
+
+ it('should load error when wrong password specified', async function () {
+ await page.type('.modal.open #currentPassword', 'foobartest123');
+ btnNo = await page.jQuery('.modal.open .modal-action:not(.modal-no)');
+ await btnNo.click();
+ await page.waitForNetworkIdle();
+
+ let pageWrap = await page.$('#notificationContainer');
+ expect(await pageWrap.screenshot()).to.matchImage('wrong_password_confirmed');
+ });
+}); \ No newline at end of file
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_already_signed_up.png b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_already_signed_up.png
new file mode 100644
index 0000000000..c80c406a1d
--- /dev/null
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_already_signed_up.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7c72e030a905a1d12b9a7f37a7ba55b4c8af795605e0dfe2b6f5720bf22b2e38
+size 256833
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_asks_confirmation.png b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_asks_confirmation.png
new file mode 100644
index 0000000000..9463f3d49a
--- /dev/null
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_asks_confirmation.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4a7d52fd49c0ec3236a9f30599d30ca50df02faabd60d7fee95cb03565b69863
+size 15729
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_load.png b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_load.png
new file mode 100644
index 0000000000..3c36a8c9c4
--- /dev/null
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_load.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:471e81890434001d43d046898ffbfa54538ab874c97edcdc71254268f5226e68
+size 281276
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_signup_success.png b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_signup_success.png
new file mode 100644
index 0000000000..0f182e8e02
--- /dev/null
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_signup_success.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:faf42e67b73481c4cb2cad9cb54bf5fb4c5e99009e7caa1f5503e48d70bf61c3
+size 269494
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_wrong_password_confirmed.png b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_wrong_password_confirmed.png
new file mode 100644
index 0000000000..59aee17129
--- /dev/null
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UserSettings_wrong_password_confirmed.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d553f29ce6bf59c9368d9496286bbfc720ecab6125560fe3fbf36051b9622bf1
+size 6092