Version Description
- 4th February 2022 =
- Improved: Select2 library is now included with the plugin instead of being loaded from CDN.
- Fixed: Various changes relating to plugin structure, data sanitisation, and validation.
Download this release
Release Info
Developer | voltronik |
Plugin | Better Notifications for WordPress |
Version | 1.8.8 |
Comparing to | |
See all releases |
Code changes from version 1.8.7 to 1.8.8
- README.txt +5 -1
- assets/css/select2.min.css +1 -0
- assets/js/select2.full.min.js +3 -0
- bnfw.php +1523 -1519
- includes/admin/bnfw-settings.php +0 -287
- includes/admin/class-bnfw-notification.php +1679 -1651
- includes/admin/class-bnfw-settings.php +281 -0
- includes/class-bnfw-import.php +180 -0
- includes/engine/class-bnfw-engine.php +1639 -1598
- includes/helpers/ajax-helpers.php +0 -68
- includes/helpers/class-bnfw-ajax.php +77 -0
- includes/helpers/helpers.php +245 -205
- includes/import.php +0 -169
- includes/libraries/EDD_SL_Plugin_Updater.php +0 -619
- includes/libraries/class-edd-sl-plugin-updater.php +695 -0
- includes/license/class-bnfw-license-setting.php +150 -136
- includes/license/class-bnfw-license.php +293 -255
- includes/notification/post-notification.php +36 -33
- includes/overrides.php +205 -193
- vendor/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php +187 -187
README.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: notification, email, alert, message, notify, send, HTML, customize, bulk,
|
|
5 |
Requires at least: 4.8
|
6 |
Tested up to: 5.9
|
7 |
Requires PHP: 7.0
|
8 |
-
Stable tag: 1.8.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
Update URI: https://wordpress.org/plugins/bnfw/
|
@@ -242,6 +242,10 @@ Yes, of course! The plugin is completely translation-friendly and if you send me
|
|
242 |
|
243 |
== Changelog ==
|
244 |
|
|
|
|
|
|
|
|
|
245 |
= 1.8.7 - 27th January 2022 =
|
246 |
* IMPORTANT! It is recommended that you update this plugin to the latest version.
|
247 |
* Fixed: A security issue affecting select2 fields when searching for a user or user role.
|
5 |
Requires at least: 4.8
|
6 |
Tested up to: 5.9
|
7 |
Requires PHP: 7.0
|
8 |
+
Stable tag: 1.8.8
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
Update URI: https://wordpress.org/plugins/bnfw/
|
242 |
|
243 |
== Changelog ==
|
244 |
|
245 |
+
= 1.8.8 - 4th February 2022 =
|
246 |
+
* Improved: Select2 library is now included with the plugin instead of being loaded from CDN.
|
247 |
+
* Fixed: Various changes relating to plugin structure, data sanitisation, and validation.
|
248 |
+
|
249 |
= 1.8.7 - 27th January 2022 =
|
250 |
* IMPORTANT! It is recommended that you update this plugin to the latest version.
|
251 |
* Fixed: A security issue affecting select2 fields when searching for a user or user role.
|
assets/css/select2.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}
|
assets/js/select2.full.min.js
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.slice(0,n.length-1).concat(a),k=0;k<a.length;k+=1)if(m=a[k],"."===m)a.splice(k,1),k-=1;else if(".."===m){if(1===k&&(".."===a[2]||".."===a[0]))break;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=v.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),n.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n<c.length;n+=1)if(m=o(c[n],f),k=m.f,"require"===k)u[n]=p.require(a);else if("exports"===k)u[n]=p.exports(a),s=!0;else if("module"===k)h=u[n]=p.module(a);else if(e(q,k)||e(r,k)||e(t,k))u[n]=j(k);else{if(!m.p)throw new Error(a+" missing "+k);m.p.load(m.n,g(f,!0),i(k),{}),u[n]=q[k]}l=d?d.apply(q[a],u):void 0,a&&(h&&h.exports!==b&&h.exports!==q[a]?q[a]=h.exports:l===b&&s||(q[a]=l))}else a&&(q[a]=d)},a=c=n=function(a,c,d,e,f){if("string"==typeof a)return p[a]?p[a](c):j(o(a,c).f);if(!a.splice){if(s=a,s.deps&&n(s.deps,s.callback),!c)return;c.splice?(a=c,c=d,d=null):a=b}return c=c||function(){},"function"==typeof d&&(d=e,e=f),e?m(b,a,c,d):setTimeout(function(){m(b,a,c,d)},4),n},n.config=function(a){return n(a)},a._defined=q,d=function(a,b,c){if("string"!=typeof a)throw new Error("See almond README: incorrect module build, no module name");b.splice||(c=b,b=[]),e(q,a)||e(r,a)||(r[a]=[a,b,c])},d.amd={jQuery:!0}}(),b.requirejs=a,b.require=c,b.define=d}}(),b.define("almond",function(){}),b.define("jquery",[],function(){var b=a||$;return null==b&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),b}),b.define("select2/utils",["jquery"],function(a){function b(a){var b=a.prototype,c=[];for(var d in b){var e=b[d];"function"==typeof e&&"constructor"!==d&&c.push(d)}return c}var c={};c.Extend=function(a,b){function c(){this.constructor=a}var d={}.hasOwnProperty;for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},c.Decorate=function(a,c){function d(){var b=Array.prototype.unshift,d=c.prototype.constructor.length,e=a.prototype.constructor;d>0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h<g.length;h++){var i=g[h];d.prototype[i]=a.prototype[i]}for(var j=(function(a){var b=function(){};a in d.prototype&&(b=d.prototype[a]);var e=c.prototype[a];return function(){var a=Array.prototype.unshift;return a.call(arguments,b),e.apply(this,arguments)}}),k=0;k<f.length;k++){var l=f[k];d.prototype[l]=j(l)}return d};var d=function(){this.listeners={}};return d.prototype.on=function(a,b){this.listeners=this.listeners||{},a in this.listeners?this.listeners[a].push(b):this.listeners[a]=[b]},d.prototype.trigger=function(a){var b=Array.prototype.slice,c=b.call(arguments,1);this.listeners=this.listeners||{},null==c&&(c=[]),0===c.length&&c.push({}),c[0]._type=a,a in this.listeners&&this.invoke(this.listeners[a],b.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},d.prototype.invoke=function(a,b){for(var c=0,d=a.length;d>c;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e<c.length;e++){var f=c[e];f=f.substring(0,1).toLowerCase()+f.substring(1),f in d||(d[f]={}),e==c.length-1&&(d[f]=a[b]),d=d[f]}delete a[b]}}return a},c.hasScroll=function(b,c){var d=a(c),e=c.style.overflowX,f=c.style.overflowY;return e!==f||"hidden"!==f&&"visible"!==f?"scroll"===e||"scroll"===f?!0:d.innerHeight()<c.scrollHeight||d.innerWidth()<c.scrollWidth:!1},c.escapeMarkup=function(a){var b={"\\":"\","&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<ul class="select2-results__options" role="tree"></ul>');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('<li role="treeitem" aria-live="assertive" class="select2-results__option"></li>'),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c<a.results.length;c++){var d=a.results[c],e=this.option(d);b.push(e)}this.$results.append(b)},c.prototype.position=function(a,b){var c=b.find(".select2-results");c.append(a)},c.prototype.sort=function(a){var b=this.options.get("sorter");return b(a)},c.prototype.highlightFirstItem=function(){var a=this.$results.find(".select2-results__option[aria-selected]"),b=a.filter("[aria-selected=true]");b.length>0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j<b.children.length;j++){var k=b.children[j],l=this.option(k);i.push(l)}var m=a("<ul></ul>",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):0>h-g&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var c=a(this),e=c.data("data");return"true"===c.attr("aria-selected")?void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{})):void d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('<span class="select2-selection" role="combobox" aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},e.prototype.selectionContainer=function(){return a("<span></span>")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('<ul class="select2-selection__rendered"></ul>'),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},d.prototype.selectionContainer=function(){var b=a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">×</span></li>');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d<a.length;d++){var e=a[d],f=this.selectionContainer(),g=this.display(e,f);f.append(g),f.prop("title",e.title||e.text),f.data("data",e),b.push(f)}var h=this.$selection.find(".select2-selection__rendered");c.appendMany(h,b)}},d}),b.define("select2/selection/placeholder",["../utils"],function(a){function b(a,b,c){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c)}return b.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},b.prototype.createPlaceholder=function(a,b){var c=this.selectionContainer();return c.html(this.display(b)),c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),c},b.prototype.update=function(a,b){var c=1==b.length&&b[0].id!=this.placeholder.id,d=b.length>1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e<d.length;e++){var f={data:d[e]};if(this.trigger("unselect",f),f.prevented)return}this.$element.val(this.placeholder.id).trigger("change"),this.trigger("toggle",{})}}},c.prototype._handleKeyboardClear=function(a,c,d){d.isOpen()||(c.which==b.DELETE||c.which==b.BACKSPACE)&&this._handleClear(c)},c.prototype.update=function(b,c){if(b.call(this,c),!(this.$selection.find(".select2-selection__placeholder").length>0||0===c.length)){var d=a('<span class="select2-selection__clear">×</span>');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" aria-autocomplete="list" /></li>');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}});var f=document.documentMode,g=f&&11>=f;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){return g?void e.$selection.off("input.search input.searchcheck"):void e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");
|
2 |
+
if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f<a.length;f++){var g=a[f].id;-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")});else{var d=a.id;this.$element.val(d),this.$element.trigger("change")}},d.prototype.unselect=function(a){var b=this;if(this.$element.prop("multiple"))return a.selected=!1,c(a.element).is("option")?(a.element.selected=!1,void this.$element.trigger("change")):void this.current(function(d){for(var e=[],f=0;f<d.length;f++){var g=d[f].id;g!==a.id&&-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")})},d.prototype.bind=function(a,b){var c=this;this.container=a,a.on("select",function(a){c.select(a.data)}),a.on("unselect",function(a){c.unselect(a.data)})},d.prototype.destroy=function(){this.$element.find("*").each(function(){c.removeData(this,"data")})},d.prototype.query=function(a,b){var d=[],e=this,f=this.$element.children();f.each(function(){var b=c(this);if(b.is("option")||b.is("optgroup")){var f=e.item(b),g=e.matches(a,f);null!==g&&d.push(g)}}),b({results:d})},d.prototype.addOptions=function(a){b.appendMany(this.$element,a)},d.prototype.option=function(a){var b;a.children?(b=document.createElement("optgroup"),b.label=a.text):(b=document.createElement("option"),void 0!==b.textContent?b.textContent=a.text:b.innerText=a.text),a.id&&(b.value=a.id),a.disabled&&(b.disabled=!0),a.selected&&(b.selected=!0),a.title&&(b.title=a.title);var d=c(b),e=this._normalizeItem(a);return e.element=b,c.data(b,"data",e),d},d.prototype.item=function(a){var b={};if(b=c.data(a[0],"data"),null!=b)return b;if(a.is("option"))b={id:a.val(),text:a.text(),disabled:a.prop("disabled"),selected:a.prop("selected"),title:a.prop("title")};else if(a.is("optgroup")){b={text:a.prop("label"),children:[],title:a.prop("title")};for(var d=a.children("option"),e=[],f=0;f<d.length;f++){var g=c(d[f]),h=this.item(g);e.push(h)}b.children=e}return b=this._normalizeItem(b),b.element=a[0],c.data(a[0],"data",b),b},d.prototype._normalizeItem=function(a){c.isPlainObject(a)||(a={id:a,text:a}),a=c.extend({},{text:""},a);var b={selected:!1,disabled:!1};return null!=a.id&&(a.id=a.id.toString()),null!=a.text&&(a.text=a.text.toString()),null==a._resultId&&a.id&&null!=this.container&&(a._resultId=this.generateResultId(this.container,a)),c.extend({},b,a)},d.prototype.matches=function(a,b){var c=this.options.get("matcher");return c(a,b)},d}),b.define("select2/data/array",["./select","../utils","jquery"],function(a,b,c){function d(a,b){var c=b.get("data")||[];d.__super__.constructor.call(this,a,b),this.addOptions(this.convertToOptions(c))}return b.Extend(d,a),d.prototype.select=function(a){var b=this.$element.find("option").filter(function(b,c){return c.value==a.id.toString()});0===b.length&&(b=this.option(a),this.addOptions(b)),d.__super__.select.call(this,a)},d.prototype.convertToOptions=function(a){function d(a){return function(){return c(this).val()==a.id}}for(var e=this,f=this.$element.find("option"),g=f.map(function(){return e.item(c(this)).id}).get(),h=[],i=0;i<a.length;i++){var j=this._normalizeItem(a[i]);if(c.inArray(j.id,g)>=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h<e.length;h++){var i=e[h],j=this._normalizeItem(i),k=this.option(j);this.$element.append(k)}}return b.prototype.query=function(a,b,c){function d(a,f){for(var g=a.results,h=0;h<g.length;h++){var i=g[h],j=null!=i.children&&!d({results:i.children},!0),k=i.text===b.term;if(k||j)return f?!1:(a.data=g,void c(a))}if(f)return!0;var l=e.createTag(b);if(null!=l){var m=e.option(l);m.attr("data-select2-tag",!0),e.addOptions([m]),e.insertTag(g,l)}a.results=g,c(a)}var e=this;return this._removeOldTags(),null==b.term||null!=b.page?void a.call(this,b,c):void a.call(this,b,d)},b.prototype.createTag=function(b,c){var d=a.trim(c.term);return""===d?null:{id:d,text:d}},b.prototype.insertTag=function(a,b,c){b.unshift(c)},b.prototype._removeOldTags=function(b){var c=(this._lastTag,this.$element.find("option[data-select2-tag]"));c.each(function(){this.selected||a(this).remove()})},b}),b.define("select2/data/tokenizer",["jquery"],function(a){function b(a,b,c){var d=c.get("tokenizer");void 0!==d&&(this.tokenizer=d),a.call(this,b,c)}return b.prototype.bind=function(a,b,c){a.call(this,b,c),this.$search=b.dropdown.$search||b.selection.$search||c.find(".select2-search__field")},b.prototype.query=function(b,c,d){function e(b){var c=g._normalizeItem(b),d=g.$element.find("option").filter(function(){return a(this).val()===c.id});if(!d.length){var e=g.option(c);e.attr("data-select2-tag",!0),g._removeOldTags(),g.addOptions([e])}f(c)}function f(a){g.trigger("select",{data:a})}var g=this;c.term=c.term||"";var h=this.tokenizer(c,this.options,e);h.term!==c.term&&(this.$search.length&&(this.$search.val(h.term),this.$search.focus()),c.term=h.term),b.call(this,c,d)},b.prototype.tokenizer=function(b,c,d,e){for(var f=d.get("tokenSeparators")||[],g=c.term,h=0,i=this.createTag||function(a){return{id:a.term,text:a.term}};h<g.length;){var j=g[h];if(-1!==a.inArray(j,f)){var k=g.substr(0,h),l=a.extend({},c,{term:k}),m=i(l);null!=m?(e(m),g=g.substr(h+1)||"",h=0):h++}else h++}return{term:g}},b}),b.define("select2/data/minimumInputLength",[],function(){function a(a,b,c){this.minimumInputLength=c.get("minimumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",b.term.length<this.minimumInputLength?void this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumInputLength",[],function(){function a(a,b,c){this.maximumInputLength=c.get("maximumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",this.maximumInputLength>0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<span class="select2-dropdown"><span class="select2-results"></span></span>');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></span>');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('<li class="select2-results__option select2-results__option--load-more"role="treeitem" aria-disabled="true"></li>'),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a("<span></span>"),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id,h=this.$container.parents().filter(b.hasScroll);h.off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.top<f.top-h.height,k=i.bottom>f.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d<b.length;d++){var e=b[d];e.children?c+=a(e.children):c++}return c}function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return a(c.data.results)<this.minimumResultsForSearch?!1:b.call(this,c)},b}),b.define("select2/dropdown/selectOnClose",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("close",function(a){d._handleSelectOnClose(a)})},a.prototype._handleSelectOnClose=function(a,b){if(b&&null!=b.originalSelect2Event){var c=b.originalSelect2Event;if("select"===c._type||"unselect"===c._type)return}var d=this.getHighlightedResults();if(!(d.length<1)){var e=d.data("data");null!=e.element&&e.element.selected||null==e.element&&e.selected||this.trigger("select",{data:e})}},a}),b.define("select2/dropdown/closeOnSelect",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("select",function(a){d._selectTriggered(a)}),b.on("unselect",function(a){d._selectTriggered(a)})},a.prototype._selectTriggered=function(a,b){var c=b.originalEvent;c&&c.ctrlKey||this.trigger("close",{originalEvent:c,originalSelect2Event:b})},a}),b.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(a){var b=a.input.length-a.maximum,c="Please delete "+b+" character";return 1!=b&&(c+="s"),c},inputTooShort:function(a){var b=a.minimum-a.input.length,c="Please enter "+b+" or more characters";return c},loadingMore:function(){return"Loading more results…"},maximumSelected:function(a){var b="You can only select "+a.maximum+" item";return 1!=a.maximum&&(b+="s"),b},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),b.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C){function D(){this.reset()}D.prototype.apply=function(l){if(l=a.extend(!0,{},this.defaults,l),null==l.dataAdapter){if(null!=l.ajax?l.dataAdapter=o:null!=l.data?l.dataAdapter=n:l.dataAdapter=m,l.minimumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L<K.length;L++){var M=K[L],N={};try{N=k.loadPath(M)}catch(O){try{M=this.defaults.amdLanguageBase+M,N=k.loadPath(M)}catch(P){l.debug&&window.console&&console.warn&&console.warn('Select2: The language file for "'+M+'" could not be automatically loaded. A fallback will be used instead.');continue}}J.extend(N)}l.translations=J}else{var Q=k.loadPath(this.defaults.amdLanguageBase+"en"),R=new k(l.language);R.extend(Q),l.translations=R}return l},D.prototype.reset=function(){function b(a){function b(a){return l[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function c(d,e){if(""===a.trim(d.term))return e;if(e.children&&e.children.length>0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e<b.addedNodes.length;e++){var f=b.addedNodes[e];f.selected&&(c=!0)}else b.removedNodes&&b.removedNodes.length>0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null;
|
3 |
+
},e.prototype.render=function(){var b=a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&(f=d(this),null!=f&&g.push(f))})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;return this._isInitialized?void b.call(this,c):void this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `<select>` element instead."),a.call(this,b,c)}return b.prototype.current=function(b,c){function d(b,c){var e=[];return b.selected||-1!==a.inArray(b.id,c)?(b.selected=!0,e.push(b)):b.selected=!1,b.children&&e.push.apply(e,d(b.children,c)),e}for(var e=[],f=0;f<this._currentData.length;f++){var g=this._currentData[f];e.push.apply(e,d(g,this.$element.val().split(this._valueSeparator)))}c(e)},b.prototype.select=function(b,c){if(this.options.get("multiple")){var d=this.$element.val();d+=this._valueSeparator+c.id,this.$element.val(d),this.$element.trigger("change")}else this.current(function(b){a.map(b,function(a){a.selected=!1})}),this.$element.val(c.id),this.$element.trigger("change")},b.prototype.unselect=function(a,b){var c=this;b.selected=!1,this.current(function(a){for(var d=[],e=0;e<a.length;e++){var f=a[e];b.id!=f.id&&d.push(f.id)}c.$element.val(d.join(c._valueSeparator)),c.$element.trigger("change")})},b.prototype.query=function(a,b,c){for(var d=[],e=0;e<this._currentData.length;e++){var f=this._currentData[e],g=this.matches(b,f);null!==g&&d.push(g)}c({results:d})},b.prototype.addOptions=function(b,c){var d=a.map(c,function(b){return a.data(b[0],"data")});this._currentData.push.apply(this._currentData,d)},b}),b.define("select2/compat/matcher",["jquery"],function(a){function b(b){function c(c,d){var e=a.extend(!0,{},d);if(null==c.term||""===a.trim(c.term))return e;if(d.children){for(var f=d.children.length-1;f>=0;f--){var g=d.children[f],h=b(c.term,g.text,g);h||e.children.splice(f,1)}if(e.children.length>0)return e}return b(c.term,d.text,d)?e:null}return c}return b}),b.define("select2/compat/query",[],function(){function a(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."),a.call(this,b,c)}return a.prototype.query=function(a,b,c){b.callback=c;var d=this.options.get("query");d.call(null,b)},a}),b.define("select2/dropdown/attachContainer",[],function(){function a(a,b,c){a.call(this,b,c)}return a.prototype.position=function(a,b,c){var d=c.find(".dropdown-wrapper");d.append(b),b.addClass("select2-dropdown--below"),c.addClass("select2-container--below")},a}),b.define("select2/dropdown/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$dropdown.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("select2/selection/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$selection.on(d.join(" "),function(a){a.stopPropagation()})},a}),function(c){"function"==typeof b.define&&b.define.amd?b.define("jquery-mousewheel",["jquery"],c):"object"==typeof exports?module.exports=c:c(a)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
|
bnfw.php
CHANGED
@@ -1,1519 +1,1523 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
* Plugin
|
5 |
-
*
|
6 |
-
*
|
7 |
-
*
|
8 |
-
* Requires
|
9 |
-
*
|
10 |
-
* Author:
|
11 |
-
*
|
12 |
-
* License:
|
13 |
-
*
|
14 |
-
*
|
15 |
-
*
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
*
|
21 |
-
*
|
22 |
-
*
|
23 |
-
*
|
24 |
-
*
|
25 |
-
*
|
26 |
-
*
|
27 |
-
*
|
28 |
-
*
|
29 |
-
*
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
$
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: Better Notifications for WP
|
4 |
+
* Plugin URI: https://wordpress.org/plugins/bnfw/
|
5 |
+
* Description: Supercharge your WordPress notifications using a WYSIWYG editor and shortcodes. Default and new notifications available. Add more power with Add-ons.
|
6 |
+
* Version: 1.8.8
|
7 |
+
* Requires at least: 4.8
|
8 |
+
* Requires PHP: 7.0
|
9 |
+
* Author: Made with Fuel
|
10 |
+
* Author URI: https://madewithfuel.com/
|
11 |
+
* License: GPLv2 or later
|
12 |
+
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
13 |
+
* Text Domain: bnfw
|
14 |
+
* Domain Path: /languages
|
15 |
+
*
|
16 |
+
* @package bnfw
|
17 |
+
*/
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Copyright © 2022 Made with Fuel Ltd. (hello@betternotificationsforwp.com)
|
21 |
+
* This program is free software; you can redistribute it and/or modify
|
22 |
+
* it under the terms of the GNU General Public License, version 2, as
|
23 |
+
* published by the Free Software Foundation.
|
24 |
+
* This program is distributed in the hope that it will be useful,
|
25 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
26 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
27 |
+
* GNU General Public License for more details.
|
28 |
+
* You should have received a copy of the GNU General Public License
|
29 |
+
* along with this program; if not, write to the Free Software
|
30 |
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
31 |
+
*/
|
32 |
+
if ( ! class_exists( 'BNFW', false ) ) {
|
33 |
+
/**
|
34 |
+
* BNFW main class.
|
35 |
+
*/
|
36 |
+
class BNFW {
|
37 |
+
/**
|
38 |
+
* BNFW version.
|
39 |
+
*
|
40 |
+
* @var string
|
41 |
+
*/
|
42 |
+
public $bnfw_version = '1.8.8';
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Class Constructor.
|
46 |
+
*
|
47 |
+
* @since 1.0
|
48 |
+
*/
|
49 |
+
public function __construct() {
|
50 |
+
$this->bnfw_define_constants();
|
51 |
+
$this->load_textdomain();
|
52 |
+
$this->includes();
|
53 |
+
$this->hooks();
|
54 |
+
/**
|
55 |
+
* BNFW Notification.
|
56 |
+
*
|
57 |
+
* @var \BNFW_Notification
|
58 |
+
*/
|
59 |
+
$this->notifier = new BNFW_Notification();
|
60 |
+
|
61 |
+
/**
|
62 |
+
* BNFW Engine.
|
63 |
+
*
|
64 |
+
* @var \BNFW_Engine
|
65 |
+
*/
|
66 |
+
$this->engine = new BNFW_Engine();
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Factory method to return the instance of the class.
|
71 |
+
*
|
72 |
+
* Makes sure that only one instance is created.
|
73 |
+
*
|
74 |
+
* @return \BNFW Instance of the class.
|
75 |
+
*/
|
76 |
+
public static function factory() {
|
77 |
+
static $instance = false;
|
78 |
+
if ( ! $instance ) {
|
79 |
+
$instance = new self();
|
80 |
+
}
|
81 |
+
return $instance;
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Loads the plugin language files
|
86 |
+
*
|
87 |
+
* @since 1.0
|
88 |
+
*/
|
89 |
+
public function load_textdomain() {
|
90 |
+
// Load localization domain.
|
91 |
+
$this->translations = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
|
92 |
+
load_plugin_textdomain( 'bnfw', false, $this->translations );
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Include required files.
|
97 |
+
*
|
98 |
+
* @since 1.0
|
99 |
+
*/
|
100 |
+
public function includes() {
|
101 |
+
|
102 |
+
// Load license related classes.
|
103 |
+
if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
|
104 |
+
require_once 'includes/libraries/class-edd-sl-plugin-updater.php';
|
105 |
+
}
|
106 |
+
|
107 |
+
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
108 |
+
|
109 |
+
require_once 'vendor/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php';
|
110 |
+
|
111 |
+
require_once 'includes/license/class-bnfw-license.php';
|
112 |
+
require_once 'includes/license/class-bnfw-license-setting.php';
|
113 |
+
|
114 |
+
// Load Engine.
|
115 |
+
require_once 'includes/engine/class-bnfw-engine.php';
|
116 |
+
require_once 'includes/overrides.php';
|
117 |
+
|
118 |
+
// Load notification post type and notification helpers.
|
119 |
+
require_once 'includes/admin/class-bnfw-notification.php';
|
120 |
+
require_once 'includes/notification/post-notification.php';
|
121 |
+
|
122 |
+
// Helpers.
|
123 |
+
require_once 'includes/helpers/helpers.php';
|
124 |
+
require_once 'includes/helpers/class-bnfw-ajax.php';
|
125 |
+
|
126 |
+
// Load Admin Pages.
|
127 |
+
if ( is_admin() ) {
|
128 |
+
require_once 'includes/admin/class-bnfw-settings.php';
|
129 |
+
}
|
130 |
+
}
|
131 |
+
/**
|
132 |
+
* Define BNFW Constants.
|
133 |
+
*/
|
134 |
+
private function bnfw_define_constants() {
|
135 |
+
define( 'BNFW_VERSION', $this->bnfw_version );
|
136 |
+
}
|
137 |
+
/**
|
138 |
+
* Register Hooks.
|
139 |
+
*
|
140 |
+
* @since 1.0
|
141 |
+
*/
|
142 |
+
public function hooks() {
|
143 |
+
global $wp_version;
|
144 |
+
|
145 |
+
register_activation_hook( __FILE__, array( $this, 'activate' ) );
|
146 |
+
|
147 |
+
add_action( 'admin_init', array( 'PAnD', 'init' ) );
|
148 |
+
add_action( 'admin_init', array( $this, 'add_capability_to_admin' ) );
|
149 |
+
|
150 |
+
add_action( 'draft_to_private', array( $this, 'private_post' ) );
|
151 |
+
add_action( 'future_to_private', array( $this, 'private_post' ) );
|
152 |
+
add_action( 'pending_to_private', array( $this, 'private_post' ) );
|
153 |
+
add_action( 'publish_to_private', array( $this, 'private_post' ) );
|
154 |
+
|
155 |
+
add_action( 'wp_insert_post', array( $this, 'insert_post' ), 10, 3 );
|
156 |
+
|
157 |
+
add_action( 'publish_to_trash', array( $this, 'trash_post' ) );
|
158 |
+
|
159 |
+
add_action( 'auto-draft_to_publish', array( $this, 'publish_post' ) );
|
160 |
+
add_action( 'draft_to_publish', array( $this, 'publish_post' ) );
|
161 |
+
add_action( 'future_to_publish', array( $this, 'publish_post' ) );
|
162 |
+
add_action( 'pending_to_publish', array( $this, 'publish_post' ) );
|
163 |
+
add_action( 'private_to_publish', array( $this, 'publish_post' ) );
|
164 |
+
|
165 |
+
add_action( 'publish_to_publish', array( $this, 'update_post' ) );
|
166 |
+
add_action( 'private_to_private', array( $this, 'update_post' ) );
|
167 |
+
|
168 |
+
add_action( 'add_attachment', array( $this, 'new_publish_media_notification' ), 10, 1 );
|
169 |
+
add_action( 'edit_attachment', array( $this, 'media_attachment_data_update_notification' ), 10 );
|
170 |
+
|
171 |
+
add_action( 'transition_post_status', array( $this, 'on_post_transition' ), 10, 3 );
|
172 |
+
|
173 |
+
add_action( 'init', array( $this, 'custom_post_type_hooks' ), 100 );
|
174 |
+
add_action( 'create_term', array( $this, 'create_term' ), 10, 3 );
|
175 |
+
|
176 |
+
add_action( 'transition_comment_status', array( $this, 'on_comment_status_change' ), 10, 3 );
|
177 |
+
add_action( 'comment_post', array( $this, 'comment_post' ) );
|
178 |
+
add_action( 'trackback_post', array( $this, 'trackback_post' ) );
|
179 |
+
add_action( 'pingback_post', array( $this, 'pingback_post' ) );
|
180 |
+
|
181 |
+
add_action( 'user_register', array( $this, 'user_register' ) );
|
182 |
+
|
183 |
+
add_action( 'user_register', array( $this, 'welcome_email' ) );
|
184 |
+
|
185 |
+
if ( is_plugin_active( 'members/members.php' ) ) {
|
186 |
+
|
187 |
+
add_action( 'add_user_role', array( $this, 'user_role_added_from_member_plugin' ), 10, 2 );
|
188 |
+
add_action( 'remove_user_role', array( $this, 'user_role_removed_from_member_plugin' ), 10, 2 );
|
189 |
+
add_action( 'set_user_role', array( $this, 'user_role_changed' ), 10, 3 );
|
190 |
+
|
191 |
+
add_action( 'profile_update', array( $this, 'user_role_added' ), 10, 2 );
|
192 |
+
} else {
|
193 |
+
add_action( 'set_user_role', array( $this, 'user_role_changed' ), 10, 3 );
|
194 |
+
}
|
195 |
+
|
196 |
+
add_action( 'wp_login', array( $this, 'user_login' ), 10, 2 );
|
197 |
+
|
198 |
+
if ( version_compare( $wp_version, '4.4', '>=' ) ) {
|
199 |
+
add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ), 10, 3 );
|
200 |
+
} else {
|
201 |
+
add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ) );
|
202 |
+
}
|
203 |
+
add_action( 'lostpassword_post', array( $this, 'on_lost_password' ) );
|
204 |
+
add_filter( 'retrieve_password_message', array( $this, 'change_password_email_message' ), 10, 4 );
|
205 |
+
|
206 |
+
add_action( 'after_password_reset', array( $this, 'on_password_reset' ) );
|
207 |
+
|
208 |
+
add_filter( 'send_password_change_email', array( $this, 'should_password_changed_email_be_sent' ), 10, 3 );
|
209 |
+
add_filter( 'password_change_email', array( $this, 'on_password_changed' ), 10, 2 );
|
210 |
+
|
211 |
+
add_filter( 'send_email_change_email', array( $this, 'should_email_changed_email_be_sent' ), 10, 3 );
|
212 |
+
add_filter( 'email_change_email', array( $this, 'on_email_changed' ), 10, 3 );
|
213 |
+
add_filter( 'new_user_email_content', array( $this, 'on_email_changing' ), 10, 2 );
|
214 |
+
|
215 |
+
add_filter( 'auto_core_update_email', array( $this, 'on_core_updated' ), 10, 4 );
|
216 |
+
|
217 |
+
add_filter( 'user_request_action_email_content', array( $this, 'handle_user_request_email_content' ), 10, 2 );
|
218 |
+
add_filter( 'user_request_action_email_subject', array( $this, 'handle_user_request_email_subject' ), 10, 3 );
|
219 |
+
|
220 |
+
add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_user_confirmed_action_email_content' ), 10, 2 );
|
221 |
+
|
222 |
+
add_filter( 'wp_privacy_personal_data_email_content', array( $this, 'handle_data_export_email_content' ), 10, 3 );
|
223 |
+
|
224 |
+
add_filter( 'user_erasure_complete_email_subject', array( $this, 'handle_erasure_complete_email_subject' ), 10, 3 );
|
225 |
+
add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_erasure_complete_email_content' ), 10, 2 );
|
226 |
+
|
227 |
+
add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 4 );
|
228 |
+
add_action( 'shutdown', array( $this, 'on_shutdown' ) );
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Add 'bnfw' capability to admin.
|
233 |
+
*/
|
234 |
+
public function add_capability_to_admin() {
|
235 |
+
$admins = get_role( 'administrator' );
|
236 |
+
|
237 |
+
if ( is_null( $admins ) ) {
|
238 |
+
return;
|
239 |
+
}
|
240 |
+
|
241 |
+
if ( ! $admins->has_cap( 'bnfw' ) ) {
|
242 |
+
$admins->add_cap( 'bnfw' );
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* On post transition.
|
248 |
+
*
|
249 |
+
* @param string $new_status New post status.
|
250 |
+
* @param string $old_status Old post status.
|
251 |
+
* @param \WP_Post $post Post object.
|
252 |
+
*/
|
253 |
+
public function on_post_transition( $new_status, $old_status, $post ) {
|
254 |
+
if ( ! is_a( $post, 'WP_Post' ) ) {
|
255 |
+
return;
|
256 |
+
}
|
257 |
+
|
258 |
+
if ( 'pending' === $old_status ) {
|
259 |
+
return;
|
260 |
+
}
|
261 |
+
|
262 |
+
if ( 'pending' !== $new_status ) {
|
263 |
+
return;
|
264 |
+
}
|
265 |
+
|
266 |
+
$this->on_post_pending( $post->ID, $post );
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Setup hooks for custom post types.
|
271 |
+
*
|
272 |
+
* @since 1.2
|
273 |
+
*/
|
274 |
+
public function custom_post_type_hooks() {
|
275 |
+
$post_types = get_post_types( array( 'public' => true ), 'names' );
|
276 |
+
$post_types = array_diff( $post_types, array( BNFW_Notification::POST_TYPE ) );
|
277 |
+
|
278 |
+
foreach ( $post_types as $post_type ) {
|
279 |
+
add_action( 'future_' . $post_type, array( $this, 'on_post_scheduled' ), 10, 2 );
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Importer.
|
285 |
+
*/
|
286 |
+
public function activate() {
|
287 |
+
require_once dirname( __FILE__ ) . '/includes/class-bnfw-import.php';
|
288 |
+
$importer = new BNFW_Import();
|
289 |
+
$importer->import();
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Add 'Settings' link below BNFW in Plugins list.
|
294 |
+
*
|
295 |
+
* @since 1.0
|
296 |
+
* @param string[] $links An array of plugin action links. By default this can include 'activate',
|
297 |
+
* 'deactivate', and 'delete'. With Multisite active this can also include.
|
298 |
+
* @param string $file Path to the plugin file relative to the plugins directory.
|
299 |
+
* @return array plugin action links.
|
300 |
+
*/
|
301 |
+
public function plugin_action_links( $links, $file ) {
|
302 |
+
$plugin_file = 'bnfw/bnfw.php';
|
303 |
+
if ( $file === $plugin_file ) {
|
304 |
+
$settings_link = '<a href="' . esc_url( admin_url( 'edit.php?post_type=bnfw_notification&page=bnfw-settings' ) ) . '">' . esc_html__( 'Settings', 'bnfw' ) . '</a>';
|
305 |
+
array_unshift( $links, $settings_link );
|
306 |
+
}
|
307 |
+
return $links;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* When a new term is created.
|
312 |
+
*
|
313 |
+
* @since 1.0
|
314 |
+
* @param int $term_id Term ID.
|
315 |
+
* @param int $tt_id Term taxonomy ID.
|
316 |
+
* @param string $taxonomy Taxonomy slug.
|
317 |
+
*/
|
318 |
+
public function create_term( $term_id, $tt_id, $taxonomy ) {
|
319 |
+
$this->send_notification( 'newterm-' . $taxonomy, $term_id );
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Fires when a post is created for the first time.
|
324 |
+
*
|
325 |
+
* @param int $post_id Post ID.
|
326 |
+
* @param object $post Post object.
|
327 |
+
* @param bool $update Whether this is an existing post being updated or not.
|
328 |
+
*
|
329 |
+
* @since 1.3.1
|
330 |
+
*/
|
331 |
+
public function insert_post( $post_id, $post, $update ) {
|
332 |
+
// Some themes like P2, directly insert posts into DB.
|
333 |
+
$insert_post_themes = apply_filters( 'bnfw_insert_post_themes', array( 'P2', 'Syncope' ) );
|
334 |
+
$current_theme = wp_get_theme();
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Whether to trigger insert post hook.
|
338 |
+
*
|
339 |
+
* @since 1.4
|
340 |
+
*/
|
341 |
+
$trigger_insert_post = apply_filters( 'bnfw_trigger_insert_post', false, $post_id, $update );
|
342 |
+
|
343 |
+
if ( in_array( $current_theme->get( 'Name' ), $insert_post_themes, true ) || $trigger_insert_post ) {
|
344 |
+
$this->handle_inserted_post( $post_id, $update );
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Trigger New Post published notification for ACF forms.
|
350 |
+
*
|
351 |
+
* @param string $form ACF Form.
|
352 |
+
* @param int $post_id Post ID.
|
353 |
+
*/
|
354 |
+
public function acf_submit_form( $form, $post_id ) {
|
355 |
+
$this->handle_inserted_post( $post_id );
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Trigger correct notifications for inserted posts.
|
360 |
+
*
|
361 |
+
* @param int $post_id Post id.
|
362 |
+
* @param bool $update Whether the post was updated.
|
363 |
+
*
|
364 |
+
* @since 1.6.7
|
365 |
+
*/
|
366 |
+
private function handle_inserted_post( $post_id, $update ) {
|
367 |
+
$post = get_post( $post_id );
|
368 |
+
|
369 |
+
if ( ! is_a( $post, 'WP_Post' ) ) {
|
370 |
+
return;
|
371 |
+
}
|
372 |
+
|
373 |
+
switch ( $post->post_status ) {
|
374 |
+
case 'publish':
|
375 |
+
if ( $update ) {
|
376 |
+
$this->update_post( $post );
|
377 |
+
} else {
|
378 |
+
$this->publish_post( $post );
|
379 |
+
}
|
380 |
+
break;
|
381 |
+
|
382 |
+
case 'private':
|
383 |
+
$this->private_post( $post );
|
384 |
+
break;
|
385 |
+
|
386 |
+
case 'pending':
|
387 |
+
$this->on_post_pending( $post_id, $post );
|
388 |
+
break;
|
389 |
+
|
390 |
+
case 'future':
|
391 |
+
$this->on_post_scheduled( $post_id, $post );
|
392 |
+
break;
|
393 |
+
}
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Fires when a post is created for the first time.
|
398 |
+
*
|
399 |
+
* @since 1.0
|
400 |
+
* @param object $post Post Object.
|
401 |
+
*/
|
402 |
+
public function publish_post( $post ) {
|
403 |
+
$post_id = $post->ID;
|
404 |
+
$post_type = $post->post_type;
|
405 |
+
|
406 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type ) {
|
407 |
+
$this->send_notification_async( 'new-' . $post_type, $post_id );
|
408 |
+
}
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Fires when a private post is created.
|
413 |
+
*
|
414 |
+
* @since 1.6
|
415 |
+
* @param object $post Post Object.
|
416 |
+
*/
|
417 |
+
public function private_post( $post ) {
|
418 |
+
$post_id = $post->ID;
|
419 |
+
$post_type = $post->post_type;
|
420 |
+
|
421 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type ) {
|
422 |
+
$this->send_notification_async( 'private-' . $post_type, $post_id );
|
423 |
+
}
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Fires when a post is updated.
|
428 |
+
*
|
429 |
+
* @since 1.0
|
430 |
+
* @param WP_Post $post Post object.
|
431 |
+
*/
|
432 |
+
public function update_post( $post ) {
|
433 |
+
if ( $this->is_metabox_request() ) {
|
434 |
+
return;
|
435 |
+
}
|
436 |
+
|
437 |
+
$post_id = $post->ID;
|
438 |
+
$post_type = $post->post_type;
|
439 |
+
|
440 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type ) {
|
441 |
+
$this->send_notification_async( 'update-' . $post_type, $post_id );
|
442 |
+
}
|
443 |
+
}
|
444 |
+
|
445 |
+
/**
|
446 |
+
* Fires when a post is moved publish to trash.
|
447 |
+
*
|
448 |
+
* @param WP_Post $post Post object.
|
449 |
+
*/
|
450 |
+
public function trash_post( $post ) {
|
451 |
+
if ( $this->is_metabox_request() ) {
|
452 |
+
return;
|
453 |
+
}
|
454 |
+
$post_id = $post->ID;
|
455 |
+
$post_type = $post->post_type;
|
456 |
+
|
457 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type ) {
|
458 |
+
$this->send_notification_async( 'trash-' . $post_type, $post_id );
|
459 |
+
}
|
460 |
+
}
|
461 |
+
|
462 |
+
/**
|
463 |
+
* Fires when a post is pending for review.
|
464 |
+
*
|
465 |
+
* @since 1.1
|
466 |
+
* @param int $post_id Post ID.
|
467 |
+
* @param object $post Post object.
|
468 |
+
*/
|
469 |
+
public function on_post_pending( $post_id, $post ) {
|
470 |
+
if ( $this->is_metabox_request() ) {
|
471 |
+
return;
|
472 |
+
}
|
473 |
+
|
474 |
+
$post_type = $post->post_type;
|
475 |
+
|
476 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type ) {
|
477 |
+
$this->send_notification_async( 'pending-' . $post_type, $post_id );
|
478 |
+
}
|
479 |
+
}
|
480 |
+
|
481 |
+
/**
|
482 |
+
* On Media Published.
|
483 |
+
*
|
484 |
+
* @param int $post_id Attachment post id.
|
485 |
+
*/
|
486 |
+
public function new_publish_media_notification( $post_id ) {
|
487 |
+
$post_type = get_post_type( $post_id );
|
488 |
+
|
489 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type && 'attachment' === $post_type ) {
|
490 |
+
$this->send_notification_async( 'new-media', $post_id );
|
491 |
+
}
|
492 |
+
}
|
493 |
+
|
494 |
+
/**
|
495 |
+
* On Media Attachment Data Update.
|
496 |
+
*
|
497 |
+
* @param int $post_id Attachment post id.
|
498 |
+
*/
|
499 |
+
public function media_attachment_data_update_notification( $post_id ) {
|
500 |
+
$post_type = get_post_type( $post_id );
|
501 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type && 'attachment' === $post_type ) {
|
502 |
+
$this->send_notification_async( 'update-media', $post_id );
|
503 |
+
}
|
504 |
+
}
|
505 |
+
|
506 |
+
/**
|
507 |
+
* Fires when a post is scheduled.
|
508 |
+
*
|
509 |
+
* @since 1.1.5
|
510 |
+
* @param int $post_id Post ID.
|
511 |
+
* @param object $post Post object.
|
512 |
+
*/
|
513 |
+
public function on_post_scheduled( $post_id, $post ) {
|
514 |
+
// Rest request also triggers the same hook. We can ignore it.
|
515 |
+
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
|
516 |
+
return;
|
517 |
+
}
|
518 |
+
|
519 |
+
$post_type = $post->post_type;
|
520 |
+
|
521 |
+
if ( BNFW_Notification::POST_TYPE !== $post_type ) {
|
522 |
+
$this->send_notification_async( 'future-' . $post_type, $post_id );
|
523 |
+
}
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* When the status of a comment is changed.
|
528 |
+
*
|
529 |
+
* @param string $new_status New status.
|
530 |
+
* @param string $old_status Old status.
|
531 |
+
* @param \WP_Comment $comment Comment.
|
532 |
+
*/
|
533 |
+
public function on_comment_status_change( $new_status, $old_status, $comment ) {
|
534 |
+
if ( 'approved' !== $new_status ) {
|
535 |
+
return;
|
536 |
+
}
|
537 |
+
|
538 |
+
$post = get_post( $comment->comment_post_ID );
|
539 |
+
|
540 |
+
$notification_type = 'approve-' . $post->post_type . '-comment';
|
541 |
+
|
542 |
+
$this->send_notification( $notification_type, $comment->comment_ID, false );
|
543 |
+
|
544 |
+
// Send new comment notification after comment approve.
|
545 |
+
$notification_type = 'new-comment'; // old notification name.
|
546 |
+
|
547 |
+
if ( 'post' !== $post->post_type ) {
|
548 |
+
$notification_type = 'comment-' . $post->post_type;
|
549 |
+
}
|
550 |
+
|
551 |
+
$this->send_notification( $notification_type, $comment->comment_ID );
|
552 |
+
|
553 |
+
// Send comment reply notification after comment approve.
|
554 |
+
$this->comments_reply( $comment->comment_ID );
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Send notification for new comments
|
559 |
+
*
|
560 |
+
* @since 1.0
|
561 |
+
* @param int $comment_id The comment ID.
|
562 |
+
*/
|
563 |
+
public function comment_post( $comment_id ) {
|
564 |
+
$the_comment = get_comment( $comment_id );
|
565 |
+
$post = get_post( $the_comment->comment_post_ID );
|
566 |
+
|
567 |
+
if ( '1' !== $the_comment->comment_approved ) {
|
568 |
+
if ( $this->can_send_comment_notification( $the_comment ) ) {
|
569 |
+
$notification_type = 'moderate-' . $post->post_type . '-comment';
|
570 |
+
$this->send_notification( $notification_type, $comment_id );
|
571 |
+
}
|
572 |
+
} else {
|
573 |
+
$notification_type = 'new-comment'; // old notification name.
|
574 |
+
|
575 |
+
if ( 'post' !== $post->post_type ) {
|
576 |
+
$notification_type = 'comment-' . $post->post_type;
|
577 |
+
}
|
578 |
+
|
579 |
+
$this->send_notification( $notification_type, $comment_id );
|
580 |
+
|
581 |
+
// comment reply notification.
|
582 |
+
$this->comments_reply( $comment_id );
|
583 |
+
}
|
584 |
+
}
|
585 |
+
|
586 |
+
/**
|
587 |
+
* Send notification for comments reply
|
588 |
+
*
|
589 |
+
* @since 1.0
|
590 |
+
* @param int $comment_id The comment ID.
|
591 |
+
*/
|
592 |
+
public function comments_reply( $comment_id ) {
|
593 |
+
$the_comment = get_comment( $comment_id );
|
594 |
+
$post = get_post( $the_comment->comment_post_ID );
|
595 |
+
|
596 |
+
// comment reply notification.
|
597 |
+
if ( $this->can_send_comment_notification( $the_comment ) ) {
|
598 |
+
if ( $the_comment->comment_parent > 0 ) {
|
599 |
+
$notification_type = 'reply-comment'; // old notification name.
|
600 |
+
if ( 'post' !== $post->post_type ) {
|
601 |
+
$notification_type = 'commentreply-' . $post->post_type;
|
602 |
+
}
|
603 |
+
$notifications = $this->notifier->get_notifications( $notification_type );
|
604 |
+
if ( count( $notifications ) > 0 ) {
|
605 |
+
$parent = get_comment( $the_comment->comment_parent );
|
606 |
+
if ( $parent->comment_author_email !== $the_comment->comment_author_email ) {
|
607 |
+
foreach ( $notifications as $notification ) {
|
608 |
+
$this->engine->send_comment_reply_email( $this->notifier->read_settings( $notification->ID ), $the_comment, $parent );
|
609 |
+
}
|
610 |
+
}
|
611 |
+
}
|
612 |
+
}
|
613 |
+
}
|
614 |
+
}
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Send notification for new trackback.
|
618 |
+
*
|
619 |
+
* @since 1.0
|
620 |
+
* @param int $comment_id Trackback ID.
|
621 |
+
*/
|
622 |
+
public function trackback_post( $comment_id ) {
|
623 |
+
$the_comment = get_comment( $comment_id );
|
624 |
+
if ( $this->can_send_comment_notification( $the_comment ) ) {
|
625 |
+
$this->send_notification( 'new-trackback', $comment_id );
|
626 |
+
}
|
627 |
+
}
|
628 |
+
|
629 |
+
/**
|
630 |
+
* Send notification for new pingbacks
|
631 |
+
*
|
632 |
+
* @since 1.0
|
633 |
+
* @param int $comment_id Comment ID.
|
634 |
+
*/
|
635 |
+
public function pingback_post( $comment_id ) {
|
636 |
+
$the_comment = get_comment( $comment_id );
|
637 |
+
if ( $this->can_send_comment_notification( $the_comment ) ) {
|
638 |
+
$this->send_notification( 'new-pingback', $comment_id );
|
639 |
+
}
|
640 |
+
}
|
641 |
+
|
642 |
+
/**
|
643 |
+
* Send notification for lost password.
|
644 |
+
*
|
645 |
+
* @since 1.0
|
646 |
+
*/
|
647 |
+
public function on_lost_password() {
|
648 |
+
$user_login = sanitize_text_field( $_POST['user_login'] );// phpcs:ignore
|
649 |
+
$user = get_user_by( 'login', $user_login ) ?: get_user_by( 'email', $user_login );// phpcs:ignore
|
650 |
+
if ( $user ) {
|
651 |
+
$this->send_notification( 'admin-password', $user->ID );
|
652 |
+
}
|
653 |
+
}
|
654 |
+
|
655 |
+
/**
|
656 |
+
* Change the title of the password reset email that is sent to the user.
|
657 |
+
*
|
658 |
+
* @since 1.1
|
659 |
+
*
|
660 |
+
* @param string $title Email subject.
|
661 |
+
* @param string $user_login The username for the user.
|
662 |
+
* @param string $user_data WP_User object.
|
663 |
+
*
|
664 |
+
* @return string
|
665 |
+
*/
|
666 |
+
public function change_password_email_title( $title, $user_login = '', $user_data = '' ) {
|
667 |
+
$notifications = $this->notifier->get_notifications( 'user-password' );
|
668 |
+
if ( count( $notifications ) > 0 ) {
|
669 |
+
// Ideally there should be only one notification for this type.
|
670 |
+
// If there are multiple notification then we will read data about only the last one.
|
671 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
672 |
+
|
673 |
+
if ( '' === $user_data ) {
|
674 |
+
return $this->engine->handle_shortcodes( $setting['subject'], 'user-password', $user_data->ID );
|
675 |
+
} else {
|
676 |
+
return $this->engine->handle_shortcodes( $setting['subject'], 'user-password', $user_data->ID );
|
677 |
+
}
|
678 |
+
}
|
679 |
+
|
680 |
+
return $title;
|
681 |
+
}
|
682 |
+
|
683 |
+
/**
|
684 |
+
* Change the message of the password reset email.
|
685 |
+
*
|
686 |
+
* @since 1.1
|
687 |
+
*
|
688 |
+
* @param string $message Email message.
|
689 |
+
* @param string $key The activation key.
|
690 |
+
* @param string $user_login The username for the user.
|
691 |
+
* @param string $user_data WP_User object.
|
692 |
+
*
|
693 |
+
* @return string
|
694 |
+
*/
|
695 |
+
public function change_password_email_message( $message, $key, $user_login = '', $user_data = '' ) {
|
696 |
+
$notifications = $this->notifier->get_notifications( 'user-password' );
|
697 |
+
if ( count( $notifications ) > 0 ) {
|
698 |
+
// Ideally there should be only one notification for this type.
|
699 |
+
// If there are multiple notification then we will read data about only the last one.
|
700 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
701 |
+
|
702 |
+
$message = $this->engine->handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data );
|
703 |
+
|
704 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
705 |
+
add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
|
706 |
+
if ( 'true' !== $setting['disable-autop'] ) {
|
707 |
+
$message = wpautop( $message );
|
708 |
+
}
|
709 |
+
} else {
|
710 |
+
add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
|
711 |
+
if ( 'text' === $setting['email-formatting'] ) {
|
712 |
+
$message = wp_strip_all_tags( $message );
|
713 |
+
}
|
714 |
+
}
|
715 |
+
} else {
|
716 |
+
if ( $this->notifier->notification_exists( 'user-password', false ) ) {
|
717 |
+
// disabled notification exists, so disable the email by returning empty string.
|
718 |
+
return '';
|
719 |
+
}
|
720 |
+
}
|
721 |
+
|
722 |
+
return $message;
|
723 |
+
}
|
724 |
+
|
725 |
+
/**
|
726 |
+
* On Password reset.
|
727 |
+
*
|
728 |
+
* @param WP_User $user User who's password was changed.
|
729 |
+
*/
|
730 |
+
public function on_password_reset( $user ) {
|
731 |
+
$notifications = $this->notifier->get_notifications( 'password-changed' );
|
732 |
+
foreach ( $notifications as $notification ) {
|
733 |
+
$this->engine->send_password_changed_email( $this->notifier->read_settings( $notification->ID ), $user );
|
734 |
+
}
|
735 |
+
}
|
736 |
+
|
737 |
+
/**
|
738 |
+
* Should the password changed email be sent?
|
739 |
+
*
|
740 |
+
* @param bool $send Whether to send the email.
|
741 |
+
* @param array $user The original user array.
|
742 |
+
* @param array $userdata The updated user array.
|
743 |
+
*
|
744 |
+
* @return bool
|
745 |
+
*/
|
746 |
+
public function should_password_changed_email_be_sent( $send, $user, $userdata ) {
|
747 |
+
$bnfw = BNFW::factory();// phpcs:ignore
|
748 |
+
|
749 |
+
if ( ! $send ) {
|
750 |
+
return $send;
|
751 |
+
}
|
752 |
+
|
753 |
+
return ! $bnfw->notifier->is_notification_disabled( 'password-changed' );
|
754 |
+
}
|
755 |
+
|
756 |
+
/**
|
757 |
+
* On Password Changed.
|
758 |
+
*
|
759 |
+
* @since 1.6
|
760 |
+
*
|
761 |
+
* @param array $email_data Email Data.
|
762 |
+
* @param array $user User data.
|
763 |
+
*
|
764 |
+
* @return array Modified Email Data
|
765 |
+
*/
|
766 |
+
public function on_password_changed( $email_data, $user ) {
|
767 |
+
return $this->handle_filtered_data_notification( 'password-changed', $email_data, $user['ID'] );
|
768 |
+
}
|
769 |
+
|
770 |
+
/**
|
771 |
+
* Should the email changed email be sent?
|
772 |
+
*
|
773 |
+
* @param bool $send Whether to send the email.
|
774 |
+
* @param array $user_old_data The original user array.
|
775 |
+
* @param array $user_new_data The updated user array.
|
776 |
+
*
|
777 |
+
* @return bool
|
778 |
+
*/
|
779 |
+
public function should_email_changed_email_be_sent( $send, $user_old_data, $user_new_data ) {
|
780 |
+
$bnfw = BNFW::factory();// phpcs:ignore
|
781 |
+
|
782 |
+
if ( $bnfw->notifier->notification_exists( 'admin-email-changed', false ) ) {
|
783 |
+
$notifications = $bnfw->notifier->get_notifications( 'admin-email-changed' );
|
784 |
+
|
785 |
+
if ( count( $notifications ) > 0 ) {
|
786 |
+
// Ideally there should be only one notification for this type.
|
787 |
+
// If there are multiple notification then we will read data about only the last one.
|
788 |
+
$setting = $bnfw->notifier->read_settings( end( $notifications )->ID );
|
789 |
+
$notification_disabled = apply_filters( 'bnfw_notification_disabled', ( 'true' === $setting['disabled'] ), $id, $setting );
|
790 |
+
|
791 |
+
if ( ! $notification_disabled ) {
|
792 |
+
|
793 |
+
$setting['message'] = str_replace( '[user_old_email]', $user_old_data['user_email'], $setting['message'] );
|
794 |
+
$setting['message'] = str_replace( '[user_new_email]', $user_new_data['user_email'], $setting['message'] );
|
795 |
+
$bnfw->engine->send_notification( $setting, $user_old_data['ID'] );
|
796 |
+
}
|
797 |
+
}
|
798 |
+
}
|
799 |
+
|
800 |
+
if ( ! $send ) {
|
801 |
+
return $send;
|
802 |
+
}
|
803 |
+
|
804 |
+
return ! $bnfw->notifier->is_notification_disabled( 'email-changed' );
|
805 |
+
}
|
806 |
+
|
807 |
+
/**
|
808 |
+
* On Email Changed.
|
809 |
+
*
|
810 |
+
* @since 1.6
|
811 |
+
*
|
812 |
+
* @param array $email_data Email Data.
|
813 |
+
* @param array $user_old_data The original user array.
|
814 |
+
* @param array $user_new_data The updated user array.
|
815 |
+
*
|
816 |
+
* @return array Modified Email Data
|
817 |
+
*/
|
818 |
+
public function on_email_changed( $email_data, $user_old_data, $user_new_data ) {
|
819 |
+
|
820 |
+
$email = $this->handle_filtered_data_notification( 'email-changed', $email_data, $user_old_data['ID'] );
|
821 |
+
$email['message'] = str_replace( '[user_old_email]', $user_old_data['user_email'], $email['message'] );
|
822 |
+
$email['message'] = str_replace( '[user_new_email]', $user_new_data['user_email'], $email['message'] );
|
823 |
+
return $email;
|
824 |
+
}
|
825 |
+
/**
|
826 |
+
* Filters the text of the email sent when a change of user email address is attempted.
|
827 |
+
*
|
828 |
+
* @param string $email_text Text in the email.
|
829 |
+
* @param array $new_user_details {
|
830 |
+
* Data relating to the new user email address.
|
831 |
+
*
|
832 |
+
* @type string $hash The secure hash used in the confirmation link URL.
|
833 |
+
* @type string $newemail The proposed new email address.
|
834 |
+
* }
|
835 |
+
*/
|
836 |
+
public function on_email_changing( $email_text, $new_user_details ) {
|
837 |
+
$notification_name = 'email-changing';
|
838 |
+
|
839 |
+
$notifications = $this->notifier->get_notifications( $notification_name );
|
840 |
+
if ( count( $notifications ) > 0 ) {
|
841 |
+
// Ideally there should be only one notification for this type.
|
842 |
+
// If there are multiple notification then we will read data about only the last one.
|
843 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
844 |
+
|
845 |
+
$email_text = $this->engine->handle_shortcodes( $setting['message'], $setting['notification'], $new_user_details['newemail'] );
|
846 |
+
$email_text = $this->engine->handle_global_user_shortcodes( $email_text, $new_user_details['newemail'] );
|
847 |
+
$email_text = str_replace( '[email_change_confirmation_link]', esc_url( admin_url( 'profile.php?newuseremail=' . $new_user_details['hash'] ) ), $email_text );
|
848 |
+
}
|
849 |
+
|
850 |
+
return $email_text;
|
851 |
+
}
|
852 |
+
|
853 |
+
/**
|
854 |
+
* Send notification on core updated event.
|
855 |
+
*
|
856 |
+
* @since 1.6
|
857 |
+
*
|
858 |
+
* @param array $email_data Email Data.
|
859 |
+
* @param string $type The type of email being sent. Can be one of
|
860 |
+
* 'success', 'fail', 'manual', 'critical'.
|
861 |
+
* @param object $core_update The update offer that was attempted.
|
862 |
+
* @param mixed $result The result for the core update. Can be WP_Error.
|
863 |
+
*
|
864 |
+
* @return array Modified Email Data.
|
865 |
+
*/
|
866 |
+
public function on_core_updated( $email_data, $type, $core_update, $result ) {
|
867 |
+
$notifications = $this->notifier->get_notifications( 'core-updated' );
|
868 |
+
if ( count( $notifications ) > 0 ) {
|
869 |
+
// Ideally there should be only one notification for this type.
|
870 |
+
// If there are multiple notification then we will read data about only the last one.
|
871 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
872 |
+
|
873 |
+
$email_data = $this->engine->handle_core_updated_notification( $email_data, $setting, $type );
|
874 |
+
}
|
875 |
+
|
876 |
+
return $email_data;
|
877 |
+
}
|
878 |
+
|
879 |
+
/**
|
880 |
+
* Process User update notifications.
|
881 |
+
*
|
882 |
+
* @since 1.6
|
883 |
+
*
|
884 |
+
* @param string $notification_name Notification Name.
|
885 |
+
* @param array $email_data Email Data.
|
886 |
+
* @param string|int $extra_data User Id.
|
887 |
+
*
|
888 |
+
* @return array Modified Email Data.
|
889 |
+
*/
|
890 |
+
private function handle_filtered_data_notification( $notification_name,
|
891 |
+
$email_data, $extra_data ) {
|
892 |
+
$notifications = $this->notifier->get_notifications( $notification_name );
|
893 |
+
if ( count( $notifications ) > 0 ) {
|
894 |
+
// Ideally there should be only one notification for this type.
|
895 |
+
// If there are multiple notification then we will read data about only the last one.
|
896 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
897 |
+
|
898 |
+
$email_data = $this->engine->handle_filtered_data_notification( $email_data, $setting, $extra_data );
|
899 |
+
}
|
900 |
+
|
901 |
+
return $email_data;
|
902 |
+
}
|
903 |
+
|
904 |
+
/**
|
905 |
+
* Set the email formatting to HTML.
|
906 |
+
*
|
907 |
+
* @since 1.4
|
908 |
+
*/
|
909 |
+
public function set_html_content_type() {
|
910 |
+
return 'text/html';
|
911 |
+
}
|
912 |
+
|
913 |
+
/**
|
914 |
+
* Set the email formatting to text.
|
915 |
+
*
|
916 |
+
* @since 1.4
|
917 |
+
*/
|
918 |
+
public function set_text_content_type() {
|
919 |
+
return 'text/plain';
|
920 |
+
}
|
921 |
+
|
922 |
+
/**
|
923 |
+
* Send notification for new users.
|
924 |
+
*
|
925 |
+
* @since 1.0
|
926 |
+
* @param int $user_id User ID.
|
927 |
+
*/
|
928 |
+
public function user_register( $user_id ) {
|
929 |
+
$this->send_notification( 'admin-user', $user_id );
|
930 |
+
}
|
931 |
+
|
932 |
+
/**
|
933 |
+
* Send notification for user when user login.
|
934 |
+
*
|
935 |
+
* @since 1.0
|
936 |
+
* @param string $user_name Username.
|
937 |
+
* @param object $user_data User object.
|
938 |
+
*/
|
939 |
+
public function user_login( $user_name, $user_data ) {
|
940 |
+
$user_id = $user_data->ID;
|
941 |
+
$notifications = $this->notifier->get_notifications( 'user-login' );
|
942 |
+
|
943 |
+
foreach ( $notifications as $notification ) {
|
944 |
+
$this->engine->send_user_login_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
|
945 |
+
}
|
946 |
+
|
947 |
+
$this->user_login_admin_notification( $user_id );
|
948 |
+
}
|
949 |
+
|
950 |
+
/**
|
951 |
+
* Send notification for admin when user login.
|
952 |
+
*
|
953 |
+
* @since 1.0
|
954 |
+
* @param int $user_id User ID.
|
955 |
+
*/
|
956 |
+
public function user_login_admin_notification( $user_id ) {
|
957 |
+
$notifications = $this->notifier->get_notifications( 'admin-user-login' );
|
958 |
+
|
959 |
+
foreach ( $notifications as $notification ) {
|
960 |
+
$this->engine->send_user_login_email_for_admin( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
|
961 |
+
}
|
962 |
+
}
|
963 |
+
|
964 |
+
/**
|
965 |
+
* Send notification about new users to site admin.
|
966 |
+
*
|
967 |
+
* @since 1.7.1
|
968 |
+
*
|
969 |
+
* @param array $email_data Email details.
|
970 |
+
* @param WP_User $user User object.
|
971 |
+
* @param string $blogname Blog name.
|
972 |
+
*
|
973 |
+
* @return array Modified email details.
|
974 |
+
*/
|
975 |
+
public function handle_user_registered_admin_email( $email_data, $user, $blogname ) {
|
976 |
+
return $this->handle_filtered_data_notification( 'admin-user', $email_data, $user->ID );
|
977 |
+
}
|
978 |
+
|
979 |
+
/**
|
980 |
+
* New User - Post-registration Email
|
981 |
+
*
|
982 |
+
* @since 1.1
|
983 |
+
* @param int $user_id New user id.
|
984 |
+
*/
|
985 |
+
public function welcome_email( $user_id ) {
|
986 |
+
$notifications = $this->notifier->get_notifications( 'welcome-email' );
|
987 |
+
foreach ( $notifications as $notification ) {
|
988 |
+
$this->engine->send_registration_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
|
989 |
+
}
|
990 |
+
}
|
991 |
+
|
992 |
+
/**
|
993 |
+
* Send notification when a user role changes.
|
994 |
+
*
|
995 |
+
* @since 1.3.9
|
996 |
+
*
|
997 |
+
* @param int $user_id User ID.
|
998 |
+
* @param string $new_role New User role.
|
999 |
+
* @param array $old_roles Old User role.
|
1000 |
+
*/
|
1001 |
+
public function user_role_changed( $user_id, $new_role, $old_roles ) {
|
1002 |
+
if ( ! empty( $old_roles ) ) {
|
1003 |
+
$notifications = $this->notifier->get_notifications( 'user-role' );
|
1004 |
+
foreach ( $notifications as $notification ) {
|
1005 |
+
|
1006 |
+
/**
|
1007 |
+
* Trigger User Role Changed - For User notification.
|
1008 |
+
*
|
1009 |
+
* @since 1.6.5
|
1010 |
+
*/
|
1011 |
+
if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, $old_roles ) ) {
|
1012 |
+
$this->engine->send_user_role_changed_email( $this->notifier->read_settings( $notification->ID ), $user_id, $old_roles[0], $new_role );
|
1013 |
+
}
|
1014 |
+
}
|
1015 |
+
$notifications = $this->notifier->get_notifications( 'admin-role' );
|
1016 |
+
foreach ( $notifications as $notification ) {
|
1017 |
+
|
1018 |
+
/**
|
1019 |
+
* Trigger User Role Changed - For User notification.
|
1020 |
+
*
|
1021 |
+
* @since 1.6.5
|
1022 |
+
*/
|
1023 |
+
if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, $old_roles ) ) {
|
1024 |
+
$setting = $this->notifier->read_settings( $notification->ID );
|
1025 |
+
$setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], $old_roles[0], $new_role );
|
1026 |
+
$setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], $old_roles[0], $new_role );
|
1027 |
+
|
1028 |
+
$this->engine->send_notification( $setting, $user_id );
|
1029 |
+
}
|
1030 |
+
}
|
1031 |
+
}
|
1032 |
+
}
|
1033 |
+
|
1034 |
+
/**
|
1035 |
+
* Send notification when a user role added through Members Plugin.
|
1036 |
+
*
|
1037 |
+
* @since 1.8.4
|
1038 |
+
*
|
1039 |
+
* @param int $user_id User ID.
|
1040 |
+
* @param string $new_role New User role.
|
1041 |
+
*/
|
1042 |
+
public function user_role_added_from_member_plugin( $user_id, $new_role ) {
|
1043 |
+
|
1044 |
+
global $pagenow;
|
1045 |
+
|
1046 |
+
if ( 'users.php' !== $pagenow ) {
|
1047 |
+
return;
|
1048 |
+
}
|
1049 |
+
if ( ! $user_id ) {
|
1050 |
+
return;
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
$notifications = $this->notifier->get_notifications( 'user-role' );
|
1054 |
+
|
1055 |
+
foreach ( $notifications as $notification ) {
|
1056 |
+
if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, null ) ) {
|
1057 |
+
$this->engine->send_user_role_changed_email( $this->notifier->read_settings( $notification->ID ), $user_id, null, $new_role );
|
1058 |
+
}
|
1059 |
+
}
|
1060 |
+
|
1061 |
+
$notifications_admin = $this->notifier->get_notifications( 'admin-role' );
|
1062 |
+
foreach ( $notifications_admin as $notification ) {
|
1063 |
+
if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, null ) ) {
|
1064 |
+
$setting = $this->notifier->read_settings( $notification->ID );
|
1065 |
+
$setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], null, $new_role );
|
1066 |
+
$setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], null, $new_role );
|
1067 |
+
|
1068 |
+
$this->engine->send_notification( $setting, $user_id );
|
1069 |
+
}
|
1070 |
+
}
|
1071 |
+
|
1072 |
+
}
|
1073 |
+
|
1074 |
+
/**
|
1075 |
+
* Send notification when a user role removed through Members Plugin.
|
1076 |
+
*
|
1077 |
+
* @since 1.8.4
|
1078 |
+
*
|
1079 |
+
* @param int $user_id User ID.
|
1080 |
+
* @param string $old_role New User role.
|
1081 |
+
*/
|
1082 |
+
public function user_role_removed_from_member_plugin( $user_id, $old_role ) {
|
1083 |
+
global $pagenow;
|
1084 |
+
|
1085 |
+
if ( 'users.php' !== $pagenow ) {
|
1086 |
+
return;
|
1087 |
+
}
|
1088 |
+
if ( ! $user_id ) {
|
1089 |
+
return;
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
$notifications = $this->notifier->get_notifications( 'user-role' );
|
1093 |
+
|
1094 |
+
foreach ( $notifications as $notification ) {
|
1095 |
+
if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, null, array( $old_role ) ) ) {
|
1096 |
+
$this->engine->send_user_role_changed_email( $this->notifier->read_settings( $notification->ID ), $user_id, $old_role, null );
|
1097 |
+
}
|
1098 |
+
}
|
1099 |
+
|
1100 |
+
$notifications_admin = $this->notifier->get_notifications( 'admin-role' );
|
1101 |
+
foreach ( $notifications_admin as $notification ) {
|
1102 |
+
if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, null, array( $old_role ) ) ) {
|
1103 |
+
$setting = $this->notifier->read_settings( $notification->ID );
|
1104 |
+
$setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], $old_role, null );
|
1105 |
+
$setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], $old_role, null );
|
1106 |
+
|
1107 |
+
$this->engine->send_notification( $setting, $user_id );
|
1108 |
+
}
|
1109 |
+
}
|
1110 |
+
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
/**
|
1114 |
+
* Send notification when a user role added support User Role Editor by Members Plugin.
|
1115 |
+
*
|
1116 |
+
* @since 1.3.9
|
1117 |
+
*
|
1118 |
+
* @param int $user_id User ID.
|
1119 |
+
* @param array $old_user_data Old User role.
|
1120 |
+
*/
|
1121 |
+
public function user_role_added( $user_id, $old_user_data ) {
|
1122 |
+
|
1123 |
+
if ( isset( $_POST['members_user_roles'] ) && ! empty( $_POST['members_user_roles'] ) ) {// phpcs:ignore
|
1124 |
+
// Get the current user roles.
|
1125 |
+
$old_roles = (array) $old_user_data->roles;
|
1126 |
+
|
1127 |
+
// Sanitize the posted roles.
|
1128 |
+
$new_roles = array_map( array( $this, 'bnfw_members_sanitize_role' ), $_POST['members_user_roles'] );// phpcs:ignore
|
1129 |
+
|
1130 |
+
sort( $old_roles );
|
1131 |
+
sort( $new_roles );
|
1132 |
+
$old_roles_str = implode( '', $old_roles );
|
1133 |
+
$new_roles_str = implode( '', $new_roles );
|
1134 |
+
if ( ! empty( $old_roles ) && $old_roles_str !== $new_roles_str ) {
|
1135 |
+
$notifications = $this->notifier->get_notifications( 'user-role' );
|
1136 |
+
foreach ( $notifications as $notification ) {
|
1137 |
+
|
1138 |
+
/**
|
1139 |
+
* Trigger User Role Changed - For User notification.
|
1140 |
+
*
|
1141 |
+
* @since 1.6.5
|
1142 |
+
*/
|
1143 |
+
if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
|
1144 |
+
$this->engine->send_user_role_added_email( $this->notifier->read_settings( $notification->ID ), $user_id, $old_roles, $new_roles );
|
1145 |
+
}
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
$notifications = $this->notifier->get_notifications( 'admin-role' );
|
1149 |
+
foreach ( $notifications as $notification ) {
|
1150 |
+
|
1151 |
+
/**
|
1152 |
+
* Trigger User Role Changed - For User notification.
|
1153 |
+
*
|
1154 |
+
* @since 1.6.5
|
1155 |
+
*/
|
1156 |
+
if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
|
1157 |
+
$setting = $this->notifier->read_settings( $notification->ID );
|
1158 |
+
$setting['message'] = $this->engine->handle_user_added_role_shortcodes( $setting['message'], $old_roles, $new_roles );
|
1159 |
+
$setting['subject'] = $this->engine->handle_user_added_role_shortcodes( $setting['subject'], $old_roles, $new_roles );
|
1160 |
+
|
1161 |
+
$this->engine->send_notification( $setting, $user_id );
|
1162 |
+
}
|
1163 |
+
}
|
1164 |
+
}
|
1165 |
+
}
|
1166 |
+
}
|
1167 |
+
|
1168 |
+
/**
|
1169 |
+
* Sanitizes a role name. This is a wrapper for the `sanitize_key()` WordPress function. Only
|
1170 |
+
* alphanumeric characters and underscores are allowed. Hyphens are also replaced with underscores.
|
1171 |
+
*
|
1172 |
+
* @since 1.0.0
|
1173 |
+
* @access public
|
1174 |
+
* @param array $role Posted user role.
|
1175 |
+
* @return int
|
1176 |
+
*/
|
1177 |
+
public function bnfw_members_sanitize_role( $role ) {
|
1178 |
+
|
1179 |
+
$_role = strtolower( $role );
|
1180 |
+
$_role = preg_replace( '/[^a-z0-9_\-\s]/', '', $_role );
|
1181 |
+
|
1182 |
+
return apply_filters( array( $this, 'bnfw_members_sanitize_role' ), str_replace( ' ', '_', $_role ), $role );
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
/**
|
1186 |
+
* Send notification based on type and ref id.
|
1187 |
+
*
|
1188 |
+
* @since 1.0
|
1189 |
+
* @param string $type Notification type.
|
1190 |
+
* @param mixed $ref_id Reference data.
|
1191 |
+
* @param bool $include_disabled Include disabled.
|
1192 |
+
*/
|
1193 |
+
public function send_notification( $type, $ref_id, $include_disabled = true ) {
|
1194 |
+
$notifications = $this->notifier->get_notifications( $type, $include_disabled );
|
1195 |
+
foreach ( $notifications as $notification ) {
|
1196 |
+
$this->engine->send_notification( $this->notifier->read_settings( $notification->ID ), $ref_id );
|
1197 |
+
}
|
1198 |
+
}
|
1199 |
+
|
1200 |
+
/**
|
1201 |
+
* Send notification async based on type and ref id.
|
1202 |
+
*
|
1203 |
+
* @param string $type Notification type.
|
1204 |
+
* @param mixed $ref_id Reference data.
|
1205 |
+
*/
|
1206 |
+
public function send_notification_async( $type, $ref_id ) {
|
1207 |
+
$notifications = $this->notifier->get_notifications( $type, false );
|
1208 |
+
foreach ( $notifications as $notification ) {
|
1209 |
+
$transient = get_transient( 'bnfw-async-notifications' );
|
1210 |
+
if ( ! is_array( $transient ) ) {
|
1211 |
+
$transient = array();
|
1212 |
+
}
|
1213 |
+
|
1214 |
+
$notification_data = array(
|
1215 |
+
'ref_id' => $ref_id,
|
1216 |
+
'notification_id' => $notification->ID,
|
1217 |
+
'notification_type' => $type,
|
1218 |
+
);
|
1219 |
+
|
1220 |
+
if ( ! in_array( $notification_data, $transient, true ) ) {
|
1221 |
+
$transient[] = $notification_data;
|
1222 |
+
set_transient( 'bnfw-async-notifications', $transient, 600 );
|
1223 |
+
}
|
1224 |
+
}
|
1225 |
+
}
|
1226 |
+
|
1227 |
+
/**
|
1228 |
+
* Can send comment notification or not.
|
1229 |
+
*
|
1230 |
+
* @since 1.0
|
1231 |
+
* @param WP_Comment $comment Comment data.
|
1232 |
+
* @return bool
|
1233 |
+
*/
|
1234 |
+
private function can_send_comment_notification( $comment ) {
|
1235 |
+
// Returns false if the comment is marked as spam AND admin has enabled suppression of spam.
|
1236 |
+
$suppress_spam = get_option( 'bnfw_suppress_spam' );
|
1237 |
+
if ( '1' === $suppress_spam && ( 0 === strcmp( $comment->comment_approved, 'spam' ) ) ) {
|
1238 |
+
return false;
|
1239 |
+
}
|
1240 |
+
return true;
|
1241 |
+
}
|
1242 |
+
|
1243 |
+
/**
|
1244 |
+
* Handle user request email content.
|
1245 |
+
*
|
1246 |
+
* @param string $content Content.
|
1247 |
+
* @param array $email_data Email data.
|
1248 |
+
*
|
1249 |
+
* @return string Modified content.
|
1250 |
+
*/
|
1251 |
+
public function handle_user_request_email_content( $content, $email_data ) {
|
1252 |
+
$field = 'message';
|
1253 |
+
$new_content = '';
|
1254 |
+
|
1255 |
+
switch ( $email_data['description'] ) {
|
1256 |
+
case 'Export Personal Data':
|
1257 |
+
$notification_name = 'ca-export-data';
|
1258 |
+
$new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
|
1259 |
+
break;
|
1260 |
+
case 'Erase Personal Data':
|
1261 |
+
$notification_name = 'ca-erase-data';
|
1262 |
+
$new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
|
1263 |
+
break;
|
1264 |
+
}
|
1265 |
+
|
1266 |
+
if ( ! empty( $new_content ) ) {
|
1267 |
+
return $new_content;
|
1268 |
+
} else {
|
1269 |
+
return $content;
|
1270 |
+
}
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
/**
|
1274 |
+
* Handle user request email subject.
|
1275 |
+
*
|
1276 |
+
* @param string $subject Subject.
|
1277 |
+
* @param string $blogname Blog name.
|
1278 |
+
* @param array $email_data Email data.
|
1279 |
+
*
|
1280 |
+
* @return string Modified subject.
|
1281 |
+
*/
|
1282 |
+
public function handle_user_request_email_subject( $subject, $blogname, $email_data ) {
|
1283 |
+
$field = 'subject';
|
1284 |
+
$new_subject = '';
|
1285 |
+
|
1286 |
+
switch ( $email_data['description'] ) {
|
1287 |
+
case 'Export Personal Data':
|
1288 |
+
$notification_name = 'ca-export-data';
|
1289 |
+
$new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
|
1290 |
+
break;
|
1291 |
+
case 'Erase Personal Data':
|
1292 |
+
$notification_name = 'ca-erase-data';
|
1293 |
+
$new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
|
1294 |
+
break;
|
1295 |
+
}
|
1296 |
+
if ( ! empty( $new_subject ) ) {
|
1297 |
+
return $new_subject;
|
1298 |
+
} else {
|
1299 |
+
return $subject;
|
1300 |
+
}
|
1301 |
+
}
|
1302 |
+
|
1303 |
+
/**
|
1304 |
+
* Handle user confirmed action email content.
|
1305 |
+
*
|
1306 |
+
* @param string $content Content.
|
1307 |
+
* @param array $email_data Email data.
|
1308 |
+
*
|
1309 |
+
* @return string Modified content.
|
1310 |
+
*/
|
1311 |
+
public function handle_user_confirmed_action_email_content( $content, $email_data ) {
|
1312 |
+
$field = 'message';
|
1313 |
+
$new_content = '';
|
1314 |
+
|
1315 |
+
switch ( $email_data['description'] ) {
|
1316 |
+
case 'Export Personal Data':
|
1317 |
+
$notification_name = 'uc-export-data';
|
1318 |
+
$new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
|
1319 |
+
break;
|
1320 |
+
case 'Erase Personal Data':
|
1321 |
+
$notification_name = 'uc-erase-data';
|
1322 |
+
$new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
|
1323 |
+
break;
|
1324 |
+
}
|
1325 |
+
|
1326 |
+
if ( ! empty( $new_content ) ) {
|
1327 |
+
return $new_content;
|
1328 |
+
} else {
|
1329 |
+
return $content;
|
1330 |
+
}
|
1331 |
+
}
|
1332 |
+
|
1333 |
+
/**
|
1334 |
+
* Handle data exported email content.
|
1335 |
+
*
|
1336 |
+
* @param string $content Text in the email.
|
1337 |
+
* @param int $request_id The request ID for this personal data export.
|
1338 |
+
* @param array $email_data Data relating to the account action email.
|
1339 |
+
*
|
1340 |
+
* @return string Modified content.
|
1341 |
+
*/
|
1342 |
+
public function handle_data_export_email_content( $content, $request_id, $email_data ) {
|
1343 |
+
|
1344 |
+
$field = 'message';
|
1345 |
+
$notification_name = 'data-export';
|
1346 |
+
$new_content = '';
|
1347 |
+
|
1348 |
+
$notifications = $this->notifier->get_notifications( $notification_name );
|
1349 |
+
if ( count( $notifications ) > 0 ) {
|
1350 |
+
// Ideally there should be only one notification for this type.
|
1351 |
+
// If there are multiple notification then we will read data about only the last one.
|
1352 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
1353 |
+
|
1354 |
+
$new_content = $this->engine->handle_data_export_email_shortcodes( $setting[ $field ], $setting, $request_id );
|
1355 |
+
$new_content = $this->engine->handle_global_user_shortcodes( $new_content, $email_data['message_recipient'] );
|
1356 |
+
}
|
1357 |
+
|
1358 |
+
if ( ! empty( $new_content ) ) {
|
1359 |
+
return $new_content;
|
1360 |
+
} else {
|
1361 |
+
return $content;
|
1362 |
+
}
|
1363 |
+
}
|
1364 |
+
/**
|
1365 |
+
* Filters the subject of the email sent when an erasure request is completed.
|
1366 |
+
*
|
1367 |
+
* @param string $subject The email subject.
|
1368 |
+
* @param string $sitename The name of the site.
|
1369 |
+
* @param array $email_data Data relating to the account action email.
|
1370 |
+
*/
|
1371 |
+
public function handle_erasure_complete_email_subject( $subject, $sitename, $email_data ) {
|
1372 |
+
return $this->handle_erasure_complete_email_notification( 'subject', $subject, $email_data );
|
1373 |
+
}
|
1374 |
+
/**
|
1375 |
+
* Filters the body of the data erasure fulfillment notification.
|
1376 |
+
*
|
1377 |
+
* @param string $content The email content.
|
1378 |
+
* @param array $email_data Data relating to the account action email.
|
1379 |
+
*/
|
1380 |
+
public function handle_erasure_complete_email_content( $content, $email_data ) {
|
1381 |
+
if ( isset( $email_data['privacy_policy_url'] ) ) {
|
1382 |
+
return $this->handle_erasure_complete_email_notification( 'message', $content, $email_data );
|
1383 |
+
}
|
1384 |
+
|
1385 |
+
return $content;
|
1386 |
+
}
|
1387 |
+
/**
|
1388 |
+
* Handles erasure fulfillment notification.
|
1389 |
+
*
|
1390 |
+
* @param string $field Field name.
|
1391 |
+
* @param string $content The email content.
|
1392 |
+
* @param array $email_data Data relating to the account action email.
|
1393 |
+
*/
|
1394 |
+
protected function handle_erasure_complete_email_notification( $field, $content, $email_data ) {
|
1395 |
+
$notification_name = 'data-erased';
|
1396 |
+
$new_content = '';
|
1397 |
+
$notifications = $this->notifier->get_notifications( $notification_name );
|
1398 |
+
if ( count( $notifications ) > 0 ) {
|
1399 |
+
// Ideally there should be only one notification for this type.
|
1400 |
+
// If there are multiple notification then we will read data about only the last one.
|
1401 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
1402 |
+
$new_content = $this->engine->handle_shortcodes( $setting[ $field ], $notification_name, $email_data );
|
1403 |
+
}
|
1404 |
+
if ( ! empty( $new_content ) ) {
|
1405 |
+
return $new_content;
|
1406 |
+
} else {
|
1407 |
+
return $content;
|
1408 |
+
}
|
1409 |
+
}
|
1410 |
+
|
1411 |
+
/**
|
1412 |
+
* Send notification emails on shutdown.
|
1413 |
+
*/
|
1414 |
+
public function on_shutdown() {
|
1415 |
+
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
1416 |
+
return;
|
1417 |
+
}
|
1418 |
+
|
1419 |
+
$transient = get_transient( 'bnfw-async-notifications' );
|
1420 |
+
if ( is_array( $transient ) ) {
|
1421 |
+
delete_transient( 'bnfw-async-notifications' );
|
1422 |
+
foreach ( $transient as $id_pairs ) {
|
1423 |
+
$this->engine->send_notification( $this->notifier->read_settings( $id_pairs['notification_id'] ), $id_pairs['ref_id'] );
|
1424 |
+
}
|
1425 |
+
}
|
1426 |
+
}
|
1427 |
+
|
1428 |
+
/**
|
1429 |
+
* Handle user request notification.
|
1430 |
+
*
|
1431 |
+
* @param string $notification_name Notification name.
|
1432 |
+
* @param string $field Field name.
|
1433 |
+
* @param array $email_data Email data.
|
1434 |
+
*
|
1435 |
+
* @return string Content.
|
1436 |
+
*/
|
1437 |
+
protected function handle_user_request_notification( $notification_name, $field, $email_data ) {
|
1438 |
+
$notifications = $this->notifier->get_notifications( $notification_name );
|
1439 |
+
if ( count( $notifications ) > 0 ) {
|
1440 |
+
// Ideally there should be only one notification for this type.
|
1441 |
+
// If there are multiple notification then we will read data about only the last one.
|
1442 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
1443 |
+
|
1444 |
+
return $this->engine->handle_user_request_email_shortcodes( $setting[ $field ], $setting, $email_data );
|
1445 |
+
}
|
1446 |
+
|
1447 |
+
return '';
|
1448 |
+
}
|
1449 |
+
|
1450 |
+
/**
|
1451 |
+
* Handle user confirmed action notification.
|
1452 |
+
*
|
1453 |
+
* @param string $notification_name Notification name.
|
1454 |
+
* @param string $field Field name.
|
1455 |
+
* @param array $email_data Email data.
|
1456 |
+
*
|
1457 |
+
* @return string Content.
|
1458 |
+
*/
|
1459 |
+
protected function handle_user_confirmed_action_notification( $notification_name, $field, $email_data ) {
|
1460 |
+
$notifications = $this->notifier->get_notifications( $notification_name );
|
1461 |
+
if ( count( $notifications ) > 0 ) {
|
1462 |
+
// Ideally there should be only one notification for this type.
|
1463 |
+
// If there are multiple notification then we will read data about only the last one.
|
1464 |
+
$setting = $this->notifier->read_settings( end( $notifications )->ID );
|
1465 |
+
|
1466 |
+
return $this->engine->handle_user_confirmed_action_email_shortcodes( $setting[ $field ], $setting, $email_data );
|
1467 |
+
}
|
1468 |
+
|
1469 |
+
return '';
|
1470 |
+
}
|
1471 |
+
|
1472 |
+
/**
|
1473 |
+
* Is this a metabox request?
|
1474 |
+
*
|
1475 |
+
* Block editor sends duplicate requests on post update.
|
1476 |
+
*
|
1477 |
+
* @return bool True if metabox request, False otherwise.
|
1478 |
+
*/
|
1479 |
+
protected function is_metabox_request() {
|
1480 |
+
return ( isset( $_GET['meta-box-loader'] ) || isset( $_GET['meta_box'] ) );// phpcs:ignore
|
1481 |
+
}
|
1482 |
+
|
1483 |
+
/**
|
1484 |
+
* Check if Gutenberg is active.
|
1485 |
+
*
|
1486 |
+
* @return bool
|
1487 |
+
* @since 1.3
|
1488 |
+
*/
|
1489 |
+
public function is_gutenberg_active() {
|
1490 |
+
$gutenberg = false;
|
1491 |
+
$block_editor = false;
|
1492 |
+
|
1493 |
+
if ( has_filter( 'replace_editor', 'gutenberg_init' ) ) {
|
1494 |
+
// Gutenberg is installed and activated.
|
1495 |
+
$gutenberg = true;
|
1496 |
+
}
|
1497 |
+
|
1498 |
+
if ( version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ) ) {
|
1499 |
+
// Block editor.
|
1500 |
+
$block_editor = true;
|
1501 |
+
}
|
1502 |
+
|
1503 |
+
if ( ! $gutenberg && ! $block_editor ) {
|
1504 |
+
return false;
|
1505 |
+
}
|
1506 |
+
|
1507 |
+
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
1508 |
+
|
1509 |
+
if ( ! is_plugin_active( 'classic-editor/classic-editor.php' ) ) {
|
1510 |
+
return true;
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
$use_block_editor = ( get_option( 'classic-editor-replace' ) === 'no-replace' );
|
1514 |
+
|
1515 |
+
return $use_block_editor;
|
1516 |
+
}
|
1517 |
+
|
1518 |
+
}
|
1519 |
+
/**
|
1520 |
+
* Fire up the plugin.
|
1521 |
+
*/
|
1522 |
+
BNFW::factory();
|
1523 |
+
}
|
includes/admin/bnfw-settings.php
DELETED
@@ -1,287 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Register the Admin pages and load the scripts action
|
4 |
-
*/
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Sub-menu pages
|
8 |
-
*/
|
9 |
-
function bnfw_admin_menu() {
|
10 |
-
|
11 |
-
// New Notifications Sub-menu
|
12 |
-
add_submenu_page(
|
13 |
-
'edit.php?post_type=bnfw_notification',
|
14 |
-
esc_html__( 'Notification Settings', 'bnfw' ),
|
15 |
-
esc_html__( 'Settings', 'bnfw' ),
|
16 |
-
'bnfw',
|
17 |
-
'bnfw-settings',
|
18 |
-
'bnfw_settings_page'
|
19 |
-
);
|
20 |
-
}
|
21 |
-
|
22 |
-
// Add the Admin pages to the WordPress menu
|
23 |
-
add_action( 'admin_menu', 'bnfw_admin_menu' );
|
24 |
-
add_action( 'admin_menu', 'bnfw_menu_item_links', 12 );
|
25 |
-
add_action( 'admin_head', 'bnfw_menu_item_link_targets' );
|
26 |
-
|
27 |
-
/* ------------------------------------------------------------------------ *
|
28 |
-
* Menu Pages
|
29 |
-
* ------------------------------------------------------------------------ */
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Settings Page
|
33 |
-
*/
|
34 |
-
function bnfw_settings_page() {
|
35 |
-
ob_start(); ?>
|
36 |
-
|
37 |
-
<div class="wrap">
|
38 |
-
<h2><?php esc_html_e( 'BNFW Settings', 'bnfw' ); ?></h2>
|
39 |
-
|
40 |
-
<form method="post" action="options.php" class="bnfw-form">
|
41 |
-
<?php
|
42 |
-
settings_errors();
|
43 |
-
settings_fields( 'bnfw-settings' );
|
44 |
-
do_settings_sections( 'bnfw-settings' );
|
45 |
-
|
46 |
-
submit_button( __( 'Save Settings', 'bnfw' ) );
|
47 |
-
?>
|
48 |
-
</form>
|
49 |
-
</div>
|
50 |
-
|
51 |
-
<?php echo ob_get_clean();
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* External Menu Item Links
|
56 |
-
*/
|
57 |
-
function bnfw_menu_item_links() {
|
58 |
-
global $submenu;
|
59 |
-
|
60 |
-
if ( current_user_can( 'bnfw' ) ) {
|
61 |
-
$doc_url = 'https://betternotificationsforwp.com/documentation/';
|
62 |
-
$store_url = 'https://betternotificationsforwp.com/downloads/';
|
63 |
-
$support_url = 'https://betternotificationsforwp.com/priority-support/';
|
64 |
-
|
65 |
-
if ( bnfw_is_tracking_allowed() ) {
|
66 |
-
$doc_url .= '?utm_source=WP%20Admin%20Submenu%20Item%20-%20"Documentation"&utm_medium=referral';
|
67 |
-
$store_url .= '?utm_source=WP%20Admin%20Submenu%20Item%20-%20"Add-on"&utm_medium=referral';
|
68 |
-
$support_url .= '?utm_source=WP%20Admin%20Submenu%20Item%20-%20"Priority%20Support"&utm_medium=referral';
|
69 |
-
}
|
70 |
-
|
71 |
-
// Documentation Link
|
72 |
-
$submenu['edit.php?post_type=bnfw_notification'][500] = array(
|
73 |
-
'<div id="bnfw-menu-item-documentation" style="color: #73daeb;">' . __( 'Documentation', 'bnfw' ) . '</div>',
|
74 |
-
'bnfw',
|
75 |
-
$doc_url,
|
76 |
-
);
|
77 |
-
|
78 |
-
// Add-ons Link
|
79 |
-
$submenu['edit.php?post_type=bnfw_notification'][600] = array(
|
80 |
-
'<div id="bnfw-menu-item-addons" style="color: #ff6f59;">' . __( 'Premium Add-ons', 'bnfw' ) . '</div>',
|
81 |
-
'bnfw',
|
82 |
-
$store_url,
|
83 |
-
);
|
84 |
-
|
85 |
-
// Add-ons Link
|
86 |
-
$submenu['edit.php?post_type=bnfw_notification'][700] = array(
|
87 |
-
'<div id="bnfw-menu-item-support" style="color: #f00001;">' . __( 'Priority Support', 'bnfw' ) . '</div>',
|
88 |
-
'bnfw',
|
89 |
-
$support_url,
|
90 |
-
);
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
-
function bnfw_menu_item_link_targets() {
|
95 |
-
?>
|
96 |
-
<script type="text/javascript">
|
97 |
-
jQuery( document ).ready( function ( $ ) {
|
98 |
-
// Documentation Link
|
99 |
-
$( '#bnfw-menu-item-documentation' ).parent().attr( 'target', '_blank' );
|
100 |
-
$( '#bnfw-menu-item-documentation' ).hover( function () {
|
101 |
-
$( this ).css( 'color', '#a0e6f1' );
|
102 |
-
}, function () {
|
103 |
-
$( this ).css( 'color', '#73daeb' );
|
104 |
-
} );
|
105 |
-
|
106 |
-
// Add-ons Link
|
107 |
-
$( '#bnfw-menu-item-addons' ).parent().attr( 'target', '_blank' );
|
108 |
-
$( '#bnfw-menu-item-addons' ).hover( function () {
|
109 |
-
$( this ).css( 'color', '#ff9b8c' );
|
110 |
-
}, function () {
|
111 |
-
$( this ).css( 'color', '#ff6f59' );
|
112 |
-
} );
|
113 |
-
|
114 |
-
// Priority Support Link
|
115 |
-
$( '#bnfw-menu-item-support' ).parent().attr( 'target', '_blank' );
|
116 |
-
$( '#bnfw-menu-item-support' ).hover( function () {
|
117 |
-
$( this ).css( 'color', '#ff3536' );
|
118 |
-
}, function () {
|
119 |
-
$( this ).css( 'color', '#f00001' );
|
120 |
-
} );
|
121 |
-
} );
|
122 |
-
</script>
|
123 |
-
<?php }
|
124 |
-
|
125 |
-
/* ------------------------------------------------------------------------ *
|
126 |
-
* Settings Page - Setting Registration
|
127 |
-
* ------------------------------------------------------------------------ */
|
128 |
-
|
129 |
-
/**
|
130 |
-
*
|
131 |
-
*/
|
132 |
-
function bnfw_general_options() {
|
133 |
-
// Set-up - General Options Section
|
134 |
-
add_settings_section(
|
135 |
-
'bnfw_general_options_section', // Section ID
|
136 |
-
'', // Title above settings section
|
137 |
-
'bnfw_general_options_callback', // Name of function that renders a description of the settings section
|
138 |
-
'bnfw-settings' // Page to show on
|
139 |
-
);
|
140 |
-
|
141 |
-
// Register - Suppress SPAM Checkbox
|
142 |
-
register_setting(
|
143 |
-
'bnfw-settings',
|
144 |
-
'bnfw_suppress_spam'
|
145 |
-
);
|
146 |
-
|
147 |
-
// Suppress notifications for SPAM comments
|
148 |
-
add_settings_field(
|
149 |
-
'bnfw_suppress_spam', // Field ID
|
150 |
-
esc_html__( 'Suppress SPAM comment notification', 'bnfw' ) . '<div class="bnfw-help-tip"><p>' . esc_html__( 'Comments that are correctly marked as SPAM by a 3rd party plugin (such as Akismet) will not generate a notification if this is ticked.', 'bnfw' ) . '</p></div>', // Label to the left
|
151 |
-
'bnfw_suppress_spam_checkbox', // Name of function that renders options on the page
|
152 |
-
'bnfw-settings', // Page to show on
|
153 |
-
'bnfw_general_options_section', // Associate with which settings section?
|
154 |
-
array(
|
155 |
-
esc_html__( 'Don\'t send notifications for comments marked as SPAM', 'bnfw' )
|
156 |
-
)
|
157 |
-
);
|
158 |
-
|
159 |
-
// Register - Email Format setting
|
160 |
-
register_setting(
|
161 |
-
'bnfw-settings',
|
162 |
-
'bnfw_email_format'
|
163 |
-
);
|
164 |
-
|
165 |
-
add_settings_field(
|
166 |
-
'bnfw_email_format', // Field ID
|
167 |
-
esc_html__( 'Default Email Format', 'bnfw' ) . '<div class="bnfw-help-tip"><p>' . esc_html__( 'This will apply to all emails sent out via WordPress, even those from other plugins. For more details, please see the ', 'bnfw' ) . '<a href="https://wordpress.org/plugins/bnfw/faq/" target="_blank">FAQ</a>.</p></div>', // Label to the left
|
168 |
-
'bnfw_email_format_radio', // Name of function that renders options on the page
|
169 |
-
'bnfw-settings', // Page to show on
|
170 |
-
'bnfw_general_options_section' // Associate with which settings section?
|
171 |
-
);
|
172 |
-
|
173 |
-
// Register - Email Format setting
|
174 |
-
register_setting(
|
175 |
-
'bnfw-settings',
|
176 |
-
'bnfw_enable_shortcodes'
|
177 |
-
);
|
178 |
-
|
179 |
-
add_settings_field(
|
180 |
-
'bnfw_enable_shortcodes', // Field ID
|
181 |
-
esc_html__( 'Enable Content Shortcodes?', 'bnfw' ) . '<div class="bnfw-help-tip"><p>' . esc_html__( 'Shortcodes in the post/page content are disabled by default.', 'bnfw' ) . '</p></div>', // Label to the left
|
182 |
-
'bnfw_enable_shortcodes_checkbox', // Name of function that renders options on the page
|
183 |
-
'bnfw-settings', // Page to show on
|
184 |
-
'bnfw_general_options_section', // Associate with which settings section?
|
185 |
-
array(
|
186 |
-
esc_html__( 'Enable shortcode output in the page/post content', 'bnfw' ),
|
187 |
-
)
|
188 |
-
);
|
189 |
-
|
190 |
-
// Register - Allow tracking setting
|
191 |
-
register_setting(
|
192 |
-
'bnfw-settings',
|
193 |
-
'bnfw_allow_tracking'
|
194 |
-
);
|
195 |
-
|
196 |
-
add_settings_field(
|
197 |
-
'bnfw_allow_tracking', // Field ID
|
198 |
-
esc_html__( 'Allow Usage Tracking?', 'bnfw' ), // Label to the left
|
199 |
-
'bnfw_render_allow_tracking', // Name of function that renders options on the page
|
200 |
-
'bnfw-settings', // Page to show on
|
201 |
-
'bnfw_general_options_section', // Associate with which settings section?
|
202 |
-
array(
|
203 |
-
esc_html__( 'Allow Better Notifications for WP to anonymously track how this plugin is used and help make the plugin better.', 'bnfw' )
|
204 |
-
)
|
205 |
-
);
|
206 |
-
}
|
207 |
-
|
208 |
-
add_action( 'admin_init', 'bnfw_general_options', 10 );
|
209 |
-
|
210 |
-
/* ------------------------------------------------------------------------ *
|
211 |
-
* Settings Page - Settings Section Callbacks
|
212 |
-
* ------------------------------------------------------------------------ */
|
213 |
-
|
214 |
-
/**
|
215 |
-
*
|
216 |
-
*/
|
217 |
-
function bnfw_general_options_callback() {
|
218 |
-
}
|
219 |
-
|
220 |
-
/* ------------------------------------------------------------------------ *
|
221 |
-
* Settings Page - Settings Field Callbacks
|
222 |
-
* ------------------------------------------------------------------------ */
|
223 |
-
|
224 |
-
/**
|
225 |
-
* Suppress SPAM checkbox.
|
226 |
-
*
|
227 |
-
* @since 1.0
|
228 |
-
*
|
229 |
-
* @param $args
|
230 |
-
*/
|
231 |
-
function bnfw_suppress_spam_checkbox( $args ) {
|
232 |
-
?>
|
233 |
-
<input type="checkbox" id="bnfw_suppress_spam" name="bnfw_suppress_spam"
|
234 |
-
value="1" <?php checked( 1, get_option( 'bnfw_suppress_spam' ), true ); ?>>
|
235 |
-
<label for="bnfw_suppress_spam"><?php echo esc_html( $args[0] ); ?></label>
|
236 |
-
<?php
|
237 |
-
}
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Show email format radio
|
241 |
-
*
|
242 |
-
* @since 1.4
|
243 |
-
*
|
244 |
-
* @param array $args
|
245 |
-
*/
|
246 |
-
function bnfw_email_format_radio( $args ) {
|
247 |
-
$email_format = get_option( 'bnfw_email_format', 'html' );
|
248 |
-
?>
|
249 |
-
<label>
|
250 |
-
<input type="radio" value="html"
|
251 |
-
name="bnfw_email_format" <?php checked( $email_format, 'html', true ); ?>><?php esc_html_e( 'HTML Formatting', 'bnfw' ); ?>
|
252 |
-
</label>
|
253 |
-
<br/>
|
254 |
-
<label>
|
255 |
-
<input type="radio" value="text"
|
256 |
-
name="bnfw_email_format" <?php checked( $email_format, 'text', true ); ?>><?php esc_html_e( 'Plain Text', 'bnfw' ); ?>
|
257 |
-
</label>
|
258 |
-
<?php
|
259 |
-
}
|
260 |
-
|
261 |
-
/**
|
262 |
-
* Render allow tracking checkbox.
|
263 |
-
*
|
264 |
-
* @since 1.6
|
265 |
-
*
|
266 |
-
* @param array $args
|
267 |
-
*/
|
268 |
-
function bnfw_render_allow_tracking( $args ) {
|
269 |
-
?>
|
270 |
-
<input type="checkbox" id="bnfw_allow_tracking" name="bnfw_allow_tracking"
|
271 |
-
value="on" <?php checked( 'on', get_option( 'bnfw_allow_tracking' ), true ); ?>>
|
272 |
-
<label for="bnfw_allow_tracking"><?php echo esc_html( $args[0] ); ?></label>
|
273 |
-
<?php
|
274 |
-
}
|
275 |
-
|
276 |
-
/**
|
277 |
-
* Render Enable shortcode checkbox.
|
278 |
-
*
|
279 |
-
* @param array $args
|
280 |
-
*/
|
281 |
-
function bnfw_enable_shortcodes_checkbox( $args ) {
|
282 |
-
?>
|
283 |
-
<input type="checkbox" id="bnfw_enable_shortcodes" name="bnfw_enable_shortcodes"
|
284 |
-
value="1" <?php checked( 1, get_option( 'bnfw_enable_shortcodes' ), true ); ?>>
|
285 |
-
<label for="bnfw_enable_shortcodes"><?php echo esc_html( $args[0] ); ?></label>
|
286 |
-
<?php
|
287 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/admin/class-bnfw-notification.php
CHANGED
@@ -1,1651 +1,1679 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
*
|
5 |
-
*
|
6 |
-
* @
|
7 |
-
*/
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
<option
|
228 |
-
<?php
|
229 |
-
|
230 |
-
|
231 |
-
<option
|
232 |
-
<?php
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
value="
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
<option
|
263 |
-
<?php
|
264 |
-
|
265 |
-
|
266 |
-
<option
|
267 |
-
<?php
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
<option
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
value="
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
<
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
<
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
<?php
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
<
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
<?php
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
</
|
546 |
-
</
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
<
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
<
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
'
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
'
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
$setting
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
if (
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
<
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
'
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
'
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
)
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
$name = esc_html__( 'New
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
$
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
|
1528 |
-
|
1529 |
-
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
return;
|
1547 |
-
}
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
-
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
|
1570 |
-
|
1571 |
-
|
1572 |
-
|
1573 |
-
|
1574 |
-
|
1575 |
-
|
1576 |
-
|
1577 |
-
|
1578 |
-
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
1588 |
-
|
1589 |
-
|
1590 |
-
|
1591 |
-
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
|
1611 |
-
|
1612 |
-
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
|
1621 |
-
|
1622 |
-
|
1623 |
-
|
1624 |
-
|
1625 |
-
|
1626 |
-
|
1627 |
-
|
1628 |
-
|
1629 |
-
|
1630 |
-
|
1631 |
-
|
1632 |
-
|
1633 |
-
|
1634 |
-
|
1635 |
-
|
1636 |
-
|
1637 |
-
|
1638 |
-
|
1639 |
-
|
1640 |
-
|
1641 |
-
|
1642 |
-
|
1643 |
-
|
1644 |
-
|
1645 |
-
|
1646 |
-
|
1647 |
-
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* BNFW Notification.
|
4 |
+
*
|
5 |
+
* @since 1.0
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit;
|
10 |
+
|
11 |
+
if ( ! class_exists( 'BNFW_Notification', false ) ) {
|
12 |
+
/**
|
13 |
+
* BNFW Notification class.
|
14 |
+
*/
|
15 |
+
class BNFW_Notification {
|
16 |
+
|
17 |
+
const POST_TYPE = 'bnfw_notification';
|
18 |
+
const META_KEY_PREFIX = 'bnfw_';
|
19 |
+
const TEST_MAIL_ARG = 'test-mail';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Class contructor.
|
23 |
+
*/
|
24 |
+
public function __construct() {
|
25 |
+
add_action( 'init', array( $this, 'register_post_type' ) );
|
26 |
+
add_action( 'do_meta_boxes', array( $this, 'remove_meta_boxes' ) );
|
27 |
+
add_action( 'add_meta_boxes_' . self::POST_TYPE, array( $this, 'add_meta_boxes' ) );
|
28 |
+
add_action( 'save_post', array( $this, 'save_meta_data' ) );
|
29 |
+
add_action( 'edit_form_top', array( $this, 'admin_notices' ) );
|
30 |
+
add_filter( 'post_updated_messages', array( $this, 'post_updated_messages' ) );
|
31 |
+
|
32 |
+
add_filter( 'use_block_editor_for_post_type', array( $this, 'disable_gutenberg_for_notification' ), 10, 2 );
|
33 |
+
|
34 |
+
add_filter( 'bulk_actions-edit-bnfw_notification', array( $this, 'add_custom_edit_action' ) );
|
35 |
+
add_filter( 'handle_bulk_actions-edit-bnfw_notification', array( $this, 'handle_custom_edit_action' ), 10, 3 );
|
36 |
+
|
37 |
+
// Custom row actions.
|
38 |
+
add_filter( 'post_row_actions', array( $this, 'custom_row_actions' ), 10, 2 );
|
39 |
+
add_action( 'admin_init', array( $this, 'handle_actions' ) );
|
40 |
+
|
41 |
+
// Custom columns.
|
42 |
+
add_filter( sprintf( 'manage_%s_posts_columns', self::POST_TYPE ), array( $this, 'columns_header' ) );
|
43 |
+
add_action( sprintf( 'manage_%s_posts_custom_column', self::POST_TYPE ), array( $this, 'custom_column_row' ), 10, 2 );
|
44 |
+
|
45 |
+
// Enqueue scripts/styles and disables autosave for this post type.
|
46 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'is_assets_needed' ) );
|
47 |
+
|
48 |
+
add_action( 'admin_notices', array( $this, 'show_help_notice' ) );
|
49 |
+
|
50 |
+
add_action( 'admin_print_scripts', array( $this, 'gutenberg_flag' ) );
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Flag variable to check if gutenberge is active.
|
55 |
+
* added fix for gutenberg.
|
56 |
+
*
|
57 |
+
* @since 1.3
|
58 |
+
*/
|
59 |
+
public function gutenberg_flag() {
|
60 |
+
$bnfw = BNFW::Factory();
|
61 |
+
?>
|
62 |
+
<script type="text/javascript">
|
63 |
+
var bnfw_gutenberge_is_active = <?php echo ( $bnfw->is_gutenberg_active() ) ? 'true;' : 'false;'; ?>
|
64 |
+
</script>
|
65 |
+
<?php
|
66 |
+
}
|
67 |
+
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Register bnfw_notification custom post type.
|
71 |
+
*
|
72 |
+
* @since 1.0
|
73 |
+
*/
|
74 |
+
public function register_post_type() {
|
75 |
+
register_post_type(
|
76 |
+
self::POST_TYPE,
|
77 |
+
array(
|
78 |
+
'labels' => array(
|
79 |
+
'name' => esc_html__( 'Notifications', 'bnfw' ),
|
80 |
+
'singular_name' => esc_html__( 'Notification', 'bnfw' ),
|
81 |
+
'add_new' => esc_html__( 'Add New', 'bnfw' ),
|
82 |
+
'menu_name' => esc_html__( 'Notifications', 'bnfw' ),
|
83 |
+
'name_admin_bar' => esc_html__( 'Notifications', 'bnfw' ),
|
84 |
+
'add_new_item' => esc_html__( 'Add New Notification', 'bnfw' ),
|
85 |
+
'edit_item' => esc_html__( 'Edit Notification', 'bnfw' ),
|
86 |
+
'new_item' => esc_html__( 'New Notification', 'bnfw' ),
|
87 |
+
'view_item' => esc_html__( 'View Notification', 'bnfw' ),
|
88 |
+
'search_items' => esc_html__( 'Search Notifications', 'bnfw' ),
|
89 |
+
'not_found' => esc_html__( 'No Notifications found', 'bnfw' ),
|
90 |
+
'not_found_in_trash' => esc_html__( 'No Notifications found in trash', 'bnfw' ),
|
91 |
+
'all_items' => esc_html__( 'All Notifications', 'bnfw' ),
|
92 |
+
),
|
93 |
+
'public' => false,
|
94 |
+
'show_in_nav_menus' => true,
|
95 |
+
'show_in_admin_bar' => true,
|
96 |
+
'has_archive' => false,
|
97 |
+
'show_ui' => true,
|
98 |
+
'show_in_menu' => true,
|
99 |
+
'menu_icon' => 'dashicons-email-alt',
|
100 |
+
'menu_position' => 101,
|
101 |
+
'rewrite' => false,
|
102 |
+
'map_meta_cap' => false,
|
103 |
+
'capabilities' => array(
|
104 |
+
// meta caps (don't assign these to roles).
|
105 |
+
'edit_post' => 'bnfw',
|
106 |
+
'read_post' => 'bnfw',
|
107 |
+
'delete_post' => 'bnfw',
|
108 |
+
|
109 |
+
// primitive/meta caps.
|
110 |
+
'create_posts' => 'bnfw',
|
111 |
+
|
112 |
+
// primitive caps used outside of map_meta_cap().
|
113 |
+
'edit_posts' => 'bnfw',
|
114 |
+
'edit_others_posts' => 'bnfw',
|
115 |
+
'publish_posts' => 'bnfw',
|
116 |
+
'read_private_posts' => 'bnfw',
|
117 |
+
|
118 |
+
// primitive caps used inside of map_meta_cap().
|
119 |
+
'read' => 'bnfw',
|
120 |
+
'delete_posts' => 'bnfw',
|
121 |
+
'delete_private_posts' => 'bnfw',
|
122 |
+
'delete_published_posts' => 'bnfw',
|
123 |
+
'delete_others_posts' => 'bnfw',
|
124 |
+
'edit_private_posts' => 'bnfw',
|
125 |
+
'edit_published_posts' => 'bnfw',
|
126 |
+
),
|
127 |
+
// What features the post type supports.
|
128 |
+
'supports' => array(
|
129 |
+
'title',
|
130 |
+
),
|
131 |
+
)
|
132 |
+
);
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Remove unwanted meta boxes.
|
137 |
+
*
|
138 |
+
* @since 1.0
|
139 |
+
*/
|
140 |
+
public function remove_meta_boxes() {
|
141 |
+
remove_meta_box( 'submitdiv', self::POST_TYPE, 'side' );
|
142 |
+
remove_meta_box( 'slugdiv', self::POST_TYPE, 'normal' );
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Add meta box to the post editor screen.
|
147 |
+
*
|
148 |
+
* @since 1.0
|
149 |
+
*/
|
150 |
+
public function add_meta_boxes() {
|
151 |
+
global $post;
|
152 |
+
|
153 |
+
add_meta_box(
|
154 |
+
'bnfw-post-notification', // Unique ID.
|
155 |
+
esc_html__( 'Notification Settings', 'bnfw' ), // Title.
|
156 |
+
array( $this, 'render_settings_meta_box' ), // Callback function.
|
157 |
+
self::POST_TYPE, // Admin page (or post type).
|
158 |
+
'normal', // Context.
|
159 |
+
'default'
|
160 |
+
);
|
161 |
+
|
162 |
+
add_meta_box(
|
163 |
+
'bnfw_submitdiv',
|
164 |
+
__( 'Save Notification', 'bnfw' ),
|
165 |
+
array( $this, 'render_submitdiv' ),
|
166 |
+
self::POST_TYPE,
|
167 |
+
'side',
|
168 |
+
'core'
|
169 |
+
);
|
170 |
+
|
171 |
+
if ( self::POST_TYPE !== get_post_type( $post ) ) {
|
172 |
+
return;
|
173 |
+
}
|
174 |
+
|
175 |
+
do_action( 'bnfw_after_metaboxes', $this->read_settings( $post->ID ) );
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Disable Gutenberg for notifications.
|
180 |
+
*
|
181 |
+
* @param bool $is_enabled Is Gutenberg enabled?.
|
182 |
+
* @param string $post_type Post Type.
|
183 |
+
*
|
184 |
+
* @return bool Should Gutenberg be enabled?
|
185 |
+
*/
|
186 |
+
public function disable_gutenberg_for_notification( $is_enabled, $post_type ) {
|
187 |
+
if ( self::POST_TYPE === $post_type ) {
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
|
191 |
+
return $is_enabled;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Render the settings meta box.
|
196 |
+
*
|
197 |
+
* @since 1.0
|
198 |
+
*
|
199 |
+
* @param WP_Post $post The post object.
|
200 |
+
*/
|
201 |
+
public function render_settings_meta_box( $post ) {
|
202 |
+
global $wp_version;
|
203 |
+
|
204 |
+
wp_nonce_field( self::POST_TYPE, self::POST_TYPE . '_nonce' );
|
205 |
+
|
206 |
+
$setting = $this->read_settings( $post->ID );
|
207 |
+
?>
|
208 |
+
<table class="form-table">
|
209 |
+
<tbody>
|
210 |
+
<tr valign="top">
|
211 |
+
<th scope="row">
|
212 |
+
<label for="notification"><?php esc_html_e( 'Notification For', 'bnfw' ); ?></label>
|
213 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'E.g. If you select "New Post Published" from the list on the right, this notification will be sent when a new post is published.', 'bnfw' ); ?></p></div>
|
214 |
+
</th>
|
215 |
+
<td>
|
216 |
+
<select name="notification" id="notification" class="select2"
|
217 |
+
data-placeholder="<?php esc_attr_e( 'Select the notification type', 'bnfw' ); ?>" style="width:75%">
|
218 |
+
<optgroup label="<?php esc_html_e( 'Admin', 'bnfw' ); ?>">
|
219 |
+
<option
|
220 |
+
value="admin-user" <?php selected( 'admin-user', $setting['notification'] ); ?>><?php esc_html_e( 'New User Registration - For Admin', 'bnfw' ); ?></option>
|
221 |
+
<option
|
222 |
+
value="admin-password" <?php selected( 'admin-password', $setting['notification'] ); ?>><?php esc_html_e( 'User Lost Password - For Admin', 'bnfw' ); ?></option>
|
223 |
+
<option
|
224 |
+
value="admin-password-changed" <?php selected( 'admin-password-changed', $setting['notification'] ); ?>><?php esc_html_e( 'Password Changed - For Admin', 'bnfw' ); ?></option>
|
225 |
+
<option
|
226 |
+
value="admin-email-changed" <?php selected( 'admin-email-changed', $setting['notification'] ); ?>><?php esc_html_e( 'User Email Changed - For Admin', 'bnfw' ); ?></option>
|
227 |
+
<option
|
228 |
+
value="admin-role" <?php selected( 'admin-role', $setting['notification'] ); ?>><?php esc_html_e( 'User Role Changed - For Admin', 'bnfw' ); ?></option>
|
229 |
+
<option
|
230 |
+
value="admin-user-login" <?php selected( 'admin-user-login', $setting['notification'] ); ?>><?php esc_html_e( 'User Logged In - For Admin', 'bnfw' ); ?></option>
|
231 |
+
<option
|
232 |
+
value="core-updated" <?php selected( 'core-updated', $setting['notification'] ); ?>><?php esc_html_e( 'WordPress Core Automatic Background Updates', 'bnfw' ); ?></option>
|
233 |
+
|
234 |
+
<?php if ( version_compare( $wp_version, '4.9.6' ) >= 0 ) : ?>
|
235 |
+
<option value="uc-export-data" <?php selected( 'uc-export-data', $setting['notification'] ); ?>>
|
236 |
+
<?php esc_html_e( 'Privacy - Confirm Action: Export Data Request - For Admin', 'bnfw' ); ?>
|
237 |
+
</option>
|
238 |
+
|
239 |
+
<option value="uc-erase-data" <?php selected( 'uc-erase-data', $setting['notification'] ); ?>>
|
240 |
+
<?php esc_html_e( 'Privacy - Confirm Action: Erase Data Request - For Admin', 'bnfw' ); ?>
|
241 |
+
</option>
|
242 |
+
<?php endif; ?>
|
243 |
+
|
244 |
+
<?php do_action( 'bnfw_after_default_notifications', $setting ); ?>
|
245 |
+
</optgroup>
|
246 |
+
<?php do_action( 'bnfw_after_default_notifications_optgroup', $setting ); ?>
|
247 |
+
|
248 |
+
<optgroup label="<?php esc_attr_e( 'Transactional', 'bnfw' ); ?>">
|
249 |
+
<option
|
250 |
+
value="new-user" <?php selected( 'new-user', $setting['notification'] ); ?>><?php esc_html_e( 'New User Registration - For User', 'bnfw' ); ?></option>
|
251 |
+
<option
|
252 |
+
value="welcome-email" <?php selected( 'welcome-email', $setting['notification'] ); ?>><?php esc_html_e( 'New User - Post-registration Email', 'bnfw' ); ?></option>
|
253 |
+
<option
|
254 |
+
value="user-password" <?php selected( 'user-password', $setting['notification'] ); ?>><?php esc_html_e( 'User Lost Password - For User', 'bnfw' ); ?></option>
|
255 |
+
<option
|
256 |
+
value="password-changed" <?php selected( 'password-changed', $setting['notification'] ); ?>><?php esc_html_e( 'Password Changed - For User', 'bnfw' ); ?></option>
|
257 |
+
<option value="email-changing" <?php selected( 'email-changing', $setting['notification'] ); ?>>
|
258 |
+
<?php esc_html_e( 'User Email Changed Confirmation - For User', 'bnfw' ); ?>
|
259 |
+
</option>
|
260 |
+
<option
|
261 |
+
value="email-changed" <?php selected( 'email-changed', $setting['notification'] ); ?>><?php esc_html_e( 'User Email Changed - For User', 'bnfw' ); ?></option>
|
262 |
+
<option
|
263 |
+
value="user-role" <?php selected( 'user-role', $setting['notification'] ); ?>><?php esc_html_e( 'User Role Changed - For User', 'bnfw' ); ?></option>
|
264 |
+
<option
|
265 |
+
value="user-login" <?php selected( 'user-login', $setting['notification'] ); ?>><?php esc_html_e( 'User Logged In - For User', 'bnfw' ); ?></option>
|
266 |
+
<option
|
267 |
+
value="reply-comment" <?php selected( 'reply-comment', $setting['notification'] ); ?>><?php esc_html_e( 'Comment Reply', 'bnfw' ); ?></option>
|
268 |
+
|
269 |
+
<?php if ( version_compare( $wp_version, '4.9.6' ) >= 0 ) : ?>
|
270 |
+
<option value="ca-export-data" <?php selected( 'ca-export-data', $setting['notification'] ); ?>>
|
271 |
+
<?php esc_html_e( 'Privacy - Confirm Action: Export Data Request - For User', 'bnfw' ); ?>
|
272 |
+
</option>
|
273 |
+
|
274 |
+
<option value="ca-erase-data" <?php selected( 'ca-erase-data', $setting['notification'] ); ?>>
|
275 |
+
<?php esc_html_e( 'Privacy - Confirm Action: Erase Data Request - For User', 'bnfw' ); ?>
|
276 |
+
</option>
|
277 |
+
|
278 |
+
<option value="data-export" <?php selected( 'data-export', $setting['notification'] ); ?>>
|
279 |
+
<?php esc_html_e( 'Privacy - Data Export - For User', 'bnfw' ); ?>
|
280 |
+
</option>
|
281 |
+
|
282 |
+
<option value="data-erased" <?php selected( 'data-erased', $setting['notification'] ); ?>>
|
283 |
+
<?php esc_html_e( 'Privacy - Data Erased - For User', 'bnfw' ); ?>
|
284 |
+
</option>
|
285 |
+
<?php endif; ?>
|
286 |
+
|
287 |
+
<?php do_action( 'bnfw_after_transactional_notifications', $setting ); ?>
|
288 |
+
</optgroup>
|
289 |
+
<?php do_action( 'bnfw_after_transactional_notifications_optgroup', $setting ); ?>
|
290 |
+
|
291 |
+
<optgroup label="Posts">
|
292 |
+
<option
|
293 |
+
value="new-post" <?php selected( 'new-post', $setting['notification'] ); ?>><?php esc_html_e( 'New Post Published', 'bnfw' ); ?></option>
|
294 |
+
<option
|
295 |
+
value="update-post" <?php selected( 'update-post', $setting['notification'] ); ?>><?php esc_html_e( 'Post Updated', 'bnfw' ); ?></option>
|
296 |
+
<option
|
297 |
+
value="pending-post" <?php selected( 'pending-post', $setting['notification'] ); ?>><?php esc_html_e( 'Post Pending Review', 'bnfw' ); ?></option>
|
298 |
+
<option
|
299 |
+
value="private-post" <?php selected( 'private-post', $setting['notification'] ); ?>><?php esc_html_e( 'New Private Post', 'bnfw' ); ?></option>
|
300 |
+
<option
|
301 |
+
value="future-post" <?php selected( 'future-post', $setting['notification'] ); ?>><?php esc_html_e( 'Post Scheduled', 'bnfw' ); ?></option>
|
302 |
+
<option
|
303 |
+
value="trash-post" <?php selected( 'trash-post', $setting['notification'] ); ?>><?php esc_html_e( 'Published Post Moved to Trash', 'bnfw' ); ?></option>
|
304 |
+
<option value="new-comment" <?php selected( 'new-comment', $setting['notification'] ); ?>>
|
305 |
+
<?php esc_html_e( 'New Comment', 'bnfw' ); ?>
|
306 |
+
</option>
|
307 |
+
<option value="moderate-post-comment" <?php selected( 'moderate-post-comment', $setting['notification'] ); ?>>
|
308 |
+
<?php esc_html_e( 'New Comment Awaiting Moderation', 'bnfw' ); ?>
|
309 |
+
</option>
|
310 |
+
<option value="approve-post-comment" <?php selected( 'approve-post-comment', $setting['notification'] ); ?>>
|
311 |
+
<?php esc_html_e( 'Post - Comment Approved', 'bnfw' ); ?>
|
312 |
+
</option>
|
313 |
+
<option
|
314 |
+
value="newterm-category" <?php selected( 'newterm-category', $setting['notification'] ); ?>><?php esc_html_e( 'New Category', 'bnfw' ); ?></option>
|
315 |
+
<option
|
316 |
+
value="newterm-post_tag" <?php selected( 'newterm-post_tag', $setting['notification'] ); ?>><?php esc_html_e( 'New Tag', 'bnfw' ); ?></option>
|
317 |
+
<option
|
318 |
+
value="new-trackback" <?php selected( 'new-trackback', $setting['notification'] ); ?>><?php esc_html_e( 'New Trackback', 'bnfw' ); ?></option>
|
319 |
+
<option
|
320 |
+
value="new-pingback" <?php selected( 'new-pingback', $setting['notification'] ); ?>><?php esc_html_e( 'New Pingback', 'bnfw' ); ?></option>
|
321 |
+
<?php do_action( 'bnfw_after_notification_options', 'post', 'Post', $setting ); ?>
|
322 |
+
</optgroup>
|
323 |
+
<?php do_action( 'bnfw_after_notification_options_optgroup', 'post', 'Post', $setting ); ?>
|
324 |
+
|
325 |
+
<optgroup label="Page">
|
326 |
+
<option
|
327 |
+
value="new-page" <?php selected( 'new-page', $setting['notification'] ); ?>><?php esc_html_e( 'New Page Published', 'bnfw' ); ?></option>
|
328 |
+
<option
|
329 |
+
value="update-page" <?php selected( 'update-page', $setting['notification'] ); ?>><?php esc_html_e( 'Page Updated', 'bnfw' ); ?></option>
|
330 |
+
<option
|
331 |
+
value="pending-page" <?php selected( 'pending-page', $setting['notification'] ); ?>><?php esc_html_e( 'Page Pending Review', 'bnfw' ); ?></option>
|
332 |
+
<option
|
333 |
+
value="private-page" <?php selected( 'private-page', $setting['notification'] ); ?>><?php esc_html_e( 'New Private Page', 'bnfw' ); ?></option>
|
334 |
+
<option
|
335 |
+
value="future-page" <?php selected( 'future-page', $setting['notification'] ); ?>><?php esc_html_e( 'Page Scheduled', 'bnfw' ); ?></option>
|
336 |
+
<option
|
337 |
+
value="comment-page" <?php selected( 'comment-page', $setting['notification'] ); ?>><?php esc_html_e( 'Page - New Comment', 'bnfw' ); ?></option>
|
338 |
+
<option value="moderate-page-comment" <?php selected( 'moderate-page-comment', $setting['notification'] ); ?>>
|
339 |
+
<?php esc_html_e( 'Page - New Comment Awaiting Moderation', 'bnfw' ); ?>
|
340 |
+
</option>
|
341 |
+
<option value="approve-page-comment" <?php selected( 'approve-page-comment', $setting['notification'] ); ?>>
|
342 |
+
<?php esc_html_e( 'Page - Comment Approved', 'bnfw' ); ?>
|
343 |
+
</option>
|
344 |
+
<option
|
345 |
+
value="commentreply-page" <?php selected( 'commentreply-page', $setting['notification'] ); ?>><?php esc_html_e( 'Page - Comment Reply', 'bnfw' ); ?></option>
|
346 |
+
<?php do_action( 'bnfw_after_notification_options', 'page', 'Page', $setting ); ?>
|
347 |
+
</optgroup>
|
348 |
+
<?php do_action( 'bnfw_after_notification_options_optgroup', 'page', 'Page', $setting ); ?>
|
349 |
+
|
350 |
+
<optgroup label="Media">
|
351 |
+
<option
|
352 |
+
value="new-media" <?php selected( 'new-media', $setting['notification'] ); ?>><?php esc_html_e( 'New Media Published', 'bnfw' ); ?></option>
|
353 |
+
<option
|
354 |
+
value="update-media" <?php selected( 'update-media', $setting['notification'] ); ?>><?php esc_html_e( 'Media Updated', 'bnfw' ); ?></option>
|
355 |
+
<option
|
356 |
+
value="comment-attachment" <?php selected( 'comment-attachment', $setting['notification'] ); ?>><?php esc_html_e( 'Media - New Comment', 'bnfw' ); ?></option>
|
357 |
+
<option value="approve-attachment-comment" <?php selected( 'approve-attachment-comment', $setting['notification'] ); ?>>
|
358 |
+
<?php esc_html_e( 'Media - Comment Approved', 'bnfw' ); ?>
|
359 |
+
</option>
|
360 |
+
<option value="moderate-attachment-comment" <?php selected( 'moderate-attachment-comment', $setting['notification'] ); ?>>
|
361 |
+
<?php esc_html_e( 'Media - New Comment Awaiting Moderation', 'bnfw' ); ?></option>
|
362 |
+
<option
|
363 |
+
value="commentreply-attachment" <?php selected( 'commentreply-attachment', $setting['notification'] ); ?>><?php esc_html_e( 'Media - Comment Reply', 'bnfw' ); ?></option>
|
364 |
+
<?php do_action( 'bnfw_after_notification_options', 'media', 'Media', $setting ); ?>
|
365 |
+
</optgroup>
|
366 |
+
<?php do_action( 'bnfw_after_notification_options_optgroup', 'media', 'Media', $setting ); ?>
|
367 |
+
|
368 |
+
<?php
|
369 |
+
$types = apply_filters(
|
370 |
+
'bnfw_notification_dropdown_posttypes',
|
371 |
+
get_post_types(
|
372 |
+
array(
|
373 |
+
'public' => true,
|
374 |
+
'_builtin' => false,
|
375 |
+
),
|
376 |
+
'names'
|
377 |
+
)
|
378 |
+
);
|
379 |
+
|
380 |
+
foreach ( $types as $type ) {
|
381 |
+
if ( self::POST_TYPE !== $type ) {
|
382 |
+
$post_obj = get_post_type_object( $type );
|
383 |
+
$label = $post_obj->labels->singular_name;
|
384 |
+
?>
|
385 |
+
<optgroup
|
386 |
+
label="<?php esc_attr( /* translators: %s Custom post type lable name. */ printf( "%s - '%s'", esc_html__( 'Custom Post Type', 'bnfw' ), esc_html( $label ) ) ); ?>">
|
387 |
+
<option
|
388 |
+
value="new-<?php echo esc_attr( $type ); ?>" <?php selected( 'new-' . $type, $setting['notification'] ); ?>><?php echo esc_html__( 'New ', 'bnfw' ), "'" . esc_html( $label ) . "'", esc_html__( ' Published', 'bnfw' ); ?></option>
|
389 |
+
<option
|
390 |
+
value="update-<?php echo esc_attr( $type ); ?>" <?php selected( 'update-' . $type, $setting['notification'] ); ?>><?php echo "'" . esc_html( $label ) . "' " . esc_html__( 'Updated', 'bnfw' ); ?></option>
|
391 |
+
<option
|
392 |
+
value="pending-<?php echo esc_attr( $type ); ?>" <?php selected( 'pending-' . $type, $setting['notification'] ); ?>><?php echo "'" . esc_html( $label ) . "' ", esc_html__( 'Pending Review', 'bnfw' ); ?></option>
|
393 |
+
<option
|
394 |
+
value="private-<?php echo esc_attr( $type ); ?>" <?php selected( 'private-' . $type, $setting['notification'] ); ?>><?php echo esc_html__( 'New Private ', 'bnfw' ), "'" . esc_html( $label ) . "'"; ?></option>
|
395 |
+
<option
|
396 |
+
value="future-<?php echo esc_attr( $type ); ?>" <?php selected( 'future-' . $type, $setting['notification'] ); ?>><?php echo "'" . esc_html( $label ) . "' ", esc_html__( 'Scheduled', 'bnfw' ); ?></option>
|
397 |
+
<option
|
398 |
+
value="comment-<?php echo esc_attr( $type ); ?>" <?php selected( 'comment-' . $type, $setting['notification'] ); ?>><?php echo "'" . esc_html( $label ) . "' ", esc_html__( 'New Comment', 'bnfw' ); ?></option>
|
399 |
+
<option value="moderate-<?php echo esc_attr( $type ); ?>-comment" <?php selected( 'moderate-' . $type . '-comment', $setting['notification'] ); ?>>
|
400 |
+
<?php echo "'" . esc_html( $label ) . "' - ", esc_html__( 'New Comment Awaiting Moderation', 'bnfw' ); ?>
|
401 |
+
</option>
|
402 |
+
<option value="approve-<?php echo esc_attr( $type ); ?>-comment" <?php selected( 'approve-' . $type . '-comment', $setting['notification'] ); ?>>
|
403 |
+
<?php echo "'" . esc_html( $label ) . "' - ", esc_html__( 'Comment Approved', 'bnfw' ); ?>
|
404 |
+
</option>
|
405 |
+
<option
|
406 |
+
value="commentreply-<?php echo esc_attr( $type ); ?>" <?php selected( 'commentreply-' . $type, $setting['notification'] ); ?>><?php echo "'" . esc_html( $label ) . "' ", esc_html__( 'Comment Reply', 'bnfw' ); ?></option>
|
407 |
+
<?php do_action( 'bnfw_after_notification_options', $type, $label, $setting ); ?>
|
408 |
+
</optgroup>
|
409 |
+
<?php do_action( 'bnfw_after_notification_options_optgroup', $type, $label, $setting ); ?>
|
410 |
+
|
411 |
+
<?php
|
412 |
+
}
|
413 |
+
}
|
414 |
+
|
415 |
+
$taxs = apply_filters(
|
416 |
+
'bnfw_notification_dropdown_taxonomies',
|
417 |
+
get_taxonomies(
|
418 |
+
array(
|
419 |
+
'public' => true,
|
420 |
+
'_builtin' => false,
|
421 |
+
),
|
422 |
+
'objects'
|
423 |
+
)
|
424 |
+
);
|
425 |
+
|
426 |
+
if ( count( $taxs ) > 0 ) {
|
427 |
+
?>
|
428 |
+
<optgroup label="<?php esc_html_e( 'Custom Taxonomy', 'bnfw' ); ?>">
|
429 |
+
<?php
|
430 |
+
foreach ( $taxs as $tax ) {
|
431 |
+
$tax_name = 'newterm-' . $tax->name;
|
432 |
+
?>
|
433 |
+
<option
|
434 |
+
value="<?php echo esc_attr( $tax_name ); ?>" <?php selected( $tax_name, $setting['notification'] ); ?>><?php printf( "%s '%s'", esc_html__( 'New', 'bnfw' ), esc_attr( $tax->labels->name ) ); ?></option>
|
435 |
+
<?php
|
436 |
+
}
|
437 |
+
?>
|
438 |
+
</optgroup>
|
439 |
+
<?php
|
440 |
+
}
|
441 |
+
do_action( 'bnfw_after_notification_optgroups', $setting );
|
442 |
+
?>
|
443 |
+
</select>
|
444 |
+
</td>
|
445 |
+
</tr>
|
446 |
+
|
447 |
+
<?php do_action( 'bnfw_after_notification_dropdown', $setting ); ?>
|
448 |
+
|
449 |
+
<tr valign="top" id="user-password-msg">
|
450 |
+
<td> </td>
|
451 |
+
<td>
|
452 |
+
<div>
|
453 |
+
<p style="margin-top: 0;"><?php esc_html_e( "This notification doesn't support additional email fields due to a limitation in WordPress.", 'bnfw' ); ?></p>
|
454 |
+
</div>
|
455 |
+
</td>
|
456 |
+
</tr>
|
457 |
+
|
458 |
+
<tr valign="top" id="email-formatting">
|
459 |
+
<th>
|
460 |
+
<?php esc_html_e( 'Email Formatting', 'bnfw' ); ?>
|
461 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'How do you want to format the sent email? HTML is recommended as it\'ll show images and links correctly.', 'bnfw' ); ?></p></div>
|
462 |
+
</th>
|
463 |
+
<td>
|
464 |
+
<label style="margin-right: 20px;">
|
465 |
+
<input type="radio" name="email-formatting"
|
466 |
+
value="html" <?php checked( 'html', $setting['email-formatting'] ); ?>>
|
467 |
+
<?php esc_html_e( 'HTML Formatting', 'bnfw' ); ?>
|
468 |
+
</label>
|
469 |
+
|
470 |
+
<label>
|
471 |
+
<input type="radio" name="email-formatting"
|
472 |
+
value="text" <?php checked( 'text', $setting['email-formatting'] ); ?>>
|
473 |
+
<?php esc_html_e( 'Plain Text', 'bnfw' ); ?>
|
474 |
+
</label>
|
475 |
+
</td>
|
476 |
+
</tr>
|
477 |
+
|
478 |
+
<?php do_action( 'bnfw_after_email_formatting', $setting ); ?>
|
479 |
+
|
480 |
+
<tr valign="top" id="toggle-fields">
|
481 |
+
<th>
|
482 |
+
<?php esc_html_e( 'Additional Email Fields', 'bnfw' ); ?>
|
483 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'This should be fairly self explanatory but if you\'re unsure, tick this checkbox and have a look at the available options. You can always untick it again should you decide you don\'t need to use it.', 'bnfw' ); ?></p></div>
|
484 |
+
</th>
|
485 |
+
<td>
|
486 |
+
<input type="checkbox" id="show-fields" name="show-fields"
|
487 |
+
value="true" <?php checked( $setting['show-fields'], 'true', true ); ?>>
|
488 |
+
<label for="show-fields"><?php esc_html_e( 'Set "From" Name & Email, Reply To, CC, BCC', 'bnfw' ); ?></label>
|
489 |
+
</td>
|
490 |
+
</tr>
|
491 |
+
|
492 |
+
|
493 |
+
<tr valign="top" id="email">
|
494 |
+
<th scope="row">
|
495 |
+
<?php esc_html_e( 'From Name and Email', 'bnfw' ); ?>
|
496 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'If you want to send the email from your site name and email address instead of the default "WordPress" from "wordpress@domain.com", this is where you can do it.', 'bnfw' ); ?></p></div>
|
497 |
+
</th>
|
498 |
+
<td>
|
499 |
+
<input type="text" name="from-name" value="<?php echo esc_attr( $setting['from-name'] ); ?>"
|
500 |
+
placeholder="<?php esc_attr_e( 'Site Name', 'bnfw' ); ?>" style="width: 37.35%">
|
501 |
+
<input type="text" name="from-email" value="<?php echo esc_attr( $setting['from-email'] ); ?>"
|
502 |
+
placeholder="<?php esc_attr_e( 'Site Email', 'bnfw' ); ?>" style="width: 37.3%">
|
503 |
+
</td>
|
504 |
+
</tr>
|
505 |
+
|
506 |
+
|
507 |
+
<tr valign="top" id="reply">
|
508 |
+
<th scope="row">
|
509 |
+
<?php esc_html_e( 'Reply To', 'bnfw' ); ?>
|
510 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'If you want any replies to your email notification to go to another person, fill in this box with their name and email address.', 'bnfw' ); ?></p></div>
|
511 |
+
</th>
|
512 |
+
<td>
|
513 |
+
<input type="text" name="reply-name" value="<?php echo esc_attr( $setting['reply-name'] ); ?>"
|
514 |
+
placeholder="<?php esc_attr_e( 'Name', 'bnfw' ); ?>" style="width: 37.35%">
|
515 |
+
<input type="text" name="reply-email" value="<?php echo esc_attr( $setting['reply-email'] ); ?>"
|
516 |
+
placeholder="<?php esc_attr_e( 'Email', 'bnfw' ); ?>" style="width: 37.3%">
|
517 |
+
</td>
|
518 |
+
</tr>
|
519 |
+
|
520 |
+
<tr valign="top" id="cc">
|
521 |
+
<th scope="row">
|
522 |
+
<?php esc_html_e( 'CC', 'bnfw' ); ?>
|
523 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'Publicly copy in any other users or user roles to this email.', 'bnfw' ); ?></p></div>
|
524 |
+
</th>
|
525 |
+
|
526 |
+
<td>
|
527 |
+
<select multiple name="cc[]" class="<?php echo sanitize_html_class( bnfw_get_user_select_class() ); ?>"
|
528 |
+
data-placeholder="<?php echo esc_attr( apply_filters( 'bnfw_email_dropdown_placeholder', __( 'Select User Roles / Users', 'bnfw' ) ) ); ?>" style="width:75%">
|
529 |
+
<?php bnfw_render_users_dropdown( $setting['cc'] ); ?>
|
530 |
+
</select>
|
531 |
+
</td>
|
532 |
+
</tr>
|
533 |
+
|
534 |
+
<tr valign="top" id="bcc">
|
535 |
+
<th scope="row">
|
536 |
+
<?php esc_html_e( 'BCC', 'bnfw' ); ?>
|
537 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'Privately copy in any other users or user roles to this email.', 'bnfw' ); ?></p></div>
|
538 |
+
</th>
|
539 |
+
|
540 |
+
<td>
|
541 |
+
<select multiple name="bcc[]" class="<?php echo sanitize_html_class( bnfw_get_user_select_class() ); ?>"
|
542 |
+
data-placeholder="<?php echo esc_attr( apply_filters( 'bnfw_email_dropdown_placeholder', __( 'Select User Roles / Users', 'bnfw' ) ) ); ?>" style="width:75%">
|
543 |
+
<?php bnfw_render_users_dropdown( $setting['bcc'] ); ?>
|
544 |
+
</select>
|
545 |
+
</td>
|
546 |
+
</tr>
|
547 |
+
|
548 |
+
<?php do_action( 'bnfw_after_additional_email_fields', $setting ); ?>
|
549 |
+
|
550 |
+
<tr valign="top" id="post-author">
|
551 |
+
<th>
|
552 |
+
<?php esc_html_e( 'Send to Author', 'bnfw' ); ?>
|
553 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'E.g. If you want a new post published notification to go to the post author, tick this box.', 'bnfw' ); ?></p></div>
|
554 |
+
</th>
|
555 |
+
|
556 |
+
<td>
|
557 |
+
<label>
|
558 |
+
<input type="checkbox" id="only-post-author" name="only-post-author"
|
559 |
+
value="true" <?php checked( 'true', $setting['only-post-author'] ); ?>>
|
560 |
+
<?php esc_html_e( 'Send this notification to the Author', 'bnfw' ); ?>
|
561 |
+
</label>
|
562 |
+
</td>
|
563 |
+
</tr>
|
564 |
+
|
565 |
+
<?php do_action( 'bnfw_after_only_post_author', $setting ); ?>
|
566 |
+
|
567 |
+
<tr valign="top" id="current-user">
|
568 |
+
<th>
|
569 |
+
|
570 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'E.g. If you\'re an editor and regularly update your posts, you might not want to be emailed about this all the time. Ticking this box will prevent you from receiving emails about your own changes.', 'bnfw' ); ?></p></div>
|
571 |
+
</th>
|
572 |
+
<td>
|
573 |
+
<label>
|
574 |
+
<input type="checkbox" name="disable-current-user"
|
575 |
+
value="true" <?php checked( 'true', $setting['disable-current-user'] ); ?>>
|
576 |
+
<?php esc_html_e( 'Do not send this Notification to the User that triggered it', 'bnfw' ); ?>
|
577 |
+
</label>
|
578 |
+
</td>
|
579 |
+
</tr>
|
580 |
+
|
581 |
+
<?php do_action( 'bnfw_after_disable_current_user', $setting ); ?>
|
582 |
+
|
583 |
+
<tr valign="top" id="users">
|
584 |
+
<th scope="row">
|
585 |
+
<?php esc_html_e( 'Send To', 'bnfw' ); ?>
|
586 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'Choose the users and/or user roles to send this email notification to.', 'bnfw' ); ?></p></div>
|
587 |
+
</th>
|
588 |
+
<td>
|
589 |
+
<select multiple id="users-select" name="users[]"
|
590 |
+
class="<?php echo sanitize_html_class( bnfw_get_user_select_class() ); ?>"
|
591 |
+
data-placeholder="<?php echo esc_attr( apply_filters( 'bnfw_email_dropdown_placeholder', __( 'Select User Roles / Users', 'bnfw' ) ) ); ?>" style="width:75%">
|
592 |
+
<?php bnfw_render_users_dropdown( $setting['users'] ); ?>
|
593 |
+
</select>
|
594 |
+
</td>
|
595 |
+
</tr>
|
596 |
+
|
597 |
+
<tr valign="top" id="exclude-users">
|
598 |
+
<th scope="row">
|
599 |
+
<?php esc_html_e( 'Except For', 'bnfw' ); ?>
|
600 |
+
<div class="bnfw-help-tip">
|
601 |
+
<p>
|
602 |
+
<?php esc_html_e( 'Choose the users and/or user roles that this notification should not be sent to.', 'bnfw' ); ?>
|
603 |
+
</p>
|
604 |
+
</div>
|
605 |
+
</th>
|
606 |
+
<td>
|
607 |
+
<select multiple id="exclude-users-select" name="exclude-users[]"
|
608 |
+
class="<?php echo sanitize_html_class( bnfw_get_user_select_class() ); ?>"
|
609 |
+
data-placeholder="<?php echo esc_attr( apply_filters( 'bnfw_email_dropdown_placeholder', __( 'Select User Roles / Users', 'bnfw' ) ) ); ?>" style="width:75%">
|
610 |
+
<?php bnfw_render_users_dropdown( $setting['exclude-users'] ); ?>
|
611 |
+
</select>
|
612 |
+
</td>
|
613 |
+
</tr>
|
614 |
+
|
615 |
+
<?php
|
616 |
+
$display = 'none';
|
617 |
+
|
618 |
+
if ( $this->should_show_users_count_msg( $setting ) ) {
|
619 |
+
$display = 'table-row';
|
620 |
+
}
|
621 |
+
?>
|
622 |
+
<tr valign="top" id="users-count-msg" style="display: <?php echo esc_attr( $display ); ?>">
|
623 |
+
<th scope="row"> </th>
|
624 |
+
<td>
|
625 |
+
<div>
|
626 |
+
<p>
|
627 |
+
<?php esc_html_e( 'You have chosen to send this notification to over 200 users. Please check the email sending rate limit at your host before sending.', 'bnfw' ); ?>
|
628 |
+
</p>
|
629 |
+
</div>
|
630 |
+
</td>
|
631 |
+
</tr>
|
632 |
+
|
633 |
+
<?php do_action( 'bnfw_after_send_to', $setting ); ?>
|
634 |
+
|
635 |
+
<tr valign="top" id="subject-wrapper">
|
636 |
+
<th scope="row">
|
637 |
+
<?php esc_html_e( 'Subject', 'bnfw' ); ?>
|
638 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'Notification subject. You can use ', 'bnfw' ); ?><a href="https://betternotificationsforwp.com/documentation/notifications/shortcodes/" target="_blank">shortcodes</a><?php esc_html_e( ' here.', 'bnfw' ); ?></p></div>
|
639 |
+
</th>
|
640 |
+
<td>
|
641 |
+
<input type="text" name="subject" id="subject" value="<?php echo esc_attr( $setting['subject'] ); ?>"
|
642 |
+
style="width:75%;">
|
643 |
+
</td>
|
644 |
+
</tr>
|
645 |
+
|
646 |
+
<?php do_action( 'bnfw_after_user_dropdown', $setting ); ?>
|
647 |
+
|
648 |
+
<?php do_action( 'bnfw_before_message_body', $setting ); ?>
|
649 |
+
<tr valign="top">
|
650 |
+
<th scope="row">
|
651 |
+
<?php esc_html_e( 'Message Body', 'bnfw' ); ?>
|
652 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'Notification message. You can use ', 'bnfw' ); ?><a href="https://betternotificationsforwp.com/documentation/notifications/shortcodes/" target="_blank">shortcodes</a><?php esc_html_e( ' here.', 'bnfw' ); ?></p></div>
|
653 |
+
|
654 |
+
<div class="wp-ui-text-highlight">
|
655 |
+
<p>
|
656 |
+
<br>
|
657 |
+
<br>
|
658 |
+
<br>
|
659 |
+
<br>
|
660 |
+
<?php esc_html_e( 'Need some more help?', 'bnfw' ); ?>
|
661 |
+
</p>
|
662 |
+
<?php
|
663 |
+
$doc_url = 'https://betternotificationsforwp.com/documentation/';
|
664 |
+
|
665 |
+
if ( bnfw_is_tracking_allowed() ) {
|
666 |
+
$doc_url .= "?utm_source=WP%20Admin%20Notification%20Editor%20-%20'Documentation'&utm_medium=referral";
|
667 |
+
}
|
668 |
+
?>
|
669 |
+
<p>
|
670 |
+
<a href="#" class="button-secondary" id="insert-default-msg"><?php esc_html_e( 'Insert Default Content', 'bnfw' ); ?></a>
|
671 |
+
</p>
|
672 |
+
<p>
|
673 |
+
<a href="<?php echo esc_url( $doc_url ); ?>"
|
674 |
+
target="_blank" class="button-secondary"><?php esc_html_e( 'Read Documentation', 'bnfw' ); ?></a>
|
675 |
+
</p>
|
676 |
+
<p>
|
677 |
+
<a href="" target="_blank" id="shortcode-help"
|
678 |
+
class="button-secondary"><?php esc_html_e( 'Find Shortcodes', 'bnfw' ); ?></a>
|
679 |
+
</p>
|
680 |
+
</div>
|
681 |
+
</th>
|
682 |
+
<td>
|
683 |
+
<?php wp_editor( $setting['message'], 'notification_message', array( 'media_buttons' => true ) ); ?>
|
684 |
+
<p> </p>
|
685 |
+
<div id="disable-autop">
|
686 |
+
<label>
|
687 |
+
<input type="checkbox" name="disable-autop"
|
688 |
+
value="true" <?php checked( 'true', $setting['disable-autop'] ); ?>>
|
689 |
+
<?php esc_html_e( 'Stop additional paragraph and line break HTML from being inserted into my notifications', 'bnfw' ); ?>
|
690 |
+
</label>
|
691 |
+
</div>
|
692 |
+
</td>
|
693 |
+
</tr>
|
694 |
+
|
695 |
+
</tbody>
|
696 |
+
</table>
|
697 |
+
<?php
|
698 |
+
}
|
699 |
+
|
700 |
+
/**
|
701 |
+
* Should we enqueue assets?.
|
702 |
+
*
|
703 |
+
* @since 1.0
|
704 |
+
*
|
705 |
+
* @param string $hook_suffix The current admin page.
|
706 |
+
*/
|
707 |
+
public function is_assets_needed( $hook_suffix ) {
|
708 |
+
if ( self::POST_TYPE === get_post_type() || 'bnfw_notification_page_bnfw-settings' === $hook_suffix ) {
|
709 |
+
// The enqueue assets function may be included from addons.
|
710 |
+
// We want to disable autosave only for notifications.
|
711 |
+
wp_dequeue_script( 'autosave' );
|
712 |
+
|
713 |
+
$this->enqueue_assets();
|
714 |
+
|
715 |
+
do_action( 'bnfw_after_enqueue_scripts' );
|
716 |
+
}
|
717 |
+
}
|
718 |
+
|
719 |
+
/**
|
720 |
+
* Enqueue assets.
|
721 |
+
*
|
722 |
+
* @since 1.4
|
723 |
+
*/
|
724 |
+
public function enqueue_assets() {
|
725 |
+
wp_deregister_script( 'select2' );
|
726 |
+
wp_dequeue_script( 'select2' );
|
727 |
+
wp_deregister_style( 'select2' );
|
728 |
+
wp_dequeue_style( 'select2' );
|
729 |
+
|
730 |
+
// Ultimate Member plugin is giving us problems. They should upgrade.
|
731 |
+
wp_deregister_script( 'um_minified' );
|
732 |
+
wp_dequeue_script( 'um_minified' );
|
733 |
+
wp_deregister_script( 'um_admin_scripts' );
|
734 |
+
wp_dequeue_script( 'um_admin_scripts' );
|
735 |
+
|
736 |
+
wp_enqueue_style( 'select2', plugins_url( '../assets/css/select2.min.css', dirname( __FILE__ ) ), array(), BNFW_VERSION );
|
737 |
+
wp_enqueue_script( 'select2', plugins_url( '../assets/js/select2.full.min.js', dirname( __FILE__ ) ), array( 'jquery' ), BNFW_VERSION, true );
|
738 |
+
|
739 |
+
wp_enqueue_script( 'bnfw', plugins_url( '../assets/js/bnfw.js', dirname( __FILE__ ) ), array( 'select2' ), BNFW_VERSION, true );
|
740 |
+
wp_enqueue_style( 'bnfw', plugins_url( '../assets/css/bnfw.css', dirname( __FILE__ ) ), array( 'dashicons', 'select2' ), BNFW_VERSION );
|
741 |
+
|
742 |
+
$strings = array(
|
743 |
+
'validation_element' => apply_filters( 'bnfw_validation_element', '#users-select' ),
|
744 |
+
'empty_user' => esc_html__( 'You must choose at least one User or User Role to send the notification to before you can save', 'bnfw' ),
|
745 |
+
'enableTags' => false,
|
746 |
+
'bnfw_users_search_ajax_nonce' => wp_create_nonce( 'bnfw_users_search_ajax_nonce' ),
|
747 |
+
);
|
748 |
+
|
749 |
+
/**
|
750 |
+
* Filter the localized array that is sent to scripts.
|
751 |
+
*
|
752 |
+
* @since 1.7.0
|
753 |
+
*/
|
754 |
+
$strings = apply_filters( 'bnfw_localize_script', $strings );
|
755 |
+
|
756 |
+
wp_localize_script( 'bnfw', 'BNFW', $strings );
|
757 |
+
}
|
758 |
+
|
759 |
+
/**
|
760 |
+
* Save the meta box's post metadata.
|
761 |
+
*
|
762 |
+
* @since 1.0
|
763 |
+
*
|
764 |
+
* @param int $post_id The ID of the post being saved.
|
765 |
+
*/
|
766 |
+
public function save_meta_data( $post_id ) {
|
767 |
+
if ( self::POST_TYPE !== get_post_type( $post_id ) ) {
|
768 |
+
return;
|
769 |
+
}
|
770 |
+
|
771 |
+
// Check nonce.
|
772 |
+
if ( empty( $_POST[ self::POST_TYPE . '_nonce' ] ) ) {
|
773 |
+
return;
|
774 |
+
}
|
775 |
+
|
776 |
+
// Verify nonce.
|
777 |
+
if ( ! wp_verify_nonce( $_POST[ self::POST_TYPE . '_nonce' ], self::POST_TYPE ) ) {// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
778 |
+
return;
|
779 |
+
}
|
780 |
+
|
781 |
+
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
782 |
+
return;
|
783 |
+
}
|
784 |
+
|
785 |
+
if ( ! current_user_can( 'bnfw' ) ) {
|
786 |
+
return;
|
787 |
+
}
|
788 |
+
if ( isset( $_POST['digest-interval'] ) && 'no' !== $_POST['digest-interval'] ) {
|
789 |
+
$subject = isset( $_POST['subject'] ) ? sanitize_text_field( wp_unslash( $_POST['subject'] ) ) : '';
|
790 |
+
} else {
|
791 |
+
$subject = isset( $_POST['subject'] ) ? sanitize_text_field( wp_unslash( $_POST['subject'] ) ) : '';
|
792 |
+
}
|
793 |
+
|
794 |
+
$setting = array(
|
795 |
+
'notification' => isset( $_POST['notification'] ) ? sanitize_text_field( wp_unslash( $_POST['notification'] ) ) : '',
|
796 |
+
'subject' => $subject,
|
797 |
+
'message' => isset( $_POST['notification_message'] ) ? sanitize_text_field( wp_unslash( $_POST['notification_message'] ) ) : '',
|
798 |
+
'disabled' => isset( $_POST['disabled'] ) ? sanitize_text_field( wp_unslash( $_POST['disabled'] ) ) : 'false',
|
799 |
+
'email-formatting' => isset( $_POST['email-formatting'] ) ? sanitize_text_field( wp_unslash( $_POST['email-formatting'] ) ) : 'html',
|
800 |
+
'disable-current-user' => isset( $_POST['disable-current-user'] ) ? sanitize_text_field( wp_unslash( $_POST['disable-current-user'] ) ) : 'false',
|
801 |
+
'disable-autop' => isset( $_POST['disable-autop'] ) ? sanitize_text_field( wp_unslash( $_POST['disable-autop'] ) ) : 'false',
|
802 |
+
'only-post-author' => isset( $_POST['only-post-author'] ) ? sanitize_text_field( wp_unslash( $_POST['only-post-author'] ) ) : 'false',
|
803 |
+
'users' => array(),
|
804 |
+
'exclude-users' => array(),
|
805 |
+
);
|
806 |
+
|
807 |
+
if ( isset( $_POST['users'] ) ) {
|
808 |
+
$setting['users'] = array_map( 'sanitize_text_field', (array) wp_unslash( $_POST['users'] ) );
|
809 |
+
}
|
810 |
+
|
811 |
+
if ( isset( $_POST['exclude-users'] ) ) {
|
812 |
+
$setting['exclude-users'] = array_map( 'sanitize_text_field', (array) wp_unslash( $_POST['exclude-users'] ) );
|
813 |
+
}
|
814 |
+
|
815 |
+
if ( isset( $_POST['show-fields'] ) && 'true' === $_POST['show-fields'] ) {
|
816 |
+
$setting['show-fields'] = 'true';
|
817 |
+
$setting['from-name'] = isset( $_POST['from-name'] ) ? sanitize_text_field( wp_unslash( $_POST['from-name'] ) ) : '';
|
818 |
+
$setting['from-email'] = isset( $_POST['from-email'] ) ? sanitize_email( wp_unslash( $_POST['from-email'] ) ) : '';
|
819 |
+
$setting['reply-name'] = isset( $_POST['reply-name'] ) ? sanitize_text_field( wp_unslash( $_POST['reply-name'] ) ) : '';
|
820 |
+
$setting['reply-email'] = isset( $_POST['reply-email'] ) ? sanitize_email( wp_unslash( $_POST['reply-email'] ) ) : '';
|
821 |
+
$setting['cc'] = isset( $_POST['cc'] ) ? array_map( 'sanitize_text_field', (array) wp_unslash( $_POST['cc'] ) ) : '';
|
822 |
+
$setting['bcc'] = isset( $_POST['bcc'] ) ? array_map( 'sanitize_text_field', (array) wp_unslash( $_POST['bcc'] ) ) : '';
|
823 |
+
} else {
|
824 |
+
$setting['show-fields'] = 'false';
|
825 |
+
}
|
826 |
+
|
827 |
+
$setting = apply_filters( 'bnfw_notification_setting', $setting, $_POST );
|
828 |
+
|
829 |
+
$this->save_settings( $post_id, $setting );
|
830 |
+
|
831 |
+
if ( isset( $_POST['send-test-email'] ) ) {
|
832 |
+
if ( 'true' === sanitize_text_field( wp_unslash( $_POST['send-test-email'] ) ) ) {
|
833 |
+
BNFW::factory()->engine->send_test_email( $setting );
|
834 |
+
add_filter( 'redirect_post_location', array( $this, 'test_mail_sent' ) );
|
835 |
+
}
|
836 |
+
}
|
837 |
+
}
|
838 |
+
|
839 |
+
/**
|
840 |
+
* Add a query parameter to url if test email was sent.
|
841 |
+
*
|
842 |
+
* @since 1.3
|
843 |
+
* @param string $loc A URL to act upon.
|
844 |
+
*/
|
845 |
+
public function test_mail_sent( $loc ) {
|
846 |
+
return add_query_arg( self::TEST_MAIL_ARG, 1, $loc );
|
847 |
+
}
|
848 |
+
|
849 |
+
/**
|
850 |
+
* Add a notification if a test email was sent.
|
851 |
+
*
|
852 |
+
* @since 1.3
|
853 |
+
*/
|
854 |
+
public function admin_notices() {
|
855 |
+
if ( isset( $_GET[ self::TEST_MAIL_ARG ] ) ) {// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
856 |
+
$screen = get_current_screen();
|
857 |
+
if ( in_array( $screen->post_type, array( self::POST_TYPE ), true ) ) {
|
858 |
+
?>
|
859 |
+
<div class="updated below-h2">
|
860 |
+
<p><?php echo esc_html__( 'Test Notification Sent.', 'bnfw' ); ?></p>
|
861 |
+
</div>
|
862 |
+
<?php
|
863 |
+
}
|
864 |
+
}
|
865 |
+
}
|
866 |
+
|
867 |
+
/**
|
868 |
+
* Save settings in post meta.
|
869 |
+
*
|
870 |
+
* @since 1.0
|
871 |
+
* @access private
|
872 |
+
*
|
873 |
+
* @param int $post_id Post id.
|
874 |
+
* @param array $setting An arraif settings options.
|
875 |
+
*/
|
876 |
+
private function save_settings( $post_id, $setting ) {
|
877 |
+
foreach ( $setting as $key => $value ) {
|
878 |
+
update_post_meta( $post_id, self::META_KEY_PREFIX . $key, $value );
|
879 |
+
}
|
880 |
+
}
|
881 |
+
|
882 |
+
/**
|
883 |
+
* Read settings from post meta.
|
884 |
+
*
|
885 |
+
* @since 1.0
|
886 |
+
*
|
887 |
+
* @param int $post_id Pota id.
|
888 |
+
*
|
889 |
+
* @return array
|
890 |
+
*/
|
891 |
+
public function read_settings( $post_id ) {
|
892 |
+
$setting = array();
|
893 |
+
$default = array(
|
894 |
+
'notification' => '',
|
895 |
+
'from-name' => '',
|
896 |
+
'from-email' => '',
|
897 |
+
'reply-name' => '',
|
898 |
+
'reply-email' => '',
|
899 |
+
'cc' => array(),
|
900 |
+
'bcc' => array(),
|
901 |
+
'users' => array(),
|
902 |
+
'exclude-users' => array(),
|
903 |
+
'subject' => '',
|
904 |
+
'email-formatting' => get_option( 'bnfw_email_format', 'html' ),
|
905 |
+
'message' => '',
|
906 |
+
'show-fields' => 'false',
|
907 |
+
'disable-current-user' => 'false',
|
908 |
+
'disable-autop' => 'false',
|
909 |
+
'only-post-author' => 'false',
|
910 |
+
'disabled' => 'false',
|
911 |
+
);
|
912 |
+
|
913 |
+
$default = apply_filters( 'bnfw_notification_setting_fields', $default );
|
914 |
+
|
915 |
+
foreach ( $default as $key => $default_value ) {
|
916 |
+
$value = get_post_meta( $post_id, self::META_KEY_PREFIX . $key, true );
|
917 |
+
if ( ! empty( $value ) ) {
|
918 |
+
$setting[ $key ] = $value;
|
919 |
+
} else {
|
920 |
+
$setting[ $key ] = $default_value;
|
921 |
+
}
|
922 |
+
}
|
923 |
+
|
924 |
+
// Compatibility code. This will be removed subsequently.
|
925 |
+
$user_roles = get_post_meta( $post_id, self::META_KEY_PREFIX . 'user-roles', true );
|
926 |
+
if ( ! empty( $user_roles ) && is_array( $user_roles ) ) {
|
927 |
+
foreach ( $user_roles as $role ) {
|
928 |
+
$setting['users'][] = 'role-' . $role;
|
929 |
+
}
|
930 |
+
|
931 |
+
update_post_meta( $post_id, self::META_KEY_PREFIX . 'users', $setting['users'] );
|
932 |
+
delete_post_meta( $post_id, self::META_KEY_PREFIX . 'user-roles' );
|
933 |
+
}
|
934 |
+
|
935 |
+
$setting['id'] = $post_id;
|
936 |
+
|
937 |
+
return $setting;
|
938 |
+
}
|
939 |
+
|
940 |
+
/**
|
941 |
+
* Change the post updated message for notification post type.
|
942 |
+
*
|
943 |
+
* @since 1.0
|
944 |
+
*
|
945 |
+
* @param array $messages Post updated messages.
|
946 |
+
*
|
947 |
+
* @return mixed
|
948 |
+
*/
|
949 |
+
public function post_updated_messages( $messages ) {
|
950 |
+
$messages[ self::POST_TYPE ] = array_fill( 0, 11, esc_html__( 'Notification saved.', 'bnfw' ) );
|
951 |
+
|
952 |
+
return $messages;
|
953 |
+
}
|
954 |
+
|
955 |
+
/**
|
956 |
+
* Render submit div meta box.
|
957 |
+
*
|
958 |
+
* @since 1.0
|
959 |
+
*
|
960 |
+
* @param $post WP_Post $post The post object.
|
961 |
+
*/
|
962 |
+
public function render_submitdiv( $post ) {
|
963 |
+
global $post;
|
964 |
+
?>
|
965 |
+
<div class="submitbox" id="submitpost">
|
966 |
+
|
967 |
+
<?php // Hidden submit button early on so that the browser chooses the right button when form is submitted with Return key. ?>
|
968 |
+
<div style="display:none;">
|
969 |
+
<?php submit_button( esc_html__( 'Save', 'bnfw' ), 'button', 'save' ); ?>
|
970 |
+
</div>
|
971 |
+
|
972 |
+
<?php // Always publish. ?>
|
973 |
+
<div class="disable-notification-checkbox" style="padding: 5px 0 10px 0;">
|
974 |
+
<div class="bnfw-help-tip-container">
|
975 |
+
<input type="hidden" name="post_status" id="hidden_post_status" value="publish">
|
976 |
+
|
977 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'Use this to enable or disable notifications. If you want to disable a default WordPress notification, just create it on the left, then disable it here.', 'bnfw' ); ?></p></div>
|
978 |
+
|
979 |
+
<?php
|
980 |
+
$setting = $this->read_settings( $post->ID );
|
981 |
+
?>
|
982 |
+
<label>
|
983 |
+
<input type="radio" name="disabled"
|
984 |
+
value="false" <?php checked( $setting['disabled'], 'false', true ); ?>><?php esc_html_e( 'Notification Enabled', 'bnfw' ); ?>
|
985 |
+
</label>
|
986 |
+
|
987 |
+
<br>
|
988 |
+
|
989 |
+
<label>
|
990 |
+
<input type="radio" name="disabled"
|
991 |
+
value="true" <?php checked( $setting['disabled'], 'true', true ); ?>><?php esc_html_e( 'Notification Disabled', 'bnfw' ); ?>
|
992 |
+
</label>
|
993 |
+
</div>
|
994 |
+
|
995 |
+
<br>
|
996 |
+
<br>
|
997 |
+
|
998 |
+
<?php if ( 'publish' === $post->post_status ) { ?>
|
999 |
+
<div class="bnfw-help-tip-container">
|
1000 |
+
<input type="hidden" name="send-test-email" id="send-test-email" value="false">
|
1001 |
+
<input name="test-email" type="submit" class="button button-secondary button-large" id="test-email"
|
1002 |
+
value="<?php esc_attr_e( 'Send Me a Test Email', 'bnfw' ); ?>">
|
1003 |
+
|
1004 |
+
<div class="bnfw-help-tip"><p><?php esc_html_e( 'This will send you (the currently logged in user) a notification so that you can check for any issues with formatting – it’s doesn\'t mean that a notification will send correctly in the future. You can read about how to improve email delivery', 'bnfw' ); ?> <a href="https://betternotificationsforwp.com/documentation/getting-started/how-to-improve-email-delivery/" target="_blank"><?php esc_html_e( 'here', 'bnfw' ); ?></a><?php esc_html_e( '. Shortcodes will not be replaced with content.', 'bnfw' ); ?></p></div>
|
1005 |
+
</div>
|
1006 |
+
<?php } ?>
|
1007 |
+
|
1008 |
+
</div>
|
1009 |
+
|
1010 |
+
<div id="major-publishing-actions">
|
1011 |
+
|
1012 |
+
<div id="delete-action">
|
1013 |
+
<?php
|
1014 |
+
if ( ! EMPTY_TRASH_DAYS ) {
|
1015 |
+
$delete_text = esc_html__( 'Delete Permanently', 'bnfw' );
|
1016 |
+
} else {
|
1017 |
+
$delete_text = esc_html__( 'Move to Trash', 'bnfw' );
|
1018 |
+
}
|
1019 |
+
?>
|
1020 |
+
<a class="submitdelete deletion"
|
1021 |
+
href="<?php echo esc_url( get_delete_post_link( $post->ID ) ); ?>"><?php echo esc_html( $delete_text ); ?></a>
|
1022 |
+
</div>
|
1023 |
+
|
1024 |
+
<div id="publishing-action">
|
1025 |
+
<span class="spinner"></span>
|
1026 |
+
<input name="original_publish" type="hidden" id="original_publish"
|
1027 |
+
value="<?php esc_attr_e( 'Save', 'bnfw' ); ?>">
|
1028 |
+
<input name="save" type="submit" class="button button-primary button-large" id="publish"
|
1029 |
+
accesskey="p" value="<?php esc_attr_e( 'Save', 'bnfw' ); ?>">
|
1030 |
+
</div>
|
1031 |
+
<div class="clear"></div>
|
1032 |
+
|
1033 |
+
</div>
|
1034 |
+
<!-- #major-publishing-actions -->
|
1035 |
+
|
1036 |
+
<div class="clear"></div>
|
1037 |
+
</div>
|
1038 |
+
<!-- #submitpost -->
|
1039 |
+
<?php
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
/**
|
1043 |
+
* Get notifications based on type.
|
1044 |
+
*
|
1045 |
+
* @since 1.0
|
1046 |
+
*
|
1047 |
+
* @param array|string $types Notification Type.
|
1048 |
+
* @param bool $exclude_disabled (optional) Whether to exclude disabled notifications or not. True by default.
|
1049 |
+
*
|
1050 |
+
* @return array WP_Post objects
|
1051 |
+
*/
|
1052 |
+
public function get_notifications( $types = array(), $exclude_disabled = true ) {
|
1053 |
+
if ( ! is_array( $types ) ) {
|
1054 |
+
$types = array( $types );
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
$args = array(
|
1058 |
+
'post_type' => self::POST_TYPE,
|
1059 |
+
);
|
1060 |
+
|
1061 |
+
$meta_query = array();
|
1062 |
+
|
1063 |
+
if ( ! empty( $types ) ) {
|
1064 |
+
$meta_query[] = array(
|
1065 |
+
'key' => self::META_KEY_PREFIX . 'notification',
|
1066 |
+
'value' => $types,
|
1067 |
+
'compare' => 'IN',
|
1068 |
+
);
|
1069 |
+
}
|
1070 |
+
|
1071 |
+
if ( $exclude_disabled ) {
|
1072 |
+
$meta_query[] = array(
|
1073 |
+
'key' => self::META_KEY_PREFIX . 'disabled',
|
1074 |
+
'value' => 'true',
|
1075 |
+
'compare' => '!=',
|
1076 |
+
);
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
if ( ! empty( $meta_query ) ) {
|
1080 |
+
$args['meta_query'] = $meta_query;
|
1081 |
+
}
|
1082 |
+
|
1083 |
+
$args['posts_per_page'] = -1;
|
1084 |
+
$args['nopagging'] = true;
|
1085 |
+
|
1086 |
+
$args = apply_filters( 'bnfw_get_notifications_args', $args, $types, $exclude_disabled );
|
1087 |
+
|
1088 |
+
$wp_query = new WP_Query();
|
1089 |
+
$posts = $wp_query->query( $args );
|
1090 |
+
|
1091 |
+
$posts = apply_filters( 'bnfw_get_notifications_posts', $posts, $args, $types, $exclude_disabled );
|
1092 |
+
|
1093 |
+
return $posts;
|
1094 |
+
}
|
1095 |
+
|
1096 |
+
/**
|
1097 |
+
* Are there any disabled notifications for a particular notification type.
|
1098 |
+
*
|
1099 |
+
* @param string $type Notification type.
|
1100 |
+
*
|
1101 |
+
* @return bool True if disabled, False otherwise.
|
1102 |
+
*/
|
1103 |
+
public function is_notification_disabled( $type ) {
|
1104 |
+
$args = array(
|
1105 |
+
'post_type' => self::POST_TYPE,
|
1106 |
+
'posts_per_page' => - 1,
|
1107 |
+
'nopagging' => true,
|
1108 |
+
'fields' => 'ids',
|
1109 |
+
'meta_query' => array(
|
1110 |
+
array(
|
1111 |
+
'key' => self::META_KEY_PREFIX . 'notification',
|
1112 |
+
'value' => $type,
|
1113 |
+
),
|
1114 |
+
array(
|
1115 |
+
'key' => self::META_KEY_PREFIX . 'disabled',
|
1116 |
+
'value' => 'true',
|
1117 |
+
),
|
1118 |
+
),
|
1119 |
+
);
|
1120 |
+
|
1121 |
+
$args = apply_filters( 'bnfw_is_notification_disabled_args', $args, $type );
|
1122 |
+
|
1123 |
+
$wp_query = new WP_Query();
|
1124 |
+
$posts = $wp_query->query( $args );
|
1125 |
+
|
1126 |
+
$posts = apply_filters( 'bnfw_is_notification_disabled_posts', $posts, $args, $type );
|
1127 |
+
|
1128 |
+
return count( $posts ) > 0;
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
/**
|
1132 |
+
* Does a particular type of notification exists or not.
|
1133 |
+
*
|
1134 |
+
* @since 1.1
|
1135 |
+
*
|
1136 |
+
* @param string $type Notification Type.
|
1137 |
+
* @param bool $exclude_disabled (optional) Whether to exclude disabled notifications or not. True by default.
|
1138 |
+
*
|
1139 |
+
* @return bool True if present, False otherwise
|
1140 |
+
*/
|
1141 |
+
public function notification_exists( $type, $exclude_disabled = true ) {
|
1142 |
+
$notifications = $this->get_notifications( $type, $exclude_disabled );
|
1143 |
+
|
1144 |
+
if ( count( $notifications ) > 0 ) {
|
1145 |
+
return true;
|
1146 |
+
} else {
|
1147 |
+
return false;
|
1148 |
+
}
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
/**
|
1152 |
+
* Custom columns for this post type.
|
1153 |
+
*
|
1154 |
+
* @since 1.0
|
1155 |
+
* @filter manage_{post_type}_posts_columns
|
1156 |
+
*
|
1157 |
+
* @param array $columns The name of the column to display.
|
1158 |
+
*
|
1159 |
+
* @return array
|
1160 |
+
*/
|
1161 |
+
public function columns_header( $columns ) {
|
1162 |
+
$columns['type'] = esc_html__( 'Notification Type', 'bnfw' );
|
1163 |
+
$columns['disabled'] = esc_html__( 'Enabled?', 'bnfw' );
|
1164 |
+
$columns['subject'] = esc_html__( 'Subject', 'bnfw' );
|
1165 |
+
$columns['users'] = esc_html__( 'User Roles / Users', 'bnfw' );
|
1166 |
+
$columns['excluded'] = esc_html__( 'Excluded User Roles / Users', 'bnfw' );
|
1167 |
+
|
1168 |
+
return $columns;
|
1169 |
+
}
|
1170 |
+
|
1171 |
+
/**
|
1172 |
+
* Custom column appears in each row.
|
1173 |
+
*
|
1174 |
+
* @since 1.0
|
1175 |
+
* @action manage_{post_type}_posts_custom_column
|
1176 |
+
*
|
1177 |
+
* @param string $column Column name.
|
1178 |
+
* @param int $post_id Post ID.
|
1179 |
+
*/
|
1180 |
+
public function custom_column_row( $column, $post_id ) {
|
1181 |
+
$setting = $this->read_settings( $post_id );
|
1182 |
+
switch ( $column ) {
|
1183 |
+
case 'disabled':
|
1184 |
+
if ( 'true' !== $setting['disabled'] ) {
|
1185 |
+
printf( '<span class="dashicons dashicons-yes"></span>' );
|
1186 |
+
}
|
1187 |
+
break;
|
1188 |
+
case 'type':
|
1189 |
+
echo wp_kses_post( $this->get_notification_name( $setting['notification'] ) );
|
1190 |
+
break;
|
1191 |
+
case 'subject':
|
1192 |
+
echo wp_kses_post( ! empty( $setting['subject'] ) ? $setting['subject'] : '' );
|
1193 |
+
break;
|
1194 |
+
case 'users':
|
1195 |
+
$users = $this->get_names_from_users( $setting['users'] );
|
1196 |
+
if ( ! empty( $users ) ) {
|
1197 |
+
echo wp_kses_post( implode( ', ', $users ) );
|
1198 |
+
} else {
|
1199 |
+
if ( isset( $setting['new-user-role'] ) ) {
|
1200 |
+
$users = $this->get_names_from_users( $setting['new-user-role'] );
|
1201 |
+
echo wp_kses_post( implode( ', ', $users ) );
|
1202 |
+
}
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
if ( 'true' === $setting['only-post-author'] ) {
|
1206 |
+
echo esc_html__( ', Post Author', 'bnfw' );
|
1207 |
+
}
|
1208 |
+
|
1209 |
+
break;
|
1210 |
+
case 'excluded':
|
1211 |
+
$excluded_users = $this->get_names_from_users( $setting['exclude-users'] );
|
1212 |
+
echo wp_kses_post( implode( ', ', $excluded_users ) );
|
1213 |
+
|
1214 |
+
break;
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
/**
|
1218 |
+
* Invoked while displaying a custom column in notification table.
|
1219 |
+
*
|
1220 |
+
* @since 1.3.9
|
1221 |
+
*
|
1222 |
+
* @param string $column Column name
|
1223 |
+
* @param int $post_id Post ID
|
1224 |
+
*/
|
1225 |
+
do_action( 'bnfw_notification_table_column', $column, $post_id );
|
1226 |
+
}
|
1227 |
+
|
1228 |
+
/**
|
1229 |
+
* Get names from users.
|
1230 |
+
*
|
1231 |
+
* @since 1.2
|
1232 |
+
* @param array $users Users.
|
1233 |
+
*/
|
1234 |
+
private function get_names_from_users( $users ) {
|
1235 |
+
$user_ids = array();
|
1236 |
+
$user_roles = array();
|
1237 |
+
$emails = array();
|
1238 |
+
$names_from_user_ids = array();
|
1239 |
+
|
1240 |
+
if ( is_array( $users ) ) {
|
1241 |
+
foreach ( $users as $user ) {
|
1242 |
+
if ( $this->starts_with( $user, 'role-' ) ) {
|
1243 |
+
$user_roles[] = ucfirst( str_replace( 'role-', '', $user ) );
|
1244 |
+
} elseif ( strpos( $user, '@' ) !== false ) {
|
1245 |
+
$emails[] = $user;
|
1246 |
+
} elseif ( absint( $user ) > 0 ) {
|
1247 |
+
$user_ids[] = absint( $user );
|
1248 |
+
} else {
|
1249 |
+
$emails[] = $user;
|
1250 |
+
}
|
1251 |
+
}
|
1252 |
+
} else {
|
1253 |
+
// User Roles not associated with a To/CC/BCC field.
|
1254 |
+
$role = get_role( $users );
|
1255 |
+
|
1256 |
+
if ( ! empty( $role ) ) {
|
1257 |
+
$user_roles = array( $role->name );
|
1258 |
+
}
|
1259 |
+
}
|
1260 |
+
|
1261 |
+
if ( ! empty( $user_ids ) ) {
|
1262 |
+
$user_query = new WP_User_Query( array( 'include' => $user_ids ) );
|
1263 |
+
foreach ( $user_query->results as $user ) {
|
1264 |
+
$names_from_user_ids[] = $user->user_login;
|
1265 |
+
}
|
1266 |
+
}
|
1267 |
+
|
1268 |
+
return array_merge( $user_roles, $names_from_user_ids, $emails );
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
/**
|
1272 |
+
* Get name of the notification based on slug.
|
1273 |
+
*
|
1274 |
+
* @param string $slug Notification Slug.
|
1275 |
+
*
|
1276 |
+
* @return string Notification Name.
|
1277 |
+
*/
|
1278 |
+
private function get_notification_name( $slug ) {
|
1279 |
+
$name = '';
|
1280 |
+
switch ( $slug ) {
|
1281 |
+
case 'new-comment':
|
1282 |
+
$name = esc_html__( 'New Comment', 'bnfw' );
|
1283 |
+
break;
|
1284 |
+
case 'approve-post-comment':
|
1285 |
+
$name = esc_html__( 'Post - Comment Approved', 'bnfw' );
|
1286 |
+
break;
|
1287 |
+
case 'moderate-comment':
|
1288 |
+
$name = esc_html__( 'New Comment Awaiting Moderation', 'bnfw' );
|
1289 |
+
break;
|
1290 |
+
case 'new-trackback':
|
1291 |
+
$name = esc_html__( 'New Trackback', 'bnfw' );
|
1292 |
+
break;
|
1293 |
+
case 'new-pingback':
|
1294 |
+
$name = esc_html__( 'New Pingback', 'bnfw' );
|
1295 |
+
break;
|
1296 |
+
case 'reply-comment':
|
1297 |
+
$name = esc_html__( 'Comment Reply', 'bnfw' );
|
1298 |
+
break;
|
1299 |
+
case 'user-password':
|
1300 |
+
$name = esc_html__( 'User Lost Password - For User', 'bnfw' );
|
1301 |
+
break;
|
1302 |
+
case 'admin-password':
|
1303 |
+
$name = esc_html__( 'User Lost Password - For Admin', 'bnfw' );
|
1304 |
+
break;
|
1305 |
+
case 'admin-password-changed':
|
1306 |
+
$name = esc_html__( 'Password Changed - For Admin', 'bnfw' );
|
1307 |
+
break;
|
1308 |
+
case 'admin-email-changed':
|
1309 |
+
$name = esc_html__( 'User Email Changed - For Admin', 'bnfw' );
|
1310 |
+
break;
|
1311 |
+
case 'password-changed':
|
1312 |
+
$name = esc_html__( 'Password Changed - For User', 'bnfw' );
|
1313 |
+
break;
|
1314 |
+
case 'email-changing':
|
1315 |
+
$name = esc_html__( 'User Email Changed Confirmation - For User', 'bnfw' );
|
1316 |
+
break;
|
1317 |
+
case 'email-changed':
|
1318 |
+
$name = esc_html__( 'User Email Changed - For User', 'bnfw' );
|
1319 |
+
break;
|
1320 |
+
case 'core-updated':
|
1321 |
+
$name = esc_html__( 'WordPress Core Automatic Background Updates', 'bnfw' );
|
1322 |
+
break;
|
1323 |
+
case 'new-user':
|
1324 |
+
$name = esc_html__( 'New User Registration - For User', 'bnfw' );
|
1325 |
+
break;
|
1326 |
+
case 'user-login':
|
1327 |
+
$name = esc_html__( 'User Logged In - For User', 'bnfw' );
|
1328 |
+
break;
|
1329 |
+
case 'admin-user-login':
|
1330 |
+
$name = esc_html__( 'User Logged In - For Admin', 'bnfw' );
|
1331 |
+
break;
|
1332 |
+
case 'welcome-email':
|
1333 |
+
$name = esc_html__( 'New User - Post-registration Email', 'bnfw' );
|
1334 |
+
break;
|
1335 |
+
case 'admin-user':
|
1336 |
+
$name = esc_html__( 'New User Registration - For Admin', 'bnfw' );
|
1337 |
+
break;
|
1338 |
+
case 'user-role':
|
1339 |
+
$name = esc_html__( 'User Role Changed - For User', 'bnfw' );
|
1340 |
+
break;
|
1341 |
+
case 'admin-role':
|
1342 |
+
$name = esc_html__( 'User Role Changed - For Admin', 'bnfw' );
|
1343 |
+
break;
|
1344 |
+
case 'new-post':
|
1345 |
+
$name = esc_html__( 'New Post Published', 'bnfw' );
|
1346 |
+
break;
|
1347 |
+
case 'update-post':
|
1348 |
+
$name = esc_html__( 'Post Updated', 'bnfw' );
|
1349 |
+
break;
|
1350 |
+
case 'pending-post':
|
1351 |
+
$name = esc_html__( 'Post Pending Review', 'bnfw' );
|
1352 |
+
break;
|
1353 |
+
case 'private-post':
|
1354 |
+
$name = esc_html__( 'New Private Post', 'bnfw' );
|
1355 |
+
break;
|
1356 |
+
case 'future-post':
|
1357 |
+
$name = esc_html__( 'Post Scheduled', 'bnfw' );
|
1358 |
+
break;
|
1359 |
+
case 'trash-post':
|
1360 |
+
$name = esc_html__( 'Published Post Moved to Trash', 'bnfw' );
|
1361 |
+
break;
|
1362 |
+
case 'new-page':
|
1363 |
+
$name = esc_html__( 'New Page Published', 'bnfw' );
|
1364 |
+
break;
|
1365 |
+
case 'newterm-category':
|
1366 |
+
$name = esc_html__( 'New Category', 'bnfw' );
|
1367 |
+
break;
|
1368 |
+
case 'newterm-post_tag':
|
1369 |
+
$name = esc_html__( 'New Tag', 'bnfw' );
|
1370 |
+
break;
|
1371 |
+
case 'ca-export-data':
|
1372 |
+
$name = esc_html__( 'Privacy – Confirm Action: Export Data Request – For User', 'bnfw' );
|
1373 |
+
break;
|
1374 |
+
case 'ca-erase-data':
|
1375 |
+
$name = esc_html__( 'Privacy – Confirm Action: Erase Data Request – For User', 'bnfw' );
|
1376 |
+
break;
|
1377 |
+
case 'uc-export-data':
|
1378 |
+
$name = esc_html__( 'Privacy - Confirm Action: Export Data Request - For Admin', 'bnfw' );
|
1379 |
+
break;
|
1380 |
+
case 'uc-erase-data':
|
1381 |
+
$name = esc_html__( 'Privacy - Confirm Action: Erase Data Request - For Admin', 'bnfw' );
|
1382 |
+
break;
|
1383 |
+
case 'data-export':
|
1384 |
+
$name = esc_html__( 'Privacy - Data Export - For User', 'bnfw' );
|
1385 |
+
break;
|
1386 |
+
case 'data-erased':
|
1387 |
+
$name = esc_html__( 'Privacy - Data Erased - For User', 'bnfw' );
|
1388 |
+
break;
|
1389 |
+
case 'new-media':
|
1390 |
+
$name = esc_html__( 'New Media Published', 'bnfw' );
|
1391 |
+
break;
|
1392 |
+
case 'update-media':
|
1393 |
+
$name = esc_html__( 'Media Updated', 'bnfw' );
|
1394 |
+
break;
|
1395 |
+
case 'comment-attachment':
|
1396 |
+
$name = esc_html__( 'Media - New Comment', 'bnfw' );
|
1397 |
+
break;
|
1398 |
+
case 'approve-page-comment':
|
1399 |
+
$name = esc_html__( 'Page - Comment Approved', 'bnfw' );
|
1400 |
+
break;
|
1401 |
+
case 'approve-attachment-comment':
|
1402 |
+
$name = esc_html__( 'Media - Comment Approved', 'bnfw' );
|
1403 |
+
break;
|
1404 |
+
case 'moderate-attachment-comment':
|
1405 |
+
$name = esc_html__( 'Media - New Comment Awaiting Moderation', 'bnfw' );
|
1406 |
+
break;
|
1407 |
+
case 'commentreply-attachment':
|
1408 |
+
$name = esc_html__( 'Media - Comment Reply', 'bnfw' );
|
1409 |
+
break;
|
1410 |
+
default:
|
1411 |
+
$splited = explode( '-', $slug );
|
1412 |
+
$label = $splited[1];
|
1413 |
+
$post_obj = get_post_type_object( $splited[1] );
|
1414 |
+
|
1415 |
+
if ( null !== $post_obj ) {
|
1416 |
+
$label = $post_obj->labels->singular_name;
|
1417 |
+
}
|
1418 |
+
|
1419 |
+
switch ( $splited[0] ) {
|
1420 |
+
case 'new':
|
1421 |
+
$name = esc_html__( 'New ', 'bnfw' ) . $label . ' ' . esc_html__( 'Published', 'bnfw' );
|
1422 |
+
break;
|
1423 |
+
case 'update':
|
1424 |
+
$name = esc_html__( 'Updated ', 'bnfw' ) . $label;
|
1425 |
+
break;
|
1426 |
+
case 'pending':
|
1427 |
+
$name = $label . esc_html__( ' Pending Review', 'bnfw' );
|
1428 |
+
break;
|
1429 |
+
case 'future':
|
1430 |
+
$name = $label . esc_html__( ' Scheduled', 'bnfw' );
|
1431 |
+
break;
|
1432 |
+
case 'private':
|
1433 |
+
$name = esc_html__( 'New Private ', 'bnfw' ) . $label;
|
1434 |
+
break;
|
1435 |
+
case 'comment':
|
1436 |
+
$name = $label . esc_html__( ' Comment', 'bnfw' );
|
1437 |
+
break;
|
1438 |
+
case 'moderate':
|
1439 |
+
$name = $label . ' - ' . esc_html__( 'New Comment Awaiting Moderation', 'bnfw' );
|
1440 |
+
break;
|
1441 |
+
case 'commentreply':
|
1442 |
+
$name = $label . esc_html__( ' Comment Reply', 'bnfw' );
|
1443 |
+
break;
|
1444 |
+
case 'approve':
|
1445 |
+
$name = $label . esc_html__( ' Comment Approved', 'bnfw' );
|
1446 |
+
break;
|
1447 |
+
case 'newterm':
|
1448 |
+
$tax = get_taxonomy( $splited[1] );
|
1449 |
+
if ( ! $tax ) {
|
1450 |
+
$name = esc_html__( 'New Term', 'bnfw' );
|
1451 |
+
} else {
|
1452 |
+
$name = esc_html__( 'New Term in ', 'bnfw' ) . $tax->labels->name;
|
1453 |
+
}
|
1454 |
+
break;
|
1455 |
+
}
|
1456 |
+
break;
|
1457 |
+
}
|
1458 |
+
|
1459 |
+
$name = apply_filters( 'bnfw_notification_name', $name, $slug );
|
1460 |
+
|
1461 |
+
return $name;
|
1462 |
+
}
|
1463 |
+
|
1464 |
+
/**
|
1465 |
+
* Add additional custom edit actions for enabling and disabling notifications in bulk.
|
1466 |
+
*
|
1467 |
+
* @param array $bulk_actions Bulk Actions.
|
1468 |
+
*
|
1469 |
+
* @return array Modified list of Bulk Actions.
|
1470 |
+
*/
|
1471 |
+
public function add_custom_edit_action( $bulk_actions ) {
|
1472 |
+
$bulk_actions['enable_notifications'] = __( 'Enable Notifications', 'bnfw' );
|
1473 |
+
$bulk_actions['disable_notifications'] = __( 'Disable Notifications', 'bnfw' );
|
1474 |
+
return $bulk_actions;
|
1475 |
+
}
|
1476 |
+
|
1477 |
+
/**
|
1478 |
+
* Handle custom edit actions.
|
1479 |
+
*
|
1480 |
+
* @param string $redirect_to The redirect URL.
|
1481 |
+
* @param string $doaction The action being taken.
|
1482 |
+
* @param array $post_ids The items to take the action on. Accepts an array of IDs of posts,
|
1483 |
+
* comments, terms, links, plugins, attachments, or users.
|
1484 |
+
*
|
1485 |
+
* @return string
|
1486 |
+
*/
|
1487 |
+
public function handle_custom_edit_action( $redirect_to, $doaction, $post_ids ) {
|
1488 |
+
if ( 'enable_notifications' !== $doaction && 'disable_notifications' !== $doaction ) {
|
1489 |
+
return $redirect_to;
|
1490 |
+
}
|
1491 |
+
|
1492 |
+
$redirect_to = remove_query_arg( array( 'bulk_enable_notifications', 'bulk_disable_notifications', 'bnfw_action' ), $redirect_to );
|
1493 |
+
|
1494 |
+
$meta_value = 'true';
|
1495 |
+
|
1496 |
+
if ( 'enable_notifications' === $doaction ) {
|
1497 |
+
$meta_value = 'false';
|
1498 |
+
}
|
1499 |
+
|
1500 |
+
foreach ( $post_ids as $post_id ) {
|
1501 |
+
update_post_meta( $post_id, self::META_KEY_PREFIX . 'disabled', $meta_value );
|
1502 |
+
}
|
1503 |
+
|
1504 |
+
$redirect_to = add_query_arg( 'bulk_' . $doaction, count( $post_ids ), $redirect_to );
|
1505 |
+
|
1506 |
+
return $redirect_to;
|
1507 |
+
}
|
1508 |
+
|
1509 |
+
/**
|
1510 |
+
* Custom row actions for this post type.
|
1511 |
+
*
|
1512 |
+
* @since 1.0
|
1513 |
+
* @filter post_row_actions
|
1514 |
+
*
|
1515 |
+
* @param array $actions An array of row action links.
|
1516 |
+
* @param WP_Post $post The post object.
|
1517 |
+
*
|
1518 |
+
* @return array
|
1519 |
+
*/
|
1520 |
+
public function custom_row_actions( $actions, $post ) {
|
1521 |
+
if ( self::POST_TYPE === get_post_type( $post ) ) {
|
1522 |
+
unset( $actions['inline hide-if-no-js'] );
|
1523 |
+
unset( $actions['view'] );
|
1524 |
+
|
1525 |
+
$notification_disabled = get_post_meta( $post->ID, self::META_KEY_PREFIX . 'disabled', true );
|
1526 |
+
|
1527 |
+
if ( 'true' === $notification_disabled ) {
|
1528 |
+
$url = add_query_arg(
|
1529 |
+
array(
|
1530 |
+
'notification_id' => $post->ID,
|
1531 |
+
'bnfw_action' => 'enable_notification',
|
1532 |
+
)
|
1533 |
+
);
|
1534 |
+
$actions['enable_notification'] = '<a href="' . esc_url( $url ) . '">' . __( 'Enable Notification', 'bnfw' ) . '</a>';
|
1535 |
+
} else {
|
1536 |
+
$url = add_query_arg(
|
1537 |
+
array(
|
1538 |
+
'notification_id' => $post->ID,
|
1539 |
+
'bnfw_action' => 'disable_notification',
|
1540 |
+
)
|
1541 |
+
);
|
1542 |
+
$actions['disable_notification'] = '<a href="' . esc_url( $url ) . '">' . __( 'Disable Notification', 'bnfw' ) . '</a>';
|
1543 |
+
}
|
1544 |
+
}
|
1545 |
+
|
1546 |
+
return $actions;
|
1547 |
+
}
|
1548 |
+
|
1549 |
+
/**
|
1550 |
+
* Handle custom actions.
|
1551 |
+
*/
|
1552 |
+
public function handle_actions() {
|
1553 |
+
if ( ! isset( $_GET['bnfw_action'] ) || ! isset( $_GET['notification_id'] ) ) {// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1554 |
+
return;
|
1555 |
+
}
|
1556 |
+
|
1557 |
+
$post_id = absint( $_GET['notification_id'] );// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1558 |
+
if ( 0 === $post_id ) {
|
1559 |
+
return;
|
1560 |
+
}
|
1561 |
+
|
1562 |
+
$action = sanitize_text_field( $_GET['bnfw_action'] );// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
1563 |
+
|
1564 |
+
if ( 'enable_notification' === $action ) {
|
1565 |
+
update_post_meta( $post_id, self::META_KEY_PREFIX . 'disabled', 'false' );
|
1566 |
+
}
|
1567 |
+
|
1568 |
+
if ( 'disable_notification' === $action ) {
|
1569 |
+
update_post_meta( $post_id, self::META_KEY_PREFIX . 'disabled', 'true' );
|
1570 |
+
}
|
1571 |
+
}
|
1572 |
+
|
1573 |
+
/**
|
1574 |
+
* Find if a string starts with another string.
|
1575 |
+
*
|
1576 |
+
* @since 1.2
|
1577 |
+
*
|
1578 |
+
* @param string $haystack The string to search in.
|
1579 |
+
* @param string $needle The substring to search for in the haystack.
|
1580 |
+
*
|
1581 |
+
* @return bool
|
1582 |
+
*/
|
1583 |
+
public function starts_with( $haystack, $needle ) {
|
1584 |
+
// search backwards starting from haystack length characters from the end.
|
1585 |
+
return '' === $needle || strrpos( $haystack, $needle, - strlen( $haystack ) ) !== false;
|
1586 |
+
}
|
1587 |
+
|
1588 |
+
/**
|
1589 |
+
* Display a help notice.
|
1590 |
+
*
|
1591 |
+
* @since 1.7
|
1592 |
+
*/
|
1593 |
+
public function show_help_notice() {
|
1594 |
+
$screen = get_current_screen();
|
1595 |
+
if ( ! in_array( $screen->post_type, array( self::POST_TYPE ), true ) ) {
|
1596 |
+
return;
|
1597 |
+
}
|
1598 |
+
|
1599 |
+
if ( ! empty( $_REQUEST['bnfw_action'] ) && 'enable_notification' === $_REQUEST['bnfw_action'] ) {// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1600 |
+
echo wp_kses_post( '<div id="message" class="updated fade"><p>' . __( 'Enabled 1 Notification.', 'bnfw' ) . '</p></div>' );
|
1601 |
+
}
|
1602 |
+
|
1603 |
+
if ( ! empty( $_REQUEST['bnfw_action'] ) && 'disable_notification' === $_REQUEST['bnfw_action'] ) {// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1604 |
+
echo wp_kses_post( '<div id="message" class="updated fade"><p>' . __( 'Disabled 1 Notification.', 'bnfw' ) . '</p></div>' );
|
1605 |
+
}
|
1606 |
+
|
1607 |
+
if ( ! empty( $_REQUEST['bulk_enable_notifications'] ) ) {// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1608 |
+
$enabled_count = intval( $_REQUEST['bulk_enable_notifications'] );// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1609 |
+
printf(
|
1610 |
+
wp_kses_post(
|
1611 |
+
'<div id="message" class="updated fade"><p>' .
|
1612 |
+
/* translators: %s: enabled notification count */
|
1613 |
+
_n(
|
1614 |
+
'Enabled %s Notification.',
|
1615 |
+
'Enabled %s Notifications.',
|
1616 |
+
$enabled_count,
|
1617 |
+
'bnfw'
|
1618 |
+
) . '</p></div>',
|
1619 |
+
$enabled_count
|
1620 |
+
)
|
1621 |
+
);
|
1622 |
+
}
|
1623 |
+
|
1624 |
+
if ( ! empty( $_REQUEST['bulk_disable_notifications'] ) ) {// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1625 |
+
$disabled_count = intval( $_REQUEST['bulk_disable_notifications'] );// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
1626 |
+
printf(
|
1627 |
+
wp_kses_post(
|
1628 |
+
'<div id="message" class="updated fade"><p>' .
|
1629 |
+
/* translators: %s: disabled notification count */
|
1630 |
+
_n(
|
1631 |
+
'Disabled %s Notification.',
|
1632 |
+
'Disabled %s Notifications.',
|
1633 |
+
$disabled_count,
|
1634 |
+
'bnfw'
|
1635 |
+
) . '</p></div>',
|
1636 |
+
$disabled_count
|
1637 |
+
)
|
1638 |
+
);
|
1639 |
+
}
|
1640 |
+
|
1641 |
+
if ( ! PAnD::is_admin_notice_active( 'disable-bnfw-help-notice-forever' ) ) {
|
1642 |
+
return;
|
1643 |
+
}
|
1644 |
+
|
1645 |
+
?>
|
1646 |
+
<div data-dismissible="disable-bnfw-help-notice-forever" class="updated notice notice-success is-dismissible">
|
1647 |
+
<p>
|
1648 |
+
<?php echo wp_kses_post( __( 'If you send out notifications with BNFW but don\'t receive them, you may need to install an SMTP plugin to <a href="https://betternotificationsforwp.com/documentation/getting-started/how-to-improve-email-delivery/" target="_blank">improve email deliverability</a>. I recommend using <a href="https://wordpress.org/plugins/post-smtp/" target="_blank">Post SMTP</a> as it\'s easy to set-up or <a href="https://wordpress.org/plugins/email-log/" target="_blank">Email Log</a> to just log and view emails that are sent.', 'bnfw' ) ); ?>
|
1649 |
+
</p>
|
1650 |
+
</div>
|
1651 |
+
<?php
|
1652 |
+
}
|
1653 |
+
|
1654 |
+
/**
|
1655 |
+
* Should the users count message be shown?
|
1656 |
+
*
|
1657 |
+
* @since 1.7
|
1658 |
+
*
|
1659 |
+
* @param array $setting Notification Setting.
|
1660 |
+
*
|
1661 |
+
* @return bool True if message should be shown.
|
1662 |
+
*/
|
1663 |
+
protected function should_show_users_count_msg( $setting ) {
|
1664 |
+
$users = $setting['users'];
|
1665 |
+
|
1666 |
+
if ( count( $users ) > 200 ) {
|
1667 |
+
return true;
|
1668 |
+
}
|
1669 |
+
|
1670 |
+
$emails = BNFW::factory()->engine->get_emails_from_users( $users );
|
1671 |
+
|
1672 |
+
if ( count( $emails ) > 200 ) {
|
1673 |
+
return true;
|
1674 |
+
}
|
1675 |
+
|
1676 |
+
return false;
|
1677 |
+
}
|
1678 |
+
}
|
1679 |
+
}
|
includes/admin/class-bnfw-settings.php
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Register the Admin pages and load the scripts action
|
4 |
+
*
|
5 |
+
* @since 1.0
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit;
|
10 |
+
|
11 |
+
if ( ! class_exists( 'BNFW_Settings', false ) ) {
|
12 |
+
/**
|
13 |
+
* BNFW Notification class.
|
14 |
+
*/
|
15 |
+
class BNFW_Settings {
|
16 |
+
/**
|
17 |
+
* Class contructor.
|
18 |
+
*/
|
19 |
+
public function __construct() {
|
20 |
+
add_action( 'admin_menu', array( $this, 'bnfw_admin_menu' ) );
|
21 |
+
add_action( 'admin_menu', array( $this, 'bnfw_menu_item_links' ), 12 );
|
22 |
+
add_action( 'admin_head', array( $this, 'bnfw_menu_item_link_targets' ) );
|
23 |
+
add_action( 'admin_init', array( $this, 'bnfw_general_options' ), 10 );
|
24 |
+
}
|
25 |
+
/**
|
26 |
+
* Sub-menu pages.
|
27 |
+
*/
|
28 |
+
public function bnfw_admin_menu() {
|
29 |
+
// New Notifications Sub-menu.
|
30 |
+
add_submenu_page(
|
31 |
+
'edit.php?post_type=bnfw_notification',
|
32 |
+
esc_html__( 'Notification Settings', 'bnfw' ),
|
33 |
+
esc_html__( 'Settings', 'bnfw' ),
|
34 |
+
'bnfw',
|
35 |
+
'bnfw-settings',
|
36 |
+
array( $this, 'bnfw_settings_page' )
|
37 |
+
);
|
38 |
+
}
|
39 |
+
/**
|
40 |
+
* Settings Page
|
41 |
+
*/
|
42 |
+
public function bnfw_settings_page() {
|
43 |
+
ob_start(); ?>
|
44 |
+
|
45 |
+
<div class="wrap">
|
46 |
+
<h2><?php esc_html_e( 'BNFW Settings', 'bnfw' ); ?></h2>
|
47 |
+
|
48 |
+
<form method="post" action="options.php" class="bnfw-form">
|
49 |
+
<?php
|
50 |
+
settings_errors();
|
51 |
+
settings_fields( 'bnfw-settings' );
|
52 |
+
do_settings_sections( 'bnfw-settings' );
|
53 |
+
|
54 |
+
submit_button( __( 'Save Settings', 'bnfw' ) );
|
55 |
+
?>
|
56 |
+
</form>
|
57 |
+
</div>
|
58 |
+
|
59 |
+
<?php
|
60 |
+
echo ob_get_clean(); // phpcs:ignore
|
61 |
+
}
|
62 |
+
/**
|
63 |
+
* External Menu Item Links
|
64 |
+
*/
|
65 |
+
public function bnfw_menu_item_links() {
|
66 |
+
global $submenu;
|
67 |
+
|
68 |
+
if ( current_user_can( 'bnfw' ) ) {
|
69 |
+
$doc_url = 'https://betternotificationsforwp.com/documentation/';
|
70 |
+
$store_url = 'https://betternotificationsforwp.com/downloads/';
|
71 |
+
$support_url = 'https://betternotificationsforwp.com/priority-support/';
|
72 |
+
|
73 |
+
if ( bnfw_is_tracking_allowed() ) {
|
74 |
+
$doc_url .= '?utm_source=WP%20Admin%20Submenu%20Item%20-%20"Documentation"&utm_medium=referral';
|
75 |
+
$store_url .= '?utm_source=WP%20Admin%20Submenu%20Item%20-%20"Add-on"&utm_medium=referral';
|
76 |
+
$support_url .= '?utm_source=WP%20Admin%20Submenu%20Item%20-%20"Priority%20Support"&utm_medium=referral';
|
77 |
+
}
|
78 |
+
|
79 |
+
// Documentation Link.
|
80 |
+
$submenu['edit.php?post_type=bnfw_notification'][500] = array(// phpcs:ignore
|
81 |
+
'<div id="bnfw-menu-item-documentation" style="color: #73daeb;">' . __( 'Documentation', 'bnfw' ) . '</div>',
|
82 |
+
'bnfw',
|
83 |
+
$doc_url,
|
84 |
+
);
|
85 |
+
|
86 |
+
// Add-ons Link.
|
87 |
+
$submenu['edit.php?post_type=bnfw_notification'][600] = array(// phpcs:ignore
|
88 |
+
'<div id="bnfw-menu-item-addons" style="color: #ff6f59;">' . __( 'Premium Add-ons', 'bnfw' ) . '</div>',
|
89 |
+
'bnfw',
|
90 |
+
$store_url,
|
91 |
+
);
|
92 |
+
|
93 |
+
// Add-ons Link.
|
94 |
+
$submenu['edit.php?post_type=bnfw_notification'][700] = array(// phpcs:ignore
|
95 |
+
'<div id="bnfw-menu-item-support" style="color: #f00001;">' . __( 'Priority Support', 'bnfw' ) . '</div>',
|
96 |
+
'bnfw',
|
97 |
+
$support_url,
|
98 |
+
);
|
99 |
+
}
|
100 |
+
}
|
101 |
+
/**
|
102 |
+
* Add script in head section for admin pages.
|
103 |
+
*/
|
104 |
+
public function bnfw_menu_item_link_targets() {
|
105 |
+
?>
|
106 |
+
<script type="text/javascript">
|
107 |
+
jQuery( document ).ready( function ( $ ) {
|
108 |
+
// Documentation Link
|
109 |
+
$( '#bnfw-menu-item-documentation' ).parent().attr( 'target', '_blank' );
|
110 |
+
$( '#bnfw-menu-item-documentation' ).hover( function () {
|
111 |
+
$( this ).css( 'color', '#a0e6f1' );
|
112 |
+
}, function () {
|
113 |
+
$( this ).css( 'color', '#73daeb' );
|
114 |
+
} );
|
115 |
+
|
116 |
+
// Add-ons Link
|
117 |
+
$( '#bnfw-menu-item-addons' ).parent().attr( 'target', '_blank' );
|
118 |
+
$( '#bnfw-menu-item-addons' ).hover( function () {
|
119 |
+
$( this ).css( 'color', '#ff9b8c' );
|
120 |
+
}, function () {
|
121 |
+
$( this ).css( 'color', '#ff6f59' );
|
122 |
+
} );
|
123 |
+
|
124 |
+
// Priority Support Link
|
125 |
+
$( '#bnfw-menu-item-support' ).parent().attr( 'target', '_blank' );
|
126 |
+
$( '#bnfw-menu-item-support' ).hover( function () {
|
127 |
+
$( this ).css( 'color', '#ff3536' );
|
128 |
+
}, function () {
|
129 |
+
$( this ).css( 'color', '#f00001' );
|
130 |
+
} );
|
131 |
+
} );
|
132 |
+
</script>
|
133 |
+
<?php
|
134 |
+
}
|
135 |
+
/**
|
136 |
+
* Settings Page - Setting Registration.
|
137 |
+
*/
|
138 |
+
public function bnfw_general_options() {
|
139 |
+
// Set-up - General Options Section.
|
140 |
+
add_settings_section(
|
141 |
+
'bnfw_general_options_section', // Section ID.
|
142 |
+
'', // Title above settings section.
|
143 |
+
array( $this, 'bnfw_general_options_callback' ), // Name of function that renders a description of the settings section.
|
144 |
+
'bnfw-settings' // Page to show on.
|
145 |
+
);
|
146 |
+
|
147 |
+
// Register - Suppress SPAM Checkbox.
|
148 |
+
register_setting(
|
149 |
+
'bnfw-settings',
|
150 |
+
'bnfw_suppress_spam'
|
151 |
+
);
|
152 |
+
|
153 |
+
// Suppress notifications for SPAM comments.
|
154 |
+
add_settings_field(
|
155 |
+
'bnfw_suppress_spam', // Field ID.
|
156 |
+
esc_html__( 'Suppress SPAM comment notification', 'bnfw' ) . '<div class="bnfw-help-tip"><p>' . esc_html__( 'Comments that are correctly marked as SPAM by a 3rd party plugin (such as Akismet) will not generate a notification if this is ticked.', 'bnfw' ) . '</p></div>', // Label to the left.
|
157 |
+
array( $this, 'bnfw_suppress_spam_checkbox' ), // Name of function that renders options on the page.
|
158 |
+
'bnfw-settings', // Page to show on.
|
159 |
+
'bnfw_general_options_section', // Associate with which settings section?.
|
160 |
+
array(
|
161 |
+
esc_html__( 'Don\'t send notifications for comments marked as SPAM', 'bnfw' ),
|
162 |
+
)
|
163 |
+
);
|
164 |
+
|
165 |
+
// Register - Email Format setting.
|
166 |
+
register_setting(
|
167 |
+
'bnfw-settings',
|
168 |
+
'bnfw_email_format'
|
169 |
+
);
|
170 |
+
|
171 |
+
add_settings_field(
|
172 |
+
'bnfw_email_format', // Field ID.
|
173 |
+
esc_html__( 'Default Email Format', 'bnfw' ) . '<div class="bnfw-help-tip"><p>' . esc_html__( 'This will apply to all emails sent out via WordPress, even those from other plugins. For more details, please see the ', 'bnfw' ) . '<a href="https://wordpress.org/plugins/bnfw/faq/" target="_blank">FAQ</a>.</p></div>', // Label to the left.
|
174 |
+
array( $this, 'bnfw_email_format_radio' ), // Name of function that renders options on the page.
|
175 |
+
'bnfw-settings', // Page to show on.
|
176 |
+
'bnfw_general_options_section' // Associate with which settings section?.
|
177 |
+
);
|
178 |
+
|
179 |
+
// Register - Email Format setting.
|
180 |
+
register_setting(
|
181 |
+
'bnfw-settings',
|
182 |
+
'bnfw_enable_shortcodes'
|
183 |
+
);
|
184 |
+
|
185 |
+
add_settings_field(
|
186 |
+
'bnfw_enable_shortcodes', // Field ID.
|
187 |
+
esc_html__( 'Enable Content Shortcodes?', 'bnfw' ) . '<div class="bnfw-help-tip"><p>' . esc_html__( 'Shortcodes in the post/page content are disabled by default.', 'bnfw' ) . '</p></div>', // Label to the left.
|
188 |
+
array( $this, 'bnfw_enable_shortcodes_checkbox' ), // Name of function that renders options on the page.
|
189 |
+
'bnfw-settings', // Page to show on.
|
190 |
+
'bnfw_general_options_section', // Associate with which settings section?.
|
191 |
+
array(
|
192 |
+
esc_html__( 'Enable shortcode output in the page/post content', 'bnfw' ),
|
193 |
+
)
|
194 |
+
);
|
195 |
+
|
196 |
+
// Register - Allow tracking setting.
|
197 |
+
register_setting(
|
198 |
+
'bnfw-settings',
|
199 |
+
'bnfw_allow_tracking'
|
200 |
+
);
|
201 |
+
|
202 |
+
add_settings_field(
|
203 |
+
'bnfw_allow_tracking', // Field ID.
|
204 |
+
esc_html__( 'Allow Usage Tracking?', 'bnfw' ), // Label to the left.
|
205 |
+
array( $this, 'bnfw_render_allow_tracking' ), // Name of function that renders options on the page.
|
206 |
+
'bnfw-settings', // Page to show on.
|
207 |
+
'bnfw_general_options_section', // Associate with which settings section?.
|
208 |
+
array(
|
209 |
+
esc_html__( 'Allow Better Notifications for WP to anonymously track how this plugin is used and help make the plugin better.', 'bnfw' ),
|
210 |
+
)
|
211 |
+
);
|
212 |
+
}
|
213 |
+
/**
|
214 |
+
* Callback funtion for general options.
|
215 |
+
*/
|
216 |
+
public function bnfw_general_options_callback() {
|
217 |
+
}
|
218 |
+
/**
|
219 |
+
* Suppress SPAM checkbox.
|
220 |
+
*
|
221 |
+
* @since 1.0
|
222 |
+
*
|
223 |
+
* @param array $args Args.
|
224 |
+
*/
|
225 |
+
public function bnfw_suppress_spam_checkbox( $args ) {
|
226 |
+
?>
|
227 |
+
<input type="checkbox" id="bnfw_suppress_spam" name="bnfw_suppress_spam"
|
228 |
+
value="1" <?php checked( 1, get_option( 'bnfw_suppress_spam' ), true ); ?>>
|
229 |
+
<label for="bnfw_suppress_spam"><?php echo esc_html( $args[0] ); ?></label>
|
230 |
+
<?php
|
231 |
+
}
|
232 |
+
/**
|
233 |
+
* Show email format radio
|
234 |
+
*
|
235 |
+
* @since 1.4
|
236 |
+
*
|
237 |
+
* @param array $args args.
|
238 |
+
*/
|
239 |
+
public function bnfw_email_format_radio( $args ) {
|
240 |
+
$email_format = get_option( 'bnfw_email_format', 'html' );
|
241 |
+
?>
|
242 |
+
<label>
|
243 |
+
<input type="radio" value="html"
|
244 |
+
name="bnfw_email_format" <?php checked( $email_format, 'html', true ); ?>><?php esc_html_e( 'HTML Formatting', 'bnfw' ); ?>
|
245 |
+
</label>
|
246 |
+
<br/>
|
247 |
+
<label>
|
248 |
+
<input type="radio" value="text"
|
249 |
+
name="bnfw_email_format" <?php checked( $email_format, 'text', true ); ?>><?php esc_html_e( 'Plain Text', 'bnfw' ); ?>
|
250 |
+
</label>
|
251 |
+
<?php
|
252 |
+
}
|
253 |
+
/**
|
254 |
+
* Render allow tracking checkbox.
|
255 |
+
*
|
256 |
+
* @since 1.6
|
257 |
+
*
|
258 |
+
* @param array $args args.
|
259 |
+
*/
|
260 |
+
public function bnfw_render_allow_tracking( $args ) {
|
261 |
+
?>
|
262 |
+
<input type="checkbox" id="bnfw_allow_tracking" name="bnfw_allow_tracking"
|
263 |
+
value="on" <?php checked( 'on', get_option( 'bnfw_allow_tracking' ), true ); ?>>
|
264 |
+
<label for="bnfw_allow_tracking"><?php echo esc_html( $args[0] ); ?></label>
|
265 |
+
<?php
|
266 |
+
}
|
267 |
+
/**
|
268 |
+
* Render Enable shortcode checkbox.
|
269 |
+
*
|
270 |
+
* @param array $args Optional. Extra arguments used when outputting the field.
|
271 |
+
*/
|
272 |
+
public function bnfw_enable_shortcodes_checkbox( $args ) {
|
273 |
+
?>
|
274 |
+
<input type="checkbox" id="bnfw_enable_shortcodes" name="bnfw_enable_shortcodes"
|
275 |
+
value="1" <?php checked( 1, get_option( 'bnfw_enable_shortcodes' ), true ); ?>>
|
276 |
+
<label for="bnfw_enable_shortcodes"><?php echo esc_html( $args[0] ); ?></label>
|
277 |
+
<?php
|
278 |
+
}
|
279 |
+
}
|
280 |
+
new BNFW_Settings();
|
281 |
+
}
|
includes/class-bnfw-import.php
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Import notification from old plugin.
|
4 |
+
*
|
5 |
+
* @since 1.0
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit;
|
10 |
+
|
11 |
+
if ( ! class_exists( 'BNFW_Import', false ) ) {
|
12 |
+
/**
|
13 |
+
* BNFW_Import Class
|
14 |
+
*/
|
15 |
+
class BNFW_Import {
|
16 |
+
const EMAIL_OPTION = 'bnfw_custom_email_settings';
|
17 |
+
const SETTING_OPTION = 'bnfw_settings';
|
18 |
+
/**
|
19 |
+
* Holds the events
|
20 |
+
*
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
private $events = array(
|
24 |
+
'create_term',
|
25 |
+
'publish_post',
|
26 |
+
'comment_post',
|
27 |
+
'user_register',
|
28 |
+
'trackback_post',
|
29 |
+
'pingback_post',
|
30 |
+
'lostpassword_post',
|
31 |
+
);
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Import notification from old plugin.
|
35 |
+
*
|
36 |
+
* @since 1.0
|
37 |
+
*/
|
38 |
+
public function import() {
|
39 |
+
global $wp_roles;
|
40 |
+
$roles = $wp_roles->get_names();
|
41 |
+
|
42 |
+
if ( $this->import_needed() ) {
|
43 |
+
$old_events = get_option( self::SETTING_OPTION );
|
44 |
+
foreach ( $old_events as $event => $value ) {
|
45 |
+
if ( '1' === $value ) {
|
46 |
+
$event_array = explode( '-', $event );
|
47 |
+
if ( 2 === count( $event_array ) ) {
|
48 |
+
if ( in_array( $event_array[0], $this->events, true ) && in_array( $event_array[1], array_keys( $roles ), true ) ) {
|
49 |
+
$event_array[1] = $roles[ $event_array[1] ];
|
50 |
+
$this->insert_notification( $event_array );
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
// delete the old options.
|
56 |
+
$this->delete_option();
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Check if import is needed.
|
62 |
+
*
|
63 |
+
* @since 1.0
|
64 |
+
* @return unknown
|
65 |
+
*/
|
66 |
+
private function import_needed() {
|
67 |
+
if ( get_option( self::EMAIL_OPTION ) && get_option( self::SETTING_OPTION ) ) {
|
68 |
+
return true;
|
69 |
+
}
|
70 |
+
|
71 |
+
return false;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Insert notification.
|
76 |
+
*
|
77 |
+
* @param mixed $event Event type.
|
78 |
+
*/
|
79 |
+
private function insert_notification( $event ) {
|
80 |
+
$post = array(
|
81 |
+
'post_title' => $event[0] . esc_html__( ' for ', 'bnfw' ) . $event[1] . esc_html__( ' (Auto Imported)', 'bnfw' ),
|
82 |
+
'post_type' => BNFW_Notification::POST_TYPE,
|
83 |
+
'post_content' => '',
|
84 |
+
'post_status' => 'publish',
|
85 |
+
);
|
86 |
+
|
87 |
+
$post_id = wp_insert_post( $post );
|
88 |
+
if ( $post_id > 0 ) {
|
89 |
+
$content = $this->map_notification_content( $event[0] );
|
90 |
+
$setting = array(
|
91 |
+
'notification' => $this->map_notification( $event[0] ),
|
92 |
+
'user-roles' => array( $event[1] ),
|
93 |
+
'users' => array(),
|
94 |
+
'subject' => $content['subject'],
|
95 |
+
'message' => $content['body'],
|
96 |
+
);
|
97 |
+
|
98 |
+
foreach ( $setting as $key => $value ) {
|
99 |
+
update_post_meta( $post_id, BNFW_Notification::META_KEY_PREFIX . $key, $value );
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Map old notification type to new notification type.
|
106 |
+
*
|
107 |
+
* @param mixed $event_name Event name.
|
108 |
+
*
|
109 |
+
* @return unknown
|
110 |
+
*/
|
111 |
+
private function map_notification( $event_name ) {
|
112 |
+
switch ( $event_name ) {
|
113 |
+
case 'create_term':
|
114 |
+
return 'new-category';
|
115 |
+
break;
|
116 |
+
case 'publish_post':
|
117 |
+
return 'new-post';
|
118 |
+
break;
|
119 |
+
case 'comment_post':
|
120 |
+
return 'new-comment';
|
121 |
+
break;
|
122 |
+
case 'user_register':
|
123 |
+
return 'new-user';
|
124 |
+
break;
|
125 |
+
case 'trackback_post':
|
126 |
+
return 'new-trackback';
|
127 |
+
break;
|
128 |
+
case 'pingback_post':
|
129 |
+
return 'new-pingback';
|
130 |
+
break;
|
131 |
+
case 'lostpassword_post':
|
132 |
+
return 'user-password';
|
133 |
+
break;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Map content from old plugin.
|
139 |
+
*
|
140 |
+
* @param unknown $event_name Event name.
|
141 |
+
*
|
142 |
+
* @return unknown
|
143 |
+
*/
|
144 |
+
private function map_notification_content( $event_name ) {
|
145 |
+
$content = array();
|
146 |
+
if ( ! isset( $this->content_map ) ) {
|
147 |
+
$this->parse_content();
|
148 |
+
}
|
149 |
+
|
150 |
+
return $this->content_map[ $event_name ];
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Parse content from old plugins setting.
|
155 |
+
*
|
156 |
+
* @since 1.0
|
157 |
+
*/
|
158 |
+
private function parse_content() {
|
159 |
+
$old_content = get_option( self::EMAIL_OPTION );
|
160 |
+
$content_map = array();
|
161 |
+
foreach ( $old_content as $key => $value ) {
|
162 |
+
$key_array = explode( '-', $key );
|
163 |
+
if ( 3 === count( $key_array ) ) {
|
164 |
+
$content_map[ $key_array[2] ][ $key_array[1] ] = $value;
|
165 |
+
}
|
166 |
+
}
|
167 |
+
$this->content_map = $content_map;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Delete old plugin database options.
|
172 |
+
*
|
173 |
+
* @since 1.0
|
174 |
+
*/
|
175 |
+
private function delete_option() {
|
176 |
+
delete_option( self::EMAIL_OPTION );
|
177 |
+
delete_option( self::SETTING_OPTION );
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
includes/engine/class-bnfw-engine.php
CHANGED
@@ -1,1598 +1,1639 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
*
|
5 |
-
*
|
6 |
-
* @
|
7 |
-
*/
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
|
1528 |
-
|
1529 |
-
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
|
1547 |
-
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
-
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
|
1570 |
-
|
1571 |
-
|
1572 |
-
|
1573 |
-
|
1574 |
-
|
1575 |
-
|
1576 |
-
|
1577 |
-
|
1578 |
-
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
1588 |
-
|
1589 |
-
|
1590 |
-
|
1591 |
-
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* BNFW Engine.
|
4 |
+
*
|
5 |
+
* @since 1.0
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit;
|
10 |
+
|
11 |
+
if ( ! class_exists( 'BNFW_Engine', false ) ) {
|
12 |
+
/**
|
13 |
+
* BNFW Engine class.
|
14 |
+
*/
|
15 |
+
class BNFW_Engine {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Send test email.
|
19 |
+
*
|
20 |
+
* @since 1.2
|
21 |
+
*
|
22 |
+
* @param array $setting Settings.
|
23 |
+
*/
|
24 |
+
public function send_test_email( $setting ) {
|
25 |
+
$subject = __( 'Test Email:', 'bnfw' ) . ' ' . $setting['subject'];
|
26 |
+
$message = '<p><strong>' . __( 'This is a test email. All shortcodes below will show in place but not be replaced with content.', 'bnfw' ) . '</strong></p>' . stripslashes( $setting['message'] );
|
27 |
+
|
28 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
29 |
+
$message = wpautop( $message );
|
30 |
+
}
|
31 |
+
|
32 |
+
$current_user = wp_get_current_user();
|
33 |
+
$email = $current_user->user_email;
|
34 |
+
|
35 |
+
$headers = array();
|
36 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
37 |
+
$headers[] = 'Content-type: text/html';
|
38 |
+
$message = apply_filters( 'bnfw_test_email_message', $message, $setting );
|
39 |
+
} elseif ( 'text' === $setting['email-formatting'] ) {
|
40 |
+
$message = wp_strip_all_tags( $message );
|
41 |
+
}
|
42 |
+
|
43 |
+
wp_mail( $email, stripslashes( $subject ), $message, $headers );
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Send the notification email.
|
48 |
+
*
|
49 |
+
* @since 1.0
|
50 |
+
* @param array $setting Setting options.
|
51 |
+
* @param int $id Id.
|
52 |
+
*/
|
53 |
+
public function send_notification( $setting, $id ) {
|
54 |
+
/**
|
55 |
+
* BNFW - Whether notification is disabled?
|
56 |
+
*
|
57 |
+
* @since 1.3.6
|
58 |
+
*/
|
59 |
+
|
60 |
+
$notification_disabled = apply_filters( 'bnfw_notification_disabled', ( 'true' === $setting['disabled'] ), $id, $setting );
|
61 |
+
|
62 |
+
if ( ! $notification_disabled ) {
|
63 |
+
|
64 |
+
$subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $id );
|
65 |
+
$message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $id );
|
66 |
+
$emails = $this->get_emails( $setting, $id );
|
67 |
+
$headers = $this->get_headers( $emails );
|
68 |
+
|
69 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
70 |
+
$message = wpautop( $message );
|
71 |
+
}
|
72 |
+
|
73 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
74 |
+
$headers[] = 'Content-type: text/html';
|
75 |
+
$message = apply_filters( 'bnfw_notification_message', $message, $setting );
|
76 |
+
} else {
|
77 |
+
$headers[] = 'Content-type: text/plain';
|
78 |
+
if ( 'text' === $setting['email-formatting'] ) {
|
79 |
+
$message = wp_strip_all_tags( $message );
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
$emails = apply_filters( 'bnfw_emails', $emails, $setting, $id );
|
84 |
+
|
85 |
+
$send = apply_filters( 'bnfw_can_send_email', true, $setting, $emails, $subject, $message, $headers );
|
86 |
+
|
87 |
+
if ( ! $send ) {
|
88 |
+
return;
|
89 |
+
}
|
90 |
+
|
91 |
+
if ( isset( $emails['to'] ) && is_array( $emails['to'] ) ) {
|
92 |
+
foreach ( $emails['to'] as $email ) {
|
93 |
+
wp_mail( $email, stripslashes( $this->handle_global_user_shortcodes( $subject, $email ) ), $this->handle_global_user_shortcodes( $message, $email ), $headers );
|
94 |
+
}
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Send new user registration notification email.
|
101 |
+
*
|
102 |
+
* @since 1.1
|
103 |
+
* @param array $setting Notification setting.
|
104 |
+
* @param object $user User object.
|
105 |
+
* @param string $password_url Plain text password in WP < 4.3 and password url in WP > 4.3.
|
106 |
+
*/
|
107 |
+
public function send_registration_email( $setting, $user, $password_url = '' ) {
|
108 |
+
/**
|
109 |
+
* Whether to trigger welcome email notification or not.
|
110 |
+
*
|
111 |
+
* @since 1.7
|
112 |
+
*/
|
113 |
+
$trigger_notification = apply_filters( 'bnfw_trigger_welcome-email_notification', true, $setting, $user );
|
114 |
+
|
115 |
+
if ( ! $trigger_notification ) {
|
116 |
+
return;
|
117 |
+
}
|
118 |
+
|
119 |
+
$user_id = $user->ID;
|
120 |
+
|
121 |
+
$subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
|
122 |
+
$message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
|
123 |
+
|
124 |
+
$subject = str_replace( '[password]', $password_url, $subject );
|
125 |
+
$message = str_replace( '[password]', $password_url, $message );
|
126 |
+
|
127 |
+
$subject = str_replace( '[password_url]', $password_url, $subject );
|
128 |
+
$message = str_replace( '[password_url]', $password_url, $message );
|
129 |
+
|
130 |
+
$subject = str_replace( '[login_url]', wp_login_url(), $subject );
|
131 |
+
$message = str_replace( '[login_url]', wp_login_url(), $message );
|
132 |
+
|
133 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
134 |
+
$message = wpautop( $message );
|
135 |
+
}
|
136 |
+
|
137 |
+
$headers = array();
|
138 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
139 |
+
$headers[] = 'Content-type: text/html';
|
140 |
+
$message = apply_filters( 'bnfw_registration_email_message', $message, $setting );
|
141 |
+
} elseif ( 'text' === $setting['email-formatting'] ) {
|
142 |
+
$message = wp_strip_all_tags( $message );
|
143 |
+
}
|
144 |
+
|
145 |
+
$subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
|
146 |
+
$message = $this->handle_global_user_shortcodes( $message, $user->user_email );
|
147 |
+
wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Send user login notification email.
|
152 |
+
*
|
153 |
+
* @since 1.1
|
154 |
+
* @param array $setting Notification setting.
|
155 |
+
* @param object $user User object.
|
156 |
+
*/
|
157 |
+
public function send_user_login_email( $setting, $user ) {
|
158 |
+
|
159 |
+
$trigger_notification = apply_filters( 'bnfw_trigger_user-login_notification', true, $setting, $user );
|
160 |
+
|
161 |
+
if ( ! $trigger_notification ) {
|
162 |
+
return;
|
163 |
+
}
|
164 |
+
|
165 |
+
$user_id = $user->ID;
|
166 |
+
|
167 |
+
$subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
|
168 |
+
$message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
|
169 |
+
$emails = $this->get_emails( $setting, $user_id );
|
170 |
+
$headers = $this->get_headers( $emails );
|
171 |
+
|
172 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
173 |
+
$message = wpautop( $message );
|
174 |
+
}
|
175 |
+
|
176 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
177 |
+
$headers[] = 'Content-type: text/html';
|
178 |
+
$message = apply_filters( 'bnfw_notification_message', $message, $setting );
|
179 |
+
} elseif ( 'text' === $setting['email-formatting'] ) {
|
180 |
+
$message = wp_strip_all_tags( $message );
|
181 |
+
}
|
182 |
+
|
183 |
+
$subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
|
184 |
+
$message = $this->handle_global_user_shortcodes( $message, $user->user_email );
|
185 |
+
|
186 |
+
wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Send user login notification email for admin.
|
191 |
+
*
|
192 |
+
* @since 1.1
|
193 |
+
* @param array $setting Notification setting.
|
194 |
+
* @param object $user User object.
|
195 |
+
*/
|
196 |
+
public function send_user_login_email_for_admin( $setting, $user ) {
|
197 |
+
|
198 |
+
$trigger_notification = apply_filters( 'bnfw_trigger_user-login_notification', true, $setting, $user );
|
199 |
+
|
200 |
+
if ( ! $trigger_notification ) {
|
201 |
+
return;
|
202 |
+
}
|
203 |
+
$user_id = $user->ID;
|
204 |
+
|
205 |
+
$this->send_notification( $setting, $user_id );
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Send comment reply notification email.
|
210 |
+
*
|
211 |
+
* @since 1.3
|
212 |
+
* @param array $setting Notification setting.
|
213 |
+
* @param object $comment Comment object.
|
214 |
+
* @param object $parent_comment Parent comment object.
|
215 |
+
*/
|
216 |
+
public function send_comment_reply_email( $setting, $comment, $parent_comment ) {
|
217 |
+
$comment_id = $comment->comment_ID;
|
218 |
+
|
219 |
+
/**
|
220 |
+
* BNFW - Whether notification is disabled?
|
221 |
+
*
|
222 |
+
* @since 1.3.6
|
223 |
+
*/
|
224 |
+
$notification_disabled = apply_filters( 'bnfw_notification_disabled', false, $comment_id, $setting );
|
225 |
+
|
226 |
+
if ( ! $notification_disabled ) {
|
227 |
+
$subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $comment_id );
|
228 |
+
$message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $comment_id );
|
229 |
+
$headers = array();
|
230 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
231 |
+
$headers[] = 'Content-type: text/html';
|
232 |
+
} elseif ( 'text' === $setting['email-formatting'] ) {
|
233 |
+
$message = wp_strip_all_tags( $message );
|
234 |
+
}
|
235 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
236 |
+
$message = wpautop( $message );
|
237 |
+
$message = apply_filters( 'bnfw_comment_reply_email_message', $message, $setting );
|
238 |
+
}
|
239 |
+
|
240 |
+
$subject = $this->handle_global_user_shortcodes( $subject, $parent_comment->comment_author_email );
|
241 |
+
$message = $this->handle_global_user_shortcodes( $message, $parent_comment->comment_author_email );
|
242 |
+
wp_mail( $parent_comment->comment_author_email, stripslashes( $subject ), $message, $headers );
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Send user role changed email.
|
248 |
+
*
|
249 |
+
* @since 1.3.9
|
250 |
+
*
|
251 |
+
* @param array $setting Notification setting.
|
252 |
+
* @param int $user_id User ID.
|
253 |
+
* @param array $old_role Old User Role.
|
254 |
+
* @param array $new_role New User Role.
|
255 |
+
*/
|
256 |
+
public function send_user_role_changed_email( $setting, $user_id, $old_role, $new_role ) {
|
257 |
+
$subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
|
258 |
+
$message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
|
259 |
+
|
260 |
+
$subject = $this->handle_user_role_shortcodes( $subject, $old_role, $new_role );
|
261 |
+
$message = $this->handle_user_role_shortcodes( $message, $old_role, $new_role );
|
262 |
+
$headers = array();
|
263 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
264 |
+
$message = wpautop( $message );
|
265 |
+
}
|
266 |
+
|
267 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
268 |
+
$headers[] = 'Content-type: text/html';
|
269 |
+
$message = apply_filters( 'bnfw_user_role_changed_email_message', $message, $setting );
|
270 |
+
} elseif ( 'text' === $setting['email-formatting'] ) {
|
271 |
+
$message = wp_strip_all_tags( $message );
|
272 |
+
}
|
273 |
+
|
274 |
+
$user = get_user_by( 'id', $user_id );
|
275 |
+
$subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
|
276 |
+
$message = $this->handle_global_user_shortcodes( $message, $user->user_email );
|
277 |
+
wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
|
278 |
+
}
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Send user role added support User Role Editor by Members Plugin.
|
282 |
+
*
|
283 |
+
* @since 1.3.9
|
284 |
+
*
|
285 |
+
* @param array $setting Notification setting.
|
286 |
+
* @param int $user_id User ID.
|
287 |
+
* @param array $old_role Old User Role.
|
288 |
+
* @param array $new_role New User Role.
|
289 |
+
*/
|
290 |
+
public function send_user_role_added_email( $setting, $user_id, $old_role, $new_role ) {
|
291 |
+
$subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
|
292 |
+
$message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
|
293 |
+
|
294 |
+
$subject = $this->handle_user_added_role_shortcodes( $subject, $old_role, $new_role );
|
295 |
+
$message = $this->handle_user_added_role_shortcodes( $message, $old_role, $new_role );
|
296 |
+
|
297 |
+
$headers = array();
|
298 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
299 |
+
$message = wpautop( $message );
|
300 |
+
}
|
301 |
+
|
302 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
303 |
+
$headers[] = 'Content-type: text/html';
|
304 |
+
$message = apply_filters( 'bnfw_user_role_changed_email_message', $message, $setting );
|
305 |
+
} elseif ( 'text' === $setting['email-formatting'] ) {
|
306 |
+
$message = wp_strip_all_tags( $message );
|
307 |
+
}
|
308 |
+
|
309 |
+
$user = get_user_by( 'id', $user_id );
|
310 |
+
|
311 |
+
$subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
|
312 |
+
$message = $this->handle_global_user_shortcodes( $message, $user->user_email );
|
313 |
+
wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Handle User Role shortcodes.
|
318 |
+
*
|
319 |
+
* @param string $message String that needs shortcode processing.
|
320 |
+
* @param array $old_role Old User Role.
|
321 |
+
* @param array $new_role New User Role.
|
322 |
+
*
|
323 |
+
* @return string Processed string.
|
324 |
+
*/
|
325 |
+
public function handle_user_role_shortcodes( $message, $old_role, $new_role ) {
|
326 |
+
$roles = wp_roles();
|
327 |
+
|
328 |
+
$old_role_name = '';
|
329 |
+
$new_role_name = '';
|
330 |
+
|
331 |
+
if ( isset( $roles->role_names[ $old_role ] ) ) {
|
332 |
+
$old_role_name = $roles->role_names[ $old_role ];
|
333 |
+
}
|
334 |
+
|
335 |
+
if ( isset( $roles->role_names[ $new_role ] ) ) {
|
336 |
+
$new_role_name = $roles->role_names[ $new_role ];
|
337 |
+
}
|
338 |
+
|
339 |
+
$message = str_replace( '[user_role_old]', $old_role_name, $message );
|
340 |
+
$message = str_replace( '[user_role_new]', $new_role_name, $message );
|
341 |
+
|
342 |
+
return $message;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Handle User Added Role shortcodes.
|
347 |
+
*
|
348 |
+
* @param string $message String that needs shortcode processing.
|
349 |
+
* @param array $old_roles Old User Role.
|
350 |
+
* @param array $new_roles New User Role.
|
351 |
+
*
|
352 |
+
* @return string Processed string.
|
353 |
+
*/
|
354 |
+
public function handle_user_added_role_shortcodes( $message, $old_roles, $new_roles ) {
|
355 |
+
$roles = wp_roles();
|
356 |
+
$old_role_name = array();
|
357 |
+
$new_role_name = array();
|
358 |
+
|
359 |
+
foreach ( $old_roles as $key => $old_role ) {
|
360 |
+
if ( isset( $roles->role_names[ $old_role ] ) ) {
|
361 |
+
$old_role_name[] = $roles->role_names[ $old_role ];
|
362 |
+
}
|
363 |
+
}
|
364 |
+
foreach ( $new_roles as $key => $new_role ) {
|
365 |
+
if ( isset( $roles->role_names[ $new_role ] ) ) {
|
366 |
+
$new_role_name[] = $roles->role_names[ $new_role ];
|
367 |
+
}
|
368 |
+
}
|
369 |
+
|
370 |
+
$message = str_replace( '[user_role_old]', implode( ',', $old_role_name ), $message );
|
371 |
+
$message = str_replace( '[user_role_new]', implode( ',', $new_role_name ), $message );
|
372 |
+
|
373 |
+
return $message;
|
374 |
+
}
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Handle shortcodes for filtered data notifications like `password_changed` and `email_changed`.
|
378 |
+
*
|
379 |
+
* @since 1.6
|
380 |
+
*
|
381 |
+
* @param array $email_data Email data.
|
382 |
+
* @param array $setting Notification settings.
|
383 |
+
* @param string|int $extra_data Extra data.
|
384 |
+
*
|
385 |
+
* @return array Modified email data.
|
386 |
+
*/
|
387 |
+
public function handle_filtered_data_notification( $email_data, $setting, $extra_data ) {
|
388 |
+
$email_data['message'] = $this->handle_shortcodes( $setting['message'], $setting['notification'], $extra_data );
|
389 |
+
$email_data['subject'] = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $extra_data );
|
390 |
+
|
391 |
+
$email_data['message'] = $this->handle_global_user_shortcodes( $email_data['message'], $email_data['to'] );
|
392 |
+
$email_data['subject'] = $this->handle_global_user_shortcodes( $email_data['subject'], $email_data['to'] );
|
393 |
+
|
394 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
395 |
+
$email_data['message'] = wpautop( $email_data['message'] );
|
396 |
+
}
|
397 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
398 |
+
$headers[] = 'Content-type: text/html';
|
399 |
+
} else {
|
400 |
+
$headers[] = 'Content-type: text/plain';
|
401 |
+
if ( 'text' === $setting['email-formatting'] ) {
|
402 |
+
$message = wp_strip_all_tags( $message );
|
403 |
+
}
|
404 |
+
}
|
405 |
+
$email_data['headers'] = $headers;
|
406 |
+
|
407 |
+
return $email_data;
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* Handle shortcodes for core updated notification.
|
412 |
+
*
|
413 |
+
* @since 1.6
|
414 |
+
*
|
415 |
+
* @param array $email_data Email data.
|
416 |
+
* @param array $setting Notification settings.
|
417 |
+
* @param string $type Result of update.
|
418 |
+
*
|
419 |
+
* @return array Modified email data.
|
420 |
+
*/
|
421 |
+
public function handle_core_updated_notification( $email_data, $setting, $type ) {
|
422 |
+
$email_data['body'] = $this->handle_shortcodes( $setting['message'], $setting['notification'], $type );
|
423 |
+
$email_data['subject'] = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $type );
|
424 |
+
|
425 |
+
$emails = $this->get_emails( $setting, $type );
|
426 |
+
$headers = $this->get_headers( $emails );
|
427 |
+
|
428 |
+
$email_data['body'] = $this->handle_global_user_shortcodes( $email_data['body'], $emails['to'][0] );
|
429 |
+
$email_data['subject'] = $this->handle_global_user_shortcodes( $email_data['subject'], $emails['to'][0] );
|
430 |
+
|
431 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
432 |
+
$email_data['body'] = wpautop( $email_data['body'] );
|
433 |
+
}
|
434 |
+
|
435 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
436 |
+
$headers[] = 'Content-type: text/html';
|
437 |
+
} else {
|
438 |
+
$headers[] = 'Content-type: text/plain';
|
439 |
+
if ( 'text' === $setting['email-formatting'] ) {
|
440 |
+
$message = wp_strip_all_tags( $message );
|
441 |
+
}
|
442 |
+
}
|
443 |
+
|
444 |
+
$email_data['headers'] = $headers;
|
445 |
+
|
446 |
+
return $email_data;
|
447 |
+
}
|
448 |
+
|
449 |
+
/**
|
450 |
+
* Handle shortcode for password reset email message.
|
451 |
+
*
|
452 |
+
* @since 1.1
|
453 |
+
*
|
454 |
+
* @param string $setting Notification settings.
|
455 |
+
* @param string $key The activation key.
|
456 |
+
* @param string $user_login The username for the user.
|
457 |
+
* @param WP_User $user_data WP_User object.
|
458 |
+
*
|
459 |
+
* @return mixed|string
|
460 |
+
*/
|
461 |
+
public function handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data ) {
|
462 |
+
$message = '';
|
463 |
+
|
464 |
+
if ( '' !== $user_login ) {
|
465 |
+
// For WordPress version 4.1.0 or less, we could have empty user_login.
|
466 |
+
$message = $this->handle_shortcodes( $setting['message'], 'user-password', $user_data->ID );
|
467 |
+
$message = $this->handle_global_user_shortcodes( $message, $user_data->user_email );
|
468 |
+
|
469 |
+
$reset_link = network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user_login ), 'login' );
|
470 |
+
$message = str_replace( '[password_reset_link]', $reset_link, $message );
|
471 |
+
}
|
472 |
+
|
473 |
+
return $message;
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Send Password Changed email.
|
478 |
+
*
|
479 |
+
* @param array $setting Notification Setting.
|
480 |
+
* @param WP_User $user User for whom the password has changed.
|
481 |
+
*/
|
482 |
+
public function send_password_changed_email( $setting, $user ) {
|
483 |
+
$user_id = $user->ID;
|
484 |
+
|
485 |
+
$subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
|
486 |
+
$message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
|
487 |
+
|
488 |
+
if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
|
489 |
+
$message = wpautop( $message );
|
490 |
+
}
|
491 |
+
|
492 |
+
$headers = array();
|
493 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
494 |
+
$headers[] = 'Content-type: text/html';
|
495 |
+
} elseif ( 'text' === $setting['email-formatting'] ) {
|
496 |
+
$message = wp_strip_all_tags( $message );
|
497 |
+
}
|
498 |
+
|
499 |
+
$subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
|
500 |
+
$message = $this->handle_global_user_shortcodes( $message, $user->user_email );
|
501 |
+
wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
|
502 |
+
}
|
503 |
+
|
504 |
+
/**
|
505 |
+
* Generate message for notification.
|
506 |
+
*
|
507 |
+
* @since 1.0
|
508 |
+
* public since @since 1.6
|
509 |
+
*
|
510 |
+
* @param string $message String may have shortcode.
|
511 |
+
* @param string $notification Notification name.
|
512 |
+
* @param string|int $extra_data Additional data for shortcode.
|
513 |
+
*
|
514 |
+
* @return string Processed string.
|
515 |
+
*/
|
516 |
+
public function handle_shortcodes( $message, $notification, $extra_data ) {
|
517 |
+
|
518 |
+
switch ( $notification ) {
|
519 |
+
case 'new-comment':
|
520 |
+
case 'new-trackback':
|
521 |
+
case 'new-pingback':
|
522 |
+
case 'reply-comment':
|
523 |
+
// handle new comments, trackbacks and pingbacks.
|
524 |
+
$message = $this->comment_shortcodes( $message, $extra_data );
|
525 |
+
$comment = get_comment( $extra_data );
|
526 |
+
$message = $this->post_shortcodes( $message, $comment->comment_post_ID );
|
527 |
+
if ( 0 !== $comment->user_id ) {
|
528 |
+
$message = $this->user_shortcodes( $message, $comment->user_id );
|
529 |
+
}
|
530 |
+
break;
|
531 |
+
|
532 |
+
case 'admin-password':
|
533 |
+
case 'admin-password-changed':
|
534 |
+
case 'admin-email-changed':
|
535 |
+
case 'admin-user':
|
536 |
+
case 'welcome-email':
|
537 |
+
case 'user-login':
|
538 |
+
$message = $this->user_shortcodes( $message, $extra_data );
|
539 |
+
break;
|
540 |
+
case 'admin-user-login':
|
541 |
+
$message = $this->user_shortcodes( $message, $extra_data );
|
542 |
+
break;
|
543 |
+
case 'new-user':
|
544 |
+
case 'user-role':
|
545 |
+
case 'admin-role':
|
546 |
+
case 'password-changed':
|
547 |
+
// handle users (lost password and new user registration).
|
548 |
+
$message = $this->user_shortcodes( $message, $extra_data );
|
549 |
+
break;
|
550 |
+
|
551 |
+
case 'email-changed':
|
552 |
+
case 'user-password':
|
553 |
+
// handle users (lost password and new user registration).
|
554 |
+
$message = $this->user_shortcodes( $message, $extra_data, 'email_' );
|
555 |
+
break;
|
556 |
+
|
557 |
+
case 'new-category':
|
558 |
+
// handle new category.
|
559 |
+
$message = $this->taxonomy_shortcodes( $message, 'category', $extra_data );
|
560 |
+
break;
|
561 |
+
|
562 |
+
case 'new-post_tag':
|
563 |
+
// handle new tag.
|
564 |
+
$message = $this->taxonomy_shortcodes( $message, 'post_tag', $extra_data );
|
565 |
+
break;
|
566 |
+
|
567 |
+
case 'core-updated':
|
568 |
+
// handle core updated type.
|
569 |
+
$message = $this->core_updated_shortcodes( $message, $extra_data );
|
570 |
+
break;
|
571 |
+
|
572 |
+
case 'data-export':
|
573 |
+
// handle data export email.
|
574 |
+
$message = $this->data_export_shortcodes( $message, $extra_data );
|
575 |
+
break;
|
576 |
+
|
577 |
+
case 'data-erased':
|
578 |
+
// handle data export email.
|
579 |
+
$message = $this->data_erased_shortcodes( $message, $extra_data );
|
580 |
+
break;
|
581 |
+
|
582 |
+
case 'new-media':
|
583 |
+
case 'update-media':
|
584 |
+
$message = $this->post_shortcodes( $message, $extra_data );
|
585 |
+
$post = get_post( $extra_data );
|
586 |
+
if ( $post instanceof WP_Post ) {
|
587 |
+
$message = $this->user_shortcodes( $message, $post->post_author );
|
588 |
+
}
|
589 |
+
break;
|
590 |
+
|
591 |
+
default:
|
592 |
+
$type = explode( '-', $notification, 2 );
|
593 |
+
if ( 'newterm' === $type[0] ) {
|
594 |
+
// handle new terms.
|
595 |
+
$message = $this->taxonomy_shortcodes( $message, $type[1], $extra_data );
|
596 |
+
} elseif ( 'new' === $type[0] || 'update' === $type[0] || 'pending' === $type[0] || 'future' === $type[0] || 'private' === $type[0] || 'trash' === $type[0] ) {
|
597 |
+
// handle new, update and pending posts.
|
598 |
+
$post_types = get_post_types( array( 'public' => true ), 'names' );
|
599 |
+
$post_types = array_diff( $post_types, array( BNFW_Notification::POST_TYPE ) );
|
600 |
+
|
601 |
+
if ( in_array( $type[1], $post_types, true ) ) {
|
602 |
+
$message = $this->post_shortcodes( $message, $extra_data );
|
603 |
+
$post = get_post( $extra_data );
|
604 |
+
if ( $post instanceof WP_Post ) {
|
605 |
+
$message = $this->user_shortcodes( $message, $post->post_author );
|
606 |
+
}
|
607 |
+
}
|
608 |
+
} elseif ( 'comment' === $type[0] || 'moderate' === $type[0] || 'commentreply' === $type[0] ) {
|
609 |
+
$message = $this->comment_shortcodes( $message, $extra_data );
|
610 |
+
$comment = get_comment( $extra_data );
|
611 |
+
$message = $this->post_shortcodes( $message, $comment->comment_post_ID );
|
612 |
+
if ( 0 !== $comment->user_id ) {
|
613 |
+
$message = $this->user_shortcodes( $message, $comment->user_id );
|
614 |
+
}
|
615 |
+
} elseif ( 'approve' === $type[0] ) {
|
616 |
+
// handle Approve comments notification.
|
617 |
+
$message = $this->comment_shortcodes( $message, $extra_data );
|
618 |
+
$comment = get_comment( $extra_data );
|
619 |
+
$message = $this->post_shortcodes( $message, $comment->comment_post_ID );
|
620 |
+
if ( 0 !== $comment->user_id ) {
|
621 |
+
$message = $this->user_shortcodes( $message, $comment->user_id );
|
622 |
+
}
|
623 |
+
break;
|
624 |
+
} elseif ( 'ca' === $type[0] ) {
|
625 |
+
$message = $this->confirm_action_shortcodes( $message, $extra_data );
|
626 |
+
$message = $this->handle_global_user_shortcodes( $message, $extra_data['email'] );
|
627 |
+
} elseif ( 'uc' === $type[0] ) {
|
628 |
+
$message = $this->confirmed_action_shortcodes( $message, $extra_data );
|
629 |
+
$message = $this->handle_global_user_shortcodes( $message, $extra_data['admin_email'] );
|
630 |
+
}
|
631 |
+
break;
|
632 |
+
}
|
633 |
+
|
634 |
+
$message = $this->global_shortcodes( $message );
|
635 |
+
|
636 |
+
$message = apply_filters( 'bnfw_shortcodes', $message, $notification, $extra_data, $this );
|
637 |
+
return $message;
|
638 |
+
}
|
639 |
+
|
640 |
+
/**
|
641 |
+
* Handle Global shortcodes.
|
642 |
+
*
|
643 |
+
* @since 1.5
|
644 |
+
*
|
645 |
+
* @param string $message String with shortcodes.
|
646 |
+
*
|
647 |
+
* @return string String after processing global shortcodes.
|
648 |
+
*/
|
649 |
+
private function global_shortcodes( $message ) {
|
650 |
+
$message = str_replace( '[global_site_title]', get_bloginfo( 'name' ), $message );
|
651 |
+
$message = str_replace( '[global_site_tagline]', get_bloginfo( 'description' ), $message );
|
652 |
+
$message = str_replace( '[global_site_url]', get_bloginfo( 'url' ), $message );
|
653 |
+
|
654 |
+
$message = str_replace( '[current_time]', current_time( get_option( 'time_format' ) ), $message );
|
655 |
+
$message = str_replace( '[current_date]', date_i18n( get_option( 'date_format' ), current_time( 'timestamp' ) ), $message );
|
656 |
+
$message = str_replace( '[admin_email]', get_option( 'admin_email' ), $message );
|
657 |
+
|
658 |
+
return $message;
|
659 |
+
}
|
660 |
+
|
661 |
+
/**
|
662 |
+
* Handle Global shortcodes.
|
663 |
+
*
|
664 |
+
* @param string $message Message.
|
665 |
+
* @param string $email Email.
|
666 |
+
*
|
667 |
+
* @return string
|
668 |
+
*/
|
669 |
+
public function handle_global_shortcodes( $message, $email ) {
|
670 |
+
$message = $this->global_shortcodes( $message );
|
671 |
+
|
672 |
+
return $this->handle_global_user_shortcodes( $message, $email );
|
673 |
+
}
|
674 |
+
|
675 |
+
/**
|
676 |
+
* Handle Global User Shortcodes.
|
677 |
+
*
|
678 |
+
* @param string $message String to be processed.
|
679 |
+
* @param string $email Email of the user.
|
680 |
+
*
|
681 |
+
* @return string Processed string.
|
682 |
+
*/
|
683 |
+
public function handle_global_user_shortcodes( $message, $email ) {
|
684 |
+
$user = get_user_by( 'email', $email );
|
685 |
+
|
686 |
+
if ( false === $user ) {
|
687 |
+
$message = str_replace( '[global_user_firstname]', $email, $message );
|
688 |
+
$message = str_replace( '[global_user_lastname]', $email, $message );
|
689 |
+
$message = str_replace( '[global_user_username]', $email, $message );
|
690 |
+
} else {
|
691 |
+
$message = str_replace( '[global_user_firstname]', $user->first_name, $message );
|
692 |
+
$message = str_replace( '[global_user_lastname]', $user->last_name, $message );
|
693 |
+
$message = str_replace( '[global_user_username]', $user->user_login, $message );
|
694 |
+
|
695 |
+
$message = $this->user_shortcodes( $message, $user->ID, 'email_' );
|
696 |
+
}
|
697 |
+
|
698 |
+
$message = str_replace( '[privacy_policy_url]', get_privacy_policy_url(), $message );
|
699 |
+
|
700 |
+
$message = str_replace( array( '[global_user_email]', '[user_email]' ), $email, $message );
|
701 |
+
|
702 |
+
return $message;
|
703 |
+
}
|
704 |
+
|
705 |
+
/**
|
706 |
+
* Handle media post shortcodes.
|
707 |
+
*
|
708 |
+
* @since 1.0
|
709 |
+
* @param string $message Message.
|
710 |
+
* @param WP_Post $post post object.
|
711 |
+
* @return string
|
712 |
+
*/
|
713 |
+
public function media_post_shortcodes( $message, $post ) {
|
714 |
+
$post_content = $this->may_be_strip_shortcode( $post->post_content );
|
715 |
+
$post_content = apply_filters( 'the_content', $post_content );
|
716 |
+
$post_content = str_replace( ']]>', ']]>', $post_content );
|
717 |
+
$message = str_replace( '[ID]', $post->ID, $message );
|
718 |
+
$message = str_replace( '[media_date]', bnfw_format_date( $post->post_date ), $message );
|
719 |
+
$message = str_replace( '[media_date_gmt]', bnfw_format_date( $post->post_date_gmt ), $message );
|
720 |
+
$message = str_replace( '[media_description]', $post_content, $message );
|
721 |
+
$message = str_replace( '[media_title]', $post->post_title, $message );
|
722 |
+
$message = str_replace( '[media_alt_text]', get_post_meta( $post->ID, '_wp_attachment_image_alt', true ), $message );
|
723 |
+
$message = str_replace( '[media_caption]', $this->may_be_strip_shortcode( get_the_excerpt( $post ) ), $message );
|
724 |
+
$message = str_replace( '[media_status]', $post->post_status, $message );
|
725 |
+
$message = str_replace( '[media_modified]', bnfw_format_date( $post->post_modified ), $message );
|
726 |
+
$message = str_replace( '[media_modified_gmt]', bnfw_format_date( $post->post_modified_gmt ), $message );
|
727 |
+
$message = str_replace( '[media_content_filtered]', $post->post_content_filtered, $message );
|
728 |
+
$message = str_replace( '[media_type]', $post->post_type, $message );
|
729 |
+
$message = str_replace( '[media_mime_type]', $post->post_mime_type, $message );
|
730 |
+
$message = str_replace( '[media_slug]', $post->post_name, $message );
|
731 |
+
$dimensions = get_post_meta( $post->ID, '_wp_attachment_metadata', true );
|
732 |
+
$media_dimensions = $dimensions['width'] . ' x ' . $dimensions['height'];
|
733 |
+
$message = str_replace( '[media_dimensions]', $media_dimensions, $message );
|
734 |
+
$user_info = get_userdata( $post->post_author );
|
735 |
+
$message = str_replace( '[media_author]', $user_info->display_name, $message );
|
736 |
+
|
737 |
+
return $message;
|
738 |
+
}
|
739 |
+
|
740 |
+
/**
|
741 |
+
* Handle post shortcodes.
|
742 |
+
*
|
743 |
+
* @since 1.0
|
744 |
+
* @param string $message String to be processed.
|
745 |
+
* @param int $post_id Post id.
|
746 |
+
* @return string
|
747 |
+
*/
|
748 |
+
public function post_shortcodes( $message, $post_id ) {
|
749 |
+
$post = get_post( $post_id );
|
750 |
+
|
751 |
+
if ( ! $post instanceof WP_Post ) {
|
752 |
+
return $message;
|
753 |
+
}
|
754 |
+
|
755 |
+
if ( 'attachment' === $post->post_type ) {
|
756 |
+
$message = $this->media_post_shortcodes( $message, $post );
|
757 |
+
}
|
758 |
+
|
759 |
+
$post_content = $this->may_be_strip_shortcode( $post->post_content );
|
760 |
+
$post_content = apply_filters( 'the_content', $post_content );
|
761 |
+
$post_content = str_replace( ']]>', ']]>', $post_content );
|
762 |
+
|
763 |
+
$message = str_replace( '[ID]', $post->ID, $message );
|
764 |
+
$message = str_replace( '[post_date]', bnfw_format_date( $post->post_date ), $message );
|
765 |
+
$message = str_replace( '[post_date_gmt]', bnfw_format_date( $post->post_date_gmt ), $message );
|
766 |
+
$message = str_replace( '[post_content]', $post_content, $message );
|
767 |
+
$message = str_replace( '[post_title]', $post->post_title, $message );
|
768 |
+
$message = str_replace( '[post_excerpt]', $this->may_be_strip_shortcode( get_the_excerpt( $post ) ), $message );
|
769 |
+
$message = str_replace( '[post_status]', $post->post_status, $message );
|
770 |
+
$message = str_replace( '[comment_status]', $post->comment_status, $message );
|
771 |
+
$message = str_replace( '[ping_status]', $post->ping_status, $message );
|
772 |
+
$message = str_replace( '[post_password]', $post->post_password, $message );
|
773 |
+
$message = str_replace( '[post_name]', $post->post_name, $message );
|
774 |
+
$message = str_replace( '[post_slug]', $post->post_name, $message );
|
775 |
+
$message = str_replace( '[to_ping]', $post->to_ping, $message );
|
776 |
+
$message = str_replace( '[pinged]', $post->pinged, $message );
|
777 |
+
$message = str_replace( '[post_modified]', bnfw_format_date( $post->post_modified ), $message );
|
778 |
+
$message = str_replace( '[post_modified_gmt]', bnfw_format_date( $post->post_modified_gmt ), $message );
|
779 |
+
$message = str_replace( '[post_content_filtered]', $post->post_content_filtered, $message );
|
780 |
+
$message = str_replace( '[post_parent]', $post->post_parent, $message );
|
781 |
+
$message = str_replace( '[post_parent_permalink]', get_permalink( $post->post_parent ), $message );
|
782 |
+
$message = str_replace( '[guid]', $post->guid, $message );
|
783 |
+
$message = str_replace( '[menu_order]', $post->menu_order, $message );
|
784 |
+
$message = str_replace( '[post_type]', $post->post_type, $message );
|
785 |
+
$message = str_replace( '[post_mime_type]', $post->post_mime_type, $message );
|
786 |
+
$message = str_replace( '[comment_count]', $post->comment_count, $message );
|
787 |
+
$message = str_replace( '[permalink]', get_permalink( $post->ID ), $message );
|
788 |
+
$message = str_replace( '[post_type_archive]', get_post_type_archive_link( $post->post_type ), $message );
|
789 |
+
|
790 |
+
$message = str_replace( '[edit_post]', $this->get_edit_post_link( $post->ID, 'return' ), $message );
|
791 |
+
|
792 |
+
$featured_image = '';
|
793 |
+
if ( has_post_thumbnail( $post->ID ) ) {
|
794 |
+
$image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail' );
|
795 |
+
if ( is_array( $image_url ) ) {
|
796 |
+
$featured_image = $image_url[0];
|
797 |
+
}
|
798 |
+
}
|
799 |
+
$message = str_replace( '[featured_image]', $featured_image, $message );
|
800 |
+
|
801 |
+
$message = str_replace( '[first_image]', $this->get_first_image( $post->post_content ), $message );
|
802 |
+
|
803 |
+
if ( 'future' === $post->post_status ) {
|
804 |
+
$message = str_replace( '[post_scheduled_date]', bnfw_format_date( $post->post_date ), $message );
|
805 |
+
$message = str_replace( '[post_scheduled_date_gmt]', bnfw_format_date( $post->post_date_gmt ), $message );
|
806 |
+
} else {
|
807 |
+
$message = str_replace( '[post_scheduled_date]', 'Published', $message );
|
808 |
+
$message = str_replace( '[post_scheduled_date_gmt]', 'Published', $message );
|
809 |
+
}
|
810 |
+
|
811 |
+
$categories = wp_get_post_categories( $post_id, array( 'fields' => 'all' ) );
|
812 |
+
|
813 |
+
$message = str_replace( '[post_category]', implode( ', ', wp_list_pluck( $categories, 'name' ) ), $message );
|
814 |
+
|
815 |
+
if ( count( $categories ) > 0 ) {
|
816 |
+
$message = str_replace(
|
817 |
+
array(
|
818 |
+
'[post_category_slug]',
|
819 |
+
'[post_category_description]',
|
820 |
+
),
|
821 |
+
array(
|
822 |
+
$categories[0]->slug,
|
823 |
+
$categories[0]->description,
|
824 |
+
),
|
825 |
+
$message
|
826 |
+
);
|
827 |
+
}
|
828 |
+
|
829 |
+
$tag_list = implode( ', ', wp_get_post_tags( $post_id, array( 'fields' => 'names' ) ) );
|
830 |
+
$message = str_replace( '[post_tag]', $tag_list, $message );
|
831 |
+
|
832 |
+
$user_info = get_userdata( $post->post_author );
|
833 |
+
$message = str_replace( '[post_author]', $user_info->display_name, $message );
|
834 |
+
|
835 |
+
$message = str_replace( '[author_link]', get_author_posts_url( $post->post_author ), $message );
|
836 |
+
$last_id = get_post_meta( $post->ID, '_edit_lock', true );
|
837 |
+
if ( $last_id ) {
|
838 |
+
$last_id = explode( ':', $last_id );
|
839 |
+
if ( count( $last_id ) > 1 ) {
|
840 |
+
$last_id = end( $last_id );
|
841 |
+
}
|
842 |
+
|
843 |
+
if ( $post->post_author !== $last_id ) {
|
844 |
+
$last_user_info = get_userdata( $last_id );
|
845 |
+
} else {
|
846 |
+
$last_user_info = $user_info;
|
847 |
+
}
|
848 |
+
|
849 |
+
$message = str_replace( '[post_update_author]', $last_user_info->display_name, $message );
|
850 |
+
}
|
851 |
+
|
852 |
+
$message = str_replace( '[post_term', '[post_term id="' . $post_id . '"', $message );
|
853 |
+
add_shortcode( 'post_term', array( $this, 'post_term_shortcode_handler' ) );
|
854 |
+
$message = do_shortcode( $message );
|
855 |
+
remove_shortcode( 'post_term', array( $this, 'post_term_shortcode_handler' ) );
|
856 |
+
|
857 |
+
return apply_filters( 'bnfw_shortcodes_post', $message, $post_id );
|
858 |
+
}
|
859 |
+
|
860 |
+
/**
|
861 |
+
* Retrieves the edit post link for post.
|
862 |
+
*
|
863 |
+
* This is a copy of the built-in function without the user check.
|
864 |
+
*
|
865 |
+
* Can be used within the WordPress loop or outside of it. Can be used with
|
866 |
+
* pages, posts, attachments, and revisions.
|
867 |
+
*
|
868 |
+
* @param int|WP_Post $id Optional. Post ID or post object. Default is the global `$post`.
|
869 |
+
* @param string $context Optional. How to output the '&' character. Default '&'.
|
870 |
+
* @return string|null The edit post link for the given post. null if the post type is invalid or does
|
871 |
+
* not allow an editing UI.
|
872 |
+
*/
|
873 |
+
public function get_edit_post_link( $id = 0, $context = 'display' ) {
|
874 |
+
$post = get_post( $id );
|
875 |
+
if ( ! $post ) {
|
876 |
+
return;
|
877 |
+
}
|
878 |
+
|
879 |
+
if ( 'revision' === $post->post_type ) {
|
880 |
+
$action = '';
|
881 |
+
} elseif ( 'display' === $context ) {
|
882 |
+
$action = '&action=edit';
|
883 |
+
} else {
|
884 |
+
$action = '&action=edit';
|
885 |
+
}
|
886 |
+
|
887 |
+
$post_type_object = get_post_type_object( $post->post_type );
|
888 |
+
if ( ! $post_type_object ) {
|
889 |
+
return;
|
890 |
+
}
|
891 |
+
|
892 |
+
if ( $post_type_object->_edit_link ) {
|
893 |
+
$link = admin_url( sprintf( $post_type_object->_edit_link . $action, $post->ID ) );
|
894 |
+
} else {
|
895 |
+
$link = '';
|
896 |
+
}
|
897 |
+
|
898 |
+
/**
|
899 |
+
* Filters the post edit link.
|
900 |
+
*
|
901 |
+
* @since 2.3.0
|
902 |
+
*
|
903 |
+
* @param string $link The edit link.
|
904 |
+
* @param int $post_id Post ID.
|
905 |
+
* @param string $context The link context. If set to 'display' then ampersands
|
906 |
+
* are encoded.
|
907 |
+
*/
|
908 |
+
return apply_filters( 'get_edit_post_link', $link, $post->ID, $context );
|
909 |
+
}
|
910 |
+
|
911 |
+
/**
|
912 |
+
* Handle post term shortcode.
|
913 |
+
*
|
914 |
+
* @param array $atts Shortocde attributes.
|
915 |
+
*
|
916 |
+
* @return string Processed string.
|
917 |
+
*/
|
918 |
+
public function post_term_shortcode_handler( $atts ) {
|
919 |
+
$atts = shortcode_atts(
|
920 |
+
array(
|
921 |
+
'taxonomy' => '',
|
922 |
+
'id' => 0,
|
923 |
+
),
|
924 |
+
$atts
|
925 |
+
);
|
926 |
+
|
927 |
+
$terms = wp_get_post_terms( $atts['id'], $atts['taxonomy'], array( 'fields' => 'names' ) );
|
928 |
+
|
929 |
+
if ( ! is_wp_error( $terms ) ) {
|
930 |
+
return implode( ', ', $terms );
|
931 |
+
}
|
932 |
+
|
933 |
+
return '';
|
934 |
+
}
|
935 |
+
|
936 |
+
/**
|
937 |
+
* Strip shortcodes, unless disabled.
|
938 |
+
*
|
939 |
+
* @param string $content Content who's shortcodes should be stripped.
|
940 |
+
*
|
941 |
+
* @return string Processed content.
|
942 |
+
*/
|
943 |
+
private function may_be_strip_shortcode( $content ) {
|
944 |
+
$enable_shortcode = get_option( 'bnfw_enable_shortcodes' );
|
945 |
+
|
946 |
+
if ( '1' === $enable_shortcode ) {
|
947 |
+
return $content;
|
948 |
+
}
|
949 |
+
|
950 |
+
return strip_shortcodes( $content );
|
951 |
+
}
|
952 |
+
|
953 |
+
/**
|
954 |
+
* Handle comment shortcodes.
|
955 |
+
*
|
956 |
+
* @since 1.0
|
957 |
+
*
|
958 |
+
* @param string $message String to be processed.
|
959 |
+
* @param int $comment_id Comment id.
|
960 |
+
*
|
961 |
+
* @return string Processed string.
|
962 |
+
*/
|
963 |
+
private function comment_shortcodes( $message, $comment_id ) {
|
964 |
+
$comment = get_comment( $comment_id );
|
965 |
+
|
966 |
+
$message = str_replace( '[comment_ID]', $comment->comment_ID, $message );
|
967 |
+
$message = str_replace( '[comment_post_ID]', $comment->comment_post_ID, $message );
|
968 |
+
$message = str_replace( '[comment_author]', $comment->comment_author, $message );
|
969 |
+
$message = str_replace( '[comment_author_email]', $comment->comment_author_email, $message );
|
970 |
+
$message = str_replace( '[comment_author_url]', $comment->comment_author_url, $message );
|
971 |
+
$message = str_replace( '[comment_author_IP]', $comment->comment_author_IP, $message );
|
972 |
+
$message = str_replace( '[comment_date]', bnfw_format_date( $comment->comment_date ), $message );
|
973 |
+
$message = str_replace( '[comment_date_gmt]', bnfw_format_date( $comment->comment_date_gmt ), $message );
|
974 |
+
$message = str_replace( '[comment_content]', get_comment_text( $comment->comment_ID ), $message );
|
975 |
+
$message = str_replace( '[comment_karma]', $comment->comment_karma, $message );
|
976 |
+
$message = str_replace( '[comment_approved]', str_replace( array( '0', '1', 'spam' ), array( 'Awaiting Moderation', 'Approved', 'Spam' ), $comment->comment_approved ), $message );
|
977 |
+
$message = str_replace( '[comment_agent]', $comment->comment_agent, $message );
|
978 |
+
$message = str_replace( '[comment_type]', $comment->comment_type, $message );
|
979 |
+
$message = str_replace( '[comment_parent]', $comment->comment_parent, $message );
|
980 |
+
$message = str_replace( '[user_id]', $comment->user_id, $message );
|
981 |
+
$message = str_replace( '[permalink]', get_comment_link( $comment->comment_ID ), $message );
|
982 |
+
$message = str_replace( '[comment_moderation_link]', admin_url( 'comment.php?action=editcomment&c=' ) . $comment->comment_ID, $message );
|
983 |
+
$message = str_replace( '[comment_moderation_approve]', '<a href="' . wp_nonce_url( admin_url( "comment.php?action=approve&c={$comment->comment_ID}#wpbody-content" ) ) . '">Approve</a>', $message );
|
984 |
+
$message = str_replace( '[comment_moderation_spam]', '<a href="' . wp_nonce_url( admin_url( "comment.php?action=spam&c={$comment->comment_ID}#wpbody-content" ) ) . '">Spam</a>', $message );
|
985 |
+
$message = str_replace( '[comment_moderation_delete]', '<a href="' . wp_nonce_url( admin_url( "comment.php?action=trash&c={$comment->comment_ID}#wpbody-content" ) ) . '">Delete</a>', $message );
|
986 |
+
|
987 |
+
$parent_comment = get_comment( $comment->comment_parent );
|
988 |
+
if ( $parent_comment instanceof WP_Comment ) {
|
989 |
+
$message = str_replace( '[comment_parent_content]', $parent_comment->comment_content, $message );
|
990 |
+
}
|
991 |
+
|
992 |
+
return $message;
|
993 |
+
}
|
994 |
+
|
995 |
+
/**
|
996 |
+
* Handle user shortcodes.
|
997 |
+
*
|
998 |
+
* @since 1.0
|
999 |
+
*
|
1000 |
+
* @param string $message String to be processed.
|
1001 |
+
* @param int $user_id User id.
|
1002 |
+
* @param string $prefix Prefix.
|
1003 |
+
*
|
1004 |
+
* @return string Processed string.
|
1005 |
+
*/
|
1006 |
+
public function user_shortcodes( $message, $user_id, $prefix = '' ) {
|
1007 |
+
global $wp_roles;
|
1008 |
+
|
1009 |
+
$user_info = get_userdata( $user_id );
|
1010 |
+
|
1011 |
+
if ( ! $user_info instanceof WP_User ) {
|
1012 |
+
return $message;
|
1013 |
+
}
|
1014 |
+
|
1015 |
+
// deprecated.
|
1016 |
+
$message = str_replace( '[ID]', $user_info->ID, $message );
|
1017 |
+
$message = str_replace( '[display_name]', $user_info->display_name, $message );
|
1018 |
+
$message = str_replace( '[nickname]', $user_info->nickname, $message );
|
1019 |
+
$message = str_replace( '[commenter_avatar]', get_avatar_url( $user_id ), $message );
|
1020 |
+
|
1021 |
+
$message = str_replace( '[' . $prefix . 'user_id]', $user_info->ID, $message );
|
1022 |
+
$message = str_replace( '[' . $prefix . 'user_login]', $user_info->user_login, $message );
|
1023 |
+
$message = str_replace( '[' . $prefix . 'user_nicename]', $user_info->user_nicename, $message );
|
1024 |
+
$message = str_replace( '[' . $prefix . 'user_email]', $user_info->user_email, $message );
|
1025 |
+
$message = str_replace( '[' . $prefix . 'user_url]', $user_info->user_url, $message );
|
1026 |
+
$message = str_replace( '[' . $prefix . 'user_registered]', $user_info->user_registered, $message );
|
1027 |
+
$message = str_replace( '[' . $prefix . 'user_display_name]', $user_info->display_name, $message );
|
1028 |
+
$message = str_replace( '[' . $prefix . 'user_firstname]', $user_info->user_firstname, $message );
|
1029 |
+
$message = str_replace( '[' . $prefix . 'user_lastname]', $user_info->user_lastname, $message );
|
1030 |
+
$message = str_replace( '[' . $prefix . 'user_nickname]', $user_info->nickname, $message );
|
1031 |
+
$message = str_replace( '[' . $prefix . 'user_description]', $user_info->user_description, $message );
|
1032 |
+
$message = str_replace( '[' . $prefix . 'user_avatar]', get_avatar_url( $user_id ), $message );
|
1033 |
+
|
1034 |
+
$roles = array_map( array( $this, 'get_role_label_by_name' ), $user_info->roles );
|
1035 |
+
$message = str_replace( '[' . $prefix . 'user_role]', implode( ', ', $roles ), $message );
|
1036 |
+
|
1037 |
+
$user_capabilities = bnfw_format_user_capabilities( $user_info->wp_capabilities );
|
1038 |
+
if ( ! empty( $user_capabilities ) ) {
|
1039 |
+
$message = str_replace( '[wp_capabilities]', $user_capabilities, $message );
|
1040 |
+
$message = str_replace( '[' . $prefix . 'user_wp_capabilities]', $user_capabilities, $message );
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
$message = apply_filters( 'bnfw_shortcodes_user', $message, $user_id, $prefix );
|
1044 |
+
return $message;
|
1045 |
+
}
|
1046 |
+
|
1047 |
+
/**
|
1048 |
+
* Handle taxonomy shortcodes.
|
1049 |
+
*
|
1050 |
+
* @access private
|
1051 |
+
* @since 1.1
|
1052 |
+
*
|
1053 |
+
* @param string $message String to be processed.
|
1054 |
+
* @param string $taxonomy Taxonomy name that `$term` is part of.
|
1055 |
+
* @param int $term_id Term ID.
|
1056 |
+
* @return string
|
1057 |
+
*/
|
1058 |
+
private function taxonomy_shortcodes( $message, $taxonomy, $term_id ) {
|
1059 |
+
$term_info = get_term( $term_id, $taxonomy );
|
1060 |
+
|
1061 |
+
$message = str_replace( '[slug]', $term_info->slug, $message );
|
1062 |
+
$message = str_replace( '[name]', $term_info->name, $message );
|
1063 |
+
$message = str_replace( '[description]', $term_info->description, $message );
|
1064 |
+
|
1065 |
+
return $message;
|
1066 |
+
}
|
1067 |
+
|
1068 |
+
/**
|
1069 |
+
* Handle Core Updated Shortcodes.
|
1070 |
+
*
|
1071 |
+
* @since 1.6
|
1072 |
+
*
|
1073 |
+
* @param string $message Original message with shortcodes.
|
1074 |
+
* @param string $type The type of email being sent. Can be one of
|
1075 |
+
* 'success', 'fail', 'manual', 'critical'.
|
1076 |
+
*
|
1077 |
+
* @return string Modified content.
|
1078 |
+
*/
|
1079 |
+
private function core_updated_shortcodes( $message, $type ) {
|
1080 |
+
$message = str_replace( '[core_update_status]', $type, $message );
|
1081 |
+
|
1082 |
+
return $message;
|
1083 |
+
}
|
1084 |
+
|
1085 |
+
/**
|
1086 |
+
* Get the list of emails from the notification settings.
|
1087 |
+
*
|
1088 |
+
* @since 1.0
|
1089 |
+
*
|
1090 |
+
* @param array $setting Notification settings.
|
1091 |
+
* @param int $id ID to be processed.
|
1092 |
+
* @param bool $process_post_authors If post author needs to be get notification.
|
1093 |
+
* @param bool $process_exclude_current_user If current user needs to be excluded.
|
1094 |
+
*
|
1095 |
+
* @return array Emails
|
1096 |
+
*/
|
1097 |
+
public function get_emails( $setting, $id, $process_post_authors = true, $process_exclude_current_user = true ) {
|
1098 |
+
global $current_user;
|
1099 |
+
|
1100 |
+
$emails = array();
|
1101 |
+
|
1102 |
+
$exclude = null;
|
1103 |
+
if ( $process_exclude_current_user && 'true' === $setting['disable-current-user'] ) {
|
1104 |
+
if ( isset( $current_user->ID ) ) {
|
1105 |
+
$exclude = $current_user->ID;
|
1106 |
+
}
|
1107 |
+
}
|
1108 |
+
|
1109 |
+
$emails['to'] = array();
|
1110 |
+
|
1111 |
+
if ( ! empty( $setting['users'] ) ) {
|
1112 |
+
$emails['to'] = $this->get_emails_from_users( $setting['users'], $exclude, $id, $setting );
|
1113 |
+
}
|
1114 |
+
|
1115 |
+
/**
|
1116 |
+
* BNFW get to emails.
|
1117 |
+
*/
|
1118 |
+
if ( $process_post_authors && 'true' === $setting['only-post-author'] ) {
|
1119 |
+
$post_id = $id;
|
1120 |
+
|
1121 |
+
if ( bnfw_is_comment_notification( $setting['notification'] ) ) {
|
1122 |
+
$comment = get_comment( $id );
|
1123 |
+
$post_id = $comment->comment_post_ID;
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
$type = explode( '-', $setting['notification'], 2 );
|
1127 |
+
if ( 'approve' === $type[0] ) {
|
1128 |
+
if ( ! in_array( $comment->comment_author_email, $emails['to'], true ) ) {
|
1129 |
+
$emails['to'][] = $comment->comment_author_email;
|
1130 |
+
}
|
1131 |
+
} else {
|
1132 |
+
if ( 'user-customfield' === $setting['notification'] || 'user-customfieldvalue' === $setting['notification'] ) {
|
1133 |
+
$post_author = $post_id;
|
1134 |
+
} else {
|
1135 |
+
$post_author = get_post_field( 'post_author', $post_id );
|
1136 |
+
}
|
1137 |
+
$author = get_user_by( 'id', $post_author );
|
1138 |
+
if ( false !== $author && $post_author !== $exclude ) {
|
1139 |
+
if ( ! in_array( $author->user_email, $emails['to'], true ) ) {
|
1140 |
+
$emails['to'][] = $author->user_email;
|
1141 |
+
}
|
1142 |
+
}
|
1143 |
+
}
|
1144 |
+
}
|
1145 |
+
|
1146 |
+
if ( 'true' === $setting['show-fields'] ) {
|
1147 |
+
$default_from_field = get_option( 'blogname' ) . ' <' . get_option( 'admin_email' ) . '>';
|
1148 |
+
|
1149 |
+
if ( ! empty( $setting['from-name'] ) && ! empty( $setting['from-email'] ) && is_email( $setting['from-email'] ) ) {
|
1150 |
+
$default_from_field = $setting['from-name'] . ' <' . $setting['from-email'] . '>';
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
/**
|
1154 |
+
* Filter Email From Field.
|
1155 |
+
*/
|
1156 |
+
$emails['from'] = apply_filters( 'bnfw_from_field', $default_from_field, $setting, $id, $emails['to'] );
|
1157 |
+
|
1158 |
+
/**
|
1159 |
+
* Filter Reply Name Field.
|
1160 |
+
*/
|
1161 |
+
$emails['reply-name'] = apply_filters( 'bnfw_reply_name_field', $setting['reply-name'], $setting, $id, $emails['to'] );
|
1162 |
+
|
1163 |
+
/**
|
1164 |
+
* Filter Reply Email Field.
|
1165 |
+
*/
|
1166 |
+
$emails['reply-email'] = apply_filters( 'bnfw_reply_email_field', $setting['reply-email'], $setting, $id, $emails['to'] );
|
1167 |
+
|
1168 |
+
if ( ! empty( $setting['cc'] ) ) {
|
1169 |
+
$emails['cc'] = $this->get_emails_from_users( $setting['cc'], $exclude, $id, $setting );
|
1170 |
+
}
|
1171 |
+
|
1172 |
+
if ( ! empty( $setting['bcc'] ) ) {
|
1173 |
+
$emails['bcc'] = $this->get_emails_from_users( $setting['bcc'], $exclude, $id, $setting );
|
1174 |
+
}
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
$excluded_emails = array();
|
1178 |
+
|
1179 |
+
if ( ! empty( $setting['exclude-users'] ) ) {
|
1180 |
+
$excluded_emails = $this->get_emails_from_users( $setting['exclude-users'] );
|
1181 |
+
}
|
1182 |
+
|
1183 |
+
if ( ! empty( $excluded_emails ) ) {
|
1184 |
+
$emails['to'] = array_diff( $emails['to'], $excluded_emails );
|
1185 |
+
|
1186 |
+
if ( ! empty( $emails['cc'] ) ) {
|
1187 |
+
$emails['cc'] = array_diff( $emails['cc'], $excluded_emails );
|
1188 |
+
}
|
1189 |
+
|
1190 |
+
if ( ! empty( $emails['bcc'] ) ) {
|
1191 |
+
$emails['bcc'] = array_diff( $emails['bcc'], $excluded_emails );
|
1192 |
+
}
|
1193 |
+
}
|
1194 |
+
$emails['to'] = apply_filters( 'bnfw_to_emails', $emails['to'], $setting, $id );
|
1195 |
+
|
1196 |
+
return $emails;
|
1197 |
+
}
|
1198 |
+
|
1199 |
+
/**
|
1200 |
+
* Get emails from users.
|
1201 |
+
*
|
1202 |
+
* @since 1.2
|
1203 |
+
*
|
1204 |
+
* @param array $users Users Array.
|
1205 |
+
* @param int $exclude User id to exclude.
|
1206 |
+
* @param int $post_id Post id.
|
1207 |
+
* @param array $setting Notification setting.
|
1208 |
+
*
|
1209 |
+
* @return array
|
1210 |
+
*/
|
1211 |
+
public function get_emails_from_users( $users, $exclude = null, $post_id = 0, $setting = array() ) {
|
1212 |
+
$user_ids = array();
|
1213 |
+
$user_roles = array();
|
1214 |
+
$non_wp_users = array();
|
1215 |
+
|
1216 |
+
if ( empty( $users ) ) {
|
1217 |
+
return array();
|
1218 |
+
}
|
1219 |
+
|
1220 |
+
foreach ( $users as $user ) {
|
1221 |
+
if ( $this->starts_with( $user, 'role-' ) ) {
|
1222 |
+
$user_roles[] = str_replace( 'role-', '', $user );
|
1223 |
+
} elseif ( strpos( $user, '@' ) !== false ) {
|
1224 |
+
$non_wp_users[] = $user;
|
1225 |
+
continue;
|
1226 |
+
} elseif ( absint( $user ) > 0 ) {
|
1227 |
+
$user_ids[] = absint( $user );
|
1228 |
+
} else {
|
1229 |
+
$non_wp_users[] = $user;
|
1230 |
+
}
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
if ( null !== $exclude ) {
|
1234 |
+
$user_ids = array_diff( $user_ids, array( $exclude ) );
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
$emails_from_user_ids = $this->get_emails_from_id( $user_ids );
|
1238 |
+
$emails_from_user_roles = $this->get_emails_from_role( $user_roles, $exclude );
|
1239 |
+
|
1240 |
+
if ( ! empty( $setting ) ) {
|
1241 |
+
// for new comment notifications, we need to use post id instead of comment id.
|
1242 |
+
if ( bnfw_is_comment_notification( $setting['notification'] ) && $post_id ) {
|
1243 |
+
$comment = get_comment( $post_id );
|
1244 |
+
$post_id = $comment->comment_post_ID;
|
1245 |
+
}
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
$non_wp_emails = apply_filters( 'bnfw_non_wp_emails', array(), $non_wp_users, $post_id );
|
1249 |
+
|
1250 |
+
return array_merge( $emails_from_user_roles, $emails_from_user_ids, $non_wp_emails );
|
1251 |
+
}
|
1252 |
+
|
1253 |
+
/**
|
1254 |
+
* Get user emails by user ids.
|
1255 |
+
*
|
1256 |
+
* @since 1.0
|
1257 |
+
*
|
1258 |
+
* @param array $user_ids An array of user IDs.
|
1259 |
+
*
|
1260 |
+
* @return array Emails.
|
1261 |
+
*/
|
1262 |
+
private function get_emails_from_id( $user_ids ) {
|
1263 |
+
$email_list = array();
|
1264 |
+
if ( is_array( $user_ids ) && count( $user_ids ) > 0 ) {
|
1265 |
+
$user_query = new WP_User_Query( array( 'include' => $user_ids ) );
|
1266 |
+
foreach ( $user_query->results as $user ) {
|
1267 |
+
$email_list[] = $user->user_email;
|
1268 |
+
}
|
1269 |
+
}
|
1270 |
+
return $email_list;
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
/**
|
1274 |
+
* Get emails of users based on role.
|
1275 |
+
*
|
1276 |
+
* @since 1.0
|
1277 |
+
* @param array $roles User Roles.
|
1278 |
+
* @param int $exclude User id to exclude.
|
1279 |
+
* @return array Email ids
|
1280 |
+
*/
|
1281 |
+
private function get_emails_from_role( $roles, $exclude = null ) {
|
1282 |
+
if ( ! is_array( $roles ) ) {
|
1283 |
+
$roles = array( $roles );
|
1284 |
+
}
|
1285 |
+
|
1286 |
+
$email_list = array();
|
1287 |
+
foreach ( $roles as $role ) {
|
1288 |
+
$role_name = $this->get_role_name_by_label( $role );
|
1289 |
+
$users = get_users(
|
1290 |
+
array(
|
1291 |
+
'role' => $role_name,
|
1292 |
+
'fields' => array( 'user_email', 'ID' ),
|
1293 |
+
)
|
1294 |
+
);
|
1295 |
+
|
1296 |
+
foreach ( $users as $user ) {
|
1297 |
+
if ( null !== $exclude ) {
|
1298 |
+
if ( $user->ID === $exclude ) {
|
1299 |
+
continue;
|
1300 |
+
}
|
1301 |
+
}
|
1302 |
+
|
1303 |
+
if ( ! in_array( $user->user_email, $email_list, true ) ) {
|
1304 |
+
$email_list[] = $user->user_email;
|
1305 |
+
}
|
1306 |
+
}
|
1307 |
+
}
|
1308 |
+
|
1309 |
+
return $email_list;
|
1310 |
+
}
|
1311 |
+
|
1312 |
+
/**
|
1313 |
+
* Find if a string starts with another string.
|
1314 |
+
*
|
1315 |
+
* @since 1.2
|
1316 |
+
*
|
1317 |
+
* @param string $haystack The string to search in.
|
1318 |
+
* @param string $needle The substring to search for in the haystack.
|
1319 |
+
*
|
1320 |
+
* @return bool
|
1321 |
+
*/
|
1322 |
+
private function starts_with( $haystack, $needle ) {
|
1323 |
+
// search backwards starting from haystack length characters from the end.
|
1324 |
+
return '' === $needle || strrpos( $haystack, $needle, -strlen( $haystack ) ) !== false;
|
1325 |
+
}
|
1326 |
+
|
1327 |
+
/**
|
1328 |
+
* Get User role name by label.
|
1329 |
+
*
|
1330 |
+
* @param mixed $role_label Role label.
|
1331 |
+
*
|
1332 |
+
* @return int|string
|
1333 |
+
*/
|
1334 |
+
protected function get_role_name_by_label( $role_label ) {
|
1335 |
+
global $wp_roles;
|
1336 |
+
foreach ( $wp_roles->roles as $role_name => $role_info ) {
|
1337 |
+
if ( $role_label === $role_info['name'] || $role_name === $role_label ) {
|
1338 |
+
return $role_name;
|
1339 |
+
}
|
1340 |
+
}
|
1341 |
+
|
1342 |
+
// There is something wrong.
|
1343 |
+
return '';
|
1344 |
+
}
|
1345 |
+
|
1346 |
+
/**
|
1347 |
+
* Get the lable for a user role from name.
|
1348 |
+
*
|
1349 |
+
* @param string $role_name Role name.
|
1350 |
+
*
|
1351 |
+
* @return string Role Label.
|
1352 |
+
*/
|
1353 |
+
public function get_role_label_by_name( $role_name ) {
|
1354 |
+
global $wp_roles;
|
1355 |
+
|
1356 |
+
if ( ! isset( $wp_roles->roles[ $role_name ] ) ) {
|
1357 |
+
return '';
|
1358 |
+
}
|
1359 |
+
|
1360 |
+
return translate_user_role( $wp_roles->roles[ $role_name ]['name'] );
|
1361 |
+
}
|
1362 |
+
|
1363 |
+
/**
|
1364 |
+
* Get first image in post.
|
1365 |
+
*
|
1366 |
+
* @param mixed $post_content Post content.
|
1367 |
+
*
|
1368 |
+
* @return string
|
1369 |
+
*/
|
1370 |
+
protected function get_first_image( $post_content ) {
|
1371 |
+
if ( preg_match_all( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post_content, $matches ) ) {
|
1372 |
+
return $matches[1][0];
|
1373 |
+
}
|
1374 |
+
}
|
1375 |
+
|
1376 |
+
/**
|
1377 |
+
* Generate email headers based on the emails.
|
1378 |
+
*
|
1379 |
+
* @since 1.0
|
1380 |
+
* @param array $emails Emails.
|
1381 |
+
* @return array
|
1382 |
+
*/
|
1383 |
+
public function get_headers( $emails ) {
|
1384 |
+
$headers = array();
|
1385 |
+
|
1386 |
+
if ( ! empty( $emails['from'] ) ) {
|
1387 |
+
$headers[] = 'From:' . $emails['from'];
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
if ( ! empty( $emails['reply-email'] ) && is_email( $emails['reply-email'] ) ) {
|
1391 |
+
$headers[] = 'Reply-To:' . $emails['reply-name'] . '<' . $emails['reply-email'] . '>';
|
1392 |
+
}
|
1393 |
+
|
1394 |
+
if ( ! empty( $emails['cc'] ) ) {
|
1395 |
+
$headers[] = 'Cc:' . implode( ',', $emails['cc'] );
|
1396 |
+
}
|
1397 |
+
if ( ! empty( $emails['bcc'] ) ) {
|
1398 |
+
$headers[] = 'Bcc:' . implode( ',', $emails['bcc'] );
|
1399 |
+
}
|
1400 |
+
|
1401 |
+
/**
|
1402 |
+
* Filter out mail headers.
|
1403 |
+
*
|
1404 |
+
* @param array $headers Headers.
|
1405 |
+
* @param array $emails Emails.
|
1406 |
+
*/
|
1407 |
+
return apply_filters( 'bnfw_mail_headers', $headers, $emails );
|
1408 |
+
}
|
1409 |
+
/**
|
1410 |
+
* Handles user shortcode.
|
1411 |
+
*
|
1412 |
+
* @param string $message String to be processed.
|
1413 |
+
* @param array $setting Notification settings.
|
1414 |
+
* @param array $email_data Email data.
|
1415 |
+
* @return string
|
1416 |
+
*/
|
1417 |
+
public function handle_user_request_email_shortcodes( $message, $setting, $email_data ) {
|
1418 |
+
$message = $this->handle_shortcodes( $message, $setting['notification'], $email_data );
|
1419 |
+
|
1420 |
+
return $message;
|
1421 |
+
}
|
1422 |
+
/**
|
1423 |
+
* Handles user confiemd action shortcode.
|
1424 |
+
*
|
1425 |
+
* @param string $message String to be processed.
|
1426 |
+
* @param array $setting Notification settings.
|
1427 |
+
* @param array $email_data Email data.
|
1428 |
+
* @return string
|
1429 |
+
*/
|
1430 |
+
public function handle_user_confirmed_action_email_shortcodes( $message, $setting, $email_data ) {
|
1431 |
+
$message = $this->handle_shortcodes( $message, $setting['notification'], $email_data );
|
1432 |
+
|
1433 |
+
return $message;
|
1434 |
+
}
|
1435 |
+
/**
|
1436 |
+
* Handles user export shortcode.
|
1437 |
+
*
|
1438 |
+
* @param string $message String to be processed.
|
1439 |
+
* @param array $setting Notification settings.
|
1440 |
+
* @param int $request_id Request ID.
|
1441 |
+
* @return string
|
1442 |
+
*/
|
1443 |
+
public function handle_data_export_email_shortcodes( $message, $setting, $request_id ) {
|
1444 |
+
$message = $this->handle_shortcodes( $message, $setting['notification'], $request_id );
|
1445 |
+
return $message;
|
1446 |
+
}
|
1447 |
+
/**
|
1448 |
+
* Handles user export shortcode.
|
1449 |
+
*
|
1450 |
+
* @param string $message String to be processed.
|
1451 |
+
* @param array $extra_data Extra data.
|
1452 |
+
* @return string
|
1453 |
+
*/
|
1454 |
+
protected function confirm_action_shortcodes( $message, $extra_data ) {
|
1455 |
+
$message = $this->data_request_shortcodes( $message, $extra_data );
|
1456 |
+
$message = str_replace( '[request_confirmation_link]', $extra_data['confirm_url'], $message );
|
1457 |
+
if ( isset( $extra_data['email'] ) ) {
|
1458 |
+
$message = str_replace( '[request_email]', $extra_data['email'], $message );
|
1459 |
+
}
|
1460 |
+
|
1461 |
+
if ( isset( $extra_data['user_email'] ) ) {
|
1462 |
+
$message = str_replace( '[request_email]', $extra_data['user_email'], $message );
|
1463 |
+
}
|
1464 |
+
|
1465 |
+
return $message;
|
1466 |
+
}
|
1467 |
+
/**
|
1468 |
+
* Handles user export shortcode.
|
1469 |
+
*
|
1470 |
+
* @param string $message String to be processed.
|
1471 |
+
* @param array $extra_data Extra data.
|
1472 |
+
* @return string
|
1473 |
+
*/
|
1474 |
+
protected function confirmed_action_shortcodes( $message, $extra_data ) {
|
1475 |
+
$message = $this->data_request_shortcodes( $message, $extra_data );
|
1476 |
+
$message = str_replace( '[data_privacy_requests_url]', $extra_data['manage_url'], $message );
|
1477 |
+
$message = str_replace( '[request_email]', $extra_data['user_email'], $message );
|
1478 |
+
|
1479 |
+
return $message;
|
1480 |
+
}
|
1481 |
+
/**
|
1482 |
+
* Handles data request shortcode.
|
1483 |
+
*
|
1484 |
+
* @param string $message String to be processed.
|
1485 |
+
* @param array $extra_data Extra data.
|
1486 |
+
* @return string
|
1487 |
+
*/
|
1488 |
+
protected function data_request_shortcodes( $message, $extra_data ) {
|
1489 |
+
$message = str_replace( '[data_request_type]', $extra_data['description'], $message );
|
1490 |
+
|
1491 |
+
return $message;
|
1492 |
+
}
|
1493 |
+
/**
|
1494 |
+
* Handles data export shortcode.
|
1495 |
+
*
|
1496 |
+
* @param string $message String to be processed.
|
1497 |
+
* @param int $request_id Resuest ID.
|
1498 |
+
* @return string
|
1499 |
+
*/
|
1500 |
+
protected function data_export_shortcodes( $message, $request_id ) {
|
1501 |
+
$export_file_url = get_post_meta( $request_id, '_export_file_url', true );
|
1502 |
+
|
1503 |
+
$export_file_url = 'Download File: ' . $this->get_export_downloadable_url( $request_id );
|
1504 |
+
|
1505 |
+
$message = str_replace( '[data_privacy_download_url]', $export_file_url, $message );
|
1506 |
+
|
1507 |
+
$expiration = apply_filters( 'wp_privacy_export_expiration', 3 * DAY_IN_SECONDS );
|
1508 |
+
$expiration_date = date_i18n( get_option( 'date_format' ), time() + $expiration );
|
1509 |
+
$message = str_replace( '[data_privacy_download_expiry]', $expiration_date, $message );
|
1510 |
+
|
1511 |
+
return $message;
|
1512 |
+
}
|
1513 |
+
/**
|
1514 |
+
* Handles data erased shortcode.
|
1515 |
+
*
|
1516 |
+
* @param string $message String to be processed.
|
1517 |
+
* @param array $extra_data Extra data.
|
1518 |
+
* @return string
|
1519 |
+
*/
|
1520 |
+
protected function data_erased_shortcodes( $message, $extra_data ) {
|
1521 |
+
$privacy_policy_url = ( ! isset( $extra_data['privacy_policy_url'] ) ) ? get_privacy_policy_url() : $extra_data['privacy_policy_url'];
|
1522 |
+
|
1523 |
+
$message = str_replace( '[privacy_policy_url]', $privacy_policy_url, $message );
|
1524 |
+
$message = str_replace( '[sitename]', $extra_data['sitename'], $message );
|
1525 |
+
|
1526 |
+
return $message;
|
1527 |
+
}
|
1528 |
+
/**
|
1529 |
+
* Process shortcodes in email.
|
1530 |
+
*
|
1531 |
+
* @param array $email Emails.
|
1532 |
+
* @param int $post_id Post ID.
|
1533 |
+
* @param array $setting Notification settings.
|
1534 |
+
* @param array $to_emails Array of to emails.
|
1535 |
+
*
|
1536 |
+
* @return string
|
1537 |
+
*/
|
1538 |
+
public function process_shortcodes_in_email( $email, $post_id, $setting, $to_emails ) {
|
1539 |
+
if ( ! empty( $setting ) ) {
|
1540 |
+
if ( $this->starts_with( $setting['notification'], 'comment-' ) || $this->starts_with( $setting['notification'], 'moderate-' ) ) {
|
1541 |
+
// For new comment notifications, we need to use post id instead of comment id.
|
1542 |
+
$post_id = bnfw_get_post_id_from_comment( $post_id );
|
1543 |
+
}
|
1544 |
+
}
|
1545 |
+
|
1546 |
+
$email = $this->handle_shortcodes( $email, $setting['notification'], $post_id );
|
1547 |
+
|
1548 |
+
if ( is_array( $to_emails ) && ! empty( $to_emails ) ) {
|
1549 |
+
$to_email = $to_emails[0];
|
1550 |
+
|
1551 |
+
$email = $this->handle_global_user_shortcodes( $email, $to_email );
|
1552 |
+
}
|
1553 |
+
|
1554 |
+
$processed_emails = array();
|
1555 |
+
if ( is_email( $email ) ) {
|
1556 |
+
$processed_emails[] = $email;
|
1557 |
+
}
|
1558 |
+
|
1559 |
+
$emails = apply_filters( 'bnfw_non_wp_emails', $processed_emails, array( $email ), $post_id );
|
1560 |
+
|
1561 |
+
if ( empty( $emails ) ) {
|
1562 |
+
return '';
|
1563 |
+
}
|
1564 |
+
|
1565 |
+
return $emails[0];
|
1566 |
+
}
|
1567 |
+
|
1568 |
+
/**
|
1569 |
+
* Check email content type.
|
1570 |
+
*
|
1571 |
+
* @param string $setting Setting.
|
1572 |
+
* @param string $content Content.
|
1573 |
+
*
|
1574 |
+
* @return string Content .
|
1575 |
+
*/
|
1576 |
+
public function check_email_content_type( $setting, $content ) {
|
1577 |
+
|
1578 |
+
if ( 'html' === $setting['email-formatting'] ) {
|
1579 |
+
add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
|
1580 |
+
if ( 'true' !== $setting['disable-autop'] ) {
|
1581 |
+
$content = wpautop( $content );
|
1582 |
+
}
|
1583 |
+
} else {
|
1584 |
+
add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
|
1585 |
+
$content = wp_strip_all_tags( $content );
|
1586 |
+
}
|
1587 |
+
|
1588 |
+
return $content;
|
1589 |
+
}
|
1590 |
+
|
1591 |
+
/**
|
1592 |
+
* Set the email formatting to HTML.
|
1593 |
+
*
|
1594 |
+
* @since 1.4
|
1595 |
+
*/
|
1596 |
+
public function set_html_content_type() {
|
1597 |
+
return 'text/html';
|
1598 |
+
}
|
1599 |
+
|
1600 |
+
/**
|
1601 |
+
* Set the email formatting to text.
|
1602 |
+
*
|
1603 |
+
* @since 1.4
|
1604 |
+
*/
|
1605 |
+
public function set_text_content_type() {
|
1606 |
+
return 'text/plain';
|
1607 |
+
}
|
1608 |
+
|
1609 |
+
/**
|
1610 |
+
* Get user's download URL from data export request.
|
1611 |
+
*
|
1612 |
+
* @since 1.8.4
|
1613 |
+
* @param int $request_id Request ID.
|
1614 |
+
* @return string $download_url | string error message
|
1615 |
+
*/
|
1616 |
+
public function get_export_downloadable_url( $request_id = null ) {
|
1617 |
+
if ( ! $request_id ) {
|
1618 |
+
return;
|
1619 |
+
}
|
1620 |
+
|
1621 |
+
global $wpdb;
|
1622 |
+
$table = $wpdb->prefix . 'posts';
|
1623 |
+
$query = 'SELECT ID FROM ' . $table . ' WHERE `post_type` = "user_request" AND `ID` = ' . $request_id;
|
1624 |
+
$query = apply_filters( 'export_downloadable_url_query', $query, $request_id );
|
1625 |
+
$get_id = $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared
|
1626 |
+
$file = get_post_meta( $get_id, '_export_file_name', true );
|
1627 |
+
$upload_url = wp_upload_dir();
|
1628 |
+
$dl_url = $upload_url['baseurl'] . '/wp-personal-data-exports/' . $file;
|
1629 |
+
$dl_url = apply_filters( 'export_downloadable_url_return', $dl_url );
|
1630 |
+
|
1631 |
+
if ( $dl_url ) {
|
1632 |
+
return $dl_url;
|
1633 |
+
} else {
|
1634 |
+
return __( 'Error: Download link is not available please contact support' );
|
1635 |
+
}
|
1636 |
+
}
|
1637 |
+
|
1638 |
+
}
|
1639 |
+
}
|
includes/helpers/ajax-helpers.php
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* BNFW AJAX Helper functions.
|
4 |
-
*
|
5 |
-
* @since 1.4
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* BNFW Search User AJAX Handler.
|
10 |
-
*
|
11 |
-
* @since 1.3.6
|
12 |
-
*/
|
13 |
-
function bnfw_search_users() {
|
14 |
-
check_ajax_referer( 'bnfw_users_search_ajax_nonce', 'bnfw_security' );
|
15 |
-
if ( ! current_user_can( 'bnfw' ) ) {
|
16 |
-
wp_die( -1 );
|
17 |
-
}
|
18 |
-
global $wp_roles;
|
19 |
-
|
20 |
-
$roles_data = array();
|
21 |
-
$user_count = count_users();
|
22 |
-
$roles = $wp_roles->get_names();
|
23 |
-
foreach ( $roles as $role_slug => $role_name ) {
|
24 |
-
$count = 0;
|
25 |
-
if ( isset( $user_count['avail_roles'][ $role_slug ] ) ) {
|
26 |
-
$count = $user_count['avail_roles'][ $role_slug ];
|
27 |
-
}
|
28 |
-
|
29 |
-
$roles_data[] = array(
|
30 |
-
'id' => 'role-' . $role_slug,
|
31 |
-
'text' => $role_name . ' (' . $count . ' Users)',
|
32 |
-
);
|
33 |
-
}
|
34 |
-
|
35 |
-
$data = array(
|
36 |
-
array(
|
37 |
-
'id' => 1,
|
38 |
-
'text' => esc_html__( 'User Roles', 'bnfw' ),
|
39 |
-
'children' => $roles_data,
|
40 |
-
),
|
41 |
-
);
|
42 |
-
|
43 |
-
$query = sanitize_text_field( $_GET['query'] );
|
44 |
-
$users = get_users( array(
|
45 |
-
'order_by' => 'email',
|
46 |
-
'search' => "$query*",
|
47 |
-
'number' => 100,
|
48 |
-
'fields' => array( 'ID', 'user_login' ),
|
49 |
-
) );
|
50 |
-
|
51 |
-
$user_data = array();
|
52 |
-
foreach ( $users as $user ) {
|
53 |
-
$user_data[] = array(
|
54 |
-
'id' => $user->ID,
|
55 |
-
'text' => $user->user_login,
|
56 |
-
);
|
57 |
-
}
|
58 |
-
|
59 |
-
$data[] = array(
|
60 |
-
'id' => 2,
|
61 |
-
'text' => esc_html__( 'Users', 'bnfw' ),
|
62 |
-
'children' => $user_data,
|
63 |
-
);
|
64 |
-
|
65 |
-
echo json_encode( $data );
|
66 |
-
wp_die();
|
67 |
-
}
|
68 |
-
add_action( 'wp_ajax_bnfw_search_users', 'bnfw_search_users' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/helpers/class-bnfw-ajax.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* BNFW AJAX Helper functions.
|
4 |
+
*
|
5 |
+
* @class BNFW_AJAX
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit;
|
10 |
+
|
11 |
+
if ( ! class_exists( 'BNFW_AJAX', false ) ) {
|
12 |
+
/**
|
13 |
+
* BNFW_AJAX class.
|
14 |
+
*/
|
15 |
+
class BNFW_AJAX {
|
16 |
+
/**
|
17 |
+
* Hook in ajax handlers.
|
18 |
+
*/
|
19 |
+
public static function init() {
|
20 |
+
add_action( 'wp_ajax_bnfw_search_users', array( __CLASS__, 'bnfw_search_users' ) );
|
21 |
+
}
|
22 |
+
/**
|
23 |
+
* BNFW Search User AJAX Handler.
|
24 |
+
*/
|
25 |
+
public static function bnfw_search_users() {
|
26 |
+
check_ajax_referer( 'bnfw_users_search_ajax_nonce', 'bnfw_security' );
|
27 |
+
if ( ! current_user_can( 'bnfw' ) ) {
|
28 |
+
wp_die( -1 );
|
29 |
+
}
|
30 |
+
global $wp_roles;
|
31 |
+
$roles_data = array();
|
32 |
+
$user_count = count_users();
|
33 |
+
$roles = $wp_roles->get_names();
|
34 |
+
foreach ( $roles as $role_slug => $role_name ) {
|
35 |
+
$count = 0;
|
36 |
+
if ( isset( $user_count['avail_roles'][ $role_slug ] ) ) {
|
37 |
+
$count = $user_count['avail_roles'][ $role_slug ];
|
38 |
+
}
|
39 |
+
$roles_data[] = array(
|
40 |
+
'id' => 'role-' . $role_slug,
|
41 |
+
'text' => $role_name . ' (' . $count . ' Users)',
|
42 |
+
);
|
43 |
+
}
|
44 |
+
$data = array(
|
45 |
+
array(
|
46 |
+
'id' => 1,
|
47 |
+
'text' => esc_html__( 'User Roles', 'bnfw' ),
|
48 |
+
'children' => $roles_data,
|
49 |
+
),
|
50 |
+
);
|
51 |
+
$query = isset( $_GET['query'] ) ? sanitize_text_field( wp_unslash( $_GET['query'] ) ) : '';
|
52 |
+
$users = get_users(
|
53 |
+
array(
|
54 |
+
'order_by' => 'email',
|
55 |
+
'search' => "$query*",
|
56 |
+
'number' => 100,
|
57 |
+
'fields' => array( 'ID', 'user_login' ),
|
58 |
+
)
|
59 |
+
);
|
60 |
+
$user_data = array();
|
61 |
+
foreach ( $users as $user ) {
|
62 |
+
$user_data[] = array(
|
63 |
+
'id' => $user->ID,
|
64 |
+
'text' => $user->user_login,
|
65 |
+
);
|
66 |
+
}
|
67 |
+
$data[] = array(
|
68 |
+
'id' => 2,
|
69 |
+
'text' => esc_html__( 'Users', 'bnfw' ),
|
70 |
+
'children' => $user_data,
|
71 |
+
);
|
72 |
+
echo wp_json_encode( $data );
|
73 |
+
wp_die();
|
74 |
+
}
|
75 |
+
}
|
76 |
+
BNFW_AJAX::init();
|
77 |
+
}
|
includes/helpers/helpers.php
CHANGED
@@ -1,205 +1,245 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* General BNFW Helpers.
|
4 |
-
*
|
5 |
-
* @since 1.3.6
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
}
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* General BNFW Helpers.
|
4 |
+
*
|
5 |
+
* @since 1.3.6
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
|
10 |
+
|
11 |
+
if ( ! function_exists( 'bnfw_get_user_select_class' ) ) {
|
12 |
+
/**
|
13 |
+
* Dynamically determine the class name for select2 user dropdown based on user count.
|
14 |
+
*
|
15 |
+
* @since 1.3.6
|
16 |
+
*/
|
17 |
+
function bnfw_get_user_select_class() {
|
18 |
+
$user_count = count_users();
|
19 |
+
|
20 |
+
if ( $user_count['total_users'] > 200 ) {
|
21 |
+
return 'user-ajax-select2';
|
22 |
+
} else {
|
23 |
+
return 'user-select2';
|
24 |
+
}
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
if ( ! function_exists( 'bnfw_expanded_alowed_tags' ) ) {
|
29 |
+
/**
|
30 |
+
* Get allowed html for wp_kses.
|
31 |
+
*
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
function bnfw_expanded_alowed_tags() {
|
35 |
+
$allowed_html['select'] = array(
|
36 |
+
'class' => array(),
|
37 |
+
'id' => array(),
|
38 |
+
'name' => array(),
|
39 |
+
'value' => array(),
|
40 |
+
'type' => array(),
|
41 |
+
);
|
42 |
+
// select options.
|
43 |
+
$allowed_html['option'] = array(
|
44 |
+
'selected' => array(),
|
45 |
+
);
|
46 |
+
return $allowed_html;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
if ( ! function_exists( 'bnfw_render_users_dropdown' ) ) {
|
51 |
+
/**
|
52 |
+
* Render users dropdown.
|
53 |
+
*
|
54 |
+
* @since 1.3.6
|
55 |
+
*
|
56 |
+
* @param array $selected_users Selected users.
|
57 |
+
*/
|
58 |
+
function bnfw_render_users_dropdown( $selected_users ) {
|
59 |
+
global $wp_roles;
|
60 |
+
$allowed_html = bnfw_expanded_alowed_tags();
|
61 |
+
|
62 |
+
$non_wp_users = $selected_users;
|
63 |
+
$user_count = count_users();
|
64 |
+
?>
|
65 |
+
<optgroup label="<?php esc_attr_e( 'User Roles', 'bnfw' ); ?>">
|
66 |
+
<?php
|
67 |
+
$roles = $wp_roles->get_names();
|
68 |
+
|
69 |
+
foreach ( $roles as $role_slug => $role_name ) {
|
70 |
+
$selected = selected( true, in_array( 'role-' . $role_slug, $selected_users, true ), false );
|
71 |
+
|
72 |
+
if ( ! empty( $selected ) ) {
|
73 |
+
$non_wp_users = array_diff( $non_wp_users, array( 'role-' . $role_slug ) );
|
74 |
+
}
|
75 |
+
|
76 |
+
// Compatibility code, which will be eventually removed.
|
77 |
+
$selected_old = selected( true, in_array( 'role-' . $role_name, $selected_users, true ), false );
|
78 |
+
if ( ! empty( $selected_old ) ) {
|
79 |
+
$selected = $selected_old;
|
80 |
+
}
|
81 |
+
|
82 |
+
$count = 0;
|
83 |
+
if ( isset( $user_count['avail_roles'][ $role_slug ] ) ) {
|
84 |
+
$count = $user_count['avail_roles'][ $role_slug ];
|
85 |
+
}
|
86 |
+
echo wp_kses( '<option value="role-', esc_attr( $role_slug ), '" ', $selected, '>', esc_html( $role_name ), ' (', $count, ' ' . __( 'Users', 'bnfw' ) . ')', '</option>', $allowed_html );
|
87 |
+
}
|
88 |
+
?>
|
89 |
+
</optgroup>
|
90 |
+
|
91 |
+
<optgroup label="<?php esc_attr_e( 'Users', 'bnfw' ); ?>">
|
92 |
+
<?php
|
93 |
+
$args = array(
|
94 |
+
'order_by' => 'email',
|
95 |
+
'fields' => array( 'ID', 'user_login' ),
|
96 |
+
'number' => 200,
|
97 |
+
);
|
98 |
+
|
99 |
+
// if there are more than 200 users then use AJAX to load them dynamically.
|
100 |
+
// So just get only the selected users.
|
101 |
+
if ( $user_count['total_users'] > 200 ) {
|
102 |
+
$selected_user_ids = array();
|
103 |
+
foreach ( $selected_users as $selected_user ) {
|
104 |
+
if ( absint( $selected_user ) > 0 ) {
|
105 |
+
$selected_user_ids[] = $selected_user;
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
if ( $selected_user_ids > 0 ) {
|
110 |
+
$args['include'] = $selected_user_ids;
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
$users = get_users( $args );
|
115 |
+
|
116 |
+
foreach ( $users as $user ) {
|
117 |
+
$selected = selected( true, in_array( $user->ID, $selected_users, true ), false );
|
118 |
+
|
119 |
+
if ( ! empty( $selected ) ) {
|
120 |
+
$non_wp_users = array_diff( $non_wp_users, array( $user->ID ) );
|
121 |
+
}
|
122 |
+
|
123 |
+
echo wp_kses( '<option value="', esc_attr( $user->ID ), '" ', $selected, '>', esc_html( $user->user_login ), '</option>', $allowed_html );
|
124 |
+
}
|
125 |
+
|
126 |
+
?>
|
127 |
+
</optgroup>
|
128 |
+
|
129 |
+
<?php if ( ! empty( $non_wp_users ) ) { ?>
|
130 |
+
<optgroup label="<?php esc_attr_e( 'Non WordPress Users', 'bnfw' ); ?>">
|
131 |
+
<?php
|
132 |
+
foreach ( $non_wp_users as $non_wp_user ) {
|
133 |
+
echo '<option value="', esc_attr( $non_wp_user ), '" selected >', esc_html( $non_wp_user ), '</option>';
|
134 |
+
}
|
135 |
+
?>
|
136 |
+
</optgroup>
|
137 |
+
<?php
|
138 |
+
}
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
if ( ! function_exists( 'bnfw_is_comment_notification' ) ) {
|
143 |
+
/**
|
144 |
+
* Find whether the notification name is a comment notification.
|
145 |
+
*
|
146 |
+
* @param string $notification_name Notification Name.
|
147 |
+
*
|
148 |
+
* @return bool True if it is a comment notification, False otherwise.
|
149 |
+
*/
|
150 |
+
function bnfw_is_comment_notification( $notification_name ) {
|
151 |
+
$is_comment_notification = false;
|
152 |
+
|
153 |
+
switch ( $notification_name ) {
|
154 |
+
case 'new-comment':
|
155 |
+
case 'new-trackback':
|
156 |
+
case 'new-pingback':
|
157 |
+
case 'reply-comment':
|
158 |
+
$is_comment_notification = true;
|
159 |
+
break;
|
160 |
+
|
161 |
+
default:
|
162 |
+
$type = explode( '-', $notification_name, 2 );
|
163 |
+
if ( 'comment' === $type[0] || 'moderate' === $type[0] || 'approve' === $type[0] ) {
|
164 |
+
$is_comment_notification = true;
|
165 |
+
}
|
166 |
+
break;
|
167 |
+
}
|
168 |
+
|
169 |
+
return $is_comment_notification;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
if ( ! function_exists( 'bnfw_format_user_capabilities' ) ) {
|
174 |
+
/**
|
175 |
+
* Format user capabilities.
|
176 |
+
*
|
177 |
+
* @param array $wp_capabilities User capabilities.
|
178 |
+
*
|
179 |
+
* @return string Formatted capabilities.
|
180 |
+
*/
|
181 |
+
function bnfw_format_user_capabilities( $wp_capabilities ) {
|
182 |
+
$capabilities = array();
|
183 |
+
|
184 |
+
if ( is_array( $wp_capabilities ) ) {
|
185 |
+
foreach ( $wp_capabilities as $capability => $enabled ) {
|
186 |
+
if ( $enabled ) {
|
187 |
+
$capabilities[] = $capability;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
return implode( ', ', $capabilities );
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
if ( ! function_exists( 'bnfw_is_tracking_allowed' ) ) {
|
197 |
+
/**
|
198 |
+
* Has the user opted-in for tracking?
|
199 |
+
*
|
200 |
+
* @return bool True if tracking is allowed, False otherwise.
|
201 |
+
*/
|
202 |
+
function bnfw_is_tracking_allowed() {
|
203 |
+
$tracking_allowed = false;
|
204 |
+
|
205 |
+
if ( get_option( 'bnfw_allow_tracking' ) === 'on' ) {
|
206 |
+
$tracking_allowed = true;
|
207 |
+
}
|
208 |
+
|
209 |
+
return $tracking_allowed;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
if ( ! function_exists( 'bnfw_get_post_id_from_comment' ) ) {
|
214 |
+
/**
|
215 |
+
* Get post id from comment id.
|
216 |
+
*
|
217 |
+
* @param int $comment_id Comment ID for which we need Post ID.
|
218 |
+
* @return int Post ID. 0 if invalid comment id.
|
219 |
+
*/
|
220 |
+
function bnfw_get_post_id_from_comment( $comment_id ) {
|
221 |
+
$comment = get_comment( $comment_id );
|
222 |
+
|
223 |
+
if ( null !== $comment ) {
|
224 |
+
return $comment->comment_post_ID;
|
225 |
+
}
|
226 |
+
|
227 |
+
return 0;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
if ( ! function_exists( 'bnfw_format_date' ) ) {
|
232 |
+
/**
|
233 |
+
* Format date based on date format stored in options.
|
234 |
+
*
|
235 |
+
* @param string $date Date.
|
236 |
+
*
|
237 |
+
* @return string Formatted date.
|
238 |
+
*/
|
239 |
+
function bnfw_format_date( $date ) {
|
240 |
+
$date_format = get_option( 'date_format' );
|
241 |
+
$time_format = get_option( 'time_format' );
|
242 |
+
|
243 |
+
return date( $date_format . ' ' . $time_format, strtotime( $date ) );
|
244 |
+
}
|
245 |
+
}
|
includes/import.php
DELETED
@@ -1,169 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Import notification from old plugin.
|
5 |
-
*
|
6 |
-
* @since 1.0
|
7 |
-
*/
|
8 |
-
class BNFW_Import {
|
9 |
-
const EMAIL_OPTION = 'bnfw_custom_email_settings';
|
10 |
-
const SETTING_OPTION = 'bnfw_settings';
|
11 |
-
private $events = array(
|
12 |
-
'create_term',
|
13 |
-
'publish_post',
|
14 |
-
'comment_post',
|
15 |
-
'user_register',
|
16 |
-
'trackback_post',
|
17 |
-
'pingback_post',
|
18 |
-
'lostpassword_post',
|
19 |
-
);
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Import notification from old plugin.
|
23 |
-
*
|
24 |
-
* @since 1.0
|
25 |
-
*/
|
26 |
-
public function import() {
|
27 |
-
global $wp_roles;
|
28 |
-
$roles = $wp_roles->get_names();
|
29 |
-
|
30 |
-
if ( $this->import_needed() ) {
|
31 |
-
$old_events = get_option( self::SETTING_OPTION );
|
32 |
-
foreach ( $old_events as $event => $value ) {
|
33 |
-
if ( '1' == $value ) {
|
34 |
-
$event_array = explode( '-', $event );
|
35 |
-
if ( 2 == count( $event_array ) ) {
|
36 |
-
if ( in_array( $event_array[0], $this->events ) && in_array( $event_array[1], array_keys( $roles ) ) ) {
|
37 |
-
$event_array[1] = $roles[ $event_array[1] ];
|
38 |
-
$this->insert_notification( $event_array );
|
39 |
-
}
|
40 |
-
}
|
41 |
-
}
|
42 |
-
}
|
43 |
-
// delete the old options
|
44 |
-
$this->delete_option();
|
45 |
-
}
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Check if import is needed.
|
50 |
-
*
|
51 |
-
* @since 1.0
|
52 |
-
* @return unknown
|
53 |
-
*/
|
54 |
-
private function import_needed() {
|
55 |
-
if ( get_option( self::EMAIL_OPTION ) && get_option( self::SETTING_OPTION ) ) {
|
56 |
-
return true;
|
57 |
-
}
|
58 |
-
|
59 |
-
return false;
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Insert notification.
|
64 |
-
*
|
65 |
-
* @param mixed $event
|
66 |
-
*/
|
67 |
-
private function insert_notification( $event ) {
|
68 |
-
$post = array(
|
69 |
-
'post_title' => $event[0] . esc_html__( ' for ', 'bnfw' ) . $event[1] . esc_html__( ' (Auto Imported)', 'bnfw' ),
|
70 |
-
'post_type' => BNFW_Notification::POST_TYPE,
|
71 |
-
'post_content' => '',
|
72 |
-
'post_status' => 'publish',
|
73 |
-
);
|
74 |
-
|
75 |
-
$post_id = wp_insert_post( $post );
|
76 |
-
if ( $post_id > 0 ) {
|
77 |
-
$content = $this->map_notification_content( $event[0] );
|
78 |
-
$setting = array(
|
79 |
-
'notification' => $this->map_notification( $event[0] ),
|
80 |
-
'user-roles' => array( $event[1] ),
|
81 |
-
'users' => array(),
|
82 |
-
'subject' => $content['subject'],
|
83 |
-
'message' => $content['body'],
|
84 |
-
);
|
85 |
-
|
86 |
-
foreach ( $setting as $key => $value ) {
|
87 |
-
update_post_meta( $post_id, BNFW_Notification::META_KEY_PREFIX . $key, $value );
|
88 |
-
}
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Map old notification type to new notification type.
|
94 |
-
*
|
95 |
-
* @param mixed $event_name
|
96 |
-
*
|
97 |
-
* @return unknown
|
98 |
-
*/
|
99 |
-
private function map_notification( $event_name ) {
|
100 |
-
switch ( $event_name ) {
|
101 |
-
case 'create_term':
|
102 |
-
return 'new-category';
|
103 |
-
break;
|
104 |
-
case 'publish_post':
|
105 |
-
return 'new-post';
|
106 |
-
break;
|
107 |
-
case 'comment_post':
|
108 |
-
return 'new-comment';
|
109 |
-
break;
|
110 |
-
case 'user_register':
|
111 |
-
return 'new-user';
|
112 |
-
break;
|
113 |
-
case 'trackback_post':
|
114 |
-
return 'new-trackback';
|
115 |
-
break;
|
116 |
-
case 'pingback_post':
|
117 |
-
return 'new-pingback';
|
118 |
-
break;
|
119 |
-
case 'lostpassword_post':
|
120 |
-
return 'user-password';
|
121 |
-
break;
|
122 |
-
}
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Map content from old plugin.
|
127 |
-
*
|
128 |
-
* @param unknown $event_name
|
129 |
-
*
|
130 |
-
* @return unknown
|
131 |
-
*/
|
132 |
-
private function map_notification_content( $event_name ) {
|
133 |
-
$content = array();
|
134 |
-
if ( ! isset( $this->content_map ) ) {
|
135 |
-
$this->parse_content();
|
136 |
-
}
|
137 |
-
|
138 |
-
return $this->content_map[ $event_name ];
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Parse content from old plugins setting.
|
143 |
-
*
|
144 |
-
* @since 1.0
|
145 |
-
*/
|
146 |
-
private function parse_content() {
|
147 |
-
$old_content = get_option( self::EMAIL_OPTION );
|
148 |
-
$content_map = array();
|
149 |
-
foreach ( $old_content as $key => $value ) {
|
150 |
-
$key_array = explode( '-', $key );
|
151 |
-
if ( 3 == count( $key_array ) ) {
|
152 |
-
$content_map[ $key_array[2] ][ $key_array[1] ] = $value;
|
153 |
-
}
|
154 |
-
}
|
155 |
-
$this->content_map = $content_map;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Delete old plugin database options.
|
160 |
-
*
|
161 |
-
* @since 1.0
|
162 |
-
*/
|
163 |
-
private function delete_option() {
|
164 |
-
delete_option( self::EMAIL_OPTION );
|
165 |
-
delete_option( self::SETTING_OPTION );
|
166 |
-
}
|
167 |
-
}
|
168 |
-
|
169 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/libraries/EDD_SL_Plugin_Updater.php
DELETED
@@ -1,619 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// Exit if accessed directly
|
4 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Allows plugins to use their own update API.
|
8 |
-
*
|
9 |
-
* @author Easy Digital Downloads
|
10 |
-
* @version 1.8.0
|
11 |
-
*/
|
12 |
-
class EDD_SL_Plugin_Updater {
|
13 |
-
|
14 |
-
private $api_url = '';
|
15 |
-
private $api_data = array();
|
16 |
-
private $name = '';
|
17 |
-
private $slug = '';
|
18 |
-
private $version = '';
|
19 |
-
private $wp_override = false;
|
20 |
-
private $cache_key = '';
|
21 |
-
private $beta = false;
|
22 |
-
private $health_check_timeout = 5;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Class constructor.
|
26 |
-
*
|
27 |
-
* @uses plugin_basename()
|
28 |
-
* @uses hook()
|
29 |
-
*
|
30 |
-
* @param string $_api_url The URL pointing to the custom API endpoint.
|
31 |
-
* @param string $_plugin_file Path to the plugin file.
|
32 |
-
* @param array $_api_data Optional data to send with API calls.
|
33 |
-
*/
|
34 |
-
public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
35 |
-
|
36 |
-
global $edd_plugin_data;
|
37 |
-
|
38 |
-
$this->api_url = trailingslashit( $_api_url );
|
39 |
-
$this->api_data = $_api_data;
|
40 |
-
$this->name = plugin_basename( $_plugin_file );
|
41 |
-
$this->slug = basename( $_plugin_file, '.php' );
|
42 |
-
$this->version = $_api_data['version'];
|
43 |
-
$this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
|
44 |
-
$this->beta = ! empty( $this->api_data['beta'] ) ? true : false;
|
45 |
-
$this->cache_key = 'edd_sl_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
|
46 |
-
|
47 |
-
$edd_plugin_data[ $this->slug ] = $this->api_data;
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Fires after the $edd_plugin_data is setup.
|
51 |
-
*
|
52 |
-
* @since x.x.x
|
53 |
-
*
|
54 |
-
* @param array $edd_plugin_data Array of EDD SL plugin data.
|
55 |
-
*/
|
56 |
-
do_action( 'post_edd_sl_plugin_updater_setup', $edd_plugin_data );
|
57 |
-
|
58 |
-
// Set up hooks.
|
59 |
-
$this->init();
|
60 |
-
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Set up WordPress filters to hook into WP's update process.
|
65 |
-
*
|
66 |
-
* @uses add_filter()
|
67 |
-
*
|
68 |
-
* @return void
|
69 |
-
*/
|
70 |
-
public function init() {
|
71 |
-
|
72 |
-
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
|
73 |
-
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
74 |
-
remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10 );
|
75 |
-
add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
|
76 |
-
add_action( 'admin_init', array( $this, 'show_changelog' ) );
|
77 |
-
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* Check for Updates at the defined API endpoint and modify the update array.
|
82 |
-
*
|
83 |
-
* This function dives into the update API just when WordPress creates its update array,
|
84 |
-
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
85 |
-
* It is reassembled from parts of the native WordPress plugin update code.
|
86 |
-
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
87 |
-
*
|
88 |
-
* @uses api_request()
|
89 |
-
*
|
90 |
-
* @param array $_transient_data Update array build by WordPress.
|
91 |
-
* @return array Modified update array with custom plugin data.
|
92 |
-
*/
|
93 |
-
public function check_update( $_transient_data ) {
|
94 |
-
|
95 |
-
global $pagenow;
|
96 |
-
|
97 |
-
if ( ! is_object( $_transient_data ) ) {
|
98 |
-
$_transient_data = new stdClass;
|
99 |
-
}
|
100 |
-
|
101 |
-
if ( 'plugins.php' == $pagenow && is_multisite() ) {
|
102 |
-
return $_transient_data;
|
103 |
-
}
|
104 |
-
|
105 |
-
if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
|
106 |
-
return $_transient_data;
|
107 |
-
}
|
108 |
-
|
109 |
-
$current = $this->get_repo_api_data();
|
110 |
-
if ( false !== $current && is_object( $current ) && isset( $current->new_version ) ) {
|
111 |
-
if ( version_compare( $this->version, $current->new_version, '<' ) ) {
|
112 |
-
$_transient_data->response[ $this->name ] = $current;
|
113 |
-
} else {
|
114 |
-
// Populating the no_update information is required to support auto-updates in WordPress 5.5.
|
115 |
-
$_transient_data->no_update[ $this->name ] = $current;
|
116 |
-
}
|
117 |
-
}
|
118 |
-
$_transient_data->last_checked = time();
|
119 |
-
$_transient_data->checked[ $this->name ] = $this->version;
|
120 |
-
|
121 |
-
return $_transient_data;
|
122 |
-
}
|
123 |
-
|
124 |
-
/**
|
125 |
-
* Get repo API data from store.
|
126 |
-
* Save to cache.
|
127 |
-
*
|
128 |
-
* @return \stdClass
|
129 |
-
*/
|
130 |
-
public function get_repo_api_data() {
|
131 |
-
$version_info = $this->get_cached_version_info();
|
132 |
-
|
133 |
-
if ( false === $version_info ) {
|
134 |
-
$version_info = $this->api_request(
|
135 |
-
'plugin_latest_version',
|
136 |
-
array(
|
137 |
-
'slug' => $this->slug,
|
138 |
-
'beta' => $this->beta,
|
139 |
-
)
|
140 |
-
);
|
141 |
-
if ( ! $version_info ) {
|
142 |
-
return false;
|
143 |
-
}
|
144 |
-
|
145 |
-
// This is required for your plugin to support auto-updates in WordPress 5.5.
|
146 |
-
$version_info->plugin = $this->name;
|
147 |
-
$version_info->id = $this->name;
|
148 |
-
|
149 |
-
$this->set_version_info_cache( $version_info );
|
150 |
-
}
|
151 |
-
|
152 |
-
return $version_info;
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
|
157 |
-
*
|
158 |
-
* @param string $file
|
159 |
-
* @param array $plugin
|
160 |
-
*/
|
161 |
-
public function show_update_notification( $file, $plugin ) {
|
162 |
-
|
163 |
-
if ( is_network_admin() ) {
|
164 |
-
return;
|
165 |
-
}
|
166 |
-
|
167 |
-
if( ! current_user_can( 'update_plugins' ) ) {
|
168 |
-
return;
|
169 |
-
}
|
170 |
-
|
171 |
-
if( ! is_multisite() ) {
|
172 |
-
return;
|
173 |
-
}
|
174 |
-
|
175 |
-
if ( $this->name != $file ) {
|
176 |
-
return;
|
177 |
-
}
|
178 |
-
|
179 |
-
// Remove our filter on the site transient
|
180 |
-
remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
|
181 |
-
|
182 |
-
$update_cache = get_site_transient( 'update_plugins' );
|
183 |
-
|
184 |
-
$update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
|
185 |
-
|
186 |
-
if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
|
187 |
-
|
188 |
-
$version_info = $this->get_repo_api_data();
|
189 |
-
|
190 |
-
if ( false === $version_info ) {
|
191 |
-
$version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
|
192 |
-
|
193 |
-
// Since we disabled our filter for the transient, we aren't running our object conversion on banners, sections, or icons. Do this now:
|
194 |
-
if ( isset( $version_info->banners ) && ! is_array( $version_info->banners ) ) {
|
195 |
-
$version_info->banners = $this->convert_object_to_array( $version_info->banners );
|
196 |
-
}
|
197 |
-
|
198 |
-
if ( isset( $version_info->sections ) && ! is_array( $version_info->sections ) ) {
|
199 |
-
$version_info->sections = $this->convert_object_to_array( $version_info->sections );
|
200 |
-
}
|
201 |
-
|
202 |
-
if ( isset( $version_info->icons ) && ! is_array( $version_info->icons ) ) {
|
203 |
-
$version_info->icons = $this->convert_object_to_array( $version_info->icons );
|
204 |
-
}
|
205 |
-
|
206 |
-
if ( isset( $version_info->contributors ) && ! is_array( $version_info->contributors ) ) {
|
207 |
-
$version_info->contributors = $this->convert_object_to_array( $version_info->contributors );
|
208 |
-
}
|
209 |
-
|
210 |
-
$this->set_version_info_cache( $version_info );
|
211 |
-
}
|
212 |
-
|
213 |
-
if ( ! is_object( $version_info ) ) {
|
214 |
-
return;
|
215 |
-
}
|
216 |
-
|
217 |
-
if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
|
218 |
-
$update_cache->response[ $this->name ] = $version_info;
|
219 |
-
} else {
|
220 |
-
$update_cache->no_update[ $this->name ] = $version_info;
|
221 |
-
}
|
222 |
-
|
223 |
-
$update_cache->last_checked = time();
|
224 |
-
$update_cache->checked[ $this->name ] = $this->version;
|
225 |
-
|
226 |
-
set_site_transient( 'update_plugins', $update_cache );
|
227 |
-
|
228 |
-
} else {
|
229 |
-
|
230 |
-
$version_info = $update_cache->response[ $this->name ];
|
231 |
-
|
232 |
-
}
|
233 |
-
|
234 |
-
// Restore our filter
|
235 |
-
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
|
236 |
-
|
237 |
-
if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
|
238 |
-
|
239 |
-
// build a plugin list row, with update notification
|
240 |
-
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
|
241 |
-
# <tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">
|
242 |
-
echo '<tr class="plugin-update-tr" id="' . $this->slug . '-update" data-slug="' . $this->slug . '" data-plugin="' . $this->slug . '/' . $file . '">';
|
243 |
-
echo '<td colspan="3" class="plugin-update colspanchange">';
|
244 |
-
echo '<div class="update-message notice inline notice-warning notice-alt">';
|
245 |
-
|
246 |
-
$changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
|
247 |
-
|
248 |
-
if ( empty( $version_info->download_link ) ) {
|
249 |
-
printf(
|
250 |
-
__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'easy-digital-downloads' ),
|
251 |
-
esc_html( $version_info->name ),
|
252 |
-
'<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
|
253 |
-
esc_html( $version_info->new_version ),
|
254 |
-
'</a>'
|
255 |
-
);
|
256 |
-
} else {
|
257 |
-
printf(
|
258 |
-
__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.', 'easy-digital-downloads' ),
|
259 |
-
esc_html( $version_info->name ),
|
260 |
-
'<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
|
261 |
-
esc_html( $version_info->new_version ),
|
262 |
-
'</a>',
|
263 |
-
'<a href="' . esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) ) .'">',
|
264 |
-
'</a>'
|
265 |
-
);
|
266 |
-
}
|
267 |
-
|
268 |
-
do_action( "in_plugin_update_message-{$file}", $plugin, $version_info );
|
269 |
-
|
270 |
-
echo '</div></td></tr>';
|
271 |
-
}
|
272 |
-
}
|
273 |
-
|
274 |
-
/**
|
275 |
-
* Updates information on the "View version x.x details" page with custom data.
|
276 |
-
*
|
277 |
-
* @uses api_request()
|
278 |
-
*
|
279 |
-
* @param mixed $_data
|
280 |
-
* @param string $_action
|
281 |
-
* @param object $_args
|
282 |
-
* @return object $_data
|
283 |
-
*/
|
284 |
-
public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
285 |
-
|
286 |
-
if ( $_action != 'plugin_information' ) {
|
287 |
-
|
288 |
-
return $_data;
|
289 |
-
|
290 |
-
}
|
291 |
-
|
292 |
-
if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
|
293 |
-
|
294 |
-
return $_data;
|
295 |
-
|
296 |
-
}
|
297 |
-
|
298 |
-
$to_send = array(
|
299 |
-
'slug' => $this->slug,
|
300 |
-
'is_ssl' => is_ssl(),
|
301 |
-
'fields' => array(
|
302 |
-
'banners' => array(),
|
303 |
-
'reviews' => false,
|
304 |
-
'icons' => array(),
|
305 |
-
)
|
306 |
-
);
|
307 |
-
|
308 |
-
// Get the transient where we store the api request for this plugin for 24 hours
|
309 |
-
$edd_api_request_transient = $this->get_cached_version_info();
|
310 |
-
|
311 |
-
//If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
|
312 |
-
if ( empty( $edd_api_request_transient ) ) {
|
313 |
-
|
314 |
-
$api_response = $this->api_request( 'plugin_information', $to_send );
|
315 |
-
|
316 |
-
// Expires in 3 hours
|
317 |
-
$this->set_version_info_cache( $api_response );
|
318 |
-
|
319 |
-
if ( false !== $api_response ) {
|
320 |
-
$_data = $api_response;
|
321 |
-
}
|
322 |
-
|
323 |
-
} else {
|
324 |
-
$_data = $edd_api_request_transient;
|
325 |
-
}
|
326 |
-
|
327 |
-
// Convert sections into an associative array, since we're getting an object, but Core expects an array.
|
328 |
-
if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
|
329 |
-
$_data->sections = $this->convert_object_to_array( $_data->sections );
|
330 |
-
}
|
331 |
-
|
332 |
-
// Convert banners into an associative array, since we're getting an object, but Core expects an array.
|
333 |
-
if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
|
334 |
-
$_data->banners = $this->convert_object_to_array( $_data->banners );
|
335 |
-
}
|
336 |
-
|
337 |
-
// Convert icons into an associative array, since we're getting an object, but Core expects an array.
|
338 |
-
if ( isset( $_data->icons ) && ! is_array( $_data->icons ) ) {
|
339 |
-
$_data->icons = $this->convert_object_to_array( $_data->icons );
|
340 |
-
}
|
341 |
-
|
342 |
-
// Convert contributors into an associative array, since we're getting an object, but Core expects an array.
|
343 |
-
if ( isset( $_data->contributors ) && ! is_array( $_data->contributors ) ) {
|
344 |
-
$_data->contributors = $this->convert_object_to_array( $_data->contributors );
|
345 |
-
}
|
346 |
-
|
347 |
-
if( ! isset( $_data->plugin ) ) {
|
348 |
-
$_data->plugin = $this->name;
|
349 |
-
}
|
350 |
-
|
351 |
-
return $_data;
|
352 |
-
}
|
353 |
-
|
354 |
-
/**
|
355 |
-
* Convert some objects to arrays when injecting data into the update API
|
356 |
-
*
|
357 |
-
* Some data like sections, banners, and icons are expected to be an associative array, however due to the JSON
|
358 |
-
* decoding, they are objects. This method allows us to pass in the object and return an associative array.
|
359 |
-
*
|
360 |
-
* @since 3.6.5
|
361 |
-
*
|
362 |
-
* @param stdClass $data
|
363 |
-
*
|
364 |
-
* @return array
|
365 |
-
*/
|
366 |
-
private function convert_object_to_array( $data ) {
|
367 |
-
if ( ! is_array( $data ) && ! is_object( $data ) ) {
|
368 |
-
return array();
|
369 |
-
}
|
370 |
-
$new_data = array();
|
371 |
-
foreach ( $data as $key => $value ) {
|
372 |
-
$new_data[ $key ] = is_object( $value ) ? $this->convert_object_to_array( $value ) : $value;
|
373 |
-
}
|
374 |
-
|
375 |
-
return $new_data;
|
376 |
-
}
|
377 |
-
|
378 |
-
/**
|
379 |
-
* Disable SSL verification in order to prevent download update failures
|
380 |
-
*
|
381 |
-
* @param array $args
|
382 |
-
* @param string $url
|
383 |
-
* @return object $array
|
384 |
-
*/
|
385 |
-
public function http_request_args( $args, $url ) {
|
386 |
-
|
387 |
-
$verify_ssl = $this->verify_ssl();
|
388 |
-
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
|
389 |
-
$args['sslverify'] = $verify_ssl;
|
390 |
-
}
|
391 |
-
return $args;
|
392 |
-
|
393 |
-
}
|
394 |
-
|
395 |
-
/**
|
396 |
-
* Calls the API and, if successfull, returns the object delivered by the API.
|
397 |
-
*
|
398 |
-
* @uses get_bloginfo()
|
399 |
-
* @uses wp_remote_post()
|
400 |
-
* @uses is_wp_error()
|
401 |
-
*
|
402 |
-
* @param string $_action The requested action.
|
403 |
-
* @param array $_data Parameters for the API action.
|
404 |
-
* @return false|object
|
405 |
-
*/
|
406 |
-
private function api_request( $_action, $_data ) {
|
407 |
-
|
408 |
-
global $wp_version, $edd_plugin_url_available;
|
409 |
-
|
410 |
-
$verify_ssl = $this->verify_ssl();
|
411 |
-
|
412 |
-
// Do a quick status check on this domain if we haven't already checked it.
|
413 |
-
$store_hash = md5( $this->api_url );
|
414 |
-
if ( ! is_array( $edd_plugin_url_available ) || ! isset( $edd_plugin_url_available[ $store_hash ] ) ) {
|
415 |
-
$test_url_parts = parse_url( $this->api_url );
|
416 |
-
|
417 |
-
$scheme = ! empty( $test_url_parts['scheme'] ) ? $test_url_parts['scheme'] : 'http';
|
418 |
-
$host = ! empty( $test_url_parts['host'] ) ? $test_url_parts['host'] : '';
|
419 |
-
$port = ! empty( $test_url_parts['port'] ) ? ':' . $test_url_parts['port'] : '';
|
420 |
-
|
421 |
-
if ( empty( $host ) ) {
|
422 |
-
$edd_plugin_url_available[ $store_hash ] = false;
|
423 |
-
} else {
|
424 |
-
$test_url = $scheme . '://' . $host . $port;
|
425 |
-
$response = wp_remote_get( $test_url, array( 'timeout' => $this->health_check_timeout, 'sslverify' => $verify_ssl ) );
|
426 |
-
$edd_plugin_url_available[ $store_hash ] = is_wp_error( $response ) ? false : true;
|
427 |
-
}
|
428 |
-
}
|
429 |
-
|
430 |
-
if ( false === $edd_plugin_url_available[ $store_hash ] ) {
|
431 |
-
return false;
|
432 |
-
}
|
433 |
-
|
434 |
-
$data = array_merge( $this->api_data, $_data );
|
435 |
-
|
436 |
-
if ( $data['slug'] != $this->slug ) {
|
437 |
-
return false;
|
438 |
-
}
|
439 |
-
|
440 |
-
if ( $this->api_url == trailingslashit ( home_url() ) ) {
|
441 |
-
return false; // Don't allow a plugin to ping itself
|
442 |
-
}
|
443 |
-
|
444 |
-
$api_params = array(
|
445 |
-
'edd_action' => 'get_version',
|
446 |
-
'license' => ! empty( $data['license'] ) ? $data['license'] : '',
|
447 |
-
'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
|
448 |
-
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
|
449 |
-
'version' => isset( $data['version'] ) ? $data['version'] : false,
|
450 |
-
'slug' => $data['slug'],
|
451 |
-
'author' => $data['author'],
|
452 |
-
'url' => home_url(),
|
453 |
-
'beta' => ! empty( $data['beta'] ),
|
454 |
-
);
|
455 |
-
|
456 |
-
$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
|
457 |
-
|
458 |
-
if ( ! is_wp_error( $request ) ) {
|
459 |
-
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
460 |
-
}
|
461 |
-
|
462 |
-
if ( $request && isset( $request->sections ) ) {
|
463 |
-
$request->sections = maybe_unserialize( $request->sections );
|
464 |
-
} else {
|
465 |
-
$request = false;
|
466 |
-
}
|
467 |
-
|
468 |
-
if ( $request && isset( $request->banners ) ) {
|
469 |
-
$request->banners = maybe_unserialize( $request->banners );
|
470 |
-
}
|
471 |
-
|
472 |
-
if ( $request && isset( $request->icons ) ) {
|
473 |
-
$request->icons = maybe_unserialize( $request->icons );
|
474 |
-
}
|
475 |
-
|
476 |
-
if ( ! empty( $request->sections ) ) {
|
477 |
-
foreach( $request->sections as $key => $section ) {
|
478 |
-
$request->$key = (array) $section;
|
479 |
-
}
|
480 |
-
}
|
481 |
-
|
482 |
-
return $request;
|
483 |
-
}
|
484 |
-
|
485 |
-
/**
|
486 |
-
* If available, show the changelog for sites in a multisite install.
|
487 |
-
*/
|
488 |
-
public function show_changelog() {
|
489 |
-
|
490 |
-
global $edd_plugin_data;
|
491 |
-
|
492 |
-
if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
|
493 |
-
return;
|
494 |
-
}
|
495 |
-
|
496 |
-
if( empty( $_REQUEST['plugin'] ) ) {
|
497 |
-
return;
|
498 |
-
}
|
499 |
-
|
500 |
-
if( empty( $_REQUEST['slug'] ) ) {
|
501 |
-
return;
|
502 |
-
}
|
503 |
-
|
504 |
-
if( ! current_user_can( 'update_plugins' ) ) {
|
505 |
-
wp_die( __( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
|
506 |
-
}
|
507 |
-
|
508 |
-
$data = $edd_plugin_data[ $_REQUEST['slug'] ];
|
509 |
-
$version_info = $this->get_cached_version_info();
|
510 |
-
|
511 |
-
if( false === $version_info ) {
|
512 |
-
|
513 |
-
$api_params = array(
|
514 |
-
'edd_action' => 'get_version',
|
515 |
-
'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
|
516 |
-
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
|
517 |
-
'slug' => $_REQUEST['slug'],
|
518 |
-
'author' => $data['author'],
|
519 |
-
'url' => home_url(),
|
520 |
-
'beta' => ! empty( $data['beta'] )
|
521 |
-
);
|
522 |
-
|
523 |
-
$verify_ssl = $this->verify_ssl();
|
524 |
-
$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
|
525 |
-
|
526 |
-
if ( ! is_wp_error( $request ) ) {
|
527 |
-
$version_info = json_decode( wp_remote_retrieve_body( $request ) );
|
528 |
-
}
|
529 |
-
|
530 |
-
if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
|
531 |
-
$version_info->sections = maybe_unserialize( $version_info->sections );
|
532 |
-
} else {
|
533 |
-
$version_info = false;
|
534 |
-
}
|
535 |
-
|
536 |
-
if( ! empty( $version_info ) ) {
|
537 |
-
foreach( $version_info->sections as $key => $section ) {
|
538 |
-
$version_info->$key = (array) $section;
|
539 |
-
}
|
540 |
-
}
|
541 |
-
|
542 |
-
$this->set_version_info_cache( $version_info );
|
543 |
-
|
544 |
-
// Delete the unneeded option
|
545 |
-
delete_option( md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $this->beta . '_version_info' ) );
|
546 |
-
}
|
547 |
-
|
548 |
-
if ( isset( $version_info->sections ) ) {
|
549 |
-
$sections = $this->convert_object_to_array( $version_info->sections );
|
550 |
-
if ( ! empty( $sections['changelog'] ) ) {
|
551 |
-
echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $sections['changelog'] ) . '</div>';
|
552 |
-
}
|
553 |
-
}
|
554 |
-
|
555 |
-
exit;
|
556 |
-
}
|
557 |
-
|
558 |
-
/**
|
559 |
-
* Gets the plugin's cached version information from the database.
|
560 |
-
*
|
561 |
-
* @param string $cache_key
|
562 |
-
* @return boolean|string
|
563 |
-
*/
|
564 |
-
public function get_cached_version_info( $cache_key = '' ) {
|
565 |
-
|
566 |
-
if( empty( $cache_key ) ) {
|
567 |
-
$cache_key = $this->cache_key;
|
568 |
-
}
|
569 |
-
|
570 |
-
$cache = get_option( $cache_key );
|
571 |
-
|
572 |
-
if( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
|
573 |
-
return false; // Cache is expired
|
574 |
-
}
|
575 |
-
|
576 |
-
// We need to turn the icons into an array, thanks to WP Core forcing these into an object at some point.
|
577 |
-
$cache['value'] = json_decode( $cache['value'] );
|
578 |
-
if ( ! empty( $cache['value']->icons ) ) {
|
579 |
-
$cache['value']->icons = (array) $cache['value']->icons;
|
580 |
-
}
|
581 |
-
|
582 |
-
return $cache['value'];
|
583 |
-
|
584 |
-
}
|
585 |
-
|
586 |
-
/**
|
587 |
-
* Adds the plugin version information to the database.
|
588 |
-
*
|
589 |
-
* @param string $value
|
590 |
-
* @param string $cache_key
|
591 |
-
*/
|
592 |
-
public function set_version_info_cache( $value = '', $cache_key = '' ) {
|
593 |
-
|
594 |
-
if( empty( $cache_key ) ) {
|
595 |
-
$cache_key = $this->cache_key;
|
596 |
-
}
|
597 |
-
|
598 |
-
$data = array(
|
599 |
-
'timeout' => strtotime( '+3 hours', time() ),
|
600 |
-
'value' => json_encode( $value )
|
601 |
-
);
|
602 |
-
|
603 |
-
update_option( $cache_key, $data, 'no' );
|
604 |
-
|
605 |
-
// Delete the duplicate option
|
606 |
-
delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );
|
607 |
-
}
|
608 |
-
|
609 |
-
/**
|
610 |
-
* Returns if the SSL of the store should be verified.
|
611 |
-
*
|
612 |
-
* @since 1.6.13
|
613 |
-
* @return bool
|
614 |
-
*/
|
615 |
-
private function verify_ssl() {
|
616 |
-
return (bool) apply_filters( 'edd_sl_api_request_verify_ssl', true, $this );
|
617 |
-
}
|
618 |
-
|
619 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
includes/libraries/class-edd-sl-plugin-updater.php
ADDED
@@ -0,0 +1,695 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Hanldles plugin updater.
|
4 |
+
*
|
5 |
+
* @package bnfw
|
6 |
+
*/
|
7 |
+
|
8 |
+
defined( 'ABSPATH' ) || exit;
|
9 |
+
|
10 |
+
if ( ! class_exists( 'EDD_SL_Plugin_Updater', false ) ) {
|
11 |
+
/**
|
12 |
+
* Allows plugins to use their own update API.
|
13 |
+
*
|
14 |
+
* @author Easy Digital Downloads
|
15 |
+
* @version 1.8.0
|
16 |
+
*/
|
17 |
+
class EDD_SL_Plugin_Updater {
|
18 |
+
/**
|
19 |
+
* Holds the custom API endpoint
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
private $api_url = '';
|
24 |
+
/**
|
25 |
+
* Holds the custom API data.
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
private $api_data = array();
|
30 |
+
/**
|
31 |
+
* Holds the basename
|
32 |
+
*
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
private $name = '';
|
36 |
+
/**
|
37 |
+
* Holds the API version
|
38 |
+
*
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
private $slug = '';
|
42 |
+
/**
|
43 |
+
* Holds the plugin basename
|
44 |
+
*
|
45 |
+
* @var string
|
46 |
+
*/
|
47 |
+
private $version = '';
|
48 |
+
/**
|
49 |
+
* WP override
|
50 |
+
*
|
51 |
+
* @var bool
|
52 |
+
*/
|
53 |
+
private $wp_override = false;
|
54 |
+
/**
|
55 |
+
* Holds the cache key
|
56 |
+
*
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
private $cache_key = '';
|
60 |
+
/**
|
61 |
+
* Holds ahether its bet or not.
|
62 |
+
*
|
63 |
+
* @var bool
|
64 |
+
*/
|
65 |
+
private $beta = false;
|
66 |
+
/**
|
67 |
+
* Holds the wp_remote_get timeout.
|
68 |
+
*
|
69 |
+
* @var bool
|
70 |
+
*/
|
71 |
+
private $health_check_timeout = 5;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Class constructor.
|
75 |
+
*
|
76 |
+
* @uses plugin_basename()
|
77 |
+
* @uses hook()
|
78 |
+
*
|
79 |
+
* @param string $_api_url The URL pointing to the custom API endpoint.
|
80 |
+
* @param string $_plugin_file Path to the plugin file.
|
81 |
+
* @param array $_api_data Optional data to send with API calls.
|
82 |
+
*/
|
83 |
+
public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
84 |
+
|
85 |
+
global $edd_plugin_data;
|
86 |
+
|
87 |
+
$this->api_url = trailingslashit( $_api_url );
|
88 |
+
$this->api_data = $_api_data;
|
89 |
+
$this->name = plugin_basename( $_plugin_file );
|
90 |
+
$this->slug = basename( $_plugin_file, '.php' );
|
91 |
+
$this->version = $_api_data['version'];
|
92 |
+
$this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
|
93 |
+
$this->beta = ! empty( $this->api_data['beta'] ) ? true : false;
|
94 |
+
$this->cache_key = 'edd_sl_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );// phpcs:ignore
|
95 |
+
|
96 |
+
$edd_plugin_data[ $this->slug ] = $this->api_data;
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Fires after the $edd_plugin_data is setup.
|
100 |
+
*
|
101 |
+
* @since x.x.x
|
102 |
+
*
|
103 |
+
* @param array $edd_plugin_data Array of EDD SL plugin data.
|
104 |
+
*/
|
105 |
+
do_action( 'post_edd_sl_plugin_updater_setup', $edd_plugin_data );
|
106 |
+
|
107 |
+
// Set up hooks.
|
108 |
+
$this->init();
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Set up WordPress filters to hook into WP's update process.
|
114 |
+
*
|
115 |
+
* @uses add_filter()
|
116 |
+
*
|
117 |
+
* @return void
|
118 |
+
*/
|
119 |
+
public function init() {
|
120 |
+
|
121 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
|
122 |
+
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
123 |
+
remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10 );
|
124 |
+
add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
|
125 |
+
add_action( 'admin_init', array( $this, 'show_changelog' ) );
|
126 |
+
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Check for Updates at the defined API endpoint and modify the update array.
|
131 |
+
*
|
132 |
+
* This function dives into the update API just when WordPress creates its update array,
|
133 |
+
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
134 |
+
* It is reassembled from parts of the native WordPress plugin update code.
|
135 |
+
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
136 |
+
*
|
137 |
+
* @uses api_request()
|
138 |
+
*
|
139 |
+
* @param array $_transient_data Update array build by WordPress.
|
140 |
+
* @return array Modified update array with custom plugin data.
|
141 |
+
*/
|
142 |
+
public function check_update( $_transient_data ) {
|
143 |
+
|
144 |
+
global $pagenow;
|
145 |
+
|
146 |
+
if ( ! is_object( $_transient_data ) ) {
|
147 |
+
$_transient_data = new stdClass; // phpcs:ignore
|
148 |
+
}
|
149 |
+
|
150 |
+
if ( 'plugins.php' === $pagenow && is_multisite() ) {
|
151 |
+
return $_transient_data;
|
152 |
+
}
|
153 |
+
|
154 |
+
if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
|
155 |
+
return $_transient_data;
|
156 |
+
}
|
157 |
+
|
158 |
+
$current = $this->get_repo_api_data();
|
159 |
+
if ( false !== $current && is_object( $current ) && isset( $current->new_version ) ) {
|
160 |
+
if ( version_compare( $this->version, $current->new_version, '<' ) ) {
|
161 |
+
$_transient_data->response[ $this->name ] = $current;
|
162 |
+
} else {
|
163 |
+
// Populating the no_update information is required to support auto-updates in WordPress 5.5.
|
164 |
+
$_transient_data->no_update[ $this->name ] = $current;
|
165 |
+
}
|
166 |
+
}
|
167 |
+
$_transient_data->last_checked = time();
|
168 |
+
$_transient_data->checked[ $this->name ] = $this->version;
|
169 |
+
|
170 |
+
return $_transient_data;
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Get repo API data from store.
|
175 |
+
* Save to cache.
|
176 |
+
*
|
177 |
+
* @return \stdClass
|
178 |
+
*/
|
179 |
+
public function get_repo_api_data() {
|
180 |
+
$version_info = $this->get_cached_version_info();
|
181 |
+
|
182 |
+
if ( false === $version_info ) {
|
183 |
+
$version_info = $this->api_request(
|
184 |
+
'plugin_latest_version',
|
185 |
+
array(
|
186 |
+
'slug' => $this->slug,
|
187 |
+
'beta' => $this->beta,
|
188 |
+
)
|
189 |
+
);
|
190 |
+
if ( ! $version_info ) {
|
191 |
+
return false;
|
192 |
+
}
|
193 |
+
|
194 |
+
// This is required for your plugin to support auto-updates in WordPress 5.5.
|
195 |
+
$version_info->plugin = $this->name;
|
196 |
+
$version_info->id = $this->name;
|
197 |
+
|
198 |
+
$this->set_version_info_cache( $version_info );
|
199 |
+
}
|
200 |
+
|
201 |
+
return $version_info;
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
|
206 |
+
*
|
207 |
+
* @param string $file Path to the plugin file relative to the plugins directory.
|
208 |
+
* @param array $plugin An array of plugin data.
|
209 |
+
*/
|
210 |
+
public function show_update_notification( $file, $plugin ) {
|
211 |
+
|
212 |
+
if ( is_network_admin() ) {
|
213 |
+
return;
|
214 |
+
}
|
215 |
+
|
216 |
+
if ( ! current_user_can( 'update_plugins' ) ) {
|
217 |
+
return;
|
218 |
+
}
|
219 |
+
|
220 |
+
if ( ! is_multisite() ) {
|
221 |
+
return;
|
222 |
+
}
|
223 |
+
|
224 |
+
if ( $this->name !== $file ) {
|
225 |
+
return;
|
226 |
+
}
|
227 |
+
|
228 |
+
// Remove our filter on the site transient.
|
229 |
+
remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
|
230 |
+
|
231 |
+
$update_cache = get_site_transient( 'update_plugins' );
|
232 |
+
|
233 |
+
$update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
|
234 |
+
|
235 |
+
if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
|
236 |
+
|
237 |
+
$version_info = $this->get_repo_api_data();
|
238 |
+
|
239 |
+
if ( false === $version_info ) {
|
240 |
+
$version_info = $this->api_request(
|
241 |
+
'plugin_latest_version',
|
242 |
+
array(
|
243 |
+
'slug' => $this->slug,
|
244 |
+
'beta' => $this->beta,
|
245 |
+
)
|
246 |
+
);
|
247 |
+
|
248 |
+
// Since we disabled our filter for the transient, we aren't running our object conversion on banners, sections, or icons. Do this now:.
|
249 |
+
if ( isset( $version_info->banners ) && ! is_array( $version_info->banners ) ) {
|
250 |
+
$version_info->banners = $this->convert_object_to_array( $version_info->banners );
|
251 |
+
}
|
252 |
+
|
253 |
+
if ( isset( $version_info->sections ) && ! is_array( $version_info->sections ) ) {
|
254 |
+
$version_info->sections = $this->convert_object_to_array( $version_info->sections );
|
255 |
+
}
|
256 |
+
|
257 |
+
if ( isset( $version_info->icons ) && ! is_array( $version_info->icons ) ) {
|
258 |
+
$version_info->icons = $this->convert_object_to_array( $version_info->icons );
|
259 |
+
}
|
260 |
+
|
261 |
+
if ( isset( $version_info->contributors ) && ! is_array( $version_info->contributors ) ) {
|
262 |
+
$version_info->contributors = $this->convert_object_to_array( $version_info->contributors );
|
263 |
+
}
|
264 |
+
|
265 |
+
$this->set_version_info_cache( $version_info );
|
266 |
+
}
|
267 |
+
|
268 |
+
if ( ! is_object( $version_info ) ) {
|
269 |
+
return;
|
270 |
+
}
|
271 |
+
|
272 |
+
if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
|
273 |
+
$update_cache->response[ $this->name ] = $version_info;
|
274 |
+
} else {
|
275 |
+
$update_cache->no_update[ $this->name ] = $version_info;
|
276 |
+
}
|
277 |
+
|
278 |
+
$update_cache->last_checked = time();
|
279 |
+
$update_cache->checked[ $this->name ] = $this->version;
|
280 |
+
|
281 |
+
set_site_transient( 'update_plugins', $update_cache );
|
282 |
+
|
283 |
+
} else {
|
284 |
+
|
285 |
+
$version_info = $update_cache->response[ $this->name ];
|
286 |
+
|
287 |
+
}
|
288 |
+
|
289 |
+
// Restore our filter.
|
290 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
|
291 |
+
|
292 |
+
if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
|
293 |
+
|
294 |
+
// build a plugin list row, with update notification.
|
295 |
+
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
|
296 |
+
echo wp_kses_post( '<tr class="plugin-update-tr" id="' . $this->slug . '-update" data-slug="' . $this->slug . '" data-plugin="' . $this->slug . '/' . $file . '">' );
|
297 |
+
echo '<td colspan="3" class="plugin-update colspanchange">';
|
298 |
+
echo '<div class="update-message notice inline notice-warning notice-alt">';
|
299 |
+
|
300 |
+
$changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
|
301 |
+
|
302 |
+
if ( empty( $version_info->download_link ) ) {
|
303 |
+
printf(
|
304 |
+
/* translators: %1$s: pluign version info, %2$s: changelog link, %3$s: new version info, %4$s: closing a tag. */
|
305 |
+
esc_html__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'easy-digital-downloads' ),
|
306 |
+
esc_html( $version_info->name ),
|
307 |
+
'<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
|
308 |
+
esc_html( $version_info->new_version ),
|
309 |
+
'</a>'
|
310 |
+
);
|
311 |
+
} else {
|
312 |
+
printf(
|
313 |
+
/* translators: %1$s: pluign version info, %2$s: changelog link, %3$s: new version info, %4$s: closing a tag, %5$s: update link, %6$s: closing a tag. */
|
314 |
+
esc_html__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.', 'easy-digital-downloads' ),
|
315 |
+
esc_html( $version_info->name ),
|
316 |
+
'<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
|
317 |
+
esc_html( $version_info->new_version ),
|
318 |
+
'</a>',
|
319 |
+
'<a href="' . esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) ) . '">',
|
320 |
+
'</a>'
|
321 |
+
);
|
322 |
+
}
|
323 |
+
|
324 |
+
do_action( "in_plugin_update_message-{$file}", $plugin, $version_info );// phpcs:ignore
|
325 |
+
|
326 |
+
echo '</div></td></tr>';
|
327 |
+
}
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Updates information on the "View version x.x details" page with custom data.
|
332 |
+
*
|
333 |
+
* @uses api_request()
|
334 |
+
*
|
335 |
+
* @param false|object|array $_data The result object or array. Default false.
|
336 |
+
* @param string $_action The type of information being requested from the Plugin Installation API.
|
337 |
+
* @param object $_args Plugin API arguments.
|
338 |
+
* @return object $_data
|
339 |
+
*/
|
340 |
+
public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
341 |
+
|
342 |
+
if ( 'plugin_information' !== $_action ) {
|
343 |
+
|
344 |
+
return $_data;
|
345 |
+
|
346 |
+
}
|
347 |
+
|
348 |
+
if ( ! isset( $_args->slug ) || ( $_args->slug !== $this->slug ) ) {
|
349 |
+
|
350 |
+
return $_data;
|
351 |
+
|
352 |
+
}
|
353 |
+
|
354 |
+
$to_send = array(
|
355 |
+
'slug' => $this->slug,
|
356 |
+
'is_ssl' => is_ssl(),
|
357 |
+
'fields' => array(
|
358 |
+
'banners' => array(),
|
359 |
+
'reviews' => false,
|
360 |
+
'icons' => array(),
|
361 |
+
),
|
362 |
+
);
|
363 |
+
|
364 |
+
// Get the transient where we store the api request for this plugin for 24 hours.
|
365 |
+
$edd_api_request_transient = $this->get_cached_version_info();
|
366 |
+
|
367 |
+
// If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
|
368 |
+
if ( empty( $edd_api_request_transient ) ) {
|
369 |
+
|
370 |
+
$api_response = $this->api_request( 'plugin_information', $to_send );
|
371 |
+
|
372 |
+
// Expires in 3 hours.
|
373 |
+
$this->set_version_info_cache( $api_response );
|
374 |
+
|
375 |
+
if ( false !== $api_response ) {
|
376 |
+
$_data = $api_response;
|
377 |
+
}
|
378 |
+
} else {
|
379 |
+
$_data = $edd_api_request_transient;
|
380 |
+
}
|
381 |
+
|
382 |
+
// Convert sections into an associative array, since we're getting an object, but Core expects an array.
|
383 |
+
if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
|
384 |
+
$_data->sections = $this->convert_object_to_array( $_data->sections );
|
385 |
+
}
|
386 |
+
|
387 |
+
// Convert banners into an associative array, since we're getting an object, but Core expects an array.
|
388 |
+
if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
|
389 |
+
$_data->banners = $this->convert_object_to_array( $_data->banners );
|
390 |
+
}
|
391 |
+
|
392 |
+
// Convert icons into an associative array, since we're getting an object, but Core expects an array.
|
393 |
+
if ( isset( $_data->icons ) && ! is_array( $_data->icons ) ) {
|
394 |
+
$_data->icons = $this->convert_object_to_array( $_data->icons );
|
395 |
+
}
|
396 |
+
|
397 |
+
// Convert contributors into an associative array, since we're getting an object, but Core expects an array.
|
398 |
+
if ( isset( $_data->contributors ) && ! is_array( $_data->contributors ) ) {
|
399 |
+
$_data->contributors = $this->convert_object_to_array( $_data->contributors );
|
400 |
+
}
|
401 |
+
|
402 |
+
if ( ! isset( $_data->plugin ) ) {
|
403 |
+
$_data->plugin = $this->name;
|
404 |
+
}
|
405 |
+
|
406 |
+
return $_data;
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Convert some objects to arrays when injecting data into the update API
|
411 |
+
*
|
412 |
+
* Some data like sections, banners, and icons are expected to be an associative array, however due to the JSON
|
413 |
+
* decoding, they are objects. This method allows us to pass in the object and return an associative array.
|
414 |
+
*
|
415 |
+
* @since 3.6.5
|
416 |
+
*
|
417 |
+
* @param stdClass $data Data.
|
418 |
+
*
|
419 |
+
* @return array
|
420 |
+
*/
|
421 |
+
private function convert_object_to_array( $data ) {
|
422 |
+
if ( ! is_array( $data ) && ! is_object( $data ) ) {
|
423 |
+
return array();
|
424 |
+
}
|
425 |
+
$new_data = array();
|
426 |
+
foreach ( $data as $key => $value ) {
|
427 |
+
$new_data[ $key ] = is_object( $value ) ? $this->convert_object_to_array( $value ) : $value;
|
428 |
+
}
|
429 |
+
|
430 |
+
return $new_data;
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* Disable SSL verification in order to prevent download update failures
|
435 |
+
*
|
436 |
+
* @param array $args An array of args.
|
437 |
+
* @param string $url URL.
|
438 |
+
* @return object $array
|
439 |
+
*/
|
440 |
+
public function http_request_args( $args, $url ) {
|
441 |
+
|
442 |
+
$verify_ssl = $this->verify_ssl();
|
443 |
+
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
|
444 |
+
$args['sslverify'] = $verify_ssl;
|
445 |
+
}
|
446 |
+
return $args;
|
447 |
+
|
448 |
+
}
|
449 |
+
|
450 |
+
/**
|
451 |
+
* Calls the API and, if successfull, returns the object delivered by the API.
|
452 |
+
*
|
453 |
+
* @uses get_bloginfo()
|
454 |
+
* @uses wp_remote_post()
|
455 |
+
* @uses is_wp_error()
|
456 |
+
*
|
457 |
+
* @param string $_action The requested action.
|
458 |
+
* @param array $_data Parameters for the API action.
|
459 |
+
* @return false|object
|
460 |
+
*/
|
461 |
+
private function api_request( $_action, $_data ) {
|
462 |
+
|
463 |
+
global $wp_version, $edd_plugin_url_available;
|
464 |
+
|
465 |
+
$verify_ssl = $this->verify_ssl();
|
466 |
+
|
467 |
+
// Do a quick status check on this domain if we haven't already checked it.
|
468 |
+
$store_hash = md5( $this->api_url );
|
469 |
+
if ( ! is_array( $edd_plugin_url_available ) || ! isset( $edd_plugin_url_available[ $store_hash ] ) ) {
|
470 |
+
$test_url_parts = parse_url( $this->api_url );
|
471 |
+
|
472 |
+
$scheme = ! empty( $test_url_parts['scheme'] ) ? $test_url_parts['scheme'] : 'http';
|
473 |
+
$host = ! empty( $test_url_parts['host'] ) ? $test_url_parts['host'] : '';
|
474 |
+
$port = ! empty( $test_url_parts['port'] ) ? ':' . $test_url_parts['port'] : '';
|
475 |
+
|
476 |
+
if ( empty( $host ) ) {
|
477 |
+
$edd_plugin_url_available[ $store_hash ] = false;
|
478 |
+
} else {
|
479 |
+
$test_url = $scheme . '://' . $host . $port;
|
480 |
+
$response = wp_remote_get(
|
481 |
+
$test_url,
|
482 |
+
array(
|
483 |
+
'timeout' => $this->health_check_timeout,
|
484 |
+
'sslverify' => $verify_ssl,
|
485 |
+
)
|
486 |
+
);
|
487 |
+
$edd_plugin_url_available[ $store_hash ] = is_wp_error( $response ) ? false : true;
|
488 |
+
}
|
489 |
+
}
|
490 |
+
|
491 |
+
if ( false === $edd_plugin_url_available[ $store_hash ] ) {
|
492 |
+
return false;
|
493 |
+
}
|
494 |
+
|
495 |
+
$data = array_merge( $this->api_data, $_data );
|
496 |
+
|
497 |
+
if ( $data['slug'] !== $this->slug ) {
|
498 |
+
return false;
|
499 |
+
}
|
500 |
+
|
501 |
+
if ( trailingslashit( home_url() ) === $this->api_url ) {
|
502 |
+
return false; // Don't allow a plugin to ping itself.
|
503 |
+
}
|
504 |
+
|
505 |
+
$api_params = array(
|
506 |
+
'edd_action' => 'get_version',
|
507 |
+
'license' => ! empty( $data['license'] ) ? $data['license'] : '',
|
508 |
+
'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
|
509 |
+
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
|
510 |
+
'version' => isset( $data['version'] ) ? $data['version'] : false,
|
511 |
+
'slug' => $data['slug'],
|
512 |
+
'author' => $data['author'],
|
513 |
+
'url' => home_url(),
|
514 |
+
'beta' => ! empty( $data['beta'] ),
|
515 |
+
);
|
516 |
+
|
517 |
+
$request = wp_remote_post(
|
518 |
+
$this->api_url,
|
519 |
+
array(
|
520 |
+
'timeout' => 15,
|
521 |
+
'sslverify' => $verify_ssl,
|
522 |
+
'body' => $api_params,
|
523 |
+
)
|
524 |
+
);
|
525 |
+
|
526 |
+
if ( ! is_wp_error( $request ) ) {
|
527 |
+
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
528 |
+
}
|
529 |
+
|
530 |
+
if ( $request && isset( $request->sections ) ) {
|
531 |
+
$request->sections = maybe_unserialize( $request->sections );
|
532 |
+
} else {
|
533 |
+
$request = false;
|
534 |
+
}
|
535 |
+
|
536 |
+
if ( $request && isset( $request->banners ) ) {
|
537 |
+
$request->banners = maybe_unserialize( $request->banners );
|
538 |
+
}
|
539 |
+
|
540 |
+
if ( $request && isset( $request->icons ) ) {
|
541 |
+
$request->icons = maybe_unserialize( $request->icons );
|
542 |
+
}
|
543 |
+
|
544 |
+
if ( ! empty( $request->sections ) ) {
|
545 |
+
foreach ( $request->sections as $key => $section ) {
|
546 |
+
$request->$key = (array) $section;
|
547 |
+
}
|
548 |
+
}
|
549 |
+
|
550 |
+
return $request;
|
551 |
+
}
|
552 |
+
|
553 |
+
/**
|
554 |
+
* If available, show the changelog for sites in a multisite install.
|
555 |
+
*/
|
556 |
+
public function show_changelog() {
|
557 |
+
|
558 |
+
global $edd_plugin_data;
|
559 |
+
|
560 |
+
if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' !== $_REQUEST['edd_sl_action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
561 |
+
return;
|
562 |
+
}
|
563 |
+
|
564 |
+
if ( empty( $_REQUEST['plugin'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
565 |
+
return;
|
566 |
+
}
|
567 |
+
|
568 |
+
if ( empty( $_REQUEST['slug'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
569 |
+
return;
|
570 |
+
}
|
571 |
+
|
572 |
+
if ( ! current_user_can( 'update_plugins' ) ) {
|
573 |
+
wp_die( esc_html__( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ), esc_html__( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
|
574 |
+
}
|
575 |
+
|
576 |
+
$data = $edd_plugin_data[ $_REQUEST['slug'] ]; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
577 |
+
$version_info = $this->get_cached_version_info();
|
578 |
+
|
579 |
+
if ( false === $version_info ) {
|
580 |
+
|
581 |
+
$api_params = array(
|
582 |
+
'edd_action' => 'get_version',
|
583 |
+
'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
|
584 |
+
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
|
585 |
+
'slug' => $_REQUEST['slug'], // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
586 |
+
'author' => $data['author'],
|
587 |
+
'url' => home_url(),
|
588 |
+
'beta' => ! empty( $data['beta'] ),
|
589 |
+
);
|
590 |
+
|
591 |
+
$verify_ssl = $this->verify_ssl();
|
592 |
+
$request = wp_remote_post(
|
593 |
+
$this->api_url,
|
594 |
+
array(
|
595 |
+
'timeout' => 15,
|
596 |
+
'sslverify' => $verify_ssl,
|
597 |
+
'body' => $api_params,
|
598 |
+
)
|
599 |
+
);
|
600 |
+
|
601 |
+
if ( ! is_wp_error( $request ) ) {
|
602 |
+
$version_info = json_decode( wp_remote_retrieve_body( $request ) );
|
603 |
+
}
|
604 |
+
|
605 |
+
if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
|
606 |
+
$version_info->sections = maybe_unserialize( $version_info->sections );
|
607 |
+
} else {
|
608 |
+
$version_info = false;
|
609 |
+
}
|
610 |
+
|
611 |
+
if ( ! empty( $version_info ) ) {
|
612 |
+
foreach ( $version_info->sections as $key => $section ) {
|
613 |
+
$version_info->$key = (array) $section;
|
614 |
+
}
|
615 |
+
}
|
616 |
+
|
617 |
+
$this->set_version_info_cache( $version_info );
|
618 |
+
|
619 |
+
// Delete the unneeded option.
|
620 |
+
delete_option( md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $this->beta . '_version_info' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
621 |
+
}
|
622 |
+
|
623 |
+
if ( isset( $version_info->sections ) ) {
|
624 |
+
$sections = $this->convert_object_to_array( $version_info->sections );
|
625 |
+
if ( ! empty( $sections['changelog'] ) ) {
|
626 |
+
echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $sections['changelog'] ) . '</div>';
|
627 |
+
}
|
628 |
+
}
|
629 |
+
|
630 |
+
exit;
|
631 |
+
}
|
632 |
+
|
633 |
+
/**
|
634 |
+
* Gets the plugin's cached version information from the database.
|
635 |
+
*
|
636 |
+
* @param string $cache_key Cache key.
|
637 |
+
* @return boolean|string
|
638 |
+
*/
|
639 |
+
public function get_cached_version_info( $cache_key = '' ) {
|
640 |
+
|
641 |
+
if ( empty( $cache_key ) ) {
|
642 |
+
$cache_key = $this->cache_key;
|
643 |
+
}
|
644 |
+
|
645 |
+
$cache = get_option( $cache_key );
|
646 |
+
|
647 |
+
if ( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
|
648 |
+
return false; // Cache is expired.
|
649 |
+
}
|
650 |
+
|
651 |
+
// We need to turn the icons into an array, thanks to WP Core forcing these into an object at some point.
|
652 |
+
$cache['value'] = json_decode( $cache['value'] );
|
653 |
+
if ( ! empty( $cache['value']->icons ) ) {
|
654 |
+
$cache['value']->icons = (array) $cache['value']->icons;
|
655 |
+
}
|
656 |
+
|
657 |
+
return $cache['value'];
|
658 |
+
|
659 |
+
}
|
660 |
+
|
661 |
+
/**
|
662 |
+
* Adds the plugin version information to the database.
|
663 |
+
*
|
664 |
+
* @param string $value Value.
|
665 |
+
* @param string $cache_key Cache key.
|
666 |
+
*/
|
667 |
+
public function set_version_info_cache( $value = '', $cache_key = '' ) {
|
668 |
+
|
669 |
+
if ( empty( $cache_key ) ) {
|
670 |
+
$cache_key = $this->cache_key;
|
671 |
+
}
|
672 |
+
|
673 |
+
$data = array(
|
674 |
+
'timeout' => strtotime( '+3 hours', time() ),
|
675 |
+
'value' => wp_json_encode( $value ),
|
676 |
+
);
|
677 |
+
|
678 |
+
update_option( $cache_key, $data, 'no' );
|
679 |
+
|
680 |
+
// Delete the duplicate option.
|
681 |
+
delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );// phpcs:ignore
|
682 |
+
}
|
683 |
+
|
684 |
+
/**
|
685 |
+
* Returns if the SSL of the store should be verified.
|
686 |
+
*
|
687 |
+
* @since 1.6.13
|
688 |
+
* @return bool
|
689 |
+
*/
|
690 |
+
private function verify_ssl() {
|
691 |
+
return (bool) apply_filters( 'edd_sl_api_request_verify_ssl', true, $this );
|
692 |
+
}
|
693 |
+
|
694 |
+
}
|
695 |
+
}
|
includes/license/class-bnfw-license-setting.php
CHANGED
@@ -1,136 +1,150 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* BNFW License setting Handler.
|
4 |
-
*
|
5 |
-
* @since v1.4
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
'
|
86 |
-
'
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* BNFW License setting Handler.
|
4 |
+
*
|
5 |
+
* @since v1.4
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
|
10 |
+
|
11 |
+
if ( ! class_exists( 'BNFW_License_Setting', false ) ) {
|
12 |
+
/**
|
13 |
+
* BNFW_License_Setting class.
|
14 |
+
*/
|
15 |
+
class BNFW_License_Setting {
|
16 |
+
/**
|
17 |
+
* Class contructor.
|
18 |
+
*/
|
19 |
+
public function __construct() {
|
20 |
+
add_action( 'admin_menu', array( $this, 'bnfw_add_license_page' ), 11 );
|
21 |
+
add_action( 'admin_init', array( $this, 'bnfw_license_settings' ), 11 );
|
22 |
+
}
|
23 |
+
/**
|
24 |
+
* Add License page.
|
25 |
+
*
|
26 |
+
* @since 1.4
|
27 |
+
*/
|
28 |
+
public function bnfw_add_license_page() {
|
29 |
+
add_submenu_page(
|
30 |
+
'edit.php?post_type=bnfw_notification',
|
31 |
+
esc_html__( 'Add-on Licenses', 'bnfw' ),
|
32 |
+
esc_html__( 'Add-on Licenses', 'bnfw' ),
|
33 |
+
'bnfw',
|
34 |
+
'bnfw-license',
|
35 |
+
array( $this, 'bnfw_render_license_page' )
|
36 |
+
);
|
37 |
+
}
|
38 |
+
/**
|
39 |
+
* Render license page.
|
40 |
+
*
|
41 |
+
* @since 1.4
|
42 |
+
*/
|
43 |
+
public function bnfw_render_license_page() {
|
44 |
+
$settings = apply_filters( 'bnfw_settings_licenses', array() );
|
45 |
+
ob_start(); ?>
|
46 |
+
|
47 |
+
<div class="wrap">
|
48 |
+
<h2><?php esc_html_e( 'BNFW Add-on Licenses', 'bnfw' ); ?></h2>
|
49 |
+
|
50 |
+
<form method="post" action="options.php" class="bnfw-form">
|
51 |
+
<?php
|
52 |
+
settings_errors();
|
53 |
+
settings_fields( 'bnfw-license-settings' );
|
54 |
+
do_settings_sections( 'bnfw-license' );
|
55 |
+
|
56 |
+
if ( ! empty( $settings ) ) {
|
57 |
+
submit_button( esc_html__( 'Save License', 'bnfw' ) );
|
58 |
+
} else {
|
59 |
+
$store_url = 'https://betternotificationsforwp.com/downloads/';
|
60 |
+
|
61 |
+
if ( bnfw_is_tracking_allowed() ) {
|
62 |
+
$store_url .= '?utm_source=WP%20Admin%20Submenu%20Item%20-%20Add-on%20Licenses&utm_medium=referral';
|
63 |
+
}
|
64 |
+
/* translators: 1: BNFW Store URL */
|
65 |
+
echo wp_kses_post( sprintf( __( '<br>You have no BNFW Premium Add-ons installed yet.<br>You can buy add-ons from the <a href="%s" target="_blank">Store</a>.<br>Once purchased, install and activate the add-on(s) like you would any other WordPress plugin. Then return here and enter your license key.', 'bnfw' ), esc_url( $store_url ) ) );
|
66 |
+
}
|
67 |
+
?>
|
68 |
+
</form>
|
69 |
+
</div>
|
70 |
+
|
71 |
+
<?php
|
72 |
+
echo ob_get_clean();
|
73 |
+
}
|
74 |
+
/**
|
75 |
+
* BNFW license settings.
|
76 |
+
*/
|
77 |
+
public function bnfw_license_settings() {
|
78 |
+
$settings = apply_filters( 'bnfw_settings_licenses', array() );
|
79 |
+
|
80 |
+
if ( ! empty( $settings ) ) {
|
81 |
+
|
82 |
+
add_settings_section(
|
83 |
+
'bnfw_license_section', // Section ID.
|
84 |
+
esc_html( '' ), // Title above settings section.
|
85 |
+
'__return_false', // Name of function that renders a description of the settings section.
|
86 |
+
'bnfw-license' // Page to show on.
|
87 |
+
);
|
88 |
+
|
89 |
+
foreach ( $settings as $option ) {
|
90 |
+
$name = isset( $option['name'] ) ? $option['name'] : '';
|
91 |
+
add_settings_field(
|
92 |
+
'bnfw_licenses[' . $option['id'] . ']',
|
93 |
+
$name,
|
94 |
+
array( $this, 'bnfw_license_key_callback' ),
|
95 |
+
'bnfw-license',
|
96 |
+
'bnfw_license_section',
|
97 |
+
array(
|
98 |
+
'id' => isset( $option['id'] ) ? $option['id'] : null,
|
99 |
+
'desc' => ! empty( $option['desc'] ) ? $option['desc'] : '',
|
100 |
+
'name' => isset( $option['name'] ) ? $option['name'] : null,
|
101 |
+
'size' => isset( $option['size'] ) ? $option['size'] : null,
|
102 |
+
'options' => isset( $option['options'] ) ? $option['options'] : '',
|
103 |
+
'std' => isset( $option['std'] ) ? $option['std'] : '',
|
104 |
+
'min' => isset( $option['min'] ) ? $option['min'] : null,
|
105 |
+
'max' => isset( $option['max'] ) ? $option['max'] : null,
|
106 |
+
'step' => isset( $option['step'] ) ? $option['step'] : null,
|
107 |
+
'chosen' => isset( $option['chosen'] ) ? $option['chosen'] : null,
|
108 |
+
'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : null,
|
109 |
+
'allow_blank' => isset( $option['allow_blank'] ) ? $option['allow_blank'] : true,
|
110 |
+
'readonly' => isset( $option['readonly'] ) ? $option['readonly'] : false,
|
111 |
+
'faux' => isset( $option['faux'] ) ? $option['faux'] : false,
|
112 |
+
)
|
113 |
+
);
|
114 |
+
}
|
115 |
+
|
116 |
+
register_setting(
|
117 |
+
'bnfw-license-settings',
|
118 |
+
'bnfw_licenses'
|
119 |
+
);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
/**
|
123 |
+
* Register the new license field type
|
124 |
+
*
|
125 |
+
* @param array $args Args.
|
126 |
+
* @return void
|
127 |
+
*/
|
128 |
+
public function bnfw_license_key_callback( $args ) {
|
129 |
+
$bnfw_options = get_option( 'bnfw_licenses' );
|
130 |
+
|
131 |
+
if ( isset( $bnfw_options[ $args['id'] ] ) ) {
|
132 |
+
$value = $bnfw_options[ $args['id'] ];
|
133 |
+
} else {
|
134 |
+
$value = isset( $args['std'] ) ? $args['std'] : '';
|
135 |
+
}
|
136 |
+
|
137 |
+
$size = isset( $args['size'] ) && ! is_null( $args['size'] ) ? $args['size'] : 'regular';
|
138 |
+
$html = '<input type="text" class="' . sanitize_html_class( $size ) . '-text" id="bnfw_licenses[' . $args['id'] . ']" name="bnfw_licenses[' . $args['id'] . ']" value="' . esc_attr( $value ) . '">';
|
139 |
+
|
140 |
+
if ( 'valid' === get_option( $args['options']['is_valid_license_option'] ) ) {
|
141 |
+
$html .= '<input type="submit" class="button-secondary" name="' . $args['id'] . '_deactivate" value="' . esc_attr__( 'Deactivate License', 'bnfw' ) . '">';
|
142 |
+
}
|
143 |
+
|
144 |
+
$html .= '<label for="bnfw_licenses[' . $args['id'] . ']"> ' . esc_html( $args['desc'] ) . '</label>';
|
145 |
+
|
146 |
+
echo $html; // phpcs:ignore
|
147 |
+
}
|
148 |
+
}
|
149 |
+
new BNFW_License_Setting();
|
150 |
+
}
|
includes/license/class-bnfw-license.php
CHANGED
@@ -1,255 +1,293 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* License handler for BNFW
|
4 |
-
*
|
5 |
-
* @since 1.4
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
$
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
$
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
$
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* License handler for BNFW
|
4 |
+
*
|
5 |
+
* @since 1.4
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
|
10 |
+
|
11 |
+
if ( ! class_exists( 'BNFW_License', false ) ) {
|
12 |
+
/**
|
13 |
+
* BNFW_License Class
|
14 |
+
*/
|
15 |
+
class BNFW_License {
|
16 |
+
/**
|
17 |
+
* Holds info about file
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
private $file;
|
22 |
+
/**
|
23 |
+
* Holds the license key
|
24 |
+
*
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
private $license;
|
28 |
+
/**
|
29 |
+
* Holds the item name
|
30 |
+
*
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
private $item_name;
|
34 |
+
/**
|
35 |
+
* Holds the item shortname
|
36 |
+
*
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
private $item_shortname;
|
40 |
+
/**
|
41 |
+
* Holds the plugin version
|
42 |
+
*
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
private $version;
|
46 |
+
/**
|
47 |
+
* Holds the info about author
|
48 |
+
*
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
private $author;
|
52 |
+
/**
|
53 |
+
* Holds the API URL
|
54 |
+
*
|
55 |
+
* @var string
|
56 |
+
*/
|
57 |
+
private $api_url = 'https://betternotificationsforwp.com/';
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Class constructor
|
61 |
+
*
|
62 |
+
* @param string $_file File.
|
63 |
+
* @param string $_item_name Item name.
|
64 |
+
* @param string $_version Verison.
|
65 |
+
* @param string $_author Author.
|
66 |
+
* @param string $_optname Optname.
|
67 |
+
* @param string $_api_url API URL.
|
68 |
+
*/
|
69 |
+
public function __construct( $_file, $_item_name, $_version, $_author, $_optname = null, $_api_url = null ) {
|
70 |
+
$bnfw_options = get_option( 'bnfw_licenses' );
|
71 |
+
|
72 |
+
$this->file = $_file;
|
73 |
+
$this->item_name = $_item_name;
|
74 |
+
$this->item_shortname = 'bnfw_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->item_name ) ) );
|
75 |
+
$this->version = $_version;
|
76 |
+
$this->license = isset( $bnfw_options[ $this->item_shortname . '_license_key' ] ) ? trim( $bnfw_options[ $this->item_shortname . '_license_key' ] ) : '';
|
77 |
+
$this->author = $_author;
|
78 |
+
$this->api_url = is_null( $_api_url ) ? $this->api_url : $_api_url;
|
79 |
+
|
80 |
+
// Setup hooks.
|
81 |
+
$this->hooks();
|
82 |
+
$this->auto_updater();
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Setup hooks
|
87 |
+
*
|
88 |
+
* @access private
|
89 |
+
* @return void
|
90 |
+
*/
|
91 |
+
private function hooks() {
|
92 |
+
// Register settings.
|
93 |
+
add_filter( 'bnfw_settings_licenses', array( $this, 'settings' ), 1 );
|
94 |
+
|
95 |
+
// Activate license key on settings save.
|
96 |
+
add_action( 'admin_init', array( $this, 'activate_license' ) );
|
97 |
+
|
98 |
+
// Deactivate license key.
|
99 |
+
add_action( 'admin_init', array( $this, 'deactivate_license' ) );
|
100 |
+
|
101 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_plugins_transient_unserialize_icons' ), 99 );
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Filter the transient data for our plugin's icons.
|
106 |
+
* Since icons are passed back as serialized arrays, we need to unserialize them.
|
107 |
+
* This has to be run from within your plugin.
|
108 |
+
*
|
109 |
+
* Based on code from https://renventura.com/adding-update-icons-for-commercial-plugins/
|
110 |
+
*
|
111 |
+
* @param mixed $transient New value of site transient.
|
112 |
+
*
|
113 |
+
* @return mixed (object) $transient
|
114 |
+
*/
|
115 |
+
public function update_plugins_transient_unserialize_icons( $transient ) {
|
116 |
+
|
117 |
+
if ( is_object( $transient ) && isset( $transient->response ) && is_array( $transient->response ) ) {
|
118 |
+
|
119 |
+
$basename = plugin_basename( __FILE__ );
|
120 |
+
|
121 |
+
// Received a response for our plugin.
|
122 |
+
$plugin = isset( $transient->response[ $basename ] ) ? $transient->response[ $basename ] : new stdClass();
|
123 |
+
|
124 |
+
// Are there any icons set for the plugin?
|
125 |
+
if ( isset( $plugin->icons ) ) {
|
126 |
+
$icons = is_string( $plugin->icons ) ? unserialize( $plugin->icons ) : $plugin->icons; // phpcs:ignore
|
127 |
+
$transient->response[ $basename ]->icons = $icons;
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
return $transient;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Auto updater
|
136 |
+
*
|
137 |
+
* @access private
|
138 |
+
* @return void
|
139 |
+
*/
|
140 |
+
private function auto_updater() {
|
141 |
+
// Setup the updater.
|
142 |
+
$edd_updater = new EDD_SL_Plugin_Updater(
|
143 |
+
$this->api_url,
|
144 |
+
$this->file,
|
145 |
+
array(
|
146 |
+
'version' => $this->version,
|
147 |
+
'license' => $this->license,
|
148 |
+
'item_name' => $this->item_name,
|
149 |
+
'author' => $this->author,
|
150 |
+
)
|
151 |
+
);
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Add license field to settings
|
156 |
+
*
|
157 |
+
* @access public
|
158 |
+
*
|
159 |
+
* @param array $settings Setting data.
|
160 |
+
*
|
161 |
+
* @return array
|
162 |
+
*/
|
163 |
+
public function settings( $settings ) {
|
164 |
+
if ( 'Multisite Add-on' === $this->item_name && ! is_multisite() ) {
|
165 |
+
return $settings;
|
166 |
+
}
|
167 |
+
|
168 |
+
if ( 'Multisite Add-on' === $this->item_name && is_multisite() ) {
|
169 |
+
if ( ! is_main_site() ) {
|
170 |
+
return $settings;
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
$bnfw_license_settings = array(
|
175 |
+
array(
|
176 |
+
'id' => $this->item_shortname . '_license_key',
|
177 |
+
'name' => sprintf( /* translators: %1$s Item name. */ esc_html__( '%1$s License Key', 'bnfw' ), $this->item_name ),
|
178 |
+
'desc' => '',
|
179 |
+
'type' => 'license_key',
|
180 |
+
'options' => array( 'is_valid_license_option' => $this->item_shortname . '_license_active' ),
|
181 |
+
'size' => 'regular',
|
182 |
+
),
|
183 |
+
);
|
184 |
+
|
185 |
+
return array_merge( $settings, $bnfw_license_settings );
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Activate the license key
|
190 |
+
*
|
191 |
+
* @access public
|
192 |
+
* @return void
|
193 |
+
*/
|
194 |
+
public function activate_license() {
|
195 |
+
if ( ! isset( $_POST['bnfw_licenses'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
196 |
+
return;
|
197 |
+
}
|
198 |
+
|
199 |
+
if ( ! isset( $_POST['bnfw_licenses'][ $this->item_shortname . '_license_key' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
200 |
+
return;
|
201 |
+
}
|
202 |
+
|
203 |
+
if ( 'valid' === get_option( $this->item_shortname . '_license_active' ) ) {
|
204 |
+
return;
|
205 |
+
}
|
206 |
+
|
207 |
+
$license = sanitize_text_field( $_POST['bnfw_licenses'][ $this->item_shortname . '_license_key' ] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
208 |
+
|
209 |
+
// Data to send to the API.
|
210 |
+
$api_params = array(
|
211 |
+
'edd_action' => 'activate_license',
|
212 |
+
'license' => $license,
|
213 |
+
'item_name' => urlencode( $this->item_name ), // phpcs:ignore
|
214 |
+
);
|
215 |
+
|
216 |
+
if ( 'Multisite Add-on' === $this->item_name && is_multisite() ) {
|
217 |
+
$api_params['url'] = get_home_url( get_main_site_id() );
|
218 |
+
}
|
219 |
+
|
220 |
+
// Call the API.
|
221 |
+
$response = wp_remote_get(
|
222 |
+
esc_url_raw( add_query_arg( $api_params, $this->api_url ) ),
|
223 |
+
array(
|
224 |
+
'timeout' => 15,
|
225 |
+
'body' => $api_params,
|
226 |
+
'sslverify' => false,
|
227 |
+
)
|
228 |
+
);
|
229 |
+
|
230 |
+
// Make sure there are no errors.
|
231 |
+
if ( is_wp_error( $response ) ) {
|
232 |
+
return;
|
233 |
+
}
|
234 |
+
|
235 |
+
// Decode license data.
|
236 |
+
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
237 |
+
|
238 |
+
update_option( $this->item_shortname . '_license_active', $license_data->license );
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Deactivate the license key
|
243 |
+
*
|
244 |
+
* @access public
|
245 |
+
* @return void
|
246 |
+
*/
|
247 |
+
public function deactivate_license() {
|
248 |
+
if ( ! isset( $_POST['bnfw_licenses'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
249 |
+
return;
|
250 |
+
}
|
251 |
+
|
252 |
+
if ( ! isset( $_POST['bnfw_licenses'][ $this->item_shortname . '_license_key' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
253 |
+
return;
|
254 |
+
}
|
255 |
+
|
256 |
+
// Run on deactivate button press.
|
257 |
+
if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
258 |
+
|
259 |
+
// Data to send to the API.
|
260 |
+
$api_params = array(
|
261 |
+
'edd_action' => 'deactivate_license',
|
262 |
+
'license' => $this->license,
|
263 |
+
'item_name' => urlencode( $this->item_name ), // phpcs:ignore
|
264 |
+
);
|
265 |
+
|
266 |
+
if ( 'Multisite Add-on' === $this->item_name && is_multisite() ) {
|
267 |
+
$api_params['url'] = get_home_url( get_main_site_id() );
|
268 |
+
}
|
269 |
+
|
270 |
+
// Call the API.
|
271 |
+
$response = wp_remote_get(
|
272 |
+
esc_url_raw( add_query_arg( $api_params, $this->api_url ) ),
|
273 |
+
array(
|
274 |
+
'timeout' => 15,
|
275 |
+
'sslverify' => false,
|
276 |
+
)
|
277 |
+
);
|
278 |
+
|
279 |
+
// Make sure there are no errors.
|
280 |
+
if ( is_wp_error( $response ) ) {
|
281 |
+
return;
|
282 |
+
}
|
283 |
+
|
284 |
+
// Decode the license data.
|
285 |
+
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
286 |
+
|
287 |
+
if ( 'deactivated' === $license_data->license ) {
|
288 |
+
delete_option( $this->item_shortname . '_license_active' );
|
289 |
+
}
|
290 |
+
}
|
291 |
+
}
|
292 |
+
}
|
293 |
+
}
|
includes/notification/post-notification.php
CHANGED
@@ -1,33 +1,36 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Handle post notifications.
|
4 |
-
*
|
5 |
-
* @since 1.3.6
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
*
|
13 |
-
*
|
14 |
-
* @
|
15 |
-
*
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
$notifications[] = '
|
22 |
-
$notifications[] = '
|
23 |
-
|
24 |
-
$notifications[] = '
|
25 |
-
|
26 |
-
$notifications[] = '
|
27 |
-
$notifications[] = '
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handle post notifications.
|
4 |
+
*
|
5 |
+
* @since 1.3.6
|
6 |
+
* @package bnfw
|
7 |
+
*/
|
8 |
+
|
9 |
+
defined( 'ABSPATH' ) || exit;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Define the list of post notifications.
|
13 |
+
*
|
14 |
+
* @since 1.3.6
|
15 |
+
*
|
16 |
+
* @param array $notifications List of post notifications.
|
17 |
+
* @param string $post_type Post type.
|
18 |
+
* @return array Filtered list of post notifications.
|
19 |
+
*/
|
20 |
+
function bnfw_post_notifications( $notifications, $post_type ) {
|
21 |
+
$notifications[] = 'new-' . $post_type;
|
22 |
+
$notifications[] = 'update-' . $post_type;
|
23 |
+
$notifications[] = 'pending-' . $post_type;
|
24 |
+
$notifications[] = 'future-' . $post_type;
|
25 |
+
$notifications[] = 'comment-' . $post_type;
|
26 |
+
$notifications[] = 'moderate-' . $post_type . '-comment';
|
27 |
+
$notifications[] = 'approve-' . $post_type . '-comment';
|
28 |
+
if ( 'post' === $post_type ) {
|
29 |
+
$notifications[] = 'new-comment';
|
30 |
+
$notifications[] = 'new-trackback';
|
31 |
+
$notifications[] = 'new-pingback';
|
32 |
+
$notifications[] = 'approve-comment';
|
33 |
+
}
|
34 |
+
return $notifications;
|
35 |
+
}
|
36 |
+
add_filter( 'bnfw_post_notifications', 'bnfw_post_notifications', 10, 2 );
|
includes/overrides.php
CHANGED
@@ -1,193 +1,205 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Override default WordPress emails
|
4 |
-
*
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
$
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
//
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
$message
|
44 |
-
|
45 |
-
$
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
'
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
*
|
59 |
-
*
|
60 |
-
*
|
61 |
-
*
|
62 |
-
* @
|
63 |
-
*
|
64 |
-
*
|
65 |
-
*
|
66 |
-
*
|
67 |
-
* @
|
68 |
-
* @
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
//
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
$
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
}
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
}
|
191 |
-
}
|
192 |
-
|
193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Override default WordPress emails
|
4 |
+
*
|
5 |
+
* @package bnfw
|
6 |
+
*/
|
7 |
+
|
8 |
+
if ( ! function_exists( 'wp_new_user_notification' ) ) {
|
9 |
+
/**
|
10 |
+
* Email login credentials to a newly-registered user.
|
11 |
+
*
|
12 |
+
* A new user registration notification is also sent to admin email.
|
13 |
+
*
|
14 |
+
* @param int $user_id User ID.
|
15 |
+
* @param null $deprecated Not used (argument deprecated).
|
16 |
+
* @param string $notify Optional. Type of notification that should happen. Accepts 'admin' or an empty
|
17 |
+
* string (admin only), or 'both' (admin and user). The empty string value was kept
|
18 |
+
* for backward-compatibility purposes with the renamed parameter. Default empty.
|
19 |
+
*/
|
20 |
+
function wp_new_user_notification( $user_id, $deprecated = null, $notify = '' ) {
|
21 |
+
global $wp_version, $wp_hasher;
|
22 |
+
|
23 |
+
$bnfw = BNFW::factory();
|
24 |
+
$user = get_userdata( $user_id );
|
25 |
+
|
26 |
+
if ( version_compare( $wp_version, '4.3', '>=' ) ) {
|
27 |
+
// for WordPress 4.3 and above.
|
28 |
+
|
29 |
+
if ( version_compare( $wp_version, '4.3', '=' ) ) {
|
30 |
+
$notify = $deprecated;
|
31 |
+
} else {
|
32 |
+
if ( null !== $deprecated ) {
|
33 |
+
_deprecated_argument( __FUNCTION__, '4.3.1' );
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
// The blogname option is escaped with esc_html on the way into the database in sanitize_option
|
38 |
+
// we want to reverse this for the plain text arena of emails.
|
39 |
+
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
|
40 |
+
|
41 |
+
if ( ! $bnfw->notifier->notification_exists( 'admin-user', false ) ) {
|
42 |
+
/* translators: %s site name. */
|
43 |
+
$message = sprintf( esc_html__( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
|
44 |
+
/* translators: %s username. */
|
45 |
+
$message .= sprintf( esc_html__( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
|
46 |
+
/* translators: %s email. */
|
47 |
+
$message .= sprintf( esc_html__( 'E-mail: %s' ), $user->user_email ) . "\r\n";
|
48 |
+
|
49 |
+
$wp_new_user_notification_email_admin = array(
|
50 |
+
'to' => get_option( 'admin_email' ),
|
51 |
+
/* translators: Password change notification email subject. %s: Site title */
|
52 |
+
'subject' => __( '[%s] New User Registration' ),
|
53 |
+
'message' => $message,
|
54 |
+
'headers' => '',
|
55 |
+
);
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Filters the contents of the new user notification email sent to the site admin.
|
59 |
+
*
|
60 |
+
* @since 4.9.0
|
61 |
+
*
|
62 |
+
* @param array $wp_new_user_notification_email {
|
63 |
+
* Used to build wp_mail().
|
64 |
+
*
|
65 |
+
* @type string $to The intended recipient - site admin email address.
|
66 |
+
* @type string $subject The subject of the email.
|
67 |
+
* @type string $message The body of the email.
|
68 |
+
* @type string $headers The headers of the email.
|
69 |
+
* }
|
70 |
+
*
|
71 |
+
* @param WP_User $user User object for new user.
|
72 |
+
* @param string $blogname The site title.
|
73 |
+
*/
|
74 |
+
$wp_new_user_notification_email_admin = apply_filters( 'wp_new_user_notification_email_admin', $wp_new_user_notification_email_admin, $user, $blogname );
|
75 |
+
|
76 |
+
if ( isset( $wp_new_user_notification_email_admin['to'] ) && ! empty( $wp_new_user_notification_email_admin['to'] ) ) {
|
77 |
+
wp_mail(
|
78 |
+
$wp_new_user_notification_email_admin['to'],
|
79 |
+
wp_specialchars_decode( sprintf( $wp_new_user_notification_email_admin['subject'], $blogname ) ),
|
80 |
+
$wp_new_user_notification_email_admin['message'],
|
81 |
+
$wp_new_user_notification_email_admin['headers']
|
82 |
+
);
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
if ( 'admin' === $notify || empty( $notify ) ) {
|
87 |
+
return;
|
88 |
+
}
|
89 |
+
|
90 |
+
// Generate something random for a password reset key.
|
91 |
+
$key = wp_generate_password( 20, false );
|
92 |
+
|
93 |
+
/** This action is documented in wp-login.php */
|
94 |
+
do_action( 'retrieve_password_key', $user->user_login, $key );
|
95 |
+
|
96 |
+
// Now insert the key, hashed, into the DB.
|
97 |
+
if ( empty( $wp_hasher ) ) {
|
98 |
+
require_once ABSPATH . WPINC . '/class-phpass.php';
|
99 |
+
$wp_hasher = new PasswordHash( 8, true ); // phpcs:ignore
|
100 |
+
}
|
101 |
+
$hashed = time() . ':' . $wp_hasher->HashPassword( $key );
|
102 |
+
|
103 |
+
wp_update_user(
|
104 |
+
array(
|
105 |
+
'ID' => $user->ID,
|
106 |
+
'user_activation_key' => $hashed,
|
107 |
+
)
|
108 |
+
);
|
109 |
+
|
110 |
+
if ( $bnfw->notifier->notification_exists( 'new-user', false ) ) {
|
111 |
+
$notifications = $bnfw->notifier->get_notifications( 'new-user' );
|
112 |
+
$password_url = network_site_url( 'wp-login.php?action=rp&key=' . $key . '&login=' . rawurlencode( $user->user_login ), 'login' );
|
113 |
+
|
114 |
+
foreach ( $notifications as $notification ) {
|
115 |
+
$setting = $bnfw->notifier->read_settings( $notification->ID );
|
116 |
+
$trigger_notification = apply_filters( 'bnfw_trigger_new-user_notification', true, $setting, $user );
|
117 |
+
|
118 |
+
if ( $trigger_notification ) {
|
119 |
+
$bnfw->engine->send_registration_email( $setting, $user, $password_url );
|
120 |
+
}
|
121 |
+
}
|
122 |
+
} else {
|
123 |
+
/* translators: %s username. */
|
124 |
+
$message = sprintf( esc_html__( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
|
125 |
+
$message .= esc_html__( 'To set your password, visit the following address:' ) . "\r\n\r\n";
|
126 |
+
$message .= '<' . network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user->user_login ), 'login' ) . ">\r\n\r\n";
|
127 |
+
|
128 |
+
$message .= wp_login_url() . "\r\n";
|
129 |
+
/* translators: %s message. */
|
130 |
+
wp_mail( $user->user_email, sprintf( esc_html__( '[%s] Your username and password info' ), $blogname ), $message );
|
131 |
+
}
|
132 |
+
} else {
|
133 |
+
|
134 |
+
// for WordPress below 4.3,.
|
135 |
+
$plaintext_pass = $deprecated;
|
136 |
+
|
137 |
+
// The blogname option is escaped with esc_html on the way into the database in sanitize_option
|
138 |
+
// we want to reverse this for the plain text arena of emails.
|
139 |
+
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
|
140 |
+
|
141 |
+
if ( ! $bnfw->notifier->notification_exists( 'admin-user', false ) ) {
|
142 |
+
/* translators: %s site name. */
|
143 |
+
$message = sprintf( esc_html__( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
|
144 |
+
/* translators: %s username. */
|
145 |
+
$message .= sprintf( esc_html__( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
|
146 |
+
/* translators: %s email. */
|
147 |
+
$message .= sprintf( esc_html__( 'E-mail: %s' ), $user->user_email ) . "\r\n";
|
148 |
+
/* translators: %s Blogname. */
|
149 |
+
wp_mail( get_option( 'admin_email' ), sprintf( esc_html__( '[%s] New User Registration' ), $blogname ), $message );
|
150 |
+
}
|
151 |
+
|
152 |
+
if ( empty( $plaintext_pass ) ) {
|
153 |
+
return;
|
154 |
+
}
|
155 |
+
|
156 |
+
if ( $bnfw->notifier->notification_exists( 'new-user', false ) ) {
|
157 |
+
$notifications = $bnfw->notifier->get_notifications( 'new-user' );
|
158 |
+
foreach ( $notifications as $notification ) {
|
159 |
+
$bnfw->engine->send_registration_email( $bnfw->notifier->read_settings( $notification->ID ), $user, $plaintext_pass );
|
160 |
+
}
|
161 |
+
} else {
|
162 |
+
/* translators: %s username. */
|
163 |
+
$message = sprintf( esc_html__( 'Username: %s' ), $user->user_login ) . "\r\n";
|
164 |
+
/* translators: %s password. */
|
165 |
+
$message .= sprintf( esc_html__( 'Password: %s' ), $plaintext_pass ) . "\r\n";
|
166 |
+
$message .= wp_login_url() . "\r\n";
|
167 |
+
/* translators: %s blogname. */
|
168 |
+
wp_mail( $user->user_email, sprintf( esc_html__( '[%s] Your username and password' ), $blogname ), $message );
|
169 |
+
}
|
170 |
+
}
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
if ( ! function_exists( 'wp_password_change_notification' ) ) {
|
175 |
+
/**
|
176 |
+
* Notify the blog admin of a user changing password, normally via email.
|
177 |
+
*
|
178 |
+
* @param WP_User $user User object.
|
179 |
+
*/
|
180 |
+
function wp_password_change_notification( $user ) {
|
181 |
+
$bnfw = BNFW::factory();
|
182 |
+
|
183 |
+
if ( $bnfw->notifier->notification_exists( 'admin-password-changed', false ) ) {
|
184 |
+
$notifications = $bnfw->notifier->get_notifications( 'admin-password-changed' );
|
185 |
+
|
186 |
+
if ( count( $notifications ) > 0 ) {
|
187 |
+
// Ideally there should be only one notification for this type.
|
188 |
+
// If there are multiple notification then we will read data about only the last one.
|
189 |
+
$bnfw->engine->send_notification( $bnfw->notifier->read_settings( end( $notifications )->ID ), $user->ID );
|
190 |
+
}
|
191 |
+
} else {
|
192 |
+
// send a copy of password change notification to the admin
|
193 |
+
// but check to see if it's the admin whose password we're changing, and skip this.
|
194 |
+
if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) {
|
195 |
+
/* translators: %s: user name */
|
196 |
+
$message = sprintf( __( 'Password changed for user: %s' ), $user->user_login ) . "\r\n";
|
197 |
+
// The blogname option is escaped with esc_html on the way into the database in sanitize_option
|
198 |
+
// we want to reverse this for the plain text arena of emails.
|
199 |
+
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
|
200 |
+
/* translators: %s: site title */
|
201 |
+
wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Password Changed' ), $blogname ), $message );
|
202 |
+
}
|
203 |
+
}
|
204 |
+
}
|
205 |
+
}
|
vendor/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php
CHANGED
@@ -1,187 +1,187 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Persist Admin notices Dismissal
|
4 |
-
*
|
5 |
-
* Copyright (C) 2016 Collins Agbonghama <https://w3guy.com>
|
6 |
-
*
|
7 |
-
* This program is free software: you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation, either version 3 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* This program is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19 |
-
*
|
20 |
-
* @package Persist Admin notices Dismissal
|
21 |
-
* @author Collins Agbonghama, Andy Fragen
|
22 |
-
* @license http://www.gnu.org/licenses GNU General Public License
|
23 |
-
*/
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Exit if called directly.
|
27 |
-
*/
|
28 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
29 |
-
die;
|
30 |
-
}
|
31 |
-
|
32 |
-
if ( ! class_exists( 'PAnD' ) ) {
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Class PAnD
|
36 |
-
*/
|
37 |
-
class PAnD {
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Init hooks.
|
41 |
-
*/
|
42 |
-
public static function init() {
|
43 |
-
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_script' ) );
|
44 |
-
add_action( 'wp_ajax_dismiss_admin_notice', array( __CLASS__, 'dismiss_admin_notice' ) );
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Filter to activate another filter providing a simpler use case.
|
48 |
-
*
|
49 |
-
* @since 1.4.3
|
50 |
-
*
|
51 |
-
* @param bool
|
52 |
-
*/
|
53 |
-
if ( apply_filters( 'pand_theme_loader', false ) ) {
|
54 |
-
add_filter(
|
55 |
-
'pand_dismiss_notice_js_url',
|
56 |
-
function( $js_url, $composer_path ) {
|
57 |
-
return get_stylesheet_directory_uri() . $composer_path;
|
58 |
-
},
|
59 |
-
10,
|
60 |
-
2
|
61 |
-
);
|
62 |
-
}
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Enqueue javascript and variables.
|
67 |
-
*/
|
68 |
-
public static function load_script() {
|
69 |
-
|
70 |
-
if ( is_customize_preview() ) {
|
71 |
-
return;
|
72 |
-
}
|
73 |
-
|
74 |
-
$js_url = plugins_url( 'dismiss-notice.js', __FILE__ );
|
75 |
-
$composer_path = '/vendor/collizo4sky/persist-admin-notices-dismissal/dismiss-notice.js';
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Filter dismiss-notice.js URL.
|
79 |
-
*
|
80 |
-
* @since 1.4.3
|
81 |
-
*
|
82 |
-
* @param string $js_url URL to the Javascript file.
|
83 |
-
* @param string $composer_path Relative path of Javascript file from composer install.
|
84 |
-
*/
|
85 |
-
$js_url = apply_filters( 'pand_dismiss_notice_js_url', $js_url, $composer_path );
|
86 |
-
wp_enqueue_script(
|
87 |
-
'dismissible-notices',
|
88 |
-
$js_url,
|
89 |
-
array( 'jquery', 'common' ),
|
90 |
-
false,
|
91 |
-
true
|
92 |
-
);
|
93 |
-
|
94 |
-
wp_localize_script(
|
95 |
-
'dismissible-notices',
|
96 |
-
'dismissible_notice',
|
97 |
-
array(
|
98 |
-
'nonce' => wp_create_nonce( 'dismissible-notice' ),
|
99 |
-
)
|
100 |
-
);
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Handles Ajax request to persist notices dismissal.
|
105 |
-
* Uses check_ajax_referer to verify nonce.
|
106 |
-
*/
|
107 |
-
public static function dismiss_admin_notice() {
|
108 |
-
$option_name = isset( $_POST['option_name'] ) ? sanitize_text_field( wp_unslash( $_POST['option_name'] ) ) : '';
|
109 |
-
$dismissible_length = isset( $_POST['dismissible_length'] ) ? sanitize_text_field( wp_unslash( $_POST['dismissible_length'] ) ) : 0;
|
110 |
-
|
111 |
-
if ( 'forever' !== $dismissible_length ) {
|
112 |
-
// If $dismissible_length is not an integer default to 1.
|
113 |
-
$dismissible_length = ( 0 === absint( $dismissible_length ) ) ? 1 : $dismissible_length;
|
114 |
-
$dismissible_length = strtotime( absint( $dismissible_length ) . ' days' );
|
115 |
-
}
|
116 |
-
|
117 |
-
check_ajax_referer( 'dismissible-notice', 'nonce' );
|
118 |
-
self::set_admin_notice_cache( $option_name, $dismissible_length );
|
119 |
-
wp_die();
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Is admin notice active?
|
124 |
-
*
|
125 |
-
* @param string $arg data-dismissible content of notice.
|
126 |
-
*
|
127 |
-
* @return bool
|
128 |
-
*/
|
129 |
-
public static function is_admin_notice_active( $arg ) {
|
130 |
-
$array = explode( '-', $arg );
|
131 |
-
$length = array_pop( $array );
|
132 |
-
$option_name = implode( '-', $array );
|
133 |
-
$db_record = self::get_admin_notice_cache( $option_name );
|
134 |
-
|
135 |
-
if ( 'forever' === $db_record ) {
|
136 |
-
return false;
|
137 |
-
} elseif ( absint( $db_record ) >= time() ) {
|
138 |
-
return false;
|
139 |
-
} else {
|
140 |
-
return true;
|
141 |
-
}
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* Returns admin notice cached timeout.
|
146 |
-
*
|
147 |
-
* @access public
|
148 |
-
*
|
149 |
-
* @param string|bool $id admin notice name or false.
|
150 |
-
*
|
151 |
-
* @return array|bool The timeout. False if expired.
|
152 |
-
*/
|
153 |
-
public static function get_admin_notice_cache( $id = false ) {
|
154 |
-
if ( ! $id ) {
|
155 |
-
return false;
|
156 |
-
}
|
157 |
-
$cache_key = 'pand-' . md5( $id );
|
158 |
-
$timeout = get_site_option( $cache_key );
|
159 |
-
$timeout = 'forever' === $timeout ? time() + 60 : $timeout;
|
160 |
-
|
161 |
-
if ( empty( $timeout ) || time() > $timeout ) {
|
162 |
-
return false;
|
163 |
-
}
|
164 |
-
|
165 |
-
return $timeout;
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* Sets admin notice timeout in site option.
|
170 |
-
*
|
171 |
-
* @access public
|
172 |
-
*
|
173 |
-
* @param string $id Data Identifier.
|
174 |
-
* @param string|bool $timeout Timeout for admin notice.
|
175 |
-
*
|
176 |
-
* @return bool
|
177 |
-
*/
|
178 |
-
public static function set_admin_notice_cache( $id, $timeout ) {
|
179 |
-
$cache_key = 'pand-' . md5( $id );
|
180 |
-
update_site_option( $cache_key, $timeout );
|
181 |
-
|
182 |
-
return true;
|
183 |
-
}
|
184 |
-
|
185 |
-
}
|
186 |
-
|
187 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Persist Admin notices Dismissal
|
4 |
+
*
|
5 |
+
* Copyright (C) 2016 Collins Agbonghama <https://w3guy.com>
|
6 |
+
*
|
7 |
+
* This program is free software: you can redistribute it and/or modify
|
8 |
+
* it under the terms of the GNU General Public License as published by
|
9 |
+
* the Free Software Foundation, either version 3 of the License, or
|
10 |
+
* (at your option) any later version.
|
11 |
+
*
|
12 |
+
* This program is distributed in the hope that it will be useful,
|
13 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
* GNU General Public License for more details.
|
16 |
+
*
|
17 |
+
* You should have received a copy of the GNU General Public License
|
18 |
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19 |
+
*
|
20 |
+
* @package Persist Admin notices Dismissal
|
21 |
+
* @author Collins Agbonghama, Andy Fragen
|
22 |
+
* @license http://www.gnu.org/licenses GNU General Public License
|
23 |
+
*/
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Exit if called directly.
|
27 |
+
*/
|
28 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
29 |
+
die;
|
30 |
+
}
|
31 |
+
|
32 |
+
if ( ! class_exists( 'PAnD' ) ) {
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Class PAnD
|
36 |
+
*/
|
37 |
+
class PAnD {
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Init hooks.
|
41 |
+
*/
|
42 |
+
public static function init() {
|
43 |
+
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_script' ) );
|
44 |
+
add_action( 'wp_ajax_dismiss_admin_notice', array( __CLASS__, 'dismiss_admin_notice' ) );
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Filter to activate another filter providing a simpler use case.
|
48 |
+
*
|
49 |
+
* @since 1.4.3
|
50 |
+
*
|
51 |
+
* @param bool
|
52 |
+
*/
|
53 |
+
if ( apply_filters( 'pand_theme_loader', false ) ) {
|
54 |
+
add_filter(
|
55 |
+
'pand_dismiss_notice_js_url',
|
56 |
+
function( $js_url, $composer_path ) {
|
57 |
+
return get_stylesheet_directory_uri() . $composer_path;
|
58 |
+
},
|
59 |
+
10,
|
60 |
+
2
|
61 |
+
);
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Enqueue javascript and variables.
|
67 |
+
*/
|
68 |
+
public static function load_script() {
|
69 |
+
|
70 |
+
if ( is_customize_preview() ) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
+
$js_url = plugins_url( 'dismiss-notice.js', __FILE__ );
|
75 |
+
$composer_path = '/vendor/collizo4sky/persist-admin-notices-dismissal/dismiss-notice.js';
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Filter dismiss-notice.js URL.
|
79 |
+
*
|
80 |
+
* @since 1.4.3
|
81 |
+
*
|
82 |
+
* @param string $js_url URL to the Javascript file.
|
83 |
+
* @param string $composer_path Relative path of Javascript file from composer install.
|
84 |
+
*/
|
85 |
+
$js_url = apply_filters( 'pand_dismiss_notice_js_url', $js_url, $composer_path );
|
86 |
+
wp_enqueue_script(
|
87 |
+
'dismissible-notices',
|
88 |
+
$js_url,
|
89 |
+
array( 'jquery', 'common' ),
|
90 |
+
false,
|
91 |
+
true
|
92 |
+
);
|
93 |
+
|
94 |
+
wp_localize_script(
|
95 |
+
'dismissible-notices',
|
96 |
+
'dismissible_notice',
|
97 |
+
array(
|
98 |
+
'nonce' => wp_create_nonce( 'dismissible-notice' ),
|
99 |
+
)
|
100 |
+
);
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Handles Ajax request to persist notices dismissal.
|
105 |
+
* Uses check_ajax_referer to verify nonce.
|
106 |
+
*/
|
107 |
+
public static function dismiss_admin_notice() {
|
108 |
+
$option_name = isset( $_POST['option_name'] ) ? sanitize_text_field( wp_unslash( $_POST['option_name'] ) ) : '';
|
109 |
+
$dismissible_length = isset( $_POST['dismissible_length'] ) ? sanitize_text_field( wp_unslash( $_POST['dismissible_length'] ) ) : 0;
|
110 |
+
|
111 |
+
if ( 'forever' !== $dismissible_length ) {
|
112 |
+
// If $dismissible_length is not an integer default to 1.
|
113 |
+
$dismissible_length = ( 0 === absint( $dismissible_length ) ) ? 1 : $dismissible_length;
|
114 |
+
$dismissible_length = strtotime( absint( $dismissible_length ) . ' days' );
|
115 |
+
}
|
116 |
+
|
117 |
+
check_ajax_referer( 'dismissible-notice', 'nonce' );
|
118 |
+
self::set_admin_notice_cache( $option_name, $dismissible_length );
|
119 |
+
wp_die();
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Is admin notice active?
|
124 |
+
*
|
125 |
+
* @param string $arg data-dismissible content of notice.
|
126 |
+
*
|
127 |
+
* @return bool
|
128 |
+
*/
|
129 |
+
public static function is_admin_notice_active( $arg ) {
|
130 |
+
$array = explode( '-', $arg );
|
131 |
+
$length = array_pop( $array );
|
132 |
+
$option_name = implode( '-', $array );
|
133 |
+
$db_record = self::get_admin_notice_cache( $option_name );
|
134 |
+
|
135 |
+
if ( 'forever' === $db_record ) {
|
136 |
+
return false;
|
137 |
+
} elseif ( absint( $db_record ) >= time() ) {
|
138 |
+
return false;
|
139 |
+
} else {
|
140 |
+
return true;
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Returns admin notice cached timeout.
|
146 |
+
*
|
147 |
+
* @access public
|
148 |
+
*
|
149 |
+
* @param string|bool $id admin notice name or false.
|
150 |
+
*
|
151 |
+
* @return array|bool The timeout. False if expired.
|
152 |
+
*/
|
153 |
+
public static function get_admin_notice_cache( $id = false ) {
|
154 |
+
if ( ! $id ) {
|
155 |
+
return false;
|
156 |
+
}
|
157 |
+
$cache_key = 'pand-' . md5( $id );
|
158 |
+
$timeout = get_site_option( $cache_key );
|
159 |
+
$timeout = 'forever' === $timeout ? time() + 60 : $timeout;
|
160 |
+
|
161 |
+
if ( empty( $timeout ) || time() > $timeout ) {
|
162 |
+
return false;
|
163 |
+
}
|
164 |
+
|
165 |
+
return $timeout;
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Sets admin notice timeout in site option.
|
170 |
+
*
|
171 |
+
* @access public
|
172 |
+
*
|
173 |
+
* @param string $id Data Identifier.
|
174 |
+
* @param string|bool $timeout Timeout for admin notice.
|
175 |
+
*
|
176 |
+
* @return bool
|
177 |
+
*/
|
178 |
+
public static function set_admin_notice_cache( $id, $timeout ) {
|
179 |
+
$cache_key = 'pand-' . md5( $id );
|
180 |
+
update_site_option( $cache_key, $timeout );
|
181 |
+
|
182 |
+
return true;
|
183 |
+
}
|
184 |
+
|
185 |
+
}
|
186 |
+
|
187 |
+
}
|