Changeset 3355428
- Timestamp:
- 09/03/2025 12:17:33 PM (3 months ago)
- Location:
- zenpress
- Files:
-
- 40 edited
- 1 copied
-
tags/2.0.2 (copied) (copied from zenpress/trunk)
-
tags/2.0.2/assets/build/index.asset.php (modified) (1 diff)
-
tags/2.0.2/assets/build/index.js (modified) (1 diff)
-
tags/2.0.2/assets/src/index.js (modified) (5 diffs)
-
tags/2.0.2/inc/snippets/disable-author-archives.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/disable-dashicons.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/disable-emoji-scripts.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/disable-jquery-migrate.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/disable-oembed.php (modified) (2 diffs)
-
tags/2.0.2/inc/snippets/disable-pdf-thumbnails.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/disable-pingback-trackback.php (modified) (3 diffs)
-
tags/2.0.2/inc/snippets/disable-woocommerce-cart-fragments.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/disable-woocommerce-scripts-styles.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/disable-woocommerce-widgets.php (modified) (2 diffs)
-
tags/2.0.2/inc/snippets/hide-woocommerce-version.php (modified) (3 diffs)
-
tags/2.0.2/inc/snippets/hide-wordpress-version.php (modified) (2 diffs)
-
tags/2.0.2/inc/snippets/protect-wp-login.php (modified) (2 diffs)
-
tags/2.0.2/inc/snippets/remove-gutenberg-unwanted-block-patterns.php (modified) (1 diff)
-
tags/2.0.2/inc/snippets/remove-woocommerce-patterns.php (modified) (2 diffs)
-
tags/2.0.2/readme.txt (modified) (6 diffs)
-
tags/2.0.2/zenpress.php (modified) (9 diffs)
-
trunk/assets/build/index.asset.php (modified) (1 diff)
-
trunk/assets/build/index.js (modified) (1 diff)
-
trunk/assets/src/index.js (modified) (5 diffs)
-
trunk/inc/snippets/disable-author-archives.php (modified) (1 diff)
-
trunk/inc/snippets/disable-dashicons.php (modified) (1 diff)
-
trunk/inc/snippets/disable-emoji-scripts.php (modified) (1 diff)
-
trunk/inc/snippets/disable-jquery-migrate.php (modified) (1 diff)
-
trunk/inc/snippets/disable-oembed.php (modified) (2 diffs)
-
trunk/inc/snippets/disable-pdf-thumbnails.php (modified) (1 diff)
-
trunk/inc/snippets/disable-pingback-trackback.php (modified) (3 diffs)
-
trunk/inc/snippets/disable-woocommerce-cart-fragments.php (modified) (1 diff)
-
trunk/inc/snippets/disable-woocommerce-scripts-styles.php (modified) (1 diff)
-
trunk/inc/snippets/disable-woocommerce-widgets.php (modified) (2 diffs)
-
trunk/inc/snippets/hide-woocommerce-version.php (modified) (3 diffs)
-
trunk/inc/snippets/hide-wordpress-version.php (modified) (2 diffs)
-
trunk/inc/snippets/protect-wp-login.php (modified) (2 diffs)
-
trunk/inc/snippets/remove-gutenberg-unwanted-block-patterns.php (modified) (1 diff)
-
trunk/inc/snippets/remove-woocommerce-patterns.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (6 diffs)
-
trunk/zenpress.php (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
zenpress/tags/2.0.2/assets/build/index.asset.php
r3352459 r3355428 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => ' 9b91df213cf8e0f8ef1f');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => 'ce3e5cbcbfb948f49cc1'); -
zenpress/tags/2.0.2/assets/build/index.js
r3352459 r3355428 1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element,i=window.wp.i18n,a=window.wp.components,r=window.wp.apiFetch;var c=e.n(r);const o=window.wp.data,l=window.wp.notices,p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:n})=>(0,p.jsx)(a.ToggleControl,{label:e,checked:s,onChange:t,help:n,__nextHasNoMarginBottom:!0}),h=({onClick:e,isBusy:s})=>(0,p.jsx)(a.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,i.__)("Save settings","zenpress")}),u=()=>{const{removeNotice:e}=(0,o.useDispatch)(l.store),s=(0,o.useSelect)(e=>e(l.store).getNotices());return s?.length?(0,p.jsx)(a.NoticeList,{notices:s,onRemove:e}):null},_=()=>{const{snippets:e,setSnippets:s,saveSettings:t,isSaving:r}=(()=>{const[e,s]=(0,n.useState)({}),[t,a]=(0,n.useState)(!1),{createSuccessNotice:r,createErrorNotice:p}=(0,o.useDispatch)(l.store);return(0,n.useEffect)(()=>{c()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n={},i=window?.zenpressSnippetsMeta||{};Object.keys(i).forEach(e=>{const s=i[e]||{};n[e]={...s,"enable-snippet":t.includes(e)}}),s(n)}).catch(()=>{p((0,i.__)("Failed to load settings.","zenpress"))})},[p]),{snippets:e,setSnippets:s,saveSettings:()=>{a(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]||!1);return c()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s}}).then(()=>{r((0,i.__)("Settings saved.","zenpress"))}).catch(()=>{p((0,i.__)("Failed to save settings.","zenpress"))}).finally(()=>a(!1))},isSaving:t}})(),[_,w]=(0,n.useState)(new Set), v=e=>{s(s=>{const t={},n=new Set(_);return Object.entries(s).forEach(([s,a])=>{const r=(Array.isArray(a?.preset)?a.preset:[]).includes(e);t[s]={...a,"enable-snippet":r},r&&n.add(a.category||(0,i.__)("Uncategorized","zenpress"))}),w(n),t})},x={};Object.keys(e).forEach(s=>{const t=e[s],n=t?.category||(0,i.__)("Uncategorized","zenpress");x[n]||(x[n]=[]),x[n].push({name:s,data:t})});const j=Object.keys(x).sort((e,s)=>e.localeCompare(s,void 0,{sensitivity:"base"}));return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)("div",{className:"zenpress-row",children:(0,p.jsxs)("div",{className:"zenpress-col",children:[(0,p.jsxs)("div",{className:"zenpress-presets",children:[(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("p",{children:(0,i.__)("Select the features that suit your needs. If you don't know which ones to choose, just select your site's type and it will set the right features for you.","zenpress")}),(0,p.jsx)("h2",{children:(0,i.__)("Pick a preset","zenpress")})]}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>v("showcase-website"),__next40pxDefaultSize:!0,children:(0,i.__)("Showcase website","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>v("blog"),__next40pxDefaultSize:!0,children:(0,i.__)("Blog","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>v("ecommerce"),__next40pxDefaultSize:!0,children:(0,i.__)("E-commerce","zenpress")}),(0,p.jsx)("div",{className:"zenpress-presets-description",children:(0,p.jsx)("h2",{children:(0,i.__)("Or just enable what you need","zenpress")})}),(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s}),w(new Set(Object.values(e).map(e=>e.category||(0,i.__)("Uncategorized","zenpress"))))},__next40pxDefaultSize:!0,children:(0,i.__)("Enable all actions","zenpress")}),(0,p.jsx)(a.Button,{isDestructive:"true",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,i.__)("Disable all actions","zenpress")})]})]}),j.map(e=>(0,p.jsx)(a.Panel,{children:(0,p.jsx)(a.PanelBody,{title:e,initialOpen:_.has(e)||x[e].some(({data:e})=>e?.["enable-snippet"]),children:x[e].map(({name:e,data:t})=>(0,p.jsx)(a.PanelRow,{children:(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""})},e))})},e)),(0,p.jsx)("div",{className:"zenpress-actions",children:(0,p.jsx)(h,{onClick:t,isBusy:r})}),(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(u,{})})]})})})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(_,{}))})})();1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element,i=window.wp.i18n,a=window.wp.components,r=window.wp.apiFetch;var c=e.n(r);const o=window.wp.data,l=window.wp.notices,p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:n})=>(0,p.jsx)(a.ToggleControl,{label:e,checked:s,onChange:t,help:n,__nextHasNoMarginBottom:!0}),h=({onClick:e,isBusy:s})=>(0,p.jsx)(a.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,i.__)("Save settings","zenpress")}),u=()=>{const{removeNotice:e}=(0,o.useDispatch)(l.store),s=(0,o.useSelect)(e=>e(l.store).getNotices());return s?.length?(0,p.jsx)(a.NoticeList,{notices:s,onRemove:e}):null},_=()=>{const{snippets:e,setSnippets:s,saveSettings:t,isSaving:r}=(()=>{const[e,s]=(0,n.useState)({}),[t,a]=(0,n.useState)(!1),{createSuccessNotice:r,createErrorNotice:p}=(0,o.useDispatch)(l.store);return(0,n.useEffect)(()=>{c()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n={},i=window?.zenpressSnippetsMeta||{};Object.keys(i).forEach(e=>{const s=i[e]||{};n[e]={...s,"enable-snippet":t.includes(e)}}),s(n)}).catch(()=>{p((0,i.__)("Failed to load settings.","zenpress"))})},[p]),{snippets:e,setSnippets:s,saveSettings:()=>{a(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]||!1);return c()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s}}).then(()=>{r((0,i.__)("Settings saved.","zenpress"))}).catch(()=>{p((0,i.__)("Failed to save settings.","zenpress"))}).finally(()=>a(!1))},isSaving:t}})(),[_,w]=(0,n.useState)(new Set),x=e=>{s(s=>{const t={};return Object.entries(s).forEach(([s,n])=>{const i=(Array.isArray(n?.preset)?n.preset:[]).includes(e);t[s]={...n,"enable-snippet":i}}),t}),w(new Set(j))},v={};Object.keys(e).forEach(s=>{const t=e[s],n=t?.category||(0,i.__)("Uncategorized","zenpress");v[n]||(v[n]=[]),v[n].push({name:s,data:t})});const j=Object.keys(v).sort((e,s)=>e.localeCompare(s,void 0,{sensitivity:"base"}));return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)("div",{className:"zenpress-row",children:(0,p.jsxs)("div",{className:"zenpress-col",children:[(0,p.jsxs)("div",{className:"zenpress-presets",children:[(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("p",{children:(0,i.__)("Select the features that suit your needs. If you don't know which ones to choose, just select your site's type and it will set the right features for you.","zenpress")}),(0,p.jsx)("h2",{children:(0,i.__)("Pick a preset","zenpress")})]}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>x("showcase-website"),__next40pxDefaultSize:!0,children:(0,i.__)("Showcase website","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>x("blog"),__next40pxDefaultSize:!0,children:(0,i.__)("Blog","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>x("ecommerce"),__next40pxDefaultSize:!0,children:(0,i.__)("E-commerce","zenpress")}),(0,p.jsx)("div",{className:"zenpress-presets-description",children:(0,p.jsx)("h2",{children:(0,i.__)("Or just enable what you need","zenpress")})}),(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s}),w(new Set(j))},__next40pxDefaultSize:!0,children:(0,i.__)("Enable all actions","zenpress")}),(0,p.jsx)(a.Button,{isDestructive:"true",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,i.__)("Disable all actions","zenpress")})]})]}),j.map(e=>(0,p.jsx)(a.Panel,{children:(0,p.jsx)(a.PanelBody,{title:e,initialOpen:_.has(e),children:v[e].map(({name:e,data:t})=>(0,p.jsx)(a.PanelRow,{children:(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""})},e))})},e)),(0,p.jsx)("div",{className:"zenpress-actions",children:(0,p.jsx)(h,{onClick:t,isBusy:r})}),(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(u,{})})]})})})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(_,{}))})})(); -
zenpress/tags/2.0.2/assets/src/index.js
r3352459 r3355428 176 176 }); 177 177 // Open all categories 178 setOpenCategories(new Set( Object.values(snippets).map((s) => s.category || __('Uncategorized', 'zenpress'))));178 setOpenCategories(new Set(sortedCategories)); 179 179 }; 180 180 … … 192 192 return updated; 193 193 }); 194 // Keep categories open (do not clear)195 194 }; 196 195 197 196 /** 198 197 * Enable snippets by preset. 199 *200 * All snippets not in the preset will be disabled.201 198 * 202 199 * @param {string} preset - Preset key to enable. … … 206 203 setSnippets((prev) => { 207 204 const updated = {}; 208 const newOpen = new Set(openCategories);209 205 Object.entries(prev).forEach(([name, data]) => { 210 206 const presets = Array.isArray(data?.preset) ? data.preset : []; … … 214 210 'enable-snippet': isEnabled, 215 211 }; 216 if (isEnabled) {217 newOpen.add(data.category || __('Uncategorized', 'zenpress'));218 }219 212 }); 220 setOpenCategories(newOpen);221 213 return updated; 222 214 }); 215 // Open all categories 216 setOpenCategories(new Set(sortedCategories)); 223 217 }; 224 218 … … 298 292 <PanelBody 299 293 title={category} 300 // Keep open if already marked or if a snippet is enabled 301 initialOpen={ 302 openCategories.has(category) || 303 groupedSnippets[category].some( 304 ({ data }) => data?.['enable-snippet'] 305 ) 306 } 294 initialOpen={openCategories.has(category)} 307 295 > 308 296 {groupedSnippets[category].map(({ name, data }) => ( -
zenpress/tags/2.0.2/inc/snippets/disable-author-archives.php
r3352459 r3355428 8 8 remove_filter('template_redirect', 'redirect_canonical'); 9 9 10 add_action('template_redirect', function () {10 add_action('template_redirect', static function () { 11 11 if (is_author()) { 12 12 global $wp_query; -
zenpress/tags/2.0.2/inc/snippets/disable-dashicons.php
r3352459 r3355428 5 5 } 6 6 7 add_action('wp_enqueue_scripts', function () {7 add_action('wp_enqueue_scripts', static function () { 8 8 if (!is_user_logged_in()) { 9 9 wp_dequeue_style('dashicons'); -
zenpress/tags/2.0.2/inc/snippets/disable-emoji-scripts.php
r3352459 r3355428 22 22 23 23 // Remove emoji support from TinyMCE editor. 24 add_filter('tiny_mce_plugins', function ($plugins) {24 add_filter('tiny_mce_plugins', static function ($plugins) { 25 25 return array_diff($plugins, ['wpemoji']); 26 26 }); -
zenpress/tags/2.0.2/inc/snippets/disable-jquery-migrate.php
r3352459 r3355428 5 5 } 6 6 7 add_action('wp_default_scripts', function (&$scripts) {7 add_action('wp_default_scripts', static function (&$scripts) { 8 8 if (!is_admin() && isset($scripts->registered['jquery'])) { 9 9 $script = $scripts->registered['jquery']; -
zenpress/tags/2.0.2/inc/snippets/disable-oembed.php
r3352459 r3355428 5 5 } 6 6 7 add_action('init', 'zenpress_disable_oembed'); 8 function zenpress_disable_oembed() { 7 add_action('init', static function () { 9 8 // Remove oEmbed from query vars. 10 9 global $wp; … … 45 44 wp_deregister_script('wp-embed'); 46 45 } 47 } 46 }); -
zenpress/tags/2.0.2/inc/snippets/disable-pdf-thumbnails.php
r3352459 r3355428 5 5 } 6 6 7 add_filter('fallback_intermediate_image_sizes', function () {7 add_filter('fallback_intermediate_image_sizes', static function () { 8 8 return []; 9 9 }); -
zenpress/tags/2.0.2/inc/snippets/disable-pingback-trackback.php
r3352459 r3355428 6 6 7 7 // Remove X-Pingback header from HTTP responses. 8 add_filter('wp_headers', function ($headers) {8 add_filter('wp_headers', static function ($headers) { 9 9 unset($headers['X-Pingback']); 10 10 … … 13 13 14 14 // Disable pingbacks and trackbacks for new posts. 15 add_action('after_setup_theme', function () {15 add_action('after_setup_theme', static function () { 16 16 update_option('default_ping_status', 'closed'); 17 17 update_option('default_pingback_flag', 0); … … 19 19 20 20 // Prevent self-pingbacks. 21 add_action('pre_ping', function (&$links) {21 add_action('pre_ping', static function (&$links) { 22 22 $home = get_option('home'); 23 23 foreach ($links as $l => $link) { -
zenpress/tags/2.0.2/inc/snippets/disable-woocommerce-cart-fragments.php
r3352459 r3355428 5 5 } 6 6 7 add_action('wp_enqueue_scripts', 'zenpress_disable_cart_fragments', 11); 8 9 function zenpress_disable_cart_fragments() { 10 if (class_exists('WooCommerce')) { 7 if (class_exists('WooCommerce')) { 8 add_action('wp_enqueue_scripts', static function () { 11 9 wp_dequeue_script('wc-cart-fragments'); 12 } 10 }, 11); 13 11 } -
zenpress/tags/2.0.2/inc/snippets/disable-woocommerce-scripts-styles.php
r3352459 r3355428 1 1 <?php 2 2 3 add_action('wp_enqueue_scripts', 'zenpress_disable_woocommerce_scripts_styles', 11); 3 if (!defined('ABSPATH')) { 4 exit; 5 } 4 6 5 function zenpress_disable_woocommerce_scripts_styles() { 6 if (!class_exists('WooCommerce')) { 7 return; 8 } 7 if (class_exists('WooCommerce')) { 8 add_action('wp_enqueue_scripts', static function () { 9 if (!is_woocommerce() && !is_cart() && !is_checkout() && !is_account_page() && !is_product() && !is_product_category() && !is_shop()) { 10 // Dequeue WooCommerce Styles 11 wp_dequeue_style('woocommerce-general'); 12 wp_dequeue_style('woocommerce-layout'); 13 wp_dequeue_style('woocommerce-smallscreen'); 14 wp_dequeue_style('woocommerce_frontend_styles'); 15 wp_dequeue_style('woocommerce_fancybox_styles'); 16 wp_dequeue_style('woocommerce_chosen_styles'); 17 wp_dequeue_style('woocommerce_prettyPhoto_css'); 9 18 10 if (!is_woocommerce() && !is_cart() && !is_checkout() && !is_account_page() && !is_product() && !is_product_category() && !is_shop()) { 11 // Dequeue WooCommerce Styles 12 wp_dequeue_style('woocommerce-general'); 13 wp_dequeue_style('woocommerce-layout'); 14 wp_dequeue_style('woocommerce-smallscreen'); 15 wp_dequeue_style('woocommerce_frontend_styles'); 16 wp_dequeue_style('woocommerce_fancybox_styles'); 17 wp_dequeue_style('woocommerce_chosen_styles'); 18 wp_dequeue_style('woocommerce_prettyPhoto_css'); 19 20 // Dequeue WooCommerce Scripts 21 wp_dequeue_script('wc-price-slider'); 22 wp_dequeue_script('wc-single-product'); 23 wp_dequeue_script('wc-add-to-cart'); 24 wp_dequeue_script('wc-checkout'); 25 wp_dequeue_script('wc-add-to-cart-variation'); 26 wp_dequeue_script('wc-cart'); 27 wp_dequeue_script('wc-chosen'); 28 wp_dequeue_script('woocommerce'); 29 wp_dequeue_script('prettyPhoto'); 30 wp_dequeue_script('prettyPhoto-init'); 31 wp_dequeue_script('jquery-blockui'); 32 wp_dequeue_script('jquery-placeholder'); 33 wp_dequeue_script('fancybox'); 34 wp_dequeue_script('jqueryui'); 35 } 19 // Dequeue WooCommerce Scripts 20 wp_dequeue_script('wc-price-slider'); 21 wp_dequeue_script('wc-single-product'); 22 wp_dequeue_script('wc-add-to-cart'); 23 wp_dequeue_script('wc-checkout'); 24 wp_dequeue_script('wc-add-to-cart-variation'); 25 wp_dequeue_script('wc-cart'); 26 wp_dequeue_script('wc-chosen'); 27 wp_dequeue_script('woocommerce'); 28 wp_dequeue_script('prettyPhoto'); 29 wp_dequeue_script('prettyPhoto-init'); 30 wp_dequeue_script('jquery-blockui'); 31 wp_dequeue_script('jquery-placeholder'); 32 wp_dequeue_script('fancybox'); 33 wp_dequeue_script('jqueryui'); 34 } 35 }, 11); 36 36 } -
zenpress/tags/2.0.2/inc/snippets/disable-woocommerce-widgets.php
r3352459 r3355428 6 6 7 7 if (class_exists('WooCommerce')) { 8 add_action('widgets_init', 'zenpress_disable_woocommerce_widgets', 99); 9 10 function zenpress_disable_woocommerce_widgets() { 8 add_action('widgets_init', static function() { 11 9 unregister_widget('WC_Widget_Products'); 12 10 unregister_widget('WC_Widget_Product_Categories'); … … 21 19 unregister_widget('WC_Widget_Top_Rated_Products'); 22 20 unregister_widget('WC_Widget_Rating_Filter'); 23 } 21 }, 99); 24 22 } -
zenpress/tags/2.0.2/inc/snippets/hide-woocommerce-version.php
r3352459 r3355428 7 7 if (class_exists('WooCommerce') && !is_admin()) { 8 8 // Remove WooCommerce version from HTTP headers 9 add_filter('wp_headers', 'zenpress_remove_woocommerce_version'); 10 function zenpress_remove_woocommerce_version($headers) { 9 add_filter('wp_headers', static function ($headers) { 11 10 if (isset($headers['X-WooCommerce-Version'])) { 12 11 unset($headers['X-WooCommerce-Version']); … … 14 13 15 14 return $headers; 16 } 15 }); 17 16 18 // Remove WooCommerce version from script and style URLs 19 add_filter('style_loader_src', 'zenpress_remove_woocommerce_version_scripts_styles', 10); 20 add_filter('script_loader_src', 'zenpress_remove_woocommerce_version_scripts_styles', 10); 21 function zenpress_remove_woocommerce_version_scripts_styles($src) { 17 // Remove WooCommerce version from style URLs 18 add_filter('style_loader_src', static function ($src) { 22 19 if (strpos($src, 'ver=') !== false && strpos($src, 'woocommerce') !== false) { 23 20 $src = remove_query_arg('ver', $src); … … 25 22 26 23 return $src; 27 } 24 }, 10); 25 26 // Remove WooCommerce version from script URLs 27 add_filter('script_loader_src', static function ($src) { 28 if (strpos($src, 'ver=') !== false && strpos($src, 'woocommerce') !== false) { 29 $src = remove_query_arg('ver', $src); 30 } 31 32 return $src; 33 }, 10); 28 34 } -
zenpress/tags/2.0.2/inc/snippets/hide-wordpress-version.php
r3352459 r3355428 9 9 10 10 // Remove WordPress version from generator 11 add_filter('the_generator', 'zenpress_remove_wordpress_version'); 12 function zenpress_remove_wordpress_version() { 11 add_filter('the_generator', static function () { 13 12 return ''; 14 } 13 }); 15 14 16 // Remove WordPress version from script and style URLs 17 add_filter('style_loader_src', 'zenpress_remove_version_from_assets'); 18 add_filter('script_loader_src', 'zenpress_remove_version_from_assets'); 19 function zenpress_remove_version_from_assets($src) { 15 // Remove WordPress version from script URLs 16 add_filter('script_loader_src', static function ($src) { 20 17 if (strpos($src, 'ver=' . get_bloginfo('version')) !== false) { 21 18 $src = remove_query_arg('ver', $src); … … 23 20 24 21 return $src; 25 } 22 }); 23 24 // Remove WordPress version from style URLs 25 add_filter('style_loader_src', static function ($src) { 26 if (strpos($src, 'ver=' . get_bloginfo('version')) !== false) { 27 $src = remove_query_arg('ver', $src); 28 } 29 30 return $src; 31 }); -
zenpress/tags/2.0.2/inc/snippets/protect-wp-login.php
r3352459 r3355428 6 6 7 7 // Remove detailed login errors 8 add_filter('login_errors', function () {8 add_filter('login_errors', static function () { 9 9 return __('Login error.', 'zenpress'); 10 10 }); 11 11 12 12 // Limit login attempts 13 add_filter('authenticate', 'zenpress_login_protection', 30, 3); 14 function zenpress_login_protection(mixed $user, string $username, string $password): mixed { 13 add_filter('authenticate', static function (mixed $user, string $username, string $password): mixed { 15 14 $MAX_LOGIN_ATTEMPTS = 5; 16 15 $BLOCK_DURATION = 300; // 5 minutes … … 55 54 56 55 return $user; 57 } 56 }, 30, 3); -
zenpress/tags/2.0.2/inc/snippets/remove-gutenberg-unwanted-block-patterns.php
r3352459 r3355428 9 9 10 10 // Remove core block patterns 11 add_action('after_setup_theme', 'zenpress_remove_core_block_patterns'); 12 function zenpress_remove_core_block_patterns() { 11 add_action('after_setup_theme', static function () { 13 12 remove_theme_support('core-block-patterns'); 14 } 13 }); -
zenpress/tags/2.0.2/inc/snippets/remove-woocommerce-patterns.php
r3352459 r3355428 7 7 use Automattic\WooCommerce\Blocks\Package; 8 8 9 add_action('woocommerce_blocks_loaded', 'zenpress_remove_wc_patterns'); 10 function zenpress_remove_wc_patterns(): void { 9 add_action('woocommerce_blocks_loaded', static function (): void { 11 10 remove_action( 12 11 'init', … … 16 15 ] 17 16 ); 18 } 17 }); -
zenpress/tags/2.0.2/readme.txt
r3352462 r3355428 1 === ZenPress ===1 === ZenPress — Cleaner, Lighter, Faster WP === 2 2 Contributors: @quentinldd 3 3 Donate link: https://github.com/sponsors/quentin-ld/ … … 5 5 Requires at least: 6.0 6 6 Tested up to: 6.8 7 Stable tag: 2.0. 17 Stable tag: 2.0.2 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 14 14 == Description == 15 15 16 ZenPress is a lightweight, super-fast plugin that boosts your WordPress & WooCommerce website through a wide range of solid actions. This is a simple solution for improving your WordPress website's performance and security while enjoying a simpler and lighter UI. 16 ZenPress is a lightweight, super-fast plugin that boosts your WordPress & WooCommerce website through a wide range of solid actions. 17 This is a simple solution for improving your WordPress website's performance and security while enjoying a simpler and lighter UI. 17 18 No database clutter, no ads, no pro version. Just install, activate, select what you need or pick up your settings preset and you are ready to go ! 18 19 … … 74 75 * Remove WooCommerce default remote block patterns 75 76 77 == Roadmap == 78 79 = Global = 80 * New presets 81 82 = Security = 83 * Disable Application Passwords 84 * Manage Heartbeat API (frontend + backend + admin whitelist) 85 * Disable REST API 86 87 = Performance = 88 * Disable capital_P_dangit filter 89 * Disable autosave 90 * Disable post revision 91 * Disable native lazy loading 92 * Disable Password Strength Meter 93 * Disable WordPress default lazy loading 94 95 = UI = 96 * Remove "howdy" from admin bar 97 * Remove WordPress logo 98 * Remove "Help button" 99 * Remove "Thanks for using WordPress" in footer 100 * Remove "site health" page 101 * Remove "Privacy tools" 102 103 = WooCommerce = 104 * Disable WooCommerce tracking 105 * Disable marketing hub 106 * Disable dashboard setup widget 107 * Disable new product editor 108 * Disable WooCommerce blocks 109 * Disable WooCommerce promo emails 110 111 = Plugins = 112 * Disable CF7 CSS & JS 113 * Disable Elementor bloat 114 * Disable WP Bakery bloat 115 * Disable Divi bloat 116 * Disable Yoast SEO bloat 117 * Disable Jetpack bloat 118 * Disable Updraft bloat 119 120 == Privacy Statement == 121 122 ZenPress is private by default and always will be. It does not store any data. It does not send data to any third party, nor does it include any third party resources. 123 124 == Accessibility Statement == 125 126 ZenPress aims to be fully accessible to all of its users. 127 76 128 == Screenshots == 77 129 78 130 1. ZenPress admin interface. 79 1. Dashboard without ZenPress. 80 2. Dashboard with ZenPress. 81 3. Site editor without ZenPress. 82 4. Site editor with ZenPress. 83 5. Login page without ZenPress login protection. 84 6. Login page with ZenPress login protection. 85 7. Login page with ZenPress login protection after trying to brute force it. 86 8. Website head without ZenPress. 87 9. Website head with ZenPress. 88 89 == Privacy Statement == 90 91 ZenPress is private by default and always will be. It does not store any data. It does not send data to any third party, nor does it include any third party resources. 92 93 == Accessibility Statement == 94 95 ZenPress aims to be fully accessible to all of its users. 131 2. Dashboard without ZenPress. 132 3. Dashboard with ZenPress. 133 4. Site editor without ZenPress. 134 5. Site editor with ZenPress. 135 6. Login page without ZenPress login protection. 136 7. Login page with ZenPress login protection. 137 8. Login page with ZenPress login protection after trying to brute force it. 138 9. Website head without ZenPress. 139 10. Website head with ZenPress. 96 140 97 141 == Frequently Asked Questions == … … 101 145 Yes, there is no pro version for this plugin and there never will be. 102 146 103 However, I am accepting donations on my buymeacoffee page : https://buymeacoffee.com/quentinld. If you work at an agency that develops with WordPress, ask your company to provide sponsorship in order to invest in its supply chain. The tools that I maintain probably save your company time and money, and Buy me a coffee supportcan now be done at the organisation level.104 105 In addition, if you like the plugin then I'd love for you to leave a review. Tell all your friends about it too!147 However, [I am accepting sponsorships via the GitHub Sponsors program](https://github.com/sponsors/quentin-ld/dashboard). If you work at an agency that develops with WordPress, ask your company to provide sponsorship in order to invest in its supply chain. The tools that I maintain probably save your company time and money, and GitHub sponsorship can now be done at the organisation level. 148 149 In addition, if you like the plugin then I'd love for you to [leave a review](https://wordpress.org/support/plugin/zenpress/reviews/). Tell all your friends about it too! 106 150 107 151 = I have a suggestion = … … 114 158 115 159 == Changelog == 160 161 = 2.0.2 = 162 163 - Global : Codebase and snippets optimization 164 - Global : Fixed a bug in the automatic opening and closing function of the panels on the settings page. 116 165 117 166 = 2.0.1 = -
zenpress/tags/2.0.2/zenpress.php
r3352462 r3355428 10 10 * @license GPL v2 or later 11 11 * 12 * Plugin Name: ZenPress 12 * Plugin Name: ZenPress — Cleaner, Lighter, Faster WP 13 13 * Description: Easily speed up and strengthen your WordPress site by cleaning out unnecessary features and protecting weak points. 14 * Version: 2.0. 114 * Version: 2.0.2 15 15 * Plugin URI: https://wordpress.org/plugins/zenpress/ 16 16 * Author: Quentin Le Duff … … 31 31 * This program is distributed in the hope that it will be useful, 32 32 * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 34 * GNU General Public License for more details. 35 * 36 */ 37 38 /***** 39 * TODOLIST ▓▒░(°◡°)░▒▓ 40 ****/ 41 // TODO: Disable comments URL 42 // TODO: CHECK THE DEPLOYMENT WORKING PROPERLY 35 */ 43 36 44 37 if (!defined('ABSPATH')) { … … 47 40 48 41 /** 49 * Add settings link on the plugins list page (next to Activate/Deactivate).50 *51 * @param array $links Existing plugin action links.52 * @return array Modified links with Settings link appended at the end.53 */54 function zenpress_add_settings_link(array $links): array {55 $settings_url = admin_url('options-general.php?page=zenpress');56 57 $settings_link = sprintf(58 '<a href="%s" aria-label="%s">%s</a>',59 esc_url($settings_url),60 esc_attr__('Go to ZenPress settings page', 'zenpress'),61 esc_html__('Settings', 'zenpress')62 );63 64 // Add "Settings" link at the end instead of first65 $links[] = $settings_link;66 67 return $links;68 }69 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'zenpress_add_settings_link');70 71 72 /**73 * Add extra links under the plugin description on the plugins page.74 *75 * @param array $links Existing links.76 * @param string $file Current plugin file.77 * @return array Modified links.78 */79 function zenpress_plugin_row_meta($links, $file) {80 if ($file === plugin_basename(__FILE__)) {81 $extra_links = array(82 '<a href="' . esc_url('https://wordpress.org/plugins/zenpress/#developers') . '" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress') . '">' . esc_html__('Changelog', 'zenpress') . '</a>',83 '<a href="' . esc_url('https://holdmywp.com/zenpress/') . '" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__('Read ZenPress documentation (opens in a new tab)', 'zenpress') . '">' . esc_html__('Docs', 'zenpress') . '</a>',84 '<a href="' . esc_url('https://buymeacoffee.com/quentinld') . '" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__('Support ZenPress by buying a coffee (opens in a new tab)', 'zenpress') . '">' . esc_html__('Support ☕', 'zenpress') . '</a>',85 );86 87 $links = array_merge($links, $extra_links);88 }89 90 return $links;91 }92 add_filter('plugin_row_meta', 'zenpress_plugin_row_meta', 10, 2);93 94 95 96 /**97 42 * Enqueue scripts and styles used by the plugin in admin area. 98 43 * … … 100 45 * @return void 101 46 */ 47 add_action('admin_enqueue_scripts', 'zenpress_admin_enqueue_scripts'); 102 48 function zenpress_admin_enqueue_scripts(string $admin_page): void { 103 if ( $admin_page !== 'settings_page_zenpress') {49 if ('settings_page_zenpress' !== $admin_page) { 104 50 return; 105 51 } 106 52 107 53 $asset_file = plugin_dir_path(__FILE__) . 'assets/build/index.asset.php'; 108 if (! is_file($asset_file)) {54 if (!file_exists($asset_file)) { 109 55 return; 110 56 } 111 57 112 /** @var mixed $asset */113 58 $asset = include $asset_file; 114 115 if (!is_array($asset) || empty($asset['dependencies']) || empty($asset['version'])) {116 return;117 }118 119 $dependencies = array_map('sanitize_key', (array) $asset['dependencies']);120 $version = sanitize_text_field((string) $asset['version']);121 122 59 wp_enqueue_script( 123 60 'zenpress-scripts', 124 61 plugins_url('assets/build/index.js', __FILE__), 125 $ dependencies,126 $ version,62 $asset['dependencies'], 63 $asset['version'], 127 64 true 128 65 ); … … 132 69 plugins_url('assets/build/index.css', __FILE__), 133 70 array_filter( 134 $dependencies, 135 static fn($style) => is_string($style) && wp_style_is($style, 'registered') 71 $asset['dependencies'], 72 function ($style) { 73 return wp_style_is($style, 'registered'); 74 } 136 75 ), 137 $version 138 ); 139 } 140 add_action('admin_enqueue_scripts', 'zenpress_admin_enqueue_scripts'); 76 $asset['version'] 77 ); 78 } 79 80 /** 81 * Localize translated snippet metadata for use in JavaScript. 82 * 83 * @param string $admin_page Current admin page hook. 84 * @return void 85 */ 86 add_action('admin_enqueue_scripts', 'zenpress_localize_snippets_meta'); 87 function zenpress_localize_snippets_meta(string $admin_page): void { 88 if ('settings_page_zenpress' !== $admin_page) { 89 return; 90 } 91 92 $snippets = []; 93 $snippets_path = plugin_dir_path(__FILE__) . 'inc/snippets/'; 94 if (!is_dir($snippets_path)) { 95 return; 96 } 97 98 foreach (glob($snippets_path . '*.php') as $file) { 99 $basename = basename($file, '.php'); 100 $snippets[$basename] = zenpress_extract_snippet_metadata($basename); 101 } 102 103 wp_localize_script('zenpress-scripts', 'zenpressSnippetsMeta', $snippets); 104 } 105 106 /** 107 * Add a settings link on the plugins list page. 108 * 109 * @param array $links Existing plugin action links. 110 * @return array Modified plugin action links. 111 */ 112 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'zenpress_add_settings_link'); 113 function zenpress_add_settings_link(array $links): array { 114 $url = admin_url('options-general.php?page=zenpress'); 115 $links[] = sprintf( 116 '<a href="%s" aria-label="%s">%s</a>', 117 esc_url($url), 118 esc_attr__('Go to ZenPress settings page', 'zenpress'), 119 esc_html__('Settings', 'zenpress') 120 ); 121 return $links; 122 } 123 124 /** 125 * Add extra links under the plugin description on the plugins page. 126 * 127 * @param array $links Existing row meta links. 128 * @param string $file Current plugin file. 129 * @return array Modified row meta links. 130 */ 131 add_filter('plugin_row_meta', 'zenpress_plugin_row_meta', 10, 2); 132 function zenpress_plugin_row_meta(array $links, string $file): array { 133 if ($file === plugin_basename(__FILE__)) { 134 $extra_links = array( 135 sprintf( 136 '<a href="%s" target="_blank" rel="noopener noreferrer" aria-label="%s">%s</a>', 137 esc_url('https://wordpress.org/plugins/zenpress/#developers'), 138 esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress'), 139 esc_html__('Changelog', 'zenpress') 140 ), 141 sprintf( 142 '<a href="%s" target="_blank" rel="noopener noreferrer" aria-label="%s">%s</a>', 143 esc_url('https://holdmywp.com/zenpress/'), 144 esc_attr__('Read ZenPress documentation (opens in a new tab)', 'zenpress'), 145 esc_html__('Docs', 'zenpress') 146 ), 147 sprintf( 148 '<a href="%s" target="_blank" rel="noopener noreferrer" aria-label="%s">%s</a>', 149 esc_url('https://buymeacoffee.com/quentinld'), 150 esc_attr__('Support ZenPress by buying a coffee (opens in a new tab)', 'zenpress'), 151 esc_html__('Support ☕', 'zenpress') 152 ) 153 ); 154 $links = array_merge($links, $extra_links); 155 } 156 return $links; 157 } 141 158 142 159 /** … … 145 162 * @return void 146 163 */ 164 add_action('admin_menu', 'zenpress_add_option_page'); 147 165 function zenpress_add_option_page(): void { 148 166 add_options_page( … … 154 172 ); 155 173 } 156 add_action('admin_menu', 'zenpress_add_option_page');157 174 158 175 /** … … 162 179 */ 163 180 function zenpress_options_page(): void { 164 $plugin_data = get_file_data(__FILE__, ['Version' => 'Version'], 'plugin');165 $plugin_version = $plugin_data['Version'] ?? '';181 $plugin_data = get_file_data(__FILE__, ['Version' => 'Version'], 'plugin'); 182 $plugin_version = $plugin_data['Version'] ?? ''; 166 183 ?> 167 184 <div class="wrap zenpress-dashboard-wrap"> 168 185 <div class="zenpress-header"> 169 186 <div class="zenpress-header-title"> 170 <h1> 171 <?php echo esc_html__('ZenPress', 'zenpress'); ?> 172 </h1> 173 <?php if ($plugin_version) : ?> 174 <p class="zenpress-plugin-version"> 175 <?php echo esc_html__('Version', 'zenpress') . ' ' . esc_html($plugin_version) . ' - '; ?> 176 <a href="https://wordpress.org/plugins/zenpress/#developers" 177 target="_blank" 178 rel="noopener noreferrer" 179 aria-label="<?php echo esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 180 <?php echo esc_html__('What\'s new ?', 'zenpress'); ?> 181 </a> 182 </p> 183 <?php endif; ?> 184 </div> 185 <div class="zenpress-header-navigation"> 186 <a href="https://holdmywp.com/zenpress/" 187 target="_blank" 188 rel="noopener noreferrer" 189 aria-label="<?php echo esc_attr__('Read the ZenPress documentation (opens in a new tab)', 'zenpress'); ?>"> 190 <?php echo esc_html__('Documentation', 'zenpress'); ?> 191 </a> 192 193 <a href="https://wordpress.org/plugins/zenpress/#reviews" 194 target="_blank" 195 rel="noopener noreferrer" 196 aria-label="<?php echo esc_attr__('Leave a review for ZenPress on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 197 <?php echo esc_html__('Leave a review (helps a lot)', 'zenpress'); ?> 198 </a> 199 200 <a href="https://buymeacoffee.com/quentinld" 201 target="_blank" 202 rel="noopener noreferrer" 203 class="components-button is-next-40px-default-size is-tertiary" 204 aria-label="<?php echo esc_attr__('Support development: Buy me a coffee (opens in a new tab)', 'zenpress'); ?>"> 205 <?php echo esc_html__('Buy me a coffee', 'zenpress'); ?> <span aria-hidden="true">☕</span> 206 </a> 207 </div> 187 <h1><?php echo esc_html__('ZenPress', 'zenpress'); ?></h1> 188 <?php if ($plugin_version) : ?> 189 <p class="zenpress-plugin-version"> 190 <?php echo esc_html__('Version', 'zenpress') . ' ' . esc_html($plugin_version) . ' - '; ?> 191 <a href="https://wordpress.org/plugins/zenpress/#developers" 192 target="_blank" 193 rel="noopener noreferrer" 194 aria-label="<?php echo esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 195 <?php echo esc_html__('What\'s new ?', 'zenpress'); ?> 196 </a> 197 </p> 198 <?php endif; ?> 199 </div> 200 <div class="zenpress-header-navigation"> 201 <a href="https://holdmywp.com/zenpress/" 202 target="_blank" 203 rel="noopener noreferrer" 204 aria-label="<?php echo esc_attr__('Read the ZenPress documentation (opens in a new tab)', 'zenpress'); ?>"> 205 <?php echo esc_html__('Documentation', 'zenpress'); ?> 206 </a> 207 <a href="https://wordpress.org/plugins/zenpress/#reviews" 208 target="_blank" 209 rel="noopener noreferrer" 210 aria-label="<?php echo esc_attr__('Leave a review for ZenPress on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 211 <?php echo esc_html__('Leave a review (helps a lot)', 'zenpress'); ?> 212 </a> 213 <a href="https://buymeacoffee.com/quentinld" 214 target="_blank" 215 rel="noopener noreferrer" 216 class="components-button is-next-40px-default-size is-tertiary" 217 aria-label="<?php echo esc_attr__('Support development: Buy me a coffee (opens in a new tab)', 'zenpress'); ?>"> 218 <?php echo esc_html__('Buy me a coffee', 'zenpress'); ?> <span aria-hidden="true">☕</span> 219 </a> 220 </div> 208 221 </div> 209 210 222 <div id="zenpress-settings" class="zenpress-settings"> 211 <div class="zenpress-loading card">212 <div class="zenpress-loading-body">213 <p class="zenpress-loading-text">214 <?php echo esc_html__('Loading your ZenPress settings…', 'zenpress'); ?>215 </p>216 </div>217 </div>223 <div class="zenpress-loading card"> 224 <div class="zenpress-loading-body"> 225 <p class="zenpress-loading-text"> 226 <?php echo esc_html__('Loading your ZenPress settings…', 'zenpress'); ?> 227 </p> 228 </div> 229 </div> 218 230 </div> 219 220 <div class="zenpress-footer"> 221 <div class="zenpress-footer-title"> 231 <div class="zenpress-footer"> 232 <div class="zenpress-footer-title"> 222 233 <p> 223 <?php echo esc_html__('Made ', 'zenpress'); ?>224 <span aria-hidden="true"> x ❤️ </span>225 <?php echo esc_html__(' by Quentin Le Duff - Your WordPress Partner', 'zenpress'); ?>226 </p>227 </div> 228 <div class="zenpress-footer-navigation">229 <a href="https://holdmywp.com/"230 target="_blank"231 rel="noopener noreferrer"232 aria-label="<?php echo esc_attr__('Visite the developper website', 'zenpress'); ?>">233 <?php echo esc_html__('My place', 'zenpress'); ?>234 </a>235 <a href="https://github.com/quentin-ld/zenpress"236 target="_blank"237 rel="noopener noreferrer"238 aria-label="<?php echo esc_attr__('Review the code on Github', 'zenpress'); ?>">239 <?php echo esc_html__('ZenPress code repository', 'zenpress'); ?>240 </a>241 </div>234 <?php echo esc_html__('Made ', 'zenpress'); ?> 235 <span aria-hidden="true"> x ❤️ </span> 236 <?php echo esc_html__(' by Quentin Le Duff - Your WordPress Partner', 'zenpress'); ?> 237 </p> 238 </div> 239 <div class="zenpress-footer-navigation"> 240 <a href="https://holdmywp.com/" 241 target="_blank" 242 rel="noopener noreferrer" 243 aria-label="<?php echo esc_attr__('Visite the developper website', 'zenpress'); ?>"> 244 <?php echo esc_html__('My place', 'zenpress'); ?> 245 </a> 246 <a href="https://github.com/quentin-ld/zenpress" 247 target="_blank" 248 rel="noopener noreferrer" 249 aria-label="<?php echo esc_attr__('Review the code on Github', 'zenpress'); ?>"> 250 <?php echo esc_html__('ZenPress code repository', 'zenpress'); ?> 251 </a> 252 </div> 242 253 </div> 243 254 </div> … … 246 257 247 258 /** 248 * Extract snippet metadata from correspondingmeta file.249 * 250 * @param string $snippet_name Base name of the snippet(without extension).251 * @return array<string,mixed> Metadata array with keys: title, description, category, weight, preset.259 * Extract snippet metadata from its meta file. 260 * 261 * @param string $snippet_name Snippet base name (without extension). 262 * @return array<string,mixed> Sanitized metadata (title, description, category, weight, preset). 252 263 */ 253 264 function zenpress_extract_snippet_metadata(string $snippet_name): array { 254 $ metadata = [265 $defaults = array( 255 266 'title' => '', 256 267 'description' => '', 257 268 'category' => '', 258 269 'weight' => 0, 259 'preset' => [], 260 ]; 261 262 $safe_name = sanitize_file_name($snippet_name); 263 $meta_file = plugin_dir_path(__FILE__) . 'inc/meta/' . $safe_name . '.meta.php'; 264 265 if (is_file($meta_file)) { 266 /** @var mixed $data */ 267 $data = include $meta_file; 268 if (is_array($data)) { 269 $metadata = array_merge($metadata, array_intersect_key($data, $metadata)); 270 } 271 } 272 273 // Sanitize values securely 274 $metadata['title'] = sanitize_text_field($metadata['title']); 275 $metadata['description'] = sanitize_text_field($metadata['description']); 276 $metadata['category'] = sanitize_text_field($metadata['category']); 277 $metadata['weight'] = intval($metadata['weight']); 278 $metadata['preset'] = array_map('sanitize_text_field', (array) $metadata['preset']); 279 280 return $metadata; 281 } 282 283 284 /** 285 * Register a single option to store all active snippets. 286 * 287 * @return void 288 */ 270 'preset' => array() 271 ); 272 273 $file = plugin_dir_path(__FILE__) . 'inc/meta/' . sanitize_file_name($snippet_name) . '.meta.php'; 274 $data = is_file($file) ? include $file : array(); 275 $metadata = array_merge($defaults, is_array($data) ? $data : array()); 276 277 return array( 278 'title' => sanitize_text_field($metadata['title']), 279 'description' => sanitize_text_field($metadata['description']), 280 'category' => sanitize_text_field($metadata['category']), 281 'weight' => (int) $metadata['weight'], 282 'preset' => array_map('sanitize_text_field', (array) $metadata['preset']) 283 ); 284 } 285 286 /** 287 * Register option to store active snippets. 288 */ 289 add_action('init', 'zenpress_register_snippet_settings'); 289 290 function zenpress_register_snippet_settings(): void { 290 291 register_setting( 291 292 'options', 292 293 'zenpress_active_snippets', 293 [294 array( 294 295 'type' => 'array', 295 'default' => [], 296 'sanitize_callback' => static function ($value): array { 297 return array_values(array_filter( 298 array_map('sanitize_file_name', (array) $value) 299 )); 300 }, 301 'show_in_rest' => [ 302 'schema' => [ 296 'default' => array(), 297 'sanitize_callback' => 'zenpress_sanitize_snippets_option', 298 'show_in_rest' => array( 299 'schema' => array( 303 300 'type' => 'array', 304 'items' => [ 'type' => 'string' ], 305 ], 306 ], 307 ] 308 ); 309 } 310 add_action('init', 'zenpress_register_snippet_settings'); 311 312 /** 313 * Load enabled snippets. 314 * 315 * @param string $folder Relative folder where snippets are stored. 316 * @return array<int,string> List of loaded snippet base names. 301 'items' => array('type' => 'string') 302 ) 303 ) 304 ) 305 ); 306 } 307 308 /** 309 * Sanitize the list of active snippets. 310 * 311 * @param mixed $value Option value. 312 * @return array<string> Sanitized base names. 313 */ 314 function zenpress_sanitize_snippets_option($value): array { 315 return array_values( 316 array_filter( 317 array_map('sanitize_file_name', (array) $value) 318 ) 319 ); 320 } 321 322 /** 323 * Load all active snippets. 324 * 325 * @param string $folder Relative folder path for snippets. 326 * @return array<string> Loaded snippet base names. 317 327 */ 318 328 function zenpress_load_snippets(string $folder = 'inc/snippets/'): array { 319 $snippets_path = plugin_dir_path(__FILE__) . rtrim($folder, '/') . '/'; 320 if (!is_dir($snippets_path)) { 321 return []; 322 } 323 324 $active_snippets = get_option('zenpress_active_snippets', []); 325 if (!is_array($active_snippets)) { 326 $active_snippets = []; 327 } 328 329 $loaded = []; 330 foreach ($active_snippets as $base_name) { 331 $safe_name = sanitize_file_name($base_name); 332 $file = $snippets_path . $safe_name . '.php'; 333 $constant_name = 'ZENPRESS_' . strtoupper(str_replace(['-', '_'], '_', $safe_name)); 334 335 if (is_file($file) && (!defined($constant_name) || constant($constant_name) !== false)) { 329 $path = plugin_dir_path(__FILE__) . rtrim($folder, '/') . '/'; 330 331 if (!is_dir($path)) { 332 return array(); 333 } 334 335 $snippets = (array) get_option('zenpress_active_snippets', array()); 336 $loaded = array(); 337 foreach ($snippets as $name) { 338 $name = sanitize_file_name($name); 339 $file = $path . $name . '.php'; 340 $constant = 'ZENPRESS_' . strtoupper(str_replace(array('-', '_'), '_', $name)); 341 if (is_file($file) && (!defined($constant) || constant($constant) !== false)) { 336 342 include_once $file; 337 $loaded[] = $ safe_name;343 $loaded[] = $name; 338 344 } 339 345 } 340 341 346 return $loaded; 342 347 } 343 add_action('init', function () { 344 return zenpress_load_snippets(); 348 349 /** 350 * Boot ZenPress snippets. 351 */ 352 add_action('init', function() : void { 353 zenpress_load_snippets(); 345 354 }); 346 347 /**348 * Localize translated snippet metadata for use in JavaScript.349 *350 * @param string $hook Current admin page hook.351 * @return void352 */353 add_action('admin_enqueue_scripts', static function (string $hook): void {354 if ($hook !== 'settings_page_zenpress') {355 return;356 }357 358 $snippets = [];359 $snippets_path = plugin_dir_path(__FILE__) . 'inc/snippets/';360 if (!is_dir($snippets_path)) {361 return;362 }363 364 foreach (glob($snippets_path . '*.php') ?: [] as $file) {365 $base_name = basename($file, '.php');366 $snippets[$base_name] = zenpress_extract_snippet_metadata($base_name);367 }368 369 wp_localize_script('zenpress-scripts', 'zenpressSnippetsMeta', $snippets);370 }); -
zenpress/trunk/assets/build/index.asset.php
r3352459 r3355428 1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => ' 9b91df213cf8e0f8ef1f');1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-notices'), 'version' => 'ce3e5cbcbfb948f49cc1'); -
zenpress/trunk/assets/build/index.js
r3352459 r3355428 1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element,i=window.wp.i18n,a=window.wp.components,r=window.wp.apiFetch;var c=e.n(r);const o=window.wp.data,l=window.wp.notices,p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:n})=>(0,p.jsx)(a.ToggleControl,{label:e,checked:s,onChange:t,help:n,__nextHasNoMarginBottom:!0}),h=({onClick:e,isBusy:s})=>(0,p.jsx)(a.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,i.__)("Save settings","zenpress")}),u=()=>{const{removeNotice:e}=(0,o.useDispatch)(l.store),s=(0,o.useSelect)(e=>e(l.store).getNotices());return s?.length?(0,p.jsx)(a.NoticeList,{notices:s,onRemove:e}):null},_=()=>{const{snippets:e,setSnippets:s,saveSettings:t,isSaving:r}=(()=>{const[e,s]=(0,n.useState)({}),[t,a]=(0,n.useState)(!1),{createSuccessNotice:r,createErrorNotice:p}=(0,o.useDispatch)(l.store);return(0,n.useEffect)(()=>{c()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n={},i=window?.zenpressSnippetsMeta||{};Object.keys(i).forEach(e=>{const s=i[e]||{};n[e]={...s,"enable-snippet":t.includes(e)}}),s(n)}).catch(()=>{p((0,i.__)("Failed to load settings.","zenpress"))})},[p]),{snippets:e,setSnippets:s,saveSettings:()=>{a(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]||!1);return c()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s}}).then(()=>{r((0,i.__)("Settings saved.","zenpress"))}).catch(()=>{p((0,i.__)("Failed to save settings.","zenpress"))}).finally(()=>a(!1))},isSaving:t}})(),[_,w]=(0,n.useState)(new Set), v=e=>{s(s=>{const t={},n=new Set(_);return Object.entries(s).forEach(([s,a])=>{const r=(Array.isArray(a?.preset)?a.preset:[]).includes(e);t[s]={...a,"enable-snippet":r},r&&n.add(a.category||(0,i.__)("Uncategorized","zenpress"))}),w(n),t})},x={};Object.keys(e).forEach(s=>{const t=e[s],n=t?.category||(0,i.__)("Uncategorized","zenpress");x[n]||(x[n]=[]),x[n].push({name:s,data:t})});const j=Object.keys(x).sort((e,s)=>e.localeCompare(s,void 0,{sensitivity:"base"}));return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)("div",{className:"zenpress-row",children:(0,p.jsxs)("div",{className:"zenpress-col",children:[(0,p.jsxs)("div",{className:"zenpress-presets",children:[(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("p",{children:(0,i.__)("Select the features that suit your needs. If you don't know which ones to choose, just select your site's type and it will set the right features for you.","zenpress")}),(0,p.jsx)("h2",{children:(0,i.__)("Pick a preset","zenpress")})]}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>v("showcase-website"),__next40pxDefaultSize:!0,children:(0,i.__)("Showcase website","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>v("blog"),__next40pxDefaultSize:!0,children:(0,i.__)("Blog","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>v("ecommerce"),__next40pxDefaultSize:!0,children:(0,i.__)("E-commerce","zenpress")}),(0,p.jsx)("div",{className:"zenpress-presets-description",children:(0,p.jsx)("h2",{children:(0,i.__)("Or just enable what you need","zenpress")})}),(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s}),w(new Set(Object.values(e).map(e=>e.category||(0,i.__)("Uncategorized","zenpress"))))},__next40pxDefaultSize:!0,children:(0,i.__)("Enable all actions","zenpress")}),(0,p.jsx)(a.Button,{isDestructive:"true",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,i.__)("Disable all actions","zenpress")})]})]}),j.map(e=>(0,p.jsx)(a.Panel,{children:(0,p.jsx)(a.PanelBody,{title:e,initialOpen:_.has(e)||x[e].some(({data:e})=>e?.["enable-snippet"]),children:x[e].map(({name:e,data:t})=>(0,p.jsx)(a.PanelRow,{children:(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""})},e))})},e)),(0,p.jsx)("div",{className:"zenpress-actions",children:(0,p.jsx)(h,{onClick:t,isBusy:r})}),(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(u,{})})]})})})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(_,{}))})})();1 (()=>{"use strict";var e={n:s=>{var t=s&&s.__esModule?()=>s.default:()=>s;return e.d(t,{a:t}),t},d:(s,t)=>{for(var n in t)e.o(t,n)&&!e.o(s,n)&&Object.defineProperty(s,n,{enumerable:!0,get:t[n]})},o:(e,s)=>Object.prototype.hasOwnProperty.call(e,s)};const s=window.wp.domReady;var t=e.n(s);const n=window.wp.element,i=window.wp.i18n,a=window.wp.components,r=window.wp.apiFetch;var c=e.n(r);const o=window.wp.data,l=window.wp.notices,p=window.ReactJSXRuntime,d=({label:e,value:s,onChange:t,help:n})=>(0,p.jsx)(a.ToggleControl,{label:e,checked:s,onChange:t,help:n,__nextHasNoMarginBottom:!0}),h=({onClick:e,isBusy:s})=>(0,p.jsx)(a.Button,{variant:"primary",onClick:e,isBusy:s,__next40pxDefaultSize:!0,children:(0,i.__)("Save settings","zenpress")}),u=()=>{const{removeNotice:e}=(0,o.useDispatch)(l.store),s=(0,o.useSelect)(e=>e(l.store).getNotices());return s?.length?(0,p.jsx)(a.NoticeList,{notices:s,onRemove:e}):null},_=()=>{const{snippets:e,setSnippets:s,saveSettings:t,isSaving:r}=(()=>{const[e,s]=(0,n.useState)({}),[t,a]=(0,n.useState)(!1),{createSuccessNotice:r,createErrorNotice:p}=(0,o.useDispatch)(l.store);return(0,n.useEffect)(()=>{c()({path:"/wp/v2/settings"}).then(e=>{const t=Array.isArray(e?.zenpress_active_snippets)?e.zenpress_active_snippets:[],n={},i=window?.zenpressSnippetsMeta||{};Object.keys(i).forEach(e=>{const s=i[e]||{};n[e]={...s,"enable-snippet":t.includes(e)}}),s(n)}).catch(()=>{p((0,i.__)("Failed to load settings.","zenpress"))})},[p]),{snippets:e,setSnippets:s,saveSettings:()=>{a(!0);const s=Object.keys(e).filter(s=>e[s]?.["enable-snippet"]||!1);return c()({path:"/wp/v2/settings",method:"POST",data:{zenpress_active_snippets:s}}).then(()=>{r((0,i.__)("Settings saved.","zenpress"))}).catch(()=>{p((0,i.__)("Failed to save settings.","zenpress"))}).finally(()=>a(!1))},isSaving:t}})(),[_,w]=(0,n.useState)(new Set),x=e=>{s(s=>{const t={};return Object.entries(s).forEach(([s,n])=>{const i=(Array.isArray(n?.preset)?n.preset:[]).includes(e);t[s]={...n,"enable-snippet":i}}),t}),w(new Set(j))},v={};Object.keys(e).forEach(s=>{const t=e[s],n=t?.category||(0,i.__)("Uncategorized","zenpress");v[n]||(v[n]=[]),v[n].push({name:s,data:t})});const j=Object.keys(v).sort((e,s)=>e.localeCompare(s,void 0,{sensitivity:"base"}));return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)("div",{className:"zenpress-row",children:(0,p.jsxs)("div",{className:"zenpress-col",children:[(0,p.jsxs)("div",{className:"zenpress-presets",children:[(0,p.jsxs)("div",{className:"zenpress-presets-description",children:[(0,p.jsx)("p",{children:(0,i.__)("Select the features that suit your needs. If you don't know which ones to choose, just select your site's type and it will set the right features for you.","zenpress")}),(0,p.jsx)("h2",{children:(0,i.__)("Pick a preset","zenpress")})]}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>x("showcase-website"),__next40pxDefaultSize:!0,children:(0,i.__)("Showcase website","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>x("blog"),__next40pxDefaultSize:!0,children:(0,i.__)("Blog","zenpress")}),(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>x("ecommerce"),__next40pxDefaultSize:!0,children:(0,i.__)("E-commerce","zenpress")}),(0,p.jsx)("div",{className:"zenpress-presets-description",children:(0,p.jsx)("h2",{children:(0,i.__)("Or just enable what you need","zenpress")})}),(0,p.jsxs)("div",{className:"zenpress-actions-bulk",children:[(0,p.jsx)(a.Button,{variant:"secondary",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!0}}),s}),w(new Set(j))},__next40pxDefaultSize:!0,children:(0,i.__)("Enable all actions","zenpress")}),(0,p.jsx)(a.Button,{isDestructive:"true",onClick:()=>{s(e=>{const s={};return Object.keys(e).forEach(t=>{s[t]={...e[t],"enable-snippet":!1}}),s})},__next40pxDefaultSize:!0,children:(0,i.__)("Disable all actions","zenpress")})]})]}),j.map(e=>(0,p.jsx)(a.Panel,{children:(0,p.jsx)(a.PanelBody,{title:e,initialOpen:_.has(e),children:v[e].map(({name:e,data:t})=>(0,p.jsx)(a.PanelRow,{children:(0,p.jsx)(d,{label:t.title||e,value:t?.["enable-snippet"]||!1,onChange:()=>{return t=e,void s(e=>({...e,[t]:{...e[t],"enable-snippet":!e[t]?.["enable-snippet"]}}));var t},help:t.description||""})},e))})},e)),(0,p.jsx)("div",{className:"zenpress-actions",children:(0,p.jsx)(h,{onClick:t,isBusy:r})}),(0,p.jsx)("div",{className:"zenpress-notices",children:(0,p.jsx)(u,{})})]})})})};t()(()=>{const e=document.getElementById("zenpress-settings");e&&(0,n.createRoot)(e).render((0,p.jsx)(_,{}))})})(); -
zenpress/trunk/assets/src/index.js
r3352459 r3355428 176 176 }); 177 177 // Open all categories 178 setOpenCategories(new Set( Object.values(snippets).map((s) => s.category || __('Uncategorized', 'zenpress'))));178 setOpenCategories(new Set(sortedCategories)); 179 179 }; 180 180 … … 192 192 return updated; 193 193 }); 194 // Keep categories open (do not clear)195 194 }; 196 195 197 196 /** 198 197 * Enable snippets by preset. 199 *200 * All snippets not in the preset will be disabled.201 198 * 202 199 * @param {string} preset - Preset key to enable. … … 206 203 setSnippets((prev) => { 207 204 const updated = {}; 208 const newOpen = new Set(openCategories);209 205 Object.entries(prev).forEach(([name, data]) => { 210 206 const presets = Array.isArray(data?.preset) ? data.preset : []; … … 214 210 'enable-snippet': isEnabled, 215 211 }; 216 if (isEnabled) {217 newOpen.add(data.category || __('Uncategorized', 'zenpress'));218 }219 212 }); 220 setOpenCategories(newOpen);221 213 return updated; 222 214 }); 215 // Open all categories 216 setOpenCategories(new Set(sortedCategories)); 223 217 }; 224 218 … … 298 292 <PanelBody 299 293 title={category} 300 // Keep open if already marked or if a snippet is enabled 301 initialOpen={ 302 openCategories.has(category) || 303 groupedSnippets[category].some( 304 ({ data }) => data?.['enable-snippet'] 305 ) 306 } 294 initialOpen={openCategories.has(category)} 307 295 > 308 296 {groupedSnippets[category].map(({ name, data }) => ( -
zenpress/trunk/inc/snippets/disable-author-archives.php
r3352459 r3355428 8 8 remove_filter('template_redirect', 'redirect_canonical'); 9 9 10 add_action('template_redirect', function () {10 add_action('template_redirect', static function () { 11 11 if (is_author()) { 12 12 global $wp_query; -
zenpress/trunk/inc/snippets/disable-dashicons.php
r3352459 r3355428 5 5 } 6 6 7 add_action('wp_enqueue_scripts', function () {7 add_action('wp_enqueue_scripts', static function () { 8 8 if (!is_user_logged_in()) { 9 9 wp_dequeue_style('dashicons'); -
zenpress/trunk/inc/snippets/disable-emoji-scripts.php
r3352459 r3355428 22 22 23 23 // Remove emoji support from TinyMCE editor. 24 add_filter('tiny_mce_plugins', function ($plugins) {24 add_filter('tiny_mce_plugins', static function ($plugins) { 25 25 return array_diff($plugins, ['wpemoji']); 26 26 }); -
zenpress/trunk/inc/snippets/disable-jquery-migrate.php
r3352459 r3355428 5 5 } 6 6 7 add_action('wp_default_scripts', function (&$scripts) {7 add_action('wp_default_scripts', static function (&$scripts) { 8 8 if (!is_admin() && isset($scripts->registered['jquery'])) { 9 9 $script = $scripts->registered['jquery']; -
zenpress/trunk/inc/snippets/disable-oembed.php
r3352459 r3355428 5 5 } 6 6 7 add_action('init', 'zenpress_disable_oembed'); 8 function zenpress_disable_oembed() { 7 add_action('init', static function () { 9 8 // Remove oEmbed from query vars. 10 9 global $wp; … … 45 44 wp_deregister_script('wp-embed'); 46 45 } 47 } 46 }); -
zenpress/trunk/inc/snippets/disable-pdf-thumbnails.php
r3352459 r3355428 5 5 } 6 6 7 add_filter('fallback_intermediate_image_sizes', function () {7 add_filter('fallback_intermediate_image_sizes', static function () { 8 8 return []; 9 9 }); -
zenpress/trunk/inc/snippets/disable-pingback-trackback.php
r3352459 r3355428 6 6 7 7 // Remove X-Pingback header from HTTP responses. 8 add_filter('wp_headers', function ($headers) {8 add_filter('wp_headers', static function ($headers) { 9 9 unset($headers['X-Pingback']); 10 10 … … 13 13 14 14 // Disable pingbacks and trackbacks for new posts. 15 add_action('after_setup_theme', function () {15 add_action('after_setup_theme', static function () { 16 16 update_option('default_ping_status', 'closed'); 17 17 update_option('default_pingback_flag', 0); … … 19 19 20 20 // Prevent self-pingbacks. 21 add_action('pre_ping', function (&$links) {21 add_action('pre_ping', static function (&$links) { 22 22 $home = get_option('home'); 23 23 foreach ($links as $l => $link) { -
zenpress/trunk/inc/snippets/disable-woocommerce-cart-fragments.php
r3352459 r3355428 5 5 } 6 6 7 add_action('wp_enqueue_scripts', 'zenpress_disable_cart_fragments', 11); 8 9 function zenpress_disable_cart_fragments() { 10 if (class_exists('WooCommerce')) { 7 if (class_exists('WooCommerce')) { 8 add_action('wp_enqueue_scripts', static function () { 11 9 wp_dequeue_script('wc-cart-fragments'); 12 } 10 }, 11); 13 11 } -
zenpress/trunk/inc/snippets/disable-woocommerce-scripts-styles.php
r3352459 r3355428 1 1 <?php 2 2 3 add_action('wp_enqueue_scripts', 'zenpress_disable_woocommerce_scripts_styles', 11); 3 if (!defined('ABSPATH')) { 4 exit; 5 } 4 6 5 function zenpress_disable_woocommerce_scripts_styles() { 6 if (!class_exists('WooCommerce')) { 7 return; 8 } 7 if (class_exists('WooCommerce')) { 8 add_action('wp_enqueue_scripts', static function () { 9 if (!is_woocommerce() && !is_cart() && !is_checkout() && !is_account_page() && !is_product() && !is_product_category() && !is_shop()) { 10 // Dequeue WooCommerce Styles 11 wp_dequeue_style('woocommerce-general'); 12 wp_dequeue_style('woocommerce-layout'); 13 wp_dequeue_style('woocommerce-smallscreen'); 14 wp_dequeue_style('woocommerce_frontend_styles'); 15 wp_dequeue_style('woocommerce_fancybox_styles'); 16 wp_dequeue_style('woocommerce_chosen_styles'); 17 wp_dequeue_style('woocommerce_prettyPhoto_css'); 9 18 10 if (!is_woocommerce() && !is_cart() && !is_checkout() && !is_account_page() && !is_product() && !is_product_category() && !is_shop()) { 11 // Dequeue WooCommerce Styles 12 wp_dequeue_style('woocommerce-general'); 13 wp_dequeue_style('woocommerce-layout'); 14 wp_dequeue_style('woocommerce-smallscreen'); 15 wp_dequeue_style('woocommerce_frontend_styles'); 16 wp_dequeue_style('woocommerce_fancybox_styles'); 17 wp_dequeue_style('woocommerce_chosen_styles'); 18 wp_dequeue_style('woocommerce_prettyPhoto_css'); 19 20 // Dequeue WooCommerce Scripts 21 wp_dequeue_script('wc-price-slider'); 22 wp_dequeue_script('wc-single-product'); 23 wp_dequeue_script('wc-add-to-cart'); 24 wp_dequeue_script('wc-checkout'); 25 wp_dequeue_script('wc-add-to-cart-variation'); 26 wp_dequeue_script('wc-cart'); 27 wp_dequeue_script('wc-chosen'); 28 wp_dequeue_script('woocommerce'); 29 wp_dequeue_script('prettyPhoto'); 30 wp_dequeue_script('prettyPhoto-init'); 31 wp_dequeue_script('jquery-blockui'); 32 wp_dequeue_script('jquery-placeholder'); 33 wp_dequeue_script('fancybox'); 34 wp_dequeue_script('jqueryui'); 35 } 19 // Dequeue WooCommerce Scripts 20 wp_dequeue_script('wc-price-slider'); 21 wp_dequeue_script('wc-single-product'); 22 wp_dequeue_script('wc-add-to-cart'); 23 wp_dequeue_script('wc-checkout'); 24 wp_dequeue_script('wc-add-to-cart-variation'); 25 wp_dequeue_script('wc-cart'); 26 wp_dequeue_script('wc-chosen'); 27 wp_dequeue_script('woocommerce'); 28 wp_dequeue_script('prettyPhoto'); 29 wp_dequeue_script('prettyPhoto-init'); 30 wp_dequeue_script('jquery-blockui'); 31 wp_dequeue_script('jquery-placeholder'); 32 wp_dequeue_script('fancybox'); 33 wp_dequeue_script('jqueryui'); 34 } 35 }, 11); 36 36 } -
zenpress/trunk/inc/snippets/disable-woocommerce-widgets.php
r3352459 r3355428 6 6 7 7 if (class_exists('WooCommerce')) { 8 add_action('widgets_init', 'zenpress_disable_woocommerce_widgets', 99); 9 10 function zenpress_disable_woocommerce_widgets() { 8 add_action('widgets_init', static function() { 11 9 unregister_widget('WC_Widget_Products'); 12 10 unregister_widget('WC_Widget_Product_Categories'); … … 21 19 unregister_widget('WC_Widget_Top_Rated_Products'); 22 20 unregister_widget('WC_Widget_Rating_Filter'); 23 } 21 }, 99); 24 22 } -
zenpress/trunk/inc/snippets/hide-woocommerce-version.php
r3352459 r3355428 7 7 if (class_exists('WooCommerce') && !is_admin()) { 8 8 // Remove WooCommerce version from HTTP headers 9 add_filter('wp_headers', 'zenpress_remove_woocommerce_version'); 10 function zenpress_remove_woocommerce_version($headers) { 9 add_filter('wp_headers', static function ($headers) { 11 10 if (isset($headers['X-WooCommerce-Version'])) { 12 11 unset($headers['X-WooCommerce-Version']); … … 14 13 15 14 return $headers; 16 } 15 }); 17 16 18 // Remove WooCommerce version from script and style URLs 19 add_filter('style_loader_src', 'zenpress_remove_woocommerce_version_scripts_styles', 10); 20 add_filter('script_loader_src', 'zenpress_remove_woocommerce_version_scripts_styles', 10); 21 function zenpress_remove_woocommerce_version_scripts_styles($src) { 17 // Remove WooCommerce version from style URLs 18 add_filter('style_loader_src', static function ($src) { 22 19 if (strpos($src, 'ver=') !== false && strpos($src, 'woocommerce') !== false) { 23 20 $src = remove_query_arg('ver', $src); … … 25 22 26 23 return $src; 27 } 24 }, 10); 25 26 // Remove WooCommerce version from script URLs 27 add_filter('script_loader_src', static function ($src) { 28 if (strpos($src, 'ver=') !== false && strpos($src, 'woocommerce') !== false) { 29 $src = remove_query_arg('ver', $src); 30 } 31 32 return $src; 33 }, 10); 28 34 } -
zenpress/trunk/inc/snippets/hide-wordpress-version.php
r3352459 r3355428 9 9 10 10 // Remove WordPress version from generator 11 add_filter('the_generator', 'zenpress_remove_wordpress_version'); 12 function zenpress_remove_wordpress_version() { 11 add_filter('the_generator', static function () { 13 12 return ''; 14 } 13 }); 15 14 16 // Remove WordPress version from script and style URLs 17 add_filter('style_loader_src', 'zenpress_remove_version_from_assets'); 18 add_filter('script_loader_src', 'zenpress_remove_version_from_assets'); 19 function zenpress_remove_version_from_assets($src) { 15 // Remove WordPress version from script URLs 16 add_filter('script_loader_src', static function ($src) { 20 17 if (strpos($src, 'ver=' . get_bloginfo('version')) !== false) { 21 18 $src = remove_query_arg('ver', $src); … … 23 20 24 21 return $src; 25 } 22 }); 23 24 // Remove WordPress version from style URLs 25 add_filter('style_loader_src', static function ($src) { 26 if (strpos($src, 'ver=' . get_bloginfo('version')) !== false) { 27 $src = remove_query_arg('ver', $src); 28 } 29 30 return $src; 31 }); -
zenpress/trunk/inc/snippets/protect-wp-login.php
r3352459 r3355428 6 6 7 7 // Remove detailed login errors 8 add_filter('login_errors', function () {8 add_filter('login_errors', static function () { 9 9 return __('Login error.', 'zenpress'); 10 10 }); 11 11 12 12 // Limit login attempts 13 add_filter('authenticate', 'zenpress_login_protection', 30, 3); 14 function zenpress_login_protection(mixed $user, string $username, string $password): mixed { 13 add_filter('authenticate', static function (mixed $user, string $username, string $password): mixed { 15 14 $MAX_LOGIN_ATTEMPTS = 5; 16 15 $BLOCK_DURATION = 300; // 5 minutes … … 55 54 56 55 return $user; 57 } 56 }, 30, 3); -
zenpress/trunk/inc/snippets/remove-gutenberg-unwanted-block-patterns.php
r3352459 r3355428 9 9 10 10 // Remove core block patterns 11 add_action('after_setup_theme', 'zenpress_remove_core_block_patterns'); 12 function zenpress_remove_core_block_patterns() { 11 add_action('after_setup_theme', static function () { 13 12 remove_theme_support('core-block-patterns'); 14 } 13 }); -
zenpress/trunk/inc/snippets/remove-woocommerce-patterns.php
r3352459 r3355428 7 7 use Automattic\WooCommerce\Blocks\Package; 8 8 9 add_action('woocommerce_blocks_loaded', 'zenpress_remove_wc_patterns'); 10 function zenpress_remove_wc_patterns(): void { 9 add_action('woocommerce_blocks_loaded', static function (): void { 11 10 remove_action( 12 11 'init', … … 16 15 ] 17 16 ); 18 } 17 }); -
zenpress/trunk/readme.txt
r3352462 r3355428 1 === ZenPress ===1 === ZenPress — Cleaner, Lighter, Faster WP === 2 2 Contributors: @quentinldd 3 3 Donate link: https://github.com/sponsors/quentin-ld/ … … 5 5 Requires at least: 6.0 6 6 Tested up to: 6.8 7 Stable tag: 2.0. 17 Stable tag: 2.0.2 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 14 14 == Description == 15 15 16 ZenPress is a lightweight, super-fast plugin that boosts your WordPress & WooCommerce website through a wide range of solid actions. This is a simple solution for improving your WordPress website's performance and security while enjoying a simpler and lighter UI. 16 ZenPress is a lightweight, super-fast plugin that boosts your WordPress & WooCommerce website through a wide range of solid actions. 17 This is a simple solution for improving your WordPress website's performance and security while enjoying a simpler and lighter UI. 17 18 No database clutter, no ads, no pro version. Just install, activate, select what you need or pick up your settings preset and you are ready to go ! 18 19 … … 74 75 * Remove WooCommerce default remote block patterns 75 76 77 == Roadmap == 78 79 = Global = 80 * New presets 81 82 = Security = 83 * Disable Application Passwords 84 * Manage Heartbeat API (frontend + backend + admin whitelist) 85 * Disable REST API 86 87 = Performance = 88 * Disable capital_P_dangit filter 89 * Disable autosave 90 * Disable post revision 91 * Disable native lazy loading 92 * Disable Password Strength Meter 93 * Disable WordPress default lazy loading 94 95 = UI = 96 * Remove "howdy" from admin bar 97 * Remove WordPress logo 98 * Remove "Help button" 99 * Remove "Thanks for using WordPress" in footer 100 * Remove "site health" page 101 * Remove "Privacy tools" 102 103 = WooCommerce = 104 * Disable WooCommerce tracking 105 * Disable marketing hub 106 * Disable dashboard setup widget 107 * Disable new product editor 108 * Disable WooCommerce blocks 109 * Disable WooCommerce promo emails 110 111 = Plugins = 112 * Disable CF7 CSS & JS 113 * Disable Elementor bloat 114 * Disable WP Bakery bloat 115 * Disable Divi bloat 116 * Disable Yoast SEO bloat 117 * Disable Jetpack bloat 118 * Disable Updraft bloat 119 120 == Privacy Statement == 121 122 ZenPress is private by default and always will be. It does not store any data. It does not send data to any third party, nor does it include any third party resources. 123 124 == Accessibility Statement == 125 126 ZenPress aims to be fully accessible to all of its users. 127 76 128 == Screenshots == 77 129 78 130 1. ZenPress admin interface. 79 1. Dashboard without ZenPress. 80 2. Dashboard with ZenPress. 81 3. Site editor without ZenPress. 82 4. Site editor with ZenPress. 83 5. Login page without ZenPress login protection. 84 6. Login page with ZenPress login protection. 85 7. Login page with ZenPress login protection after trying to brute force it. 86 8. Website head without ZenPress. 87 9. Website head with ZenPress. 88 89 == Privacy Statement == 90 91 ZenPress is private by default and always will be. It does not store any data. It does not send data to any third party, nor does it include any third party resources. 92 93 == Accessibility Statement == 94 95 ZenPress aims to be fully accessible to all of its users. 131 2. Dashboard without ZenPress. 132 3. Dashboard with ZenPress. 133 4. Site editor without ZenPress. 134 5. Site editor with ZenPress. 135 6. Login page without ZenPress login protection. 136 7. Login page with ZenPress login protection. 137 8. Login page with ZenPress login protection after trying to brute force it. 138 9. Website head without ZenPress. 139 10. Website head with ZenPress. 96 140 97 141 == Frequently Asked Questions == … … 101 145 Yes, there is no pro version for this plugin and there never will be. 102 146 103 However, I am accepting donations on my buymeacoffee page : https://buymeacoffee.com/quentinld. If you work at an agency that develops with WordPress, ask your company to provide sponsorship in order to invest in its supply chain. The tools that I maintain probably save your company time and money, and Buy me a coffee supportcan now be done at the organisation level.104 105 In addition, if you like the plugin then I'd love for you to leave a review. Tell all your friends about it too!147 However, [I am accepting sponsorships via the GitHub Sponsors program](https://github.com/sponsors/quentin-ld/dashboard). If you work at an agency that develops with WordPress, ask your company to provide sponsorship in order to invest in its supply chain. The tools that I maintain probably save your company time and money, and GitHub sponsorship can now be done at the organisation level. 148 149 In addition, if you like the plugin then I'd love for you to [leave a review](https://wordpress.org/support/plugin/zenpress/reviews/). Tell all your friends about it too! 106 150 107 151 = I have a suggestion = … … 114 158 115 159 == Changelog == 160 161 = 2.0.2 = 162 163 - Global : Codebase and snippets optimization 164 - Global : Fixed a bug in the automatic opening and closing function of the panels on the settings page. 116 165 117 166 = 2.0.1 = -
zenpress/trunk/zenpress.php
r3352462 r3355428 10 10 * @license GPL v2 or later 11 11 * 12 * Plugin Name: ZenPress 12 * Plugin Name: ZenPress — Cleaner, Lighter, Faster WP 13 13 * Description: Easily speed up and strengthen your WordPress site by cleaning out unnecessary features and protecting weak points. 14 * Version: 2.0. 114 * Version: 2.0.2 15 15 * Plugin URI: https://wordpress.org/plugins/zenpress/ 16 16 * Author: Quentin Le Duff … … 31 31 * This program is distributed in the hope that it will be useful, 32 32 * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 34 * GNU General Public License for more details. 35 * 36 */ 37 38 /***** 39 * TODOLIST ▓▒░(°◡°)░▒▓ 40 ****/ 41 // TODO: Disable comments URL 42 // TODO: CHECK THE DEPLOYMENT WORKING PROPERLY 35 */ 43 36 44 37 if (!defined('ABSPATH')) { … … 47 40 48 41 /** 49 * Add settings link on the plugins list page (next to Activate/Deactivate).50 *51 * @param array $links Existing plugin action links.52 * @return array Modified links with Settings link appended at the end.53 */54 function zenpress_add_settings_link(array $links): array {55 $settings_url = admin_url('options-general.php?page=zenpress');56 57 $settings_link = sprintf(58 '<a href="%s" aria-label="%s">%s</a>',59 esc_url($settings_url),60 esc_attr__('Go to ZenPress settings page', 'zenpress'),61 esc_html__('Settings', 'zenpress')62 );63 64 // Add "Settings" link at the end instead of first65 $links[] = $settings_link;66 67 return $links;68 }69 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'zenpress_add_settings_link');70 71 72 /**73 * Add extra links under the plugin description on the plugins page.74 *75 * @param array $links Existing links.76 * @param string $file Current plugin file.77 * @return array Modified links.78 */79 function zenpress_plugin_row_meta($links, $file) {80 if ($file === plugin_basename(__FILE__)) {81 $extra_links = array(82 '<a href="' . esc_url('https://wordpress.org/plugins/zenpress/#developers') . '" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress') . '">' . esc_html__('Changelog', 'zenpress') . '</a>',83 '<a href="' . esc_url('https://holdmywp.com/zenpress/') . '" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__('Read ZenPress documentation (opens in a new tab)', 'zenpress') . '">' . esc_html__('Docs', 'zenpress') . '</a>',84 '<a href="' . esc_url('https://buymeacoffee.com/quentinld') . '" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__('Support ZenPress by buying a coffee (opens in a new tab)', 'zenpress') . '">' . esc_html__('Support ☕', 'zenpress') . '</a>',85 );86 87 $links = array_merge($links, $extra_links);88 }89 90 return $links;91 }92 add_filter('plugin_row_meta', 'zenpress_plugin_row_meta', 10, 2);93 94 95 96 /**97 42 * Enqueue scripts and styles used by the plugin in admin area. 98 43 * … … 100 45 * @return void 101 46 */ 47 add_action('admin_enqueue_scripts', 'zenpress_admin_enqueue_scripts'); 102 48 function zenpress_admin_enqueue_scripts(string $admin_page): void { 103 if ( $admin_page !== 'settings_page_zenpress') {49 if ('settings_page_zenpress' !== $admin_page) { 104 50 return; 105 51 } 106 52 107 53 $asset_file = plugin_dir_path(__FILE__) . 'assets/build/index.asset.php'; 108 if (! is_file($asset_file)) {54 if (!file_exists($asset_file)) { 109 55 return; 110 56 } 111 57 112 /** @var mixed $asset */113 58 $asset = include $asset_file; 114 115 if (!is_array($asset) || empty($asset['dependencies']) || empty($asset['version'])) {116 return;117 }118 119 $dependencies = array_map('sanitize_key', (array) $asset['dependencies']);120 $version = sanitize_text_field((string) $asset['version']);121 122 59 wp_enqueue_script( 123 60 'zenpress-scripts', 124 61 plugins_url('assets/build/index.js', __FILE__), 125 $ dependencies,126 $ version,62 $asset['dependencies'], 63 $asset['version'], 127 64 true 128 65 ); … … 132 69 plugins_url('assets/build/index.css', __FILE__), 133 70 array_filter( 134 $dependencies, 135 static fn($style) => is_string($style) && wp_style_is($style, 'registered') 71 $asset['dependencies'], 72 function ($style) { 73 return wp_style_is($style, 'registered'); 74 } 136 75 ), 137 $version 138 ); 139 } 140 add_action('admin_enqueue_scripts', 'zenpress_admin_enqueue_scripts'); 76 $asset['version'] 77 ); 78 } 79 80 /** 81 * Localize translated snippet metadata for use in JavaScript. 82 * 83 * @param string $admin_page Current admin page hook. 84 * @return void 85 */ 86 add_action('admin_enqueue_scripts', 'zenpress_localize_snippets_meta'); 87 function zenpress_localize_snippets_meta(string $admin_page): void { 88 if ('settings_page_zenpress' !== $admin_page) { 89 return; 90 } 91 92 $snippets = []; 93 $snippets_path = plugin_dir_path(__FILE__) . 'inc/snippets/'; 94 if (!is_dir($snippets_path)) { 95 return; 96 } 97 98 foreach (glob($snippets_path . '*.php') as $file) { 99 $basename = basename($file, '.php'); 100 $snippets[$basename] = zenpress_extract_snippet_metadata($basename); 101 } 102 103 wp_localize_script('zenpress-scripts', 'zenpressSnippetsMeta', $snippets); 104 } 105 106 /** 107 * Add a settings link on the plugins list page. 108 * 109 * @param array $links Existing plugin action links. 110 * @return array Modified plugin action links. 111 */ 112 add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'zenpress_add_settings_link'); 113 function zenpress_add_settings_link(array $links): array { 114 $url = admin_url('options-general.php?page=zenpress'); 115 $links[] = sprintf( 116 '<a href="%s" aria-label="%s">%s</a>', 117 esc_url($url), 118 esc_attr__('Go to ZenPress settings page', 'zenpress'), 119 esc_html__('Settings', 'zenpress') 120 ); 121 return $links; 122 } 123 124 /** 125 * Add extra links under the plugin description on the plugins page. 126 * 127 * @param array $links Existing row meta links. 128 * @param string $file Current plugin file. 129 * @return array Modified row meta links. 130 */ 131 add_filter('plugin_row_meta', 'zenpress_plugin_row_meta', 10, 2); 132 function zenpress_plugin_row_meta(array $links, string $file): array { 133 if ($file === plugin_basename(__FILE__)) { 134 $extra_links = array( 135 sprintf( 136 '<a href="%s" target="_blank" rel="noopener noreferrer" aria-label="%s">%s</a>', 137 esc_url('https://wordpress.org/plugins/zenpress/#developers'), 138 esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress'), 139 esc_html__('Changelog', 'zenpress') 140 ), 141 sprintf( 142 '<a href="%s" target="_blank" rel="noopener noreferrer" aria-label="%s">%s</a>', 143 esc_url('https://holdmywp.com/zenpress/'), 144 esc_attr__('Read ZenPress documentation (opens in a new tab)', 'zenpress'), 145 esc_html__('Docs', 'zenpress') 146 ), 147 sprintf( 148 '<a href="%s" target="_blank" rel="noopener noreferrer" aria-label="%s">%s</a>', 149 esc_url('https://buymeacoffee.com/quentinld'), 150 esc_attr__('Support ZenPress by buying a coffee (opens in a new tab)', 'zenpress'), 151 esc_html__('Support ☕', 'zenpress') 152 ) 153 ); 154 $links = array_merge($links, $extra_links); 155 } 156 return $links; 157 } 141 158 142 159 /** … … 145 162 * @return void 146 163 */ 164 add_action('admin_menu', 'zenpress_add_option_page'); 147 165 function zenpress_add_option_page(): void { 148 166 add_options_page( … … 154 172 ); 155 173 } 156 add_action('admin_menu', 'zenpress_add_option_page');157 174 158 175 /** … … 162 179 */ 163 180 function zenpress_options_page(): void { 164 $plugin_data = get_file_data(__FILE__, ['Version' => 'Version'], 'plugin');165 $plugin_version = $plugin_data['Version'] ?? '';181 $plugin_data = get_file_data(__FILE__, ['Version' => 'Version'], 'plugin'); 182 $plugin_version = $plugin_data['Version'] ?? ''; 166 183 ?> 167 184 <div class="wrap zenpress-dashboard-wrap"> 168 185 <div class="zenpress-header"> 169 186 <div class="zenpress-header-title"> 170 <h1> 171 <?php echo esc_html__('ZenPress', 'zenpress'); ?> 172 </h1> 173 <?php if ($plugin_version) : ?> 174 <p class="zenpress-plugin-version"> 175 <?php echo esc_html__('Version', 'zenpress') . ' ' . esc_html($plugin_version) . ' - '; ?> 176 <a href="https://wordpress.org/plugins/zenpress/#developers" 177 target="_blank" 178 rel="noopener noreferrer" 179 aria-label="<?php echo esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 180 <?php echo esc_html__('What\'s new ?', 'zenpress'); ?> 181 </a> 182 </p> 183 <?php endif; ?> 184 </div> 185 <div class="zenpress-header-navigation"> 186 <a href="https://holdmywp.com/zenpress/" 187 target="_blank" 188 rel="noopener noreferrer" 189 aria-label="<?php echo esc_attr__('Read the ZenPress documentation (opens in a new tab)', 'zenpress'); ?>"> 190 <?php echo esc_html__('Documentation', 'zenpress'); ?> 191 </a> 192 193 <a href="https://wordpress.org/plugins/zenpress/#reviews" 194 target="_blank" 195 rel="noopener noreferrer" 196 aria-label="<?php echo esc_attr__('Leave a review for ZenPress on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 197 <?php echo esc_html__('Leave a review (helps a lot)', 'zenpress'); ?> 198 </a> 199 200 <a href="https://buymeacoffee.com/quentinld" 201 target="_blank" 202 rel="noopener noreferrer" 203 class="components-button is-next-40px-default-size is-tertiary" 204 aria-label="<?php echo esc_attr__('Support development: Buy me a coffee (opens in a new tab)', 'zenpress'); ?>"> 205 <?php echo esc_html__('Buy me a coffee', 'zenpress'); ?> <span aria-hidden="true">☕</span> 206 </a> 207 </div> 187 <h1><?php echo esc_html__('ZenPress', 'zenpress'); ?></h1> 188 <?php if ($plugin_version) : ?> 189 <p class="zenpress-plugin-version"> 190 <?php echo esc_html__('Version', 'zenpress') . ' ' . esc_html($plugin_version) . ' - '; ?> 191 <a href="https://wordpress.org/plugins/zenpress/#developers" 192 target="_blank" 193 rel="noopener noreferrer" 194 aria-label="<?php echo esc_attr__('View ZenPress changelog on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 195 <?php echo esc_html__('What\'s new ?', 'zenpress'); ?> 196 </a> 197 </p> 198 <?php endif; ?> 199 </div> 200 <div class="zenpress-header-navigation"> 201 <a href="https://holdmywp.com/zenpress/" 202 target="_blank" 203 rel="noopener noreferrer" 204 aria-label="<?php echo esc_attr__('Read the ZenPress documentation (opens in a new tab)', 'zenpress'); ?>"> 205 <?php echo esc_html__('Documentation', 'zenpress'); ?> 206 </a> 207 <a href="https://wordpress.org/plugins/zenpress/#reviews" 208 target="_blank" 209 rel="noopener noreferrer" 210 aria-label="<?php echo esc_attr__('Leave a review for ZenPress on WordPress.org (opens in a new tab)', 'zenpress'); ?>"> 211 <?php echo esc_html__('Leave a review (helps a lot)', 'zenpress'); ?> 212 </a> 213 <a href="https://buymeacoffee.com/quentinld" 214 target="_blank" 215 rel="noopener noreferrer" 216 class="components-button is-next-40px-default-size is-tertiary" 217 aria-label="<?php echo esc_attr__('Support development: Buy me a coffee (opens in a new tab)', 'zenpress'); ?>"> 218 <?php echo esc_html__('Buy me a coffee', 'zenpress'); ?> <span aria-hidden="true">☕</span> 219 </a> 220 </div> 208 221 </div> 209 210 222 <div id="zenpress-settings" class="zenpress-settings"> 211 <div class="zenpress-loading card">212 <div class="zenpress-loading-body">213 <p class="zenpress-loading-text">214 <?php echo esc_html__('Loading your ZenPress settings…', 'zenpress'); ?>215 </p>216 </div>217 </div>223 <div class="zenpress-loading card"> 224 <div class="zenpress-loading-body"> 225 <p class="zenpress-loading-text"> 226 <?php echo esc_html__('Loading your ZenPress settings…', 'zenpress'); ?> 227 </p> 228 </div> 229 </div> 218 230 </div> 219 220 <div class="zenpress-footer"> 221 <div class="zenpress-footer-title"> 231 <div class="zenpress-footer"> 232 <div class="zenpress-footer-title"> 222 233 <p> 223 <?php echo esc_html__('Made ', 'zenpress'); ?>224 <span aria-hidden="true"> x ❤️ </span>225 <?php echo esc_html__(' by Quentin Le Duff - Your WordPress Partner', 'zenpress'); ?>226 </p>227 </div> 228 <div class="zenpress-footer-navigation">229 <a href="https://holdmywp.com/"230 target="_blank"231 rel="noopener noreferrer"232 aria-label="<?php echo esc_attr__('Visite the developper website', 'zenpress'); ?>">233 <?php echo esc_html__('My place', 'zenpress'); ?>234 </a>235 <a href="https://github.com/quentin-ld/zenpress"236 target="_blank"237 rel="noopener noreferrer"238 aria-label="<?php echo esc_attr__('Review the code on Github', 'zenpress'); ?>">239 <?php echo esc_html__('ZenPress code repository', 'zenpress'); ?>240 </a>241 </div>234 <?php echo esc_html__('Made ', 'zenpress'); ?> 235 <span aria-hidden="true"> x ❤️ </span> 236 <?php echo esc_html__(' by Quentin Le Duff - Your WordPress Partner', 'zenpress'); ?> 237 </p> 238 </div> 239 <div class="zenpress-footer-navigation"> 240 <a href="https://holdmywp.com/" 241 target="_blank" 242 rel="noopener noreferrer" 243 aria-label="<?php echo esc_attr__('Visite the developper website', 'zenpress'); ?>"> 244 <?php echo esc_html__('My place', 'zenpress'); ?> 245 </a> 246 <a href="https://github.com/quentin-ld/zenpress" 247 target="_blank" 248 rel="noopener noreferrer" 249 aria-label="<?php echo esc_attr__('Review the code on Github', 'zenpress'); ?>"> 250 <?php echo esc_html__('ZenPress code repository', 'zenpress'); ?> 251 </a> 252 </div> 242 253 </div> 243 254 </div> … … 246 257 247 258 /** 248 * Extract snippet metadata from correspondingmeta file.249 * 250 * @param string $snippet_name Base name of the snippet(without extension).251 * @return array<string,mixed> Metadata array with keys: title, description, category, weight, preset.259 * Extract snippet metadata from its meta file. 260 * 261 * @param string $snippet_name Snippet base name (without extension). 262 * @return array<string,mixed> Sanitized metadata (title, description, category, weight, preset). 252 263 */ 253 264 function zenpress_extract_snippet_metadata(string $snippet_name): array { 254 $ metadata = [265 $defaults = array( 255 266 'title' => '', 256 267 'description' => '', 257 268 'category' => '', 258 269 'weight' => 0, 259 'preset' => [], 260 ]; 261 262 $safe_name = sanitize_file_name($snippet_name); 263 $meta_file = plugin_dir_path(__FILE__) . 'inc/meta/' . $safe_name . '.meta.php'; 264 265 if (is_file($meta_file)) { 266 /** @var mixed $data */ 267 $data = include $meta_file; 268 if (is_array($data)) { 269 $metadata = array_merge($metadata, array_intersect_key($data, $metadata)); 270 } 271 } 272 273 // Sanitize values securely 274 $metadata['title'] = sanitize_text_field($metadata['title']); 275 $metadata['description'] = sanitize_text_field($metadata['description']); 276 $metadata['category'] = sanitize_text_field($metadata['category']); 277 $metadata['weight'] = intval($metadata['weight']); 278 $metadata['preset'] = array_map('sanitize_text_field', (array) $metadata['preset']); 279 280 return $metadata; 281 } 282 283 284 /** 285 * Register a single option to store all active snippets. 286 * 287 * @return void 288 */ 270 'preset' => array() 271 ); 272 273 $file = plugin_dir_path(__FILE__) . 'inc/meta/' . sanitize_file_name($snippet_name) . '.meta.php'; 274 $data = is_file($file) ? include $file : array(); 275 $metadata = array_merge($defaults, is_array($data) ? $data : array()); 276 277 return array( 278 'title' => sanitize_text_field($metadata['title']), 279 'description' => sanitize_text_field($metadata['description']), 280 'category' => sanitize_text_field($metadata['category']), 281 'weight' => (int) $metadata['weight'], 282 'preset' => array_map('sanitize_text_field', (array) $metadata['preset']) 283 ); 284 } 285 286 /** 287 * Register option to store active snippets. 288 */ 289 add_action('init', 'zenpress_register_snippet_settings'); 289 290 function zenpress_register_snippet_settings(): void { 290 291 register_setting( 291 292 'options', 292 293 'zenpress_active_snippets', 293 [294 array( 294 295 'type' => 'array', 295 'default' => [], 296 'sanitize_callback' => static function ($value): array { 297 return array_values(array_filter( 298 array_map('sanitize_file_name', (array) $value) 299 )); 300 }, 301 'show_in_rest' => [ 302 'schema' => [ 296 'default' => array(), 297 'sanitize_callback' => 'zenpress_sanitize_snippets_option', 298 'show_in_rest' => array( 299 'schema' => array( 303 300 'type' => 'array', 304 'items' => [ 'type' => 'string' ], 305 ], 306 ], 307 ] 308 ); 309 } 310 add_action('init', 'zenpress_register_snippet_settings'); 311 312 /** 313 * Load enabled snippets. 314 * 315 * @param string $folder Relative folder where snippets are stored. 316 * @return array<int,string> List of loaded snippet base names. 301 'items' => array('type' => 'string') 302 ) 303 ) 304 ) 305 ); 306 } 307 308 /** 309 * Sanitize the list of active snippets. 310 * 311 * @param mixed $value Option value. 312 * @return array<string> Sanitized base names. 313 */ 314 function zenpress_sanitize_snippets_option($value): array { 315 return array_values( 316 array_filter( 317 array_map('sanitize_file_name', (array) $value) 318 ) 319 ); 320 } 321 322 /** 323 * Load all active snippets. 324 * 325 * @param string $folder Relative folder path for snippets. 326 * @return array<string> Loaded snippet base names. 317 327 */ 318 328 function zenpress_load_snippets(string $folder = 'inc/snippets/'): array { 319 $snippets_path = plugin_dir_path(__FILE__) . rtrim($folder, '/') . '/'; 320 if (!is_dir($snippets_path)) { 321 return []; 322 } 323 324 $active_snippets = get_option('zenpress_active_snippets', []); 325 if (!is_array($active_snippets)) { 326 $active_snippets = []; 327 } 328 329 $loaded = []; 330 foreach ($active_snippets as $base_name) { 331 $safe_name = sanitize_file_name($base_name); 332 $file = $snippets_path . $safe_name . '.php'; 333 $constant_name = 'ZENPRESS_' . strtoupper(str_replace(['-', '_'], '_', $safe_name)); 334 335 if (is_file($file) && (!defined($constant_name) || constant($constant_name) !== false)) { 329 $path = plugin_dir_path(__FILE__) . rtrim($folder, '/') . '/'; 330 331 if (!is_dir($path)) { 332 return array(); 333 } 334 335 $snippets = (array) get_option('zenpress_active_snippets', array()); 336 $loaded = array(); 337 foreach ($snippets as $name) { 338 $name = sanitize_file_name($name); 339 $file = $path . $name . '.php'; 340 $constant = 'ZENPRESS_' . strtoupper(str_replace(array('-', '_'), '_', $name)); 341 if (is_file($file) && (!defined($constant) || constant($constant) !== false)) { 336 342 include_once $file; 337 $loaded[] = $ safe_name;343 $loaded[] = $name; 338 344 } 339 345 } 340 341 346 return $loaded; 342 347 } 343 add_action('init', function () { 344 return zenpress_load_snippets(); 348 349 /** 350 * Boot ZenPress snippets. 351 */ 352 add_action('init', function() : void { 353 zenpress_load_snippets(); 345 354 }); 346 347 /**348 * Localize translated snippet metadata for use in JavaScript.349 *350 * @param string $hook Current admin page hook.351 * @return void352 */353 add_action('admin_enqueue_scripts', static function (string $hook): void {354 if ($hook !== 'settings_page_zenpress') {355 return;356 }357 358 $snippets = [];359 $snippets_path = plugin_dir_path(__FILE__) . 'inc/snippets/';360 if (!is_dir($snippets_path)) {361 return;362 }363 364 foreach (glob($snippets_path . '*.php') ?: [] as $file) {365 $base_name = basename($file, '.php');366 $snippets[$base_name] = zenpress_extract_snippet_metadata($base_name);367 }368 369 wp_localize_script('zenpress-scripts', 'zenpressSnippetsMeta', $snippets);370 });
Note: See TracChangeset
for help on using the changeset viewer.