Nav Menu Roles - Version 2.1.0

Version Description

  • New: Add support for "hiding" a menu item by role.
Download this release

Release Info

Developer helgatheviking
Plugin Icon 128x128 Nav Menu Roles
Version 2.1.0
Comparing to
See all releases

Code changes from version 2.0.2 to 2.1.0

dist/customize-controls.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array(), 'version' => '5e56aaf00e61acd0f8b2ae0ce3240ca8');
dist/customize-controls.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){function n(e,n){e.set(Object.assign({},_.clone(e()),{roles:n}))}function i(e){const n=e.setting().roles||"",i="hide"===e.setting().display_mode?"hide":"show",t=_.isArray(n)?"in":n,d=_.isArray(n)?n:[];e.rolesFieldset.toggle("in"===t);const o=e.modeFieldset.find(`input[type = radio][value = "${i}"]`),s=e.authFieldset.find(`input[type = radio][value = "${t}"]`);o.prop("checked",!0),s.prop("checked",!0),e.rolesFieldset.find("input[type=checkbox]").each((function(){this.checked=d.includes(this.value)}))}e.control.bind("add",(t=>{t.extended(e.Menus.MenuItemControl)&&t.deferred.embedded.done((()=>{!function(e){e.modeFieldset=e.container.find(".nav_menu_role_display_mode"),e.authFieldset=e.container.find(".nav_menu_role_authentication"),e.rolesFieldset=e.container.find(".nav_menu_roles"),i(e),e.setting.bind((()=>{i(e)})),e.modeFieldset.find("input").on("click",(function(){var n,i;n=e.setting,i=this.value,n.set(Object.assign({},_.clone(n()),{display_mode:i}))})),e.authFieldset.find("input").on("click",(function(){n(e.setting,this.value)})),e.rolesFieldset.find("input").on("click",(function(){const i=[];e.rolesFieldset.find(":checked").each((function(){i.push(this.value)})),n(e.setting,0===i.length?"in":i)}))}(t)}))}))}(wp.customize);
dist/js/customize.js DELETED
@@ -1,2 +0,0 @@
1
- !function(e){var n={};function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:i})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(i,o,function(n){return e[n]}.bind(null,o));return i},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=0)}([function(e,n){!function(e){function n(e,n){e.set(Object.assign({},_.clone(e()),{roles:n}))}function t(e){var n=e.setting().roles||"",t=_.isArray(n)?"in":n,i=_.isArray(n)?n:[];e.rolesFieldset.toggle("in"===t),e.authFieldset.find('input[type = radio][value = "'.concat(t,'"]')).prop("checked",!0),e.rolesFieldset.find("input[type=checkbox]").each((function(){this.checked=i.includes(this.value)}))}e.control.bind("add",(function(i){i.extended(e.Menus.MenuItemControl)&&i.deferred.embedded.done((function(){!function(e){e.authFieldset=e.container.find(".nav_menu_role_authentication"),e.rolesFieldset=e.container.find(".nav_menu_roles"),t(e),e.setting.bind((function(){t(e)})),e.authFieldset.find("input").on("click",(function(){n(e.setting,this.value)})),e.rolesFieldset.find("input").on("click",(function(){var t=[];e.rolesFieldset.find(":checked").each((function(){t.push(this.value)})),n(e.setting,0===t.length?"in":t)}))}(i)}))}))}(wp.customize)}]);
2
- //# sourceMappingURL=customize.js.map
 
 
dist/js/customize.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/js/nav-menu-roles-customize-controls.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","api","setSettingRoles","setting","roles","set","assign","_","clone","updateControlFields","control","radioValue","isArray","checkedRoles","rolesFieldset","toggle","authFieldset","find","prop","each","this","checked","includes","extended","Menus","MenuItemControl","deferred","embedded","done","container","on","push","length","extendControl","wp","customize"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,G,iBC5ErD,SAAaC,GA8DZ,SAASC,EAAiBC,EAASC,GAClCD,EAAQE,IACP1B,OAAO2B,OACN,GACAC,EAAEC,MAAOL,KACT,CAAEC,WAUL,SAASK,EAAqBC,GAC7B,IAAMN,EAAQM,EAAQP,UAAUC,OAAS,GAEnCO,EAAeJ,EAAEK,QAASR,GAAU,KAAOA,EAC3CS,EAAeN,EAAEK,QAASR,GAAUA,EAAQ,GAElDM,EAAQI,cAAcC,OAAQ,OAASJ,GAErBD,EAAQM,aAAaC,KAArB,uCAA4DN,EAA5D,OAERO,KAAM,WAAW,GAE3BR,EAAQI,cAAcG,KAAM,wBAAyBE,MACpD,WACCC,KAAKC,QAAUR,EAAaS,SAAUF,KAAKlC,UAxF9Ce,EAAIS,QAAQjB,KACX,OACA,SAAEiB,GACIA,EAAQa,SAAUtB,EAAIuB,MAAMC,kBAChCf,EAAQgB,SAASC,SAASC,MAC1B,YAaH,SAAwBlB,GACvBA,EAAQM,aAAgBN,EAAQmB,UAAUZ,KAAM,iCAChDP,EAAQI,cAAgBJ,EAAQmB,UAAUZ,KAAM,mBAGhDR,EAAqBC,GAGrBA,EAAQP,QAAQV,MACf,WACCgB,EAAqBC,MAKvBA,EAAQM,aAAaC,KAAM,SAAUa,GACpC,SACA,WACC5B,EAAiBQ,EAAQP,QAASiB,KAAKlC,UAGzCwB,EAAQI,cAAcG,KAAM,SAAUa,GACrC,SACA,WACC,IAAMjB,EAAe,GACrBH,EAAQI,cAAcG,KAAM,YAAaE,MACxC,WACCN,EAAakB,KAAMX,KAAKlC,UAG1BgB,EAAiBQ,EAAQP,QAAiC,IAAxBU,EAAamB,OAAe,KAAOnB,MA1CpEoB,CAAevB,SATpB,CA+FIwB,GAAGC","file":"customize.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 = 0);\n","/**\r\n * Customizer scripts.\r\n *\r\n * @package Nav Menu Roles\r\n */\r\n\r\n( function ( api ) {\r\n\r\n\t// Augment each menu item control once it is added and embedded.\r\n\tapi.control.bind(\r\n\t\t'add',\r\n\t\t( control ) => {\r\n\t\t\tif ( control.extended( api.Menus.MenuItemControl ) ) {\r\n\t\t\t\tcontrol.deferred.embedded.done(\r\n\t\t\t\t() => {\r\n\t\t\t\t\textendControl( control );\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\r\n\t/**\r\n\t * Extend the control with roles information.\r\n\t *\r\n\t * @param {wp.customize.Menus.MenuItemControl} control\r\n\t */\r\n\tfunction extendControl( control ) {\r\n\t\tcontrol.authFieldset = control.container.find( '.nav_menu_role_authentication' );\r\n\t\tcontrol.rolesFieldset = control.container.find( '.nav_menu_roles' );\r\n\r\n\t\t// Set the initial UI state.\r\n\t\tupdateControlFields( control );\r\n\r\n\t\t// Update the UI state when the setting changes programmatically.\r\n\t\tcontrol.setting.bind(\r\n\t\t\t() => {\r\n\t\t\t\tupdateControlFields( control );\r\n\t\t\t}\r\n\t\t);\r\n\r\n\t\t// Update the setting when the inputs are modified.\r\n\t\tcontrol.authFieldset.find( 'input' ).on(\r\n\t\t\t'click',\r\n\t\t\tfunction () {\r\n\t\t\t\tsetSettingRoles( control.setting, this.value );\r\n\t\t\t}\r\n\t\t);\r\n\t\tcontrol.rolesFieldset.find( 'input' ).on(\r\n\t\t\t'click',\r\n\t\t\tfunction () {\r\n\t\t\t\tconst checkedRoles = [];\r\n\t\t\t\tcontrol.rolesFieldset.find( ':checked' ).each(\r\n\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\tcheckedRoles.push( this.value );\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\t\tsetSettingRoles( control.setting, checkedRoles.length === 0 ? 'in' : checkedRoles );\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Extend the setting with roles information.\r\n\t *\r\n\t * @param {wp.customize.Setting} setting\r\n\t * @param {string|Array} roles\r\n\t */\r\n\tfunction setSettingRoles( setting, roles ) {\r\n\t\tsetting.set(\r\n\t\t\tObject.assign(\r\n\t\t\t\t{},\r\n\t\t\t\t_.clone( setting() ),\r\n\t\t\t\t{ roles }\r\n\t\t\t)\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Apply the control's setting value to the control's fields.\r\n\t *\r\n\t * @param {wp.customize.Menus.MenuItemControl} control\r\n\t */\r\n\tfunction updateControlFields( control ) {\r\n\t\tconst roles = control.setting().roles || '';\r\n\r\n\t\tconst radioValue = _.isArray( roles ) ? 'in' : roles;\r\n\t\tconst checkedRoles = _.isArray( roles ) ? roles : [];\r\n\r\n\t\tcontrol.rolesFieldset.toggle( 'in' === radioValue );\r\n\r\n\t\tconst authRadio = control.authFieldset.find( `input[type = radio][value = \"${ radioValue }\"]` );\r\n\r\n\t\tauthRadio.prop( 'checked', true );\r\n\r\n\t\tcontrol.rolesFieldset.find( 'input[type=checkbox]' ).each(\r\n\t\t\tfunction () {\r\n\t\t\t\tthis.checked = checkedRoles.includes( this.value );\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n})( wp.customize );\r\n"],"sourceRoot":""}
 
dist/js/roles.js DELETED
@@ -1,2 +0,0 @@
1
- !function(e){var n={};function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:o})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(t.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)t.d(o,r,function(n){return e[n]}.bind(null,r));return o},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=1)}([,function(e,n){var t;(t=jQuery)(".nav_menu_logged_in_out_field").each((function(e){var n=t(this);n.find("input.nav-menu-id").val(),"in"===n.find("input.nav-menu-logged-in-out:checked").val()?n.next(".nav_menu_role_field").show():n.next(".nav_menu_role_field").hide()})),t("#menu-to-edit").on("change","input.nav-menu-logged-in-out",(function(){"in"===t(this).val()?t(this).parentsUntil(".nav_menu_logged_in_out").next(".nav_menu_role_field").slideDown():t(this).parentsUntil(".nav_menu_logged_in_out").next(".nav_menu_role_field").slideUp()}))}]);
2
- //# sourceMappingURL=roles.js.map
 
 
dist/js/roles.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/js/nav-menu-roles.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","$","jQuery","each","$field","this","find","val","next","show","hide","on","parentsUntil","slideDown","slideUp"],"mappings":"aACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QAKfF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,G,iBC7ErD,IAAUC,KA+BNC,QA7BA,iCAAkCC,MACpC,SAASlC,GAER,IAAImC,EAASH,EAAGI,MAEPD,EAAOE,KAAM,qBAAsBC,MAGyB,OAAhEH,EAAOE,KAAM,wCAAyCC,MAC1DH,EAAOI,KAAM,wBAAyBC,OAEtCL,EAAOI,KAAM,wBAAyBE,UAMzCT,EAAG,iBAAkBU,GACpB,SACA,gCACA,WAC0B,OAApBV,EAAGI,MAAOE,MACdN,EAAGI,MAAOO,aAAc,2BAA4BJ,KAAM,wBAAyBK,YAEnFZ,EAAGI,MAAOO,aAAc,2BAA4BJ,KAAM,wBAAyBM","file":"roles.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 = 1);\n","/**\r\n * Admin menu scripts.\r\n *\r\n * @package Nav Menu Roles\r\n */\r\n(function($) {\r\n\r\n\t$( '.nav_menu_logged_in_out_field' ).each(\r\n\t\tfunction(i) {\r\n\r\n\t\t\tvar $field = $( this );\r\n\r\n\t\t\tvar id = $field.find( 'input.nav-menu-id' ).val();\r\n\r\n\t\t\t// if set to display by role (aka is null) then show the roles list, otherwise hide\r\n\t\t\tif ( $field.find( 'input.nav-menu-logged-in-out:checked' ).val() === 'in' ) {\r\n\t\t\t\t$field.next( '.nav_menu_role_field' ).show();\r\n\t\t\t} else {\r\n\t\t\t\t$field.next( '.nav_menu_role_field' ).hide();\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\r\n\t// on in/out/role change, hide/show the roles\r\n\t$( '#menu-to-edit' ).on(\r\n\t\t'change',\r\n\t\t'input.nav-menu-logged-in-out',\r\n\t\tfunction() {\r\n\t\t\tif ( $( this ).val() === 'in' ) {\r\n\t\t\t\t$( this ).parentsUntil( '.nav_menu_logged_in_out' ).next( '.nav_menu_role_field' ).slideDown();\r\n\t\t\t} else {\r\n\t\t\t\t$( this ).parentsUntil( '.nav_menu_logged_in_out' ).next( '.nav_menu_role_field' ).slideUp();\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\r\n})( jQuery );\r\n"],"sourceRoot":""}
 
dist/nav-menu-roles.asset.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php return array('dependencies' => array(), 'version' => 'c9e86e88146d7c970387ee8acfaa80c9');
dist/nav-menu-roles.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(){var n;(n=jQuery)(".nav_menu_logged_in_out_field").each((function(e){var i=n(this);i.find("input.nav-menu-id").val(),"in"===i.find("input.nav-menu-logged-in-out:checked").val()?i.next(".nav_menu_role_field").show():i.next(".nav_menu_role_field").hide()})),n("#menu-to-edit").on("change","input.nav-menu-logged-in-out",(function(){"in"===n(this).val()?n(this).parentsUntil(".nav_menu_logged_in_out").next(".nav_menu_role_field").slideDown():n(this).parentsUntil(".nav_menu_logged_in_out").next(".nav_menu_role_field").slideUp()}))}();
inc/class-nav-menu-roles-import.php CHANGED
File without changes
inc/class-nav-menu-roles.php ADDED
@@ -0,0 +1,668 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Nav Menu Roles main
4
+ *
5
+ * @package Nav Menu Roles
6
+ *
7
+ * @since 1.0.0
8
+ * @version 2.1.0
9
+ */
10
+
11
+ // Exit if accessed directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ /**
17
+ * Nav Menu Roles class
18
+ */
19
+ class Nav_Menu_Roles {
20
+
21
+ /**
22
+ * @var Nav_Menu_Roles The single instance of the class
23
+ * @since 1.5
24
+ */
25
+ protected static $_instance = null;
26
+
27
+ /**
28
+ * @var string Path to main plugin file.
29
+ * @since 2.1.0
30
+ */
31
+ protected $main_file;
32
+
33
+ /**
34
+ * @constant string donate url
35
+ * @since 1.9.1
36
+ */
37
+ const DONATE_URL = 'https://www.paypal.com/fundraiser/charity/1451316';
38
+
39
+ /**
40
+ * @constant string version number
41
+ * @since 1.7.0
42
+ */
43
+ const VERSION = '2.1.0';
44
+
45
+ /**
46
+ * Main Nav Menu Roles Instance
47
+ *
48
+ * Ensures only one instance of Nav Menu Roles is loaded or can be loaded.
49
+ *
50
+ * @since 1.5
51
+ * @static
52
+ * @see Nav_Menu_Roles()
53
+ * @return Nav_Menu_Roles - Main instance
54
+ */
55
+ public static function instance( $file ) {
56
+ if ( is_null( self::$_instance ) ) {
57
+ self::$_instance = new self( $file );
58
+ }
59
+ return self::$_instance;
60
+ }
61
+
62
+ /**
63
+ * Cloning is forbidden.
64
+ *
65
+ * @since 1.5
66
+ */
67
+ public function __clone() {
68
+ _doing_it_wrong( __FUNCTION__, esc_html__( 'Cloning this object is forbidden.', 'nav-menu-roles' ), '1.5' );
69
+ }
70
+
71
+ /**
72
+ * Unserializing instances of this class is forbidden.
73
+ *
74
+ * @since 1.5
75
+ */
76
+ public function __wakeup() {
77
+ _doing_it_wrong( __FUNCTION__, esc_html__( 'Unserializing instances of this class is forbidden.', 'nav-menu-roles' ), '1.5' );
78
+ }
79
+
80
+ /**
81
+ * Nav_Menu_Roles Constructor.
82
+ * @access public
83
+ * @return Nav_Menu_Roles
84
+ * @since 1.0
85
+ */
86
+ public function __construct( $file ) {
87
+
88
+ $this->main_file = $file;
89
+
90
+ require_once plugin_dir_path( __FILE__ ) . 'customizer.php';
91
+
92
+ // Admin functions.
93
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
94
+
95
+ // Load the textdomain.
96
+ add_action( 'init', array( $this, 'load_text_domain' ) );
97
+
98
+ // Register the meta key.
99
+ add_action( 'init', array( $this, 'register_meta' ) );
100
+
101
+ // Add FAQ and Donate link to plugin.
102
+ add_filter( 'plugin_row_meta', array( $this, 'add_action_links' ), 10, 2 );
103
+
104
+ // Maybe switch the admin walker.
105
+ if ( ! self::is_wp_gte( '5.4' ) ) {
106
+ add_filter( 'wp_edit_nav_menu_walker', array( $this, 'edit_nav_menu_walker' ) );
107
+ }
108
+
109
+ // Add new fields via hook.
110
+ add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'custom_fields' ), 10, 4 );
111
+
112
+ // Add some JS.
113
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
114
+
115
+ // Save the menu item meta.
116
+ add_action( 'wp_update_nav_menu_item', array( $this, 'nav_update' ), 10, 2 );
117
+
118
+ // Add meta to menu item.
119
+ add_filter( 'wp_setup_nav_menu_item', array( $this, 'setup_nav_item' ) );
120
+
121
+ // Exclude items via filter instead of via custom Walker.
122
+ if ( ! is_admin() ) {
123
+ // Because WP_Customize_Nav_Menu_Item_Setting::filter_wp_get_nav_menu_items() runs at 10.
124
+ add_filter( 'wp_get_nav_menu_items', array( $this, 'exclude_menu_items' ), 20 );
125
+ }
126
+
127
+ // Upgrade routine.
128
+ add_action( 'plugins_loaded', array( $this, 'maybe_upgrade' ) );
129
+
130
+ }
131
+
132
+ /**
133
+ * Include the custom admin walker
134
+ *
135
+ * @access public
136
+ * @return void
137
+ */
138
+ public function admin_init() {
139
+
140
+ // Register Importer.
141
+ $this->register_importer();
142
+
143
+ }
144
+
145
+
146
+ /**
147
+ * Register the Importer
148
+ * the regular Importer skips post meta for the menu items
149
+ *
150
+ * @access private
151
+ * @return void
152
+ */
153
+ public function register_importer() {
154
+ // Register the new importer.
155
+ if ( defined( 'WP_LOAD_IMPORTERS' ) ) {
156
+
157
+ include_once plugin_dir_path( __FILE__ ) . 'class-nav-menu-roles-import.php';
158
+ // Register the custom importer we've created.
159
+ $roles_import = new Nav_Menu_Roles_Import();
160
+
161
+ register_importer( 'nav_menu_roles', __( 'Nav Menu Roles', 'nav-menu-roles' ), __( 'Import <strong>nav menu roles</strong> and other menu item meta skipped by the default importer', 'nav-menu-roles' ), array( $roles_import, 'dispatch' ) );
162
+
163
+ }
164
+
165
+ }
166
+
167
+ /**
168
+ * Make Plugin Translation-ready
169
+ *
170
+ * @since 1.0
171
+ */
172
+ public function load_text_domain() {
173
+ load_plugin_textdomain( 'nav-menu-roles', false, dirname( plugin_basename( $this->main_file ) ) . '/languages/' );
174
+ }
175
+
176
+ /**
177
+ * Register the meta keys for nav menus.
178
+ *
179
+ * @since 2.0
180
+ */
181
+ public function register_meta() {
182
+ register_meta(
183
+ 'post',
184
+ '_nav_menu_role',
185
+ array(
186
+ 'object_subtype' => 'nav_menu_item',
187
+ 'type' => 'mixed',
188
+ 'sanitize_callback' => array( $this, 'sanitize_meta' ),
189
+ )
190
+ );
191
+ register_meta(
192
+ 'post',
193
+ '_nav_menu_role_display_mode',
194
+ array(
195
+ 'object_subtype' => 'nav_menu_item',
196
+ 'type' => 'mixed',
197
+ 'sanitize_callback' => array( $this, 'sanitize_meta_mode' ),
198
+ )
199
+ );
200
+ }
201
+
202
+ /**
203
+ * Sanitize the meta.
204
+ *
205
+ * @since 2.0.0
206
+ *
207
+ * @param mixed $meta_value The meta value.
208
+ * @return mixed The meta value.
209
+ *
210
+ */
211
+ public function sanitize_meta( $meta_value ) {
212
+ global $wp_roles;
213
+
214
+ $clean = '';
215
+
216
+ if ( is_array( $meta_value ) ) {
217
+
218
+ $clean = array();
219
+
220
+ /**
221
+ * Pass the menu item to the filter function.
222
+ * This change is suggested as it allows the use of information from the menu item (and
223
+ * by extension the target object) to further customize what filters appear during menu
224
+ * construction.
225
+ */
226
+ $allowed_roles = apply_filters( 'nav_menu_roles', $wp_roles->role_names );
227
+
228
+ // Only save allowed roles.
229
+ $clean = array_intersect( $meta_value, array_keys( $allowed_roles ) );
230
+
231
+ } elseif ( in_array( $meta_value, array( 'in', 'out' ) ) ) {
232
+ $clean = $meta_value;
233
+ }
234
+
235
+ return $clean;
236
+ }
237
+
238
+ /**
239
+ * Sanitize the display mode meta.
240
+ *
241
+ * @since 2.1.0
242
+ *
243
+ * @param mixed $meta_value The meta value.
244
+ * @return mixed The meta value.
245
+ *
246
+ */
247
+ public function sanitize_meta_mode( $meta_value ) {
248
+ return 'hide' === $meta_value ? 'hide' : 'show';
249
+ }
250
+
251
+ /**
252
+ * Display a Notice if plugin conflicts with another
253
+ *
254
+ * @since 1.5
255
+ * @deprecated will removed in 2.0
256
+ */
257
+ public function admin_notice() {
258
+ _deprecated_function( __METHOD__, '1.7.8' );
259
+ }
260
+
261
+
262
+ /**
263
+ * Allow the notice to be dismissable
264
+ *
265
+ * @since 1.6
266
+ * @deprecated will removed in 2.0
267
+ */
268
+ public function nag_ignore() {
269
+ _deprecated_function( __METHOD__, '1.7.8' );
270
+ }
271
+
272
+ /**
273
+ * Delete the transient when a plugin is activated or deactivated
274
+ *
275
+ * @since 1.5
276
+ * @deprecated will removed in 2.0
277
+ */
278
+ public function delete_transient() {
279
+ _deprecated_function( __METHOD__, '1.7.8' );
280
+ delete_transient( 'nav_menu_roles_conflicts' );
281
+ }
282
+
283
+
284
+ /**
285
+ * Add docu link
286
+ *
287
+ * @since 1.7.3
288
+ * @param array $plugin_meta
289
+ * @param string $plugin_file
290
+ */
291
+ public function add_action_links( $plugin_meta, $plugin_file ) {
292
+ if ( plugin_basename( $this->main_file ) === $plugin_file ) {
293
+ $plugin_meta[] = sprintf( '<a class="dashicons-before dashicons-welcome-learn-more" href="https://wordpress.org/plugins/nav-menu-roles/faq/#conflict">%s</a>', __( 'FAQ', 'nav-menu-roles' ) );
294
+ $plugin_meta[] = '<a class="dashicons-before dashicons-admin-generic" href="' . self::DONATE_URL . '" target="_blank">' . __( 'Donate', 'nav-menu-roles' ) . '</a>';
295
+ }
296
+ return $plugin_meta;
297
+ }
298
+
299
+
300
+ /**
301
+ * Override the Admin Menu Walker
302
+ *
303
+ * @since 1.0
304
+ */
305
+ public function edit_nav_menu_walker( $walker ) {
306
+ if ( ! class_exists( 'Walker_Nav_Menu_Edit_Roles' ) ) {
307
+
308
+ if ( self::is_wp_gte( '4.7' ) ) {
309
+ require_once plugin_dir_path( __FILE__ ) . 'class-walker-nav-menu-edit-roles-4.7.php';
310
+ } elseif ( self::is_wp_gte( '4.5' ) ) {
311
+ require_once plugin_dir_path( __FILE__ ) . 'class-walker-nav-menu-edit-roles-4.5.php';
312
+ } else {
313
+ require_once plugin_dir_path( __FILE__ ) . 'class-walker-nav-menu-edit-roles.php';
314
+ }
315
+ }
316
+ return 'Walker_Nav_Menu_Edit_Roles';
317
+ }
318
+
319
+
320
+ /**
321
+ * Add fields to hook added in Walker
322
+ * This will allow us to play nicely with any other plugin that is adding the same hook
323
+ * @params obj $item - the menu item
324
+ * @params array $args
325
+ * @since 1.6.0
326
+ */
327
+ public function custom_fields( $item_id, $item, $depth, $args ) {
328
+ global $wp_roles;
329
+
330
+ /**
331
+ * Pass the menu item to the filter function.
332
+ * This change is suggested as it allows the use of information from the menu item (and
333
+ * by extension the target object) to further customize what filters appear during menu
334
+ * construction.
335
+ */
336
+ $display_roles = apply_filters( 'nav_menu_roles', $wp_roles->role_names, $item );
337
+
338
+ // Alpha sort roles by label.
339
+ asort( $wp_roles->role_names );
340
+
341
+ /**
342
+ * If no roles are being used, don't display the role selection radio buttons at all.
343
+ * Unless something deliberately removes the WordPress roles from this list, nothing will
344
+ * be functionally altered to the end user.
345
+ * This change is suggested for the benefit of users constructing granular admin permissions
346
+ * using extensive custom roles as it is an effective means of stopping admins with partial
347
+ * permissions to the menu from accidentally removing all restrictions from a menu item to
348
+ * which they do not have access.
349
+ */
350
+ if ( ! $display_roles ) {
351
+ return;
352
+ }
353
+
354
+ /* Get the roles saved for the post. */
355
+ $roles = get_post_meta( $item->ID, '_nav_menu_role', true );
356
+
357
+ // By default nothing is checked (will match "everyone" radio).
358
+ $logged_in_out = '';
359
+
360
+ // Show/Hide items to specific users.
361
+ $display_mode = 'hide' === get_post_meta( $item->ID, '_nav_menu_role_display_mode', true ) ? 'hide' : 'show';
362
+
363
+ // Specific roles are saved as an array, so "in" or an array equals "in" is checked.
364
+ if ( is_array( $roles ) || 'in' === $roles ) {
365
+ $logged_in_out = 'in';
366
+ } elseif ( 'out' === $roles ) {
367
+ $logged_in_out = 'out';
368
+ }
369
+
370
+ // The specific roles to check.
371
+ $checked_roles = is_array( $roles ) ? $roles : false;
372
+
373
+ // Whether to display the role checkboxes.
374
+ $hidden = 'in' === $logged_in_out ? '' : 'display: none;';
375
+
376
+ $float = is_rtl() ? 'float:"right";' : 'float:"left";';
377
+
378
+ ?>
379
+
380
+ <input type="hidden" name="nav-menu-role-nonce" value="<?php echo esc_attr( wp_create_nonce( 'nav-menu-nonce-name' ) ); ?>" />
381
+
382
+ <fieldset class="field-nav_menu_role nav_menu_display_mode_field description-wide" style="margin: 5px 0;">
383
+ <legend class="description"><?php esc_html_e( 'Display Mode', 'nav-menu-roles' ); ?></legend>
384
+
385
+ <input type="hidden" class="nav-menu-id" value="<?php echo esc_attr( $item->ID ); ?>" />
386
+
387
+ <label for="nav_menu_show-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 35%;">
388
+ <input type="radio" class="nav-menu-display-mode" name="nav-menu-display-mode[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_show-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( 'show', $display_mode ); ?> value="show" />
389
+ <?php esc_html_e( 'Show', 'nav-menu-roles' ); ?>
390
+ </label>
391
+
392
+ <label for="nav_menu_hide-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 35%;">
393
+ <input type="radio" class="nav-menu-display-mode" name="nav-menu-display-mode[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_hide-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( 'hide', $display_mode ); ?> value="hide" />
394
+ <?php esc_html_e( 'Hide', 'nav-menu-roles' ); ?>
395
+ </label>
396
+
397
+ </fieldset>
398
+
399
+ <fieldset class="field-nav_menu_role nav_menu_logged_in_out_field description-wide" style="margin: 5px 0;">
400
+ <legend class="description"><?php esc_html_e( 'Target audience', 'nav-menu-roles' ); ?></legend>
401
+
402
+ <input type="hidden" class="nav-menu-id" value="<?php echo esc_attr( $item->ID ); ?>" />
403
+
404
+ <label for="nav_menu_logged_in-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 35%;">
405
+ <input type="radio" class="nav-menu-logged-in-out" name="nav-menu-logged-in-out[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_logged_in-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( 'in', $logged_in_out ); ?> value="in" />
406
+ <?php esc_html_e( 'Logged In Users', 'nav-menu-roles' ); ?>
407
+ </label>
408
+
409
+ <label for="nav_menu_logged_out-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 35%;">
410
+ <input type="radio" class="nav-menu-logged-in-out" name="nav-menu-logged-in-out[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_logged_out-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( 'out', $logged_in_out ); ?> value="out" />
411
+ <?php esc_html_e( 'Logged Out Users', 'nav-menu-roles' ); ?>
412
+ </label>
413
+
414
+ <label for="nav_menu_by_role-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 30%;">
415
+ <input type="radio" class="nav-menu-logged-in-out" name="nav-menu-logged-in-out[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_by_role-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( '', $logged_in_out ); ?> value="" />
416
+ <?php esc_html_e( 'Everyone', 'nav-menu-roles' ); ?>
417
+ </label>
418
+
419
+ </fieldset>
420
+
421
+ <fieldset class="field-nav_menu_role nav_menu_role_field description-wide" style="margin: 5px 0; <?php echo esc_attr( $hidden ); ?>">
422
+ <legend class="description"><?php esc_html_e( 'Target role', 'nav-menu-roles' ); ?></legend>
423
+
424
+ <?php
425
+
426
+ $i = 1;
427
+
428
+ /* Loop through each of the available roles. */
429
+ foreach ( $display_roles as $role => $name ) {
430
+
431
+ /* If the role has been selected, make sure it's checked. */
432
+ $checked = checked( true, ( is_array( $checked_roles ) && in_array( $role, $checked_roles ) ), false );
433
+ ?>
434
+
435
+ <label for="nav_menu_role-<?php echo esc_attr( $role ); ?>-for-<?php echo esc_attr( $item->ID ); ?>" style="display: block; margin: 2px 0;">
436
+ <input type="checkbox" name="nav-menu-role[<?php echo esc_attr( $item->ID ); ?>][<?php echo esc_attr( $i ); ?>]" id="nav_menu_role-<?php echo esc_attr( $role ); ?>-for-<?php echo esc_attr( $item->ID ); ?>" <?php echo esc_attr( $checked ); ?> value="<?php echo esc_attr( $role ); ?>" />
437
+ <?php echo esc_html( $name ); ?>
438
+ <?php $i++; ?>
439
+ </label>
440
+
441
+ <?php } ?>
442
+
443
+ </fieldset>
444
+
445
+ <?php
446
+ }
447
+
448
+
449
+ /**
450
+ * Load the scripts on the menu page.
451
+ *
452
+ * @since 1.4
453
+ */
454
+ public function enqueue_scripts( $hook ) {
455
+ if ( 'nav-menus.php' === $hook ) {
456
+ wp_enqueue_script( 'nav-menu-roles', plugins_url( 'dist/nav-menu-roles.js', $this->main_file ), array( 'jquery' ), self::VERSION, true );
457
+ }
458
+ }
459
+
460
+ /**
461
+ * Save the roles as menu item meta
462
+ *
463
+ * @since 1.0
464
+ * @return string
465
+ */
466
+ public function nav_update( $menu_id, $menu_item_db_id ) {
467
+
468
+ // Verify this came from our screen and with proper authorization.
469
+ if ( ! isset( $_POST['nav-menu-role-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['nav-menu-role-nonce'] ), 'nav-menu-nonce-name' ) ) {
470
+ return $menu_id;
471
+ }
472
+
473
+ // Save display mode.
474
+ if ( isset( $_POST['nav-menu-display-mode'][ $menu_item_db_id ] ) && 'hide' === wp_unslash( $_POST['nav-menu-display-mode'][ $menu_item_db_id ] ) ) {
475
+ update_post_meta( $menu_item_db_id, '_nav_menu_role_display_mode', 'hide' );
476
+ } else {
477
+ update_post_meta( $menu_item_db_id, '_nav_menu_role_display_mode', 'show' );
478
+ }
479
+
480
+ // Save target/roles.
481
+ if ( isset( $_POST['nav-menu-logged-in-out'][ $menu_item_db_id ] ) ) {
482
+
483
+ if ( 'in' === $_POST['nav-menu-logged-in-out'][ $menu_item_db_id ] && ! empty( $_POST['nav-menu-role'][ $menu_item_db_id ] ) ) {
484
+ $meta = wp_unslash( $_POST['nav-menu-role'][ $menu_item_db_id ] );
485
+ } else {
486
+ $meta = wp_unslash( $_POST['nav-menu-logged-in-out'][ $menu_item_db_id ] );
487
+ }
488
+
489
+ update_post_meta( $menu_item_db_id, '_nav_menu_role', $meta ); // Sanitization handled by $this->sanitize_meta().
490
+
491
+ } else {
492
+ delete_post_meta( $menu_item_db_id, '_nav_menu_role' );
493
+ }
494
+
495
+ return $menu_id;
496
+ }
497
+
498
+ /**
499
+ * Adds value of new field to $item object
500
+ * is be passed to Walker_Nav_Menu_Edit_Custom
501
+ *
502
+ * @since 1.0
503
+ */
504
+ public function setup_nav_item( $menu_item ) {
505
+
506
+ if ( is_object( $menu_item ) && isset( $menu_item->ID ) ) {
507
+
508
+ $menu_item->display_mode = 'hide' === get_post_meta( $menu_item->ID, '_nav_menu_role_display_mode', true ) ? 'hide' : 'show';
509
+
510
+ $roles = get_post_meta( $menu_item->ID, '_nav_menu_role', true );
511
+
512
+ if ( ! empty( $roles ) ) {
513
+ $menu_item->roles = $roles;
514
+
515
+ // Add the NMR roles as CSS info.
516
+ $new_classes = array();
517
+
518
+ switch ( $roles ) {
519
+ case 'in':
520
+ $new_classes[] = 'nmr-logged-in';
521
+ break;
522
+ case 'out':
523
+ $new_classes[] = 'nmr-logged-out';
524
+ break;
525
+ default:
526
+ if ( is_array( $menu_item->roles ) && ! empty( $menu_item->roles ) ) {
527
+ foreach ( $menu_item->roles as $role ) {
528
+ $new_classes[] = 'nmr-' . $role;
529
+ }
530
+ }
531
+ break;
532
+ }
533
+
534
+ // Only apply classes on front-end.
535
+ if ( ! is_admin() ) {
536
+ $menu_item->classes = array_unique( array_merge( (array) $menu_item->classes, (array) $new_classes ) );
537
+ }
538
+ }
539
+ }
540
+ return $menu_item;
541
+ }
542
+
543
+ /**
544
+ * Exclude menu items via wp_get_nav_menu_items filter
545
+ * this fixes plugin's incompatibility with theme's that use their own custom Walker
546
+ * Thanks to Evan Stein @vanpop http://vanpop.com/
547
+ *
548
+ * @since 1.2
549
+ *
550
+ * @param WP_Post[] array of Nav Menu Post objects
551
+ *
552
+ * Multisite compatibility added in 1.9.0
553
+ * by @open-dsi https://www.open-dsi.fr/ with props to @fiech
554
+ */
555
+ public function exclude_menu_items( $items ) {
556
+
557
+ $hide_children_of = array();
558
+
559
+ if ( ! empty( $items ) ) {
560
+
561
+ // Iterate over the items to search and destroy.
562
+ foreach ( $items as $key => $item ) {
563
+
564
+ $visible = true;
565
+
566
+ // Hide any item that is the child of a hidden item.
567
+ if ( isset( $item->menu_item_parent ) && in_array( $item->menu_item_parent, $hide_children_of ) ) {
568
+ $visible = false;
569
+ }
570
+
571
+ // Check any item that has NMR roles set.
572
+ if ( $visible && isset( $item->roles ) ) {
573
+
574
+ // Check all logged in, all logged out, or role.
575
+ switch ( $item->roles ) {
576
+ case 'in':
577
+ /**
578
+ * Multisite compatibility.
579
+ *
580
+ * For the logged in condition to work,
581
+ * the user has to be a logged in member of the current blog
582
+ * or be a logged in super user.
583
+ */
584
+ $visible = is_user_member_of_blog() || is_super_admin() ? true : false;
585
+ break;
586
+ case 'out':
587
+ /**
588
+ * Multisite compatibility.
589
+ *
590
+ * For the logged out condition to work,
591
+ * the user has to be either logged out
592
+ * or not be a member of the current blog.
593
+ * But they also may not be a super admin,
594
+ * because logged in super admins should see the internal stuff, not the external.
595
+ */
596
+ $visible = ! is_user_member_of_blog() && ! is_super_admin() ? true : false;
597
+ break;
598
+ default:
599
+ $visible = false;
600
+ if ( is_array( $item->roles ) && ! empty( $item->roles ) ) {
601
+ foreach ( $item->roles as $role ) {
602
+ if ( current_user_can( $role ) ) {
603
+ $visible = true;
604
+ break;
605
+ }
606
+ }
607
+ }
608
+
609
+ break;
610
+ }
611
+ }
612
+
613
+ // Invert visibility if display mode is "hide".
614
+ if ( ! empty( $item->display_mode ) && 'hide' === $item->display_mode ) {
615
+ $visible = ! $visible;
616
+ }
617
+
618
+ /*
619
+ * Filter: nav_menu_roles_item_visibility
620
+ * Add filter to work with plugins that don't use traditional roles
621
+ *
622
+ * @param bool $visible
623
+ * @param object $item
624
+ */
625
+ $visible = apply_filters( 'nav_menu_roles_item_visibility', $visible, $item );
626
+
627
+ // Unset non-visible item.
628
+ if ( ! $visible ) {
629
+ if ( isset( $item->ID ) ) {
630
+ $hide_children_of[] = $item->ID; // Store ID of item to hide it's children.
631
+ }
632
+ unset( $items[ $key ] );
633
+ }
634
+ }
635
+ }
636
+
637
+ return $items;
638
+ }
639
+
640
+
641
+ /**
642
+ * Maybe upgrade
643
+ *
644
+ * @access public
645
+ * @return void
646
+ */
647
+ public function maybe_upgrade() {
648
+ $db_version = get_option( 'nav_menu_roles_db_version', false );
649
+
650
+ // 1.7.7 upgrade: changed the debug notice so the old transient is invalid.
651
+ if ( false === $db_version || version_compare( '1.7.7', $db_version, '<' ) ) {
652
+ update_option( 'nav_menu_roles_db_version', self::VERSION );
653
+ }
654
+ }
655
+
656
+ /**
657
+ * Test WordPress version
658
+ *
659
+ * @access public
660
+ * @param string $version - A WordPress version to compare against current version.
661
+ * @return boolean
662
+ */
663
+ public static function is_wp_gte( $version = '5.4' ) {
664
+ global $wp_version;
665
+ return version_compare( strtolower( $wp_version ), strtolower( $version ), '>=' );
666
+ }
667
+
668
+ } // End class.
inc/class-walker-nav-menu-edit-roles-4.5.php CHANGED
File without changes
inc/class-walker-nav-menu-edit-roles-4.7.php CHANGED
File without changes
inc/class-walker-nav-menu-edit-roles.php CHANGED
File without changes
inc/customizer.php CHANGED
@@ -24,7 +24,9 @@ add_action( 'wp_nav_menu_item_custom_fields_customize_template', __NAMESPACE__ .
24
  add_action( 'customize_controls_enqueue_scripts', __NAMESPACE__ . '\customizer_scripts' );
25
 
26
  // Workaround for previewing changes.
27
- add_action( 'customize_register', __NAMESPACE__ . '\customizer_preview', 1000 );
 
 
28
 
29
  // Workaround for saving changes.
30
  add_action( 'customize_save_after', __NAMESPACE__ . '\customizer_save' );
@@ -53,8 +55,23 @@ function customizer_custom_fields() {
53
  }
54
 
55
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  <fieldset class="nav_menu_role_authentication">
57
- <legend class="customize-control-title"><?php esc_html_e( 'Display Mode', 'nav-menu-roles' ); ?></legend>
58
 
59
  <label for="edit-menu-item-role_logged_in-{{ data.menu_item_id }}">
60
  <input type="radio" id="edit-menu-item-role_logged_in-{{ data.menu_item_id }}" value="in" name="menu-item-role-{{ data.menu_item_id }}" />
@@ -71,7 +88,7 @@ function customizer_custom_fields() {
71
  </fieldset>
72
 
73
  <fieldset class="nav_menu_roles">
74
- <legend class="customize-control-title"><?php esc_html_e( 'Restrict menu item to minimum role', 'nav-menu-roles' ); ?></legend>
75
 
76
  <?php foreach ( $display_roles as $role => $name ) : ?>
77
  <label for="edit-menu-item-role_<?php echo esc_attr( $role ); ?>-{{ data.menu_item_id }}">
@@ -88,15 +105,32 @@ function customizer_custom_fields() {
88
  * Load the customizer scripts which extends nav menu item controls.
89
  */
90
  function customizer_scripts() {
 
91
  wp_enqueue_script(
92
  'customize-nav-menu-roles',
93
- plugins_url( 'dist/js/customize.js', dirname( __FILE__ ) ),
94
- array( 'customize-nav-menus' ),
95
- \Nav_Menu_Roles::VERSION,
96
  true
97
  );
98
  }
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  /**
101
  * Get posted value for a setting's roles.
102
  *
@@ -123,24 +157,47 @@ function get_roles_post_data( WP_Customize_Nav_Menu_Item_Setting $setting ) {
123
  * @param WP_Customize_Nav_Menu_Item_Setting $setting Setting.
124
  */
125
  function preview_nav_menu_setting_postmeta( WP_Customize_Nav_Menu_Item_Setting $setting ) {
126
- $roles = get_roles_post_data( $setting );
127
- if ( null === $roles ) {
128
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
 
131
- $roles = Nav_Menu_Roles()->sanitize_meta( $roles );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
- add_filter(
134
- 'get_post_metadata',
135
- static function ( $value, $object_id, $meta_key ) use ( $setting, $roles ) {
136
- if ( $object_id === $setting->post_id && '_nav_menu_role' === $meta_key ) {
137
- return array( $roles );
138
- }
139
- return $value;
140
- },
141
- 10,
142
- 3
143
- );
144
  }
145
 
146
  /**
@@ -153,6 +210,11 @@ function preview_nav_menu_setting_postmeta( WP_Customize_Nav_Menu_Item_Setting $
153
  * @param WP_Customize_Nav_Menu_Item_Setting $setting Setting.
154
  */
155
  function save_nav_menu_setting_postmeta( WP_Customize_Nav_Menu_Item_Setting $setting ) {
 
 
 
 
 
156
  $roles = get_roles_post_data( $setting );
157
  if ( null !== $roles ) {
158
  update_post_meta( $setting->post_id, '_nav_menu_role', $roles );
24
  add_action( 'customize_controls_enqueue_scripts', __NAMESPACE__ . '\customizer_scripts' );
25
 
26
  // Workaround for previewing changes.
27
+ if ( \Nav_Menu_Roles::is_wp_gte( '4.9' ) ) {
28
+ add_action( 'customize_register', __NAMESPACE__ . '\customizer_preview', 1000 );
29
+ }
30
 
31
  // Workaround for saving changes.
32
  add_action( 'customize_save_after', __NAMESPACE__ . '\customizer_save' );
55
  }
56
 
57
  ?>
58
+ <fieldset class="nav_menu_role_display_mode">
59
+ <legend class="customize-control-title"><?php esc_html_e( 'Display Mode', 'nav-menu-roles' ); ?></legend>
60
+
61
+ <label for="edit-menu-item-role_display_mode_show-{{ data.menu_item_id }}">
62
+ <input type="radio" class="nav-menu-display-mode" name="nav-menu-display-mode[{{ data.menu_item_id }}]" id="edit-menu-item-role_display_mode_show-{{ data.menu_item_id }}" value="show" />
63
+ <?php esc_html_e( 'Show', 'nav-menu-roles' ); ?>
64
+ </label>
65
+
66
+ <label for="edit-menu-item-role_display_mode_hide-{{ data.menu_item_id }}">
67
+ <input type="radio" class="nav-menu-display-mode" name="nav-menu-display-mode[{{ data.menu_item_id }}]" id="edit-menu-item-role_display_mode_hide-{{ data.menu_item_id }}" value="hide" />
68
+ <?php esc_html_e( 'Hide', 'nav-menu-roles' ); ?>
69
+ </label>
70
+
71
+ </fieldset>
72
+
73
  <fieldset class="nav_menu_role_authentication">
74
+ <legend class="customize-control-title"><?php esc_html_e( 'Target Audience', 'nav-menu-roles' ); ?></legend>
75
 
76
  <label for="edit-menu-item-role_logged_in-{{ data.menu_item_id }}">
77
  <input type="radio" id="edit-menu-item-role_logged_in-{{ data.menu_item_id }}" value="in" name="menu-item-role-{{ data.menu_item_id }}" />
88
  </fieldset>
89
 
90
  <fieldset class="nav_menu_roles">
91
+ <legend class="customize-control-title"><?php esc_html_e( 'Target Roles', 'nav-menu-roles' ); ?></legend>
92
 
93
  <?php foreach ( $display_roles as $role => $name ) : ?>
94
  <label for="edit-menu-item-role_<?php echo esc_attr( $role ); ?>-{{ data.menu_item_id }}">
105
  * Load the customizer scripts which extends nav menu item controls.
106
  */
107
  function customizer_scripts() {
108
+ $script_dependencies = include plugin_dir_path( __DIR__ ) . '/dist/customize-controls.asset.php';
109
  wp_enqueue_script(
110
  'customize-nav-menu-roles',
111
+ plugins_url( 'dist/customize-controls.js', dirname( __FILE__ ) ),
112
+ array_merge( array( 'customize-nav-menus' ), $script_dependencies['dependencies'] ),
113
+ $script_dependencies['version'],
114
  true
115
  );
116
  }
117
 
118
+ /**
119
+ * Get posted value for a setting's display mode.
120
+ *
121
+ * @param WP_Customize_Nav_Menu_Item_Setting $setting Setting.
122
+ *
123
+ * @return array|string|null Roles value or null if no posted value present.
124
+ */
125
+ function get_display_mode_post_data( WP_Customize_Nav_Menu_Item_Setting $setting ) {
126
+ if ( ! $setting->post_value() ) {
127
+ return null;
128
+ }
129
+
130
+ $unsanitized_post_value = $setting->manager->unsanitized_post_values()[ $setting->id ];
131
+ return isset( $unsanitized_post_value['display_mode'] ) ? $unsanitized_post_value['display_mode'] : 'show';
132
+ }
133
+
134
  /**
135
  * Get posted value for a setting's roles.
136
  *
157
  * @param WP_Customize_Nav_Menu_Item_Setting $setting Setting.
158
  */
159
  function preview_nav_menu_setting_postmeta( WP_Customize_Nav_Menu_Item_Setting $setting ) {
160
+
161
+ $mode = get_display_mode_post_data( $setting );
162
+
163
+ if ( null !== $mode ) {
164
+
165
+ $mode = Nav_Menu_Roles()->sanitize_meta_mode( $mode );
166
+
167
+ add_filter(
168
+ 'get_post_metadata',
169
+ static function ( $value, $object_id, $meta_key ) use ( $setting, $mode ) {
170
+ if ( $object_id === $setting->post_id && '_nav_menu_role_display_mode' === $meta_key ) {
171
+ return array( $mode );
172
+ }
173
+ return $value;
174
+ },
175
+ 10,
176
+ 3
177
+ );
178
+
179
  }
180
 
181
+ $roles = get_roles_post_data( $setting );
182
+
183
+ if ( null !== $roles ) {
184
+
185
+ $roles = Nav_Menu_Roles()->sanitize_meta( $roles );
186
+
187
+ add_filter(
188
+ 'get_post_metadata',
189
+ static function ( $value, $object_id, $meta_key ) use ( $setting, $roles ) {
190
+ if ( $object_id === $setting->post_id && '_nav_menu_role' === $meta_key ) {
191
+ return array( $roles );
192
+ }
193
+ return $value;
194
+ },
195
+ 10,
196
+ 3
197
+ );
198
+
199
+ }
200
 
 
 
 
 
 
 
 
 
 
 
 
201
  }
202
 
203
  /**
210
  * @param WP_Customize_Nav_Menu_Item_Setting $setting Setting.
211
  */
212
  function save_nav_menu_setting_postmeta( WP_Customize_Nav_Menu_Item_Setting $setting ) {
213
+ $mode = get_display_mode_post_data( $setting );
214
+ if ( null !== $mode ) {
215
+ update_post_meta( $setting->post_id, '_nav_menu_role_display_mode', $mode );
216
+ }
217
+
218
  $roles = get_roles_post_data( $setting );
219
  if ( null !== $roles ) {
220
  update_post_meta( $setting->post_id, '_nav_menu_role', $roles );
languages/nav-menu-roles-fa.mo CHANGED
File without changes
languages/nav-menu-roles-fa.po CHANGED
File without changes
languages/nav-menu-roles-it.mo CHANGED
File without changes
languages/nav-menu-roles-it.po CHANGED
File without changes
languages/nav-menu-roles.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the GPL-3.0.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Nav Menu Roles 2.0.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/nav-menu-roles\n"
7
- "POT-Creation-Date: 2021-03-18 01:56:18+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -183,23 +183,23 @@ msgstr ""
183
  msgid "Edit Menu Item"
184
  msgstr ""
185
 
186
- #: inc/customizer.php:57 nav-menu-roles.php:371
187
  msgid "Display Mode"
188
  msgstr ""
189
 
190
- #: inc/customizer.php:61 nav-menu-roles.php:377
191
  msgid "Logged In Users"
192
  msgstr ""
193
 
194
- #: inc/customizer.php:65 nav-menu-roles.php:382
195
  msgid "Logged Out Users"
196
  msgstr ""
197
 
198
- #: inc/customizer.php:69 nav-menu-roles.php:387
199
  msgid "Everyone"
200
  msgstr ""
201
 
202
- #: inc/customizer.php:74
203
  msgid "Restrict menu item to minimum role"
204
  msgstr ""
205
 
2
  # This file is distributed under the GPL-3.0.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Nav Menu Roles 2.0.2\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/nav-menu-roles\n"
7
+ "POT-Creation-Date: 2021-04-06 13:20:57+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
183
  msgid "Edit Menu Item"
184
  msgstr ""
185
 
186
+ #: inc/customizer.php:59 nav-menu-roles.php:371
187
  msgid "Display Mode"
188
  msgstr ""
189
 
190
+ #: inc/customizer.php:63 nav-menu-roles.php:377
191
  msgid "Logged In Users"
192
  msgstr ""
193
 
194
+ #: inc/customizer.php:67 nav-menu-roles.php:382
195
  msgid "Logged Out Users"
196
  msgstr ""
197
 
198
+ #: inc/customizer.php:71 nav-menu-roles.php:387
199
  msgid "Everyone"
200
  msgstr ""
201
 
202
+ #: inc/customizer.php:76
203
  msgid "Restrict menu item to minimum role"
204
  msgstr ""
205
 
nav-menu-roles.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Nav Menu Roles
4
  * Plugin URI: http://www.kathyisawesome.com/449/nav-menu-roles/
5
  * Description: Hide custom menu items based on user roles.
6
- * Version: 2.0.1
7
  * Author: Kathy Darling
8
  * Author URI: http://www.kathyisawesome.com
9
  * License: GPL-3.0
@@ -34,606 +34,26 @@ if ( ! function_exists( 'is_admin' ) ) {
34
  exit();
35
  }
36
 
37
- /**
38
- * Nav Menu Roles class
39
- */
40
- class Nav_Menu_Roles {
41
 
42
- /**
43
- * @var Nav_Menu_Roles The single instance of the class
44
- * @since 1.5
45
- */
46
- protected static $_instance = null;
47
 
48
  /**
49
- * @constant string donate url
50
- * @since 1.9.1
51
- */
52
- const DONATE_URL = 'https://www.paypal.com/fundraiser/charity/1451316';
53
-
54
- /**
55
- * @constant string version number
56
- * @since 1.7.0
57
- */
58
- const VERSION = '1.10.2';
59
-
60
- /**
61
- * Main Nav Menu Roles Instance
62
- *
63
- * Ensures only one instance of Nav Menu Roles is loaded or can be loaded.
64
  *
65
- * @since 1.5
66
- * @static
67
- * @see Nav_Menu_Roles()
68
- * @return Nav_Menu_Roles - Main instance
69
- */
70
- public static function instance() {
71
- if ( is_null( self::$_instance ) ) {
72
- self::$_instance = new self();
73
- }
74
- return self::$_instance;
75
- }
76
-
77
- /**
78
- * Cloning is forbidden.
79
- *
80
- * @since 1.5
81
- */
82
- public function __clone() {
83
- _doing_it_wrong( __FUNCTION__, esc_html__( 'Cloning this object is forbidden.', 'nav-menu-roles' ), '1.5' );
84
- }
85
-
86
- /**
87
- * Unserializing instances of this class is forbidden.
88
- *
89
- * @since 1.5
90
- */
91
- public function __wakeup() {
92
- _doing_it_wrong( __FUNCTION__, esc_html__( 'Unserializing instances of this class is forbidden.', 'nav-menu-roles' ), '1.5' );
93
- }
94
-
95
- /**
96
- * Nav_Menu_Roles Constructor.
97
- * @access public
98
  * @return Nav_Menu_Roles
99
- * @since 1.0
100
- */
101
- public function __construct() {
102
-
103
- require_once 'inc/customizer.php';
104
-
105
- // Admin functions.
106
- add_action( 'admin_init', array( $this, 'admin_init' ) );
107
-
108
- // Load the textdomain.
109
- add_action( 'init', array( $this, 'load_text_domain' ) );
110
-
111
- // Register the meta key.
112
- add_action( 'init', array( $this, 'register_meta' ) );
113
-
114
- // Add FAQ and Donate link to plugin.
115
- add_filter( 'plugin_row_meta', array( $this, 'add_action_links' ), 10, 2 );
116
-
117
- // Maybe switch the admin walker.
118
- if ( ! self::is_wp_gte( '5.4' ) ) {
119
- add_filter( 'wp_edit_nav_menu_walker', array( $this, 'edit_nav_menu_walker' ) );
120
- }
121
-
122
- // Add new fields via hook.
123
- add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'custom_fields' ), 10, 4 );
124
-
125
- // Add some JS.
126
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
127
-
128
- // Save the menu item meta.
129
- add_action( 'wp_update_nav_menu_item', array( $this, 'nav_update' ), 10, 2 );
130
-
131
- // Add meta to menu item.
132
- add_filter( 'wp_setup_nav_menu_item', array( $this, 'setup_nav_item' ) );
133
-
134
- // Exclude items via filter instead of via custom Walker.
135
- if ( ! is_admin() ) {
136
- // Because WP_Customize_Nav_Menu_Item_Setting::filter_wp_get_nav_menu_items() runs at 10.
137
- add_filter( 'wp_get_nav_menu_items', array( $this, 'exclude_menu_items' ), 20 );
138
- }
139
-
140
- // Upgrade routine.
141
- add_action( 'plugins_loaded', array( $this, 'maybe_upgrade' ) );
142
-
143
- }
144
-
145
- /**
146
- * Include the custom admin walker
147
- *
148
- * @access public
149
- * @return void
150
  */
151
- public function admin_init() {
 
152
 
153
- // Register Importer.
154
- $this->register_importer();
155
 
 
156
  }
 
157
 
158
-
159
- /**
160
- * Register the Importer
161
- * the regular Importer skips post meta for the menu items
162
- *
163
- * @access private
164
- * @return void
165
- */
166
- public function register_importer() {
167
- // Register the new importer.
168
- if ( defined( 'WP_LOAD_IMPORTERS' ) ) {
169
-
170
- include_once plugin_dir_path( __FILE__ ) . 'inc/class-nav-menu-roles-import.php';
171
- // Register the custom importer we've created.
172
- $roles_import = new Nav_Menu_Roles_Import();
173
-
174
- register_importer( 'nav_menu_roles', __( 'Nav Menu Roles', 'nav-menu-roles' ), __( 'Import <strong>nav menu roles</strong> and other menu item meta skipped by the default importer', 'nav-menu-roles' ), array( $roles_import, 'dispatch' ) );
175
-
176
- }
177
-
178
- }
179
-
180
- /**
181
- * Make Plugin Translation-ready
182
- *
183
- * @since 1.0
184
- */
185
- public function load_text_domain() {
186
- load_plugin_textdomain( 'nav-menu-roles', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
187
- }
188
-
189
- /**
190
- * Register the meta keys for nav menus.
191
- *
192
- * @since 2.0
193
- */
194
- public function register_meta() {
195
- register_meta(
196
- 'post',
197
- '_nav_menu_role',
198
- array(
199
- 'object_subtype' => 'nav_menu_item',
200
- 'type' => 'mixed',
201
- 'sanitize_callback' => array( $this, 'sanitize_meta' ),
202
- )
203
- );
204
- }
205
-
206
- /**
207
- * Sanitize the meta.
208
- *
209
- * @since 2.0.0
210
- *
211
- * @param mixed $meta_value The meta value.
212
- * @return mixed The meta value.
213
- *
214
- */
215
- public function sanitize_meta( $meta_value ) {
216
- global $wp_roles;
217
-
218
- $clean = '';
219
-
220
- if ( is_array( $meta_value ) ) {
221
-
222
- $clean = array();
223
-
224
- /**
225
- * Pass the menu item to the filter function.
226
- * This change is suggested as it allows the use of information from the menu item (and
227
- * by extension the target object) to further customize what filters appear during menu
228
- * construction.
229
- */
230
- $allowed_roles = apply_filters( 'nav_menu_roles', $wp_roles->role_names );
231
-
232
- // Only save allowed roles.
233
- $clean = array_intersect( $meta_value, array_keys( $allowed_roles ) );
234
-
235
- } elseif ( in_array( $meta_value, array( 'in', 'out' ) ) ) {
236
- $clean = $meta_value;
237
- }
238
-
239
- return $clean;
240
- }
241
-
242
- /**
243
- * Display a Notice if plugin conflicts with another
244
- *
245
- * @since 1.5
246
- * @deprecated will removed in 2.0
247
- */
248
- public function admin_notice() {
249
- _deprecated_function( __METHOD__, '1.7.8' );
250
- }
251
-
252
-
253
- /**
254
- * Allow the notice to be dismissable
255
- *
256
- * @since 1.6
257
- * @deprecated will removed in 2.0
258
- */
259
- public function nag_ignore() {
260
- _deprecated_function( __METHOD__, '1.7.8' );
261
- }
262
-
263
- /**
264
- * Delete the transient when a plugin is activated or deactivated
265
- *
266
- * @since 1.5
267
- * @deprecated will removed in 2.0
268
- */
269
- public function delete_transient() {
270
- _deprecated_function( __METHOD__, '1.7.8' );
271
- delete_transient( 'nav_menu_roles_conflicts' );
272
- }
273
-
274
-
275
- /**
276
- * Add docu link
277
- *
278
- * @since 1.7.3
279
- * @param array $plugin_meta
280
- * @param string $plugin_file
281
- */
282
- public function add_action_links( $plugin_meta, $plugin_file ) {
283
- if ( plugin_basename( __FILE__ ) === $plugin_file ) {
284
- $plugin_meta[] = sprintf( '<a class="dashicons-before dashicons-welcome-learn-more" href="https://wordpress.org/plugins/nav-menu-roles/faq/#conflict">%s</a>', __( 'FAQ', 'nav-menu-roles' ) );
285
- $plugin_meta[] = '<a class="dashicons-before dashicons-admin-generic" href="' . self::DONATE_URL . '" target="_blank">' . __( 'Donate', 'nav-menu-roles' ) . '</a>';
286
- }
287
- return $plugin_meta;
288
- }
289
-
290
-
291
- /**
292
- * Override the Admin Menu Walker
293
- *
294
- * @since 1.0
295
- */
296
- public function edit_nav_menu_walker( $walker ) {
297
- if ( ! class_exists( 'Walker_Nav_Menu_Edit_Roles' ) ) {
298
-
299
- if ( self::is_wp_gte( '4.7' ) ) {
300
- require_once plugin_dir_path( __FILE__ ) . 'inc/class-walker-nav-menu-edit-roles-4.7.php';
301
- } elseif ( self::is_wp_gte( '4.5' ) ) {
302
- require_once plugin_dir_path( __FILE__ ) . 'inc/class-walker-nav-menu-edit-roles-4.5.php';
303
- } else {
304
- require_once plugin_dir_path( __FILE__ ) . 'inc/class-walker-nav-menu-edit-roles.php';
305
- }
306
- }
307
- return 'Walker_Nav_Menu_Edit_Roles';
308
- }
309
-
310
-
311
- /**
312
- * Add fields to hook added in Walker
313
- * This will allow us to play nicely with any other plugin that is adding the same hook
314
- * @params obj $item - the menu item
315
- * @params array $args
316
- * @since 1.6.0
317
- */
318
- public function custom_fields( $item_id, $item, $depth, $args ) {
319
- global $wp_roles;
320
-
321
- /**
322
- * Pass the menu item to the filter function.
323
- * This change is suggested as it allows the use of information from the menu item (and
324
- * by extension the target object) to further customize what filters appear during menu
325
- * construction.
326
- */
327
- $display_roles = apply_filters( 'nav_menu_roles', $wp_roles->role_names, $item );
328
-
329
- // Alpha sort roles by label.
330
- asort( $wp_roles->role_names );
331
-
332
- /**
333
- * If no roles are being used, don't display the role selection radio buttons at all.
334
- * Unless something deliberately removes the WordPress roles from this list, nothing will
335
- * be functionally altered to the end user.
336
- * This change is suggested for the benefit of users constructing granular admin permissions
337
- * using extensive custom roles as it is an effective means of stopping admins with partial
338
- * permissions to the menu from accidentally removing all restrictions from a menu item to
339
- * which they do not have access.
340
- */
341
- if ( ! $display_roles ) {
342
- return;
343
- }
344
-
345
- /* Get the roles saved for the post. */
346
- $roles = get_post_meta( $item->ID, '_nav_menu_role', true );
347
-
348
- // By default nothing is checked (will match "everyone" radio).
349
- $logged_in_out = '';
350
-
351
- // Specific roles are saved as an array, so "in" or an array equals "in" is checked.
352
- if ( is_array( $roles ) || 'in' === $roles ) {
353
- $logged_in_out = 'in';
354
- } elseif ( 'out' === $roles ) {
355
- $logged_in_out = 'out';
356
- }
357
-
358
- // The specific roles to check.
359
- $checked_roles = is_array( $roles ) ? $roles : false;
360
-
361
- // Whether to display the role checkboxes.
362
- $hidden = 'in' === $logged_in_out ? '' : 'display: none;';
363
-
364
- $float = is_rtl() ? 'float:"right";' : 'float:"left";';
365
-
366
- ?>
367
-
368
- <input type="hidden" name="nav-menu-role-nonce" value="<?php echo esc_attr( wp_create_nonce( 'nav-menu-nonce-name' ) ); ?>" />
369
-
370
- <fieldset class="field-nav_menu_role nav_menu_logged_in_out_field description-wide" style="margin: 5px 0;">
371
- <legend class="description"><?php esc_html_e( 'Display Mode', 'nav-menu-roles' ); ?></legend>
372
-
373
- <input type="hidden" class="nav-menu-id" value="<?php echo esc_attr( $item->ID ); ?>" />
374
-
375
- <label for="nav_menu_logged_in-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 35%;">
376
- <input type="radio" class="nav-menu-logged-in-out" name="nav-menu-logged-in-out[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_logged_in-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( 'in', $logged_in_out ); ?> value="in" />
377
- <?php esc_html_e( 'Logged In Users', 'nav-menu-roles' ); ?>
378
- </label>
379
-
380
- <label for="nav_menu_logged_out-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 35%;">
381
- <input type="radio" class="nav-menu-logged-in-out" name="nav-menu-logged-in-out[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_logged_out-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( 'out', $logged_in_out ); ?> value="out" />
382
- <?php esc_html_e( 'Logged Out Users', 'nav-menu-roles' ); ?>
383
- </label>
384
-
385
- <label for="nav_menu_by_role-for-<?php echo esc_attr( $item->ID ); ?>" style="<?php echo esc_attr( $float ); ?> width: 30%;">
386
- <input type="radio" class="nav-menu-logged-in-out" name="nav-menu-logged-in-out[<?php echo esc_attr( $item->ID ); ?>]" id="nav_menu_by_role-for-<?php echo esc_attr( $item->ID ); ?>" <?php checked( '', $logged_in_out ); ?> value="" />
387
- <?php esc_html_e( 'Everyone', 'nav-menu-roles' ); ?>
388
- </label>
389
-
390
- </fieldset>
391
-
392
- <fieldset class="field-nav_menu_role nav_menu_role_field description-wide" style="margin: 5px 0; <?php echo esc_attr( $hidden ); ?>">
393
- <legend class="description"><?php esc_html_e( 'Restrict menu item to a minimum role', 'nav-menu-roles' ); ?></legend>
394
- <br />
395
-
396
- <?php
397
-
398
- $i = 1;
399
-
400
- /* Loop through each of the available roles. */
401
- foreach ( $display_roles as $role => $name ) {
402
-
403
- /* If the role has been selected, make sure it's checked. */
404
- $checked = checked( true, ( is_array( $checked_roles ) && in_array( $role, $checked_roles ) ), false );
405
- ?>
406
-
407
- <label for="nav_menu_role-<?php echo esc_attr( $role ); ?>-for-<?php echo esc_attr( $item->ID ); ?>" style="display: block; margin: 2px 0;">
408
- <input type="checkbox" name="nav-menu-role[<?php echo esc_attr( $item->ID ); ?>][<?php echo esc_attr( $i ); ?>]" id="nav_menu_role-<?php echo esc_attr( $role ); ?>-for-<?php echo esc_attr( $item->ID ); ?>" <?php echo esc_attr( $checked ); ?> value="<?php echo esc_attr( $role ); ?>" />
409
- <?php echo esc_html( $name ); ?>
410
- <?php $i++; ?>
411
- </label>
412
-
413
- <?php } ?>
414
-
415
- </fieldset>
416
-
417
- <?php
418
- }
419
-
420
-
421
- /**
422
- * Load the scripts on the menu page.
423
- *
424
- * @since 1.4
425
- */
426
- public function enqueue_scripts( $hook ) {
427
- if ( 'nav-menus.php' === $hook ) {
428
- wp_enqueue_script( 'nav-menu-roles', plugins_url( 'dist/js/roles.js', __FILE__ ), array( 'jquery' ), self::VERSION, true );
429
- }
430
- }
431
-
432
- /**
433
- * Save the roles as menu item meta
434
- *
435
- * @since 1.0
436
- * @return string
437
- */
438
- public function nav_update( $menu_id, $menu_item_db_id ) {
439
-
440
- // Verify this came from our screen and with proper authorization.
441
- if ( ! isset( $_POST['nav-menu-role-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['nav-menu-role-nonce'] ), 'nav-menu-nonce-name' ) ) {
442
- return;
443
- }
444
-
445
- if ( isset( $_POST['nav-menu-logged-in-out'][ $menu_item_db_id ] ) ) {
446
-
447
- if ( 'in' === $_POST['nav-menu-logged-in-out'][ $menu_item_db_id ] && ! empty( $_POST['nav-menu-role'][ $menu_item_db_id ] ) ) {
448
- $meta = wp_unslash( $_POST['nav-menu-role'][ $menu_item_db_id ] );
449
- } else {
450
- $meta = wp_unslash( $_POST['nav-menu-logged-in-out'][ $menu_item_db_id ] );
451
- }
452
-
453
- update_post_meta( $menu_item_db_id, '_nav_menu_role', $meta ); // Sanitization handled by $this->sanitize_meta().
454
-
455
- } else {
456
- delete_post_meta( $menu_item_db_id, '_nav_menu_role' );
457
- }
458
- }
459
-
460
- /**
461
- * Adds value of new field to $item object
462
- * is be passed to Walker_Nav_Menu_Edit_Custom
463
- *
464
- * @since 1.0
465
- */
466
- public function setup_nav_item( $menu_item ) {
467
-
468
- if ( is_object( $menu_item ) && isset( $menu_item->ID ) ) {
469
-
470
- $roles = get_post_meta( $menu_item->ID, '_nav_menu_role', true );
471
-
472
- if ( ! empty( $roles ) ) {
473
- $menu_item->roles = $roles;
474
-
475
- // Add the NMR roles as CSS info.
476
- $new_classes = array();
477
-
478
- switch ( $roles ) {
479
- case 'in':
480
- $new_classes[] = 'nmr-logged-in';
481
- break;
482
- case 'out':
483
- $new_classes[] = 'nmr-logged-out';
484
- break;
485
- default:
486
- if ( is_array( $menu_item->roles ) && ! empty( $menu_item->roles ) ) {
487
- foreach ( $menu_item->roles as $role ) {
488
- $new_classes[] = 'nmr-' . $role;
489
- }
490
- }
491
- break;
492
- }
493
-
494
- // Only apply classes on front-end.
495
- if ( ! is_admin() ) {
496
- $menu_item->classes = array_unique( array_merge( (array) $menu_item->classes, (array) $new_classes ) );
497
- }
498
- }
499
- }
500
- return $menu_item;
501
- }
502
-
503
- /**
504
- * Exclude menu items via wp_get_nav_menu_items filter
505
- * this fixes plugin's incompatibility with theme's that use their own custom Walker
506
- * Thanks to Evan Stein @vanpop http://vanpop.com/
507
- *
508
- * @since 1.2
509
- *
510
- * @param WP_Post[] array of Nav Menu Post objects
511
- *
512
- * Multisite compatibility added in 1.9.0
513
- * by @open-dsi https://www.open-dsi.fr/ with props to @fiech
514
- */
515
- public function exclude_menu_items( $items ) {
516
-
517
- $hide_children_of = array();
518
-
519
- if ( ! empty( $items ) ) {
520
-
521
- // Iterate over the items to search and destroy.
522
- foreach ( $items as $key => $item ) {
523
-
524
- $visible = true;
525
-
526
- // Hide any item that is the child of a hidden item.
527
- if ( isset( $item->menu_item_parent ) && in_array( $item->menu_item_parent, $hide_children_of ) ) {
528
- $visible = false;
529
- }
530
-
531
- // Check any item that has NMR roles set.
532
- if ( $visible && isset( $item->roles ) ) {
533
-
534
- // Check all logged in, all logged out, or role.
535
- switch ( $item->roles ) {
536
- case 'in':
537
- /**
538
- * Multisite compatibility.
539
- *
540
- * For the logged in condition to work,
541
- * the user has to be a logged in member of the current blog
542
- * or be a logged in super user.
543
- */
544
- $visible = is_user_member_of_blog() || is_super_admin() ? true : false;
545
- break;
546
- case 'out':
547
- /**
548
- * Multisite compatibility.
549
- *
550
- * For the logged out condition to work,
551
- * the user has to be either logged out
552
- * or not be a member of the current blog.
553
- * But they also may not be a super admin,
554
- * because logged in super admins should see the internal stuff, not the external.
555
- */
556
- $visible = ! is_user_member_of_blog() && ! is_super_admin() ? true : false;
557
- break;
558
- default:
559
- $visible = false;
560
- if ( is_array( $item->roles ) && ! empty( $item->roles ) ) {
561
- foreach ( $item->roles as $role ) {
562
- if ( current_user_can( $role ) ) {
563
- $visible = true;
564
- break;
565
- }
566
- }
567
- }
568
-
569
- break;
570
- }
571
- }
572
-
573
- /*
574
- * Filter: nav_menu_roles_item_visibility
575
- * Add filter to work with plugins that don't use traditional roles
576
- *
577
- * @param bool $visible
578
- * @param object $item
579
- */
580
- $visible = apply_filters( 'nav_menu_roles_item_visibility', $visible, $item );
581
-
582
- // Unset non-visible item.
583
- if ( ! $visible ) {
584
- if ( isset( $item->ID ) ) {
585
- $hide_children_of[] = $item->ID; // Store ID of item to hide it's children.
586
- }
587
- unset( $items[ $key ] );
588
- }
589
- }
590
- }
591
-
592
- return $items;
593
- }
594
-
595
-
596
- /**
597
- * Maybe upgrade
598
- *
599
- * @access public
600
- * @return void
601
- */
602
- public function maybe_upgrade() {
603
- $db_version = get_option( 'nav_menu_roles_db_version', false );
604
-
605
- // 1.7.7 upgrade: changed the debug notice so the old transient is invalid.
606
- if ( false === $db_version || version_compare( '1.7.7', $db_version, '<' ) ) {
607
- update_option( 'nav_menu_roles_db_version', self::VERSION );
608
- }
609
- }
610
-
611
- /**
612
- * Test WordPress version
613
- *
614
- * @access public
615
- * @param string $version - A WordPress version to compare against current version.
616
- * @return boolean
617
- */
618
- public static function is_wp_gte( $version = '5.4' ) {
619
- global $wp_version;
620
- return version_compare( strtolower( $wp_version ), strtolower( $version ), '>=' );
621
- }
622
-
623
- } // end class
624
-
625
- /**
626
- * Launch the whole plugin
627
- * Returns the main instance of Nav Menu Roles to prevent the need to use globals.
628
- *
629
- * @since 1.5
630
- * @return Nav_Menu_Roles
631
- */
632
- function nav_menu_roles() {
633
- return Nav_Menu_Roles::instance();
634
  }
635
-
636
- add_action( 'plugins_loaded', 'nav_menu_roles' );
637
-
638
- // Global for backwards compatibility.
639
- $GLOBALS['Nav_Menu_Roles'] = Nav_Menu_Roles();
3
  * Plugin Name: Nav Menu Roles
4
  * Plugin URI: http://www.kathyisawesome.com/449/nav-menu-roles/
5
  * Description: Hide custom menu items based on user roles.
6
+ * Version: 2.1.0
7
  * Author: Kathy Darling
8
  * Author URI: http://www.kathyisawesome.com
9
  * License: GPL-3.0
34
  exit();
35
  }
36
 
37
+ // Execute when not already loaded.
38
+ if ( ! class_exists( 'Nav_Menu_Roles' ) ) {
 
 
39
 
40
+ require_once dirname( __FILE__ ) . '/inc/class-nav-menu-roles.php';
 
 
 
 
41
 
42
  /**
43
+ * Launch the whole plugin
44
+ * Returns the main instance of Nav Menu Roles to prevent the need to use globals.
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  *
46
+ * @since 1.5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  * @return Nav_Menu_Roles
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  */
49
+ function nav_menu_roles() {
50
+ $instance = Nav_Menu_Roles::instance( __FILE__ );
51
 
52
+ // Global for backwards compatibility.
53
+ $GLOBALS['Nav_Menu_Roles'] = $instance;
54
 
55
+ return $instance;
56
  }
57
+ add_action( 'plugins_loaded', 'nav_menu_roles' );
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
 
 
 
 
 
readme.txt CHANGED
@@ -4,9 +4,9 @@ Contributors: helgatheviking
4
  Donate link: https://www.paypal.com/fundraiser/charity/1451316
5
  Tags: menu, menus, nav menu, nav menus
6
  Requires at least: 4.5.0
7
- Tested up to: 5.7.0
8
  Requires PHP: 5.3.2
9
- Stable tag: 2.0.2
10
  License: GPLv3
11
 
12
  Hide custom menu items based on user roles. PLEASE READ THE FAQ IF YOU ARE NOT SEEING THE SETTINGS.
@@ -265,6 +265,10 @@ Yes, but manually. WPML developers have informed me that the meta data for nav m
265
 
266
  == Changelog ==
267
 
 
 
 
 
268
  = 2.0.2 =
269
  * Fix: PHP Fatal error: Uncaught Error: Call to undefined method WP_Customize_Manager::settings_previewed(). settings_previewed() does not exist until WordPress 3.9.0+.
270
 
4
  Donate link: https://www.paypal.com/fundraiser/charity/1451316
5
  Tags: menu, menus, nav menu, nav menus
6
  Requires at least: 4.5.0
7
+ Tested up to: 6.0.0
8
  Requires PHP: 5.3.2
9
+ Stable tag: 2.1.0
10
  License: GPLv3
11
 
12
  Hide custom menu items based on user roles. PLEASE READ THE FAQ IF YOU ARE NOT SEEING THE SETTINGS.
265
 
266
  == Changelog ==
267
 
268
+ = 2.1.0 =
269
+ * New: Add support for "hiding" a menu item by role.
270
+
271
+
272
  = 2.0.2 =
273
  * Fix: PHP Fatal error: Uncaught Error: Call to undefined method WP_Customize_Manager::settings_previewed(). settings_previewed() does not exist until WordPress 3.9.0+.
274