diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml new file mode 100644 index 0000000..c3a0901 --- /dev/null +++ b/.github/workflows/coding-standards.yml @@ -0,0 +1,37 @@ +name: Coding Standards + +# When to run. +on: + pull_request: + types: + - opened + - synchronize + push: + branches: + - master + +jobs: + coding-standards: + name: Coding Standards / PHP ${{ matrix.php-versions }} + runs-on: ubuntu-latest + + strategy: + matrix: + php-versions: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] + + steps: + - name: Checkout Plugin + uses: actions/checkout@v4 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + tools: cs2pr + + - name: Install Composer dependencies + run: composer update --no-interaction --no-progress + + - name: Run PHP Coding Standards + run: vendor/bin/phpcs -q --standard=phpcs.xml --report=checkstyle ./ | cs2pr diff --git a/.gitignore b/.gitignore index f1ff8a5..937b472 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ - .svn **/.DS_Store +composer.lock +/vendor/ \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..049054b --- /dev/null +++ b/composer.json @@ -0,0 +1,22 @@ +{ + "name": "usefathom/fathom-analytics", + "description": "Fathom Analytics for WordPress.", + "type": "wordpress-plugin", + "license": "GPL-2.0-or-later", + "require": { + "php": ">=5.4" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "wp-coding-standards/wpcs": "^3.0.0" + }, + "scripts": { + "phpcs": "vendor/bin/phpcs ./ -s -v", + "phpcbf": "vendor/bin/phpcbf ./ -s -v" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/fathom-analytics.php b/fathom-analytics.php index cd6696b..1fb0071 100644 --- a/fathom-analytics.php +++ b/fathom-analytics.php @@ -1,5 +1,5 @@ . */ +// Exit if accessed directly. +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + const FATHOM_PLUGIN_VERSION = '3.3.1'; const FATHOM_SITE_ID_OPTION_NAME = 'fathom_site_id'; const FATHOM_EXCLUDE_ROLES_OPTION_NAME = 'fathom_exclude_roles'; @@ -75,10 +80,36 @@ function fathom_get_excluded_roles() return $excluded_roles; } +/** + * Sanitize a checkbox option to 1 or 0. + * + * @since 3.3.2 + */ +function fathom_sanitize_checkbox( $value ) +{ + return empty( $value ) ? 0 : 1; +} + +/** + * Sanitize the excluded roles option to an array of valid role slugs. + * + * @since 3.3.2 + */ +function fathom_sanitize_excluded_roles( $roles ) +{ + if ( ! is_array( $roles ) ) { + return array(); + } + + $valid_roles = array_keys( wp_roles()->get_names() ); + + return array_values( array_intersect( $valid_roles, array_map( 'sanitize_key', $roles ) ) ); +} + /** * Determine if the current user has any of the excluded roles. * - * @return void + * @return bool */ function fathom_is_excluded_from_tracking() { if ( ! is_user_logged_in() ) { @@ -87,7 +118,7 @@ function fathom_is_excluded_from_tracking() { $user = wp_get_current_user(); - return array_intersect( fathom_get_excluded_roles(), $user->roles ); + return (bool) array_intersect( fathom_get_excluded_roles(), $user->roles ); } /** @@ -99,7 +130,7 @@ function fathom_enqueue_js_snippet() return; } - wp_enqueue_script( 'fathom-snippet', 'https://cdn.usefathom.com/script.js', array(), null, array( 'strategy' => 'defer' ) ); + wp_enqueue_script( 'fathom-snippet', 'https://cdn.usefathom.com/script.js', array(), null, array( 'strategy' => 'defer' ) ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- External CDN script, version intentionally omitted. } /** @@ -116,7 +147,7 @@ function fathom_enqueue_js_snippet() function fathom_add_data_attributes_to_js_script( $tag, $handle, $src ) { if ( 'fathom-snippet' === $handle ) { - $attributes = ' data-site="' . fathom_get_site_id() . '" ' . exclude_fathom_script_from_cookiebot(); + $attributes = ' data-site="' . esc_attr( fathom_get_site_id() ) . '" ' . exclude_fathom_script_from_cookiebot(); if ( get_option( FATHOM_IGNORE_CANONICAL ) ) { $attributes .= ' data-canonical="false"'; @@ -139,7 +170,7 @@ function fathom_add_data_attributes_to_js_script( $tag, $handle, $src ) function fathom_get_menu_icon() { $icon = ''; - return sprintf( 'data:image/svg+xml;base64,%s', base64_encode( $icon ) ); + return sprintf( 'data:image/svg+xml;base64,%s', base64_encode( $icon ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Encoding an inline SVG for the menu icon. } /** @@ -163,10 +194,11 @@ function fathom_stats_page() { function fathom_print_stats_page() { if (!empty(get_option(FATHOM_SITE_ID_OPTION_NAME))) { - wp_enqueue_script('fathom-iframresize', plugins_url('iframeResizer.min.js', __FILE__)); - wp_enqueue_script('fathom-stats-iframe', plugins_url('fathom-stats-iframe.js', __FILE__)); + wp_enqueue_script( 'fathom-iframe-resizer', plugins_url( 'iframeResizer.min.js', __FILE__ ), array(), FATHOM_PLUGIN_VERSION, false ); + wp_enqueue_script( 'fathom-stats-iframe', plugins_url( 'fathom-stats-iframe.js', __FILE__ ), array( 'fathom-iframe-resizer' ), FATHOM_PLUGIN_VERSION, false ); echo '
%s