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/views/admin_settings.php b/views/admin_settings.php index 010424d..86366cd 100644 --- a/views/admin_settings.php +++ b/views/admin_settings.php @@ -31,9 +31,18 @@ $parsedIncludeParams = $this->plugin->helpers->parseIncludeParamsSetting($this- errorMessage ) ) { + if(is_array($this->errorMessage)) { + foreach($this->errorMessage as $error) { + ?> +

+

errorMessage); ?>

@@ -43,14 +52,14 @@ $parsedIncludeParams = $this->plugin->helpers->parseIncludeParamsSetting($this- - +

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.

@@ -71,8 +80,6 @@ $parsedIncludeParams = $this->plugin->helpers->parseIncludeParamsSetting($this- - - @@ -94,7 +101,7 @@ $parsedIncludeParams = $this->plugin->helpers->parseIncludeParamsSetting($this- $param = $parsedIncludeParams[$i]; ?>
- +
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); } }