Changeset 3378680
- Timestamp:
- 10/15/2025 07:54:44 AM (6 months ago)
- Location:
- shutterpress-gallery
- Files:
-
- 30 edited
- 1 copied
-
tags/1.7.6 (copied) (copied from shutterpress-gallery/trunk)
-
tags/1.7.6/README.txt (modified) (2 diffs)
-
tags/1.7.6/includes/blocks/shutterpress-gallery-block/block.json (modified) (1 diff)
-
tags/1.7.6/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block-render.php (modified) (1 diff)
-
tags/1.7.6/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.asset.php (modified) (1 diff)
-
tags/1.7.6/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.js (modified) (1 diff)
-
tags/1.7.6/shutterpress-gallery.php (modified) (3 diffs)
-
tags/1.7.6/src/admin/Shutterpress_Gallery_Admin.php (modified) (2 diffs)
-
tags/1.7.6/src/admin/Shutterpress_Gallery_Elementor_Widget.php (modified) (1 diff)
-
tags/1.7.6/src/includes/Shutterpress_Gallery.php (modified) (1 diff)
-
tags/1.7.6/src/includes/Shutterpress_Gallery_REST.php (modified) (2 diffs)
-
tags/1.7.6/src/public/Shutterpress_Gallery_Public.php (modified) (2 diffs)
-
tags/1.7.6/src/shutterpress-gallery-block/block.json (modified) (1 diff)
-
tags/1.7.6/src/shutterpress-gallery-block/shutterpress-gallery-block-render.php (modified) (1 diff)
-
tags/1.7.6/src/shutterpress-gallery-block/shutterpress-gallery-block.js (modified) (6 diffs)
-
tags/1.7.6/vendor/composer/installed.php (modified) (2 diffs)
-
trunk/README.txt (modified) (2 diffs)
-
trunk/includes/blocks/shutterpress-gallery-block/block.json (modified) (1 diff)
-
trunk/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block-render.php (modified) (1 diff)
-
trunk/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.asset.php (modified) (1 diff)
-
trunk/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.js (modified) (1 diff)
-
trunk/shutterpress-gallery.php (modified) (3 diffs)
-
trunk/src/admin/Shutterpress_Gallery_Admin.php (modified) (2 diffs)
-
trunk/src/admin/Shutterpress_Gallery_Elementor_Widget.php (modified) (1 diff)
-
trunk/src/includes/Shutterpress_Gallery.php (modified) (1 diff)
-
trunk/src/includes/Shutterpress_Gallery_REST.php (modified) (2 diffs)
-
trunk/src/public/Shutterpress_Gallery_Public.php (modified) (2 diffs)
-
trunk/src/shutterpress-gallery-block/block.json (modified) (1 diff)
-
trunk/src/shutterpress-gallery-block/shutterpress-gallery-block-render.php (modified) (1 diff)
-
trunk/src/shutterpress-gallery-block/shutterpress-gallery-block.js (modified) (6 diffs)
-
trunk/vendor/composer/installed.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
shutterpress-gallery/tags/1.7.6/README.txt
r3376238 r3378680 6 6 Tested up to: 6.8 7 7 Requires PHP: 8.0 8 Stable tag: 1.7. 58 Stable tag: 1.7.6 9 9 License: GPLv2 or later 10 10 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 119 119 120 120 == Changelog == 121 122 = 1.7.6 = 123 124 * Update - Shortcodes show current post gallery when no id is set 125 * Update - Refactor Gallery Block Defaults 126 * Fix - Shortcodes take defaults from gallery template 121 127 122 128 = 1.7.5 = -
shutterpress-gallery/tags/1.7.6/includes/blocks/shutterpress-gallery-block/block.json
r3376238 r3378680 27 27 "galleryLayout": { 28 28 "type": "string", 29 "default": " masonry"29 "default": "grid" 30 30 }, 31 31 "galleryGap": { -
shutterpress-gallery/tags/1.7.6/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block-render.php
r3371808 r3378680 67 67 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) { 68 68 $gallery_attributes['infinite_scroll'] = '0'; 69 $gallery_attributes['use_lightbox'] = '0'; 69 70 } 70 71 71 72 if (method_exists($renderer, 'set_attributes')) { 72 73 $renderer->set_attributes($gallery_attributes); 73 }74 75 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) {76 74 } 77 75 -
shutterpress-gallery/tags/1.7.6/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.asset.php
r3376238 r3378680 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp- api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '0961de81d9cf02dac39c');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'aead3cea6f4ea9eea0c9'); -
shutterpress-gallery/tags/1.7.6/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.js
r3376238 r3378680 1 (()=>{"use strict";var e={n:l=>{var t=l&&l.__esModule?()=>l.default:()=>l;return e.d(t,{a:t}),t},d:(l,t)=>{for(var r in t)e.o(t,r)&&!e.o(l,r)&&Object.defineProperty(l,r,{enumerable:!0,get:t[r]})},o:(e,l)=>Object.prototype.hasOwnProperty.call(e,l)};const l=window.wp.blocks,t=window.wp.element,r=window.wp.components,s=window.wp.i18n,o=window.wp.blockEditor,a=window.wp.apiFetch;var n=e.n(a);const u=JSON.parse('{"UU":"shutterpress-gallery/shutterpress-gallery-block"}'),i=window.wp.serverSideRender;var p=e.n(i);const g=window.ReactJSXRuntime;(0,l.registerBlockType)(u.UU,{attributes:{galleryId:{type:"number",default:-1},useLightbox:{type:"boolean",default:!0},showDefaultButtons:{type:"boolean",default:!0},galleryLayout:{type:"string",default:"masonry"},galleryGap:{type:"number",default:20},rowHeight:{type:"number",default:300},columns_desktop:{type:"number",default:3},columns_tablet:{type:"number",default:2},columns_mobile:{type:"number",default:1},hasLoadedDefaults:{type:"boolean",default:!1}},edit:function(e){const{attributes:l,setAttributes:a}=e,{galleryId:i,useLightbox:c,showDefaultButtons:d,galleryLayout:h,galleryGap:y,rowHeight:b,columns_desktop:_,columns_tablet:m,columns_mobile:v}=l,[f,w]=(0,t.useState)([]),[x,j]=(0,t.useState)(!0),[S,L]=(0,t.useState)(null),k=(0,o.useBlockProps)();(0,t.useEffect)(()=>{j(!0),L(null);let e=[];const t=async(l=1)=>{const r=await n()({path:`wp/v2/shutterpress-gallery?per_page=100&page=${l}`,parse:!1}),s=await r.json();if(e=e.concat(Array.isArray(s)?s:[]),l<parseInt(r.headers.get("X-WP-TotalPages")||"1",10))return t(l+1)};t(1).then(()=>{w(e),j(!1)}).catch(e=>{L(e&&e.message?e.message:String(e)),w([]),j(!1)}),l.hasLoadedDefaults||n()({path:"shutterpress/v1/options"}).then(e=>{const t=(e,l)=>{const t=parseInt(e,10);return Number.isFinite(t)?t:l},r={};void 0!==l.useLightbox&&null!==l.useLightbox||(r.useLightbox=!!e.sp_gallery_use_lightbox),void 0!==l.galleryLayout&&null!==l.galleryLayout||(r.galleryLayout=e.sp_gallery_layout||"masonry"),void 0!==l.galleryGap&&null!==l.galleryGap||(r.galleryGap=t(e.sp_gallery_column_gap,20)),void 0!==l.rowHeight&&null!==l.rowHeight||(r.rowHeight=t(e.sp_gallery_justified_row_height,300)),void 0!==l.columns_desktop&&null!==l.columns_desktop||(r.columns_desktop=t(e.sp_gallery_columns_desktop,3)),void 0!==l.columns_tablet&&null!==l.columns_tablet||(r.columns_tablet=t(e.sp_gallery_columns_tablet,2)),void 0!==l.columns_mobile&&null!==l.columns_mobile||(r.columns_mobile=t(e.sp_gallery_columns_mobile,1)),a({...r,hasLoadedDefaults:!0})}).catch(e=>{console.error("Error fetching options:",e),a({hasLoadedDefaults:!0})})},[l.hasLoadedDefaults]);const C=(()=>{if(!x&&Array.isArray(f)&&f.length>0){const e=f.map(e=>({label:e.title?.rendered||(0,s.__)("Untitled Gallery","shutterpress-gallery"),value:String(e.id)}));return[{label:(0,s.__)("Use Post Gallery","shutterpress-gallery"),value:"-1"},...e]}return[]})(),N=(e,l)=>Number.isFinite(e)?e:l,G={galleryId:N(i,0),useLightbox:!!c,showDefaultButtons:!!d,galleryLayout:h||"masonry",galleryGap:N(y,20),rowHeight:"justified"===h?N(b,300):void 0,columns_desktop:"grid"===h||"masonry"===h?N(_,3):void 0,columns_tablet:"grid"===h||"masonry"===h?N(m,2):void 0,columns_mobile:"grid"===h||"masonry"===h?N(v,1):void 0},I=Object.fromEntries(Object.entries(G).filter(([,e])=>null!=e)),P=I;return(0,g.jsxs)("div",{...k,children:[x&&(0,g.jsx)(r.Spinner,{}),Number.isFinite(i)&&-1===i&&!x&&!S&&(0,g.jsx)("div",{className:"sp-gallery-block-preview",children:(0,g.jsx)("div",{className:"components-placeholder",children:(0,g.jsx)("p",{children:(0,s.__)("ShutterPress Gallery. View the post to see images.","shutterpress-gallery")})})}),Number.isFinite(i)&&i>0&&!x&&!S&&(0,g.jsxs)("div",{className:"sp-gallery-block-preview",children:[console&&"function"==typeof console.log?console.log("[ShutterPress] SSR attributes",I):null,(0,g.jsx)(p(),{block:u.UU,httpMethod:"GET",attributes:P,LoadingResponsePlaceholder:()=>(0,g.jsx)(r.Spinner,{}),ErrorResponsePlaceholder:e=>{const l=e&&e.error?e.error:null;console&&"function"==typeof console.error&&console.error("[ShutterPress] SSR error props",e);let t=(0,s.__)("Error rendering block","shutterpress-gallery");if(l)if("string"==typeof l)t=l;else if(l&&"string"==typeof l.message)t=l.message;else try{t=JSON.stringify(l)}catch(e){t=String(l)}return console&&"function"==typeof console.error&&console.error("[ShutterPress] Block render error",l),(0,g.jsx)("div",{className:"components-error",children:(0,g.jsx)("p",{children:t})})}})]}),S&&(0,g.jsx)("p",{style:{color:"red"},children:(0,s.sprintf)((0,s.__)("Error: %s","shutterpress-gallery"),S)}),(0,g.jsx)(o.InspectorControls,{children:(0,g.jsxs)(r.PanelBody,{title:(0,s.__)("Gallery Settings","shutterpress-gallery"),initialOpen:!0,children:[(0,g.jsx)(r.ComboboxControl,{label:(0,s.__)("Select Gallery","shutterpress-gallery"),value:String(Number.isFinite(i)?i:""),options:C,onChange:e=>{const l=parseInt(e,10);a({galleryId:Number.isFinite(l)?l:0})},help:x?(0,s.__)("Loading galleries…","shutterpress-gallery"):S?(0,s.__)("Error loading galleries","shutterpress-gallery"):(0,s.__)("Type to search by gallery name","shutterpress-gallery"),disabled:x||!!S}),(0,g.jsx)(r.ToggleControl,{label:(0,s.__)("Use Lightbox","shutterpress-gallery"),checked:c,onChange:e=>a({useLightbox:!!e})}),(0,g.jsx)(r.ToggleControl,{label:(0,s.__)("Use Default Buttons","shutterpress-gallery"),checked:d,onChange:e=>a({showDefaultButtons:!!e})}),(0,g.jsxs)("p",{className:"components-base-control__help",children:[(0,s.sprintf)((0,s.__)('If you want to add custom buttons, set the button HTML anchor to "%s".',"shutterpress-gallery"),`sp-gallery-filter-liked-photos-${i}`)," ",(0,g.jsx)("a",{href:"https://shutterpress.io",target:"_blank",rel:"noopener noreferrer",children:(0,s.__)("See ShutterPress.io for more info.","shutterpress-gallery")})]}),(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Layout","shutterpress-gallery"),value:h,options:[{label:(0,s.__)("Masonry","shutterpress-gallery"),value:"masonry"},{label:(0,s.__)("Grid","shutterpress-gallery"),value:"grid"},{label:(0,s.__)("Justified","shutterpress-gallery"),value:"justified"}],onChange:e=>a({galleryLayout:e})}),(0,g.jsx)(r.RangeControl,{label:(0,s.__)("Image Gap","shutterpress-gallery"),value:y,onChange:e=>a({galleryGap:parseInt(e,10)}),min:0,max:100}),"justified"===h&&(0,g.jsx)(r.RangeControl,{label:(0,s.__)("Row Height","shutterpress-gallery"),value:b,onChange:e=>a({rowHeight:parseInt(e,10)}),min:0,max:1e3}),("grid"===h||"masonry"===h)&&(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Number of Desktop Columns","shutterpress-gallery"),value:_,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8},{label:"9",value:9},{label:"10",value:10}],onChange:e=>a({columns_desktop:parseInt(e,10)})}),(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Number of Tablet Columns","shutterpress-gallery"),value:m,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8}],onChange:e=>a({columns_tablet:parseInt(e,10)})}),(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Number of Mobile Columns","shutterpress-gallery"),value:v,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4}],onChange:e=>a({columns_mobile:parseInt(e,10)})})]})]})})]})},save:function(){return null}})})();1 (()=>{"use strict";var e={n:l=>{var t=l&&l.__esModule?()=>l.default:()=>l;return e.d(t,{a:t}),t},d:(l,t)=>{for(var s in t)e.o(t,s)&&!e.o(l,s)&&Object.defineProperty(l,s,{enumerable:!0,get:t[s]})},o:(e,l)=>Object.prototype.hasOwnProperty.call(e,l)};const l=window.wp.blocks,t=window.wp.element,s=window.wp.components,r=window.wp.i18n,a=window.wp.blockEditor,o=JSON.parse('{"UU":"shutterpress-gallery/shutterpress-gallery-block"}'),n=window.wp.serverSideRender;var u=e.n(n);const i=window.wp.data,p=window.ReactJSXRuntime,d=()=>(0,p.jsx)(s.Spinner,{}),g=e=>{const l=e&&e.error?e.error:null;let t=(0,r.__)("Error rendering block","shutterpress-gallery");if(l)if("string"==typeof l)t=l;else if(l&&"string"==typeof l.message)t=l.message;else try{t=JSON.stringify(l)}catch(e){t=String(l)}return(0,p.jsx)("div",{className:"components-error",children:(0,p.jsx)("p",{children:t})})};(0,l.registerBlockType)(o.UU,{attributes:{galleryId:{type:"number",default:-1},useLightbox:{type:"boolean",default:!0},showDefaultButtons:{type:"boolean",default:!0},galleryLayout:{type:"string",default:"grid"},galleryGap:{type:"number",default:20},rowHeight:{type:"number",default:300},columns_desktop:{type:"number",default:3},columns_tablet:{type:"number",default:2},columns_mobile:{type:"number",default:1},hasLoadedDefaults:{type:"boolean",default:!1}},edit:function(e){const{attributes:l,setAttributes:n}=e,{galleryId:b,useLightbox:c,showDefaultButtons:h,galleryLayout:y,galleryGap:m,rowHeight:_,columns_desktop:f,columns_tablet:v,columns_mobile:w}=l,x=(0,a.useBlockProps)(),j=(0,i.useSelect)(e=>e("core").getEntityRecords("postType","shutterpress-gallery",{per_page:-1,orderby:"title",order:"asc",_fields:["id","title"]}),[]),C=null===j;(0,t.useEffect)(()=>{if(!l.hasLoadedDefaults){const e="undefined"!=typeof window&&window.shutterpressDefaults?window.shutterpressDefaults:{},t=(e,l)=>{const t=parseInt(e,10);return Number.isFinite(t)?t:l},s={};null==l.useLightbox&&(s.useLightbox=!!e.use_lightbox),null==l.galleryLayout&&(s.galleryLayout=e.layout||"grid"),null==l.galleryGap&&(s.galleryGap=t(e.gap,20)),null==l.rowHeight&&(s.rowHeight=t(e.row_height,300)),null==l.columns_desktop&&(s.columns_desktop=t(e.columns_desktop,3)),null==l.columns_tablet&&(s.columns_tablet=t(e.columns_tablet,2)),null==l.columns_mobile&&(s.columns_mobile=t(e.columns_mobile,1)),n({...s,hasLoadedDefaults:!0})}},[l.hasLoadedDefaults]);const k=(()=>{if(!C&&Array.isArray(j)&&j.length>0){const e=j.map(e=>({label:e.title?.rendered||(0,r.__)("Untitled Gallery","shutterpress-gallery"),value:String(e.id)}));return[{label:(0,r.__)("Use Post Gallery","shutterpress-gallery"),value:"-1"},...e]}return[]})(),L=(e,l)=>Number.isFinite(e)?e:l,S=(0,t.useMemo)(()=>{const e={galleryId:L(b,0),useLightbox:!!c,showDefaultButtons:!!h,galleryLayout:null!=y?y:void 0,galleryGap:L(m,20),rowHeight:"justified"===y?L(_,300):void 0,columns_desktop:"grid"===y||"masonry"===y?L(f,3):void 0,columns_tablet:"grid"===y||"masonry"===y?L(v,2):void 0,columns_mobile:"grid"===y||"masonry"===y?L(w,1):void 0};return Object.fromEntries(Object.entries(e).filter(([,e])=>null!=e))},[b,c,h,y,m,_,f,v,w]);return(0,p.jsxs)("div",{...x,children:[C&&(0,p.jsx)(s.Spinner,{}),Number.isFinite(b)&&-1===b&&!C&&(0,p.jsx)("div",{className:"sp-gallery-block-preview",children:(0,p.jsx)("div",{className:"components-placeholder",children:(0,p.jsx)("p",{children:(0,r.__)("ShutterPress Gallery. View the post to see images.","shutterpress-gallery")})})}),Number.isFinite(b)&&b>0&&!C&&(0,p.jsx)("div",{className:"sp-gallery-block-preview",children:(0,p.jsx)(u(),{block:o.UU,httpMethod:"GET",attributes:S,LoadingResponsePlaceholder:d,ErrorResponsePlaceholder:g})}),null,(0,p.jsx)(a.InspectorControls,{children:(0,p.jsxs)(s.PanelBody,{title:(0,r.__)("Gallery Settings","shutterpress-gallery"),initialOpen:!0,children:[(0,p.jsx)(s.ComboboxControl,{label:(0,r.__)("Select Gallery","shutterpress-gallery"),value:String(Number.isFinite(b)?b:""),options:k,onChange:e=>{const l=parseInt(e,10);n({galleryId:Number.isFinite(l)?l:0})},help:C?(0,r.__)("Loading galleries…","shutterpress-gallery"):(0,r.__)("Type to search by gallery name","shutterpress-gallery"),disabled:C||!1}),(0,p.jsx)(s.ToggleControl,{label:(0,r.__)("Use Lightbox","shutterpress-gallery"),checked:c,onChange:e=>n({useLightbox:!!e})}),(0,p.jsx)(s.ToggleControl,{label:(0,r.__)("Use Default Buttons","shutterpress-gallery"),checked:h,onChange:e=>n({showDefaultButtons:!!e})}),(0,p.jsxs)("p",{className:"components-base-control__help",children:[(0,r.sprintf)((0,r.__)('If you want to add custom buttons, set the button HTML anchor to "%s".',"shutterpress-gallery"),`sp-gallery-filter-liked-photos-${b}`)," ",(0,p.jsx)("a",{href:"https://shutterpress.io",target:"_blank",rel:"noopener noreferrer",children:(0,r.__)("See ShutterPress.io for more info.","shutterpress-gallery")})]}),(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Layout","shutterpress-gallery"),value:y,options:[{label:(0,r.__)("Grid","shutterpress-gallery"),value:"grid"},{label:(0,r.__)("Masonry","shutterpress-gallery"),value:"masonry"},{label:(0,r.__)("Justified","shutterpress-gallery"),value:"justified"}],onChange:e=>n({galleryLayout:e})}),(0,p.jsx)(s.RangeControl,{label:(0,r.__)("Image Gap","shutterpress-gallery"),value:m,onChange:e=>n({galleryGap:parseInt(e,10)}),min:0,max:100}),"justified"===y&&(0,p.jsx)(s.RangeControl,{label:(0,r.__)("Row Height","shutterpress-gallery"),value:_,onChange:e=>n({rowHeight:parseInt(e,10)}),min:0,max:1e3}),("grid"===y||"masonry"===y)&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Number of Desktop Columns","shutterpress-gallery"),value:f,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8},{label:"9",value:9},{label:"10",value:10}],onChange:e=>n({columns_desktop:parseInt(e,10)})}),(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Number of Tablet Columns","shutterpress-gallery"),value:v,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8}],onChange:e=>n({columns_tablet:parseInt(e,10)})}),(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Number of Mobile Columns","shutterpress-gallery"),value:w,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4}],onChange:e=>n({columns_mobile:parseInt(e,10)})})]})]})})]})},save:function(){return null}})})(); -
shutterpress-gallery/tags/1.7.6/shutterpress-gallery.php
r3376238 r3378680 1 1 <?php 2 3 2 /** 4 3 * The plugin bootstrap file … … 10 9 * @wordpress-plugin 11 10 * Plugin Name: ShutterPress Gallery 12 * Plugin URI: shutterpress.io11 * Plugin URI: https://shutterpress.io 13 12 * Description: WordPress photo gallery plugin for photographers and creatives. Build fast, responsive image galleries with Masonry, Justified, and Grid layouts, lightbox support, and Infinite Scroll. 14 * Version: 1.7. 513 * Version: 1.7.6 15 14 * Author: ShutterPress 16 15 * Author URI: https://shutterpress.io … … 28 27 * Current plugin version. 29 28 */ 30 define('SHUTTERPRESS_GALLERY_VERSION', '1.7. 5');29 define('SHUTTERPRESS_GALLERY_VERSION', '1.7.6'); 31 30 32 31 define('SP_GALLERY_DIR', plugin_dir_path(__FILE__)); -
shutterpress-gallery/tags/1.7.6/src/admin/Shutterpress_Gallery_Admin.php
r3376238 r3378680 105 105 } 106 106 107 if (!is_admin() || !function_exists('get_current_screen')) { 107 $should_load = true; 108 if (function_exists('wp_should_load_block_editor_scripts_and_styles')) { 109 $should_load = wp_should_load_block_editor_scripts_and_styles(); 110 } 111 if (!$should_load && !defined('SHUTTERPRESS_TESTING')) { 108 112 return; 109 113 } 110 $screen = get_current_screen();111 if (!$screen || !$screen->is_block_editor()) {112 return;113 }114 114 115 115 wp_enqueue_style($this->plugin_name . '-public', SP_GALLERY_URL . 'includes/css/shutterpress-gallery-public.css', [], $this->version, 'all'); 116 116 117 117 $vendor_base = SP_GALLERY_URL . 'includes/js/'; 118 wp_register_script('infinite-scroll', $vendor_base . 'infinite-scroll.pkgd.min.js', ['jquery'], '5.0.0', false);118 119 119 wp_register_script('isotope', $vendor_base . 'isotope.pkgd.min.js', ['jquery'], '3.0.0', false); 120 120 121 wp_enqueue_script('shutterpress-gallery-editor', SP_GALLERY_URL . 'includes/js/shutterpress-gallery-editor.js', ['isotope', 'infinite-scroll', 'wp-i18n'], $this->version, false); 121 wp_enqueue_script($this->plugin_name . '-editor', SP_GALLERY_URL . 'includes/js/shutterpress-gallery-editor.js', ['isotope', 'wp-i18n'], $this->version, false); 122 123 $defaults = Shutterpress_Gallery_Defaults::get_template_defaults(); 122 124 123 125 $localize_data = [ 124 'rest_url' => esc_url_raw(rest_url()), 125 'nonce' => wp_create_nonce('wp_rest'), 126 'use_lightbox' => (bool) $defaults['use_lightbox'], 127 'layout' => $defaults['layout'], 128 'gap' => (int) $defaults['gap'], 129 'row_height' => (int) $defaults['row_height'], 130 'columns_desktop' => (int) $defaults['columns']['desktop'], 131 'columns_tablet' => (int) $defaults['columns']['tablet'], 132 'columns_mobile' => (int) $defaults['columns']['mobile'], 126 133 ]; 127 134 if (get_option('sp_gallery_debug') === '1') { … … 130 137 131 138 $localize_data['is'] = false; 139 $localize_data['lg'] = false; 132 140 133 141 Shutterpress_Gallery_Debug::log('Localising Data', [$localize_data]); 134 142 135 wp_localize_script('shutterpress-gallery-editor', 'shutterpressD ata', $localize_data);143 wp_localize_script('shutterpress-gallery-editor', 'shutterpressDefaults', $localize_data); 136 144 137 145 wp_set_script_translations('shutterpress-gallery-editor', 'shutterpress-gallery', SP_GALLERY_DIR . 'languages'); -
shutterpress-gallery/tags/1.7.6/src/admin/Shutterpress_Gallery_Elementor_Widget.php
r3371857 r3378680 294 294 295 295 if (!empty($filtered_content)) { 296 296 297 echo \Shutterpress\Gallery\Shutterpress_Gallery_Utils::sanitize_form_html($filtered_content); 297 298 } else { -
shutterpress-gallery/tags/1.7.6/src/includes/Shutterpress_Gallery.php
r3374472 r3378680 135 135 $this->loader->sp_gallery_add_action('elementor/widgets/register', $plugin_admin, 'sp_gallery_register_elementor_widget', 10); 136 136 $this->loader->sp_gallery_add_action('elementor/elements/categories_registered', $plugin_admin, 'sp_gallery_add_elementor_category'); 137 $this->loader->sp_gallery_add_action('rest_api_init', $plugin_admin_rest, 'register_options_route');138 137 $this->loader->sp_gallery_add_action('rest_api_init', $plugin_admin_rest, 'register_save_field_route'); 139 138 $this->loader->sp_gallery_add_action('rest_api_init', $plugin_admin_rest, 'register_dismiss_notice_route'); -
shutterpress-gallery/tags/1.7.6/src/includes/Shutterpress_Gallery_REST.php
r3371808 r3378680 23 23 { 24 24 /** 25 * Returns the JSON schema definition for Shutterpress Gallery plugin options.26 *27 * This schema describes the structure and allowed types for the plugin's settings28 * when accessed via the REST API. It helps ensure validation and consistency when29 * reading or updating plugin options externally.30 *31 * @since 1.3.632 *33 * @return array The JSON schema for plugin options.34 */35 public function options_schema()36 {37 return [38 '$schema' => 'http://json-schema.org/draft-04/schema#',39 'title' => 'Gallery Options',40 'type' => 'object',41 'properties' => [42 'some_option' => [43 'type' => 'string',44 'description' => 'A sample option',45 ],46 ],47 ];48 }49 50 /**51 * Registers a custom REST API route to retrieve plugin options.52 *53 * This method registers a new REST API route at `/wp/v2/options` that can be accessed by users with the `manage_options` capability (typically administrators). When the route is accessed, it calls the `sp_gallery_get_options_for_api()` method to retrieve the following plugin options:54 *55 * - `sp_gallery_use_lightbox`: Whether the lightbox feature is enabled.56 * - `sp_gallery_layout`: The selected layout for the gallery.57 * - `sp_gallery_column_gap`: The gap between columns in the gallery.58 * - `sp_gallery_columns_desktop`: The number of columns to display on desktop devices.59 * - `sp_gallery_columns_tablet`: The number of columns to display on tablet devices.60 * - `sp_gallery_columns_mobile`: The number of columns to display on mobile devices.61 *62 * The method returns the options as a JSON response.63 */64 public function register_options_route()65 {66 register_rest_route('shutterpress/v1', '/options', [67 'schema' => [$this, 'options_schema'],68 'methods' => 'GET',69 'callback' => [$this, 'get_options_for_api'],70 'permission_callback' => function () {71 return current_user_can('manage_options');72 },73 ]);74 }75 /**76 25 * Registers a custom REST API route to save a single metabox field. 77 26 * … … 251 200 do_action('sp_gallery_review_notice_dismissed', $user_id); 252 201 return rest_ensure_response(['message' => 'Review notice dismissed']); 253 }254 255 /**256 * Retrieves the options for the Shutterpress Gallery plugin and returns them as a JSON response.257 *258 * This method is registered as a custom REST API route at `/wp/v2/options`. It retrieves the following options:259 *260 * - `sp_gallery_use_lightbox`: Whether the lightbox feature is enabled.261 * - `sp_gallery_layout`: The selected layout for the gallery.262 * - `sp_gallery_column_gap`: The gap between columns in the gallery.263 * - `sp_gallery_columns_desktop`: The number of columns to display on desktop devices.264 * - `sp_gallery_columns_tablet`: The number of columns to display on tablet devices.265 * - `sp_gallery_columns_mobile`: The number of columns to display on mobile devices.266 *267 * The method returns the options as a JSON response, and is only accessible to users with the `manage_options` capability (typically administrators).268 *269 * @return WP_REST_Response The options as a JSON response.270 */271 public function get_options_for_api()272 {273 274 $options = [275 'sp_gallery_use_lightbox' => filter_var(get_option('sp_gallery_use_lightbox'), FILTER_VALIDATE_BOOLEAN),276 'sp_gallery_layout' => sanitize_text_field(get_option('sp_gallery_layout')),277 'sp_gallery_column_gap' => intval(get_option('sp_gallery_column_gap')),278 'sp_gallery_columns_desktop' => intval(get_option('sp_gallery_columns_desktop')),279 'sp_gallery_columns_tablet' => intval(get_option('sp_gallery_columns_tablet')),280 'sp_gallery_columns_mobile' => intval(get_option('sp_gallery_columns_mobile')),281 ];282 Shutterpress_Gallery_Debug::log('REST API options output', $options);283 return rest_ensure_response($options);284 202 } 285 203 -
shutterpress-gallery/tags/1.7.6/src/public/Shutterpress_Gallery_Public.php
r3376238 r3378680 66 66 wp_enqueue_script('lightgallery', SP_GALLERY_URL . 'includes/js/lightgallery.bundle.js', ['jquery'], '2.7.1', true); 67 67 wp_enqueue_script('imagesloaded'); 68 wp_enqueue_script('infinite-scroll', SP_GALLERY_URL . 'includes/js/infinite-scroll.pkgd.min.js', ['jquery'] );68 wp_enqueue_script('infinite-scroll', SP_GALLERY_URL . 'includes/js/infinite-scroll.pkgd.min.js', ['jquery'], null, true); 69 69 wp_enqueue_script('isotope', SP_GALLERY_URL . 'includes/js/isotope.pkgd.min.js', ['jquery'], null, true); 70 70 wp_enqueue_script('shutterpress-gallery-isotope', SP_GALLERY_URL . 'src/public/js/shutterpress-gallery-isotope.js', ['isotope', 'jquery'], null, true); … … 187 187 Shutterpress_Gallery_Debug::log('Rendering gallery shortcode', $attributes); 188 188 189 $use_lightbox = isset($attributes['use_lightbox']) 190 ? $this->sp_gallery_is_truthy($attributes['use_lightbox']) 191 : filter_var(get_option('sp_gallery_use_lightbox', true), FILTER_VALIDATE_BOOLEAN); 192 193 $show_buttons = isset($attributes['show_buttons']) 194 ? $this->sp_gallery_is_truthy($attributes['show_buttons']) 195 : filter_var(get_option('sp_gallery_show_buttons', true), FILTER_VALIDATE_BOOLEAN); 189 $use_lightbox = isset($attributes['use_lightbox']) ? $this->sp_gallery_is_truthy($attributes['use_lightbox']) : null; 190 191 $show_buttons = isset($attributes['show_buttons']) ? $this->sp_gallery_is_truthy($attributes['show_buttons']) : null; 196 192 197 193 $gallery_attributes = [ 198 194 'gallery_id' => isset($attributes['id']) ? intval($attributes['id']) : null, 199 195 'use_lightbox' => $use_lightbox, 200 'layout' => isset($attributes['layout']) ? $attributes['layout'] : sanitize_text_field(get_option('sp_gallery_layout', 'masonry')),201 'gap' => isset($attributes['gap']) ? intval($attributes['gap']) : intval(get_option('sp_gallery_column_gap', 20)),202 'row_height' => isset($attributes['row_height']) ? intval($attributes['row_height']) : intval(get_option('sp_gallery_justified_row_height', 300)),196 'layout' => isset($attributes['layout']) ? $attributes['layout'] : null, 197 'gap' => isset($attributes['gap']) ? intval($attributes['gap']) : null, 198 'row_height' => isset($attributes['row_height']) ? intval($attributes['row_height']) : null, 203 199 'show_buttons' => $show_buttons, 204 200 'gallery_type' => 'shortcode', 205 201 ]; 206 202 207 $gallery_id = $gallery_attributes['gallery_id'] ?? 'default'; 203 if (empty($gallery_attributes['gallery_id'])) { 204 $current_id = get_the_ID(); 205 if ($current_id && is_numeric($current_id)) { 206 $gallery_attributes['gallery_id'] = (int) $current_id; 207 } 208 } 209 210 $gallery_id = !empty($gallery_attributes['gallery_id']) ? (int) $gallery_attributes['gallery_id'] : 'default'; 208 211 Shutterpress_Gallery_Debug::log('Resolved gallery ID', ['gallery_id' => $gallery_id]); 209 212 -
shutterpress-gallery/tags/1.7.6/src/shutterpress-gallery-block/block.json
r3376238 r3378680 16 16 "useLightbox": { "type": "boolean", "default": true }, 17 17 "showDefaultButtons": { "type": "boolean", "default": true }, 18 "galleryLayout": { "type": "string", "default": " masonry" },18 "galleryLayout": { "type": "string", "default": "grid" }, 19 19 "galleryGap": { "type": "number", "default": 20 }, 20 20 "rowHeight": { "type": "number", "default": 300 }, -
shutterpress-gallery/tags/1.7.6/src/shutterpress-gallery-block/shutterpress-gallery-block-render.php
r3371808 r3378680 67 67 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) { 68 68 $gallery_attributes['infinite_scroll'] = '0'; 69 $gallery_attributes['use_lightbox'] = '0'; 69 70 } 70 71 71 72 if (method_exists($renderer, 'set_attributes')) { 72 73 $renderer->set_attributes($gallery_attributes); 73 }74 75 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) {76 74 } 77 75 -
shutterpress-gallery/tags/1.7.6/src/shutterpress-gallery-block/shutterpress-gallery-block.js
r3376238 r3378680 1 1 import { registerBlockType } from '@wordpress/blocks'; 2 import { useState, useEffect } from '@wordpress/element';2 import { useState, useEffect, useMemo } from '@wordpress/element'; 3 3 import { SelectControl, ToggleControl, RangeControl, TextControl, PanelBody, Spinner, ComboboxControl } from '@wordpress/components'; 4 4 import { __, sprintf } from '@wordpress/i18n'; 5 5 import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; 6 import apiFetch from '@wordpress/api-fetch'; // Use WordPress built-in fetch7 6 import metadata from './block.json'; 8 7 import ServerSideRender from '@wordpress/server-side-render'; 8 import { useSelect } from '@wordpress/data'; 9 10 // Loading and error placeholders for SSR 11 const LoadingPlaceholder = () => <Spinner />; 12 const ErrorPlaceholder = (props) => { 13 const err = props && props.error ? props.error : null; 14 let msg = __('Error rendering block', 'shutterpress-gallery'); 15 if (err) { 16 if (typeof err === 'string') msg = err; 17 else if (err && typeof err.message === 'string') msg = err.message; 18 else { 19 try { 20 msg = JSON.stringify(err); 21 } catch (e) { 22 msg = String(err); 23 } 24 } 25 } 26 return ( 27 <div className="components-error"> 28 <p>{msg}</p> 29 </div> 30 ); 31 }; 9 32 10 33 // Register the block … … 25 48 galleryLayout: { 26 49 type: 'string', 27 default: ' masonry',50 default: 'grid', 28 51 }, 29 52 galleryGap: { … … 57 80 const { galleryId, useLightbox, showDefaultButtons, galleryLayout, galleryGap, rowHeight, columns_desktop, columns_tablet, columns_mobile } = attributes; 58 81 59 const [galleries, setGalleries] = useState([]); 60 const [loading, setLoading] = useState(true); 61 const [error, setError] = useState(null); 82 // Remove local state for galleries, loading, error. 62 83 63 84 const blockProps = useBlockProps(); 64 85 86 // Fetch galleries using useSelect at the top level (not in useEffect). 87 const galleries = useSelect( 88 (select) => 89 select('core').getEntityRecords('postType', 'shutterpress-gallery', { 90 per_page: -1, 91 orderby: 'title', 92 order: 'asc', 93 _fields: ['id', 'title'], 94 }), 95 [], 96 ); 97 const loading = galleries === null; 98 const error = null; 99 65 100 useEffect(() => { 66 // always fetch galleries list67 setLoading(true);68 setError(null);69 70 const perPage = 100;71 let all = [];72 73 const fetchPage = async (page = 1) => {74 // Use parse:false so we can read headers for total pages75 const res = await apiFetch({76 path: `wp/v2/shutterpress-gallery?per_page=${perPage}&page=${page}`,77 parse: false,78 });79 const json = await res.json();80 all = all.concat(Array.isArray(json) ? json : []);81 const totalPages = parseInt(res.headers.get('X-WP-TotalPages') || '1', 10);82 if (page < totalPages) {83 return fetchPage(page + 1);84 }85 };86 87 fetchPage(1)88 .then(() => {89 setGalleries(all);90 setLoading(false);91 })92 .catch((err) => {93 setError(err && err.message ? err.message : String(err));94 setGalleries([]);95 setLoading(false);96 });97 98 // only pull REST defaults once, and never overwrite saved values99 101 if (!attributes.hasLoadedDefaults) { 100 apiFetch({ path: 'shutterpress/v1/options' }) 101 .then((options) => { 102 const toInt = (v, fb) => { 103 const n = parseInt(v, 10); 104 return Number.isFinite(n) ? n : fb; 105 }; 106 107 const next = {}; 108 if (attributes.useLightbox === undefined || attributes.useLightbox === null) next.useLightbox = !!options.sp_gallery_use_lightbox; 109 if (attributes.galleryLayout === undefined || attributes.galleryLayout === null) next.galleryLayout = options.sp_gallery_layout || 'masonry'; 110 if (attributes.galleryGap === undefined || attributes.galleryGap === null) next.galleryGap = toInt(options.sp_gallery_column_gap, 20); 111 if (attributes.rowHeight === undefined || attributes.rowHeight === null) next.rowHeight = toInt(options.sp_gallery_justified_row_height, 300); 112 if (attributes.columns_desktop === undefined || attributes.columns_desktop === null) next.columns_desktop = toInt(options.sp_gallery_columns_desktop, 3); 113 if (attributes.columns_tablet === undefined || attributes.columns_tablet === null) next.columns_tablet = toInt(options.sp_gallery_columns_tablet, 2); 114 if (attributes.columns_mobile === undefined || attributes.columns_mobile === null) next.columns_mobile = toInt(options.sp_gallery_columns_mobile, 1); 115 116 setAttributes({ ...next, hasLoadedDefaults: true }); 117 }) 118 .catch((error) => { 119 console.error('Error fetching options:', error); 120 // still mark as loaded to avoid future overwrites 121 setAttributes({ hasLoadedDefaults: true }); 122 }); 102 const options = typeof window !== 'undefined' && window.shutterpressDefaults ? window.shutterpressDefaults : {}; 103 104 const toInt = (v, fb) => { 105 const n = parseInt(v, 10); 106 return Number.isFinite(n) ? n : fb; 107 }; 108 109 const next = {}; 110 if (attributes.useLightbox == null) next.useLightbox = !!options.use_lightbox; 111 if (attributes.galleryLayout == null) next.galleryLayout = options.layout || 'grid'; 112 if (attributes.galleryGap == null) next.galleryGap = toInt(options.gap, 20); 113 if (attributes.rowHeight == null) next.rowHeight = toInt(options.row_height, 300); 114 if (attributes.columns_desktop == null) next.columns_desktop = toInt(options.columns_desktop, 3); 115 if (attributes.columns_tablet == null) next.columns_tablet = toInt(options.columns_tablet, 2); 116 if (attributes.columns_mobile == null) next.columns_mobile = toInt(options.columns_mobile, 1); 117 118 setAttributes({ ...next, hasLoadedDefaults: true }); 123 119 } 124 120 }, [attributes.hasLoadedDefaults]); … … 137 133 // Sanitize attributes for preview and exclude internal-only keys 138 134 const sanitizeNumber = (val, fallback) => (Number.isFinite(val) ? val : fallback); 139 const renderAttributes = { 140 galleryId: sanitizeNumber(galleryId, 0), 141 useLightbox: !!useLightbox, 142 showDefaultButtons: !!showDefaultButtons, 143 galleryLayout: galleryLayout || 'masonry', 144 galleryGap: sanitizeNumber(galleryGap, 20), 145 rowHeight: galleryLayout === 'justified' ? sanitizeNumber(rowHeight, 300) : undefined, 146 columns_desktop: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_desktop, 3) : undefined, 147 columns_tablet: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_tablet, 2) : undefined, 148 columns_mobile: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_mobile, 1) : undefined, 149 }; 150 const filteredRenderAttributes = Object.fromEntries(Object.entries(renderAttributes).filter(([, v]) => v !== undefined && v !== null)); 151 const ssrAttributes = filteredRenderAttributes; 135 const ssrAttributes = useMemo(() => { 136 const base = { 137 galleryId: sanitizeNumber(galleryId, 0), 138 useLightbox: !!useLightbox, 139 showDefaultButtons: !!showDefaultButtons, 140 galleryLayout: galleryLayout ?? undefined, 141 galleryGap: sanitizeNumber(galleryGap, 20), 142 rowHeight: galleryLayout === 'justified' ? sanitizeNumber(rowHeight, 300) : undefined, 143 columns_desktop: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_desktop, 3) : undefined, 144 columns_tablet: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_tablet, 2) : undefined, 145 columns_mobile: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_mobile, 1) : undefined, 146 }; 147 return Object.fromEntries(Object.entries(base).filter(([, v]) => v !== undefined && v !== null)); 148 }, [galleryId, useLightbox, showDefaultButtons, galleryLayout, galleryGap, rowHeight, columns_desktop, columns_tablet, columns_mobile]); 152 149 153 150 return ( … … 165 162 {Number.isFinite(galleryId) && galleryId > 0 && !loading && !error && ( 166 163 <div className="sp-gallery-block-preview"> 167 {console && typeof console.log === 'function' ? console.log('[ShutterPress] SSR attributes', filteredRenderAttributes) : null} 168 <ServerSideRender 169 block={metadata.name} 170 httpMethod="GET" 171 attributes={ssrAttributes} 172 LoadingResponsePlaceholder={() => <Spinner />} 173 ErrorResponsePlaceholder={(props) => { 174 const err = props && props.error ? props.error : null; 175 if (console && typeof console.error === 'function') { 176 console.error('[ShutterPress] SSR error props', props); 177 } 178 let msg = __('Error rendering block', 'shutterpress-gallery'); 179 if (err) { 180 if (typeof err === 'string') { 181 msg = err; 182 } else if (err && typeof err.message === 'string') { 183 msg = err.message; 184 } else { 185 try { 186 msg = JSON.stringify(err); 187 } catch (e) { 188 msg = String(err); 189 } 190 } 191 } 192 if (console && typeof console.error === 'function') { 193 console.error('[ShutterPress] Block render error', err); 194 } 195 return ( 196 <div className="components-error"> 197 <p>{msg}</p> 198 </div> 199 ); 200 }} 201 /> 164 <ServerSideRender block={metadata.name} httpMethod="GET" attributes={ssrAttributes} LoadingResponsePlaceholder={LoadingPlaceholder} ErrorResponsePlaceholder={ErrorPlaceholder} /> 202 165 </div> 203 166 )} … … 239 202 value={galleryLayout} 240 203 options={[ 204 { label: __('Grid', 'shutterpress-gallery'), value: 'grid' }, 241 205 { label: __('Masonry', 'shutterpress-gallery'), value: 'masonry' }, 242 { label: __('Grid', 'shutterpress-gallery'), value: 'grid' },243 206 { label: __('Justified', 'shutterpress-gallery'), value: 'justified' }, 244 207 ]} -
shutterpress-gallery/tags/1.7.6/vendor/composer/installed.php
r3376238 r3378680 4 4 'pretty_version' => 'dev-master', 5 5 'version' => 'dev-master', 6 'reference' => ' 1037916b588c758f6615994b2c77f6588d3b29b5',6 'reference' => 'ee154d9281e430a177064ec382dda47bc35fbef9', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 35 35 'pretty_version' => 'dev-master', 36 36 'version' => 'dev-master', 37 'reference' => ' 1037916b588c758f6615994b2c77f6588d3b29b5',37 'reference' => 'ee154d9281e430a177064ec382dda47bc35fbef9', 38 38 'type' => 'wordpress-plugin', 39 39 'install_path' => __DIR__ . '/../../', -
shutterpress-gallery/trunk/README.txt
r3376238 r3378680 6 6 Tested up to: 6.8 7 7 Requires PHP: 8.0 8 Stable tag: 1.7. 58 Stable tag: 1.7.6 9 9 License: GPLv2 or later 10 10 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 119 119 120 120 == Changelog == 121 122 = 1.7.6 = 123 124 * Update - Shortcodes show current post gallery when no id is set 125 * Update - Refactor Gallery Block Defaults 126 * Fix - Shortcodes take defaults from gallery template 121 127 122 128 = 1.7.5 = -
shutterpress-gallery/trunk/includes/blocks/shutterpress-gallery-block/block.json
r3376238 r3378680 27 27 "galleryLayout": { 28 28 "type": "string", 29 "default": " masonry"29 "default": "grid" 30 30 }, 31 31 "galleryGap": { -
shutterpress-gallery/trunk/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block-render.php
r3371808 r3378680 67 67 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) { 68 68 $gallery_attributes['infinite_scroll'] = '0'; 69 $gallery_attributes['use_lightbox'] = '0'; 69 70 } 70 71 71 72 if (method_exists($renderer, 'set_attributes')) { 72 73 $renderer->set_attributes($gallery_attributes); 73 }74 75 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) {76 74 } 77 75 -
shutterpress-gallery/trunk/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.asset.php
r3376238 r3378680 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp- api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '0961de81d9cf02dac39c');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'aead3cea6f4ea9eea0c9'); -
shutterpress-gallery/trunk/includes/blocks/shutterpress-gallery-block/shutterpress-gallery-block.js
r3376238 r3378680 1 (()=>{"use strict";var e={n:l=>{var t=l&&l.__esModule?()=>l.default:()=>l;return e.d(t,{a:t}),t},d:(l,t)=>{for(var r in t)e.o(t,r)&&!e.o(l,r)&&Object.defineProperty(l,r,{enumerable:!0,get:t[r]})},o:(e,l)=>Object.prototype.hasOwnProperty.call(e,l)};const l=window.wp.blocks,t=window.wp.element,r=window.wp.components,s=window.wp.i18n,o=window.wp.blockEditor,a=window.wp.apiFetch;var n=e.n(a);const u=JSON.parse('{"UU":"shutterpress-gallery/shutterpress-gallery-block"}'),i=window.wp.serverSideRender;var p=e.n(i);const g=window.ReactJSXRuntime;(0,l.registerBlockType)(u.UU,{attributes:{galleryId:{type:"number",default:-1},useLightbox:{type:"boolean",default:!0},showDefaultButtons:{type:"boolean",default:!0},galleryLayout:{type:"string",default:"masonry"},galleryGap:{type:"number",default:20},rowHeight:{type:"number",default:300},columns_desktop:{type:"number",default:3},columns_tablet:{type:"number",default:2},columns_mobile:{type:"number",default:1},hasLoadedDefaults:{type:"boolean",default:!1}},edit:function(e){const{attributes:l,setAttributes:a}=e,{galleryId:i,useLightbox:c,showDefaultButtons:d,galleryLayout:h,galleryGap:y,rowHeight:b,columns_desktop:_,columns_tablet:m,columns_mobile:v}=l,[f,w]=(0,t.useState)([]),[x,j]=(0,t.useState)(!0),[S,L]=(0,t.useState)(null),k=(0,o.useBlockProps)();(0,t.useEffect)(()=>{j(!0),L(null);let e=[];const t=async(l=1)=>{const r=await n()({path:`wp/v2/shutterpress-gallery?per_page=100&page=${l}`,parse:!1}),s=await r.json();if(e=e.concat(Array.isArray(s)?s:[]),l<parseInt(r.headers.get("X-WP-TotalPages")||"1",10))return t(l+1)};t(1).then(()=>{w(e),j(!1)}).catch(e=>{L(e&&e.message?e.message:String(e)),w([]),j(!1)}),l.hasLoadedDefaults||n()({path:"shutterpress/v1/options"}).then(e=>{const t=(e,l)=>{const t=parseInt(e,10);return Number.isFinite(t)?t:l},r={};void 0!==l.useLightbox&&null!==l.useLightbox||(r.useLightbox=!!e.sp_gallery_use_lightbox),void 0!==l.galleryLayout&&null!==l.galleryLayout||(r.galleryLayout=e.sp_gallery_layout||"masonry"),void 0!==l.galleryGap&&null!==l.galleryGap||(r.galleryGap=t(e.sp_gallery_column_gap,20)),void 0!==l.rowHeight&&null!==l.rowHeight||(r.rowHeight=t(e.sp_gallery_justified_row_height,300)),void 0!==l.columns_desktop&&null!==l.columns_desktop||(r.columns_desktop=t(e.sp_gallery_columns_desktop,3)),void 0!==l.columns_tablet&&null!==l.columns_tablet||(r.columns_tablet=t(e.sp_gallery_columns_tablet,2)),void 0!==l.columns_mobile&&null!==l.columns_mobile||(r.columns_mobile=t(e.sp_gallery_columns_mobile,1)),a({...r,hasLoadedDefaults:!0})}).catch(e=>{console.error("Error fetching options:",e),a({hasLoadedDefaults:!0})})},[l.hasLoadedDefaults]);const C=(()=>{if(!x&&Array.isArray(f)&&f.length>0){const e=f.map(e=>({label:e.title?.rendered||(0,s.__)("Untitled Gallery","shutterpress-gallery"),value:String(e.id)}));return[{label:(0,s.__)("Use Post Gallery","shutterpress-gallery"),value:"-1"},...e]}return[]})(),N=(e,l)=>Number.isFinite(e)?e:l,G={galleryId:N(i,0),useLightbox:!!c,showDefaultButtons:!!d,galleryLayout:h||"masonry",galleryGap:N(y,20),rowHeight:"justified"===h?N(b,300):void 0,columns_desktop:"grid"===h||"masonry"===h?N(_,3):void 0,columns_tablet:"grid"===h||"masonry"===h?N(m,2):void 0,columns_mobile:"grid"===h||"masonry"===h?N(v,1):void 0},I=Object.fromEntries(Object.entries(G).filter(([,e])=>null!=e)),P=I;return(0,g.jsxs)("div",{...k,children:[x&&(0,g.jsx)(r.Spinner,{}),Number.isFinite(i)&&-1===i&&!x&&!S&&(0,g.jsx)("div",{className:"sp-gallery-block-preview",children:(0,g.jsx)("div",{className:"components-placeholder",children:(0,g.jsx)("p",{children:(0,s.__)("ShutterPress Gallery. View the post to see images.","shutterpress-gallery")})})}),Number.isFinite(i)&&i>0&&!x&&!S&&(0,g.jsxs)("div",{className:"sp-gallery-block-preview",children:[console&&"function"==typeof console.log?console.log("[ShutterPress] SSR attributes",I):null,(0,g.jsx)(p(),{block:u.UU,httpMethod:"GET",attributes:P,LoadingResponsePlaceholder:()=>(0,g.jsx)(r.Spinner,{}),ErrorResponsePlaceholder:e=>{const l=e&&e.error?e.error:null;console&&"function"==typeof console.error&&console.error("[ShutterPress] SSR error props",e);let t=(0,s.__)("Error rendering block","shutterpress-gallery");if(l)if("string"==typeof l)t=l;else if(l&&"string"==typeof l.message)t=l.message;else try{t=JSON.stringify(l)}catch(e){t=String(l)}return console&&"function"==typeof console.error&&console.error("[ShutterPress] Block render error",l),(0,g.jsx)("div",{className:"components-error",children:(0,g.jsx)("p",{children:t})})}})]}),S&&(0,g.jsx)("p",{style:{color:"red"},children:(0,s.sprintf)((0,s.__)("Error: %s","shutterpress-gallery"),S)}),(0,g.jsx)(o.InspectorControls,{children:(0,g.jsxs)(r.PanelBody,{title:(0,s.__)("Gallery Settings","shutterpress-gallery"),initialOpen:!0,children:[(0,g.jsx)(r.ComboboxControl,{label:(0,s.__)("Select Gallery","shutterpress-gallery"),value:String(Number.isFinite(i)?i:""),options:C,onChange:e=>{const l=parseInt(e,10);a({galleryId:Number.isFinite(l)?l:0})},help:x?(0,s.__)("Loading galleries…","shutterpress-gallery"):S?(0,s.__)("Error loading galleries","shutterpress-gallery"):(0,s.__)("Type to search by gallery name","shutterpress-gallery"),disabled:x||!!S}),(0,g.jsx)(r.ToggleControl,{label:(0,s.__)("Use Lightbox","shutterpress-gallery"),checked:c,onChange:e=>a({useLightbox:!!e})}),(0,g.jsx)(r.ToggleControl,{label:(0,s.__)("Use Default Buttons","shutterpress-gallery"),checked:d,onChange:e=>a({showDefaultButtons:!!e})}),(0,g.jsxs)("p",{className:"components-base-control__help",children:[(0,s.sprintf)((0,s.__)('If you want to add custom buttons, set the button HTML anchor to "%s".',"shutterpress-gallery"),`sp-gallery-filter-liked-photos-${i}`)," ",(0,g.jsx)("a",{href:"https://shutterpress.io",target:"_blank",rel:"noopener noreferrer",children:(0,s.__)("See ShutterPress.io for more info.","shutterpress-gallery")})]}),(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Layout","shutterpress-gallery"),value:h,options:[{label:(0,s.__)("Masonry","shutterpress-gallery"),value:"masonry"},{label:(0,s.__)("Grid","shutterpress-gallery"),value:"grid"},{label:(0,s.__)("Justified","shutterpress-gallery"),value:"justified"}],onChange:e=>a({galleryLayout:e})}),(0,g.jsx)(r.RangeControl,{label:(0,s.__)("Image Gap","shutterpress-gallery"),value:y,onChange:e=>a({galleryGap:parseInt(e,10)}),min:0,max:100}),"justified"===h&&(0,g.jsx)(r.RangeControl,{label:(0,s.__)("Row Height","shutterpress-gallery"),value:b,onChange:e=>a({rowHeight:parseInt(e,10)}),min:0,max:1e3}),("grid"===h||"masonry"===h)&&(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Number of Desktop Columns","shutterpress-gallery"),value:_,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8},{label:"9",value:9},{label:"10",value:10}],onChange:e=>a({columns_desktop:parseInt(e,10)})}),(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Number of Tablet Columns","shutterpress-gallery"),value:m,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8}],onChange:e=>a({columns_tablet:parseInt(e,10)})}),(0,g.jsx)(r.SelectControl,{label:(0,s.__)("Number of Mobile Columns","shutterpress-gallery"),value:v,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4}],onChange:e=>a({columns_mobile:parseInt(e,10)})})]})]})})]})},save:function(){return null}})})();1 (()=>{"use strict";var e={n:l=>{var t=l&&l.__esModule?()=>l.default:()=>l;return e.d(t,{a:t}),t},d:(l,t)=>{for(var s in t)e.o(t,s)&&!e.o(l,s)&&Object.defineProperty(l,s,{enumerable:!0,get:t[s]})},o:(e,l)=>Object.prototype.hasOwnProperty.call(e,l)};const l=window.wp.blocks,t=window.wp.element,s=window.wp.components,r=window.wp.i18n,a=window.wp.blockEditor,o=JSON.parse('{"UU":"shutterpress-gallery/shutterpress-gallery-block"}'),n=window.wp.serverSideRender;var u=e.n(n);const i=window.wp.data,p=window.ReactJSXRuntime,d=()=>(0,p.jsx)(s.Spinner,{}),g=e=>{const l=e&&e.error?e.error:null;let t=(0,r.__)("Error rendering block","shutterpress-gallery");if(l)if("string"==typeof l)t=l;else if(l&&"string"==typeof l.message)t=l.message;else try{t=JSON.stringify(l)}catch(e){t=String(l)}return(0,p.jsx)("div",{className:"components-error",children:(0,p.jsx)("p",{children:t})})};(0,l.registerBlockType)(o.UU,{attributes:{galleryId:{type:"number",default:-1},useLightbox:{type:"boolean",default:!0},showDefaultButtons:{type:"boolean",default:!0},galleryLayout:{type:"string",default:"grid"},galleryGap:{type:"number",default:20},rowHeight:{type:"number",default:300},columns_desktop:{type:"number",default:3},columns_tablet:{type:"number",default:2},columns_mobile:{type:"number",default:1},hasLoadedDefaults:{type:"boolean",default:!1}},edit:function(e){const{attributes:l,setAttributes:n}=e,{galleryId:b,useLightbox:c,showDefaultButtons:h,galleryLayout:y,galleryGap:m,rowHeight:_,columns_desktop:f,columns_tablet:v,columns_mobile:w}=l,x=(0,a.useBlockProps)(),j=(0,i.useSelect)(e=>e("core").getEntityRecords("postType","shutterpress-gallery",{per_page:-1,orderby:"title",order:"asc",_fields:["id","title"]}),[]),C=null===j;(0,t.useEffect)(()=>{if(!l.hasLoadedDefaults){const e="undefined"!=typeof window&&window.shutterpressDefaults?window.shutterpressDefaults:{},t=(e,l)=>{const t=parseInt(e,10);return Number.isFinite(t)?t:l},s={};null==l.useLightbox&&(s.useLightbox=!!e.use_lightbox),null==l.galleryLayout&&(s.galleryLayout=e.layout||"grid"),null==l.galleryGap&&(s.galleryGap=t(e.gap,20)),null==l.rowHeight&&(s.rowHeight=t(e.row_height,300)),null==l.columns_desktop&&(s.columns_desktop=t(e.columns_desktop,3)),null==l.columns_tablet&&(s.columns_tablet=t(e.columns_tablet,2)),null==l.columns_mobile&&(s.columns_mobile=t(e.columns_mobile,1)),n({...s,hasLoadedDefaults:!0})}},[l.hasLoadedDefaults]);const k=(()=>{if(!C&&Array.isArray(j)&&j.length>0){const e=j.map(e=>({label:e.title?.rendered||(0,r.__)("Untitled Gallery","shutterpress-gallery"),value:String(e.id)}));return[{label:(0,r.__)("Use Post Gallery","shutterpress-gallery"),value:"-1"},...e]}return[]})(),L=(e,l)=>Number.isFinite(e)?e:l,S=(0,t.useMemo)(()=>{const e={galleryId:L(b,0),useLightbox:!!c,showDefaultButtons:!!h,galleryLayout:null!=y?y:void 0,galleryGap:L(m,20),rowHeight:"justified"===y?L(_,300):void 0,columns_desktop:"grid"===y||"masonry"===y?L(f,3):void 0,columns_tablet:"grid"===y||"masonry"===y?L(v,2):void 0,columns_mobile:"grid"===y||"masonry"===y?L(w,1):void 0};return Object.fromEntries(Object.entries(e).filter(([,e])=>null!=e))},[b,c,h,y,m,_,f,v,w]);return(0,p.jsxs)("div",{...x,children:[C&&(0,p.jsx)(s.Spinner,{}),Number.isFinite(b)&&-1===b&&!C&&(0,p.jsx)("div",{className:"sp-gallery-block-preview",children:(0,p.jsx)("div",{className:"components-placeholder",children:(0,p.jsx)("p",{children:(0,r.__)("ShutterPress Gallery. View the post to see images.","shutterpress-gallery")})})}),Number.isFinite(b)&&b>0&&!C&&(0,p.jsx)("div",{className:"sp-gallery-block-preview",children:(0,p.jsx)(u(),{block:o.UU,httpMethod:"GET",attributes:S,LoadingResponsePlaceholder:d,ErrorResponsePlaceholder:g})}),null,(0,p.jsx)(a.InspectorControls,{children:(0,p.jsxs)(s.PanelBody,{title:(0,r.__)("Gallery Settings","shutterpress-gallery"),initialOpen:!0,children:[(0,p.jsx)(s.ComboboxControl,{label:(0,r.__)("Select Gallery","shutterpress-gallery"),value:String(Number.isFinite(b)?b:""),options:k,onChange:e=>{const l=parseInt(e,10);n({galleryId:Number.isFinite(l)?l:0})},help:C?(0,r.__)("Loading galleries…","shutterpress-gallery"):(0,r.__)("Type to search by gallery name","shutterpress-gallery"),disabled:C||!1}),(0,p.jsx)(s.ToggleControl,{label:(0,r.__)("Use Lightbox","shutterpress-gallery"),checked:c,onChange:e=>n({useLightbox:!!e})}),(0,p.jsx)(s.ToggleControl,{label:(0,r.__)("Use Default Buttons","shutterpress-gallery"),checked:h,onChange:e=>n({showDefaultButtons:!!e})}),(0,p.jsxs)("p",{className:"components-base-control__help",children:[(0,r.sprintf)((0,r.__)('If you want to add custom buttons, set the button HTML anchor to "%s".',"shutterpress-gallery"),`sp-gallery-filter-liked-photos-${b}`)," ",(0,p.jsx)("a",{href:"https://shutterpress.io",target:"_blank",rel:"noopener noreferrer",children:(0,r.__)("See ShutterPress.io for more info.","shutterpress-gallery")})]}),(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Layout","shutterpress-gallery"),value:y,options:[{label:(0,r.__)("Grid","shutterpress-gallery"),value:"grid"},{label:(0,r.__)("Masonry","shutterpress-gallery"),value:"masonry"},{label:(0,r.__)("Justified","shutterpress-gallery"),value:"justified"}],onChange:e=>n({galleryLayout:e})}),(0,p.jsx)(s.RangeControl,{label:(0,r.__)("Image Gap","shutterpress-gallery"),value:m,onChange:e=>n({galleryGap:parseInt(e,10)}),min:0,max:100}),"justified"===y&&(0,p.jsx)(s.RangeControl,{label:(0,r.__)("Row Height","shutterpress-gallery"),value:_,onChange:e=>n({rowHeight:parseInt(e,10)}),min:0,max:1e3}),("grid"===y||"masonry"===y)&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Number of Desktop Columns","shutterpress-gallery"),value:f,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8},{label:"9",value:9},{label:"10",value:10}],onChange:e=>n({columns_desktop:parseInt(e,10)})}),(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Number of Tablet Columns","shutterpress-gallery"),value:v,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4},{label:"5",value:5},{label:"6",value:6},{label:"7",value:7},{label:"8",value:8}],onChange:e=>n({columns_tablet:parseInt(e,10)})}),(0,p.jsx)(s.SelectControl,{label:(0,r.__)("Number of Mobile Columns","shutterpress-gallery"),value:w,options:[{label:"1",value:1},{label:"2",value:2},{label:"3",value:3},{label:"4",value:4}],onChange:e=>n({columns_mobile:parseInt(e,10)})})]})]})})]})},save:function(){return null}})})(); -
shutterpress-gallery/trunk/shutterpress-gallery.php
r3376238 r3378680 1 1 <?php 2 3 2 /** 4 3 * The plugin bootstrap file … … 10 9 * @wordpress-plugin 11 10 * Plugin Name: ShutterPress Gallery 12 * Plugin URI: shutterpress.io11 * Plugin URI: https://shutterpress.io 13 12 * Description: WordPress photo gallery plugin for photographers and creatives. Build fast, responsive image galleries with Masonry, Justified, and Grid layouts, lightbox support, and Infinite Scroll. 14 * Version: 1.7. 513 * Version: 1.7.6 15 14 * Author: ShutterPress 16 15 * Author URI: https://shutterpress.io … … 28 27 * Current plugin version. 29 28 */ 30 define('SHUTTERPRESS_GALLERY_VERSION', '1.7. 5');29 define('SHUTTERPRESS_GALLERY_VERSION', '1.7.6'); 31 30 32 31 define('SP_GALLERY_DIR', plugin_dir_path(__FILE__)); -
shutterpress-gallery/trunk/src/admin/Shutterpress_Gallery_Admin.php
r3376238 r3378680 105 105 } 106 106 107 if (!is_admin() || !function_exists('get_current_screen')) { 107 $should_load = true; 108 if (function_exists('wp_should_load_block_editor_scripts_and_styles')) { 109 $should_load = wp_should_load_block_editor_scripts_and_styles(); 110 } 111 if (!$should_load && !defined('SHUTTERPRESS_TESTING')) { 108 112 return; 109 113 } 110 $screen = get_current_screen();111 if (!$screen || !$screen->is_block_editor()) {112 return;113 }114 114 115 115 wp_enqueue_style($this->plugin_name . '-public', SP_GALLERY_URL . 'includes/css/shutterpress-gallery-public.css', [], $this->version, 'all'); 116 116 117 117 $vendor_base = SP_GALLERY_URL . 'includes/js/'; 118 wp_register_script('infinite-scroll', $vendor_base . 'infinite-scroll.pkgd.min.js', ['jquery'], '5.0.0', false);118 119 119 wp_register_script('isotope', $vendor_base . 'isotope.pkgd.min.js', ['jquery'], '3.0.0', false); 120 120 121 wp_enqueue_script('shutterpress-gallery-editor', SP_GALLERY_URL . 'includes/js/shutterpress-gallery-editor.js', ['isotope', 'infinite-scroll', 'wp-i18n'], $this->version, false); 121 wp_enqueue_script($this->plugin_name . '-editor', SP_GALLERY_URL . 'includes/js/shutterpress-gallery-editor.js', ['isotope', 'wp-i18n'], $this->version, false); 122 123 $defaults = Shutterpress_Gallery_Defaults::get_template_defaults(); 122 124 123 125 $localize_data = [ 124 'rest_url' => esc_url_raw(rest_url()), 125 'nonce' => wp_create_nonce('wp_rest'), 126 'use_lightbox' => (bool) $defaults['use_lightbox'], 127 'layout' => $defaults['layout'], 128 'gap' => (int) $defaults['gap'], 129 'row_height' => (int) $defaults['row_height'], 130 'columns_desktop' => (int) $defaults['columns']['desktop'], 131 'columns_tablet' => (int) $defaults['columns']['tablet'], 132 'columns_mobile' => (int) $defaults['columns']['mobile'], 126 133 ]; 127 134 if (get_option('sp_gallery_debug') === '1') { … … 130 137 131 138 $localize_data['is'] = false; 139 $localize_data['lg'] = false; 132 140 133 141 Shutterpress_Gallery_Debug::log('Localising Data', [$localize_data]); 134 142 135 wp_localize_script('shutterpress-gallery-editor', 'shutterpressD ata', $localize_data);143 wp_localize_script('shutterpress-gallery-editor', 'shutterpressDefaults', $localize_data); 136 144 137 145 wp_set_script_translations('shutterpress-gallery-editor', 'shutterpress-gallery', SP_GALLERY_DIR . 'languages'); -
shutterpress-gallery/trunk/src/admin/Shutterpress_Gallery_Elementor_Widget.php
r3371857 r3378680 294 294 295 295 if (!empty($filtered_content)) { 296 296 297 echo \Shutterpress\Gallery\Shutterpress_Gallery_Utils::sanitize_form_html($filtered_content); 297 298 } else { -
shutterpress-gallery/trunk/src/includes/Shutterpress_Gallery.php
r3374472 r3378680 135 135 $this->loader->sp_gallery_add_action('elementor/widgets/register', $plugin_admin, 'sp_gallery_register_elementor_widget', 10); 136 136 $this->loader->sp_gallery_add_action('elementor/elements/categories_registered', $plugin_admin, 'sp_gallery_add_elementor_category'); 137 $this->loader->sp_gallery_add_action('rest_api_init', $plugin_admin_rest, 'register_options_route');138 137 $this->loader->sp_gallery_add_action('rest_api_init', $plugin_admin_rest, 'register_save_field_route'); 139 138 $this->loader->sp_gallery_add_action('rest_api_init', $plugin_admin_rest, 'register_dismiss_notice_route'); -
shutterpress-gallery/trunk/src/includes/Shutterpress_Gallery_REST.php
r3371808 r3378680 23 23 { 24 24 /** 25 * Returns the JSON schema definition for Shutterpress Gallery plugin options.26 *27 * This schema describes the structure and allowed types for the plugin's settings28 * when accessed via the REST API. It helps ensure validation and consistency when29 * reading or updating plugin options externally.30 *31 * @since 1.3.632 *33 * @return array The JSON schema for plugin options.34 */35 public function options_schema()36 {37 return [38 '$schema' => 'http://json-schema.org/draft-04/schema#',39 'title' => 'Gallery Options',40 'type' => 'object',41 'properties' => [42 'some_option' => [43 'type' => 'string',44 'description' => 'A sample option',45 ],46 ],47 ];48 }49 50 /**51 * Registers a custom REST API route to retrieve plugin options.52 *53 * This method registers a new REST API route at `/wp/v2/options` that can be accessed by users with the `manage_options` capability (typically administrators). When the route is accessed, it calls the `sp_gallery_get_options_for_api()` method to retrieve the following plugin options:54 *55 * - `sp_gallery_use_lightbox`: Whether the lightbox feature is enabled.56 * - `sp_gallery_layout`: The selected layout for the gallery.57 * - `sp_gallery_column_gap`: The gap between columns in the gallery.58 * - `sp_gallery_columns_desktop`: The number of columns to display on desktop devices.59 * - `sp_gallery_columns_tablet`: The number of columns to display on tablet devices.60 * - `sp_gallery_columns_mobile`: The number of columns to display on mobile devices.61 *62 * The method returns the options as a JSON response.63 */64 public function register_options_route()65 {66 register_rest_route('shutterpress/v1', '/options', [67 'schema' => [$this, 'options_schema'],68 'methods' => 'GET',69 'callback' => [$this, 'get_options_for_api'],70 'permission_callback' => function () {71 return current_user_can('manage_options');72 },73 ]);74 }75 /**76 25 * Registers a custom REST API route to save a single metabox field. 77 26 * … … 251 200 do_action('sp_gallery_review_notice_dismissed', $user_id); 252 201 return rest_ensure_response(['message' => 'Review notice dismissed']); 253 }254 255 /**256 * Retrieves the options for the Shutterpress Gallery plugin and returns them as a JSON response.257 *258 * This method is registered as a custom REST API route at `/wp/v2/options`. It retrieves the following options:259 *260 * - `sp_gallery_use_lightbox`: Whether the lightbox feature is enabled.261 * - `sp_gallery_layout`: The selected layout for the gallery.262 * - `sp_gallery_column_gap`: The gap between columns in the gallery.263 * - `sp_gallery_columns_desktop`: The number of columns to display on desktop devices.264 * - `sp_gallery_columns_tablet`: The number of columns to display on tablet devices.265 * - `sp_gallery_columns_mobile`: The number of columns to display on mobile devices.266 *267 * The method returns the options as a JSON response, and is only accessible to users with the `manage_options` capability (typically administrators).268 *269 * @return WP_REST_Response The options as a JSON response.270 */271 public function get_options_for_api()272 {273 274 $options = [275 'sp_gallery_use_lightbox' => filter_var(get_option('sp_gallery_use_lightbox'), FILTER_VALIDATE_BOOLEAN),276 'sp_gallery_layout' => sanitize_text_field(get_option('sp_gallery_layout')),277 'sp_gallery_column_gap' => intval(get_option('sp_gallery_column_gap')),278 'sp_gallery_columns_desktop' => intval(get_option('sp_gallery_columns_desktop')),279 'sp_gallery_columns_tablet' => intval(get_option('sp_gallery_columns_tablet')),280 'sp_gallery_columns_mobile' => intval(get_option('sp_gallery_columns_mobile')),281 ];282 Shutterpress_Gallery_Debug::log('REST API options output', $options);283 return rest_ensure_response($options);284 202 } 285 203 -
shutterpress-gallery/trunk/src/public/Shutterpress_Gallery_Public.php
r3376238 r3378680 66 66 wp_enqueue_script('lightgallery', SP_GALLERY_URL . 'includes/js/lightgallery.bundle.js', ['jquery'], '2.7.1', true); 67 67 wp_enqueue_script('imagesloaded'); 68 wp_enqueue_script('infinite-scroll', SP_GALLERY_URL . 'includes/js/infinite-scroll.pkgd.min.js', ['jquery'] );68 wp_enqueue_script('infinite-scroll', SP_GALLERY_URL . 'includes/js/infinite-scroll.pkgd.min.js', ['jquery'], null, true); 69 69 wp_enqueue_script('isotope', SP_GALLERY_URL . 'includes/js/isotope.pkgd.min.js', ['jquery'], null, true); 70 70 wp_enqueue_script('shutterpress-gallery-isotope', SP_GALLERY_URL . 'src/public/js/shutterpress-gallery-isotope.js', ['isotope', 'jquery'], null, true); … … 187 187 Shutterpress_Gallery_Debug::log('Rendering gallery shortcode', $attributes); 188 188 189 $use_lightbox = isset($attributes['use_lightbox']) 190 ? $this->sp_gallery_is_truthy($attributes['use_lightbox']) 191 : filter_var(get_option('sp_gallery_use_lightbox', true), FILTER_VALIDATE_BOOLEAN); 192 193 $show_buttons = isset($attributes['show_buttons']) 194 ? $this->sp_gallery_is_truthy($attributes['show_buttons']) 195 : filter_var(get_option('sp_gallery_show_buttons', true), FILTER_VALIDATE_BOOLEAN); 189 $use_lightbox = isset($attributes['use_lightbox']) ? $this->sp_gallery_is_truthy($attributes['use_lightbox']) : null; 190 191 $show_buttons = isset($attributes['show_buttons']) ? $this->sp_gallery_is_truthy($attributes['show_buttons']) : null; 196 192 197 193 $gallery_attributes = [ 198 194 'gallery_id' => isset($attributes['id']) ? intval($attributes['id']) : null, 199 195 'use_lightbox' => $use_lightbox, 200 'layout' => isset($attributes['layout']) ? $attributes['layout'] : sanitize_text_field(get_option('sp_gallery_layout', 'masonry')),201 'gap' => isset($attributes['gap']) ? intval($attributes['gap']) : intval(get_option('sp_gallery_column_gap', 20)),202 'row_height' => isset($attributes['row_height']) ? intval($attributes['row_height']) : intval(get_option('sp_gallery_justified_row_height', 300)),196 'layout' => isset($attributes['layout']) ? $attributes['layout'] : null, 197 'gap' => isset($attributes['gap']) ? intval($attributes['gap']) : null, 198 'row_height' => isset($attributes['row_height']) ? intval($attributes['row_height']) : null, 203 199 'show_buttons' => $show_buttons, 204 200 'gallery_type' => 'shortcode', 205 201 ]; 206 202 207 $gallery_id = $gallery_attributes['gallery_id'] ?? 'default'; 203 if (empty($gallery_attributes['gallery_id'])) { 204 $current_id = get_the_ID(); 205 if ($current_id && is_numeric($current_id)) { 206 $gallery_attributes['gallery_id'] = (int) $current_id; 207 } 208 } 209 210 $gallery_id = !empty($gallery_attributes['gallery_id']) ? (int) $gallery_attributes['gallery_id'] : 'default'; 208 211 Shutterpress_Gallery_Debug::log('Resolved gallery ID', ['gallery_id' => $gallery_id]); 209 212 -
shutterpress-gallery/trunk/src/shutterpress-gallery-block/block.json
r3376238 r3378680 16 16 "useLightbox": { "type": "boolean", "default": true }, 17 17 "showDefaultButtons": { "type": "boolean", "default": true }, 18 "galleryLayout": { "type": "string", "default": " masonry" },18 "galleryLayout": { "type": "string", "default": "grid" }, 19 19 "galleryGap": { "type": "number", "default": 20 }, 20 20 "rowHeight": { "type": "number", "default": 300 }, -
shutterpress-gallery/trunk/src/shutterpress-gallery-block/shutterpress-gallery-block-render.php
r3371808 r3378680 67 67 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) { 68 68 $gallery_attributes['infinite_scroll'] = '0'; 69 $gallery_attributes['use_lightbox'] = '0'; 69 70 } 70 71 71 72 if (method_exists($renderer, 'set_attributes')) { 72 73 $renderer->set_attributes($gallery_attributes); 73 }74 75 if (defined('REST_REQUEST') && REST_REQUEST && 'edit' === $_GET['context']) {76 74 } 77 75 -
shutterpress-gallery/trunk/src/shutterpress-gallery-block/shutterpress-gallery-block.js
r3376238 r3378680 1 1 import { registerBlockType } from '@wordpress/blocks'; 2 import { useState, useEffect } from '@wordpress/element';2 import { useState, useEffect, useMemo } from '@wordpress/element'; 3 3 import { SelectControl, ToggleControl, RangeControl, TextControl, PanelBody, Spinner, ComboboxControl } from '@wordpress/components'; 4 4 import { __, sprintf } from '@wordpress/i18n'; 5 5 import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; 6 import apiFetch from '@wordpress/api-fetch'; // Use WordPress built-in fetch7 6 import metadata from './block.json'; 8 7 import ServerSideRender from '@wordpress/server-side-render'; 8 import { useSelect } from '@wordpress/data'; 9 10 // Loading and error placeholders for SSR 11 const LoadingPlaceholder = () => <Spinner />; 12 const ErrorPlaceholder = (props) => { 13 const err = props && props.error ? props.error : null; 14 let msg = __('Error rendering block', 'shutterpress-gallery'); 15 if (err) { 16 if (typeof err === 'string') msg = err; 17 else if (err && typeof err.message === 'string') msg = err.message; 18 else { 19 try { 20 msg = JSON.stringify(err); 21 } catch (e) { 22 msg = String(err); 23 } 24 } 25 } 26 return ( 27 <div className="components-error"> 28 <p>{msg}</p> 29 </div> 30 ); 31 }; 9 32 10 33 // Register the block … … 25 48 galleryLayout: { 26 49 type: 'string', 27 default: ' masonry',50 default: 'grid', 28 51 }, 29 52 galleryGap: { … … 57 80 const { galleryId, useLightbox, showDefaultButtons, galleryLayout, galleryGap, rowHeight, columns_desktop, columns_tablet, columns_mobile } = attributes; 58 81 59 const [galleries, setGalleries] = useState([]); 60 const [loading, setLoading] = useState(true); 61 const [error, setError] = useState(null); 82 // Remove local state for galleries, loading, error. 62 83 63 84 const blockProps = useBlockProps(); 64 85 86 // Fetch galleries using useSelect at the top level (not in useEffect). 87 const galleries = useSelect( 88 (select) => 89 select('core').getEntityRecords('postType', 'shutterpress-gallery', { 90 per_page: -1, 91 orderby: 'title', 92 order: 'asc', 93 _fields: ['id', 'title'], 94 }), 95 [], 96 ); 97 const loading = galleries === null; 98 const error = null; 99 65 100 useEffect(() => { 66 // always fetch galleries list67 setLoading(true);68 setError(null);69 70 const perPage = 100;71 let all = [];72 73 const fetchPage = async (page = 1) => {74 // Use parse:false so we can read headers for total pages75 const res = await apiFetch({76 path: `wp/v2/shutterpress-gallery?per_page=${perPage}&page=${page}`,77 parse: false,78 });79 const json = await res.json();80 all = all.concat(Array.isArray(json) ? json : []);81 const totalPages = parseInt(res.headers.get('X-WP-TotalPages') || '1', 10);82 if (page < totalPages) {83 return fetchPage(page + 1);84 }85 };86 87 fetchPage(1)88 .then(() => {89 setGalleries(all);90 setLoading(false);91 })92 .catch((err) => {93 setError(err && err.message ? err.message : String(err));94 setGalleries([]);95 setLoading(false);96 });97 98 // only pull REST defaults once, and never overwrite saved values99 101 if (!attributes.hasLoadedDefaults) { 100 apiFetch({ path: 'shutterpress/v1/options' }) 101 .then((options) => { 102 const toInt = (v, fb) => { 103 const n = parseInt(v, 10); 104 return Number.isFinite(n) ? n : fb; 105 }; 106 107 const next = {}; 108 if (attributes.useLightbox === undefined || attributes.useLightbox === null) next.useLightbox = !!options.sp_gallery_use_lightbox; 109 if (attributes.galleryLayout === undefined || attributes.galleryLayout === null) next.galleryLayout = options.sp_gallery_layout || 'masonry'; 110 if (attributes.galleryGap === undefined || attributes.galleryGap === null) next.galleryGap = toInt(options.sp_gallery_column_gap, 20); 111 if (attributes.rowHeight === undefined || attributes.rowHeight === null) next.rowHeight = toInt(options.sp_gallery_justified_row_height, 300); 112 if (attributes.columns_desktop === undefined || attributes.columns_desktop === null) next.columns_desktop = toInt(options.sp_gallery_columns_desktop, 3); 113 if (attributes.columns_tablet === undefined || attributes.columns_tablet === null) next.columns_tablet = toInt(options.sp_gallery_columns_tablet, 2); 114 if (attributes.columns_mobile === undefined || attributes.columns_mobile === null) next.columns_mobile = toInt(options.sp_gallery_columns_mobile, 1); 115 116 setAttributes({ ...next, hasLoadedDefaults: true }); 117 }) 118 .catch((error) => { 119 console.error('Error fetching options:', error); 120 // still mark as loaded to avoid future overwrites 121 setAttributes({ hasLoadedDefaults: true }); 122 }); 102 const options = typeof window !== 'undefined' && window.shutterpressDefaults ? window.shutterpressDefaults : {}; 103 104 const toInt = (v, fb) => { 105 const n = parseInt(v, 10); 106 return Number.isFinite(n) ? n : fb; 107 }; 108 109 const next = {}; 110 if (attributes.useLightbox == null) next.useLightbox = !!options.use_lightbox; 111 if (attributes.galleryLayout == null) next.galleryLayout = options.layout || 'grid'; 112 if (attributes.galleryGap == null) next.galleryGap = toInt(options.gap, 20); 113 if (attributes.rowHeight == null) next.rowHeight = toInt(options.row_height, 300); 114 if (attributes.columns_desktop == null) next.columns_desktop = toInt(options.columns_desktop, 3); 115 if (attributes.columns_tablet == null) next.columns_tablet = toInt(options.columns_tablet, 2); 116 if (attributes.columns_mobile == null) next.columns_mobile = toInt(options.columns_mobile, 1); 117 118 setAttributes({ ...next, hasLoadedDefaults: true }); 123 119 } 124 120 }, [attributes.hasLoadedDefaults]); … … 137 133 // Sanitize attributes for preview and exclude internal-only keys 138 134 const sanitizeNumber = (val, fallback) => (Number.isFinite(val) ? val : fallback); 139 const renderAttributes = { 140 galleryId: sanitizeNumber(galleryId, 0), 141 useLightbox: !!useLightbox, 142 showDefaultButtons: !!showDefaultButtons, 143 galleryLayout: galleryLayout || 'masonry', 144 galleryGap: sanitizeNumber(galleryGap, 20), 145 rowHeight: galleryLayout === 'justified' ? sanitizeNumber(rowHeight, 300) : undefined, 146 columns_desktop: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_desktop, 3) : undefined, 147 columns_tablet: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_tablet, 2) : undefined, 148 columns_mobile: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_mobile, 1) : undefined, 149 }; 150 const filteredRenderAttributes = Object.fromEntries(Object.entries(renderAttributes).filter(([, v]) => v !== undefined && v !== null)); 151 const ssrAttributes = filteredRenderAttributes; 135 const ssrAttributes = useMemo(() => { 136 const base = { 137 galleryId: sanitizeNumber(galleryId, 0), 138 useLightbox: !!useLightbox, 139 showDefaultButtons: !!showDefaultButtons, 140 galleryLayout: galleryLayout ?? undefined, 141 galleryGap: sanitizeNumber(galleryGap, 20), 142 rowHeight: galleryLayout === 'justified' ? sanitizeNumber(rowHeight, 300) : undefined, 143 columns_desktop: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_desktop, 3) : undefined, 144 columns_tablet: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_tablet, 2) : undefined, 145 columns_mobile: galleryLayout === 'grid' || galleryLayout === 'masonry' ? sanitizeNumber(columns_mobile, 1) : undefined, 146 }; 147 return Object.fromEntries(Object.entries(base).filter(([, v]) => v !== undefined && v !== null)); 148 }, [galleryId, useLightbox, showDefaultButtons, galleryLayout, galleryGap, rowHeight, columns_desktop, columns_tablet, columns_mobile]); 152 149 153 150 return ( … … 165 162 {Number.isFinite(galleryId) && galleryId > 0 && !loading && !error && ( 166 163 <div className="sp-gallery-block-preview"> 167 {console && typeof console.log === 'function' ? console.log('[ShutterPress] SSR attributes', filteredRenderAttributes) : null} 168 <ServerSideRender 169 block={metadata.name} 170 httpMethod="GET" 171 attributes={ssrAttributes} 172 LoadingResponsePlaceholder={() => <Spinner />} 173 ErrorResponsePlaceholder={(props) => { 174 const err = props && props.error ? props.error : null; 175 if (console && typeof console.error === 'function') { 176 console.error('[ShutterPress] SSR error props', props); 177 } 178 let msg = __('Error rendering block', 'shutterpress-gallery'); 179 if (err) { 180 if (typeof err === 'string') { 181 msg = err; 182 } else if (err && typeof err.message === 'string') { 183 msg = err.message; 184 } else { 185 try { 186 msg = JSON.stringify(err); 187 } catch (e) { 188 msg = String(err); 189 } 190 } 191 } 192 if (console && typeof console.error === 'function') { 193 console.error('[ShutterPress] Block render error', err); 194 } 195 return ( 196 <div className="components-error"> 197 <p>{msg}</p> 198 </div> 199 ); 200 }} 201 /> 164 <ServerSideRender block={metadata.name} httpMethod="GET" attributes={ssrAttributes} LoadingResponsePlaceholder={LoadingPlaceholder} ErrorResponsePlaceholder={ErrorPlaceholder} /> 202 165 </div> 203 166 )} … … 239 202 value={galleryLayout} 240 203 options={[ 204 { label: __('Grid', 'shutterpress-gallery'), value: 'grid' }, 241 205 { label: __('Masonry', 'shutterpress-gallery'), value: 'masonry' }, 242 { label: __('Grid', 'shutterpress-gallery'), value: 'grid' },243 206 { label: __('Justified', 'shutterpress-gallery'), value: 'justified' }, 244 207 ]} -
shutterpress-gallery/trunk/vendor/composer/installed.php
r3376238 r3378680 4 4 'pretty_version' => 'dev-master', 5 5 'version' => 'dev-master', 6 'reference' => ' 1037916b588c758f6615994b2c77f6588d3b29b5',6 'reference' => 'ee154d9281e430a177064ec382dda47bc35fbef9', 7 7 'type' => 'wordpress-plugin', 8 8 'install_path' => __DIR__ . '/../../', … … 35 35 'pretty_version' => 'dev-master', 36 36 'version' => 'dev-master', 37 'reference' => ' 1037916b588c758f6615994b2c77f6588d3b29b5',37 'reference' => 'ee154d9281e430a177064ec382dda47bc35fbef9', 38 38 'type' => 'wordpress-plugin', 39 39 'install_path' => __DIR__ . '/../../',
Note: See TracChangeset
for help on using the changeset viewer.