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:
authorJulienMoumne <julien@piwik.org>2012-08-14 00:26:46 +0400
committerJulienMoumne <julien@piwik.org>2012-08-14 00:26:46 +0400
commit7427003ab87ef41d1b1f23365480cf8c8bb11242 (patch)
tree203b52fb8bcb69f2b4b999cb828dc3386c29e8ae /plugins/MobileMessaging
parent4931b9809c69947a16b67954802cecd5140bdfad (diff)
refs #2708
* fixing a bug in ''Piwik::getPrettyValue()'' where a revenue evolution would be prettified like so: ''$ 100%'' * fixing a bug happening when no data is available for the selected day * when MultiSites plugin is deactivated, invite user via SMS to activate it back * SMS API accounts are now managed using an API key instead of a username and a password * adding ''[too long]'' at the end of the SMS content when it reaches the maximum length allowed by the SMS API * support for UCS-2 characters * Mediaburst rebranded to Clockwork * various UI improvements based on comment:31:ticket:2708 * PDFReport.generateReport now supports $outputType=3 : output report in browser * removing non-libre select-to-autocomplete jQuery plugin * tracking count of phone number validation requests and SMS sent * SMS content now contains CoreHome_ThereIsNoDataForThisReport when applicable * setting SMS From with General_Reports when configured report is MultiSites_getAll * adding Clockwork description TODO * using POST instead of GET to send SMS to go around a Clockwork limitation git-svn-id: http://dev.piwik.org/svn/trunk@6727 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'plugins/MobileMessaging')
-rw-r--r--plugins/MobileMessaging/API.php87
-rw-r--r--plugins/MobileMessaging/Controller.php1
-rw-r--r--plugins/MobileMessaging/CountryCallingCodes.php1
-rw-r--r--plugins/MobileMessaging/GSMCharset.php160
-rw-r--r--plugins/MobileMessaging/MobileMessaging.php47
-rw-r--r--plugins/MobileMessaging/ReportRenderer/Exception.php67
-rw-r--r--plugins/MobileMessaging/ReportRenderer/Sms.php12
-rw-r--r--plugins/MobileMessaging/SMSProvider.php110
-rw-r--r--plugins/MobileMessaging/SMSProvider/Clockwork.php (renamed from plugins/MobileMessaging/SMSProvider/Mediaburst.php)31
-rw-r--r--plugins/MobileMessaging/lang/en.php32
-rw-r--r--plugins/MobileMessaging/scripts/MobileMessagingSettings.js101
-rw-r--r--plugins/MobileMessaging/scripts/jquery.select-to-autocomplete.js283
-rw-r--r--plugins/MobileMessaging/templates/ReportParameters.tpl2
-rw-r--r--plugins/MobileMessaging/templates/SMSReport.tpl5
-rw-r--r--plugins/MobileMessaging/templates/Settings.tpl165
15 files changed, 657 insertions, 447 deletions
diff --git a/plugins/MobileMessaging/API.php b/plugins/MobileMessaging/API.php
index 31a32bedab..1a9ca47d17 100644
--- a/plugins/MobileMessaging/API.php
+++ b/plugins/MobileMessaging/API.php
@@ -55,9 +55,7 @@ class Piwik_MobileMessaging_API
Piwik::checkUserIsNotAnonymous();
$credential = $this->getSMSAPICredential();
- return
- isset($credential[Piwik_MobileMessaging::USERNAME_OPTION])
- && !empty($credential[Piwik_MobileMessaging::USERNAME_OPTION]);
+ return isset($credential[Piwik_MobileMessaging::API_KEY_OPTION]);
}
private function getSMSAPICredential()
@@ -66,26 +64,12 @@ class Piwik_MobileMessaging_API
return array(
Piwik_MobileMessaging::PROVIDER_OPTION =>
isset($settings[Piwik_MobileMessaging::PROVIDER_OPTION]) ? $settings[Piwik_MobileMessaging::PROVIDER_OPTION] : null,
- Piwik_MobileMessaging::USERNAME_OPTION =>
- isset($settings[Piwik_MobileMessaging::USERNAME_OPTION]) ? $settings[Piwik_MobileMessaging::USERNAME_OPTION] : null,
- Piwik_MobileMessaging::PASSWORD_OPTION =>
- isset($settings[Piwik_MobileMessaging::PASSWORD_OPTION]) ? $settings[Piwik_MobileMessaging::PASSWORD_OPTION] : null,
+ Piwik_MobileMessaging::API_KEY_OPTION =>
+ isset($settings[Piwik_MobileMessaging::API_KEY_OPTION]) ? $settings[Piwik_MobileMessaging::API_KEY_OPTION] : null,
);
}
/**
- * return the username of the SMS API account for the current user
- *
- * @return string username of the SMS API account
- */
- public function getAPIUsername()
- {
- $this->checkCredentialManagementRights();
- $credential = $this->getSMSAPICredential();
- return $credential[Piwik_MobileMessaging::USERNAME_OPTION];
- }
-
- /**
* return the SMS API Provider for the current user
*
* @return string SMS API Provider
@@ -101,23 +85,21 @@ class Piwik_MobileMessaging_API
* set the SMS API credential
*
* @param string $provider SMS API provider
- * @param string $username SMS API username
- * @param string $password SMS API password
+ * @param string $apiKey API Key
*
* @return bool true if SMS API credential were validated and saved, false otherwise
*/
- public function setSMSAPICredential($provider, $username, $password)
+ public function setSMSAPICredential($provider, $apiKey)
{
$this->checkCredentialManagementRights();
$smsProviderInstance = self::getSMSProviderInstance($provider);
- $smsProviderInstance->verifyCredential($username, $password);
+ $smsProviderInstance->verifyCredential($apiKey);
$settings = $this->getCredentialManagerSettings();
$settings[Piwik_MobileMessaging::PROVIDER_OPTION] = $provider;
- $settings[Piwik_MobileMessaging::USERNAME_OPTION] = $username;
- $settings[Piwik_MobileMessaging::PASSWORD_OPTION] = $password;
+ $settings[Piwik_MobileMessaging::API_KEY_OPTION] = $apiKey;
$this->setCredentialManagerSettings($settings);
@@ -141,7 +123,14 @@ class Piwik_MobileMessaging_API
$verificationCode .= rand(0,9);
}
- $smsText = Piwik_Translate('MobileMessaging_VerificationText', $verificationCode);
+ $smsText = Piwik_Translate(
+ 'MobileMessaging_VerificationText',
+ array(
+ $verificationCode,
+ Piwik_Translate('UserSettings_SubmenuSettings'),
+ Piwik_Translate('MobileMessaging_SettingsMenu')
+ )
+ );
$this->sendSMS($smsText, $phoneNumber, self::SMS_FROM);
@@ -149,6 +138,8 @@ class Piwik_MobileMessaging_API
$phoneNumbers[$phoneNumber] = $verificationCode;
$this->savePhoneNumbers($phoneNumbers);
+ $this->increaseCount(Piwik_MobileMessaging::PHONE_NUMBER_VALIDATION_REQUEST_COUNT_OPTION, $phoneNumber);
+
return true;
}
@@ -166,13 +157,14 @@ class Piwik_MobileMessaging_API
$credential = $this->getSMSAPICredential();
$SMSProvider = self::getSMSProviderInstance($credential[Piwik_MobileMessaging::PROVIDER_OPTION]);
$SMSProvider->sendSMS(
- $credential[Piwik_MobileMessaging::USERNAME_OPTION],
- $credential[Piwik_MobileMessaging::PASSWORD_OPTION],
+ $credential[Piwik_MobileMessaging::API_KEY_OPTION],
$content,
$phoneNumber,
$from
);
+ $this->increaseCount(Piwik_MobileMessaging::SMS_SENT_COUNT_OPTION, $phoneNumber);
+
return true;
}
@@ -188,8 +180,7 @@ class Piwik_MobileMessaging_API
$credential = $this->getSMSAPICredential();
$SMSProvider = self::getSMSProviderInstance($credential[Piwik_MobileMessaging::PROVIDER_OPTION]);
return $SMSProvider->getCreditLeft(
- $credential[Piwik_MobileMessaging::USERNAME_OPTION],
- $credential[Piwik_MobileMessaging::PASSWORD_OPTION]
+ $credential[Piwik_MobileMessaging::API_KEY_OPTION]
);
}
@@ -236,6 +227,7 @@ class Piwik_MobileMessaging_API
{
$reportParameters[Piwik_MobileMessaging::PHONE_NUMBERS_PARAMETER] = $updatedPhoneNumbers;
+ // note: reports can end up without any recipients
$pdfReportsAPIInstance->updateReport(
$report['idreport'],
$report['idsite'],
@@ -275,6 +267,38 @@ class Piwik_MobileMessaging_API
$this->setCurrentUserSettings($settings);
}
+ private function increaseCount($option, $phoneNumber)
+ {
+ $settings = $this->getCurrentUserSettings();
+
+ $counts = array();
+ if(isset($settings[$option]))
+ {
+ $counts = $settings[$option];
+ }
+
+ $countToUpdate = 0;
+ if(isset($counts[$phoneNumber]))
+ {
+ $countToUpdate = $counts[$phoneNumber];
+ }
+
+ $counts[$phoneNumber] = $countToUpdate + 1;
+
+ $settings[$option] = $counts;
+
+ $this->setCurrentUserSettings($settings);
+ }
+
+ private function saveSMSSentCount($smsSentCount)
+ {
+ $settings = $this->getCurrentUserSettings();
+
+ $settings[Piwik_MobileMessaging::SMS_SENT_COUNT_OPTION] = $smsSentCount;
+
+ $this->setCurrentUserSettings($settings);
+ }
+
/**
* validate phone number
*
@@ -363,8 +387,7 @@ class Piwik_MobileMessaging_API
$settings = $this->getCredentialManagerSettings();
- $settings[Piwik_MobileMessaging::USERNAME_OPTION] = null;
- $settings[Piwik_MobileMessaging::PASSWORD_OPTION] = null;
+ $settings[Piwik_MobileMessaging::API_KEY_OPTION] = null;
$this->setCredentialManagerSettings($settings);
diff --git a/plugins/MobileMessaging/Controller.php b/plugins/MobileMessaging/Controller.php
index 619c39b7a0..4c3606c61b 100644
--- a/plugins/MobileMessaging/Controller.php
+++ b/plugins/MobileMessaging/Controller.php
@@ -41,7 +41,6 @@ class Piwik_MobileMessaging_Controller extends Piwik_Controller_Admin
if($view->credentialSupplied && $view->accountManagedByCurrentUser)
{
$view->provider = $mobileMessagingAPI->getSMSProvider();
- $view->APIUsername = $mobileMessagingAPI->getAPIUsername();
$view->creditLeft = $mobileMessagingAPI->getCreditLeft();
}
diff --git a/plugins/MobileMessaging/CountryCallingCodes.php b/plugins/MobileMessaging/CountryCallingCodes.php
index 7313b5937e..1e260c4c46 100644
--- a/plugins/MobileMessaging/CountryCallingCodes.php
+++ b/plugins/MobileMessaging/CountryCallingCodes.php
@@ -16,7 +16,6 @@
*/
class Piwik_MobileMessaging_CountryCallingCodes
{
- // @review is this the correct way to store calling codes or should we use GLOBALS like in core/DataFiles/Countries.php?
// list taken from core/DataFiles/Countries.php
public static $countryCallingCodes = array(
'ad' => '376',
diff --git a/plugins/MobileMessaging/GSMCharset.php b/plugins/MobileMessaging/GSMCharset.php
new file mode 100644
index 0000000000..cbd2980676
--- /dev/null
+++ b/plugins/MobileMessaging/GSMCharset.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ * @version $Id$
+ *
+ * @category Piwik_Plugins
+ * @package Piwik_MobileMessaging
+ */
+
+/**
+ * GSM 03.38 Charset
+ *
+ * @package Piwik_MobileMessaging
+ */
+class Piwik_MobileMessaging_GSMCharset
+{
+ public static $GSMCharset = array(
+
+ // Standard GSM Characters, weight = 1
+ '@' => 1,
+ '£' => 1,
+ '$' => 1,
+ '¥' => 1,
+ 'è' => 1,
+ 'é' => 1,
+ 'ù' => 1,
+ 'ì' => 1,
+ 'ò' => 1,
+ 'Ç' => 1,
+ 'Ø' => 1,
+ 'ø' => 1,
+ 'Å' => 1,
+ 'å' => 1,
+ '∆' => 1,
+ '_' => 1,
+ 'Φ' => 1,
+ 'Γ' => 1,
+ 'Λ' => 1,
+ 'Ω' => 1,
+ 'Π' => 1,
+ 'Ψ' => 1,
+ 'Σ' => 1,
+ 'Θ' => 1,
+ 'Ξ' => 1,
+ 'Æ' => 1,
+ 'æ' => 1,
+ 'ß' => 1,
+ 'É' => 1,
+ ' ' => 1,
+ '!' => 1,
+ '"' => 1,
+ '#' => 1,
+ '¤' => 1,
+ '%' => 1,
+ '&' => 1,
+ '\'' => 1,
+ '(' => 1,
+ ')' => 1,
+ '*' => 1,
+ '+' => 1,
+ ',' => 1,
+ '-' => 1,
+ '.' => 1,
+ '/' => 1,
+ '0' => 1,
+ '1' => 1,
+ '2' => 1,
+ '3' => 1,
+ '4' => 1,
+ '5' => 1,
+ '6' => 1,
+ '7' => 1,
+ '8' => 1,
+ '9' => 1,
+ ':' => 1,
+ ';' => 1,
+ '<' => 1,
+ '=' => 1,
+ '>' => 1,
+ '?' => 1,
+ '¡' => 1,
+ 'A' => 1,
+ 'B' => 1,
+ 'C' => 1,
+ 'D' => 1,
+ 'E' => 1,
+ 'F' => 1,
+ 'G' => 1,
+ 'H' => 1,
+ 'I' => 1,
+ 'J' => 1,
+ 'K' => 1,
+ 'L' => 1,
+ 'M' => 1,
+ 'N' => 1,
+ 'O' => 1,
+ 'P' => 1,
+ 'Q' => 1,
+ 'R' => 1,
+ 'S' => 1,
+ 'T' => 1,
+ 'U' => 1,
+ 'V' => 1,
+ 'W' => 1,
+ 'X' => 1,
+ 'Y' => 1,
+ 'Z' => 1,
+ 'Ä' => 1,
+ 'Ö' => 1,
+ 'Ñ' => 1,
+ 'Ü' => 1,
+ '§' => 1,
+ '¿' => 1,
+ 'a' => 1,
+ 'b' => 1,
+ 'c' => 1,
+ 'd' => 1,
+ 'e' => 1,
+ 'f' => 1,
+ 'g' => 1,
+ 'h' => 1,
+ 'i' => 1,
+ 'j' => 1,
+ 'k' => 1,
+ 'l' => 1,
+ 'm' => 1,
+ 'n' => 1,
+ 'o' => 1,
+ 'p' => 1,
+ 'q' => 1,
+ 'r' => 1,
+ 's' => 1,
+ 't' => 1,
+ 'u' => 1,
+ 'v' => 1,
+ 'w' => 1,
+ 'x' => 1,
+ 'y' => 1,
+ 'z' => 1,
+ 'ä' => 1,
+ 'ö' => 1,
+ 'ñ' => 1,
+ 'ü' => 1,
+ 'à' => 1,
+
+ // Extended GSM Characters, weight = 2
+ '^' => 2,
+ '{' => 2,
+ '}' => 2,
+ '\\' => 2,
+ '[' => 2,
+ '~' => 2,
+ ']' => 2,
+ '|' => 2,
+ '€' => 2,
+ );
+}
diff --git a/plugins/MobileMessaging/MobileMessaging.php b/plugins/MobileMessaging/MobileMessaging.php
index e52c2cfdc4..ba79a349d8 100644
--- a/plugins/MobileMessaging/MobileMessaging.php
+++ b/plugins/MobileMessaging/MobileMessaging.php
@@ -18,9 +18,10 @@ class Piwik_MobileMessaging extends Piwik_Plugin
{
const DELEGATED_MANAGEMENT_OPTION = 'MobileMessaging_DelegatedManagement';
const PROVIDER_OPTION = 'Provider';
- const USERNAME_OPTION = 'Username';
- const PASSWORD_OPTION = 'Password';
+ const API_KEY_OPTION = 'APIKey';
const PHONE_NUMBERS_OPTION = 'PhoneNumbers';
+ const PHONE_NUMBER_VALIDATION_REQUEST_COUNT_OPTION = 'PhoneNumberValidationRequestCount';
+ const SMS_SENT_COUNT_OPTION = 'SMSSentCount';
const DELEGATED_MANAGEMENT_OPTION_DEFAULT = 'false';
const USER_SETTINGS_POSTFIX_OPTION = '_MobileMessagingSettings';
@@ -111,7 +112,6 @@ class Piwik_MobileMessaging extends Piwik_Plugin
$jsFiles = &$notification->getNotificationObject();
$jsFiles[] = "plugins/MobileMessaging/scripts/MobileMessagingSettings.js";
- $jsFiles[] = "plugins/MobileMessaging/scripts/jquery.select-to-autocomplete.js"; // @review should this go in the LEGALNOTICE file ?
}
/**
@@ -129,7 +129,7 @@ class Piwik_MobileMessaging extends Piwik_Plugin
$phoneNumbers = $parameters[self::PHONE_NUMBERS_PARAMETER];
foreach($phoneNumbers as $key => $phoneNumber)
{
- //@review when a wrong phone number is supplied we silently discard it, should an exception be raised?
+ //when a wrong phone number is supplied we silently discard it
if(!in_array($phoneNumber, $availablePhoneNumbers))
{
unset($phoneNumbers[$key]);
@@ -160,9 +160,12 @@ class Piwik_MobileMessaging extends Piwik_Plugin
$availableReport['module'],
$availableReport['action']
);
- $reportMetadata = reset($reportMetadata);
- $availableReportMetadata[] = $reportMetadata;
+ if($reportMetadata != null)
+ {
+ $reportMetadata = reset($reportMetadata);
+ $availableReportMetadata[] = $reportMetadata;
+ }
}
}
}
@@ -208,7 +211,17 @@ class Piwik_MobileMessaging extends Piwik_Plugin
if(self::manageEvent($notification))
{
$reportRenderer = &$notification->getNotificationObject();
- $reportRenderer = new Piwik_MobileMessaging_ReportRenderer_Sms();
+
+ if(Piwik_PluginsManager::getInstance()->isPluginActivated('MultiSites'))
+ {
+ $reportRenderer = new Piwik_MobileMessaging_ReportRenderer_Sms();
+ }
+ else
+ {
+ $reportRenderer = new Piwik_MobileMessaging_ReportRenderer_Exception(
+ Piwik_Translate('MobileMessaging_MultiSites_Must_Be_Activated')
+ );
+ }
}
}
@@ -245,19 +258,27 @@ class Piwik_MobileMessaging extends Piwik_Plugin
{
$notificationInfo = $notification->getNotificationInfo();
$report = $notificationInfo[Piwik_PDFReports_API::REPORT_KEY];
- $websiteName = $notificationInfo[Piwik_PDFReports_API::WEBSITE_NAME_KEY];
$contents = $notificationInfo[Piwik_PDFReports_API::REPORT_CONTENT_KEY];
$parameters = $report['parameters'];
$phoneNumbers = $parameters[self::PHONE_NUMBERS_PARAMETER];
+ if(in_array('MultiSites_getAll', $report['reports']))
+ {
+ $from = Piwik_Translate('General_Reports');
+ }
+ else
+ {
+ $from = $notificationInfo[Piwik_PDFReports_API::WEBSITE_NAME_KEY];
+ }
+
$mobileMessagingAPI = Piwik_MobileMessaging_API::getInstance();
foreach($phoneNumbers as $phoneNumber)
{
$mobileMessagingAPI->sendSMS(
$contents,
$phoneNumber,
- $websiteName
+ $from
);
}
}
@@ -291,7 +312,6 @@ class Piwik_MobileMessaging extends Piwik_Plugin
}
}
- //@review should we also delete the plugin settings (API credentials, phone numbers) located in table piwik_option?
function deactivate()
{
// delete all mobile reports
@@ -306,4 +326,11 @@ class Piwik_MobileMessaging extends Piwik_Plugin
}
}
}
+
+ public function uninstall()
+ {
+ // currently the UI does not allow to delete a plugin
+ // when it becomes available, all the MobileMessaging settings (API credentials, phone numbers, etc..) should be removed from the option table
+ return;
+ }
}
diff --git a/plugins/MobileMessaging/ReportRenderer/Exception.php b/plugins/MobileMessaging/ReportRenderer/Exception.php
new file mode 100644
index 0000000000..7e9df15dc1
--- /dev/null
+++ b/plugins/MobileMessaging/ReportRenderer/Exception.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ * @version $Id$
+ *
+ * @category Piwik_Plugins
+ * @package Piwik_MobileMessaging_ReportRenderer
+ */
+
+/**
+ *
+ * @package Piwik_MobileMessaging_ReportRenderer
+ */
+class Piwik_MobileMessaging_ReportRenderer_Exception extends Piwik_ReportRenderer
+{
+ private $rendering = "";
+
+ function __construct($exception)
+ {
+ $this->rendering = $exception;
+ }
+
+ public function setLocale($locale)
+ {
+ // nothing to do
+ }
+
+ public function sendToDisk($filename)
+ {
+ return Piwik_ReportRenderer::writeFile(
+ $filename,
+ Piwik_MobileMessaging_ReportRenderer_Sms::SMS_FILE_EXTENSION,
+ $this->rendering
+ );
+ }
+
+ public function sendToBrowserDownload($filename)
+ {
+ Piwik_ReportRenderer::sendToBrowser(
+ $filename,
+ Piwik_MobileMessaging_ReportRenderer_Sms::SMS_FILE_EXTENSION,
+ Piwik_MobileMessaging_ReportRenderer_Sms::SMS_CONTENT_TYPE,
+ $this->rendering
+ );
+ }
+
+ public function sendToBrowserInline($filename)
+ {
+ Piwik_ReportRenderer::inlineToBrowser(
+ Piwik_MobileMessaging_ReportRenderer_Sms::SMS_CONTENT_TYPE,
+ $this->rendering
+ );
+ }
+
+ public function renderFrontPage($websiteName, $prettyDate, $description, $reportMetadata)
+ {
+ // nothing to do
+ }
+
+ public function renderReport($processedReport)
+ {
+ // nothing to do
+ }
+}
diff --git a/plugins/MobileMessaging/ReportRenderer/Sms.php b/plugins/MobileMessaging/ReportRenderer/Sms.php
index 5f3662fc59..88f64aa81a 100644
--- a/plugins/MobileMessaging/ReportRenderer/Sms.php
+++ b/plugins/MobileMessaging/ReportRenderer/Sms.php
@@ -18,6 +18,9 @@ const FLOAT_REGEXP = '/[-+]?[0-9]*[\.,]?[0-9]+/';
*/
class Piwik_MobileMessaging_ReportRenderer_Sms extends Piwik_ReportRenderer
{
+ const SMS_CONTENT_TYPE = 'text/plain';
+ const SMS_FILE_EXTENSION = 'sms';
+
private $rendering = "";
public function setLocale($locale)
@@ -27,12 +30,17 @@ class Piwik_MobileMessaging_ReportRenderer_Sms extends Piwik_ReportRenderer
public function sendToDisk($filename)
{
- return Piwik_ReportRenderer::writeFile($filename, 'sms', $this->rendering);
+ return Piwik_ReportRenderer::writeFile($filename, self::SMS_FILE_EXTENSION, $this->rendering);
}
public function sendToBrowserDownload($filename)
{
- Piwik_ReportRenderer::sendToBrowser($filename, 'sms', 'text/plain', $this->rendering);
+ Piwik_ReportRenderer::sendToBrowser($filename, self::SMS_FILE_EXTENSION, self::SMS_CONTENT_TYPE, $this->rendering);
+ }
+
+ public function sendToBrowserInline($filename)
+ {
+ Piwik_ReportRenderer::inlineToBrowser(self::SMS_CONTENT_TYPE, $this->rendering);
}
public function renderFrontPage($websiteName, $prettyDate, $description, $reportMetadata)
diff --git a/plugins/MobileMessaging/SMSProvider.php b/plugins/MobileMessaging/SMSProvider.php
index 1e205de0de..26faf10403 100644
--- a/plugins/MobileMessaging/SMSProvider.php
+++ b/plugins/MobileMessaging/SMSProvider.php
@@ -18,8 +18,13 @@
*/
abstract class Piwik_MobileMessaging_SMSProvider
{
+ const MAX_GSM_CHARS_IN_ONE_UNIQUE_SMS = 160;
+ const MAX_GSM_CHARS_IN_ONE_CONCATENATED_SMS = 153;
+ const MAX_UCS2_CHARS_IN_ONE_UNIQUE_SMS = 70;
+ const MAX_UCS2_CHARS_IN_ONE_CONCATENATED_SMS = 67;
+
static public $availableSMSProviders = array(
- 'Mediaburst',
+ 'Clockwork' => 'MobileMessaging_SMSProvider_Description_Clockwork',
);
/**
@@ -41,38 +46,121 @@ abstract class Piwik_MobileMessaging_SMSProvider
throw new Exception(
Piwik_TranslateException(
'MobileMessaging_Exception_UnknownProvider',
- array($name, implode(', ', self::$availableSMSProviders))
+ array($name, implode(', ', array_keys(self::$availableSMSProviders)))
)
);
}
}
/**
+ * Assert whether a given String contains UCS2 characters
+ *
+ * @param string $string
+ * @return bool true if $string contains UCS2 characters
+ */
+ static public function containsUCS2Characters($string)
+ {
+ $GSMCharsetAsString = implode(array_keys(Piwik_MobileMessaging_GSMCharset::$GSMCharset));
+
+ foreach(self::mb_str_split($string) as $char)
+ {
+ if(mb_strpos($GSMCharsetAsString, $char) === false) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Truncate $string and append $appendedString at the end if $string can not fit the
+ * the $maximumNumberOfConcatenatedSMS.
+ *
+ * @param string $string String to truncate
+ * @param int $maximumNumberOfConcatenatedSMS
+ * @param string $appendedString
+ * @return string original $string or truncated $string appended with $appendedString
+ */
+ static public function truncate($string, $maximumNumberOfConcatenatedSMS, $appendedString = 'MobileMessaging_SMS_Content_Too_Long')
+ {
+ $appendedString = Piwik_Translate($appendedString);
+
+ $smsContentContainsUCS2Chars = self::containsUCS2Characters($string);
+ $maxCharsAllowed = self::maxCharsAllowed($maximumNumberOfConcatenatedSMS, $smsContentContainsUCS2Chars);
+ $sizeOfSMSContent = self::sizeOfSMSContent($string, $smsContentContainsUCS2Chars);
+
+ if($sizeOfSMSContent <= $maxCharsAllowed) return $string;
+
+ $smsContentContainsUCS2Chars = $smsContentContainsUCS2Chars || self::containsUCS2Characters($appendedString);
+ $maxCharsAllowed = self::maxCharsAllowed($maximumNumberOfConcatenatedSMS, $smsContentContainsUCS2Chars);
+ $sizeOfSMSContent = self::sizeOfSMSContent($string . $appendedString, $smsContentContainsUCS2Chars);
+
+ $sizeToTruncate = $sizeOfSMSContent - $maxCharsAllowed;
+
+ $subStrToTruncate = '';
+ $subStrSize = 0;
+ $reversedStringChars = array_reverse(self::mb_str_split($string));
+ for($i = 0; $subStrSize < $sizeToTruncate; $i++)
+ {
+ $subStrToTruncate = $reversedStringChars[$i] . $subStrToTruncate;
+ $subStrSize = self::sizeOfSMSContent($subStrToTruncate, $smsContentContainsUCS2Chars);
+ }
+
+ return preg_replace('/' . preg_quote($subStrToTruncate) . '$/', $appendedString, $string);
+ }
+
+ static private function mb_str_split($string)
+ {
+ return preg_split('//u',$string, -1, PREG_SPLIT_NO_EMPTY);
+ }
+
+ static private function sizeOfSMSContent($smsContent, $containsUCS2Chars)
+ {
+ if($containsUCS2Chars) return mb_strlen($smsContent, 'UTF-8');
+
+ $sizeOfSMSContent = 0;
+ foreach(self::mb_str_split($smsContent) as $char)
+ {
+ $sizeOfSMSContent += Piwik_MobileMessaging_GSMCharset::$GSMCharset[$char];
+ }
+ return $sizeOfSMSContent;
+ }
+
+ static private function maxCharsAllowed($maximumNumberOfConcatenatedSMS, $containsUCS2Chars)
+ {
+ $maxCharsInOneUniqueSMS = $containsUCS2Chars ? self::MAX_UCS2_CHARS_IN_ONE_UNIQUE_SMS : self::MAX_GSM_CHARS_IN_ONE_UNIQUE_SMS;
+ $maxCharsInOneConcatenatedSMS = $containsUCS2Chars ? self::MAX_UCS2_CHARS_IN_ONE_CONCATENATED_SMS : self::MAX_GSM_CHARS_IN_ONE_CONCATENATED_SMS;
+
+ $uniqueSMS = $maximumNumberOfConcatenatedSMS == 1;
+
+ return $uniqueSMS ?
+ $maxCharsInOneUniqueSMS :
+ $maxCharsInOneConcatenatedSMS * $maximumNumberOfConcatenatedSMS;
+ }
+
+ /**
* verify the SMS API credential
*
- * @param string $username SMS API username
- * @param string $password SMS API password
+ * @param string $apiKey API Key
* @return bool true if SMS API credential are valid, false otherwise
*/
- abstract public function verifyCredential($username, $password);
+ abstract public function verifyCredential($apiKey);
/**
* get remaining credits
*
- * @param string $username SMS API username
- * @param string $password SMS API password
+ * @param string $apiKey API Key
* @return string remaining credits
*/
- abstract public function getCreditLeft($username, $password);
+ abstract public function getCreditLeft($apiKey);
/**
* send SMS
*
- * @param string $username
- * @param string $password
+ * @param string $apiKey
* @param string $smsText
* @param string $phoneNumber
* @return bool true
*/
- abstract public function sendSMS($username, $password, $smsText, $phoneNumber, $from);
+ abstract public function sendSMS($apiKey, $smsText, $phoneNumber, $from);
}
diff --git a/plugins/MobileMessaging/SMSProvider/Mediaburst.php b/plugins/MobileMessaging/SMSProvider/Clockwork.php
index 71cf280cf2..91a5ac0a56 100644
--- a/plugins/MobileMessaging/SMSProvider/Mediaburst.php
+++ b/plugins/MobileMessaging/SMSProvider/Clockwork.php
@@ -4,7 +4,7 @@
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- * @version $Id$$
+ * @version $Id$
*
* @category Piwik_Plugins
* @package Piwik_MobileMessaging_SMSProvider
@@ -15,7 +15,7 @@ require_once PIWIK_INCLUDE_PATH . "/plugins/MobileMessaging/APIException.php";
*
* @package Piwik_MobileMessaging_SMSProvider
*/
-class Piwik_MobileMessaging_SMSProvider_Mediaburst extends Piwik_MobileMessaging_SMSProvider
+class Piwik_MobileMessaging_SMSProvider_Clockwork extends Piwik_MobileMessaging_SMSProvider
{
const SOCKET_TIMEOUT = 15;
@@ -26,42 +26,40 @@ class Piwik_MobileMessaging_SMSProvider_Mediaburst extends Piwik_MobileMessaging
const ERROR_STRING = 'Error';
const MAXIMUM_FROM_LENGTH = 11;
- const MAXIMUM_CONTENT_LENGTH = 459;
+ const MAXIMUM_CONCATENATED_SMS = 3;
- public function verifyCredential($username, $password)
+ public function verifyCredential($apiKey)
{
- $this->getCreditLeft($username, $password);
+ $this->getCreditLeft($apiKey);
return true;
}
- public function sendSMS($username, $password, $smsText, $phoneNumber, $from)
+ public function sendSMS($apiKey, $smsText, $phoneNumber, $from)
{
$from = substr($from, 0, self::MAXIMUM_FROM_LENGTH);
- //@review the length of the SMS text is limited by Mediaburst. Here, we truncate the SMS content because MultiSites.getAll can return a lot of sites. Is this the proper way to handle this case?
- $smsText = substr($smsText, 0, self::MAXIMUM_CONTENT_LENGTH);
+ $smsText = self::truncate($smsText, self::MAXIMUM_CONCATENATED_SMS);
$additionalParameters = array(
'To' => str_replace('+','', $phoneNumber),
'Content' => $smsText,
'From' => $from,
'Long' => 1,
+ 'MsgType' => self::containsUCS2Characters($smsText) ? 'UCS2' : 'TEXT',
);
$this->issueApiCall(
- $username,
- $password,
+ $apiKey,
self::SEND_SMS_RESOURCE,
$additionalParameters
);
}
- private function issueApiCall($username, $password, $resource, $additionalParameters = array())
+ private function issueApiCall($apiKey, $resource, $additionalParameters = array())
{
$accountParameters = array(
- 'Username' => $username,
- 'Password' => $password,
+ 'Key' => $apiKey,
);
$parameters = array_merge($accountParameters, $additionalParameters);
@@ -87,18 +85,17 @@ class Piwik_MobileMessaging_SMSProvider_Mediaburst extends Piwik_MobileMessaging
if(strpos($result, self::ERROR_STRING) !== false)
{
throw new Piwik_MobileMessaging_APIException(
- 'Mediaburst API returned the following error message : ' . $result
+ 'Clockwork API returned the following error message : ' . $result
);
}
return $result;
}
- public function getCreditLeft($username, $password)
+ public function getCreditLeft($apiKey)
{
return $this->issueApiCall(
- $username,
- $password,
+ $apiKey,
self::CHECK_CREDIT_RESOURCE
);
}
diff --git a/plugins/MobileMessaging/lang/en.php b/plugins/MobileMessaging/lang/en.php
index 5f14e7760f..d5ad9543fc 100644
--- a/plugins/MobileMessaging/lang/en.php
+++ b/plugins/MobileMessaging/lang/en.php
@@ -15,24 +15,38 @@ $translations = array(
'MobileMessaging_PluginDescription' => 'Create and download custom SMS reports and have them sent to your mobile daily, weekly or monthly.',
'MobileMessaging_TopMenu' => 'Email & SMS Reports',
'MobileMessaging_SettingsMenu' => 'Mobile Messaging',
- 'MobileMessaging_VerificationText' => 'Code is %s. To validate your phone number and receive Piwik SMS reports please copy this code in the form accessible via Piwik > Settings > SMS.',
+ 'MobileMessaging_Settings_SuperAdmin' => 'Super Admin Settings',
+ 'MobileMessaging_VerificationText' => 'Code is %s. To validate your phone number and receive Piwik SMS reports please copy this code in the form accessible via Piwik > %s > %s.',
'MobileMessaging_Settings_LetUsersManageAPICredential' => 'Allow users to manage their own SMS API credential',
+ 'MobileMessaging_Settings_LetUsersManageAPICredential_No_Help' => 'All users are able to receive SMS Reports and will use your account\'s credits.',
'MobileMessaging_Settings_SMSProvider' => 'SMS Provider',
- 'MobileMessaging_Settings_SMSAPIAccount' => 'SMS API Account',
+ 'MobileMessaging_Settings_SMSAPIAccount' => 'Manage SMS API Account',
'MobileMessaging_Settings_PhoneNumbers' => 'Phone Numbers',
- 'MobileMessaging_Settings_UpdateAccount' => 'Update Account',
- 'MobileMessaging_Settings_DeleteAccount' => 'Delete Account',
- 'MobileMessaging_Settings_Username' => 'Username',
- 'MobileMessaging_Settings_Password' => 'Password',
+ 'MobileMessaging_Settings_PhoneNumbers_Help' => 'Before receiving SMS (text messages) reports on a phone, the phone number must be entered below. <br/> When you click "Add", a SMS containing a code will be sent to the phone. The user will then be able to validate the phone number if he has access to Piwik.',
+ 'MobileMessaging_Settings_PhoneNumbers_CountryCode_Help' => 'If you do not know the phone country code, look for your country here',
+ 'MobileMessaging_Settings_PhoneNumbers_Add' => 'Add a new Phone Number',
+ 'MobileMessaging_Settings_VerificationCodeJustSent' => 'We just sent a SMS to this number with a code: please enter this code above and click "Validate".',
+ 'MobileMessaging_Settings_PhoneActivated' => 'Phone number validated! You can now receive SMS with your stats.',
+ 'MobileMessaging_Settings_InvalidActivationCode' => 'Code entered was not valid, please try again.',
+ 'MobileMessaging_Settings_CountryCode' => 'Country Code',
+ 'MobileMessaging_Settings_PhoneNumber' => 'Phone Number',
+ 'MobileMessaging_Settings_ManagePhoneNumbers' => 'Manage Phone Numbers',
+ 'MobileMessaging_Settings_PleaseSignUp' => 'To create SMS reports and receive short text messages with your websites\' stats on your mobile phone, please sign up with the SMS API and enter your information below.',
+ 'MobileMessaging_Settings_APIKey' => 'API Key',
'MobileMessaging_Settings_AddPhoneNumber' => 'Add',
'MobileMessaging_Settings_ValidatePhoneNumber' => 'Validate',
'MobileMessaging_Settings_RemovePhoneNumber' => 'Remove',
'MobileMessaging_Settings_SuspiciousPhoneNumber' => 'If you don\'t receive the text message, you may try without the leading zero. ie. "53948298"',
- 'MobileMessaging_Settings_CredentialNotProvidedByAdmin' => 'You can not configure phone numbers. The SMS API account has not been correctly configured. Please contact your administrator.',
- 'MobileMessaging_Settings_CredentialNotProvided' => 'You can not configure phone numbers. The API username and password have not been correctly configured.',
- 'MobileMessaging_Settings_CredentialProvided' => 'The %s SMS API account associated with username %s is correctly configured.',
+ 'MobileMessaging_Settings_CredentialNotProvidedByAdmin' => 'Before you can create and manage phone numbers, please ask your administrator to connect Piwik to a SMS Account.',
+ 'MobileMessaging_Settings_CredentialNotProvided' => 'Before you can create and manage phone numbers, please connect Piwik to your SMS Account above.',
+ 'MobileMessaging_Settings_CredentialProvided' => 'Your %s SMS API account is correctly configured!',
+ 'MobileMessaging_Settings_UpdateOrDeleteAccount' => 'You can also %supdate%s or %sdelete%s this account.',
+ 'MobileMessaging_Settings_DeleteAccountConfirm' => 'Are you sure you want to delete the SMS account?',
'MobileMessaging_MobileReport_PhoneNumbers' => 'Phone Numbers',
'MobileMessaging_MobileReport_NoPhoneNumbers' => 'Please activate at least one phone number by accessing',
'MobileMessaging_MobileReport_MobileMessagingSettingsLink' => 'the Mobile Messaging settings page',
'MobileMessaging_MobileReport_AdditionalPhoneNumbers' => 'You can add more phone numbers by accessing',
+ 'MobileMessaging_SMS_Content_Too_Long' => '[too long]',
+ 'MobileMessaging_MultiSites_Must_Be_Activated' => 'To generate SMS texts of your website stats, please enable the plugin MultiSites in Piwik.',
+ 'MobileMessaging_SMSProvider_Description_Clockwork' => 'You can use Clockwork.com to send SMS Reports from Piwik.<br/> * First, get an API Key form <a href="http://clockworksms.com/platforms/piwik/">Clockwork</a> (Signup is free with some test messages) <br/> * Put your Clockwork API Key in Piwik. <br/> About Clockwork <br/> * Clockwork gives you fast, reliable high quality worldwide SMS delivery, over 450 networks in every corner of the globe. <br/> * Cost per SMS message is circa ~0.08USD (0.06EUR). </br> * Most countries and networks are supported but we suggest you check the latest position on their coverage map here <a href="www.clockworksms.com/sms-coverage/">www.clockworksms.com/sms-coverage/</a>',
);
diff --git a/plugins/MobileMessaging/scripts/MobileMessagingSettings.js b/plugins/MobileMessaging/scripts/MobileMessagingSettings.js
index d4fc7f639f..55c5a24966 100644
--- a/plugins/MobileMessaging/scripts/MobileMessagingSettings.js
+++ b/plugins/MobileMessaging/scripts/MobileMessagingSettings.js
@@ -16,19 +16,26 @@ var MobileMessagingSettings = MobileMessagingSettings || (function () {
apiAccountSubmitSelector = '#apiAccountSubmit',
addPhoneNumberSubmitSelector = '#addPhoneNumberSubmit',
providersSelector = '#smsProviders',
- usernameSelector = '#username',
- passwordSelector = '#password',
+ providerDescriptionsSelector = '.providerDescription',
+ apiKeySelector = '#apiKey',
countriesSelector = '#countries',
- countryCallingCodeAttribute = 'calling-code',
countryCallingCodeSelector = '#countryCallingCode',
newPhoneNumberSelector = '#newPhoneNumber',
suspiciousPhoneNumberSelector = '#suspiciousPhoneNumber',
validatePhoneNumberSubmitSelector = '.validatePhoneNumberSubmit',
+ formDescriptionSelector = '.form-description',
removePhoneNumberSubmitSelector = '.removePhoneNumberSubmit',
verificationCodeSelector = '.verificationCode',
phoneNumberSelector = '.phoneNumber',
deleteAcountSelector = '#deleteAccount',
+ confirmDeleteAccountSelector = '#confirmDeleteAccount',
+ accountFormSelector = '#accountForm',
+ displayAccountFormSelector = '#displayAccountForm',
+ autoCompleteInputSelector = 'input.ui-autocomplete-input',
+ phoneNumberActivatedSelector = '#phoneNumberActivated',
+ invalidActivationCodeMsgSelector = '#invalidActivationCode',
ajaxErrorsSelector = 'ajaxErrorMobileMessagingSettings',
+ invalidVerificationCodeAjaxErrorSelector = 'invalidVerificationCodeAjaxError',
ajaxLoadingSelector = 'ajaxLoadingMobileMessagingSettings';
/************************************************************
@@ -39,30 +46,70 @@ var MobileMessagingSettings = MobileMessagingSettings || (function () {
$(delegatedManagementSelector).change(updateDelegatedManagement);
$(apiAccountSubmitSelector).click(updateApiAccount);
- $(deleteAcountSelector).click(deleteApiAccount);
+ $(deleteAcountSelector).click(confirmDeleteApiAccount);
+ $(displayAccountFormSelector).click(displayAccountForm);
$(addPhoneNumberSubmitSelector).click(addPhoneNumber);
$(newPhoneNumberSelector).keyup(updateSuspiciousPhoneNumberMessage);
$(validatePhoneNumberSubmitSelector).click(validatePhoneNumber);
$(removePhoneNumberSubmitSelector).click(removePhoneNumber);
-
- var defaultCountry = getSelectedCountry();
- $(countriesSelector).selectToAutocomplete();
- // previous function seems to reset the pre-selected option
- defaultCountry.attr('selected', 'selected');
-
+ $(countryCallingCodeSelector).keyup(updateCountry);
$(countriesSelector).change(updateCountryCallingCode);
updateCountryCallingCode();
+ $(providersSelector).change(updateProviderDescription);
+ updateProviderDescription();
+ }
+
+ function updateCountry()
+ {
+ var countryCallingCode = $(countryCallingCodeSelector).val();
+ if(countryCallingCode != null && countryCallingCode != '')
+ {
+ var countryToSelect = $(countriesSelector + ' option[value='+countryCallingCode+']');
+ if(countryToSelect.size() > 0)
+ {
+ countryToSelect.attr('selected', 'selected');
+ }
+ else
+ {
+ $(countriesSelector + ' option:selected').removeAttr('selected');
+ }
+ }
+ }
+
+ function displayAccountForm()
+ {
+ $(accountFormSelector).show();
}
function validatePhoneNumber(event)
{
var phoneNumberContainer = $(event.target).parent();
- var verificationCode = phoneNumberContainer.find(verificationCodeSelector).val();
+ var verificationCodeContainer = phoneNumberContainer.find(verificationCodeSelector);
+ var verificationCode = verificationCodeContainer.val();
var phoneNumber = phoneNumberContainer.find(phoneNumberSelector).html();
if(verificationCode != null && verificationCode != '')
{
- var ajaxRequest = piwikHelper.getStandardAjaxConf(ajaxLoadingSelector, ajaxErrorsSelector);
+ var ajaxRequest = piwikHelper.getStandardAjaxConf(ajaxLoadingSelector, invalidVerificationCodeAjaxErrorSelector);
+
+ ajaxRequest.success =
+ function(response)
+ {
+ piwikHelper.hideAjaxLoading(ajaxLoadingSelector);
+ $(phoneNumberActivatedSelector).hide();
+ if(!response.value)
+ {
+ piwikHelper.showAjaxError($(invalidActivationCodeMsgSelector).html(), invalidVerificationCodeAjaxErrorSelector);
+ }
+ else
+ {
+ piwikHelper.hideAjaxError(invalidVerificationCodeAjaxErrorSelector);
+ $(phoneNumberActivatedSelector).show();
+ $(verificationCodeContainer).remove();
+ $(phoneNumberContainer).find(validatePhoneNumberSubmitSelector).remove();
+ $(phoneNumberContainer).find(formDescriptionSelector).remove();
+ }
+ };
var parameters = {};
ajaxRequest.data = parameters;
@@ -119,7 +166,7 @@ var MobileMessagingSettings = MobileMessagingSettings || (function () {
var phoneNumber = '+' + countryCallingCode + newPhoneNumber;
- if(phoneNumber != null && phoneNumber != '')
+ if(newPhoneNumber != null && newPhoneNumber != '')
{
var ajaxRequest = piwikHelper.getStandardAjaxConf(ajaxLoadingSelector, ajaxErrorsSelector);
@@ -136,21 +183,25 @@ var MobileMessagingSettings = MobileMessagingSettings || (function () {
}
}
- function getSelectedCountry()
+ function updateCountryCallingCode()
{
- return $(countriesSelector + ' option:selected');
+ $(countryCallingCodeSelector).val($(countriesSelector + ' option:selected').val());
}
- function updateCountryCallingCode()
+ function updateProviderDescription()
{
- $(countryCallingCodeSelector).val(
- getSelectedCountry().attr(countryCallingCodeAttribute)
- );
+ $(providerDescriptionsSelector).hide();
+ $('#' + $(providersSelector + ' option:selected').val() + providerDescriptionsSelector).show();
}
function updateDelegatedManagement() {
setDelegatedManagement(getDelegatedManagement());
}
+
+ function confirmDeleteApiAccount()
+ {
+ piwikHelper.modalConfirm(confirmDeleteAccountSelector, {yes: deleteApiAccount});
+ }
function deleteApiAccount() {
@@ -170,10 +221,9 @@ var MobileMessagingSettings = MobileMessagingSettings || (function () {
function updateApiAccount() {
var provider = $(providersSelector + ' option:selected').val();
- var username = $(usernameSelector).val();
- var password = $(passwordSelector).val();
+ var apiKey = $(apiKeySelector).val();
- if(username != '' && password != '') {
+ if(apiKey != '') {
var ajaxRequest = piwikHelper.getStandardAjaxConf(ajaxLoadingSelector, ajaxErrorsSelector);
@@ -182,10 +232,9 @@ var MobileMessagingSettings = MobileMessagingSettings || (function () {
parameters.module = 'API';
parameters.format = 'json';
- parameters.method = 'MobileMessaging.setSMSAPICredential';
- parameters.provider = provider;
- parameters.username = username;
- parameters.password = password;
+ parameters.method = 'MobileMessaging.setSMSAPICredential';
+ parameters.provider = provider;
+ parameters.apiKey = apiKey;
parameters.token_auth = piwik.token_auth;
$.ajax(ajaxRequest);
diff --git a/plugins/MobileMessaging/scripts/jquery.select-to-autocomplete.js b/plugins/MobileMessaging/scripts/jquery.select-to-autocomplete.js
deleted file mode 100644
index 600e88eb87..0000000000
--- a/plugins/MobileMessaging/scripts/jquery.select-to-autocomplete.js
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
-Version: 1.0.5
-
-Documentation: http://baymard.com/labs/country-selector#documentation
-
-Copyright (C) 2011 by Jamie Appleseed, Baymard Institute (baymard.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-(function($){
- var settings = {
- 'sort': false,
- 'sort-attr': 'data-priority',
- 'sort-desc': false,
- 'autoselect': true,
- 'alternative-spellings': true,
- 'alternative-spellings-attr': 'data-alternative-spellings',
- 'remove-valueless-options': true,
- 'copy-attributes-to-text-field': true,
- 'autocomplete-plugin': 'jquery_ui',
- 'relevancy-sorting': true,
- 'relevancy-sorting-partial-match-value': 1,
- 'relevancy-sorting-strict-match-value': 5,
- 'relevancy-sorting-booster-attr': 'data-relevancy-booster',
- handle_invalid_input: function( context ) {
- context.$text_field.val( context.$select_field.find('option:selected:first').text() );
- },
- handle_select_field: function( $select_field ) {
- return $select_field.hide();
- },
- insert_text_field: function( context ) {
- var $text_field = $( "<input></input>" );
- if ( settings['copy-attributes-to-text-field'] ) {
- var attrs = {};
- var raw_attrs = context.$select_field[0].attributes;
- for (var i=0; i < raw_attrs.length; i++) {
- var key = raw_attrs[i].nodeName;
- var value = raw_attrs[i].nodeValue;
- if ( key !== 'name' && key !== 'id' ) {
- attrs[key] = raw_attrs[i].nodeValue;
- }
- };
- $text_field.attr( attrs );
- }
- $text_field.blur(function() {
- var valid_values = context.$select_field.find('option').map(function(i, option) { return $(option).text(); });
- if ( !($text_field.val() in valid_values) && typeof settings['handle_invalid_input'] === 'function' ) {
- settings['handle_invalid_input'](context);
- }
- });
- // give the input box the ability to select all text on mouse click
- if ( context.settings['autoselect'] ) {
- $text_field.click( function() {
- this.select();
- });
- }
- return $text_field.val( context.$select_field.find('option:selected:first').text() )
- .insertAfter( context.$select_field );
- },
- extract_options: function( $select_field ) {
- var options = [];
- var $options = $select_field.find('option');
- var number_of_options = $options.length;
-
- // go over each option in the select tag
- $options.each(function(){
- var $option = $(this);
- var option = {
- 'real-value': $option.attr('value'),
- 'label': $option.text()
- }
- if ( settings['remove-valueless-options'] && option['real-value'] === '') {
- // skip options without a value
- } else {
- // prepare the 'matches' string which must be filtered on later
- option['matches'] = option['label'];
- var alternative_spellings = $option.attr( settings['alternative-spellings-attr'] );
- if ( alternative_spellings ) {
- option['matches'] += ' ' + alternative_spellings;
- }
- // give each option a weight paramter for sorting
- if ( settings['sort'] ) {
- var weight = parseInt( $option.attr( settings['sort-attr'] ), 10 );
- if ( weight ) {
- option['weight'] = weight;
- } else {
- option['weight'] = number_of_options;
- }
- }
- // add relevancy score
- if ( settings['relevancy-sorting'] ) {
- option['relevancy-score'] = 0;
- option['relevancy-score-booster'] = 1;
- var boost_by = parseFloat( $option.attr( settings['relevancy-sorting-booster-attr'] ) );
- if ( boost_by ) {
- option['relevancy-score-booster'] = boost_by;
- }
- }
- // add option to combined array
- options.push( option );
- }
- });
- // sort the options based on weight
- if ( settings['sort'] ) {
- if ( settings['sort-desc'] ) {
- options.sort( function( a, b ) { return b['weight'] - a['weight']; } );
- } else {
- options.sort( function( a, b ) { return a['weight'] - b['weight']; } );
- }
- }
-
- // return the set of options, each with the following attributes: real-value, label, matches, weight (optional)
- return options;
- }
- };
-
- var public_methods = {
- init: function( customizations ) {
-
- if ( $.browser.msie && parseInt($.browser.version, 10) <= 7) {
-
- return this;
-
- } else {
-
- settings = $.extend( settings, customizations );
-
- return this.each(function(){
- var $select_field = $(this);
-
- var context = {
- '$select_field': $select_field,
- 'options': settings['extract_options']( $select_field ),
- 'settings': settings
- };
-
- context['$text_field'] = settings['insert_text_field']( context );
-
- settings['handle_select_field']( $select_field );
-
- if ( typeof settings['autocomplete-plugin'] === 'string' ) {
- adapters[settings['autocomplete-plugin']]( context );
- } else {
- settings['autocomplete-plugin']( context );
- }
- });
-
- }
-
- }
- };
-
- var adapters = {
- jquery_ui: function( context ) {
- // loose matching of search terms
- var filter_options = function( term ) {
- var split_term = term.split(' ');
- var matchers = [];
- for (var i=0; i < split_term.length; i++) {
- if ( split_term[i].length > 0 ) {
- var matcher = {};
- matcher['partial'] = new RegExp( $.ui.autocomplete.escapeRegex( split_term[i] ), "i" );
- if ( context.settings['relevancy-sorting'] ) {
- matcher['strict'] = new RegExp( "^" + $.ui.autocomplete.escapeRegex( split_term[i] ), "i" );
- }
- matchers.push( matcher );
- }
- };
-
- return $.grep( context.options, function( option ) {
- var partial_matches = 0;
- if ( context.settings['relevancy-sorting'] ) {
- var strict_match = false;
- var split_option_matches = option.matches.split(' ');
- }
- for ( var i=0; i < matchers.length; i++ ) {
- if ( matchers[i]['partial'].test( option.matches ) ) {
- partial_matches++;
- }
- if ( context.settings['relevancy-sorting'] ) {
- for (var q=0; q < split_option_matches.length; q++) {
- if ( matchers[i]['strict'].test( split_option_matches[q] ) ) {
- strict_match = true;
- break;
- }
- };
- }
- };
- if ( context.settings['relevancy-sorting'] ) {
- var option_score = 0;
- option_score += partial_matches * context.settings['relevancy-sorting-partial-match-value'];
- if ( strict_match ) {
- option_score += context.settings['relevancy-sorting-strict-match-value'];
- }
- option_score = option_score * option['relevancy-score-booster'];
- option['relevancy-score'] = option_score;
- }
- return (!term || matchers.length === partial_matches );
- });
- }
- // update the select field value using either selected option or current input in the text field
- var update_select_value = function( option ) {
- if ( option ) {
- if ( context.$select_field.val() !== option['real-value'] ) {
- context.$select_field.val( option['real-value'] );
- context.$select_field.change();
- }
- } else {
- var option_name = context.$text_field.val().toLowerCase();
- var matching_option = { 'real-value': false };
- for (var i=0; i < context.options.length; i++) {
- if ( option_name === context.options[i]['label'].toLowerCase() ) {
- matching_option = context.options[i];
- break;
- }
- };
- if ( context.$select_field.val() !== matching_option['real-value'] ) {
- context.$select_field.val( matching_option['real-value'] || '' );
- context.$select_field.change();
- }
- if ( matching_option['real-value'] ) {
- context.$text_field.val( matching_option['label'] );
- }
- if ( typeof context.settings['handle_invalid_input'] === 'function' && context.$select_field.val() === '' ) {
- context.settings['handle_invalid_input']( context );
- }
- }
- }
- // jQuery UI autocomplete settings & behavior
- context.$text_field.autocomplete({
- 'minLength': 0,
- 'delay': 0,
- 'autoFocus': true,
- source: function( request, response ) {
- var filtered_options = filter_options( request.term );
- if ( context.settings['relevancy-sorting'] ) {
- filtered_options = filtered_options.sort( function( a, b ) { return b['relevancy-score'] - a['relevancy-score']; } );
- }
- response( filtered_options );
- },
- select: function( event, ui ) {
- update_select_value( ui.item );
- },
- change: function( event, ui ) {
- update_select_value( ui.item );
- }
- });
- // force refresh value of select field when form is submitted
- context.$text_field.parents('form:first').submit(function(){
- update_select_value();
- });
- // select current value
- update_select_value();
- }
- };
-
- $.fn.selectToAutocomplete = function( method ) {
- if ( public_methods[method] ) {
- return public_methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
- } else if ( typeof method === 'object' || ! method ) {
- return public_methods.init.apply( this, arguments );
- } else {
- $.error( 'Method ' + method + ' does not exist on jQuery.fn.selectToAutocomplete' );
- }
- };
-
-})(jQuery);
diff --git a/plugins/MobileMessaging/templates/ReportParameters.tpl b/plugins/MobileMessaging/templates/ReportParameters.tpl
index 7a6af178f0..cc2ffb1de5 100644
--- a/plugins/MobileMessaging/templates/ReportParameters.tpl
+++ b/plugins/MobileMessaging/templates/ReportParameters.tpl
@@ -56,6 +56,6 @@
{/foreach}
{'MobileMessaging_MobileReport_AdditionalPhoneNumbers'|translate}
{/if}
- <a href='{url module="MobileMessaging"}'>{'MobileMessaging_MobileReport_MobileMessagingSettingsLink'|translate}</a>
+ <a href='{url module="MobileMessaging" updated="false"}'>{'MobileMessaging_MobileReport_MobileMessagingSettingsLink'|translate}</a>
</td>
</tr>
diff --git a/plugins/MobileMessaging/templates/SMSReport.tpl b/plugins/MobileMessaging/templates/SMSReport.tpl
index eb007bbe51..80caba02c0 100644
--- a/plugins/MobileMessaging/templates/SMSReport.tpl
+++ b/plugins/MobileMessaging/templates/SMSReport.tpl
@@ -1,5 +1,10 @@
{strip}
{$prettyDate}.{literal} {/literal}
+
+ {if empty($reportRows)}
+ {'CoreHome_ThereIsNoDataForThisReport'|translate}
+ {/if}
+
{foreach name=reportRows from=$reportRows item=row key=rowId}
{assign var=rowMetrics value=$row->getColumns()}
diff --git a/plugins/MobileMessaging/templates/Settings.tpl b/plugins/MobileMessaging/templates/Settings.tpl
index 3b97e3981c..6cbdcd4ea5 100644
--- a/plugins/MobileMessaging/templates/Settings.tpl
+++ b/plugins/MobileMessaging/templates/Settings.tpl
@@ -3,54 +3,44 @@
{include file='CoreAdminHome/templates/header.tpl'}
{loadJavascriptTranslations plugins='MobileMessaging'}
-{* TODO this UI probably needs some embellishment by working out a better HTML structure (table ? list ?), specifying better locations for errors and so on *}
-
-{if $isSuperUser}
-<h2>{'MobileMessaging_Settings_LetUsersManageAPICredential'|translate}</h2>
-
-<input
- type='radio'
- value='true'
- name='delegatedManagement'{if $delegatedManagement} checked='checked'{/if} />
-{'General_Yes'|translate}
-
-<input
- type='radio'
- value='false'
- name='delegatedManagement'{if !$delegatedManagement} checked='checked'{/if} />
-{'General_No'|translate}
-
-{/if}
-
{if $accountManagedByCurrentUser}
<h2>{'MobileMessaging_Settings_SMSAPIAccount'|translate}</h2>
{if $credentialSupplied}
- {'MobileMessaging_Settings_CredentialProvided'|translate:$provider:$APIUsername}
+ {'MobileMessaging_Settings_CredentialProvided'|translate:$provider}
{$creditLeft}
- <a id='deleteAccount'>{'MobileMessaging_Settings_DeleteAccount'|translate}</a>
<br/>
+ {'MobileMessaging_Settings_UpdateOrDeleteAccount'|translate:"<a id='displayAccountForm'>":"</a>":"<a id='deleteAccount'>":"</a>"}
+ {else}
+ {'MobileMessaging_Settings_PleaseSignUp'|translate}
{/if}
- {'MobileMessaging_Settings_UpdateAccount'|translate} : <br/>
+ <div id='accountForm' {if $credentialSupplied}style='display: none;'{/if}>
+ <br/>
+ {'MobileMessaging_Settings_SMSProvider'|translate}
+ <select id='smsProviders'>
+ {foreach from=$smsProviders key=smsProvider item=description}
+ <option value='{$smsProvider}'>
+ {$smsProvider}
+ </option>
+ {/foreach}
+ </select>
- {'MobileMessaging_Settings_SMSProvider'|translate}
- <select id="smsProviders">
- {foreach from=$smsProviders item=smsProvider}
- <option value="{$smsProvider}">
- {$smsProvider}
- </option>
- {/foreach}
- </select>
+ {'MobileMessaging_Settings_APIKey'|translate}
+ <input size='25' id='apiKey'/>
- {'MobileMessaging_Settings_Username'|translate}
- <input size='25' id='username'/>
+ <input type='submit' value='{'General_Save'|translate}' id='apiAccountSubmit' class='submit' />
- {'MobileMessaging_Settings_Password'|translate}
- <input size='25' id='password' type='password' autocomplete='off'/>
+ {foreach from=$smsProviders key=smsProvider item=description}
+ <p class='providerDescription' id='{$smsProvider}'>
+ {$description|translate}
+ </p>
+ {/foreach}
- <input type='submit' value='{'General_Save'|translate}' id='apiAccountSubmit' class='submit' />
+ </div>
{/if}
+{ajaxErrorDiv id=ajaxErrorMobileMessagingSettings}
+
<h2>{'MobileMessaging_Settings_PhoneNumbers'|translate}</h2>
{if !$credentialSupplied}
{if $accountManagedByCurrentUser}
@@ -59,30 +49,53 @@
{'MobileMessaging_Settings_CredentialNotProvidedByAdmin'|translate}
{/if}
{else}
+
+ {'MobileMessaging_Settings_PhoneNumbers_Help'|translate}<br/><br/>
+ <strong>{'MobileMessaging_Settings_PhoneNumbers_Add'|translate}</strong><br/><br/>
+
<span id='suspiciousPhoneNumber' style='display:none;'>
- {'MobileMessaging_Settings_SuspiciousPhoneNumber'|translate}
- <br/>
+ {'MobileMessaging_Settings_SuspiciousPhoneNumber'|translate}<br/><br/>
</span>
+
+ +<input id='countryCallingCode' size='7' maxlength='4'/>&nbsp;
+ <input id='newPhoneNumber'/>
+ <input
+ type='submit'
+ value='{'MobileMessaging_Settings_AddPhoneNumber'|translate}'
+ id='addPhoneNumberSubmit'
+ />
+
+ <br/>
+ <span class="form-description">{'MobileMessaging_Settings_CountryCode'|translate}</span><span class="form-description">{'MobileMessaging_Settings_PhoneNumber'|translate}</span><br/><br/>
+
+ {'MobileMessaging_Settings_PhoneNumbers_CountryCode_Help'|translate}
<select id='countries'>
- <option>&nbsp;</option> {* this is a trick to avoid selecting the first country when no default could be found *}
+ <option value=''>&nbsp;</option> {* this is a trick to avoid selecting the first country when no default could be found *}
{foreach from=$countries key=countryCode item=country}
<option
- value='{$countryCode}'
- calling-code='{$country.countryCallingCode}'
+ value='{$country.countryCallingCode}'
{if $defaultCountry==$countryCode} selected='selected' {/if}
- >
- {$country.countryName}
- </option>
+ >
+ {$country.countryName}
+ </option>
{/foreach}
</select>
- +<input id='countryCallingCode'/>
- <input id='newPhoneNumber'/>
- <input
- type='submit'
- value='{'MobileMessaging_Settings_AddPhoneNumber'|translate}'
- id='addPhoneNumberSubmit'
- class='submit'
- />
+
+ {if $phoneNumbers|@count gt 0}
+ <br/>
+ <br/>
+ <strong>{'MobileMessaging_Settings_ManagePhoneNumbers'|translate}</strong><br/><br/>
+ {/if}
+
+ {ajaxErrorDiv id=invalidVerificationCodeAjaxError}
+
+ <div id='phoneNumberActivated' class="ajaxSuccess" style="display:none;">
+ {'MobileMessaging_Settings_PhoneActivated'|translate}
+ </div>
+
+ <div id='invalidActivationCode' style="display:none;">
+ {'MobileMessaging_Settings_InvalidActivationCode'|translate}
+ </div>
<ul>
{foreach from=$phoneNumbers key=phoneNumber item=validated}
@@ -93,20 +106,64 @@
<input
type='submit'
value='{'MobileMessaging_Settings_ValidatePhoneNumber'|translate}'
- class='submit validatePhoneNumberSubmit'
+ class='validatePhoneNumberSubmit'
/>
{/if}
<input
type='submit'
value='{'MobileMessaging_Settings_RemovePhoneNumber'|translate}'
- class='submit removePhoneNumberSubmit'
+ class='removePhoneNumberSubmit'
/>
+ {if !$validated}
+ <br/>
+ <span class='form-description'>{'MobileMessaging_Settings_VerificationCodeJustSent'|translate}</span>
+ {/if}
+ <br/>
+ <br/>
</li>
{/foreach}
</ul>
{/if}
-{ajaxErrorDiv id=ajaxErrorMobileMessagingSettings}
+{if $isSuperUser}
+ <h2>{'MobileMessaging_Settings_SuperAdmin'|translate}</h2>
+
+ <table class='adminTable' style='width:650px;'>
+ <tr>
+ <td style='width:400px'>{'MobileMessaging_Settings_LetUsersManageAPICredential'|translate}</td>
+ <td style='width:250px'>
+ <fieldset>
+ <label>
+ <input
+ type='radio'
+ value='true'
+ name='delegatedManagement' {if $delegatedManagement} checked='checked'{/if} />
+ {'General_Yes'|translate}
+ <br/>
+ </label>
+ <br/>
+
+ <label>
+ <input
+ type='radio'
+ value='false'
+ name='delegatedManagement' {if !$delegatedManagement} checked='checked'{/if} />
+ {'General_No'|translate}
+ <br/>
+ <span class='form-description'>({'General_Default'|translate}) {'MobileMessaging_Settings_LetUsersManageAPICredential_No_Help'|translate}</span>
+ </label>
+ </fieldset>
+ </tr>
+ </table>
+{/if}
+
{ajaxLoadingDiv id=ajaxLoadingMobileMessagingSettings}
{include file='CoreAdminHome/templates/footer.tpl'}
+
+<div class='ui-confirm' id='confirmDeleteAccount'>
+ <h2>{'MobileMessaging_Settings_DeleteAccountConfirm'|translate}</h2>
+ <input role='yes' type='button' value='{'General_Yes'|translate}' />
+ <input role='no' type='button' value='{'General_No'|translate}' />
+</div>
+