Better Notifications for WordPress - Version 1.8.8

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 Icon 128x128 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 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.7
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={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};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">&times;</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">&times;</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 Name: Better Notifications for WP
5
- * Plugin URI: https://wordpress.org/plugins/bnfw/
6
- * Description: Supercharge your WordPress notifications using a WYSIWYG editor and shortcodes. Default and new notifications available. Add more power with Add-ons.
7
- * Version: 1.8.7
8
- * Requires at least: 4.8
9
- * Requires PHP: 7.0
10
- * Author: Made with Fuel
11
- * Author URI: https://madewithfuel.com/
12
- * License: GPLv2 or later
13
- * License URI: http://www.gnu.org/licenses/gpl-2.0.html
14
- * Text Domain: bnfw
15
- * Domain Path: /languages
16
- */
17
-
18
- /**
19
- * Copyright © 2022 Made with Fuel Ltd. (hello@betternotificationsforwp.com)
20
- * This program is free software; you can redistribute it and/or modify
21
- * it under the terms of the GNU General Public License, version 2, as
22
- * published by the Free Software Foundation.
23
- * This program is distributed in the hope that it will be useful,
24
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
- * GNU General Public License for more details.
27
- * You should have received a copy of the GNU General Public License
28
- * along with this program; if not, write to the Free Software
29
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30
- */
31
- class BNFW {
32
-
33
- /**
34
- * Constructor.
35
- *
36
- * @since 1.0
37
- */
38
- function __construct() {
39
- $this->load_textdomain();
40
- $this->includes();
41
- $this->hooks();
42
-
43
- /**
44
- * BNFW Notification.
45
- *
46
- * @var \BNFW_Notification
47
- */
48
- $this->notifier = new BNFW_Notification;
49
-
50
- /**
51
- * BNFW Engine.
52
- *
53
- * @var \BNFW_Engine
54
- */
55
- $this->engine = new BNFW_Engine;
56
- }
57
-
58
- /**
59
- * Factory method to return the instance of the class.
60
- *
61
- * Makes sure that only one instance is created.
62
- *
63
- * @return \BNFW Instance of the class.
64
- */
65
- public static function factory() {
66
- static $instance = false;
67
- if ( ! $instance ) {
68
- $instance = new self();
69
- }
70
- return $instance;
71
- }
72
-
73
- /**
74
- * Loads the plugin language files
75
- *
76
- * @since 1.0
77
- */
78
- public function load_textdomain() {
79
- // Load localization domain
80
- $this->translations = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
81
- load_plugin_textdomain( 'bnfw', false, $this->translations );
82
- }
83
-
84
- /**
85
- * Include required files.
86
- *
87
- * @since 1.0
88
- */
89
- public function includes() {
90
-
91
- // Load license related classes
92
- if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
93
- require_once 'includes/libraries/EDD_SL_Plugin_Updater.php';
94
- }
95
-
96
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
97
-
98
- require_once 'vendor/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php';
99
-
100
- require_once 'includes/license/class-bnfw-license.php';
101
- require_once 'includes/license/class-bnfw-license-setting.php';
102
-
103
- // Load Engine
104
- require_once 'includes/engine/class-bnfw-engine.php';
105
- require_once 'includes/overrides.php';
106
-
107
- // Load notification post type and notification helpers
108
- require_once 'includes/admin/class-bnfw-notification.php';
109
- require_once 'includes/notification/post-notification.php';
110
-
111
- // Helpers
112
- require_once 'includes/helpers/helpers.php';
113
- require_once 'includes/helpers/ajax-helpers.php';
114
-
115
- // Load Admin Pages
116
- if ( is_admin() ) {
117
- require_once 'includes/admin/bnfw-settings.php';
118
- }
119
- }
120
-
121
- /**
122
- * Register Hooks.
123
- *
124
- * @since 1.0
125
- */
126
- public function hooks() {
127
- global $wp_version;
128
-
129
- register_activation_hook( __FILE__, array( $this, 'activate' ) );
130
-
131
- add_action( 'admin_init', array( 'PAnD', 'init' ) );
132
- add_action( 'admin_init', array( $this, 'add_capability_to_admin' ) );
133
-
134
- add_action( 'draft_to_private', array( $this, 'private_post' ) );
135
- add_action( 'future_to_private', array( $this, 'private_post' ) );
136
- add_action( 'pending_to_private', array( $this, 'private_post' ) );
137
- add_action( 'publish_to_private', array( $this, 'private_post' ) );
138
-
139
- add_action( 'wp_insert_post', array( $this, 'insert_post' ), 10, 3 );
140
-
141
- add_action( 'publish_to_trash', array( $this, 'trash_post' ) );
142
-
143
- add_action( 'auto-draft_to_publish', array( $this, 'publish_post' ) );
144
- add_action( 'draft_to_publish', array( $this, 'publish_post' ) );
145
- add_action( 'future_to_publish', array( $this, 'publish_post' ) );
146
- add_action( 'pending_to_publish', array( $this, 'publish_post' ) );
147
- add_action( 'private_to_publish', array( $this, 'publish_post' ) );
148
- // add_action( 'acf/submit_form' , array( $this, 'acf_submit_form' ), 10, 2 );
149
-
150
- add_action( 'publish_to_publish', array( $this, 'update_post' ) );
151
- add_action( 'private_to_private', array( $this, 'update_post' ) );
152
-
153
- add_action( 'add_attachment', array( $this, 'new_publish_media_notification' ), 10, 1 );
154
- add_action( 'edit_attachment', array( $this, 'media_attachment_data_update_notification' ), 10 );
155
-
156
- add_action( 'transition_post_status', array( $this, 'on_post_transition' ), 10, 3 );
157
-
158
- add_action( 'init', array( $this, 'custom_post_type_hooks' ), 100 );
159
- add_action( 'create_term', array( $this, 'create_term' ), 10, 3 );
160
-
161
- add_action( 'transition_comment_status', array( $this, 'on_comment_status_change' ), 10, 3 );
162
- add_action( 'comment_post', array( $this, 'comment_post' ) );
163
- add_action( 'trackback_post', array( $this, 'trackback_post' ) );
164
- add_action( 'pingback_post', array( $this, 'pingback_post' ) );
165
-
166
- add_action( 'user_register', array( $this, 'user_register' ) );
167
-
168
- add_action( 'user_register', array( $this, 'welcome_email' ) );
169
-
170
- if ( is_plugin_active( 'members/members.php' ) ) {
171
-
172
- add_action('add_user_role', array($this,'user_role_added_from_member_plugin'), 10, 2);
173
- add_action('remove_user_role', array($this,'user_role_removed_from_member_plugin'), 10, 2);
174
- add_action('set_user_role', array( $this, 'user_role_changed' ), 10, 3 );
175
-
176
- add_action( 'profile_update', array( $this, 'user_role_added' ), 10, 2 );
177
- } else {
178
- add_action( 'set_user_role', array( $this, 'user_role_changed' ), 10, 3 );
179
- }
180
-
181
-
182
-
183
- add_action( 'wp_login', array( $this, 'user_login' ), 10, 2 );
184
-
185
- if ( version_compare( $wp_version, '4.4', '>=' ) ) {
186
- add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ), 10, 3 );
187
- } else {
188
- add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ) );
189
- }
190
- add_action( 'lostpassword_post', array( $this, 'on_lost_password' ) );
191
- add_filter( 'retrieve_password_message', array( $this, 'change_password_email_message' ), 10, 4 );
192
-
193
- add_action( 'after_password_reset', array( $this, 'on_password_reset' ) );
194
-
195
- add_filter( 'send_password_change_email', array( $this, 'should_password_changed_email_be_sent' ), 10, 3 );
196
- add_filter( 'password_change_email', array( $this, 'on_password_changed' ), 10, 2 );
197
-
198
- add_filter( 'send_email_change_email', array( $this, 'should_email_changed_email_be_sent' ), 10, 3 );
199
- add_filter( 'email_change_email', array( $this, 'on_email_changed' ), 10, 3 );
200
- add_filter( 'new_user_email_content', array( $this, 'on_email_changing' ), 10, 2 );
201
-
202
- add_filter( 'auto_core_update_email', array( $this, 'on_core_updated' ), 10, 4 );
203
-
204
- add_filter( 'user_request_action_email_content', array( $this, 'handle_user_request_email_content' ), 10, 2 );
205
- add_filter( 'user_request_action_email_subject', array( $this, 'handle_user_request_email_subject' ), 10, 3 );
206
-
207
- add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_user_confirmed_action_email_content' ), 10, 2 );
208
-
209
- add_filter( 'wp_privacy_personal_data_email_content', array( $this, 'handle_data_export_email_content' ), 10, 3 );
210
-
211
- add_filter( 'user_erasure_complete_email_subject', array( $this, 'handle_erasure_complete_email_subject' ), 10, 3 );
212
- add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_erasure_complete_email_content' ), 10, 2 );
213
-
214
- add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 4 );
215
- add_action( 'shutdown', array( $this, 'on_shutdown' ) );
216
- }
217
-
218
- /**
219
- * Add 'bnfw' capability to admin.
220
- */
221
- public function add_capability_to_admin() {
222
- $admins = get_role( 'administrator' );
223
-
224
- if ( is_null( $admins ) ) {
225
- return;
226
- }
227
-
228
- if ( ! $admins->has_cap( 'bnfw' ) ) {
229
- $admins->add_cap( 'bnfw' );
230
- }
231
- }
232
-
233
- /**
234
- * On post transition.
235
- *
236
- * @param string $new_status New post status.
237
- * @param string $old_status Old post status.
238
- * @param \WP_Post $post Post object.
239
- */
240
- public function on_post_transition( $new_status, $old_status, $post ) {
241
- if ( ! is_a( $post, 'WP_Post' ) ) {
242
- return;
243
- }
244
-
245
- if ( 'pending' === $old_status ) {
246
- return;
247
- }
248
-
249
- if ( 'pending' !== $new_status ) {
250
- return;
251
- }
252
-
253
- $this->on_post_pending( $post->ID, $post );
254
- }
255
-
256
- /**
257
- * Setup hooks for custom post types.
258
- *
259
- * @since 1.2
260
- */
261
- function custom_post_type_hooks() {
262
- $post_types = get_post_types( array( 'public' => true ), 'names' );
263
- $post_types = array_diff( $post_types, array( BNFW_Notification::POST_TYPE ) );
264
-
265
- foreach ( $post_types as $post_type ) {
266
- add_action( 'future_' . $post_type, array( $this, 'on_post_scheduled' ), 10, 2 );
267
- }
268
- }
269
-
270
- /**
271
- * importer
272
- */
273
- public function activate() {
274
- require_once dirname( __FILE__ ) . '/includes/import.php';
275
- $importer = new BNFW_Import;
276
- $importer->import();
277
- }
278
-
279
- /**
280
- * Add 'Settings' link below BNFW in Plugins list.
281
- *
282
- * @since 1.0
283
- * @param unknown $links
284
- * @param unknown $file
285
- * @return unknown
286
- */
287
- public function plugin_action_links( $links, $file ) {
288
- $plugin_file = 'bnfw/bnfw.php';
289
- if ( $file == $plugin_file ) {
290
- $settings_link = '<a href="' . esc_url( admin_url( 'edit.php?post_type=bnfw_notification&page=bnfw-settings' ) ) . '">' . esc_html__( 'Settings', 'bnfw' ) . '</a>';
291
- array_unshift( $links, $settings_link );
292
- }
293
- return $links;
294
- }
295
-
296
- /**
297
- * When a new term is created.
298
- *
299
- * @since 1.0
300
- * @param int $term_id
301
- * @param int $tt_id
302
- * @param string $taxonomy
303
- */
304
- public function create_term( $term_id, $tt_id, $taxonomy ) {
305
- $this->send_notification( 'newterm-' . $taxonomy, $term_id );
306
- }
307
-
308
- /**
309
- * Fires when a post is created for the first time.
310
- *
311
- * @param int $post_id Post ID
312
- * @param object $post Post object
313
- * @param bool $update Whether this is an existing post being updated or not.
314
- *
315
- * @since 1.3.1
316
- */
317
- public function insert_post( $post_id, $post, $update ) {
318
- // Some themes like P2, directly insert posts into DB.
319
- $insert_post_themes = apply_filters( 'bnfw_insert_post_themes', array( 'P2', 'Syncope' ) );
320
- $current_theme = wp_get_theme();
321
-
322
- /**
323
- * Whether to trigger insert post hook.
324
- *
325
- * @since 1.4
326
- */
327
- $trigger_insert_post = apply_filters( 'bnfw_trigger_insert_post', false, $post_id, $update );
328
-
329
- if ( in_array( $current_theme->get( 'Name' ), $insert_post_themes ) || $trigger_insert_post ) {
330
- $this->handle_inserted_post( $post_id, $update );
331
- }
332
- }
333
-
334
- /**
335
- * Trigger New Post published notification for ACF forms.
336
- *
337
- * @param string $form ACF Form.
338
- * @param int $post_id Post ID.
339
- */
340
- public function acf_submit_form( $form, $post_id ) {
341
- $this->handle_inserted_post( $post_id );
342
- }
343
-
344
- /**
345
- * Trigger correct notifications for inserted posts.
346
- *
347
- * @param int $post_id Post id.
348
- * @param bool $update Whether the post was updated.
349
- *
350
- * @since 1.6.7
351
- */
352
- private function handle_inserted_post( $post_id, $update ) {
353
- $post = get_post( $post_id );
354
-
355
- if ( ! is_a( $post, 'WP_Post' ) ) {
356
- return;
357
- }
358
-
359
- switch ( $post->post_status ) {
360
- case 'publish':
361
- if ( $update ) {
362
- $this->update_post( $post );
363
- } else {
364
- $this->publish_post( $post );
365
- }
366
- break;
367
-
368
- case 'private':
369
- $this->private_post( $post );
370
- break;
371
-
372
- case 'pending':
373
- $this->on_post_pending( $post_id, $post );
374
- break;
375
-
376
- case 'future':
377
- $this->on_post_scheduled( $post_id, $post );
378
- break;
379
- }
380
- }
381
-
382
- /**
383
- * Fires when a post is created for the first time.
384
- *
385
- * @since 1.0
386
- * @param object $post Post Object
387
- */
388
- function publish_post( $post ) {
389
- $post_id = $post->ID;
390
- $post_type = $post->post_type;
391
-
392
- if ( BNFW_Notification::POST_TYPE != $post_type ) {
393
- $this->send_notification_async( 'new-' . $post_type, $post_id );
394
- }
395
- }
396
-
397
- /**
398
- * Fires when a private post is created.
399
- *
400
- * @since 1.6
401
- * @param object $post Post Object
402
- */
403
- public function private_post( $post ) {
404
- $post_id = $post->ID;
405
- $post_type = $post->post_type;
406
-
407
- if ( BNFW_Notification::POST_TYPE != $post_type ) {
408
- $this->send_notification_async( 'private-' . $post_type, $post_id );
409
- }
410
- }
411
-
412
- /**
413
- * Fires when a post is updated.
414
- *
415
- * @since 1.0
416
- * @param unknown $post
417
- */
418
- public function update_post( $post ) {
419
- if ( $this->is_metabox_request() ) {
420
- return;
421
- }
422
-
423
- $post_id = $post->ID;
424
- $post_type = $post->post_type;
425
-
426
- if ( BNFW_Notification::POST_TYPE != $post_type ) {
427
- $this->send_notification_async( 'update-' . $post_type, $post_id );
428
- }
429
- }
430
-
431
- /**
432
- * Fires when a post is moved publish to trash.
433
- *
434
- */
435
- public function trash_post( $post ) {
436
- if ( $this->is_metabox_request() ) {
437
- return;
438
- }
439
- $post_id = $post->ID;
440
- $post_type = $post->post_type;
441
-
442
- if ( BNFW_Notification::POST_TYPE != $post_type ) {
443
- $this->send_notification_async( 'trash-' . $post_type, $post_id );
444
- }
445
- }
446
-
447
- /**
448
- * Fires when a post is pending for review.
449
- *
450
- * @since 1.1
451
- * @param int $post_id Post ID
452
- * @param object $post Post object
453
- */
454
- public function on_post_pending( $post_id, $post ) {
455
- if ( $this->is_metabox_request() ) {
456
- return;
457
- }
458
-
459
- $post_type = $post->post_type;
460
-
461
- if ( BNFW_Notification::POST_TYPE != $post_type ) {
462
- $this->send_notification_async( 'pending-' . $post_type, $post_id );
463
- }
464
- }
465
-
466
- /**
467
- * On Media Published.
468
- *
469
- * @param int $post_id Attachment post id.
470
- */
471
- public function new_publish_media_notification( $post_id ) {
472
- $post_type = get_post_type( $post_id );
473
-
474
- if ( BNFW_Notification::POST_TYPE != $post_type && $post_type == 'attachment' ) {
475
- $this->send_notification_async( 'new-media', $post_id );
476
- }
477
- }
478
-
479
- /**
480
- * On Media Attachment Data Update.
481
- *
482
- * @param int $post_id Attachment post id.
483
- */
484
- public function media_attachment_data_update_notification( $post_id ) {
485
- $post_type = get_post_type( $post_id );
486
- if ( BNFW_Notification::POST_TYPE != $post_type && $post_type == 'attachment' ) {
487
- $this->send_notification_async( 'update-media', $post_id );
488
- }
489
- }
490
-
491
- /**
492
- * Fires when a post is scheduled.
493
- *
494
- * @since 1.1.5
495
- * @param int $post_id Post ID
496
- * @param object $post Post object
497
- */
498
- function on_post_scheduled( $post_id, $post ) {
499
- // Rest request also triggers the same hook. We can ignore it.
500
- if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
501
- return;
502
- }
503
-
504
- $post_type = $post->post_type;
505
-
506
- if ( BNFW_Notification::POST_TYPE != $post_type ) {
507
- $this->send_notification_async( 'future-' . $post_type, $post_id );
508
- }
509
- }
510
-
511
- /**
512
- * When the status of a comment is changed.
513
- *
514
- * @param string $new_status New status.
515
- * @param string $old_status Old status.
516
- * @param \WP_Comment $comment Comment.
517
- */
518
- public function on_comment_status_change( $new_status, $old_status, $comment ) {
519
- if ( 'approved' !== $new_status ) {
520
- return;
521
- }
522
-
523
- $post = get_post( $comment->comment_post_ID );
524
-
525
- $notification_type = 'approve-' . $post->post_type . '-comment';
526
-
527
- $this->send_notification( $notification_type, $comment->comment_ID, false );
528
-
529
- // Send new comment notification after comment approve
530
- $notification_type = 'new-comment'; // old notification name
531
-
532
- if ( 'post' != $post->post_type ) {
533
- $notification_type = 'comment-' . $post->post_type;
534
- }
535
-
536
- $this->send_notification( $notification_type, $comment->comment_ID );
537
-
538
- // Send comment reply notification after comment approve.
539
- $this->commentsReply( $comment->comment_ID );
540
- }
541
-
542
- /**
543
- * Send notification for new comments
544
- *
545
- * @since 1.0
546
- * @param int $comment_id
547
- */
548
- public function comment_post( $comment_id ) {
549
- $the_comment = get_comment( $comment_id );
550
- $post = get_post( $the_comment->comment_post_ID );
551
-
552
- if ( '1' !== $the_comment->comment_approved ) {
553
- if ( $this->can_send_comment_notification( $the_comment ) ) {
554
- $notification_type = 'moderate-' . $post->post_type . '-comment';
555
- $this->send_notification( $notification_type, $comment_id );
556
- }
557
- } else {
558
- $notification_type = 'new-comment'; // old notification name
559
-
560
- if ( 'post' != $post->post_type ) {
561
- $notification_type = 'comment-' . $post->post_type;
562
- }
563
-
564
- $this->send_notification( $notification_type, $comment_id );
565
-
566
- // comment reply notification.
567
- $this->commentsReply( $comment_id );
568
- }
569
- }
570
-
571
- /**
572
- * Send notification for comments reply
573
- *
574
- * @since 1.0
575
- * @param int $comment_id
576
- */
577
- public function commentsReply( $comment_id ) {
578
- $the_comment = get_comment( $comment_id );
579
- $post = get_post( $the_comment->comment_post_ID );
580
-
581
- // comment reply notification.
582
- if ( $this->can_send_comment_notification( $the_comment ) ) {
583
- if ( $the_comment->comment_parent > 0 ) {
584
- $notification_type = 'reply-comment'; // old notification name
585
- if ( 'post' != $post->post_type ) {
586
- $notification_type = 'commentreply-' . $post->post_type;
587
- }
588
- $notifications = $this->notifier->get_notifications( $notification_type );
589
- if ( count( $notifications ) > 0 ) {
590
- $parent = get_comment( $the_comment->comment_parent );
591
- if ( $parent->comment_author_email != $the_comment->comment_author_email ) {
592
- foreach ( $notifications as $notification ) {
593
- $this->engine->send_comment_reply_email( $this->notifier->read_settings( $notification->ID ), $the_comment, $parent );
594
- }
595
- }
596
- }
597
- }
598
- }
599
- }
600
-
601
- /**
602
- * Send notification for new trackback
603
- *
604
- * @since 1.0
605
- * @param unknown $comment_id
606
- */
607
- function trackback_post( $comment_id ) {
608
- $the_comment = get_comment( $comment_id );
609
- if ( $this->can_send_comment_notification( $the_comment ) ) {
610
- $this->send_notification( 'new-trackback', $comment_id );
611
- }
612
- }
613
-
614
- /**
615
- * Send notification for new pingbacks
616
- *
617
- * @since 1.0
618
- * @param unknown $comment_id
619
- */
620
- function pingback_post( $comment_id ) {
621
- $the_comment = get_comment( $comment_id );
622
- if ( $this->can_send_comment_notification( $the_comment ) ) {
623
- $this->send_notification( 'new-pingback', $comment_id );
624
- }
625
- }
626
-
627
- /**
628
- * Send notification for lost password.
629
- *
630
- * @since 1.0
631
- */
632
- function on_lost_password() {
633
- $user_login = sanitize_text_field( $_POST[ 'user_login' ] );
634
- $user = get_user_by( 'login', $user_login ) ?: get_user_by( 'email', $user_login );
635
- if ( $user ) {
636
- $this->send_notification( 'admin-password', $user->ID );
637
- }
638
- }
639
-
640
- /**
641
- * Change the title of the password reset email that is sent to the user.
642
- *
643
- * @since 1.1
644
- *
645
- * @param string $title
646
- * @param string $user_login
647
- * @param string $user_data
648
- *
649
- * @return string
650
- */
651
- public function change_password_email_title( $title, $user_login = '',
652
- $user_data = '' ) {
653
- $notifications = $this->notifier->get_notifications( 'user-password' );
654
- if ( count( $notifications ) > 0 ) {
655
- // Ideally there should be only one notification for this type.
656
- // If there are multiple notification then we will read data about only the last one
657
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
658
-
659
- if ( '' === $user_data ) {
660
- return $this->engine->handle_shortcodes( $setting[ 'subject' ], 'user-password', $user_data->ID );
661
- } else {
662
- return $this->engine->handle_shortcodes( $setting[ 'subject' ], 'user-password', $user_data->ID );
663
- }
664
- }
665
-
666
- return $title;
667
- }
668
-
669
- /**
670
- * Change the message of the password reset email.
671
- *
672
- * @since 1.1
673
- *
674
- * @param string $message
675
- * @param string $key
676
- * @param string $user_login
677
- * @param string $user_data
678
- *
679
- * @return string
680
- */
681
- public function change_password_email_message( $message, $key,
682
- $user_login = '',
683
- $user_data = '' ) {
684
- $notifications = $this->notifier->get_notifications( 'user-password' );
685
- if ( count( $notifications ) > 0 ) {
686
- // Ideally there should be only one notification for this type.
687
- // If there are multiple notification then we will read data about only the last one
688
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
689
-
690
- $message = $this->engine->handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data );
691
-
692
- if ( 'html' == $setting[ 'email-formatting' ] ) {
693
- add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
694
- if ( 'true' !== $setting[ 'disable-autop' ] ) {
695
- $message = wpautop( $message );
696
- }
697
- } else {
698
- add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
699
- if ( 'text' == $setting[ 'email-formatting' ] ) {
700
- $message = strip_tags( $message );
701
- }
702
- }
703
- } else {
704
- if ( $this->notifier->notification_exists( 'user-password', false ) ) {
705
- // disabled notification exists, so disable the email by returning empty string.
706
- return '';
707
- }
708
- }
709
-
710
- return $message;
711
- }
712
-
713
- /**
714
- * On Password reset.
715
- *
716
- * @param WP_User $user User who's password was changed.
717
- */
718
- public function on_password_reset( $user ) {
719
- $notifications = $this->notifier->get_notifications( 'password-changed' );
720
- foreach ( $notifications as $notification ) {
721
- $this->engine->send_password_changed_email( $this->notifier->read_settings( $notification->ID ), $user );
722
- }
723
- }
724
-
725
- /**
726
- * Should the password changed email be sent?
727
- *
728
- * @param $send
729
- * @param $user
730
- * @param $userdata
731
- *
732
- * @return bool
733
- */
734
- public function should_password_changed_email_be_sent( $send, $user,
735
- $userdata ) {
736
- $bnfw = BNFW::factory();
737
-
738
- if ( ! $send ) {
739
- return $send;
740
- }
741
-
742
- return ! $bnfw->notifier->is_notification_disabled( 'password-changed' );
743
- }
744
-
745
- /**
746
- * On Password Changed.
747
- *
748
- * @since 1.6
749
- *
750
- * @param array $email_data Email Data.
751
- * @param array $user User data.
752
- *
753
- * @return array Modified Email Data
754
- */
755
- public function on_password_changed( $email_data, $user ) {
756
- return $this->handle_filtered_data_notification( 'password-changed', $email_data, $user[ 'ID' ] );
757
- }
758
-
759
- /**
760
- * Should the email changed email be sent?
761
- *
762
- * @param $send
763
- * @param $user
764
- * @param $userdata
765
- *
766
- * @return bool
767
- */
768
- public function should_email_changed_email_be_sent( $send, $user_old_data,
769
- $user_new_data ) {
770
- $bnfw = BNFW::factory();
771
-
772
- if ( $bnfw->notifier->notification_exists( 'admin-email-changed', false ) ) {
773
- $notifications = $bnfw->notifier->get_notifications( 'admin-email-changed' );
774
-
775
- if ( count( $notifications ) > 0 ) {
776
- // Ideally there should be only one notification for this type.
777
- // If there are multiple notification then we will read data about only the last one
778
- $setting = $bnfw->notifier->read_settings( end( $notifications )->ID );
779
- $notification_disabled = apply_filters( 'bnfw_notification_disabled', ( 'true' === $setting[ 'disabled' ] ), $id, $setting );
780
-
781
- if ( ! $notification_disabled ) {
782
-
783
- $setting[ 'message' ] = str_replace( '[user_old_email]', $user_old_data[ 'user_email' ], $setting[ 'message' ] );
784
- $setting[ 'message' ] = str_replace( '[user_new_email]', $user_new_data[ 'user_email' ], $setting[ 'message' ] );
785
- $bnfw->engine->send_notification( $setting, $user_old_data[ 'ID' ] );
786
- }
787
- }
788
- }
789
-
790
- if ( ! $send ) {
791
- return $send;
792
- }
793
-
794
- return ! $bnfw->notifier->is_notification_disabled( 'email-changed' );
795
- }
796
-
797
- /**
798
- * On Email Changed.
799
- *
800
- * @since 1.6
801
- *
802
- * @param array $email_data Email Data.
803
- * @param array $user User data.
804
- *
805
- * @return array Modified Email Data
806
- */
807
- public function on_email_changed( $email_data, $user_old_data,
808
- $user_new_data ) {
809
-
810
- $email = $this->handle_filtered_data_notification( 'email-changed', $email_data, $user_old_data[ 'ID' ] );
811
- $email[ 'message' ] = str_replace( '[user_old_email]', $user_old_data[ 'user_email' ], $email[ 'message' ] );
812
- $email[ 'message' ] = str_replace( '[user_new_email]', $user_new_data[ 'user_email' ], $email[ 'message' ] );
813
- return $email;
814
- }
815
-
816
- public function on_email_changing( $email_text, $new_user_details ) {
817
- $notification_name = 'email-changing';
818
-
819
- $notifications = $this->notifier->get_notifications( $notification_name );
820
- if ( count( $notifications ) > 0 ) {
821
- // Ideally there should be only one notification for this type.
822
- // If there are multiple notification then we will read data about only the last one
823
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
824
-
825
- $email_text = $this->engine->handle_shortcodes( $setting[ 'message' ], $setting[ 'notification' ], $new_user_details[ 'newemail' ] );
826
- $email_text = $this->engine->handle_global_user_shortcodes( $email_text, $new_user_details[ 'newemail' ] );
827
- $email_text = str_replace( '[email_change_confirmation_link]', esc_url( admin_url( 'profile.php?newuseremail=' . $new_user_details[ 'hash' ] ) ), $email_text );
828
- }
829
-
830
- return $email_text;
831
- }
832
-
833
- /**
834
- * Send notification on core updated event.
835
- *
836
- * @since 1.6
837
- *
838
- * @param array $email_data Email Data.
839
- * @param string $type The type of email being sent. Can be one of
840
- * 'success', 'fail', 'manual', 'critical'.
841
- * @param object $core_update The update offer that was attempted.
842
- * @param mixed $result The result for the core update. Can be WP_Error.
843
- *
844
- * @return array Modified Email Data.
845
- */
846
- public function on_core_updated( $email_data, $type, $core_update, $result ) {
847
- $notifications = $this->notifier->get_notifications( 'core-updated' );
848
- if ( count( $notifications ) > 0 ) {
849
- // Ideally there should be only one notification for this type.
850
- // If there are multiple notification then we will read data about only the last one
851
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
852
-
853
- $email_data = $this->engine->handle_core_updated_notification( $email_data, $setting, $type );
854
- }
855
-
856
- return $email_data;
857
- }
858
-
859
- /**
860
- * Process User update notifications.
861
- *
862
- * @since 1.6
863
- *
864
- * @param string $notification_name Notification Name.
865
- * @param array $email_data Email Data.
866
- * @param string|int $extra_data User Id.
867
- *
868
- * @return array Modified Email Data.
869
- */
870
- private function handle_filtered_data_notification( $notification_name,
871
- $email_data, $extra_data ) {
872
- $notifications = $this->notifier->get_notifications( $notification_name );
873
- if ( count( $notifications ) > 0 ) {
874
- // Ideally there should be only one notification for this type.
875
- // If there are multiple notification then we will read data about only the last one
876
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
877
-
878
- $email_data = $this->engine->handle_filtered_data_notification( $email_data, $setting, $extra_data );
879
- }
880
-
881
- return $email_data;
882
- }
883
-
884
- /**
885
- * Set the email formatting to HTML.
886
- *
887
- * @since 1.4
888
- */
889
- public function set_html_content_type() {
890
- return 'text/html';
891
- }
892
-
893
- /**
894
- * Set the email formatting to text.
895
- *
896
- * @since 1.4
897
- */
898
- public function set_text_content_type() {
899
- return 'text/plain';
900
- }
901
-
902
- /**
903
- * Send notification for new users.
904
- *
905
- * @since 1.0
906
- * @param int $user_id
907
- */
908
- public function user_register( $user_id ) {
909
- $this->send_notification( 'admin-user', $user_id );
910
- }
911
-
912
- /**
913
- * Send notification for user when user login.
914
- *
915
- * @since 1.0
916
- * @param string $user_name
917
- * @param object $user_data User object.
918
- */
919
- public function user_login( $user_name, $user_data ) {
920
- $user_id = $user_data->ID;
921
- $notifications = $this->notifier->get_notifications( 'user-login' );
922
-
923
- foreach ( $notifications as $notification ) {
924
- $this->engine->send_user_login_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
925
- }
926
-
927
- $this->user_login_admin_notification( $user_id );
928
- }
929
-
930
- /**
931
- * Send notification for admin when user login.
932
- *
933
- * @since 1.0
934
- * @param int $user_id
935
- */
936
- public function user_login_admin_notification( $user_id ) {
937
- $notifications = $this->notifier->get_notifications( 'admin-user-login' );
938
-
939
- foreach ( $notifications as $notification ) {
940
- $this->engine->send_user_login_email_for_admin( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
941
- }
942
- }
943
-
944
- /**
945
- * Send notification about new users to site admin.
946
- *
947
- * @since 1.7.1
948
- *
949
- * @param array $email_data Email details.
950
- * @param WP_User $user User object.
951
- * @param string $blogname Blog name.
952
- *
953
- * @return array Modified email details.
954
- */
955
- public function handle_user_registered_admin_email( $email_data, $user,
956
- $blogname ) {
957
- return $this->handle_filtered_data_notification( 'admin-user', $email_data, $user->ID );
958
- }
959
-
960
- /**
961
- * New User - Post-registration Email
962
- *
963
- * @since 1.1
964
- * @param int $user_id New user id
965
- */
966
- public function welcome_email( $user_id ) {
967
- $notifications = $this->notifier->get_notifications( 'welcome-email' );
968
- foreach ( $notifications as $notification ) {
969
- $this->engine->send_registration_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
970
- }
971
- }
972
-
973
- /**
974
- * Send notification when a user role changes.
975
- *
976
- * @since 1.3.9
977
- *
978
- * @param int $user_id User ID
979
- * @param string $new_role New User role
980
- * @param array $old_roles Old User role
981
- */
982
- public function user_role_changed( $user_id, $new_role, $old_roles ) {
983
- if ( ! empty( $old_roles ) ) {
984
- $notifications = $this->notifier->get_notifications( 'user-role' );
985
- foreach ( $notifications as $notification ) {
986
-
987
- /**
988
- * Trigger User Role Changed - For User notification.
989
- *
990
- * @since 1.6.5
991
- */
992
- if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, $old_roles ) ) {
993
- $this->engine->send_user_role_changed_email(
994
- $this->notifier->read_settings( $notification->ID ),
995
- $user_id,
996
- $old_roles[ 0 ],
997
- $new_role
998
- );
999
- }
1000
- }
1001
-
1002
- $notifications = $this->notifier->get_notifications( 'admin-role' );
1003
- foreach ( $notifications as $notification ) {
1004
-
1005
- /**
1006
- * Trigger User Role Changed - For User notification.
1007
- *
1008
- * @since 1.6.5
1009
- */
1010
- if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, $old_roles ) ) {
1011
- $setting = $this->notifier->read_settings( $notification->ID );
1012
- $setting[ 'message' ] = $this->engine->handle_user_role_shortcodes( $setting[ 'message' ], $old_roles[ 0 ], $new_role );
1013
- $setting[ 'subject' ] = $this->engine->handle_user_role_shortcodes( $setting[ 'subject' ], $old_roles[ 0 ], $new_role );
1014
-
1015
- $this->engine->send_notification( $setting, $user_id );
1016
- }
1017
- }
1018
- }
1019
- }
1020
-
1021
- /**
1022
- * Send notification when a user role added through Members Plugin.
1023
- *
1024
- * @since 1.8.4
1025
- *
1026
- * @param int $user_id User ID
1027
- * @param string $new_role New User role
1028
- *
1029
- */
1030
- public function user_role_added_from_member_plugin($user_id, $new_role){
1031
-
1032
- global $pagenow;
1033
-
1034
- if($pagenow != 'users.php')
1035
- return;
1036
-
1037
- if(!$user_id)
1038
- return;
1039
-
1040
- $notifications = $this->notifier->get_notifications( 'user-role' );
1041
-
1042
- foreach ( $notifications as $notification ) {
1043
-
1044
- if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, null ) ) {
1045
- $this->engine->send_user_role_changed_email(
1046
- $this->notifier->read_settings( $notification->ID ),
1047
- $user_id,
1048
- null,
1049
- $new_role
1050
- );
1051
- }
1052
- }
1053
-
1054
- $notifications_admin = $this->notifier->get_notifications( 'admin-role' );
1055
- foreach ( $notifications_admin as $notification ) {
1056
- if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, null ) ) {
1057
- $setting = $this->notifier->read_settings( $notification->ID );
1058
- $setting[ 'message' ] = $this->engine->handle_user_role_shortcodes( $setting[ 'message' ], null, $new_role );
1059
- $setting[ 'subject' ] = $this->engine->handle_user_role_shortcodes( $setting[ 'subject' ], null, $new_role );
1060
-
1061
- $this->engine->send_notification( $setting, $user_id );
1062
- }
1063
- }
1064
-
1065
- }
1066
-
1067
- /**
1068
- * Send notification when a user role removed through Members Plugin.
1069
- *
1070
- * @since 1.8.4
1071
- *
1072
- * @param int $user_id User ID
1073
- * @param string $old_role New User role
1074
- *
1075
- */
1076
- public function user_role_removed_from_member_plugin($user_id, $old_role){
1077
- global $pagenow;
1078
-
1079
- if($pagenow != 'users.php')
1080
- return;
1081
-
1082
- if(!$user_id)
1083
- return;
1084
-
1085
- $notifications = $this->notifier->get_notifications( 'user-role' );
1086
-
1087
- foreach ( $notifications as $notification ) {
1088
- if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, null, array($old_role) ) ) {
1089
- $this->engine->send_user_role_changed_email(
1090
- $this->notifier->read_settings( $notification->ID ),
1091
- $user_id,
1092
- $old_role,
1093
- null
1094
- );
1095
- }
1096
- }
1097
-
1098
- $notifications_admin = $this->notifier->get_notifications( 'admin-role' );
1099
- foreach ( $notifications_admin as $notification ) {
1100
- if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, null, array($old_role) ) ) {
1101
- $setting = $this->notifier->read_settings( $notification->ID );
1102
- $setting[ 'message' ] = $this->engine->handle_user_role_shortcodes( $setting[ 'message' ], $old_role, null );
1103
- $setting[ 'subject' ] = $this->engine->handle_user_role_shortcodes( $setting[ 'subject' ], $old_role, null );
1104
-
1105
-
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 string $new_role New User role
1120
- * @param array $old_roles Old User role
1121
- */
1122
- public function user_role_added( $user_id, $old_user_data ) {
1123
-
1124
- if ( isset( $_POST[ 'members_user_roles' ] ) && ! empty( $_POST[ 'members_user_roles' ] ) ) {
1125
- // Get the current user roles.
1126
- $old_roles = (array) $old_user_data->roles;
1127
-
1128
- // Sanitize the posted roles.
1129
- $new_roles = array_map( 'members_sanitize_role', $_POST[ 'members_user_roles' ] );
1130
-
1131
- sort( $old_roles );
1132
- sort( $new_roles );
1133
- $old_roles_str = implode( '', $old_roles );
1134
- $new_roles_str = implode( '', $new_roles );
1135
- if ( ! empty( $old_roles ) && $old_roles_str !== $new_roles_str ) {
1136
- $notifications = $this->notifier->get_notifications( 'user-role' );
1137
- foreach ( $notifications as $notification ) {
1138
-
1139
- /**
1140
- * Trigger User Role Changed - For User notification.
1141
- *
1142
- * @since 1.6.5
1143
- */
1144
- if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1145
- $this->engine->send_user_role_added_email(
1146
- $this->notifier->read_settings( $notification->ID ),
1147
- $user_id,
1148
- $old_roles,
1149
- $new_roles
1150
- );
1151
- }
1152
- }
1153
-
1154
- $notifications = $this->notifier->get_notifications( 'admin-role' );
1155
- foreach ( $notifications as $notification ) {
1156
-
1157
- /**
1158
- * Trigger User Role Changed - For User notification.
1159
- *
1160
- * @since 1.6.5
1161
- */
1162
- if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1163
- $setting = $this->notifier->read_settings( $notification->ID );
1164
- $setting[ 'message' ] = $this->engine->handle_user_added_role_shortcodes( $setting[ 'message' ], $old_roles, $new_roles );
1165
- $setting[ 'subject' ] = $this->engine->handle_user_added_role_shortcodes( $setting[ 'subject' ], $old_roles, $new_roles );
1166
-
1167
- $this->engine->send_notification( $setting, $user_id );
1168
- }
1169
- }
1170
- }
1171
- }
1172
- }
1173
-
1174
- /**
1175
- * Sanitizes a role name. This is a wrapper for the `sanitize_key()` WordPress function. Only
1176
- * alphanumeric characters and underscores are allowed. Hyphens are also replaced with underscores.
1177
- *
1178
- * @since 1.0.0
1179
- * @access public
1180
- * @return int
1181
- */
1182
- function members_sanitize_role( $role ) {
1183
-
1184
- $_role = strtolower( $role );
1185
- $_role = preg_replace( '/[^a-z0-9_\-\s]/', '', $_role );
1186
-
1187
- return apply_filters( 'members_sanitize_role', str_replace( ' ', '_', $_role ), $role );
1188
- }
1189
-
1190
- /**
1191
- * Send notification based on type and ref id
1192
- *
1193
- * @since 1.0
1194
- * @param string $type Notification type.
1195
- * @param mixed $ref_id Reference data.
1196
- */
1197
- public function send_notification( $type, $ref_id, $include_disabled = true ) {
1198
- $notifications = $this->notifier->get_notifications( $type , $include_disabled);
1199
- foreach ( $notifications as $notification ) {
1200
- $this->engine->send_notification( $this->notifier->read_settings( $notification->ID ), $ref_id );
1201
- }
1202
- }
1203
-
1204
- /**
1205
- * Send notification async based on type and ref id.
1206
- *
1207
- * @param string $type Notification type.
1208
- * @param mixed $ref_id Reference data.
1209
- */
1210
- public function send_notification_async( $type, $ref_id ) {
1211
- $notifications = $this->notifier->get_notifications( $type, false );
1212
- foreach ( $notifications as $notification ) {
1213
- $transient = get_transient( 'bnfw-async-notifications' );
1214
- if ( ! is_array( $transient ) ) {
1215
- $transient = array();
1216
- }
1217
-
1218
- $notification_data = array(
1219
- 'ref_id' => $ref_id,
1220
- 'notification_id' => $notification->ID,
1221
- 'notification_type' => $type,
1222
- );
1223
-
1224
- if ( ! in_array( $notification_data, $transient ) ) {
1225
- $transient[] = $notification_data;
1226
- set_transient( 'bnfw-async-notifications', $transient, 600 );
1227
- }
1228
- }
1229
- }
1230
-
1231
- /**
1232
- * Can send comment notification or not
1233
- *
1234
- * @since 1.0
1235
- * @param unknown $comment
1236
- * @return unknown
1237
- */
1238
- private function can_send_comment_notification( $comment ) {
1239
- // Returns false if the comment is marked as spam AND admin has enabled suppression of spam
1240
- $suppress_spam = get_option( 'bnfw_suppress_spam' );
1241
- if ( '1' === $suppress_spam && ( 0 === strcmp( $comment->comment_approved, 'spam' ) ) ) {
1242
- return false;
1243
- }
1244
- return true;
1245
- }
1246
-
1247
- /**
1248
- * Handle user request email content.
1249
- *
1250
- * @param string $content Content.
1251
- * @param array $email_data Email data.
1252
- *
1253
- * @return string Modified content.
1254
- */
1255
- public function handle_user_request_email_content( $content, $email_data ) {
1256
- $field = 'message';
1257
- $new_content = '';
1258
-
1259
- switch ( $email_data[ 'description' ] ) {
1260
- case 'Export Personal Data':
1261
- $notification_name = 'ca-export-data';
1262
- $new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1263
- break;
1264
- case 'Erase Personal Data':
1265
- $notification_name = 'ca-erase-data';
1266
- $new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1267
- break;
1268
- }
1269
-
1270
- if ( ! empty( $new_content ) ) {
1271
- return $new_content;
1272
- } else {
1273
- return $content;
1274
- }
1275
- }
1276
-
1277
- /**
1278
- * Handle user request email subject.
1279
- *
1280
- * @param string $subject Subject
1281
- * @param string $blogname Blog name
1282
- * @param array $email_data Email data.
1283
- *
1284
- * @return string Modified subject.
1285
- */
1286
- public function handle_user_request_email_subject( $subject, $blogname,
1287
- $email_data ) {
1288
- $field = 'subject';
1289
- $new_subject = '';
1290
-
1291
- switch ( $email_data[ 'description' ] ) {
1292
- case 'Export Personal Data':
1293
- $notification_name = 'ca-export-data';
1294
- $new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1295
- break;
1296
- case 'Erase Personal Data':
1297
- $notification_name = 'ca-erase-data';
1298
- $new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1299
- break;
1300
- }
1301
- if ( ! empty( $new_subject ) ) {
1302
- return $new_subject;
1303
- } else {
1304
- return $subject;
1305
- }
1306
- }
1307
-
1308
- /**
1309
- * Handle user confirmed action email content.
1310
- *
1311
- * @param string $content Content.
1312
- * @param array $email_data Email data.
1313
- *
1314
- * @return string Modified content.
1315
- */
1316
- public function handle_user_confirmed_action_email_content( $content,
1317
- $email_data ) {
1318
- $field = 'message';
1319
- $new_content = '';
1320
-
1321
- switch ( $email_data[ 'description' ] ) {
1322
- case 'Export Personal Data':
1323
- $notification_name = 'uc-export-data';
1324
- $new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1325
- break;
1326
- case 'Erase Personal Data':
1327
- $notification_name = 'uc-erase-data';
1328
- $new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1329
- break;
1330
- }
1331
-
1332
- if ( ! empty( $new_content ) ) {
1333
- return $new_content;
1334
- } else {
1335
- return $content;
1336
- }
1337
- }
1338
-
1339
- /**
1340
- * Handle data exported email content.
1341
- *
1342
- * @param string $content Content.
1343
- * @param int $request_id
1344
- *
1345
- * @return string Modified content.
1346
- */
1347
- public function handle_data_export_email_content( $content, $request_id,$email_data ) {
1348
-
1349
- $field = 'message';
1350
- $notification_name = 'data-export';
1351
- $new_content = '';
1352
-
1353
- $notifications = $this->notifier->get_notifications( $notification_name );
1354
- if ( count( $notifications ) > 0 ) {
1355
- // Ideally there should be only one notification for this type.
1356
- // If there are multiple notification then we will read data about only the last one
1357
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
1358
-
1359
- $new_content = $this->engine->handle_data_export_email_shortcodes( $setting[ $field ], $setting, $request_id );
1360
- $new_content = $this->engine->handle_global_user_shortcodes( $new_content, $email_data['message_recipient'] );
1361
- }
1362
-
1363
- if ( ! empty( $new_content ) ) {
1364
- return $new_content;
1365
- } else {
1366
- return $content;
1367
- }
1368
- }
1369
-
1370
- public function handle_erasure_complete_email_subject( $subject, $sitename,
1371
- $email_data ) {
1372
- return $this->handle_erasure_complete_email_notification( 'subject', $subject, $email_data );
1373
- }
1374
-
1375
- public function handle_erasure_complete_email_content( $content, $email_data ) {
1376
- if ( isset( $email_data[ 'privacy_policy_url' ] ) ) {
1377
- return $this->handle_erasure_complete_email_notification( 'message', $content, $email_data );
1378
- }
1379
-
1380
- return $content;
1381
- }
1382
-
1383
- protected function handle_erasure_complete_email_notification( $field,
1384
- $content,
1385
- $email_data ) {
1386
- $notification_name = 'data-erased';
1387
- $new_content = '';
1388
- $notifications = $this->notifier->get_notifications( $notification_name );
1389
- if ( count( $notifications ) > 0 ) {
1390
- // Ideally there should be only one notification for this type.
1391
- // If there are multiple notification then we will read data about only the last one
1392
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
1393
- $new_content = $this->engine->handle_shortcodes( $setting[ $field ], $notification_name, $email_data );
1394
- }
1395
- if ( ! empty( $new_content ) ) {
1396
- return $new_content;
1397
- } else {
1398
- return $content;
1399
- }
1400
- }
1401
-
1402
- /**
1403
- * Send notification emails on shutdown.
1404
- */
1405
- public function on_shutdown() {
1406
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1407
- return;
1408
- }
1409
-
1410
- $transient = get_transient( 'bnfw-async-notifications' );
1411
- if ( is_array( $transient ) ) {
1412
- delete_transient( 'bnfw-async-notifications' );
1413
- foreach ( $transient as $id_pairs ) {
1414
- $this->engine->send_notification( $this->notifier->read_settings( $id_pairs[ 'notification_id' ] ), $id_pairs[ 'ref_id' ] );
1415
- }
1416
- }
1417
- }
1418
-
1419
- /**
1420
- * Handle user request notification.
1421
- *
1422
- * @param string $notification_name Notification name.
1423
- * @param string $field Field name.
1424
- * @param array $email_data Email data.
1425
- *
1426
- * @return string Content.
1427
- */
1428
- protected function handle_user_request_notification( $notification_name,
1429
- $field, $email_data ) {
1430
- $notifications = $this->notifier->get_notifications( $notification_name );
1431
- if ( count( $notifications ) > 0 ) {
1432
- // Ideally there should be only one notification for this type.
1433
- // If there are multiple notification then we will read data about only the last one
1434
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
1435
-
1436
- return $this->engine->handle_user_request_email_shortcodes( $setting[ $field ], $setting, $email_data );
1437
- }
1438
-
1439
- return '';
1440
- }
1441
-
1442
- /**
1443
- * Handle user confirmed action notification.
1444
- *
1445
- * @param string $notification_name Notification name.
1446
- * @param string $field Field name.
1447
- * @param array $email_data Email data.
1448
- *
1449
- * @return string Content.
1450
- */
1451
- protected function handle_user_confirmed_action_notification( $notification_name,
1452
- $field,
1453
- $email_data ) {
1454
- $notifications = $this->notifier->get_notifications( $notification_name );
1455
- if ( count( $notifications ) > 0 ) {
1456
- // Ideally there should be only one notification for this type.
1457
- // If there are multiple notification then we will read data about only the last one
1458
- $setting = $this->notifier->read_settings( end( $notifications )->ID );
1459
-
1460
- return $this->engine->handle_user_confirmed_action_email_shortcodes( $setting[ $field ], $setting, $email_data );
1461
- }
1462
-
1463
- return '';
1464
- }
1465
-
1466
- /**
1467
- * Is this a metabox request?
1468
- *
1469
- * Block editor sends duplicate requests on post update.
1470
- *
1471
- * @return bool True if metabox request, False otherwise.
1472
- */
1473
- protected function is_metabox_request() {
1474
- return ( isset( $_GET[ 'meta-box-loader' ] ) || isset( $_GET[ 'meta_box' ] ) );
1475
- }
1476
-
1477
-
1478
- /**
1479
- * Check if Gutenberg is active.
1480
- *
1481
- *
1482
- * @return bool
1483
- * @since 1.3
1484
- */
1485
- public function is_gutenberg_active() {
1486
- $gutenberg = false;
1487
- $block_editor = false;
1488
-
1489
- if ( has_filter( 'replace_editor', 'gutenberg_init' ) ) {
1490
- // Gutenberg is installed and activated.
1491
- $gutenberg = true;
1492
- }
1493
-
1494
- if ( version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ) ) {
1495
- // Block editor.
1496
- $block_editor = true;
1497
- }
1498
-
1499
- if ( ! $gutenberg && ! $block_editor ) {
1500
- return false;
1501
- }
1502
-
1503
- include_once ABSPATH . 'wp-admin/includes/plugin.php';
1504
-
1505
- if ( ! is_plugin_active( 'classic-editor/classic-editor.php' ) ) {
1506
- return true;
1507
- }
1508
-
1509
- $use_block_editor = ( get_option( 'classic-editor-replace' ) === 'no-replace' );
1510
-
1511
- return $use_block_editor;
1512
- }
1513
-
1514
- }
1515
-
1516
- /* ------------------------------------------------------------------------ *
1517
- * Fire up the plugin
1518
- * ------------------------------------------------------------------------ */
1519
- BNFW::factory();
 
 
 
 
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