diff --git a/readme.txt b/readme.txt index f0ecf10..2ea964e 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: web analytics, tracking, web traffic, analytics Requires at least: 5.2 Tested up to: 5.8.2 Requires PHP: 7.2 -Stable tag: trunk +Stable tag: 1.0.1 License: GPLv2 Easily add Wide Angle Analytics tracker script to your WordPress site. You can quickly configure your web analytics tracker script. diff --git a/types/WideAngleConfig.php b/types/WideAngleConfig.php index 09d3106..7a74bc4 100644 --- a/types/WideAngleConfig.php +++ b/types/WideAngleConfig.php @@ -18,7 +18,7 @@ class WideAngleConfig { function generateHeaderScript() { $script = << + EOD; return $script; } @@ -29,7 +29,7 @@ EOD; $script = << diff --git a/types/WideAngleHelpers.php b/types/WideAngleHelpers.php index 606d6f2..891a174 100644 --- a/types/WideAngleHelpers.php +++ b/types/WideAngleHelpers.php @@ -1,9 +1,12 @@ plugin->folder . '/types/WideAngleExclusion.php' ); +include_once( $this->plugin->folder . '/types/WideAngleValidated.php' ); class WideAngleHelpers { - - + const WAA_SEPARTOR = "|:"; + private const includeParamRequestKeyPattern = "/^waa_inc_params_(\d{1,2})$/"; + private const includeParamRequestValuePattern = "/^[A-Za-z0-9_-]{1,128}$/"; + private const excludePathRequestKeyPattern = "/^waa_exc_path_(\d{1,2})_type$/"; function normalizeBoolean($value) { $trimmed = trim($value); @@ -18,8 +21,65 @@ class WideAngleHelpers { } } - function normalizeTrackerDomain($domain) { - return "https://" . parse_url($domain, PHP_URL_HOST); + function validateIgnoreHashFlag($name, $ignoreHash) { + if(filter_var($ignoreHash, FILTER_VALIDATE_BOOLEAN)) { + return WideAngleValidated::createValid($name, $ignoreHash, "true"); + } else { + return WideAngleValidated::createValid($name, $ignoreHash, "false"); + } + } + + function validateSiteId($name, $siteId) { + if(preg_match("/^[a-zA-Z0-9]{10,24}$/", $siteId)) { + return WideAngleValidated::createValid($name, $siteId, strtoupper(trim($siteId))); + } else { + return WideAngleValidated::createInvalid($name, $siteId, "Site ID is expected to consist only letters and digits. It must be at least 10 character long and no longer than 24."); + } + } + + function validateTrackerDomain($name, $domain) { + if(filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) { + return WideAngleValidated::createValid($name, $domain, $domain); + } else { + return WideAngleValidated::createInvalid($name, $domain, "The tracked domain must be a valid domain name."); + } + } + + + function validateIncludeParams($name, $request) { + $params = array(); + foreach($request as $requestKey => $paramValue) { + if(preg_match(self::includeParamRequestKeyPattern, $requestKey)) { + if(preg_match(self::includeParamRequestValuePattern, $paramValue)) { + array_push($params, trim($paramValue)); + } else { + return WideAngleValidated::createInvalid($name, $paramValue, "Name of parameter to include in request must consint of letters, numbers and can contain _ or - sign only."); + } + } + } + return WideAngleValidated::createValid($name, $params, implode(self::WAA_SEPARTOR, $params)); + } + + + function validateExclusionPathsRequest($name, $request) { + $exclusions = array(); + foreach($request as $key => $exclusionType) { + $idx = array(); + if(preg_match(self::excludePathRequestKeyPattern, $key, $idx)) { + $valueKey = "waa_exc_path_".$idx[1]."_value"; + $exclusionValue = trim($request[$valueKey]); + if($exclusionValue != null) { + if(filter_var($exclusionValue, FILTER_VALIDATE_REGEXP)) { + $typedExclusion = "[" . $exclusionType . "]" . $exclusionValue; + array_push($exclusions, $typedExclusion); + } else { + $typedExclusion = "[" . $exclusionType . "]" . filter_var($exclusionValue, FILTER_SANITIZE_SPECIAL_CHARS); + array_push($exclusions, $typedExclusion); + } + } + } + } + return WideAngleValidated::createValid($name, implode(self::WAA_SEPARTOR, $exclusions), null); } function parseIncludeParamsSetting($params) { @@ -30,23 +90,12 @@ class WideAngleHelpers { } } - function parseRequestIncludeParams($request) { - $pattern = "/^waa_inc_params_(\d{1,2})$/"; - $params = array(); - foreach($request as $key => $value) { - if(preg_match($pattern, $key)) { - array_push($params, trim($value)); - } - } - return $params; - } - function parseExclusionSetting($path) { $flatExclusions = $path; - $exclusions = preg_split("/\|\:/", $flatExclusions); - $exclusionPattern = '/^\[([A-Za-z0-9]{1,10})\](.*)$/'; - $matches = array(); - $parsedExclusions = array(); + $exclusions = preg_split("/\|\:/", $flatExclusions); + $exclusionPattern = '/^\[([A-Za-z0-9]{1,10})\](.*)$/'; + $matches = array(); + $parsedExclusions = array(); foreach($exclusions as $exclusion) { @@ -57,22 +106,6 @@ class WideAngleHelpers { return $parsedExclusions; } - function parseRequestExclusionPaths($request) { - $pattern = "/^waa_exc_path_(\d{1,2})_type$/"; - $exclusions = array(); - foreach($request as $key => $exclusionType) { - $idx = array(); - if(preg_match($pattern, $key, $idx)) { - $valueKey = "waa_exc_path_".$idx[1]."_value"; - $exclusionValue = trim($request[$valueKey]); - if($exclusionValue != null && $exclusionValue != "") { - $typedExclusion = "[" . $exclusionType . "]" .$exclusionValue; - array_push($exclusions, $typedExclusion); - } - } - } - return $exclusions; - } } ?> \ No newline at end of file diff --git a/types/WideAngleValidated.php b/types/WideAngleValidated.php new file mode 100644 index 0000000..80f7487 --- /dev/null +++ b/types/WideAngleValidated.php @@ -0,0 +1,49 @@ +name = $name; + $this->value = $value; + $this->normalized = $normalized; + $this->error = $error; + $this->isValid = $isValid; + } + + public static function createValid($name, $value, $normalized) { + return new self($name, $value, $normalized, null, true); + } + + public static function createInvalid($name, $value, $error) { + return new self($name, $value, null, $error, false); + } + + public function get_name() { + return $this->name; + } + + public function get_value() { + if($this->normalized !== null) { + return $this->normalized; + } + return $this->value; + } + + public function get_error() { + if(!$this->isValid) { + return $this->error; + } + return null; + } + + public function is_valid() { + return $this->isValid; + } + +} +?> \ No newline at end of file diff --git a/views/admin_settings.php b/views/admin_settings.php index b064019..86366cd 100644 --- a/views/admin_settings.php +++ b/views/admin_settings.php @@ -7,7 +7,7 @@ $parsedIncludeParams = $this->plugin->helpers->parseIncludeParamsSetting($this- ?> - plugin->displayName; ?> » + plugin->displayName; ?> » @@ -27,30 +27,39 @@ $parsedIncludeParams = $this->plugin->helpers->parseIncludeParamsSetting($this- message ) ) { ?> - message; ?> + message); ?> errorMessage ) ) { + if(is_array($this->errorMessage)) { + foreach($this->errorMessage as $error) { + ?> + + - errorMessage; ?> + errorMessage); ?> - + Site ID - + A Site ID. You will find it in the Site Settings, in Wide Angle Analytics Dashboard. Tracker Domain - + A domain you selected for your tracker. You can check current domain in the Site Settings, in the Wide Angle Analytics. If you haven't set custom domain for your site, there is no need to change this field. @@ -62,20 +71,18 @@ $parsedIncludeParams = $this->plugin->helpers->parseIncludeParamsSetting($this- for($i = 0; $i < sizeof($parsedExclusions); $i++) { $exclusion = $parsedExclusions[$i]; ?> - - + + plugin->exclusionTypes as $id => $label) { ?> - get_type() == $id) echo ' selected'; ?>> + get_type() == $id) echo ' selected'; ?>> - get_type() == "end") echo ' selected'; ?>>Ends with - get_type() == "regex") echo ' selected'; ?>>RegEx - - Remove + + Remove plugin->helpers->parseIncludeParamsSetting($this- for($i = 0; $i < sizeof($parsedIncludeParams); $i++) { $param = $parsedIncludeParams[$i]; ?> - - - Remove + + + Remove plugin->helpers->parseIncludeParamsSetting($this- <head> <!-- .. --> -settings[self::WAA_CONF_GENERATED_HEADER_SCRIPT]; ?> +settings[self::WAA_CONF_GENERATED_HEADER_SCRIPT]); ?> </head> <!-- .. --> -settings[self::WAA_CONF_GENERATED_FOOTER_SCRIPT]; ?> +settings[self::WAA_CONF_GENERATED_FOOTER_SCRIPT]); ?> diff --git a/wide-angle-analytics.php b/wide-angle-analytics.php index ab6d725..d428433 100644 --- a/wide-angle-analytics.php +++ b/wide-angle-analytics.php @@ -5,7 +5,7 @@ Description: Easily enable and configure Wide Angle Analytics on your Wordpress site Author: Wide Angle Analytics by Input Objects GmbH Author URI: https://wideangle.co - Version: 1.0.0 + Version: 1.0.1 Requires at least: 5.2 Requires PHP: 7.2 License: GPL v2 @@ -15,7 +15,6 @@ plugin->name . '_nonce' ], $this->plugin->name ) ) { $this->errorMessage = __( 'Invalid nonce specified. Settings NOT saved.', $this->plugin->name ); } else { - $waaSiteId = $_REQUEST['waa_site_id']; - $waaTrackerDomain = $this->plugin->helpers->normalizeTrackerDomain(trim($_REQUEST['waa_tracker_domain'])); - $waaIgnoreHash = $this->plugin->helpers->normalizeBoolean($_REQUEST['waa_ignore_hash']); - $waaExclusionPaths = implode(self::WAA_SEPARTOR, $this->plugin->helpers->parseRequestExclusionPaths($_REQUEST)); - $waaIncParams = implode(self::WAA_SEPARTOR, $this->plugin->helpers->parseRequestIncludeParams($_REQUEST)); + $waaSiteId = $this->plugin->helpers->validateSiteId(self::WAA_CONF_SITE_ID, $_REQUEST['waa_site_id']); + $waaTrackerDomain = $this->plugin->helpers->validateTrackerDomain(self::WAA_CONF_TRACKER_DOMAIN, $_REQUEST['waa_tracker_domain']); + $waaIgnoreHash = $this->plugin->helpers->validateIgnoreHashFlag(self::WAA_CONF_IGNORE_HASH, $_REQUEST['waa_ignore_hash']); + $waaIncParams = $this->plugin->helpers->validateIncludeParams(self::WAA_CONF_INC_PARAMS, $_REQUEST); + $waaExclusionPaths = $this->plugin->helpers->validateExclusionPathsRequest(self::WAA_CONF_EXC_PATHS, $_REQUEST); - include_once( $this->plugin->folder . '/types/WideAngleConfig.php' ); - $config = new WideAngleConfig($waaSiteId, $waaTrackerDomain, $waaIgnoreHash, $waaExclusionPaths, $waaIncParams); + include_once( $this->plugin->folder . '/types/WideAngleConfig.php'); + $merged = array($waaSiteId, $waaTrackerDomain, $waaIgnoreHash, $waaIncParams, $waaExclusionPaths); + $errors = array(); + foreach($merged as $validated) { + if(!$validated->is_valid()) { + array_push($errors, $validated->get_error()); + } + } - update_option(self::WAA_CONF_GENERATED_FOOTER_SCRIPT, $config->generateFooterScript()); - update_option(self::WAA_CONF_GENERATED_HEADER_SCRIPT, $config->generateHeaderScript()); - update_option(self::WAA_CONF_SITE_ID, $waaSiteId ); - update_option(self::WAA_CONF_TRACKER_DOMAIN, $waaTrackerDomain); - update_option(self::WAA_CONF_IGNORE_HASH, $waaIgnoreHash ); - update_option(self::WAA_CONF_EXC_PATHS, $waaExclusionPaths ); - update_option(self::WAA_CONF_INC_PARAMS, $waaIncParams); + if(count($errors) === 0) { + $config = new WideAngleConfig($waaSiteId->get_value(), $waaTrackerDomain->get_value(), $waaIgnoreHash->get_value(), $waaExclusionPaths->get_value(), $waaIncParams->get_value()); + + update_option(self::WAA_CONF_GENERATED_FOOTER_SCRIPT, $config->generateFooterScript()); + update_option(self::WAA_CONF_GENERATED_HEADER_SCRIPT, $config->generateHeaderScript()); + update_option(self::WAA_CONF_SITE_ID, $waaSiteId->get_value()); + update_option(self::WAA_CONF_TRACKER_DOMAIN, $waaTrackerDomain->get_value()); + update_option(self::WAA_CONF_IGNORE_HASH, $waaIgnoreHash->get_value()); + update_option(self::WAA_CONF_EXC_PATHS, $waaExclusionPaths->get_value()); + update_option(self::WAA_CONF_INC_PARAMS, $waaIncParams->get_value()); + $this->message = __('Settings updated', $this->plugin->name); + } else { + $this->errorMessage = $errors; + } } } $this->settings = array( - self::WAA_CONF_SITE_ID => esc_html(get_option( self::WAA_CONF_SITE_ID)), - self::WAA_CONF_EXC_PATHS => esc_html(get_option( self::WAA_CONF_EXC_PATHS)), - self::WAA_CONF_INC_PARAMS => esc_html(get_option( self::WAA_CONF_INC_PARAMS)), - self::WAA_CONF_TRACKER_DOMAIN => esc_html(get_option( self::WAA_CONF_TRACKER_DOMAIN)), - self::WAA_CONF_IGNORE_HASH => esc_html(get_option( self::WAA_CONF_IGNORE_HASH)), - self::WAA_CONF_GENERATED_HEADER_SCRIPT => esc_html(get_option( self::WAA_CONF_GENERATED_HEADER_SCRIPT )), - self::WAA_CONF_GENERATED_FOOTER_SCRIPT => esc_html(get_option( self::WAA_CONF_GENERATED_FOOTER_SCRIPT )), + self::WAA_CONF_SITE_ID => get_option( self::WAA_CONF_SITE_ID), + self::WAA_CONF_EXC_PATHS => get_option( self::WAA_CONF_EXC_PATHS), + self::WAA_CONF_INC_PARAMS => get_option( self::WAA_CONF_INC_PARAMS), + self::WAA_CONF_TRACKER_DOMAIN => get_option( self::WAA_CONF_TRACKER_DOMAIN), + self::WAA_CONF_IGNORE_HASH => get_option( self::WAA_CONF_IGNORE_HASH), + self::WAA_CONF_GENERATED_HEADER_SCRIPT => get_option( self::WAA_CONF_GENERATED_HEADER_SCRIPT), + self::WAA_CONF_GENERATED_FOOTER_SCRIPT => get_option( self::WAA_CONF_GENERATED_FOOTER_SCRIPT), ); include_once( $this->plugin->folder . '/views/admin_settings.php' ); } @@ -155,32 +167,13 @@ class WideAngleAnalytics { * - waa_footer_script */ function registerPluginSettings() { - register_setting( $this->plugin->name, self::WAA_CONF_SITE_ID, array( - 'sanitize_callback' => 'trim', - ) ); - register_setting( $this->plugin->name, self::WAA_CONF_EXC_PATHS, array( - 'sanitize_callback' => 'trim', - ) ); - register_setting( $this->plugin->name, self::WAA_CONF_INC_PARAMS, array( - 'sanitize_callback' =>'trim', - 'default' => '' - ) ); - register_setting( $this->plugin->name, self::WAA_CONF_TRACKER_DOMAIN, array( - 'sanitize_callback' => array(&$this->plugin->helpers, 'normalizeTrackerDomain'), - 'default' => 'https://stats.wideangle.co' - ) ); - register_setting( $this->plugin->name, self::WAA_CONF_IGNORE_HASH, array( - 'sanitize_callback' => array(&$this->plugin->helpers, 'normalizeBoolean'), - 'default' => 'false' - ) ); - register_setting( $this->plugin->name, self::WAA_CONF_GENERATED_HEADER_SCRIPT, array( - 'sanitize_callback' => 'trim', - 'default' => '' - ) ); - register_setting( $this->plugin->name, self::WAA_CONF_GENERATED_FOOTER_SCRIPT, array( - 'sanitize_callback' => 'trim', - 'default' => '' - ) ); + register_setting($this->plugin->name, self::WAA_CONF_SITE_ID); + register_setting($this->plugin->name, self::WAA_CONF_EXC_PATHS); + register_setting($this->plugin->name, self::WAA_CONF_INC_PARAMS); + register_setting($this->plugin->name, self::WAA_CONF_TRACKER_DOMAIN, array('default' => 'stats.wideangle.co')); + register_setting($this->plugin->name, self::WAA_CONF_IGNORE_HASH, array('default' => 'false')); + register_setting($this->plugin->name, self::WAA_CONF_GENERATED_HEADER_SCRIPT); + register_setting($this->plugin->name, self::WAA_CONF_GENERATED_FOOTER_SCRIPT); } }
message; ?>
message); ?>
errorMessage; ?>
errorMessage); ?>
A Site ID. You will find it in the Site Settings, in Wide Angle Analytics Dashboard.
A domain you selected for your tracker. You can check current domain in the Site Settings, in the Wide Angle Analytics. If you haven't set custom domain for your site, there is no need to change this field.
<head> <!-- .. --> -settings[self::WAA_CONF_GENERATED_HEADER_SCRIPT]; ?> +settings[self::WAA_CONF_GENERATED_HEADER_SCRIPT]); ?> </head> <!-- .. --> -settings[self::WAA_CONF_GENERATED_FOOTER_SCRIPT]; ?> +settings[self::WAA_CONF_GENERATED_FOOTER_SCRIPT]); ?>