Plugin Directory

Changeset 3238690


Ignore:
Timestamp:
02/11/2025 04:15:49 PM (14 months ago)
Author:
termageddon
Message:

[1.6.0] Improved Implementation with v3 & Settings ID

Location:
termageddon-usercentrics
Files:
188 added
12 edited

Legend:

Unmodified
Added
Removed
  • termageddon-usercentrics/trunk/README.txt

    r3191623 r3238690  
    44Tags: termageddon, cookie, consent, embed, usercentrics
    55Requires at least: 3.0.1
    6 Tested up to: 6.7
    7 Stable tag: 1.5.4
     6Tested up to: 6.7.1
     7Stable tag: 1.6.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    2626
    2727== Changelog ==
     28
     29= 1.6.0 =
     30
     31-   [ADD] Added Usercentrics Consent API V3 with new and improved embed code.
     32-   [ADD] Added alternative injection method for alternate implementation of Usercentrics.
     33-   [CHANGE] Switch to using Settings ID instead of an embed code. Plugin will prompt for one-click conversion on visiting the settings page.
     34-   [ADD] Added support for new integrations: PowerPack Video, Ultimate Addons for Beaver Builder Video.
    2835
    2936= 1.5.4 =
  • termageddon-usercentrics/trunk/admin/class-termageddon-usercentrics-admin.php

    r3187188 r3238690  
    5050
    5151    /**
     52     * The tabs for the admin page.
     53     *
     54     * @since    1.0.0
     55     * @access   private
     56     * @var      array    $tabs    The tabs for the admin page.
     57     */
     58    private $tabs;
     59
     60    /**
    5261     * Initialize the class and set its properties.
    5362     *
     
    6170        $this->version     = $version;
    6271
     72        $this->tabs = array(
     73            'config'       => array(
     74                'title' => __( 'Configuration', 'termageddon-usercentrics' ),
     75                'url'   => '?page=termageddon-usercentrics',
     76            ),
     77            'integrations' => array(
     78                'title' => __( 'Integrations', 'termageddon-usercentrics' ),
     79                'url'   => '?page=termageddon-usercentrics&tab=integrations',
     80            ),
     81            'settings'     => array(
     82                'title' => __( 'Settings', 'termageddon-usercentrics' ),
     83                'url'   => '?page=termageddon-usercentrics&tab=settings',
     84            ),
     85            'geolocation'  => array(
     86                'title' => __( 'Geo-Location', 'termageddon-usercentrics' ),
     87                'url'   => '?page=termageddon-usercentrics&tab=geolocation',
     88            ),
     89            'admin'        => array(
     90                'title'  => __( 'Advanced Configuration & Troubleshooting', 'termageddon-usercentrics' ),
     91                'url'    => '?page=termageddon-usercentrics&tab=admin',
     92                'hidden' => true,
     93            ),
     94        );
     95
    6396        // Calculate current tab.
    64         $default_tab = 'embed';
     97        $default_tab = array_keys( $this->tabs )[0];
    6598        $tab         = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : $default_tab;
    6699
     
    156189            <h1>' . esc_html__( 'Termageddon + Usercentrics', 'termageddon-usercentrics' ) . '</h1>';
    157190
    158             // Get the active tab from the $_GET param.
     191        // Get the active tab from the $_GET param.
    159192
    160193        // Invalid tab error message.
    161         if ( ! in_array( $this->current_tab, array( 'embed', 'settings', 'geolocation', 'admin' ), true ) ) {
     194        if ( ! in_array( $this->current_tab, array_keys( $this->tabs ) ) ) {
    162195            echo '<div class="error notice">' . esc_html__( 'Invalid tab. Please check the link and try again.', 'termageddon-usercentrics' ) . '</div>';
    163196            return;
     
    168201        ?>
    169202        <nav class="nav-tab-wrapper">
    170             <a href="?page=termageddon-usercentrics" class="nav-tab <?php echo ( 'embed' === $this->current_tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e( 'Embed Code', 'termageddon-usercentrics' ); ?></a>
    171             <a href="?page=termageddon-usercentrics&tab=settings" class="nav-tab <?php echo( 'settings' === $this->current_tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e( 'Settings', 'termageddon-usercentrics' ); ?></a>
    172             <a href="?page=termageddon-usercentrics&tab=geolocation" class="nav-tab <?php echo ( 'geolocation' === $this->current_tab ? 'nav-tab-active' : '' ); ?>"><?php esc_html_e( 'Geo-Location', 'termageddon-usercentrics' ); ?></a>
     203        <?php
     204        foreach ( $this->tabs as $tab_key => $tab ) {
     205            if ( ! isset( $tab['hidden'] ) ) {
     206                echo '<a href="' . esc_url( $tab['url'] ) . '" class="nav-tab ' . ( $tab_key === $this->current_tab ? 'nav-tab-active' : '' ) . '">' . esc_html( $tab['title'] ) . '</a>';
     207            }
     208        }
     209        ?>
    173210        </nav>
    174211
     
    199236        }
    200237        echo '<form method="post" action="options.php">';
    201                 settings_fields( 'termageddon_usercentrics_settings' ); // Settings group name.
    202                 do_settings_sections( 'termageddon-usercentrics' ); // page slug.
    203                 submit_button();
     238            settings_fields( 'termageddon_usercentrics_settings' ); // Settings group name.
     239            do_settings_sections( 'termageddon-usercentrics' ); // page slug.
     240            submit_button();
    204241        echo '
    205242                </form>
     
    296333     * @return void  */
    297334    public function register_all_settings() {
    298 
    299         $this->register_settings_embed();
    300         $this->register_settings_settings();
    301         $this->register_settings_geolocation();
    302         $this->register_settings_admin();
    303 
     335        // Based on the tab, call the appropriate register_settings function.
     336        foreach ( $this->tabs as $tab_key => $tab ) {
     337            call_user_func( array( $this, "register_settings_{$tab_key}" ) );
     338        }
    304339    }
    305340
     
    360395     * @return void
    361396     */
    362     public function register_settings_embed() {
     397    public function register_settings_config() {
    363398
    364399        // Build Settings Sections.
    365400        add_settings_section(
    366401            'termageddon_usercentrics_section_embed', // section ID.
    367             'Embed Code', // title (if needed).
     402            'Configuration', // title (if needed).
    368403            array( &$this, 'embed_description_html' ), // callback function (if needed).
    369404            'termageddon-usercentrics', // page slug.
    370             $this->build_section_args( 'embed' ) // before and after sections.
     405            $this->build_section_args( 'config' )
     406        );
     407
     408        // Settings ID Field.
     409        add_settings_field(
     410            'termageddon_usercentrics_settings_id',
     411            __( 'Settings ID', 'termageddon-usercentrics' ),
     412            array( &$this, 'settings_id_html' ),
     413            'termageddon-usercentrics', // page slug.
     414            'termageddon_usercentrics_section_embed', // section ID.
     415            array(
     416                'label_for'   => 'termageddon_usercentrics_settings_id',
     417                'description' => __( 'Enter your Usercentrics Settings ID. This can be found on the "View Embed Code" page of your Cookie Policy and Consent Tool questionnaire.', 'termageddon-usercentrics' ) . self::generate_conversion_script(),
     418                'type'        => 'text',
     419                'option'      => 'settings_id', // Pass option name for generate_input.
     420            )
     421        );
     422
     423        register_setting(
     424            'termageddon_usercentrics_settings', // settings group name.
     425            'termageddon_usercentrics_settings_id', // option name.
     426            array(
     427                'type'              => 'string',
     428                'sanitize_callback' => array( &$this, 'sanitize_text' ),
     429            )
    371430        );
    372431
     
    374433        add_settings_field(
    375434            'termageddon_usercentrics_embed_code',
    376             __( 'Embed Code', 'termageddon-usercentrics' ),
     435            Termageddon_Usercentrics::check_for_conversion_needed() ? __( 'Embed Code (Legacy)', 'termageddon-usercentrics' ) : __( 'Additional Scripts', 'termageddon-usercentrics' ),
    377436            array( &$this, 'embed_code_html' ), // function which prints the field.
    378437            'termageddon-usercentrics', // page slug.
    379438            'termageddon_usercentrics_section_embed', // section ID.
    380439            array(
    381                 'label_for' => 'termageddon_usercentrics_embed_code',
     440                'label_for'   => 'termageddon_usercentrics_embed_code',
     441                'description' => Termageddon_Usercentrics::check_for_conversion_needed() ? __( 'This section should no longer be used for the embed code from the Termageddon dashboard. We recommend migrating to the new Settings ID format using the button above.', 'termageddon-usercentrics' ) : __( 'This section can be used to add customizations to your Usercentrics embed code, such as event handling, and other customizations. Reach out to our support team for more information.', 'termageddon-usercentrics' ),
    382442            )
    383443        );
     
    390450
    391451    }
    392 
    393452
    394453    /**
     
    481540            array(
    482541                'label_for'   => 'termageddon_usercentrics_location_psl_hide',
    483                 'description' => __( 'When enabled, the Privacy Settings link will be hidden from certain users, whether that be certain logged in users (via your selections above in the “Hide widget for:” area) or if you enabled geolocation and are hiding the consent tool from certain visitors. For example, if you enable the option to hide the consent tool for logged in administrator (and enable this toggle), the Privacy Settings link will <strong>not</strong> show to logged in administrators.  If you enable the option to hide the consent tool based on geolocation for certain users, the Privacy Settings link will no longer be displayed to those respective users as well.', 'termageddon-usercentrics' ),
     542                'description' => __( 'When enabled, the Privacy Settings link will be hidden from certain users, whether that be certain logged in users (via your selections above in the "Hide widget for:" area) or if you enabled geolocation and are hiding the consent tool from certain visitors. For example, if you enable the option to hide the consent tool for logged in administrator (and enable this toggle), the Privacy Settings link will <strong>not</strong> show to logged in administrators.  If you enable the option to hide the consent tool based on geolocation for certain users, the Privacy Settings link will no longer be displayed to those respective users as well.', 'termageddon-usercentrics' ),
    484543            )
    485544        );
     
    510569        );
    511570
    512         // BREAK SECTION FOR INTEGRATION SETTINGS.
    513         $this->add_new_subsection(
    514             'termageddon_usercentrics_section_settings',
    515             array(
    516                 'name'        => 'Integrations',
    517                 'description' => 'We love to partner with other plugin developers to improve support with their plugins. If you encounter an issue, please contact our support to let us know.',
    518             )
    519         );
    520 
    521         // Divi Video Overlay Integration Player.
    522         add_settings_field(
    523             'termageddon_usercentrics_integration_divi_video',
    524             __( 'Divi Video Player Integration', 'termageddon-usercentrics' ) . '<br>
    525             <em>' . __( 'This resolves and improves the cookie-consent implementation when using an image placeholder overlay for the Divi video embed.', 'termageddon-usercentrics' ) . '</em>',
    526             array( &$this, 'divi_video_support' ), // function which prints the field.
    527             'termageddon-usercentrics', // page slug.
    528             'termageddon_usercentrics_section_settings', // section ID.
    529             array(
    530                 'label_for' => 'termageddon_usercentrics_integration_divi_video',
    531             )
    532         );
    533 
    534         register_setting(
    535             'termageddon_usercentrics_settings', // settings group name.
    536             'termageddon_usercentrics_integration_divi_video', // option name.
    537             '' // sanitization function.
    538         );
    539 
    540         // Elementor Video Overlay Integration Player.
    541         add_settings_field(
    542             'termageddon_usercentrics_integration_elementor_video',
    543             __( 'Elementor Video Player Integration', 'termageddon-usercentrics' ) . $this->mark_as_beta() . '<br>
    544             <em>' . __( 'This resolves and improves the cookie-consent implementation when using an image placeholder overlay for the Elementor video embed.', 'termageddon-usercentrics' ) . '</em>',
    545             array( &$this, 'elementor_video_support' ), // function which prints the field.
    546             'termageddon-usercentrics', // page slug.
    547             'termageddon_usercentrics_section_settings', // section ID.
    548             array(
    549                 'label_for' => 'termageddon_usercentrics_integration_elementor_video',
    550             )
    551         );
    552 
    553         register_setting(
    554             'termageddon_usercentrics_settings', // settings group name.
    555             'termageddon_usercentrics_integration_elementor_video', // option name.
    556             '' // sanitization function.
    557         );
    558 
    559         // Presto Player.
    560         add_settings_field(
    561             'termageddon_usercentrics_integration_presto_player',
    562             __( 'Presto Player', 'termageddon-usercentrics' ),
    563             array( &$this, 'presto_player_support' ), // function which prints the field.
    564             'termageddon-usercentrics', // page slug.
    565             'termageddon_usercentrics_section_settings', // section ID.
    566             array(
    567                 'label_for' => 'termageddon_usercentrics_integration_presto_player',
    568             )
    569         );
    570 
    571         register_setting(
    572             'termageddon_usercentrics_settings', // settings group name.
    573             'termageddon_usercentrics_integration_presto_player', // option name.
    574             '' // sanitization function.
    575         );
    576 
    577571        // BREAK SECTION FOR OTHER SETTINGS.
    578572        $this->add_new_subsection(
     
    584578        );
    585579
    586         // Privacy Settings Link Disable.
     580        // Embed Code Priority.
    587581        add_settings_field(
    588582            'termageddon_usercentrics_embed_priority',
    589             __( 'Embed Code Priority', 'termageddon-usercentrics' ) . $this->mark_as_beta(),
     583            __( 'Embed Code Priority', 'termageddon-usercentrics' ),
    590584            array( &$this, 'embed_priority_html' ), // function which prints the field.
    591585            'termageddon-usercentrics', // page slug.
     
    607601        );
    608602
     603        // Embed Code Injection Method.
     604        add_settings_field(
     605            'termageddon_usercentrics_embed_injection_method',
     606            __( 'Embed Code Injection Method', 'termageddon-usercentrics' ) . $this->mark_as_beta(),
     607            array( &$this, 'embed_implementation_html' ), // function which prints the field.
     608            'termageddon-usercentrics', // page slug.
     609            'termageddon_usercentrics_section_settings', // section ID.
     610            array(
     611                'label_for'   => 'termageddon_usercentrics_embed_injection_method',
     612                'description' => __( 'The default injection option, wp_head, will inject the embed code in the wp_head action which typically runs before any other action. Alternatively, wp_enqueue_scripts will inject the embed code along with other scripts, leading to more compatibility with certain websites.', 'termageddon-usercentrics' ),
     613                'options'     => array(
     614                    'wp_head'            => __( 'wp_head (Default)', 'termageddon-usercentrics' ),
     615                    'wp_enqueue_scripts' => __( 'wp_enqueue_scripts', 'termageddon-usercentrics' ),
     616                ),
     617                'default'     => 'wp_head',
     618            )
     619        );
     620
     621        register_setting(
     622            'termageddon_usercentrics_settings', // settings group name.
     623            'termageddon_usercentrics_embed_injection_method', // option name.
     624            array(
     625                'type'              => 'string',
     626                'sanitize_callback' => array( &$this, 'sanitize_text' ),
     627                'default'           => 'wp_head',
     628            )
     629        );
     630
     631        // Embed Code Version Field.
     632        add_settings_field(
     633            'termageddon_usercentrics_embed_version',
     634            __( 'Embed Code Version', 'termageddon-usercentrics' ),
     635            array( &$this, 'embed_version_html' ),
     636            'termageddon-usercentrics',
     637            'termageddon_usercentrics_section_settings',
     638            array(
     639                'label_for'   => 'termageddon_usercentrics_embed_version',
     640                'description' => __( 'Select which version of the Usercentrics embed code you would like to use.', 'termageddon-usercentrics' ),
     641                'options'     => array(
     642                    'v2' => __( 'v2', 'termageddon-usercentrics' ),
     643                    'v3' => __( 'v3 (Beta)', 'termageddon-usercentrics' ),
     644                ),
     645                'default'     => 'v2',
     646            )
     647        );
     648
     649        register_setting(
     650            'termageddon_usercentrics_settings',
     651            'termageddon_usercentrics_embed_version',
     652            array(
     653                'type'              => 'string',
     654                'sanitize_callback' => array( &$this, 'sanitize_text' ),
     655                'default'           => 'v2',
     656            )
     657        );
     658
     659        // Disable Troubleshooting.
    609660        add_settings_field(
    610661            'termageddon_usercentrics_disable_troubleshooting',
     
    750801    }
    751802    /**
     803     * Register all settings for the integrations tab.
     804     *
     805     * @return void
     806     */
     807    public function register_settings_integrations() {
     808        // Build Settings Section.
     809        add_settings_section(
     810            'termageddon_usercentrics_section_integrations', // section ID.
     811            __( 'Integrations', 'termageddon-usercentrics' ), // title.
     812            array( &$this, 'settings_integrations_html' ), // callback function.
     813            'termageddon-usercentrics', // page slug.
     814            $this->build_section_args( 'integrations' ) // section args.
     815        );
     816
     817        // BREAK SECTION FOR INTEGRATION SETTINGS.
     818        $this->add_new_subsection(
     819            'termageddon_usercentrics_section_integrations',
     820            array(
     821                'name'        => __( 'Plugin & Theme Integrations', 'termageddon-usercentrics' ),
     822                'description' => __( 'If you have a script or code snippet to share, would like to improve support with your plugin/theme, or run into an issue implementing Termageddon/Usercentrics, please contact our support team.', 'termageddon-usercentrics' ),
     823            )
     824        );
     825
     826        // Add settings fields for all integrations.
     827        foreach ( Termageddon_Usercentrics::get_integrations() as $integration => $integration_config ) {
     828            list( 'name' => $display_name, 'description' => $description, 'beta' => $beta ) = $integration_config;
     829
     830            add_settings_field(
     831                'termageddon_usercentrics_integration_' . $integration,
     832                $display_name . ' ' . __( 'Integration', 'termageddon-usercentrics' ) . ( $beta ? $this->mark_as_beta() : '' ) . ( $description ? '<br>
     833                <em>' . $description . '</em>' : '' ),
     834                array( &$this, 'integration_support' ), // function which prints the field.
     835                'termageddon-usercentrics', // page slug.
     836                'termageddon_usercentrics_section_integrations', // section ID.
     837                array(
     838                    'label_for'   => 'termageddon_usercentrics_integration_' . $integration,
     839                    'integration' => $integration,
     840                )
     841            );
     842
     843            register_setting(
     844                'termageddon_usercentrics_settings', // settings group name.
     845                'termageddon_usercentrics_integration_' . $integration, // option name.
     846                '' // sanitization function.
     847            );
     848        }
     849
     850    }
     851
     852    /**
     853     * The html for above the integrations settings.
     854     *
     855     * @return void
     856     */
     857    public function settings_integrations_html() {
     858        echo '<p>' .
     859            esc_html__( 'On this page, you can find custom implementation to improve support and compatibility with various plugins and page-builders.', 'termageddon-usercentrics' ) .
     860        '</p>';
     861
     862        echo '<div class="tu-section-settings">
     863            <div class="tu-section">
     864            ';
     865
     866    }
     867
     868    /**
    752869     * Register all settings for the admin tab.
    753870     *
     
    826943        $tip         = ( isset( $args['tip'] ) ? $args['tip'] : null );
    827944        $description = ( isset( $args['description'] ) ? $args['description'] : null );
     945        $placeholder = ( isset( $args['placeholder'] ) ? $args['placeholder'] : null );
    828946
    829947        // Is the option currently active?
     
    836954            name="' . esc_attr( $option_name ) . '"
    837955            value="' . esc_attr( $value ) . '"
     956            ' . ( is_null( $placeholder ) ? '' : 'placeholder="' . esc_attr( $placeholder ) . '"' ) . '
    838957            ' . ( is_null( $min ) ? '' : 'min="' . esc_attr( $min ) . '"' ) . '
    839958            ' . ( is_null( $max ) ? '' : 'max="' . esc_attr( $max ) . '"' ) . '
     
    848967
    849968    }
     969
     970    /**
     971     * Helper method to easily generate a quick select field.
     972     *
     973     * @param string $option - The option name/location you are building the select for.
     974     * @param array  $args The arguments provided by the add_settings_field() method.
     975     * @return void
     976     */
     977    private static function generate_select( string $option, array $args = array() ) {
     978        $option_name = 'termageddon_usercentrics_' . $option;
     979
     980        // Options.
     981        $default     = ( isset( $args['default'] ) ? $args['default'] : null );
     982        $options     = ( isset( $args['options'] ) ? $args['options'] : array() );
     983        $tip         = ( isset( $args['tip'] ) ? $args['tip'] : null );
     984        $description = ( isset( $args['description'] ) ? $args['description'] : null );
     985
     986        // Get current value.
     987        $value = get_option( $option_name, $default );
     988
     989        echo '<select id="' . esc_attr( $option_name ) . '" name="' . esc_attr( $option_name ) . '" class="regular-text">';
     990
     991        foreach ( $options as $option_value => $label ) {
     992            printf(
     993                '<option value="%s" %s>%s</option>',
     994                esc_attr( $option_value ),
     995                selected( $value, $option_value, false ),
     996                esc_html( $label )
     997            );
     998        }
     999
     1000        echo '</select>';
     1001
     1002        if ( $tip ) {
     1003            echo '<b class="wntip" data-title="' . esc_attr( $tip ) . '"> ? </b>';
     1004        }
     1005        if ( $description ) {
     1006            echo '<p class="description">' . wp_kses_post( $description ) . '</p>';
     1007        }
     1008    }
     1009
    8501010    /**
    8511011     * Helper method to easily generate a quick checkbox.
     
    9131073
    9141074    /**
    915      * The HTML field for the admin disable checkbox.
     1075     * Generate the HTML for the integration support checkbox.
    9161076     *
    9171077     * @param array $args The arguments provided by the add_settings_field() method.
    9181078     * @return void
    9191079     */
    920     public function divi_video_support( array $args ) {
     1080    public function integration_support( array $args ) {
    9211081        $args['label'] = 'enabled';
    922         self::generate_checkbox( 'divi_video', 'integration', $args );
    923     }
    924 
    925     /**
    926      * The HTML field for the admin disable checkbox.
    927      *
    928      * @param array $args The arguments provided by the add_settings_field() method.
    929      * @return void
    930      */
    931     public function elementor_video_support( array $args ) {
    932         $args['label'] = 'enabled';
    933         self::generate_checkbox( 'elementor_video', 'integration', $args );
    934     }
    935 
    936     /**
    937      * The HTML field for the admin disable checkbox.
    938      *
    939      * @param array $args The arguments provided by the add_settings_field() method.
    940      * @return void
    941      */
    942     public function presto_player_support( array $args ) {
    943         $args['label'] = 'enabled';
    944         self::generate_checkbox( 'presto_player', 'integration', $args );
     1082        self::generate_checkbox( $args['integration'], 'integration', $args );
    9451083    }
    9461084
     
    9721110        self::generate_checkbox( 'alternate', 'psl', $args );
    9731111    }
    974     /**
    975      * The HTML field for the disable troubleshooting checkbox.
     1112
     1113    /**
     1114     * Generate the conversion script.
     1115     *
     1116     * @return string
     1117     */
     1118    public function generate_conversion_script() {
     1119        if ( Termageddon_Usercentrics::check_for_conversion_needed() ) {
     1120            return '
     1121            <div class="notice notice-warning is-dismissible">
     1122                <p><strong>' . esc_html__( 'Action Needed', 'termageddon-usercentrics' ) . '</strong></p>
     1123                <p>' . esc_html__( 'We are moving to using a Settings ID instead of an embed code format to allow for more features.', 'termageddon-usercentrics' ) . '<br><strong>' . esc_html__( 'This update will take a few seconds to complete.', 'termageddon-usercentrics' ) . '</strong></p>
     1124                <p><a href="?page=termageddon-usercentrics" class="button button-primary">' . esc_html__( 'Go to Configuration', 'termageddon-usercentrics' ) . '</a></p>
     1125            </div>
     1126           
     1127            <div class="description migration-message tu-alert-warning">
     1128                <p class="alert-title"><strong>' . esc_html__( 'Conversion Needed:', 'termageddon-usercentrics' ) . '</strong></p>
     1129                <p class="alert-description">' .
     1130                    esc_html__( 'It looks like you are still using the old embed code (below) instead of the Settings ID. To automatically switch update your configuration, please click the button bellow.', 'termageddon-usercentrics' ) . '<br/><br/>' .
     1131                    esc_html__( 'Behind the scenes, we will remove the Usercentrics embed code from the field below, ensuring custom scripts are maintained.', 'termageddon-usercentrics' ) . '<br/><br/>
     1132                    <a href="#" class="button button-small button-warning" id="run_settings_migration">' . esc_html__( 'Convert', 'termageddon-usercentrics' ) . '</a>
     1133                </p>
     1134            </div>';
     1135        }
     1136    }
     1137    /**
     1138     * The HTML field for the settings ID field.
     1139     *
     1140     * @param array $args The arguments provided by the add_settings_field() method.
     1141     * @return void
     1142     */
     1143    public function settings_id_html( array $args ) {
     1144        $args['default']     = '';
     1145        $args['placeholder'] = 'XXXXXXXXXXXXXX';
     1146        $args['type']        = 'text';
     1147
     1148        self::generate_input( 'settings_id', $args );
     1149    }
     1150    /**
     1151     * The HTML field for the priority number field.
    9761152     *
    9771153     * @param array $args The arguments provided by the add_settings_field() method.
     
    9861162        self::generate_input( 'embed_priority', $args );
    9871163    }
     1164
     1165    /**
     1166     * The HTML field for the embed implementation select.
     1167     *
     1168     * @param array $args The arguments provided by the add_settings_field() method.
     1169     * @return void
     1170     */
     1171    public function embed_implementation_html( array $args ) {
     1172        self::generate_select( 'embed_injection_method', $args );
     1173    }
     1174
    9881175    /**
    9891176     * The HTML field for the disable troubleshooting checkbox.
     
    10201207     * The embed code html for the text area field
    10211208     *
    1022      * @return void
    1023      */
    1024     public function embed_code_html() {
    1025 
    1026         $text = get_option( 'termageddon_usercentrics_embed_code' );
     1209     * @param array $args The arguments provided by the add_settings_field() method.
     1210     * @return void
     1211     */
     1212    public function embed_code_html( array $args ) {
     1213        $text = Termageddon_Usercentrics::get_embed_code();
     1214
     1215        $description = ( isset( $args['description'] ) ? $args['description'] : null );
    10271216
    10281217        printf(
    1029             '<textarea class="termageddon-embed-code" type="text" id="termageddon_usercentrics_embed_code" name="termageddon_usercentrics_embed_code" placeholder="' . esc_attr( 'Your embed code should look similar to this', 'termageddon-usercentrics' ) . ':
    1030 
    1031 &lt;link rel=&quot;preconnect&quot; href=&quot;//privacy-proxy.usercentrics.eu&quot;&gt;
    1032 &lt;link rel=&quot;preload&quot; href=&quot;//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js&quot; as=&quot;script&quot;&gt;
    1033 &lt;script type=&quot;application/javascript&quot; src=&quot;https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js&quot;&gt;&lt;/script&gt;
    1034 &lt;script id=&quot;usercentrics-cmp&quot; src=&quot;https://app.usercentrics.eu/browser-ui/latest/loader.js&quot; data-settings-id=&quot;XXXXXXXXX&quot; async&gt;&lt;/script&gt;">%s</textarea>',
     1218            '<textarea class="termageddon-embed-code" type="text" id="termageddon_usercentrics_embed_code" name="termageddon_usercentrics_embed_code" placeholder="' . esc_attr( 'This section can be used to add customizations to your Usercentrics embed code, such as event handling, and other customizations. Reach out to our support team for more information.', 'termageddon-usercentrics' ) . '">%s</textarea>',
    10351219            esc_textarea( $text )
    10361220        );
    10371221
     1222        if ( $description ) {
     1223            echo '<p>' . wp_kses_post( $description ) . '</p>';
     1224        }
     1225
     1226    }
     1227
     1228    /**
     1229     * The HTML field for the embed version select.
     1230     *
     1231     * @param array $args The arguments provided by the add_settings_field() method.
     1232     * @return void
     1233     */
     1234    public function embed_version_html( array $args ) {
     1235        self::generate_select( 'embed_version', $args );
    10381236    }
    10391237
     
    10651263
    10661264    }
    1067 
    10681265
    10691266    /**
     
    10961293        esc_html__( 'If you would like to remove Usercentrics for logged in users such as admins, you can do so below.', 'termageddon-usercentrics' ) .
    10971294        ' <strong>' . esc_html__( 'If you are using the Divi theme', 'termageddon-usercentrics' ) . '</strong>, ' .
    1098         esc_html__( 'you will need to enable at least one of the settings below to ensure logged in users/admins can properly use the “Enable Visual Builder” feature provided by Divi when editing the design of a webpage.', 'termageddon-usercentrics' ) . '
     1295        esc_html__( 'you will need to enable at least one of the settings below to ensure logged in users/admins can properly use the "Enable Visual Builder" feature provided by Divi when editing the design of a webpage.', 'termageddon-usercentrics' ) . '
    10991296            </p>';
    11001297
     
    11461343    }
    11471344
    1148 
    1149 
    1150 
    11511345}
  • termageddon-usercentrics/trunk/admin/css/termageddon-usercentrics-admin.css

    r3160131 r3238690  
    1313.tu-section-settings {
    1414    margin-top: 2rem;
     15}
     16
     17/* Hide Extra spacing for the Integration section */
     18.tu-settings-tab.tu-tab-integrations .tu-section {
     19    display: none;
    1520}
    1621
     
    186191    font-weight: 400;
    187192}
     193
     194.tu-alert-error {
     195    color: #d63638;
     196    background: #fcf0f1;
     197    padding: 10px;
     198    border-left: 4px solid #d63638;
     199    margin: 10px 0;
     200}
     201
     202.tu-alert-warning {
     203    color: #856404;
     204    background: #fff3cd;
     205    padding: 10px;
     206    border-left: 4px solid #ffc107;
     207    margin: 10px 0;
     208}
     209
     210.tu-alert-success {
     211    color: #00a32a;
     212    background: #edfaef;
     213    padding: 10px;
     214    border-left: 4px solid #00a32a;
     215    margin: 10px 0;
     216}
     217
     218.button-danger {
     219    background: #d63638 !important;
     220    border-color: #d63638 !important;
     221    color: #fff !important;
     222}
     223
     224.button-danger:hover,
     225.button-danger:focus {
     226    background: #b32d2e !important;
     227    border-color: #b32d2e !important;
     228    color: #fff !important;
     229}
     230
     231.button-warning {
     232    background: #ffc107 !important;
     233    border-color: #ffc107 !important;
     234    color: #333 !important;
     235    font-weight: 700;
     236}
     237
     238.button-warning:hover,
     239.button-warning:focus {
     240    background: #e0a800 !important;
     241    border-color: #e0a800 !important;
     242    color: black !important;
     243}
  • termageddon-usercentrics/trunk/admin/css/termageddon-usercentrics-admin.min.css

    r3160131 r3238690  
    1 textarea.termageddon-embed-code{width:100%;height:250px}.tu-section-settings,.tu-toggle-section{margin-top:2rem}.tu-toggle-section .tu-section-title{font-size:125%;font-weight:800}.tu-toggle-section .tu-section-title-helper{padding:1rem;color:#6c6c6c;font-style:italic}.tu-toggle-section input[readonly]{opacity:50%;pointer-events:none}.tu-toggle-section .form-table{margin-left:2rem}.tu-toggle-section .form-table td,.tu-toggle-section .form-table th{padding:.5rem 0}.tu-toggle-section .form-table th{width:300px}.tu-toggle-section.slim-section .form-table th{width:125px}.tu-settings-section .form-table th{width:300px}.tu-section-hidden{display:none}.tu-label-success{background-color:#3db44c;color:#fff;padding:3px 5px;border-radius:5px;font-size:60%}.tu-label-info{background-color:#019ed5;color:#fff;padding:3px 5px;border-radius:5px;font-size:60%}.tu-label-warning{background-color:orange;color:#fff;padding:3px 5px;border-radius:5px;font-size:60%}input[type=checkbox].wppd-ui-toggle{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;width:auto;height:auto;vertical-align:middle;position:relative;border:0;outline:0;cursor:pointer;margin:0 4px;background:0 0;box-shadow:none}input[type=checkbox].wppd-ui-toggle:focus{box-shadow:none}input[type=checkbox].wppd-ui-toggle:after{content:"";font-size:6px;font-weight:400;line-height:18px;text-indent:-14px;color:#fff;width:36px;height:18px;display:inline-block;background-color:#a7aaad;border-radius:72px;box-shadow:0 0 12px rgb(0 0 0 / 15%) inset}input[type=checkbox].wppd-ui-toggle:before{content:"";width:14px;height:14px;display:block;position:absolute;top:2px;left:2px;margin:0;border-radius:50%;background-color:#fff}input[type=checkbox].wppd-ui-toggle:checked:before{left:20px;margin:0;background-color:#fff}input[type=checkbox].wppd-ui-toggle,input[type=checkbox].wppd-ui-toggle:after,input[type=checkbox].wppd-ui-toggle:before,input[type=checkbox].wppd-ui-toggle:checked:after,input[type=checkbox].wppd-ui-toggle:checked:before{transition:ease .15s}input[type=checkbox].wppd-ui-toggle:checked:after{content:"ON";background-color:#2271b1}input[type=checkbox].wppd-ui-toggle.label-hidden:after{width:48px}input[type=checkbox].wppd-ui-toggle.label-hidden:checked:before{left:32px}input[type=checkbox].wppd-ui-toggle.label-hidden:checked:after{content:"HIDDEN"}input[type=checkbox].wppd-ui-toggle.label-enabled:after{font-size:8px;width:60px;content:"DISABLED";text-indent:15px}input[type=checkbox].wppd-ui-toggle.label-enabled:checked:before{left:44px}input[type=checkbox].wppd-ui-toggle.label-enabled:checked:after{background-color:#1ed14b;content:"ENABLED";text-indent:-14px}.notice-inline{border-top:1px solid #c3c4c7;border-bottom:1px solid #c3c4c7;border-right:1px solid #c3c4c7;border-left-width:4px;border-left-style:solid;background:#fff;box-shadow:0 1px 1px rgba(0,0,0,.04);margin:5px 15px 2px;padding:1px 12px}.tu-settings-section label em{font-size:12px;font-weight:400}
     1textarea.termageddon-embed-code{width:100%;height:250px}.tu-section-settings,.tu-toggle-section{margin-top:2rem}.tu-settings-tab.tu-tab-integrations .tu-section{display:none}.tu-toggle-section .tu-section-title{font-size:125%;font-weight:800}.tu-toggle-section .tu-section-title-helper{padding:1rem;color:#6c6c6c;font-style:italic}.tu-toggle-section input[readonly]{opacity:50%;pointer-events:none}.tu-toggle-section .form-table{margin-left:2rem}.tu-toggle-section .form-table td,.tu-toggle-section .form-table th{padding:.5rem 0}.tu-toggle-section .form-table th{width:300px}.tu-toggle-section.slim-section .form-table th{width:125px}.tu-settings-section .form-table th{width:300px}.tu-section-hidden{display:none}.tu-label-success{background-color:#3db44c;color:#fff;padding:3px 5px;border-radius:5px;font-size:60%}.tu-label-info{background-color:#019ed5;color:#fff;padding:3px 5px;border-radius:5px;font-size:60%}.tu-label-warning{background-color:orange;color:#fff;padding:3px 5px;border-radius:5px;font-size:60%}input[type=checkbox].wppd-ui-toggle{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-tap-highlight-color:transparent;width:auto;height:auto;vertical-align:middle;position:relative;border:0;outline:0;cursor:pointer;margin:0 4px;background:0 0;box-shadow:none}input[type=checkbox].wppd-ui-toggle:focus{box-shadow:none}input[type=checkbox].wppd-ui-toggle:after{content:"";font-size:6px;font-weight:400;line-height:18px;text-indent:-14px;color:#fff;width:36px;height:18px;display:inline-block;background-color:#a7aaad;border-radius:72px;box-shadow:0 0 12px rgb(0 0 0 / 15%) inset}input[type=checkbox].wppd-ui-toggle:before{content:"";width:14px;height:14px;display:block;position:absolute;top:2px;left:2px;margin:0;border-radius:50%;background-color:#fff}input[type=checkbox].wppd-ui-toggle:checked:before{left:20px;margin:0;background-color:#fff}input[type=checkbox].wppd-ui-toggle,input[type=checkbox].wppd-ui-toggle:after,input[type=checkbox].wppd-ui-toggle:before,input[type=checkbox].wppd-ui-toggle:checked:after,input[type=checkbox].wppd-ui-toggle:checked:before{transition:ease .15s}input[type=checkbox].wppd-ui-toggle:checked:after{content:"ON";background-color:#2271b1}input[type=checkbox].wppd-ui-toggle.label-hidden:after{width:48px}input[type=checkbox].wppd-ui-toggle.label-hidden:checked:before{left:32px}input[type=checkbox].wppd-ui-toggle.label-hidden:checked:after{content:"HIDDEN"}input[type=checkbox].wppd-ui-toggle.label-enabled:after{font-size:8px;width:60px;content:"DISABLED";text-indent:15px}input[type=checkbox].wppd-ui-toggle.label-enabled:checked:before{left:44px}input[type=checkbox].wppd-ui-toggle.label-enabled:checked:after{background-color:#1ed14b;content:"ENABLED";text-indent:-14px}.notice-inline{border-top:1px solid #c3c4c7;border-bottom:1px solid #c3c4c7;border-right:1px solid #c3c4c7;border-left-width:4px;border-left-style:solid;background:#fff;box-shadow:0 1px 1px rgba(0,0,0,.04);margin:5px 15px 2px;padding:1px 12px}.tu-settings-section label em{font-size:12px;font-weight:400}.tu-alert-error{color:#d63638;background:#fcf0f1;padding:10px;border-left:4px solid #d63638;margin:10px 0}.tu-alert-warning{color:#856404;background:#fff3cd;padding:10px;border-left:4px solid #ffc107;margin:10px 0}.tu-alert-success{color:#00a32a;background:#edfaef;padding:10px;border-left:4px solid #00a32a;margin:10px 0}.button-danger{background:#d63638!important;border-color:#d63638!important;color:#fff!important}.button-danger:focus,.button-danger:hover{background:#b32d2e!important;border-color:#b32d2e!important;color:#fff!important}.button-warning{background:#ffc107!important;border-color:#ffc107!important;color:#333!important;font-weight:700}.button-warning:focus,.button-warning:hover{background:#e0a800!important;border-color:#e0a800!important;color:#000!important}
  • termageddon-usercentrics/trunk/admin/js/termageddon-usercentrics-admin.js

    r2948875 r3238690  
    8181    animationSpeed = 300;
    8282    initialLoad = true;
     83
     84    // ============================================ //
     85    // ======== Conversion from Embed Code ======== //
     86    // ============================================ //
     87
     88    let migrationButton = $("#run_settings_migration");
     89
     90    if (migrationButton.length === 1) {
     91        migrationButton.off("click.tu").on("click.tu", function () {
     92            // Get the current embed code
     93            const embedCode = document.querySelector(
     94                "#termageddon_usercentrics_embed_code"
     95            ).value;
     96
     97            // Try to extract settings ID using regex
     98            const settingsIdMatch = embedCode.match(
     99                /data-settings-id="([^"]+)"/
     100            );
     101
     102            if (!settingsIdMatch || !settingsIdMatch[1]) {
     103                alert(
     104                    "Unable to find settings ID in embed code. Please ensure your embed code section contains a data-settings-id attribute. Please contact our support team if would like assistance."
     105                );
     106                return;
     107            }
     108
     109            const settingsId = settingsIdMatch[1];
     110
     111            // Update the settings ID field
     112            document.querySelector(
     113                "#termageddon_usercentrics_settings_id"
     114            ).value = settingsId;
     115
     116            // Remove items from the embed code field:
     117            // <link rel="preconnect" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu">
     118            // <link rel="preload" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" as="script">
     119            // <script type="application/javascript" src="https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js"></script>
     120            // <script id="usercentrics-cmp" src="https://web.cmp.usercentrics.eu/ui/loader.js"   async></script>
     121            // <script>uc.setCustomTranslations('https://termageddon.ams3.cdn.digitaloceanspaces.com/translations/');</script>
     122
     123            // Remove the items from the embed code field
     124            document.querySelector(
     125                "#termageddon_usercentrics_embed_code"
     126            ).value = embedCode
     127                .replace(
     128                    '<link rel="preconnect" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu">',
     129                    ""
     130                )
     131                .replace(
     132                    '<link rel="preload" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" as="script">',
     133                    ""
     134                )
     135                .replace(
     136                    '<script type="application/javascript" src="https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js"></script>',
     137                    ""
     138                )
     139                .replace(
     140                    /<script.*id="usercentrics-cmp".*async>.*<\/script>/g,
     141                    ""
     142                )
     143                .replace(
     144                    "<script>uc.setCustomTranslations('https://termageddon.ams3.cdn.digitaloceanspaces.com/translations/');</script>",
     145                    ""
     146                )
     147                .trim();
     148
     149            // Update the migration message
     150            const migrationMessage = $(".migration-message");
     151
     152            migrationMessage
     153                .removeClass("tu-alert-error")
     154                .addClass("tu-alert-success");
     155            migrationMessage.find("strong").text("Conversion Complete");
     156            migrationMessage.find("p.alert-description").html(
     157                `The embed code has been converted to a settings ID. All custom scripts outside of the original embed code have been maintained.<br/></br>
     158                    <strong><em>The changes have been submitted.</em></strong>`
     159            );
     160
     161            // Submit the form to save changes
     162            $(".tab-content form input.button").click();
     163        });
     164    }
    83165});
  • termageddon-usercentrics/trunk/admin/js/termageddon-usercentrics-admin.min.js

    r2948875 r3238690  
    1 jQuery((function($){let animationSpeed=0,initialLoad=!1,loggedIn=$(".tu-tab-settings .tu-toggle-section input#termageddon_usercentrics_disable_logged_in"),editor=$(".tu-tab-settings .tu-toggle-section input#termageddon_usercentrics_disable_editor"),admin=$(".tu-tab-settings .tu-toggle-section input#termageddon_usercentrics_disable_admin");const check=(elem,checked=!0)=>{console.log(elem,checked),elem.prop("checked",checked).attr("readonly",checked).trigger("change")};1===loggedIn.length&&loggedIn.off("change.tu").on("change.tu",(function(){($(this).is(":checked")||initialLoad)&&(check(editor,$(this).is(":checked")),check(admin,$(this).is(":checked")))})).trigger("change");let geolocationToggle=$("input#termageddon_usercentrics_toggle_geolocation"),policyToggles=$(".tu-tab-geolocation .tu-toggle-section input");1===geolocationToggle.length&&(geolocationToggle.off("change.tu").on("change.tu",(function(){$(this).is(":checked")?$(".tu-tab-geolocation .tu-section-settings > div").slideDown(animationSpeed):$(".tu-tab-geolocation .tu-section-settings > div").slideUp(animationSpeed)})).trigger("change"),policyToggles.off("change.tu").on("change.tu",(function(){policyToggles.is(":checked")?jQuery("#no-geolocation-locations-selected,#no-geolocation-locations-selected-top").slideUp(animationSpeed):jQuery("#no-geolocation-locations-selected").slideDown(animationSpeed)})).trigger("change")),animationSpeed=300,initialLoad=!0}));
     1jQuery((function($){let animationSpeed=0,initialLoad=!1,loggedIn=$(".tu-tab-settings .tu-toggle-section input#termageddon_usercentrics_disable_logged_in"),editor=$(".tu-tab-settings .tu-toggle-section input#termageddon_usercentrics_disable_editor"),admin=$(".tu-tab-settings .tu-toggle-section input#termageddon_usercentrics_disable_admin");const check=(elem,checked=!0)=>{console.log(elem,checked),elem.prop("checked",checked).attr("readonly",checked).trigger("change")};1===loggedIn.length&&loggedIn.off("change.tu").on("change.tu",(function(){($(this).is(":checked")||initialLoad)&&(check(editor,$(this).is(":checked")),check(admin,$(this).is(":checked")))})).trigger("change");let geolocationToggle=$("input#termageddon_usercentrics_toggle_geolocation"),policyToggles=$(".tu-tab-geolocation .tu-toggle-section input");1===geolocationToggle.length&&(geolocationToggle.off("change.tu").on("change.tu",(function(){$(this).is(":checked")?$(".tu-tab-geolocation .tu-section-settings > div").slideDown(animationSpeed):$(".tu-tab-geolocation .tu-section-settings > div").slideUp(animationSpeed)})).trigger("change"),policyToggles.off("change.tu").on("change.tu",(function(){policyToggles.is(":checked")?jQuery("#no-geolocation-locations-selected,#no-geolocation-locations-selected-top").slideUp(animationSpeed):jQuery("#no-geolocation-locations-selected").slideDown(animationSpeed)})).trigger("change")),animationSpeed=300,initialLoad=!0;let migrationButton=$("#run_settings_migration");1===migrationButton.length&&migrationButton.off("click.tu").on("click.tu",(function(){const embedCode=document.querySelector("#termageddon_usercentrics_embed_code").value,settingsIdMatch=embedCode.match(/data-settings-id="([^"]+)"/);if(!settingsIdMatch||!settingsIdMatch[1])return void alert("Unable to find settings ID in embed code. Please ensure your embed code section contains a data-settings-id attribute. Please contact our support team if would like assistance.");const settingsId=settingsIdMatch[1];document.querySelector("#termageddon_usercentrics_settings_id").value=settingsId,document.querySelector("#termageddon_usercentrics_embed_code").value=embedCode.replace('<link rel="preconnect" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu">',"").replace('<link rel="preload" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" as="script">',"").replace('<script type="application/javascript" src="https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js"><\/script>',"").replace(/<script.*id="usercentrics-cmp".*async>.*<\/script>/g,"").replace("<script>uc.setCustomTranslations('https://termageddon.ams3.cdn.digitaloceanspaces.com/translations/');<\/script>","").trim();const migrationMessage=$(".migration-message");migrationMessage.removeClass("tu-alert-error").addClass("tu-alert-success"),migrationMessage.find("strong").text("Conversion Complete"),migrationMessage.find("p.alert-description").html("The embed code has been converted to a settings ID. All custom scripts outside of the original embed code have been maintained.<br/></br>\n\t\t\t\t\t<strong><em>The changes have been submitted.</em></strong>"),$(".tab-content form input.button").click()}))}));
  • termageddon-usercentrics/trunk/includes/class-termageddon-usercentrics.php

    r3160131 r3238690  
    289289                );
    290290
    291                 return '<a href="javascript:(function()%7Bdocument.querySelector(%22div%23usercentrics-root%22).style.display%20%3D%20\'block\'%3BUC_UI.showSecondLayer()%7D)()" id="usercentrics-psl">' . $a['text'] . '</a>';
     291                return '<a href="javascript:void(0)" onclick="(function(){var r=document.querySelector(\'div#usercentrics-root\'),c=document.querySelector(\'aside#usercentrics-cmp-ui\');if(r)r.style.display=\'block\';if(c)c.style.display=\'block\';if(typeof UC_UI!==\'undefined\')UC_UI.showSecondLayer()})()" id="usercentrics-psl">' . $a['text'] . '</a>';
    292292            }
    293293        );
    294294
    295295    }
    296 
    297296
    298297    /**
     
    356355        $this->loader->add_action( 'wp_ajax_nopriv_uc_geolocation_lookup', $this, 'geolocation_lookup_ajax' );
    357356
    358         // Load the primary embed (or disabled) script in the head.
     357        // WP Head Implementation.
    359358        $this->loader->add_action(
    360359            'wp_head',
     
    363362            self::get_embed_priority()
    364363        );
     364
     365        // Load the primary embed (or disabled) script in the head.
     366        $this->loader->add_action(
     367            'wp_enqueue_scripts',
     368            $plugin_public,
     369            'build_termageddon_enqueue',
     370            self::get_embed_priority()
     371        );
     372
     373        $this->loader->add_filter(
     374            'script_loader_tag',
     375            $plugin_public,
     376            'filter_script_loader_tag',
     377            10,
     378            3
     379        );
     380
    365381    }
    366382
     
    547563    }
    548564
     565    /**
     566     * Check if migration is needed by looking for a settings ID in the embed code.
     567     *
     568     * @return bool True if migration is needed, false otherwise.
     569     */
     570    public static function check_for_conversion_needed(): bool {
     571        $embed_code = self::get_embed_code();
     572        return (bool) ! empty( $embed_code ) && preg_match( '/data-settings-id="[^"]*"/', $embed_code );
     573    }
     574
    549575
    550576    /**
     
    554580    public static function get_download_error_logs(): array {
    555581        return (array) array_filter( get_option( 'termageddon_usercentrics_download_error_log', array() ) );
     582    }
     583
     584    /**
     585     * Filter out the standard embed code when a settings ID is present.
     586     *
     587     * @param string $embed_code The embed code to filter.
     588     * @return string The filtered embed code.
     589     */
     590    public static function filter_out_standard_embed_code( string $embed_code ): string {
     591        if ( empty( self::get_settings_id() ) ) {
     592            return $embed_code;
     593        }
     594
     595        // Check if $embed_code is not null before running preg_replace.
     596        if ( null !== $embed_code ) {
     597            $embed_code = preg_replace( '~<link rel="preconnect" href="\/\/privacy-proxy.usercentrics.eu">~', '', $embed_code );
     598            $embed_code = preg_replace( '~<link rel="preload" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" as="script">~', '', $embed_code );
     599            $embed_code = preg_replace( '~<script type="application/javascript" src="https:\/\/privacy-proxy.usercentrics.eu\/latest\/uc-block.bundle.js"><\/script>~', '', $embed_code );
     600            $embed_code = preg_replace( '~<script id="usercentrics-cmp".*async>.*<\/script>~', '', $embed_code );
     601            $embed_code = preg_replace( '~<script>uc.setCustomTranslations\(\'https://termageddon.ams3.cdn.digitaloceanspaces.com/translations/\'\);</script>~', '', $embed_code );
     602        }
     603
     604        return trim( $embed_code );
     605    }
     606    /**
     607     * Append the settings ID embed code to the existing embed code.
     608     *
     609     * @param string $embed_code The embed code to append to.
     610     * @return string The embed code with settings ID code appended.
     611     */
     612    public static function append_settings_id_embed_code( string $embed_code ): string {
     613        if ( empty( self::get_settings_id() ) ) {
     614            return $embed_code;
     615        }
     616
     617        $embed_version = self::get_embed_script_version();
     618        $loader_url    = ( 'v2' === $embed_version ) ? '//app.usercentrics.eu/browser-ui/latest/loader.js' : '//web.cmp.usercentrics.eu/ui/loader.js';
     619
     620        $new_embed_code  = '<link rel="preconnect" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu">' . PHP_EOL;
     621        $new_embed_code .= '<link rel="preload" href="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" as="script">' . PHP_EOL;
     622        $new_embed_code .= '<script type="application/javascript" src="https://plugins.trac.wordpress.org//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js"></script>' . PHP_EOL;
     623        $new_embed_code .= '<script id="usercentrics-cmp" data-cmp-version="' . esc_attr( self::get_embed_script_version() ) . '" src="' . esc_url( $loader_url ) . '" data-settings-id="' . self::get_settings_id() . '"  async></script>' . PHP_EOL;
     624        $new_embed_code .= '<script>uc.setCustomTranslations(\'https://termageddon.ams3.cdn.digitaloceanspaces.com/translations/\');</script>' . PHP_EOL;
     625        $new_embed_code .= self::filter_out_standard_embed_code( $embed_code );
     626
     627        return $new_embed_code;
     628    }
     629
     630    /**
     631     * Get the injection method for the embed code.
     632     *
     633     * @return string The injection method, defaults to 'wp_head'. Alternatively, 'wp_enqueue_scripts' is also supported.
     634     */
     635    public static function get_embed_injection_method(): string {
     636        return get_option( 'termageddon_usercentrics_embed_injection_method', 'wp_head' );
     637    }
     638
     639
     640    /**
     641     * Get the version of the embed script to use.
     642     *
     643     * @return string The embed script version, defaults to 'v2'.
     644     */
     645    public static function get_embed_script_version(): string {
     646        return get_option( 'termageddon_usercentrics_embed_version', 'v2' );
     647    }
     648
     649    /**
     650     * Get the Usercentrics settings ID.
     651     *
     652     * @return string The settings ID, empty string if not set.
     653     */
     654    public static function get_settings_id(): string {
     655        return get_option( 'termageddon_usercentrics_settings_id', '' );
     656    }
     657
     658    /**
     659     * Get the embed code.
     660     * Valid Options:
     661     *  'filter_standard_embed_code' => false, // Filter out the standard embed code to prevent duplication.
     662     *  'force_include_embed_code' => false, // Force the inclusion of the embed code, even if the settings ID is not set due to the implementation mode.
     663     *
     664     * @param array $options The configuration options to build the embed code.
     665     * @return string The embed code, empty string if not set.
     666     */
     667    public static function get_embed_code( array $options = array() ): string {
     668        $embed_code = get_option( 'termageddon_usercentrics_embed_code', '' );
     669        // Options Configuration.
     670        $filter_standard_embed_code = ( isset( $options['filter_standard_embed_code'] ) ? $options['filter_standard_embed_code'] : false );
     671        $force_include_embed_code   = ( isset( $options['force_include_embed_code'] ) ? $options['force_include_embed_code'] : false );
     672
     673        if ( $filter_standard_embed_code ) {
     674            $embed_code = self::filter_out_standard_embed_code( $embed_code );
     675        }
     676
     677        if ( $force_include_embed_code ) {
     678            $embed_code = self::append_settings_id_embed_code( $embed_code );
     679        }
     680
     681        return $embed_code;
    556682    }
    557683
     
    10901216            return '1' === $enabled;
    10911217        }
     1218    }
     1219
     1220
     1221    /**
     1222     * Returns a list of all possible integrations
     1223     *
     1224     * @return array with the integration slugs
     1225     */
     1226    public static function get_integrations(): array {
     1227        return array(
     1228            'divi_video'      => array(
     1229                'name'        => __( 'Divi Video', 'termageddon-usercentrics' ),
     1230                'description' => __( 'This resolves and improves the cookie-consent implementation when using an image placeholder overlay for the Divi video embed.', 'termageddon-usercentrics' ),
     1231                'beta'        => false,
     1232            ),
     1233            'elementor_video' => array(
     1234                'name'        => __( 'Elementor Video', 'termageddon-usercentrics' ),
     1235                'description' => __( 'This resolves and improves the cookie-consent implementation when using an image placeholder overlay for the Elementor video embed.', 'termageddon-usercentrics' ),
     1236                'beta'        => false,
     1237            ),
     1238            'powerpack_video' => array(
     1239                'name'        => __( 'PowerPack Video', 'termageddon-usercentrics' ),
     1240                'description' => __( 'This resolves and improves the cookie-consent implementation when using an image placeholder overlay for the PowerPack for BeaverBuilder video embed. This requires window events to be enabled in your Usercentrics settings. Please reach out to support if needed.', 'termageddon-usercentrics' ),
     1241                'beta'        => true,
     1242            ),
     1243            'presto_player'   => array(
     1244                'name'        => __( 'Presto Player', 'termageddon-usercentrics' ),
     1245                'description' => __( 'This resolves and improves the cookie-consent implementation when using an image placeholder overlay for the Presto Player video embed.', 'termageddon-usercentrics' ),
     1246                'beta'        => false,
     1247            ),
     1248            'uabb_video'      => array(
     1249                'name'        => __( 'Ultimate Addons for Beaver Builder Video', 'termageddon-usercentrics' ),
     1250                'description' => __( 'This resolves and improves the cookie-consent implementation when using an image placeholder overlay for the Ultimate Addons for Beaver Builder video embed.', 'termageddon-usercentrics' ),
     1251                'beta'        => false,
     1252            ),
     1253        );
    10921254    }
    10931255
  • termageddon-usercentrics/trunk/languages/termageddon-usercentrics.pot

    r3160131 r3238690  
    44"Project-Id-Version: Termageddon + Usercentrics\n"
    55"Report-Msgid-Bugs-To: \n"
    6 "POT-Creation-Date: 2024-09-24 04:08+0000\n"
     6"POT-Creation-Date: 2025-02-11 05:02+0000\n"
    77"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    88"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1717"X-Domain: termageddon-usercentrics"
    1818
    19 #: admin/class-termageddon-usercentrics-admin.php:413
     19#: admin/class-termageddon-usercentrics-admin.php:1122
     20msgid "Action Needed"
     21msgstr ""
     22
     23#: admin/class-termageddon-usercentrics-admin.php:435
     24msgid "Additional Scripts"
     25msgstr ""
     26
     27#: admin/class-termageddon-usercentrics-admin.php:472
    2028msgid "Administrators"
    2129msgstr ""
    2230
    23 #: admin/class-termageddon-usercentrics-admin.php:178
     31#: admin/class-termageddon-usercentrics-admin.php:90
     32#: admin/class-termageddon-usercentrics-admin.php:215
    2433msgid "Advanced Configuration & Troubleshooting"
    2534msgstr ""
    2635
    27 #: admin/class-termageddon-usercentrics-admin.php:188
     36#: admin/class-termageddon-usercentrics-admin.php:225
    2837msgid "Allowed HTML Tags"
    2938msgstr ""
    3039
    31 #: admin/class-termageddon-usercentrics-admin.php:1119
     40#: admin/class-termageddon-usercentrics-admin.php:1316
    3241msgid "along with page 1 of your Privacy Policy questionnaire within "
    3342msgstr ""
    3443
    35 #: admin/class-termageddon-usercentrics-admin.php:1126
     44#: admin/class-termageddon-usercentrics-admin.php:1323
    3645msgid "based on which privacy laws apply to you"
     46msgstr ""
     47
     48#: admin/class-termageddon-usercentrics-admin.php:1131
     49msgid ""
     50"Behind the scenes, we will remove the Usercentrics embed code from the field "
     51"below, ensuring custom scripts are maintained."
    3752msgstr ""
    3853
     
    4964msgstr ""
    5065
     66#: admin/class-termageddon-usercentrics-admin.php:74
     67msgid "Configuration"
     68msgstr ""
     69
    5170#: includes/class-termageddon-usercentrics.php:145
    5271msgid "Connecticut (CTDPA)"
     
    5473
    5574#. section ID.
    56 #: admin/class-termageddon-usercentrics-admin.php:761
     75#: admin/class-termageddon-usercentrics-admin.php:878
    5776msgid "Control Panel"
    5877msgstr ""
    5978
    60 #: admin/class-termageddon-usercentrics-admin.php:1079
     79#: admin/class-termageddon-usercentrics-admin.php:1128
     80msgid "Conversion Needed:"
     81msgstr ""
     82
     83#: admin/class-termageddon-usercentrics-admin.php:1132
     84msgid "Convert"
     85msgstr ""
     86
     87#: admin/class-termageddon-usercentrics-admin.php:1276
    6188msgid "Cookie Policy and Consent Solution"
    6289msgstr ""
    6390
    64 #: admin/class-termageddon-usercentrics-admin.php:180
     91#: admin/class-termageddon-usercentrics-admin.php:217
    6592msgid "Debug Information"
    6693msgstr ""
    6794
    68 #: admin/class-termageddon-usercentrics-admin.php:611
     95#: admin/class-termageddon-usercentrics-admin.php:662
    6996msgid "Disable for Troubleshooting"
    7097msgstr ""
    7198
    72 #: admin/class-termageddon-usercentrics-admin.php:524
    73 msgid "Divi Video Player Integration"
     99#: includes/class-termageddon-usercentrics.php:1232
     100msgid "Divi Video"
    74101msgstr ""
    75102
     
    80107msgstr ""
    81108
    82 #: admin/class-termageddon-usercentrics-admin.php:431
     109#: admin/class-termageddon-usercentrics-admin.php:490
    83110msgid "Editors"
    84111msgstr ""
    85112
    86 #: admin/class-termageddon-usercentrics-admin.php:543
    87 msgid "Elementor Video Player Integration"
    88 msgstr ""
    89 
    90 #: admin/class-termageddon-usercentrics-admin.php:170
    91 #: admin/class-termageddon-usercentrics-admin.php:376
    92 msgid "Embed Code"
    93 msgstr ""
    94 
    95 #: admin/class-termageddon-usercentrics-admin.php:589
     113#: includes/class-termageddon-usercentrics.php:1237
     114msgid "Elementor Video"
     115msgstr ""
     116
     117#: admin/class-termageddon-usercentrics-admin.php:435
     118msgid "Embed Code (Legacy)"
     119msgstr ""
     120
     121#: admin/class-termageddon-usercentrics-admin.php:606
     122msgid "Embed Code Injection Method"
     123msgstr ""
     124
     125#: admin/class-termageddon-usercentrics-admin.php:583
    96126msgid "Embed Code Priority"
    97127msgstr ""
    98128
    99 #: admin/class-termageddon-usercentrics-admin.php:714
     129#: admin/class-termageddon-usercentrics-admin.php:634
     130msgid "Embed Code Version"
     131msgstr ""
     132
     133#: admin/class-termageddon-usercentrics-admin.php:765
    100134msgid "Enable location logging"
    101135msgstr ""
    102136
    103 #: admin/class-termageddon-usercentrics-admin.php:734
     137#: admin/class-termageddon-usercentrics-admin.php:785
    104138msgid "Enable page caching support via AJAX"
    105139msgstr ""
    106140
    107 #: admin/class-termageddon-usercentrics-admin.php:775
     141#: admin/class-termageddon-usercentrics-admin.php:417
     142msgid ""
     143"Enter your Usercentrics Settings ID. This can be found on the \"View Embed "
     144"Code\" page of your Cookie Policy and Consent Tool questionnaire."
     145msgstr ""
     146
     147#: admin/class-termageddon-usercentrics-admin.php:892
    108148msgid "Error Count"
    109149msgstr ""
    110150
    111 #: admin/class-termageddon-usercentrics-admin.php:192
     151#: admin/class-termageddon-usercentrics-admin.php:229
    112152msgid "Error Information"
    113153msgstr ""
    114154
    115 #: admin/class-termageddon-usercentrics-admin.php:793
     155#: admin/class-termageddon-usercentrics-admin.php:910
    116156msgid "Error List"
    117157msgstr ""
     
    121161msgstr ""
    122162
    123 #: includes/class-termageddon-usercentrics.php:307
     163#: includes/class-termageddon-usercentrics.php:306
    124164msgid "Every Month"
    125165msgstr ""
    126166
    127 #: admin/class-termageddon-usercentrics-admin.php:502
     167#: admin/class-termageddon-usercentrics-admin.php:561
    128168msgid ""
    129169"For some theme builders including Divi, the footer (bottom bar) does not "
     
    134174
    135175#. section ID.
    136 #: admin/class-termageddon-usercentrics-admin.php:172
    137 #: admin/class-termageddon-usercentrics-admin.php:639
     176#: admin/class-termageddon-usercentrics-admin.php:86
     177#: admin/class-termageddon-usercentrics-admin.php:690
    138178msgid "Geo-Location"
    139179msgstr ""
    140180
    141 #: admin/class-termageddon-usercentrics-admin.php:143
    142 #: admin/class-termageddon-usercentrics-admin.php:1128
     181#: admin/class-termageddon-usercentrics-admin.php:176
     182#: admin/class-termageddon-usercentrics-admin.php:1325
    143183msgid ""
    144184"Geo-Location is enabled, but no locations have been toggled on. This means "
     
    146186msgstr ""
    147187
    148 #: admin/class-termageddon-usercentrics-admin.php:185
     188#: admin/class-termageddon-usercentrics-admin.php:222
    149189msgid "Geolocation Database Directory Writable"
    150190msgstr ""
    151191
    152 #: admin/class-termageddon-usercentrics-admin.php:183
     192#: admin/class-termageddon-usercentrics-admin.php:220
    153193msgid "Geolocation Database Exists"
    154194msgstr ""
    155195
    156 #: admin/class-termageddon-usercentrics-admin.php:186
     196#: admin/class-termageddon-usercentrics-admin.php:223
    157197msgid "Geolocation Database Last Updated"
    158198msgstr ""
    159199
    160 #: admin/class-termageddon-usercentrics-admin.php:187
     200#: admin/class-termageddon-usercentrics-admin.php:224
    161201msgid "Geolocation Database Next Update"
    162202msgstr ""
    163203
    164 #: admin/class-termageddon-usercentrics-admin.php:182
     204#: admin/class-termageddon-usercentrics-admin.php:219
    165205msgid "Geolocation Database Path"
    166206msgstr ""
    167207
    168 #: admin/class-termageddon-usercentrics-admin.php:184
     208#: admin/class-termageddon-usercentrics-admin.php:221
    169209msgid "Geolocation Database Readable"
    170210msgstr ""
    171211
    172 #: admin/class-termageddon-usercentrics-admin.php:477
     212#: admin/class-termageddon-usercentrics-admin.php:1124
     213msgid "Go to Configuration"
     214msgstr ""
     215
     216#: admin/class-termageddon-usercentrics-admin.php:536
    173217msgid "Hide Privacy Settings Link when cookie consent tool is disabled"
    174218msgstr ""
     
    178222msgstr ""
    179223
    180 #: admin/class-termageddon-usercentrics-admin.php:1097
     224#: admin/class-termageddon-usercentrics-admin.php:1294
    181225msgid "If you are using the Divi theme"
    182226msgstr ""
    183227
    184 #: admin/class-termageddon-usercentrics-admin.php:1096
     228#: admin/class-termageddon-usercentrics-admin.php:822
     229msgid ""
     230"If you have a script or code snippet to share, would like to improve support "
     231"with your plugin/theme, or run into an issue implementing "
     232"Termageddon/Usercentrics, please contact our support team."
     233msgstr ""
     234
     235#: admin/class-termageddon-usercentrics-admin.php:1293
    185236msgid ""
    186237"If you would like to remove Usercentrics for logged in users such as admins, "
     
    188239msgstr ""
    189240
    190 #: admin/class-termageddon-usercentrics-admin.php:162
     241#: admin/class-termageddon-usercentrics-admin.php:832
     242msgid "Integration"
     243msgstr ""
     244
     245#. section ID.
     246#: admin/class-termageddon-usercentrics-admin.php:78
     247#: admin/class-termageddon-usercentrics-admin.php:811
     248msgid "Integrations"
     249msgstr ""
     250
     251#: admin/class-termageddon-usercentrics-admin.php:195
    191252msgid "Invalid tab. Please check the link and try again."
    192253msgstr ""
    193254
    194 #: admin/class-termageddon-usercentrics-admin.php:151
     255#: admin/class-termageddon-usercentrics-admin.php:1130
     256msgid ""
     257"It looks like you are still using the old embed code (below) instead of the "
     258"Settings ID. To automatically switch update your configuration, please click "
     259"the button bellow."
     260msgstr ""
     261
     262#: admin/class-termageddon-usercentrics-admin.php:184
    195263msgid "Location logging is enabled."
    196264msgstr ""
    197265
    198 #: admin/class-termageddon-usercentrics-admin.php:449
     266#: admin/class-termageddon-usercentrics-admin.php:508
    199267msgid "Logged-in Users"
    200268msgstr ""
    201269
    202 #: admin/class-termageddon-usercentrics-admin.php:1126
     270#: admin/class-termageddon-usercentrics-admin.php:1323
    203271msgid "Not sure what to select?"
    204272msgstr ""
    205273
    206 #: admin/class-termageddon-usercentrics-admin.php:1119
     274#: admin/class-termageddon-usercentrics-admin.php:1316
    207275msgid "Not sure what to select? Review"
     276msgstr ""
     277
     278#: admin/class-termageddon-usercentrics-admin.php:859
     279msgid ""
     280"On this page, you can find custom implementation to improve support and "
     281"compatibility with various plugins and page-builders."
    208282msgstr ""
    209283
     
    212286msgstr ""
    213287
    214 #: admin/class-termageddon-usercentrics-admin.php:595
     288#: admin/class-termageddon-usercentrics-admin.php:589
    215289msgid ""
    216290"Override the default priority of the embed code (Defaults to 1). By "
     
    220294msgstr ""
    221295
    222 #: admin/class-termageddon-usercentrics-admin.php:144
     296#: admin/class-termageddon-usercentrics-admin.php:177
    223297msgid ""
    224298"Please go to geo-location settings to enable at least one location or to "
     
    226300msgstr ""
    227301
    228 #: admin/class-termageddon-usercentrics-admin.php:562
     302#: admin/class-termageddon-usercentrics-admin.php:821
     303msgid "Plugin & Theme Integrations"
     304msgstr ""
     305
     306#: includes/class-termageddon-usercentrics.php:1242
     307msgid "PowerPack Video"
     308msgstr ""
     309
     310#: includes/class-termageddon-usercentrics.php:1247
    229311msgid "Presto Player"
    230312msgstr ""
    231313
    232 #: admin/class-termageddon-usercentrics-admin.php:496
     314#: admin/class-termageddon-usercentrics-admin.php:555
    233315msgid "Privacy Settings Link - Alternative Implementation"
    234316msgstr ""
    235317
     318#: admin/class-termageddon-usercentrics-admin.php:640
     319msgid ""
     320"Select which version of the Usercentrics embed code you would like to use."
     321msgstr ""
     322
    236323#. section ID.
    237 #: includes/class-termageddon-usercentrics.php:492
    238 #: admin/class-termageddon-usercentrics-admin.php:171
    239 #: admin/class-termageddon-usercentrics-admin.php:404
     324#: includes/class-termageddon-usercentrics.php:508
     325#: admin/class-termageddon-usercentrics-admin.php:82
     326#: admin/class-termageddon-usercentrics-admin.php:463
    240327msgid "Settings"
    241328msgstr ""
    242329
    243 #: admin/class-termageddon-usercentrics-admin.php:1125
     330#: admin/class-termageddon-usercentrics-admin.php:411
     331msgid "Settings ID"
     332msgstr ""
     333
     334#: admin/class-termageddon-usercentrics-admin.php:1322
    244335msgid "Show widget if visitor is located in"
    245336msgstr ""
     
    250341
    251342#. Name of the plugin
    252 #: admin/class-termageddon-usercentrics-admin.php:156
     343#: admin/class-termageddon-usercentrics-admin.php:189
    253344msgid "Termageddon + Usercentrics"
    254345msgstr ""
     
    258349msgstr ""
    259350
    260 #: admin/class-termageddon-usercentrics-admin.php:1119
     351#: admin/class-termageddon-usercentrics-admin.php:612
     352msgid ""
     353"The default injection option, wp_head, will inject the embed code in the "
     354"wp_head action which typically runs before any other action. Alternatively, "
     355"wp_enqueue_scripts will inject the embed code along with other scripts, "
     356"leading to more compatibility with certain websites."
     357msgstr ""
     358
     359#: admin/class-termageddon-usercentrics-admin.php:1316
    261360msgid "this article"
    262361msgstr ""
    263362
    264 #: admin/class-termageddon-usercentrics-admin.php:1126
     363#: admin/class-termageddon-usercentrics-admin.php:1323
    265364msgid "This article outlines which regions to select"
    266365msgstr ""
    267366
    268 #: admin/class-termageddon-usercentrics-admin.php:178
     367#: admin/class-termageddon-usercentrics-admin.php:215
    269368msgid ""
    270369"This panel is for advanced configuration and troubleshooting. Please contact "
     
    272371msgstr ""
    273372
    274 #: admin/class-termageddon-usercentrics-admin.php:525
     373#: includes/class-termageddon-usercentrics.php:1233
    275374msgid ""
    276375"This resolves and improves the cookie-consent implementation when using an "
     
    278377msgstr ""
    279378
    280 #: admin/class-termageddon-usercentrics-admin.php:544
     379#: includes/class-termageddon-usercentrics.php:1238
    281380msgid ""
    282381"This resolves and improves the cookie-consent implementation when using an "
     
    284383msgstr ""
    285384
    286 #: admin/class-termageddon-usercentrics-admin.php:1140
     385#: includes/class-termageddon-usercentrics.php:1243
     386msgid ""
     387"This resolves and improves the cookie-consent implementation when using an "
     388"image placeholder overlay for the PowerPack for BeaverBuilder video embed. "
     389"This requires window events to be enabled in your Usercentrics settings. "
     390"Please reach out to support if needed."
     391msgstr ""
     392
     393#: includes/class-termageddon-usercentrics.php:1248
     394msgid ""
     395"This resolves and improves the cookie-consent implementation when using an "
     396"image placeholder overlay for the Presto Player video embed."
     397msgstr ""
     398
     399#: includes/class-termageddon-usercentrics.php:1253
     400msgid ""
     401"This resolves and improves the cookie-consent implementation when using an "
     402"image placeholder overlay for the Ultimate Addons for Beaver Builder video "
     403"embed."
     404msgstr ""
     405
     406#: admin/class-termageddon-usercentrics-admin.php:441
     407msgid ""
     408"This section can be used to add customizations to your Usercentrics embed "
     409"code, such as event handling, and other customizations. Reach out to our "
     410"support team for more information."
     411msgstr ""
     412
     413#: admin/class-termageddon-usercentrics-admin.php:441
     414msgid ""
     415"This section should no longer be used for the embed code from the "
     416"Termageddon dashboard. We recommend migrating to the new Settings ID format "
     417"using the button above."
     418msgstr ""
     419
     420#: admin/class-termageddon-usercentrics-admin.php:1123
     421msgid "This update will take a few seconds to complete."
     422msgstr ""
     423
     424#: admin/class-termageddon-usercentrics-admin.php:1337
    287425msgid ""
    288426"To reset any of the backend variables, update the values below and save your "
     
    290428msgstr ""
    291429
     430#: includes/class-termageddon-usercentrics.php:1252
     431msgid "Ultimate Addons for Beaver Builder Video"
     432msgstr ""
     433
    292434#: includes/class-termageddon-usercentrics.php:125
    293435msgid "United Kingdom (UK DPA)"
     
    298440msgstr ""
    299441
    300 #: admin/class-termageddon-usercentrics-admin.php:1078
     442#: admin/class-termageddon-usercentrics-admin.php:1275
    301443msgid "Upon generating your "
    302444msgstr ""
    303445
    304 #: admin/class-termageddon-usercentrics-admin.php:1064
     446#: admin/class-termageddon-usercentrics-admin.php:1262
    305447msgid "Upon saving, all previous errors in the log will be deleted."
    306448msgstr ""
     
    310452msgstr ""
    311453
     454#: admin/class-termageddon-usercentrics-admin.php:642
     455msgid "v2"
     456msgstr ""
     457
     458#: admin/class-termageddon-usercentrics-admin.php:643
     459msgid "v3 (Beta)"
     460msgstr ""
     461
    312462#: includes/class-termageddon-usercentrics.php:161
    313463msgid "Virginia (VCDPA)"
    314464msgstr ""
    315465
    316 #: admin/class-termageddon-usercentrics-admin.php:136
     466#: admin/class-termageddon-usercentrics-admin.php:1123
     467msgid ""
     468"We are moving to using a Settings ID instead of an embed code format to "
     469"allow for more features."
     470msgstr ""
     471
     472#: admin/class-termageddon-usercentrics-admin.php:169
    317473msgid ""
    318474"We were unable to download the database necessary for geolocation to your "
     
    321477msgstr ""
    322478
    323 #: admin/class-termageddon-usercentrics-admin.php:483
     479#: admin/class-termageddon-usercentrics-admin.php:542
    324480msgid ""
    325481"When enabled, the Privacy Settings link will be hidden from certain users, "
    326482"whether that be certain logged in users (via your selections above in the "
    327 "“Hide widget for:” area) or if you enabled geolocation and are hiding the "
     483"\"Hide widget for:\" area) or if you enabled geolocation and are hiding the "
    328484"consent tool from certain visitors. For example, if you enable the option to "
    329485"hide the consent tool for logged in administrator (and enable this toggle), "
     
    334490msgstr ""
    335491
    336 #: admin/class-termageddon-usercentrics-admin.php:720
     492#: admin/class-termageddon-usercentrics-admin.php:771
    337493msgid ""
    338494"When enabled, the visitor's location can be viewed in the browser console, "
     
    340496msgstr ""
    341497
    342 #: admin/class-termageddon-usercentrics-admin.php:740
     498#: admin/class-termageddon-usercentrics-admin.php:791
    343499msgid ""
    344500"When enabled, the visitor's location is checked via javascript to allow "
     
    346502msgstr ""
    347503
    348 #: admin/class-termageddon-usercentrics-admin.php:617
     504#: admin/class-termageddon-usercentrics-admin.php:668
    349505msgid ""
    350506"When enabled, this feature allows you to turn off the consent tool for all "
     
    355511msgstr ""
    356512
    357 #: admin/class-termageddon-usercentrics-admin.php:1115
     513#: admin/class-termageddon-usercentrics-admin.php:1312
    358514msgid ""
    359515"When enabled, you will be collecting IP addresses for the purposes of "
     
    367523msgstr ""
    368524
    369 #: admin/class-termageddon-usercentrics-admin.php:151
     525#: admin/class-termageddon-usercentrics-admin.php:184
    370526msgid "with the IP Address of"
    371527msgstr ""
    372528
    373 #: admin/class-termageddon-usercentrics-admin.php:1080
     529#: admin/class-termageddon-usercentrics-admin.php:1277
    374530msgid ""
    375531"within your Termageddon account, you will be brought to the \"View embed "
     
    378534msgstr ""
    379535
    380 #: admin/class-termageddon-usercentrics-admin.php:1098
     536#: admin/class-termageddon-usercentrics-admin.php:615
     537msgid "wp_enqueue_scripts"
     538msgstr ""
     539
     540#: admin/class-termageddon-usercentrics-admin.php:614
     541msgid "wp_head (Default)"
     542msgstr ""
     543
     544#: admin/class-termageddon-usercentrics-admin.php:1295
    381545msgid ""
    382546"you will need to enable at least one of the settings below to ensure logged "
    383 "in users/admins can properly use the “Enable Visual Builder” feature "
     547"in users/admins can properly use the \"Enable Visual Builder\" feature "
    384548"provided by Divi when editing the design of a webpage."
    385549msgstr ""
    386550
    387 #: admin/class-termageddon-usercentrics-admin.php:151
     551#: admin/class-termageddon-usercentrics-admin.php:184
    388552msgid "Your location"
    389553msgstr ""
  • termageddon-usercentrics/trunk/public/class-termageddon-usercentrics-public.php

    r3187188 r3238690  
    121121        echo wp_kses( $script, Termageddon_Usercentrics::ALLOWED_HTML );
    122122        echo '<!-- END TERMAGEDDON + USERCENTRICS -->';
     123    }
     124
     125    /**
     126     * Disable the termageddon enqueue if the psl should be hidden.
     127     *
     128     * @return void
     129     */
     130    public function disable_termageddon_enqueue() {
     131        if ( Termageddon_Usercentrics::should_hide_psl() ) {
     132            wp_enqueue_style( $this->plugin_name . '_disable', plugin_dir_url( __FILE__ ) . 'public/css/termageddon-usercentrics-disable.min.css', array(), $this->version );
     133        }
    123134    }
    124135
     
    185196     */
    186197    public function build_termageddon_script() {
    187         $script = get_option( 'termageddon_usercentrics_embed_code' );
    188         if ( empty( $script ) ) {
    189             return self::disable_termageddon_script();
    190         }
    191198
    192199        // If forcibly enabled, bypass individual detections.
     
    194201            // Check for Disable for troubleshooting.
    195202            if ( Termageddon_Usercentrics::is_disabled_for_troubleshooting() ) {
    196                 return self::disable_termageddon_script();
     203                return;
    197204            }
    198205
     
    203210            $disable_on_logged_in = get_option( 'termageddon_usercentrics_disable_logged_in', false ) ? true : false;
    204211            if ( $disable_on_logged_in && is_user_logged_in() ) {
    205                 return self::disable_termageddon_script();
     212                return;
    206213            }
    207214
    208215            $disable_on_editor = get_option( 'termageddon_usercentrics_disable_editor', false ) ? true : false;
    209216            if ( $disable_on_editor && current_user_can( 'editor' ) ) {
    210                 return self::disable_termageddon_script();
     217                return;
    211218            }
    212219
    213220            $disable_on_admin = get_option( 'termageddon_usercentrics_disable_admin', false ) ? true : false;
    214221            if ( $disable_on_admin && current_user_can( 'administrator' ) ) {
    215                 return self::disable_termageddon_script();
     222                return;
    216223            }
    217224
    218225            if ( Termageddon_Usercentrics::is_geoip_enabled() && ! Termageddon_Usercentrics::is_ajax_mode_enabled() && Termageddon_Usercentrics::should_hide_due_to_location() ) {
    219                 return self::disable_termageddon_script();
     226                return;
    220227            }
    221228        } else {
     
    224231        }
    225232
    226         if ( Termageddon_Usercentrics::is_geoip_enabled() && Termageddon_Usercentrics::is_ajax_mode_enabled() ) {
    227             $script .= '<script type="application/javascript">
    228             var UC_UI_SUPPRESS_CMP_DISPLAY=true;
    229           </script>';
    230         }
    231 
    232         // Divi Video Player Integration Javascript.
    233         if ( Termageddon_Usercentrics::is_integration_enabled( 'divi_video' ) ) {
    234             $script .= '<script type="application/javascript" id="uc-integration-divi-video">
    235 window.addEventListener(\'load\', function () {
    236     jQuery(\'div.et_pb_video_overlay_hover\').on(\'click\', function(e) {
    237         jQuery(this).closest(\'div.et_pb_video_overlay\').hide()
    238     }).find(\'a.et_pb_video_play\').attr(\'href\', \'javascript:void(0)\')
    239 })
    240 </script>';
    241         }
    242 
    243         // Elementor Video Player Integration Javascript.
    244         if ( Termageddon_Usercentrics::is_integration_enabled( 'elementor_video' ) ) {
    245             $script .= '<script type="application/javascript" id="uc-integration-elementor-video">
    246 window.addEventListener(\'load\', function () {
    247     jQuery(\'.pp-media-overlay\').on(\'click\', function(e) {
    248         jQuery(this).hide()
    249     })
    250 })
    251 </script>';
    252         }
    253 
    254         // Presto Player Integration Javascript.
    255         if ( Termageddon_Usercentrics::is_integration_enabled( 'presto_player' ) ) {
    256             $script .= '<script type="application/javascript" id="uc-integration-presto-player">
    257     function uc_integration_setup(iID,service) {
    258         uc.blockElements({[iID] : \'figure.presto-block-video.presto-provider-\'+service});
    259         uc.reloadOnOptIn(iID);
    260         uc.reloadOnOptOut(iID);
    261     }
    262     uc_integration_setup("BJz7qNsdj-7","youtube"); // Youtube
    263     uc_integration_setup("HyEX5Nidi-m","vimeo"); // Vimeo
    264 </script>';
     233        $should_append_settings_id_embed_code = ! empty( Termageddon_Usercentrics::get_settings_id() ) && Termageddon_Usercentrics::get_embed_injection_method() === 'wp_head' ? true : false;
     234
     235        $script = Termageddon_Usercentrics::get_embed_code(
     236            array(
     237                'filter_standard_embed_code' => true,
     238                'force_include_embed_code'   => $should_append_settings_id_embed_code,
     239            )
     240        );
     241        if ( empty( $script ) ) {
     242            return;
    265243        }
    266244
     
    271249
    272250    }
     251    /**
     252     * Dynamically hide or show the termageddon script based on settings. Outputs directly to script tag.
     253     */
     254    public function build_termageddon_enqueue() {
     255        // If forcibly enabled, bypass individual detections.
     256        if ( ! Termageddon_Usercentrics::is_enabled_via_get_override() ) {
     257            // Check for Disable for troubleshooting.
     258            if ( Termageddon_Usercentrics::is_disabled_for_troubleshooting() ) {
     259                return self::disable_termageddon_enqueue();
     260            }
     261
     262            // Check for individual disable detections.
     263            $disable_on_logged_in = get_option( 'termageddon_usercentrics_disable_logged_in', false ) ? true : false;
     264            if ( $disable_on_logged_in && is_user_logged_in() ) {
     265                return self::disable_termageddon_enqueue();
     266            }
     267
     268            $disable_on_editor = get_option( 'termageddon_usercentrics_disable_editor', false ) ? true : false;
     269            if ( $disable_on_editor && current_user_can( 'editor' ) ) {
     270                return self::disable_termageddon_enqueue();
     271            }
     272
     273            $disable_on_admin = get_option( 'termageddon_usercentrics_disable_admin', false ) ? true : false;
     274            if ( $disable_on_admin && current_user_can( 'administrator' ) ) {
     275                return self::disable_termageddon_enqueue();
     276            }
     277
     278            if ( Termageddon_Usercentrics::is_geoip_enabled() && ! Termageddon_Usercentrics::is_ajax_mode_enabled() && Termageddon_Usercentrics::should_hide_due_to_location() ) {
     279                return self::disable_termageddon_enqueue();
     280            }
     281        }
     282
     283        $settings_id            = Termageddon_Usercentrics::get_settings_id();
     284        $embed_version          = Termageddon_Usercentrics::get_embed_script_version();
     285        $should_enqueue_scripts = Termageddon_Usercentrics::get_embed_injection_method() === 'wp_enqueue_scripts';
     286
     287        if ( $settings_id && $should_enqueue_scripts ) {
     288            // Enqueue Embed Script.
     289            wp_enqueue_script( $this->plugin_name . '-preconnect', '//privacy-proxy.usercentrics.eu', array(), $this->version, false );
     290            wp_enqueue_script( $this->plugin_name . '-sdp', '//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js', array(), $this->version, false );
     291            if ( 'v2' === $embed_version ) {
     292                wp_enqueue_script( $this->plugin_name . '-cmp', '//app.usercentrics.eu/browser-ui/latest/loader.js', array(), $this->version, false );
     293            } else {
     294                wp_enqueue_script( $this->plugin_name . '-cmp', '//web.cmp.usercentrics.eu/ui/loader.js', array(), $this->version, false );
     295            }
     296            wp_enqueue_script( $this->plugin_name . '-translations', plugin_dir_url( __FILE__ ) . 'js/termageddon-usercentrics-translations.min.js', array(), $this->version, false );
     297        }
     298
     299        if ( Termageddon_Usercentrics::is_geoip_enabled() && Termageddon_Usercentrics::is_ajax_mode_enabled() ) {
     300            wp_enqueue_script( $this->plugin_name . '-geoip-disable', plugin_dir_url( __FILE__ ) . 'js/termageddon-usercentrics-geoip-disable.min.js', array(), $this->version, array() );
     301        }
     302
     303        foreach ( array_keys( Termageddon_Usercentrics::get_integrations() ) as $integration ) {
     304            if ( Termageddon_Usercentrics::is_integration_enabled( $integration ) ) {
     305                $slug = str_replace( '_', '-', $integration );
     306                wp_enqueue_script( $this->plugin_name . '-integration-' . $slug, plugin_dir_url( __FILE__ ) . 'js/termageddon-usercentrics-integration-' . $slug . '.min.js', array(), $this->version, array() );
     307            }
     308        }
     309
     310    }
     311
     312    /**
     313     * Filter the script loader tag to add the correct attributes to the script tags for Usercentrics.
     314     *
     315     * @param string $tag    The full HTML tag for the script.
     316     * @param string $handle The script handle/ID.
     317     * @param string $src    The script source URL.
     318     * @return string The modified script tag.
     319     */
     320    public function filter_script_loader_tag( $tag, $handle, $src ) {
     321        switch ( $handle ) {
     322            case $this->plugin_name . '-preconnect':
     323                $tag = '<link rel="preconnect" href="' . esc_url( $src ) . '">';
     324                break;
     325            case $this->plugin_name . '-preload':
     326                $tag = '<link rel="preload" href="' . esc_url( $src ) . '" as="script">';
     327                break;
     328            case $this->plugin_name . '-cmp':
     329                $tag = '<script type="text/javascript" id="usercentrics-cmp" data-cmp-version="' . esc_attr( Termageddon_Usercentrics::get_embed_script_version() ) . '" src="' . esc_url( $src ) . '" data-settings-id="' . esc_attr( Termageddon_Usercentrics::get_settings_id() ) . '" async></script>';
     330                break;
     331            case $this->plugin_name . '-translations':
     332                $tag = '<script type="text/javascript" id="usercentrics-translations" src="' . esc_url( $src ) . '"></script>';
     333                break;
     334        }
     335
     336        return $tag;
     337    }
    273338
    274339}
  • termageddon-usercentrics/trunk/public/js/termageddon-usercentrics-ajax.js

    r3160131 r3238690  
    22const tuDebug = termageddon_usercentrics_obj.debug === "true";
    33const tuPSLHide = termageddon_usercentrics_obj["psl_hide"] === "true";
     4const tuToggle = "div#usercentrics-root,aside#usercentrics-cmp-ui";
    45
    56if (tuDebug) console.log("UC: AJAX script initialized");
     
    3738                jQuery("#usercentrics-psl, .usercentrics-psl").show();
    3839
    39             jQuery("div#usercentrics-root").show();
     40            jQuery(tuToggle).show();
    4041
    4142            if (!UC_UI.isConsentRequired()) return UC_UI.closeCMP();
     
    4748                jQuery("#usercentrics-psl, .usercentrics-psl").hide();
    4849
    49             jQuery("div#usercentrics-root").hide();
     50            jQuery(tuToggle).hide();
    5051
    5152            //Check for already acceptance.
  • termageddon-usercentrics/trunk/public/js/termageddon-usercentrics-ajax.min.js

    r3160131 r3238690  
    1 const tuCookieHideName="tu-geoip-hide",tuDebug="true"===termageddon_usercentrics_obj.debug,tuPSLHide="true"===termageddon_usercentrics_obj.psl_hide;tuDebug&&console.log("UC: AJAX script initialized"),window.addEventListener("UC_UI_INITIALIZED",(function(){const getCookie=name=>{const value=`; ${document.cookie}`,parts=value.split(`; ${name}=`);if(2===parts.length)return parts.pop().split(";").shift()},getQueryParams=param=>{const params=new Proxy(new URLSearchParams(window.location.search),{get:(searchParams,prop)=>searchParams.get(prop)});return params[param]},setCookie=(name,value,days)=>{var expires="";if(days){var date=new Date;date.setTime(date.getTime()+24*days*60*60*1e3),expires="; expires="+date.toUTCString()}document.cookie=name+"="+(value||"")+expires+"; path=/"},updateCookieConsent=hide=>{if(!hide)return tuDebug&&console.log("UC: Showing consent widget"),tuPSLHide&&jQuery("#usercentrics-psl, .usercentrics-psl").show(),jQuery("div#usercentrics-root").show(),UC_UI.isConsentRequired()?UC_UI.showFirstLayer():UC_UI.closeCMP();tuDebug&&console.log("UC: Hiding consent widget"),tuPSLHide&&jQuery("#usercentrics-psl, .usercentrics-psl").hide(),jQuery("div#usercentrics-root").hide(),UC_UI.areAllConsentsAccepted()||UC_UI.acceptAllConsents().then(()=>{tuDebug&&console.log("UC: All consents have been accepted."),UC_UI.closeCMP().then(()=>{tuDebug&&console.log("UC: CMP Widget has been closed.")})})};if("undefined"==typeof UC_UI)return console.error("Usercentrics not loaded");const query_hide=""===getQueryParams("enable-usercentrics"),cookie_hide=getCookie("tu-geoip-hide");if(null==cookie_hide||tuDebug){tuDebug&&console.log("UC: Making AJAX Call");var data={action:"uc_geolocation_lookup",nonce:termageddon_usercentrics_obj.nonce};void 0!==termageddon_usercentrics_obj.location&&(data.location=termageddon_usercentrics_obj.location),jQuery.post(termageddon_usercentrics_obj.ajax_url,data).done((function(response){if(!response.success)return console.error("Unable to lookup location.",response.message||"");if(!response.data)return console.error("Location data was not provided.",response.data);const data=response.data;if(tuDebug&&console.log("TERMAGEDDON USERCENTRICS (AJAX)\nIP Address: "+data.ipAddress+"\nCity: "+(data.city||"Unknown")+"\nState: "+(data.state||"Unknown")+"\nCountry: "+(data.country||"Unknown")+"\nLocations: ",data.locations),query_hide)return tuDebug&&console.log("UC: Enabling due to query parameter override.","Showing Usercentrics"),updateCookieConsent(!1);setCookie("tu-geoip-hide",data.hide?"true":"false"),updateCookieConsent(data.hide)})).fail((function(response){console.error("Usercentrics: Invalid response returned. Showing widget as a default.",response),updateCookieConsent(!1)}))}else tuDebug&&console.log("UC: Cookie found.",(cookie_hide?"Showing":"Hiding")+" Usercentrics"),updateCookieConsent("true"===cookie_hide)}));
     1const tuCookieHideName="tu-geoip-hide",tuDebug="true"===termageddon_usercentrics_obj.debug,tuPSLHide="true"===termageddon_usercentrics_obj.psl_hide,tuToggle="div#usercentrics-root,aside#usercentrics-cmp-ui";tuDebug&&console.log("UC: AJAX script initialized"),window.addEventListener("UC_UI_INITIALIZED",(function(){const getCookie=name=>{const value=`; ${document.cookie}`,parts=value.split(`; ${name}=`);if(2===parts.length)return parts.pop().split(";").shift()},getQueryParams=param=>{const params=new Proxy(new URLSearchParams(window.location.search),{get:(searchParams,prop)=>searchParams.get(prop)});return params[param]},setCookie=(name,value,days)=>{var expires="";if(days){var date=new Date;date.setTime(date.getTime()+24*days*60*60*1e3),expires="; expires="+date.toUTCString()}document.cookie=name+"="+(value||"")+expires+"; path=/"},updateCookieConsent=hide=>{if(!hide)return tuDebug&&console.log("UC: Showing consent widget"),tuPSLHide&&jQuery("#usercentrics-psl, .usercentrics-psl").show(),jQuery(tuToggle).show(),UC_UI.isConsentRequired()?UC_UI.showFirstLayer():UC_UI.closeCMP();tuDebug&&console.log("UC: Hiding consent widget"),tuPSLHide&&jQuery("#usercentrics-psl, .usercentrics-psl").hide(),jQuery(tuToggle).hide(),UC_UI.areAllConsentsAccepted()||UC_UI.acceptAllConsents().then(()=>{tuDebug&&console.log("UC: All consents have been accepted."),UC_UI.closeCMP().then(()=>{tuDebug&&console.log("UC: CMP Widget has been closed.")})})};if("undefined"==typeof UC_UI)return console.error("Usercentrics not loaded");const query_hide=""===getQueryParams("enable-usercentrics"),cookie_hide=getCookie("tu-geoip-hide");if(null==cookie_hide||tuDebug){tuDebug&&console.log("UC: Making AJAX Call");var data={action:"uc_geolocation_lookup",nonce:termageddon_usercentrics_obj.nonce};void 0!==termageddon_usercentrics_obj.location&&(data.location=termageddon_usercentrics_obj.location),jQuery.post(termageddon_usercentrics_obj.ajax_url,data).done((function(response){if(!response.success)return console.error("Unable to lookup location.",response.message||"");if(!response.data)return console.error("Location data was not provided.",response.data);const data=response.data;if(tuDebug&&console.log("TERMAGEDDON USERCENTRICS (AJAX)\nIP Address: "+data.ipAddress+"\nCity: "+(data.city||"Unknown")+"\nState: "+(data.state||"Unknown")+"\nCountry: "+(data.country||"Unknown")+"\nLocations: ",data.locations),query_hide)return tuDebug&&console.log("UC: Enabling due to query parameter override.","Showing Usercentrics"),updateCookieConsent(!1);setCookie("tu-geoip-hide",data.hide?"true":"false"),updateCookieConsent(data.hide)})).fail((function(response){console.error("Usercentrics: Invalid response returned. Showing widget as a default.",response),updateCookieConsent(!1)}))}else tuDebug&&console.log("UC: Cookie found.",(cookie_hide?"Showing":"Hiding")+" Usercentrics"),updateCookieConsent("true"===cookie_hide)}));
  • termageddon-usercentrics/trunk/termageddon-usercentrics.php

    r3191623 r3238690  
    1515 * Plugin Name:       Termageddon + Usercentrics
    1616 * Description:       Easily integrate the Usercentrics consent solution into your website while controlling visibility for logged in users and admins.
    17  * Version:           1.5.4
     17 * Version:           1.6.0
    1818 * Author:            Termageddon
    1919 * Author URI:        https://termageddon.com
     
    3434 * Rename this for your plugin and update it as you release new versions.
    3535 */
    36 define( 'TERMAGEDDON_COOKIE_VERSION', '1.5.4' );
     36define( 'TERMAGEDDON_COOKIE_VERSION', '1.6.0' );
    3737
    3838define( 'TERMAGEDDON_COOKIE_PLUGIN_PATH', dirname( __FILE__ ) );// No trailing slash.
Note: See TracChangeset for help on using the changeset viewer.