From 3db051802769e624cfd1ab97bf5a540a0fc9e542 Mon Sep 17 00:00:00 2001 From: WordPress Fan <146129302+wordpressfan@users.noreply.github.com> Date: Fri, 28 Jun 2024 18:11:27 +0300 Subject: [PATCH] Closes #6599 validate image source before saving it into the DB (#6605) Co-authored-by: Gael Robin Co-authored-by: Michael Lee Co-authored-by: Mathieu Lamiot --- assets/js/lcp-beacon.js | 2 +- assets/js/lcp-beacon.min.js | 2 +- assets/js/lcp-beacon.min.js.map | 2 +- .../Media/AboveTheFold/AJAX/Controller.php | 99 +++- .../AJAX/Controller/addLcpData.php | 431 +++++++++++++++++- .../AJAX/Controller/addLcpData.php | 12 +- 6 files changed, 531 insertions(+), 17 deletions(-) diff --git a/assets/js/lcp-beacon.js b/assets/js/lcp-beacon.js index eb74ebfee5..9150860ba3 100644 --- a/assets/js/lcp-beacon.js +++ b/assets/js/lcp-beacon.js @@ -255,7 +255,7 @@ class RocketLcpBeacon { _fillATFWithoutDuplications(elements) { elements.forEach(({ element, elementInfo }) => { - if ( this._isDuplicateImage(element) ) { + if ( this._isDuplicateImage(element) || !elementInfo ) { return; } diff --git a/assets/js/lcp-beacon.min.js b/assets/js/lcp-beacon.min.js index 9695b4792f..1eca46f9ff 100644 --- a/assets/js/lcp-beacon.min.js +++ b/assets/js/lcp-beacon.min.js @@ -1,2 +1,2 @@ -!function n(r,s,o){function c(t,e){if(!s[t]){if(!r[t]){var i="function"==typeof require&&require;if(!e&&i)return i(t,!0);if(a)return a(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}i=s[t]={exports:{}},r[t][0].call(i.exports,function(e){return c(r[t][1][e]||e)},i,i.exports,n,r,s,o)}return s[t].exports}for(var a="function"==typeof require&&require,e=0;e{this._handleInfiniteLoop()},1e4);try{var e=this._generateLcpCandidates(1/0);e&&(this._initWithFirstElementWithInfo(e),this._fillATFWithoutDuplications(e))}catch(e){this.errorCode="script_error",this._logMessage("Script Error: "+e)}this._saveFinalResultIntoDB()}else this._finalize()}async _isValidPreconditions(){return this._isNotValidScreensize()?(this._logMessage("Bailing out because screen size is not acceptable"),!1):!this._isPageCached()||!await this._isGeneratedBefore()||(this._logMessage("Bailing out because data is already available"),!1)}_isPageCached(){var e=document.documentElement.nextSibling&&document.documentElement.nextSibling.data?document.documentElement.nextSibling.data:"";return e&&e.includes("Debug: cached")}async _isGeneratedBefore(){var e=new FormData;return e.append("action","rocket_check_lcp"),e.append("rocket_lcp_nonce",this.config.nonce),e.append("url",this.config.url),e.append("is_mobile",this.config.is_mobile),(e=await fetch(this.config.ajax_url,{method:"POST",credentials:"same-origin",body:e}).then(e=>e.json())).success}_isNotValidScreensize(){var e=window.innerWidth||document.documentElement.clientWidth,t=window.innerHeight||document.documentElement.clientHeight,i=this.config.is_mobile&&(e>this.config.width_threshold||t>this.config.height_threshold),e=!this.config.is_mobile&&(e{if("img"===e.nodeName.toLowerCase()&&"picture"===e.parentElement.nodeName.toLowerCase())return null;let t;if("picture"===e.nodeName.toLowerCase()){var i=e.querySelector("img");if(!i)return null;t=i.getBoundingClientRect()}else t=e.getBoundingClientRect();return{element:e,rect:t}}).filter(e=>null!==e).filter(e=>0({item:e,area:this._getElementArea(e.rect),elementInfo:this._getElementInfo(e.element)})).sort((e,t)=>t.area-e.area).slice(0,e).map(e=>({element:e.item.element,elementInfo:e.elementInfo}))}_isIntersecting(e){return 0<=e.bottom&&0<=e.right&&e.top<=(window.innerHeight||document.documentElement.clientHeight)&&e.left<=(window.innerWidth||document.documentElement.clientWidth)}_getElementArea(e){return Math.min(e.width,(window.innerWidth||document.documentElement.clientWidth)-e.left)*Math.min(e.height,(window.innerHeight||document.documentElement.clientHeight)-e.top)}_getElementInfo(e){var t=e.nodeName.toLowerCase(),i={type:"",src:"",srcset:"",sizes:"",sources:[],bg_set:[],current_src:""};if("img"===t&&e.srcset)i.type="img-srcset",i.src=e.src,i.srcset=e.srcset,i.sizes=e.sizes,i.current_src=e.currentSrc;else if("img"===t)i.type="img",i.src=e.src,i.current_src=e.currentSrc;else if("video"===t){i.type="img";var n=e.querySelector("source");i.src=e.poster||(n?n.src:""),i.current_src=i.src}else if("svg"===t)(n=e.querySelector("image"))&&(i.type="img",i.src=n.getAttribute("href")||"",i.current_src=i.src);else if("picture"===t)i.type="picture",n=e.querySelector("img"),i.src=n?n.src:"",i.sources=Array.from(e.querySelectorAll("source")).map(e=>({srcset:e.srcset||"",media:e.media||"",type:e.type||"",sizes:e.sizes||""}));else{if(0===(t=[window.getComputedStyle(e,null).getPropertyValue("background-image"),getComputedStyle(e,":after").getPropertyValue("background-image"),getComputedStyle(e,":before").getPropertyValue("background-image")].filter(e=>"none"!==e)).length)return null;if(n=t[0],i.type="bg-img",n.includes("image-set(")&&(i.type="bg-img-set"),!n||""===n||n.includes("data:image"))return null;e=[...n.matchAll(/url\(\s*?['"]?\s*?(.+?)\s*?["']?\s*?\)/gi)],i.bg_set=e.map(e=>e[1]?{src:e[1].trim()+(e[2]?" "+e[2].trim():"")}:{}),i.bg_set.every(e=>""===e.src)&&(i.bg_set=e.map(e=>e[1]?{src:e[1].trim()}:{})),0null!==e.elementInfo))?this.performanceImages=[{...e.elementInfo,label:"lcp"}]:(this._logMessage("No LCP candidate found."),this.performanceImages=[])}_fillATFWithoutDuplications(e){e.forEach(e=>{var{element:e,elementInfo:t}=e;this._isDuplicateImage(e)||this.performanceImages.push({...t,label:"above-the-fold"})})}_isDuplicateImage(e){const t=this._getElementInfo(e);var i;return null!==t&&(e="img"===t.type||"img-srcset"===t.type||"video"===t.type,i="bg-img"===t.type||"bg-img-set"===t.type||"picture"===t.type,e||i)&&this.performanceImages.some(e=>e.src===t.src)}_getFinalStatus(){return""!==this.errorCode?this.errorCode:10<=(new Date-this.scriptTimer)/1e3?"timeout":"success"}_saveFinalResultIntoDB(){var e=new FormData;e.append("action","rocket_lcp"),e.append("rocket_lcp_nonce",this.config.nonce),e.append("url",this.config.url),e.append("is_mobile",this.config.is_mobile),e.append("images",JSON.stringify(this.performanceImages)),e.append("status",this._getFinalStatus()),fetch(this.config.ajax_url,{method:"POST",credentials:"same-origin",body:e,headers:{"wpr-saas-no-intercept":!0}}).then(e=>e.json()).then(e=>{this._logMessage(e)}).catch(e=>{this._logMessage(e)}).finally(()=>{this._finalize()})}_handleInfiniteLoop(){this._saveFinalResultIntoDB()}_finalize(){document.querySelector('[data-name="wpr-lcp-beacon"]').setAttribute("beacon-completed","true"),clearTimeout(this.infiniteLoopId)}_logMessage(e){this.config.debug&&console.log(e)}static run(){if(window.rocket_lcp_data){const e=new n(window.rocket_lcp_data);"loading"!==document.readyState?setTimeout(()=>{e.init()},window.rocket_lcp_data.delay):document.addEventListener("DOMContentLoaded",()=>{setTimeout(()=>{e.init()},window.rocket_lcp_data.delay)})}}}).run()},{}]},{},[1]); +!function n(r,s,o){function c(t,e){if(!s[t]){if(!r[t]){var i="function"==typeof require&&require;if(!e&&i)return i(t,!0);if(a)return a(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}i=s[t]={exports:{}},r[t][0].call(i.exports,function(e){return c(r[t][1][e]||e)},i,i.exports,n,r,s,o)}return s[t].exports}for(var a="function"==typeof require&&require,e=0;e{this._handleInfiniteLoop()},1e4);try{var e=this._generateLcpCandidates(1/0);e&&(this._initWithFirstElementWithInfo(e),this._fillATFWithoutDuplications(e))}catch(e){this.errorCode="script_error",this._logMessage("Script Error: "+e)}this._saveFinalResultIntoDB()}else this._finalize()}async _isValidPreconditions(){return this._isNotValidScreensize()?(this._logMessage("Bailing out because screen size is not acceptable"),!1):!this._isPageCached()||!await this._isGeneratedBefore()||(this._logMessage("Bailing out because data is already available"),!1)}_isPageCached(){var e=document.documentElement.nextSibling&&document.documentElement.nextSibling.data?document.documentElement.nextSibling.data:"";return e&&e.includes("Debug: cached")}async _isGeneratedBefore(){var e=new FormData;return e.append("action","rocket_check_lcp"),e.append("rocket_lcp_nonce",this.config.nonce),e.append("url",this.config.url),e.append("is_mobile",this.config.is_mobile),(e=await fetch(this.config.ajax_url,{method:"POST",credentials:"same-origin",body:e}).then(e=>e.json())).success}_isNotValidScreensize(){var e=window.innerWidth||document.documentElement.clientWidth,t=window.innerHeight||document.documentElement.clientHeight,i=this.config.is_mobile&&(e>this.config.width_threshold||t>this.config.height_threshold),e=!this.config.is_mobile&&(e{if("img"===e.nodeName.toLowerCase()&&"picture"===e.parentElement.nodeName.toLowerCase())return null;let t;if("picture"===e.nodeName.toLowerCase()){var i=e.querySelector("img");if(!i)return null;t=i.getBoundingClientRect()}else t=e.getBoundingClientRect();return{element:e,rect:t}}).filter(e=>null!==e).filter(e=>0({item:e,area:this._getElementArea(e.rect),elementInfo:this._getElementInfo(e.element)})).sort((e,t)=>t.area-e.area).slice(0,e).map(e=>({element:e.item.element,elementInfo:e.elementInfo}))}_isIntersecting(e){return 0<=e.bottom&&0<=e.right&&e.top<=(window.innerHeight||document.documentElement.clientHeight)&&e.left<=(window.innerWidth||document.documentElement.clientWidth)}_getElementArea(e){return Math.min(e.width,(window.innerWidth||document.documentElement.clientWidth)-e.left)*Math.min(e.height,(window.innerHeight||document.documentElement.clientHeight)-e.top)}_getElementInfo(e){var t=e.nodeName.toLowerCase(),i={type:"",src:"",srcset:"",sizes:"",sources:[],bg_set:[],current_src:""};if("img"===t&&e.srcset)i.type="img-srcset",i.src=e.src,i.srcset=e.srcset,i.sizes=e.sizes,i.current_src=e.currentSrc;else if("img"===t)i.type="img",i.src=e.src,i.current_src=e.currentSrc;else if("video"===t){i.type="img";var n=e.querySelector("source");i.src=e.poster||(n?n.src:""),i.current_src=i.src}else if("svg"===t)(n=e.querySelector("image"))&&(i.type="img",i.src=n.getAttribute("href")||"",i.current_src=i.src);else if("picture"===t)i.type="picture",n=e.querySelector("img"),i.src=n?n.src:"",i.sources=Array.from(e.querySelectorAll("source")).map(e=>({srcset:e.srcset||"",media:e.media||"",type:e.type||"",sizes:e.sizes||""}));else{if(0===(t=[window.getComputedStyle(e,null).getPropertyValue("background-image"),getComputedStyle(e,":after").getPropertyValue("background-image"),getComputedStyle(e,":before").getPropertyValue("background-image")].filter(e=>"none"!==e)).length)return null;if(n=t[0],i.type="bg-img",n.includes("image-set(")&&(i.type="bg-img-set"),!n||""===n||n.includes("data:image"))return null;e=[...n.matchAll(/url\(\s*?['"]?\s*?(.+?)\s*?["']?\s*?\)/gi)],i.bg_set=e.map(e=>e[1]?{src:e[1].trim()+(e[2]?" "+e[2].trim():"")}:{}),i.bg_set.every(e=>""===e.src)&&(i.bg_set=e.map(e=>e[1]?{src:e[1].trim()}:{})),0null!==e.elementInfo))?this.performanceImages=[{...e.elementInfo,label:"lcp"}]:(this._logMessage("No LCP candidate found."),this.performanceImages=[])}_fillATFWithoutDuplications(e){e.forEach(e=>{var{element:e,elementInfo:t}=e;!this._isDuplicateImage(e)&&t&&this.performanceImages.push({...t,label:"above-the-fold"})})}_isDuplicateImage(e){const t=this._getElementInfo(e);var i;return null!==t&&(e="img"===t.type||"img-srcset"===t.type||"video"===t.type,i="bg-img"===t.type||"bg-img-set"===t.type||"picture"===t.type,e||i)&&this.performanceImages.some(e=>e.src===t.src)}_getFinalStatus(){return""!==this.errorCode?this.errorCode:10<=(new Date-this.scriptTimer)/1e3?"timeout":"success"}_saveFinalResultIntoDB(){var e=new FormData;e.append("action","rocket_lcp"),e.append("rocket_lcp_nonce",this.config.nonce),e.append("url",this.config.url),e.append("is_mobile",this.config.is_mobile),e.append("images",JSON.stringify(this.performanceImages)),e.append("status",this._getFinalStatus()),fetch(this.config.ajax_url,{method:"POST",credentials:"same-origin",body:e,headers:{"wpr-saas-no-intercept":!0}}).then(e=>e.json()).then(e=>{this._logMessage(e)}).catch(e=>{this._logMessage(e)}).finally(()=>{this._finalize()})}_handleInfiniteLoop(){this._saveFinalResultIntoDB()}_finalize(){document.querySelector('[data-name="wpr-lcp-beacon"]').setAttribute("beacon-completed","true"),clearTimeout(this.infiniteLoopId)}_logMessage(e){this.config.debug&&console.log(e)}static run(){if(window.rocket_lcp_data){const e=new n(window.rocket_lcp_data);"loading"!==document.readyState?setTimeout(()=>{e.init()},window.rocket_lcp_data.delay):document.addEventListener("DOMContentLoaded",()=>{setTimeout(()=>{e.init()},window.rocket_lcp_data.delay)})}}}).run()},{}]},{},[1]); //# sourceMappingURL=lcp-beacon.min.js.map diff --git a/assets/js/lcp-beacon.min.js.map b/assets/js/lcp-beacon.min.js.map index 4db70f4121..3db9f48fc2 100644 --- a/assets/js/lcp-beacon.min.js.map +++ b/assets/js/lcp-beacon.min.js.map @@ -1 +1 @@ -{"version":3,"names":[],"mappings":"","sources":["lcp-beacon.min.js"],"sourcesContent":["!function n(r,s,o){function c(t,e){if(!s[t]){if(!r[t]){var i=\"function\"==typeof require&&require;if(!e&&i)return i(t,!0);if(a)return a(t,!0);throw(e=new Error(\"Cannot find module '\"+t+\"'\")).code=\"MODULE_NOT_FOUND\",e}i=s[t]={exports:{}},r[t][0].call(i.exports,function(e){return c(r[t][1][e]||e)},i,i.exports,n,r,s,o)}return s[t].exports}for(var a=\"function\"==typeof require&&require,e=0;e{this._handleInfiniteLoop()},1e4);try{var e=this._generateLcpCandidates(1/0);e&&(this._initWithFirstElementWithInfo(e),this._fillATFWithoutDuplications(e))}catch(e){this.errorCode=\"script_error\",this._logMessage(\"Script Error: \"+e)}this._saveFinalResultIntoDB()}else this._finalize()}async _isValidPreconditions(){return this._isNotValidScreensize()?(this._logMessage(\"Bailing out because screen size is not acceptable\"),!1):!this._isPageCached()||!await this._isGeneratedBefore()||(this._logMessage(\"Bailing out because data is already available\"),!1)}_isPageCached(){var e=document.documentElement.nextSibling&&document.documentElement.nextSibling.data?document.documentElement.nextSibling.data:\"\";return e&&e.includes(\"Debug: cached\")}async _isGeneratedBefore(){var e=new FormData;return e.append(\"action\",\"rocket_check_lcp\"),e.append(\"rocket_lcp_nonce\",this.config.nonce),e.append(\"url\",this.config.url),e.append(\"is_mobile\",this.config.is_mobile),(e=await fetch(this.config.ajax_url,{method:\"POST\",credentials:\"same-origin\",body:e}).then(e=>e.json())).success}_isNotValidScreensize(){var e=window.innerWidth||document.documentElement.clientWidth,t=window.innerHeight||document.documentElement.clientHeight,i=this.config.is_mobile&&(e>this.config.width_threshold||t>this.config.height_threshold),e=!this.config.is_mobile&&(e{if(\"img\"===e.nodeName.toLowerCase()&&\"picture\"===e.parentElement.nodeName.toLowerCase())return null;let t;if(\"picture\"===e.nodeName.toLowerCase()){var i=e.querySelector(\"img\");if(!i)return null;t=i.getBoundingClientRect()}else t=e.getBoundingClientRect();return{element:e,rect:t}}).filter(e=>null!==e).filter(e=>0({item:e,area:this._getElementArea(e.rect),elementInfo:this._getElementInfo(e.element)})).sort((e,t)=>t.area-e.area).slice(0,e).map(e=>({element:e.item.element,elementInfo:e.elementInfo}))}_isIntersecting(e){return 0<=e.bottom&&0<=e.right&&e.top<=(window.innerHeight||document.documentElement.clientHeight)&&e.left<=(window.innerWidth||document.documentElement.clientWidth)}_getElementArea(e){return Math.min(e.width,(window.innerWidth||document.documentElement.clientWidth)-e.left)*Math.min(e.height,(window.innerHeight||document.documentElement.clientHeight)-e.top)}_getElementInfo(e){var t=e.nodeName.toLowerCase(),i={type:\"\",src:\"\",srcset:\"\",sizes:\"\",sources:[],bg_set:[],current_src:\"\"};if(\"img\"===t&&e.srcset)i.type=\"img-srcset\",i.src=e.src,i.srcset=e.srcset,i.sizes=e.sizes,i.current_src=e.currentSrc;else if(\"img\"===t)i.type=\"img\",i.src=e.src,i.current_src=e.currentSrc;else if(\"video\"===t){i.type=\"img\";var n=e.querySelector(\"source\");i.src=e.poster||(n?n.src:\"\"),i.current_src=i.src}else if(\"svg\"===t)(n=e.querySelector(\"image\"))&&(i.type=\"img\",i.src=n.getAttribute(\"href\")||\"\",i.current_src=i.src);else if(\"picture\"===t)i.type=\"picture\",n=e.querySelector(\"img\"),i.src=n?n.src:\"\",i.sources=Array.from(e.querySelectorAll(\"source\")).map(e=>({srcset:e.srcset||\"\",media:e.media||\"\",type:e.type||\"\",sizes:e.sizes||\"\"}));else{if(0===(t=[window.getComputedStyle(e,null).getPropertyValue(\"background-image\"),getComputedStyle(e,\":after\").getPropertyValue(\"background-image\"),getComputedStyle(e,\":before\").getPropertyValue(\"background-image\")].filter(e=>\"none\"!==e)).length)return null;if(n=t[0],i.type=\"bg-img\",n.includes(\"image-set(\")&&(i.type=\"bg-img-set\"),!n||\"\"===n||n.includes(\"data:image\"))return null;e=[...n.matchAll(/url\\(\\s*?['\"]?\\s*?(.+?)\\s*?[\"']?\\s*?\\)/gi)],i.bg_set=e.map(e=>e[1]?{src:e[1].trim()+(e[2]?\" \"+e[2].trim():\"\")}:{}),i.bg_set.every(e=>\"\"===e.src)&&(i.bg_set=e.map(e=>e[1]?{src:e[1].trim()}:{})),0null!==e.elementInfo))?this.performanceImages=[{...e.elementInfo,label:\"lcp\"}]:(this._logMessage(\"No LCP candidate found.\"),this.performanceImages=[])}_fillATFWithoutDuplications(e){e.forEach(e=>{var{element:e,elementInfo:t}=e;this._isDuplicateImage(e)||this.performanceImages.push({...t,label:\"above-the-fold\"})})}_isDuplicateImage(e){const t=this._getElementInfo(e);var i;return null!==t&&(e=\"img\"===t.type||\"img-srcset\"===t.type||\"video\"===t.type,i=\"bg-img\"===t.type||\"bg-img-set\"===t.type||\"picture\"===t.type,e||i)&&this.performanceImages.some(e=>e.src===t.src)}_getFinalStatus(){return\"\"!==this.errorCode?this.errorCode:10<=(new Date-this.scriptTimer)/1e3?\"timeout\":\"success\"}_saveFinalResultIntoDB(){var e=new FormData;e.append(\"action\",\"rocket_lcp\"),e.append(\"rocket_lcp_nonce\",this.config.nonce),e.append(\"url\",this.config.url),e.append(\"is_mobile\",this.config.is_mobile),e.append(\"images\",JSON.stringify(this.performanceImages)),e.append(\"status\",this._getFinalStatus()),fetch(this.config.ajax_url,{method:\"POST\",credentials:\"same-origin\",body:e,headers:{\"wpr-saas-no-intercept\":!0}}).then(e=>e.json()).then(e=>{this._logMessage(e)}).catch(e=>{this._logMessage(e)}).finally(()=>{this._finalize()})}_handleInfiniteLoop(){this._saveFinalResultIntoDB()}_finalize(){document.querySelector('[data-name=\"wpr-lcp-beacon\"]').setAttribute(\"beacon-completed\",\"true\"),clearTimeout(this.infiniteLoopId)}_logMessage(e){this.config.debug&&console.log(e)}static run(){if(window.rocket_lcp_data){const e=new n(window.rocket_lcp_data);\"loading\"!==document.readyState?setTimeout(()=>{e.init()},window.rocket_lcp_data.delay):document.addEventListener(\"DOMContentLoaded\",()=>{setTimeout(()=>{e.init()},window.rocket_lcp_data.delay)})}}}).run()},{}]},{},[1]);"],"file":"lcp-beacon.min.js"} \ No newline at end of file +{"version":3,"names":[],"mappings":"","sources":["lcp-beacon.min.js"],"sourcesContent":["!function n(r,s,o){function c(t,e){if(!s[t]){if(!r[t]){var i=\"function\"==typeof require&&require;if(!e&&i)return i(t,!0);if(a)return a(t,!0);throw(e=new Error(\"Cannot find module '\"+t+\"'\")).code=\"MODULE_NOT_FOUND\",e}i=s[t]={exports:{}},r[t][0].call(i.exports,function(e){return c(r[t][1][e]||e)},i,i.exports,n,r,s,o)}return s[t].exports}for(var a=\"function\"==typeof require&&require,e=0;e{this._handleInfiniteLoop()},1e4);try{var e=this._generateLcpCandidates(1/0);e&&(this._initWithFirstElementWithInfo(e),this._fillATFWithoutDuplications(e))}catch(e){this.errorCode=\"script_error\",this._logMessage(\"Script Error: \"+e)}this._saveFinalResultIntoDB()}else this._finalize()}async _isValidPreconditions(){return this._isNotValidScreensize()?(this._logMessage(\"Bailing out because screen size is not acceptable\"),!1):!this._isPageCached()||!await this._isGeneratedBefore()||(this._logMessage(\"Bailing out because data is already available\"),!1)}_isPageCached(){var e=document.documentElement.nextSibling&&document.documentElement.nextSibling.data?document.documentElement.nextSibling.data:\"\";return e&&e.includes(\"Debug: cached\")}async _isGeneratedBefore(){var e=new FormData;return e.append(\"action\",\"rocket_check_lcp\"),e.append(\"rocket_lcp_nonce\",this.config.nonce),e.append(\"url\",this.config.url),e.append(\"is_mobile\",this.config.is_mobile),(e=await fetch(this.config.ajax_url,{method:\"POST\",credentials:\"same-origin\",body:e}).then(e=>e.json())).success}_isNotValidScreensize(){var e=window.innerWidth||document.documentElement.clientWidth,t=window.innerHeight||document.documentElement.clientHeight,i=this.config.is_mobile&&(e>this.config.width_threshold||t>this.config.height_threshold),e=!this.config.is_mobile&&(e{if(\"img\"===e.nodeName.toLowerCase()&&\"picture\"===e.parentElement.nodeName.toLowerCase())return null;let t;if(\"picture\"===e.nodeName.toLowerCase()){var i=e.querySelector(\"img\");if(!i)return null;t=i.getBoundingClientRect()}else t=e.getBoundingClientRect();return{element:e,rect:t}}).filter(e=>null!==e).filter(e=>0({item:e,area:this._getElementArea(e.rect),elementInfo:this._getElementInfo(e.element)})).sort((e,t)=>t.area-e.area).slice(0,e).map(e=>({element:e.item.element,elementInfo:e.elementInfo}))}_isIntersecting(e){return 0<=e.bottom&&0<=e.right&&e.top<=(window.innerHeight||document.documentElement.clientHeight)&&e.left<=(window.innerWidth||document.documentElement.clientWidth)}_getElementArea(e){return Math.min(e.width,(window.innerWidth||document.documentElement.clientWidth)-e.left)*Math.min(e.height,(window.innerHeight||document.documentElement.clientHeight)-e.top)}_getElementInfo(e){var t=e.nodeName.toLowerCase(),i={type:\"\",src:\"\",srcset:\"\",sizes:\"\",sources:[],bg_set:[],current_src:\"\"};if(\"img\"===t&&e.srcset)i.type=\"img-srcset\",i.src=e.src,i.srcset=e.srcset,i.sizes=e.sizes,i.current_src=e.currentSrc;else if(\"img\"===t)i.type=\"img\",i.src=e.src,i.current_src=e.currentSrc;else if(\"video\"===t){i.type=\"img\";var n=e.querySelector(\"source\");i.src=e.poster||(n?n.src:\"\"),i.current_src=i.src}else if(\"svg\"===t)(n=e.querySelector(\"image\"))&&(i.type=\"img\",i.src=n.getAttribute(\"href\")||\"\",i.current_src=i.src);else if(\"picture\"===t)i.type=\"picture\",n=e.querySelector(\"img\"),i.src=n?n.src:\"\",i.sources=Array.from(e.querySelectorAll(\"source\")).map(e=>({srcset:e.srcset||\"\",media:e.media||\"\",type:e.type||\"\",sizes:e.sizes||\"\"}));else{if(0===(t=[window.getComputedStyle(e,null).getPropertyValue(\"background-image\"),getComputedStyle(e,\":after\").getPropertyValue(\"background-image\"),getComputedStyle(e,\":before\").getPropertyValue(\"background-image\")].filter(e=>\"none\"!==e)).length)return null;if(n=t[0],i.type=\"bg-img\",n.includes(\"image-set(\")&&(i.type=\"bg-img-set\"),!n||\"\"===n||n.includes(\"data:image\"))return null;e=[...n.matchAll(/url\\(\\s*?['\"]?\\s*?(.+?)\\s*?[\"']?\\s*?\\)/gi)],i.bg_set=e.map(e=>e[1]?{src:e[1].trim()+(e[2]?\" \"+e[2].trim():\"\")}:{}),i.bg_set.every(e=>\"\"===e.src)&&(i.bg_set=e.map(e=>e[1]?{src:e[1].trim()}:{})),0null!==e.elementInfo))?this.performanceImages=[{...e.elementInfo,label:\"lcp\"}]:(this._logMessage(\"No LCP candidate found.\"),this.performanceImages=[])}_fillATFWithoutDuplications(e){e.forEach(e=>{var{element:e,elementInfo:t}=e;!this._isDuplicateImage(e)&&t&&this.performanceImages.push({...t,label:\"above-the-fold\"})})}_isDuplicateImage(e){const t=this._getElementInfo(e);var i;return null!==t&&(e=\"img\"===t.type||\"img-srcset\"===t.type||\"video\"===t.type,i=\"bg-img\"===t.type||\"bg-img-set\"===t.type||\"picture\"===t.type,e||i)&&this.performanceImages.some(e=>e.src===t.src)}_getFinalStatus(){return\"\"!==this.errorCode?this.errorCode:10<=(new Date-this.scriptTimer)/1e3?\"timeout\":\"success\"}_saveFinalResultIntoDB(){var e=new FormData;e.append(\"action\",\"rocket_lcp\"),e.append(\"rocket_lcp_nonce\",this.config.nonce),e.append(\"url\",this.config.url),e.append(\"is_mobile\",this.config.is_mobile),e.append(\"images\",JSON.stringify(this.performanceImages)),e.append(\"status\",this._getFinalStatus()),fetch(this.config.ajax_url,{method:\"POST\",credentials:\"same-origin\",body:e,headers:{\"wpr-saas-no-intercept\":!0}}).then(e=>e.json()).then(e=>{this._logMessage(e)}).catch(e=>{this._logMessage(e)}).finally(()=>{this._finalize()})}_handleInfiniteLoop(){this._saveFinalResultIntoDB()}_finalize(){document.querySelector('[data-name=\"wpr-lcp-beacon\"]').setAttribute(\"beacon-completed\",\"true\"),clearTimeout(this.infiniteLoopId)}_logMessage(e){this.config.debug&&console.log(e)}static run(){if(window.rocket_lcp_data){const e=new n(window.rocket_lcp_data);\"loading\"!==document.readyState?setTimeout(()=>{e.init()},window.rocket_lcp_data.delay):document.addEventListener(\"DOMContentLoaded\",()=>{setTimeout(()=>{e.init()},window.rocket_lcp_data.delay)})}}}).run()},{}]},{},[1]);"],"file":"lcp-beacon.min.js"} \ No newline at end of file diff --git a/inc/Engine/Media/AboveTheFold/AJAX/Controller.php b/inc/Engine/Media/AboveTheFold/AJAX/Controller.php index 7213182d86..ed5d60526c 100644 --- a/inc/Engine/Media/AboveTheFold/AJAX/Controller.php +++ b/inc/Engine/Media/AboveTheFold/AJAX/Controller.php @@ -24,6 +24,15 @@ class Controller { */ protected $context; + /** + * An array of unsupported atf schemes. + * + * @var array + */ + private $invalid_schemes = [ + 'chrome-[^:]+://', + ]; + /** * Constructor * @@ -69,20 +78,25 @@ public function add_lcp_data() { $keys = [ 'bg_set', 'src' ]; foreach ( (array) $images as $image ) { - if ( isset( $image->type ) ) { - $image_object = $this->create_object( $image, $keys ); - - if ( 'lcp' === $image->label && null !== $image_object ) { - $lcp = $image_object; - } elseif ( 'above-the-fold' === $image->label && null !== $image_object ) { - if ( 0 === $max_atf_images_number ) { - continue; - } + if ( empty( $image->type ) ) { + continue; + } - $viewport[] = $image_object; + $image_object = $this->create_object( $image, $keys ); - --$max_atf_images_number; - } + if ( ! $image_object || ! $this->validate_image( $image_object ) ) { + continue; + } + + if ( 'lcp' === $image->label ) { + $lcp = $image_object; + continue; + } + + if ( 'above-the-fold' === $image->label && 0 < $max_atf_images_number ) { + $viewport[] = $image_object; + + --$max_atf_images_number; } } @@ -254,4 +268,65 @@ public function check_lcp_data() { wp_send_json_error( 'data does not exist' ); } + + /** + * Validate image object. + * + * @param object $image_object Image full object. + * @return bool + */ + private function validate_image( $image_object ) { + $valid_image = ! empty( $image_object->src ) ? $this->validate_image_src( $image_object->src ?? '' ) : true; + + /** + * Filters If the image src is a valid image or not. + * + * @param bool $valid_image Valid image or not. + * @param string $image_src_url Image src url. + * @param object $image_object Image object with full details. + */ + return (bool) apply_filters( 'rocket_atf_valid_image', $valid_image, $image_object->src, $image_object ); + } + + /** + * Make sure that this url is valid image without loading the image itself. + * + * @param string $image_src Image src url. + * @return bool + */ + private function validate_image_src( $image_src ) { + if ( empty( $image_src ) ) { + return false; + } + + /** + * Filters the supported schemes of LCP/ATF images. + * + * @param array $invalid_schemes Array of invalid schemes. + */ + $invalid_schemes = apply_filters( 'rocket_atf_invalid_schemes', $this->invalid_schemes ); + + if ( ! is_array( $invalid_schemes ) ) { + $invalid_schemes = $this->invalid_schemes; + } + + $invalid_schemes = implode( '|', $invalid_schemes ); + + if ( preg_match( '#^' . $invalid_schemes . '#', $image_src ) ) { + return false; + } + + // Here we get the url PATH part only to strip all query strings. + $image_src_path = wp_parse_url( $image_src, PHP_URL_PATH ); + if ( empty( $image_src_path ) ) { + return false; + } + + // Add svg to allowed mime types. + $allowed_mime_types = get_allowed_mime_types(); + $allowed_mime_types['svg'] = 'image/svg+xml'; + $image_src_filetype_array = wp_check_filetype( $image_src_path, $allowed_mime_types ); + + return ! empty( $image_src_filetype_array['type'] ) && str_starts_with( $image_src_filetype_array['type'], 'image/' ); + } } diff --git a/tests/Fixtures/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php b/tests/Fixtures/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php index 2266c2c9c2..b3d0eaf2dc 100644 --- a/tests/Fixtures/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php +++ b/tests/Fixtures/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php @@ -66,6 +66,21 @@ ], ] ), + 'filetype' => [ + 'ext' => 'jpg', + 'type' => 'image/jpeg', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], ], 'expected' => [ 'images_valid_sources' => [], @@ -111,6 +126,21 @@ ], ] ), + 'filetype' => [ + 'ext' => 'jpg', + 'type' => 'image/jpeg', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], ], 'expected' => [ 'images_valid_sources' => [], @@ -174,6 +204,21 @@ ], ] ), + 'filetype' => [ + 'ext' => 'jpg', + 'type' => 'image/jpeg', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], ], 'expected' => [ 'images_valid_sources' => [], @@ -239,6 +284,21 @@ ], ] ), + 'filetype' => [ + 'ext' => 'jpg', + 'type' => 'image/jpeg', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], ], 'expected' => [ 'images_valid_sources' => [ @@ -296,7 +356,7 @@ (object) [ 'label' => 'lcp', 'type' => 'bg-img', - 'src' => 'http://example.org/lcp.jpg', + 'src' => '', 'bg_set' => [ [ 'src' => 'http://example.org/anotherlcp.jpg' @@ -313,6 +373,21 @@ ], ] ), + 'filetype' => [ + 'ext' => 'jpg', + 'type' => 'image/jpeg', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], ], 'expected' => [ 'images_valid_sources' => [ @@ -408,6 +483,21 @@ ], ] ), + 'filetype' => [ + 'ext' => 'jpg', + 'type' => 'image/jpeg', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], ], 'expected' => [ 'images_valid_sources' => [], @@ -476,6 +566,21 @@ 'images' => json_encode( $long_array ), + 'filetype' => [ + 'ext' => 'jpg', + 'type' => 'image/jpeg', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], ], 'expected' => [ 'images_valid_sources' => [], @@ -637,4 +742,328 @@ ], ], ], + + 'testShouldBailoutWithNotValidImages1' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'images' => json_encode( + [ + (object) [ + 'label' => 'lcp', + 'type' => 'img', + 'src' => 'http://example.org/file.php?url=img.jpg', + ], + ] + ), + 'filetype' => [ + 'ext' => 'php', + 'type' => false, + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + ], + ], + 'testShouldBailoutWithNotValidImages2' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'images' => json_encode( + [ + (object) [ + 'label' => 'lcp', + 'type' => 'img', + 'src' => 'http://example.org/file.js?url=img.jpg', + ], + ] + ), + 'filetype' => [ + 'ext' => 'js', + 'type' => 'application/javascript', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + ], + ], + 'testShouldBailoutWithNotValidImages3' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'images' => json_encode( + [ + (object) [ + 'label' => 'lcp', + 'type' => 'img', + 'src' => 'http://example.org/file.php#url=img.jpg', + ], + ] + ), + 'filetype' => [ + 'ext' => 'php', + 'type' => 'application/php', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + ], + ], + 'testShouldBailoutWithNotValidImages4' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'images' => json_encode( + [ + (object) [ + 'label' => 'lcp', + 'type' => 'img', + 'src' => 'chrome-extension://extension-hash/path/to/image/x.svg', + ], + ] + ), + 'filetype' => [ + 'ext' => 'svg', + 'type' => 'image/svg+xml', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + ], + ], + 'testShouldBailoutWithNotValidImages5' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'images' => json_encode( + [ + (object) [ + 'label' => 'lcp', + 'type' => 'bg-img', + 'src' => 'linear-gradient(160deg, rgb(255, 255, 255) 0%, rgb(248, 246, 243) 100%)', + ], + ] + ), + 'filetype' => [ + 'ext' => false, + 'type' => false, + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], + ], + 'expected' => [ + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => 'not found', + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + ], + ], + 'testShouldAddItemToDBWhenSvgWithHttpProtocol' => [ + 'config' => [ + 'filter' => true, + 'url' => 'http://example.org', + 'is_mobile' => false, + 'images' => json_encode( + [ + (object) [ + 'label' => 'lcp', + 'type' => 'img', + 'src' => 'http://example.org/path/to/images/image.svg', + ], + ] + ), + 'filetype' => [ + 'ext' => 'svg', + 'type' => 'image/svg+xml', + ], + 'allowed_mime_types' => [ + 'jpg|jpeg|jpe' => 'image/jpeg', + 'gif' => 'image/gif', + 'png' => 'image/png', + 'bmp' => 'image/bmp', + 'tiff|tif' => 'image/tiff', + 'webp' => 'image/webp', + 'avif' => 'image/avif', + 'ico' => 'image/x-icon', + 'heic' => 'image/heic', + ], + ], + 'expected' => [ + 'images_valid_sources' => [], + 'item' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => json_encode( + (object) [ + 'type' => 'img', + 'src' => 'http://example.org/path/to/images/image.svg', + ], + ), + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + 'result' => true, + 'message' => [ + 'url' => 'http://example.org', + 'is_mobile' => false, + 'status' => 'completed', + 'lcp' => json_encode( + (object) [ + 'type' => 'img', + 'src' => 'http://example.org/path/to/images/image.svg', + ], + ), + 'viewport' => '[]', + 'last_accessed' => '2024-01-01 00:00:00', + 'error_message' => '', + ], + ], + ], ]; diff --git a/tests/Unit/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php b/tests/Unit/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php index a2d4ec4166..e02cfea9de 100644 --- a/tests/Unit/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php +++ b/tests/Unit/inc/Engine/Media/AboveTheFold/AJAX/Controller/addLcpData.php @@ -8,6 +8,7 @@ use WP_Rocket\Engine\Media\AboveTheFold\Database\Queries\AboveTheFold; use WP_Rocket\Engine\Media\AboveTheFold\AJAX\Controller; use WP_Rocket\Tests\Unit\TestCase; +use Brain\Monkey\Filters; /** * Test class covering WP_Rocket\Engine\Media\AboveTheFold\AJAX\Controller::add_lcp_data @@ -77,7 +78,7 @@ function ( $value ) { } ); - $images_valid_sources = $expected['images_valid_sources']; + $images_valid_sources = $expected['images_valid_sources'] ?? []; Functions\when( 'sanitize_url' )->alias( function( $url ) use ( $images_valid_sources ) { @@ -108,6 +109,15 @@ function( $url ) use ( $images_valid_sources ) { ->with( $expected['message'] ); } + $this->stubWpParseUrl(); + + Filters\expectApplied('rocket_atf_invalid_schemes')->with([ 'chrome-[^:]+://' ])->andReturn([ 'chrome-[^:]+://' ]); + + if ( ! empty( $config['filetype'] ) ) { + Functions\when('get_allowed_mime_types')->justReturn( $config['allowed_mime_types'] ); + Functions\when('wp_check_filetype')->justReturn( $config['filetype'] ); + } + $this->controller->add_lcp_data(); } }