WordPress Popular Posts - Version 5.3.4

Version Description

  • Experimental Gutenberg support! This version introduces the first WPP block. It's not enabled by default though, see the Release Notes for more.
  • Fixes a potential authenticated stored XSS vulnerability (props to Visse for reporting it!)
  • Overall security enhancements (props to Visse for assisting with this!)
  • Other minor improvements / fixes.

Release notes

Download this release

Release Info

Developer hcabrera
Plugin Icon 128x128 WordPress Popular Posts
Version 5.3.4
Comparing to
See all releases

Code changes from version 5.3.3 to 5.3.4

Files changed (44) hide show
  1. assets/js/blocks/block-wpp-widget.asset.php +1 -0
  2. assets/js/blocks/block-wpp-widget.js +1 -0
  3. assets/js/wpp.js +11 -10
  4. assets/js/wpp.min.js +6 -1
  5. assets/themes/cards-compact/style.css +5 -0
  6. assets/themes/cards/style.css +5 -0
  7. assets/themes/cardview-compact/style.css +5 -0
  8. assets/themes/cardview/style.css +5 -0
  9. assets/themes/evergreen/style.css +5 -0
  10. assets/themes/midnight/style.css +5 -0
  11. assets/themes/sunrise/style.css +5 -0
  12. assets/themes/sunset/style.css +5 -0
  13. assets/themes/tiles/style.css +5 -0
  14. assets/themes/tiny/style.css +5 -0
  15. i18n/wordpress-popular-posts.pot +555 -419
  16. readme.txt +11 -2
  17. src/Admin/admin-page.php +7 -0
  18. src/Block/Block.php +27 -0
  19. src/Block/Widget/Widget.php +506 -0
  20. src/Block/Widget/edit.js +752 -0
  21. src/Block/Widget/editor.css +42 -0
  22. src/Block/Widget/widget.js +209 -0
  23. src/Block/icons.js +5 -0
  24. src/Block/utils.js +20 -0
  25. src/Container/WordPressPopularPostsConfiguration.php +18 -2
  26. src/Front/Front.php +4 -10
  27. src/Helper.php +139 -0
  28. src/Image.php +7 -41
  29. src/Output.php +28 -5
  30. src/Rest/Controller.php +34 -1
  31. src/Rest/TaxonomiesEndpoint.php +39 -0
  32. src/Rest/ThemesEndpoint.php +63 -0
  33. src/Rest/ThumbnailsEndpoint.php +58 -0
  34. src/Settings.php +1 -0
  35. src/Widget/Widget.php +20 -11
  36. src/Widget/form.php +1 -1
  37. src/WordPressPopularPosts.php +11 -1
  38. src/htmLawed.php +741 -0
  39. vendor/composer/ClassLoader.php +39 -5
  40. vendor/composer/autoload_classmap.php +1 -0
  41. vendor/composer/autoload_real.php +7 -2
  42. vendor/composer/autoload_static.php +5 -0
  43. vendor/composer/platform_check.php +26 -0
  44. wordpress-popular-posts.php +2 -2
assets/js/blocks/block-wpp-widget.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array('wp-polyfill'), 'version' => 'f57813198efb65304d0e7914715bab7e');
assets/js/blocks/block-wpp-widget.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){var t={};function a(s){if(t[s])return t[s].exports;var r=t[s]={i:s,l:!1,exports:{}};return e[s].call(r.exports,r,r.exports,a),r.l=!0,r.exports}a.m=e,a.c=t,a.d=function(e,t,s){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(a.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)a.d(s,r,function(t){return e[t]}.bind(null,r));return s},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=0)}([function(e,t,a){"use strict";a.r(t);var s={};s.flame=React.createElement("svg",{viewBox:"0 0 248 379"},React.createElement("path",{fill:"#fff",d:"M-83,96q0-122.5,0-245H165q0,131,0,262a31.87,31.87,0,0,1-.95-4.33A123.87,123.87,0,0,0,153.47,68.3c-12.28-27.74-31.1-50.64-53-71.21C75.67-26.13,55.85-52,54.32-87.87c-.79-18.47.81-36.24,11.59-52.15,1.08-1.59.38-4.4.5-6.64-2.43.1-5.5-.7-7.18.47a140.91,140.91,0,0,0-17.12,13.72C19.49-110.67,3-84.6-9.51-56A149,149,0,0,0-21.86-3.77c-2,39.4,11.38,73.46,36.17,103.51,1.74,2.11,3.51,4.2,5.27,6.3l-.67,1.07c-3.94-1.07-8-1.83-11.82-3.24C-25.17,91.94-52.36,58.57-51.12,21c.1-2.91.21-6.45-3.51-6.49-2,0-4.76,2.16-5.79,4.09-9.4,17.55-16.35,36-19.73,55.73C-81.38,81.49-82.07,88.76-83,96Z",transform:"translate(83 149)"}),React.createElement("path",{fill:"#ba2f2f",d:"M-83,96c.93-7.24,1.62-14.51,2.85-21.7,3.38-19.69,10.33-38.18,19.73-55.73,1-1.93,3.83-4.11,5.79-4.09,3.72,0,3.61,3.58,3.51,6.49-1.25,37.59,25.94,71,58.2,82.89,3.82,1.41,7.87,2.18,11.82,3.24l.67-1.07c-1.76-2.1-3.52-4.19-5.27-6.3C-10.49,69.68-23.88,35.63-21.86-3.77A149,149,0,0,1-9.51-56c12.48-28.62,29-54.69,51.62-76.5a140.91,140.91,0,0,1,17.12-13.72c1.68-1.18,4.75-.37,7.18-.47-.13,2.24.58,5-.5,6.64-10.78,15.9-12.37,33.68-11.59,52.15,1.53,35.89,21.35,61.74,46.11,85,21.94,20.57,40.76,43.47,53,71.21a123.87,123.87,0,0,1,10.59,40.36A31.87,31.87,0,0,0,165,113v9c-.7,4.24-1.17,8.54-2.13,12.73-10.74,46.51-37.08,78.75-84.34,91.58C72.16,228,65.52,228.79,59,230H43a25.19,25.19,0,0,0-3.12-1.18c-10-2.37-20.21-4.12-30-7.12-45.83-14-75.19-44.64-89-90.24-2.28-7.52-2.64-15.63-3.88-23.46Q-83,102-83,96ZM61.63-143.61c-6.24,5.39-12.87,10.38-18.64,16.22A229,229,0,0,0-8.77-46.26,138.37,138.37,0,0,0-16.63,23c4.69,32.54,20.21,59.59,42.4,83.23,1.34,1.43,2.7,2.83,4.8,5-15.23,1-28-3.3-39.74-10.64-29.74-18.62-46-45.23-46.8-81a138.75,138.75,0,0,0-7.46,14.67A178.29,178.29,0,0,0-78.24,93.09C-80.9,129.7-68,160.25-42.78,185.71c28.91,29.16,65.19,41.42,105.43,38.91,43.82-2.73,80.34-35.08,93.53-79.39,8.68-29.18,3.11-56.71-10.29-83.15C134.15,38.92,117.71,19.34,99,1.57,85-11.65,71.34-25.28,62.72-42.69,46.33-75.79,44.36-109.22,61.63-143.61Z",transform:"translate(83 149)"}),React.createElement("path",{fill:"#fff",d:"M-83,108c1.25,7.84,1.61,15.94,3.88,23.46,13.79,45.6,43.15,76.21,89,90.24,9.82,3,20,4.76,30,7.12A25.19,25.19,0,0,1,43,230H-83Q-83,169-83,108Z",transform:"translate(83 149)"}),React.createElement("path",{fill:"#fff",d:"M59,230c6.52-1.21,13.16-2,19.53-3.69,47.26-12.83,73.6-45.07,84.34-91.58,1-4.18,1.43-8.48,2.13-12.73V230Z",transform:"translate(83 149)"}),React.createElement("path",{fill:"#ba2f2f",d:"M61.63-143.61c-17.28,34.39-15.3,67.82,1.09,100.92C71.34-25.28,85-11.65,99,1.57c18.75,17.77,35.2,37.35,46.94,60.51,13.4,26.44,19,54,10.29,83.15-13.18,44.31-49.71,76.66-93.53,79.39-40.25,2.51-76.52-9.75-105.43-38.91C-68,160.25-80.9,129.7-78.24,93.09A178.29,178.29,0,0,1-63.45,34.31,138.75,138.75,0,0,1-56,19.64c.77,35.79,17.06,62.4,46.8,81C2.54,108,15.33,112.3,30.56,111.3c-2.1-2.21-3.46-3.62-4.8-5C3.57,82.62-11.94,55.57-16.63,23A138.37,138.37,0,0,1-8.77-46.26,229,229,0,0,1,43-127.38C48.76-133.23,55.39-138.22,61.63-143.61Z",transform:"translate(83 149)"}));var r=s;function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function n(e,t){for(var a=0;a<t.length;a++){var s=t[a];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function i(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function p(e){return(p=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}var u=wp.editor.ServerSideRender,c=wp.element,m=c.Component,d=c.Fragment,h=wp.blockEditor.BlockControls,f=wp.components,b=f.Button,_=f.CheckboxControl,g=f.Disabled,y=f.SelectControl,v=f.Spinner,w=f.TextareaControl,x=f.TextControl,R=f.Toolbar,__=wp.i18n.__,E="wordpress-popular-posts/v1",C=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&l(e,t)}(c,e);var t,a,s,r,o=(s=c,r=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=p(s);if(r){var a=p(this).constructor;e=Reflect.construct(t,arguments,a)}else e=t.apply(this,arguments);return i(this,e)});function c(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,c),(t=o.call(this,e)).state={error:null,editMode:!0,themes:null,imgSizes:null,taxonomies:null},t}return t=c,(a=[{key:"componentDidMount",value:function(){var e=this.props.attributes;this.getThemes(),this.getImageSizes(),this.getTaxonomies(),this.setState({editMode:e._editMode})}},{key:"getThemes",value:function(){var e=this;wp.apiFetch({path:E+"/themes"}).then((function(t){e.setState({themes:t})}),(function(t){e.setState({error:t,themes:null})}))}},{key:"getImageSizes",value:function(){var e=this;wp.apiFetch({path:E+"/thumbnails"}).then((function(t){e.setState({imgSizes:t})}),(function(t){e.setState({error:t,imgSizes:null})}))}},{key:"getTaxonomies",value:function(){var e=this,t=this.props.attributes;wp.apiFetch({path:E+"/taxonomies"}).then((function(a){if(a){var s=t.tax.split(";"),r=t.term_id.split(";");if(s.length&&s.length==r.length){for(var o={},n=0;n<s.length;n++)o[s[n]]=r[n];for(var l in a)a[l]._terms=void 0!==o[l]?o[l]:""}}e.setState({taxonomies:a})}),(function(t){e.setState({error:t,taxonomies:null})}))}},{key:"getBlockControls",value:function(){var e=this.props.setAttributes,t=this;return React.createElement(h,null,React.createElement(R,null,React.createElement(b,{label:this.state.editMode?__("Preview","wordpress-popular-posts"):__("Edit","wordpress-popular-posts"),icon:this.state.editMode?"format-image":"edit",onClick:function(){var a=!t.state.editMode;t.setState({editMode:a}),e({_editMode:a})}})))}},{key:"getMainFields",value:function(){var e=this.props,t=e.attributes,a=e.setAttributes;return React.createElement(d,null,React.createElement(x,{label:__("Title","wordpress-popular-posts"),value:t.title,onChange:function(e){e=function(e){var t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;","`":"&grave;"};return e.replace(/[&<>"'/]/gi,(function(e){return t[e]}))}(function(e){var t=document.createElement("div");t.innerHTML=e;var a=t.childNodes[0];return a?a.nodeValue:""}(e)),a({title:e})}}),React.createElement(x,{label:__("Limit","wordpress-popular-posts"),value:t.limit,onChange:function(e){var t=Number.isInteger(Number(e))&&Number(e)>0?e:10;a({limit:Number(t)})}}),React.createElement(y,{label:__("Sort posts by","wordpress-popular-posts"),value:t.order_by,options:[{label:__("Total views","wordpress-popular-posts"),value:"views"},{label:__("Comments","wordpress-popular-posts"),value:"comments"}],onChange:function(e){a({order_by:e})}}),React.createElement(y,{label:__("Time Range","wordpress-popular-posts"),value:t.range,options:[{label:__("Last 24 Hours","wordpress-popular-posts"),value:"last24hours"},{label:__("Last 7 days","wordpress-popular-posts"),value:"last7days"},{label:__("Last 30 days","wordpress-popular-posts"),value:"last30days"},{label:__("All-time","wordpress-popular-posts"),value:"all"},{label:__("Custom","wordpress-popular-posts"),value:"custom"}],onChange:function(e){a({range:e})}}),"custom"==t.range&&React.createElement("div",{className:"option-subset"},React.createElement(x,{label:__("Time Quantity","wordpress-popular-posts"),value:t.time_quantity,onChange:function(e){var t=Number.isInteger(Number(e))&&Number(e)>0?e:24;a({time_quantity:Number(t)})}}),React.createElement(y,{label:__("Time Unit","wordpress-popular-posts"),value:t.time_unit,options:[{label:__("Minute(s)","wordpress-popular-posts"),value:"minute"},{label:__("Hour(s)","wordpress-popular-posts"),value:"hour"},{label:__("Day(s)","wordpress-popular-posts"),value:"day"}],onChange:function(e){a({time_unit:e})}})),React.createElement(_,{label:__("Display only posts published within the selected Time Range","wordpress-popular-posts"),checked:t.freshness,onChange:function(e){a({freshness:e})}}))}},{key:"getFiltersFields",value:function(){var e=this.props,t=e.attributes,a=e.setAttributes,s=this,r=[];if(this.state.taxonomies)for(var o in this.state.taxonomies)r.push({name:this.state.taxonomies[o].name,label:this.state.taxonomies[o].labels.singular_name+" ("+this.state.taxonomies[o].name+")",terms:this.state.taxonomies[o]._terms});return React.createElement(d,null,React.createElement("p",{className:"not-a-legend"},React.createElement("strong",null,__("Filters","wordpress-popular-posts"))),React.createElement(x,{label:__("Post type(s)","wordpress-popular-posts"),help:__("Post types must be comma separated.","wordpress-popular-posts"),value:t.post_type,onChange:function(e){var t=e.replace(/[^a-z0-9-_\,]+/gi,"");a({post_type:t})}}),React.createElement(x,{label:__("Post ID(s) to exclude","wordpress-popular-posts"),help:__("IDs must be comma separated.","wordpress-popular-posts"),value:t.pid,onChange:function(e){var t=e.replace(/[^0-9\,]/g,"");a({pid:t})}}),React.createElement(x,{label:__("Author ID(s)","wordpress-popular-posts"),help:__("IDs must be comma separated.","wordpress-popular-posts"),value:t.author,onChange:function(e){var t=e.replace(/[^0-9\,]/g,"");a({author:t})}}),r&&r.filter((function(e){return"post_format"!=e.name})).map((function(e){return React.createElement(x,{label:e.label,help:__("Term IDs must be comma separated, prefix a minus sign to exclude.","wordpress-popular-posts"),value:e.terms,onChange:function(t){return function(e,t){var a=s.state.taxonomies;t=t.replace(/[^0-9-\,]/g,""),a&&void 0!==a[e]&&(a[e]._terms=t,s.setState({taxonomies:a}))}(e.name,t)},onBlur:function(){return function(e){var t=s.state.taxonomies;if(t&&void 0!==t[e]){var r=t[e]._terms.split(",");r.length&&(r=r.map((function(e){return e.trim()})).filter((function(e){return""!=e&&"-"!=e}))),r.length&&(r=Array.from(new Set(r))),t[e]._terms=r.join(","),s.setState({taxonomies:t});var o="",n="";for(var l in s.state.taxonomies)if(s.state.taxonomies.hasOwnProperty(l)){if(!s.state.taxonomies[l]._terms.length)continue;o+=l+";",n+=s.state.taxonomies[l]._terms+";"}o&&n&&(o=o.replace(new RegExp(";$"),""),n=n.replace(new RegExp(";$"),"")),a({tax:o,term_id:n})}}(e.name)}})})))}},{key:"getPostSettingsFields",value:function(){var e=this.props,t=e.attributes,a=e.setAttributes,s=this;function r(e,t){var s=Number.isInteger(Number(t))&&Number(t)>=0?t:0;a("width"==e?{thumbnail_width:Number(s)}:{thumbnail_height:Number(s)})}var o=[];if(this.state.imgSizes)for(var n in this.state.imgSizes)o.push({label:n,value:n});return React.createElement(d,null,React.createElement("p",{className:"not-a-legend"},React.createElement("strong",null,__("Posts settings","wordpress-popular-posts"))),React.createElement(_,{label:__("Shorten title","wordpress-popular-posts"),checked:t.shorten_title,onChange:function(e){a(0==e?{title_length:0,title_by_words:0,shorten_title:e}:{shorten_title:e,title_length:25})}}),t.shorten_title&&React.createElement("div",{className:"option-subset"},React.createElement(x,{label:__("Shorten title to","wordpress-popular-posts"),value:t.title_length,onChange:function(e){var t=Number.isInteger(Number(e))&&Number(e)>=0?e:0;a({title_length:Number(t)})}}),React.createElement(y,{value:t.title_by_words,options:[{label:__("characters","wordpress-popular-posts"),value:0},{label:__("words","wordpress-popular-posts"),value:1}],onChange:function(e){return a({title_by_words:Number(e)})}})),React.createElement(_,{label:__("Display post excerpt","wordpress-popular-posts"),checked:t.display_post_excerpt,onChange:function(e){a(0==e?{excerpt_length:0,excerpt_by_words:0,display_post_excerpt:e}:{display_post_excerpt:e,excerpt_length:55})}}),t.display_post_excerpt&&React.createElement("div",{className:"option-subset"},React.createElement(_,{label:__("Keep text format and links","wordpress-popular-posts"),checked:t.excerpt_format,onChange:function(e){return a({excerpt_format:e})}}),React.createElement(x,{label:__("Excerpt length","wordpress-popular-posts"),value:t.excerpt_length,onChange:function(e){var t=Number.isInteger(Number(e))&&Number(e)>=0?e:0;a({excerpt_length:Number(t)})}}),React.createElement(y,{value:t.excerpt_by_words,options:[{label:__("characters","wordpress-popular-posts"),value:0},{label:__("words","wordpress-popular-posts"),value:1}],onChange:function(e){return a({excerpt_by_words:Number(e)})}})),React.createElement(_,{label:__("Display post thumbnail","wordpress-popular-posts"),checked:t.display_post_thumbnail,onChange:function(e){a(0==e?{thumbnail_width:0,thumbnail_height:0,display_post_thumbnail:e}:{thumbnail_width:75,thumbnail_height:75,display_post_thumbnail:e})}}),t.display_post_thumbnail&&React.createElement("div",{className:"option-subset"},React.createElement(y,{value:t.thumbnail_build,options:[{label:__("Set size manually","wordpress-popular-posts"),value:"manual"},{label:__("Use predefined size","wordpress-popular-posts"),value:"predefined"}],onChange:function(e){"predefined"==e&&a({thumbnail_width:s.state.imgSizes[o[0].value].width,thumbnail_height:s.state.imgSizes[o[0].value].height,thumbnail_size:o[0].value}),a({thumbnail_build:e})}}),"manual"==t.thumbnail_build&&React.createElement(d,null,React.createElement(x,{label:__("Thumbnail width","wordpress-popular-posts"),help:__("Size in px units (pixels)","wordpress-popular-posts"),value:t.thumbnail_width,onChange:function(e){return r("width",e)}}),React.createElement(x,{label:__("Thumbnail height","wordpress-popular-posts"),help:__("Size in px units (pixels)","wordpress-popular-posts"),value:t.thumbnail_height,onChange:function(e){return r("height",e)}})),"predefined"==t.thumbnail_build&&React.createElement(d,null,React.createElement(y,{value:t.thumbnail_size,options:o,onChange:function(e){a({thumbnail_width:s.state.imgSizes[e].width,thumbnail_height:s.state.imgSizes[e].height,thumbnail_size:e})}}))))}},{key:"getStatsTagFields",value:function(){var e=this.props,t=e.attributes,a=e.setAttributes,s=[];if(this.state.taxonomies)for(var r in this.state.taxonomies)s.push({label:this.state.taxonomies[r].labels.singular_name+" ("+this.state.taxonomies[r].name+")",value:this.state.taxonomies[r].name});return React.createElement(d,null,React.createElement("p",{className:"not-a-legend"},React.createElement("strong",null,__("Stats Tag settings","wordpress-popular-posts"))),React.createElement(_,{label:__("Display comments count","wordpress-popular-posts"),checked:t.stats_comments,onChange:function(e){return a({stats_comments:e})}}),React.createElement(_,{label:__("Display views","wordpress-popular-posts"),checked:t.stats_views,onChange:function(e){return a({stats_views:e})}}),React.createElement(_,{label:__("Display author","wordpress-popular-posts"),checked:t.stats_author,onChange:function(e){return a({stats_author:e})}}),React.createElement(_,{label:__("Display date","wordpress-popular-posts"),checked:t.stats_date,onChange:function(e){return a({stats_date:e})}}),t.stats_date&&React.createElement("div",{className:"option-subset"},React.createElement(y,{label:__("Date Format","wordpress-popular-posts"),value:t.stats_date_format,options:[{label:__("Relative","wordpress-popular-posts"),value:"relative"},{label:__("Month Day, Year","wordpress-popular-posts"),value:"F j, Y"},{label:__("yyyy/mm/dd","wordpress-popular-posts"),value:"Y/m/d"},{label:__("mm/dd/yyyy","wordpress-popular-posts"),value:"m/d/Y"},{label:__("dd/mm/yyyy","wordpress-popular-posts"),value:"d/m/Y"}],onChange:function(e){return a({stats_date_format:e})}})),React.createElement(_,{label:__("Display taxonomy","wordpress-popular-posts"),checked:t.stats_taxonomy,onChange:function(e){return a({stats_taxonomy:e})}}),t.stats_taxonomy&&React.createElement("div",{className:"option-subset"},React.createElement(y,{label:__("Taxonomy","wordpress-popular-posts"),value:t.taxonomy,options:s,onChange:function(e){return a({taxonomy:e})}})))}},{key:"getHTMLMarkupFields",value:function(){var e=this.props,t=e.attributes,a=e.setAttributes,s=this,r=[{label:__("None","wordpress-popular-posts"),value:""}];if(this.state.themes)for(var o in this.state.themes)r.push({label:this.state.themes[o].json.name,value:o});return React.createElement(d,null,React.createElement("p",{className:"not-a-legend"},React.createElement("strong",null,__("HTML Markup settings","wordpress-popular-posts"))),React.createElement(_,{label:__("Use custom HTML Markup","wordpress-popular-posts"),checked:t.custom_html,onChange:function(e){return a({custom_html:e})}}),t.custom_html&&React.createElement("div",{className:"option-subset"},React.createElement(w,{rows:"1",label:__("Before title","wordpress-popular-posts"),value:t.header_start,onChange:function(e){return a({header_start:e})}}),React.createElement(w,{rows:"1",label:__("After title","wordpress-popular-posts"),value:t.header_end,onChange:function(e){return a({header_end:e})}}),React.createElement(w,{rows:"1",label:__("Before popular posts","wordpress-popular-posts"),value:t.wpp_start,onChange:function(e){return a({wpp_start:e})}}),React.createElement(w,{rows:"1",label:__("After popular posts","wordpress-popular-posts"),value:t.wpp_end,onChange:function(e){return a({wpp_end:e})}}),React.createElement(w,{label:__("Post HTML markup","wordpress-popular-posts"),value:t.post_html,onChange:function(e){return a({post_html:e})}})),React.createElement(y,{label:__("Theme","wordpress-popular-posts"),value:t.theme,options:r,onChange:function(e){if(void 0!==s.state.themes[e]){var t=s.state.themes[e].json.config;a({shorten_title:t.shorten_title.active,title_length:t.shorten_title.title_length,title_by_words:t.shorten_title.words?1:0,display_post_excerpt:t["post-excerpt"].active,excerpt_format:t["post-excerpt"].format,excerpt_length:t["post-excerpt"].length,excerpt_by_words:t["post-excerpt"].words?1:0,display_post_thumbnail:t.thumbnail.active,thumbnail_build:t.thumbnail.build,thumbnail_width:t.thumbnail.width,thumbnail_height:t.thumbnail.height,stats_comments:t.stats_tag.comment_count,stats_views:t.stats_tag.views,stats_author:t.stats_tag.author,stats_date:t.stats_tag.date.active,stats_date_format:t.stats_tag.date.format,stats_taxonomy:t.stats_tag.taxonomy.active,taxonomy:t.stats_tag.taxonomy.name,custom_html:!0,wpp_start:t.markup["wpp-start"],wpp_end:t.markup["wpp-end"],post_html:t.markup["post-html"],theme:e})}else a({theme:e})}}))}},{key:"render",value:function(){if(!this.state.taxonomies||!this.state.themes||!this.state.imgSizes)return React.createElement(v,null);var e=this.props,t=e.isSelected,a=e.className,s=e.attributes,r=a;return r+=this.state.editMode?" in-edit-mode":" in-preview-mode",r+=t?" is-selected":"",[this.getBlockControls(),React.createElement("div",{className:r},this.state.editMode&&React.createElement(d,null,this.getMainFields(),this.getFiltersFields(),this.getPostSettingsFields(),this.getStatsTagFields(),this.getHTMLMarkupFields()),!this.state.editMode&&React.createElement(g,null,React.createElement(u,{block:this.props.name,className:a,attributes:s})))]}}])&&n(t.prototype,a),c}(m),S=wp.blocks.registerBlockType,k=wp.i18n.__;S("wordpress-popular-posts/widget",{title:"WordPress Popular Posts",category:"widgets",icon:r.flame,description:k("A highly customizable block that displays your most popular posts.","wordpress-popular-posts"),keywords:["popular","posts","trending","popularity"],attributes:{_editMode:{type:"boolean",default:!0},title:{type:"string"},limit:{type:"number",default:10},offset:{type:"number",default:0},order_by:{type:"string",default:"views"},range:{type:"string",default:"last24hours"},time_quantity:{type:"number",default:24},time_unit:{type:"string",default:"hour"},freshness:{type:"boolean",default:!1},post_type:{type:"string",default:"post"},pid:{type:"string",default:""},author:{type:"string",default:""},tax:{type:"string",default:""},term_id:{type:"string",default:""},shorten_title:{type:"boolean",default:!1},title_length:{type:"number",default:0},title_by_words:{type:"number",default:0},display_post_excerpt:{type:"boolean",default:!1},excerpt_format:{type:"boolean",default:!1},excerpt_length:{type:"number",default:0},excerpt_by_words:{type:"number",default:0},display_post_thumbnail:{type:"boolean",default:!1},thumbnail_width:{type:"number",default:0},thumbnail_height:{type:"number",default:0},thumbnail_build:{type:"string",default:"manual"},thumbnail_size:{type:"string",default:""},stats_comments:{type:"boolean",default:!1},stats_views:{type:"boolean",default:!0},stats_author:{type:"boolean",default:!1},stats_date:{type:"boolean",default:!1},stats_date_format:{type:"string",default:"F j, Y"},stats_taxonomy:{type:"boolean",default:!1},taxonomy:{type:"string",default:""},custom_html:{type:"boolean",default:!1},header_start:{type:"string",default:"<h2>"},header_end:{type:"string",default:"</h2>"},wpp_start:{type:"string",default:'<ul class="wpp-list">'},wpp_end:{type:"string",default:"</ul>"},post_html:{type:"string",default:'<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>'},theme:{type:"string",default:""}},supports:{anchor:!0,align:!0,html:!1},example:{attributes:{_editMode:!1,title:"Popular Posts",limit:3,range:"last7days",display_post_excerpt:!0,excerpt_length:75,display_post_thumbnail:!0,thumbnail_width:75,thumbnail_height:75,stats_views:!1,stats_taxonomy:!0,custom_html:!0,wpp_start:'<ul class="wpp-list wpp-cards">',post_html:'<li>{thumb_img} <div class="wpp-item-data"><div class="taxonomies">{taxonomy}</div>{title} <p class="wpp-excerpt">{excerpt}</p></div></li>',theme:"cards"}},edit:C,save:function(){return null}})}]);
assets/js/wpp.js CHANGED
@@ -108,17 +108,18 @@ var WordPressPopularPosts = (function(){
108
  document.addEventListener('DOMContentLoaded', function() {
109
  var widget_placeholders = document.querySelectorAll('.wpp-widget-placeholder');
110
 
111
- if ( widget_placeholders.length ) {
112
- for( var w = 0; w < widget_placeholders.length; w++ ) {
113
- fetchWidget(widget_placeholders[w]);
114
- }
115
- } else {
116
- var sr = document.querySelectorAll('.popular-posts-sr');
117
 
118
- if ( sr.length ) {
119
- for( var s = 0; s < sr.length; s++ ) {
120
- WordPressPopularPosts.theme(sr[s]);
121
- }
 
 
 
 
 
 
122
  }
123
  }
124
 
108
  document.addEventListener('DOMContentLoaded', function() {
109
  var widget_placeholders = document.querySelectorAll('.wpp-widget-placeholder');
110
 
111
+ var w = 0;
 
 
 
 
 
112
 
113
+ while ( w < widget_placeholders.length ) {
114
+ fetchWidget(widget_placeholders[w]);
115
+ w++;
116
+ }
117
+
118
+ var sr = document.querySelectorAll('.popular-posts-sr');
119
+
120
+ if ( sr.length ) {
121
+ for( var s = 0; s < sr.length; s++ ) {
122
+ WordPressPopularPosts.theme(sr[s]);
123
  }
124
  }
125
 
assets/js/wpp.min.js CHANGED
@@ -1 +1,6 @@
1
- var wpp_params=null,WordPressPopularPosts=function(){"use strict";var a=function(){},b=!!HTMLElement.prototype.attachShadow,c=function(a,b,c,d){var e=new XMLHttpRequest,f=c;a=-1==["GET","POST"].indexOf(a)?"GET":a,e.open(a,b+("GET"==a?"?"+f:""),!0),"POST"==a&&e.setRequestHeader("Content-type","application/x-www-form-urlencoded"),e.setRequestHeader("X-Requested-With","XMLHttpRequest"),e.onreadystatechange=function(){4===e.readyState&&200<=e.status&&300>e.status&&"function"==typeof d&&d.call(void 0,e.response)},e.send("POST"==a?f:null)};return{get:function(b,d,e){e="function"==typeof e?e:a,c("GET",b,d,e)},post:function(b,d,e){e="function"==typeof e?e:a,c("POST",b,d,e)},ajax:c,theme:function(a){if(b){let b=document.createElement("style"),c=document.createElement("ul");c.innerHTML="<li><a href=\"#\"></a></li>",a.parentNode.appendChild(c);let d=getComputedStyle(c.querySelector("li")),e=getComputedStyle(c.querySelector("li a"));b.innerHTML=".wpp-list li {font-size: "+d.fontSize+"}",b.innerHTML+=".wpp-list li a {color: "+e.color+"}",a.parentNode.removeChild(c);let f=a.attachShadow({mode:"open"});for(f.append(b);a.firstElementChild;)f.append(a.firstElementChild)}}}}();(function(){try{var a=document.querySelector("script#wpp-json"),b=!0;if(wpp_params=JSON.parse(a.textContent),wpp_params.ID){if("1"==wpp_params.sampling_active){var c=Math.floor(Math.random()*wpp_params.sampling_rate)+1;b=1===c}b&&WordPressPopularPosts.post(wpp_params.ajax_url,"_wpnonce="+wpp_params.token+"&wpp_id="+wpp_params.ID+"&sampling="+wpp_params.sampling_active+"&sampling_rate="+wpp_params.sampling_rate,function(a){wpp_params.debug&&window.console&&window.console.log&&window.console.log(JSON.parse(a))})}}catch(a){console.error("WPP: Couldn't read JSON data")}})(),document.addEventListener("DOMContentLoaded",function(){function a(a){WordPressPopularPosts.get(wpp_params.ajax_url+"/widget/"+a.getAttribute("data-widget-id").split("-")[1],"is_single="+wpp_params.ID+(wpp_params.lang?"&lang="+wpp_params.lang:""),function(b){a.insertAdjacentHTML("afterend",JSON.parse(b).widget);let c=a.parentNode,d=c.querySelector(".popular-posts-sr");c.removeChild(a),d&&WordPressPopularPosts.theme(d);let e=null;"function"==typeof Event?e=new Event("wpp-onload",{bubbles:!0,cancelable:!1}):document.createEvent&&(e=document.createEvent("Event"),e.initEvent("wpp-onload",!0,!1)),e&&c.dispatchEvent(e)})}var b=document.querySelectorAll(".wpp-widget-placeholder");if(b.length)for(var c=0;c<b.length;c++)a(b[c]);else{var d=document.querySelectorAll(".popular-posts-sr");if(d.length)for(var e=0;e<d.length;e++)WordPressPopularPosts.theme(d[e])}});
 
 
 
 
 
1
+ var wpp_params=null,WordPressPopularPosts=function(){var g=function(){},e=!!HTMLElement.prototype.attachShadow,d=function(b,c,a,h){var f=new XMLHttpRequest;b=-1!=["GET","POST"].indexOf(b)?b:"GET";f.open(b,c+("GET"==b?"?"+a:""),!0);"POST"==b&&f.setRequestHeader("Content-type","application/x-www-form-urlencoded");f.setRequestHeader("X-Requested-With","XMLHttpRequest");f.onreadystatechange=function(){4===f.readyState&&200<=f.status&&300>f.status&&"function"===typeof h&&h.call(void 0,f.response)};f.send("POST"==
2
+ b?a:null)};return{get:function(b,c,a){a="function"===typeof a?a:g;d("GET",b,c,a)},post:function(b,c,a){a="function"===typeof a?a:g;d("POST",b,c,a)},ajax:d,theme:function(b){if(e){var c=document.createElement("style"),a=document.createElement("ul");a.innerHTML='<li><a href="#"></a></li>';b.parentNode.appendChild(a);var h=getComputedStyle(a.querySelector("li")),f=getComputedStyle(a.querySelector("li a"));c.innerHTML=".wpp-list li {font-size: "+h.fontSize+"}";c.innerHTML+=".wpp-list li a {color: "+f.color+
3
+ "}";b.parentNode.removeChild(a);a=b.attachShadow({mode:"open"});for(a.append(c);b.firstElementChild;)a.append(b.firstElementChild)}}}}();
4
+ (function(){try{var g=document.querySelector("script#wpp-json"),e=!0;wpp_params=JSON.parse(g.textContent);wpp_params.ID&&("1"==wpp_params.sampling_active&&(e=1===Math.floor(Math.random()*wpp_params.sampling_rate)+1),e&&WordPressPopularPosts.post(wpp_params.ajax_url,"_wpnonce="+wpp_params.token+"&wpp_id="+wpp_params.ID+"&sampling="+wpp_params.sampling_active+"&sampling_rate="+wpp_params.sampling_rate,function(d){wpp_params.debug&&window.console&&window.console.log&&window.console.log(JSON.parse(d))}))}catch(d){console.error("WPP: Couldn't read JSON data")}})();
5
+ document.addEventListener("DOMContentLoaded",function(){function g(b){WordPressPopularPosts.get(wpp_params.ajax_url+"/widget/"+b.getAttribute("data-widget-id").split("-")[1],"is_single="+wpp_params.ID+(wpp_params.lang?"&lang="+wpp_params.lang:""),function(c){b.insertAdjacentHTML("afterend",JSON.parse(c).widget);c=b.parentNode;var a=c.querySelector(".popular-posts-sr");c.removeChild(b);a&&WordPressPopularPosts.theme(a);a=null;"function"===typeof Event?a=new Event("wpp-onload",{bubbles:!0,cancelable:!1}):
6
+ document.createEvent&&(a=document.createEvent("Event"),a.initEvent("wpp-onload",!0,!1));a&&c.dispatchEvent(a)})}for(var e=document.querySelectorAll(".wpp-widget-placeholder"),d=0;d<e.length;)g(e[d]),d++;e=document.querySelectorAll(".popular-posts-sr");if(e.length)for(d=0;d<e.length;d++)WordPressPopularPosts.theme(e[d])});
assets/themes/cards-compact/style.css CHANGED
@@ -13,6 +13,11 @@
13
  border-bottom: #ddd 1px solid;
14
  }
15
 
 
 
 
 
 
16
  .wpp-cards-compact li:last-of-type,
17
  .wpp-cards-compact li:only-child {
18
  margin: 0;
13
  border-bottom: #ddd 1px solid;
14
  }
15
 
16
+ .in-preview-mode .wpp-cards-compact li {
17
+ margin: 0 0 1.2em 0;
18
+ padding: 0 0 1em 0;
19
+ }
20
+
21
  .wpp-cards-compact li:last-of-type,
22
  .wpp-cards-compact li:only-child {
23
  margin: 0;
assets/themes/cards/style.css CHANGED
@@ -12,6 +12,11 @@
12
  border-bottom: #ddd 1px solid;
13
  }
14
 
 
 
 
 
 
15
  .wpp-cards li:last-of-type,
16
  .wpp-cards li:only-child {
17
  margin: 0;
12
  border-bottom: #ddd 1px solid;
13
  }
14
 
15
+ .in-preview-mode .wpp-cards li {
16
+ margin: 0 0 1.2em 0;
17
+ padding: 0 0 1em 0;
18
+ }
19
+
20
  .wpp-cards li:last-of-type,
21
  .wpp-cards li:only-child {
22
  margin: 0;
assets/themes/cardview-compact/style.css CHANGED
@@ -11,6 +11,11 @@
11
  border-bottom: #ddd 1px solid;
12
  }
13
 
 
 
 
 
 
14
  .wpp-cardview-compact li:last-of-type,
15
  .wpp-cardview-compact li:only-child {
16
  margin: 0;
11
  border-bottom: #ddd 1px solid;
12
  }
13
 
14
+ .in-preview-mode .wpp-cardview-compact li {
15
+ margin: 0 0 1.2em 0;
16
+ padding: 0 0 1em 0;
17
+ }
18
+
19
  .wpp-cardview-compact li:last-of-type,
20
  .wpp-cardview-compact li:only-child {
21
  margin: 0;
assets/themes/cardview/style.css CHANGED
@@ -11,6 +11,11 @@
11
  border-bottom: #ddd 1px solid;
12
  }
13
 
 
 
 
 
 
14
  .wpp-cardview li:last-of-type,
15
  .wpp-cardview li:only-child {
16
  margin: 0;
11
  border-bottom: #ddd 1px solid;
12
  }
13
 
14
+ .in-preview-mode .wpp-cardview li {
15
+ margin: 0 0 1.2em 0;
16
+ padding: 0 0 1em 0;
17
+ }
18
+
19
  .wpp-cardview li:last-of-type,
20
  .wpp-cardview li:only-child {
21
  margin: 0;
assets/themes/evergreen/style.css CHANGED
@@ -20,6 +20,11 @@
20
  box-sizing: border-box;
21
  }
22
 
 
 
 
 
 
23
  .wpp-evergreen li .item-position::before {
24
  display: inline-block;
25
  flex: 1 0 0;
20
  box-sizing: border-box;
21
  }
22
 
23
+ .in-preview-mode .wpp-evergreen li {
24
+ margin: 0;
25
+ padding: 15px 15px 15px 0;
26
+ }
27
+
28
  .wpp-evergreen li .item-position::before {
29
  display: inline-block;
30
  flex: 1 0 0;
assets/themes/midnight/style.css CHANGED
@@ -20,6 +20,11 @@
20
  box-sizing: border-box;
21
  }
22
 
 
 
 
 
 
23
  .wpp-midnight li .item-position::before {
24
  display: inline-block;
25
  flex: 1 0 0;
20
  box-sizing: border-box;
21
  }
22
 
23
+ .in-preview-mode .wpp-midnight li {
24
+ margin: 0;
25
+ padding: 15px 15px 15px 0;
26
+ }
27
+
28
  .wpp-midnight li .item-position::before {
29
  display: inline-block;
30
  flex: 1 0 0;
assets/themes/sunrise/style.css CHANGED
@@ -20,6 +20,11 @@
20
  box-sizing: border-box;
21
  }
22
 
 
 
 
 
 
23
  .wpp-sunrise li .item-position::before {
24
  display: inline-block;
25
  flex: 1 0 0;
20
  box-sizing: border-box;
21
  }
22
 
23
+ .in-preview-mode .wpp-sunrise li {
24
+ margin: 0;
25
+ padding: 15px 15px 15px 0;
26
+ }
27
+
28
  .wpp-sunrise li .item-position::before {
29
  display: inline-block;
30
  flex: 1 0 0;
assets/themes/sunset/style.css CHANGED
@@ -20,6 +20,11 @@
20
  box-sizing: border-box;
21
  }
22
 
 
 
 
 
 
23
  .wpp-sunset li .item-position::before {
24
  display: inline-block;
25
  flex: 1 0 0;
20
  box-sizing: border-box;
21
  }
22
 
23
+ .in-preview-mode .wpp-sunset li {
24
+ margin: 0;
25
+ padding: 15px 15px 15px 0;
26
+ }
27
+
28
  .wpp-sunset li .item-position::before {
29
  display: inline-block;
30
  flex: 1 0 0;
assets/themes/tiles/style.css CHANGED
@@ -11,6 +11,11 @@
11
  padding: 0;
12
  }
13
 
 
 
 
 
 
14
  .wpp-tiles li:last-of-type {
15
  margin: 0;
16
  }
11
  padding: 0;
12
  }
13
 
14
+ .in-preview-mode .wpp-tiles li {
15
+ margin: 0 0 1.2em 0;
16
+ padding: 0;
17
+ }
18
+
19
  .wpp-tiles li:last-of-type {
20
  margin: 0;
21
  }
assets/themes/tiny/style.css CHANGED
@@ -10,6 +10,11 @@
10
  padding: 0;
11
  }
12
 
 
 
 
 
 
13
  .wpp-tiny li:last-of-type {
14
  margin: 0;
15
  }
10
  padding: 0;
11
  }
12
 
13
+ .in-preview-mode .wpp-tiny li {
14
+ margin: 0 0 1.2em 0;
15
+ padding: 0;
16
+ }
17
+
18
  .wpp-tiny li:last-of-type {
19
  margin: 0;
20
  }
i18n/wordpress-popular-posts.pot CHANGED
@@ -5,7 +5,7 @@ msgid ""
5
  msgstr ""
6
  "Project-Id-Version: WordPress Popular Posts\n"
7
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/wordpress-popular-posts\n"
8
- "POT-Creation-Date: 2020-10-12 13:04-0400\n"
9
  "PO-Revision-Date: 2015-04-24 13:30-0430\n"
10
  "Last-Translator: Héctor Cabrera <hcabrerab@gmail.com>\n"
11
  "Language-Team: Héctor Cabrera <me@cabrerahector.com>\n"
@@ -14,7 +14,7 @@ msgstr ""
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
- "X-Generator: Poedit 2.4.1\n"
18
  "X-Poedit-KeywordsList: _e;__;__ngettext;__ngettext_noop;_n_noop;_x;_nx;_nx_noop;_ex;"
19
  "esc_attr__;esc_attr_e;esc_attr_x;esc_html__;esc_html_e;esc_html_x;_c;_nc;_n:1,2\n"
20
  "X-Poedit-Basepath: .\n"
@@ -22,6 +22,304 @@ msgstr ""
22
  "X-Poedit-SearchPath-0: .\n"
23
  "X-Poedit-SearchPath-1: ..\n"
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  #: ../src/Admin/Admin.php:371
26
  #, php-format
27
  msgid "%s view in the last hour"
@@ -29,7 +327,7 @@ msgid_plural "%s views in the last hour"
29
  msgstr[0] ""
30
  msgstr[1] ""
31
 
32
- #: ../src/Admin/Admin.php:405 ../src/Admin/admin-page.php:349
33
  msgid "Trending now"
34
  msgstr ""
35
 
@@ -72,49 +370,45 @@ msgid ""
72
  "a></li><li><a href=\"%2$s\">Support</a></li></ul>"
73
  msgstr ""
74
 
75
- #: ../src/Admin/Admin.php:622
76
  msgid "Settings"
77
  msgstr ""
78
 
79
- #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1088 ../src/Admin/Admin.php:1092
80
- #: ../src/Output.php:757
 
 
 
 
81
  #, php-format
82
  msgid "%s view"
83
  msgid_plural "%s views"
84
  msgstr[0] ""
85
  msgstr[1] ""
86
 
87
- #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1090 ../src/Admin/Admin.php:1092
88
- #: ../src/Output.php:740
89
  #, php-format
90
  msgid "%s comment"
91
  msgid_plural "%s comments"
92
  msgstr[0] ""
93
  msgstr[1] ""
94
 
95
- #: ../src/Admin/Admin.php:720 ../src/Widget/form.php:21
96
- msgid "Comments"
97
- msgstr ""
98
-
99
- #: ../src/Admin/Admin.php:724
100
  msgid "Views"
101
  msgstr ""
102
 
103
- #: ../src/Admin/Admin.php:1094
104
  msgid "View"
105
  msgstr ""
106
 
107
- #: ../src/Admin/Admin.php:1094
108
- msgid "Edit"
109
- msgstr ""
110
-
111
- #: ../src/Admin/Admin.php:1105
112
  msgid ""
113
  "Looks like your site's activity is a little low right now. <br />Spread the word and "
114
  "come back later!"
115
  msgstr ""
116
 
117
- #: ../src/Admin/Admin.php:1367
118
  #, php-format
119
  msgid ""
120
  "<strong>WordPress Popular Posts:</strong> It seems your site is popular (great!) You "
@@ -122,159 +416,124 @@ msgid ""
122
  "performance stays up to par."
123
  msgstr ""
124
 
125
- #: ../src/Admin/admin-page.php:6 ../src/Admin/admin-page.php:240
126
  msgid "Stats"
127
  msgstr ""
128
 
129
- #: ../src/Admin/admin-page.php:7 ../src/Admin/admin-page.php:241
130
  msgid "Tools"
131
  msgstr ""
132
 
133
- #: ../src/Admin/admin-page.php:8 ../src/Admin/admin-page.php:242
134
  msgid "Parameters"
135
  msgstr ""
136
 
137
- #: ../src/Admin/admin-page.php:30 ../src/Admin/admin-page.php:41
138
- #: ../src/Admin/admin-page.php:67 ../src/Admin/admin-page.php:103
139
  msgid "Settings saved."
140
  msgstr ""
141
 
142
- #: ../src/Admin/admin-page.php:52
143
  msgid "Please provide the name of your custom field."
144
  msgstr ""
145
 
146
- #: ../src/Admin/admin-page.php:121
147
  msgid ""
148
  "This operation will delete all entries from WordPress Popular Posts' cache table and "
149
  "cannot be undone."
150
  msgstr ""
151
 
152
- #: ../src/Admin/admin-page.php:121 ../src/Admin/admin-page.php:160
153
- #: ../src/Admin/admin-page.php:199
154
  msgid "Do you want to continue?"
155
  msgstr ""
156
 
157
- #: ../src/Admin/admin-page.php:133
158
  msgid "Success! The cache table has been cleared!"
159
  msgstr ""
160
 
161
- #: ../src/Admin/admin-page.php:137
162
  msgid "Error: cache table does not exist."
163
  msgstr ""
164
 
165
- #: ../src/Admin/admin-page.php:141 ../src/Admin/admin-page.php:149
166
- #: ../src/Admin/admin-page.php:180 ../src/Admin/admin-page.php:188
167
- #: ../src/Admin/admin-page.php:218 ../src/Admin/admin-page.php:226
168
  msgid "Invalid action."
169
  msgstr ""
170
 
171
- #: ../src/Admin/admin-page.php:145 ../src/Admin/admin-page.php:184
172
- #: ../src/Admin/admin-page.php:222
173
  msgid ""
174
  "Sorry, you do not have enough permissions to do this. Please contact the site "
175
  "administrator for support."
176
  msgstr ""
177
 
178
- #: ../src/Admin/admin-page.php:160
179
  msgid ""
180
  "This operation will delete all stored info from WordPress Popular Posts' data tables "
181
  "and cannot be undone."
182
  msgstr ""
183
 
184
- #: ../src/Admin/admin-page.php:172
185
  msgid "Success! All data have been cleared!"
186
  msgstr ""
187
 
188
- #: ../src/Admin/admin-page.php:176
189
  msgid "Error: one or both data tables are missing."
190
  msgstr ""
191
 
192
- #: ../src/Admin/admin-page.php:199
193
  msgid "This operation will delete all cached thumbnails and cannot be undone."
194
  msgstr ""
195
 
196
- #: ../src/Admin/admin-page.php:210
197
  msgid "Success! All files have been deleted!"
198
  msgstr ""
199
 
200
- #: ../src/Admin/admin-page.php:214
201
  msgid "The thumbnail cache is already empty!"
202
  msgstr ""
203
 
204
- #: ../src/Admin/admin-page.php:239
205
  msgid "Menu"
206
  msgstr ""
207
 
208
- #: ../src/Admin/admin-page.php:266
209
  msgid "Post type"
210
  msgstr ""
211
 
212
- #: ../src/Admin/admin-page.php:269
213
- msgid "Limit"
214
- msgstr ""
215
-
216
- #: ../src/Admin/admin-page.php:272 ../src/Widget/form.php:52
217
- msgid "Display only posts published within the selected Time Range"
218
- msgstr ""
219
-
220
- #: ../src/Admin/admin-page.php:278 ../src/Admin/admin-page.php:310
221
- #: ../src/Admin/admin-page.php:462 ../src/Admin/admin-page.php:569
222
- #: ../src/Admin/admin-page.php:609
223
  msgid "Apply"
224
  msgstr ""
225
 
226
- #: ../src/Admin/admin-page.php:279 ../src/Admin/admin-page.php:313
227
  msgid "Cancel"
228
  msgstr ""
229
 
230
- #: ../src/Admin/admin-page.php:288
231
  msgid "Custom Time Range"
232
  msgstr ""
233
 
234
- #: ../src/Admin/admin-page.php:289
235
  msgid "Date Range"
236
  msgstr ""
237
 
238
- #: ../src/Admin/admin-page.php:296 ../src/Admin/admin-page.php:535
239
- #: ../src/Widget/form.php:45
240
- msgid "Minute(s)"
241
- msgstr ""
242
-
243
- #: ../src/Admin/admin-page.php:297 ../src/Admin/admin-page.php:536
244
- #: ../src/Widget/form.php:46
245
- msgid "Hour(s)"
246
- msgstr ""
247
-
248
- #: ../src/Admin/admin-page.php:298 ../src/Admin/admin-page.php:537
249
- #: ../src/Widget/form.php:47
250
- msgid "Day(s)"
251
- msgstr ""
252
-
253
- #: ../src/Admin/admin-page.php:303
254
  msgid "Select a date..."
255
  msgstr ""
256
 
257
- #: ../src/Admin/admin-page.php:323
258
  msgid "Today"
259
  msgstr ""
260
 
261
- #: ../src/Admin/admin-page.php:324 ../src/Widget/form.php:34
262
  msgid "Last 24 hours"
263
  msgstr ""
264
 
265
- #: ../src/Admin/admin-page.php:325 ../src/Widget/form.php:35
266
- msgid "Last 7 days"
267
- msgstr ""
268
-
269
- #: ../src/Admin/admin-page.php:326 ../src/Widget/form.php:36
270
- msgid "Last 30 days"
271
- msgstr ""
272
-
273
- #: ../src/Admin/admin-page.php:327 ../src/Widget/form.php:38
274
- msgid "Custom"
275
- msgstr ""
276
-
277
- #: ../src/Admin/admin-page.php:331
278
  #, php-format
279
  msgid ""
280
  "Err... A nice little chart is supposed to be here, instead you are seeing this because "
@@ -282,196 +541,196 @@ msgid ""
282
  "browser</a>."
283
  msgstr ""
284
 
285
- #: ../src/Admin/admin-page.php:347
286
  msgid "Most viewed"
287
  msgstr ""
288
 
289
- #: ../src/Admin/admin-page.php:348
290
  msgid "Most commented"
291
  msgstr ""
292
 
293
- #: ../src/Admin/admin-page.php:350
294
  msgid "Hall of Fame"
295
  msgstr ""
296
 
297
- #: ../src/Admin/admin-page.php:390
298
  msgid "Thumbnails"
299
  msgstr ""
300
 
301
- #: ../src/Admin/admin-page.php:396
302
  msgid "Default thumbnail"
303
  msgstr ""
304
 
305
- #: ../src/Admin/admin-page.php:402
306
  msgid "Change thumbnail"
307
  msgstr ""
308
 
309
- #: ../src/Admin/admin-page.php:405
310
  msgid "This image will be displayed when no thumbnail is available"
311
  msgstr ""
312
 
313
- #: ../src/Admin/admin-page.php:409
314
  msgid "Pick image from"
315
  msgstr ""
316
 
317
- #: ../src/Admin/admin-page.php:412
318
  msgid "Featured image"
319
  msgstr ""
320
 
321
- #: ../src/Admin/admin-page.php:413
322
  msgid "First image on post"
323
  msgstr ""
324
 
325
- #: ../src/Admin/admin-page.php:414
326
  msgid "First attachment"
327
  msgstr ""
328
 
329
- #: ../src/Admin/admin-page.php:415
330
  msgid "Custom field"
331
  msgstr ""
332
 
333
- #: ../src/Admin/admin-page.php:418
334
  msgid "Tell WordPress Popular Posts where it should get thumbnails from"
335
  msgstr ""
336
 
337
- #: ../src/Admin/admin-page.php:422
338
  msgid "Lazy load"
339
  msgstr ""
340
 
341
- #: ../src/Admin/admin-page.php:422 ../src/Admin/admin-page.php:519
342
- #: ../src/Admin/admin-page.php:547 ../src/Widget/form.php:7 ../src/Widget/form.php:54
343
  #: ../src/Widget/form.php:60 ../src/Widget/form.php:88 ../src/Widget/form.php:98
344
  #: ../src/Widget/form.php:190
345
  msgid "What is this?"
346
  msgstr ""
347
 
348
- #: ../src/Admin/admin-page.php:425
349
  msgid "No"
350
  msgstr ""
351
 
352
- #: ../src/Admin/admin-page.php:426 ../src/Admin/admin-page.php:441
353
  msgid "Yes"
354
  msgstr ""
355
 
356
- #: ../src/Admin/admin-page.php:431
357
  msgid "Custom field name"
358
  msgstr ""
359
 
360
- #: ../src/Admin/admin-page.php:437
361
  msgid "Resize image from Custom field?"
362
  msgstr ""
363
 
364
- #: ../src/Admin/admin-page.php:440
365
  msgid "No, use image as is"
366
  msgstr ""
367
 
368
- #: ../src/Admin/admin-page.php:452
369
  msgid "Empty image cache"
370
  msgstr ""
371
 
372
- #: ../src/Admin/admin-page.php:453
373
  msgid "Use this button to clear WPP's thumbnails cache"
374
  msgstr ""
375
 
376
- #: ../src/Admin/admin-page.php:473
377
  msgid "Data"
378
  msgstr ""
379
 
380
- #: ../src/Admin/admin-page.php:479
381
  msgid "Log views from"
382
  msgstr ""
383
 
384
- #: ../src/Admin/admin-page.php:482
385
  msgid "Visitors only"
386
  msgstr ""
387
 
388
- #: ../src/Admin/admin-page.php:483
389
  msgid "Logged-in users only"
390
  msgstr ""
391
 
392
- #: ../src/Admin/admin-page.php:484
393
  msgid "Everyone"
394
  msgstr ""
395
 
396
- #: ../src/Admin/admin-page.php:490
397
  msgid "Log limit"
398
  msgstr ""
399
 
400
- #: ../src/Admin/admin-page.php:493 ../src/Admin/admin-page.php:510
401
- #: ../src/Admin/admin-page.php:550 ../src/Admin/admin-page.php:600
402
  msgid "Disabled"
403
  msgstr ""
404
 
405
- #: ../src/Admin/admin-page.php:494
406
  msgid "Keep data for"
407
  msgstr ""
408
 
409
- #: ../src/Admin/admin-page.php:498
410
  msgid "day(s)"
411
  msgstr ""
412
 
413
- #: ../src/Admin/admin-page.php:501
414
  msgid "Data older than the specified time frame will be automatically discarded"
415
  msgstr ""
416
 
417
- #: ../src/Admin/admin-page.php:507
418
  msgid "Ajaxify widget"
419
  msgstr ""
420
 
421
- #: ../src/Admin/admin-page.php:511 ../src/Admin/admin-page.php:551
422
- #: ../src/Admin/admin-page.php:599
423
  msgid "Enabled"
424
  msgstr ""
425
 
426
- #: ../src/Admin/admin-page.php:515
427
  msgid ""
428
  "If you are using a caching plugin such as WP Super Cache, enabling this feature will "
429
  "keep the popular list from being cached by it"
430
  msgstr ""
431
 
432
- #: ../src/Admin/admin-page.php:519
433
  msgid "Data Caching"
434
  msgstr ""
435
 
436
- #: ../src/Admin/admin-page.php:522
437
  msgid "Never cache"
438
  msgstr ""
439
 
440
- #: ../src/Admin/admin-page.php:523
441
  msgid "Enable caching"
442
  msgstr ""
443
 
444
- #: ../src/Admin/admin-page.php:527
445
  msgid ""
446
  "WPP can cache the popular list for a specified amount of time. Recommended for large / "
447
  "high traffic sites"
448
  msgstr ""
449
 
450
- #: ../src/Admin/admin-page.php:531
451
  msgid "Refresh cache every"
452
  msgstr ""
453
 
454
- #: ../src/Admin/admin-page.php:538
455
  msgid "Week(s)"
456
  msgstr ""
457
 
458
- #: ../src/Admin/admin-page.php:539
459
  msgid "Month(s)"
460
  msgstr ""
461
 
462
- #: ../src/Admin/admin-page.php:540
463
  msgid "Year(s)"
464
  msgstr ""
465
 
466
- #: ../src/Admin/admin-page.php:543
467
  msgid "Really? That long?"
468
  msgstr ""
469
 
470
- #: ../src/Admin/admin-page.php:547
471
  msgid "Data Sampling"
472
  msgstr ""
473
 
474
- #: ../src/Admin/admin-page.php:555
475
  #, php-format
476
  msgid ""
477
  "By default, WordPress Popular Posts stores in database every single visit your site "
@@ -482,38 +741,38 @@ msgid ""
482
  "(for more, <a href=\"%2$s\" target=\"_blank\">please read here</a>)"
483
  msgstr ""
484
 
485
- #: ../src/Admin/admin-page.php:559
486
  msgid "Sample Rate"
487
  msgstr ""
488
 
489
- #: ../src/Admin/admin-page.php:563
490
  #, php-format
491
  msgid ""
492
  "A sampling rate of %d is recommended for large / high traffic sites. For lower traffic "
493
  "sites, you should lower the value"
494
  msgstr ""
495
 
496
- #: ../src/Admin/admin-page.php:580
497
  msgid "Miscellaneous"
498
  msgstr ""
499
 
500
- #: ../src/Admin/admin-page.php:586
501
  msgid "Open links in"
502
  msgstr ""
503
 
504
- #: ../src/Admin/admin-page.php:589
505
  msgid "Current window"
506
  msgstr ""
507
 
508
- #: ../src/Admin/admin-page.php:590
509
  msgid "New tab/window"
510
  msgstr ""
511
 
512
- #: ../src/Admin/admin-page.php:596
513
  msgid "Use plugin's stylesheet"
514
  msgstr ""
515
 
516
- #: ../src/Admin/admin-page.php:603
517
  msgid ""
518
  "By default, the plugin includes a stylesheet called wpp.css which you can use to style "
519
  "your popular posts listing. If you wish to use your own stylesheet or do not want it "
@@ -521,6 +780,10 @@ msgid ""
521
  msgstr ""
522
 
523
  #: ../src/Admin/admin-page.php:623
 
 
 
 
524
  msgid ""
525
  "WordPress Popular Posts maintains data in two separate tables: one for storing the "
526
  "most popular entries on a daily basis (from now on, \"cache\"), and another one to "
@@ -529,23 +792,23 @@ msgid ""
529
  "tables, please use the buttons below to do so."
530
  msgstr ""
531
 
532
- #: ../src/Admin/admin-page.php:624
533
  msgid "Empty cache"
534
  msgstr ""
535
 
536
- #: ../src/Admin/admin-page.php:624
537
  msgid "Use this button to manually clear entries from WPP cache only"
538
  msgstr ""
539
 
540
- #: ../src/Admin/admin-page.php:625
541
  msgid "Clear all data"
542
  msgstr ""
543
 
544
- #: ../src/Admin/admin-page.php:625
545
  msgid "Use this button to manually clear entries from all WPP data tables"
546
  msgstr ""
547
 
548
- #: ../src/Admin/admin-page.php:633
549
  #, php-format
550
  msgid ""
551
  "With the following parameters you can customize the popular posts list when using "
@@ -553,490 +816,483 @@ msgid ""
553
  "\"%2$s\">[wpp] shortcode</a>."
554
  msgstr ""
555
 
556
- #: ../src/Admin/admin-page.php:643
557
  msgid "Parameter"
558
  msgstr ""
559
 
560
- #: ../src/Admin/admin-page.php:644
561
  msgid "What it does "
562
  msgstr ""
563
 
564
- #: ../src/Admin/admin-page.php:645
565
  msgid "Possible values"
566
  msgstr ""
567
 
568
- #: ../src/Admin/admin-page.php:646
569
  msgid "Defaults to"
570
  msgstr ""
571
 
572
- #: ../src/Admin/admin-page.php:647
573
  msgid "Example"
574
  msgstr ""
575
 
576
- #: ../src/Admin/admin-page.php:653
577
  msgid "Sets a heading for the list"
578
  msgstr ""
579
 
580
- #: ../src/Admin/admin-page.php:654 ../src/Admin/admin-page.php:661
581
- #: ../src/Admin/admin-page.php:668 ../src/Admin/admin-page.php:717
582
- #: ../src/Admin/admin-page.php:724 ../src/Admin/admin-page.php:731
583
- #: ../src/Admin/admin-page.php:738 ../src/Admin/admin-page.php:745
584
- #: ../src/Admin/admin-page.php:752 ../src/Admin/admin-page.php:843
585
- #: ../src/Admin/admin-page.php:864 ../src/Admin/admin-page.php:871
586
- msgid "Text string"
587
- msgstr ""
588
-
589
- #: ../src/Admin/admin-page.php:655 ../src/Admin/admin-page.php:725
590
- #: ../src/Admin/admin-page.php:732 ../src/Admin/admin-page.php:739
591
  #: ../src/Admin/admin-page.php:746 ../src/Admin/admin-page.php:753
592
- #: ../src/Widget/form.php:226
593
- msgid "None"
 
 
594
  msgstr ""
595
 
596
- #: ../src/Admin/admin-page.php:656 ../src/Admin/admin-page.php:663
597
- #: ../src/Admin/admin-page.php:670 ../src/Admin/admin-page.php:677
598
- #: ../src/Admin/admin-page.php:684 ../src/Admin/admin-page.php:691
599
- #: ../src/Admin/admin-page.php:698 ../src/Admin/admin-page.php:705
600
- #: ../src/Admin/admin-page.php:712 ../src/Admin/admin-page.php:719
601
- #: ../src/Admin/admin-page.php:726 ../src/Admin/admin-page.php:733
602
- #: ../src/Admin/admin-page.php:740 ../src/Admin/admin-page.php:747
603
- #: ../src/Admin/admin-page.php:754 ../src/Admin/admin-page.php:761
604
- #: ../src/Admin/admin-page.php:768 ../src/Admin/admin-page.php:775
605
- #: ../src/Admin/admin-page.php:782 ../src/Admin/admin-page.php:789
606
- #: ../src/Admin/admin-page.php:796 ../src/Admin/admin-page.php:803
607
- #: ../src/Admin/admin-page.php:810 ../src/Admin/admin-page.php:817
608
- #: ../src/Admin/admin-page.php:824 ../src/Admin/admin-page.php:831
609
- #: ../src/Admin/admin-page.php:838 ../src/Admin/admin-page.php:845
610
- #: ../src/Admin/admin-page.php:852 ../src/Admin/admin-page.php:859
611
- #: ../src/Admin/admin-page.php:866 ../src/Admin/admin-page.php:873
612
- #: ../src/Admin/admin-page.php:880
613
  msgid "With wpp_get_mostpopular():"
614
  msgstr ""
615
 
616
- #: ../src/Admin/admin-page.php:656 ../src/Admin/admin-page.php:663
617
- #: ../src/Admin/admin-page.php:670 ../src/Admin/admin-page.php:677
618
- #: ../src/Admin/admin-page.php:684 ../src/Admin/admin-page.php:691
619
- #: ../src/Admin/admin-page.php:698 ../src/Admin/admin-page.php:705
620
- #: ../src/Admin/admin-page.php:712 ../src/Admin/admin-page.php:719
621
- #: ../src/Admin/admin-page.php:726 ../src/Admin/admin-page.php:733
622
- #: ../src/Admin/admin-page.php:740 ../src/Admin/admin-page.php:747
623
- #: ../src/Admin/admin-page.php:754 ../src/Admin/admin-page.php:761
624
- #: ../src/Admin/admin-page.php:768 ../src/Admin/admin-page.php:775
625
- #: ../src/Admin/admin-page.php:782 ../src/Admin/admin-page.php:789
626
- #: ../src/Admin/admin-page.php:796 ../src/Admin/admin-page.php:803
627
- #: ../src/Admin/admin-page.php:810 ../src/Admin/admin-page.php:817
628
- #: ../src/Admin/admin-page.php:824 ../src/Admin/admin-page.php:831
629
- #: ../src/Admin/admin-page.php:838 ../src/Admin/admin-page.php:845
630
- #: ../src/Admin/admin-page.php:852 ../src/Admin/admin-page.php:859
631
- #: ../src/Admin/admin-page.php:866 ../src/Admin/admin-page.php:873
632
- #: ../src/Admin/admin-page.php:880
633
  msgid "With the [wpp] shortcode:"
634
  msgstr ""
635
 
636
- #: ../src/Admin/admin-page.php:660
637
  msgid "Set the opening tag for the heading of the list"
638
  msgstr ""
639
 
640
- #: ../src/Admin/admin-page.php:667
641
  msgid "Set the closing tag for the heading of the list"
642
  msgstr ""
643
 
644
- #: ../src/Admin/admin-page.php:674
645
  msgid "Sets the maximum number of popular posts to be shown on the listing"
646
  msgstr ""
647
 
648
- #: ../src/Admin/admin-page.php:675 ../src/Admin/admin-page.php:689
649
- #: ../src/Admin/admin-page.php:759 ../src/Admin/admin-page.php:773
650
- #: ../src/Admin/admin-page.php:794 ../src/Admin/admin-page.php:801
651
  msgid "Positive integer"
652
  msgstr ""
653
 
654
- #: ../src/Admin/admin-page.php:681
655
  msgid ""
656
  "Tells WordPress Popular Posts to retrieve the most popular entries within the time "
657
  "range specified by you"
658
  msgstr ""
659
 
660
- #: ../src/Admin/admin-page.php:688
661
  msgid "Especifies the number of time units of the custom time range"
662
  msgstr ""
663
 
664
- #: ../src/Admin/admin-page.php:695
665
  msgid "Especifies the time unit of the custom time range"
666
  msgstr ""
667
 
668
- #: ../src/Admin/admin-page.php:702
669
  msgid ""
670
  "Tells WordPress Popular Posts to retrieve the most popular entries published within "
671
  "the time range specified by you"
672
  msgstr ""
673
 
674
- #: ../src/Admin/admin-page.php:709
675
  msgid "Sets the sorting option of the popular posts"
676
  msgstr ""
677
 
678
- #: ../src/Admin/admin-page.php:710
679
  msgid "(for average views per day)"
680
  msgstr ""
681
 
682
- #: ../src/Admin/admin-page.php:716
683
  msgid "Defines the type of posts to show on the listing"
684
  msgstr ""
685
 
686
- #: ../src/Admin/admin-page.php:723
687
  msgid ""
688
  "If set, WordPress Popular Posts will exclude the specified post(s) ID(s) form the "
689
  "listing."
690
  msgstr ""
691
 
692
- #: ../src/Admin/admin-page.php:730
693
  msgid ""
694
  "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
695
  "category ID(s). If a minus sign is used, entries associated to the category will be "
696
  "excluded instead."
697
  msgstr ""
698
 
699
- #: ../src/Admin/admin-page.php:737
700
  msgid "If set, WordPress Popular Posts will filter posts by a given taxonomy."
701
  msgstr ""
702
 
703
- #: ../src/Admin/admin-page.php:744
704
  msgid ""
705
  "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
706
  "term ID(s). If a minus sign is used, entries associated to the term(s) will be "
707
  "excluded instead."
708
  msgstr ""
709
 
710
- #: ../src/Admin/admin-page.php:751
711
  msgid ""
712
  "If set, WordPress Popular Posts will retrieve all entries created by specified "
713
  "author(s) ID(s)."
714
  msgstr ""
715
 
716
- #: ../src/Admin/admin-page.php:758
717
  msgid ""
718
  "If set, WordPress Popular Posts will shorten each post title to \"n\" characters "
719
  "whenever possible"
720
  msgstr ""
721
 
722
- #: ../src/Admin/admin-page.php:765
723
  msgid ""
724
  "If set to 1, WordPress Popular Posts will shorten each post title to \"n\" words "
725
  "instead of characters"
726
  msgstr ""
727
 
728
- #: ../src/Admin/admin-page.php:772
729
  msgid ""
730
  "If set, WordPress Popular Posts will build and include an excerpt of \"n\" characters "
731
  "long from the content of each post listed as popular"
732
  msgstr ""
733
 
734
- #: ../src/Admin/admin-page.php:779
735
  msgid ""
736
  "If set, WordPress Popular Posts will maintaing all styling tags (strong, italic, etc) "
737
  "and hyperlinks found in the excerpt"
738
  msgstr ""
739
 
740
- #: ../src/Admin/admin-page.php:786
741
  msgid ""
742
  "If set to 1, WordPress Popular Posts will shorten the excerpt to \"n\" words instead "
743
  "of characters"
744
  msgstr ""
745
 
746
- #: ../src/Admin/admin-page.php:793
747
  msgid ""
748
  "If set, and if your current server configuration allows it, you will be able to "
749
  "display thumbnails of your posts. This attribute sets the width for thumbnails"
750
  msgstr ""
751
 
752
- #: ../src/Admin/admin-page.php:800
753
  msgid ""
754
  "If set, and if your current server configuration allows it, you will be able to "
755
  "display thumbnails of your posts. This attribute sets the height for thumbnails"
756
  msgstr ""
757
 
758
- #: ../src/Admin/admin-page.php:807
759
  msgid ""
760
  "If set, and if the WP-PostRatings plugin is installed and enabled on your blog, "
761
  "WordPress Popular Posts will show how your visitors are rating your entries"
762
  msgstr ""
763
 
764
- #: ../src/Admin/admin-page.php:814
765
  msgid ""
766
  "If set, WordPress Popular Posts will show how many comments each popular post has got "
767
  "during the specified time range"
768
  msgstr ""
769
 
770
- #: ../src/Admin/admin-page.php:821
771
  msgid ""
772
  "If set, WordPress Popular Posts will show how many views each popular post has got "
773
  "during the specified time range"
774
  msgstr ""
775
 
776
- #: ../src/Admin/admin-page.php:828
777
  msgid ""
778
  "If set, WordPress Popular Posts will show who published each popular post on the list"
779
  msgstr ""
780
 
781
- #: ../src/Admin/admin-page.php:835
782
  msgid ""
783
  "If set, WordPress Popular Posts will display the date when each popular post on the "
784
  "list was published"
785
  msgstr ""
786
 
787
- #: ../src/Admin/admin-page.php:842
788
  msgid "Sets the date format"
789
  msgstr ""
790
 
791
- #: ../src/Admin/admin-page.php:849
792
  msgid ""
793
  "If set, WordPress Popular Posts will display the categories associated to each entry"
794
  msgstr ""
795
 
796
- #: ../src/Admin/admin-page.php:856
797
  msgid ""
798
  "If set, WordPress Popular Posts will display the taxonomies associated to each entry"
799
  msgstr ""
800
 
801
- #: ../src/Admin/admin-page.php:863
802
  msgid "Sets the opening tag for the listing"
803
  msgstr ""
804
 
805
- #: ../src/Admin/admin-page.php:870
806
  msgid "Sets the closing tag for the listing"
807
  msgstr ""
808
 
809
- #: ../src/Admin/admin-page.php:877
810
  msgid "Sets the HTML structure of each post"
811
  msgstr ""
812
 
813
- #: ../src/Admin/admin-page.php:878
814
  msgid "Text string, custom HTML"
815
  msgstr ""
816
 
817
- #: ../src/Admin/admin-page.php:878
818
  msgid "Available Content Tags"
819
  msgstr ""
820
 
821
- #: ../src/Admin/admin-page.php:878
822
  msgid ""
823
  "returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height"
824
  msgstr ""
825
 
826
- #: ../src/Admin/admin-page.php:878
827
  msgid ""
828
  "returns thumbnail image without linking to post/page, requires thumbnail_width & "
829
  "thumbnail_height"
830
  msgstr ""
831
 
832
- #: ../src/Admin/admin-page.php:878
833
  msgid "returns thumbnail url, requires thumbnail_width & thumbnail_height"
834
  msgstr ""
835
 
836
- #: ../src/Admin/admin-page.php:878
837
  msgid "returns linked post/page title"
838
  msgstr ""
839
 
840
- #: ../src/Admin/admin-page.php:878
841
  msgid "returns the post/page ID"
842
  msgstr ""
843
 
844
- #: ../src/Admin/admin-page.php:878
845
  msgid "returns post/page excerpt, and requires excerpt_length to be greater than 0"
846
  msgstr ""
847
 
848
- #: ../src/Admin/admin-page.php:878
849
  msgid "returns the default stats tags"
850
  msgstr ""
851
 
852
- #: ../src/Admin/admin-page.php:878
853
  msgid "returns post/page current rating, requires WP-PostRatings installed and enabled"
854
  msgstr ""
855
 
856
- #: ../src/Admin/admin-page.php:878
857
  msgid ""
858
  "returns post/page current rating as an integer, requires WP-PostRatings installed and "
859
  "enabled"
860
  msgstr ""
861
 
862
- #: ../src/Admin/admin-page.php:878
863
  msgid "returns the URL of the post/page"
864
  msgstr ""
865
 
866
- #: ../src/Admin/admin-page.php:878
867
  msgid "returns post/page title, no link"
868
  msgstr ""
869
 
870
- #: ../src/Admin/admin-page.php:878
871
  msgid "similar to text_title, sanitized for use in title/alt attributes"
872
  msgstr ""
873
 
874
- #: ../src/Admin/admin-page.php:878
875
  msgid "returns linked author name, requires stats_author=1"
876
  msgstr ""
877
 
878
- #: ../src/Admin/admin-page.php:878
879
  msgid "returns linked author name with copy, requires stats_author=1"
880
  msgstr ""
881
 
882
- #: ../src/Admin/admin-page.php:878
883
  msgid "returns linked category name, requires stats_category=1"
884
  msgstr ""
885
 
886
- #: ../src/Admin/admin-page.php:878
887
  msgid "returns linked category name with copy, requires stats_category=1"
888
  msgstr ""
889
 
890
- #: ../src/Admin/admin-page.php:878
891
  msgid "returns linked taxonomy names, requires stats_taxonomy=1"
892
  msgstr ""
893
 
894
- #: ../src/Admin/admin-page.php:878
895
  msgid "returns linked taxonomy names with copy, requires stats_taxonomy=1"
896
  msgstr ""
897
 
898
- #: ../src/Admin/admin-page.php:878
899
  msgid "returns views count only, no text, requires stats_views=1"
900
  msgstr ""
901
 
902
- #: ../src/Admin/admin-page.php:878
903
  msgid "returns views count with copy, requires stats_views=1"
904
  msgstr ""
905
 
906
- #: ../src/Admin/admin-page.php:878
907
  msgid "returns comments count only, no text, requires stats_comments=1"
908
  msgstr ""
909
 
910
- #: ../src/Admin/admin-page.php:878
911
  msgid "returns comments count with copy, requires stats_comments=1"
912
  msgstr ""
913
 
914
- #: ../src/Admin/admin-page.php:878
915
  msgid "returns post/page date, requires stats_date=1"
916
  msgstr ""
917
 
918
- #: ../src/Admin/admin-page.php:878
919
  msgid "returns post/page date with copy, requires stats_date=1"
920
  msgstr ""
921
 
922
- #: ../src/Admin/admin-page.php:878
923
  msgid "outputs number of popular posts found"
924
  msgstr ""
925
 
926
- #: ../src/Admin/admin-page.php:878
927
  msgid "outputs the position of the post in the listing"
928
  msgstr ""
929
 
930
- #: ../src/Output.php:248
 
 
 
 
931
  msgid "Sorry. No data so far."
932
  msgstr ""
933
 
934
- #: ../src/Output.php:588
935
  #, php-format
936
  msgid "%s ago"
937
  msgstr ""
938
 
939
- #: ../src/Output.php:751
940
  #, php-format
941
  msgid "%s view per day"
942
  msgid_plural "%s views per day"
943
  msgstr[0] ""
944
  msgstr[1] ""
945
 
946
- #: ../src/Output.php:769
947
  #, php-format
948
  msgid "by %s"
949
  msgstr ""
950
 
951
- #: ../src/Output.php:774
952
  #, php-format
953
  msgid "posted %s"
954
  msgstr ""
955
 
956
- #: ../src/Output.php:774
957
  #, php-format
958
  msgid "posted on %s"
959
  msgstr ""
960
 
961
- #: ../src/Output.php:779
962
  #, php-format
963
  msgid "under %s"
964
  msgstr ""
965
 
966
- #: ../src/Rest/Controller.php:308
967
- msgid "Invalid Widget Instance ID"
968
- msgstr ""
969
-
970
- #: ../src/Rest/Controller.php:406
971
  msgid "Return popular posts from specified custom post type(s)."
972
  msgstr ""
973
 
974
- #: ../src/Rest/Controller.php:413
975
  msgid "The maximum number of popular posts to return."
976
  msgstr ""
977
 
978
- #: ../src/Rest/Controller.php:421
979
  msgid "Retrieve the most popular entries published within the specified time range."
980
  msgstr ""
981
 
982
- #: ../src/Rest/Controller.php:429
983
  msgid "An offset point for the collection."
984
  msgstr ""
985
 
986
- #: ../src/Rest/Controller.php:437
987
  msgid "Set the sorting option of the popular posts."
988
  msgstr ""
989
 
990
- #: ../src/Rest/Controller.php:445
991
  msgid "Return popular posts from a specified time range."
992
  msgstr ""
993
 
994
- #: ../src/Rest/Controller.php:453
995
  msgid "Specifies the time unit of the custom time range."
996
  msgstr ""
997
 
998
- #: ../src/Rest/Controller.php:461
999
  msgid "Specifies the number of time units of the custom time range."
1000
  msgstr ""
1001
 
1002
- #: ../src/Rest/Controller.php:469
1003
  msgid "Post IDs to exclude from the listing."
1004
  msgstr ""
1005
 
1006
- #: ../src/Rest/Controller.php:477
1007
  msgid "Include posts in a specified taxonomy."
1008
  msgstr ""
1009
 
1010
- #: ../src/Rest/Controller.php:485
1011
  msgid "Taxonomy IDs, separated by comma (prefix a minus sign to exclude)."
1012
  msgstr ""
1013
 
1014
- #: ../src/Rest/Controller.php:493
1015
  msgid "Include popular posts from author ID(s)."
1016
  msgstr ""
1017
 
1018
- #: ../src/Rest/Controller.php:514
1019
  msgid "Security nonce."
1020
  msgstr ""
1021
 
1022
- #: ../src/Rest/Controller.php:520
1023
  msgid "The post / page ID."
1024
  msgstr ""
1025
 
1026
- #: ../src/Rest/Controller.php:527
1027
  msgid "Enables Data Sampling."
1028
  msgstr ""
1029
 
1030
- #: ../src/Rest/Controller.php:534
1031
  msgid "Sets the Sampling Rate."
1032
  msgstr ""
1033
 
1034
- #: ../src/Widget/Widget.php:77
1035
- msgid "The most Popular Posts on your blog."
1036
  msgstr ""
1037
 
1038
- #: ../src/Widget/form.php:7
1039
- msgid "Title"
1040
  msgstr ""
1041
 
1042
  #: ../src/Widget/form.php:13
@@ -1047,99 +1303,19 @@ msgstr ""
1047
  msgid "posts"
1048
  msgstr ""
1049
 
1050
- #: ../src/Widget/form.php:19
1051
- msgid "Sort posts by"
1052
- msgstr ""
1053
-
1054
- #: ../src/Widget/form.php:22
1055
- msgid "Total views"
1056
- msgstr ""
1057
-
1058
  #: ../src/Widget/form.php:23
1059
  msgid "Avg. daily views"
1060
  msgstr ""
1061
 
1062
- #: ../src/Widget/form.php:30
1063
- msgid "Filters"
1064
- msgstr ""
1065
-
1066
- #: ../src/Widget/form.php:32
1067
- msgid "Time Range"
1068
- msgstr ""
1069
-
1070
- #: ../src/Widget/form.php:37
1071
- msgid "All-time"
1072
- msgstr ""
1073
-
1074
- #: ../src/Widget/form.php:54
1075
- msgid "Post type(s)"
1076
- msgstr ""
1077
-
1078
- #: ../src/Widget/form.php:57
1079
- msgid "Post ID(s) to exclude"
1080
- msgstr ""
1081
-
1082
- #: ../src/Widget/form.php:60
1083
- msgid "Taxonomy"
1084
- msgstr ""
1085
-
1086
  #: ../src/Widget/form.php:82
1087
  #, php-format
1088
  msgid "%s IDs, separated by comma (prefix a minus sign to exclude)"
1089
  msgstr ""
1090
 
1091
- #: ../src/Widget/form.php:88
1092
- msgid "Author ID(s)"
1093
- msgstr ""
1094
-
1095
- #: ../src/Widget/form.php:94
1096
- msgid "Posts settings"
1097
- msgstr ""
1098
-
1099
  #: ../src/Widget/form.php:98
1100
  msgid "Display post rating"
1101
  msgstr ""
1102
 
1103
- #: ../src/Widget/form.php:101
1104
- msgid "Shorten title"
1105
- msgstr ""
1106
-
1107
- #: ../src/Widget/form.php:104
1108
- msgid "Shorten title to"
1109
- msgstr ""
1110
-
1111
- #: ../src/Widget/form.php:105 ../src/Widget/form.php:115
1112
- msgid "characters"
1113
- msgstr ""
1114
-
1115
- #: ../src/Widget/form.php:106 ../src/Widget/form.php:116
1116
- msgid "words"
1117
- msgstr ""
1118
-
1119
- #: ../src/Widget/form.php:109
1120
- msgid "Display post excerpt"
1121
- msgstr ""
1122
-
1123
- #: ../src/Widget/form.php:112
1124
- msgid "Keep text format and links"
1125
- msgstr ""
1126
-
1127
- #: ../src/Widget/form.php:113
1128
- msgid "Excerpt length"
1129
- msgstr ""
1130
-
1131
- #: ../src/Widget/form.php:119
1132
- msgid "Display post thumbnail"
1133
- msgstr ""
1134
-
1135
- #: ../src/Widget/form.php:122
1136
- msgid "Use predefined size"
1137
- msgstr ""
1138
-
1139
- #: ../src/Widget/form.php:134
1140
- msgid "Set size manually"
1141
- msgstr ""
1142
-
1143
  #: ../src/Widget/form.php:136
1144
  msgid "Width"
1145
  msgstr ""
@@ -1148,50 +1324,14 @@ msgstr ""
1148
  msgid "Height"
1149
  msgstr ""
1150
 
1151
- #: ../src/Widget/form.php:146
1152
- msgid "Stats Tag settings"
1153
- msgstr ""
1154
-
1155
  #: ../src/Widget/form.php:148
1156
  msgid "Display comment count"
1157
  msgstr ""
1158
 
1159
- #: ../src/Widget/form.php:150
1160
- msgid "Display views"
1161
- msgstr ""
1162
-
1163
- #: ../src/Widget/form.php:152
1164
- msgid "Display author"
1165
- msgstr ""
1166
-
1167
- #: ../src/Widget/form.php:154
1168
- msgid "Display date"
1169
- msgstr ""
1170
-
1171
- #: ../src/Widget/form.php:157
1172
- msgid "Date Format"
1173
- msgstr ""
1174
-
1175
- #: ../src/Widget/form.php:159
1176
- msgid "Relative"
1177
- msgstr ""
1178
-
1179
  #: ../src/Widget/form.php:160
1180
  msgid "WordPress Date Format"
1181
  msgstr ""
1182
 
1183
- #: ../src/Widget/form.php:167
1184
- msgid "Display taxonomy"
1185
- msgstr ""
1186
-
1187
- #: ../src/Widget/form.php:188
1188
- msgid "HTML Markup settings"
1189
- msgstr ""
1190
-
1191
- #: ../src/Widget/form.php:190
1192
- msgid "Use custom HTML Markup"
1193
- msgstr ""
1194
-
1195
  #: ../src/Widget/form.php:205
1196
  msgid "Before / after title"
1197
  msgstr ""
@@ -1204,10 +1344,6 @@ msgstr ""
1204
  msgid "Post HTML Markup"
1205
  msgstr ""
1206
 
1207
- #: ../src/Widget/form.php:218
1208
- msgid "Theme"
1209
- msgstr ""
1210
-
1211
  #: ../src/Widget/form.php:218
1212
  #, php-format
1213
  msgid "see a <a href=\"%s\">list of supported browsers</a>"
5
  msgstr ""
6
  "Project-Id-Version: WordPress Popular Posts\n"
7
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/wordpress-popular-posts\n"
8
+ "POT-Creation-Date: 2021-07-03 13:54-0400\n"
9
  "PO-Revision-Date: 2015-04-24 13:30-0430\n"
10
  "Last-Translator: Héctor Cabrera <hcabrerab@gmail.com>\n"
11
  "Language-Team: Héctor Cabrera <me@cabrerahector.com>\n"
14
  "Content-Type: text/plain; charset=UTF-8\n"
15
  "Content-Transfer-Encoding: 8bit\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
+ "X-Generator: Poedit 2.4.2\n"
18
  "X-Poedit-KeywordsList: _e;__;__ngettext;__ngettext_noop;_n_noop;_x;_nx;_nx_noop;_ex;"
19
  "esc_attr__;esc_attr_e;esc_attr_x;esc_html__;esc_html_e;esc_html_x;_c;_nc;_n:1,2\n"
20
  "X-Poedit-Basepath: .\n"
22
  "X-Poedit-SearchPath-0: .\n"
23
  "X-Poedit-SearchPath-1: ..\n"
24
 
25
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:125
26
+ msgid "Preview"
27
+ msgstr ""
28
+
29
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/Admin.php:1098
30
+ #: ../src/Block/Widget/edit.js:125
31
+ msgid "Edit"
32
+ msgstr ""
33
+
34
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:176
35
+ #: ../src/Widget/form.php:7
36
+ msgid "Title"
37
+ msgstr ""
38
+
39
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:270
40
+ #: ../src/Block/Widget/edit.js:181
41
+ msgid "Limit"
42
+ msgstr ""
43
+
44
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:186
45
+ #: ../src/Widget/form.php:19
46
+ msgid "Sort posts by"
47
+ msgstr ""
48
+
49
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:189
50
+ #: ../src/Widget/form.php:22
51
+ msgid "Total views"
52
+ msgstr ""
53
+
54
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/Admin.php:724
55
+ #: ../src/Block/Widget/edit.js:190 ../src/Widget/form.php:21
56
+ msgid "Comments"
57
+ msgstr ""
58
+
59
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:195
60
+ #: ../src/Widget/form.php:32
61
+ msgid "Time Range"
62
+ msgstr ""
63
+
64
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:198
65
+ msgid "Last 24 Hours"
66
+ msgstr ""
67
+
68
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:326
69
+ #: ../src/Block/Widget/edit.js:199 ../src/Widget/form.php:35
70
+ msgid "Last 7 days"
71
+ msgstr ""
72
+
73
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:327
74
+ #: ../src/Block/Widget/edit.js:200 ../src/Widget/form.php:36
75
+ msgid "Last 30 days"
76
+ msgstr ""
77
+
78
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:201
79
+ #: ../src/Widget/form.php:37
80
+ msgid "All-time"
81
+ msgstr ""
82
+
83
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:328
84
+ #: ../src/Block/Widget/edit.js:202 ../src/Widget/form.php:38
85
+ msgid "Custom"
86
+ msgstr ""
87
+
88
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:209
89
+ msgid "Time Quantity"
90
+ msgstr ""
91
+
92
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:214
93
+ msgid "Time Unit"
94
+ msgstr ""
95
+
96
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:297
97
+ #: ../src/Admin/admin-page.php:551 ../src/Block/Widget/edit.js:217
98
+ #: ../src/Widget/form.php:45
99
+ msgid "Minute(s)"
100
+ msgstr ""
101
+
102
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:298
103
+ #: ../src/Admin/admin-page.php:552 ../src/Block/Widget/edit.js:218
104
+ #: ../src/Widget/form.php:46
105
+ msgid "Hour(s)"
106
+ msgstr ""
107
+
108
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:299
109
+ #: ../src/Admin/admin-page.php:553 ../src/Block/Widget/edit.js:219
110
+ #: ../src/Widget/form.php:47
111
+ msgid "Day(s)"
112
+ msgstr ""
113
+
114
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:273
115
+ #: ../src/Block/Widget/edit.js:226 ../src/Widget/form.php:52
116
+ msgid "Display only posts published within the selected Time Range"
117
+ msgstr ""
118
+
119
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:327
120
+ #: ../src/Widget/form.php:30
121
+ msgid "Filters"
122
+ msgstr ""
123
+
124
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:329
125
+ #: ../src/Widget/form.php:54
126
+ msgid "Post type(s)"
127
+ msgstr ""
128
+
129
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:330
130
+ msgid "Post types must be comma separated."
131
+ msgstr ""
132
+
133
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:335
134
+ #: ../src/Widget/form.php:57
135
+ msgid "Post ID(s) to exclude"
136
+ msgstr ""
137
+
138
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:336
139
+ #: ../src/Block/Widget/edit.js:342
140
+ msgid "IDs must be comma separated."
141
+ msgstr ""
142
+
143
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:341
144
+ #: ../src/Widget/form.php:88
145
+ msgid "Author ID(s)"
146
+ msgstr ""
147
+
148
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:351
149
+ msgid "Term IDs must be comma separated, prefix a minus sign to exclude."
150
+ msgstr ""
151
+
152
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:442
153
+ #: ../src/Widget/form.php:94
154
+ msgid "Posts settings"
155
+ msgstr ""
156
+
157
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:444
158
+ #: ../src/Widget/form.php:101
159
+ msgid "Shorten title"
160
+ msgstr ""
161
+
162
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:451
163
+ #: ../src/Widget/form.php:104
164
+ msgid "Shorten title to"
165
+ msgstr ""
166
+
167
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:458
168
+ #: ../src/Block/Widget/edit.js:485 ../src/Widget/form.php:105 ../src/Widget/form.php:115
169
+ msgid "characters"
170
+ msgstr ""
171
+
172
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:459
173
+ #: ../src/Block/Widget/edit.js:486 ../src/Widget/form.php:106 ../src/Widget/form.php:116
174
+ msgid "words"
175
+ msgstr ""
176
+
177
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:466
178
+ #: ../src/Widget/form.php:109
179
+ msgid "Display post excerpt"
180
+ msgstr ""
181
+
182
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:473
183
+ #: ../src/Widget/form.php:112
184
+ msgid "Keep text format and links"
185
+ msgstr ""
186
+
187
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:478
188
+ #: ../src/Widget/form.php:113
189
+ msgid "Excerpt length"
190
+ msgstr ""
191
+
192
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:493
193
+ #: ../src/Widget/form.php:119
194
+ msgid "Display post thumbnail"
195
+ msgstr ""
196
+
197
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:502
198
+ #: ../src/Widget/form.php:134
199
+ msgid "Set size manually"
200
+ msgstr ""
201
+
202
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:503
203
+ #: ../src/Widget/form.php:122
204
+ msgid "Use predefined size"
205
+ msgstr ""
206
+
207
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:510
208
+ msgid "Thumbnail width"
209
+ msgstr ""
210
+
211
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:511
212
+ #: ../src/Block/Widget/edit.js:517
213
+ msgid "Size in px units (pixels)"
214
+ msgstr ""
215
+
216
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:516
217
+ msgid "Thumbnail height"
218
+ msgstr ""
219
+
220
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:555
221
+ #: ../src/Widget/form.php:146
222
+ msgid "Stats Tag settings"
223
+ msgstr ""
224
+
225
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:557
226
+ msgid "Display comments count"
227
+ msgstr ""
228
+
229
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:562
230
+ #: ../src/Widget/form.php:150
231
+ msgid "Display views"
232
+ msgstr ""
233
+
234
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:567
235
+ #: ../src/Widget/form.php:152
236
+ msgid "Display author"
237
+ msgstr ""
238
+
239
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:572
240
+ #: ../src/Widget/form.php:154
241
+ msgid "Display date"
242
+ msgstr ""
243
+
244
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:579
245
+ #: ../src/Widget/form.php:157
246
+ msgid "Date Format"
247
+ msgstr ""
248
+
249
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:582
250
+ #: ../src/Widget/form.php:159
251
+ msgid "Relative"
252
+ msgstr ""
253
+
254
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:583
255
+ msgid "Month Day, Year"
256
+ msgstr ""
257
+
258
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:584
259
+ msgid "yyyy/mm/dd"
260
+ msgstr ""
261
+
262
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:585
263
+ msgid "mm/dd/yyyy"
264
+ msgstr ""
265
+
266
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:586
267
+ msgid "dd/mm/yyyy"
268
+ msgstr ""
269
+
270
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:593
271
+ #: ../src/Widget/form.php:167
272
+ msgid "Display taxonomy"
273
+ msgstr ""
274
+
275
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:600
276
+ #: ../src/Widget/form.php:60
277
+ msgid "Taxonomy"
278
+ msgstr ""
279
+
280
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Admin/admin-page.php:677
281
+ #: ../src/Admin/admin-page.php:747 ../src/Admin/admin-page.php:754
282
+ #: ../src/Admin/admin-page.php:761 ../src/Admin/admin-page.php:768
283
+ #: ../src/Admin/admin-page.php:775 ../src/Block/Widget/edit.js:652
284
+ #: ../src/Widget/form.php:226
285
+ msgid "None"
286
+ msgstr ""
287
+
288
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:669
289
+ #: ../src/Widget/form.php:188
290
+ msgid "HTML Markup settings"
291
+ msgstr ""
292
+
293
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:671
294
+ #: ../src/Widget/form.php:190
295
+ msgid "Use custom HTML Markup"
296
+ msgstr ""
297
+
298
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:679
299
+ msgid "Before title"
300
+ msgstr ""
301
+
302
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:685
303
+ msgid "After title"
304
+ msgstr ""
305
+
306
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:691
307
+ msgid "Before popular posts"
308
+ msgstr ""
309
+
310
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:697
311
+ msgid "After popular posts"
312
+ msgstr ""
313
+
314
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:702
315
+ msgid "Post HTML markup"
316
+ msgstr ""
317
+
318
+ #: ../assets/js/blocks/block-wpp-widget.js:1 ../src/Block/Widget/edit.js:709
319
+ #: ../src/Widget/form.php:218
320
+ msgid "Theme"
321
+ msgstr ""
322
+
323
  #: ../src/Admin/Admin.php:371
324
  #, php-format
325
  msgid "%s view in the last hour"
327
  msgstr[0] ""
328
  msgstr[1] ""
329
 
330
+ #: ../src/Admin/Admin.php:405 ../src/Admin/admin-page.php:350
331
  msgid "Trending now"
332
  msgstr ""
333
 
370
  "a></li><li><a href=\"%2$s\">Support</a></li></ul>"
371
  msgstr ""
372
 
373
+ #: ../src/Admin/Admin.php:624
374
  msgid "Settings"
375
  msgstr ""
376
 
377
+ #: ../src/Admin/Admin.php:625
378
+ msgid "Support"
379
+ msgstr ""
380
+
381
+ #: ../src/Admin/Admin.php:703 ../src/Admin/Admin.php:1092 ../src/Admin/Admin.php:1096
382
+ #: ../src/Output.php:781
383
  #, php-format
384
  msgid "%s view"
385
  msgid_plural "%s views"
386
  msgstr[0] ""
387
  msgstr[1] ""
388
 
389
+ #: ../src/Admin/Admin.php:703 ../src/Admin/Admin.php:1094 ../src/Admin/Admin.php:1096
390
+ #: ../src/Output.php:764
391
  #, php-format
392
  msgid "%s comment"
393
  msgid_plural "%s comments"
394
  msgstr[0] ""
395
  msgstr[1] ""
396
 
397
+ #: ../src/Admin/Admin.php:728
 
 
 
 
398
  msgid "Views"
399
  msgstr ""
400
 
401
+ #: ../src/Admin/Admin.php:1098
402
  msgid "View"
403
  msgstr ""
404
 
405
+ #: ../src/Admin/Admin.php:1109
 
 
 
 
406
  msgid ""
407
  "Looks like your site's activity is a little low right now. <br />Spread the word and "
408
  "come back later!"
409
  msgstr ""
410
 
411
+ #: ../src/Admin/Admin.php:1371
412
  #, php-format
413
  msgid ""
414
  "<strong>WordPress Popular Posts:</strong> It seems your site is popular (great!) You "
416
  "performance stays up to par."
417
  msgstr ""
418
 
419
+ #: ../src/Admin/admin-page.php:6 ../src/Admin/admin-page.php:241
420
  msgid "Stats"
421
  msgstr ""
422
 
423
+ #: ../src/Admin/admin-page.php:7 ../src/Admin/admin-page.php:242
424
  msgid "Tools"
425
  msgstr ""
426
 
427
+ #: ../src/Admin/admin-page.php:8 ../src/Admin/admin-page.php:243
428
  msgid "Parameters"
429
  msgstr ""
430
 
431
+ #: ../src/Admin/admin-page.php:30 ../src/Admin/admin-page.php:42
432
+ #: ../src/Admin/admin-page.php:68 ../src/Admin/admin-page.php:104
433
  msgid "Settings saved."
434
  msgstr ""
435
 
436
+ #: ../src/Admin/admin-page.php:53
437
  msgid "Please provide the name of your custom field."
438
  msgstr ""
439
 
440
+ #: ../src/Admin/admin-page.php:122
441
  msgid ""
442
  "This operation will delete all entries from WordPress Popular Posts' cache table and "
443
  "cannot be undone."
444
  msgstr ""
445
 
446
+ #: ../src/Admin/admin-page.php:122 ../src/Admin/admin-page.php:161
447
+ #: ../src/Admin/admin-page.php:200
448
  msgid "Do you want to continue?"
449
  msgstr ""
450
 
451
+ #: ../src/Admin/admin-page.php:134
452
  msgid "Success! The cache table has been cleared!"
453
  msgstr ""
454
 
455
+ #: ../src/Admin/admin-page.php:138
456
  msgid "Error: cache table does not exist."
457
  msgstr ""
458
 
459
+ #: ../src/Admin/admin-page.php:142 ../src/Admin/admin-page.php:150
460
+ #: ../src/Admin/admin-page.php:181 ../src/Admin/admin-page.php:189
461
+ #: ../src/Admin/admin-page.php:219 ../src/Admin/admin-page.php:227
462
  msgid "Invalid action."
463
  msgstr ""
464
 
465
+ #: ../src/Admin/admin-page.php:146 ../src/Admin/admin-page.php:185
466
+ #: ../src/Admin/admin-page.php:223
467
  msgid ""
468
  "Sorry, you do not have enough permissions to do this. Please contact the site "
469
  "administrator for support."
470
  msgstr ""
471
 
472
+ #: ../src/Admin/admin-page.php:161
473
  msgid ""
474
  "This operation will delete all stored info from WordPress Popular Posts' data tables "
475
  "and cannot be undone."
476
  msgstr ""
477
 
478
+ #: ../src/Admin/admin-page.php:173
479
  msgid "Success! All data have been cleared!"
480
  msgstr ""
481
 
482
+ #: ../src/Admin/admin-page.php:177
483
  msgid "Error: one or both data tables are missing."
484
  msgstr ""
485
 
486
+ #: ../src/Admin/admin-page.php:200
487
  msgid "This operation will delete all cached thumbnails and cannot be undone."
488
  msgstr ""
489
 
490
+ #: ../src/Admin/admin-page.php:211
491
  msgid "Success! All files have been deleted!"
492
  msgstr ""
493
 
494
+ #: ../src/Admin/admin-page.php:215
495
  msgid "The thumbnail cache is already empty!"
496
  msgstr ""
497
 
498
+ #: ../src/Admin/admin-page.php:240
499
  msgid "Menu"
500
  msgstr ""
501
 
502
+ #: ../src/Admin/admin-page.php:267
503
  msgid "Post type"
504
  msgstr ""
505
 
506
+ #: ../src/Admin/admin-page.php:279 ../src/Admin/admin-page.php:311
507
+ #: ../src/Admin/admin-page.php:478 ../src/Admin/admin-page.php:585
508
+ #: ../src/Admin/admin-page.php:631
 
 
 
 
 
 
 
 
509
  msgid "Apply"
510
  msgstr ""
511
 
512
+ #: ../src/Admin/admin-page.php:280 ../src/Admin/admin-page.php:314
513
  msgid "Cancel"
514
  msgstr ""
515
 
516
+ #: ../src/Admin/admin-page.php:289
517
  msgid "Custom Time Range"
518
  msgstr ""
519
 
520
+ #: ../src/Admin/admin-page.php:290
521
  msgid "Date Range"
522
  msgstr ""
523
 
524
+ #: ../src/Admin/admin-page.php:304
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  msgid "Select a date..."
526
  msgstr ""
527
 
528
+ #: ../src/Admin/admin-page.php:324
529
  msgid "Today"
530
  msgstr ""
531
 
532
+ #: ../src/Admin/admin-page.php:325 ../src/Widget/form.php:34
533
  msgid "Last 24 hours"
534
  msgstr ""
535
 
536
+ #: ../src/Admin/admin-page.php:332
 
 
 
 
 
 
 
 
 
 
 
 
537
  #, php-format
538
  msgid ""
539
  "Err... A nice little chart is supposed to be here, instead you are seeing this because "
541
  "browser</a>."
542
  msgstr ""
543
 
544
+ #: ../src/Admin/admin-page.php:348
545
  msgid "Most viewed"
546
  msgstr ""
547
 
548
+ #: ../src/Admin/admin-page.php:349
549
  msgid "Most commented"
550
  msgstr ""
551
 
552
+ #: ../src/Admin/admin-page.php:351
553
  msgid "Hall of Fame"
554
  msgstr ""
555
 
556
+ #: ../src/Admin/admin-page.php:391
557
  msgid "Thumbnails"
558
  msgstr ""
559
 
560
+ #: ../src/Admin/admin-page.php:397
561
  msgid "Default thumbnail"
562
  msgstr ""
563
 
564
+ #: ../src/Admin/admin-page.php:418
565
  msgid "Change thumbnail"
566
  msgstr ""
567
 
568
+ #: ../src/Admin/admin-page.php:421
569
  msgid "This image will be displayed when no thumbnail is available"
570
  msgstr ""
571
 
572
+ #: ../src/Admin/admin-page.php:425
573
  msgid "Pick image from"
574
  msgstr ""
575
 
576
+ #: ../src/Admin/admin-page.php:428
577
  msgid "Featured image"
578
  msgstr ""
579
 
580
+ #: ../src/Admin/admin-page.php:429
581
  msgid "First image on post"
582
  msgstr ""
583
 
584
+ #: ../src/Admin/admin-page.php:430
585
  msgid "First attachment"
586
  msgstr ""
587
 
588
+ #: ../src/Admin/admin-page.php:431
589
  msgid "Custom field"
590
  msgstr ""
591
 
592
+ #: ../src/Admin/admin-page.php:434
593
  msgid "Tell WordPress Popular Posts where it should get thumbnails from"
594
  msgstr ""
595
 
596
+ #: ../src/Admin/admin-page.php:438
597
  msgid "Lazy load"
598
  msgstr ""
599
 
600
+ #: ../src/Admin/admin-page.php:438 ../src/Admin/admin-page.php:535
601
+ #: ../src/Admin/admin-page.php:563 ../src/Widget/form.php:7 ../src/Widget/form.php:54
602
  #: ../src/Widget/form.php:60 ../src/Widget/form.php:88 ../src/Widget/form.php:98
603
  #: ../src/Widget/form.php:190
604
  msgid "What is this?"
605
  msgstr ""
606
 
607
+ #: ../src/Admin/admin-page.php:441
608
  msgid "No"
609
  msgstr ""
610
 
611
+ #: ../src/Admin/admin-page.php:442 ../src/Admin/admin-page.php:457
612
  msgid "Yes"
613
  msgstr ""
614
 
615
+ #: ../src/Admin/admin-page.php:447
616
  msgid "Custom field name"
617
  msgstr ""
618
 
619
+ #: ../src/Admin/admin-page.php:453
620
  msgid "Resize image from Custom field?"
621
  msgstr ""
622
 
623
+ #: ../src/Admin/admin-page.php:456
624
  msgid "No, use image as is"
625
  msgstr ""
626
 
627
+ #: ../src/Admin/admin-page.php:468
628
  msgid "Empty image cache"
629
  msgstr ""
630
 
631
+ #: ../src/Admin/admin-page.php:469
632
  msgid "Use this button to clear WPP's thumbnails cache"
633
  msgstr ""
634
 
635
+ #: ../src/Admin/admin-page.php:489
636
  msgid "Data"
637
  msgstr ""
638
 
639
+ #: ../src/Admin/admin-page.php:495
640
  msgid "Log views from"
641
  msgstr ""
642
 
643
+ #: ../src/Admin/admin-page.php:498
644
  msgid "Visitors only"
645
  msgstr ""
646
 
647
+ #: ../src/Admin/admin-page.php:499
648
  msgid "Logged-in users only"
649
  msgstr ""
650
 
651
+ #: ../src/Admin/admin-page.php:500
652
  msgid "Everyone"
653
  msgstr ""
654
 
655
+ #: ../src/Admin/admin-page.php:506
656
  msgid "Log limit"
657
  msgstr ""
658
 
659
+ #: ../src/Admin/admin-page.php:509 ../src/Admin/admin-page.php:526
660
+ #: ../src/Admin/admin-page.php:566 ../src/Admin/admin-page.php:616
661
  msgid "Disabled"
662
  msgstr ""
663
 
664
+ #: ../src/Admin/admin-page.php:510
665
  msgid "Keep data for"
666
  msgstr ""
667
 
668
+ #: ../src/Admin/admin-page.php:514
669
  msgid "day(s)"
670
  msgstr ""
671
 
672
+ #: ../src/Admin/admin-page.php:517
673
  msgid "Data older than the specified time frame will be automatically discarded"
674
  msgstr ""
675
 
676
+ #: ../src/Admin/admin-page.php:523
677
  msgid "Ajaxify widget"
678
  msgstr ""
679
 
680
+ #: ../src/Admin/admin-page.php:527 ../src/Admin/admin-page.php:567
681
+ #: ../src/Admin/admin-page.php:615
682
  msgid "Enabled"
683
  msgstr ""
684
 
685
+ #: ../src/Admin/admin-page.php:531
686
  msgid ""
687
  "If you are using a caching plugin such as WP Super Cache, enabling this feature will "
688
  "keep the popular list from being cached by it"
689
  msgstr ""
690
 
691
+ #: ../src/Admin/admin-page.php:535
692
  msgid "Data Caching"
693
  msgstr ""
694
 
695
+ #: ../src/Admin/admin-page.php:538
696
  msgid "Never cache"
697
  msgstr ""
698
 
699
+ #: ../src/Admin/admin-page.php:539
700
  msgid "Enable caching"
701
  msgstr ""
702
 
703
+ #: ../src/Admin/admin-page.php:543
704
  msgid ""
705
  "WPP can cache the popular list for a specified amount of time. Recommended for large / "
706
  "high traffic sites"
707
  msgstr ""
708
 
709
+ #: ../src/Admin/admin-page.php:547
710
  msgid "Refresh cache every"
711
  msgstr ""
712
 
713
+ #: ../src/Admin/admin-page.php:554
714
  msgid "Week(s)"
715
  msgstr ""
716
 
717
+ #: ../src/Admin/admin-page.php:555
718
  msgid "Month(s)"
719
  msgstr ""
720
 
721
+ #: ../src/Admin/admin-page.php:556
722
  msgid "Year(s)"
723
  msgstr ""
724
 
725
+ #: ../src/Admin/admin-page.php:559
726
  msgid "Really? That long?"
727
  msgstr ""
728
 
729
+ #: ../src/Admin/admin-page.php:563
730
  msgid "Data Sampling"
731
  msgstr ""
732
 
733
+ #: ../src/Admin/admin-page.php:571
734
  #, php-format
735
  msgid ""
736
  "By default, WordPress Popular Posts stores in database every single visit your site "
741
  "(for more, <a href=\"%2$s\" target=\"_blank\">please read here</a>)"
742
  msgstr ""
743
 
744
+ #: ../src/Admin/admin-page.php:575
745
  msgid "Sample Rate"
746
  msgstr ""
747
 
748
+ #: ../src/Admin/admin-page.php:579
749
  #, php-format
750
  msgid ""
751
  "A sampling rate of %d is recommended for large / high traffic sites. For lower traffic "
752
  "sites, you should lower the value"
753
  msgstr ""
754
 
755
+ #: ../src/Admin/admin-page.php:596
756
  msgid "Miscellaneous"
757
  msgstr ""
758
 
759
+ #: ../src/Admin/admin-page.php:602
760
  msgid "Open links in"
761
  msgstr ""
762
 
763
+ #: ../src/Admin/admin-page.php:605
764
  msgid "Current window"
765
  msgstr ""
766
 
767
+ #: ../src/Admin/admin-page.php:606
768
  msgid "New tab/window"
769
  msgstr ""
770
 
771
+ #: ../src/Admin/admin-page.php:612
772
  msgid "Use plugin's stylesheet"
773
  msgstr ""
774
 
775
+ #: ../src/Admin/admin-page.php:619
776
  msgid ""
777
  "By default, the plugin includes a stylesheet called wpp.css which you can use to style "
778
  "your popular posts listing. If you wish to use your own stylesheet or do not want it "
780
  msgstr ""
781
 
782
  #: ../src/Admin/admin-page.php:623
783
+ msgid "Enable experimental features"
784
+ msgstr ""
785
+
786
+ #: ../src/Admin/admin-page.php:645
787
  msgid ""
788
  "WordPress Popular Posts maintains data in two separate tables: one for storing the "
789
  "most popular entries on a daily basis (from now on, \"cache\"), and another one to "
792
  "tables, please use the buttons below to do so."
793
  msgstr ""
794
 
795
+ #: ../src/Admin/admin-page.php:646
796
  msgid "Empty cache"
797
  msgstr ""
798
 
799
+ #: ../src/Admin/admin-page.php:646
800
  msgid "Use this button to manually clear entries from WPP cache only"
801
  msgstr ""
802
 
803
+ #: ../src/Admin/admin-page.php:647
804
  msgid "Clear all data"
805
  msgstr ""
806
 
807
+ #: ../src/Admin/admin-page.php:647
808
  msgid "Use this button to manually clear entries from all WPP data tables"
809
  msgstr ""
810
 
811
+ #: ../src/Admin/admin-page.php:655
812
  #, php-format
813
  msgid ""
814
  "With the following parameters you can customize the popular posts list when using "
816
  "\"%2$s\">[wpp] shortcode</a>."
817
  msgstr ""
818
 
819
+ #: ../src/Admin/admin-page.php:665
820
  msgid "Parameter"
821
  msgstr ""
822
 
823
+ #: ../src/Admin/admin-page.php:666
824
  msgid "What it does "
825
  msgstr ""
826
 
827
+ #: ../src/Admin/admin-page.php:667
828
  msgid "Possible values"
829
  msgstr ""
830
 
831
+ #: ../src/Admin/admin-page.php:668
832
  msgid "Defaults to"
833
  msgstr ""
834
 
835
+ #: ../src/Admin/admin-page.php:669
836
  msgid "Example"
837
  msgstr ""
838
 
839
+ #: ../src/Admin/admin-page.php:675
840
  msgid "Sets a heading for the list"
841
  msgstr ""
842
 
843
+ #: ../src/Admin/admin-page.php:676 ../src/Admin/admin-page.php:683
844
+ #: ../src/Admin/admin-page.php:690 ../src/Admin/admin-page.php:739
 
 
 
 
 
 
 
 
 
845
  #: ../src/Admin/admin-page.php:746 ../src/Admin/admin-page.php:753
846
+ #: ../src/Admin/admin-page.php:760 ../src/Admin/admin-page.php:767
847
+ #: ../src/Admin/admin-page.php:774 ../src/Admin/admin-page.php:865
848
+ #: ../src/Admin/admin-page.php:886 ../src/Admin/admin-page.php:893
849
+ msgid "Text string"
850
  msgstr ""
851
 
852
+ #: ../src/Admin/admin-page.php:678 ../src/Admin/admin-page.php:685
853
+ #: ../src/Admin/admin-page.php:692 ../src/Admin/admin-page.php:699
854
+ #: ../src/Admin/admin-page.php:706 ../src/Admin/admin-page.php:713
855
+ #: ../src/Admin/admin-page.php:720 ../src/Admin/admin-page.php:727
856
+ #: ../src/Admin/admin-page.php:734 ../src/Admin/admin-page.php:741
857
+ #: ../src/Admin/admin-page.php:748 ../src/Admin/admin-page.php:755
858
+ #: ../src/Admin/admin-page.php:762 ../src/Admin/admin-page.php:769
859
+ #: ../src/Admin/admin-page.php:776 ../src/Admin/admin-page.php:783
860
+ #: ../src/Admin/admin-page.php:790 ../src/Admin/admin-page.php:797
861
+ #: ../src/Admin/admin-page.php:804 ../src/Admin/admin-page.php:811
862
+ #: ../src/Admin/admin-page.php:818 ../src/Admin/admin-page.php:825
863
+ #: ../src/Admin/admin-page.php:832 ../src/Admin/admin-page.php:839
864
+ #: ../src/Admin/admin-page.php:846 ../src/Admin/admin-page.php:853
865
+ #: ../src/Admin/admin-page.php:860 ../src/Admin/admin-page.php:867
866
+ #: ../src/Admin/admin-page.php:874 ../src/Admin/admin-page.php:881
867
+ #: ../src/Admin/admin-page.php:888 ../src/Admin/admin-page.php:895
868
+ #: ../src/Admin/admin-page.php:902
869
  msgid "With wpp_get_mostpopular():"
870
  msgstr ""
871
 
872
+ #: ../src/Admin/admin-page.php:678 ../src/Admin/admin-page.php:685
873
+ #: ../src/Admin/admin-page.php:692 ../src/Admin/admin-page.php:699
874
+ #: ../src/Admin/admin-page.php:706 ../src/Admin/admin-page.php:713
875
+ #: ../src/Admin/admin-page.php:720 ../src/Admin/admin-page.php:727
876
+ #: ../src/Admin/admin-page.php:734 ../src/Admin/admin-page.php:741
877
+ #: ../src/Admin/admin-page.php:748 ../src/Admin/admin-page.php:755
878
+ #: ../src/Admin/admin-page.php:762 ../src/Admin/admin-page.php:769
879
+ #: ../src/Admin/admin-page.php:776 ../src/Admin/admin-page.php:783
880
+ #: ../src/Admin/admin-page.php:790 ../src/Admin/admin-page.php:797
881
+ #: ../src/Admin/admin-page.php:804 ../src/Admin/admin-page.php:811
882
+ #: ../src/Admin/admin-page.php:818 ../src/Admin/admin-page.php:825
883
+ #: ../src/Admin/admin-page.php:832 ../src/Admin/admin-page.php:839
884
+ #: ../src/Admin/admin-page.php:846 ../src/Admin/admin-page.php:853
885
+ #: ../src/Admin/admin-page.php:860 ../src/Admin/admin-page.php:867
886
+ #: ../src/Admin/admin-page.php:874 ../src/Admin/admin-page.php:881
887
+ #: ../src/Admin/admin-page.php:888 ../src/Admin/admin-page.php:895
888
+ #: ../src/Admin/admin-page.php:902
889
  msgid "With the [wpp] shortcode:"
890
  msgstr ""
891
 
892
+ #: ../src/Admin/admin-page.php:682
893
  msgid "Set the opening tag for the heading of the list"
894
  msgstr ""
895
 
896
+ #: ../src/Admin/admin-page.php:689
897
  msgid "Set the closing tag for the heading of the list"
898
  msgstr ""
899
 
900
+ #: ../src/Admin/admin-page.php:696
901
  msgid "Sets the maximum number of popular posts to be shown on the listing"
902
  msgstr ""
903
 
904
+ #: ../src/Admin/admin-page.php:697 ../src/Admin/admin-page.php:711
905
+ #: ../src/Admin/admin-page.php:781 ../src/Admin/admin-page.php:795
906
+ #: ../src/Admin/admin-page.php:816 ../src/Admin/admin-page.php:823
907
  msgid "Positive integer"
908
  msgstr ""
909
 
910
+ #: ../src/Admin/admin-page.php:703
911
  msgid ""
912
  "Tells WordPress Popular Posts to retrieve the most popular entries within the time "
913
  "range specified by you"
914
  msgstr ""
915
 
916
+ #: ../src/Admin/admin-page.php:710
917
  msgid "Especifies the number of time units of the custom time range"
918
  msgstr ""
919
 
920
+ #: ../src/Admin/admin-page.php:717
921
  msgid "Especifies the time unit of the custom time range"
922
  msgstr ""
923
 
924
+ #: ../src/Admin/admin-page.php:724
925
  msgid ""
926
  "Tells WordPress Popular Posts to retrieve the most popular entries published within "
927
  "the time range specified by you"
928
  msgstr ""
929
 
930
+ #: ../src/Admin/admin-page.php:731
931
  msgid "Sets the sorting option of the popular posts"
932
  msgstr ""
933
 
934
+ #: ../src/Admin/admin-page.php:732
935
  msgid "(for average views per day)"
936
  msgstr ""
937
 
938
+ #: ../src/Admin/admin-page.php:738
939
  msgid "Defines the type of posts to show on the listing"
940
  msgstr ""
941
 
942
+ #: ../src/Admin/admin-page.php:745
943
  msgid ""
944
  "If set, WordPress Popular Posts will exclude the specified post(s) ID(s) form the "
945
  "listing."
946
  msgstr ""
947
 
948
+ #: ../src/Admin/admin-page.php:752
949
  msgid ""
950
  "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
951
  "category ID(s). If a minus sign is used, entries associated to the category will be "
952
  "excluded instead."
953
  msgstr ""
954
 
955
+ #: ../src/Admin/admin-page.php:759
956
  msgid "If set, WordPress Popular Posts will filter posts by a given taxonomy."
957
  msgstr ""
958
 
959
+ #: ../src/Admin/admin-page.php:766
960
  msgid ""
961
  "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
962
  "term ID(s). If a minus sign is used, entries associated to the term(s) will be "
963
  "excluded instead."
964
  msgstr ""
965
 
966
+ #: ../src/Admin/admin-page.php:773
967
  msgid ""
968
  "If set, WordPress Popular Posts will retrieve all entries created by specified "
969
  "author(s) ID(s)."
970
  msgstr ""
971
 
972
+ #: ../src/Admin/admin-page.php:780
973
  msgid ""
974
  "If set, WordPress Popular Posts will shorten each post title to \"n\" characters "
975
  "whenever possible"
976
  msgstr ""
977
 
978
+ #: ../src/Admin/admin-page.php:787
979
  msgid ""
980
  "If set to 1, WordPress Popular Posts will shorten each post title to \"n\" words "
981
  "instead of characters"
982
  msgstr ""
983
 
984
+ #: ../src/Admin/admin-page.php:794
985
  msgid ""
986
  "If set, WordPress Popular Posts will build and include an excerpt of \"n\" characters "
987
  "long from the content of each post listed as popular"
988
  msgstr ""
989
 
990
+ #: ../src/Admin/admin-page.php:801
991
  msgid ""
992
  "If set, WordPress Popular Posts will maintaing all styling tags (strong, italic, etc) "
993
  "and hyperlinks found in the excerpt"
994
  msgstr ""
995
 
996
+ #: ../src/Admin/admin-page.php:808
997
  msgid ""
998
  "If set to 1, WordPress Popular Posts will shorten the excerpt to \"n\" words instead "
999
  "of characters"
1000
  msgstr ""
1001
 
1002
+ #: ../src/Admin/admin-page.php:815
1003
  msgid ""
1004
  "If set, and if your current server configuration allows it, you will be able to "
1005
  "display thumbnails of your posts. This attribute sets the width for thumbnails"
1006
  msgstr ""
1007
 
1008
+ #: ../src/Admin/admin-page.php:822
1009
  msgid ""
1010
  "If set, and if your current server configuration allows it, you will be able to "
1011
  "display thumbnails of your posts. This attribute sets the height for thumbnails"
1012
  msgstr ""
1013
 
1014
+ #: ../src/Admin/admin-page.php:829
1015
  msgid ""
1016
  "If set, and if the WP-PostRatings plugin is installed and enabled on your blog, "
1017
  "WordPress Popular Posts will show how your visitors are rating your entries"
1018
  msgstr ""
1019
 
1020
+ #: ../src/Admin/admin-page.php:836
1021
  msgid ""
1022
  "If set, WordPress Popular Posts will show how many comments each popular post has got "
1023
  "during the specified time range"
1024
  msgstr ""
1025
 
1026
+ #: ../src/Admin/admin-page.php:843
1027
  msgid ""
1028
  "If set, WordPress Popular Posts will show how many views each popular post has got "
1029
  "during the specified time range"
1030
  msgstr ""
1031
 
1032
+ #: ../src/Admin/admin-page.php:850
1033
  msgid ""
1034
  "If set, WordPress Popular Posts will show who published each popular post on the list"
1035
  msgstr ""
1036
 
1037
+ #: ../src/Admin/admin-page.php:857
1038
  msgid ""
1039
  "If set, WordPress Popular Posts will display the date when each popular post on the "
1040
  "list was published"
1041
  msgstr ""
1042
 
1043
+ #: ../src/Admin/admin-page.php:864
1044
  msgid "Sets the date format"
1045
  msgstr ""
1046
 
1047
+ #: ../src/Admin/admin-page.php:871
1048
  msgid ""
1049
  "If set, WordPress Popular Posts will display the categories associated to each entry"
1050
  msgstr ""
1051
 
1052
+ #: ../src/Admin/admin-page.php:878
1053
  msgid ""
1054
  "If set, WordPress Popular Posts will display the taxonomies associated to each entry"
1055
  msgstr ""
1056
 
1057
+ #: ../src/Admin/admin-page.php:885
1058
  msgid "Sets the opening tag for the listing"
1059
  msgstr ""
1060
 
1061
+ #: ../src/Admin/admin-page.php:892
1062
  msgid "Sets the closing tag for the listing"
1063
  msgstr ""
1064
 
1065
+ #: ../src/Admin/admin-page.php:899
1066
  msgid "Sets the HTML structure of each post"
1067
  msgstr ""
1068
 
1069
+ #: ../src/Admin/admin-page.php:900
1070
  msgid "Text string, custom HTML"
1071
  msgstr ""
1072
 
1073
+ #: ../src/Admin/admin-page.php:900
1074
  msgid "Available Content Tags"
1075
  msgstr ""
1076
 
1077
+ #: ../src/Admin/admin-page.php:900
1078
  msgid ""
1079
  "returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height"
1080
  msgstr ""
1081
 
1082
+ #: ../src/Admin/admin-page.php:900
1083
  msgid ""
1084
  "returns thumbnail image without linking to post/page, requires thumbnail_width & "
1085
  "thumbnail_height"
1086
  msgstr ""
1087
 
1088
+ #: ../src/Admin/admin-page.php:900
1089
  msgid "returns thumbnail url, requires thumbnail_width & thumbnail_height"
1090
  msgstr ""
1091
 
1092
+ #: ../src/Admin/admin-page.php:900
1093
  msgid "returns linked post/page title"
1094
  msgstr ""
1095
 
1096
+ #: ../src/Admin/admin-page.php:900
1097
  msgid "returns the post/page ID"
1098
  msgstr ""
1099
 
1100
+ #: ../src/Admin/admin-page.php:900
1101
  msgid "returns post/page excerpt, and requires excerpt_length to be greater than 0"
1102
  msgstr ""
1103
 
1104
+ #: ../src/Admin/admin-page.php:900
1105
  msgid "returns the default stats tags"
1106
  msgstr ""
1107
 
1108
+ #: ../src/Admin/admin-page.php:900
1109
  msgid "returns post/page current rating, requires WP-PostRatings installed and enabled"
1110
  msgstr ""
1111
 
1112
+ #: ../src/Admin/admin-page.php:900
1113
  msgid ""
1114
  "returns post/page current rating as an integer, requires WP-PostRatings installed and "
1115
  "enabled"
1116
  msgstr ""
1117
 
1118
+ #: ../src/Admin/admin-page.php:900
1119
  msgid "returns the URL of the post/page"
1120
  msgstr ""
1121
 
1122
+ #: ../src/Admin/admin-page.php:900
1123
  msgid "returns post/page title, no link"
1124
  msgstr ""
1125
 
1126
+ #: ../src/Admin/admin-page.php:900
1127
  msgid "similar to text_title, sanitized for use in title/alt attributes"
1128
  msgstr ""
1129
 
1130
+ #: ../src/Admin/admin-page.php:900
1131
  msgid "returns linked author name, requires stats_author=1"
1132
  msgstr ""
1133
 
1134
+ #: ../src/Admin/admin-page.php:900
1135
  msgid "returns linked author name with copy, requires stats_author=1"
1136
  msgstr ""
1137
 
1138
+ #: ../src/Admin/admin-page.php:900
1139
  msgid "returns linked category name, requires stats_category=1"
1140
  msgstr ""
1141
 
1142
+ #: ../src/Admin/admin-page.php:900
1143
  msgid "returns linked category name with copy, requires stats_category=1"
1144
  msgstr ""
1145
 
1146
+ #: ../src/Admin/admin-page.php:900
1147
  msgid "returns linked taxonomy names, requires stats_taxonomy=1"
1148
  msgstr ""
1149
 
1150
+ #: ../src/Admin/admin-page.php:900
1151
  msgid "returns linked taxonomy names with copy, requires stats_taxonomy=1"
1152
  msgstr ""
1153
 
1154
+ #: ../src/Admin/admin-page.php:900
1155
  msgid "returns views count only, no text, requires stats_views=1"
1156
  msgstr ""
1157
 
1158
+ #: ../src/Admin/admin-page.php:900
1159
  msgid "returns views count with copy, requires stats_views=1"
1160
  msgstr ""
1161
 
1162
+ #: ../src/Admin/admin-page.php:900
1163
  msgid "returns comments count only, no text, requires stats_comments=1"
1164
  msgstr ""
1165
 
1166
+ #: ../src/Admin/admin-page.php:900
1167
  msgid "returns comments count with copy, requires stats_comments=1"
1168
  msgstr ""
1169
 
1170
+ #: ../src/Admin/admin-page.php:900
1171
  msgid "returns post/page date, requires stats_date=1"
1172
  msgstr ""
1173
 
1174
+ #: ../src/Admin/admin-page.php:900
1175
  msgid "returns post/page date with copy, requires stats_date=1"
1176
  msgstr ""
1177
 
1178
+ #: ../src/Admin/admin-page.php:900
1179
  msgid "outputs number of popular posts found"
1180
  msgstr ""
1181
 
1182
+ #: ../src/Admin/admin-page.php:900
1183
  msgid "outputs the position of the post in the listing"
1184
  msgstr ""
1185
 
1186
+ #: ../src/Block/Widget/widget.js:11
1187
+ msgid "A highly customizable block that displays your most popular posts."
1188
+ msgstr ""
1189
+
1190
+ #: ../src/Output.php:271
1191
  msgid "Sorry. No data so far."
1192
  msgstr ""
1193
 
1194
+ #: ../src/Output.php:612
1195
  #, php-format
1196
  msgid "%s ago"
1197
  msgstr ""
1198
 
1199
+ #: ../src/Output.php:775
1200
  #, php-format
1201
  msgid "%s view per day"
1202
  msgid_plural "%s views per day"
1203
  msgstr[0] ""
1204
  msgstr[1] ""
1205
 
1206
+ #: ../src/Output.php:793
1207
  #, php-format
1208
  msgid "by %s"
1209
  msgstr ""
1210
 
1211
+ #: ../src/Output.php:798
1212
  #, php-format
1213
  msgid "posted %s"
1214
  msgstr ""
1215
 
1216
+ #: ../src/Output.php:798
1217
  #, php-format
1218
  msgid "posted on %s"
1219
  msgstr ""
1220
 
1221
+ #: ../src/Output.php:803
1222
  #, php-format
1223
  msgid "under %s"
1224
  msgstr ""
1225
 
1226
+ #: ../src/Rest/PostsEndpoint.php:97
 
 
 
 
1227
  msgid "Return popular posts from specified custom post type(s)."
1228
  msgstr ""
1229
 
1230
+ #: ../src/Rest/PostsEndpoint.php:104
1231
  msgid "The maximum number of popular posts to return."
1232
  msgstr ""
1233
 
1234
+ #: ../src/Rest/PostsEndpoint.php:112
1235
  msgid "Retrieve the most popular entries published within the specified time range."
1236
  msgstr ""
1237
 
1238
+ #: ../src/Rest/PostsEndpoint.php:120
1239
  msgid "An offset point for the collection."
1240
  msgstr ""
1241
 
1242
+ #: ../src/Rest/PostsEndpoint.php:128
1243
  msgid "Set the sorting option of the popular posts."
1244
  msgstr ""
1245
 
1246
+ #: ../src/Rest/PostsEndpoint.php:136
1247
  msgid "Return popular posts from a specified time range."
1248
  msgstr ""
1249
 
1250
+ #: ../src/Rest/PostsEndpoint.php:144
1251
  msgid "Specifies the time unit of the custom time range."
1252
  msgstr ""
1253
 
1254
+ #: ../src/Rest/PostsEndpoint.php:152
1255
  msgid "Specifies the number of time units of the custom time range."
1256
  msgstr ""
1257
 
1258
+ #: ../src/Rest/PostsEndpoint.php:160
1259
  msgid "Post IDs to exclude from the listing."
1260
  msgstr ""
1261
 
1262
+ #: ../src/Rest/PostsEndpoint.php:168
1263
  msgid "Include posts in a specified taxonomy."
1264
  msgstr ""
1265
 
1266
+ #: ../src/Rest/PostsEndpoint.php:176
1267
  msgid "Taxonomy IDs, separated by comma (prefix a minus sign to exclude)."
1268
  msgstr ""
1269
 
1270
+ #: ../src/Rest/PostsEndpoint.php:184
1271
  msgid "Include popular posts from author ID(s)."
1272
  msgstr ""
1273
 
1274
+ #: ../src/Rest/ViewLoggerEndpoint.php:214
1275
  msgid "Security nonce."
1276
  msgstr ""
1277
 
1278
+ #: ../src/Rest/ViewLoggerEndpoint.php:220
1279
  msgid "The post / page ID."
1280
  msgstr ""
1281
 
1282
+ #: ../src/Rest/ViewLoggerEndpoint.php:227
1283
  msgid "Enables Data Sampling."
1284
  msgstr ""
1285
 
1286
+ #: ../src/Rest/ViewLoggerEndpoint.php:234
1287
  msgid "Sets the Sampling Rate."
1288
  msgstr ""
1289
 
1290
+ #: ../src/Rest/WidgetEndpoint.php:66
1291
+ msgid "Invalid Widget Instance ID"
1292
  msgstr ""
1293
 
1294
+ #: ../src/Widget/Widget.php:77
1295
+ msgid "The most Popular Posts on your blog."
1296
  msgstr ""
1297
 
1298
  #: ../src/Widget/form.php:13
1303
  msgid "posts"
1304
  msgstr ""
1305
 
 
 
 
 
 
 
 
 
1306
  #: ../src/Widget/form.php:23
1307
  msgid "Avg. daily views"
1308
  msgstr ""
1309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1310
  #: ../src/Widget/form.php:82
1311
  #, php-format
1312
  msgid "%s IDs, separated by comma (prefix a minus sign to exclude)"
1313
  msgstr ""
1314
 
 
 
 
 
 
 
 
 
1315
  #: ../src/Widget/form.php:98
1316
  msgid "Display post rating"
1317
  msgstr ""
1318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1319
  #: ../src/Widget/form.php:136
1320
  msgid "Width"
1321
  msgstr ""
1324
  msgid "Height"
1325
  msgstr ""
1326
 
 
 
 
 
1327
  #: ../src/Widget/form.php:148
1328
  msgid "Display comment count"
1329
  msgstr ""
1330
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1331
  #: ../src/Widget/form.php:160
1332
  msgid "WordPress Date Format"
1333
  msgstr ""
1334
 
 
 
 
 
 
 
 
 
 
 
 
 
1335
  #: ../src/Widget/form.php:205
1336
  msgid "Before / after title"
1337
  msgstr ""
1344
  msgid "Post HTML Markup"
1345
  msgstr ""
1346
 
 
 
 
 
1347
  #: ../src/Widget/form.php:218
1348
  #, php-format
1349
  msgid "see a <a href=\"%s\">list of supported browsers</a>"
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: hcabrera
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=hcabrerab%40gmail%2ecom&lc=GB&item_name=WordPress%20Popular%20Posts%20Plugin&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG_global%2egif%3aNonHosted
4
  Tags: popular, posts, widget, popularity, top
5
  Requires at least: 4.9
6
- Tested up to: 5.7.2
7
  Requires PHP: 5.4
8
- Stable tag: 5.3.3
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -97,6 +97,15 @@ The FAQ section has been moved [here](https://github.com/cabrerahector/wordpress
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
 
 
 
100
  = 5.3.3 =
101
 
102
  - Fixes a potential XSS vulnerability (props to Yu Iwama of Secure Sky Technology Inc. and the JPCERT/CC Vulnerability Coordination Group).
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=hcabrerab%40gmail%2ecom&lc=GB&item_name=WordPress%20Popular%20Posts%20Plugin&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG_global%2egif%3aNonHosted
4
  Tags: popular, posts, widget, popularity, top
5
  Requires at least: 4.9
6
+ Tested up to: 5.8
7
  Requires PHP: 5.4
8
+ Stable tag: 5.3.4
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
97
 
98
  == Changelog ==
99
 
100
+ = 5.3.4 =
101
+
102
+ - Experimental Gutenberg support! This version introduces the first WPP block. It's not enabled by default though, see the Release Notes for more.
103
+ - Fixes a potential authenticated stored XSS vulnerability (props to Visse for reporting it!)
104
+ - Overall security enhancements (props to Visse for assisting with this!)
105
+ - Other minor improvements / fixes.
106
+
107
+ [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-3-improved-php-8-support-retina-display-support-and-more/#5.3.4)
108
+
109
  = 5.3.3 =
110
 
111
  - Fixes a potential XSS vulnerability (props to Yu Iwama of Secure Sky Technology Inc. and the JPCERT/CC Vulnerability Coordination Group).
src/Admin/admin-page.php CHANGED
@@ -36,6 +36,7 @@ if ( isset($_POST['section']) ) {
36
  if ( isset($_POST['wpp-update-misc-options-token'] ) && wp_verify_nonce($_POST['wpp-update-misc-options-token'], 'wpp-update-misc-options') ) {
37
  $this->config['tools']['link']['target'] = $_POST['link_target'];
38
  $this->config['tools']['css'] = $_POST['css'];
 
39
 
40
  update_option('wpp_settings_config', $this->config);
41
  echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
@@ -618,6 +619,12 @@ if ( ! $wpp_rand = get_option("wpp_rand") ) {
618
  <p class="description"><?php _e("By default, the plugin includes a stylesheet called wpp.css which you can use to style your popular posts listing. If you wish to use your own stylesheet or do not want it to have it included in the header section of your site, use this.", 'wordpress-popular-posts'); ?></p>
619
  </td>
620
  </tr>
 
 
 
 
 
 
621
  <tr valign="top">
622
  <td colspan="2">
623
  <input type="hidden" name="section" value="misc">
36
  if ( isset($_POST['wpp-update-misc-options-token'] ) && wp_verify_nonce($_POST['wpp-update-misc-options-token'], 'wpp-update-misc-options') ) {
37
  $this->config['tools']['link']['target'] = $_POST['link_target'];
38
  $this->config['tools']['css'] = $_POST['css'];
39
+ $this->config['tools']['experimental'] = empty($_POST['experimental_features']) ? false : $_POST['experimental_features'];
40
 
41
  update_option('wpp_settings_config', $this->config);
42
  echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
619
  <p class="description"><?php _e("By default, the plugin includes a stylesheet called wpp.css which you can use to style your popular posts listing. If you wish to use your own stylesheet or do not want it to have it included in the header section of your site, use this.", 'wordpress-popular-posts'); ?></p>
620
  </td>
621
  </tr>
622
+ <tr valign="top">
623
+ <th scope="row"><label for="experimental_features"><?php _e("Enable experimental features", 'wordpress-popular-posts'); ?>:</label></th>
624
+ <td>
625
+ <input type="checkbox" class="checkbox" id="experimental_features" name="experimental_features" <?php echo ($this->config['tools']['experimental']) ? 'checked="checked"' : ''; ?>>
626
+ </td>
627
+ </tr>
628
  <tr valign="top">
629
  <td colspan="2">
630
  <input type="hidden" name="section" value="misc">
src/Block/Block.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contract to build blocks.
4
+ */
5
+
6
+ namespace WordPressPopularPosts\Block;
7
+
8
+ abstract class Block {
9
+
10
+ /**
11
+ *
12
+ */
13
+ public function hooks()
14
+ {
15
+ add_action('init', [$this, 'register']);
16
+ }
17
+
18
+ /**
19
+ *
20
+ */
21
+ abstract function register();
22
+
23
+ /**
24
+ *
25
+ */
26
+ abstract function render(array $attribute);
27
+ }
src/Block/Widget/Widget.php ADDED
@@ -0,0 +1,506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Block\Widget;
3
+
4
+ use WordPressPopularPosts\Helper;
5
+ use WordPressPopularPosts\Query;
6
+ use WordPressPopularPosts\Output;
7
+ use WordPressPopularPosts\Block\Block;
8
+
9
+ class Widget extends Block
10
+ {
11
+
12
+ /**
13
+ * Administrative settings.
14
+ *
15
+ * @since 5.4.0
16
+ * @var array
17
+ * @access private
18
+ */
19
+ private $admin_options = [];
20
+
21
+ /**
22
+ * Image object.
23
+ *
24
+ * @since 5.4.0
25
+ * @var WordPressPopularPosts\Image
26
+ * @access private
27
+ */
28
+ private $thumbnail;
29
+
30
+ /**
31
+ * Output object.
32
+ *
33
+ * @since 5.4.0
34
+ * @var \WordPressPopularPosts\Output
35
+ * @access private
36
+ */
37
+ private $output;
38
+
39
+ /**
40
+ * Translate object.
41
+ *
42
+ * @since 5.4.0
43
+ * @var \WordPressPopularPosts\Translate $translate
44
+ * @access private
45
+ */
46
+ private $translate;
47
+
48
+ /**
49
+ * Themer object.
50
+ *
51
+ * @since 5.4.0
52
+ * @var \WordPressPopularPosts\Themer $themer
53
+ * @access private
54
+ */
55
+ private $themer;
56
+
57
+ /**
58
+ * Default attributes.
59
+ *
60
+ * @since 5.4.0
61
+ * @var array $defaults
62
+ * @access private
63
+ */
64
+ private $defaults;
65
+
66
+ /**
67
+ * Construct.
68
+ *
69
+ * @since 5.4.0
70
+ * @param array $config
71
+ * @param \WordPressPopularPosts\Output $output
72
+ * @param \WordPressPopularPosts\Image $image
73
+ * @param \WordPressPopularPosts\Translate $translate
74
+ * @param \WordPressPopularPosts\Themer $themer
75
+ */
76
+ public function __construct(array $config, \WordPressPopularPosts\Output $output, \WordPressPopularPosts\Image $thumbnail, \WordPressPopularPosts\Translate $translate, \WordPressPopularPosts\Themer $themer)
77
+ {
78
+ $this->admin_options = $config;
79
+ $this->output = $output;
80
+ $this->thumbnail = $thumbnail;
81
+ $this->translate = $translate;
82
+ $this->themer = $themer;
83
+
84
+ $this->defaults = [
85
+ 'title' => '',
86
+ 'limit' => 10,
87
+ 'offset' => 0,
88
+ 'range' => 'daily',
89
+ 'time_unit' => 'hour',
90
+ 'time_quantity' => 24,
91
+ 'freshness' => false,
92
+ 'order_by' => 'views',
93
+ 'post_type' => 'post',
94
+ 'pid' => '',
95
+ 'cat' => '',
96
+ 'taxonomy' => 'category',
97
+ 'tax' => '',
98
+ 'term_id' => '',
99
+ 'author' => '',
100
+ 'title_length' => 0,
101
+ 'title_by_words' => 0,
102
+ 'excerpt_length' => 0,
103
+ 'excerpt_format' => 0,
104
+ 'excerpt_by_words' => 0,
105
+ 'thumbnail_width' => 0,
106
+ 'thumbnail_height' => 0,
107
+ 'thumbnail_build' => 'manual',
108
+ 'thumbnail_size' => '',
109
+ 'rating' => false,
110
+ 'stats_comments' => false,
111
+ 'stats_views' => true,
112
+ 'stats_author' => false,
113
+ 'stats_date' => false,
114
+ 'stats_date_format' => 'F j, Y',
115
+ 'stats_category' => false,
116
+ 'stats_taxonomy' => false,
117
+ 'custom_html' => false,
118
+ 'wpp_start' => '<ul class="wpp-list">',
119
+ 'wpp_end' => '</ul>',
120
+ 'header_start' => '<h2>',
121
+ 'header_end' => '</h2>',
122
+ 'post_html' => '',
123
+ 'theme' => ''
124
+ ];
125
+ }
126
+
127
+ /**
128
+ *
129
+ *
130
+ * @since 5.4.0
131
+ */
132
+ public function register()
133
+ {
134
+ // Block editor is not available, bail.
135
+ if ( ! function_exists('register_block_type') ) {
136
+ return;
137
+ }
138
+
139
+ // Experimental feature, bail if disabled.
140
+ if ( ! $this->admin_options['tools']['experimental'] )
141
+ return;
142
+
143
+ wp_enqueue_script(
144
+ 'block-wpp-widget-js',
145
+ plugin_dir_url(dirname(dirname(dirname(__FILE__)))) . 'assets/js/blocks/block-wpp-widget.js',
146
+ ['wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-editor'],
147
+ WPP_VERSION
148
+ );
149
+
150
+ wp_register_style(
151
+ 'block-wpp-editor-css',
152
+ plugins_url('editor.css', __FILE__),
153
+ [],
154
+ filemtime(plugin_dir_path(__FILE__) . 'editor.css')
155
+ );
156
+
157
+ register_block_type(
158
+ 'wordpress-popular-posts/widget',
159
+ [
160
+ 'editor_style' => 'block-wpp-editor-css',
161
+ 'editor_script' => 'block-wpp-widget-js',
162
+ 'render_callback' => [$this, 'render'],
163
+ 'attributes' => [
164
+ '_editMode' => [
165
+ 'type' => 'boolean',
166
+ 'default' => true
167
+ ],
168
+ 'title' => [
169
+ 'type' => 'string',
170
+ 'default' => ''
171
+ ],
172
+ 'limit' => [
173
+ 'type' =>'number',
174
+ 'default' => 10
175
+ ],
176
+ 'offset' => [
177
+ 'type' => 'number',
178
+ 'default' => 0
179
+ ],
180
+ 'order_by' => [
181
+ 'type' => 'string',
182
+ 'default' => 'views'
183
+ ],
184
+ 'range' => [
185
+ 'type' => 'string',
186
+ 'default' => 'last24hours'
187
+ ],
188
+ 'time_quantity' => [
189
+ 'type' => 'number',
190
+ 'default' => 24
191
+ ],
192
+ 'time_unit' => [
193
+ 'type' => 'string',
194
+ 'default' => 'hour'
195
+ ],
196
+ 'freshness' => [
197
+ 'type' => 'boolean',
198
+ 'default' => false
199
+ ],
200
+ /* filters */
201
+ 'post_type' => [
202
+ 'type' => 'string',
203
+ 'default' => 'post'
204
+ ],
205
+ 'pid' => [
206
+ 'type' => 'string',
207
+ 'default' => ''
208
+ ],
209
+ 'author' => [
210
+ 'type' => 'string',
211
+ 'default' => ''
212
+ ],
213
+ 'tax' => [
214
+ 'type' => 'string',
215
+ 'default' => ''
216
+ ],
217
+ 'term_id' => [
218
+ 'type' => 'string',
219
+ 'default' => ''
220
+ ],
221
+ /* post settings */
222
+ 'shorten_title' => [
223
+ 'type' => 'boolean',
224
+ 'default' => false
225
+ ],
226
+ 'title_length' => [
227
+ 'type' =>'number',
228
+ 'default' => 0
229
+ ],
230
+ 'title_by_words' => [
231
+ 'type' =>'number',
232
+ 'default' => 0
233
+ ],
234
+ 'display_post_excerpt' => [
235
+ 'type' => 'boolean',
236
+ 'default' => false
237
+ ],
238
+ 'excerpt_format' => [
239
+ 'type' => 'boolean',
240
+ 'default' => false
241
+ ],
242
+ 'excerpt_length' => [
243
+ 'type' =>'number',
244
+ 'default' => 0
245
+ ],
246
+ 'excerpt_by_words' => [
247
+ 'type' =>'number',
248
+ 'default' => 0
249
+ ],
250
+ 'display_post_thumbnail' => [
251
+ 'type' => 'boolean',
252
+ 'default' => false
253
+ ],
254
+ 'thumbnail_width' => [
255
+ 'type' =>'number',
256
+ 'default' => 0
257
+ ],
258
+ 'thumbnail_height' => [
259
+ 'type' =>'number',
260
+ 'default' => 0
261
+ ],
262
+ 'thumbnail_build' => [
263
+ 'type' => 'string',
264
+ 'default' => 'manual'
265
+ ],
266
+ 'thumbnail_size' => [
267
+ 'type' => 'string',
268
+ 'default' => ''
269
+ ],
270
+ /* stats tag settings */
271
+ 'stats_comments' => [
272
+ 'type' => 'boolean',
273
+ 'default' => false
274
+ ],
275
+ 'stats_views' => [
276
+ 'type' => 'boolean',
277
+ 'default' => true
278
+ ],
279
+ 'stats_author' => [
280
+ 'type' => 'boolean',
281
+ 'default' => false
282
+ ],
283
+ 'stats_date' => [
284
+ 'type' => 'boolean',
285
+ 'default' => false
286
+ ],
287
+ 'stats_date_format' => [
288
+ 'type' => 'string',
289
+ 'default' => 'F j, Y'
290
+ ],
291
+ 'stats_taxonomy' => [
292
+ 'type' => 'boolean',
293
+ 'default' => false
294
+ ],
295
+ 'taxonomy' => [
296
+ 'type' => 'string',
297
+ 'default' => 'category'
298
+ ],
299
+ /* HTML markup settings */
300
+ 'custom_html' => [
301
+ 'type' => 'boolean',
302
+ 'default' => false
303
+ ],
304
+ 'header_start' => [
305
+ 'type' => 'string',
306
+ 'default' => '<h2>'
307
+ ],
308
+ 'header_end' => [
309
+ 'type' => 'string',
310
+ 'default' => '</h2>'
311
+ ],
312
+ 'wpp_start' => [
313
+ 'type' => 'string',
314
+ 'default' => '<ul class="wpp-list">'
315
+ ],
316
+ 'wpp_end' => [
317
+ 'type' => 'string',
318
+ 'default' => '</ul>'
319
+ ],
320
+ 'post_html' => [
321
+ 'type' => 'string',
322
+ 'default' => '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>'
323
+ ],
324
+ 'theme' => [
325
+ 'type' => 'string',
326
+ 'default' => ''
327
+ ],
328
+ ]
329
+ ]
330
+ );
331
+ }
332
+
333
+ /**
334
+ * Renders the block.
335
+ *
336
+ * @since 5.4.0
337
+ * @param array
338
+ * @return string
339
+ */
340
+ public function render($attributes)
341
+ {
342
+ extract($this->parse_attributes($attributes));
343
+
344
+ $html = '<div class="widget popular-posts' . (( isset($attributes['className']) && $attributes['className'] ) ? ' '. esc_attr($attributes['className']) : '') . '">';
345
+
346
+ // possible values for "Time Range" and "Order by"
347
+ $time_units = ["minute", "hour", "day", "week", "month"];
348
+ $range_values = ["daily", "last24hours", "weekly", "last7days", "monthly", "last30days", "all", "custom"];
349
+ $order_by_values = ["comments", "views", "avg"];
350
+
351
+ $theme_data = $this->themer->get_theme($theme);
352
+
353
+ if ( ! isset($theme_data['json']) ) {
354
+ $theme = '';
355
+ }
356
+
357
+ $query_args = [
358
+ 'title' => strip_tags($title),
359
+ 'limit' => ( ! empty($limit) && Helper::is_number($limit) && $limit > 0 ) ? $limit : 10,
360
+ 'offset' => ( ! empty($offset) && Helper::is_number($offset) && $offset >= 0 ) ? $offset : 0,
361
+ 'range' => ( in_array($range, $range_values) ) ? $range : 'daily',
362
+ 'time_quantity' => ( ! empty($time_quantity) && Helper::is_number($time_quantity) && $time_quantity > 0 ) ? $time_quantity : 24,
363
+ 'time_unit' => ( in_array($time_unit, $time_units) ) ? $time_unit : 'hour',
364
+ 'freshness' => empty($freshness) ? false : $freshness,
365
+ 'order_by' => ( in_array($order_by, $order_by_values) ) ? $order_by : 'views',
366
+ 'post_type' => empty($post_type) ? 'post' : $post_type,
367
+ 'pid' => rtrim(preg_replace('|[^0-9,]|', '', $pid), ","),
368
+ 'cat' => rtrim(preg_replace('|[^0-9,-]|', '', $cat), ","),
369
+ 'taxonomy' => empty($tax) ? 'category' : $tax,
370
+ 'term_id' => rtrim(preg_replace('|[^0-9,;-]|', '', $term_id), ","),
371
+ 'author' => rtrim(preg_replace('|[^0-9,]|', '', $author), ","),
372
+ 'shorten_title' => [
373
+ 'active' => ( ! empty($title_length) && Helper::is_number($title_length) && $title_length > 0 ),
374
+ 'length' => ( ! empty($title_length) && Helper::is_number($title_length) ) ? $title_length : 0,
375
+ 'words' => (( ! empty($title_by_words) && Helper::is_number($title_by_words) && $title_by_words > 0 )),
376
+ ],
377
+ 'post-excerpt' => [
378
+ 'active' => ( ! empty($excerpt_length) && Helper::is_number($excerpt_length) && $excerpt_length > 0 ),
379
+ 'length' => ( ! empty($excerpt_length) && Helper::is_number($excerpt_length) ) ? $excerpt_length : 0,
380
+ 'keep_format' => ( ! empty($excerpt_format) && Helper::is_number($excerpt_format) && $excerpt_format > 0 ),
381
+ 'words' => ( ! empty($excerpt_by_words) && Helper::is_number($excerpt_by_words) && $excerpt_by_words > 0 ),
382
+ ],
383
+ 'thumbnail' => [
384
+ 'active' => ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ),
385
+ 'width' => ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ) ? $thumbnail_width : 0,
386
+ 'height' => ( ! empty($thumbnail_height) && Helper::is_number($thumbnail_height) && $thumbnail_height > 0 ) ? $thumbnail_height : 0,
387
+ 'build' => 'predefined' == $thumbnail_build ? 'predefined' : 'manual',
388
+ 'size' => empty($thumbnail_size) ? '' : $thumbnail_size,
389
+ ],
390
+ 'rating' => empty($rating) ? false : $rating,
391
+ 'stats_tag' => [
392
+ 'comment_count' => empty($stats_comments) ? false : $stats_comments,
393
+ 'views' => empty($stats_views) ? false : $stats_views,
394
+ 'author' => empty($stats_author) ? false : $stats_author,
395
+ 'date' => [
396
+ 'active' => empty($stats_date) ? false : $stats_date,
397
+ 'format' => empty($stats_date_format) ? 'F j, Y' : $stats_date_format
398
+ ],
399
+ 'category' => empty($stats_category) ? false : $stats_category,
400
+ 'taxonomy' => [
401
+ 'active' => empty($stats_taxonomy) ? false : $stats_taxonomy,
402
+ 'name' => empty($taxonomy) ? 'category' : $taxonomy,
403
+ ]
404
+ ],
405
+ 'markup' => [
406
+ 'custom_html' => empty($custom_html) ? false : $custom_html,
407
+ 'wpp-start' => empty($wpp_start) ? '' : $wpp_start,
408
+ 'wpp-end' => empty($wpp_end) ? '' : $wpp_end,
409
+ 'title-start' => empty($header_start) ? '' : $header_start,
410
+ 'title-end' => empty($header_end) ? '' : $header_end,
411
+ 'post-html' => empty($post_html) ? '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>' : $post_html
412
+ ],
413
+ 'theme' => [
414
+ 'name' => empty($theme) ? '' : $theme
415
+ ]
416
+ ];
417
+
418
+ // Post / Page / CTP filter
419
+ $ids = array_filter(explode(",", $query_args['pid']), 'is_numeric');
420
+ // Got no valid IDs, clear
421
+ if ( empty($ids) ) {
422
+ $query_args['pid'] = '';
423
+ }
424
+
425
+ // Category filter
426
+ $ids = array_filter(explode(",", $query_args['cat']), 'is_numeric');
427
+ // Got no valid IDs, clear
428
+ if ( empty($ids) ) {
429
+ $query_args['cat'] = '';
430
+ }
431
+
432
+ // Author filter
433
+ $ids = array_filter(explode(",", $query_args['author']), 'is_numeric');
434
+ // Got no valid IDs, clear
435
+ if ( empty($ids) ) {
436
+ $query_args['author'] = '';
437
+ }
438
+
439
+ // Has user set a title?
440
+ if ( '' != $query_args['title'] ) {
441
+ if ( ! $query_args['markup']['custom_html'] ) {
442
+ $query_args['markup']['title-start'] = apply_filters('wpp_block_before_title', '<h2>');
443
+ $query_args['markup']['title-end'] = apply_filters('wpp_block_after_title', '</h2>');
444
+ }
445
+ }
446
+
447
+ // Return cached results
448
+ if ( $this->admin_options['tools']['cache']['active'] ) {
449
+
450
+ $key = md5(json_encode($query_args));
451
+ $popular_posts = \WordPressPopularPosts\Cache::get($key);
452
+
453
+ if ( false === $popular_posts ) {
454
+ $popular_posts = new Query($query_args);
455
+
456
+ $time_value = $this->admin_options['tools']['cache']['interval']['value']; // eg. 5
457
+ $time_unit = $this->admin_options['tools']['cache']['interval']['time']; // eg. 'minute'
458
+
459
+ // No popular posts found, check again in 1 minute
460
+ if ( ! $popular_posts->get_posts() ) {
461
+ $time_value = 1;
462
+ $time_unit = 'minute';
463
+ }
464
+
465
+ \WordPressPopularPosts\Cache::set(
466
+ $key,
467
+ $popular_posts,
468
+ $time_value,
469
+ $time_unit
470
+ );
471
+ }
472
+
473
+ } // Get popular posts
474
+ else {
475
+ $popular_posts = new Query($query_args);
476
+ }
477
+
478
+ $this->output->set_data($popular_posts->get_posts());
479
+ $this->output->set_public_options($query_args);
480
+ $this->output->build_output();
481
+
482
+ $html .= $this->output->get_output();
483
+
484
+ $html .= '</div>';
485
+
486
+ return $html;
487
+ }
488
+
489
+ /**
490
+ * Parses attributes.
491
+ *
492
+ * @since 5.4.0
493
+ * @param array
494
+ * @return array
495
+ */
496
+ private function parse_attributes($atts = [])
497
+ {
498
+ $out = array();
499
+
500
+ foreach ( $this->defaults as $name => $default ) {
501
+ $out[$name] = array_key_exists($name, $atts) ? trim($atts[$name]) : $default;
502
+ }
503
+
504
+ return $out;
505
+ }
506
+ }
src/Block/Widget/edit.js ADDED
@@ -0,0 +1,752 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { escape_html, unescape_html } from '../utils';
2
+
3
+ const { ServerSideRender } = wp.editor;
4
+ const { Component, Fragment } = wp.element;
5
+ const { BlockControls } = wp.blockEditor;
6
+ const { Button, CheckboxControl, Disabled, SelectControl, Spinner, TextareaControl, TextControl, Toolbar } = wp.components;
7
+ const { __ } = wp.i18n;
8
+ const endpoint = 'wordpress-popular-posts/v1';
9
+
10
+ export class WPPWidgetBlockEdit extends Component
11
+ {
12
+ constructor(props)
13
+ {
14
+ super(props);
15
+
16
+ this.state = {
17
+ error: null,
18
+ editMode: true,
19
+ themes: null,
20
+ imgSizes: null,
21
+ taxonomies: null
22
+ }
23
+ }
24
+
25
+ componentDidMount()
26
+ {
27
+ const { attributes } = this.props;
28
+
29
+ this.getThemes();
30
+ this.getImageSizes();
31
+ this.getTaxonomies();
32
+
33
+ this.setState({ editMode: attributes._editMode });
34
+ }
35
+
36
+ getThemes()
37
+ {
38
+ wp.apiFetch({ path: endpoint + '/themes' })
39
+ .then(
40
+ ( themes ) => {
41
+ this.setState({
42
+ themes
43
+ });
44
+ },
45
+ ( error ) => {
46
+ this.setState({
47
+ error,
48
+ themes: null
49
+ });
50
+ }
51
+ );
52
+ }
53
+
54
+ getImageSizes()
55
+ {
56
+ wp.apiFetch({ path: endpoint + '/thumbnails' })
57
+ .then(
58
+ ( imgSizes ) => {
59
+ this.setState({
60
+ imgSizes
61
+ });
62
+ },
63
+ ( error ) => {
64
+ this.setState({
65
+ error,
66
+ imgSizes: null
67
+ });
68
+ }
69
+ );
70
+ }
71
+
72
+ getTaxonomies()
73
+ {
74
+ const { attributes } = this.props;
75
+
76
+ wp.apiFetch({ path: endpoint + '/taxonomies' })
77
+ .then(
78
+ ( taxonomies ) => {
79
+ if ( taxonomies ) {
80
+ let tax = attributes.tax.split(';'),
81
+ term_id = attributes.term_id.split(';');
82
+
83
+ if ( tax.length && tax.length == term_id.length ) {
84
+ let selected_taxonomies = {};
85
+
86
+ for( var t = 0; t < tax.length; t++ ) {
87
+ selected_taxonomies[tax[t]] = term_id[t];
88
+ }
89
+
90
+ for( const tax in taxonomies ) {
91
+ taxonomies[tax]._terms = 'undefined' != typeof selected_taxonomies[tax] ? selected_taxonomies[tax] : '';
92
+ }
93
+ }
94
+ }
95
+
96
+ this.setState({
97
+ taxonomies
98
+ });
99
+ },
100
+ ( error ) => {
101
+ this.setState({
102
+ error,
103
+ taxonomies: null
104
+ });
105
+ }
106
+ );
107
+ }
108
+
109
+ getBlockControls()
110
+ {
111
+ const { setAttributes } = this.props;
112
+ const _self = this;
113
+
114
+ function onPreviewChange()
115
+ {
116
+ let editMode = ! _self.state.editMode;
117
+ _self.setState({ editMode: editMode });
118
+ setAttributes({ _editMode: editMode });
119
+ }
120
+
121
+ return (
122
+ <BlockControls>
123
+ <Toolbar>
124
+ <Button
125
+ label={ this.state.editMode ? __('Preview', 'wordpress-popular-posts') : __('Edit', 'wordpress-popular-posts') }
126
+ icon={ this.state.editMode ? "format-image" : "edit" }
127
+ onClick={onPreviewChange}
128
+ />
129
+ </Toolbar>
130
+ </BlockControls>
131
+ );
132
+ }
133
+
134
+ getMainFields()
135
+ {
136
+ const { attributes, setAttributes } = this.props;
137
+
138
+ function onTitleChange(value)
139
+ {
140
+ value = escape_html(unescape_html(value));
141
+ setAttributes({ title: value });
142
+ }
143
+
144
+ function onLimitChange(value)
145
+ {
146
+ let limit = Number.isInteger(Number(value)) && Number(value) > 0 ? value : 10;
147
+ setAttributes({ limit: Number(limit) });
148
+ }
149
+
150
+ function onOrderByChange(value)
151
+ {
152
+ setAttributes({ order_by: value });
153
+ }
154
+
155
+ function onTimeRangeChange(value)
156
+ {
157
+ setAttributes({ range: value });
158
+ }
159
+
160
+ function onTimeQuantityChange(value) {
161
+ let qty = Number.isInteger(Number(value)) && Number(value) > 0 ? value : 24;
162
+ setAttributes({ time_quantity: Number(qty) });
163
+ }
164
+
165
+ function onTimeUnitChange(value) {
166
+ setAttributes({ time_unit: value });
167
+ }
168
+
169
+ function onFreshnessChange(value)
170
+ {
171
+ setAttributes({ freshness: value });
172
+ }
173
+
174
+ return <Fragment>
175
+ <TextControl
176
+ label={__('Title', 'wordpress-popular-posts')}
177
+ value={attributes.title}
178
+ onChange={onTitleChange}
179
+ />
180
+ <TextControl
181
+ label={__('Limit', 'wordpress-popular-posts')}
182
+ value={attributes.limit}
183
+ onChange={onLimitChange}
184
+ />
185
+ <SelectControl
186
+ label={__('Sort posts by', 'wordpress-popular-posts')}
187
+ value={attributes.order_by}
188
+ options={[
189
+ {label: __('Total views', 'wordpress-popular-posts'), value: 'views'},
190
+ {label: __('Comments', 'wordpress-popular-posts'), value: 'comments'}
191
+ ]}
192
+ onChange={onOrderByChange}
193
+ />
194
+ <SelectControl
195
+ label={__('Time Range', 'wordpress-popular-posts')}
196
+ value={attributes.range}
197
+ options={[
198
+ {label: __('Last 24 Hours', 'wordpress-popular-posts'), value: 'last24hours'},
199
+ {label: __('Last 7 days', 'wordpress-popular-posts'), value: 'last7days'},
200
+ {label: __('Last 30 days', 'wordpress-popular-posts'), value: 'last30days'},
201
+ {label: __('All-time', 'wordpress-popular-posts'), value: 'all'},
202
+ {label: __('Custom', 'wordpress-popular-posts'), value: 'custom'},
203
+ ]}
204
+ onChange={onTimeRangeChange}
205
+ />
206
+ { 'custom' == attributes.range &&
207
+ <div className='option-subset'>
208
+ <TextControl
209
+ label={__('Time Quantity', 'wordpress-popular-posts')}
210
+ value={attributes.time_quantity}
211
+ onChange={onTimeQuantityChange}
212
+ />
213
+ <SelectControl
214
+ label={__('Time Unit', 'wordpress-popular-posts')}
215
+ value={attributes.time_unit}
216
+ options={[
217
+ {label: __('Minute(s)', 'wordpress-popular-posts'), value: 'minute'},
218
+ {label: __('Hour(s)', 'wordpress-popular-posts'), value: 'hour'},
219
+ {label: __('Day(s)', 'wordpress-popular-posts'), value: 'day'}
220
+ ]}
221
+ onChange={onTimeUnitChange}
222
+ />
223
+ </div>
224
+ }
225
+ <CheckboxControl
226
+ label={__('Display only posts published within the selected Time Range', 'wordpress-popular-posts')}
227
+ checked={attributes.freshness}
228
+ onChange={onFreshnessChange}
229
+ />
230
+ </Fragment>;
231
+ }
232
+
233
+ getFiltersFields()
234
+ {
235
+ const { attributes, setAttributes } = this.props;
236
+ const _self = this;
237
+
238
+ function onPostTypeChange(value)
239
+ {
240
+ let new_value = value.replace(/[^a-z0-9-_\,]+/gi, '');
241
+ setAttributes({ post_type: new_value });
242
+ }
243
+
244
+ function onPostIDExcludeChange(value)
245
+ {
246
+ let new_value = value.replace(/[^0-9\,]/g, '');
247
+ setAttributes({ pid: new_value });
248
+ }
249
+
250
+ function onAuthorChange(value)
251
+ {
252
+ let new_value = value.replace(/[^0-9\,]/g, '');
253
+ setAttributes({ author: new_value });
254
+ }
255
+
256
+ function onTaxChange(taxonomy_name, terms)
257
+ {
258
+ let taxonomies = _self.state.taxonomies;
259
+
260
+ terms = terms.replace(/[^0-9-\,]/g, '');
261
+
262
+ if ( taxonomies && 'undefined' != typeof taxonomies[taxonomy_name] ) {
263
+ taxonomies[taxonomy_name]._terms = terms;
264
+ _self.setState({ taxonomies: taxonomies });
265
+ }
266
+ }
267
+
268
+ function onTaxBlur(taxonomy_name)
269
+ {
270
+ let taxonomies = _self.state.taxonomies;
271
+
272
+ if ( taxonomies && 'undefined' != typeof taxonomies[taxonomy_name] ) {
273
+ let terms_arr = taxonomies[taxonomy_name]._terms.split(',');
274
+
275
+ // Remove invalid values
276
+ if ( terms_arr.length )
277
+ terms_arr = terms_arr.map((term) => term.trim())
278
+ .filter((term) => '' != term && '-' != term);
279
+
280
+ // Remove duplicates
281
+ if ( terms_arr.length )
282
+ terms_arr = Array.from(new Set(terms_arr));
283
+
284
+ taxonomies[taxonomy_name]._terms = terms_arr.join(',');
285
+
286
+ _self.setState({ taxonomies });
287
+
288
+ let tax = '',
289
+ term_id = '';
290
+
291
+ for ( let key in _self.state.taxonomies ) {
292
+ if ( _self.state.taxonomies.hasOwnProperty(key) ) {
293
+
294
+ if ( ! _self.state.taxonomies[key]._terms.length )
295
+ continue;
296
+
297
+ tax += key + ';';
298
+ term_id += _self.state.taxonomies[key]._terms + ';';
299
+ }
300
+ }
301
+
302
+ // Remove trailing semicolon
303
+ if ( tax && term_id ) {
304
+ tax = tax.replace(new RegExp(';$'), '');
305
+ term_id = term_id.replace(new RegExp(';$'), '');
306
+ }
307
+
308
+ setAttributes({ tax: tax, term_id: term_id });
309
+ }
310
+ }
311
+
312
+ let taxonomies = [];
313
+
314
+ if ( this.state.taxonomies ) {
315
+ for( const tax in this.state.taxonomies ) {
316
+ taxonomies.push(
317
+ {
318
+ name: this.state.taxonomies[tax].name,
319
+ label: this.state.taxonomies[tax].labels.singular_name + ' (' + this.state.taxonomies[tax].name + ')',
320
+ terms: this.state.taxonomies[tax]._terms
321
+ }
322
+ );
323
+ }
324
+ }
325
+
326
+ return <Fragment>
327
+ <p className='not-a-legend'><strong>{__('Filters', 'wordpress-popular-posts')}</strong></p>
328
+ <TextControl
329
+ label={__('Post type(s)', 'wordpress-popular-posts')}
330
+ help={__('Post types must be comma separated.', 'wordpress-popular-posts')}
331
+ value={attributes.post_type}
332
+ onChange={onPostTypeChange}
333
+ />
334
+ <TextControl
335
+ label={__('Post ID(s) to exclude', 'wordpress-popular-posts')}
336
+ help={__('IDs must be comma separated.', 'wordpress-popular-posts')}
337
+ value={attributes.pid}
338
+ onChange={onPostIDExcludeChange}
339
+ />
340
+ <TextControl
341
+ label={__('Author ID(s)', 'wordpress-popular-posts')}
342
+ help={__('IDs must be comma separated.', 'wordpress-popular-posts')}
343
+ value={attributes.author}
344
+ onChange={onAuthorChange}
345
+ />
346
+ { taxonomies && taxonomies.filter((tax) => 'post_format' != tax.name).map((tax) =>
347
+ {
348
+ return (
349
+ <TextControl
350
+ label={tax.label}
351
+ help={__('Term IDs must be comma separated, prefix a minus sign to exclude.', 'wordpress-popular-posts')}
352
+ value={tax.terms}
353
+ onChange={(terms) => onTaxChange(tax.name, terms)}
354
+ onBlur={() => onTaxBlur(tax.name)}
355
+ />
356
+ );
357
+ }
358
+ )}
359
+ </Fragment>;
360
+ }
361
+
362
+ getPostSettingsFields()
363
+ {
364
+ const { attributes, setAttributes } = this.props;
365
+ const _self = this;
366
+
367
+ function onShortenTitleChange(value) {
368
+ if ( false == value )
369
+ setAttributes({ title_length: 0, title_by_words: 0, shorten_title: value });
370
+ else
371
+ setAttributes({ shorten_title: value, title_length: 25 });
372
+ }
373
+
374
+ function onTitleLengthChange(value)
375
+ {
376
+ let length = Number.isInteger(Number(value)) && Number(value) >= 0 ? value : 0;
377
+ setAttributes({ title_length: Number(length) });
378
+ }
379
+
380
+ function onDisplayExcerptChange(value) {
381
+ if ( false == value )
382
+ setAttributes({ excerpt_length: 0, excerpt_by_words: 0, display_post_excerpt: value });
383
+ else
384
+ setAttributes({ display_post_excerpt: value, excerpt_length: 55 });
385
+ }
386
+
387
+ function onExcerptLengthChange(value)
388
+ {
389
+ let length = Number.isInteger(Number(value)) && Number(value) >= 0 ? value : 0;
390
+ setAttributes({ excerpt_length: Number(length) });
391
+ }
392
+
393
+ function onDisplayThumbnailChange(value) {
394
+ if ( false == value )
395
+ setAttributes({ thumbnail_width: 0, thumbnail_height: 0, display_post_thumbnail: value });
396
+ else
397
+ setAttributes({ thumbnail_width: 75, thumbnail_height: 75, display_post_thumbnail: value });
398
+ }
399
+
400
+ function onThumbnailDimChange(dim, value)
401
+ {
402
+ let width = Number.isInteger(Number(value)) && Number(value) >= 0 ? value : 0;
403
+ setAttributes(( 'width' == dim ? { thumbnail_width: Number(width) } : { thumbnail_height: Number(width) } ));
404
+ }
405
+
406
+ function onThumbnailBuildChange(value)
407
+ {
408
+ if ( 'predefined' == value ) {
409
+ let fallback = 0;
410
+
411
+ setAttributes({
412
+ thumbnail_width: _self.state.imgSizes[sizes[fallback].value].width,
413
+ thumbnail_height: _self.state.imgSizes[sizes[fallback].value].height,
414
+ thumbnail_size: sizes[fallback].value
415
+ });
416
+ }
417
+ setAttributes({ thumbnail_build: value });
418
+ }
419
+
420
+ function onThumbnailSizeChange(value) {
421
+ setAttributes({
422
+ thumbnail_width: _self.state.imgSizes[value].width,
423
+ thumbnail_height: _self.state.imgSizes[value].height,
424
+ thumbnail_size: value
425
+ });
426
+ }
427
+
428
+ let sizes = [];
429
+
430
+ if ( this.state.imgSizes ) {
431
+ for( const size in this.state.imgSizes ) {
432
+ sizes.push(
433
+ {
434
+ label: size,
435
+ value: size
436
+ },
437
+ );
438
+ }
439
+ }
440
+
441
+ return <Fragment>
442
+ <p className='not-a-legend'><strong>{__('Posts settings', 'wordpress-popular-posts')}</strong></p>
443
+ <CheckboxControl
444
+ label={__('Shorten title', 'wordpress-popular-posts')}
445
+ checked={attributes.shorten_title}
446
+ onChange={onShortenTitleChange}
447
+ />
448
+ { attributes.shorten_title &&
449
+ <div className='option-subset'>
450
+ <TextControl
451
+ label={__('Shorten title to', 'wordpress-popular-posts')}
452
+ value={attributes.title_length}
453
+ onChange={onTitleLengthChange}
454
+ />
455
+ <SelectControl
456
+ value={attributes.title_by_words}
457
+ options={[
458
+ { label: __('characters', 'wordpress-popular-posts'), value: 0 },
459
+ { label: __('words', 'wordpress-popular-posts'), value: 1 },
460
+ ]}
461
+ onChange={(value) => setAttributes({ title_by_words: Number(value) })}
462
+ />
463
+ </div>
464
+ }
465
+ <CheckboxControl
466
+ label={__('Display post excerpt', 'wordpress-popular-posts')}
467
+ checked={attributes.display_post_excerpt}
468
+ onChange={onDisplayExcerptChange}
469
+ />
470
+ { attributes.display_post_excerpt &&
471
+ <div className='option-subset'>
472
+ <CheckboxControl
473
+ label={__('Keep text format and links', 'wordpress-popular-posts')}
474
+ checked={attributes.excerpt_format}
475
+ onChange={(value) => setAttributes({ excerpt_format: value })}
476
+ />
477
+ <TextControl
478
+ label={__('Excerpt length', 'wordpress-popular-posts')}
479
+ value={attributes.excerpt_length}
480
+ onChange={onExcerptLengthChange}
481
+ />
482
+ <SelectControl
483
+ value={attributes.excerpt_by_words}
484
+ options={[
485
+ { label: __('characters', 'wordpress-popular-posts'), value: 0 },
486
+ { label: __('words', 'wordpress-popular-posts'), value: 1 },
487
+ ]}
488
+ onChange={(value) => setAttributes({ excerpt_by_words: Number(value) })}
489
+ />
490
+ </div>
491
+ }
492
+ <CheckboxControl
493
+ label={__('Display post thumbnail', 'wordpress-popular-posts')}
494
+ checked={attributes.display_post_thumbnail}
495
+ onChange={onDisplayThumbnailChange}
496
+ />
497
+ { attributes.display_post_thumbnail &&
498
+ <div className='option-subset'>
499
+ <SelectControl
500
+ value={attributes.thumbnail_build}
501
+ options={[
502
+ { label: __('Set size manually', 'wordpress-popular-posts'), value: 'manual' },
503
+ { label: __('Use predefined size', 'wordpress-popular-posts'), value: 'predefined' },
504
+ ]}
505
+ onChange={onThumbnailBuildChange}
506
+ />
507
+ { 'manual' == attributes.thumbnail_build &&
508
+ <Fragment>
509
+ <TextControl
510
+ label={__('Thumbnail width', 'wordpress-popular-posts')}
511
+ help={__('Size in px units (pixels)', 'wordpress-popular-posts')}
512
+ value={attributes.thumbnail_width}
513
+ onChange={(value) => onThumbnailDimChange('width', value)}
514
+ />
515
+ <TextControl
516
+ label={__('Thumbnail height', 'wordpress-popular-posts')}
517
+ help={__('Size in px units (pixels)', 'wordpress-popular-posts')}
518
+ value={attributes.thumbnail_height}
519
+ onChange={(value) => onThumbnailDimChange('height', value)}
520
+ />
521
+ </Fragment>
522
+ }
523
+ { 'predefined' == attributes.thumbnail_build &&
524
+ <Fragment>
525
+ <SelectControl
526
+ value={attributes.thumbnail_size}
527
+ options={sizes}
528
+ onChange={onThumbnailSizeChange}
529
+ />
530
+ </Fragment>
531
+ }
532
+ </div>
533
+ }
534
+ </Fragment>;
535
+ }
536
+
537
+ getStatsTagFields()
538
+ {
539
+ const { attributes, setAttributes } = this.props;
540
+
541
+ let taxonomies = [];
542
+
543
+ if ( this.state.taxonomies ) {
544
+ for( const tax in this.state.taxonomies ) {
545
+ taxonomies.push(
546
+ {
547
+ label: this.state.taxonomies[tax].labels.singular_name + ' (' + this.state.taxonomies[tax].name + ')',
548
+ value: this.state.taxonomies[tax].name
549
+ },
550
+ );
551
+ }
552
+ }
553
+
554
+ return <Fragment>
555
+ <p className='not-a-legend'><strong>{__('Stats Tag settings', 'wordpress-popular-posts')}</strong></p>
556
+ <CheckboxControl
557
+ label={__('Display comments count', 'wordpress-popular-posts')}
558
+ checked={attributes.stats_comments}
559
+ onChange={(value) => setAttributes({ stats_comments: value })}
560
+ />
561
+ <CheckboxControl
562
+ label={__('Display views', 'wordpress-popular-posts')}
563
+ checked={attributes.stats_views}
564
+ onChange={(value) => setAttributes({ stats_views: value })}
565
+ />
566
+ <CheckboxControl
567
+ label={__('Display author', 'wordpress-popular-posts')}
568
+ checked={attributes.stats_author}
569
+ onChange={(value) => setAttributes({ stats_author: value })}
570
+ />
571
+ <CheckboxControl
572
+ label={__('Display date', 'wordpress-popular-posts')}
573
+ checked={attributes.stats_date}
574
+ onChange={(value) => setAttributes({ stats_date: value })}
575
+ />
576
+ { attributes.stats_date &&
577
+ <div className='option-subset'>
578
+ <SelectControl
579
+ label={__('Date Format', 'wordpress-popular-posts')}
580
+ value={attributes.stats_date_format}
581
+ options={[
582
+ { label: __('Relative', 'wordpress-popular-posts'), value: 'relative' },
583
+ { label: __('Month Day, Year', 'wordpress-popular-posts'), value: 'F j, Y' },
584
+ { label: __('yyyy/mm/dd', 'wordpress-popular-posts'), value: 'Y/m/d' },
585
+ { label: __('mm/dd/yyyy', 'wordpress-popular-posts'), value: 'm/d/Y' },
586
+ { label: __('dd/mm/yyyy', 'wordpress-popular-posts'), value: 'd/m/Y' },
587
+ ]}
588
+ onChange={(value) => setAttributes({ stats_date_format: value })}
589
+ />
590
+ </div>
591
+ }
592
+ <CheckboxControl
593
+ label={__('Display taxonomy', 'wordpress-popular-posts')}
594
+ checked={attributes.stats_taxonomy}
595
+ onChange={(value) => setAttributes({ stats_taxonomy: value })}
596
+ />
597
+ { attributes.stats_taxonomy &&
598
+ <div className='option-subset'>
599
+ <SelectControl
600
+ label={__('Taxonomy', 'wordpress-popular-posts')}
601
+ value={attributes.taxonomy}
602
+ options={taxonomies}
603
+ onChange={(value) => setAttributes({ taxonomy: value })}
604
+ />
605
+ </div>
606
+ }
607
+ </Fragment>;
608
+ }
609
+
610
+ getHTMLMarkupFields()
611
+ {
612
+ const { attributes, setAttributes } = this.props;
613
+ const _self = this;
614
+
615
+ function onThemeChange(value)
616
+ {
617
+ if ( 'undefined' != typeof _self.state.themes[value] ) {
618
+ let config = _self.state.themes[value].json.config;
619
+
620
+ setAttributes({
621
+ shorten_title: config.shorten_title.active,
622
+ title_length: config.shorten_title.title_length,
623
+ title_by_words: config.shorten_title.words ? 1 : 0,
624
+ display_post_excerpt: config['post-excerpt'].active,
625
+ excerpt_format: config['post-excerpt'].format,
626
+ excerpt_length: config['post-excerpt'].length,
627
+ excerpt_by_words: config['post-excerpt'].words ? 1 : 0,
628
+ display_post_thumbnail: config.thumbnail.active,
629
+ thumbnail_build: config.thumbnail.build,
630
+ thumbnail_width: config.thumbnail.width,
631
+ thumbnail_height: config.thumbnail.height,
632
+ stats_comments: config.stats_tag.comment_count,
633
+ stats_views: config.stats_tag.views,
634
+ stats_author: config.stats_tag.author,
635
+ stats_date: config.stats_tag.date.active,
636
+ stats_date_format: config.stats_tag.date.format,
637
+ stats_taxonomy: config.stats_tag.taxonomy.active,
638
+ taxonomy: config.stats_tag.taxonomy.name,
639
+ custom_html: true,
640
+ wpp_start: config.markup['wpp-start'],
641
+ wpp_end: config.markup['wpp-end'],
642
+ post_html: config.markup['post-html'],
643
+ theme: value
644
+ });
645
+ } else {
646
+ setAttributes({ theme: value });
647
+ }
648
+ }
649
+
650
+ let themes = [
651
+ {
652
+ label: __('None', 'wordpress-popular-posts'),
653
+ value: ''
654
+ },
655
+ ];
656
+
657
+ if ( this.state.themes ) {
658
+ for( const theme in this.state.themes ) {
659
+ themes.push(
660
+ {
661
+ label: this.state.themes[theme].json.name,
662
+ value: theme
663
+ },
664
+ );
665
+ }
666
+ }
667
+
668
+ return <Fragment>
669
+ <p className='not-a-legend'><strong>{__('HTML Markup settings', 'wordpress-popular-posts')}</strong></p>
670
+ <CheckboxControl
671
+ label={__('Use custom HTML Markup', 'wordpress-popular-posts')}
672
+ checked={attributes.custom_html}
673
+ onChange={(value) => setAttributes({ custom_html: value })}
674
+ />
675
+ { attributes.custom_html &&
676
+ <div className='option-subset'>
677
+ <TextareaControl
678
+ rows="1"
679
+ label={__('Before title', 'wordpress-popular-posts')}
680
+ value={attributes.header_start}
681
+ onChange={(value) => setAttributes({ header_start: value })}
682
+ />
683
+ <TextareaControl
684
+ rows="1"
685
+ label={__('After title', 'wordpress-popular-posts')}
686
+ value={attributes.header_end}
687
+ onChange={(value) => setAttributes({ header_end: value })}
688
+ />
689
+ <TextareaControl
690
+ rows="1"
691
+ label={__('Before popular posts', 'wordpress-popular-posts')}
692
+ value={attributes.wpp_start}
693
+ onChange={(value) => setAttributes({ wpp_start: value })}
694
+ />
695
+ <TextareaControl
696
+ rows="1"
697
+ label={__('After popular posts', 'wordpress-popular-posts')}
698
+ value={attributes.wpp_end}
699
+ onChange={(value) => setAttributes({ wpp_end: value })}
700
+ />
701
+ <TextareaControl
702
+ label={__('Post HTML markup', 'wordpress-popular-posts')}
703
+ value={attributes.post_html}
704
+ onChange={(value) => setAttributes({ post_html: value })}
705
+ />
706
+ </div>
707
+ }
708
+ <SelectControl
709
+ label={__('Theme', 'wordpress-popular-posts')}
710
+ value={attributes.theme}
711
+ options={themes}
712
+ onChange={onThemeChange}
713
+ />
714
+ </Fragment>;
715
+ }
716
+
717
+ render()
718
+ {
719
+ if ( ! this.state.taxonomies || ! this.state.themes || ! this.state.imgSizes )
720
+ return <Spinner />;
721
+
722
+ const { isSelected, className, attributes } = this.props;
723
+
724
+ let classes = className;
725
+ classes += this.state.editMode ? ' in-edit-mode' : ' in-preview-mode';
726
+ classes += isSelected ? ' is-selected' : '';
727
+
728
+ return ([
729
+ this.getBlockControls(),
730
+ <div className={classes}>
731
+ { this.state.editMode &&
732
+ <Fragment>
733
+ {this.getMainFields()}
734
+ {this.getFiltersFields()}
735
+ {this.getPostSettingsFields()}
736
+ {this.getStatsTagFields()}
737
+ {this.getHTMLMarkupFields()}
738
+ </Fragment>
739
+ }
740
+ { ! this.state.editMode &&
741
+ <Disabled>
742
+ <ServerSideRender
743
+ block={this.props.name}
744
+ className={className}
745
+ attributes={attributes}
746
+ />
747
+ </Disabled>
748
+ }
749
+ </div>
750
+ ]);
751
+ }
752
+ }
src/Block/Widget/editor.css ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wp-block-wordpress-popular-posts-widget.in-edit-mode {
2
+ padding: 1.8em 1.5em;
3
+ background: #fafafa;
4
+ }
5
+
6
+ .wp-block-wordpress-popular-posts-widget .wpp-list {
7
+ margin-left: 0 !important;
8
+ margin-right: 0 !important;
9
+ padding-left: 0 !important;
10
+ padding-right: 0 !important;
11
+ }
12
+
13
+ .wp-block-wordpress-popular-posts-widget .option-subset {
14
+ margin: 0 0 1em;
15
+ padding: 1.25em 1.5em;
16
+ background: #f0f0f0;
17
+ }
18
+
19
+ .wp-block-wordpress-popular-posts-widget .components-base-control {
20
+ }
21
+
22
+ .wp-block-wordpress-popular-posts-widget .components-base-control .components-base-control__help {
23
+ margin: 0 0 1em;
24
+ font-size: 0.9em;
25
+ }
26
+
27
+ .wp-block-wordpress-popular-posts-widget .components-base-control .components-base-control__field {
28
+ }
29
+
30
+ .wp-block-wordpress-popular-posts-widget .components-base-control .components-base-control__field label {
31
+ font-weight: 600;
32
+ }
33
+
34
+ .wp-block-wordpress-popular-posts-widget .components-base-control .components-base-control__field .components-select-control {
35
+ }
36
+
37
+ .wp-block-wordpress-popular-posts-widget .components-base-control .components-base-control__field .components-select-control .components-input-control__container {
38
+ }
39
+
40
+ .wp-block-wordpress-popular-posts-widget .components-base-control .components-base-control__field .components-select-control .components-input-control__container .components-select-control__input {
41
+ max-width: none;
42
+ }
src/Block/Widget/widget.js ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import icons from '../icons';
2
+ import { WPPWidgetBlockEdit } from './edit';
3
+
4
+ const { registerBlockType } = wp.blocks;
5
+ const { __ } = wp.i18n;
6
+
7
+ registerBlockType('wordpress-popular-posts/widget', {
8
+ title: 'WordPress Popular Posts',
9
+ category: 'widgets',
10
+ icon: icons.flame,
11
+ description: __('A highly customizable block that displays your most popular posts.', 'wordpress-popular-posts'),
12
+ keywords: ['popular', 'posts', 'trending', 'popularity'],
13
+
14
+ attributes: {
15
+ _editMode: {
16
+ type: 'boolean',
17
+ default: true
18
+ },
19
+ title: {
20
+ type: 'string',
21
+ },
22
+ limit: {
23
+ type: 'number',
24
+ default: 10
25
+ },
26
+ offset: {
27
+ type: 'number',
28
+ default: 0
29
+ },
30
+ order_by: {
31
+ type: 'string',
32
+ default: 'views'
33
+ },
34
+ range: {
35
+ type: 'string',
36
+ default: 'last24hours'
37
+ },
38
+ time_quantity: {
39
+ type: 'number',
40
+ default: 24
41
+ },
42
+ time_unit: {
43
+ type: 'string',
44
+ default: 'hour'
45
+ },
46
+ freshness: {
47
+ type: 'boolean',
48
+ default: false
49
+ },
50
+ /* filters */
51
+ post_type: {
52
+ type: 'string',
53
+ default: 'post'
54
+ },
55
+ pid: {
56
+ type: 'string',
57
+ default: ''
58
+ },
59
+ author: {
60
+ type: 'string',
61
+ default: ''
62
+ },
63
+ tax: {
64
+ type: 'string',
65
+ default: ''
66
+ },
67
+ term_id: {
68
+ type: 'string',
69
+ default: ''
70
+ },
71
+ /* post settings */
72
+ shorten_title: {
73
+ type: 'boolean',
74
+ default: false
75
+ },
76
+ title_length: {
77
+ type: 'number',
78
+ default: 0
79
+ },
80
+ title_by_words: {
81
+ type: 'number',
82
+ default: 0
83
+ },
84
+ display_post_excerpt: {
85
+ type: 'boolean',
86
+ default: false
87
+ },
88
+ excerpt_format: {
89
+ type: 'boolean',
90
+ default: false
91
+ },
92
+ excerpt_length: {
93
+ type: 'number',
94
+ default: 0
95
+ },
96
+ excerpt_by_words: {
97
+ type: 'number',
98
+ default: 0
99
+ },
100
+ display_post_thumbnail: {
101
+ type: 'boolean',
102
+ default: false
103
+ },
104
+ thumbnail_width: {
105
+ type: 'number',
106
+ default: 0
107
+ },
108
+ thumbnail_height: {
109
+ type: 'number',
110
+ default: 0
111
+ },
112
+ thumbnail_build: {
113
+ type: 'string',
114
+ default: 'manual'
115
+ },
116
+ thumbnail_size: {
117
+ type: 'string',
118
+ default: ''
119
+ },
120
+ /* stats tag settings */
121
+ stats_comments: {
122
+ type: 'boolean',
123
+ default: false
124
+ },
125
+ stats_views: {
126
+ type: 'boolean',
127
+ default: true
128
+ },
129
+ stats_author: {
130
+ type: 'boolean',
131
+ default: false
132
+ },
133
+ stats_date: {
134
+ type: 'boolean',
135
+ default: false
136
+ },
137
+ stats_date_format: {
138
+ type: 'string',
139
+ default: 'F j, Y'
140
+ },
141
+ stats_taxonomy: {
142
+ type: 'boolean',
143
+ default: false
144
+ },
145
+ taxonomy: {
146
+ type: 'string',
147
+ default: ''
148
+ },
149
+ /* HTML markup settings */
150
+ custom_html: {
151
+ type: 'boolean',
152
+ default: false
153
+ },
154
+ header_start: {
155
+ type: 'string',
156
+ default: '<h2>'
157
+ },
158
+ header_end: {
159
+ type: 'string',
160
+ default: '</h2>'
161
+ },
162
+ wpp_start: {
163
+ type: 'string',
164
+ default: '<ul class="wpp-list">'
165
+ },
166
+ wpp_end: {
167
+ type: 'string',
168
+ default: '</ul>'
169
+ },
170
+ post_html: {
171
+ type: 'string',
172
+ default: '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>'
173
+ },
174
+ theme: {
175
+ type: 'string',
176
+ default: ''
177
+ },
178
+ },
179
+ supports: {
180
+ anchor: true,
181
+ align: true,
182
+ html: false
183
+ },
184
+ example: {
185
+ attributes: {
186
+ _editMode: false,
187
+ title: 'Popular Posts',
188
+ limit: 3,
189
+ range: 'last7days',
190
+ display_post_excerpt: true,
191
+ excerpt_length: 75,
192
+ display_post_thumbnail: true,
193
+ thumbnail_width: 75,
194
+ thumbnail_height: 75,
195
+ stats_views: false,
196
+ stats_taxonomy: true,
197
+ custom_html: true,
198
+ wpp_start: '<ul class="wpp-list wpp-cards">',
199
+ post_html: '<li>{thumb_img} <div class="wpp-item-data"><div class="taxonomies">{taxonomy}</div>{title} <p class="wpp-excerpt">{excerpt}</p></div></li>',
200
+ theme: 'cards'
201
+ }
202
+ },
203
+
204
+ edit: WPPWidgetBlockEdit,
205
+
206
+ save: () => {
207
+ return null;
208
+ }
209
+ });
src/Block/icons.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ const icons = {};
2
+
3
+ icons.flame = <svg viewBox="0 0 248 379"><path fill="#fff" d="M-83,96q0-122.5,0-245H165q0,131,0,262a31.87,31.87,0,0,1-.95-4.33A123.87,123.87,0,0,0,153.47,68.3c-12.28-27.74-31.1-50.64-53-71.21C75.67-26.13,55.85-52,54.32-87.87c-.79-18.47.81-36.24,11.59-52.15,1.08-1.59.38-4.4.5-6.64-2.43.1-5.5-.7-7.18.47a140.91,140.91,0,0,0-17.12,13.72C19.49-110.67,3-84.6-9.51-56A149,149,0,0,0-21.86-3.77c-2,39.4,11.38,73.46,36.17,103.51,1.74,2.11,3.51,4.2,5.27,6.3l-.67,1.07c-3.94-1.07-8-1.83-11.82-3.24C-25.17,91.94-52.36,58.57-51.12,21c.1-2.91.21-6.45-3.51-6.49-2,0-4.76,2.16-5.79,4.09-9.4,17.55-16.35,36-19.73,55.73C-81.38,81.49-82.07,88.76-83,96Z" transform="translate(83 149)"/><path fill="#ba2f2f" d="M-83,96c.93-7.24,1.62-14.51,2.85-21.7,3.38-19.69,10.33-38.18,19.73-55.73,1-1.93,3.83-4.11,5.79-4.09,3.72,0,3.61,3.58,3.51,6.49-1.25,37.59,25.94,71,58.2,82.89,3.82,1.41,7.87,2.18,11.82,3.24l.67-1.07c-1.76-2.1-3.52-4.19-5.27-6.3C-10.49,69.68-23.88,35.63-21.86-3.77A149,149,0,0,1-9.51-56c12.48-28.62,29-54.69,51.62-76.5a140.91,140.91,0,0,1,17.12-13.72c1.68-1.18,4.75-.37,7.18-.47-.13,2.24.58,5-.5,6.64-10.78,15.9-12.37,33.68-11.59,52.15,1.53,35.89,21.35,61.74,46.11,85,21.94,20.57,40.76,43.47,53,71.21a123.87,123.87,0,0,1,10.59,40.36A31.87,31.87,0,0,0,165,113v9c-.7,4.24-1.17,8.54-2.13,12.73-10.74,46.51-37.08,78.75-84.34,91.58C72.16,228,65.52,228.79,59,230H43a25.19,25.19,0,0,0-3.12-1.18c-10-2.37-20.21-4.12-30-7.12-45.83-14-75.19-44.64-89-90.24-2.28-7.52-2.64-15.63-3.88-23.46Q-83,102-83,96ZM61.63-143.61c-6.24,5.39-12.87,10.38-18.64,16.22A229,229,0,0,0-8.77-46.26,138.37,138.37,0,0,0-16.63,23c4.69,32.54,20.21,59.59,42.4,83.23,1.34,1.43,2.7,2.83,4.8,5-15.23,1-28-3.3-39.74-10.64-29.74-18.62-46-45.23-46.8-81a138.75,138.75,0,0,0-7.46,14.67A178.29,178.29,0,0,0-78.24,93.09C-80.9,129.7-68,160.25-42.78,185.71c28.91,29.16,65.19,41.42,105.43,38.91,43.82-2.73,80.34-35.08,93.53-79.39,8.68-29.18,3.11-56.71-10.29-83.15C134.15,38.92,117.71,19.34,99,1.57,85-11.65,71.34-25.28,62.72-42.69,46.33-75.79,44.36-109.22,61.63-143.61Z" transform="translate(83 149)"/><path fill="#fff" d="M-83,108c1.25,7.84,1.61,15.94,3.88,23.46,13.79,45.6,43.15,76.21,89,90.24,9.82,3,20,4.76,30,7.12A25.19,25.19,0,0,1,43,230H-83Q-83,169-83,108Z" transform="translate(83 149)"/><path fill="#fff" d="M59,230c6.52-1.21,13.16-2,19.53-3.69,47.26-12.83,73.6-45.07,84.34-91.58,1-4.18,1.43-8.48,2.13-12.73V230Z" transform="translate(83 149)"/><path fill="#ba2f2f" d="M61.63-143.61c-17.28,34.39-15.3,67.82,1.09,100.92C71.34-25.28,85-11.65,99,1.57c18.75,17.77,35.2,37.35,46.94,60.51,13.4,26.44,19,54,10.29,83.15-13.18,44.31-49.71,76.66-93.53,79.39-40.25,2.51-76.52-9.75-105.43-38.91C-68,160.25-80.9,129.7-78.24,93.09A178.29,178.29,0,0,1-63.45,34.31,138.75,138.75,0,0,1-56,19.64c.77,35.79,17.06,62.4,46.8,81C2.54,108,15.33,112.3,30.56,111.3c-2.1-2.21-3.46-3.62-4.8-5C3.57,82.62-11.94,55.57-16.63,23A138.37,138.37,0,0,1-8.77-46.26,229,229,0,0,1,43-127.38C48.76-133.23,55.39-138.22,61.63-143.61Z" transform="translate(83 149)"/></svg>
4
+
5
+ export default icons;
src/Block/utils.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export function escape_html(value) {
2
+ const map = {
3
+ '&': '&amp;',
4
+ '<': '&lt;',
5
+ '>': '&gt;',
6
+ '"': '&quot;',
7
+ "'": '&#x27;',
8
+ "/": '&#x2F;',
9
+ '`': '&grave;',
10
+ };
11
+ const reg = /[&<>"'/]/ig;
12
+ return value.replace(reg, (match)=>(map[match]));
13
+ }
14
+
15
+ export function unescape_html(value) {
16
+ var div = document.createElement('div');
17
+ div.innerHTML = value;
18
+ var child = div.childNodes[0];
19
+ return child ? child.nodeValue : '';
20
+ }
src/Container/WordPressPopularPostsConfiguration.php CHANGED
@@ -40,6 +40,10 @@ class WordPressPopularPostsConfiguration implements ContainerConfigurationInterf
40
  return new \WordPressPopularPosts\Widget\Widget($container['widget_options'], $container['admin_options'], $container['output'], $container['image'], $container['translate'], $container['themer']);
41
  });
42
 
 
 
 
 
43
  $container['posts_endpoint'] = $container->service(function(Container $container) {
44
  return new \WordPressPopularPosts\Rest\PostsEndpoint($container['admin_options'], $container['translate']);
45
  });
@@ -48,12 +52,24 @@ class WordPressPopularPostsConfiguration implements ContainerConfigurationInterf
48
  return new \WordPressPopularPosts\Rest\ViewLoggerEndpoint($container['admin_options'], $container['translate']);
49
  });
50
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  $container['widget_endpoint'] = $container->service(function(Container $container) {
52
  return new \WordPressPopularPosts\Rest\WidgetEndpoint($container['admin_options'], $container['translate'], $container['output']);
53
  });
54
 
55
  $container['rest'] = $container->service(function(Container $container) {
56
- return new \WordPressPopularPosts\Rest\Controller($container['posts_endpoint'], $container['view_logger_endpoint'], $container['widget_endpoint']);
57
  });
58
 
59
  $container['admin'] = $container->service(function(Container $container) {
@@ -65,7 +81,7 @@ class WordPressPopularPostsConfiguration implements ContainerConfigurationInterf
65
  });
66
 
67
  $container['wpp'] = $container->service(function(Container $container) {
68
- return new \WordPressPopularPosts\WordPressPopularPosts($container['i18n'], $container['rest'], $container['admin'], $container['front'], $container['widget']);
69
  });
70
  }
71
  }
40
  return new \WordPressPopularPosts\Widget\Widget($container['widget_options'], $container['admin_options'], $container['output'], $container['image'], $container['translate'], $container['themer']);
41
  });
42
 
43
+ $container['block_widget'] = $container->service(function(Container $container) {
44
+ return new \WordPressPopularPosts\Block\Widget\Widget($container['admin_options'], $container['output'], $container['image'], $container['translate'], $container['themer']);
45
+ });
46
+
47
  $container['posts_endpoint'] = $container->service(function(Container $container) {
48
  return new \WordPressPopularPosts\Rest\PostsEndpoint($container['admin_options'], $container['translate']);
49
  });
52
  return new \WordPressPopularPosts\Rest\ViewLoggerEndpoint($container['admin_options'], $container['translate']);
53
  });
54
 
55
+ $container['taxonomies_endpoint'] = $container->service(function(Container $container) {
56
+ return new \WordPressPopularPosts\Rest\TaxonomiesEndpoint($container['admin_options'], $container['translate']);
57
+ });
58
+
59
+ $container['themes_endpoint'] = $container->service(function(Container $container) {
60
+ return new \WordPressPopularPosts\Rest\ThemesEndpoint($container['admin_options'], $container['translate'], $container['themer']);
61
+ });
62
+
63
+ $container['thumbnails_endpoint'] = $container->service(function(Container $container) {
64
+ return new \WordPressPopularPosts\Rest\ThumbnailsEndpoint($container['admin_options'], $container['translate']);
65
+ });
66
+
67
  $container['widget_endpoint'] = $container->service(function(Container $container) {
68
  return new \WordPressPopularPosts\Rest\WidgetEndpoint($container['admin_options'], $container['translate'], $container['output']);
69
  });
70
 
71
  $container['rest'] = $container->service(function(Container $container) {
72
+ return new \WordPressPopularPosts\Rest\Controller($container['posts_endpoint'], $container['view_logger_endpoint'], $container['widget_endpoint'], $container['themes_endpoint'], $container['thumbnails_endpoint'], $container['taxonomies_endpoint']);
73
  });
74
 
75
  $container['admin'] = $container->service(function(Container $container) {
81
  });
82
 
83
  $container['wpp'] = $container->service(function(Container $container) {
84
+ return new \WordPressPopularPosts\WordPressPopularPosts($container['i18n'], $container['rest'], $container['admin'], $container['front'], $container['widget'], $container['block_widget']);
85
  });
86
  }
87
  }
src/Front/Front.php CHANGED
@@ -373,6 +373,7 @@ class Front {
373
  'header_start' => '<h2>',
374
  'header_end' => '</h2>',
375
  'post_html' => '',
 
376
  'php' => false
377
  ], $atts, 'wpp'));
378
 
@@ -434,6 +435,9 @@ class Front {
434
  'title-start' => empty($header_start) ? '' : $header_start,
435
  'title-end' => empty($header_end) ? '' : $header_end,
436
  'post-html' => empty($post_html) ? '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>' : $post_html
 
 
 
437
  ]
438
  ];
439
 
@@ -459,16 +463,6 @@ class Front {
459
  }
460
 
461
  $shortcode_content = '';
462
-
463
- // is there a title defined by user?
464
- if (
465
- ! empty($header)
466
- && ! empty($header_start)
467
- && ! empty($header_end)
468
- ) {
469
- $shortcode_content .= htmlspecialchars_decode($header_start, ENT_QUOTES) . $header . htmlspecialchars_decode($header_end, ENT_QUOTES);
470
- }
471
-
472
  $cached = false;
473
 
474
  // Return cached results
373
  'header_start' => '<h2>',
374
  'header_end' => '</h2>',
375
  'post_html' => '',
376
+ 'theme' => '',
377
  'php' => false
378
  ], $atts, 'wpp'));
379
 
435
  'title-start' => empty($header_start) ? '' : $header_start,
436
  'title-end' => empty($header_end) ? '' : $header_end,
437
  'post-html' => empty($post_html) ? '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>' : $post_html
438
+ ],
439
+ 'theme' => [
440
+ 'name' => trim($theme)
441
  ]
442
  ];
443
 
463
  }
464
 
465
  $shortcode_content = '';
 
 
 
 
 
 
 
 
 
 
466
  $cached = false;
467
 
468
  // Return cached results
src/Helper.php CHANGED
@@ -334,4 +334,143 @@ class Helper {
334
  // Invalid/malformed URL
335
  return false;
336
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
  }
334
  // Invalid/malformed URL
335
  return false;
336
  }
337
+
338
+ /**
339
+ * Checks whether an URL points to an actual image.
340
+ *
341
+ * This function used to live in src/Image, moved it here
342
+ * on version 5.4.0 to use it where needed.
343
+ *
344
+ * @since 5.0.0
345
+ * @access private
346
+ * @param string
347
+ * @return array|bool
348
+ */
349
+ static function is_image_url($url)
350
+ {
351
+ $path = parse_url($url, PHP_URL_PATH);
352
+ $encoded_path = array_map('urlencode', explode('/', $path));
353
+ $parse_url = str_replace($path, implode('/', $encoded_path), $url);
354
+
355
+ if ( ! filter_var($parse_url, FILTER_VALIDATE_URL) )
356
+ return false;
357
+
358
+ // Check extension
359
+ $file_name = basename($path);
360
+ $file_name = sanitize_file_name($file_name);
361
+ $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
362
+ $allowed_ext = ['jpg', 'jpeg', 'png', 'gif'];
363
+
364
+ if ( ! in_array($ext, $allowed_ext) )
365
+ return false;
366
+
367
+ // sanitize URL, just in case
368
+ $image_url = esc_url($url);
369
+ // remove querystring
370
+ preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $image_url, $matches);
371
+
372
+ return ( is_array($matches) && ! empty($matches) ) ? $matches : false;
373
+ }
374
+
375
+ /**
376
+ * Removes unsafe HTML tags / attributes.
377
+ *
378
+ * @since 5.4.0
379
+ * @param string
380
+ * @return string
381
+ */
382
+ static function remove_unsafe_html($string)
383
+ {
384
+ $html = trim($string);
385
+
386
+ if ( $html ) {
387
+ $unsafe_tags = [
388
+ 'html',
389
+ 'head',
390
+ 'meta',
391
+ 'link',
392
+ 'title',
393
+ 'body',
394
+ 'canvas',
395
+ 'pre',
396
+ 'iframe',
397
+ 'frame',
398
+ 'frameset',
399
+ 'object',
400
+ 'embed',
401
+ 'script',
402
+ 'applet',
403
+ 'form',
404
+ 'input',
405
+ 'textarea',
406
+ 'button'
407
+ ];
408
+
409
+ $doc = new \DOMDocument();
410
+
411
+ /**
412
+ * @TODO
413
+ *
414
+ * We should be able to just use:
415
+ * $doc->loadHTML($html, LIBXML_NOWARNING | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
416
+ * and remove the lines below once the minimum required PHP version is 7.1.4 or higher
417
+ *
418
+ * @see https://www.php.net/ChangeLog-7.php#7.1.4, https://stackoverflow.com/q/41844778/9131961
419
+ */
420
+
421
+ # clear errors list if any
422
+ libxml_clear_errors();
423
+ # use internal errors, don't spill out warnings
424
+ $previous = libxml_use_internal_errors(true);
425
+
426
+ $doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
427
+
428
+ $elements = $doc->getElementsByTagname('*');
429
+
430
+ for ( $i = $elements->length; --$i >= 0; ) {
431
+ $element = $elements->item($i);
432
+
433
+ // Remove unsafe tags
434
+ if ( in_array($element->tagName, $unsafe_tags) ) {
435
+ $element->parentNode->removeChild($element);
436
+ }
437
+ else {
438
+ // Remove unsafe attributes (onclick, onerror, etc.)
439
+ foreach (iterator_to_array($element->attributes) as $name => $attribute) {
440
+ if ( 0 === substr_compare($name, 'on', 0, 2, true) ) {
441
+ $element->removeAttribute($name);
442
+ }
443
+ }
444
+
445
+ // Remove <img> tag if src is not an image URL
446
+ if ( 'img' == $element->tagName ) {
447
+ $src = trim($element->getAttribute('src'));
448
+
449
+ if ( ! Helper::is_image_url($src) ) {
450
+ $element->parentNode->removeChild($element);
451
+ }
452
+ }
453
+ }
454
+ }
455
+
456
+ $html = $doc->saveHTML();
457
+
458
+ /**
459
+ * @TODO
460
+ *
461
+ * We should be able to just use:
462
+ * $doc->loadHTML($html, LIBXML_NOWARNING | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
463
+ * and remove the lines below once the minimum required PHP version is 7.1.4 or higher
464
+ *
465
+ * @see https://www.php.net/ChangeLog-7.php#7.1.4, https://stackoverflow.com/q/41844778/9131961
466
+ */
467
+
468
+ # clear errors list if any
469
+ libxml_clear_errors();
470
+ # restore previous behavior
471
+ libxml_use_internal_errors($previous);
472
+ }
473
+
474
+ return $html;
475
+ }
476
  }
src/Image.php CHANGED
@@ -64,7 +64,7 @@ class Image {
64
  // Set default thumbnail
65
  $this->default_thumbnail = plugins_url() . "/wordpress-popular-posts/assets/images/no_thumb.jpg";
66
 
67
- if ( $this->is_image_url($this->admin_options['tools']['thumbnail']['default']) )
68
  $this->default_thumbnail = $this->admin_options['tools']['thumbnail']['default'];
69
 
70
  // Set uploads folder
@@ -176,7 +176,7 @@ class Image {
176
  true
177
  );
178
 
179
- if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
180
  // Is this an attachment ID instead of an image URL?
181
  if ( Helper::is_number($thumb_url) ) {
182
  $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
@@ -254,7 +254,7 @@ class Image {
254
  true
255
  );
256
 
257
- if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
258
  // Is this an attachment ID instead of an image URL?
259
  // If so, try to fetch the image
260
  if ( Helper::is_number($thumb_url) ) {
@@ -265,7 +265,7 @@ class Image {
265
  }
266
  }
267
 
268
- if ( $thumb_url && $this->is_image_url($thumb_url) ) {
269
  $file_path = $this->url_to_path($thumb_url, $post_id);
270
  }
271
  } else {
@@ -411,7 +411,7 @@ class Image {
411
  */
412
  private function url_to_path($url, $post_ID = null)
413
  {
414
- if ( $this->is_image_url($url) ) {
415
  $attachment_id = $this->get_attachment_id($url);
416
 
417
  // Image is hosted locally
@@ -624,7 +624,7 @@ class Image {
624
  */
625
  private function fetch_external_image($id, $url)
626
  {
627
- if ( ! $this->is_image_url($url) )
628
  return false;
629
 
630
  $full_image_path = trailingslashit($this->get_plugin_uploads_dir()['basedir']) . "{$id}_" . sanitize_file_name(rawurldecode(wp_basename($url)));
@@ -911,44 +911,10 @@ class Image {
911
  if ( has_filter('wpp_default_thumbnail_url') ) {
912
  $default_thumbnail_url = apply_filters('wpp_default_thumbnail_url', $this->default_thumbnail, $post_ID);
913
 
914
- if ( $default_thumbnail_url != $this->default_thumbnail && $this->is_image_url($default_thumbnail_url) )
915
  return $default_thumbnail_url;
916
  }
917
 
918
  return $this->default_thumbnail;
919
  }
920
-
921
- /**
922
- * Checks whether an URL points to an actual image.
923
- *
924
- * @since 5.0.0
925
- * @access private
926
- * @param string
927
- * @return array|bool
928
- */
929
- private function is_image_url($url)
930
- {
931
- $path = parse_url($url, PHP_URL_PATH);
932
- $encoded_path = array_map('urlencode', explode('/', $path));
933
- $parse_url = str_replace($path, implode('/', $encoded_path), $url);
934
-
935
- if ( ! filter_var($parse_url, FILTER_VALIDATE_URL) )
936
- return false;
937
-
938
- // Check extension
939
- $file_name = basename($path);
940
- $file_name = sanitize_file_name($file_name);
941
- $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
942
- $allowed_ext = ['jpg', 'jpeg', 'png', 'gif'];
943
-
944
- if ( ! in_array($ext, $allowed_ext) )
945
- return false;
946
-
947
- // sanitize URL, just in case
948
- $image_url = esc_url($url);
949
- // remove querystring
950
- preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $image_url, $matches);
951
-
952
- return ( is_array($matches) && ! empty($matches) ) ? $matches : false;
953
- }
954
  }
64
  // Set default thumbnail
65
  $this->default_thumbnail = plugins_url() . "/wordpress-popular-posts/assets/images/no_thumb.jpg";
66
 
67
+ if ( Helper::is_image_url($this->admin_options['tools']['thumbnail']['default']) )
68
  $this->default_thumbnail = $this->admin_options['tools']['thumbnail']['default'];
69
 
70
  // Set uploads folder
176
  true
177
  );
178
 
179
+ if ( ! $thumb_url || ! Helper::is_image_url($thumb_url) ) {
180
  // Is this an attachment ID instead of an image URL?
181
  if ( Helper::is_number($thumb_url) ) {
182
  $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
254
  true
255
  );
256
 
257
+ if ( ! $thumb_url || ! Helper::is_image_url($thumb_url) ) {
258
  // Is this an attachment ID instead of an image URL?
259
  // If so, try to fetch the image
260
  if ( Helper::is_number($thumb_url) ) {
265
  }
266
  }
267
 
268
+ if ( $thumb_url && Helper::is_image_url($thumb_url) ) {
269
  $file_path = $this->url_to_path($thumb_url, $post_id);
270
  }
271
  } else {
411
  */
412
  private function url_to_path($url, $post_ID = null)
413
  {
414
+ if ( Helper::is_image_url($url) ) {
415
  $attachment_id = $this->get_attachment_id($url);
416
 
417
  // Image is hosted locally
624
  */
625
  private function fetch_external_image($id, $url)
626
  {
627
+ if ( ! Helper::is_image_url($url) )
628
  return false;
629
 
630
  $full_image_path = trailingslashit($this->get_plugin_uploads_dir()['basedir']) . "{$id}_" . sanitize_file_name(rawurldecode(wp_basename($url)));
911
  if ( has_filter('wpp_default_thumbnail_url') ) {
912
  $default_thumbnail_url = apply_filters('wpp_default_thumbnail_url', $this->default_thumbnail, $post_ID);
913
 
914
+ if ( $default_thumbnail_url != $this->default_thumbnail && Helper::is_image_url($default_thumbnail_url) )
915
  return $default_thumbnail_url;
916
  }
917
 
918
  return $this->default_thumbnail;
919
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
920
  }
src/Output.php CHANGED
@@ -120,7 +120,7 @@ class Output {
120
  public function set_public_options(array $public_options = [])
121
  {
122
  $this->public_options = Helper::merge_array_r(
123
- $this->public_options,
124
  $public_options
125
  );
126
  }
@@ -132,7 +132,7 @@ class Output {
132
  */
133
  public function output()
134
  {
135
- echo $this->output;
136
  }
137
 
138
  /**
@@ -143,7 +143,17 @@ class Output {
143
  */
144
  public function get_output()
145
  {
146
- return $this->output;
 
 
 
 
 
 
 
 
 
 
147
  }
148
 
149
  /**
@@ -156,7 +166,7 @@ class Output {
156
  // Got some posts, format 'em!
157
  if ( ! empty($this->data) ) {
158
 
159
- $this->output = "\n" . ( WP_DEBUG ? '<!-- WordPress Popular Posts v' . WPP_VERSION . ( $this->admin_options['tools']['cache']['active'] ? ' - cached' : '' ) . ' -->' : '' ) . "\n";
160
 
161
  // Allow WP themers / coders access to raw data
162
  // so they can build their own output
@@ -165,6 +175,19 @@ class Output {
165
  return;
166
  }
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  if (
169
  isset($this->public_options['theme']['name'])
170
  && $this->public_options['theme']['name']
@@ -776,7 +799,7 @@ class Output {
776
  }
777
 
778
  // taxonomy
779
- if ( $this->public_options['stats_tag']['category'] && $post_tax != '' ) {
780
  $stats['taxonomy'] = '<span class="wpp-category">' . sprintf(__('under %s', 'wordpress-popular-posts'), $post_tax) . '</span>';
781
  }
782
 
120
  public function set_public_options(array $public_options = [])
121
  {
122
  $this->public_options = Helper::merge_array_r(
123
+ Settings::get('widget_options'),
124
  $public_options
125
  );
126
  }
132
  */
133
  public function output()
134
  {
135
+ echo $this->get_output();
136
  }
137
 
138
  /**
143
  */
144
  public function get_output()
145
  {
146
+ $this->output = "\n" . ( WP_DEBUG ? '<!-- WordPress Popular Posts v' . WPP_VERSION . ( $this->admin_options['tools']['cache']['active'] ? ' - cached' : '' ) . ' -->' : '' ) . "\n" . $this->output;
147
+
148
+ return \WordPressPopularPosts\htmLawed::hl(
149
+ Helper::remove_unsafe_html($this->output),
150
+ [
151
+ 'cdata' => 1,
152
+ 'comment' => 1,
153
+ 'deny_attribute' => 'on*',
154
+ 'schemes' => 'href: mailto, tel, http, https; src: http, https; srcset: http, https'
155
+ ]
156
+ );
157
  }
158
 
159
  /**
166
  // Got some posts, format 'em!
167
  if ( ! empty($this->data) ) {
168
 
169
+ $this->output = '';
170
 
171
  // Allow WP themers / coders access to raw data
172
  // so they can build their own output
175
  return;
176
  }
177
 
178
+ // Has user set a title?
179
+ if (
180
+ '' != $this->public_options['title']
181
+ && '' != $this->public_options['markup']['title-start']
182
+ && '' != $this->public_options['markup']['title-end']
183
+ ) {
184
+ $id_base = isset($this->public_options['id_base']) ? $this->public_options['id_base'] : null;
185
+ $this->public_options['title'] = apply_filters('widget_title', $this->public_options['title'], $this->public_options, $id_base);
186
+ $this->public_options['title'] = htmlspecialchars_decode($this->public_options['markup']['title-start'], ENT_QUOTES) . $this->public_options['title'] . htmlspecialchars_decode($this->public_options['markup']['title-end'], ENT_QUOTES);
187
+
188
+ $this->output .= $this->public_options['title'] . "\n";
189
+ }
190
+
191
  if (
192
  isset($this->public_options['theme']['name'])
193
  && $this->public_options['theme']['name']
799
  }
800
 
801
  // taxonomy
802
+ if ( ($this->public_options['stats_tag']['category'] || $this->public_options['stats_tag']['taxonomy']['active']) && $post_tax != '' ) {
803
  $stats['taxonomy'] = '<span class="wpp-category">' . sprintf(__('under %s', 'wordpress-popular-posts'), $post_tax) . '</span>';
804
  }
805
 
src/Rest/Controller.php CHANGED
@@ -27,18 +27,48 @@ class Controller {
27
  */
28
  private $widget_endpoint;
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  /**
31
  * Initialize class.
32
  *
33
  * @param \WordPressPopularPosts\Rest\PostsEndpoint
34
  * @param \WordPressPopularPosts\Rest\ViewLoggerEndpoint
35
  * @param \WordPressPopularPosts\Rest\WidgetEndpoint
 
 
 
36
  */
37
- public function __construct(\WordPressPopularPosts\Rest\PostsEndpoint $posts_endpoint, \WordPressPopularPosts\Rest\ViewLoggerEndpoint $view_logger_endpoint, \WordPressPopularPosts\Rest\WidgetEndpoint $widget_endpoint)
38
  {
39
  $this->posts_endpoint = $posts_endpoint;
40
  $this->view_logger_endpoint = $view_logger_endpoint;
41
  $this->widget_endpoint = $widget_endpoint;
 
 
 
42
  }
43
 
44
  /**
@@ -59,5 +89,8 @@ class Controller {
59
  $this->posts_endpoint->register();
60
  $this->view_logger_endpoint->register();
61
  $this->widget_endpoint->register();
 
 
 
62
  }
63
  }
27
  */
28
  private $widget_endpoint;
29
 
30
+ /**
31
+ * Themes Endpoint.
32
+ *
33
+ * @var \WordPressPopularPosts\Rest\ThemesEndpoint
34
+ * @access private
35
+ */
36
+ private $themes_endpoint;
37
+
38
+ /**
39
+ * Themes Endpoint.
40
+ *
41
+ * @var \WordPressPopularPosts\Rest\ThumbnailsEndpoint
42
+ * @access private
43
+ */
44
+ private $thumbnails_endpoint;
45
+
46
+ /**
47
+ * Themes Endpoint.
48
+ *
49
+ * @var \WordPressPopularPosts\Rest\TaxonomiesEndpoint
50
+ * @access private
51
+ */
52
+ private $taxonomies_endpoint;
53
+
54
  /**
55
  * Initialize class.
56
  *
57
  * @param \WordPressPopularPosts\Rest\PostsEndpoint
58
  * @param \WordPressPopularPosts\Rest\ViewLoggerEndpoint
59
  * @param \WordPressPopularPosts\Rest\WidgetEndpoint
60
+ * @param \WordPressPopularPosts\Rest\ThemesEndpoint
61
+ * @param \WordPressPopularPosts\Rest\ThumbnailsEndpoint
62
+ * @param \WordPressPopularPosts\Rest\TaxonomiesEndpoint
63
  */
64
+ public function __construct(\WordPressPopularPosts\Rest\PostsEndpoint $posts_endpoint, \WordPressPopularPosts\Rest\ViewLoggerEndpoint $view_logger_endpoint, \WordPressPopularPosts\Rest\WidgetEndpoint $widget_endpoint, \WordPressPopularPosts\Rest\ThemesEndpoint $themes_endpoint, \WordPressPopularPosts\Rest\ThumbnailsEndpoint $thumbnails_endpoint, \WordPressPopularPosts\Rest\TaxonomiesEndpoint $taxonomies_endpoint)
65
  {
66
  $this->posts_endpoint = $posts_endpoint;
67
  $this->view_logger_endpoint = $view_logger_endpoint;
68
  $this->widget_endpoint = $widget_endpoint;
69
+ $this->themes_endpoint = $themes_endpoint;
70
+ $this->thumbnails_endpoint = $thumbnails_endpoint;
71
+ $this->taxonomies_endpoint = $taxonomies_endpoint;
72
  }
73
 
74
  /**
89
  $this->posts_endpoint->register();
90
  $this->view_logger_endpoint->register();
91
  $this->widget_endpoint->register();
92
+ $this->themes_endpoint->register();
93
+ $this->thumbnails_endpoint->register();
94
+ $this->taxonomies_endpoint->register();
95
  }
96
  }
src/Rest/TaxonomiesEndpoint.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Rest;
3
+
4
+ class TaxonomiesEndpoint extends Endpoint {
5
+
6
+ /**
7
+ * Registers the endpoint(s).
8
+ *
9
+ * @since 5.4.0
10
+ */
11
+ public function register()
12
+ {
13
+ $version = '1';
14
+ $namespace = 'wordpress-popular-posts/v' . $version;
15
+
16
+ register_rest_route($namespace, '/taxonomies', [
17
+ [
18
+ 'methods' => \WP_REST_Server::READABLE,
19
+ 'callback' => [$this, 'get_items'],
20
+ 'permission_callback' => function() {
21
+ return current_user_can('edit_posts');
22
+ }
23
+ ]
24
+ ]);
25
+ }
26
+
27
+ /**
28
+ * Gets popular posts.
29
+ *
30
+ * @since 5.4.0
31
+ * @param \WP_REST_Request $request Full data about the request.
32
+ * @return \WP_REST_Response
33
+ */
34
+ public function get_items($request)
35
+ {
36
+ $taxonomies = get_taxonomies(['public' => true], 'objects');
37
+ return new \WP_REST_Response($taxonomies, 200);
38
+ }
39
+ }
src/Rest/ThemesEndpoint.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Rest;
3
+
4
+ class ThemesEndpoint extends Endpoint {
5
+
6
+ /**
7
+ * Themer object.
8
+ *
9
+ * @var \WordPressPopularPosts\Themer $themer
10
+ * @access private
11
+ */
12
+ private $themer;
13
+
14
+ /**
15
+ * Initializes class.
16
+ *
17
+ * @param array
18
+ * @param \WordPressPopularPosts\Translate
19
+ * @param \WordPressPopularPosts\Themer
20
+ */
21
+ public function __construct(array $config, \WordPressPopularPosts\Translate $translate, \WordPressPopularPosts\Themer $themer)
22
+ {
23
+ $this->config = $config;
24
+ $this->translate = $translate;
25
+ $this->themer = $themer;
26
+ }
27
+
28
+ /**
29
+ * Registers the endpoint(s).
30
+ *
31
+ * @since 5.4.0
32
+ */
33
+ public function register()
34
+ {
35
+ $version = '1';
36
+ $namespace = 'wordpress-popular-posts/v' . $version;
37
+
38
+ register_rest_route($namespace, '/themes', [
39
+ [
40
+ 'methods' => \WP_REST_Server::READABLE,
41
+ 'callback' => [$this, 'get_items'],
42
+ 'permission_callback' => function() {
43
+ return current_user_can('edit_posts');
44
+ }
45
+ ]
46
+ ]);
47
+ }
48
+
49
+ /**
50
+ * Gets popular posts.
51
+ *
52
+ * @since 5.4.0
53
+ * @param \WP_REST_Request $request Full data about the request.
54
+ * @return \WP_REST_Response
55
+ */
56
+ public function get_items($request)
57
+ {
58
+ $registered_themes = $this->themer->get_themes();
59
+ ksort($registered_themes);
60
+
61
+ return new \WP_REST_Response($registered_themes, 200);
62
+ }
63
+ }
src/Rest/ThumbnailsEndpoint.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WordPressPopularPosts\Rest;
3
+
4
+ class ThumbnailsEndpoint extends Endpoint {
5
+
6
+ /**
7
+ * Registers the endpoint(s).
8
+ *
9
+ * @since 5.4.0
10
+ */
11
+ public function register()
12
+ {
13
+ $version = '1';
14
+ $namespace = 'wordpress-popular-posts/v' . $version;
15
+
16
+ register_rest_route($namespace, '/thumbnails', [
17
+ [
18
+ 'methods' => \WP_REST_Server::READABLE,
19
+ 'callback' => [$this, 'get_items'],
20
+ 'permission_callback' => function() {
21
+ return current_user_can('edit_posts');
22
+ }
23
+ ]
24
+ ]);
25
+ }
26
+
27
+ /**
28
+ * Gets popular posts.
29
+ *
30
+ * @since 5.4.0
31
+ * @param \WP_REST_Request $request Full data about the request.
32
+ * @return \WP_REST_Response
33
+ */
34
+ public function get_items($request)
35
+ {
36
+ global $_wp_additional_image_sizes;
37
+
38
+ $available_sizes = [];
39
+ $get_intermediate_image_sizes = get_intermediate_image_sizes();
40
+
41
+ // Create the full array with sizes and crop info
42
+ foreach( $get_intermediate_image_sizes as $_size ) {
43
+ if ( in_array($_size, ['thumbnail', 'medium', 'large']) ) {
44
+ $available_sizes[$_size]['width'] = get_option($_size . '_size_w');
45
+ $available_sizes[$_size]['height'] = get_option($_size . '_size_h');
46
+ $available_sizes[$_size]['crop'] = (bool) get_option($_size . '_crop');
47
+ } elseif ( isset($_wp_additional_image_sizes[$_size]) ) {
48
+ $available_sizes[$_size] = [
49
+ 'width' => $_wp_additional_image_sizes[$_size]['width'],
50
+ 'height' => $_wp_additional_image_sizes[$_size]['height'],
51
+ 'crop' => $_wp_additional_image_sizes[$_size]['crop']
52
+ ];
53
+ }
54
+ }
55
+
56
+ return new \WP_REST_Response($available_sizes, 200);
57
+ }
58
+ }
src/Settings.php CHANGED
@@ -98,6 +98,7 @@ class Settings {
98
  'freshness' => false
99
  ],
100
  'tools' => [
 
101
  'ajax' => true,
102
  'css' => true,
103
  'link' => [
98
  'freshness' => false
99
  ],
100
  'tools' => [
101
+ 'experimental' => false,
102
  'ajax' => true,
103
  'css' => true,
104
  'link' => [
src/Widget/Widget.php CHANGED
@@ -95,6 +95,8 @@ class Widget extends \WP_Widget {
95
  {
96
  // Register the widget
97
  add_action('widgets_init', [$this, 'register']);
 
 
98
  }
99
 
100
  /**
@@ -143,21 +145,15 @@ class Widget extends \WP_Widget {
143
 
144
  // Has user set a title?
145
  if ( '' != $instance['title'] ) {
146
- $title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base);
147
-
148
- if (
149
- $instance['markup']['custom_html']
150
- && $instance['markup']['title-start'] != ""
151
- && $instance['markup']['title-end'] != ""
152
- ) {
153
- echo htmlspecialchars_decode($instance['markup']['title-start'], ENT_QUOTES) . $title . htmlspecialchars_decode($instance['markup']['title-end'], ENT_QUOTES);
154
- } else {
155
- echo $before_title . $title . $after_title;
156
  }
157
  }
158
 
159
- // Expose Widget ID for customization
160
  $instance['widget_id'] = $widget_id;
 
161
 
162
  // Get posts
163
  if ( $this->admin_options['tools']['ajax'] && ! is_customize_preview() ) {
@@ -390,6 +386,7 @@ class Widget extends \WP_Widget {
390
  public function get_popular($instance = null)
391
  {
392
  if ( is_array($instance) && ! empty($instance) ) {
 
393
  // Return cached results
394
  if ( $this->admin_options['tools']['cache']['active'] ) {
395
 
@@ -447,4 +444,16 @@ class Widget extends \WP_Widget {
447
 
448
  return null;
449
  }
 
 
 
 
 
 
 
 
 
 
 
 
450
  }
95
  {
96
  // Register the widget
97
  add_action('widgets_init', [$this, 'register']);
98
+ // Remove widget from Legacy Widget block
99
+ add_filter('widget_types_to_hide_from_legacy_widget_block', [$this, 'remove_from_legacy_widget_block']);
100
  }
101
 
102
  /**
145
 
146
  // Has user set a title?
147
  if ( '' != $instance['title'] ) {
148
+ if ( ! $instance['markup']['custom_html'] ) {
149
+ $instance['markup']['title-start'] = $before_title;
150
+ $instance['markup']['title-end'] = $after_title;
 
 
 
 
 
 
 
151
  }
152
  }
153
 
154
+ // Expose Widget ID & base for customization
155
  $instance['widget_id'] = $widget_id;
156
+ $instance['id_base'] = $this->id_base;
157
 
158
  // Get posts
159
  if ( $this->admin_options['tools']['ajax'] && ! is_customize_preview() ) {
386
  public function get_popular($instance = null)
387
  {
388
  if ( is_array($instance) && ! empty($instance) ) {
389
+
390
  // Return cached results
391
  if ( $this->admin_options['tools']['cache']['active'] ) {
392
 
444
 
445
  return null;
446
  }
447
+
448
+ /**
449
+ * Removes the standard widget from the Legacy Widget block.
450
+ *
451
+ * @param array
452
+ * @return array
453
+ */
454
+ public function remove_from_legacy_widget_block($widget_types)
455
+ {
456
+ $widget_types[] = 'wpp';
457
+ return $widget_types;
458
+ }
459
  }
src/Widget/form.php CHANGED
@@ -52,7 +52,7 @@ $current_sidebar = $current_sidebar_data ? $current_sidebar_data['id'] : null;
52
  <input type="checkbox" class="checkbox" <?php echo ($instance['freshness']) ? 'checked="checked"' : ''; ?> id="<?php echo $this->get_field_id('freshness'); ?>" name="<?php echo $this->get_field_name('freshness'); ?>" /> <label for="<?php echo $this->get_field_id('freshness'); ?>"><small><?php _e('Display only posts published within the selected Time Range', 'wordpress-popular-posts'); ?></small></label><br /><br />
53
 
54
  <label for="<?php echo $this->get_field_id('post_type'); ?>"><?php _e('Post type(s)', 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/5.-FAQ#what-is-post-type-for" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>" target="_blank">?</a>]</small>
55
- <input type="text" id="<?php echo $this->get_field_id('post_type'); ?>" name="<?php echo $this->get_field_name('post_type'); ?>" value="<?php echo $instance['post_type']; ?>" class="widefat" /><br /><br />
56
 
57
  <label for="<?php echo $this->get_field_id('pid'); ?>"><?php _e('Post ID(s) to exclude', 'wordpress-popular-posts'); ?>:</label>
58
  <input type="text" id="<?php echo $this->get_field_id('pid'); ?>" name="<?php echo $this->get_field_name('pid'); ?>" value="<?php echo $instance['pid']; ?>" class="widefat" /><br /><br />
52
  <input type="checkbox" class="checkbox" <?php echo ($instance['freshness']) ? 'checked="checked"' : ''; ?> id="<?php echo $this->get_field_id('freshness'); ?>" name="<?php echo $this->get_field_name('freshness'); ?>" /> <label for="<?php echo $this->get_field_id('freshness'); ?>"><small><?php _e('Display only posts published within the selected Time Range', 'wordpress-popular-posts'); ?></small></label><br /><br />
53
 
54
  <label for="<?php echo $this->get_field_id('post_type'); ?>"><?php _e('Post type(s)', 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/5.-FAQ#what-is-post-type-for" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>" target="_blank">?</a>]</small>
55
+ <input type="text" id="<?php echo $this->get_field_id('post_type'); ?>" name="<?php echo $this->get_field_name('post_type'); ?>" value="<?php echo esc_attr($instance['post_type']); ?>" class="widefat" /><br /><br />
56
 
57
  <label for="<?php echo $this->get_field_id('pid'); ?>"><?php _e('Post ID(s) to exclude', 'wordpress-popular-posts'); ?>:</label>
58
  <input type="text" id="<?php echo $this->get_field_id('pid'); ?>" name="<?php echo $this->get_field_name('pid'); ?>" value="<?php echo $instance['pid']; ?>" class="widefat" /><br /><br />
src/WordPressPopularPosts.php CHANGED
@@ -48,6 +48,14 @@ class WordPressPopularPosts {
48
  */
49
  private $widget;
50
 
 
 
 
 
 
 
 
 
51
  /**
52
  * Constructor.
53
  *
@@ -58,13 +66,14 @@ class WordPressPopularPosts {
58
  * @param Front\Front $front
59
  * @param Widget\Widget $widget
60
  */
61
- public function __construct(I18N $i18n, Rest\Controller $rest, Admin\Admin $admin, Front\Front $front, Widget\Widget $widget)
62
  {
63
  $this->i18n = $i18n;
64
  $this->rest = $rest;
65
  $this->admin = $admin;
66
  $this->front = $front;
67
  $this->widget = $widget;
 
68
  }
69
 
70
  /**
@@ -79,5 +88,6 @@ class WordPressPopularPosts {
79
  $this->admin->hooks();
80
  $this->front->hooks();
81
  $this->widget->hooks();
 
82
  }
83
  }
48
  */
49
  private $widget;
50
 
51
+ /**
52
+ * Block Widget class.
53
+ *
54
+ * @var Block\Widget $widget
55
+ * @access private
56
+ */
57
+ private $block_widget;
58
+
59
  /**
60
  * Constructor.
61
  *
66
  * @param Front\Front $front
67
  * @param Widget\Widget $widget
68
  */
69
+ public function __construct(I18N $i18n, Rest\Controller $rest, Admin\Admin $admin, Front\Front $front, Widget\Widget $widget, Block\Widget\Widget $block_widget)
70
  {
71
  $this->i18n = $i18n;
72
  $this->rest = $rest;
73
  $this->admin = $admin;
74
  $this->front = $front;
75
  $this->widget = $widget;
76
+ $this->block_widget = $block_widget;
77
  }
78
 
79
  /**
88
  $this->admin->hooks();
89
  $this->front->hooks();
90
  $this->widget->hooks();
91
+ $this->block_widget->hooks();
92
  }
93
  }
src/htmLawed.php ADDED
@@ -0,0 +1,741 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ htmLawed 1.2.5, 24 September 2019
5
+ OOP code for htmLawed class, 24 September 2019
6
+ Copyright Santosh Patnaik
7
+ Dual licensed with LGPL 3 and GPL 2+
8
+ A PHP Labware internal utility - www.bioinformatics.org/phplabware/internal_utilities/htmLawed
9
+
10
+ See htmLawed_README.txt/htm
11
+ */
12
+
13
+ /**
14
+ * Class modified by Hector Cabrera so it can work within a namespace.
15
+ */
16
+
17
+ namespace WordPressPopularPosts;
18
+
19
+ class htmLawed{
20
+ // begin class
21
+ public static function hl($t, $C=1, $S=array()){
22
+ $C = is_array($C) ? $C : array();
23
+ if(!empty($C['valid_xhtml'])){
24
+ $C['elements'] = empty($C['elements']) ? '*-acronym-big-center-dir-font-isindex-s-strike-tt' : $C['elements'];
25
+ $C['make_tag_strict'] = isset($C['make_tag_strict']) ? $C['make_tag_strict'] : 2;
26
+ $C['xml:lang'] = isset($C['xml:lang']) ? $C['xml:lang'] : 2;
27
+ }
28
+ // config eles
29
+ $e = array('a'=>1, 'abbr'=>1, 'acronym'=>1, 'address'=>1, 'applet'=>1, 'area'=>1, 'article'=>1, 'aside'=>1, 'audio'=>1, 'b'=>1, 'bdi'=>1, 'bdo'=>1, 'big'=>1, 'blockquote'=>1, 'br'=>1, 'button'=>1, 'canvas'=>1, 'caption'=>1, 'center'=>1, 'cite'=>1, 'code'=>1, 'col'=>1, 'colgroup'=>1, 'command'=>1, 'data'=>1, 'datalist'=>1, 'dd'=>1, 'del'=>1, 'details'=>1, 'dfn'=>1, 'dir'=>1, 'div'=>1, 'dl'=>1, 'dt'=>1, 'em'=>1, 'embed'=>1, 'fieldset'=>1, 'figcaption'=>1, 'figure'=>1, 'font'=>1, 'footer'=>1, 'form'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'header'=>1, 'hgroup'=>1, 'hr'=>1, 'i'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'ins'=>1, 'isindex'=>1, 'kbd'=>1, 'keygen'=>1, 'label'=>1, 'legend'=>1, 'li'=>1, 'link'=>1, 'main'=>1, 'map'=>1, 'mark'=>1, 'menu'=>1, 'meta'=>1, 'meter'=>1, 'nav'=>1, 'noscript'=>1, 'object'=>1, 'ol'=>1, 'optgroup'=>1, 'option'=>1, 'output'=>1, 'p'=>1, 'param'=>1, 'pre'=>1, 'progress'=>1, 'q'=>1, 'rb'=>1, 'rbc'=>1, 'rp'=>1, 'rt'=>1, 'rtc'=>1, 'ruby'=>1, 's'=>1, 'samp'=>1, 'script'=>1, 'section'=>1, 'select'=>1, 'small'=>1, 'source'=>1, 'span'=>1, 'strike'=>1, 'strong'=>1, 'style'=>1, 'sub'=>1, 'summary'=>1, 'sup'=>1, 'table'=>1, 'tbody'=>1, 'td'=>1, 'textarea'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'time'=>1, 'tr'=>1, 'track'=>1, 'tt'=>1, 'u'=>1, 'ul'=>1, 'var'=>1, 'video'=>1, 'wbr'=>1); // 118 incl. deprecated & some Ruby
30
+
31
+ if(!empty($C['safe'])){
32
+ unset($e['applet'], $e['audio'], $e['canvas'], $e['embed'], $e['iframe'], $e['object'], $e['script'], $e['video']);
33
+ }
34
+ $x = !empty($C['elements']) ? str_replace(array("\n", "\r", "\t", ' '), '', $C['elements']) : '*';
35
+ if($x == '-*'){$e = array();}
36
+ elseif(strpos($x, '*') === false){$e = array_flip(explode(',', $x));}
37
+ else{
38
+ if(isset($x[1])){
39
+ preg_match_all('`(?:^|-|\+)[^\-+]+?(?=-|\+|$)`', $x, $m, PREG_SET_ORDER);
40
+ for($i=count($m); --$i>=0;){$m[$i] = $m[$i][0];}
41
+ foreach($m as $v){
42
+ if($v[0] == '+'){$e[substr($v, 1)] = 1;}
43
+ if($v[0] == '-' && isset($e[($v = substr($v, 1))]) && !in_array('+'. $v, $m)){unset($e[$v]);}
44
+ }
45
+ }
46
+ }
47
+ $C['elements'] =& $e;
48
+ // config attrs
49
+ $x = !empty($C['deny_attribute']) ? strtolower(str_replace(array("\n", "\r", "\t", ' '), '', $C['deny_attribute'])) : '';
50
+ $x = array_flip((isset($x[0]) && $x[0] == '*') ? str_replace('/', 'data-', explode('-', str_replace('data-', '/', $x))) : explode(',', $x. (!empty($C['safe']) ? ',on*' : '')));
51
+ $C['deny_attribute'] = $x;
52
+ // config URLs
53
+ $x = (isset($C['schemes'][2]) && strpos($C['schemes'], ':')) ? strtolower($C['schemes']) : 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, tel, telnet'. (empty($C['safe']) ? ', app, javascript; *: data, javascript, ' : '; *:'). 'file, http, https';
54
+ $C['schemes'] = array();
55
+ foreach(explode(';', trim(str_replace(array(' ', "\t", "\r", "\n"), '', $x), ';')) as $v){
56
+ $x = $x2 = null; list($x, $x2) = explode(':', $v, 2);
57
+ if($x2){$C['schemes'][$x] = array_flip(explode(',', $x2));}
58
+ }
59
+ if(!isset($C['schemes']['*'])){
60
+ $C['schemes']['*'] = array('file'=>1, 'http'=>1, 'https'=>1);
61
+ if(empty($C['safe'])){$C['schemes']['*'] += array('data'=>1, 'javascript'=>1);}
62
+ }
63
+ if(!empty($C['safe']) && empty($C['schemes']['style'])){$C['schemes']['style'] = array('!'=>1);}
64
+ $C['abs_url'] = isset($C['abs_url']) ? $C['abs_url'] : 0;
65
+ if(!isset($C['base_url']) or !preg_match('`^[a-zA-Z\d.+\-]+://[^/]+/(.+?/)?$`', $C['base_url'])){
66
+ $C['base_url'] = $C['abs_url'] = 0;
67
+ }
68
+ // config rest
69
+ $C['and_mark'] = empty($C['and_mark']) ? 0 : 1;
70
+ $C['anti_link_spam'] = (isset($C['anti_link_spam']) && is_array($C['anti_link_spam']) && count($C['anti_link_spam']) == 2 && (empty($C['anti_link_spam'][0]) or self::hl_regex($C['anti_link_spam'][0])) && (empty($C['anti_link_spam'][1]) or self::hl_regex($C['anti_link_spam'][1]))) ? $C['anti_link_spam'] : 0;
71
+ $C['anti_mail_spam'] = isset($C['anti_mail_spam']) ? $C['anti_mail_spam'] : 0;
72
+ $C['balance'] = isset($C['balance']) ? (bool)$C['balance'] : 1;
73
+ $C['cdata'] = isset($C['cdata']) ? $C['cdata'] : (empty($C['safe']) ? 3 : 0);
74
+ $C['clean_ms_char'] = empty($C['clean_ms_char']) ? 0 : $C['clean_ms_char'];
75
+ $C['comment'] = isset($C['comment']) ? $C['comment'] : (empty($C['safe']) ? 3 : 0);
76
+ $C['css_expression'] = empty($C['css_expression']) ? 0 : 1;
77
+ $C['direct_list_nest'] = empty($C['direct_list_nest']) ? 0 : 1;
78
+ $C['hexdec_entity'] = isset($C['hexdec_entity']) ? $C['hexdec_entity'] : 1;
79
+ $C['hook'] = (!empty($C['hook']) && function_exists($C['hook'])) ? $C['hook'] : 0;
80
+ $C['hook_tag'] = (!empty($C['hook_tag']) && function_exists($C['hook_tag'])) ? $C['hook_tag'] : 0;
81
+ $C['keep_bad'] = isset($C['keep_bad']) ? $C['keep_bad'] : 6;
82
+ $C['lc_std_val'] = isset($C['lc_std_val']) ? (bool)$C['lc_std_val'] : 1;
83
+ $C['make_tag_strict'] = isset($C['make_tag_strict']) ? $C['make_tag_strict'] : 1;
84
+ $C['named_entity'] = isset($C['named_entity']) ? (bool)$C['named_entity'] : 1;
85
+ $C['no_deprecated_attr'] = isset($C['no_deprecated_attr']) ? $C['no_deprecated_attr'] : 1;
86
+ $C['parent'] = isset($C['parent'][0]) ? strtolower($C['parent']) : 'body';
87
+ $C['show_setting'] = !empty($C['show_setting']) ? $C['show_setting'] : 0;
88
+ $C['style_pass'] = empty($C['style_pass']) ? 0 : 1;
89
+ $C['tidy'] = empty($C['tidy']) ? 0 : $C['tidy'];
90
+ $C['unique_ids'] = isset($C['unique_ids']) && (!preg_match('`\W`', $C['unique_ids'])) ? $C['unique_ids'] : 1;
91
+ $C['xml:lang'] = isset($C['xml:lang']) ? $C['xml:lang'] : 0;
92
+
93
+ if(isset($GLOBALS['C'])){$reC = $GLOBALS['C'];}
94
+ $GLOBALS['C'] = $C;
95
+ $S = is_array($S) ? $S : self::hl_spec($S);
96
+ if(isset($GLOBALS['S'])){$reS = $GLOBALS['S'];}
97
+ $GLOBALS['S'] = $S;
98
+
99
+ $t = preg_replace('`[\x00-\x08\x0b-\x0c\x0e-\x1f]`', '', $t);
100
+ if($C['clean_ms_char']){
101
+ $x = array("\x7f"=>'', "\x80"=>'&#8364;', "\x81"=>'', "\x83"=>'&#402;', "\x85"=>'&#8230;', "\x86"=>'&#8224;', "\x87"=>'&#8225;', "\x88"=>'&#710;', "\x89"=>'&#8240;', "\x8a"=>'&#352;', "\x8b"=>'&#8249;', "\x8c"=>'&#338;', "\x8d"=>'', "\x8e"=>'&#381;', "\x8f"=>'', "\x90"=>'', "\x95"=>'&#8226;', "\x96"=>'&#8211;', "\x97"=>'&#8212;', "\x98"=>'&#732;', "\x99"=>'&#8482;', "\x9a"=>'&#353;', "\x9b"=>'&#8250;', "\x9c"=>'&#339;', "\x9d"=>'', "\x9e"=>'&#382;', "\x9f"=>'&#376;');
102
+ $x = $x + ($C['clean_ms_char'] == 1 ? array("\x82"=>'&#8218;', "\x84"=>'&#8222;', "\x91"=>'&#8216;', "\x92"=>'&#8217;', "\x93"=>'&#8220;', "\x94"=>'&#8221;') : array("\x82"=>'\'', "\x84"=>'"', "\x91"=>'\'', "\x92"=>'\'', "\x93"=>'"', "\x94"=>'"'));
103
+ $t = strtr($t, $x);
104
+ }
105
+ if($C['cdata'] or $C['comment']){$t = preg_replace_callback('`<!(?:(?:--.*?--)|(?:\[CDATA\[.*?\]\]))>`sm', 'self::hl_cmtcd', $t);}
106
+ $t = preg_replace_callback('`&amp;([a-zA-Z][a-zA-Z0-9]{1,30}|#(?:[0-9]{1,8}|[Xx][0-9A-Fa-f]{1,7}));`', 'self::hl_ent', str_replace('&', '&amp;', $t));
107
+ if($C['unique_ids'] && !isset($GLOBALS['hl_Ids'])){$GLOBALS['hl_Ids'] = array();}
108
+ if($C['hook']){$t = $C['hook']($t, $C, $S);}
109
+ if($C['show_setting'] && preg_match('`^[a-z][a-z0-9_]*$`i', $C['show_setting'])){
110
+ $GLOBALS[$C['show_setting']] = array('config'=>$C, 'spec'=>$S, 'time'=>microtime());
111
+ }
112
+ // main
113
+ $t = preg_replace_callback('`<(?:(?:\s|$)|(?:[^>]*(?:>|$)))|>`m', 'self::hl_tag', $t);
114
+ $t = $C['balance'] ? self::hl_bal($t, $C['keep_bad'], $C['parent']) : $t;
115
+ $t = (($C['cdata'] or $C['comment']) && strpos($t, "\x01") !== false) ? str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05"), array('', '', '&', '<', '>'), $t) : $t;
116
+ $t = $C['tidy'] ? self::hl_tidy($t, $C['tidy'], $C['parent']) : $t;
117
+ unset($C, $e);
118
+ if(isset($reC)){$GLOBALS['C'] = $reC;}
119
+ if(isset($reS)){$GLOBALS['S'] = $reS;}
120
+ return $t;
121
+ }
122
+
123
+ public static function hl_attrval($a, $t, $p){
124
+ // check attr val against $S
125
+ static $ma = array('accesskey', 'class', 'itemtype', 'rel');
126
+ $s = in_array($a, $ma) ? ' ' : ($a == 'srcset' ? ',': '');
127
+ $r = array();
128
+ $t = !empty($s) ? explode($s, $t) : array($t);
129
+ foreach($t as $tk=>$tv){
130
+ $o = 1; $tv = trim($tv); $l = strlen($tv);
131
+ foreach($p as $k=>$v){
132
+ if(!$l){continue;}
133
+ switch($k){
134
+ case 'maxlen': if($l > $v){$o = 0;}
135
+ break; case 'minlen': if($l < $v){$o = 0;}
136
+ break; case 'maxval': if((float)($tv) > $v){$o = 0;}
137
+ break; case 'minval': if((float)($tv) < $v){$o = 0;}
138
+ break; case 'match': if(!preg_match($v, $tv)){$o = 0;}
139
+ break; case 'nomatch': if(preg_match($v, $tv)){$o = 0;}
140
+ break; case 'oneof':
141
+ $m = 0;
142
+ foreach(explode('|', $v) as $n){if($tv == $n){$m = 1; break;}}
143
+ $o = $m;
144
+ break; case 'noneof':
145
+ $m = 1;
146
+ foreach(explode('|', $v) as $n){if($tv == $n){$m = 0; break;}}
147
+ $o = $m;
148
+ break; default:
149
+ break;
150
+ }
151
+ if(!$o){break;}
152
+ }
153
+ if($o){$r[] = $tv;}
154
+ }
155
+ if($s == ','){$s = ', ';}
156
+ $r = implode($s, $r);
157
+ return (isset($r[0]) ? $r : (isset($p['default']) ? $p['default'] : 0));
158
+ }
159
+
160
+ public static function hl_bal($t, $do=1, $in='div'){
161
+ // balance tags
162
+ // by content
163
+ $cB = array('blockquote'=>1, 'form'=>1, 'map'=>1, 'noscript'=>1); // Block
164
+ $cE = array('area'=>1, 'br'=>1, 'col'=>1, 'command'=>1, 'embed'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'keygen'=>1, 'link'=>1, 'meta'=>1, 'param'=>1, 'source'=>1, 'track'=>1, 'wbr'=>1); // Empty
165
+ $cF = array('a'=>1, 'article'=>1, 'aside'=>1, 'audio'=>1, 'button'=>1, 'canvas'=>1, 'del'=>1, 'details'=>1, 'div'=>1, 'dd'=>1, 'fieldset'=>1, 'figure'=>1, 'footer'=>1, 'header'=>1, 'iframe'=>1, 'ins'=>1, 'li'=>1, 'main'=>1, 'menu'=>1, 'nav'=>1, 'noscript'=>1, 'object'=>1, 'section'=>1, 'style'=>1, 'td'=>1, 'th'=>1, 'video'=>1); // Flow; later context-wise dynamic move of ins & del to $cI
166
+ $cI = array('abbr'=>1, 'acronym'=>1, 'address'=>1, 'b'=>1, 'bdi'=>1, 'bdo'=>1, 'big'=>1, 'caption'=>1, 'cite'=>1, 'code'=>1, 'data'=>1, 'datalist'=>1, 'dfn'=>1, 'dt'=>1, 'em'=>1, 'figcaption'=>1, 'font'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hgroup'=>1, 'i'=>1, 'kbd'=>1, 'label'=>1, 'legend'=>1, 'mark'=>1, 'meter'=>1, 'output'=>1, 'p'=>1, 'pre'=>1, 'progress'=>1, 'q'=>1, 'rb'=>1, 'rt'=>1, 's'=>1, 'samp'=>1, 'small'=>1, 'span'=>1, 'strike'=>1, 'strong'=>1, 'sub'=>1, 'summary'=>1, 'sup'=>1, 'time'=>1, 'tt'=>1, 'u'=>1, 'var'=>1); // Inline
167
+ $cN = array('a'=>array('a'=>1, 'address'=>1, 'button'=>1, 'details'=>1, 'embed'=>1, 'keygen'=>1, 'label'=>1, 'select'=>1, 'textarea'=>1), 'address'=>array('address'=>1, 'article'=>1, 'aside'=>1, 'header'=>1, 'keygen'=>1, 'footer'=>1, 'nav'=>1, 'section'=>1), 'button'=>array('a'=>1, 'address'=>1, 'button'=>1, 'details'=>1, 'embed'=>1, 'fieldset'=>1, 'form'=>1, 'iframe'=>1, 'input'=>1, 'keygen'=>1, 'label'=>1, 'select'=>1, 'textarea'=>1), 'fieldset'=>array('fieldset'=>1), 'footer'=>array('header'=>1, 'footer'=>1), 'form'=>array('form'=>1), 'header'=>array('header'=>1, 'footer'=>1), 'label'=>array('label'=>1), 'main'=>array('main'=>1), 'meter'=>array('meter'=>1), 'noscript'=>array('script'=>1), 'pre'=>array('big'=>1, 'font'=>1, 'img'=>1, 'object'=>1, 'script'=>1, 'small'=>1, 'sub'=>1, 'sup'=>1), 'progress'=>array('progress'=>1), 'rb'=>array('ruby'=>1), 'rt'=>array('ruby'=>1), 'time'=>array('time'=>1), ); // Illegal
168
+ $cN2 = array_keys($cN);
169
+ $cS = array('colgroup'=>array('col'=>1), 'datalist'=>array('option'=>1), 'dir'=>array('li'=>1), 'dl'=>array('dd'=>1, 'dt'=>1), 'hgroup'=>array('h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1), 'menu'=>array('li'=>1), 'ol'=>array('li'=>1), 'optgroup'=>array('option'=>1), 'option'=>array('#pcdata'=>1), 'rbc'=>array('rb'=>1), 'rp'=>array('#pcdata'=>1), 'rtc'=>array('rt'=>1), 'ruby'=>array('rb'=>1, 'rbc'=>1, 'rp'=>1, 'rt'=>1, 'rtc'=>1), 'select'=>array('optgroup'=>1, 'option'=>1), 'script'=>array('#pcdata'=>1), 'table'=>array('caption'=>1, 'col'=>1, 'colgroup'=>1, 'tfoot'=>1, 'tbody'=>1, 'tr'=>1, 'thead'=>1), 'tbody'=>array('tr'=>1), 'tfoot'=>array('tr'=>1), 'textarea'=>array('#pcdata'=>1), 'thead'=>array('tr'=>1), 'tr'=>array('td'=>1, 'th'=>1), 'ul'=>array('li'=>1)); // Specific - immediate parent-child
170
+ if($GLOBALS['C']['direct_list_nest']){$cS['ol'] = $cS['ul'] = $cS['menu'] += array('menu'=>1, 'ol'=>1, 'ul'=>1);}
171
+ $cO = array('address'=>array('p'=>1), 'applet'=>array('param'=>1), 'audio'=>array('source'=>1, 'track'=>1), 'blockquote'=>array('script'=>1), 'details'=>array('summary'=>1), 'fieldset'=>array('legend'=>1, '#pcdata'=>1), 'figure'=>array('figcaption'=>1),'form'=>array('script'=>1), 'map'=>array('area'=>1), 'object'=>array('param'=>1, 'embed'=>1), 'video'=>array('source'=>1, 'track'=>1)); // Other
172
+ $cT = array('colgroup'=>1, 'dd'=>1, 'dt'=>1, 'li'=>1, 'option'=>1, 'p'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1); // Omitable closing
173
+ // block/inline type; a/ins/del both type; #pcdata: text
174
+ $eB = array('a'=>1, 'address'=>1, 'article'=>1, 'aside'=>1, 'blockquote'=>1, 'center'=>1, 'del'=>1, 'details'=>1, 'dir'=>1, 'dl'=>1, 'div'=>1, 'fieldset'=>1, 'figure'=>1, 'footer'=>1, 'form'=>1, 'ins'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'header'=>1, 'hr'=>1, 'isindex'=>1, 'main'=>1, 'menu'=>1, 'nav'=>1, 'noscript'=>1, 'ol'=>1, 'p'=>1, 'pre'=>1, 'section'=>1, 'style'=>1, 'table'=>1, 'ul'=>1);
175
+ $eI = array('#pcdata'=>1, 'a'=>1, 'abbr'=>1, 'acronym'=>1, 'applet'=>1, 'audio'=>1, 'b'=>1, 'bdi'=>1, 'bdo'=>1, 'big'=>1, 'br'=>1, 'button'=>1, 'canvas'=>1, 'cite'=>1, 'code'=>1, 'command'=>1, 'data'=>1, 'datalist'=>1, 'del'=>1, 'dfn'=>1, 'em'=>1, 'embed'=>1, 'figcaption'=>1, 'font'=>1, 'i'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'ins'=>1, 'kbd'=>1, 'label'=>1, 'link'=>1, 'map'=>1, 'mark'=>1, 'meta'=>1, 'meter'=>1, 'object'=>1, 'output'=>1, 'progress'=>1, 'q'=>1, 'ruby'=>1, 's'=>1, 'samp'=>1, 'select'=>1, 'script'=>1, 'small'=>1, 'span'=>1, 'strike'=>1, 'strong'=>1, 'sub'=>1, 'summary'=>1, 'sup'=>1, 'textarea'=>1, 'time'=>1, 'tt'=>1, 'u'=>1, 'var'=>1, 'video'=>1, 'wbr'=>1);
176
+ $eN = array('a'=>1, 'address'=>1, 'article'=>1, 'aside'=>1, 'big'=>1, 'button'=>1, 'details'=>1, 'embed'=>1, 'fieldset'=>1, 'font'=>1, 'footer'=>1, 'form'=>1, 'header'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'keygen'=>1, 'label'=>1, 'meter'=>1, 'nav'=>1, 'object'=>1, 'progress'=>1, 'ruby'=>1, 'script'=>1, 'select'=>1, 'small'=>1, 'sub'=>1, 'sup'=>1, 'textarea'=>1, 'time'=>1); // Exclude from specific ele; $cN values
177
+ $eO = array('area'=>1, 'caption'=>1, 'col'=>1, 'colgroup'=>1, 'command'=>1, 'dd'=>1, 'dt'=>1, 'hgroup'=>1, 'keygen'=>1, 'legend'=>1, 'li'=>1, 'optgroup'=>1, 'option'=>1, 'param'=>1, 'rb'=>1, 'rbc'=>1, 'rp'=>1, 'rt'=>1, 'rtc'=>1, 'script'=>1, 'source'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'thead'=>1, 'th'=>1, 'tr'=>1, 'track'=>1); // Missing in $eB & $eI
178
+ $eF = $eB + $eI;
179
+
180
+ // $in sets allowed child
181
+ $in = ((isset($eF[$in]) && $in != '#pcdata') or isset($eO[$in])) ? $in : 'div';
182
+ if(isset($cE[$in])){
183
+ return (!$do ? '' : str_replace(array('<', '>'), array('&lt;', '&gt;'), $t));
184
+ }
185
+ if(isset($cS[$in])){$inOk = $cS[$in];}
186
+ elseif(isset($cI[$in])){$inOk = $eI; $cI['del'] = 1; $cI['ins'] = 1;}
187
+ elseif(isset($cF[$in])){$inOk = $eF; unset($cI['del'], $cI['ins']);}
188
+ elseif(isset($cB[$in])){$inOk = $eB; unset($cI['del'], $cI['ins']);}
189
+ if(isset($cO[$in])){$inOk = $inOk + $cO[$in];}
190
+ if(isset($cN[$in])){$inOk = array_diff_assoc($inOk, $cN[$in]);}
191
+
192
+ $t = explode('<', $t);
193
+ $ok = $q = array(); // $q seq list of open non-empty ele
194
+ ob_start();
195
+
196
+ for($i=-1, $ci=count($t); ++$i<$ci;){
197
+ // allowed $ok in parent $p
198
+ if($ql = count($q)){
199
+ $p = array_pop($q);
200
+ $q[] = $p;
201
+ if(isset($cS[$p])){$ok = $cS[$p];}
202
+ elseif(isset($cI[$p])){$ok = $eI; $cI['del'] = 1; $cI['ins'] = 1;}
203
+ elseif(isset($cF[$p])){$ok = $eF; unset($cI['del'], $cI['ins']);}
204
+ elseif(isset($cB[$p])){$ok = $eB; unset($cI['del'], $cI['ins']);}
205
+ if(isset($cO[$p])){$ok = $ok + $cO[$p];}
206
+ if(isset($cN[$p])){$ok = array_diff_assoc($ok, $cN[$p]);}
207
+ }else{$ok = $inOk; unset($cI['del'], $cI['ins']);}
208
+ // bad tags, & ele content
209
+ if(isset($e) && ($do == 1 or (isset($ok['#pcdata']) && ($do == 3 or $do == 5)))){
210
+ echo '&lt;', $s, $e, $a, '&gt;';
211
+ }
212
+ if(isset($x[0])){
213
+ if(strlen(trim($x)) && (($ql && isset($cB[$p])) or (isset($cB[$in]) && !$ql))){
214
+ echo '<div>', $x, '</div>';
215
+ }
216
+ elseif($do < 3 or isset($ok['#pcdata'])){echo $x;}
217
+ elseif(strpos($x, "\x02\x04")){
218
+ foreach(preg_split('`(\x01\x02[^\x01\x02]+\x02\x01)`', $x, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $v){
219
+ echo (substr($v, 0, 2) == "\x01\x02" ? $v : ($do > 4 ? preg_replace('`\S`', '', $v) : ''));
220
+ }
221
+ }elseif($do > 4){echo preg_replace('`\S`', '', $x);}
222
+ }
223
+ // get markup
224
+ if(!preg_match('`^(/?)([a-z1-6]+)([^>]*)>(.*)`sm', $t[$i], $r)){$x = $t[$i]; continue;}
225
+ $s = null; $e = null; $a = null; $x = null; list($all, $s, $e, $a, $x) = $r;
226
+ // close tag
227
+ if($s){
228
+ if(isset($cE[$e]) or !in_array($e, $q)){continue;} // Empty/unopen
229
+ if($p == $e){array_pop($q); echo '</', $e, '>'; unset($e); continue;} // Last open
230
+ $add = ''; // Nesting - close open tags that need to be
231
+ for($j=-1, $cj=count($q); ++$j<$cj;){
232
+ if(($d = array_pop($q)) == $e){break;}
233
+ else{$add .= "</{$d}>";}
234
+ }
235
+ echo $add, '</', $e, '>'; unset($e); continue;
236
+ }
237
+ // open tag
238
+ // $cB ele needs $eB ele as child
239
+ if(isset($cB[$e]) && strlen(trim($x))){
240
+ $t[$i] = "{$e}{$a}>";
241
+ array_splice($t, $i+1, 0, 'div>'. $x); unset($e, $x); ++$ci; --$i; continue;
242
+ }
243
+ if((($ql && isset($cB[$p])) or (isset($cB[$in]) && !$ql)) && !isset($eB[$e]) && !isset($ok[$e])){
244
+ array_splice($t, $i, 0, 'div>'); unset($e, $x); ++$ci; --$i; continue;
245
+ }
246
+ // if no open ele, $in = parent; mostly immediate parent-child relation should hold
247
+ if(!$ql or !isset($eN[$e]) or !array_intersect($q, $cN2)){
248
+ if(!isset($ok[$e])){
249
+ if($ql && isset($cT[$p])){echo '</', array_pop($q), '>'; unset($e, $x); --$i;}
250
+ continue;
251
+ }
252
+ if(!isset($cE[$e])){$q[] = $e;}
253
+ echo '<', $e, $a, '>'; unset($e); continue;
254
+ }
255
+ // specific parent-child
256
+ if(isset($cS[$p][$e])){
257
+ if(!isset($cE[$e])){$q[] = $e;}
258
+ echo '<', $e, $a, '>'; unset($e); continue;
259
+ }
260
+ // nesting
261
+ $add = '';
262
+ $q2 = array();
263
+ for($k=-1, $kc=count($q); ++$k<$kc;){
264
+ $d = $q[$k];
265
+ $ok2 = array();
266
+ if(isset($cS[$d])){$q2[] = $d; continue;}
267
+ $ok2 = isset($cI[$d]) ? $eI : $eF;
268
+ if(isset($cO[$d])){$ok2 = $ok2 + $cO[$d];}
269
+ if(isset($cN[$d])){$ok2 = array_diff_assoc($ok2, $cN[$d]);}
270
+ if(!isset($ok2[$e])){
271
+ if(!$k && !isset($inOk[$e])){continue 2;}
272
+ $add = "</{$d}>";
273
+ for(;++$k<$kc;){$add = "</{$q[$k]}>{$add}";}
274
+ break;
275
+ }
276
+ else{$q2[] = $d;}
277
+ }
278
+ $q = $q2;
279
+ if(!isset($cE[$e])){$q[] = $e;}
280
+ echo $add, '<', $e, $a, '>'; unset($e); continue;
281
+ }
282
+
283
+ // end
284
+ if($ql = count($q)){
285
+ $p = array_pop($q);
286
+ $q[] = $p;
287
+ if(isset($cS[$p])){$ok = $cS[$p];}
288
+ elseif(isset($cI[$p])){$ok = $eI; $cI['del'] = 1; $cI['ins'] = 1;}
289
+ elseif(isset($cF[$p])){$ok = $eF; unset($cI['del'], $cI['ins']);}
290
+ elseif(isset($cB[$p])){$ok = $eB; unset($cI['del'], $cI['ins']);}
291
+ if(isset($cO[$p])){$ok = $ok + $cO[$p];}
292
+ if(isset($cN[$p])){$ok = array_diff_assoc($ok, $cN[$p]);}
293
+ }else{$ok = $inOk; unset($cI['del'], $cI['ins']);}
294
+ if(isset($e) && ($do == 1 or (isset($ok['#pcdata']) && ($do == 3 or $do == 5)))){
295
+ echo '&lt;', $s, $e, $a, '&gt;';
296
+ }
297
+ if(isset($x[0])){
298
+ if(strlen(trim($x)) && (($ql && isset($cB[$p])) or (isset($cB[$in]) && !$ql))){
299
+ echo '<div>', $x, '</div>';
300
+ }
301
+ elseif($do < 3 or isset($ok['#pcdata'])){echo $x;}
302
+ elseif(strpos($x, "\x02\x04")){
303
+ foreach(preg_split('`(\x01\x02[^\x01\x02]+\x02\x01)`', $x, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $v){
304
+ echo (substr($v, 0, 2) == "\x01\x02" ? $v : ($do > 4 ? preg_replace('`\S`', '', $v) : ''));
305
+ }
306
+ }elseif($do > 4){echo preg_replace('`\S`', '', $x);}
307
+ }
308
+ while(!empty($q) && ($e = array_pop($q))){echo '</', $e, '>';}
309
+ $o = ob_get_contents();
310
+ ob_end_clean();
311
+ return $o;
312
+ }
313
+
314
+ public static function hl_cmtcd($t){
315
+ // comment/CDATA sec handler
316
+ $t = $t[0];
317
+ global $C;
318
+ if(!($v = $C[$n = $t[3] == '-' ? 'comment' : 'cdata'])){return $t;}
319
+ if($v == 1){return '';}
320
+ if($n == 'comment' && $v < 4){
321
+ if(substr(($t = preg_replace('`--+`', '-', substr($t, 4, -3))), -1) != ' '){$t .= ' ';}
322
+ }
323
+ else{$t = substr($t, 1, -1);}
324
+ $t = $v == 2 ? str_replace(array('&', '<', '>'), array('&amp;', '&lt;', '&gt;'), $t) : $t;
325
+ return str_replace(array('&', '<', '>'), array("\x03", "\x04", "\x05"), ($n == 'comment' ? "\x01\x02\x04!--$t--\x05\x02\x01" : "\x01\x01\x04$t\x05\x01\x01"));
326
+ }
327
+
328
+ public static function hl_ent($t){
329
+ // entitity handler
330
+ global $C;
331
+ $t = $t[1];
332
+ static $U = array('quot'=>1,'amp'=>1,'lt'=>1,'gt'=>1);
333
+ static $N = array('fnof'=>'402', 'Alpha'=>'913', 'Beta'=>'914', 'Gamma'=>'915', 'Delta'=>'916', 'Epsilon'=>'917', 'Zeta'=>'918', 'Eta'=>'919', 'Theta'=>'920', 'Iota'=>'921', 'Kappa'=>'922', 'Lambda'=>'923', 'Mu'=>'924', 'Nu'=>'925', 'Xi'=>'926', 'Omicron'=>'927', 'Pi'=>'928', 'Rho'=>'929', 'Sigma'=>'931', 'Tau'=>'932', 'Upsilon'=>'933', 'Phi'=>'934', 'Chi'=>'935', 'Psi'=>'936', 'Omega'=>'937', 'alpha'=>'945', 'beta'=>'946', 'gamma'=>'947', 'delta'=>'948', 'epsilon'=>'949', 'zeta'=>'950', 'eta'=>'951', 'theta'=>'952', 'iota'=>'953', 'kappa'=>'954', 'lambda'=>'955', 'mu'=>'956', 'nu'=>'957', 'xi'=>'958', 'omicron'=>'959', 'pi'=>'960', 'rho'=>'961', 'sigmaf'=>'962', 'sigma'=>'963', 'tau'=>'964', 'upsilon'=>'965', 'phi'=>'966', 'chi'=>'967', 'psi'=>'968', 'omega'=>'969', 'thetasym'=>'977', 'upsih'=>'978', 'piv'=>'982', 'bull'=>'8226', 'hellip'=>'8230', 'prime'=>'8242', 'Prime'=>'8243', 'oline'=>'8254', 'frasl'=>'8260', 'weierp'=>'8472', 'image'=>'8465', 'real'=>'8476', 'trade'=>'8482', 'alefsym'=>'8501', 'larr'=>'8592', 'uarr'=>'8593', 'rarr'=>'8594', 'darr'=>'8595', 'harr'=>'8596', 'crarr'=>'8629', 'lArr'=>'8656', 'uArr'=>'8657', 'rArr'=>'8658', 'dArr'=>'8659', 'hArr'=>'8660', 'forall'=>'8704', 'part'=>'8706', 'exist'=>'8707', 'empty'=>'8709', 'nabla'=>'8711', 'isin'=>'8712', 'notin'=>'8713', 'ni'=>'8715', 'prod'=>'8719', 'sum'=>'8721', 'minus'=>'8722', 'lowast'=>'8727', 'radic'=>'8730', 'prop'=>'8733', 'infin'=>'8734', 'ang'=>'8736', 'and'=>'8743', 'or'=>'8744', 'cap'=>'8745', 'cup'=>'8746', 'int'=>'8747', 'there4'=>'8756', 'sim'=>'8764', 'cong'=>'8773', 'asymp'=>'8776', 'ne'=>'8800', 'equiv'=>'8801', 'le'=>'8804', 'ge'=>'8805', 'sub'=>'8834', 'sup'=>'8835', 'nsub'=>'8836', 'sube'=>'8838', 'supe'=>'8839', 'oplus'=>'8853', 'otimes'=>'8855', 'perp'=>'8869', 'sdot'=>'8901', 'lceil'=>'8968', 'rceil'=>'8969', 'lfloor'=>'8970', 'rfloor'=>'8971', 'lang'=>'9001', 'rang'=>'9002', 'loz'=>'9674', 'spades'=>'9824', 'clubs'=>'9827', 'hearts'=>'9829', 'diams'=>'9830', 'apos'=>'39', 'OElig'=>'338', 'oelig'=>'339', 'Scaron'=>'352', 'scaron'=>'353', 'Yuml'=>'376', 'circ'=>'710', 'tilde'=>'732', 'ensp'=>'8194', 'emsp'=>'8195', 'thinsp'=>'8201', 'zwnj'=>'8204', 'zwj'=>'8205', 'lrm'=>'8206', 'rlm'=>'8207', 'ndash'=>'8211', 'mdash'=>'8212', 'lsquo'=>'8216', 'rsquo'=>'8217', 'sbquo'=>'8218', 'ldquo'=>'8220', 'rdquo'=>'8221', 'bdquo'=>'8222', 'dagger'=>'8224', 'Dagger'=>'8225', 'permil'=>'8240', 'lsaquo'=>'8249', 'rsaquo'=>'8250', 'euro'=>'8364', 'nbsp'=>'160', 'iexcl'=>'161', 'cent'=>'162', 'pound'=>'163', 'curren'=>'164', 'yen'=>'165', 'brvbar'=>'166', 'sect'=>'167', 'uml'=>'168', 'copy'=>'169', 'ordf'=>'170', 'laquo'=>'171', 'not'=>'172', 'shy'=>'173', 'reg'=>'174', 'macr'=>'175', 'deg'=>'176', 'plusmn'=>'177', 'sup2'=>'178', 'sup3'=>'179', 'acute'=>'180', 'micro'=>'181', 'para'=>'182', 'middot'=>'183', 'cedil'=>'184', 'sup1'=>'185', 'ordm'=>'186', 'raquo'=>'187', 'frac14'=>'188', 'frac12'=>'189', 'frac34'=>'190', 'iquest'=>'191', 'Agrave'=>'192', 'Aacute'=>'193', 'Acirc'=>'194', 'Atilde'=>'195', 'Auml'=>'196', 'Aring'=>'197', 'AElig'=>'198', 'Ccedil'=>'199', 'Egrave'=>'200', 'Eacute'=>'201', 'Ecirc'=>'202', 'Euml'=>'203', 'Igrave'=>'204', 'Iacute'=>'205', 'Icirc'=>'206', 'Iuml'=>'207', 'ETH'=>'208', 'Ntilde'=>'209', 'Ograve'=>'210', 'Oacute'=>'211', 'Ocirc'=>'212', 'Otilde'=>'213', 'Ouml'=>'214', 'times'=>'215', 'Oslash'=>'216', 'Ugrave'=>'217', 'Uacute'=>'218', 'Ucirc'=>'219', 'Uuml'=>'220', 'Yacute'=>'221', 'THORN'=>'222', 'szlig'=>'223', 'agrave'=>'224', 'aacute'=>'225', 'acirc'=>'226', 'atilde'=>'227', 'auml'=>'228', 'aring'=>'229', 'aelig'=>'230', 'ccedil'=>'231', 'egrave'=>'232', 'eacute'=>'233', 'ecirc'=>'234', 'euml'=>'235', 'igrave'=>'236', 'iacute'=>'237', 'icirc'=>'238', 'iuml'=>'239', 'eth'=>'240', 'ntilde'=>'241', 'ograve'=>'242', 'oacute'=>'243', 'ocirc'=>'244', 'otilde'=>'245', 'ouml'=>'246', 'divide'=>'247', 'oslash'=>'248', 'ugrave'=>'249', 'uacute'=>'250', 'ucirc'=>'251', 'uuml'=>'252', 'yacute'=>'253', 'thorn'=>'254', 'yuml'=>'255');
334
+ if($t[0] != '#'){
335
+ return ($C['and_mark'] ? "\x06" : '&'). (isset($U[$t]) ? $t : (isset($N[$t]) ? (!$C['named_entity'] ? '#'. ($C['hexdec_entity'] > 1 ? 'x'. dechex($N[$t]) : $N[$t]) : $t) : 'amp;'. $t)). ';';
336
+ }
337
+ if(($n = ctype_digit($t = substr($t, 1)) ? intval($t) : hexdec(substr($t, 1))) < 9 or ($n > 13 && $n < 32) or $n == 11 or $n == 12 or ($n > 126 && $n < 160 && $n != 133) or ($n > 55295 && ($n < 57344 or ($n > 64975 && $n < 64992) or $n == 65534 or $n == 65535 or $n > 1114111))){
338
+ return ($C['and_mark'] ? "\x06" : '&'). "amp;#{$t};";
339
+ }
340
+ return ($C['and_mark'] ? "\x06" : '&'). '#'. (((ctype_digit($t) && $C['hexdec_entity'] < 2) or !$C['hexdec_entity']) ? $n : 'x'. dechex($n)). ';';
341
+ }
342
+
343
+ public static function hl_prot($p, $c=null){
344
+ // check URL scheme
345
+ global $C;
346
+ $b = $a = '';
347
+ if($c == null){$c = 'style'; $b = $p[1]; $a = $p[3]; $p = trim($p[2]);}
348
+ $c = isset($C['schemes'][$c]) ? $C['schemes'][$c] : $C['schemes']['*'];
349
+ static $d = 'denied:';
350
+ if(isset($c['!']) && substr($p, 0, 7) != $d){$p = "$d$p";}
351
+ if(isset($c['*']) or !strcspn($p, '#?;') or (substr($p, 0, 7) == $d)){return "{$b}{$p}{$a}";} // All ok, frag, query, param
352
+ if(preg_match('`^([^:?[@!$()*,=/\'\]]+?)(:|&#(58|x3a);|%3a|\\\\0{0,4}3a).`i', $p, $m) && !isset($c[strtolower($m[1])])){ // Denied prot
353
+ return "{$b}{$d}{$p}{$a}";
354
+ }
355
+ if($C['abs_url']){
356
+ if($C['abs_url'] == -1 && strpos($p, $C['base_url']) === 0){ // Make url rel
357
+ $p = substr($p, strlen($C['base_url']));
358
+ }elseif(empty($m[1])){ // Make URL abs
359
+ if(substr($p, 0, 2) == '//'){$p = substr($C['base_url'], 0, strpos($C['base_url'], ':')+1). $p;}
360
+ elseif($p[0] == '/'){$p = preg_replace('`(^.+?://[^/]+)(.*)`', '$1', $C['base_url']). $p;}
361
+ elseif(strcspn($p, './')){$p = $C['base_url']. $p;}
362
+ else{
363
+ preg_match('`^([a-zA-Z\d\-+.]+://[^/]+)(.*)`', $C['base_url'], $m);
364
+ $p = preg_replace('`(?<=/)\./`', '', $m[2]. $p);
365
+ while(preg_match('`(?<=/)([^/]{3,}|[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`', $p)){
366
+ $p = preg_replace('`(?<=/)([^/]{3,}|[^/.]+?|\.[^/.]|[^/.]\.)/\.\./`', '', $p);
367
+ }
368
+ $p = $m[1]. $p;
369
+ }
370
+ }
371
+ }
372
+ return "{$b}{$p}{$a}";
373
+ }
374
+
375
+ public static function hl_regex($p){
376
+ // check regex
377
+ if(empty($p)){return 0;}
378
+ if($v = function_exists('error_clear_last') && function_exists('error_get_last')){error_clear_last();}
379
+ else{
380
+ if($t = ini_get('track_errors')){$o = isset($php_errormsg) ? $php_errormsg : null;}
381
+ else{ini_set('track_errors', 1);}
382
+ unset($php_errormsg);
383
+ }
384
+ if(($d = ini_get('display_errors'))){ini_set('display_errors', 0);}
385
+ preg_match($p, '');
386
+ if($v){$r = error_get_last() == null ? 1 : 0; }
387
+ else{
388
+ $r = isset($php_errormsg) ? 0 : 1;
389
+ if($t){$php_errormsg = isset($o) ? $o : null;}
390
+ else{ini_set('track_errors', 0);}
391
+ }
392
+ if($d){ini_set('display_errors', 1);}
393
+ return $r;
394
+ }
395
+
396
+ public static function hl_spec($t){
397
+ // final $spec
398
+ $s = array();
399
+ if(!function_exists('hl_aux1')){function hl_aux1($m){
400
+ return substr(str_replace(array(";", "|", "~", " ", ",", "/", "(", ")", '`"'), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", '"'), $m[0]), 1, -1);
401
+ }}
402
+ $t = str_replace(array("\t", "\r", "\n", ' '), '', preg_replace_callback('/"(?>(`.|[^"])*)"/sm', 'hl_aux1', trim($t)));
403
+ for($i = count(($t = explode(';', $t))); --$i>=0;){
404
+ $w = $t[$i];
405
+ if(empty($w) or ($e = strpos($w, '=')) === false or !strlen(($a = substr($w, $e+1)))){continue;}
406
+ $y = $n = array();
407
+ foreach(explode(',', $a) as $v){
408
+ if(!preg_match('`^([a-z:\-\*]+)(?:\((.*?)\))?`i', $v, $m)){continue;}
409
+ if(($x = strtolower($m[1])) == '-*'){$n['*'] = 1; continue;}
410
+ if($x[0] == '-'){$n[substr($x, 1)] = 1; continue;}
411
+ if(!isset($m[2])){$y[$x] = 1; continue;}
412
+ foreach(explode('/', $m[2]) as $m){
413
+ if(empty($m) or ($p = strpos($m, '=')) == 0 or $p < 5){$y[$x] = 1; continue;}
414
+ $y[$x][strtolower(substr($m, 0, $p))] = str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08"), array(";", "|", "~", " ", ",", "/", "(", ")"), substr($m, $p+1));
415
+ }
416
+ if(isset($y[$x]['match']) && !self::hl_regex($y[$x]['match'])){unset($y[$x]['match']);}
417
+ if(isset($y[$x]['nomatch']) && !self::hl_regex($y[$x]['nomatch'])){unset($y[$x]['nomatch']);}
418
+ }
419
+ if(!count($y) && !count($n)){continue;}
420
+ foreach(explode(',', substr($w, 0, $e)) as $v){
421
+ if(!strlen(($v = strtolower($v)))){continue;}
422
+ if(count($y)){if(!isset($s[$v])){$s[$v] = $y;} else{$s[$v] = array_merge($s[$v], $y);}}
423
+ if(count($n)){if(!isset($s[$v]['n'])){$s[$v]['n'] = $n;} else{$s[$v]['n'] = array_merge($s[$v]['n'], $n);}}
424
+ }
425
+ }
426
+ return $s;
427
+ }
428
+
429
+ public static function hl_tag($t){
430
+ // tag/attribute handler
431
+ global $C;
432
+ $t = $t[0];
433
+ // invalid < >
434
+ if($t == '< '){return '&lt; ';}
435
+ if($t == '>'){return '&gt;';}
436
+ if(!preg_match('`^<(/?)([a-zA-Z][a-zA-Z1-6]*)([^>]*?)\s?>$`m', $t, $m)){
437
+ return str_replace(array('<', '>'), array('&lt;', '&gt;'), $t);
438
+ }elseif(!isset($C['elements'][($e = strtolower($m[2]))])){
439
+ return (($C['keep_bad']%2) ? str_replace(array('<', '>'), array('&lt;', '&gt;'), $t) : '');
440
+ }
441
+ // attr string
442
+ $a = str_replace(array("\n", "\r", "\t"), ' ', trim($m[3]));
443
+ // tag transform
444
+ static $eD = array('acronym'=>1, 'applet'=>1, 'big'=>1, 'center'=>1, 'dir'=>1, 'font'=>1, 'isindex'=>1, 's'=>1, 'strike'=>1, 'tt'=>1); // Deprecated
445
+ if($C['make_tag_strict'] && isset($eD[$e])){
446
+ $trt = self::hl_tag2($e, $a, $C['make_tag_strict']);
447
+ if(!$e){return (($C['keep_bad']%2) ? str_replace(array('<', '>'), array('&lt;', '&gt;'), $t) : '');}
448
+ }
449
+ // close tag
450
+ static $eE = array('area'=>1, 'br'=>1, 'col'=>1, 'command'=>1, 'embed'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'keygen'=>1, 'link'=>1, 'meta'=>1, 'param'=>1, 'source'=>1, 'track'=>1, 'wbr'=>1); // Empty ele
451
+ if(!empty($m[1])){
452
+ return (!isset($eE[$e]) ? (empty($C['hook_tag']) ? "</$e>" : $C['hook_tag']($e)) : (($C['keep_bad'])%2 ? str_replace(array('<', '>'), array('&lt;', '&gt;'), $t) : ''));
453
+ }
454
+
455
+ // open tag & attr
456
+ static $aN = array('abbr'=>array('td'=>1, 'th'=>1), 'accept'=>array('form'=>1, 'input'=>1), 'accept-charset'=>array('form'=>1), 'action'=>array('form'=>1), 'align'=>array('applet'=>1, 'caption'=>1, 'col'=>1, 'colgroup'=>1, 'div'=>1, 'embed'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hr'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'legend'=>1, 'object'=>1, 'p'=>1, 'table'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'allowfullscreen'=>array('iframe'=>1), 'alt'=>array('applet'=>1, 'area'=>1, 'img'=>1, 'input'=>1), 'archive'=>array('applet'=>1, 'object'=>1), 'async'=>array('script'=>1), 'autocomplete'=>array('form'=>1, 'input'=>1), 'autofocus'=>array('button'=>1, 'input'=>1, 'keygen'=>1, 'select'=>1, 'textarea'=>1), 'autoplay'=>array('audio'=>1, 'video'=>1), 'axis'=>array('td'=>1, 'th'=>1), 'bgcolor'=>array('embed'=>1, 'table'=>1, 'td'=>1, 'th'=>1, 'tr'=>1), 'border'=>array('img'=>1, 'object'=>1, 'table'=>1), 'bordercolor'=>array('table'=>1, 'td'=>1, 'tr'=>1), 'cellpadding'=>array('table'=>1), 'cellspacing'=>array('table'=>1), 'challenge'=>array('keygen'=>1), 'char'=>array('col'=>1, 'colgroup'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'charoff'=>array('col'=>1, 'colgroup'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'charset'=>array('a'=>1, 'script'=>1), 'checked'=>array('command'=>1, 'input'=>1), 'cite'=>array('blockquote'=>1, 'del'=>1, 'ins'=>1, 'q'=>1), 'classid'=>array('object'=>1), 'clear'=>array('br'=>1), 'code'=>array('applet'=>1), 'codebase'=>array('applet'=>1, 'object'=>1), 'codetype'=>array('object'=>1), 'color'=>array('font'=>1), 'cols'=>array('textarea'=>1), 'colspan'=>array('td'=>1, 'th'=>1), 'compact'=>array('dir'=>1, 'dl'=>1, 'menu'=>1, 'ol'=>1, 'ul'=>1), 'content'=>array('meta'=>1), 'controls'=>array('audio'=>1, 'video'=>1), 'coords'=>array('a'=>1, 'area'=>1), 'crossorigin'=>array('img'=>1), 'data'=>array('object'=>1), 'datetime'=>array('del'=>1, 'ins'=>1, 'time'=>1), 'declare'=>array('object'=>1), 'default'=>array('track'=>1), 'defer'=>array('script'=>1), 'dirname'=>array('input'=>1, 'textarea'=>1), 'disabled'=>array('button'=>1, 'command'=>1, 'fieldset'=>1, 'input'=>1, 'keygen'=>1, 'optgroup'=>1, 'option'=>1, 'select'=>1, 'textarea'=>1), 'download'=>array('a'=>1), 'enctype'=>array('form'=>1), 'face'=>array('font'=>1), 'flashvars'=>array('embed'=>1), 'for'=>array('label'=>1, 'output'=>1), 'form'=>array('button'=>1, 'fieldset'=>1, 'input'=>1, 'keygen'=>1, 'label'=>1, 'object'=>1, 'output'=>1, 'select'=>1, 'textarea'=>1), 'formaction'=>array('button'=>1, 'input'=>1), 'formenctype'=>array('button'=>1, 'input'=>1), 'formmethod'=>array('button'=>1, 'input'=>1), 'formnovalidate'=>array('button'=>1, 'input'=>1), 'formtarget'=>array('button'=>1, 'input'=>1), 'frame'=>array('table'=>1), 'frameborder'=>array('iframe'=>1), 'headers'=>array('td'=>1, 'th'=>1), 'height'=>array('applet'=>1, 'canvas'=>1, 'embed'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'object'=>1, 'td'=>1, 'th'=>1, 'video'=>1), 'high'=>array('meter'=>1), 'href'=>array('a'=>1, 'area'=>1, 'link'=>1), 'hreflang'=>array('a'=>1, 'area'=>1, 'link'=>1), 'hspace'=>array('applet'=>1, 'embed'=>1, 'img'=>1, 'object'=>1), 'icon'=>array('command'=>1), 'ismap'=>array('img'=>1, 'input'=>1), 'keyparams'=>array('keygen'=>1), 'keytype'=>array('keygen'=>1), 'kind'=>array('track'=>1), 'label'=>array('command'=>1, 'menu'=>1, 'option'=>1, 'optgroup'=>1, 'track'=>1), 'language'=>array('script'=>1), 'list'=>array('input'=>1), 'longdesc'=>array('img'=>1, 'iframe'=>1), 'loop'=>array('audio'=>1, 'video'=>1), 'low'=>array('meter'=>1), 'marginheight'=>array('iframe'=>1), 'marginwidth'=>array('iframe'=>1), 'max'=>array('input'=>1, 'meter'=>1, 'progress'=>1), 'maxlength'=>array('input'=>1, 'textarea'=>1), 'media'=>array('a'=>1, 'area'=>1, 'link'=>1, 'source'=>1, 'style'=>1), 'mediagroup'=>array('audio'=>1, 'video'=>1), 'method'=>array('form'=>1), 'min'=>array('input'=>1, 'meter'=>1), 'model'=>array('embed'=>1), 'multiple'=>array('input'=>1, 'select'=>1), 'muted'=>array('audio'=>1, 'video'=>1), 'name'=>array('a'=>1, 'applet'=>1, 'button'=>1, 'embed'=>1, 'fieldset'=>1, 'form'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'keygen'=>1, 'map'=>1, 'object'=>1, 'output'=>1, 'param'=>1, 'select'=>1, 'textarea'=>1), 'nohref'=>array('area'=>1), 'noshade'=>array('hr'=>1), 'novalidate'=>array('form'=>1), 'nowrap'=>array('td'=>1, 'th'=>1), 'object'=>array('applet'=>1), 'open'=>array('details'=>1), 'optimum'=>array('meter'=>1), 'pattern'=>array('input'=>1), 'ping'=>array('a'=>1, 'area'=>1), 'placeholder'=>array('input'=>1, 'textarea'=>1), 'pluginspage'=>array('embed'=>1), 'pluginurl'=>array('embed'=>1), 'poster'=>array('video'=>1), 'pqg'=>array('keygen'=>1), 'preload'=>array('audio'=>1, 'video'=>1), 'prompt'=>array('isindex'=>1), 'pubdate'=>array('time'=>1), 'radiogroup'=>array('command'=>1), 'readonly'=>array('input'=>1, 'textarea'=>1), 'rel'=>array('a'=>1, 'area'=>1, 'link'=>1), 'required'=>array('input'=>1, 'select'=>1, 'textarea'=>1), 'rev'=>array('a'=>1), 'reversed'=>array('ol'=>1), 'rows'=>array('textarea'=>1), 'rowspan'=>array('td'=>1, 'th'=>1), 'rules'=>array('table'=>1), 'sandbox'=>array('iframe'=>1), 'scope'=>array('td'=>1, 'th'=>1), 'scoped'=>array('style'=>1), 'scrolling'=>array('iframe'=>1), 'seamless'=>array('iframe'=>1), 'selected'=>array('option'=>1), 'shape'=>array('a'=>1, 'area'=>1), 'size'=>array('font'=>1, 'hr'=>1, 'input'=>1, 'select'=>1), 'sizes'=>array('link'=>1), 'span'=>array('col'=>1, 'colgroup'=>1), 'src'=>array('audio'=>1, 'embed'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'script'=>1, 'source'=>1, 'track'=>1, 'video'=>1), 'srcdoc'=>array('iframe'=>1), 'srclang'=>array('track'=>1), 'srcset'=>array('img'=>1), 'standby'=>array('object'=>1), 'start'=>array('ol'=>1), 'step'=>array('input'=>1), 'summary'=>array('table'=>1), 'target'=>array('a'=>1, 'area'=>1, 'form'=>1), 'type'=>array('a'=>1, 'area'=>1, 'button'=>1, 'command'=>1, 'embed'=>1, 'input'=>1, 'li'=>1, 'link'=>1, 'menu'=>1, 'object'=>1, 'ol'=>1, 'param'=>1, 'script'=>1, 'source'=>1, 'style'=>1, 'ul'=>1), 'typemustmatch'=>array('object'=>1), 'usemap'=>array('img'=>1, 'input'=>1, 'object'=>1), 'valign'=>array('col'=>1, 'colgroup'=>1, 'tbody'=>1, 'td'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1), 'value'=>array('button'=>1, 'data'=>1, 'input'=>1, 'li'=>1, 'meter'=>1, 'option'=>1, 'param'=>1, 'progress'=>1), 'valuetype'=>array('param'=>1), 'vspace'=>array('applet'=>1, 'embed'=>1, 'img'=>1, 'object'=>1), 'width'=>array('applet'=>1, 'canvas'=>1, 'col'=>1, 'colgroup'=>1, 'embed'=>1, 'hr'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'object'=>1, 'pre'=>1, 'table'=>1, 'td'=>1, 'th'=>1, 'video'=>1), 'wmode'=>array('embed'=>1), 'wrap'=>array('textarea'=>1)); // Ele-specific
457
+ static $aNA = array('aria-activedescendant'=>1, 'aria-atomic'=>1, 'aria-autocomplete'=>1, 'aria-busy'=>1, 'aria-checked'=>1, 'aria-controls'=>1, 'aria-describedby'=>1, 'aria-disabled'=>1, 'aria-dropeffect'=>1, 'aria-expanded'=>1, 'aria-flowto'=>1, 'aria-grabbed'=>1, 'aria-haspopup'=>1, 'aria-hidden'=>1, 'aria-invalid'=>1, 'aria-label'=>1, 'aria-labelledby'=>1, 'aria-level'=>1, 'aria-live'=>1, 'aria-multiline'=>1, 'aria-multiselectable'=>1, 'aria-orientation'=>1, 'aria-owns'=>1, 'aria-posinset'=>1, 'aria-pressed'=>1, 'aria-readonly'=>1, 'aria-relevant'=>1, 'aria-required'=>1, 'aria-selected'=>1, 'aria-setsize'=>1, 'aria-sort'=>1, 'aria-valuemax'=>1, 'aria-valuemin'=>1, 'aria-valuenow'=>1, 'aria-valuetext'=>1); // ARIA
458
+ static $aNE = array('allowfullscreen'=>1, 'checkbox'=>1, 'checked'=>1, 'command'=>1, 'compact'=>1, 'declare'=>1, 'defer'=>1, 'default'=>1, 'disabled'=>1, 'hidden'=>1, 'inert'=>1, 'ismap'=>1, 'itemscope'=>1, 'multiple'=>1, 'nohref'=>1, 'noresize'=>1, 'noshade'=>1, 'nowrap'=>1, 'open'=>1, 'radio'=>1, 'readonly'=>1, 'required'=>1, 'reversed'=>1, 'selected'=>1); // Empty
459
+ static $aNO = array('onabort'=>1, 'onblur'=>1, 'oncanplay'=>1, 'oncanplaythrough'=>1, 'onchange'=>1, 'onclick'=>1, 'oncontextmenu'=>1, 'oncopy'=>1, 'oncuechange'=>1, 'oncut'=>1, 'ondblclick'=>1, 'ondrag'=>1, 'ondragend'=>1, 'ondragenter'=>1, 'ondragleave'=>1, 'ondragover'=>1, 'ondragstart'=>1, 'ondrop'=>1, 'ondurationchange'=>1, 'onemptied'=>1, 'onended'=>1, 'onerror'=>1, 'onfocus'=>1, 'onformchange'=>1, 'onforminput'=>1, 'oninput'=>1, 'oninvalid'=>1, 'onkeydown'=>1, 'onkeypress'=>1, 'onkeyup'=>1, 'onload'=>1, 'onloadeddata'=>1, 'onloadedmetadata'=>1, 'onloadstart'=>1, 'onlostpointercapture'=>1, 'onmousedown'=>1, 'onmousemove'=>1, 'onmouseout'=>1, 'onmouseover'=>1, 'onmouseup'=>1, 'onmousewheel'=>1, 'onpaste'=>1, 'onpause'=>1, 'onplay'=>1, 'onplaying'=>1, 'onpointercancel'=>1, 'ongotpointercapture'=>1, 'onpointerdown'=>1, 'onpointerenter'=>1, 'onpointerleave'=>1, 'onpointermove'=>1, 'onpointerout'=>1, 'onpointerover'=>1, 'onpointerup'=>1, 'onprogress'=>1, 'onratechange'=>1, 'onreadystatechange'=>1, 'onreset'=>1, 'onsearch'=>1, 'onscroll'=>1, 'onseeked'=>1, 'onseeking'=>1, 'onselect'=>1, 'onshow'=>1, 'onstalled'=>1, 'onsubmit'=>1, 'onsuspend'=>1, 'ontimeupdate'=>1, 'ontoggle'=>1, 'ontouchcancel'=>1, 'ontouchend'=>1, 'ontouchmove'=>1, 'ontouchstart'=>1, 'onvolumechange'=>1, 'onwaiting'=>1, 'onwheel'=>1); // Event
460
+ static $aNP = array('action'=>1, 'cite'=>1, 'classid'=>1, 'codebase'=>1, 'data'=>1, 'href'=>1, 'itemtype'=>1, 'longdesc'=>1, 'model'=>1, 'pluginspage'=>1, 'pluginurl'=>1, 'src'=>1, 'srcset'=>1, 'usemap'=>1); // Need scheme check; excludes style, on*
461
+ static $aNU = array('accesskey'=>1, 'class'=>1, 'contenteditable'=>1, 'contextmenu'=>1, 'dir'=>1, 'draggable'=>1, 'dropzone'=>1, 'hidden'=>1, 'id'=>1, 'inert'=>1, 'itemid'=>1, 'itemprop'=>1, 'itemref'=>1, 'itemscope'=>1, 'itemtype'=>1, 'lang'=>1, 'role'=>1, 'spellcheck'=>1, 'style'=>1, 'tabindex'=>1, 'title'=>1, 'translate'=>1, 'xmlns'=>1, 'xml:base'=>1, 'xml:lang'=>1, 'xml:space'=>1); // Univ; excludes on*, aria*
462
+
463
+ if($C['lc_std_val']){
464
+ // predef attr vals for $eAL & $aNE ele
465
+ static $aNL = array('all'=>1, 'auto'=>1, 'baseline'=>1, 'bottom'=>1, 'button'=>1, 'captions'=>1, 'center'=>1, 'chapters'=>1, 'char'=>1, 'checkbox'=>1, 'circle'=>1, 'col'=>1, 'colgroup'=>1, 'color'=>1, 'cols'=>1, 'data'=>1, 'date'=>1, 'datetime'=>1, 'datetime-local'=>1, 'default'=>1, 'descriptions'=>1, 'email'=>1, 'file'=>1, 'get'=>1, 'groups'=>1, 'hidden'=>1, 'image'=>1, 'justify'=>1, 'left'=>1, 'ltr'=>1, 'metadata'=>1, 'middle'=>1, 'month'=>1, 'none'=>1, 'number'=>1, 'object'=>1, 'password'=>1, 'poly'=>1, 'post'=>1, 'preserve'=>1, 'radio'=>1, 'range'=>1, 'rect'=>1, 'ref'=>1, 'reset'=>1, 'right'=>1, 'row'=>1, 'rowgroup'=>1, 'rows'=>1, 'rtl'=>1, 'search'=>1, 'submit'=>1, 'subtitles'=>1, 'tel'=>1, 'text'=>1, 'time'=>1, 'top'=>1, 'url'=>1, 'week'=>1);
466
+ static $eAL = array('a'=>1, 'area'=>1, 'bdo'=>1, 'button'=>1, 'col'=>1, 'fieldset'=>1, 'form'=>1, 'img'=>1, 'input'=>1, 'object'=>1, 'ol'=>1, 'optgroup'=>1, 'option'=>1, 'param'=>1, 'script'=>1, 'select'=>1, 'table'=>1, 'td'=>1, 'textarea'=>1, 'tfoot'=>1, 'th'=>1, 'thead'=>1, 'tr'=>1, 'track'=>1, 'xml:space'=>1);
467
+ $lcase = isset($eAL[$e]) ? 1 : 0;
468
+ }
469
+
470
+ $depTr = 0;
471
+ if($C['no_deprecated_attr']){
472
+ // depr attr:applicable ele
473
+ static $aND = array('align'=>array('caption'=>1, 'div'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'legend'=>1, 'object'=>1, 'p'=>1, 'table'=>1), 'bgcolor'=>array('table'=>1, 'td'=>1, 'th'=>1, 'tr'=>1), 'border'=>array('object'=>1), 'bordercolor'=>array('table'=>1, 'td'=>1, 'tr'=>1), 'cellspacing'=>array('table'=>1), 'clear'=>array('br'=>1), 'compact'=>array('dl'=>1, 'ol'=>1, 'ul'=>1), 'height'=>array('td'=>1, 'th'=>1), 'hspace'=>array('img'=>1, 'object'=>1), 'language'=>array('script'=>1), 'name'=>array('a'=>1, 'form'=>1, 'iframe'=>1, 'img'=>1, 'map'=>1), 'noshade'=>array('hr'=>1), 'nowrap'=>array('td'=>1, 'th'=>1), 'size'=>array('hr'=>1), 'vspace'=>array('img'=>1, 'object'=>1), 'width'=>array('hr'=>1, 'pre'=>1, 'table'=>1, 'td'=>1, 'th'=>1));
474
+ static $eAD = array('a'=>1, 'br'=>1, 'caption'=>1, 'div'=>1, 'dl'=>1, 'form'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'hr'=>1, 'iframe'=>1, 'img'=>1, 'input'=>1, 'legend'=>1, 'map'=>1, 'object'=>1, 'ol'=>1, 'p'=>1, 'pre'=>1, 'script'=>1, 'table'=>1, 'td'=>1, 'th'=>1, 'tr'=>1, 'ul'=>1);
475
+ $depTr = isset($eAD[$e]) ? 1 : 0;
476
+ }
477
+
478
+ // attr name-vals
479
+ if(strpos($a, "\x01") !== false){$a = preg_replace('`\x01[^\x01]*\x01`', '', $a);} // No comment/CDATA sec
480
+ $mode = 0; $a = trim($a, ' /'); $aA = array();
481
+ while(strlen($a)){
482
+ $w = 0;
483
+ switch($mode){
484
+ case 0: // Name
485
+ if(preg_match('`^[a-zA-Z][^\s=/]+`', $a, $m)){
486
+ $nm = strtolower($m[0]);
487
+ $w = $mode = 1; $a = ltrim(substr_replace($a, '', 0, strlen($m[0])));
488
+ }
489
+ break; case 1:
490
+ if($a[0] == '='){ // =
491
+ $w = 1; $mode = 2; $a = ltrim($a, '= ');
492
+ }else{ // No val
493
+ $w = 1; $mode = 0; $a = ltrim($a);
494
+ $aA[$nm] = '';
495
+ }
496
+ break; case 2: // Val
497
+ if(preg_match('`^((?:"[^"]*")|(?:\'[^\']*\')|(?:\s*[^\s"\']+))(.*)`', $a, $m)){
498
+ $a = ltrim($m[2]); $m = $m[1]; $w = 1; $mode = 0;
499
+ $aA[$nm] = trim(str_replace('<', '&lt;', ($m[0] == '"' or $m[0] == '\'') ? substr($m, 1, -1) : $m));
500
+ }
501
+ break;
502
+ }
503
+ if($w == 0){ // Parse errs, deal with space, " & '
504
+ $a = preg_replace('`^(?:"[^"]*("|$)|\'[^\']*(\'|$)|\S)*\s*`', '', $a);
505
+ $mode = 0;
506
+ }
507
+ }
508
+ if($mode == 1){$aA[$nm] = '';}
509
+
510
+ // clean attrs
511
+ global $S;
512
+ $rl = isset($S[$e]) ? $S[$e] : array();
513
+ $a = array(); $nfr = 0; $d = $C['deny_attribute'];
514
+ foreach($aA as $k=>$v){
515
+ if(((isset($d['*']) ? isset($d[$k]) : !isset($d[$k])) && (isset($aN[$k][$e]) or isset($aNU[$k]) or (isset($aNO[$k]) && !isset($d['on*'])) or (isset($aNA[$k]) && !isset($d['aria*'])) or (!isset($d['data*']) && preg_match('`data-((?!xml)[^:]+$)`', $k))) && !isset($rl['n'][$k]) && !isset($rl['n']['*'])) or isset($rl[$k])){
516
+ if(isset($aNE[$k])){$v = $k;}
517
+ elseif(!empty($lcase) && (($e != 'button' or $e != 'input') or $k == 'type')){ // Rather loose but ?not cause issues
518
+ $v = (isset($aNL[($v2 = strtolower($v))])) ? $v2 : $v;
519
+ }
520
+ if($k == 'style' && !$C['style_pass']){
521
+ if(false !== strpos($v, '&#')){
522
+ static $sC = array('&#x20;'=>' ', '&#32;'=>' ', '&#x45;'=>'e', '&#69;'=>'e', '&#x65;'=>'e', '&#101;'=>'e', '&#x58;'=>'x', '&#88;'=>'x', '&#x78;'=>'x', '&#120;'=>'x', '&#x50;'=>'p', '&#80;'=>'p', '&#x70;'=>'p', '&#112;'=>'p', '&#x53;'=>'s', '&#83;'=>'s', '&#x73;'=>'s', '&#115;'=>'s', '&#x49;'=>'i', '&#73;'=>'i', '&#x69;'=>'i', '&#105;'=>'i', '&#x4f;'=>'o', '&#79;'=>'o', '&#x6f;'=>'o', '&#111;'=>'o', '&#x4e;'=>'n', '&#78;'=>'n', '&#x6e;'=>'n', '&#110;'=>'n', '&#x55;'=>'u', '&#85;'=>'u', '&#x75;'=>'u', '&#117;'=>'u', '&#x52;'=>'r', '&#82;'=>'r', '&#x72;'=>'r', '&#114;'=>'r', '&#x4c;'=>'l', '&#76;'=>'l', '&#x6c;'=>'l', '&#108;'=>'l', '&#x28;'=>'(', '&#40;'=>'(', '&#x29;'=>')', '&#41;'=>')', '&#x20;'=>':', '&#32;'=>':', '&#x22;'=>'"', '&#34;'=>'"', '&#x27;'=>"'", '&#39;'=>"'", '&#x2f;'=>'/', '&#47;'=>'/', '&#x2a;'=>'*', '&#42;'=>'*', '&#x5c;'=>'\\', '&#92;'=>'\\');
523
+ $v = strtr($v, $sC);
524
+ }
525
+ $v = preg_replace_callback('`(url(?:\()(?: )*(?:\'|"|&(?:quot|apos);)?)(.+?)((?:\'|"|&(?:quot|apos);)?(?: )*(?:\)))`iS', 'self::hl_prot', $v);
526
+ $v = !$C['css_expression'] ? preg_replace('`expression`i', ' ', preg_replace('`\\\\\S|(/|(%2f))(\*|(%2a))`i', ' ', $v)) : $v;
527
+ }elseif(isset($aNP[$k]) or isset($aNO[$k])){
528
+ $v = str_replace("­", ' ', (strpos($v, '&') !== false ? str_replace(array('&#xad;', '&#173;', '&shy;'), ' ', $v) : $v)); # double-quoted char: soft-hyphen; appears here as "­" or hyphen or something else depending on viewing software
529
+ if($k == 'srcset'){
530
+ $v2 = '';
531
+ foreach(explode(',', $v) as $k1=>$v1){
532
+ $v1 = explode(' ', ltrim($v1), 2);
533
+ $k1 = isset($v1[1]) ? trim($v1[1]) : '';
534
+ $v1 = trim($v1[0]);
535
+ if(isset($v1[0])){$v2 .= self::hl_prot($v1, $k). (empty($k1) ? '' : ' '. $k1). ', ';}
536
+ }
537
+ $v = trim($v2, ', ');
538
+ }
539
+ if($k == 'itemtype'){
540
+ $v2 = '';
541
+ foreach(explode(' ', $v) as $v1){
542
+ if(isset($v1[0])){$v2 .= self::hl_prot($v1, $k). ' ';}
543
+ }
544
+ $v = trim($v2, ' ');
545
+ }
546
+ else{$v = self::hl_prot($v, $k);}
547
+ if($k == 'href'){ // X-spam
548
+ if($C['anti_mail_spam'] && strpos($v, 'mailto:') === 0){
549
+ $v = str_replace('@', htmlspecialchars($C['anti_mail_spam']), $v);
550
+ }elseif($C['anti_link_spam']){
551
+ $r1 = $C['anti_link_spam'][1];
552
+ if(!empty($r1) && preg_match($r1, $v)){continue;}
553
+ $r0 = $C['anti_link_spam'][0];
554
+ if(!empty($r0) && preg_match($r0, $v)){
555
+ if(isset($a['rel'])){
556
+ if(!preg_match('`\bnofollow\b`i', $a['rel'])){$a['rel'] .= ' nofollow';}
557
+ }elseif(isset($aA['rel'])){
558
+ if(!preg_match('`\bnofollow\b`i', $aA['rel'])){$nfr = 1;}
559
+ }else{$a['rel'] = 'nofollow';}
560
+ }
561
+ }
562
+ }
563
+ }
564
+ if(isset($rl[$k]) && is_array($rl[$k]) && ($v = self::hl_attrval($k, $v, $rl[$k])) === 0){continue;}
565
+ $a[$k] = str_replace('"', '&quot;', $v);
566
+ }
567
+ }
568
+ if($nfr){$a['rel'] = isset($a['rel']) ? $a['rel']. ' nofollow' : 'nofollow';}
569
+
570
+ // rqd attr
571
+ static $eAR = array('area'=>array('alt'=>'area'), 'bdo'=>array('dir'=>'ltr'), 'command'=>array('label'=>''), 'form'=>array('action'=>''), 'img'=>array('src'=>'', 'alt'=>'image'), 'map'=>array('name'=>''), 'optgroup'=>array('label'=>''), 'param'=>array('name'=>''), 'style'=>array('scoped'=>''), 'textarea'=>array('rows'=>'10', 'cols'=>'50'));
572
+ if(isset($eAR[$e])){
573
+ foreach($eAR[$e] as $k=>$v){
574
+ if(!isset($a[$k])){$a[$k] = isset($v[0]) ? $v : $k;}
575
+ }
576
+ }
577
+
578
+ // depr attr
579
+ if($depTr){
580
+ $c = array();
581
+ foreach($a as $k=>$v){
582
+ if($k == 'style' or !isset($aND[$k][$e])){continue;}
583
+ $v = str_replace(array('\\', ':', ';', '&#'), '', $v);
584
+ if($k == 'align'){
585
+ unset($a['align']);
586
+ if($e == 'img' && ($v == 'left' or $v == 'right')){$c[] = 'float: '. $v;}
587
+ elseif(($e == 'div' or $e == 'table') && $v == 'center'){$c[] = 'margin: auto';}
588
+ else{$c[] = 'text-align: '. $v;}
589
+ }elseif($k == 'bgcolor'){
590
+ unset($a['bgcolor']);
591
+ $c[] = 'background-color: '. $v;
592
+ }elseif($k == 'border'){
593
+ unset($a['border']); $c[] = "border: {$v}px";
594
+ }elseif($k == 'bordercolor'){
595
+ unset($a['bordercolor']); $c[] = 'border-color: '. $v;
596
+ }elseif($k == 'cellspacing'){
597
+ unset($a['cellspacing']); $c[] = "border-spacing: {$v}px";
598
+ }elseif($k == 'clear'){
599
+ unset($a['clear']); $c[] = 'clear: '. ($v != 'all' ? $v : 'both');
600
+ }elseif($k == 'compact'){
601
+ unset($a['compact']); $c[] = 'font-size: 85%';
602
+ }elseif($k == 'height' or $k == 'width'){
603
+ unset($a[$k]); $c[] = $k. ': '. ($v[0] != '*' ? $v. (ctype_digit($v) ? 'px' : '') : 'auto');
604
+ }elseif($k == 'hspace'){
605
+ unset($a['hspace']); $c[] = "margin-left: {$v}px; margin-right: {$v}px";
606
+ }elseif($k == 'language' && !isset($a['type'])){
607
+ unset($a['language']);
608
+ $a['type'] = 'text/'. strtolower($v);
609
+ }elseif($k == 'name'){
610
+ if($C['no_deprecated_attr'] == 2 or ($e != 'a' && $e != 'map')){unset($a['name']);}
611
+ if(!isset($a['id']) && !preg_match('`\W`', $v)){$a['id'] = $v;}
612
+ }elseif($k == 'noshade'){
613
+ unset($a['noshade']); $c[] = 'border-style: none; border: 0; background-color: gray; color: gray';
614
+ }elseif($k == 'nowrap'){
615
+ unset($a['nowrap']); $c[] = 'white-space: nowrap';
616
+ }elseif($k == 'size'){
617
+ unset($a['size']); $c[] = 'size: '. $v. 'px';
618
+ }elseif($k == 'vspace'){
619
+ unset($a['vspace']); $c[] = "margin-top: {$v}px; margin-bottom: {$v}px";
620
+ }
621
+ }
622
+ if(count($c)){
623
+ $c = implode('; ', $c);
624
+ $a['style'] = isset($a['style']) ? rtrim($a['style'], ' ;'). '; '. $c. ';': $c. ';';
625
+ }
626
+ }
627
+ // unique ID
628
+ if($C['unique_ids'] && isset($a['id'])){
629
+ if(preg_match('`\s`', ($id = $a['id'])) or (isset($GLOBALS['hl_Ids'][$id]) && $C['unique_ids'] == 1)){unset($a['id']);
630
+ }else{
631
+ while(isset($GLOBALS['hl_Ids'][$id])){$id = $C['unique_ids']. $id;}
632
+ $GLOBALS['hl_Ids'][($a['id'] = $id)] = 1;
633
+ }
634
+ }
635
+ // xml:lang
636
+ if($C['xml:lang'] && isset($a['lang'])){
637
+ $a['xml:lang'] = isset($a['xml:lang']) ? $a['xml:lang'] : $a['lang'];
638
+ if($C['xml:lang'] == 2){unset($a['lang']);}
639
+ }
640
+ // for transformed tag
641
+ if(!empty($trt)){
642
+ $a['style'] = isset($a['style']) ? rtrim($a['style'], ' ;'). '; '. $trt : $trt;
643
+ }
644
+ // return with empty ele /
645
+ if(empty($C['hook_tag'])){
646
+ $aA = '';
647
+ foreach($a as $k=>$v){$aA .= " {$k}=\"{$v}\"";}
648
+ return "<{$e}{$aA}". (isset($eE[$e]) ? ' /' : ''). '>';
649
+ }
650
+ else{return $C['hook_tag']($e, $a);}
651
+ }
652
+
653
+ public static function hl_tag2(&$e, &$a, $t=1){
654
+ // transform tag
655
+ if($e == 'big'){$e = 'span'; return 'font-size: larger;';}
656
+ if($e == 's' or $e == 'strike'){$e = 'span'; return 'text-decoration: line-through;';}
657
+ if($e == 'tt'){$e = 'code'; return '';}
658
+ if($e == 'center'){$e = 'div'; return 'text-align: center;';}
659
+ static $fs = array('0'=>'xx-small', '1'=>'xx-small', '2'=>'small', '3'=>'medium', '4'=>'large', '5'=>'x-large', '6'=>'xx-large', '7'=>'300%', '-1'=>'smaller', '-2'=>'60%', '+1'=>'larger', '+2'=>'150%', '+3'=>'200%', '+4'=>'300%');
660
+ if($e == 'font'){
661
+ $a2 = '';
662
+ while(preg_match('`(^|\s)(color|size)\s*=\s*(\'|")?(.+?)(\\3|\s|$)`i', $a, $m)){
663
+ $a = str_replace($m[0], ' ', $a);
664
+ $a2 .= strtolower($m[2]) == 'color' ? (' color: '. str_replace(array('"', ';', ':'), '\'', trim($m[4])). ';') : (isset($fs[($m = trim($m[4]))]) ? (' font-size: '. $fs[$m]. ';') : '');
665
+ }
666
+ while(preg_match('`(^|\s)face\s*=\s*(\'|")?([^=]+?)\\2`i', $a, $m) or preg_match('`(^|\s)face\s*=(\s*)(\S+)`i', $a, $m)){
667
+ $a = str_replace($m[0], ' ', $a);
668
+ $a2 .= ' font-family: '. str_replace(array('"', ';', ':'), '\'', trim($m[3])). ';';
669
+ }
670
+ $e = 'span'; return ltrim(str_replace('<', '', $a2));
671
+ }
672
+ if($e == 'acronym'){$e = 'abbr'; return '';}
673
+ if($e == 'dir'){$e = 'ul'; return '';}
674
+ if($t == 2){$e = 0; return 0;}
675
+ return '';
676
+ }
677
+
678
+ public static function hl_tidy($t, $w, $p){
679
+ // tidy/compact HTM
680
+ if(strpos(' pre,script,textarea', "$p,")){return $t;}
681
+ if(!function_exists('hl_aux2')){function hl_aux2($m){
682
+ return $m[1]. str_replace(array("<", ">", "\n", "\r", "\t", ' '), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), $m[3]). $m[4];
683
+ }}
684
+ $t = preg_replace(array('`(<\w[^>]*(?<!/)>)\s+`', '`\s+`', '`(<\w[^>]*(?<!/)>) `'), array(' $1', ' ', '$1'), preg_replace_callback(array('`(<(!\[CDATA\[))(.+?)(\]\]>)`sm', '`(<(!--))(.+?)(-->)`sm', '`(<(pre|script|textarea)[^>]*?>)(.+?)(</\2>)`sm'), 'hl_aux2', $t));
685
+ if(($w = strtolower($w)) == -1){
686
+ return str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), array('<', '>', "\n", "\r", "\t", ' '), $t);
687
+ }
688
+ $s = strpos(" $w", 't') ? "\t" : ' ';
689
+ $s = preg_match('`\d`', $w, $m) ? str_repeat($s, $m[0]) : str_repeat($s, ($s == "\t" ? 1 : 2));
690
+ $N = preg_match('`[ts]([1-9])`', $w, $m) ? $m[1] : 0;
691
+ $a = array('br'=>1);
692
+ $b = array('button'=>1, 'command'=>1, 'input'=>1, 'option'=>1, 'param'=>1, 'track'=>1);
693
+ $c = array('audio'=>1, 'canvas'=>1, 'caption'=>1, 'dd'=>1, 'dt'=>1, 'figcaption'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'isindex'=>1, 'label'=>1, 'legend'=>1, 'li'=>1, 'object'=>1, 'p'=>1, 'pre'=>1, 'style'=>1, 'summary'=>1, 'td'=>1, 'textarea'=>1, 'th'=>1, 'video'=>1);
694
+ $d = array('address'=>1, 'article'=>1, 'aside'=>1, 'blockquote'=>1, 'center'=>1, 'colgroup'=>1, 'datalist'=>1, 'details'=>1, 'dir'=>1, 'div'=>1, 'dl'=>1, 'fieldset'=>1, 'figure'=>1, 'footer'=>1, 'form'=>1, 'header'=>1, 'hgroup'=>1, 'hr'=>1, 'iframe'=>1, 'main'=>1, 'map'=>1, 'menu'=>1, 'nav'=>1, 'noscript'=>1, 'ol'=>1, 'optgroup'=>1, 'rbc'=>1, 'rtc'=>1, 'ruby'=>1, 'script'=>1, 'section'=>1, 'select'=>1, 'table'=>1, 'tbody'=>1, 'tfoot'=>1, 'thead'=>1, 'tr'=>1, 'ul'=>1);
695
+ $T = explode('<', $t);
696
+ $X = 1;
697
+ while($X){
698
+ $n = $N;
699
+ $t = $T;
700
+ ob_start();
701
+ if(isset($d[$p])){echo str_repeat($s, ++$n);}
702
+ echo ltrim(array_shift($t));
703
+ for($i=-1, $j=count($t); ++$i<$j;){
704
+ $r = ''; list($e, $r) = explode('>', $t[$i]);
705
+ $x = $e[0] == '/' ? 0 : (substr($e, -1) == '/' ? 1 : ($e[0] != '!' ? 2 : -1));
706
+ $y = !$x ? ltrim($e, '/') : ($x > 0 ? substr($e, 0, strcspn($e, ' ')) : 0);
707
+ $e = "<$e>";
708
+ if(isset($d[$y])){
709
+ if(!$x){
710
+ if($n){echo "\n", str_repeat($s, --$n), "$e\n", str_repeat($s, $n);}
711
+ else{++$N; ob_end_clean(); continue 2;}
712
+ }
713
+ else{echo "\n", str_repeat($s, $n), "$e\n", str_repeat($s, ($x != 1 ? ++$n : $n));}
714
+ echo $r; continue;
715
+ }
716
+ $f = "\n". str_repeat($s, $n);
717
+ if(isset($c[$y])){
718
+ if(!$x){echo $e, $f, $r;}
719
+ else{echo $f, $e, $r;}
720
+ }elseif(isset($b[$y])){echo $f, $e, $r;
721
+ }elseif(isset($a[$y])){echo $e, $f, $r;
722
+ }elseif(!$y){echo $f, $e, $f, $r;
723
+ }else{echo $e, $r;}
724
+ }
725
+ $X = 0;
726
+ }
727
+ $t = str_replace(array("\n ", " \n"), "\n", preg_replace('`[\n]\s*?[\n]+`', "\n", ob_get_contents()));
728
+ ob_end_clean();
729
+ if(($l = strpos(" $w", 'r') ? (strpos(" $w", 'n') ? "\r\n" : "\r") : 0)){
730
+ $t = str_replace("\n", $l, $t);
731
+ }
732
+ return str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), array('<', '>', "\n", "\r", "\t", ' '), $t);
733
+ }
734
+
735
+ public static function hl_version(){
736
+ // version
737
+ return '1.2.5';
738
+ }
739
+
740
+ // end class
741
+ }
vendor/composer/ClassLoader.php CHANGED
@@ -37,11 +37,13 @@ namespace Composer\Autoload;
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
- * @see http://www.php-fig.org/psr/psr-0/
41
- * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
 
 
45
  // PSR-4
46
  private $prefixLengthsPsr4 = array();
47
  private $prefixDirsPsr4 = array();
@@ -57,10 +59,17 @@ class ClassLoader
57
  private $missingClasses = array();
58
  private $apcuPrefix;
59
 
 
 
 
 
 
 
 
60
  public function getPrefixes()
61
  {
62
  if (!empty($this->prefixesPsr0)) {
63
- return call_user_func_array('array_merge', $this->prefixesPsr0);
64
  }
65
 
66
  return array();
@@ -279,7 +288,7 @@ class ClassLoader
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
282
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
283
  }
284
 
285
  /**
@@ -300,6 +309,17 @@ class ClassLoader
300
  public function register($prepend = false)
301
  {
302
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
305
  /**
@@ -308,6 +328,10 @@ class ClassLoader
308
  public function unregister()
309
  {
310
  spl_autoload_unregister(array($this, 'loadClass'));
 
 
 
 
311
  }
312
 
313
  /**
@@ -367,6 +391,16 @@ class ClassLoader
367
  return $file;
368
  }
369
 
 
 
 
 
 
 
 
 
 
 
370
  private function findFileWithExtension($class, $ext)
371
  {
372
  // PSR-4 lookup
@@ -377,7 +411,7 @@ class ClassLoader
377
  $subPath = $class;
378
  while (false !== $lastPos = strrpos($subPath, '\\')) {
379
  $subPath = substr($subPath, 0, $lastPos);
380
- $search = $subPath.'\\';
381
  if (isset($this->prefixDirsPsr4[$search])) {
382
  $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see https://www.php-fig.org/psr/psr-0/
41
+ * @see https://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
45
+ private $vendorDir;
46
+
47
  // PSR-4
48
  private $prefixLengthsPsr4 = array();
49
  private $prefixDirsPsr4 = array();
59
  private $missingClasses = array();
60
  private $apcuPrefix;
61
 
62
+ private static $registeredLoaders = array();
63
+
64
+ public function __construct($vendorDir = null)
65
+ {
66
+ $this->vendorDir = $vendorDir;
67
+ }
68
+
69
  public function getPrefixes()
70
  {
71
  if (!empty($this->prefixesPsr0)) {
72
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
73
  }
74
 
75
  return array();
288
  */
289
  public function setApcuPrefix($apcuPrefix)
290
  {
291
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
292
  }
293
 
294
  /**
309
  public function register($prepend = false)
310
  {
311
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
312
+
313
+ if (null === $this->vendorDir) {
314
+ return;
315
+ }
316
+
317
+ if ($prepend) {
318
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
319
+ } else {
320
+ unset(self::$registeredLoaders[$this->vendorDir]);
321
+ self::$registeredLoaders[$this->vendorDir] = $this;
322
+ }
323
  }
324
 
325
  /**
328
  public function unregister()
329
  {
330
  spl_autoload_unregister(array($this, 'loadClass'));
331
+
332
+ if (null !== $this->vendorDir) {
333
+ unset(self::$registeredLoaders[$this->vendorDir]);
334
+ }
335
  }
336
 
337
  /**
391
  return $file;
392
  }
393
 
394
+ /**
395
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
396
+ *
397
+ * @return self[]
398
+ */
399
+ public static function getRegisteredLoaders()
400
+ {
401
+ return self::$registeredLoaders;
402
+ }
403
+
404
  private function findFileWithExtension($class, $ext)
405
  {
406
  // PSR-4 lookup
411
  $subPath = $class;
412
  while (false !== $lastPos = strrpos($subPath, '\\')) {
413
  $subPath = substr($subPath, 0, $lastPos);
414
+ $search = $subPath . '\\';
415
  if (isset($this->prefixDirsPsr4[$search])) {
416
  $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
417
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
vendor/composer/autoload_classmap.php CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
  );
vendor/composer/autoload_real.php CHANGED
@@ -13,19 +13,24 @@ class ComposerAutoloaderInit2a403b03a84e333364c96d224aa62f5c
13
  }
14
  }
15
 
 
 
 
16
  public static function getLoader()
17
  {
18
  if (null !== self::$loader) {
19
  return self::$loader;
20
  }
21
 
 
 
22
  spl_autoload_register(array('ComposerAutoloaderInit2a403b03a84e333364c96d224aa62f5c', 'loadClassLoader'), true, true);
23
- self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
  spl_autoload_unregister(array('ComposerAutoloaderInit2a403b03a84e333364c96d224aa62f5c', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
- require_once __DIR__ . '/autoload_static.php';
29
 
30
  call_user_func(\Composer\Autoload\ComposerStaticInit2a403b03a84e333364c96d224aa62f5c::getInitializer($loader));
31
  } else {
13
  }
14
  }
15
 
16
+ /**
17
+ * @return \Composer\Autoload\ClassLoader
18
+ */
19
  public static function getLoader()
20
  {
21
  if (null !== self::$loader) {
22
  return self::$loader;
23
  }
24
 
25
+ require __DIR__ . '/platform_check.php';
26
+
27
  spl_autoload_register(array('ComposerAutoloaderInit2a403b03a84e333364c96d224aa62f5c', 'loadClassLoader'), true, true);
28
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
  spl_autoload_unregister(array('ComposerAutoloaderInit2a403b03a84e333364c96d224aa62f5c', 'loadClassLoader'));
30
 
31
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
32
  if ($useStaticLoader) {
33
+ require __DIR__ . '/autoload_static.php';
34
 
35
  call_user_func(\Composer\Autoload\ComposerStaticInit2a403b03a84e333364c96d224aa62f5c::getInitializer($loader));
36
  } else {
vendor/composer/autoload_static.php CHANGED
@@ -20,11 +20,16 @@ class ComposerStaticInit2a403b03a84e333364c96d224aa62f5c
20
  ),
21
  );
22
 
 
 
 
 
23
  public static function getInitializer(ClassLoader $loader)
24
  {
25
  return \Closure::bind(function () use ($loader) {
26
  $loader->prefixLengthsPsr4 = ComposerStaticInit2a403b03a84e333364c96d224aa62f5c::$prefixLengthsPsr4;
27
  $loader->prefixDirsPsr4 = ComposerStaticInit2a403b03a84e333364c96d224aa62f5c::$prefixDirsPsr4;
 
28
 
29
  }, null, ClassLoader::class);
30
  }
20
  ),
21
  );
22
 
23
+ public static $classMap = array (
24
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
25
+ );
26
+
27
  public static function getInitializer(ClassLoader $loader)
28
  {
29
  return \Closure::bind(function () use ($loader) {
30
  $loader->prefixLengthsPsr4 = ComposerStaticInit2a403b03a84e333364c96d224aa62f5c::$prefixLengthsPsr4;
31
  $loader->prefixDirsPsr4 = ComposerStaticInit2a403b03a84e333364c96d224aa62f5c::$prefixDirsPsr4;
32
+ $loader->classMap = ComposerStaticInit2a403b03a84e333364c96d224aa62f5c::$classMap;
33
 
34
  }, null, ClassLoader::class);
35
  }
vendor/composer/platform_check.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // platform_check.php @generated by Composer
4
+
5
+ $issues = array();
6
+
7
+ if (!(PHP_VERSION_ID >= 50400)) {
8
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 5.4.0". You are running ' . PHP_VERSION . '.';
9
+ }
10
+
11
+ if ($issues) {
12
+ if (!headers_sent()) {
13
+ header('HTTP/1.1 500 Internal Server Error');
14
+ }
15
+ if (!ini_get('display_errors')) {
16
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
17
+ fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
18
+ } elseif (!headers_sent()) {
19
+ echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
20
+ }
21
+ }
22
+ trigger_error(
23
+ 'Composer detected issues in your platform: ' . implode(' ', $issues),
24
+ E_USER_ERROR
25
+ );
26
+ }
wordpress-popular-posts.php CHANGED
@@ -16,7 +16,7 @@
16
  * Plugin Name: WordPress Popular Posts
17
  * Plugin URI: https://wordpress.org/plugins/wordpress-popular-posts/
18
  * Description: A highly customizable widget that displays the most popular posts on your blog.
19
- * Version: 5.3.3
20
  * Author: Hector Cabrera
21
  * Author URI: https://cabrerahector.com/
22
  * License: GPL-2.0+
@@ -29,7 +29,7 @@ if ( ! defined( 'WPINC' ) ) {
29
  die();
30
  }
31
 
32
- define('WPP_VERSION', '5.3.3');
33
  define('WPP_MIN_PHP_VERSION', '5.4');
34
  define('WPP_MIN_WP_VERSION', '4.9');
35
 
16
  * Plugin Name: WordPress Popular Posts
17
  * Plugin URI: https://wordpress.org/plugins/wordpress-popular-posts/
18
  * Description: A highly customizable widget that displays the most popular posts on your blog.
19
+ * Version: 5.3.4
20
  * Author: Hector Cabrera
21
  * Author URI: https://cabrerahector.com/
22
  * License: GPL-2.0+
29
  die();
30
  }
31
 
32
+ define('WPP_VERSION', '5.3.4');
33
  define('WPP_MIN_PHP_VERSION', '5.4');
34
  define('WPP_MIN_WP_VERSION', '4.9');
35