• Resolved wpuser

    (@forinn)


    I do have the following strange issue that occurs.

    Usually, my snippet conditional loading settings are working as expected. However, I now have a particular strange situation with the WHERE for one particular snippet.

    The snippet is to delay turnstile until user interaction, except for the registration page.

    function bzp_should_delay_turnstile_script( $value ) {
    $value = html_entity_decode(
    (string) $value,
    ENT_QUOTES | ENT_HTML5,
    'UTF-8'
    );

    $needles = array(
    '/wp-content/plugins/buddypress-recaptcha/public/js/wbc-captcha-theme.js',
    '/wp-content/plugins/buddypress-recaptcha/public/js/recaptcha-for-buddypress-public.js',
    'challenges.cloudflare.com/turnstile/v0/api.js',
    );

    foreach ( $needles as $needle ) {
    if ( false !== strpos( $value, $needle ) ) {
    return true;
    }
    }

    return false;
    }

    add_filter(
    'script_loader_tag',
    function ( $tag, $handle, $src ) {
    if (
    ! bzp_should_delay_turnstile_script( $src ) &&
    ! bzp_should_delay_turnstile_script( $tag )
    ) {
    return $tag;
    }

    if ( false !== strpos( $tag, 'data-bzp-captcha-delay' ) ) {
    return $tag;
    }

    if ( class_exists( 'WP_HTML_Tag_Processor' ) ) {
    $processor = new WP_HTML_Tag_Processor( $tag );

    if ( $processor->next_tag( array( 'tag_name' => 'SCRIPT' ) ) ) {
    $actual_src = $processor->get_attribute( 'src' );

    if ( is_string( $actual_src ) && '' !== $actual_src ) {
    $processor->set_attribute( 'data-bzp-captcha-delay', '1' );
    $processor->set_attribute( 'data-bzp-src', $actual_src );
    $processor->remove_attribute( 'src' );

    return $processor->get_updated_html();
    }
    }
    }

    $modified_tag = preg_replace(
    '/\ssrc=(["\'])(.*?)\1/i',
    ' data-bzp-src=$1$2$1',
    $tag,
    1,
    $count
    );

    if ( 1 !== $count ) {
    return $tag;
    }

    return preg_replace(
    '/<script\b/i',
    '<script data-bzp-captcha-delay="1"',
    $modified_tag,
    1
    );
    },
    999,
    3
    );

    function bzp_turnstile_delay_loader() {
    ?>
    <script id="bzp-turnstile-delay" data-cfasync="false">
    (function () {
    'use strict';

    var selector = 'script[data-bzp-captcha-delay][data-bzp-src]';

    var requested = false;
    var scheduled = false;
    var observer = null;
    var loadPromise = null;

    var debug = true;

    var events = [
    'pointermove',
    'pointerdown',
    'mousemove',
    'mousedown',
    'keydown',
    'touchstart',
    'wheel',
    'scroll',
    'click',
    'focusin'
    ];

    var targets = [
    window,
    document
    ];

    var listenerOptions = {
    passive: true,
    capture: true
    };

    function log() {
    if (!debug || !window.console || !window.console.log) {
    return;
    }

    window.console.log.apply(window.console, arguments);
    }

    function addInteractionListeners() {
    targets.forEach(function (target) {
    events.forEach(function (eventName) {
    target.addEventListener(
    eventName,
    requestLoading,
    listenerOptions
    );
    });
    });
    }

    function removeInteractionListeners() {
    targets.forEach(function (target) {
    events.forEach(function (eventName) {
    target.removeEventListener(
    eventName,
    requestLoading,
    listenerOptions
    );
    });
    });
    }

    function getPriority(node) {
    var src = node.getAttribute('data-bzp-src') || '';

    if (src.indexOf('wbc-captcha-theme.js') !== -1) {
    return 10;
    }

    if (src.indexOf('recaptcha-for-buddypress-public.js') !== -1) {
    return 20;
    }

    if (src.indexOf('/turnstile/v0/api.js') !== -1) {
    return 30;
    }

    return 100;
    }

    function copyScriptAttributes(oldScript, newScript) {
    Array.prototype.forEach.call(
    oldScript.attributes,
    function (attribute) {
    var name = attribute.name.toLowerCase();

    if (
    name === 'src' ||
    name === 'data-bzp-src' ||
    name === 'data-bzp-captcha-delay' ||
    name === 'data-bzp-loading' ||
    name === 'async' ||
    name === 'defer'
    ) {
    return;
    }

    if (name === 'nonce') {
    newScript.nonce = oldScript.nonce || attribute.value;
    return;
    }

    newScript.setAttribute(attribute.name, attribute.value);
    }
    );
    }

    function loadScript(oldScript) {
    return new Promise(function (resolve) {
    var src = oldScript.getAttribute('data-bzp-src');

    if (!src || !oldScript.parentNode) {
    resolve();
    return;
    }

    if (oldScript.getAttribute('data-bzp-loading') === '1') {
    resolve();
    return;
    }

    oldScript.setAttribute('data-bzp-loading', '1');

    var newScript = document.createElement('script');

    copyScriptAttributes(oldScript, newScript);

    /*
    * Dynamische scripts zijn standaard async.
    * async=false houdt uitvoervolgorde betrouwbaar.
    */
    newScript.async = false;

    newScript.onload = function () {
    log('CAPTCHA-script geladen:', src);
    resolve();
    };

    newScript.onerror = function () {
    if (window.console && window.console.error) {
    window.console.error(
    'Kon uitgesteld CAPTCHA-script niet laden:',
    src
    );
    }

    resolve();
    };

    newScript.src = src;

    oldScript.parentNode.replaceChild(
    newScript,
    oldScript
    );
    });
    }

    function getDelayedNodes() {
    var nodes = Array.prototype.slice.call(
    document.querySelectorAll(selector)
    );

    nodes = nodes.filter(function (node) {
    return (
    node.parentNode &&
    node.getAttribute('data-bzp-loading') !== '1'
    );
    });

    nodes.sort(function (a, b) {
    var priorityDifference = getPriority(a) - getPriority(b);

    if (priorityDifference !== 0) {
    return priorityDifference;
    }

    return 0;
    });

    return nodes;
    }

    function loadDelayedScripts() {
    var nodes = getDelayedNodes();

    if (!nodes.length) {
    log('Nog geen uitgestelde CAPTCHA-scripts gevonden.');
    return Promise.resolve();
    }

    log('Uitgestelde CAPTCHA-scripts gevonden:', nodes.length);

    var chain = Promise.resolve();

    nodes.forEach(function (node) {
    chain = chain.then(function () {
    return loadScript(node);
    });
    });

    return chain;
    }

    function scheduleLoadDelayedScripts() {
    if (scheduled) {
    return;
    }

    scheduled = true;

    window.setTimeout(function () {
    scheduled = false;

    loadPromise = loadDelayedScripts().then(function () {
    return waitForTurnstileObject(8000);
    });
    }, 25);
    }

    function startObserver() {
    if (observer || !document.documentElement) {
    return;
    }

    observer = new MutationObserver(function () {
    scheduleLoadDelayedScripts();
    });

    observer.observe(
    document.documentElement,
    {
    childList: true,
    subtree: true
    }
    );

    window.setTimeout(function () {
    if (observer) {
    observer.disconnect();
    observer = null;
    }
    }, 10000);
    }

    function requestLoading(event) {
    if (requested) {
    return loadPromise || Promise.resolve();
    }

    requested = true;

    log(
    'CAPTCHA-load gestart door:',
    event && event.type ? event.type : 'onbekend'
    );

    removeInteractionListeners();

    loadPromise = loadDelayedScripts().then(function () {
    return waitForTurnstileObject(8000);
    });

    startObserver();

    if (document.readyState === 'loading') {
    document.addEventListener(
    'DOMContentLoaded',
    function () {
    scheduleLoadDelayedScripts();
    },
    { once: true }
    );
    } else {
    scheduleLoadDelayedScripts();
    }

    return loadPromise;
    }

    function waitForTurnstileObject(timeout) {
    return new Promise(function (resolve) {
    var started = Date.now();

    function check() {
    if (
    window.turnstile &&
    typeof window.turnstile.execute === 'function'
    ) {
    log('Turnstile object beschikbaar.');
    resolve(true);
    return;
    }

    if (Date.now() - started >= timeout) {
    log('Timeout: Turnstile object nog niet beschikbaar.');
    resolve(false);
    return;
    }

    window.setTimeout(check, 50);
    }

    check();
    });
    }

    function getTurnstileResponse(form) {
    var field = form.querySelector(
    'input[name="cf-turnstile-response"], textarea[name="cf-turnstile-response"]'
    );

    if (!field) {
    field = document.querySelector(
    'input[name="cf-turnstile-response"], textarea[name="cf-turnstile-response"]'
    );
    }

    if (!field) {
    return '';
    }

    return (field.value || '').trim();
    }

    function findTurnstileContainers(form) {
    var containers = [];

    if (form) {
    containers = containers.concat(
    Array.prototype.slice.call(
    form.querySelectorAll('.cf-turnstile, [data-sitekey]')
    )
    );
    }

    containers = containers.concat(
    Array.prototype.slice.call(
    document.querySelectorAll('.cf-turnstile')
    )
    );

    /*
    * Duplicaten verwijderen.
    */
    return containers.filter(function (item, index, list) {
    return list.indexOf(item) === index;
    });
    }

    function executeTurnstile(form) {
    if (
    !window.turnstile ||
    typeof window.turnstile.execute !== 'function'
    ) {
    return;
    }

    findTurnstileContainers(form).forEach(function (container) {
    try {
    window.turnstile.execute(container);
    log('Turnstile execute aangeroepen.');
    } catch (error) {
    log('Turnstile execute overgeslagen:', error);
    }
    });
    }

    function waitForTurnstileResponse(form, timeout) {
    return new Promise(function (resolve) {
    var started = Date.now();

    function check() {
    var token = getTurnstileResponse(form);

    if (token) {
    log('Turnstile-token gevonden.');
    resolve(true);
    return;
    }

    if (Date.now() - started >= timeout) {
    log('Timeout: geen Turnstile-token gevonden.');
    resolve(false);
    return;
    }

    window.setTimeout(check, 100);
    }

    check();
    });
    }

    function setFormWaiting(form, waiting) {
    var submitButtons = form.querySelectorAll(
    'button[type="submit"], input[type="submit"]'
    );

    submitButtons.forEach(function (button) {
    if (waiting) {
    button.setAttribute('data-bzp-original-disabled', button.disabled ? '1' : '0');
    button.disabled = true;
    } else {
    if (button.getAttribute('data-bzp-original-disabled') !== '1') {
    button.disabled = false;
    }

    button.removeAttribute('data-bzp-original-disabled');
    }
    });
    }

    function resubmitForm(form, submitter) {
    form.setAttribute('data-bzp-captcha-ready-submit', '1');

    if (
    submitter &&
    typeof form.requestSubmit === 'function'
    ) {
    form.requestSubmit(submitter);
    return;
    }

    if (typeof form.requestSubmit === 'function') {
    form.requestSubmit();
    return;
    }

    form.submit();
    }

    document.addEventListener(
    'submit',
    function (event) {
    var form = event.target;

    if (!form || !form.querySelector) {
    return;
    }

    if (
    !form.querySelector('.cf-turnstile, [name="cf-turnstile-response"]') &&
    !document.querySelector('.cf-turnstile, [name="cf-turnstile-response"]')
    ) {
    return;
    }

    if (form.getAttribute('data-bzp-captcha-ready-submit') === '1') {
    form.removeAttribute('data-bzp-captcha-ready-submit');
    return;
    }

    if (getTurnstileResponse(form)) {
    return;
    }

    event.preventDefault();
    event.stopImmediatePropagation();

    var submitter = event.submitter || null;

    setFormWaiting(form, true);

    log('Submit geblokkeerd: wachten op Turnstile-token.');

    Promise.resolve()
    .then(function () {
    return requestLoading({ type: 'submit' });
    })
    .then(function () {
    executeTurnstile(form);
    return waitForTurnstileResponse(form, 10000);
    })
    .then(function (hasToken) {
    setFormWaiting(form, false);

    if (hasToken) {
    resubmitForm(form, submitter);
    return;
    }

    if (window.console && window.console.warn) {
    window.console.warn(
    'Geen Turnstile-token na wachten. Formulier wordt niet automatisch opnieuw ingediend.'
    );
    }
    });
    },
    true
    );

    addInteractionListeners();
    })();
    </script>
    <?php
    }

    add_action( 'wp_head', 'bzp_turnstile_delay_loader', 1 );
    add_action( 'login_head', 'bzp_turnstile_delay_loader', 1 );

    The condition is:

    Logged in = No
    Page URL does not contain or is not and than the correct value.
    However, it works exactly the other way around. It WILL load when I say to NOT load it, and it won’t load when I say to DO lot it.

    The particular page is NOT cached. So it is not cache issue.

    Trust me, I have correctly implemented it. I am working with WP code for years without any issues and it is my lifesaver. See screenshots for reference

    Checklist:

    • Snippet is active
    • Page URL value is correct
    • Changes have been published
    • Snippet type is PHP
    • Cache is not enabled
    • Settings, see screenshots below

    Outcome: It will load exactly on the page I have set it not to load. Only for this snippet.

You must be logged in to reply to this topic.