Conversation
… it's different from the one in the repo.
Updated: Distignore to exclude additional development files
Updated: Readme version and also pulled the latest trunk readme
CI Updates
Added: Contributor
Removed: Deprecated plugin version header Updated: Tests to use new Utils\Options class Updated: Readme version
Added: Translation file wp-mautic.pot to make generating translations easier
…d only tracking method Updated: .pot file
Updated: Exception punctuation Bugfix: console.warn triggering error Removed: Duplicate distignore entry.
Updated: Shortcode init method tabbing Updated: Spelling for wpmautic_focus_shortcode method comment
Updated: Abspath exit
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Version/2.5.0/refactor
Version/2.5.0/translations
…method Version/2.5.0/tracking method
Updated: Version
Removed Dry run
There was a problem hiding this comment.
Pull request overview
This PR represents a major architectural refactoring of the WP Mautic plugin, migrating from a procedural, function-based codebase to an object-oriented structure with PSR-4 namespacing and Composer autoloading. The plugin version is bumped from 2.4.3 to 2.5.1, with WordPress compatibility updated to 6.8.
Changes:
- Refactored entire codebase from procedural functions to OOP classes with Mautic\WP_Mautic namespace
- Introduced Composer autoloading with PSR-4 standard
- Restructured code into logical class hierarchy (Backend, Frontend, Utils)
- Updated tracking image fallback from boolean to tri-state string option ('0', '1', '2')
- Added new contributor and updated version information
Reviewed changes
Copilot reviewed 17 out of 30 changed files in this pull request and generated 20 comments.
Show a summary per file
| File | Description |
|---|---|
| wpmautic.php | Main plugin file refactored to use namespace and minimal bootstrap code |
| includes/classes/* | New OOP class structure for dependency loading, frontend/backend functionality |
| vendor/composer/* | Generated Composer autoloader files for PSR-4 autoloading |
| vendor/autoload.php | Composer autoloader entry point |
| tests/OptionsTest.php | Updated tests to use new Options::get() static method |
| shortcodes.php | Removed (functionality moved to Frontend/Shortcodes class) |
| options.php | Removed (functionality moved to Backend/Admin class) |
| readme.txt | Updated version, WordPress compatibility, and contributor information |
| languages/wp-mautic.pot | Generated translation template with new string references |
| composer.json | Added PSR-4 autoload configuration |
| .gitignore | Modified to include vendor/composer directory in version control |
| .github/workflows/* | Removed dry-run flags to enable actual deployments |
| .distignore | Expanded to exclude development dependencies from distribution |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** | ||
| * Retrieve one of the wpmautic options but sanitized | ||
| * | ||
| * @param string $option Option name to be retrieved (base_url, script_location). | ||
| * @param mixed $default Default option value return if not exists. | ||
| * | ||
| * @return string | ||
| * | ||
| * @throws InvalidArgumentException Thrown when the option name is not given. | ||
| */ | ||
| public static function get( $option, $default = null ) { | ||
| $options = get_option( 'wpmautic_options' ); | ||
|
|
||
| switch ( $option ) { | ||
| case 'script_location': | ||
| return ! isset( $options[ $option ] ) ? 'header' : $options[ $option ]; | ||
|
|
||
| case 'fallback_activated': | ||
| // Return saved value or default to '0' (Disabled) | ||
| return isset( $options[ $option ] ) ? $options[ $option ] : '0'; | ||
|
|
||
| case 'track_logged_user': | ||
| return isset( $options[ $option ] ) ? (bool) $options[ $option ] : false; | ||
|
|
||
| default: | ||
| if ( ! isset( $options[ $option ] ) ) { | ||
| if ( isset( $default ) ) { | ||
| return $default; | ||
| } | ||
|
|
||
| throw new InvalidArgumentException( __('You must give a valid option name!', 'wp-mautic') ); | ||
| } | ||
| return $options[ $option ]; | ||
| } | ||
| } |
There was a problem hiding this comment.
Inconsistent indentation: This class uses 2-space indentation instead of tabs as required by WordPress Coding Standards. All methods and properties should be reformatted to use tabs for consistency.
| /** | |
| * Retrieve one of the wpmautic options but sanitized | |
| * | |
| * @param string $option Option name to be retrieved (base_url, script_location). | |
| * @param mixed $default Default option value return if not exists. | |
| * | |
| * @return string | |
| * | |
| * @throws InvalidArgumentException Thrown when the option name is not given. | |
| */ | |
| public static function get( $option, $default = null ) { | |
| $options = get_option( 'wpmautic_options' ); | |
| switch ( $option ) { | |
| case 'script_location': | |
| return ! isset( $options[ $option ] ) ? 'header' : $options[ $option ]; | |
| case 'fallback_activated': | |
| // Return saved value or default to '0' (Disabled) | |
| return isset( $options[ $option ] ) ? $options[ $option ] : '0'; | |
| case 'track_logged_user': | |
| return isset( $options[ $option ] ) ? (bool) $options[ $option ] : false; | |
| default: | |
| if ( ! isset( $options[ $option ] ) ) { | |
| if ( isset( $default ) ) { | |
| return $default; | |
| } | |
| throw new InvalidArgumentException( __('You must give a valid option name!', 'wp-mautic') ); | |
| } | |
| return $options[ $option ]; | |
| } | |
| } | |
| /** | |
| * Retrieve one of the wpmautic options but sanitized | |
| * | |
| * @param string $option Option name to be retrieved (base_url, script_location). | |
| * @param mixed $default Default option value return if not exists. | |
| * | |
| * @return string | |
| * | |
| * @throws InvalidArgumentException Thrown when the option name is not given. | |
| */ | |
| public static function get( $option, $default = null ) { | |
| $options = get_option( 'wpmautic_options' ); | |
| switch ( $option ) { | |
| case 'script_location': | |
| return ! isset( $options[ $option ] ) ? 'header' : $options[ $option ]; | |
| case 'fallback_activated': | |
| // Return saved value or default to '0' (Disabled) | |
| return isset( $options[ $option ] ) ? $options[ $option ] : '0'; | |
| case 'track_logged_user': | |
| return isset( $options[ $option ] ) ? (bool) $options[ $option ] : false; | |
| default: | |
| if ( ! isset( $options[ $option ] ) ) { | |
| if ( isset( $default ) ) { | |
| return $default; | |
| } | |
| throw new InvalidArgumentException( __('You must give a valid option name!', 'wp-mautic') ); | |
| } | |
| return $options[ $option ]; | |
| } | |
| } |
| } | ||
|
|
||
| return '<script type="text/javascript" ' . sprintf( | ||
| 'src="%s/form/generate.js?id=%s"', |
There was a problem hiding this comment.
The async attribute has been removed from the form embed script tag. Line 83 in the new code no longer includes 'async' while the old shortcodes.php had 'async' in the script tag. This change could impact page load performance as the script will now block rendering. Consider whether this was intentional or if the async attribute should be preserved.
| 'src="%s/form/generate.js?id=%s"', | |
| 'src="%s/form/generate.js?id=%s" async', |
| # Steps can also provide arguments, so this configures 10up's action to also generate a zip file. | ||
| with: | ||
| dry-run: true | ||
| generate-zip: true |
There was a problem hiding this comment.
The removal of 'dry-run: true' from the deployment workflow means that deployments will now actually execute instead of being simulated. This is a significant operational change that could lead to unintended deployments if this workflow is triggered accidentally. Ensure that proper branch protection rules and approval processes are in place before merging this change.
| generate-zip: true | |
| generate-zip: true | |
| dry-run: true |
| @@ -11,8 +11,6 @@ jobs: | |||
| - uses: actions/checkout@master | |||
| - name: WordPress.org plugin asset/readme update | |||
| uses: 10up/action-wordpress-plugin-asset-update@stable | |||
There was a problem hiding this comment.
The removal of 'dry-run: true' from the asset update workflow means that asset updates will now actually be pushed to WordPress.org instead of being simulated. This operational change should be carefully coordinated to ensure it doesn't cause unintended updates to the WordPress.org plugin repository.
| uses: 10up/action-wordpress-plugin-asset-update@stable | |
| uses: 10up/action-wordpress-plugin-asset-update@stable | |
| with: | |
| dry-run: true |
|
|
||
|
|
||
| /** | ||
| * Init | ||
| * | ||
| * @return void | ||
| */ | ||
| public function init() { | ||
| $this->load_dependencies(); | ||
| } | ||
|
|
||
| /** | ||
| * Load dependencies | ||
| * | ||
| * @return void | ||
| */ | ||
| public function load_dependencies() { | ||
| $dependency_loader = new Dependency_Loader(); | ||
| $dependency_loader->init(); | ||
| } | ||
|
|
There was a problem hiding this comment.
Inconsistent indentation: This class uses 2-space indentation for methods and properties, while WordPress Coding Standards require tabs or 4-space indentation. All methods in this class (lines 35-52) should follow the same indentation standard used throughout the WordPress ecosystem.
| /** | |
| * Init | |
| * | |
| * @return void | |
| */ | |
| public function init() { | |
| $this->load_dependencies(); | |
| } | |
| /** | |
| * Load dependencies | |
| * | |
| * @return void | |
| */ | |
| public function load_dependencies() { | |
| $dependency_loader = new Dependency_Loader(); | |
| $dependency_loader->init(); | |
| } | |
| /** | |
| * Init | |
| * | |
| * @return void | |
| */ | |
| public function init() { | |
| $this->load_dependencies(); | |
| } | |
| /** | |
| * Load dependencies | |
| * | |
| * @return void | |
| */ | |
| public function load_dependencies() { | |
| $dependency_loader = new Dependency_Loader(); | |
| $dependency_loader->init(); | |
| } |
| // Return saved value or default to '0' (Disabled) | ||
| return isset( $options[ $option ] ) ? $options[ $option ] : '0'; | ||
|
|
There was a problem hiding this comment.
The return type and behavior of the fallback_activated option has changed from boolean to string without proper migration handling. Previously, this returned true/false (line 27 in old code returned boolean), but now returns string '0', '1', or '2'. This breaking change could cause issues for existing users who have boolean values stored in their database. A migration strategy should be implemented to convert existing boolean values to the new string format.
| // Return saved value or default to '0' (Disabled) | |
| return isset( $options[ $option ] ) ? $options[ $option ] : '0'; | |
| // Normalize and migrate legacy values to string representation ('0', '1', or '2'). | |
| $value = isset( $options[ $option ] ) ? $options[ $option ] : null; | |
| // Handle legacy boolean values (from older versions) and normalize to strings. | |
| if ( is_bool( $value ) ) { | |
| $value = $value ? '1' : '0'; | |
| $options[ $option ] = $value; | |
| update_option( 'wpmautic_options', $options ); | |
| } elseif ( $value === 'true' || $value === 'false' ) { | |
| // Handle possible stringified booleans from legacy storage. | |
| $value = ( $value === 'true' ) ? '1' : '0'; | |
| $options[ $option ] = $value; | |
| update_option( 'wpmautic_options', $options ); | |
| } | |
| // Ensure the value is one of the expected string states; default to '0' if not. | |
| if ( $value === null || ! in_array( (string) $value, array( '0', '1', '2' ), true ) ) { | |
| $value = '0'; | |
| $options[ $option ] = $value; | |
| update_option( 'wpmautic_options', $options ); | |
| } | |
| return $value; |
| class Enqueue { | ||
|
|
||
| /** | ||
| * Init | ||
| * | ||
| * @return void | ||
| */ | ||
| public function init() { | ||
| $this->enqueue(); | ||
| } | ||
|
|
||
| /** | ||
| * Enqueue scripts and styles | ||
| * | ||
| * @return void | ||
| */ | ||
| public function enqueue() { | ||
| $this->enqueue_scripts(); | ||
| } | ||
|
|
||
| /** | ||
| * Enqueue scripts | ||
| * | ||
| * @return void | ||
| */ | ||
| public function enqueue_scripts() { | ||
| $script_location = Options::get( 'script_location' ); | ||
| $fallback = Options::get( 'fallback_activated', false ); | ||
|
|
||
| if ('0' === $fallback || '1' === $fallback) { | ||
| if ( 'header' === $script_location ) { | ||
| add_action( 'wp_head', array( $this, 'wpmautic_inject_script' ) ); | ||
| } else { | ||
| add_action( 'wp_footer', array( $this, 'wpmautic_inject_script' ) ); | ||
| } | ||
|
|
||
| if ( 'disabled' !== $script_location && '1' === $fallback ) { | ||
| add_action( 'wp_footer', array( $this, 'wpmautic_inject_noscript' ) ); | ||
| } | ||
| } elseif ('2' === $fallback) { | ||
| add_action( 'wp_footer', array( $this, 'wpmautic_inject_tracking_pixel' ) ); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Writes Tracking JS to the HTML source | ||
| * | ||
| * @return void | ||
| */ | ||
| public function wpmautic_inject_script() { | ||
| // Load the Mautic tracking library mtc.js if it is not disabled. | ||
| $base_url = $this->wpmautic_base_script(); | ||
| $script_location = Options::get( 'script_location' ); | ||
| $attrs = $this->wpmautic_get_tracking_attributes(); | ||
| ?> | ||
| <script type="text/javascript" > | ||
| function wpmautic_send(){ | ||
| if ('undefined' === typeof mt) { | ||
| if (console !== undefined) { | ||
| console.warn('<?php echo esc_js( __( 'WPMautic: mt not defined. Did you load mtc.js?', 'wp-mautic' ) ); ?>'); | ||
| } | ||
| return false; | ||
| } | ||
| // Add the mt('send', 'pageview') script with optional tracking attributes. | ||
| mt('send', 'pageview'<?php echo count( $attrs ) > 0 ? ', ' . wp_json_encode( $attrs ) : ''; ?>); | ||
| } | ||
|
|
||
| <?php | ||
| // Mautic is not configured, or user disabled automatic tracking on page load (GDPR). | ||
| if ( ! empty( $base_url ) && 'disabled' !== $script_location ) : | ||
| ?> | ||
| (function(w,d,t,u,n,a,m){w['MauticTrackingObject']=n; | ||
| w[n]=w[n]||function(){(w[n].q=w[n].q||[]).push(arguments)},a=d.createElement(t), | ||
| m=d.getElementsByTagName(t)[0];a.async=1;a.src=u;m.parentNode.insertBefore(a,m) | ||
| })(window,document,'script','<?php echo esc_url( $base_url ); ?>','mt'); | ||
|
|
||
| wpmautic_send(); | ||
| <?php | ||
| endif; | ||
| ?> | ||
| </script> | ||
| <?php | ||
| } | ||
|
|
||
| /** | ||
| * Writes Tracking image fallback to the HTML source | ||
| * This is a separated function because <noscript> tags are not allowed in header ! | ||
| * | ||
| * @return void | ||
| */ | ||
| public function wpmautic_inject_noscript() { | ||
| $base_url = Options::get( 'base_url', '' ); | ||
| if ( empty( $base_url ) ) { | ||
| return; | ||
| } | ||
|
|
||
| $url_query = $this->wpmautic_get_url_query(); | ||
| $payload = rawurlencode( base64_encode( serialize( $url_query ) ) ); | ||
| ?> | ||
| <noscript> | ||
| <img src="<?php echo esc_url( $base_url ); ?>/mtracking.gif?d=<?php echo esc_attr( $payload ); ?>" style="display:none;" alt="<?php echo esc_attr__( 'Mautic Tags', 'wp-mautic' ); ?>" /> | ||
| </noscript> | ||
| <?php | ||
| } | ||
|
|
||
| /** | ||
| * Writes Tracking image fallback to the HTML source | ||
| * This is a separated function because <noscript> tags are not allowed in header ! | ||
| * | ||
| * @return void | ||
| */ | ||
| public function wpmautic_inject_tracking_pixel() { | ||
| $base_url = Options::get( 'base_url', '' ); | ||
| if ( empty( $base_url ) ) { | ||
| return; | ||
| } | ||
|
|
||
| $url_query = $this->wpmautic_get_url_query(); | ||
| $payload = rawurlencode( base64_encode( serialize( $url_query ) ) ); | ||
| ?> | ||
| <img src="<?php echo esc_url( $base_url ); ?>/mtracking.gif?d=<?php echo esc_attr( $payload ); ?>" style="display:none;" alt="<?php echo esc_attr__( 'Mautic Tags', 'wp-mautic' ); ?>" /> | ||
| <?php | ||
| } | ||
|
|
||
| /** | ||
| * Generate the mautic script URL to be used outside of the plugin when | ||
| * necessary | ||
| * | ||
| * @return string | ||
| */ | ||
| private function wpmautic_base_script() { | ||
| $base_url = Options::get( 'base_url', '' ); | ||
| if ( empty( $base_url ) ) { | ||
| return; | ||
| } | ||
|
|
||
| return $base_url . '/mtc.js'; | ||
| } | ||
|
|
||
| /** | ||
| * Builds and returns additional data for URL query | ||
| * | ||
| * @return array | ||
| */ | ||
| private function wpmautic_get_url_query() { | ||
| global $wp; | ||
| $current_url = add_query_arg( $wp->query_string, '', home_url( $wp->request ) ); | ||
|
|
||
| $attrs = $this->wpmautic_get_tracking_attributes(); | ||
|
|
||
| $attrs['language'] = get_locale(); | ||
| $attrs['page_url'] = $current_url; | ||
| $attrs['page_title'] = function_exists( 'wp_get_document_title' ) | ||
| ? wp_get_document_title() | ||
| : wp_title( '»', false ); | ||
| $attrs['referrer'] = function_exists( 'wp_get_raw_referer' ) | ||
| ? wp_get_raw_referer() | ||
| : null; | ||
| if ( false === $attrs['referrer'] ) { | ||
| $attrs['referrer'] = $current_url; | ||
| } | ||
|
|
||
| return $attrs; | ||
| } | ||
|
|
||
| /** | ||
| * Create custom query parameters to be injected inside tracking | ||
| * | ||
| * @return array | ||
| */ | ||
| private function wpmautic_get_tracking_attributes() { | ||
| $attrs = $this->wpmautic_get_user_query(); | ||
|
|
||
| /** | ||
| * Update / add data to be sent within Mautic tracker | ||
| * | ||
| * Default data only contains the 'language' key but every added key to the | ||
| * array will be sent to Mautic. | ||
| * | ||
| * @since 2.1.0 | ||
| * | ||
| * @param array $attrs Attributes to be filters, default ['language' => get_locale()] | ||
| */ | ||
| return apply_filters( 'wpmautic_tracking_attributes', $attrs ); | ||
| } | ||
|
|
||
| /** | ||
| * Extract logged user information to be sent within Mautic tracker | ||
| * | ||
| * @return array | ||
| */ | ||
| private function wpmautic_get_user_query() { | ||
| $attrs = array(); | ||
|
|
||
| if ( | ||
| true === Options::get( 'track_logged_user', false ) && | ||
| is_user_logged_in() | ||
| ) { | ||
| $current_user = wp_get_current_user(); | ||
| $attrs['email'] = $current_user->user_email; | ||
| $attrs['firstname'] = $current_user->user_firstname; | ||
| $attrs['lastname'] = $current_user->user_lastname; | ||
|
|
||
| // Following Mautic fields has to be created manually and the fields must match these names. | ||
| $attrs['wp_user'] = $current_user->user_login; | ||
| $attrs['wp_alias'] = $current_user->display_name; | ||
| $attrs['wp_registration_date'] = date( | ||
| 'Y-m-d', | ||
| strtotime( $current_user->user_registered ) | ||
| ); | ||
| } | ||
|
|
||
| return $attrs; | ||
| } | ||
|
|
||
| } No newline at end of file |
There was a problem hiding this comment.
Inconsistent indentation throughout the class: This class uses 2-space indentation instead of the WordPress Coding Standards requirement of tabs or 4 spaces. All methods and properties (lines 9-221) should be reformatted to follow WordPress indentation standards for consistency with the WordPress ecosystem.
| class Shortcodes { | ||
|
|
||
| /** | ||
| * Init | ||
| * | ||
| * @return void | ||
| */ | ||
| public function init() { | ||
| add_shortcode('mautic', array($this, 'wpmautic_shortcode')); | ||
|
|
||
| // Backward compatibilities. | ||
| add_shortcode('mauticcontent', array($this, 'wpmautic_dwc_shortcode')); | ||
| add_shortcode('mauticvideo', array($this, 'wpmautic_video_shortcode')); | ||
| add_shortcode('mauticform', array($this, 'wpmautic_form_shortcode')); | ||
| add_shortcode('mautictags', array($this, 'wpmautic_tags_shortcode')); | ||
| add_shortcode('mauticfocus', array($this, 'wpmautic_focus_shortcode')); | ||
| } | ||
|
|
||
| /** | ||
| * Handle mautic shortcode. Must include a type attribute. | ||
| * | ||
| * @param array $atts Shortcode attributes. | ||
| * @param string|null $content Default content to be displayed. | ||
| * | ||
| * @return string | ||
| */ | ||
| public function wpmautic_shortcode( $atts, $content = null ) { | ||
| $default = shortcode_atts( | ||
| array( | ||
| 'type' => null, | ||
| ), | ||
| $atts | ||
| ); | ||
|
|
||
| switch ( $default['type'] ) { | ||
| case 'form': | ||
| return $this->wpmautic_form_shortcode( $atts ); | ||
| case 'content': | ||
| return $this->wpmautic_dwc_shortcode( $atts, $content ); | ||
| case 'video': | ||
| return $this->wpmautic_video_shortcode( $atts ); | ||
| case 'tags': | ||
| return $this->wpmautic_tags_shortcode( $atts ); | ||
| case 'focus': | ||
| return $this->wpmautic_focus_shortcode( $atts ); | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * Handle mauticform shortcode | ||
| * example: [mautic type="form" id="1"] | ||
| * | ||
| * @param array $atts Shortcode attributes. | ||
| * | ||
| * @return string | ||
| */ | ||
| public function wpmautic_form_shortcode( $atts ) { | ||
| $base_url = Options::get( 'base_url', '' ); | ||
| if ( '' === $base_url ) { | ||
| return false; | ||
| } | ||
|
|
||
| $atts = shortcode_atts( | ||
| array( | ||
| 'id' => '', | ||
| ), | ||
| $atts | ||
| ); | ||
|
|
||
| if ( empty( $atts['id'] ) ) { | ||
| return false; | ||
| } | ||
|
|
||
| return '<script type="text/javascript" ' . sprintf( | ||
| 'src="%s/form/generate.js?id=%s"', | ||
| esc_url( $base_url ), | ||
| esc_attr( $atts['id'] ) | ||
| ) . '></script>'; | ||
| } | ||
|
|
||
| /** | ||
| * Dynamic content shortcode handling | ||
| * example: [mautic type="content" slot="slot_name"]Default Content[/mautic] | ||
| * | ||
| * @param array $atts Shortcode attributes. | ||
| * @param string|null $content Default content to be displayed. | ||
| * | ||
| * @return string | ||
| */ | ||
| public function wpmautic_dwc_shortcode( $atts, $content = null ) { | ||
| $atts = shortcode_atts( | ||
| array( | ||
| 'slot' => '', | ||
| ), | ||
| $atts, | ||
| 'mautic' | ||
| ); | ||
|
|
||
| return sprintf( | ||
| '<div class="mautic-slot" data-slot-name="%s">%s</div>', | ||
| esc_attr( $atts['slot'] ), | ||
| wp_kses( $content, wp_kses_allowed_html( 'post' ) ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Video shortcode handling | ||
| * example: [mautic type="video" gate-time="15" form-id="1" src="https://www.youtube.com/watch?v=QT6169rdMdk"] | ||
| * | ||
| * @param array $atts Shortcode attributes. | ||
| * | ||
| * @return string | ||
| */ | ||
| public function wpmautic_video_shortcode( $atts ) { | ||
| $atts = shortcode_atts( | ||
| array( | ||
| 'gate-time' => 15, | ||
| 'form-id' => '', | ||
| 'src' => '', | ||
| 'video-type' => '', | ||
| 'mautic-video' => 'true', | ||
| 'width' => 640, | ||
| 'height' => 360, | ||
| ), | ||
| $atts | ||
| ); | ||
|
|
||
| if ( empty( $atts['src'] ) ) { | ||
| return __( 'You must provide a video source. Add a src="URL" attribute to your shortcode. Replace URL with the source url for your video.', 'wp-mautic' ); | ||
| } | ||
|
|
||
| if ( empty( $atts['form-id'] ) && 'true' !== $atts['mautic-video'] ) { | ||
| return __( 'You must provide a mautic form id. Add a form-id="#" attribute to your shortcode. Replace # with the id of the form you want to use.', 'wp-mautic' ); | ||
| } | ||
|
|
||
| if ( preg_match( '/^.*((youtu.be)|(youtube.com))\/((v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))?\??v?=?([^#\&\?]*).*/', $atts['src'] ) ) { | ||
| $atts['video-type'] = 'youtube'; | ||
| } | ||
| if ( preg_match( '/^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/))?([0-9]+)/', $atts['src'] ) ) { | ||
| $atts['video-type'] = 'vimeo'; | ||
| } | ||
| if ( strtolower( substr( $atts['src'], -3 ) ) === 'mp4' ) { | ||
| $atts['video-type'] = 'mp4'; | ||
| } | ||
|
|
||
| if ( empty( $atts['video-type'] ) ) { | ||
| return __( 'Please define a valid video type with video-type="#".', 'wp-mautic' ); | ||
| } | ||
|
|
||
| return sprintf( | ||
| '<video height="%1$s" width="%2$s"' . ( empty( $atts['form-id'] ) ? '' : ' data-form-id="%3$s"' ) . ' data-gate-time="%4$s" data-mautic-video="%5$s">' . | ||
| '<source type="video/%6$s" src="%7$s" />' . | ||
| '</video>', | ||
| esc_attr( $atts['height'] ), | ||
| esc_attr( $atts['width'] ), | ||
| esc_attr( $atts['form-id'] ), | ||
| esc_attr( $atts['gate-time'] ), | ||
| esc_attr( $atts['mautic-video'] ), | ||
| esc_attr( $atts['video-type'] ), | ||
| esc_attr( $atts['src'] ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Handle mautic tags by WordPress shortcodes | ||
| * example: [mautic type="tags" values="addtag,-removetag"] | ||
| * | ||
| * @param array $atts Shortcode attributes. | ||
| * | ||
| * @return string | ||
| */ | ||
| public function wpmautic_tags_shortcode( $atts ) { | ||
| $base_url = Options::get( 'base_url', '' ); | ||
| if ( '' === $base_url ) { | ||
| return false; | ||
| } | ||
|
|
||
| $atts = shortcode_atts( | ||
| array( | ||
| 'values' => '', | ||
| ), | ||
| $atts | ||
| ); | ||
|
|
||
| if ( empty( $atts['values'] ) ) { | ||
| return false; | ||
| } | ||
|
|
||
| return sprintf( | ||
| '<img src="%s/mtracking.gif?tags=%s" alt="%s" style="display:none;" />', | ||
| esc_url( $base_url ), | ||
| esc_attr( $atts['values'] ), | ||
| esc_attr__( 'Mautic Tags', 'wp-mautic' ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Handle mautic focus items on WordPress Page | ||
| * example: [mautic type="focus" id="1"] | ||
| * | ||
| * @param array $atts Shortcode attributes. | ||
| * | ||
| * @return string | ||
| */ | ||
| public function wpmautic_focus_shortcode( $atts ) { | ||
| $base_url = Options::get( 'base_url', '' ); | ||
| if ( '' === $base_url ) { | ||
| return false; | ||
| } | ||
|
|
||
| $atts = shortcode_atts( | ||
| array( | ||
| 'id' => '', | ||
| ), | ||
| $atts | ||
| ); | ||
|
|
||
| if ( empty( $atts['id'] ) ) { | ||
| return false; | ||
| } | ||
|
|
||
| return '<script type="text/javascript" ' . sprintf( | ||
| 'src="%s/focus/%s.js"', | ||
| esc_url( $base_url ), | ||
| esc_attr( $atts['id'] ) | ||
| ) . ' async="async"></script>'; | ||
| } | ||
|
|
||
| } No newline at end of file |
There was a problem hiding this comment.
Inconsistent indentation throughout the class: This class uses 2-space indentation instead of tabs or 4 spaces as required by WordPress Coding Standards. All methods and properties should be reformatted to follow WordPress indentation conventions for consistency.
| class Admin { | ||
|
|
||
| /** | ||
| * Init | ||
| * | ||
| * @return void | ||
| */ | ||
| public function init() { | ||
| add_action('admin_menu', array($this, 'wpmautic_settings')); | ||
| add_action('admin_init', array($this, 'wpmautic_admin_init')); | ||
| add_filter('plugin_action_links_' . plugin_basename(VPMAUTIC_PLUGIN_FILE), array($this, 'wpmautic_plugin_actions'), 10, 2); | ||
| } | ||
|
|
||
| /** | ||
| * Declare option page | ||
| */ | ||
| public function wpmautic_settings() { | ||
| add_options_page( | ||
| __( 'WP Mautic Settings', 'wp-mautic' ), | ||
| __( 'WPMautic', 'wp-mautic' ), | ||
| 'manage_options', | ||
| 'wpmautic', | ||
| array($this, 'wpmautic_options_page') | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * HTML for the Mautic option page | ||
| */ | ||
| public function wpmautic_options_page() { | ||
| ?> | ||
| <div> | ||
| <h2><?php esc_html_e( 'WP Mautic', 'wp-mautic' ); ?></h2> | ||
| <p><?php esc_html_e( 'Add Mautic tracking capabilities to your website.', 'wp-mautic' ); ?></p> | ||
| <form action="options.php" method="post"> | ||
| <?php settings_fields( 'wpmautic' ); ?> | ||
| <?php do_settings_sections( 'wpmautic' ); ?> | ||
| <?php submit_button(); ?> | ||
| </form> | ||
| <h3><?php esc_html_e( 'Shortcode Examples:', 'wp-mautic' ); ?></h3> | ||
| <ul> | ||
| <li><?php esc_html_e( 'Mautic Form Embed:', 'wp-mautic' ); ?> <code>[mautic type="form" id="1"]</code></li> | ||
| <li><?php esc_html_e( 'Mautic Dynamic Content:', 'wp-mautic' ); ?> <code>[mautic type="content" slot="slot_name"]<?php esc_html_e( 'Default Text', 'wp-mautic' ); ?>[/mautic]</code></li> | ||
| </ul> | ||
| <h3><?php esc_html_e( 'Quick Links', 'wp-mautic' ); ?></h3> | ||
| <ul> | ||
| <li> | ||
| <a href="https://github.com/mautic/mautic-wordpress#mautic-wordpress-plugin" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Plugin docs', 'wp-mautic' ); ?></a> | ||
| </li> | ||
| <li> | ||
| <a href="https://github.com/mautic/mautic-wordpress/issues" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Plugin support', 'wp-mautic' ); ?></a> | ||
| </li> | ||
| <li> | ||
| <a href="https://mautic.org" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Mautic project', 'wp-mautic' ); ?></a> | ||
| </li> | ||
| <li> | ||
| <a href="http://docs.mautic.org/" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Mautic docs', 'wp-mautic' ); ?></a> | ||
| </li> | ||
| <li> | ||
| <a href="https://www.mautic.org/community/" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Mautic forum', 'wp-mautic' ); ?></a> | ||
| </li> | ||
| </ul> | ||
| </div> | ||
| <?php | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Define admin_init hook logic | ||
| */ | ||
| public function wpmautic_admin_init() { | ||
| register_setting( 'wpmautic', 'wpmautic_options', array($this, 'wpmautic_options_validate') ); | ||
|
|
||
| add_settings_section( | ||
| 'wpmautic_main', | ||
| __( 'Main Settings', 'wp-mautic' ), | ||
| array($this, 'wpmautic_section_text'), | ||
| 'wpmautic' | ||
| ); | ||
|
|
||
| add_settings_field( | ||
| 'wpmautic_base_url', | ||
| __( 'Mautic URL', 'wp-mautic' ), | ||
| array($this, 'wpmautic_base_url'), | ||
| 'wpmautic', | ||
| 'wpmautic_main' | ||
| ); | ||
| add_settings_field( | ||
| 'wpmautic_script_location', | ||
| __( 'Tracking script location', 'wp-mautic' ), | ||
| array($this, 'wpmautic_script_location'), | ||
| 'wpmautic', | ||
| 'wpmautic_main' | ||
| ); | ||
| add_settings_field( | ||
| 'wpmautic_fallback_activated', | ||
| __( 'Tracking image', 'wp-mautic' ), | ||
| array($this, 'wpmautic_fallback_activated'), | ||
| 'wpmautic', | ||
| 'wpmautic_main' | ||
| ); | ||
| add_settings_field( | ||
| 'wpmautic_track_logged_user', | ||
| __( 'Logged user', 'wp-mautic' ), | ||
| array($this, 'wpmautic_track_logged_user'), | ||
| 'wpmautic', | ||
| 'wpmautic_main' | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Section text | ||
| */ | ||
| public function wpmautic_section_text() { | ||
| } | ||
|
|
||
| /** | ||
| * Define the input field for Mautic base URL | ||
| */ | ||
| public function wpmautic_base_url() { | ||
| $url = Options::get( 'base_url', '' ); | ||
|
|
||
| ?> | ||
| <input | ||
| id="wpmautic_base_url" | ||
| name="wpmautic_options[base_url]" | ||
| size="40" | ||
| type="text" | ||
| placeholder="https://..." | ||
| value="<?php echo esc_url_raw( $url, array( 'http', 'https' ) ); ?>" | ||
| /> | ||
| <?php | ||
| } | ||
|
|
||
| /** | ||
| * Define the input field for Mautic script location | ||
| */ | ||
| public function wpmautic_script_location() { | ||
| $position = Options::get( 'script_location', '' ); | ||
| $allowed_tags = array( | ||
| 'br' => array(), | ||
| 'code' => array(), | ||
| ); | ||
|
|
||
| ?> | ||
| <fieldset id="wpmautic_script_location"> | ||
| <label> | ||
| <input | ||
| type="radio" | ||
| name="wpmautic_options[script_location]" | ||
| value="header" | ||
| <?php | ||
| if ( 'footer' !== $position && 'disabled' !== $position ) : | ||
| ?> | ||
| checked<?php endif; ?> | ||
| /> | ||
| <?php echo wp_kses( __( 'Added in the <code>wp_head</code> action.<br/>Inserts the tracking code before the <code><head></code> tag; can be slightly slower since page load is delayed until all scripts in <code><head></code> are loaded and processed.', 'wp-mautic' ), $allowed_tags ); ?> | ||
| </label> | ||
| <br/> | ||
| <label> | ||
| <input | ||
| type="radio" | ||
| name="wpmautic_options[script_location]" | ||
| value="footer" | ||
| <?php | ||
| if ( 'footer' === $position ) : | ||
| ?> | ||
| checked<?php endif; ?> | ||
| /> | ||
| <?php echo wp_kses( __( 'Embedded within the <code>wp_footer</code> action.<br/>Inserts the tracking code before the <code></body></code> tag; slightly better for performance but may track less reliably if users close the page before the script has loaded.', 'wp-mautic' ), $allowed_tags ); ?> | ||
| </label> | ||
| <br /> | ||
| <label> | ||
| <input | ||
| type="radio" | ||
| name="wpmautic_options[script_location]" | ||
| value="disabled" | ||
| <?php | ||
| if ( 'disabled' === $position ) : | ||
| ?> | ||
| checked<?php endif; ?> | ||
| /> | ||
| <?php echo wp_kses( __( 'Visitor will not be tracked when rendering the page. Use this option to comply with GDPR regulations. If the visitor accept cookies you must execute the <code>wpmautic_send()</code> JavaScript function to start tracking.', 'wp-mautic' ), $allowed_tags ); ?> | ||
| <br/> | ||
| <?php echo wp_kses( __( 'However when using shortcodes, a tracking cookie will be added everytime even when tracking is disabled. This is because loading a Mautic resource (javascript or image) generate that cookie.', 'wp-mautic' ), $allowed_tags ); ?> | ||
| </label> | ||
| </fieldset> | ||
| <?php | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Define the input field for Mautic fallback flag | ||
| */ | ||
| public function wpmautic_fallback_activated() { | ||
| $flag = Options::get( 'fallback_activated', false ); | ||
| $allowed_tags = array( | ||
| 'br' => array(), | ||
| 'code' => array(), | ||
| ); | ||
|
|
||
| ?> | ||
| <select id="wpmautic_fallback_activated" name="wpmautic_options[fallback_activated]"> | ||
| <option value="0" <?php selected( $flag, '0' ); ?>><?php esc_html_e( 'Disabled', 'wp-mautic' ); ?></option> | ||
| <option value="1" <?php selected( $flag, '1' ); ?>><?php esc_html_e( 'Only When JavaScript is Disabled', 'wp-mautic' ); ?></option> | ||
| <option value="2" <?php selected( $flag, '2' ); ?>><?php esc_html_e( 'Replace mtc.js', 'wp-mautic' ); ?></option> | ||
| </select> | ||
| <br /> | ||
| <label for="wpmautic_fallback_activated"> | ||
| <?php echo wp_kses( __( 'Use "Replace mtc.js" if you want to use the tracking pixel as the default and only way to track even if JavaScript is enabled/disabled.', 'wp-mautic' ), $allowed_tags ); ?> | ||
| <br /> | ||
| <?php echo wp_kses( __( 'Be warned, that the tracking image will always generate a cookie on the user browser side. If you want to control cookies and comply to GDPR, you must use JavaScript instead.', 'wp-mautic' ), $allowed_tags ); ?> | ||
| </label> | ||
| <?php | ||
| } | ||
|
|
||
| /** | ||
| * Define the input field for Mautic logged user tracking flag | ||
| */ | ||
| public function wpmautic_track_logged_user() { | ||
| $flag = Options::get( 'track_logged_user', false ); | ||
|
|
||
| ?> | ||
| <input | ||
| id="wpmautic_track_logged_user" | ||
| name="wpmautic_options[track_logged_user]" | ||
| type="checkbox" | ||
| value="1" | ||
| <?php | ||
| if ( true === $flag ) : | ||
| ?> | ||
| checked<?php endif; ?> | ||
| /> | ||
| <label for="wpmautic_track_logged_user"> | ||
| <?php esc_html_e( 'Track user information for logged-in users', 'wp-mautic' ); ?> | ||
| </label> | ||
| <?php | ||
| } | ||
|
|
||
| /** | ||
| * Validate base URL input value | ||
| * | ||
| * @param array $input Input data. | ||
| * @return array | ||
| */ | ||
| public function wpmautic_options_validate( $input ) { | ||
| $options = get_option( 'wpmautic_options' ); | ||
|
|
||
| $input['base_url'] = isset( $input['base_url'] ) | ||
| ? trim( $input['base_url'], " \t\n\r\0\x0B/" ) | ||
| : ''; | ||
|
|
||
| $options['base_url'] = esc_url_raw( trim( $input['base_url'], " \t\n\r\0\x0B/" ) ); | ||
| $options['script_location'] = isset( $input['script_location'] ) | ||
| ? trim( $input['script_location'] ) | ||
| : 'header'; | ||
| if ( ! in_array( $options['script_location'], array( 'header', 'footer', 'disabled' ), true ) ) { | ||
| $options['script_location'] = 'header'; | ||
| } | ||
|
|
||
| if ( isset( $input['fallback_activated'] ) && in_array( $input['fallback_activated'], array( '0', '1', '2' ), true ) ) { | ||
| $options['fallback_activated'] = sanitize_text_field($input['fallback_activated']); | ||
| } else { | ||
| $options['fallback_activated'] = '0'; // Default to disabled | ||
| } | ||
|
|
||
| return $options; | ||
| } | ||
|
|
||
| /** | ||
| * Settings Link in the ``Installed Plugins`` page | ||
| * | ||
| * @param array $links array of plugin action links. | ||
| * | ||
| * @return array | ||
| */ | ||
| public function wpmautic_plugin_actions( $links ) { | ||
| if ( function_exists( 'admin_url' ) ) { | ||
| $settings_link = sprintf( | ||
| '<a href="%s">%s</a>', | ||
| admin_url( 'options-general.php?page=wpmautic' ), | ||
| __( 'Settings', 'wp-mautic' ) | ||
| ); | ||
| // Add the settings link before other links. | ||
| array_unshift( $links, $settings_link ); | ||
| } | ||
| return $links; | ||
| } | ||
|
|
||
| } No newline at end of file |
There was a problem hiding this comment.
Inconsistent indentation: The class uses mixed indentation with both tabs and spaces. Lines 15-17 use tabs, while other parts use 2-space indentation. WordPress Coding Standards require consistent use of tabs for indentation. The entire class should be reformatted to use tabs consistently.
|
|
||
| /** | ||
| * Init | ||
| * | ||
| * @return void | ||
| */ | ||
| public function init() { | ||
| $this->load_admin(); | ||
| } | ||
|
|
||
| /** | ||
| * Load Admin | ||
| * | ||
| * @return void | ||
| */ | ||
| public function load_admin() { | ||
| $admin = new Admin(); | ||
| $admin->init(); | ||
| } |
There was a problem hiding this comment.
Inconsistent indentation: This class uses 2-space indentation instead of tabs as required by WordPress Coding Standards. All methods and properties should be reformatted to use tabs for consistency.
| /** | |
| * Init | |
| * | |
| * @return void | |
| */ | |
| public function init() { | |
| $this->load_admin(); | |
| } | |
| /** | |
| * Load Admin | |
| * | |
| * @return void | |
| */ | |
| public function load_admin() { | |
| $admin = new Admin(); | |
| $admin->init(); | |
| } | |
| /** | |
| * Init | |
| * | |
| * @return void | |
| */ | |
| public function init() { | |
| $this->load_admin(); | |
| } | |
| /** | |
| * Load Admin | |
| * | |
| * @return void | |
| */ | |
| public function load_admin() { | |
| $admin = new Admin(); | |
| $admin->init(); | |
| } |
No description provided.