Plugin Directory

Changeset 3435793


Ignore:
Timestamp:
01/09/2026 10:29:10 AM (3 months ago)
Author:
slaFFik
Message:

release v1.4.0

Location:
blocks-randomizer
Files:
15 added
7 edited

Legend:

Unmodified
Added
Removed
  • blocks-randomizer/trunk/blocks-randomizer.php

    r3431694 r3435793  
    44 * Plugin URI:        https://github.com/slaffik/blocks-randomizer
    55 * Description:       Display randomly any of the top-level blocks within the "Blocks Randomizer" main block.
    6  * Version:           1.3.1
     6 * Version:           1.4.0
    77 * Requires at least: 6.7
    88 * Requires PHP:      7.4
  • blocks-randomizer/trunk/build/blocks-manifest.php

    r3431694 r3435793  
    66        'apiVersion' => 3,
    77        'name' => 'blocks-randomizer/holder',
    8         'version' => '1.3.1',
     8        'version' => '1.4.0',
    99        'title' => 'Blocks Randomizer',
    1010        'category' => 'widgets',
     
    1919                'type' => 'boolean',
    2020                'default' => false
     21            ),
     22            'preventRepeatsUsingSession' => array(
     23                'type' => 'boolean',
     24                'default' => false
    2125            )
    2226        ),
     
    2832        'editorStyle' => 'file:./index.css',
    2933        'style' => 'file:./style-index.css',
    30         'render' => 'file:./render.php',
    31         'viewScript' => 'file:./view.js'
     34        'render' => 'file:./render.php'
    3235    )
    3336);
  • blocks-randomizer/trunk/build/blocks-randomizer/block.json

    r3431694 r3435793  
    33  "apiVersion": 3,
    44  "name": "blocks-randomizer/holder",
    5   "version": "1.3.1",
     5  "version": "1.4.0",
    66  "title": "Blocks Randomizer",
    77  "category": "widgets",
     
    1616      "type": "boolean",
    1717      "default": false
     18    },
     19    "preventRepeatsUsingSession": {
     20      "type": "boolean",
     21      "default": false
    1822    }
    1923  },
     
    2529  "editorStyle": "file:./index.css",
    2630  "style": "file:./style-index.css",
    27   "render": "file:./render.php",
    28   "viewScript": "file:./view.js"
     31  "render": "file:./render.php"
    2932}
  • blocks-randomizer/trunk/build/blocks-randomizer/index.asset.php

    r3431694 r3435793  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '06c48da46934c53268fa');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'f51feb6ff5a68df2d379');
  • blocks-randomizer/trunk/build/blocks-randomizer/index.js

    r3431694 r3435793  
    1 (()=>{"use strict";var e,o={334(){const e=window.wp.blocks,o=window.wp.i18n,r=window.wp.blockEditor,n=window.wp.components,l=window.wp.element,a=window.ReactJSXRuntime,t=JSON.parse('{"UU":"blocks-randomizer/holder"}');(0,e.registerBlockType)(t.UU,{keywords:[(0,o.__)("content","blocks-randomizer"),(0,o.__)("random","blocks-randomizer"),(0,o.__)("randomizer","blocks-randomizer")],example:{innerBlocks:[{name:"core/heading",attributes:{level:1,content:(0,o.__)("Randomly display custom block inside","blocks-randomizer")}},{name:"core/spacer",attributes:{height:"25px"}},{name:"core/heading",attributes:{level:2,content:(0,o.__)("it can be images …","blocks-randomizer")}},{name:"core/heading",attributes:{level:2,content:(0,o.__)("… or any text blocks","blocks-randomizer")}}]},edit:function({attributes:t,setAttributes:s}){const{numberOfItems:i,shuffle:c}=t,d=(0,r.useBlockProps)({}),m=(0,l.useMemo)(()=>(0,e.getBlockTypes)().map(e=>e.name).filter(e=>"blocks-randomizer/holder"!==e),[]),b=(0,r.useInnerBlocksProps)({...d,className:"wp-block-blocks-randomizer-holder-inner"},{allowedBlocks:m,orientation:"vertical",defaultBlock:{name:"core/paragraph",attributes:{placeholder:(0,o.__)("Start typing or add any block inside this container…","blocks-randomizer")}},templateLock:!1});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(r.InspectorControls,{children:(0,a.jsxs)(n.PanelBody,{title:(0,o.__)("Display","blocks-randomizer"),initialOpen:!0,children:[(0,a.jsx)(n.__experimentalNumberControl,{__next40pxDefaultSize:!0,label:(0,o.__)("Number of child blocks to display","blocks-randomizer"),help:(0,o.__)("How many random blocks to show on the front-end. If you specify more than available, all blocks will be displayed.","blocks-randomizer"),value:i,onChange:e=>{const o=Math.max(0,parseInt(e,10));s({numberOfItems:o})},required:!0,min:0,step:1}),(0,a.jsx)(n.ToggleControl,{label:(0,o.__)("Shuffle Random Blocks","blocks-randomizer"),help:(0,o.__)("Randomize the order of randomly selected child blocks.","blocks-randomizer"),checked:c,disabled:i<2,onChange:e=>s({shuffle:e})})]})}),(0,a.jsx)("div",{...d,children:(0,a.jsx)("div",{...b})})]})},save:function({attributes:e,innerBlocks:o}){const n=r.useBlockProps.save({}),l=r.useInnerBlocksProps.save({...n});return(0,a.jsx)("div",{...l})}})}},r={};function n(e){var l=r[e];if(void 0!==l)return l.exports;var a=r[e]={exports:{}};return o[e](a,a.exports,n),a.exports}n.m=o,e=[],n.O=(o,r,l,a)=>{if(!r){var t=1/0;for(d=0;d<e.length;d++){for(var[r,l,a]=e[d],s=!0,i=0;i<r.length;i++)(!1&a||t>=a)&&Object.keys(n.O).every(e=>n.O[e](r[i]))?r.splice(i--,1):(s=!1,a<t&&(t=a));if(s){e.splice(d--,1);var c=l();void 0!==c&&(o=c)}}return o}a=a||0;for(var d=e.length;d>0&&e[d-1][2]>a;d--)e[d]=e[d-1];e[d]=[r,l,a]},n.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),(()=>{var e={414:0,650:0};n.O.j=o=>0===e[o];var o=(o,r)=>{var l,a,[t,s,i]=r,c=0;if(t.some(o=>0!==e[o])){for(l in s)n.o(s,l)&&(n.m[l]=s[l]);if(i)var d=i(n)}for(o&&o(r);c<t.length;c++)a=t[c],n.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return n.O(d)},r=globalThis.webpackChunkblocks_randomizer=globalThis.webpackChunkblocks_randomizer||[];r.forEach(o.bind(null,0)),r.push=o.bind(null,r.push.bind(r))})();var l=n.O(void 0,[650],()=>n(334));l=n.O(l)})();
     1(()=>{"use strict";var e,o={334(){const e=window.wp.blocks,o=window.wp.i18n,r=window.wp.blockEditor,n=window.wp.components,s=window.wp.element,l=window.ReactJSXRuntime,t=JSON.parse('{"UU":"blocks-randomizer/holder"}');(0,e.registerBlockType)(t.UU,{keywords:[(0,o.__)("content","blocks-randomizer"),(0,o.__)("random","blocks-randomizer"),(0,o.__)("randomizer","blocks-randomizer")],example:{innerBlocks:[{name:"core/heading",attributes:{level:1,content:(0,o.__)("Randomly display custom block inside","blocks-randomizer")}},{name:"core/spacer",attributes:{height:"25px"}},{name:"core/heading",attributes:{level:2,content:(0,o.__)("it can be images …","blocks-randomizer")}},{name:"core/heading",attributes:{level:2,content:(0,o.__)("… or any text blocks","blocks-randomizer")}}]},edit:function({attributes:t,setAttributes:a}){const{numberOfItems:i,shuffle:c,preventRepeatsUsingSession:d}=t,m=(0,r.useBlockProps)({}),b=(0,s.useMemo)(()=>(0,e.getBlockTypes)().map(e=>e.name).filter(e=>"blocks-randomizer/holder"!==e),[]),p=(0,r.useInnerBlocksProps)({...m,className:"wp-block-blocks-randomizer-holder-inner"},{allowedBlocks:b,orientation:"vertical",defaultBlock:{name:"core/paragraph",attributes:{placeholder:(0,o.__)("Start typing or add any block inside this container…","blocks-randomizer")}},templateLock:!1});return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(r.InspectorControls,{children:(0,l.jsxs)(n.PanelBody,{title:(0,o.__)("Display","blocks-randomizer"),initialOpen:!0,children:[(0,l.jsx)(n.__experimentalNumberControl,{__next40pxDefaultSize:!0,label:(0,o.__)("Number of child blocks to display","blocks-randomizer"),help:(0,o.__)("How many random blocks to show on the front-end. If you specify more than available, all blocks will be displayed.","blocks-randomizer"),value:i,onChange:e=>{const o=Math.max(0,parseInt(e,10));a({numberOfItems:o})},required:!0,min:0,step:1}),(0,l.jsx)(n.ToggleControl,{label:(0,o.__)("Shuffle Random Blocks","blocks-randomizer"),help:(0,o.__)("Randomize the order of randomly selected child blocks.","blocks-randomizer"),checked:c,disabled:i<2,onChange:e=>a({shuffle:e})}),(0,l.jsx)(n.ToggleControl,{label:(0,o.__)("Prevent immediate repeats","blocks-randomizer"),help:(0,o.__)("Random blocks will stay the same until the browser is completely closed. This prevents different blocks from appearing when navigating between pages.","blocks-randomizer"),checked:d,onChange:e=>a({preventRepeatsUsingSession:e})})]})}),(0,l.jsx)("div",{...m,children:(0,l.jsx)("div",{...p})})]})},save:function({attributes:e,innerBlocks:o}){const n=r.useBlockProps.save({}),s=r.useInnerBlocksProps.save({...n});return(0,l.jsx)("div",{...s})}})}},r={};function n(e){var s=r[e];if(void 0!==s)return s.exports;var l=r[e]={exports:{}};return o[e](l,l.exports,n),l.exports}n.m=o,e=[],n.O=(o,r,s,l)=>{if(!r){var t=1/0;for(d=0;d<e.length;d++){for(var[r,s,l]=e[d],a=!0,i=0;i<r.length;i++)(!1&l||t>=l)&&Object.keys(n.O).every(e=>n.O[e](r[i]))?r.splice(i--,1):(a=!1,l<t&&(t=l));if(a){e.splice(d--,1);var c=s();void 0!==c&&(o=c)}}return o}l=l||0;for(var d=e.length;d>0&&e[d-1][2]>l;d--)e[d]=e[d-1];e[d]=[r,s,l]},n.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),(()=>{var e={414:0,650:0};n.O.j=o=>0===e[o];var o=(o,r)=>{var s,l,[t,a,i]=r,c=0;if(t.some(o=>0!==e[o])){for(s in a)n.o(a,s)&&(n.m[s]=a[s]);if(i)var d=i(n)}for(o&&o(r);c<t.length;c++)l=t[c],n.o(e,l)&&e[l]&&e[l][0](),e[l]=0;return n.O(d)},r=globalThis.webpackChunkblocks_randomizer=globalThis.webpackChunkblocks_randomizer||[];r.forEach(o.bind(null,0)),r.push=o.bind(null,r.push.bind(r))})();var s=n.O(void 0,[650],()=>n(334));s=n.O(s)})();
  • blocks-randomizer/trunk/build/blocks-randomizer/render.php

    r3384247 r3435793  
    2424
    2525    // Get all inner blocks as an array.
    26     $inner_blocks = iterator_to_array( $block->inner_blocks );
    27     $total_blocks = count( $inner_blocks );
     26    $inner_blocks  = iterator_to_array( $block->inner_blocks );
     27    $random_blocks = [];
    2828
    29     // If requesting more blocks than available, display all of them.
    30     if ( $number_of_items >= $total_blocks ) {
    31         $random_blocks = $inner_blocks;
     29    // This id will be different every time the block holder inner blocks are changed (attributes do not affect this).
     30    $session_cookie_name = 'br_ids_' . md5( wp_json_encode( $inner_blocks ) );
     31    $stored_block_ids    = [];
     32
     33    // Check if session-based repeat prevention is enabled.
     34    $prevent_repeats = isset( $attributes['preventRepeatsUsingSession'] ) && (bool) $attributes['preventRepeatsUsingSession'];
     35
     36    if ( $prevent_repeats ) {
     37        $stored_block_ids = array_filter(
     38            (array) explode( ',', $_COOKIE[ $session_cookie_name ] ?? '' ),
     39            static function ( $hash ) {
     40                return ! empty( $hash ) && is_string( $hash ) && preg_match( '/^[a-f0-9]{32}$/i', $hash );
     41            }
     42        );
    3243    } else {
    33         // Pick N random blocks.
    34         $random_keys = array_rand( $inner_blocks, $number_of_items );
    35 
    36         // array_rand returns a single value if $number_of_items is 1, so normalize to array.
    37         if ( ! is_array( $random_keys ) ) {
    38             $random_keys = array( $random_keys );
    39         }
    40 
    41         $random_blocks = array();
    42         foreach ( $random_keys as $key ) {
    43             $random_blocks[] = $inner_blocks[ $key ];
     44        // Clear the cookie if it exists.
     45        if ( isset( $_COOKIE[ $session_cookie_name ] ) ) {
     46            setcookie(
     47                $session_cookie_name,
     48                '',
     49                [
     50                    'expires'  => time() - 3600,
     51                    'path'     => defined( 'COOKIEPATH' ) ? COOKIEPATH : '/',
     52                    'secure'   => is_ssl(),
     53                    'httponly' => true,
     54                    'samesite' => 'Lax',
     55                ]
     56            );
     57            unset( $_COOKIE[ $session_cookie_name ] );
    4458        }
    4559    }
    4660
    47     // Shuffle the selected blocks if shuffle is enabled and more than 1 block is displayed.
    48     $shuffle = isset( $attributes['shuffle'] ) && (bool) $attributes['shuffle'];
     61    if ( empty( $stored_block_ids ) ) {
     62        /*
     63         * We don't have the session IDs yet - pick new random blocks.
     64         */
     65        $total_blocks  = count( $inner_blocks );
    4966
    50     if ( $shuffle && $number_of_items > 1 && count( $random_blocks ) > 1 ) {
    51         shuffle( $random_blocks );
     67        // If requesting more blocks than available, display all of them.
     68        if ( $number_of_items >= $total_blocks ) {
     69            $random_blocks = $inner_blocks;
     70        } else {
     71            // Pick N random blocks.
     72            $random_keys = (array) array_rand( $inner_blocks, $number_of_items );
     73
     74            foreach ( $random_keys as $key ) {
     75                $random_blocks[] = $inner_blocks[ $key ];
     76            }
     77        }
     78
     79        // Shuffle the selected blocks if shuffle is enabled and more than 1 block is displayed.
     80        $shuffle = isset( $attributes['shuffle'] ) && (bool) $attributes['shuffle'];
     81
     82        if ( $shuffle && $number_of_items > 1 && count( $random_blocks ) > 1 ) {
     83            shuffle( $random_blocks );
     84        }
     85
     86        // Save to the session cookie only if the option is enabled.
     87        if ( $prevent_repeats ) {
     88            // Generate a unique block instance ID.
     89            $ids = array_map(
     90                static function ( $inner_block ) {
     91                    return md5( wp_json_encode( $inner_block->parsed_block ) );
     92                },
     93                $random_blocks
     94            );
     95
     96            // After 100 blocks we are approaching cookie size limits.
     97            if ( ! empty( $ids ) && count( $ids ) <= 100 ) {
     98                setcookie(
     99                    $session_cookie_name,
     100                    implode( ',', $ids ),
     101                    [
     102                        // Omit 'expires' to use a session cookie (setcookie() defaults to expires=0).
     103                        'path'     => defined( 'COOKIEPATH' ) ? COOKIEPATH : '/',
     104                        'secure'   => is_ssl(),
     105                        'httponly' => true, // Don't allow JavaScript access.
     106                        'samesite' => 'Lax',
     107                    ]
     108                );
     109            }
     110        }
     111
     112    } else {
     113        /*
     114         * Get the random blocks out of the session IDs - preserve the original (shuffled) order.
     115         */
     116        foreach ( $stored_block_ids as $session_block_id ) {
     117            foreach ( $inner_blocks as $inner_block ) {
     118                $block_id = md5( wp_json_encode( $inner_block->parsed_block ) );
     119
     120                if ( $block_id === $session_block_id ) {
     121                    $random_blocks[] = $inner_block;
     122                    break; // Found the block, move to the next session_block_id.
     123                }
     124            }
     125        }
    52126    }
    53127
    54128    // Render each selected block.
    55129    foreach ( $random_blocks as $random_block ) {
     130        /* @var $random_block WP_Block */
    56131        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    57132        echo $random_block->render();
  • blocks-randomizer/trunk/readme.txt

    r3431694 r3435793  
    55Requires PHP: 7.4
    66Tested up to: 6.9
    7 Stable tag: 1.3.1
     7Stable tag: 1.4.0
    88License: GPL-2.0-or-later
    99
     
    340340== Changelog ==
    341341
     342= 1.4.0 =
     343* Added: New cookie-based repeat prevention to ensure random blocks remain consistent across page loads within the same user session.
     344
    342345= 1.3.1 =
    343346* Changed: The plugin is fully compatible with WordPress 6.9.
Note: See TracChangeset for help on using the changeset viewer.