Plugin Directory

Changeset 1072407


Ignore:
Timestamp:
01/21/2015 09:32:27 AM (11 years ago)
Author:
themeavenue
Message:

Update to 3.1.0

Location:
awesome-support/trunk
Files:
12 added
5 deleted
36 edited

Legend:

Unmodified
Added
Removed
  • awesome-support/trunk/assets/admin/css/admin.css

    r1048776 r1072407  
    1 @charset 'UTF-8';.wpas-cf:before,.wpas-cf:after{content:" ";display:table}.wpas-cf:after{clear:both}.wpas-pl{float:left}.wpas-pr{float:right}.wpas-label{display:inline-block;padding:2px 8px;font-weight:bold;color:#fff;white-space:nowrap;vertical-align:baseline;background-color:#999;border-radius:3px}.wpas-lead{font-size:16px}.wpas-alert-danger{color:red}.wpas-alert-success{color:green}.column-status{width:90px !important;overflow:hidden}.wpas-activity ul,.wpas-activity li{margin:0;padding:0}@media screen and (max-width:782px){.column-taxonomy-ticket-tag,.column-taxonomy-product,.column-wpas-activity{display:none}}#wpas-system-status-output{width:100%;padding:1em}.wpas-system-status,.wpas-system-status-table{margin-bottom:2em}.wpas-system-status-table .row-title{width:20%}.wpas-table-replies tr>td{vertical-align:top;padding-top:2.25em;padding-bottom:2.25em;position:relative}.wpas-table-replies tr.wpas-ticket-history>td,.wpas-table-replies tr.wpas-ticket-history p{font-size:13px}.wpas-table-replies tr.wpas-ticket-history>td{padding-top:0.75em;padding-bottom:0.75em;text-align:center;border:1px solid;color:#555;background-color:#f5f5f5;border-color:#dedede}.wpas-table-replies tr.wpas-trash>td{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.wpas-table-replies tr.wpas-editor>td{background-color:#d9edf7}.wpas-table-replies .avatar-64{border-radius:3px}.wpas-table-replies h1,.wpas-table-replies h2,.wpas-table-replies h3,.wpas-table-replies h4,.wpas-table-replies h5,.wpas-table-replies h6{border:none;margin:0 0 10px 0;padding:0}.wpas-table-replies ul{list-style-type:disc;list-style-position:inside}.wpas-table-replies ol{list-style-type:decimal;list-style-position:inside}.wpas-table-replies ul ul,.wpas-table-replies ol ul{list-style-type:circle;list-style-position:inside;margin-left:15px}.wpas-table-replies ol ol,.wpas-table-replies td ul ol{list-style-type:lower-latin;list-style-position:inside;margin-left:15px}.wpas-ticket-controls,.wpas-profilerole,.wpas-human-date{opacity:0;transition:opacity .25s ease}.wpas-table-row{border-top:1px solid #ddd}.wpas-table-row:hover .wpas-ticket-controls,.wpas-table-row:hover .wpas-profilerole,.wpas-table-row:hover .wpas-human-date,.wpas-table-row:hover .wpas-unread-badge{opacity:1}.wpas-ticket-controls{position:absolute;top:50px;right:0}.wpas-ticket-controls .wpas-delete:first-child{border-top-right-radius:0px;border-bottom-right-radius:0px;border-right:none}.wpas-ticket-controls .wpas-edit:last-child{border-top-left-radius:0px;border-bottom-left-radius:0px}.wpas-reply-meta{padding-bottom:0.75em}.wpas-reply-meta:before,.wpas-reply-meta:after{content:" ";display:table}.wpas-reply-meta:after{clear:both}.wpas-reply-meta .wpas-reply-user{float:left}.wpas-reply-meta .wpas-reply-time{float:right}.wpas-action-details ul,.wpas-action-details li,.wpas-action-details p{list-style:none;margin:0;padding:0}.wpas-action-details li,.wpas-action-details p{margin-top:4px}.wpas-time{white-space:nowrap;background-color:#fff;border:1px solid #ddd;padding:1px 5px;border-radius:3px}.wpas-unread-badge{position:absolute;top:0;right:0;background:#0074a2;color:white;padding:4px 8px;font-size:12px;opacity:0.5}.wpas-reply-attachements{margin-top:2em;background-color:#f1f1f1;border:1px solid #ddd;padding:1.5em}.wpas-reply-attachements ul,.wpas-reply-attachements li{list-style:none;margin:0;padding:0}.wpas-attachment-container{background-color:#FFFFED;padding:1.5em;margin:1.5em 0;border:1px solid #ddd}.wpas-attachment-container label{display:block}.wpas-attachment-container p{margin:0}@media screen and (max-width:782px){.wpas-table-replies tr>td.col1{display:none}.wpas-table-replies tr.wpas-ticket-history>td{line-height:1.6}.wpas-reply-meta .wpas-reply-user,.wpas-reply-meta .wpas-reply-time{float:none;clear:both}.wpas-ticket-controls,.wpas-profilerole,.wpas-human-date{opacity:1}.wpas-ticket-controls{position:static;top:0;text-align:right}}
     1@charset 'UTF-8';.wpas-cf:after,.wpas-cf:before{content:" ";display:table}.wpas-cf:after{clear:both}.wpas-pl{float:left}.wpas-pr{float:right}.wpas-label{display:inline-block;padding:2px 8px;font-weight:700;color:#fff;vertical-align:baseline;background-color:#999;border-radius:3px}.wpas-label+.wpas-label{margin-top:5px}.wpas-lead{font-size:16px}.wpas-alert-danger{color:red}.wpas-alert-success{color:green}.column-status{width:90px!important;overflow:hidden}.wpas-activity li,.wpas-activity ul{margin:0;padding:0}@media screen and (max-width:782px){.column-taxonomy-product,.column-taxonomy-ticket-tag,.column-wpas-activity{display:none}}#wpas-system-status-output{width:100%;padding:1em}.wpas-system-status,.wpas-system-status-table{margin-bottom:2em}.wpas-system-status-table .row-title{width:20%}.wpas-table-replies tr>td{vertical-align:top;padding-top:2.25em;padding-bottom:2.25em;position:relative}.wpas-table-replies tr.wpas-ticket-history p,.wpas-table-replies tr.wpas-ticket-history>td{font-size:13px}.wpas-table-replies tr.wpas-ticket-history>td{padding-top:.75em;padding-bottom:.75em;text-align:center;border:1px solid;color:#555;background-color:#f5f5f5;border-color:#dedede}.wpas-table-replies tr.wpas-trash>td{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.wpas-table-replies tr.wpas-editor>td{background-color:#d9edf7}.wpas-table-replies .avatar-64{border-radius:3px}.wpas-table-replies h1,.wpas-table-replies h2,.wpas-table-replies h3,.wpas-table-replies h4,.wpas-table-replies h5,.wpas-table-replies h6{border:none;margin:0 0 10px;padding:0}.wpas-table-replies ul{list-style-type:disc;list-style-position:inside}.wpas-table-replies ol{list-style-type:decimal;list-style-position:inside}.wpas-table-replies ol ul,.wpas-table-replies ul ul{list-style-type:circle;list-style-position:inside;margin-left:15px}.wpas-table-replies ol ol,.wpas-table-replies td ul ol{list-style-type:lower-latin;list-style-position:inside;margin-left:15px}.wpas-human-date,.wpas-profilerole,.wpas-ticket-controls{opacity:0;transition:opacity .25s ease}.wpas-table-row{border-top:1px solid #ddd}.wpas-table-row:hover .wpas-human-date,.wpas-table-row:hover .wpas-profilerole,.wpas-table-row:hover .wpas-ticket-controls,.wpas-table-row:hover .wpas-unread-badge{opacity:1}.wpas-ticket-controls{position:absolute;top:50px;right:0}.wpas-ticket-controls .wpas-delete:first-child{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none}.wpas-ticket-controls .wpas-edit:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.wpas-reply-meta{padding-bottom:.75em}.wpas-reply-meta:after,.wpas-reply-meta:before{content:" ";display:table}.wpas-reply-meta:after{clear:both}.wpas-reply-meta .wpas-reply-user{float:left}.wpas-reply-meta .wpas-reply-time{float:right}.wpas-action-details li,.wpas-action-details p,.wpas-action-details ul{list-style:none;margin:0;padding:0}.wpas-action-details li,.wpas-action-details p{margin-top:4px}.wpas-time{white-space:nowrap;background-color:#fff;border:1px solid #ddd;padding:1px 5px;border-radius:3px}.wpas-unread-badge{position:absolute;top:0;right:0;background:#0074a2;color:#fff;padding:4px 8px;font-size:12px;opacity:.5}.wpas-reply-attachements{margin-top:2em;background-color:#f1f1f1;border:1px solid #ddd;padding:1.5em}.wpas-reply-attachements li,.wpas-reply-attachements ul{list-style:none;margin:0;padding:0}.wpas-attachment-container{background-color:#FFFFED;padding:1.5em;margin:1.5em 0;border:1px solid #ddd}.wpas-attachment-container label{display:block}.wpas-attachment-container p{margin:0}@media screen and (max-width:782px){.wpas-table-replies tr>td.col1{display:none}.wpas-table-replies tr.wpas-ticket-history>td{line-height:1.6}.wpas-reply-meta .wpas-reply-time,.wpas-reply-meta .wpas-reply-user{float:none;clear:both}.wpas-human-date,.wpas-profilerole,.wpas-ticket-controls{opacity:1}.wpas-ticket-controls{position:static;top:0;text-align:right}}
  • awesome-support/trunk/assets/admin/less/admin.less

    r1049994 r1072407  
    2929    font-weight: bold;
    3030    color: #fff;
    31     white-space: nowrap;
    3231    vertical-align: baseline;
    3332    background-color: #999;
    3433    border-radius: 3px;
     34}
     35.wpas-label + .wpas-label {
     36    margin-top: 5px;
    3537}
    3638.wpas-lead {
  • awesome-support/trunk/assets/public/css/public.css

    r1048776 r1072407  
    1 @charset 'UTF-8';.wpas *,.wpas *:before,.wpas *:after{box-sizing:border-box}.wpas-table{width:100%;max-width:100%;text-align:left}.wpas-human-date{opacity:0}.wpas-reply-attachements{border-top:1px solid}.wpas-reply-new textarea{width:100%}.mce-toolbar .mce-btn button:hover{background:inherit;border:inherit;color:#333;padding:2px 3px}.wpas-alert{padding:15px;margin-bottom:20px;border:1px solid transparent}.wpas-alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.wpas-alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.wpas-alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.wpas-alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}
     1@charset 'UTF-8';.wpas *,.wpas :after,.wpas :before{-moz-box-sizing:border-box;box-sizing:border-box}.wpas-table{width:100%;max-width:100%;text-align:left}.wpas-human-date{display:none}.wpas-reply-attachements{border-top:1px solid}.wpas-reply-new textarea{width:100%}.mce-toolbar .mce-btn button:hover{background:inherit;color:#333;padding:2px 3px}.wpas-alert{padding:15px;margin-bottom:20px;border:1px solid transparent}.wpas-alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.wpas-alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.wpas-alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.wpas-alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.featherlight .featherlight-inner{max-width:800px;padding:15px}.featherlight .featherlight-close-icon{text-indent:-9999em;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTFH80I3AAABIklEQVQ4T62T20oDQRBE+9EIGo1/H4gEQd8E74lJvKHiV+mmai7QNdu+ZFNwWKqmpzJhdq3rur0ShkMIwyGoMTsEl+AenDDw62WGmoAFOAcjWRdjdgX+Ck9gDPw6xbIN4MwvmEmHmFzCQRo+H0E6aRHL1sDP3EiHmLx5WQbrBv4Ic3+yuvYAxtIhJusUtKUf4LvJUhnQDm9SkNWe1MPsDhyD/v42SGEWT/oFfBl5BWFZ2huGWWfgB/gy8g7CVyrt7QVZLHsB//1lvoNhqZqstozPN/DZZPX2tUNMXFYvILr9dFLpEGO2KoNtWRVLezPSIcbsogyRWyC3WcTSZ8AZfnpT6RCDDx3MwTU4YuDXywzFUn6WU3Ag697sgzAcQhjuTmdbpLYNJt1Fr50AAAAASUVORK5CYII=) 50% 50% no-repeat;display:block;height:25px;width:25px}@media all{.featherlight{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:2;text-align:center;white-space:nowrap;cursor:pointer;background:0 0}.featherlight:last-of-type{background:rgba(0,0,0,.8)}.featherlight:before{content:'';display:inline-block;height:100%;vertical-align:middle;margin-right:-.25em}.featherlight .featherlight-content{position:relative;text-align:left;vertical-align:middle;display:inline-block;overflow:auto;padding:25px 25px 0;border-bottom:25px solid transparent;min-width:30%;margin-left:5%;margin-right:5%;max-height:95%;background:#fff;cursor:auto;white-space:normal}.featherlight .featherlight-inner{display:block}.featherlight .featherlight-close-icon{position:absolute;z-index:9999;top:0;right:0;line-height:25px;width:25px;cursor:pointer;text-align:center;font:Arial,sans-serif;background:#fff;background:rgba(255,255,255,.3);color:#000}.featherlight .featherlight-image{width:100%}.featherlight-iframe .featherlight-content{border-bottom:0;padding:0}.featherlight iframe{border:0}}@media only screen and (max-width:1024px){.featherlight .featherlight-content{margin-left:10px;margin-right:10px;max-height:98%;padding:10px 10px 0;border-bottom:10px solid transparent}}
  • awesome-support/trunk/assets/public/js/public-dist.js

    r1049994 r1072407  
    1 /**
    2  * Featherlight - ultra slim jQuery lightbox
    3  * Version 1.0.3 - http://noelboss.github.io/featherlight/
    4  *
    5  * Copyright 2014, Noël Raoul Bossart (http://www.noelboss.com)
    6  * MIT Licensed.
    7 **/
    8 !function(a){"use strict";function b(a,c){if(!(this instanceof b)){var d=new b(a,c);return d.open(),d}this.id=b.id++,this.setup(a,c),this.chainCallbacks(b._callbackChain)}if("undefined"==typeof a)return void("console"in window&&window.console.info("Too much lightness, Featherlight needs jQuery."));var c=function(a){if(!a.isDefaultPrevented()){var c=b.current();c&&c.onKeyDown(a)}};b.prototype={constructor:b,namespace:"featherlight",targetAttr:"data-featherlight",variant:null,resetCss:!1,background:null,openTrigger:"click",closeTrigger:"click",filter:null,root:"body",openSpeed:250,closeSpeed:250,closeOnClick:"background",closeOnEsc:!0,closeIcon:"&#10005;",otherClose:null,beforeOpen:a.noop,beforeContent:a.noop,beforeClose:a.noop,afterOpen:a.noop,afterContent:a.noop,afterClose:a.noop,onKeyDown:a.noop,type:null,contentFilters:["jquery","image","html","ajax","text"],setup:function(b,c){"object"!=typeof b||b instanceof a!=!1||c||(c=b,b=void 0);var d=a.extend(this,c,{target:b}),e=d.resetCss?d.namespace+"-reset":d.namespace,f=a(d.background||['<div class="'+e+'">','<div class="'+e+'-content">','<span class="'+e+"-close-icon "+d.namespace+'-close">',d.closeIcon,"</span>",'<div class="'+d.namespace+'-inner"></div>',"</div>","</div>"].join("")),g="."+d.namespace+"-close"+(d.otherClose?","+d.otherClose:"");return d.$instance=f.clone().addClass(d.variant),d.$instance.on(d.closeTrigger+"."+d.namespace,function(b){var c=a(b.target);("background"===d.closeOnClick&&c.is("."+d.namespace)||"anywhere"===d.closeOnClick||c.is(g))&&(b.preventDefault(),d.close())}),this},getContent:function(){var b=this,c=this.constructor.contentFilters,d=function(a){return b.$currentTarget&&b.$currentTarget.attr(a)},e=d(b.targetAttr),f=b.target||e||"",g=c[b.type];if(!g&&f in c&&(g=c[f],f=b.target&&e),f=f||d("href")||"",!g)for(var h in c)b[h]&&(g=c[h],f=b[h]);if(!g){var i=f;if(f=null,a.each(b.contentFilters,function(){return g=c[this],g.test&&(f=g.test(i)),!f&&g.regex&&i.match&&i.match(g.regex)&&(f=i),!f}),!f)return"console"in window&&window.console.error("Featherlight: no content filter found "+(i?' for "'+i+'"':" (no target specified)")),!1}return g.process.call(b,f)},setContent:function(b){var c=this;return(b.is("iframe")||a("iframe",b).length>0)&&c.$instance.addClass(c.namespace+"-iframe"),c.$content=b.addClass(c.namespace+"-inner"),c.$instance.find("."+c.namespace+"-inner").slice(1).remove().end().replaceWith(c.$content),c},open:function(d){var e=this;if(!(d&&d.isDefaultPrevented()||e.beforeOpen(d)===!1)){d&&d.preventDefault();var f=e.getContent();if(f)return e.constructor._opened.add(e._openedCallback=function(a,b){e instanceof a&&e.$instance.closest("body").length>0&&(b.currentFeatherlight=e)}),b._keyHandlerInstalled||(a(document).on("keyup."+b.prototype.namespace,c),b._keyHandlerInstalled=!0),e.$instance.appendTo(e.root).fadeIn(e.openSpeed),e.beforeContent(d),a.when(f).done(function(b){e.setContent(b),e.afterContent(d),a.when(e.$instance.promise()).done(function(){e.afterOpen(d)})}),e}return!1},close:function(d){var e=this;return e.beforeClose(d)===!1?!1:(e.constructor._opened.remove(e._openedCallback),b.current()||(a(document).off("keyup."+b.namespace,c),e.constructor._keyHandlerInstalled=!1),void e.$instance.fadeOut(e.closeSpeed,function(){e.$instance.detach(),e.afterClose(d)}))},chainCallbacks:function(b){for(var c in b)this[c]=a.proxy(b[c],this,a.proxy(this[c],this))}},a.extend(b,{id:0,autoBind:"[data-featherlight]",defaults:b.prototype,contentFilters:{jquery:{regex:/^[#.]\w/,test:function(b){return b instanceof a&&b},process:function(b){return a(b).clone(!0)}},image:{regex:/\.(png|jpg|jpeg|gif|tiff|bmp)(\?\S*)?$/i,process:function(b){var c=this,d=a.Deferred(),e=new Image;return e.onload=function(){d.resolve(a('<img src="'+b+'" alt="" class="'+c.namespace+'-image" />'))},e.onerror=function(){d.reject()},e.src=b,d.promise()}},html:{regex:/^\s*<[\w!][^<]*>/,process:function(b){return a(b)}},ajax:{regex:/./,process:function(b){var c=a.Deferred(),d=a("<div></div>").load(b,function(a,b){"error"!==b&&c.resolve(d.contents()),c.fail()});return c.promise()}},text:{process:function(b){return a("<div>",{text:b})}}},functionAttributes:["beforeOpen","afterOpen","beforeContent","afterContent","beforeClose","afterClose"],readElementConfig:function(b){var c=this,d={};return b&&b.attributes&&a.each(b.attributes,function(){var b=this.name.match(/^data-featherlight-(.*)/);if(b){var e=this.value,f=a.camelCase(b[1]);if(a.inArray(f,c.functionAttributes)>=0)e=new Function(e);else try{e=a.parseJSON(e)}catch(g){}d[f]=e}}),d},extend:function(b,c){var d=function(){this.constructor=b};return d.prototype=this.prototype,b.prototype=new d,b.__super__=this.prototype,a.extend(b,this,c),b.defaults=b.prototype,b},attach:function(b,c,d){var e=this;"object"!=typeof c||c instanceof a!=!1||d||(d=c,c=void 0),d=a.extend({},d);var f=a.extend({},e.defaults,e.readElementConfig(b[0]),d);return b.on(f.openTrigger+"."+f.namespace,f.filter,function(f){var g=a.extend({$source:b,$currentTarget:a(this)},e.readElementConfig(b[0]),e.readElementConfig(this),d);new e(c,g).open(f)}),b},current:function(){var a={};return this._opened.fire(this,a),a.currentFeatherlight},close:function(){var a=this.current();a&&a.close()},_onReady:function(){var b=this;b.autoBind&&(b.attach(a(document),{filter:b.autoBind}),a(b.autoBind).filter("[data-featherlight-filter]").each(function(){b.attach(a(this))}))},_callbackChain:{onKeyDown:function(a,b){return 27===b.keyCode&&this.closeOnEsc?(this.$instance.find("."+this.namespace+"-close:first").click(),void b.preventDefault()):(console.log("pass"),a(b))}},_opened:a.Callbacks()}),a.featherlight=b,a.fn.featherlight=function(a,c){return b.attach(this,a,c)},a(document).ready(function(){b._onReady()})}(jQuery);!function(t){"use strict";t(function(){t(".wpas-form").submit("undefined"!=typeof tinyMCE?function(){var i=t('[type="submit"]',t(this)),e=tinyMCE.activeEditor.getContent();return""===e||null===e?(t(tinyMCE.activeEditor.getBody()).css("background-color","#ffeeee"),alert("You can't submit an empty ticket reply."),t(tinyMCE.activeEditor.getBody()).css("background-color",""),tinyMCE.activeEditor.focus(),!1):void i.prop("disabled",!0).text(i.data("onsubmit"))}:function(){var i=t('[type="submit"]',t(this));i.prop("disabled",!0).text(i.data("onsubmit"))}),t(".wpas-modal-trigger").featherlight()})}(jQuery);
     1!function(a){"use strict";function b(a,c){if(!(this instanceof b)){var d=new b(a,c);return d.open(),d}this.id=b.id++,this.setup(a,c),this.chainCallbacks(b._callbackChain)}if("undefined"==typeof a)return void("console"in window&&window.console.info("Too much lightness, Featherlight needs jQuery."));var c=function(a){if(!a.isDefaultPrevented()){var c=b.current();c&&c.onKeyDown(a)}};b.prototype={constructor:b,namespace:"featherlight",targetAttr:"data-featherlight",variant:null,resetCss:!1,background:null,openTrigger:"click",closeTrigger:"click",filter:null,root:"body",openSpeed:250,closeSpeed:250,closeOnClick:"background",closeOnEsc:!0,closeIcon:"&#10005;",otherClose:null,beforeOpen:a.noop,beforeContent:a.noop,beforeClose:a.noop,afterOpen:a.noop,afterContent:a.noop,afterClose:a.noop,onKeyDown:a.noop,type:null,contentFilters:["jquery","image","html","ajax","text"],setup:function(b,c){"object"!=typeof b||b instanceof a!=0||c||(c=b,b=void 0);var d=a.extend(this,c,{target:b}),e=d.resetCss?d.namespace+"-reset":d.namespace,f=a(d.background||['<div class="'+e+'">','<div class="'+e+'-content">','<span class="'+e+"-close-icon "+d.namespace+'-close">',d.closeIcon,"</span>",'<div class="'+d.namespace+'-inner"></div>',"</div>","</div>"].join("")),g="."+d.namespace+"-close"+(d.otherClose?","+d.otherClose:"");return d.$instance=f.clone().addClass(d.variant),d.$instance.on(d.closeTrigger+"."+d.namespace,function(b){var c=a(b.target);("background"===d.closeOnClick&&c.is("."+d.namespace)||"anywhere"===d.closeOnClick||c.is(g))&&(b.preventDefault(),d.close())}),this},getContent:function(){var b=this,c=this.constructor.contentFilters,d=function(a){return b.$currentTarget&&b.$currentTarget.attr(a)},e=d(b.targetAttr),f=b.target||e||"",g=c[b.type];if(!g&&f in c&&(g=c[f],f=b.target&&e),f=f||d("href")||"",!g)for(var h in c)b[h]&&(g=c[h],f=b[h]);if(!g){var i=f;if(f=null,a.each(b.contentFilters,function(){return g=c[this],g.test&&(f=g.test(i)),!f&&g.regex&&i.match&&i.match(g.regex)&&(f=i),!f}),!f)return"console"in window&&window.console.error("Featherlight: no content filter found "+(i?' for "'+i+'"':" (no target specified)")),!1}return g.process.call(b,f)},setContent:function(b){var c=this;return(b.is("iframe")||a("iframe",b).length>0)&&c.$instance.addClass(c.namespace+"-iframe"),c.$content=b.addClass(c.namespace+"-inner"),c.$instance.find("."+c.namespace+"-inner").slice(1).remove().end().replaceWith(c.$content),c},open:function(d){var e=this;if(!(d&&d.isDefaultPrevented()||e.beforeOpen(d)===!1)){d&&d.preventDefault();var f=e.getContent();if(f)return e.constructor._opened.add(e._openedCallback=function(a,b){e instanceof a&&e.$instance.closest("body").length>0&&(b.currentFeatherlight=e)}),b._keyHandlerInstalled||(a(document).on("keyup."+b.prototype.namespace,c),b._keyHandlerInstalled=!0),e.$instance.appendTo(e.root).fadeIn(e.openSpeed),e.beforeContent(d),a.when(f).done(function(b){e.setContent(b),e.afterContent(d),a.when(e.$instance.promise()).done(function(){e.afterOpen(d)})}),e}return!1},close:function(d){var e=this;return e.beforeClose(d)===!1?!1:(e.constructor._opened.remove(e._openedCallback),b.current()||(a(document).off("keyup."+b.namespace,c),e.constructor._keyHandlerInstalled=!1),void e.$instance.fadeOut(e.closeSpeed,function(){e.$instance.detach(),e.afterClose(d)}))},chainCallbacks:function(b){for(var c in b)this[c]=a.proxy(b[c],this,a.proxy(this[c],this))}},a.extend(b,{id:0,autoBind:"[data-featherlight]",defaults:b.prototype,contentFilters:{jquery:{regex:/^[#.]\w/,test:function(b){return b instanceof a&&b},process:function(b){return a(b).clone(!0)}},image:{regex:/\.(png|jpg|jpeg|gif|tiff|bmp)(\?\S*)?$/i,process:function(b){var c=this,d=a.Deferred(),e=new Image;return e.onload=function(){d.resolve(a('<img src="'+b+'" alt="" class="'+c.namespace+'-image" />'))},e.onerror=function(){d.reject()},e.src=b,d.promise()}},html:{regex:/^\s*<[\w!][^<]*>/,process:function(b){return a(b)}},ajax:{regex:/./,process:function(b){var c=a.Deferred(),d=a("<div></div>").load(b,function(a,b){"error"!==b&&c.resolve(d.contents()),c.fail()});return c.promise()}},text:{process:function(b){return a("<div>",{text:b})}}},functionAttributes:["beforeOpen","afterOpen","beforeContent","afterContent","beforeClose","afterClose"],readElementConfig:function(b){var c=this,d={};return b&&b.attributes&&a.each(b.attributes,function(){var b=this.name.match(/^data-featherlight-(.*)/);if(b){var e=this.value,f=a.camelCase(b[1]);if(a.inArray(f,c.functionAttributes)>=0)e=new Function(e);else try{e=a.parseJSON(e)}catch(g){}d[f]=e}}),d},extend:function(b,c){var d=function(){this.constructor=b};return d.prototype=this.prototype,b.prototype=new d,b.__super__=this.prototype,a.extend(b,this,c),b.defaults=b.prototype,b},attach:function(b,c,d){var e=this;"object"!=typeof c||c instanceof a!=0||d||(d=c,c=void 0),d=a.extend({},d);var f=a.extend({},e.defaults,e.readElementConfig(b[0]),d);return b.on(f.openTrigger+"."+f.namespace,f.filter,function(f){var g=a.extend({$source:b,$currentTarget:a(this)},e.readElementConfig(b[0]),e.readElementConfig(this),d);new e(c,g).open(f)}),b},current:function(){var a={};return this._opened.fire(this,a),a.currentFeatherlight},close:function(){var a=this.current();a&&a.close()},_onReady:function(){var b=this;b.autoBind&&(b.attach(a(document),{filter:b.autoBind}),a(b.autoBind).filter("[data-featherlight-filter]").each(function(){b.attach(a(this))}))},_callbackChain:{onKeyDown:function(a,b){return 27===b.keyCode&&this.closeOnEsc?(this.$instance.find("."+this.namespace+"-close:first").click(),void b.preventDefault()):(console.log("pass"),a(b))}},_opened:a.Callbacks()}),a.featherlight=b,a.fn.featherlight=function(a,c){return b.attach(this,a,c)},a(document).ready(function(){b._onReady()})}(jQuery),!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],a):a(b.jQuery)}(function(a,b){function c(b,c){this.element=a(b),this.wrapperElement=a(),this.toggleElement=a(),this.init(c)}var d="plugin_hideShowPassword",e=["show","innerToggle"],f=32,g=13,h=function(){var a=document.body,b=document.createElement("input"),c=!0;a||(a=document.createElement("body")),b=a.appendChild(b);try{b.setAttribute("type","text")}catch(d){c=!1}return a.removeChild(b),c}(),i={show:"infer",innerToggle:!1,enable:h,className:"hideShowPassword-field",initEvent:"hideShowPasswordInit",changeEvent:"passwordVisibilityChange",props:{autocapitalize:"off",autocomplete:"off",autocorrect:"off",spellcheck:"false"},toggle:{element:'<button type="button">',className:"hideShowPassword-toggle",touchSupport:"undefined"==typeof Modernizr?!1:Modernizr.touch,attachToEvent:"click",attachToTouchEvent:"touchstart mousedown",attachToKeyEvent:"keyup",attachToKeyCodes:!0,styles:{position:"absolute"},touchStyles:{pointerEvents:"none"},position:"infer",verticalAlign:"middle",offset:0,attr:{role:"button","aria-label":"Show Password",tabIndex:0}},wrapper:{element:"<div>",className:"hideShowPassword-wrapper",enforceWidth:!0,styles:{position:"relative"},inheritStyles:["display","verticalAlign","marginTop","marginRight","marginBottom","marginLeft"],innerElementStyles:{marginTop:0,marginRight:0,marginBottom:0,marginLeft:0}},states:{shown:{className:"hideShowPassword-shown",changeEvent:"passwordShown",props:{type:"text"},toggle:{className:"hideShowPassword-toggle-hide",content:"Hide",attr:{"aria-pressed":"true"}}},hidden:{className:"hideShowPassword-hidden",changeEvent:"passwordHidden",props:{type:"password"},toggle:{className:"hideShowPassword-toggle-show",content:"Show",attr:{"aria-pressed":"false"}}}}};c.prototype={init:function(b){this.update(b,i)&&(this.element.addClass(this.options.className),this.options.innerToggle&&(this.wrapElement(this.options.wrapper),this.initToggle(this.options.toggle),"string"==typeof this.options.innerToggle&&(this.toggleElement.hide(),this.element.one(this.options.innerToggle,a.proxy(function(){this.toggleElement.show()},this)))),this.element.trigger(this.options.initEvent,[this]))},update:function(a,b){return this.options=this.prepareOptions(a,b),this.updateElement()&&this.element.trigger(this.options.changeEvent,[this]).trigger(this.state().changeEvent,[this]),this.options.enable},toggle:function(a){return a=a||"toggle",this.update({show:a})},prepareOptions:function(b,c){var d,e=[];if(c=c||this.options,b=a.extend(!0,{},c,b),b.enable&&("toggle"===b.show?b.show=this.isType("hidden",b.states):"infer"===b.show&&(b.show=this.isType("shown",b.states)),"infer"===b.toggle.position&&(b.toggle.position="rtl"===this.element.css("text-direction")?"left":"right"),!a.isArray(b.toggle.attachToKeyCodes))){if(b.toggle.attachToKeyCodes===!0)switch(d=a(b.toggle.element),d.prop("tagName").toLowerCase()){case"button":case"input":break;case"a":if(d.filter("[href]").length){e.push(f);break}default:e.push(f,g)}b.toggle.attachToKeyCodes=e}return b},updateElement:function(){return!this.options.enable||this.isType()?!1:(this.element.prop(a.extend({},this.options.props,this.state().props)).addClass(this.state().className).removeClass(this.otherState().className),this.updateToggle(),!0)},isType:function(a,c){return c=c||this.options.states,a=a||this.state(b,b,c).props.type,c[a]&&(a=c[a].props.type),this.element.prop("type")===a},state:function(a,c,d){return d=d||this.options.states,a===b&&(a=this.options.show),"boolean"==typeof a&&(a=a?"shown":"hidden"),c&&(a="shown"===a?"hidden":"shown"),d[a]},otherState:function(a){return this.state(a,!0)},wrapElement:function(b){var c,d=b.enforceWidth;return this.wrapperElement.length||(c=this.element.outerWidth(),a.each(b.inheritStyles,a.proxy(function(a,c){b.styles[c]=this.element.css(c)},this)),this.element.css(b.innerElementStyles).wrap(a(b.element).addClass(b.className).css(b.styles)),this.wrapperElement=this.element.parent(),d===!0&&(d=this.wrapperElement.outerWidth()===c?!1:c),d!==!1&&this.wrapperElement.css("width",d)),this.wrapperElement},initToggle:function(b){return this.toggleElement.length||(this.toggleElement=a(b.element).attr(b.attr).addClass(b.className).css(b.styles).appendTo(this.wrapperElement),this.updateToggle(),this.positionToggle(b.position,b.verticalAlign,b.offset),b.touchSupport?(this.toggleElement.css(b.touchStyles),this.element.on(b.attachToTouchEvent,a.proxy(this.toggleTouchEvent,this))):this.toggleElement.on(b.attachToEvent,a.proxy(this.toggleEvent,this)),b.attachToKeyCodes.length&&this.toggleElement.on(b.attachToKeyEvent,a.proxy(this.toggleKeyEvent,this))),this.toggleElement},positionToggle:function(a,b,c){var d={};switch(d[a]=c,b){case"top":case"bottom":d[b]=c;break;case"middle":d.top="50%",d.marginTop=this.toggleElement.outerHeight()/-2}return this.toggleElement.css(d)},updateToggle:function(a,b){var c,d;return this.toggleElement.length&&(c="padding-"+this.options.toggle.position,a=a||this.state().toggle,b=b||this.otherState().toggle,this.toggleElement.attr(a.attr).addClass(a.className).removeClass(b.className).html(a.content),d=this.toggleElement.outerWidth()+2*this.options.toggle.offset,this.element.css(c)!==d&&this.element.css(c,d)),this.toggleElement},toggleEvent:function(a){a.preventDefault(),this.toggle()},toggleKeyEvent:function(b){a.each(this.options.toggle.attachToKeyCodes,a.proxy(function(a,c){return b.which===c?(this.toggleEvent(b),!1):void 0},this))},toggleTouchEvent:function(a){var b,c,d,e=this.toggleElement.offset().left;e&&(b=a.pageX||a.originalEvent.pageX,"left"===this.options.toggle.position?(e+=this.toggleElement.outerWidth(),c=b,d=e):(c=e,d=b),d>=c&&this.toggleEvent(a))}},a.fn.hideShowPassword=function(){var b={};return a.each(arguments,function(c,d){var f={};if("object"==typeof d)f=d;else{if(!e[c])return!1;f[e[c]]=d}a.extend(!0,b,f)}),this.each(function(){var e=a(this),f=e.data(d);f?f.update(b):e.data(d,new c(this,b))})},a.each({show:!0,hide:!1,toggle:"toggle"},function(b,c){a.fn[b+"Password"]=function(a,b){return this.hideShowPassword(c,a,b)}})},this),function(a){"use strict";function b(a){return"true"===(a+"").toLowerCase()}a(function(){if(a(".wpas-form").submit("undefined"!=typeof tinyMCE?function(){var b=a('[type="submit"]',a(this)),c=tinyMCE.activeEditor.getContent();return""===c||null===c?(a(tinyMCE.activeEditor.getBody()).css("background-color","#ffeeee"),alert("You can't submit an empty ticket reply."),a(tinyMCE.activeEditor.getBody()).css("background-color",""),tinyMCE.activeEditor.focus(),!1):void b.prop("disabled",!0).text(b.data("onsubmit"))}:function(){var b=a('[type="submit"]',a(this));b.prop("disabled",!0).text(b.data("onsubmit"))}),a(".wpas-modal-trigger").featherlight(),a('input[name="pwdshow"]').change(function(){a("#password").hideShowPassword(a(this).prop("checked"))}),"undefined"!=typeof wpas&&b(wpas.emailCheck)){var c=a('input[name="email"]'),d=a("#email-validation");c.change(function(){var b={action:"email_validation",email:c.val()};a.post(wpas.ajaxurl,b,function(a){d.html(a).show()})}),d.on("click","strong",function(){c.val(a(this).html()),d.hide()})}})}(jQuery);
  • awesome-support/trunk/assets/public/js/public.js

    r1049994 r1072407  
    11//@prepros-prepend ../vendor/featherlight/featherlight.min.js
     2//@prepros-prepend ../vendor/hideShowPassword/hideShowPassword.js
    23
    34(function ($) {
    45    "use strict";
     6
     7    /*
     8    Convert string to Boolean
     9    http://stackoverflow.com/a/21445227
     10     */
     11    function stringToBool(val) {
     12        return (val + '').toLowerCase() === 'true';
     13    }
    514
    615    $(function () {
     
    918        Check if TinyMCE is empty
    1019        http://codeblow.com/questions/method-to-check-whether-tinymce-is-active-in-wordpress/
     20        http://stackoverflow.com/a/8749616
    1121         */
    1222        if (typeof tinyMCE != "undefined") {
     
    4353
    4454        /*
    45         Modal used on registration form (terms and conditions)
     55        Registration form: terms and conditions modal
     56        https://github.com/noelboss/featherlight/
    4657         */
    4758        $('.wpas-modal-trigger').featherlight();
     59
     60        /*
     61        Registration form: toggle password visibility
     62        https://github.com/cloudfour/hideShowPassword
     63         */
     64        $('input[name="pwdshow"]').change(function () {
     65            $('#password').hideShowPassword($(this).prop('checked'));
     66        });
     67
     68        /*
     69        Registration form: email validation by MailGun
     70        http://www.mailgun.com/email-validation
     71        http://documentation.mailgun.com/api-email-validation.html
     72         */
     73        if (typeof wpas !== 'undefined' && stringToBool(wpas.emailCheck)) {
     74            var emailInput = $('input[name="email"]'),
     75                emailCheck = $('#email-validation');
     76
     77            emailInput.change(function () {
     78                var data = {
     79                    'action': 'email_validation',
     80                    'email': emailInput.val()
     81                };
     82                $.post(wpas.ajaxurl, data, function (response) {
     83                    emailCheck.html(response).show();
     84                });
     85            });
     86
     87            emailCheck.on('click', 'strong', function () {
     88                emailInput.val($(this).html());
     89                emailCheck.hide();
     90            });
     91        }
    4892
    4993    });
  • awesome-support/trunk/awesome-support.php

    r1049994 r1072407  
    1111 * Plugin URI:        http://getawesomesupport.com
    1212 * Description:       Awesome Support is a great ticketing system that will help you improve your customer satisfaction by providing a unique customer support experience.
    13  * Version:           3.0.1
     13 * Version:           3.1.0
    1414 * Author:            ThemeAvenue
    1515 * Author URI:        http://themeavenue.net
     
    2929 *----------------------------------------------------------------------------*/
    3030
    31 define( 'WPAS_VERSION',           '3.0.1' );
     31define( 'WPAS_VERSION',           '3.1.0' );
    3232define( 'WPAS_DB_VERSION',        '1' );
    3333define( 'WPAS_URL',               trailingslashit( plugin_dir_url( __FILE__ ) ) );
     
    4848
    4949require_once( WPAS_PATH . 'includes/functions-fallback.php' );
    50 require_once( plugin_dir_path( __FILE__ ) . 'class-awesome-support.php' );
     50require_once( WPAS_PATH . 'includes/class-logger.php' );
     51require_once( WPAS_PATH . 'class-awesome-support.php' );
    5152
    5253/**
     
    7071require_once( WPAS_PATH . 'includes/addons/custom-fields/class-custom-fields.php' );
    7172require_once( WPAS_PATH . 'includes/addons/file-uploader/class-file-uploader.php' );
     73require_once( WPAS_PATH . 'includes/addons/class-mailgun-email-check.php' );
    7274
    7375/**
     
    8587require_once( WPAS_PATH . 'includes/functions-templating.php' );      // Templating function
    8688require_once( WPAS_PATH . 'includes/class-post-type.php' );           // Register post types and related functions
     89require_once( WPAS_PATH . 'includes/class-product-sync.php' );        // Keep the product taxonomy in sync with e-commerce products
     90
     91/**
     92 * Check if dependencies are loaded.
     93 *
     94 * The plugin uses a certain number of dependencies managed through Composer.
     95 * If those dependencies are not loaded the plugin won't work.
     96 *
     97 * In order to avoid errors we check if dependencies are present. If not we simply
     98 * don't load the plugin.
     99 *
     100 * This problem won't happen with the production version as we have scripts
     101 * doing all the work, but on the development verison this can be a problem.
     102 *
     103 * @since  3.0.2
     104 */
     105if ( !Awesome_Support::dependencies_loaded() ) {
     106    add_action( 'admin_notices', 'wpas_missing_dependencied' );
     107}
    87108
    88109/*----------------------------------------------------------------------------*
    89110 * Public-Facing Only Functionality
    90111 *----------------------------------------------------------------------------*/
    91 if( !is_admin() ) {
     112if( !is_admin() && Awesome_Support::dependencies_loaded() ) {
    92113    require_once( WPAS_PATH . 'includes/class-notification.php' ); // Load notifications class
    93114    require_once( WPAS_PATH . 'includes/shortcodes/shortcode-tickets.php' ); // The plugin main shortcodes
     
    102123 * The code below is intended to to give the lightest footprint possible.
    103124 */
    104 if ( is_admin() ) {
     125if ( is_admin() && Awesome_Support::dependencies_loaded() ) {
    105126
    106127    /* Load main admin class */
     
    108129    add_action( 'plugins_loaded', array( 'Awesome_Support_Admin', 'get_instance' ) );
    109130
     131    /* Load the MailGun e-mail check settings */
     132    add_filter( 'wpas_plugin_settings', array( 'WPAS_MailGun_EMail_Check', 'settings' ), 10, 1 );
     133
    110134}
     135
     136/*----------------------------------------------------------------------------*
     137 * Integrations
     138 *----------------------------------------------------------------------------*/
     139require_once( WPAS_PATH . 'includes/integrations/loader.php' );
    111140
    112141/**
  • awesome-support/trunk/class-awesome-support.php

    r1049994 r1072407  
    3131    private function __construct() {
    3232
    33         add_action( 'plugins_loaded',                 array( 'WPAS_Ticket_Post_Type', 'get_instance' ), 11 );
    34         add_action( 'pre_user_query',                 'wpas_randomize_uers_query' );                  // Alter the user query to randomize the results
    35         add_action( 'wp',                             array( $this, 'get_replies_object' ) );         // Generate the object used for the custom loop for displaying ticket replies
    36         add_action( 'wpmu_new_blog',                  array( $this, 'activate_new_site' ) );          // Activate plugin when new blog is added
    37         add_action( 'init',                           array( $this, 'load_plugin_textdomain' ) );     // Load the plugin textdomain
    38         add_action( 'init',                           array( $this, 'init' ), 10, 0 );                // Register main post type
    39         add_action( 'admin_bar_menu',                 array( $this, 'toolbar_tickets_link' ), 999 );  // Add a link to agent's tickets in the toolbar
    40         add_action( 'wp_print_styles',                array( $this, 'enqueue_styles' ) );             // Load public-facing style sheets
    41         add_action( 'wp_print_scripts',               array( $this, 'enqueue_scripts' ) );            // Load public-facing JavaScripts
    42         add_action( 'template_redirect',              array( $this, 'redirect_archive' ) );
    43         add_action( 'wpas_after_registration_fields', array( $this, 'terms_and_conditions_checkbox' ), 10, 3 );// Load the terms and conditions in a hidden div in the footer
    44         add_action( 'wpas_after_template',            array( $this, 'terms_and_conditions_modal' ), 10, 3 );// Load the terms and conditions in a hidden div in the footer
    45         add_filter( 'template_include',               array( $this, 'template_include' ), 10, 1 );
    46 
    47         /* Hook all e-mail notifications */
    48         add_action( 'wpas_open_ticket_after',  array( $this, 'notify_confirmation' ), 10, 2 );
    49         add_action( 'wpas_add_reply_after',    array( $this, 'notify_reply' ), 10, 2 );
    50         add_action( 'wpas_after_close_ticket', array( $this, 'notify_close' ), 10, 1 );
    51 
    52         /**
    53          * Modify the ticket single page content.
    54          *
    55          * wpas_single_ticket() is located in includes/functions-templating.php
    56          *
    57          * @since  3.0.0
    58          */
    59         add_filter( 'the_content', 'wpas_single_ticket', 10, 1 );
     33        /* Ajax actions */
     34        add_action( 'wp_ajax_nopriv_email_validation', array( $this, 'mailgun_check' ) );
     35
     36        if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
     37
     38            add_action( 'plugins_loaded',                 array( 'WPAS_Ticket_Post_Type', 'get_instance' ), 11 );
     39            add_action( 'pre_user_query',                 'wpas_randomize_uers_query' );                  // Alter the user query to randomize the results
     40            add_action( 'wp',                             array( $this, 'get_replies_object' ) );         // Generate the object used for the custom loop for displaying ticket replies
     41            add_action( 'wpmu_new_blog',                  array( $this, 'activate_new_site' ) );          // Activate plugin when new blog is added
     42            add_action( 'init',                           array( $this, 'load_plugin_textdomain' ) );     // Load the plugin textdomain
     43            add_action( 'init',                           array( $this, 'init' ), 11, 0 );                // Register main post type
     44            add_action( 'admin_bar_menu',                 array( $this, 'toolbar_tickets_link' ), 999 );  // Add a link to agent's tickets in the toolbar
     45            add_action( 'wp_print_styles',                array( $this, 'enqueue_styles' ) );             // Load public-facing style sheets
     46            add_action( 'wp_print_scripts',               array( $this, 'enqueue_scripts' ) );            // Load public-facing JavaScripts
     47            add_action( 'template_redirect',              array( $this, 'redirect_archive' ) );
     48            add_action( 'wpas_after_registration_fields', array( $this, 'terms_and_conditions_checkbox' ), 10, 3 );// Load the terms and conditions in a hidden div in the footer
     49            add_action( 'wpas_after_template',            array( $this, 'terms_and_conditions_modal' ), 10, 3 );// Load the terms and conditions in a hidden div in the footer
     50            add_filter( 'template_include',               array( $this, 'template_include' ), 10, 1 );
     51            add_filter( 'wpas_logs_handles',              array( $this, 'default_log_handles' ), 10, 1 );
     52            add_filter( 'authenticate',                   array( $this, 'email_signon' ), 20, 3 );
     53
     54            /* Hook all e-mail notifications */
     55            add_action( 'wpas_open_ticket_after',  array( $this, 'notify_confirmation' ), 10, 2 );
     56            add_action( 'wpas_add_reply_after',    array( $this, 'notify_reply' ), 10, 2 );
     57            add_action( 'wpas_after_close_ticket', array( $this, 'notify_close' ), 10, 1 );
     58
     59            /**
     60             * Modify the ticket single page content.
     61             *
     62             * wpas_single_ticket() is located in includes/functions-templating.php
     63             *
     64             * @since  3.0.0
     65             */
     66            add_filter( 'the_content', 'wpas_single_ticket', 10, 1 );
     67
     68        }
     69    }
     70
     71    /**
     72     * Check if plugin dependencies are present.
     73     *
     74     * @since  3.0.2
     75     * @return boolean True of dependencies are here, false otherwise
     76     */
     77    public static function dependencies_loaded() {
     78
     79        if ( !is_dir( WPAS_PATH . 'vendor' ) ) {
     80            return false;
     81        }
     82
     83        return true;
     84
    6085    }
    6186
     
    194219            /* Possibly close the ticket */
    195220            if ( isset( $_POST['wpas_close_ticket'] ) && false !== $reply_id ) {
    196                 update_post_meta( intval( $_POST['ticket_id'] ), '_wpas_status', 'closed', 'open' );
    197                 wpas_log( intval( $_POST['ticket_id'] ), __( 'The ticket was closed.', 'wpas' ) );
    198                 do_action( 'wpas_after_close_ticket', intval( $_POST['ticket_id'] ) );
     221                wpas_close_ticket( intval( $_POST['ticket_id'] ) );
    199222            }
    200223
     
    217240
    218241    /**
     242     * Allow e-mail to be used as the login.
     243     *
     244     * @since  3.0.2
     245     * @param  null|WP_User $user     User to authenticate.
     246     * @param  string       $username User login
     247     * @param  string       $password User password
     248     * @return object                 WP_User if authentication succeed, WP_Error on failure
     249     */
     250    public function email_signon( $user, $username, $password ) {
     251
     252        /* Authentication was successful, we don't touch it */
     253        if ( is_object( $user ) && is_a( $user, 'WP_User' ) ) {
     254            return $user;
     255        }
     256
     257        /**
     258         * If the $user isn't a WP_User object nor a WP_Error
     259         * we don' touch it and let WordPress handle it.
     260         */
     261        if ( !is_wp_error( $user ) ) {
     262            return $user;
     263        }
     264
     265        /**
     266         * We only wanna alter the authentication process if the username was rejected.
     267         * If the error is different lwe let WordPress handle it.
     268         */
     269        if ( 'invalid_username' !== $user->get_error_code() ) {
     270            return $user;
     271        }
     272
     273        /**
     274         * If the username is not an e-mail there is nothing else we can do,
     275         * the error is probably legitimate.
     276         */
     277        if ( !is_email( $username ) ) {
     278            return $user;
     279        }
     280
     281        /* Try to get the user with this e-mail address */
     282        $user_data = get_user_by( 'email', $username );
     283
     284        /**
     285         * If there is no user with this e-mail the error is legitimate
     286         * so let's just return it.
     287         */
     288        if ( false === $user_data || !is_a( $user_data, 'WP_User' ) ) {
     289            return $user;
     290        }
     291
     292        return wp_authenticate_username_password( null, $user_data->data->user_login, $password );
     293
     294    }
     295
     296    /**
    219297     * Run pre-defined actions.
    220298     *
     
    238316
    239317                if ( isset( $_GET['ticket_id'] ) ) {
    240                     update_post_meta( intval( $_GET['ticket_id'] ), '_wpas_status', 'open', 'closed' );
    241                     wpas_log( intval( $_GET['ticket_id'] ), __( 'The ticket was re-opened.', 'wpas' ) );
     318                    wpas_reopen_ticket( $_GET['ticket_id'] );
    242319                }
    243320
     
    528605     * Register and enqueue public-facing style sheet.
    529606     *
    530      * @since    1.0.0
     607     * @since    1.0.2
    531608     */
    532609    public function enqueue_styles() {
    533610
    534         if ( !is_admin() && wpas_is_plugin_page() ) {
    535 
    536             /* Load the theme stylesheet */
    537             $theme = wpas_get_theme();
     611        /* Load the theme stylesheet */
     612        $theme = wpas_get_theme();
     613
     614        wp_register_style( 'wpas-theme-styles', WPAS_URL . "themes/$theme/css/style.css", array(), WPAS_VERSION );
     615        wp_register_style( 'wpas-plugin-styles', WPAS_URL . 'assets/public/css/public.css', array(), WPAS_VERSION );
     616
     617        if ( ! is_admin() && wpas_is_plugin_page() ) {
    538618
    539619            if ( file_exists( WPAS_PATH . "themes/$theme/css/style.css" ) && true === boolval( wpas_get_option( 'theme_stylesheet' ) ) ) {
    540                 wp_enqueue_style( 'wpas-theme-styles', WPAS_URL . "themes/$theme/css/style.css", array(), WPAS_VERSION );
     620                wp_enqueue_style( 'wpas-theme-styles' );
    541621            } else {
    542                 wp_enqueue_style( 'wpas-plugin-styles', WPAS_URL . 'assets/public/css/public.css', array(), WPAS_VERSION );
    543             }
    544         }
     622                wp_enqueue_style( 'wpas-plugin-styles' );
     623            }
     624           
     625        }
     626
    545627    }
    546628
     
    548630     * Register and enqueues public-facing JavaScript files.
    549631     *
    550      * @since    1.0.0
     632     * @since    1.0.2
    551633     */
    552634    public function enqueue_scripts() {
    553         if ( !is_admin() && wpas_is_plugin_page() ) {
    554             wp_enqueue_script( 'wpas-plugin-script', WPAS_URL . 'assets/public/js/public-dist.js', array( 'jquery' ), WPAS_VERSION, true );
    555         }
     635
     636        wp_register_script( 'wpas-plugin-script', WPAS_URL . 'assets/public/js/public-dist.js', array( 'jquery' ), WPAS_VERSION, true );
     637
     638        if ( ! is_admin() && wpas_is_plugin_page() ) {
     639            wp_enqueue_script( 'wpas-plugin-script' );
     640        }
     641
     642        wp_localize_script( 'wpas-plugin-script', 'wpas', $this->get_javascript_object() );
     643
     644    }
     645
     646    /**
     647     * JavaScript object.
     648     *
     649     * The plugin uses a couple of JS variables that we pass
     650     * to the main script through a "wpas" object.
     651     *
     652     * @since  3.0.2
     653     * @return array The JavaScript object
     654     */
     655    protected function get_javascript_object() {
     656
     657        $object = array(
     658            'ajaxurl'    => admin_url( 'admin-ajax.php' ),
     659            'emailCheck' => true === boolval( wpas_get_option( 'enable_mail_check', false ) ) ? 'true' : 'false',
     660        );
     661
     662        return $object;
     663
    556664    }
    557665
     
    605713     */
    606714    public function notify_confirmation( $ticket_id, $data ) {
    607         new WPAS_Email_Notification( $ticket_id, 'submission_confirmation' );
    608         new WPAS_Email_Notification( $ticket_id, 'new_ticket_assigned' );
     715        wpas_email_notify( $ticket_id, array( 'submission_confirmation', 'new_ticket_assigned' ) );
    609716    }
    610717
     
    616723        }
    617724
    618         $case = current_user_can( 'edit_ticket' ) ? 'agent_reply' : 'client_reply';
    619         new WPAS_Email_Notification( $reply_id, $case );
     725        $case = user_can( $data['post_author'], 'edit_ticket' ) ? 'agent_reply' : 'client_reply';
     726        wpas_email_notify( $reply_id, $case );
    620727    }
    621728
    622729    public function notify_close( $ticket_id ) {
    623         new WPAS_Email_Notification( $ticket_id, 'ticket_closed' );
     730        wpas_email_notify( $ticket_id, 'ticket_closed' );
    624731    }
    625732
     
    752859    }
    753860
     861    /**
     862     * Register default logs handles.
     863     *
     864     * @since  3.0.2
     865     * @param  array $handles Array of registered log handles
     866     * @return array          Array of registered handles with the default ones added
     867     */
     868    public function default_log_handles( $handles ) {
     869        array_push( $handles, 'error' );
     870        return $handles;
     871    }
     872
     873    public function mailgun_check( $data = '' ) {
     874
     875        if ( empty( $data ) ) {
     876            if ( isset( $_POST ) ) {
     877                $data = $_POST;
     878            } else {
     879                echo '';
     880                die();
     881            }
     882        }
     883
     884        if ( !isset( $data['email'] ) ) {
     885            echo '';
     886            die();
     887        }
     888
     889        $mailgun = new WPAS_MailGun_EMail_Check();
     890        $check   = $mailgun->check_email( $data );
     891
     892        if ( !is_wp_error( $check ) ) {
     893
     894            $check = json_decode( $check );
     895
     896            if ( is_object( $check ) && isset( $check->did_you_mean ) && !is_null( $check->did_you_mean ) ) {
     897                printf( __( 'Did you mean %s', 'wpas' ), "<strong>{$check->did_you_mean}</strong>?" );
     898                die();
     899            }
     900
     901        }
     902
     903        die();
     904
     905    }
     906
    754907}
  • awesome-support/trunk/includes/addons/custom-fields/class-custom-fields.php

    r1049994 r1072407  
    741741        $slug = defined( 'WPAS_PRODUCT_SLUG' ) ? WPAS_PRODUCT_SLUG : 'product';
    742742
     743        /* Filter the taxonomy labels */
     744        $labels = apply_filters( 'wpas_product_taxonomy_labels', array(
     745            'label'        => __( 'Product', 'wpas' ),
     746            'name'         => __( 'Product', 'wpas' ),
     747            'label_plural' => __( 'Products', 'wpas' )
     748            )
     749        );
     750
    743751        $wpas_cf->add_field( 'product', array(
    744752            'core'                  => false,
     
    746754            'log'                   => true,
    747755            'callback'              => 'taxonomy',
    748             'taxo_std'              => true,
     756            'taxo_std'              => false,
    749757            'save_callback'         => null,
    750             'label'                 => __( 'Product', 'wpas' ),
    751             'name'                  => __( 'Product', 'wpas' ),
    752             'label_plural'          => __( 'Products', 'wpas' ),
     758            'label'                 => $labels['label'],
     759            'name'                  => $labels['name'],
     760            'label_plural'          => $labels['label_plural'],
    753761            'taxo_hierarchical'     => true,
    754762            'update_count_callback' => 'wpas_update_ticket_tag_terms_count',
  • awesome-support/trunk/includes/addons/custom-fields/class-display.php

    r1049994 r1072407  
    3737                $callback = !empty( $field['args']['callback'] ) ? $field['args']['callback'] : 'text';
    3838
    39                 if ( method_exists( 'WPAS_Custom_Fields_Display', $callback ) ) {
     39                /* Check for a custom function */
     40                if ( function_exists( $callback ) ) {
     41                    call_user_func( $callback, $field );
     42                }
     43
     44                /* Check for a matching method in the custom fields display class */
     45                elseif ( method_exists( 'WPAS_Custom_Fields_Display', $callback ) ) {
    4046                    call_user_func( array( 'WPAS_Custom_Fields_Display', $callback ), $field );
    41                 } else {
     47                }
     48
     49                /* Fallback on a standard text field */
     50                else {
    4251                    WPAS_Custom_Fields_Display::text( $field );
    4352                }
  • awesome-support/trunk/includes/addons/custom-fields/class-save.php

    r1049994 r1072407  
    8383            }
    8484
     85            /* Process the agent (re)attribution differently */
     86            if ( 'assignee' === $option['name'] ) {
     87
     88                /* Don't od anything if the agent didn't change */
     89                if ( $_POST[$option_name] == get_post_meta( $post_id, '_wpas_assignee', true ) ) {
     90                    continue;
     91                }
     92
     93                wpas_assign_ticket( $post_id, $_POST["_$option_name"], $option_args['log'] );
     94                continue;
     95            }
     96
    8597            /* We handle different option types differently */
    8698            if ( 'taxonomy' != $option_args['callback'] ):
     
    342354                     * we delete it to avoid DB overload.
    343355                     */
    344                     if ( !empty( $old ) && 'status' !== $field['name'] ) {
     356                    if ( !empty( $old ) && 'status' !== $field['name'] && 'assignee' !== $field['name'] ) {
    345357                        delete_post_meta( $post_id, "_$field_name", $old );
    346358                    }
  • awesome-support/trunk/includes/admin/class-admin-help.php

    r1049994 r1072407  
    9090         * Gather the list of e-mail template tags and their description
    9191         */
    92         $emails = new WPAS_Email_Notification( false );
    93         $list_tags = $emails->get_tags();
     92        $list_tags = WPAS_Email_Notification::get_tags();
    9493
    9594        $tags = '<table class="widefat"><thead><th class="row-title">' . __( 'Tag', 'wpas' ) . '</th><th>' . __( 'Description', 'wpas' ) . '</th></thead><tbody>';
  • awesome-support/trunk/includes/admin/class-admin.php

    r1049994 r1072407  
    9999            add_action( 'pre_get_posts',             array( $this, 'hide_others_tickets' ), 10, 1 );
    100100            add_action( 'admin_init',                array( $this, 'system_tools' ), 10, 0 );
    101             add_action( 'admin_init',                array( $this, 'remote_notifications' ), 10, 0 );
     101            add_action( 'plugins_loaded',            array( $this, 'remote_notifications' ), 15, 0 );
    102102            add_action( 'admin_enqueue_scripts',     array( $this, 'enqueue_admin_styles' ) );              // Load plugin styles
    103103            add_action( 'admin_enqueue_scripts',     array( $this, 'enqueue_admin_scripts' ) );             // Load plugin scripts
    104104            add_action( 'admin_menu',                array( $this, 'register_submenu_items' ) );            // Register all the submenus
    105105            add_action( 'admin_menu',                array( $this, 'tickets_count' ) );                     // Add the tickets count
    106             add_action( 'admin_notices',             array( $this, 'wpas_admin_notices' ) );                // Display custom admin notices
     106            add_action( 'admin_notices',             array( $this, 'admin_notices' ) );                     // Display custom admin notices
    107107            add_action( 'add_meta_boxes',            array( $this, 'metaboxes' ) );                         // Register the metaboxes
    108108            add_action( 'save_post_ticket',          array( $this, 'save_ticket' ) );                       // Save all custom fields
     
    420420     * @return void
    421421     */
    422     public function wpas_admin_notices() {
    423 
    424         if ( isset( $_GET['message'] ) ) {
    425 
    426             switch( $_GET['message'] ) {
    427 
    428                 case 'wpas-opened':
     422    public function admin_notices() {
     423
     424        if ( isset( $_GET['wpas-message'] ) ) {
     425
     426            switch( $_GET['wpas-message'] ) {
     427
     428                case 'opened':
    429429                    ?>
    430430                    <div class="updated">
     
    434434                break;
    435435
    436                 case 'wpas-closed':
     436                case 'closed':
    437437                    ?>
    438438                    <div class="updated">
     
    524524        add_submenu_page( 'edit.php?post_type=ticket', __( 'System Status', 'wpas' ), __( 'System Status', 'wpas' ), 'administrator', 'wpas-status', array( $this, 'display_status_page' ) );
    525525        add_submenu_page( 'edit.php?post_type=ticket', __( 'Awesome Support Addons', 'wpas' ), '<span style="color:#f39c12;">' . __( 'Addons', 'wpas' ) . '</span>', 'edit_posts', 'wpas-addons', array( $this, 'display_addons_page' ) );
    526         add_submenu_page( 'edit.php?post_type=ticket', __( 'About Awesome Support', 'wpas' ), __( 'About', 'wpas' ), 'edit_posts', 'wpas-about', array( $this, 'display_about_page' ) );
     526        add_submenu_page( 'options.php', __( 'About Awesome Support', 'wpas' ), __( 'About', 'wpas' ), 'edit_posts', 'wpas-about', array( $this, 'display_about_page' ) );
    527527    }
    528528
     
    624624                if( isset( $_GET['post'] ) && 'ticket' == get_post_type( intval( $_GET['post'] ) ) ) {
    625625
    626                     update_post_meta( intval( $_GET['post'] ), '_wpas_status', 'closed' );
    627 
    628                     $url = add_query_arg( array( 'post' => $_GET['post'], 'action' => 'edit', 'message' => 'wpas-closed' ), admin_url( 'post.php' ) );
    629 
    630                     wpas_log( $_GET['post'], __( 'The ticket was closed.', 'wpas' ) );
    631                     do_action( 'wpas_after_close_ticket', intval( $_GET['post'] ) );
     626                    $url = add_query_arg( array( 'post' => $_GET['post'], 'action' => 'edit', 'wpas-message' => 'closed' ), admin_url( 'post.php' ) );
     627
     628                    wpas_close_ticket( $_GET['post'] );
    632629
    633630                }
     
    639636                if( isset( $_GET['post'] ) && 'ticket' == get_post_type( intval( $_GET['post'] ) ) ) {
    640637
    641                     update_post_meta( intval( $_GET['post'] ), '_wpas_status', 'open' );
    642 
    643                     $url = add_query_arg( array( 'post' => $_GET['post'], 'action' => 'edit', 'message' => 'wpas-opened' ), admin_url( 'post.php' ) );
    644 
    645                     wpas_log( $_GET['post'], __( 'The ticket was re-opened.', 'wpas' ) );
     638                    $url = add_query_arg( array( 'post' => $_GET['post'], 'action' => 'edit', 'wpas-message' => 'opened' ), admin_url( 'post.php' ) );
     639
     640                    wpas_reopen_ticket( $_GET['post'] );
     641
    646642                }
    647643
     
    877873
    878874                    /* Set the redirection */
    879                     $_SESSION['wpas_redirect'] = add_query_arg( array( 'message' => 'wpas_reply_error' ), get_permalink( $post_id ) );
     875                    $_SESSION['wpas_redirect'] = add_query_arg( array( 'wpas-message' => 'wpas_reply_error' ), get_permalink( $post_id ) );
    880876
    881877                } else {
  • awesome-support/trunk/includes/admin/metaboxes/stakeholders.php

    r1049994 r1072407  
    55 * This metabox is used to display all parties involved in the ticket resolution.
    66 *
    7  * @since 3.0.0
     7 * @since 3.0.2
    88 */
    99
     
    8686
    8787                    /* Exclude agents */
    88                     if ( !$user->has_cap( 'create_ticket' ) ) {
     88                    if ( $user->has_cap( 'create_ticket' ) && ! $user->has_cap( 'edit_ticket' ) ) {
    8989
    9090                        $user_id   = $user->ID;
    9191                        $user_name = $user->data->user_nicename;
    9292
    93                         if( $user_id == $post->post_author )
    94                             $selected  = "selected='selected'";
     93                        $selected = ( $user_id == $post->post_author ) ? "selected='selected'" : '';
    9594
    9695                        /* Output the option */
  • awesome-support/trunk/includes/admin/settings/settings-general.php

    r1049994 r1072407  
    7575                    'id'      => 'ticket_submit',
    7676                    'type'    => 'select',
    77                     'desc'    => __( 'The page used for ticket submission.', 'wpas' ),
     77                    'desc'    => sprintf( __( 'The page used for ticket submission. This page should contain the shortcode %s', 'wpas' ), '<code>[ticket-submit]</code>' ),
    7878                    'options' => wpas_list_pages(),
    7979                    'default' => ''
     
    8383                    'id'      => 'ticket_list',
    8484                    'type'    => 'select',
    85                     'desc'    => __( 'The page that will list all tickets for a client.', 'wpas' ),
     85                    'desc'    => sprintf( __( 'The page that will list all tickets for a client. This page should contain the shortcode %s', 'wpas' ), '<code>[tickets]</code>' ),
    8686                    'options' => wpas_list_pages(),
    8787                    'default' => ''
  • awesome-support/trunk/includes/admin/settings/settings-notifications.php

    r1049994 r1072407  
    2626                    'name'    => __( 'Sender E-Mail', 'wpas' ),
    2727                    'id'      => 'sender_email',
     28                    'type'    => 'text',
     29                    'default' => get_bloginfo( 'admin_email' )
     30                ),
     31                array(
     32                    'name'    => __( 'Reply-To E-Mail', 'wpas' ),
     33                    'id'      => 'reply_email',
    2834                    'type'    => 'text',
    2935                    'default' => get_bloginfo( 'admin_email' )
  • awesome-support/trunk/includes/admin/views/addons.php

    r1049994 r1072407  
    4545.wpas-addon-img-wrap {
    4646    width: 100%;
    47     min-height: 311px;
     47    min-height: 302px;
    4848    background: #ddd url('<?php echo admin_url(); ?>/images/wpspin_light-2x.gif') no-repeat 50% 50%;
    4949}
  • awesome-support/trunk/includes/class-email-notifications.php

    r1049994 r1072407  
    33 * E-Mail Notifications.
    44 *
    5  * @package   Awesome_Support
     5 * This class handles all e-mail notifications. One instance of this class
     6 * relates to one and one only post, but can handle multiple notifications
     7 * for the same post.
     8 *
     9 * The available notifications can be extended with the use of a few filters
     10 * available throughout the class and the dispatch of e-mails is handled by
     11 * the pluggable function wp_mail(). It is recommended to use a proper SMTP
     12 * server for e-mail routing in order to ensure a safe delivery.
     13 *
     14 * @package   Awesome Support
    615 * @author    ThemeAvenue <[email protected]>
    716 * @license   GPL-2.0+
     
    1120class WPAS_Email_Notification {
    1221
    13     public function __construct( $post_id, $case = false ) {
    14 
    15         /* If $case if false we don't know what e-mail to send. */
    16         if ( false === $case ) {
    17             return;
    18         }
    19 
    20         $this->post_id   = $post_id;
    21         $this->post      = get_post( $this->post_id );
    22         $this->ticket_id = ( 0 === intval( $this->post->post_parent ) ) ? $post_id : intval( $this->post->post_parent );
    23         $this->case      = $case;
    24 
    25         /* Prepare and send the message. */
    26         $this->init();
    27 
    28     }
    29 
    30     public function init() {
    31 
    32         switch( $this->case ) {
    33 
    34             case 'submission_confirmation':
    35 
    36                 $enable         = boolval( wpas_get_option( 'enable_confirmation', true ) );
    37                 $this->subject  = wpas_get_option( 'subject_confirmation' );
    38                 $this->contents = wpas_get_option( 'content_confirmation' );
    39                 $user           = get_user_by( 'id', $this->post->post_author );
    40                 $this->to_name  = $user->user_nicename;
    41                 $this->to_email = $user->user_email;
    42 
    43             break;
    44 
    45             case 'new_ticket_assigned':
    46 
    47                 $enable         = boolval( wpas_get_option( 'enable_assignment', true ) );
    48                 $this->subject  = wpas_get_option( 'subject_assignment' );
    49                 $this->contents = wpas_get_option( 'content_assignment' );
    50                 $user           = get_user_by( 'id', intval( get_post_meta( $this->ticket_id, '_assigned_agent' ) ) );
    51                 $this->to_name  = $user->user_nicename;
    52                 $this->to_email = $user->user_email;
    53 
    54             break;
    55 
    56             case 'agent_reply':
    57 
    58                 $enable         = boolval( wpas_get_option( 'enable_reply_agent', true ) );
    59                 $this->subject  = wpas_get_option( 'subject_reply_agent' );
    60                 $this->contents = wpas_get_option( 'content_reply_agent' );
    61                 $user           = get_user_by( 'id', $this->post->post_author );
    62                 $this->to_name  = $user->data->user_nicename;
    63                 $this->to_email = $user->data->user_email;
    64 
    65             break;
    66 
    67             case 'client_reply':
    68 
    69                 $enable         = boolval( wpas_get_option( 'enable_reply_client', true ) );
    70                 $this->subject  = wpas_get_option( 'subject_reply_client' );
    71                 $this->contents = wpas_get_option( 'content_reply_client' );
    72                 $user           = get_user_by( 'id', intval( get_post_meta( $this->ticket_id, '_assigned_agent' ) ) );
    73                 $this->to_name  = $user->data->user_nicename;
    74                 $this->to_email = $user->data->user_email;
    75 
    76             break;
    77 
    78             case 'ticket_closed':
    79 
    80                 $enable         = boolval( wpas_get_option( 'enable_closed', true ) );
    81                 $this->subject  = wpas_get_option( 'subject_closed' );
    82                 $this->contents = wpas_get_option( 'content_closed' );
    83                 $user           = get_user_by( 'id', $this->post->post_author );
    84                 $this->to_name  = $user->data->user_nicename;
    85                 $this->to_email = $user->data->user_email;
    86 
    87             break;
    88 
    89         }
    90 
    91         if ( !isset( $enable ) || false === $enable ) {
    92             return;
    93         }
    94 
    95         $this->prepare();
    96 
    97     }
    98 
    99     public function prepare() {
    100 
    101         $this->from_name   = apply_filters( 'wpas_email_from_name',      wpas_get_option( 'sender_name', get_bloginfo( 'name' ) ) );
    102         $this->from_email  = apply_filters( 'wpas_email_from_email',     wpas_get_option( 'sender_email', get_bloginfo( 'admin_email' ) ) );
    103         $this->reply_name  = apply_filters( 'wpas_email_reply_to_name',  $this->from_name );
    104         $this->reply_email = apply_filters( 'wpas_email_reply_to_email', $this->from_email );
    105         $this->subject     = $this->fetch( $this->subject );
    106         $this->body        = $this->fetch( $this->contents );
    107 
    108         $this->send();
    109 
    110     }
    111 
     22    /**
     23     * ID of the post to notify about.
     24     *
     25     * @var integer
     26     */
     27    private $post_id;
     28
     29    /**
     30     * ID of the related ticket.
     31     *
     32     * The ticket ID can be the same as the post ID if the provided post ID
     33     * is a new ticket. Otherwise $post_id is a reply.
     34     *
     35     * @var  integer
     36     */
     37    private $ticket_id;
     38
     39    /**
     40     * Class constructor.
     41     *
     42     * @param integer $post_id ID of the post to notify about
     43     */
     44    public function __construct( $post_id ) {
     45
     46        /* Make sure the given post belongs to our plugin. */
     47        if ( !in_array( get_post_type( $post_id ), array( 'ticket', 'ticket_reply' ) ) ) {
     48            return new WP_Error( 'incorrect_post_type', __( 'The post ID provided does not match any of the plugin post types', 'wpas' ) );
     49        }
     50
     51        /* Set the post ID */
     52        $this->post_id = $post_id;
     53       
     54        /**
     55         * Define the ticket ID, be it $post_id or not.
     56         */
     57        if ( 'ticket' === get_post_type( $post_id ) ) {
     58            $this->ticket_id = $post_id;
     59        } else {
     60            $reply           = $this->get_reply();
     61            $this->ticket_id = $reply->post_parent;
     62        }
     63
     64    }
     65
     66    /**
     67     * Ge the post object for the reply.
     68     *
     69     * @since  3.0.2
     70     * @return boolean|object The reply object if there is a reply, false otherwise
     71     */
     72    public function get_reply() {
     73
     74        if ( isset( $this->reply ) ) {
     75            return $this->reply;
     76        }
     77
     78        if ( 'ticket_reply' !== get_post_type( $this->post_id ) ) {
     79            return false;
     80        }
     81
     82        $this->reply = get_post( $this->post_id );
     83
     84        return $this->reply;
     85
     86    }
     87
     88    /**
     89     * Ge the post object for the ticket.
     90     *
     91     * @since  3.0.2
     92     * @return boolean|object The ticket object if there is a reply, false otherwise
     93     */
     94    public function get_ticket() {
     95
     96        if ( isset( $this->ticket ) ) {
     97            return $this->ticket;
     98        }
     99
     100        if ( 'ticket' !== get_post_type( $this->ticket_id ) ) {
     101            return false;
     102        }
     103
     104        $this->ticket = get_post( $this->ticket_id );
     105
     106        return $this->ticket;
     107
     108    }
     109
     110    /**
     111     * Check if the requested notification is active.
     112     *
     113     * E-mail notifications can be enabled or disabled on a
     114     * per-case basis by the user in the plugin settings.
     115     * We need to check that the requested notification hasn't been
     116     * disabled by the user before sending it out.
     117     *
     118     * @since  3.0.2
     119     * @param  string  $case The notification case requested
     120     * @return boolean       True if the notification is enabled for this case, false otherwise
     121     */
     122    public function is_active( $case ) {
     123
     124        /* Make sure this case actually exists. */
     125        if ( !$this->notification_exists( $case ) ) {
     126            return false;
     127        }
     128
     129        $options = $this->cases_active_option();
     130
     131        /* Make sure we have the option name for this case, otherwise we abort */
     132        if ( !array_key_exists( $case, $options ) ) {
     133            return false;
     134        }
     135
     136        $option = $options[$case];
     137
     138        return boolval( wpas_get_option( $option, false ) );
     139
     140    }
     141
     142    /**
     143     * Check if the requested notification exists.
     144     *
     145     * @param  string  $case The notification case requested
     146     * @return boolean       True if such a case exists, false otherwise
     147     */
     148    public function notification_exists( $case ) {
     149
     150        $cases = $this->get_cases();
     151
     152        if ( !in_array( $case, $cases ) ) {
     153            return false;
     154        }
     155
     156        return true;
     157
     158    }
     159
     160    /**
     161     * Get available notification cases.
     162     *
     163     * @since  3.0.2
     164     * @return array Array of the available cases
     165     */
     166    public function get_cases() {
     167
     168        $cases = array(
     169            'submission_confirmation',
     170            'new_ticket_assigned',
     171            'agent_reply',
     172            'client_reply',
     173            'ticket_closed',
     174        );
     175
     176        return apply_filters( 'wpas_email_notifications_cases', $cases );
     177
     178    }
     179
     180    /**
     181     * Get notification cases active option name.
     182     *
     183     * @since  3.0.2
     184     * @return array Array of available cases with their activation option name
     185     */
     186    private function cases_active_option() {
     187
     188        $cases                            = $this->get_cases();
     189        $cases['submission_confirmation'] = 'enable_confirmation';
     190        $cases['new_ticket_assigned']     = 'enable_assignment';
     191        $cases['agent_reply']             = 'enable_reply_agent';
     192        $cases['client_reply']            = 'enable_reply_client';
     193        $cases['ticket_closed']           = 'enable_closed';
     194
     195        return apply_filters( 'wpas email_notifications_cases_active_option', $cases );
     196    }
     197
     198    /**
     199     * Get sender data.
     200     *
     201     * @since  3.0.2
     202     * @return array Array containing the sender name and e-mail as well as the reply address
     203     */
     204    public function get_sender() {
     205
     206        if ( isset( $this->data ) && !empty( $this->data ) ) {
     207            return $this->data;
     208        }
     209
     210        $data = array(
     211            'from_name'   => wpas_get_option( 'sender_name', get_bloginfo( 'name' ) ),
     212            'from_email'  => wpas_get_option( 'sender_email', get_bloginfo( 'admin_email' ) ),
     213            'reply_email' => wpas_get_option( 'reply_email', get_bloginfo( 'admin_email' ) ),
     214        );
     215
     216        $data['reply_name']  = $data['from_name'];
     217
     218        $this->data = apply_filters( 'wpas_email_notifications_sender_data', $data );
     219
     220        return $this->data;
     221
     222    }
     223
     224    /**
     225     * Convert tags within a string.
     226     *
     227     * Takes a string (subject or body) and replace the tags
     228     * with their current value if any.
     229     *
     230     * @since  3.0.0
     231     * @param  string $contents String to convert tags from
     232     * @return string           String with tags converted into their corresponding value
     233     */
    112234    public function fetch( $contents ) {
    113235
    114         $tags = $this->get_tags();
     236        $tags = $this->get_tags_values();
    115237
    116238        foreach ( $tags as $tag ) {
    117239
    118             $id    = $tag['tag'];
    119             $value = $tag['value'];
    120 
     240            $id       = $tag['tag'];
     241            $value    = $tag['value'];
    121242            $contents = str_replace( $id, $value, $contents );
    122243
     
    127248    }
    128249
    129     public function send() {
    130 
    131         $headers   = array();
    132         $headers[] = "MIME-Version: 1.0";
    133         $headers[] = "Content-type: text/html; charset=utf-8";
    134         $headers[] = "From: {$this->from_name} <{$this->from_email}>";
    135         // $headers[] = "Bcc: JJ Chong <[email protected]>";
    136         $headers[] = "Reply-To: {$this->reply_name} <{$this->reply_email}>";
    137         $headers[] = "Subject: {$this->subject}";
    138         $headers[] = "X-Mailer: PHP/" . phpversion();
    139 
    140         return wp_mail( $this->to_email, $this->subject, $this->body, implode( "\r\n", $headers ) );
    141 
    142     }
    143 
    144     public function get_tags() {
    145 
    146         $ticket_id    = '';
    147         $ticket_title = '';
    148         $agent_name   = '';
    149         $agent_email  = '';
    150         $client_name  = '';
    151         $client_email = '';
    152 
    153         if ( isset( $this->post ) && is_object( $this->post ) ) {
    154 
    155             $ticket_id    = $this->ticket_id;
    156             $agent        = get_user_by( 'id', intval( get_post_meta( $ticket_id, '_wpas_assignee' ) ) );
    157             $agent_name   = $agent->user_nicename;
    158             $agent_email  = $agent->user_email;
    159             $client       = get_user_by( 'id', $this->post->post_author );
    160             $client_name  = $client->user_nicename;
    161             $client_email = $client->user_email;
    162 
    163             if ( isset( $this->post_id ) && $this->post_id === $this->ticket_id ) {
    164                 $ticket_title = $this->post->post_title;
    165             } else {
    166                 $post         = get_post( $this->ticket_id );
    167                 $ticket_title = $post->post_title;
    168             }
    169         }
    170 
    171         $message           = isset( $this->post ) ? $this->post->post_content : '';
    172         $ticket_url        = !empty( $ticket_id ) ? esc_url( get_permalink( $ticket_id ) ) : '';
    173         $ticket_link       = !empty( $ticket_url ) ? "<a href='$ticket_url'>$ticket_url</a>" : '';
    174         $ticket_admin_url  = !empty( $ticket_id ) ? esc_url( add_query_arg( array( 'post' => $ticket_id, 'action' => 'edit' ), admin_url( 'post.php' ) ) ) : '';
    175         $ticket_admin_link = !empty( $ticket_admin_url ) ? "<a href='$ticket_admin_url'>$ticket_admin_url</a>" : '';
    176 
    177         /* List tags */
     250    /**
     251     * Get the available template tags.
     252     *
     253     * This is just a list of available tags, no value is attached to those tags.
     254     * This list is used both for value attribution and in the contextual help
     255     * in the plugin settings page.
     256     *
     257     * @since  3.0.2
     258     * @return array Array of tags with their description
     259     */
     260    public static function get_tags() {
     261
    178262        $tags = array(
    179263            array(
    180264                'tag'   => '{ticket_id}',
    181                 'value' => $ticket_id,
    182265                'desc'  => __( 'Convert into ticket ID', 'wpas' )
    183266            ),
    184267            array(
    185268                'tag'   => '{site_name}',
    186                 'value' => get_bloginfo( 'name' ),
    187269                'desc'  => __( 'Convert into website name', 'wpas' )
    188270            ),
    189271            array(
    190272                'tag'   => '{agent_name}',
    191                 'value' => $agent_name,
    192273                'desc'  => __( 'Convert into agent name', 'wpas' )
    193274            ),
    194275            array(
    195276                'tag'   => '{agent_email}',
    196                 'value' => $agent_email,
    197277                'desc'  => __( 'Convert into agent e-mail address', 'wpas' )
    198278            ),
    199279            array(
    200280                'tag'   => '{client_name}',
    201                 'value' => $client_name,
    202281                'desc'  => __( 'Convert into client name', 'wpas' )
    203282            ),
    204283            array(
    205284                'tag'   => '{client_email}',
    206                 'value' => $client_email,
    207285                'desc'  => __( 'Convert into client e-mail address', 'wpas' )
    208286            ),
    209287            array(
    210288                'tag'   => '{ticket_title}',
    211                 'value' => $ticket_title,
    212289                'desc'  => __( 'Convert into current ticket title', 'wpas' )
    213290            ),
    214291            array(
    215292                'tag'   => '{ticket_link}',
    216                 'value' => $ticket_link,
    217293                'desc'  => __( 'Displays a link to public ticket', 'wpas' )
    218294            ),
    219295            array(
    220296                'tag'   => '{ticket_url}',
    221                 'value' => $ticket_url,
    222297                'desc'  => __( 'Displays the URL <strong>only</strong> (not a link link) to public ticket', 'wpas' )
    223298            ),
    224299            array(
    225300                'tag'   => '{ticket_admin_link}',
    226                 'value' => $ticket_admin_link,
    227301                'desc'  => __( 'Displays a link to ticket details in admin (for agents)', 'wpas' )
    228302            ),
    229303            array(
    230304                'tag'   => '{ticket_admin_url}',
    231                 'value' => $ticket_admin_url,
    232305                'desc'  => __( 'Displays the URL <strong>only</strong> (not a link link) to ticket details in admin (for agents)', 'wpas' )
    233306            ),
    234307            array(
    235308                'tag'   => '{date}',
    236                 'value' => date( get_option( 'date_format' ) ),
    237309                'desc'  => __( 'Convert into current date', 'wpas' )
    238310            ),
    239311            array(
    240312                'tag'   => '{admin_email}',
    241                 'value' => get_bloginfo( 'admin_email' ),
    242313                'desc'  => sprintf( __( 'Convert into WordPress admin e-mail (<em>currently: %s</em>)', 'wpas' ), get_bloginfo( 'admin_email' ) )
    243314            ),
    244315            array(
    245316                'tag'   => '{message}',
    246                 'value' => $message,
    247317                'desc'  => __( 'Convert into ticket content or reply content', 'wpas' )
    248318            )
    249319        );
    250320
    251         return apply_filters( 'wpas_email_template_tags', $tags );
     321        return apply_filters( 'wpas_email_notifications_template_tags', $tags );
     322
     323    }
     324
     325    /**
     326     * Get tags and their value in the current context.
     327     *
     328     * @since  3.0.0
     329     * @return array Array of tag / value pairs
     330     */
     331    public function get_tags_values() {
     332
     333        /* Get all available tags */
     334        $tags = self::get_tags();
     335
     336        /* This is where we save the tags with their new value */
     337        $new = array();
     338
     339        /* Get the involved users' information */
     340        $agent  = get_user_by( 'id', intval( get_post_meta( $this->ticket_id, '_wpas_assignee' ) ) );
     341        $client = get_user_by( 'id', $this->get_ticket()->post_author );
     342
     343        /* Get the ticket links */
     344        $url_public  = get_permalink( $this->get_ticket()->ID );
     345        $url_private = add_query_arg( array( 'post' => $this->ticket_id, 'action' => 'edit' ), admin_url( 'post.php' ) );
     346
     347        /* Add the tag value in the current context */
     348        foreach ( $tags as $key => $tag ) {
     349
     350            $name = trim( $tag['tag'], '{}' );
     351
     352            switch ( $name ) {
     353
     354                /* Ticket ID */
     355                case 'ticket_id';
     356                    $tag['value'] = $this->ticket_id;
     357                    break;
     358
     359                /* Name of the website */
     360                case 'site_name':
     361                    $tag['value'] = get_bloginfo( 'name' );
     362                    break;
     363
     364                /* Name of the agent assigned to this ticket */
     365                case 'agent_name':
     366                    $tag['value'] = $agent->display_name;
     367                    break;
     368
     369                /* E-mail of the agent assigned to this ticket */
     370                case 'agent_email':
     371                    $tag['value'] = $agent->user_email;
     372                    break;
     373
     374                case 'client_name':
     375                    $tag['value'] = $client->display_name;
     376                    break;
     377
     378                case 'client_email':
     379                    $tag['value'] = $client->user_email;
     380                    break;
     381
     382                case 'ticket_title':
     383                    $tag['value'] = wp_strip_all_tags( $this->get_ticket()->post_title );
     384                    break;
     385
     386                case 'ticket_link':
     387                    $tag['value'] = '<a href="' . $url_public . '">' . $url_public . '</a>';
     388                    break;
     389
     390                case 'ticket_url':
     391                    $tag['value'] = $url_public;
     392                    break;
     393
     394                case 'ticket_admin_link':
     395                    $tag['value'] = '<a href="' . $url_private . '">' . $url_private . '</a>';
     396                    break;
     397
     398                case 'ticket_admin_url':
     399                    $tag['value'] = $url_private;
     400                    break;
     401
     402                case 'date':
     403                    $tag['value'] = date( get_option( 'date_format' ) );
     404                    break;
     405
     406                case 'admin_email':
     407                    $tag['value'] = get_bloginfo( 'admin_email' );
     408                    break;
     409
     410                case 'message':
     411                    $tag['value'] = $this->ticket_id === $this->post_id ? $this->get_ticket()->post_content : $this->get_reply()->post_content;
     412                    break;
     413
     414
     415            }
     416
     417            array_push( $new, $tag );
     418
     419        }
     420
     421        /* Replace the valueless tags array by the new one */
     422        $tags = apply_filters( 'wpas_email_notifications_tags_values', $new, $this->post_id );
     423
     424        return $tags;
     425
     426    }
     427
     428    /**
     429     * Get e-mail subject.
     430     *
     431     * @since  3.0.2
     432     * @return string E-mail subject
     433     */
     434    private function get_subject( $case ) {
     435        return apply_filters( 'wpas_email_notifications_subject', $this->get_content( 'subject', $case ), $this->post_id );
     436    }
     437
     438    /**
     439     * Get e-mail body.
     440     *
     441     * @since  3.0.2
     442     * @return string E-mail body
     443     */
     444    private function get_body( $case ) {
     445        return apply_filters( 'wpas_email_notifications_body', $this->get_content( 'content', $case ), $this->post_id );
     446    }
     447
     448    /**
     449     * Get e-mail content.
     450     *
     451     * Get the content for the given part.
     452     *
     453     * @since  3.0.2
     454     * @param  string $part Part of the e-mail to retrieve
     455     * @param  string $case Which notification is requested
     456     * @return string       The content with tags converted into their values
     457     */
     458    private function get_content( $part, $case ) {
     459
     460        if ( !in_array( $part, array( 'subject', 'content' ) ) ) {
     461            return false;
     462        }
     463
     464        /* Set the output value */
     465        $value = '';
     466
     467        switch ( $case ) {
     468
     469            case 'submission_confirmation':
     470                $value = wpas_get_option( "{$part}_confirmation", "" );
     471                break;
     472
     473            case 'new_ticket_assigned':
     474                $value = wpas_get_option( "{$part}_assignment", "" );
     475                break;
     476
     477            case 'agent_reply':
     478                $value = wpas_get_option( "{$part}_reply_agent", "" );
     479                break;
     480
     481            case 'client_reply':
     482                $value = wpas_get_option( "{$part}_reply_client", "" );
     483                break;
     484
     485            case 'ticket_closed':
     486                $value = wpas_get_option( "{$part}_closed", "" );
     487                break;
     488
     489        }
     490
     491        return $this->fetch( apply_filters( 'wpas_email_notifications_pre_fetch_' . $part, $value, $this->post_id ) );
     492
     493    }
     494
     495    /**
     496     * Send out the e-mail notification.
     497     *
     498     * @since  3.0.2
     499     * @param  string         $case The notification case
     500     * @return boolean|object       True if the notification was sent, WP_Error otherwise
     501     */
     502    public function notify( $case ) {
     503
     504        if ( !$this->notification_exists( $case ) ) {
     505            return new WP_Error( 'unknown_notification', __( 'The requested notification does not exist', 'wpas' ) );
     506        }
     507
     508        if ( !$this->is_active( $case ) ) {
     509            return new WP_Error( 'disabled_notification', __( 'The requested notification is disabled', 'wpas' ) );
     510        }
     511
     512        /**
     513         * Find out who's the user to notify
     514         */
     515        switch ( $case ) {
     516            case 'submission_confirmation':
     517            case 'agent_reply':
     518            case 'ticket_closed':
     519                $user = get_user_by( 'id', $this->get_ticket()->post_author );
     520                break;
     521
     522            case 'new_ticket_assigned':
     523            case 'client_reply':
     524                $user = get_user_by( 'id', intval( get_post_meta( $this->ticket_id, '_wpas_assignee' ) ) );
     525                break;
     526        }
     527
     528        /**
     529         * Get the sender information
     530         */
     531        $sender      = $this->get_sender();
     532        $from_name   = $sender['from_name'];
     533        $from_email  = $sender['from_email'];
     534        $reply_name  = $sender['reply_name'];
     535        $reply_email = $sender['reply_email'];
     536
     537        /**
     538         * Get e-mail subject
     539         *
     540         * @var  stirng
     541         */
     542        $subject = $this->get_subject( $case );
     543
     544        /**
     545         * Get the e-mail body
     546         *
     547         * @var  string
     548         */
     549        $body = $this->get_body( $case );
     550
     551        /**
     552         * Prepare e-mail headers
     553         *
     554         * @var array
     555         */
     556        $headers = array(
     557            "MIME-Version: 1.0",
     558            "Content-type: text/html; charset=utf-8",
     559            "From: {$from_name} <{$from_email}>",
     560            "Reply-To: {$reply_name} <{$reply_email}>",
     561            "Subject: {$subject}",
     562            "X-Mailer: Awesome Support/" . WPAS_VERSION,
     563        );
     564
     565        /**
     566         * Merge all the e-mail variables and apply the wpas_email_notifications_email filter.
     567         */
     568        $email = apply_filters( 'wpas_email_notifications_email', array(
     569            'recipient_email' => $user->user_email,
     570            'subject'         => $subject,
     571            'body'            => $body,
     572            'header'          => $headers,
     573            'attachments'     => ''
     574            )
     575        );
     576
     577        return wp_mail( $email['recipient_email'], $email['subject'], $email['body'], implode( "\r\n", $email['headers'] ) );
    252578
    253579    }
    254580
    255581}
     582
     583/**
     584 * Wrapper function to trigger an e-mail notification.
     585 *
     586 * @since  3.0.2
     587 * @param  integer         $post_id ID of the post to notify about
     588 * @param  string|array    $cases   The case(s) to notify for
     589 * @return boolean|object           True if the notificaiton was sent, WP_Error or false otherwise
     590 */
     591function wpas_email_notify( $post_id, $cases ) {
     592
     593    $notify = new WPAS_Email_Notification( $post_id );
     594    $error  = false;
     595
     596    if ( is_wp_error( $notify ) ) {
     597        return $notify;
     598    }
     599
     600    if ( is_array( $cases ) ) {
     601
     602        foreach ( $cases as $case ) {
     603            if ( !$notify->notify( $case ) ) {
     604                $error = true;
     605            }
     606        }
     607
     608        return true === $error ? false : true;
     609
     610    } else {
     611        return $notify->notify( $cases );
     612    }
     613
     614}
  • awesome-support/trunk/includes/class-post-type.php

    r1049994 r1072407  
    2121
    2222    public function __construct() {
    23         add_action( 'after_setup_theme',     array( $this, 'post_type' ),            10, 0 );
     23        add_action( 'init',                  array( $this, 'post_type' ),            10, 0 );
    2424        add_action( 'init',                  array( $this, 'secondary_post_type' ),  10, 0 );
    2525        add_action( 'init',                  array( $this, 'register_post_status' ), 10, 0 );
     
    4646     * Register the ticket post type.
    4747     *
    48      * @since 1.0.0
     48     * @since 1.0.2
    4949     */
    5050    public function post_type() {
     
    6464
    6565        /* Post type labels */
    66         $labels = array(
     66        $labels = apply_filters( 'wpas_ticket_type_labels', array(
    6767            'name'               => _x( 'Tickets', 'post type general name', 'wpas' ),
    6868            'singular_name'      => _x( 'Ticket', 'post type singular name', 'wpas' ),
     
    7979            'not_found'          => __( 'No tickets found.', 'wpas' ),
    8080            'not_found_in_trash' => __( 'No tickets found in Trash.', 'wpas' ),
    81         );
     81        ) );
    8282
    8383        /* Post type capabilities */
    84         $cap = array(
     84        $cap = apply_filters( 'wpas_ticket_type_cap', array(
    8585            'read'                   => 'view_ticket',
    8686            'read_post'              => 'view_ticket',
     
    9797            'delete_published_posts' => 'delete_ticket',
    9898            'delete_others_posts'    => 'delete_other_ticket'
    99         );
     99        ) );
    100100
    101101        /* Post type arguments */
    102         $args = array(
     102        $args = apply_filters( 'wpas_ticket_type_args', array(
    103103            'labels'              => $labels,
    104104            'public'              => true,
     
    116116            'menu_icon'           => $icon,
    117117            'supports'            => $supports
    118         );
     118        ) );
    119119
    120120        register_post_type( 'ticket', $args );
  • awesome-support/trunk/includes/class-remote-notification-client.php

    r1049994 r1072407  
    1515 * @license   GPL-2.0+
    1616 * @link      http://themeavenue.net
    17  * @link      http://themeavenue.net/plugin-url
     17 * @link      http://wordpress.org/plugins/remote-dashboard-notifications/
     18 * @link      https://github.com/ThemeAvenue/Remote-Dashboard-Notifications
    1819 * @copyright 2014 ThemeAvenue
    1920 */
     
    3334     * @var      string
    3435     */
    35     protected static $version = '0.1.0';
    36 
    37     public function __construct( $channel_id = false, $channel_key = false, $server = false ) {
     36    protected static $version = '0.1.2';
     37
     38    public function __construct( $channel_id = false, $channel_key = false, $server = false, $debug = false ) {
    3839
    3940        /* Don't continue during Ajax process */
    40         if( !is_admin() || defined( 'DOING_AJAX' ) && DOING_AJAX )
    41             return;
    42 
    43         $this->id     = intval( $channel_id );
    44         $this->key    = sanitize_key( $channel_key );
     41        if ( !is_admin() || defined( 'DOING_AJAX' ) && DOING_AJAX ) {
     42            return;
     43        }
     44
     45        $this->id     = intval( $channel_id );
     46        $this->key    = sanitize_key( $channel_key );
    4547        $this->server = esc_url( $server );
    4648        $this->notice = false;
    4749        $this->cache  = apply_filters( 'rn_notice_caching_time', 6 );
     50        $this->debug  = $debug;
     51        $this->error  = null;
    4852
    4953        /* The plugin can't work without those 2 parameters */
    50         if( false === ( $this->id || $this->key || $this->server ) )
    51             return;
     54        if ( false === ( $this->id || $this->key || $this->server ) ) {
     55            return;
     56        }
    5257
    5358        /* Call the dismiss method before testing for Ajax */
    54         if( isset( $_GET['rn'] ) && isset( $_GET['notification'] ) )
     59        if ( isset( $_GET['rn'] ) && isset( $_GET['notification'] ) ) {
    5560            add_action( 'init', array( $this, 'dismiss' ) );
     61        }
    5662
    5763        add_action( 'init', array( $this, 'request_server' ) );
     
    6975    public function request_server() {
    7076
     77        /* Current channel ID */
     78        $channel_id = $this->id;
     79
     80        /* Current channel key */
     81        $channel_key = $this->key;
     82
     83        /* Generate a unique identifyer used for the transient */
     84        $uniqid = $channel_id . substr( $channel_key, 0, 5 );
     85
     86        /* Prepare the payload to send to server */
     87        $payload = base64_encode( json_encode( array( 'channel' => $channel_id, 'key' => $channel_key ) ) );
     88
     89        /* Get the endpoint URL ready */
     90        $url = add_query_arg( array( 'payload' => $payload ), $this->server );
     91
    7192        /* Content is false at first */
    72         $content = get_transient( 'rn_last_notification' );
     93        $content = get_transient( "rn_last_notification_$uniqid" );
    7394
    7495        /* Set the request response to null */
     
    7697
    7798        /* If no notice is present in DB we query the server */
    78         if( false === $content || defined( 'RDN_DEV' ) && RDN_DEV ) {
    79 
    80             /* Prepare the payload to send to server */
    81             $payload = base64_encode( json_encode( array( 'channel' => $this->id, 'key' => $this->key ) ) );
    82 
    83             /* Get the endpoint URL ready */
    84             $url = add_query_arg( array( 'payload' => $payload ), $this->server );
     99        if ( false === $content || defined( 'RDN_DEV' ) && RDN_DEV ) {
    85100
    86101            /* Query the server */
     
    88103
    89104            /* If we have a WP_Error object we abort */
    90             if( is_wp_error( $request ) )
     105            if ( is_wp_error( $request ) ) {
    91106                return;
     107            }
    92108
    93109            /* Check if we have a valid response */
    94             if( is_array( $request ) && isset( $request['response']['code'] ) && 200 === intval( $request['response']['code'] ) ) {
     110            if ( is_array( $request ) && isset( $request['response']['code'] ) && 200 === intval( $request['response']['code'] ) ) {
    95111
    96112                /* Get the response body */
    97                 if( isset( $request['body'] ) ) {
     113                if ( isset( $request['body'] ) ) {
    98114
    99115                    /**
     
    105121                     * Check if the payload is in a usable JSON format
    106122                     */
    107                     if( json_last_error() != JSON_ERROR_NONE ) {
    108                         return false;
     123                    if ( version_compare( phpversion(), '5.3.0', '>=' ) ) {
     124
     125                        if ( ! ( json_last_error() == JSON_ERROR_NONE ) ) {
     126                            return false;
     127                        }
     128
     129                    } else {
     130
     131                        if ( $content == NULL ) {
     132                            return false;
     133                        }
     134
    109135                    }
    110136
    111                     set_transient( 'rn_last_notification', $content, $this->cache*60*60 );
     137                    set_transient( "rn_last_notification_$uniqid", $content, $this->cache*60*60 );
    112138
    113139                }           
     
    120146         * If the JSON string has been decoded we can go ahead
    121147         */
    122         if( is_object( $content ) ) {
    123 
    124             if( isset( $content->error ) )
     148        if ( is_object( $content ) ) {
     149
     150            if ( isset( $content->error ) ) {
     151
     152                /* Display debug info in the admin footer */
     153                if ( true === $this->debug ) {
     154
     155                    /* Save the error message */
     156                    $this->error = $content->error;
     157
     158                    /* Display it commented in the footer */
     159                    add_action( 'admin_footer', array( $this, 'debug_info' ) );
     160
     161                }
     162
     163                /* Stop */
    125164                return;
     165
     166            }
    126167
    127168            $this->notice = $content;
     
    132173            $dismissed = get_option( '_rn_dismissed' );
    133174
    134             if( is_array( $dismissed ) && in_array( $content->slug, $dismissed ) )
     175            if ( is_array( $dismissed ) && in_array( $content->slug, $dismissed ) ) {
    135176                return;
     177            }
    136178
    137179            /**
     
    168210
    169211        /* If there is no content we abort */
    170         if( false === $content )
    171             return;
     212        if ( false === $content ) {
     213            return;
     214        }
    172215
    173216        /* If the type array isn't empty we have a limitation */
    174         if( isset( $content->type ) && is_array( $content->type ) && !empty( $content->type ) ) {
     217        if ( isset( $content->type ) && is_array( $content->type ) && !empty( $content->type ) ) {
    175218
    176219            /* Get current post type */
     
    182225             * then we don't display the admin notice.
    183226             */
    184             if( false === $pt || !in_array( $pt, $content->type ) )
     227            if ( false === $pt || !in_array( $pt, $content->type ) ) {
    185228                return;
     229            }
    186230
    187231        }
     
    190234        $style = isset( $content->style ) ? $content->style : 'updated';
    191235
    192         if( 'updated' == $style )
     236        if ( 'updated' == $style ) {
    193237            $class = $style;
    194 
    195         elseif( 'error' == $style )
     238        }
     239
     240        elseif ( 'error' == $style ) {
    196241            $class = 'updated error';
    197 
    198         else
     242        }
     243
     244        else {
    199245            $class = "updated rn-alert rn-alert-$style";
     246        }
    200247
    201248        /**
     
    219266
    220267        $args = implode( '&', $args );
    221         $url = "?$args";
     268        $url  = "?$args";
    222269        ?>
    223270
    224271        <div class="<?php echo $class; ?>">
    225             <?php if( !in_array( $style, array( 'updated', 'error' ) ) ): ?><a href="<?php echo $url; ?>" id="rn-dismiss" class="rn-dismiss-btn" title="<?php _e( 'Dismiss notification', 'remote-notifications' ); ?>">&times;</a><?php endif; ?>
     272            <?php if ( !in_array( $style, array( 'updated', 'error' ) ) ): ?><a href="<?php echo $url; ?>" id="rn-dismiss" class="rn-dismiss-btn" title="<?php _e( 'Dismiss notification', 'remote-notifications' ); ?>">&times;</a><?php endif; ?>
    226273            <p><?php echo html_entity_decode( $content->message ); ?></p>
    227             <?php if( in_array( $style, array( 'updated', 'error' ) ) ): ?><p><a href="<?php echo $url; ?>" id="rn-dismiss" class="rn-dismiss-button button-secondary"><?php _e( 'Dismiss', 'remote-notifications' ); ?></a></p><?php endif; ?>
     274            <?php if ( in_array( $style, array( 'updated', 'error' ) ) ): ?><p><a href="<?php echo $url; ?>" id="rn-dismiss" class="rn-dismiss-button button-secondary"><?php _e( 'Dismiss', 'remote-notifications' ); ?></a></p><?php endif; ?>
    228275        </div>
    229276        <?php
     
    244291
    245292        /* Check if we have all the vars */
    246         if( !isset( $_GET['rn'] ) || !isset( $_GET['notification'] ) )
    247             return;
     293        if ( !isset( $_GET['rn'] ) || !isset( $_GET['notification'] ) ) {
     294            return;
     295        }
    248296
    249297        /* Validate nonce */
    250         if( !wp_verify_nonce( sanitize_key( $_GET['rn'] ), 'rn-dismiss' ) )
    251             return;
     298        if ( !wp_verify_nonce( sanitize_key( $_GET['rn'] ), 'rn-dismiss' ) ) {
     299            return;
     300        }
    252301
    253302        /* Get dismissed list */
     
    255304
    256305        /* Add the current notice to the list if needed */
    257         if( is_array( $dismissed ) && !in_array( $_GET['notification'], $dismissed ) )
     306        if ( is_array( $dismissed ) && !in_array( $_GET['notification'], $dismissed ) ) {
    258307            array_push( $dismissed, $_GET['notification'] );
     308        }
    259309
    260310        /* Update option */
     
    267317        foreach( $_GET as $key => $value ) {
    268318
    269             if( in_array( $key, array( 'rn', 'notification' ) ) )
     319            if ( in_array( $key, array( 'rn', 'notification' ) ) )
    270320                continue;
    271321
     
    275325
    276326        $args = implode( '&', $args );
    277         $url = "?$args";
     327        $url  = "?$args";
    278328
    279329        /* Redirect */
     
    329379    }
    330380
     381    /**
     382     * Debug info.
     383     *
     384     * Display an error message commented in the admin footer.
     385     *
     386     * @since  0.1.2
     387     */
     388    public function debug_info() {
     389
     390        $error = $this->error;
     391
     392        echo "<!-- RDN Debug Info: $error -->";
     393
     394    }
     395
    331396}
  • awesome-support/trunk/includes/functions-general.php

    r1049994 r1072407  
    301301
    302302}
     303
     304/**
     305 * Write log file.
     306 *
     307 * Wrapper function for WPAS_Logger. The function
     308 * will open (or create if needed) a log file
     309 * and write the $message at the end of it.
     310 *
     311 * @since  3.0.2
     312 * @param  string $handle  The log file handle
     313 * @param  string $message The message to write
     314 * @return void
     315 */
     316function wpas_write_log( $handle, $message ) {
     317    $log = new WPAS_Logger( $handle );
     318    $log->add( $message );
     319}
     320
     321/**
     322 * Show a warning if dependencies aren't loaded.
     323 *
     324 * If the dependencies aren't present in the plugin folder
     325 * we display a warning to the user and explain him how to
     326 * fix the issue.
     327 *
     328 * @since  3.0.2
     329 * @return void
     330 */
     331function wpas_missing_dependencied() { ?>
     332    <div class="error">
     333        <p><?php printf( __( 'Awesome Support dependencies are missing. The plugin can&#39;t be loaded properly. Please run %s before anything else. If you don&#39;t know what this is you should <a href="%s" class="thickbox">install the production version</a> of this plugin instead.', 'wpas' ), '<a href="https://getcomposer.org/doc/00-intro.md#using-composer" target="_blank"><code>composer install</code></a>', esc_url( add_query_arg( array( 'tab' => 'plugin-information', 'plugin' => 'awesome-support', 'TB_iframe' => 'true', 'width' => '772', 'height' => '935' ), admin_url( 'plugin-install.php' ) ) ) ); ?></p>
     334    </div>
     335<?php }
  • awesome-support/trunk/includes/functions-post.php

    r1049994 r1072407  
    236236    }
    237237
     238    /* Assign an agent to the ticket */
     239    wpas_assign_ticket( $ticket_id, $agent_id, false );
     240
    238241    /**
    239242     * Fire wpas_after_open_ticket just after the post is successfully submitted.
    240243     */
    241244    do_action( 'wpas_open_ticket_after', $ticket_id, $data );
    242 
    243     /* Assign an agent to the ticket */
    244     add_post_meta( $ticket_id, '_wpas_assignee', $agent_id, true );
    245245
    246246    return $ticket_id;
     
    341341
    342342    if ( false !== $author_id ) {
    343         $defaults['post_author'] = $author_id;
     343        $data['post_author'] = $author_id;
    344344    } else {
    345345        global $current_user;
    346         $defaults['post_author'] = $current_user->ID;
     346        $data['post_author'] = $current_user->ID;
    347347    }
    348348
    349349    $insert = wpas_insert_reply( $data, $parent_id );
    350350
    351     if ( $insert && user_can( $defaults['post_author'], 'edit_ticket' ) ) {
     351    if ( $insert && user_can( $data['post_author'], 'edit_ticket' ) ) {
    352352        $replies = wpas_get_replies( $parent_id );
    353353        if ( 1 === count( $replies ) ) {
     
    668668
    669669/**
     670 * Assign an agent to a ticket.
     671 *
     672 * Assign the given agent to a ticket or find an available
     673 * agent if no agent ID is given.
     674 *
     675 * @since  3.0.2
     676 * @param  integer  $ticket_id    ID of the post in need of a new agent
     677 * @param  integer  $agent_id     ID of the agent to assign the ticket to
     678 * @param  boolean  $log          Shall the assignment be logged or not
     679 * @return object|boolean|integer WP_Error in case of problem, true if no change is required or the post meta ID if the agent was changed
     680 */
     681function wpas_assign_ticket( $ticket_id, $agent_id = null, $log = true ) {
     682
     683    if ( 'ticket' !== get_post_type( $ticket_id ) ) {
     684        return new WP_Error( 'incorrect_post_type', __( 'The given post ID is not a ticket', 'wpas' ) );
     685    }
     686
     687    if ( is_null( $agent_id ) ) {
     688        $agent_id = wpas_find_agent( $ticket_id );
     689    }
     690
     691    if ( !user_can( $agent_id, 'edit_ticket' ) ) {
     692        return new WP_Error( 'incorrect_agent', __( 'The chosen agent does not have the sufficient capapbilities to be assigned a ticket', 'wpas' ) );
     693    }
     694
     695    /* Get the current agent if any */
     696    $current = get_post_meta( $ticket_id, '_wpas_assignee', true );
     697
     698    if ( $current === $agent_id ) {
     699        return true;
     700    }
     701
     702    $update = update_post_meta( $ticket_id, '_wpas_assignee', $agent_id, $current );
     703
     704    /* Log the action */
     705    if ( true === $log ) {
     706        $log = array();
     707        $log[] = array(
     708            'action'   => 'updated',
     709            'label'    => __( 'Support staff', 'wpas' ),
     710            'value'    => $agent_id,
     711            'field_id' => 'assignee'
     712        );
     713    }
     714
     715    wpas_log( $ticket_id, $log );
     716
     717    /**
     718     * wpas_ticket_assigned hook
     719     *
     720     * since 3.0.2
     721     */
     722    do_action( 'wpas_ticket_assigned', $ticket_id, $agent_id );
     723
     724    return $update;
     725
     726}
     727
     728/**
    670729 * Save form values.
    671730 *
     
    721780 * using one of the custom status registered by the plugin
    722781 * or its addons.
    723  *
    724  * @param  [type] $post_id [description]
    725  * @param  [type] $status  [description]
    726  * @return [type]          [description]
     782 *
     783 * @since  3.0.0
     784 * @param  integer $post_id ID of the ticket being updated
     785 * @param  string  $status  New status to attribute
     786 * @return boolean          True if the query was successfully executed
    727787 */
    728788function wpas_update_ticket_status( $post_id, $status ) {
     
    734794    }
    735795
    736     global $wpdb;
    737 
    738     $updated = $wpdb->query(
    739         $wpdb->prepare(
    740             "UPDATE $wpdb->posts SET post_status = '%s' WHERE ID = '%d'",
    741             $status,
    742             $post_id
    743         )
     796    $post = get_post( $post_id );
     797
     798    if( !$post || $post->post_status === $status ) {
     799        return false;
     800    }
     801
     802    $my_post = array(
     803        'ID'          => $post_id,
     804        'post_status' => $status
    744805    );
    745806
    746     if ( true === boolval( $updated ) ) {
     807    $updated = wp_update_post( $my_post );
     808
     809    if ( 0 !== intval( $updated ) ) {
    747810        wpas_log( $post_id, sprintf( __( 'Ticket state changed to &laquo;%s&raquo;', 'wpas' ), $custom_status[$status] ) );
    748811    }
    749812
     813    /**
     814     * wpas_ticket_status_updated hook
     815     *
     816     * @since  3.0.2
     817     */
     818    do_action( 'wpas_ticket_status_updated', $post_id, $status, $updated );
     819
    750820    return $updated;
    751821
    752822}
     823
     824/**
     825 * Change a ticket status to closed.
     826 *
     827 * @since  3.0.2
     828 * @param  integer         $ticket_id ID of the ticket to close
     829 * @return integer|boolean            ID of the post meta if exists, true on success or false on failure
     830 */
     831function wpas_close_ticket( $ticket_id ) {
     832
     833    if ( 'ticket' == get_post_type( $ticket_id ) ) {
     834
     835        $update = update_post_meta( intval( $ticket_id ), '_wpas_status', 'closed' );
     836
     837        /* Log the action */
     838        wpas_log( $ticket_id, __( 'The ticket was closed.', 'wpas' ) );
     839
     840        /**
     841         * wpas_after_close_ticket hook
     842         *
     843         * @since  3.0.0
     844         */
     845        do_action( 'wpas_after_close_ticket', intval( $ticket_id ), $update );
     846
     847        return $update;
     848
     849    } else {
     850        return false;
     851    }
     852
     853}
     854
     855/**
     856 * Change a ticket status to open.
     857 *
     858 * @since  3.0.2
     859 * @param  integer         $ticket_id ID of the ticket to re-open
     860 * @return integer|boolean            ID of the post meta if exists, true on success or false on failure
     861 */
     862function wpas_reopen_ticket( $ticket_id ) {
     863
     864    if ( 'ticket' == get_post_type( $ticket_id ) ) {
     865
     866        $update = update_post_meta( intval( $ticket_id ), '_wpas_status', 'open' );
     867
     868        /* Log the action */
     869        wpas_log( $ticket_id, __( 'The ticket was re-opened.', 'wpas' ) );
     870
     871        /**
     872         * wpas_after_reopen_ticket hook
     873         *
     874         * @since  3.0.2
     875         */
     876        do_action( 'wpas_after_reopen_ticket', intval( $ticket_id ), $update );
     877
     878        return $update;
     879
     880    } else {
     881        return false;
     882    }
     883
     884}
  • awesome-support/trunk/includes/functions-templating.php

    r1049994 r1072407  
    1313 */
    1414
    15 add_filter( 'the_content', 'wpas_single_ticket' );
    1615/**
    1716 * Alter page content for single ticket.
     
    3231    global $post;
    3332
    34     /* Remove the filter to avoid infinite loops. */
    35     remove_filter( 'the_content', 'wpas_single_ticket' );
    36 
    3733    $slug = 'ticket';
    3834
     
    4642        return $content;
    4743    }
     44
     45    /* Only apply this on the main query. */
     46    if( ! is_main_query() ) {
     47        return $content;
     48    }
     49
     50    /* Only apply this if it's inside of a loop. */
     51    if( ! in_the_loop() ) {
     52        return $content;
     53    }
     54
     55    /* Remove the filter to avoid infinite loops. */
     56    remove_filter( 'the_content', 'wpas_single_ticket' );
    4857
    4958    /* Check if the current user can view the ticket */
  • awesome-support/trunk/includes/functions-user.php

    r1049994 r1072407  
    2626    $last_name  = isset( $data['last_name'] ) && !empty( $data['last_name'] ) ? sanitize_text_field( $data['last_name'] ) : false;
    2727    $pwd        = isset( $data['pwd'] ) && !empty( $data['pwd'] ) ? $data['pwd'] : false;
    28     $pwd2       = isset( $data['pwd-validate'] ) && !empty( $data['pwd-validate'] ) ? $data['pwd-validate'] : false;
    2928
    3029    /* Save the user information in session to pre populate the form in case of error. */
     
    5150
    5251    /* Make sure we have all the necessary data. */
    53     if ( false === ( $email || $first_name || $last_name || $pwd || $pwd2 ) ) {
     52    if ( false === ( $email || $first_name || $last_name || $pwd ) ) {
    5453        wp_redirect( add_query_arg( array( 'message' => wpas_create_notification( __( 'You didn\'t correctly fill all the fields.', 'wpas' ) ), get_permalink( $post->ID ) ) ) );
    55         exit;
    56     }
    57 
    58     /* Check passwords */
    59     if ( $pwd !== $pwd2 ) {
    60         wp_redirect( add_query_arg( array( 'message' => wpas_create_notification( __( 'The password confirmation does not match the password.', 'wpas' ) ), get_permalink( $post->ID ) ) ) );
    6154        exit;
    6255    }
     
    190183            wp_redirect( add_query_arg( array( 'message' => urlencode( base64_encode( json_encode( $error ) ) ) ), get_permalink( $post->ID ) ) );
    191184            exit;
    192         } elseif( is_a( $login, 'WP_User' ) ) { var_dump( $post->ID );
     185        } elseif( is_a( $login, 'WP_User' ) ) {
    193186            wp_redirect( get_permalink( $post->ID ) );
    194187            exit;
  • awesome-support/trunk/includes/shortcodes/shortcode-submit.php

    r1049994 r1072407  
    7070             */
    7171            if ( false === is_user_logged_in() ) {
    72                 wpas_notification( 'failure', sprintf( __( 'You need to <a href="%s">log-in</a> to veiw this ticket.', 'wpas' ), esc_url( '' ) ) );
     72                wpas_notification( 'failure', sprintf( __( 'You need to <a href="%s">log-in</a> to submit a ticket.', 'wpas' ), esc_url( '' ) ) );
    7373            } else {
    7474
     
    7777                 */
    7878                if ( false === wpas_can_submit_ticket( $post->ID ) ) {
    79                     wpas_notification( 'failure', __( 'You are not allowed to view this ticket.', 'wpas' ) );
     79                    wpas_notification( 'failure', __( 'You are not allowed to submit a ticket.', 'wpas' ) );
    8080                }
    8181
  • awesome-support/trunk/readme.txt

    r1065903 r1072407  
    66Requires at least: 3.5.1
    77Tested up to: 4.1
    8 Stable tag: 3.0.1
     8Stable tag: 3.1.0
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    128128== Changelog ==
    129129
     130= 3.1.0 =
     131
     132* Add new filters before registering the post type
     133* Add a logging class that can be used for debugging purposes
     134* Add support for e-commerce plugins when multi-products is enabled (currently supports WooCommerce, Easy Digital Downloads, WP eCommerce and Jigoshop)
     135* Ask for a password only once on the registration form
     136* Add e-mail verification to the registration form (uses MailGun, free account required)
     137* Allow e-mail to be used as the login for clients
     138* Improve agent assignment function
     139* Re-written and optimized e-mail notification class (with a wrapper function `wpas_email_notify()`)
     140* Filter subject and body on e-mail notifications
     141* Let the user specify a reply-to e-mail for notifications
     142* Make the display of ticket details more secure (to avoid conflicts with plugins/themes)
     143* Use users display name instead of user name everywhere on the site
     144* Don't display agents in the clients list of the stakeholders metabox
     145* Fix issue with the blank page after login
     146* Fixed some notices on the ticket single page
     147* Few bugfixes
     148
     149* Hide about page from the menu
     150
    130151= 3.0.1 =
    131152
     
    141162== Upgrade Notice ==
    142163
    143 Version 3.0.1 adds compatibility for some of the latest add-on available (such as the [MailChimp](http://getawesomesupport.com/addons/mailchimp/) add-on).
     164This version fixes a few bugs and introduces a lot of new features
  • awesome-support/trunk/themes/default/details.php

    r1049994 r1072407  
    4141                    <div class="wpas-reply-meta">
    4242                        <div class="wpas-reply-user">
    43                             <strong class="wpas-profilename"><?php echo $author->data->user_nicename; ?></strong>
     43                            <strong class="wpas-profilename"><?php echo $author->data->display_name; ?></strong>
    4444                        </div>
    4545                        <div class="wpas-reply-time">
     
    8484
    8585                    $wpas_replies->the_post();
     86                    $user      = get_userdata( $post->post_author );
    8687                    $user_role = get_the_author_meta( 'roles' );
    8788                    $user_role = $user_role[0];
    88                     $time_ago  = human_time_diff( get_the_time( 'U', $post->ID ), current_time( 'timestamp' ) );  ?>
     89                    $time_ago  = human_time_diff( get_the_time( 'U', $post->ID ), current_time( 'timestamp' ) ); ?>
    8990
    9091                    <tr id="reply-<?php echo the_ID(); ?>" class="wpas-reply-single wpas-status-<?php echo get_post_status(); ?>" valign="top">
     
    111112                            <div class="wpas-reply-meta">
    112113                                <div class="wpas-reply-user">
    113                                     <strong class="wpas-profilename"><?php echo get_the_author_meta( 'user_nicename' ); ?></strong>
     114                                    <strong class="wpas-profilename"><?php echo $user->data->display_name; ?></strong>
    114115                                </div>
    115116                                <div class="wpas-reply-time">
  • awesome-support/trunk/themes/default/registration.php

    r1049994 r1072407  
    4141       
    4242        <div <?php wpas_get_field_container_class( 'log' ); ?>>         
    43             <label><?php _e( 'Username' ); ?></label>
    44             <input type="text" name="log" <?php wpas_get_field_class( 'log' ); ?> placeholder="<?php _e( 'Username' ); ?>" required>
     43            <label><?php _e( 'E-mail or username' ); ?></label>
     44            <input type="text" name="log" <?php wpas_get_field_class( 'log' ); ?> placeholder="<?php _e( 'E-mail or username' ); ?>" required>
    4545        </div>
    4646        <div <?php wpas_get_field_container_class( 'pwd' ); ?>>
     
    6868        <form class="wpas-form" method="post" action="<?php echo get_permalink( $post->ID ); ?>">
    6969            <h3><?php _e( 'Register' ); ?></h3>
    70             <div <?php wpas_get_field_container_class( 'email' ); ?>>
    71                 <label><?php _e( 'Email' ); ?></label>
    72                 <input <?php wpas_get_field_class( 'email' ); ?> type="email" placeholder="<?php _e( 'Email' ); ?>" name="email" value="<?php echo wpas_get_registration_field_value( 'email' ); ?>" required>
    73             </div>
    7470            <div <?php wpas_get_field_container_class( 'first_name' ); ?>>
    7571                <label><?php _e( 'First Name', 'wpas' ); ?></label>
     
    8076                <input <?php wpas_get_field_class( 'last_name' ); ?> type="text" placeholder="<?php _e( 'Last Name', 'wpas' ); ?>" name="last_name" value="<?php echo wpas_get_registration_field_value( 'last_name' ); ?>" required>
    8177            </div>
     78            <div <?php wpas_get_field_container_class( 'email' ); ?>>
     79                <label><?php _e( 'Email' ); ?></label>
     80                <input <?php wpas_get_field_class( 'email' ); ?> type="email" placeholder="<?php _e( 'Email' ); ?>" name="email" value="<?php echo wpas_get_registration_field_value( 'email' ); ?>" required>
     81                <small class="wpas-help-block" id="email-validation" style="display: none;">Example block-level help text here.</small>
     82            </div>
    8283            <div <?php wpas_get_field_container_class( 'pwd' ); ?>>
    8384                <label><?php _e( 'Enter a password', 'wpas' ); ?></label>
    84                 <input <?php wpas_get_field_class( 'pwd', 'wpas-pwd' ); ?> type="password" placeholder="<?php _e( 'Enter a password', 'wpas' ); ?>" id="password" name="pwd" required>
     85                <input <?php wpas_get_field_class( 'pwd', 'wpas-pwd' ); ?> type="password" placeholder="<?php _e( 'Password', 'wpas' ); ?>" id="password" name="pwd" required>
    8586            </div>
    86             <div <?php wpas_get_field_container_class( 'pwd-validate' ); ?>>
    87                 <label><?php _e( 'Repeat password', 'wpas' ); ?></label>
    88                 <input <?php wpas_get_field_class( 'pwd-validate', 'wpas-checkpwd' ); ?> type="password" placeholder="<?php _e( 'Repeat password', 'wpas' ); ?>" id="passwordconf" name="pwd-validate" data-validation="<?php _e( 'The two passwords must match.', 'wpas' ); ?>" required>
     87            <div class="wpas-checkbox">
     88                <label><input type="checkbox" name="pwdshow" id="pwdshow" class="wpas-form-control-checkbox"> <?php echo _x( 'Show Password', 'Login form', 'wpas' ); ?></label>
    8989            </div>
    9090
  • awesome-support/trunk/uninstall.php

    r1049994 r1072407  
    126126    global $wpdb;
    127127
    128     $query = 'SELECT t.name, t.term_id
    129             FROM ' . $wpdb->terms . ' AS t
    130             INNER JOIN ' . $wpdb->term_taxonomy . ' AS tt
    131             ON t.term_id = tt.term_id
    132             WHERE tt.taxonomy = "' . $taxonomy . '"';
     128    $query = 'SELECT t.name, t.term_id
     129            FROM ' . $wpdb->terms . ' AS t
     130            INNER JOIN ' . $wpdb->term_taxonomy . ' AS tt
     131            ON t.term_id = tt.term_id
     132            WHERE tt.taxonomy = "' . $taxonomy . '"';
    133133
    134     $terms = $wpdb->get_results($query);
     134    $terms = $wpdb->get_results($query);
    135135
    136     foreach ( $terms as $term ) {
    137         wp_delete_term( $term->term_id, $taxonomy );
    138     }
     136    foreach ( $terms as $term ) {
     137        wp_delete_term( $term->term_id, $taxonomy );
     138    }
    139139
    140140}
  • awesome-support/trunk/vendor/autoload.php

    r1048776 r1072407  
    55require_once __DIR__ . '/composer' . '/autoload_real.php';
    66
    7 return ComposerAutoloaderInit783a7fc5d31a9f8053c86dfcf65083b3::getLoader();
     7return ComposerAutoloaderInita96d300638d5185568af1a764ca6b6bb::getLoader();
  • awesome-support/trunk/vendor/composer/autoload_real.php

    r1048776 r1072407  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit783a7fc5d31a9f8053c86dfcf65083b3
     5class ComposerAutoloaderInita96d300638d5185568af1a764ca6b6bb
    66{
    77    private static $loader;
     
    2020        }
    2121
    22         spl_autoload_register(array('ComposerAutoloaderInit783a7fc5d31a9f8053c86dfcf65083b3', 'loadClassLoader'), true, true);
     22        spl_autoload_register(array('ComposerAutoloaderInita96d300638d5185568af1a764ca6b6bb', 'loadClassLoader'), true, true);
    2323        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
    24         spl_autoload_unregister(array('ComposerAutoloaderInit783a7fc5d31a9f8053c86dfcf65083b3', 'loadClassLoader'));
     24        spl_autoload_unregister(array('ComposerAutoloaderInita96d300638d5185568af1a764ca6b6bb', 'loadClassLoader'));
    2525
    2626        $map = require __DIR__ . '/autoload_namespaces.php';
     
    4343        $includeFiles = require __DIR__ . '/autoload_files.php';
    4444        foreach ($includeFiles as $file) {
    45             composerRequire783a7fc5d31a9f8053c86dfcf65083b3($file);
     45            composerRequirea96d300638d5185568af1a764ca6b6bb($file);
    4646        }
    4747
     
    5050}
    5151
    52 function composerRequire783a7fc5d31a9f8053c86dfcf65083b3($file)
     52function composerRequirea96d300638d5185568af1a764ca6b6bb($file)
    5353{
    5454    require $file;
  • awesome-support/trunk/vendor/composer/installed.json

    r1048776 r1072407  
    22    {
    33        "name": "gambitph/titan-framework",
    4         "version": "v1.7.2",
    5         "version_normalized": "1.7.2.0",
     4        "version": "v1.7.3",
     5        "version_normalized": "1.7.3.0",
    66        "source": {
    77            "type": "git",
    88            "url": "https://github.com/gambitph/Titan-Framework.git",
    9             "reference": "068875e28369e4066d1e5d181c8b48a2c8c8038b"
     9            "reference": "c083fa441a2fe77c485385782b7eb606220e3cf5"
    1010        },
    1111        "dist": {
    1212            "type": "zip",
    13             "url": "https://api.github.com/repos/gambitph/Titan-Framework/zipball/068875e28369e4066d1e5d181c8b48a2c8c8038b",
    14             "reference": "068875e28369e4066d1e5d181c8b48a2c8c8038b",
     13            "url": "https://api.github.com/repos/gambitph/Titan-Framework/zipball/c083fa441a2fe77c485385782b7eb606220e3cf5",
     14            "reference": "c083fa441a2fe77c485385782b7eb606220e3cf5",
    1515            "shasum": ""
    1616        },
    17         "time": "2014-12-18 06:48:11",
     17        "time": "2014-12-22 07:58:51",
    1818        "type": "library",
    1919        "installation-source": "dist",
  • awesome-support/trunk/vendor/gambitph/titan-framework/README.md

    r1048776 r1072407  
    2020
    2121## Recent Changelog
     22
     23#### Version 1.7.3
     24* Fixed bug introduced in 1.7.2 where admin options sometimes were not being saved
    2225
    2326#### Version 1.7.2
  • awesome-support/trunk/vendor/gambitph/titan-framework/class-admin-panel.php

    r1048776 r1072407  
    3131
    3232        if ( ! is_admin() ) {
     33            return;
     34        }
     35
     36        // If we are just initializing, do not create our admin panels yet. During this phase all we want is to get all the options to create
     37        if ( TitanFramework::$initializing ) {
    3338            return;
    3439        }
  • awesome-support/trunk/vendor/gambitph/titan-framework/class-titan-framework.php

    r1048776 r1072407  
    2424    public $trackerInstance;
    2525
     26    // We have an initialization phase where the options are just being gathered
     27    // for processing, during this phase we need to stop certain steps when creat
     28    public static $initializing = false;
     29
    2630    // We store the options (with IDs) here, used for ensuring our serialized option
    2731    // value doesn't get cluttered with unused options
     
    8993    public function verifyUniqueIDs( $option ) {
    9094        if ( empty( $option->settings['id'] ) ) {
     95            return;
     96        }
     97
     98        // During initialization don't display ID errors
     99        if ( self::$initializing ) {
    91100            return;
    92101        }
  • awesome-support/trunk/vendor/gambitph/titan-framework/readme.txt

    r1048776 r1072407  
    44Tags: framework, options, admin, admin panel, meta box, theme customizer, option framework, library, sdk, edd, settings, api, theme creator, theme framework
    55Requires at least: 3.8
    6 Tested up to: 4.0.1
    7 Stable tag: 1.7.2
     6Tested up to: 4.1
     7Stable tag: 1.7.3
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    217217== Changelog ==
    218218
     219= 1.7.3 =
     220* Fixed bug introduced in 1.7.2 where admin options sometimes were not being saved
     221
    219222= 1.7.2 =
    220223* EDD option can now check for updates all by itself (thank you julien731)
  • awesome-support/trunk/vendor/gambitph/titan-framework/titan-framework.php

    r1048776 r1072407  
    55Description: Titan Framework allows theme and plugin developers to create a admin pages, options, meta boxes, and theme customizer options with just a few simple lines of code.
    66Author: Benjamin Intal, Gambit
    7 Version: 1.7.2
     7Version: 1.7.3
    88Author URI: http://gambit.ph
    99*/
     
    1212
    1313// Used for tracking the version used
    14 defined( 'TF_VERSION' ) or define( 'TF_VERSION', '1.7.2' );
     14defined( 'TF_VERSION' ) or define( 'TF_VERSION', '1.7.3' );
    1515// Used for text domains
    1616defined( 'TF_I18NDOMAIN' ) or define( 'TF_I18NDOMAIN', 'titan-framework' );
     
    8080        add_action( 'plugins_loaded', array( $this, 'forceLoadFirst' ), 10, 1 );
    8181        add_filter( 'plugin_row_meta', array( $this, 'pluginLinks' ), 10, 2 );
     82
     83        // Initialize options, but do not really create them yet
     84        add_action( 'after_setup_theme', array( $this, 'triggerOptionCreation' ), 5 );
     85
     86        // Create the options
    8287        add_action( 'init', array( $this, 'triggerOptionCreation' ), 11 );
    8388    }
     
    9297     */
    9398    public function triggerOptionCreation() {
     99        // The after_setup_theme is the initialization stage
     100        if ( current_filter() == 'after_setup_theme' ) {
     101            TitanFramework::$initializing = true;
     102        }
     103
    94104        do_action( 'tf_create_options' );
     105
     106        TitanFramework::$initializing = false;
    95107    }
    96108
Note: See TracChangeset for help on using the changeset viewer.