No results
')}function C(e){switch(e){case"addEmpty":u.classList.add("empty");break;case"removeEmpty":u.classList.remove("empty");break;case"allUnavailable":y.classList.add("unavailable");break;case"all":y.classList.remove("unavailable");break;case"noneUnavailable":b.classList.add("unavailable");break;case"none":b.classList.remove("unavailable")}}function x(){if(n.focus(),!a.classList.contains("loaded")){a.classList.remove("message-error"),a.classList.add("loaded");var e={action:"dt_load_connections",loadConnectionsNonce:i.dt.loadConnectionsNonce,postId:i.dt.postId},t=!!i.dt.usexhr&&{withCredentials:!0};o.a.ajax({url:i.dt.ajaxurl,xhrFields:t,method:"post",data:e}).done((function(e){if(!e.success||!e.data)return a.classList.remove("loaded"),void a.classList.add("message-error");c=e.data,a.innerHTML=l("dt-show-connections")({connections:c}),u=a.querySelector(".connections-selected"),p=a.querySelector(".selected-connections-list"),m=a.querySelector(".new-connections-list"),y=a.querySelector(".selectall-connections"),b=a.querySelector(".selectno-connections"),g=document.getElementById("dt-connection-search"),L=document.getElementById("dt-post-status"),h=document.getElementById("dt-as-draft"),null!==m&&(f=m.querySelectorAll(".add-connection")),o()(g).on("keyup change",r.a.debounce((function(e){""===e.currentTarget.value&&w(),d=e.currentTarget.value.replace(/https?:\/\//i,"").replace(/www/i,"").replace(/[^0-9a-zA-Z ]+/,""),w()}),300)),r.a.each(f,(function(e){e.classList.contains("syndicated")||(y.classList.remove("unavailable"),v++)}))})).error((function(){a.classList.remove("loaded"),a.classList.add("message-error")}))}}}))},2:function(e,t){e.exports=_}}); +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=13)}([function(e,t){e.exports=window},function(e,t){e.exports=jQuery},function(e,t){e.exports=_},,function(e,t,n){e.exports=function(){"use strict"; +/*! + * mustache.js - Logic-less {{mustache}} templates with JavaScript + * http://github.com/janl/mustache.js + */var e=Object.prototype.toString,t=Array.isArray||function(t){return"[object Array]"===e.call(t)};function n(e){return"function"==typeof e}function r(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function a(e,t){return null!=e&&"object"==typeof e&&t in e}var o=RegExp.prototype.test,i=/\S/;function c(e){return!function(e,t){return o.call(e,t)}(i,e)}var s={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="},l=/\s*/,u=/\s+/,d=/\s*=/,p=/\s*\}/,f=/#|\^|\/|>|\{|&|=|!/;function h(e){this.string=e,this.tail=e,this.pos=0}function v(e,t){this.view=e,this.cache={".":this.view},this.parent=t}function m(){this.templateCache={_cache:{},set:function(e,t){this._cache[e]=t},get:function(e){return this._cache[e]},clear:function(){this._cache={}}}}h.prototype.eos=function(){return""===this.tail},h.prototype.scan=function(e){var t=this.tail.match(e);if(!t||0!==t.index)return"";var n=t[0];return this.tail=this.tail.substring(n.length),this.pos+=n.length,n},h.prototype.scanUntil=function(e){var t,n=this.tail.search(e);switch(n){case-1:t=this.tail,this.tail="";break;case 0:t="";break;default:t=this.tail.substring(0,n),this.tail=this.tail.substring(n)}return this.pos+=t.length,t},v.prototype.push=function(e){return new v(e,this)},v.prototype.lookup=function(e){var t,r,o,i=this.cache;if(i.hasOwnProperty(e))t=i[e];else{for(var c,s,l,u=this,d=!1;u;){if(e.indexOf(".")>0)for(c=u.view,s=e.split("."),l=0;null!=c&&lNo results
'),"mustache"===e&&x()}function E(e){switch(e){case"addEmpty":s.classList.add("empty");break;case"removeEmpty":s.classList.remove("empty");break;case"allUnavailable":g.classList.add("unavailable");break;case"all":g.classList.remove("unavailable");break;case"noneUnavailable":y.classList.add("unavailable");break;case"none":y.classList.remove("unavailable")}}function S(){if(n.focus(),!r.classList.contains("loaded")){r.classList.remove("message-error"),r.classList.add("loaded");var e={action:"dt_load_connections",loadConnectionsNonce:c.dt.loadConnectionsNonce,postId:c.dt.postId},t=p("dt-show-connections"),u=!!c.dt.usexhr&&{withCredentials:!0};a.a.ajax({url:c.dt.ajaxurl,xhrFields:u,method:"post",data:e}).done((function(e){if(!e.success||!e.data)return r.classList.remove("loaded"),void r.classList.add("message-error");if(o=e.data,"mustache"===t){var n={connections:[]};i.a.each(o,(function(e){"internal"===e.type&&(e.internal=!0),n.connections.push(e)})),r.innerHTML=l.a.render(document.getElementById("dt-show-connections").innerHTML,{connections:n.connections,foundConnections:n.connections.length,showSearch:5No results
';\n\t\t}\n\t}\n\n\t/**\n\t * Add or remove CSS classes to indicate button functionality\n\t*/\n\tfunction classList( expr ) {\n\t\tswitch ( expr ) {\n\t\t\t\tcase 'addEmpty':\n\t\t\t\t\tconnectionsSelected.classList.add( 'empty' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'removeEmpty':\n\t\t\t\t\tconnectionsSelected.classList.remove( 'empty' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'allUnavailable':\n\t\t\t\t\tselectAllConnections.classList.add ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'all':\n\t\t\t\t\tselectAllConnections.classList.remove ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'noneUnavailable':\n\t\t\t\t\tselectNoConnections.classList.add ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'none':\n\t\t\t\t\tselectNoConnections.classList.remove ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle distributor push dropdown menu.\n\t */\n\tfunction distributorMenuEntered() {\n\t\tdistributorMenuItem.focus();\n\n\t\tif ( distributorPushWrapper.classList.contains( 'loaded' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdistributorPushWrapper.classList.remove( 'message-error' );\n\t\tdistributorPushWrapper.classList.add( 'loaded' );\n\n\t\tconst data = {\n\t\t\taction: 'dt_load_connections',\n\t\t\tloadConnectionsNonce: dt.loadConnectionsNonce,\n\t\t\tpostId: dt.postId\n\t\t};\n\n\t\tconst xhr = dt.usexhr ? { withCredentials: true } : false;\n\n\t\tjQuery.ajax( {\n\t\t\turl: dt.ajaxurl,\n\t\t\txhrFields: xhr,\n\t\t\tmethod: 'post',\n\t\t\tdata: data\n\t\t} ).done( ( response ) => {\n\t\t\tif ( ! response.success || ! response.data ) {\n\t\t\t\tdistributorPushWrapper.classList.remove( 'loaded' );\n\t\t\t\tdistributorPushWrapper.classList.add( 'message-error' );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdtConnections = response.data;\n\n\t\t\tdistributorPushWrapper.innerHTML = processTemplate( 'dt-show-connections' )( {\n\t\t\t\tconnections: dtConnections,\n\t\t\t} );\n\n\t\t\tsetVariables();\n\t\t} ).error( () => {\n\t\t\tdistributorPushWrapper.classList.remove( 'loaded' );\n\t\t\tdistributorPushWrapper.classList.add( 'message-error' );\n\t\t} );\n\t}\n\n\t// Event listerners when to fetch distributor data.\n\tdistributorAdminItem.addEventListener( 'keydown', function( e ) {\n\t\t// Pressing Enter.\n\t\tif ( ( 13 === e.keyCode ) ) {\n\t\t\tdistributorMenuEntered();\n\t\t}\n\t}, false );\n\n\tdistributorAdminItem.addEventListener( 'touchstart', distributorMenuEntered, false );\n\tdistributorAdminItem.addEventListener( 'mouseenter', distributorMenuEntered, false );\n\n\t/**\n\t * Do syndication ajax\n\t */\n\tjQuery( distributorPushWrapper ).on( 'click', '.syndicate-button', () => {\n\t\tif ( distributorTopMenu.classList.contains( 'syncing' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdistributorTopMenu.classList.add( 'syncing' );\n\n\t\tconst data = {\n\t\t\taction: 'dt_push',\n\t\t\tnonce: dt.nonce,\n\t\t\tconnections: selectedConnections,\n\t\t\tpostId: dt.postId\n\t\t};\n\n\t\tdata.postStatus = ( null !== asDraftInput && asDraftInput.checked ) ? 'draft' : postStatusInput.value;\n\n\t\tconst xhr = dt.usexhr ? { withCredentials: true } : false;\n\n\t\tjQuery.ajax( {\n\t\t\turl: dt.ajaxurl,\n\t\t\txhrFields: xhr,\n\t\t\tmethod: 'post',\n\t\t\tdata: data\n\t\t} ).done( ( response ) => {\n\t\t\tsetTimeout( () => {\n\t\t\t\tdistributorTopMenu.classList.remove( 'syncing' );\n\n\t\t\t\tif ( ! response.data || ! response.data.results ) {\n\t\t\t\t\tdoError();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tdoSuccess( response.data.results );\n\t\t\t}, 500 );\n\t\t} ).error( () => {\n\t\t\tsetTimeout( () => {\n\t\t\t\tdistributorTopMenu.classList.remove( 'syncing' );\n\n\t\t\t\tdoError();\n\t\t\t}, 500 );\n\t\t} );\n\t} );\n\n\t/**\n\t * Add a connection to selected connections for ajax and to the UI list.\n\t */\n\tjQuery( distributorPushWrapper ).on( 'click', '.add-connection', ( event ) => {\n\t\tif ( 'A' === event.target.nodeName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\n\t\tif ( event.currentTarget.classList.contains( 'syndicated' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( event.currentTarget.classList.contains( 'added' ) ) {\n\t\t\tconst type = event.currentTarget.getAttribute( 'data-connection-type' );\n\t\t\tconst id = event.currentTarget.getAttribute( 'data-connection-id' );\n\n\t\t\tconst deleteNode = connectionsSelectedList.querySelector( `[data-connection-id=\"${ id }\"][data-connection-type=\"${ type }\"]` );\n\n\t\t\tdeleteNode.parentNode.removeChild( deleteNode );\n\n\t\t\tdelete selectedConnections[type + id];\n\n\t\t\tif ( selectAllConnections.classList.contains ( 'unavailable' ) ) {\n\t\t\t\tclassList ( 'all' );\n\t\t\t}\n\t\t\tif ( ! Object.keys( selectedConnections ).length ) {\n\t\t\t\tclassList ( 'addEmpty' );\n\t\t\t\tclassList ( 'noneUnavailable' );\n\t\t\t}\n\n\t\t\tshowConnections();\n\t\t} else {\n\t\t\tconst type = event.currentTarget.getAttribute( 'data-connection-type' );\n\t\t\tconst id = event.currentTarget.getAttribute( 'data-connection-id' );\n\n\t\t\tselectedConnections[type + id] = dtConnections[type + id];\n\n\t\t\tconst element = event.currentTarget.cloneNode( true );\n\n\t\t\tconst removeLink = document.createElement( 'span' );\n\t\t\tremoveLink.classList.add( 'remove-connection' );\n\n\t\t\telement.appendChild( removeLink );\n\t\t\telement.classList = 'added-connection';\n\n\t\t\tconnectionsSelectedList.appendChild( element );\n\n\t\t\tif ( selectNoConnections.classList.contains ( 'unavailable' ) ) {\n\t\t\t\tclassList ( 'removeEmpty' );\n\t\t\t\tclassList ( 'none' );\n\t\t\t}\n\n\t\t\tif ( Object.keys( selectedConnections ).length == connectionsAvailableTotal ){\n\t\t\t\tclassList ( 'allUnavailable' );\n\t\t\t}\n\n\t\t\tshowConnections();\n\t\t}\n\t} );\n\n\t/**\n\t * Select all connections for distribution.\n\t*/\n\tjQuery( distributorPushWrapper ).on( 'click', '.selectall-connections', () => {\n\t\tjQuery ( connectionsNewList ).children( '.add-connection' ).each( ( index, childTarget ) => {\n\t\t\tif ( childTarget.classList.contains( 'syndicated' ) || childTarget.classList.contains( 'added' ) ) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tconst type = childTarget.getAttribute( 'data-connection-type' );\n\t\t\t\tconst id = childTarget.getAttribute( 'data-connection-id' );\n\n\t\t\t\tselectedConnections[type + id] = dtConnections[type + id];\n\n\t\t\t\tconst element = childTarget.cloneNode();\n\t\t\t\telement.innerText = childTarget.innerText;\n\n\t\t\t\tconst removeLink = document.createElement( 'span' );\n\t\t\t\tremoveLink.classList.add( 'remove-connection' );\n\n\t\t\t\telement.appendChild( removeLink );\n\t\t\t\telement.classList = 'added-connection';\n\n\t\t\t\tconnectionsSelectedList.appendChild( element );\n\n\t\t\t}\n\n\t\t\tif ( '' !== connectionsAvailableTotal ) {\n\t\t\t\tclassList ( 'removeEmpty' );\n\t\t\t\tclassList ( 'allUnavailable' );\n\t\t\t\tclassList ( 'none' );\n\t\t\t}\n\n\t\t} );\n\n\t\tshowConnections();\n\t} );\n\n\t/**\n\t * Select no connections for distribution.\n\t*/\n\tjQuery( distributorPushWrapper ).on( 'click', '.selectno-connections', () => {\n\n\t\twhile ( connectionsSelectedList.firstChild ) {\n\t\t\tconst type = connectionsSelectedList.firstChild.getAttribute( 'data-connection-type' );\n\t\t\tconst id = connectionsSelectedList.firstChild.getAttribute( 'data-connection-id' );\n\n\t\t\tdelete selectedConnections[type + id];\n\n\t\t\tconnectionsSelectedList.removeChild( connectionsSelectedList.firstChild );\n\n\t\t}\n\n\t\tif ( '' !== connectionsAvailableTotal ) {\n\t\t\tclassList ( 'addEmpty' );\n\t\t\tclassList ( 'noneUnavailable' );\n\t\t\tclassList ( 'all' );\n\t\t}\n\n\t\tshowConnections();\n\t} );\n\n\t/**\n\t * Remove a connection from selected connections and the UI list\n\t */\n\tjQuery( distributorPushWrapper ).on( 'click', '.added-connection', ( event ) => {\n\t\tevent.currentTarget.parentNode.removeChild( event.currentTarget );\n\t\tconst type = event.currentTarget.getAttribute( 'data-connection-type' );\n\t\tconst id = event.currentTarget.getAttribute( 'data-connection-id' );\n\n\t\tdelete selectedConnections[type + id];\n\n\t\tif ( selectAllConnections.classList.contains ( 'unavailable' ) ) {\n\t\t\tclassList ( 'all' );\n\t\t}\n\t\tif ( ! Object.keys( selectedConnections ).length ) {\n\t\t\tclassList ( 'addEmpty' );\n\t\t\tclassList ( 'noneUnavailable' );\n\t\t}\n\n\t\tshowConnections();\n\t} );\n} );\n","module.exports = _;"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///external \"window\"","webpack:///external \"jQuery\"","webpack:///external \"_\"","webpack:///./node_modules/mustache/mustache.js","webpack:///./assets/js/push.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","window","jQuery","_","objectToString","toString","isArray","Array","isFunction","escapeRegExp","string","replace","hasProperty","obj","propName","regExpTest","RegExp","test","nonSpaceRe","isWhitespace","re","testRegExp","entityMap","whiteRe","spaceRe","equalsRe","curlyRe","tagRe","Scanner","this","tail","pos","Context","view","parentContext","cache","parent","Writer","templateCache","_cache","set","clear","eos","scan","match","index","substring","length","scanUntil","search","push","lookup","primitive","intermediateValue","names","context","lookupHit","indexOf","split","clearCache","parse","template","tags","cacheKey","mustache","join","isCacheEnabled","tokens","undefined","openingTagRe","closingTagRe","closingCurlyRe","lineHasNonSpace","sections","spaces","hasTag","nonSpace","indentation","tagIndex","stripSpace","pop","compileTags","tagsToCompile","Error","start","type","chr","token","openSection","scanner","valueLength","charAt","nestedTokens","collector","numTokens","nestTokens","lastToken","squashedTokens","squashTokens","parseTemplate","render","partials","renderTokens","originalTemplate","symbol","buffer","renderSection","renderInverted","renderPartial","unescapedValue","escapedValue","rawValue","self","j","slice","indentPartial","partial","filteredIndentation","partialByNl","indentedValue","escape","version","defaultWriter","TypeError","String","factory","selectedConnections","searchString","processTemplate","memoize","id","element","document","getElementById","attributes","Mustache","innerHTML","evaluate","interpolate","on","distributorAdminItem","querySelector","distributorTopMenu","distributorMenuItem","distributorPushWrapper","dtConnections","connectionsSelected","connectionsSelectedList","connectionsNewList","connectionsNewListChildren","connectionsAvailableTotal","selectAllConnections","selectNoConnections","connectionsSearchInput","postStatusInput","asDraftInput","errorDetails","appendChild","addEventListener","e","keyCode","distributorMenuEntered","classList","contains","add","data","action","nonce","dt","connections","postId","postStatus","checked","xhr","usexhr","withCredentials","ajax","url","ajaxurl","xhrFields","method","done","response","setTimeout","results","success","errors","remove","map","each","result","connectionId","status","syndicated","isEmpty","doError","messages","message","innerText","showConnections","empty_result","error","textStatus","errorThrown","ajax_error","event","target","nodeName","preventDefault","currentTarget","getAttribute","deleteNode","parentNode","removeChild","keys","cloneNode","removeLink","createElement","children","childTarget","firstChild","setDisabledConnections","querySelectorAll","disabled","isString","has","prepareMessages","errorItem","showConnection","connection","nameMatch","toLowerCase","urlMatch","added","internal","expr","focus","loadConnectionsNonce","mustacheData","foundConnections","showSearch","debounce"],"mappings":"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","file":"push.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 13);\n","module.exports = window;","module.exports = jQuery;","module.exports = _;","// This file has been generated from mustache.mjs\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = global || self, global.Mustache = factory());\n}(this, (function () { 'use strict';\n\n /*!\n * mustache.js - Logic-less {{mustache}} templates with JavaScript\n * http://github.com/janl/mustache.js\n */\n\n var objectToString = Object.prototype.toString;\n var isArray = Array.isArray || function isArrayPolyfill (object) {\n return objectToString.call(object) === '[object Array]';\n };\n\n function isFunction (object) {\n return typeof object === 'function';\n }\n\n /**\n * More correct typeof string handling array\n * which normally returns typeof 'object'\n */\n function typeStr (obj) {\n return isArray(obj) ? 'array' : typeof obj;\n }\n\n function escapeRegExp (string) {\n return string.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&');\n }\n\n /**\n * Null safe way of checking whether or not an object,\n * including its prototype, has a given property\n */\n function hasProperty (obj, propName) {\n return obj != null && typeof obj === 'object' && (propName in obj);\n }\n\n /**\n * Safe way of detecting whether or not the given thing is a primitive and\n * whether it has the given property\n */\n function primitiveHasOwnProperty (primitive, propName) {\n return (\n primitive != null\n && typeof primitive !== 'object'\n && primitive.hasOwnProperty\n && primitive.hasOwnProperty(propName)\n );\n }\n\n // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577\n // See https://github.com/janl/mustache.js/issues/189\n var regExpTest = RegExp.prototype.test;\n function testRegExp (re, string) {\n return regExpTest.call(re, string);\n }\n\n var nonSpaceRe = /\\S/;\n function isWhitespace (string) {\n return !testRegExp(nonSpaceRe, string);\n }\n\n var entityMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '='\n };\n\n function escapeHtml (string) {\n return String(string).replace(/[&<>\"'`=\\/]/g, function fromEntityMap (s) {\n return entityMap[s];\n });\n }\n\n var whiteRe = /\\s*/;\n var spaceRe = /\\s+/;\n var equalsRe = /\\s*=/;\n var curlyRe = /\\s*\\}/;\n var tagRe = /#|\\^|\\/|>|\\{|&|=|!/;\n\n /**\n * Breaks up the given `template` string into a tree of tokens. If the `tags`\n * argument is given here it must be an array with two string values: the\n * opening and closing tags used in the template (e.g. [ \"<%\", \"%>\" ]). Of\n * course, the default is to use mustaches (i.e. mustache.tags).\n *\n * A token is an array with at least 4 elements. The first element is the\n * mustache symbol that was used inside the tag, e.g. \"#\" or \"&\". If the tag\n * did not contain a symbol (i.e. {{myValue}}) this element is \"name\". For\n * all text that appears outside a symbol this element is \"text\".\n *\n * The second element of a token is its \"value\". For mustache tags this is\n * whatever else was inside the tag besides the opening symbol. For text tokens\n * this is the text itself.\n *\n * The third and fourth elements of the token are the start and end indices,\n * respectively, of the token in the original template.\n *\n * Tokens that are the root node of a subtree contain two more elements: 1) an\n * array of tokens in the subtree and 2) the index in the original template at\n * which the closing tag for that section begins.\n *\n * Tokens for partials also contain two more elements: 1) a string value of\n * indendation prior to that tag and 2) the index of that tag on that line -\n * eg a value of 2 indicates the partial is the third tag on this line.\n */\n function parseTemplate (template, tags) {\n if (!template)\n return [];\n var lineHasNonSpace = false;\n var sections = []; // Stack to hold section tokens\n var tokens = []; // Buffer to hold the tokens\n var spaces = []; // Indices of whitespace tokens on the current line\n var hasTag = false; // Is there a {{tag}} on the current line?\n var nonSpace = false; // Is there a non-space char on the current line?\n var indentation = ''; // Tracks indentation for tags that use it\n var tagIndex = 0; // Stores a count of number of tags encountered on a line\n\n // Strips all whitespace tokens array for the current line\n // if there was a {{#tag}} on it and otherwise only space.\n function stripSpace () {\n if (hasTag && !nonSpace) {\n while (spaces.length)\n delete tokens[spaces.pop()];\n } else {\n spaces = [];\n }\n\n hasTag = false;\n nonSpace = false;\n }\n\n var openingTagRe, closingTagRe, closingCurlyRe;\n function compileTags (tagsToCompile) {\n if (typeof tagsToCompile === 'string')\n tagsToCompile = tagsToCompile.split(spaceRe, 2);\n\n if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)\n throw new Error('Invalid tags: ' + tagsToCompile);\n\n openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\\\s*');\n closingTagRe = new RegExp('\\\\s*' + escapeRegExp(tagsToCompile[1]));\n closingCurlyRe = new RegExp('\\\\s*' + escapeRegExp('}' + tagsToCompile[1]));\n }\n\n compileTags(tags || mustache.tags);\n\n var scanner = new Scanner(template);\n\n var start, type, value, chr, token, openSection;\n while (!scanner.eos()) {\n start = scanner.pos;\n\n // Match any text between tags.\n value = scanner.scanUntil(openingTagRe);\n\n if (value) {\n for (var i = 0, valueLength = value.length; i < valueLength; ++i) {\n chr = value.charAt(i);\n\n if (isWhitespace(chr)) {\n spaces.push(tokens.length);\n indentation += chr;\n } else {\n nonSpace = true;\n lineHasNonSpace = true;\n indentation += ' ';\n }\n\n tokens.push([ 'text', chr, start, start + 1 ]);\n start += 1;\n\n // Check for whitespace on the current line.\n if (chr === '\\n') {\n stripSpace();\n indentation = '';\n tagIndex = 0;\n lineHasNonSpace = false;\n }\n }\n }\n\n // Match the opening tag.\n if (!scanner.scan(openingTagRe))\n break;\n\n hasTag = true;\n\n // Get the tag type.\n type = scanner.scan(tagRe) || 'name';\n scanner.scan(whiteRe);\n\n // Get the tag value.\n if (type === '=') {\n value = scanner.scanUntil(equalsRe);\n scanner.scan(equalsRe);\n scanner.scanUntil(closingTagRe);\n } else if (type === '{') {\n value = scanner.scanUntil(closingCurlyRe);\n scanner.scan(curlyRe);\n scanner.scanUntil(closingTagRe);\n type = '&';\n } else {\n value = scanner.scanUntil(closingTagRe);\n }\n\n // Match the closing tag.\n if (!scanner.scan(closingTagRe))\n throw new Error('Unclosed tag at ' + scanner.pos);\n\n if (type == '>') {\n token = [ type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace ];\n } else {\n token = [ type, value, start, scanner.pos ];\n }\n tagIndex++;\n tokens.push(token);\n\n if (type === '#' || type === '^') {\n sections.push(token);\n } else if (type === '/') {\n // Check section nesting.\n openSection = sections.pop();\n\n if (!openSection)\n throw new Error('Unopened section \"' + value + '\" at ' + start);\n\n if (openSection[1] !== value)\n throw new Error('Unclosed section \"' + openSection[1] + '\" at ' + start);\n } else if (type === 'name' || type === '{' || type === '&') {\n nonSpace = true;\n } else if (type === '=') {\n // Set the tags for the next time around.\n compileTags(value);\n }\n }\n\n stripSpace();\n\n // Make sure there are no open sections when we're done.\n openSection = sections.pop();\n\n if (openSection)\n throw new Error('Unclosed section \"' + openSection[1] + '\" at ' + scanner.pos);\n\n return nestTokens(squashTokens(tokens));\n }\n\n /**\n * Combines the values of consecutive text tokens in the given `tokens` array\n * to a single token.\n */\n function squashTokens (tokens) {\n var squashedTokens = [];\n\n var token, lastToken;\n for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n token = tokens[i];\n\n if (token) {\n if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {\n lastToken[1] += token[1];\n lastToken[3] = token[3];\n } else {\n squashedTokens.push(token);\n lastToken = token;\n }\n }\n }\n\n return squashedTokens;\n }\n\n /**\n * Forms the given array of `tokens` into a nested tree structure where\n * tokens that represent a section have two additional items: 1) an array of\n * all tokens that appear in that section and 2) the index in the original\n * template that represents the end of that section.\n */\n function nestTokens (tokens) {\n var nestedTokens = [];\n var collector = nestedTokens;\n var sections = [];\n\n var token, section;\n for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n token = tokens[i];\n\n switch (token[0]) {\n case '#':\n case '^':\n collector.push(token);\n sections.push(token);\n collector = token[4] = [];\n break;\n case '/':\n section = sections.pop();\n section[5] = token[2];\n collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;\n break;\n default:\n collector.push(token);\n }\n }\n\n return nestedTokens;\n }\n\n /**\n * A simple string scanner that is used by the template parser to find\n * tokens in template strings.\n */\n function Scanner (string) {\n this.string = string;\n this.tail = string;\n this.pos = 0;\n }\n\n /**\n * Returns `true` if the tail is empty (end of string).\n */\n Scanner.prototype.eos = function eos () {\n return this.tail === '';\n };\n\n /**\n * Tries to match the given regular expression at the current position.\n * Returns the matched text if it can match, the empty string otherwise.\n */\n Scanner.prototype.scan = function scan (re) {\n var match = this.tail.match(re);\n\n if (!match || match.index !== 0)\n return '';\n\n var string = match[0];\n\n this.tail = this.tail.substring(string.length);\n this.pos += string.length;\n\n return string;\n };\n\n /**\n * Skips all text until the given regular expression can be matched. Returns\n * the skipped string, which is the entire tail if no match can be made.\n */\n Scanner.prototype.scanUntil = function scanUntil (re) {\n var index = this.tail.search(re), match;\n\n switch (index) {\n case -1:\n match = this.tail;\n this.tail = '';\n break;\n case 0:\n match = '';\n break;\n default:\n match = this.tail.substring(0, index);\n this.tail = this.tail.substring(index);\n }\n\n this.pos += match.length;\n\n return match;\n };\n\n /**\n * Represents a rendering context by wrapping a view object and\n * maintaining a reference to the parent context.\n */\n function Context (view, parentContext) {\n this.view = view;\n this.cache = { '.': this.view };\n this.parent = parentContext;\n }\n\n /**\n * Creates a new context using the given view with this context\n * as the parent.\n */\n Context.prototype.push = function push (view) {\n return new Context(view, this);\n };\n\n /**\n * Returns the value of the given name in this context, traversing\n * up the context hierarchy if the value is absent in this context's view.\n */\n Context.prototype.lookup = function lookup (name) {\n var cache = this.cache;\n\n var value;\n if (cache.hasOwnProperty(name)) {\n value = cache[name];\n } else {\n var context = this, intermediateValue, names, index, lookupHit = false;\n\n while (context) {\n if (name.indexOf('.') > 0) {\n intermediateValue = context.view;\n names = name.split('.');\n index = 0;\n\n /**\n * Using the dot notion path in `name`, we descend through the\n * nested objects.\n *\n * To be certain that the lookup has been successful, we have to\n * check if the last object in the path actually has the property\n * we are looking for. We store the result in `lookupHit`.\n *\n * This is specially necessary for when the value has been set to\n * `undefined` and we want to avoid looking up parent contexts.\n *\n * In the case where dot notation is used, we consider the lookup\n * to be successful even if the last \"object\" in the path is\n * not actually an object but a primitive (e.g., a string, or an\n * integer), because it is sometimes useful to access a property\n * of an autoboxed primitive, such as the length of a string.\n **/\n while (intermediateValue != null && index < names.length) {\n if (index === names.length - 1)\n lookupHit = (\n hasProperty(intermediateValue, names[index])\n || primitiveHasOwnProperty(intermediateValue, names[index])\n );\n\n intermediateValue = intermediateValue[names[index++]];\n }\n } else {\n intermediateValue = context.view[name];\n\n /**\n * Only checking against `hasProperty`, which always returns `false` if\n * `context.view` is not an object. Deliberately omitting the check\n * against `primitiveHasOwnProperty` if dot notation is not used.\n *\n * Consider this example:\n * ```\n * Mustache.render(\"The length of a football field is {{#length}}{{length}}{{/length}}.\", {length: \"100 yards\"})\n * ```\n *\n * If we were to check also against `primitiveHasOwnProperty`, as we do\n * in the dot notation case, then render call would return:\n *\n * \"The length of a football field is 9.\"\n *\n * rather than the expected:\n *\n * \"The length of a football field is 100 yards.\"\n **/\n lookupHit = hasProperty(context.view, name);\n }\n\n if (lookupHit) {\n value = intermediateValue;\n break;\n }\n\n context = context.parent;\n }\n\n cache[name] = value;\n }\n\n if (isFunction(value))\n value = value.call(this.view);\n\n return value;\n };\n\n /**\n * A Writer knows how to take a stream of tokens and render them to a\n * string, given a context. It also maintains a cache of templates to\n * avoid the need to parse the same template twice.\n */\n function Writer () {\n this.templateCache = {\n _cache: {},\n set: function set (key, value) {\n this._cache[key] = value;\n },\n get: function get (key) {\n return this._cache[key];\n },\n clear: function clear () {\n this._cache = {};\n }\n };\n }\n\n /**\n * Clears all cached templates in this writer.\n */\n Writer.prototype.clearCache = function clearCache () {\n if (typeof this.templateCache !== 'undefined') {\n this.templateCache.clear();\n }\n };\n\n /**\n * Parses and caches the given `template` according to the given `tags` or\n * `mustache.tags` if `tags` is omitted, and returns the array of tokens\n * that is generated from the parse.\n */\n Writer.prototype.parse = function parse (template, tags) {\n var cache = this.templateCache;\n var cacheKey = template + ':' + (tags || mustache.tags).join(':');\n var isCacheEnabled = typeof cache !== 'undefined';\n var tokens = isCacheEnabled ? cache.get(cacheKey) : undefined;\n\n if (tokens == undefined) {\n tokens = parseTemplate(template, tags);\n isCacheEnabled && cache.set(cacheKey, tokens);\n }\n return tokens;\n };\n\n /**\n * High-level method that is used to render the given `template` with\n * the given `view`.\n *\n * The optional `partials` argument may be an object that contains the\n * names and templates of partials that are used in the template. It may\n * also be a function that is used to load partial templates on the fly\n * that takes a single argument: the name of the partial.\n *\n * If the optional `tags` argument is given here it must be an array with two\n * string values: the opening and closing tags used in the template (e.g.\n * [ \"<%\", \"%>\" ]). The default is to mustache.tags.\n */\n Writer.prototype.render = function render (template, view, partials, tags) {\n var tokens = this.parse(template, tags);\n var context = (view instanceof Context) ? view : new Context(view, undefined);\n return this.renderTokens(tokens, context, partials, template, tags);\n };\n\n /**\n * Low-level method that renders the given array of `tokens` using\n * the given `context` and `partials`.\n *\n * Note: The `originalTemplate` is only ever used to extract the portion\n * of the original template that was contained in a higher-order section.\n * If the template doesn't use higher-order sections, this argument may\n * be omitted.\n */\n Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, tags) {\n var buffer = '';\n\n var token, symbol, value;\n for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {\n value = undefined;\n token = tokens[i];\n symbol = token[0];\n\n if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate);\n else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate);\n else if (symbol === '>') value = this.renderPartial(token, context, partials, tags);\n else if (symbol === '&') value = this.unescapedValue(token, context);\n else if (symbol === 'name') value = this.escapedValue(token, context);\n else if (symbol === 'text') value = this.rawValue(token);\n\n if (value !== undefined)\n buffer += value;\n }\n\n return buffer;\n };\n\n Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate) {\n var self = this;\n var buffer = '';\n var value = context.lookup(token[1]);\n\n // This function is used to render an arbitrary template\n // in the current context by higher-order sections.\n function subRender (template) {\n return self.render(template, context, partials);\n }\n\n if (!value) return;\n\n if (isArray(value)) {\n for (var j = 0, valueLength = value.length; j < valueLength; ++j) {\n buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate);\n }\n } else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {\n buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate);\n } else if (isFunction(value)) {\n if (typeof originalTemplate !== 'string')\n throw new Error('Cannot use higher-order sections without the original template');\n\n // Extract the portion of the original template that the section contains.\n value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);\n\n if (value != null)\n buffer += value;\n } else {\n buffer += this.renderTokens(token[4], context, partials, originalTemplate);\n }\n return buffer;\n };\n\n Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate) {\n var value = context.lookup(token[1]);\n\n // Use JavaScript's definition of falsy. Include empty arrays.\n // See https://github.com/janl/mustache.js/issues/186\n if (!value || (isArray(value) && value.length === 0))\n return this.renderTokens(token[4], context, partials, originalTemplate);\n };\n\n Writer.prototype.indentPartial = function indentPartial (partial, indentation, lineHasNonSpace) {\n var filteredIndentation = indentation.replace(/[^ \\t]/g, '');\n var partialByNl = partial.split('\\n');\n for (var i = 0; i < partialByNl.length; i++) {\n if (partialByNl[i].length && (i > 0 || !lineHasNonSpace)) {\n partialByNl[i] = filteredIndentation + partialByNl[i];\n }\n }\n return partialByNl.join('\\n');\n };\n\n Writer.prototype.renderPartial = function renderPartial (token, context, partials, tags) {\n if (!partials) return;\n\n var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];\n if (value != null) {\n var lineHasNonSpace = token[6];\n var tagIndex = token[5];\n var indentation = token[4];\n var indentedValue = value;\n if (tagIndex == 0 && indentation) {\n indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);\n }\n return this.renderTokens(this.parse(indentedValue, tags), context, partials, indentedValue, tags);\n }\n };\n\n Writer.prototype.unescapedValue = function unescapedValue (token, context) {\n var value = context.lookup(token[1]);\n if (value != null)\n return value;\n };\n\n Writer.prototype.escapedValue = function escapedValue (token, context) {\n var value = context.lookup(token[1]);\n if (value != null)\n return mustache.escape(value);\n };\n\n Writer.prototype.rawValue = function rawValue (token) {\n return token[1];\n };\n\n var mustache = {\n name: 'mustache.js',\n version: '4.0.1',\n tags: [ '{{', '}}' ],\n clearCache: undefined,\n escape: undefined,\n parse: undefined,\n render: undefined,\n Scanner: undefined,\n Context: undefined,\n Writer: undefined,\n /**\n * Allows a user to override the default caching strategy, by providing an\n * object with set, get and clear methods. This can also be used to disable\n * the cache by setting it to the literal `undefined`.\n */\n set templateCache (cache) {\n defaultWriter.templateCache = cache;\n },\n /**\n * Gets the default or overridden caching object from the default writer.\n */\n get templateCache () {\n return defaultWriter.templateCache;\n }\n };\n\n // All high-level mustache.* functions use this writer.\n var defaultWriter = new Writer();\n\n /**\n * Clears all cached templates in the default writer.\n */\n mustache.clearCache = function clearCache () {\n return defaultWriter.clearCache();\n };\n\n /**\n * Parses and caches the given template in the default writer and returns the\n * array of tokens it contains. Doing this ahead of time avoids the need to\n * parse templates on the fly as they are rendered.\n */\n mustache.parse = function parse (template, tags) {\n return defaultWriter.parse(template, tags);\n };\n\n /**\n * Renders the `template` with the given `view` and `partials` using the\n * default writer. If the optional `tags` argument is given here it must be an\n * array with two string values: the opening and closing tags used in the\n * template (e.g. [ \"<%\", \"%>\" ]). The default is to mustache.tags.\n */\n mustache.render = function render (template, view, partials, tags) {\n if (typeof template !== 'string') {\n throw new TypeError('Invalid template! Template should be a \"string\" ' +\n 'but \"' + typeStr(template) + '\" was given as the first ' +\n 'argument for mustache#render(template, view, partials)');\n }\n\n return defaultWriter.render(template, view, partials, tags);\n };\n\n // Export the escaping function so that the user may override it.\n // See https://github.com/janl/mustache.js/issues/244\n mustache.escape = escapeHtml;\n\n // Export these mainly for testing, but also for advanced usage.\n mustache.Scanner = Scanner;\n mustache.Context = Context;\n mustache.Writer = Writer;\n\n return mustache;\n\n})));\n","import jQuery from 'jquery';\nimport _ from 'underscores';\nimport { dt } from 'window';\nimport Mustache from 'mustache';\n\nlet selectedConnections = {},\n\tsearchString = '';\nconst processTemplate = _.memoize( ( id ) => {\n\tconst element = document.getElementById( id );\n\tif ( ! element ) {\n\t\treturn false;\n\t}\n\n\tif ( element.attributes.template ) {\n\t\tMustache.parse( element.innerHTML );\n\t\treturn 'mustache';\n\t} else {\n\t\t// Use WordPress style Backbone template syntax\n\t\tconst options = {\n\t\t\tevaluate: /<#([\\s\\S]+?)#>/g,\n\t\t\tinterpolate: /{{{([\\s\\S]+?)}}}/g,\n\t\t\tescape: /{{([^}]+?)}}(?!})/g\n\t\t};\n\n\t\treturn _.template( element.innerHTML, null, options );\n\t}\n} );\n\njQuery( window ).on( 'load', () => {\n\tconst distributorAdminItem = document.querySelector( '#wp-admin-bar-distributor > a' );\n\tconst distributorTopMenu = document.querySelector( '#wp-admin-bar-distributor' );\n\tconst distributorMenuItem = document.querySelector( '#wp-admin-bar-distributor #wp-admin-bar-distributor-placeholder' );\n\tconst distributorPushWrapper = document.querySelector( '#distributor-push-wrapper' );\n\n\tif ( ! distributorMenuItem || ! distributorPushWrapper ) {\n\t\treturn;\n\t}\n\n\tlet dtConnections \t\t= '';\n\tlet connectionsSelected \t\t= '';\n\tlet connectionsSelectedList \t\t= '';\n\tlet connectionsNewList \t\t= '';\n\tlet connectionsNewListChildren \t= '';\n\tlet connectionsAvailableTotal\t\t= '';\n\tlet selectAllConnections \t\t\t= '';\n\tlet selectNoConnections\t\t\t\t= '';\n\tlet connectionsSearchInput \t\t= '';\n\tlet postStatusInput \t\t= '';\n\tlet asDraftInput \t\t= '';\n\tlet errorDetails \t\t= '';\n\n\tdistributorMenuItem.appendChild( distributorPushWrapper );\n\n\t/**\n\t * Set variables after connections have been rendered\n\t */\n\tfunction setVariables() {\n\t\tconnectionsSelected \t= distributorPushWrapper.querySelector( '.connections-selected' );\n\t\tconnectionsSelectedList \t= distributorPushWrapper.querySelector( '.selected-connections-list' );\n\t\tconnectionsNewList \t= distributorPushWrapper.querySelector( '.new-connections-list' );\n\t\tselectAllConnections \t\t= distributorPushWrapper.querySelector( '.selectall-connections' );\n\t\tselectNoConnections \t\t= distributorPushWrapper.querySelector( '.selectno-connections' );\n\t\tconnectionsSearchInput \t= document.getElementById( 'dt-connection-search' );\n\t\tpostStatusInput \t= document.getElementById( 'dt-post-status' );\n\t\tasDraftInput \t= document.getElementById( 'dt-as-draft' );\n\t\terrorDetails = document.querySelector( '.dt-error ul.details' );\n\n\t\tif ( null !== connectionsNewList ){\n\t\t\tconnectionsNewListChildren = connectionsNewList.querySelectorAll( '.add-connection' );\n\t\t}\n\n\t\t/**\n\t\t * Listen for connection filtering\n\t\t */\n\t\tjQuery( connectionsSearchInput ).on( 'keyup change', _.debounce( ( event ) => {\n\t\t\tif ( '' === event.currentTarget.value ) {\n\t\t\t\tshowConnections( dtConnections );\n\t\t\t}\n\t\t\tsearchString = event.currentTarget.value.replace( /https?:\\/\\//i, '' ).replace( /www/i, '' ).replace( /[^0-9a-zA-Z ]+/, '' );\n\t\t\tshowConnections();\n\t\t}, 300 ) );\n\n\t\t/**\n\t\t * Disable select all button if all connections are syndicated and set variable for total connections available\n\t\t */\n\t\t_.each( connectionsNewListChildren, ( element ) => {\n\t\t\tif ( ! element.classList.contains ( 'syndicated' ) ) {\n\t\t\t\tselectAllConnections.classList.remove( 'unavailable' );\n\t\t\t\tconnectionsAvailableTotal ++;\n\t\t\t}\n\t\t} );\n\n\t}\n\n\t/**\n\t * Set the disabled attribute on connections already syndicated\n\t *\n\t * This is currently only used for the mustache templates, which\n\t * are only used in AMP contexts. Seems the AMP plugin will\n\t * strip out any normal disabled attributes, so we handle that here\n\t * instead of in the template.\n\t */\n\tfunction setDisabledConnections() {\n\t\tconnectionsNewList = distributorPushWrapper.querySelector( '.new-connections-list' );\n\n\t\tif ( null !== connectionsNewList ) {\n\t\t\tconnectionsNewListChildren = connectionsNewList.querySelectorAll( '.add-connection' );\n\n\t\t\t_.each( connectionsNewListChildren, ( element ) => {\n\t\t\t\tif ( element.classList.contains ( 'syndicated' ) ) {\n\t\t\t\t\telement.disabled = true;\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Handle UI error changes\n\t */\n\tfunction doError( messages ) {\n\t\tdistributorPushWrapper.classList.add( 'message-error' );\n\t\terrorDetails.innerText = '';\n\n\t\t_.each( prepareMessages( messages ), function( message ) {\n\t\t\tconst errorItem = document.createElement( 'li' );\n\t\t\terrorItem.innerText = message;\n\t\t\terrorDetails.appendChild( errorItem );\n\t\t} );\n\t}\n\n\t/**\n\t * Prepare error messages for printing.\n\t *\n\t * @param {string|array} messages Error messages.\n\t */\n\tfunction prepareMessages( messages ) {\n\t\tif ( ! _.isArray( messages ) ) {\n\t\t\treturn [ messages ];\n\t\t}\n\n\t\treturn _.map( messages, function( message ) {\n\t\t\tif ( _.isString( message ) ) {\n\t\t\t\treturn message;\n\t\t\t}\n\t\t\tif ( _.has( message, 'message' ) ) {\n\t\t\t\treturn message.message;\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Handle UI success changes\n\t */\n\tfunction doSuccess( results ) {\n\t\tlet success = false;\n\t\tconst errors = {};\n\n\t\t[ 'internal', 'external' ].map( type => {\n\t\t\t_.each( results[type], ( result, connectionId ) => {\n\t\t\t\tif ( 'success' === result.status ) {\n\t\t\t\t\tdtConnections[ `${type}${ connectionId }` ].syndicated = result.url;\n\t\t\t\t\tsuccess = true;\n\t\t\t\t}\n\n\t\t\t\tif ( ! _.isEmpty( result.errors ) ) {\n\t\t\t\t\terrors[ `${type}${ connectionId }` ] = result.errors;\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\n\t\tif ( ! _.isEmpty( errors ) ) {\n\t\t\tconst formattedErrors = _.map( errors, function( messages, connectionId ) {\n\t\t\t\treturn `${dtConnections[ connectionId ].name }:\\n${\n\t\t\t\t\t_.map( messages, function( message ) {\n\t\t\t\t\t\treturn `- ${message}\\n`;\n\t\t\t\t\t} )}`;\n\t\t\t} );\n\n\t\t\tdoError( formattedErrors );\n\t\t}\n\n\t\tif ( success && _.isEmpty( errors ) ) {\n\t\t\tdistributorPushWrapper.classList.add( 'message-success' );\n\n\t\t\tconnectionsSelected.classList.add( 'empty' );\n\t\t\tconnectionsSelectedList.innerText = '';\n\n\t\t\tsetTimeout( () => {\n\t\t\t\tdistributorPushWrapper.classList.remove( 'message-success' );\n\t\t\t}, 6000 );\n\t\t}\n\n\t\tselectedConnections = {};\n\n\t\tshowConnections();\n\t}\n\n\t/**\n\t * Show connections. If there is a search string, then filter by it\n\t*/\n\tfunction showConnections() {\n\t\tconnectionsNewList.innerText = '';\n\t\tconst template = processTemplate( 'dt-add-connection' );\n\t\tlet showConnection = '';\n\n\t\t_.each( dtConnections, ( connection ) => {\n\t\t\tif ( '' !== searchString ) {\n\t\t\t\tconst nameMatch = connection.name.replace( /[^0-9a-zA-Z ]+/, '' ).toLowerCase().match( searchString.toLowerCase() );\n\t\t\t\tconst urlMatch = connection.url.replace( /https?:\\/\\//i, '' ).replace( /www/i, '' ).replace( /[^0-9a-zA-Z ]+/, '' ).toLowerCase().match( searchString.toLowerCase() );\n\n\t\t\t\tif ( ! nameMatch && ! urlMatch ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( 'mustache' === template ) {\n\t\t\t\t// Modify connection data to match what mustache wants\n\t\t\t\tif ( selectedConnections[connection.type + connection.id] ) {\n\t\t\t\t\tconnection.added = true;\n\t\t\t\t} else {\n\t\t\t\t\tconnection.added = false;\n\t\t\t\t}\n\n\t\t\t\tif ( 'internal' === connection.type ) {\n\t\t\t\t\tconnection.internal = true;\n\t\t\t\t}\n\n\t\t\t\tshowConnection = Mustache.render( document.getElementById( 'dt-add-connection' ).innerHTML, {\n\t\t\t\t\tconnection: connection,\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tshowConnection = template( {\n\t\t\t\t\tconnection: connection,\n\t\t\t\t\tselectedConnections: selectedConnections\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\tconnectionsNewList.innerHTML += showConnection;\n\t\t} );\n\n\t\tif ( '' === connectionsNewList.innerHTML ) {\n\t\t\tconnectionsNewList.innerHTML = 'No results
';\n\t\t}\n\n\t\tif ( 'mustache' === template ) {\n\t\t\tsetDisabledConnections();\n\t\t}\n\t}\n\n\t/**\n\t * Add or remove CSS classes to indicate button functionality\n\t*/\n\tfunction classList( expr ) {\n\t\tswitch ( expr ) {\n\t\t\t\tcase 'addEmpty':\n\t\t\t\t\tconnectionsSelected.classList.add( 'empty' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'removeEmpty':\n\t\t\t\t\tconnectionsSelected.classList.remove( 'empty' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'allUnavailable':\n\t\t\t\t\tselectAllConnections.classList.add ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'all':\n\t\t\t\t\tselectAllConnections.classList.remove ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'noneUnavailable':\n\t\t\t\t\tselectNoConnections.classList.add ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'none':\n\t\t\t\t\tselectNoConnections.classList.remove ( 'unavailable' );\n\t\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle distributor push dropdown menu.\n\t */\n\tfunction distributorMenuEntered() {\n\t\tdistributorMenuItem.focus();\n\n\t\tif ( distributorPushWrapper.classList.contains( 'loaded' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdistributorPushWrapper.classList.remove( 'message-error' );\n\t\tdistributorPushWrapper.classList.add( 'loaded' );\n\n\t\tconst data = {\n\t\t\taction: 'dt_load_connections',\n\t\t\tloadConnectionsNonce: dt.loadConnectionsNonce,\n\t\t\tpostId: dt.postId\n\t\t};\n\n\t\tconst template = processTemplate( 'dt-show-connections' );\n\t\tconst xhr = dt.usexhr ? { withCredentials: true } : false;\n\n\t\tjQuery.ajax( {\n\t\t\turl: dt.ajaxurl,\n\t\t\txhrFields: xhr,\n\t\t\tmethod: 'post',\n\t\t\tdata: data\n\t\t} ).done( ( response ) => {\n\t\t\tif ( ! response.success || ! response.data ) {\n\t\t\t\tdistributorPushWrapper.classList.remove( 'loaded' );\n\t\t\t\tdistributorPushWrapper.classList.add( 'message-error' );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tdtConnections = response.data;\n\n\t\t\tif ( 'mustache' === template ) {\n\t\t\t\t// Manipulate the data to match what mustache needs\n\t\t\t\tconst mustacheData = { 'connections' : [] };\n\t\t\t\t_.each( dtConnections, ( connection ) => {\n\t\t\t\t\tif ( 'internal' === connection.type ) {\n\t\t\t\t\t\tconnection.internal = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tmustacheData.connections.push( connection );\n\t\t\t\t} );\n\n\t\t\t\tdistributorPushWrapper.innerHTML = Mustache.render( document.getElementById( 'dt-show-connections' ).innerHTML, {\n\t\t\t\t\tconnections: mustacheData.connections,\n\t\t\t\t\tfoundConnections: mustacheData.connections.length,\n\t\t\t\t\tshowSearch: 5 < mustacheData.connections.length,\n\t\t\t\t} );\n\n\t\t\t\tsetDisabledConnections();\n\t\t\t} else {\n\t\t\t\tdistributorPushWrapper.innerHTML = template( {\n\t\t\t\t\tconnections: dtConnections,\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\tsetVariables();\n\t\t} ).error( () => {\n\t\t\tdistributorPushWrapper.classList.remove( 'loaded' );\n\t\t\tdistributorPushWrapper.classList.add( 'message-error' );\n\t\t} );\n\t}\n\n\t// Event listerners when to fetch distributor data.\n\tdistributorAdminItem.addEventListener( 'keydown', function( e ) {\n\t\t// Pressing Enter.\n\t\tif ( ( 13 === e.keyCode ) ) {\n\t\t\tdistributorMenuEntered();\n\t\t}\n\t}, false );\n\n\tdistributorAdminItem.addEventListener( 'touchstart', distributorMenuEntered, false );\n\tdistributorAdminItem.addEventListener( 'mouseenter', distributorMenuEntered, false );\n\n\t/**\n\t * Do syndication ajax\n\t */\n\tjQuery( distributorPushWrapper ).on( 'click', '.syndicate-button', () => {\n\t\tif ( distributorTopMenu.classList.contains( 'syncing' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdistributorTopMenu.classList.add( 'syncing' );\n\n\t\tconst data = {\n\t\t\taction: 'dt_push',\n\t\t\tnonce: dt.nonce,\n\t\t\tconnections: selectedConnections,\n\t\t\tpostId: dt.postId\n\t\t};\n\n\t\tdata.postStatus = ( null !== asDraftInput && asDraftInput.checked ) ? 'draft' : postStatusInput.value;\n\n\t\tconst xhr = dt.usexhr ? { withCredentials: true } : false;\n\n\t\tjQuery.ajax( {\n\t\t\turl: dt.ajaxurl,\n\t\t\txhrFields: xhr,\n\t\t\tmethod: 'post',\n\t\t\tdata: data\n\t\t} ).done( ( response ) => {\n\t\t\tsetTimeout( () => {\n\t\t\t\tdistributorTopMenu.classList.remove( 'syncing' );\n\n\t\t\t\tif ( ! response.success ) {\n\t\t\t\t\tdoError( response.data );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( ! response.data || ! response.data.results ) {\n\t\t\t\t\tdoError( dt.messages.empty_result );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tdoSuccess( response.data.results );\n\t\t\t}, 500 );\n\t\t} ).error( ( xhr, textStatus, errorThrown ) => {\n\t\t\tsetTimeout( () => {\n\t\t\t\tdistributorTopMenu.classList.remove( 'syncing' );\n\n\t\t\t\tdoError( `${dt.messages.ajax_error} ${errorThrown}` );\n\t\t\t}, 500 );\n\t\t} );\n\t} );\n\n\t/**\n\t * Add a connection to selected connections for ajax and to the UI list.\n\t */\n\tjQuery( distributorPushWrapper ).on( 'click', '.add-connection', ( event ) => {\n\t\tif ( 'A' === event.target.nodeName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.preventDefault();\n\n\t\tif ( event.currentTarget.classList.contains( 'syndicated' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( event.currentTarget.classList.contains( 'added' ) ) {\n\t\t\tconst type = event.currentTarget.getAttribute( 'data-connection-type' );\n\t\t\tconst id = event.currentTarget.getAttribute( 'data-connection-id' );\n\n\t\t\tconst deleteNode = connectionsSelectedList.querySelector( `[data-connection-id=\"${ id }\"][data-connection-type=\"${ type }\"]` );\n\n\t\t\tdeleteNode.parentNode.removeChild( deleteNode );\n\n\t\t\tdelete selectedConnections[type + id];\n\n\t\t\tif ( selectAllConnections.classList.contains ( 'unavailable' ) ) {\n\t\t\t\tclassList ( 'all' );\n\t\t\t}\n\t\t\tif ( ! Object.keys( selectedConnections ).length ) {\n\t\t\t\tclassList ( 'addEmpty' );\n\t\t\t\tclassList ( 'noneUnavailable' );\n\t\t\t}\n\n\t\t\tshowConnections();\n\t\t} else {\n\t\t\tconst type = event.currentTarget.getAttribute( 'data-connection-type' );\n\t\t\tconst id = event.currentTarget.getAttribute( 'data-connection-id' );\n\n\t\t\tselectedConnections[type + id] = dtConnections[type + id];\n\n\t\t\tconst element = event.currentTarget.cloneNode( true );\n\n\t\t\tconst removeLink = document.createElement( 'span' );\n\t\t\tremoveLink.classList.add( 'remove-connection' );\n\n\t\t\telement.appendChild( removeLink );\n\t\t\telement.classList = 'added-connection';\n\t\t\tconnectionsSelectedList.appendChild( element );\n\n\t\t\tif ( selectNoConnections.classList.contains ( 'unavailable' ) ) {\n\t\t\t\tclassList ( 'removeEmpty' );\n\t\t\t\tclassList ( 'none' );\n\t\t\t}\n\n\t\t\tif ( Object.keys( selectedConnections ).length == connectionsAvailableTotal ){\n\t\t\t\tclassList ( 'allUnavailable' );\n\t\t\t}\n\n\t\t\tshowConnections();\n\t\t}\n\t} );\n\n\t/**\n\t * Select all connections for distribution.\n\t*/\n\tjQuery( distributorPushWrapper ).on( 'click', '.selectall-connections', () => {\n\t\tjQuery ( connectionsNewList ).children( '.add-connection' ).each( ( index, childTarget ) => {\n\t\t\tif ( childTarget.classList.contains( 'syndicated' ) || childTarget.classList.contains( 'added' ) ) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tconst type = childTarget.getAttribute( 'data-connection-type' );\n\t\t\t\tconst id = childTarget.getAttribute( 'data-connection-id' );\n\n\t\t\t\tselectedConnections[type + id] = dtConnections[type + id];\n\n\t\t\t\tconst element = childTarget.cloneNode();\n\t\t\t\telement.innerText = childTarget.innerText;\n\n\t\t\t\tconst removeLink = document.createElement( 'span' );\n\t\t\t\tremoveLink.classList.add( 'remove-connection' );\n\n\t\t\t\telement.appendChild( removeLink );\n\t\t\t\telement.classList = 'added-connection';\n\n\t\t\t\tconnectionsSelectedList.appendChild( element );\n\n\t\t\t}\n\n\t\t\tif ( '' !== connectionsAvailableTotal ) {\n\t\t\t\tclassList ( 'removeEmpty' );\n\t\t\t\tclassList ( 'allUnavailable' );\n\t\t\t\tclassList ( 'none' );\n\t\t\t}\n\n\t\t} );\n\n\t\tshowConnections();\n\t} );\n\n\t/**\n\t * Select no connections for distribution.\n\t*/\n\tjQuery( distributorPushWrapper ).on( 'click', '.selectno-connections', () => {\n\n\t\twhile ( connectionsSelectedList.firstChild ) {\n\t\t\tconst type = connectionsSelectedList.firstChild.getAttribute( 'data-connection-type' );\n\t\t\tconst id = connectionsSelectedList.firstChild.getAttribute( 'data-connection-id' );\n\n\t\t\tdelete selectedConnections[type + id];\n\n\t\t\tconnectionsSelectedList.removeChild( connectionsSelectedList.firstChild );\n\n\t\t}\n\n\t\tif ( '' !== connectionsAvailableTotal ) {\n\t\t\tclassList ( 'addEmpty' );\n\t\t\tclassList ( 'noneUnavailable' );\n\t\t\tclassList ( 'all' );\n\t\t}\n\n\t\tshowConnections();\n\t} );\n\n\t/**\n\t * Remove a connection from selected connections and the UI list\n\t */\n\tjQuery( distributorPushWrapper ).on( 'click', '.added-connection', ( event ) => {\n\t\tevent.currentTarget.parentNode.removeChild( event.currentTarget );\n\t\tconst type = event.currentTarget.getAttribute( 'data-connection-type' );\n\t\tconst id = event.currentTarget.getAttribute( 'data-connection-id' );\n\n\t\tdelete selectedConnections[type + id];\n\n\t\tif ( selectAllConnections.classList.contains ( 'unavailable' ) ) {\n\t\t\tclassList ( 'all' );\n\t\t}\n\t\tif ( ! Object.keys( selectedConnections ).length ) {\n\t\t\tclassList ( 'addEmpty' );\n\t\t\tclassList ( 'noneUnavailable' );\n\t\t}\n\n\t\tshowConnections();\n\t} );\n} );\n"],"sourceRoot":""} \ No newline at end of file diff --git a/distributor.php b/distributor.php index 39ef59b51..d767e0f11 100644 --- a/distributor.php +++ b/distributor.php @@ -2,7 +2,7 @@ /** * Plugin Name: Distributor * Description: Makes it easy to distribute and reuse content across your websites, whether inside of a multisite or across the web. - * Version: 1.6.0 + * Version: 1.6.1 * Author: 10up Inc. * Author URI: https://distributorplugin.com * License: GPLv2 or later @@ -17,8 +17,9 @@ exit; // Exit if accessed directly. } -define( 'DT_VERSION', '1.6.0' ); +define( 'DT_VERSION', '1.6.1' ); define( 'DT_PLUGIN_FILE', preg_replace( '#^.*plugins/(.*)$#i', '$1', __FILE__ ) ); +define( 'DT_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); // Define a constant if we're network activated to allow plugin to respond accordingly. $active_plugins = get_site_option( 'active_sitewide_plugins' ); diff --git a/includes/classes/Connection.php b/includes/classes/Connection.php index e2648830d..72af93b0d 100644 --- a/includes/classes/Connection.php +++ b/includes/classes/Connection.php @@ -18,7 +18,7 @@ abstract class Connection { * @param int $item_id Item ID to push if an update. * @param array $args Array of args to push. * @since 0.8 - * @return bool|WP_Error + * @return array|\WP_Error */ abstract public function push( $item_id, $args = array() ); diff --git a/includes/classes/ExternalConnections/WordPressExternalConnection.php b/includes/classes/ExternalConnections/WordPressExternalConnection.php index 9cb5cea5d..8b377f463 100644 --- a/includes/classes/ExternalConnections/WordPressExternalConnection.php +++ b/includes/classes/ExternalConnections/WordPressExternalConnection.php @@ -480,7 +480,7 @@ public function pull( $items ) { * @param int $post_id Post id * @param array $args Post args to push. * @since 0.8 - * @return bool|\WP_Error + * @return array|\WP_Error */ public function push( $post_id, $args = array() ) { if ( empty( $post_id ) ) { @@ -658,7 +658,15 @@ public function push( $post_id, $args = array() ) { \Distributor\Subscriptions\create_subscription( $post_id, $body_array['id'], untrailingslashit( $this->base_url ), $signature ); } - return $body_array['id']; + $remote_post = array( + 'id' => $body_array['id'], + ); + + if ( ! empty( $body_array['push-errors'] ) ) { + $remote_post['push-errors'] = $body_array['push-errors']; + } + + return $remote_post; } /** @@ -733,6 +741,7 @@ public function check_connections() { } else { $response = wp_remote_get( untrailingslashit( $this->base_url ), $this->auth_handler->format_get_args( array( 'timeout' => self::$timeout ) ) ); } + $body = wp_remote_retrieve_body( $response ); if ( is_wp_error( $response ) || empty( $body ) ) { @@ -787,70 +796,67 @@ public function check_connections() { } else { $types_response = wp_remote_get( $types_path, $this->auth_handler->format_get_args( array( 'timeout' => self::$timeout ) ) ); } + $types_body = wp_remote_retrieve_body( $types_response ); + $types = json_decode( $types_body, true ); - if ( is_wp_error( $types_response ) || empty( $types_body ) ) { + if ( is_wp_error( $types_response ) || 200 !== wp_remote_retrieve_response_code( $types_response ) || empty( $types_body ) || empty( $types ) ) { $output['errors']['no_types'] = 'no_types'; } else { - $types = json_decode( $types_body, true ); + $can_get = array(); + $can_post = array(); - if ( 200 !== wp_remote_retrieve_response_code( $types_response ) || empty( $types ) ) { - $output['errors']['no_types'] = 'no_types'; - } else { - $can_get = array(); - $can_post = array(); - - $permission_url = untrailingslashit( $this->base_url ) . '/' . self::$namespace . '/distributor/post-types-permissions'; - - if ( function_exists( 'vip_safe_wp_remote_get' ) && \Distributor\Utils\is_vip_com() ) { - $permission_response = vip_safe_wp_remote_get( - $permission_url, - false, - 3, - 3, - 10, - $this->auth_handler->format_get_args() - ); - } else { + $permission_url = untrailingslashit( $this->base_url ) . '/' . self::$namespace . '/distributor/post-types-permissions'; - $permission_response = wp_remote_get( - $permission_url, - $this->auth_handler->format_get_args( - array( - 'timeout' => self::$timeout, - ) + if ( function_exists( 'vip_safe_wp_remote_get' ) && \Distributor\Utils\is_vip_com() ) { + $permission_response = vip_safe_wp_remote_get( + $permission_url, + false, + 3, + 3, + 10, + $this->auth_handler->format_get_args() + ); + } else { + $permission_response = wp_remote_get( + $permission_url, + $this->auth_handler->format_get_args( + array( + 'timeout' => self::$timeout, ) - ); - } + ) + ); + } - $permissions = json_decode( wp_remote_retrieve_body( $permission_response ) ); + $permissions = json_decode( wp_remote_retrieve_body( $permission_response ) ); - if ( - is_wp_error( $permission_response ) - || empty( $permissions ) - || ! isset( $permissions->can_get ) - || ! isset( $permissions->can_post ) - ) { - $output['errors']['no_permissions'] = 'no_permissions'; - } else { - $can_get = array_values( - array_filter( - $permissions->can_get, - [ $this, 'not_distributor_internal_post_type' ] - ) - ); + $output['is_authenticated'] = isset( $permissions->is_authenticated ) ? $permissions->is_authenticated : 'na'; - $can_post = array_values( - array_filter( - $permissions->can_post, - [ $this, 'not_distributor_internal_post_type' ] - ) - ); - } + if ( + is_wp_error( $permission_response ) + || empty( $permissions ) + || ! isset( $permissions->can_get ) + || ! isset( $permissions->can_post ) + ) { + $output['errors']['no_permissions'] = 'no_permissions'; + } else { + $can_get = array_values( + array_filter( + $permissions->can_get, + [ $this, 'not_distributor_internal_post_type' ] + ) + ); - $output['can_get'] = $can_get; - $output['can_post'] = $can_post; + $can_post = array_values( + array_filter( + $permissions->can_post, + [ $this, 'not_distributor_internal_post_type' ] + ) + ); } + + $output['can_get'] = $can_get; + $output['can_post'] = $can_post; } return $output; diff --git a/includes/classes/InternalConnections/NetworkSiteConnection.php b/includes/classes/InternalConnections/NetworkSiteConnection.php index fe0d8c079..0c330206f 100644 --- a/includes/classes/InternalConnections/NetworkSiteConnection.php +++ b/includes/classes/InternalConnections/NetworkSiteConnection.php @@ -60,13 +60,14 @@ public function __construct( WP_Site $site ) { * @param int $post_id Post ID. * @param array $args Push args. * @since 0.8 - * @return int|WP_Error + * @return array|\WP_Error */ public function push( $post_id, $args = array() ) { $post = get_post( $post_id ); $original_blog_id = get_current_blog_id(); $original_post_url = get_permalink( $post_id ); $using_gutenberg = \Distributor\Utils\is_using_gutenberg( $post ); + $output = array(); $new_post_args = array( 'post_title' => get_the_title( $post_id ), @@ -115,6 +116,8 @@ public function push( $post_id, $args = array() ) { remove_filter( 'wp_insert_post_data', array( '\Distributor\InternalConnections\NetworkSiteConnection', 'maybe_set_modified_date' ), 10, 2 ); if ( ! is_wp_error( $new_post_id ) ) { + $output['id'] = $new_post_id; + update_post_meta( $new_post_id, 'dt_original_post_id', (int) $post_id ); update_post_meta( $new_post_id, 'dt_original_blog_id', (int) $original_blog_id ); update_post_meta( $new_post_id, 'dt_syndicate_time', time() ); @@ -144,6 +147,13 @@ public function push( $post_id, $args = array() ) { if ( apply_filters( 'dt_push_post_media', true, $new_post_id, $post->media, $post_id, $args, $this ) ) { Utils\set_media( $new_post_id, $post->media, [ 'use_filesystem' => true ] ); }; + + $media_errors = get_transient( 'dt_media_errors_' . $new_post_id ); + + if ( $media_errors ) { + $output['push-errors'] = $media_errors; + delete_transient( 'dt_media_errors_' . $new_post_id ); + } } /** @@ -160,7 +170,11 @@ public function push( $post_id, $args = array() ) { restore_current_blog(); - return $new_post_id; + if ( is_wp_error( $new_post_id ) ) { + return $new_post_id; + } + + return $output; } /** diff --git a/includes/external-connection-cpt.php b/includes/external-connection-cpt.php index 22a811be6..40e509a7c 100644 --- a/includes/external-connection-cpt.php +++ b/includes/external-connection-cpt.php @@ -281,10 +281,11 @@ function admin_enqueue_scripts( $hook ) { 'good_connection' => esc_html__( 'Connection established.', 'distributor' ), 'limited_connection' => esc_html__( 'Limited connection established.', 'distributor' ), 'no_push' => esc_html__( 'Push distribution unavailable.', 'distributor' ), + 'no_permissions' => esc_html__( 'Authentication succeeded but your account does not have permissions to create posts on the external site.', 'distributor' ), 'pull_limited' => esc_html__( 'Pull distribution limited to basic content, i.e. title and content body.', 'distributor' ), 'endpoint_suggestion' => esc_html__( 'Did you mean: ', 'distributor' ), 'endpoint_checking_message' => esc_html__( 'Checking endpoint...', 'distributor' ), - 'bad_auth' => esc_html__( 'Authentication failed.', 'distributor' ), + 'bad_auth' => esc_html__( 'Authentication failed due to invalid credentials.', 'distributor' ), 'change' => esc_html__( 'Change', 'distributor' ), 'cancel' => esc_html__( 'Cancel', 'distributor' ), 'invalid_url' => esc_html__( 'Please enter a valid URL, including the HTTP(S).', 'distributor' ), @@ -444,6 +445,15 @@ function meta_box_external_connection_details( $post ) { $external_connection_url = ''; } + $external_connection_status = get_post_meta( $post->ID, 'dt_external_connections', true ); + + $post_types = get_post_types( + array( + 'show_in_rest' => true, + ), + 'objects' + ); + $registered_external_connection_types = \Distributor\Connections::factory()->get_registered(); foreach ( $registered_external_connection_types as $slug => $class ) { @@ -469,7 +479,7 @@ function meta_box_external_connection_details( $post ) { ?>- +