Compare commits

..

45 Commits
0.17 ... master

Author SHA1 Message Date
abuyoyo
00ab82a35d 0.27
Some checks failed
Create Release / Create Release (push) Has been cancelled
2024-09-07 08:05:22 +03:00
abuyoyo
51cfce0071 0.27 - version bump + changelog 2024-09-07 08:04:22 +03:00
abuyoyo
416039449f composer.json - prepend-autoloader: false
Local vendor/autoload should not prepend if required locally.
Give precedence to main composer installation if available.
2024-09-07 00:44:37 +03:00
abuyoyo
e548158c15 0.26
Some checks failed
Create Release / Create Release (push) Has been cancelled
2024-09-01 08:04:08 +03:00
abuyoyo
41a42d3a2a 0.26 - version bump + changelog 2024-09-01 08:03:34 +03:00
abuyoyo
b6aca366b2 Mutation Observer replaces DOMNodeRemoved event 2024-09-01 07:48:58 +03:00
abuyoyo
7cc5b6de5a NoticeManager.bootstrap - refactor + modernize 2024-09-01 07:48:58 +03:00
abuyoyo
ca68f59a28 0.25
Some checks failed
Create Release / Create Release (push) Has been cancelled
2024-02-18 03:43:24 +02:00
abuyoyo
a3040b6c47 0.25 - version bump + changelog 2024-02-18 03:41:05 +02:00
abuyoyo
b99be56795 composer.lock + vendor/
- abuyoyo/metabox 0.8
- abuyoyo/adminmenupage 0.29
2024-02-18 03:34:30 +02:00
abuyoyo
3458b724be composer.json - update abuyoyo/adminmenupage ~0.29 2024-02-18 03:22:21 +02:00
abuyoyo
57fb24aa22 0.24
Some checks failed
Create Release / Create Release (push) Has been cancelled
2023-10-04 03:50:31 +03:00
abuyoyo
42db8f67df 0.24 - version bump + changelog 2023-10-04 02:40:21 +03:00
abuyoyo
1cd273bded composer.lock + vendor/ 2023-10-04 02:40:20 +03:00
abuyoyo
2c166a33a8 composer.json - update dependencies (PluginCore 0.27 supports plugin-update-checker v5|v4) 2023-10-04 02:40:20 +03:00
abuyoyo
1321d35bdf De-prioritize vendor/autoload.php 2023-10-04 02:40:20 +03:00
abuyoyo
7cf7b477bc PluginCore - set update_checker to true.
If Plugin-Update-Checker library (v4|v5) is available - enables updates from repo.
2023-10-04 01:29:04 +03:00
abuyoyo
42e26c9a4f 0.23
Some checks failed
Create Release / Create Release (push) Has been cancelled
2023-09-27 23:56:57 +03:00
abuyoyo
920dd0b683 0.23 - version bump + changelog 2023-09-27 23:21:52 +03:00
abuyoyo
fa4099a6dd composer.lock + vendor update 2023-09-27 23:21:50 +03:00
abuyoyo
2efc23c123 Update Description plugin header 2023-09-27 22:49:43 +03:00
abuyoyo
03473b957c Fix notices-panel removing all screen-meta-links panels when removing self 2023-09-27 22:32:57 +03:00
abuyoyo
ff4a8f542b Filter .hidden notices
Fix 0-count notices panel.
Fix wrong priority color plugin-count bullet on auto-collapsed panel.
2023-09-27 22:31:13 +03:00
abuyoyo
93afbe9b5b Fix plugin-count styling issue
.notice class was adding border to .plugin-count bullet
2023-09-27 22:24:20 +03:00
abuyoyo
bbec303755 0.22
Some checks failed
Create Release / Create Release (push) Has been cancelled
2023-08-11 22:37:46 +03:00
abuyoyo
24d4e54ca8 0.22 - version bump + changelog 2023-08-11 22:33:58 +03:00
abuyoyo
c0ca10a9c0 Fix - do not collect .theme-info notice 2023-08-11 22:33:58 +03:00
abuyoyo
0f13626dab Fix vendor/autoload.php include path 2023-08-11 22:33:56 +03:00
abuyoyo
320496722d 0.21
Some checks failed
Create Release / Create Release (push) Has been cancelled
2023-08-10 03:44:35 +03:00
abuyoyo
a856f85cb8 0.21 - version bump + changelog 2023-08-10 03:40:54 +03:00
abuyoyo
fcee298dab composer.lock + vendor update 2023-08-10 03:40:01 +03:00
abuyoyo
abedf94f24 composer.json - update abuyoyo/screen-meta-links ~0.13 2023-08-10 03:34:31 +03:00
abuyoyo
873b9abdd0 0.20
Some checks failed
Create Release / Create Release (push) Has been cancelled
2023-06-09 22:12:50 +03:00
abuyoyo
20eda54314 0.20 - version bump 2023-06-09 22:11:21 +03:00
abuyoyo
e9a5f8f71e 0.19
Some checks failed
Create Release / Create Release (push) Has been cancelled
2023-06-09 21:54:54 +03:00
abuyoyo
1d060b9a22 0.19 - version bump + changelog 2023-06-09 21:52:26 +03:00
abuyoyo
9d574615e8 composer.lock + vendor 2023-06-09 21:52:26 +03:00
abuyoyo
4229406ec8 composer.json - update dependencies 2023-06-09 21:46:48 +03:00
abuyoyo
acf477a0c0 vendor/autoload - check if file exists 2023-06-09 21:46:48 +03:00
abuyoyo
2bdd4b24b7 option: distraction_free 2023-06-09 21:46:48 +03:00
abuyoyo
bc1a864dd1 disable plugin-info meta box 2023-06-09 21:46:48 +03:00
abuyoyo
bffd39afe5 js - remove all semi-colons 2023-01-14 15:01:45 +02:00
abuyoyo
1cbb0a5aea 0.18
Some checks failed
Create Release / Create Release (push) Has been cancelled
2022-08-06 18:01:27 +03:00
abuyoyo
72684cf182 0.18 - version bump + changelog 2022-08-06 17:59:39 +03:00
abuyoyo
10b24ea86f composer.json + vendor - update dependencies 2022-08-06 17:59:39 +03:00
54 changed files with 1878 additions and 569 deletions

View File

@ -1,5 +1,79 @@
# Notice Manager Changelog # Notice Manager Changelog
## 0.27
Release date: Sep 7 2024
### Dependencies
- Composer config: `prepend-autoloader: false` - Give precedence to other composer installations if present.
## 0.26
Release date: Sep 1 2024
### Changed
- Use Mutation Observer instead of deprecated `DOMNodeRemoved` event.
### Added
- Add method `NoticeManager.bootstrap()` to initialize Notice manager.
## 0.25
Release date: Feb 18 2024
### Fixed
- Fix fatal error `Class "WPHelper\MetaBox" not found` due to dependency `abuyoyo/adminmenupage` < 0.29 not requiring dependency `abuyoyo/metabox`.
### Dependencies
- Library WPHelper\AdminPage (`abuyoyo/adminmenupage`) updated to 0.29. Requires `abuyoyo/metabox`.
## 0.24
Release date: Oct 4 2023
### Fixed
- Set `WPHelper\PluginCore` option `update_checker` to true. If library Plugin-Update-Checker is installed, allows updates from repo.
### Dependencies
- Library WPHelper\PluginCore (`abuyoyo/plugincore`) updated to 0.27. Supports both Plugin-Update-Checker v5 and v4.
## 0.23
### Fixed
- Fix `.plugin-count` bullet styling issue.
- Fix 0-count panel caused by collecting `.hidden` notices.
- Fix wrong priority color `.plugin-count` bullet caused by collecting `.hidden` notices.
- Fix empty notices-panel removing all screen-meta-link panels.
## 0.22
### Fixed
- Do not collect `.theme-info` notices.
- Fix `vendor/autoload` include path.
## 0.21
### Fixed
- Fix PHP 8.2 deprecated optional parameter before required parameter. Fixed upstream in `abuyoyo/screen-meta-links ~0.13`.
### Dependencies
- Update library `abuyoyo/screen-meta-links` to version 0.13.
## 0.20
### Minor
- Just another version bump (composer.json as well).
## 0.19
### Added
- Add 'Distraction Free' option.
## 0.18
### Minor
- Version bump everywhere.
## 0.17 ## 0.17
### Removed ### Removed

View File

@ -2,7 +2,7 @@
"name": "abuyoyo/notice-manager", "name": "abuyoyo/notice-manager",
"description": "Manage notices on WordPress admin pages. Adds 'Notices' screen-meta-link.", "description": "Manage notices on WordPress admin pages. Adds 'Notices' screen-meta-link.",
"type": "wordpress-plugin", "type": "wordpress-plugin",
"version": "0.17", "version": "0.27",
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "vcs",
@ -10,8 +10,11 @@
} }
], ],
"require":{ "require":{
"abuyoyo/screen-meta-links": "~0.11", "abuyoyo/screen-meta-links": "~0.13",
"abuyoyo/plugincore": "~0.22", "abuyoyo/plugincore": "~0.27",
"abuyoyo/adminmenupage": "~0.21" "abuyoyo/adminmenupage": "~0.29"
},
"config": {
"prepend-autoloader": false
} }
} }

86
composer.lock generated
View File

@ -4,24 +4,27 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "5d77ff6e04d24911491a5e639a4d1dd1", "content-hash": "b1a74cf1316f5dd317f70efeb60d9f4d",
"packages": [ "packages": [
{ {
"name": "abuyoyo/adminmenupage", "name": "abuyoyo/adminmenupage",
"version": "0.21", "version": "0.29",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/abuyoyo/AdminMenuPage.git", "url": "https://github.com/abuyoyo/AdminMenuPage.git",
"reference": "d05a9e9977d7e7c4ba3c913993493fefba4359d6" "reference": "4cd47d5217ca25ed17af76f5fdbab3cab3b37ef8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/abuyoyo/AdminMenuPage/zipball/d05a9e9977d7e7c4ba3c913993493fefba4359d6", "url": "https://api.github.com/repos/abuyoyo/AdminMenuPage/zipball/4cd47d5217ca25ed17af76f5fdbab3cab3b37ef8",
"reference": "d05a9e9977d7e7c4ba3c913993493fefba4359d6", "reference": "4cd47d5217ca25ed17af76f5fdbab3cab3b37ef8",
"shasum": "" "shasum": ""
}, },
"require": {
"abuyoyo/metabox": "~0.8"
},
"suggest": { "suggest": {
"abuyoyo/plugincore": "~0.18", "abuyoyo/plugincore": "~0.26",
"cmb2/cmb2": "~2.9" "cmb2/cmb2": "~2.9"
}, },
"type": "library", "type": "library",
@ -40,22 +43,22 @@
"description": "WordPress admin menu page helper class", "description": "WordPress admin menu page helper class",
"support": { "support": {
"issues": "https://github.com/abuyoyo/AdminMenuPage/issues", "issues": "https://github.com/abuyoyo/AdminMenuPage/issues",
"source": "https://github.com/abuyoyo/AdminMenuPage/tree/0.21" "source": "https://github.com/abuyoyo/AdminMenuPage/tree/0.29"
}, },
"time": "2022-08-06T13:42:37+00:00" "time": "2023-10-05T00:00:00+00:00"
}, },
{ {
"name": "abuyoyo/plugincore", "name": "abuyoyo/metabox",
"version": "0.22", "version": "0.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/abuyoyo/PluginCore.git", "url": "https://github.com/abuyoyo/MetaBox.git",
"reference": "736b38d82fc41c7102ec28f386f4df807a10ab05" "reference": "98cb4c30db4c366c0d273985eb9c31ffa1cd78f9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/abuyoyo/PluginCore/zipball/736b38d82fc41c7102ec28f386f4df807a10ab05", "url": "https://api.github.com/repos/abuyoyo/MetaBox/zipball/98cb4c30db4c366c0d273985eb9c31ffa1cd78f9",
"reference": "736b38d82fc41c7102ec28f386f4df807a10ab05", "reference": "98cb4c30db4c366c0d273985eb9c31ffa1cd78f9",
"shasum": "" "shasum": ""
}, },
"type": "library", "type": "library",
@ -68,25 +71,60 @@
"license": [ "license": [
"BSD-3-Clause" "BSD-3-Clause"
], ],
"description": "WordPress metabox helper class",
"support": {
"issues": "https://github.com/abuyoyo/MetaBox/issues",
"source": "https://github.com/abuyoyo/MetaBox/tree/0.8"
},
"time": "2023-07-18T19:14:03+00:00"
},
{
"name": "abuyoyo/plugincore",
"version": "0.27",
"source": {
"type": "git",
"url": "https://github.com/abuyoyo/PluginCore.git",
"reference": "d730a674cbe2dc92e60ace8e25a2e0e3fdeee3e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/abuyoyo/PluginCore/zipball/d730a674cbe2dc92e60ace8e25a2e0e3fdeee3e6",
"reference": "d730a674cbe2dc92e60ace8e25a2e0e3fdeee3e6",
"shasum": ""
},
"suggest": {
"abuyoyo/adminmenupage": "~0.27",
"yahnis-elsts/plugin-update-checker": "~5.2"
},
"type": "library",
"autoload": {
"psr-4": {
"WPHelper\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "WordPress plugin core helper class", "description": "WordPress plugin core helper class",
"support": { "support": {
"issues": "https://github.com/abuyoyo/PluginCore/issues", "issues": "https://github.com/abuyoyo/PluginCore/issues",
"source": "https://github.com/abuyoyo/PluginCore/tree/0.22" "source": "https://github.com/abuyoyo/PluginCore/tree/0.27"
}, },
"time": "2022-08-05T00:00:00+00:00" "time": "2022-10-03T00:00:00+00:00"
}, },
{ {
"name": "abuyoyo/screen-meta-links", "name": "abuyoyo/screen-meta-links",
"version": "0.11", "version": "0.13",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/abuyoyo/screen-meta-links.git", "url": "https://github.com/abuyoyo/screen-meta-links.git",
"reference": "04e3c892f0c6095b4c31a489e06336f0917128d3" "reference": "b324cef9eb5825d04ffa17f771237b7deca5cd01"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/abuyoyo/screen-meta-links/zipball/04e3c892f0c6095b4c31a489e06336f0917128d3", "url": "https://api.github.com/repos/abuyoyo/screen-meta-links/zipball/b324cef9eb5825d04ffa17f771237b7deca5cd01",
"reference": "04e3c892f0c6095b4c31a489e06336f0917128d3", "reference": "b324cef9eb5825d04ffa17f771237b7deca5cd01",
"shasum": "" "shasum": ""
}, },
"type": "library", "type": "library",
@ -97,10 +135,10 @@
}, },
"description": "API for adding custom screen-meta-links alongside the 'Screen Options' and 'Help' links.", "description": "API for adding custom screen-meta-links alongside the 'Screen Options' and 'Help' links.",
"support": { "support": {
"source": "https://github.com/abuyoyo/screen-meta-links/tree/0.11", "source": "https://github.com/abuyoyo/screen-meta-links/tree/0.13",
"issues": "https://github.com/abuyoyo/screen-meta-links/issues" "issues": "https://github.com/abuyoyo/screen-meta-links/issues"
}, },
"time": "2022-05-18T01:18:24+00:00" "time": "2023-08-08T22:37:03+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],
@ -108,8 +146,8 @@
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": [],
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": true,
"platform": [], "platform": [],
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.1.0" "plugin-api-version": "2.3.0"
} }

View File

@ -2,160 +2,181 @@
* NoticeManager class/module * NoticeManager class/module
* *
*/ */
var NoticeManager = (function ($, document) { const NoticeManager = function ($) {
let options = window.notice_manager_options;
let selectors_notice = [ const selectors_notice = [
"div.notice", "div.notice",
"div.updated", "div.updated",
]; ]
let selectors_warning = [ const selectors_warning = [
"div.notice-warning", "div.notice-warning",
"div.update-nag", "div.update-nag",
]; ]
let selectors_error = [ const selectors_error = [
"div.error", "div.error",
"div.notice-error", "div.notice-error",
]; ]
let selectors_all = selectors_notice.concat(selectors_warning, selectors_error); const selectors_all = selectors_notice.concat(selectors_warning, selectors_error)
const selectors_skip = [
".inline",
".below-h2",
".theme-info .notice",
".hidden",
]
// wait function used with autoCollapse // wait function used with autoCollapse
let wait = function (ms) { const wait = function (ms) {
var dfd = $.Deferred(); var dfd = $.Deferred()
setTimeout(dfd.resolve, ms); //callback, timeout till callback setTimeout(dfd.resolve, ms) //callback, timeout till callback
return dfd.promise(); return dfd.promise()
}; }
let notices; const options = window.notice_manager_options
let button; let notices
let panel;
let haveClosed; // set to true on first close/collect
let dismissNoticesButton;
// bootstrap let button
// some of these need to run BEFORE document.ready - don't know why really let panel
button = $("#meta-link-notices"); let dismissNoticesButton
panel = $("#meta-link-notices-wrap");
haveClosed = false;
dismissNoticesButton = $("#meta-link-notices-wrap button.notice-dismiss");
dismissNoticesButton.on("click", () => { let haveClosed // set to true on first close/collect
screenMeta.close(panel, button); let panelObserver
if (! haveClosed){
NoticeManager.collectNotices();
}
NoticeManager.addCounter();
});
//original wp focus on click function
button.on("focus.scroll-into-view", (e) => {
if (e.target.scrollIntoView) e.target.scrollIntoView(false);
});
// scroll page to top when closing notice panel
// function used to work with $(this)
// using e.target instead
// not sure if this should perhaps be e.currentTarget
button.on("click", (e) => {
if ($(e.target).hasClass("screen-meta-active")) {
if (haveClosed) {
NoticeManager.addCounter();
}
// $(window).scrollTop(true);
} else {
NoticeManager.removeCounter();
// wait (500).then(function(){ //still jumpy sometimes - but scrolls to correct position 400 ~ 600
// $(window).scrollTop(true);
// });
}
});
/**
* document.on.ready
*/
$(() => {
console.log("NoticeManager.on.ready");
console.log("options");
console.log(options);
// bootstrap notices
// get all notices that are not explicitly marked as `.inline` or `.below-h2`
// we add .update-nag.inline for WordPress Update notice
notices = $( selectors_all.join(', ') )
.not(".inline, .below-h2")
.add("div.update-nag");
/**
* Remove panel if there are no notices on this page
*/
if (options.screen_panel) {
NoticeManager.maybeRemoveNoticesPanel();
}
if (options.screen_panel && options.auto_collect) {
NoticeManager.collectNotices();
} else {
if (options.above_title) {
NoticeManager.moveAboveTitle();
}
}
/**
* auto-open notices panel
*/
if (button.length) {
panel.toggle();
button.addClass("screen-meta-active");
screenMeta.open(panel, button);
}
/**
* auto-close notices panel after short delay
* only auto-close if we have collected notices previously
* only auto-close if no error messages
*/
if (options.auto_collapse) {
wait(4000).then(() => {
if (haveClosed && NoticeManager.getNoticesTopPriority() != 'error') {
screenMeta.close(panel, button);
NoticeManager.addCounter();
}
});
}
}); // end document.on.ready
// prevent jumpy scrollRestoration on reload page
// fixed below on 'beforeunload'
// if (history.scrollRestoration) {
// history.scrollRestoration = 'manual';
//}
/**
* Set history.scrollTop to prevent jump on page refresh when scrollRestoration = auto
*/
$(window).on("beforeunload", () => {
history.pushState(
{ scrollTop: document.body.scrollTop },
document.title,
document.location.pathname
);
});
return { return {
bootstrap: () => {
// Init selectors
button = $("#meta-link-notices")
panel = $("#meta-link-notices-wrap")
dismissNoticesButton = $("#meta-link-notices-wrap button.notice-dismiss")
// bootstrap notices
// get all notices that are not explicitly marked as `.inline` or `.below-h2`
// we add .update-nag.inline for WordPress Update notice
notices = $(selectors_all.join(', '))
.not(selectors_skip.join(', '))
.add("div.update-nag")
// Set state
haveClosed = false
dismissNoticesButton.on("click", () => {
screenMeta.close(panel, button)
if (!haveClosed) {
NoticeManager.collectNotices()
}
NoticeManager.addCounter()
})
//original wp focus on click function
button.on("focus.scroll-into-view", (e) => {
if (e.target.scrollIntoView) e.target.scrollIntoView(false)
})
// scroll page to top when closing notice panel
// function used to work with $(this)
// using e.target instead
// not sure if this should perhaps be e.currentTarget
button.on("click", (e) => {
if ($(e.target).hasClass("screen-meta-active")) {
if (haveClosed) {
NoticeManager.addCounter()
}
// $(window).scrollTop(true)
} else {
NoticeManager.removeCounter()
// wait (500).then(function(){ //still jumpy sometimes - but scrolls to correct position 400 ~ 600
// $(window).scrollTop(true)
// })
}
})
// prevent jumpy scrollRestoration on reload page
// fixed below on 'beforeunload'
// if (history.scrollRestoration) {
// history.scrollRestoration = 'manual'
//}
/**
* Set history.scrollTop to prevent jump on page refresh when scrollRestoration = auto
*/
$(window).on('beforeunload', () => history.pushState(
{ scrollTop: document.body.scrollTop },
document.title,
document.location.pathname
)
)
/**
* Remove panel if there are no notices on this page
*/
if (options.screen_panel) {
NoticeManager.maybeRemoveNoticesPanel()
}
if (options.screen_panel && options.auto_collect) {
NoticeManager.collectNotices()
} else {
if (options.above_title) {
NoticeManager.moveAboveTitle()
}
}
/**
* auto-open notices panel
*/
if (button.length && !options.distraction_free) {
panel.toggle()
button.addClass("screen-meta-active")
screenMeta.open(panel, button)
}
/**
* auto-close notices panel after short delay
* only auto-close if we have collected notices previously
* only auto-close if no error messages
*/
if (options.auto_collapse && !options.distraction_free) {
wait(4000).then(() => {
if (haveClosed && NoticeManager.getNoticesTopPriority() != 'error') {
screenMeta.close(panel, button)
NoticeManager.addCounter()
}
})
}
if (options.distraction_free) {
NoticeManager.addCounterWhenClosed()
}
},
getNotices: () => notices, getNotices: () => notices,
getNoticesTopPriority: () => { getNoticesTopPriority: () => {
if (notices.filter(":visible").filter(selectors_error.join(", ")).length) if (notices.filter(":visible").filter(selectors_error.join(", ")).length)
return 'error'; return 'error'
if (notices.filter(":visible").filter(selectors_warning.join(", ")).length) if (notices.filter(":visible").filter(selectors_warning.join(", ")).length)
return 'warning'; return 'warning'
return 'notice'; return 'info'
},
/**
* .filter(":visible") unreliable when closed
*
* @returns {string} top priority
*/
getNoticesTopPriorityWhenClosed: () => {
if (notices.filter(selectors_error.join(", ")).length)
return 'error'
if (notices.filter(selectors_warning.join(", ")).length)
return 'warning'
return 'info'
}, },
/** /**
@ -163,39 +184,50 @@ var NoticeManager = (function ($, document) {
* Remove dismiss-notices button. * Remove dismiss-notices button.
*/ */
collectNotices: () => { collectNotices: () => {
notices.appendTo(".notice_container").eq(0); notices.appendTo(".notice_container").eq(0)
$(".notice_container").removeClass("empty"); // .empty removes padding $(".notice_container").removeClass("empty") // .empty removes padding
haveClosed = true; // initial collection has occurred. haveClosed = true // initial collection has occurred.
/** /**
* When dismissible notices are dismissed, check if any notices are left on page. * When dismissible notices are dismissed, check if any notices are left on page.
* If no notices are left - remove Notice Panel entirely * If no notices are left - remove Notice Panel entirely
*/ */
$(document).on( panelObserver = new MutationObserver(() => {
"DOMNodeRemoved", notices = panel
"#meta-link-notices-wrap div.notice", .find(selectors_all.join(", "))
() => { .filter(":visible")
notices = panel NoticeManager.maybeRemoveNoticesPanel()
.find(selectors_all.join(", ")) });
.filter(":visible"); panelObserver.observe(panel.get(0), { childList: true, subtree: true }); // only run once
NoticeManager.maybeRemoveNoticesPanel();
}
);
}, },
addCounter: () => { addCounter: () => {
if (!button.children('.plugin-count').length){ if (!button.children('.plugin-count').length) {
button.append( button.append(
$("<span/>").text(notices.filter(":visible").length).attr({ $("<span/>").text(notices.filter(":visible").length).attr({
class: "plugin-count", class: "plugin-count",
}).addClass(NoticeManager.getNoticesTopPriority()) }).addClass(NoticeManager.getNoticesTopPriority())
); )
}
},
/**
* cannot rely on filter(:visible)
*/
addCounterWhenClosed: () => {
if (!button.children('.plugin-count').length) {
button.append(
$("<span/>").text(notices.length).attr({
class: "plugin-count",
}).addClass(NoticeManager.getNoticesTopPriorityWhenClosed())
)
} }
}, },
removeCounter: () => { removeCounter: () => {
button.children(".plugin-count").remove(); button.children(".plugin-count").remove()
}, },
/** /**
@ -204,13 +236,14 @@ var NoticeManager = (function ($, document) {
*/ */
maybeRemoveNoticesPanel: () => { maybeRemoveNoticesPanel: () => {
if (!notices.length) { if (!notices.length) {
screenMeta.close(panel, button); screenMeta.close(panel, button)
$("#meta-link-notices-link-wrap").detach(); $("#meta-link-notices-link-wrap").detach()
$("#meta-link-notices-wrap").detach(); $("#meta-link-notices-wrap").detach()
if (!$("#screen-meta-links").children().length) if ($("#screen-meta-links").children().length == 0) {
$("#screen-meta-links").detach(); $("#screen-meta-links").detach()
}
} }
}, },
@ -220,7 +253,9 @@ var NoticeManager = (function ($, document) {
* I HATE it when WordPress moves notices below title. * I HATE it when WordPress moves notices below title.
*/ */
moveAboveTitle: () => { moveAboveTitle: () => {
notices.insertBefore(".wrap:first"); notices.insertBefore(".wrap:first")
}, },
}; }
}(jQuery,document) ) }(jQuery);
jQuery(NoticeManager.bootstrap);

View File

@ -1,8 +1,8 @@
<?php <?php
/** /**
* Plugin Name: Notice Manager * Plugin Name: Notice Manager
* Description: Manage notices on WordPress admin pages. Adds 'Notices' screen-meta-link. * Description: Manage notices on WordPress admin pages. Adds 'Notices' screen-meta-link panel to collect notices from page.
* Version: 0.17 * Version: 0.27
* Author: abuyoyo * Author: abuyoyo
* Author URI: https://github.com/abuyoyo/ * Author URI: https://github.com/abuyoyo/
* Plugin URI: https://github.com/abuyoyo/notice-manager * Plugin URI: https://github.com/abuyoyo/notice-manager
@ -10,9 +10,24 @@
*/ */
defined( 'ABSPATH' ) || die( 'No soup for you!' ); defined( 'ABSPATH' ) || die( 'No soup for you!' );
use WPHelper\PluginCore; /**
* Dependencies
* Allow all other auto-loaders to fail before including our own.
*/
if (
! class_exists( 'WPHelper\PluginCore' )
||
! class_exists( 'WPHelper\AdminPage' )
||
! function_exists( 'wph_add_screen_meta_panel' )
)
{
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ){
require_once __DIR__ . '/vendor/autoload.php';
}
}
require_once 'vendor/autoload.php'; use WPHelper\PluginCore;
/** /**
* Bootstrap plugin and admin page (Tools > Notice Manager) * Bootstrap plugin and admin page (Tools > Notice Manager)
@ -29,7 +44,7 @@ new PluginCore(
'admin_page' => [ 'admin_page' => [
'parent' => 'options', 'parent' => 'options',
'render' => 'settings-page', // built-in settings page 'render' => 'settings-page', // built-in settings page
'plugin_info' => true, // 'plugin_info' => true, // disable on public repo
'settings' => [ 'settings' => [
'option_name' => 'notice_manager', // option_name used in wp_options table 'option_name' => 'notice_manager', // option_name used in wp_options table
'sections' => [ 'sections' => [
@ -62,12 +77,19 @@ new PluginCore(
'type' => 'checkbox', 'type' => 'checkbox',
'description' => 'If auto-collect is enabled - Notices panel will stay open for a few seconds on page load, and then close automatically. Panel will not auto-collapse if it contains `error` level notices.', 'description' => 'If auto-collect is enabled - Notices panel will stay open for a few seconds on page load, and then close automatically. Panel will not auto-collapse if it contains `error` level notices.',
], ],
] [
] 'id' => 'distraction_free',
] 'title' => 'Distraction Free',
] 'type' => 'checkbox',
] 'description' => 'Notice Panel is closed on page load. Requires auto_collect.'
] ],
],
],
],
],
],
'update_checker' => true, // If Plugin Update Checker library is available - allow updates/auto-updates.
],
); );
require_once 'src/NoticeManager.php'; require_once 'src/NoticeManager.php';

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "notice-manager", "name": "notice-manager",
"version": "0.16.0", "version": "0.18.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "notice-manager", "name": "notice-manager",
"version": "0.16.0", "version": "0.18.0",
"description": "Manage notices on WordPress admin pages. Adds 'Notices' screen-meta-link.", "description": "Manage notices on WordPress admin pages. Adds 'Notices' screen-meta-link.",
"author": "abuyoyo", "author": "abuyoyo",
"repository": { "repository": {

View File

@ -1,6 +1,83 @@
# Changelog # Changelog
WPHelper\AdminMenuPage WPHelper\AdminMenuPage
## 0.29
Release date: Oct 5 2023
### Fixed
- `composer.json` - Require `abuyoyo/metabox`. WPHelper\Metabox has been a required library since 0.25.
### Dependencies
- lib: WPHelper\Metabox (`abuyoyo/metabox`) ~0.8.
## 0.28
Release date: Oct 4 2023
### Added
- Option `parent` accepts `tools` as shorthand for `tools.php`.
- Add link to Install Plugin page in "CMB2 plugin missing" template.
## 0.27
Release date: Sep 10 2023
### Fixed
- Fix nav-tabs appearing on pages without `tab_group`.
## 0.26
Release date: Jun 20 2023
### Added
- Add `allow_on_front` setting to CMB2 pages. Hooks metabox on `cmb2_init` instead of `cmb2_admin_init`.
- If defined `WPH_DEBUG` add WPHelper classes debug information to plugin info meta box.
## 0.25
Release date: Jun 9 2023
### Added
- Non-CMB2 pages can be added to CMB2 tab groups. New options `tab_group` and `tab_title`
### Changed
- New method `render_plugin_info_meta_box`. Deprecate `render_plugin_info_box`.
- Plugin info meta box rendered using `WPHelper\MetaBox`.
### Fixed
- Fix several PHP undefined variable warnings.
### Internal
- Setting pages/wrap template uses WordPress Core `do_meta_boxes` to render `side` meta boxes div.
- Add variables to `AdminPage::options()` array.
- Multiple code refactoring and template restructuring.
## 0.24
Release date: Jan 28 2023
### Fixed
- Fix plugin info meta box when no PluginCore is available.
- Fix PHP deprecated notice.
## 0.23
Release date: Jan 15 2023
### Added
- Add action hook `wphelper/plugin_info_meta_box/{$slug}` to modify and render plugin info meta box.
- Add support for `textarea` input field in SettingsPage.
- Add `sanitize_callback` option - allow plugins to supply their own sanitize function.
- Add `render` to fields - allow plugins to supply their own render callback for fields.
- Add `placeholder` to fields - allow plugins to supply placeholder values for fields.
### Fixed
- Fix default value handling for fields.
### Internal
- Rename `tpl/` template parts.
- Minor changes and fixes.
## 0.22
Release date: Jan 1 2023
### Fixed
- Fix error when `plugin_info = true` but `plugin_core` is not set.
## 0.21 ## 0.21
### Fixed ### Fixed
@ -9,7 +86,7 @@ WPHelper\AdminMenuPage
## 0.20 ## 0.20
### Added ### Added
- Add SettingsPage section option `desciption-container`. Accepts `card` div, `notice`, `notice-info` and `none`. - Add SettingsPage section option `description-container`. Accepts `card` div, `notice`, `notice-info` and `none`.
- Sanitize SettingsPage text, url and email fields. - Sanitize SettingsPage text, url and email fields.
## 0.19 ## 0.19
@ -19,7 +96,7 @@ WPHelper\AdminMenuPage
- CMB2_OptionsPage supports all admin menu top-level slugs. - CMB2_OptionsPage supports all admin menu top-level slugs.
### Fixed ### Fixed
- Fixed PHP fatal error: cannot redeclare function `wph_extra_plugin_headers()`. - Fix PHP fatal error: cannot redeclare function `wph_extra_plugin_headers()`.
### Changed ### Changed
- If CMB2 plugin is not activated - show missing plugin card on `cmb2` and `cmb2-tabs` pages. - If CMB2 plugin is not activated - show missing plugin card on `cmb2` and `cmb2-tabs` pages.

View File

@ -19,7 +19,7 @@ require __DIR__ . '/vendor/autoload.php';
WPHelper\AdminMenuPage uses [PSR-4](https://www.php-fig.org/psr/psr-4/) to autoload. WPHelper\AdminMenuPage uses [PSR-4](https://www.php-fig.org/psr/psr-4/) to autoload.
OR OR
Install as WordPress plugin and activate. Install as WordPress plugin and activate.
@ -40,14 +40,13 @@ $args = [
'icon_url' => $icon_url; // optional - icon url passed to add_menu_page/add_submenu_page 'icon_url' => $icon_url; // optional - icon url passed to add_menu_page/add_submenu_page
'position' => 4; // optional - passed to add_menu_page 'position' => 4; // optional - passed to add_menu_page
'scripts' => [ // optional - script parameters passed to enqueue_scripts. Will only enqueue scripts on admin page 'scripts' => [ // optional - script parameters passed to enqueue_scripts. Will only enqueue scripts on admin page
[ 'script_handle', 'js/myscript.js', ['jquery'], false, true ], [ 'script_handle', 'js/my_script.js', ['jquery'], false, true ],
[ 'another_script', 'js/my_other_script.js', ['jquery', 'script_handle'], false, true ] [ 'another_script', 'js/my_other_script.js', ['jquery', 'script_handle'], false, true ]
]; ];
]; ];
// Register the admin menu page. // Register the admin menu page.
$admin_menu_page = new AdminPage( $args ); $admin_menu_page = new AdminPage( $args );
$admin_menu_page->setup();
// That's it. We're done. // That's it. We're done.
// This function can be called from anywhere. No need to wrap in any hook. // This function can be called from anywhere. No need to wrap in any hook.

View File

@ -2,10 +2,14 @@
"name": "abuyoyo/adminmenupage", "name": "abuyoyo/adminmenupage",
"description": "WordPress admin menu page helper class", "description": "WordPress admin menu page helper class",
"type": "library", "type": "library",
"version": "0.21", "version": "0.29",
"time": "2023-10-05",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"require": {
"abuyoyo/metabox": "~0.8"
},
"suggest": { "suggest": {
"abuyoyo/plugincore": "~0.18", "abuyoyo/plugincore": "~0.26",
"cmb2/cmb2": "~2.9" "cmb2/cmb2": "~2.9"
}, },
"autoload": { "autoload": {

View File

@ -3,7 +3,7 @@ namespace WPHelper;
defined( 'ABSPATH' ) || die( 'No soup for you!' ); defined( 'ABSPATH' ) || die( 'No soup for you!' );
if ( ! class_exists( 'WPHelper\AdminMenuPage' ) ): if ( ! class_exists( AdminMenuPage::class ) ):
/** /**
* AdminMenuPage * AdminMenuPage
* *

View File

@ -1,13 +1,15 @@
<?php <?php
namespace WPHelper; namespace WPHelper;
use CMB2_Options_Hookup;
defined( 'ABSPATH' ) || die( 'No soup for you!' ); defined( 'ABSPATH' ) || die( 'No soup for you!' );
use function add_menu_page; use function add_menu_page;
use function add_options_page; use function add_options_page;
use function add_submenu_page; use function add_submenu_page;
if ( ! class_exists( 'WPHelper\AdminPage' ) ): if ( ! class_exists( AdminPage::class ) ):
/** /**
* AdminPage * AdminPage
* *
@ -106,6 +108,20 @@ class AdminPage
*/ */
protected $wrap; protected $wrap;
/**
* Tab Group
*
* @var string CMB2 tab group
*/
protected $tab_group;
/**
* Tab Title
*
* @var string CMB2 tab title
*/
protected $tab_title;
/** /**
* Render callback function. * Render callback function.
* *
@ -120,6 +136,13 @@ class AdminPage
*/ */
protected $scripts; protected $scripts;
/**
* Settings
*
* @var array[] arrays of settings sections and fields
*/
protected $settings;
/** /**
* Styles * Styles
* *
@ -156,11 +179,18 @@ class AdminPage
protected $settings_page; protected $settings_page;
/** /**
* Delegate admin_menu hookup to CMB2 implementation * CMB2 custom settings page
* *
* @var boolean * @var CMB2_OptionsPage|CMB2_OptionsPage_Multi
*/ */
protected $delegate_hookup = false; protected $cmb2_page;
/**
* Plugin Info Meta Box render object
*
* @var PluginInfoMetaBox
*/
protected $plugin_info_meta_box;
/** /**
* Constructor. * Constructor.
@ -178,14 +208,13 @@ class AdminPage
if ( isset( $options->plugin_core ) ) if ( isset( $options->plugin_core ) )
$this->plugin_core( $options->plugin_core ); $this->plugin_core( $options->plugin_core );
if ( isset( $options->title ) ) $this->title( $options->title ?? null );
$this->title( $options->title );
/** /**
* @todo move this to bootstrap() * @todo move this to bootstrap()
*/ */
if ( ! isset( $options->menu_title ) ) if ( ! isset( $options->menu_title ) )
$options->menu_title = $options->title; $options->menu_title = $this->title;
if ( isset( $options->menu_title ) ) if ( isset( $options->menu_title ) )
$this->menu_title( $options->menu_title ); $this->menu_title( $options->menu_title );
@ -193,8 +222,7 @@ class AdminPage
if ( isset( $options->capability ) ) if ( isset( $options->capability ) )
$this->capability( $options->capability ); $this->capability( $options->capability );
if ( isset( $options->slug ) ) $this->slug( $options->slug ?? null );
$this->slug( $options->slug );
if ( isset( $options->plugin_info ) ){ // before render() if ( isset( $options->plugin_info ) ){ // before render()
$this->plugin_info( $options->plugin_info ); $this->plugin_info( $options->plugin_info );
@ -204,21 +232,24 @@ class AdminPage
$this->wrap( $options->wrap ); $this->wrap( $options->wrap );
} }
if ( isset( $options->render ) ) // dev if ( isset( $options->render_cb ) )
$this->render( $options->render );
if ( isset( $options->render_cb ) ) // dev - deprecate?
$this->render_cb( $options->render_cb ); $this->render_cb( $options->render_cb );
if ( isset( $options->render_tpl ) ) // dev - deprecate? if ( isset( $options->render_tpl ) ) // before render()
$this->render_tpl( $options->render_tpl ); $this->render_tpl( $options->render_tpl );
// This runs last so we can have 'settings-page' with custom render_tpl
if ( isset( $options->render ) )
$this->render( $options->render );
if (true) if (true)
$this->render(); // render anyway - will use default tpl if render is empty $this->render(); // render anyway - will use default tpl if render is empty
if (true) if (true)
$this->wrap(); // set wrap anyway - will set to 'none' if empty $this->wrap(); // set wrap anyway - will set to 'none' if empty
if ( isset( $options->parent ) ) if ( isset( $options->parent ) )
$this->parent( $options->parent ); $this->parent( $options->parent );
@ -228,6 +259,11 @@ class AdminPage
if ( isset( $options->position ) ) if ( isset( $options->position ) )
$this->position( $options->position ); $this->position( $options->position );
if ( isset( $options->tab_group ) ){
$this->tab_group( $options->tab_group );
$this->tab_title( $options->tab_title ?? $options->submenu_title ?? $options->menu_title );
}
if ( isset( $options->scripts ) ) if ( isset( $options->scripts ) )
$this->scripts( $options->scripts ); $this->scripts( $options->scripts );
@ -253,8 +289,8 @@ class AdminPage
* *
* @access private * @access private
*/ */
private function title( $title ) { private function title( $title=null ) {
$this->title = $title; $this->title = $title ?? ( isset( $this->plugin_core ) ? $this->plugin_core->title() : __METHOD__ );
} }
/** /**
@ -284,7 +320,19 @@ class AdminPage
* @access private * @access private
*/ */
private function slug( $slug ) { private function slug( $slug ) {
$this->slug = $slug;
$this->slug = $slug // if not empty
?: $this->settings['option_key'] // if isset option_key
?? (
isset( $this->plugin_core )
? (
method_exists( PluginCore::class, 'token' )
? $this->plugin_core->token() // PluginCore ~0.25
: str_replace('-','_', strtolower( $this->plugin_core->slug() ) ) // PluginCore <= 0.24
)
: 'slug' . time() // unique slug
);
} }
/** /**
@ -300,6 +348,10 @@ class AdminPage
case 'options-general.php': case 'options-general.php':
$this->parent = 'options-general.php'; $this->parent = 'options-general.php';
break; break;
case 'tools':
case 'tools.php':
$this->parent = 'tools.php';
break;
default: default:
$this->parent = $parent; $this->parent = $parent;
break; break;
@ -316,7 +368,6 @@ class AdminPage
$this->icon_url = $icon_url; $this->icon_url = $icon_url;
} }
/** /**
* Setter - position * Setter - position
* WordPress admin menu param * WordPress admin menu param
@ -327,6 +378,44 @@ class AdminPage
$this->position = $position; $this->position = $position;
} }
/**
* Setter - tab_group
* CMB2 Tab Group - used by regular 'wrap' pages as well.
*
* @access private
*/
private function tab_group( $tab_group ) {
$this->tab_group = $tab_group;
add_filter( 'cmb2_tab_group_tabs', [ $this, 'add_to_tab_group' ], 10, 2 );
add_action( 'cmb2_admin_init', function(){
/**
* When deactivating CMB2 and reactivating - got this fatal error:
*
* Fatal error: Uncaught Error: Argument 1 passed to CMB2_Options_Hookup::__construct()
* must be an instance of CMB2, bool given,
* called in \wp-content\plugins\cgv\inc\CGV.php on line 56
* in \wp-content\plugins\cmb2\includes\CMB2_Options_Hookup.php on line 39
*
* Validate cmb2_get_metabox did not return false.
*/
if ( $cmb = cmb2_get_metabox( $this->parent ) ){
$hookup = new CMB2_Options_Hookup( $cmb, $this->slug );
add_action ( "wphelper/adminpage/tab_nav/{$this->tab_group}", [ $hookup, 'options_page_tab_nav_output' ] );
}
});
}
/**
* Setter - tab_title
* CMB2 Tab Title - only set if tab_group.
*
* @access private
*/
private function tab_title( $tab_title ) {
$this->tab_title = $tab_title;
}
/** /**
* Setter - render * Setter - render
* Sets render cb or tpl * Sets render cb or tpl
@ -340,34 +429,30 @@ class AdminPage
*/ */
private function render( $render=null ) { private function render( $render=null ) {
if ( 'settings-page' == $render ) { if ( 'settings-page' == $render ) {
$this->render_tpl( __DIR__ . '/tpl/settings-form.php' ); $this->render_tpl( __DIR__ . '/tpl/form-basic.php' );
$this->render = $this->render ?? $render; // 'settings-page' $this->render = $this->render ?? $render; // 'settings-page'
} else if ( 'cmb2' == $render || 'cmb2-tabs' == $render ) { } else if ( 'cmb2' == $render || 'cmb2-tabs' == $render ) {
// validate // validate
if ( ! defined( 'CMB2_LOADED' ) ){ if ( ! defined( 'CMB2_LOADED' ) ){
$this->render_tpl( __DIR__ . '/tpl/cmb2-unavailable.php' ); $this->render_tpl( __DIR__ . '/tpl/wrap-cmb2-unavailable.php' );
$this->render = $this->render ?? 'render_tpl'; $this->render = $this->render ?? 'render_tpl';
} else { } else {
$this->delegate_hookup = true; /**
* Render templates managed and included by CMB2_OptionsPage
if ( ! empty( $this->plugin_core ) || ! empty( $this->plugin_info ) ){ * @see CMB2_OptionsPage::options_page_output()
$this->render_tpl( __DIR__ . '/tpl/cmb2_options_page-plugin_info.php' ); */
} else {
$this->render_tpl( __DIR__ . '/tpl/cmb2_options_page.php' );
}
$this->render = $this->render ?? $render; // 'cmb2' || 'cmb2-tabs' $this->render = $this->render ?? $render; // 'cmb2' || 'cmb2-tabs'
} }
} else if( is_callable( $render ) ) { } else if( is_callable( $render ) ) {
$this->render_cb( $render ); $this->render_cb( $render );
$this->render = $this->render ?? 'render_cb'; $this->render = $this->render ?? 'render_cb';
} else if ( is_readable( $render ) ) { } else if ( is_readable( $render ?? '' ) ) {
$this->render_tpl( $render ); $this->render_tpl( $render );
$this->render = $this->render ?? 'render_tpl'; $this->render = $this->render ?? 'render_tpl';
} else { } else {
$this->render_tpl( __DIR__ . '/tpl/default.php' ); $this->render_tpl( __DIR__ . '/tpl/wrap-default.php' );
$this->render = $this->render ?? 'render_tpl'; $this->render = $this->render ?? 'render_tpl';
} }
} }
@ -465,11 +550,23 @@ class AdminPage
if( is_callable( $plugin_info ) ) if( is_callable( $plugin_info ) )
$this->plugin_info = $plugin_info; $this->plugin_info = $plugin_info;
// if true-y value passed and PluginCore class exists - set to true // if true-y value passed and plugin_core isset
else if (!empty($plugin_info) && class_exists('WPHelper\PluginCore')) else if ( ! empty( $plugin_info ) && ! empty( $this->plugin_core ) )
$this->plugin_info = true; $this->plugin_info = true;
} }
/**
* Add to tab group
*
* @hook cmb2_tab_group_tabs
*/
public function add_to_tab_group( $tabs, $tab_group ){
if ( $tab_group == $this->tab_group ){
$tabs[ $this->slug ] = $this->tab_title;
}
return $tabs;
}
/** /**
* Setter - scripts * Setter - scripts
* Scripts to enqueue on admin page * Scripts to enqueue on admin page
@ -501,7 +598,7 @@ class AdminPage
} }
function plugin_core($plugin_core){ function plugin_core($plugin_core){
if ( is_a( $plugin_core, 'WPHelper\PluginCore') ){ if ( $plugin_core instanceof PluginCore ){
$this->plugin_core = $plugin_core; $this->plugin_core = $plugin_core;
} }
} }
@ -525,13 +622,18 @@ class AdminPage
'capability' => $this->capability, 'capability' => $this->capability,
'slug' => $this->slug, 'slug' => $this->slug,
'parent' => $this->parent, 'parent' => $this->parent,
'hook_suffix' => $this->hook_suffix,
'icon_url' => $this->icon_url, 'icon_url' => $this->icon_url,
'position' => $this->position, 'position' => $this->position,
'render' => $this->render, // render_cb | render_tpl | settings-page | cmb2 | cmb2-tabs 'render' => $this->render, // render_cb | render_tpl | settings-page | cmb2 | cmb2-tabs
'render_cb' => $this->render_cb, 'render_cb' => $this->render_cb,
'render_tpl' => $this->render_tpl, 'render_tpl' => $this->render_tpl,
'settings' => $this->settings, 'settings' => $this->settings,
'wrap' => $this->wrap,
'tab_group' => $this->tab_group,
'tab_title' => $this->tab_title,
'plugin_core' => $this->plugin_core, 'plugin_core' => $this->plugin_core,
'plugin_info' => $this->plugin_info,
]; ];
return $options; return $options;
@ -570,37 +672,30 @@ class AdminPage
if ( ! $this->capability ) if ( ! $this->capability )
$this->capability = 'manage_options'; $this->capability = 'manage_options';
if ( $this->render == 'settings-page' ){ add_action( "wphelper/adminpage/plugin_info_box/{$this->slug}" , [ $this , 'render_plugin_info_meta_box' ] );
$this->settings_page = new SettingsPage($this); /**
$this->settings_page->setup(); * @todo Perhaps this can hook on admin_init - right after admin_menu has finished
* @todo CMB2 options-page does not return page_hook/hook_suffix - MUST validate
*/
add_action ( 'admin_init' , [ $this , '_bootstrap_admin_page' ] );
} if ( in_array( $this->render, [ 'cmb2', 'cmb2-tabs' ] ) ){
add_action( "wphelper/adminpage/plugin_info_box/{$this->slug}" , [ $this , 'render_plugin_info_box' ] ); $this->cmb2_page = $this->settings['options_type'] ?? '' == 'multi'
? new CMB2_OptionsPage_Multi( $this )
// if ( $this->delegate_hookup ){ : new CMB2_OptionsPage( $this );
if ( 'cmb2' == $this->render || 'cmb2-tabs' == $this->render ){
if ( isset( $this->settings['options_type'] ) && $this->settings['options_type'] == 'multi' ) {
$this->cmb2_page = new CMB2_OptionsPage_Multi( $this );
} else {
$this->cmb2_page = new CMB2_OptionsPage( $this );
}
/**
* @todo Perhaps this can hook on admin_init - right after admin_menu has finished
* @todo CMB2 options-page does not return page_hook/hook_suffix - MUST validate
*/
add_action ( 'admin_menu' , [ $this , '_bootstrap_admin_page' ], 12 );
// skip add_menu_page // skip add_menu_page
return; return;
} }
// if ( ! $this->delegate_hookup ){ if ( $this->render == 'settings-page' ){
$this->settings_page = new SettingsPage($this);
}
add_action ( 'admin_menu' , [ $this , 'add_menu_page' ], 11 ); add_action ( 'admin_menu' , [ $this , 'add_menu_page' ], 11 );
add_action ( 'admin_menu' , [ $this , '_bootstrap_admin_page' ], 12 ); add_action ( 'admin_menu' , [ $this , 'add_plugin_info_meta_box' ], 11 );
} }
@ -644,6 +739,21 @@ class AdminPage
); );
break; break;
} }
}
/**
*
*/
public function add_plugin_info_meta_box() {
$metabox_args = [
'id' => $this->slug . '_plugin_info_meta_box', // id is unique (in case a plugin uses $this->slug)
'title' => 'Plugin Info',
'context' => 'side',
'screens' => [ $this->get_hook_suffix() ],
// 'template',
'render' => [ $this , 'render_plugin_info_meta_box_inside' ],
];
( new MetaBox($metabox_args) )->add();
} }
@ -653,14 +763,6 @@ class AdminPage
*/ */
public function validate_page_hook(){ public function validate_page_hook(){
/**
* hack!
* This is ad hoc validation - should do this earlier
*/
if ( empty( $this->slug ) ){
$this->slug = $this->settings['option_key'];
}
if ( empty( $this->hook_suffix ) ){ if ( empty( $this->hook_suffix ) ){
$this->hook_suffix = get_plugin_page_hookname( $this->slug, $this->parent ); $this->hook_suffix = get_plugin_page_hookname( $this->slug, $this->parent );
} }
@ -678,14 +780,9 @@ class AdminPage
* *
* @hook admin_menu priority 12 * @hook admin_menu priority 12
* @access private * @access private
*
* @todo move this function to admin_init - after admin_menu has finished
*/ */
public function _bootstrap_admin_page(){ public function _bootstrap_admin_page(){
/**
* @todo perhaps run this on 'admin_init'
*/
$this->validate_page_hook(); $this->validate_page_hook();
add_action ( 'load-' . $this->hook_suffix , [ $this , '_admin_page_setup' ] ); add_action ( 'load-' . $this->hook_suffix , [ $this , '_admin_page_setup' ] );
@ -854,19 +951,21 @@ class AdminPage
*/ */
public function render_admin_page() public function render_admin_page()
{ {
// @todo if render callback supplied - add shortcircuit hook here
// execute render callback and return early
// if wrap - 1. We collect output buffer
if ( 'none' != $this->wrap ){ if ( 'none' != $this->wrap ){
ob_start(); ob_start();
} }
//---------------------------[The McGuffin]---------------------------------//
if ( isset( $this->render_cb ) && is_callable( $this->render_cb ) ) { if ( isset( $this->render_cb ) && is_callable( $this->render_cb ) ) {
call_user_func( $this->render_cb ); call_user_func( $this->render_cb );
} else if ( isset( $this->render_tpl ) && is_readable( $this->render_tpl ) ) { } else if ( isset( $this->render_tpl ) && is_readable( $this->render_tpl ) ) {
include $this->render_tpl; include $this->render_tpl;
} }
//---------------------------[The McGuffin]---------------------------------//
// if wrap - 2. include chosen wrap template
if ( 'none' != $this->wrap ){ if ( 'none' != $this->wrap ){
$ob_content = ob_get_clean(); $ob_content = ob_get_clean();
@ -885,7 +984,21 @@ class AdminPage
} }
/** /**
* Render plugin info metabox *
* @see render_plugin_info_meta_box()
* @deprecated
*/
public function render_plugin_info_box(){
_doing_it_wrong( __METHOD__, 'Deprecated. Use render_plugin_info_meta_box() instead.', '0.26' );
$this->render_plugin_info_meta_box();
}
/**
* Render plugin info meta-box
* *
* Call user-provided callable. * Call user-provided callable.
* Or else attempt to create PluginInfoMetaBox class from $this->plugin_core and call its render function. * Or else attempt to create PluginInfoMetaBox class from $this->plugin_core and call its render function.
@ -895,17 +1008,55 @@ class AdminPage
* @todo See if this function should be public API or only run on action hook * @todo See if this function should be public API or only run on action hook
* @todo deprecate public use - use wphelper/adminpage/plugin_info_box/{$this->slug} instead * @todo deprecate public use - use wphelper/adminpage/plugin_info_box/{$this->slug} instead
*/ */
public function render_plugin_info_box(){ public function render_plugin_info_meta_box(){
if ( isset( $this->plugin_info ) && is_callable( $this->plugin_info ) ) { if ( isset( $this->plugin_info ) && is_callable( $this->plugin_info ) ) {
call_user_func( $this->plugin_info ); call_user_func( $this->plugin_info );
} else { } else {
if ( ! empty( $this->plugin_core ) && empty( $this->plugin_info_meta_box ) ){
$this->plugin_info_meta_box = new PluginInfoMetaBox( $this->plugin_core ); if (!$this->bootstrap_plugin_info_meta_box()){
return;
} }
$this->plugin_info_meta_box->plugin_info_box();
/**
* Allow plugins to modify plugin info meta box
*
* @since 0.23
*/
do_action( "wphelper/plugin_info_meta_box/{$this->plugin_core->slug()}" );
}
}
/**
*
*/
public function render_plugin_info_meta_box_inside(){
if ( isset( $this->plugin_info ) && is_callable( $this->plugin_info ) ) {
call_user_func( $this->plugin_info );
} else {
if (!$this->bootstrap_plugin_info_meta_box()){
return;
}
do_action( "wphelper/plugin_info_meta_box/inside/{$this->plugin_core->slug()}" );
}
}
/**
* Bootstrap PluginInfoMetaBox
*/
private function bootstrap_plugin_info_meta_box() {
if ( empty( $this->plugin_info_meta_box ) && ! empty( $this->plugin_core ) ){
$this->plugin_info_meta_box = new PluginInfoMetaBox( $this->plugin_core );
} }
// If no plugin_info_meta_box - return false
if ( empty( $this->plugin_info_meta_box ) ) {
return false;
}
return true;
} }
} }
endif; endif;

View File

@ -4,9 +4,9 @@ namespace WPHelper;
defined( 'ABSPATH' ) || die( 'No soup for you!' ); defined( 'ABSPATH' ) || die( 'No soup for you!' );
use CMB2; use CMB2;
use CMB2_Options_Hook; use CMB2_Options_Hookup;
if ( ! class_exists( 'WPHelper\CMB2_OptionsPage' ) ): if ( ! class_exists( CMB2_OptionsPage::class ) ):
/** /**
* CMB2_OptionsPage * CMB2_OptionsPage
* *
@ -26,11 +26,21 @@ class CMB2_OptionsPage{
*/ */
public $admin_page; public $admin_page;
/**
* @var array $fields
*/
protected $fields;
/** /**
* @var CMB2 $cmb * @var CMB2 $cmb
*/ */
private $cmb; private $cmb;
/**
* @var array $cmb2_options
*/
protected $cmb2_options;
/** /**
* @param AdminPage $admin_page * @param AdminPage $admin_page
*/ */
@ -48,6 +58,8 @@ class CMB2_OptionsPage{
$settings['option_key'] ??= ( $settings['option_name'] ?? ( $settings['id'] ?? $admin_options['slug'] ) ); $settings['option_key'] ??= ( $settings['option_name'] ?? ( $settings['id'] ?? $admin_options['slug'] ) );
$settings['title'] ??= $admin_options['title']; $settings['title'] ??= $admin_options['title'];
$settings['menu_title'] ??= $admin_options['menu_title']; $settings['menu_title'] ??= $admin_options['menu_title'];
// @todo Only if cmb2-tabs
$settings['tab_title'] ??= $admin_options['tab_title'] ?? $settings['submenu_title'] ?? $settings['menu_title'];
$settings['parent_slug'] ??= $admin_options['parent']; $settings['parent_slug'] ??= $admin_options['parent'];
$settings['position'] ??= $admin_options['position']; $settings['position'] ??= $admin_options['position'];
$settings['icon_url'] ??= $admin_options['icon_url']; $settings['icon_url'] ??= $admin_options['icon_url'];
@ -63,7 +75,8 @@ class CMB2_OptionsPage{
/** /**
* CMB2 only accepts url slug * CMB2 only accepts url slug
* *
* @todo export parent_slug convertion to dedicated method * @todo export parent_slug conversion to dedicated method
* @todo perhaps move this to AdminPage::parent() method
*/ */
switch ( $settings['parent_slug'] ) { switch ( $settings['parent_slug'] ) {
case 'dashboard': case 'dashboard':
@ -116,11 +129,11 @@ class CMB2_OptionsPage{
$settings['tab_title'] ??= $settings['menu_title']; $settings['tab_title'] ??= $settings['menu_title'];
} }
$this->fields = $settings['fields'] ?? [];
/**
* @todo revisit this - might not need to unset fields
*/
if ( isset( $settings['fields'] ) ){ if ( isset( $settings['fields'] ) ){
$this->fields = $settings['fields'];
/**
* @todo revisit this - might not need to unset fields
*/
unset( $settings['fields'] ); unset( $settings['fields'] );
} }
@ -179,7 +192,11 @@ class CMB2_OptionsPage{
// register parent pages before sub-menu pages // register parent pages before sub-menu pages
$priority = empty( $settings['parent_slug'] ) ? 9 : 10; $priority = empty( $settings['parent_slug'] ) ? 9 : 10;
add_action( 'cmb2_admin_init', [ $this, 'register_metabox' ], $priority ); if ( $settings['allow_on_front'] ?? false ){
add_action( 'cmb2_init', [ $this, 'register_metabox' ], $priority );
} else {
add_action( 'cmb2_admin_init', [ $this, 'register_metabox' ], $priority );
}
/** /**
* @todo add 'submenu' field and functionality to WPHelper\AdminPage * @todo add 'submenu' field and functionality to WPHelper\AdminPage
@ -198,12 +215,20 @@ class CMB2_OptionsPage{
/** /**
* Display options-page output. To override, set 'display_cb' box property. * Display options-page output. To override, set 'display_cb' box property.
* *
* @param CMB2_Options_Hook $hookup - instance of Options Page Hookup class (caller of this function) * @param CMB2_Options_Hookup $hookup - instance of Options Page Hookup class (caller of this function)
* *
* @see CMB2_Options_Hook * @see CMB2_Options_Hookup
*/ */
public function options_page_output( $hookup ) { public function options_page_output( $hookup ) {
include $this->admin_page->get_render_tpl();
$options = $this->admin_page->options();
if ( ! empty( $options['plugin_core'] ) || ! empty( $options['plugin_info'] ) ){
include __DIR__ . '/tpl/wrap-cmb2-sidebar.php';
} else {
include __DIR__ . '/tpl/wrap-cmb2-simple.php';
}
} }

View File

@ -3,9 +3,13 @@ namespace WPHelper;
defined( 'ABSPATH' ) || die( 'No soup for you!' ); defined( 'ABSPATH' ) || die( 'No soup for you!' );
include_once __DIR__ . '/CMB2_Override_Meta.php'; if ( ! class_exists( CMB2_OptionsPage_Multi::class ) ):
// Require dependency CMB2_Override_Meta
if ( ! trait_exists( CMB2_Override_Meta::class ) ) {
require_once __DIR__ . '/CMB2_Override_Meta.php';
}
if ( ! class_exists( 'WPHelper\CMB2_OptionsPage_Multi' ) ):
/** /**
* CMB2_OptionsPage - MULTI * CMB2_OptionsPage - MULTI
* *

View File

@ -3,7 +3,7 @@ namespace WPHelper;
defined( 'ABSPATH' ) || die( 'No soup for you!' ); defined( 'ABSPATH' ) || die( 'No soup for you!' );
if ( ! trait_exists('CMB2_Override_Meta') ): if ( ! trait_exists( CMB2_Override_Meta::class ) ):
/** /**
* CMB2 Options page override meta * CMB2 Options page override meta
* *

View File

@ -2,27 +2,75 @@
namespace WPHelper; namespace WPHelper;
use DateTime; use DateTime;
use function get_plugin_data;
if ( ! class_exists( 'WPHelper\PluginInfoMetaBox' ) ): if ( ! class_exists( PluginInfoMetaBox::class ) ):
/** /**
* Plugin Info Metabox * Plugin Info Metabox
* *
* Get instance of PluginCore * Get instance of PluginCore
* Render default plugin info box template. * Render default plugin info box template.
*
* @since 0.14
*/ */
class PluginInfoMetaBox{ class PluginInfoMetaBox{
private $tpl = '/tpl/plugin_info_meta_box.php'; private $tpl = '/tpl/plugin_info_meta_box.php';
private $tpl_inside = '/tpl/plugin_info_meta_box-inside.php';
private $tpl_debug = '/tpl/plugin_info_meta_box-wph_debug.php';
/** /**
* @var PluginCore * @var PluginCore
*/ */
private $plugin_core; public $plugin_core;
function __construct( PluginCore $plugin_core ) function __construct( PluginCore $plugin_core )
{ {
$this->plugin_core = $plugin_core; $this->plugin_core = $plugin_core;
/**
* Allow plugins to render or modify plugin info box
*
* Call: do_action('wphelper/plugin_info_meta_box/{$slug}')
* action used in AdminPage::render_plugin_info_meta_box()
*
* @since 0.23
*/
add_action( "wphelper/plugin_info_meta_box/{$this->plugin_core->slug()}", [ $this, 'plugin_info_box' ] );
add_action( "wphelper/plugin_info_meta_box/inside/{$this->plugin_core->slug()}", [ $this, 'inside' ] );
}
/**
* Setup args used in template.
*
* @todo move 'repo' setup to method from template
*/
function setup_template_args() {
$plugin_data = $this->plugin_core->plugin_data();
$last_update = $plugin_data['Last Update'] ?: $plugin_data['Release Date'];
$last_update = DateTime::createFromFormat('Y_m_d', $last_update);
if ($last_update) {
$diff = (int) abs( time() - $last_update->format('U') );
if ( $diff < (DAY_IN_SECONDS) ){
$update_message = 'Today';
}elseif ($diff < (2 * DAY_IN_SECONDS)){
$update_message = 'Yesterday';
}else{
$update_message = human_time_diff($last_update->format('U')) . ' ago';
}
} else {
$update_message = '';
}
return compact('plugin_data','update_message');
} }
/** /**
@ -33,33 +81,36 @@ class PluginInfoMetaBox{
* @since iac_engine 1.1.0 * @since iac_engine 1.1.0
* @since iac_engine 1.2.0 plugin_info_box now a function * @since iac_engine 1.2.0 plugin_info_box now a function
* @since iac_engine 1.3.0 use 'Last Update' header * @since iac_engine 1.3.0 use 'Last Update' header
* @since 0.14 PluginInfoMetaBox::plugin_info_box()
*
* @todo rename method render()
*/ */
function plugin_info_box(){ function plugin_info_box(){
$args = $this->setup_template_args();
$plugin_data = get_plugin_data( $this->plugin_core->file() , false ); // false = no markup (i think) extract($args);
$last_update = $plugin_data['Last Update'] ?: $plugin_data['Release Date'];
$last_update = DateTime::createFromFormat('Y_m_d', $last_update);
// $last_update = new DateTime('now');
// $last_update->add(new DateInterval('P1D'));
// $last_update->add(new DateInterval('P2D'));
if ($last_update):
$diff = (int) abs( time() - $last_update->format('U') );
if ( $diff < (DAY_IN_SECONDS) ){
$update_message = 'Today';
}elseif ($diff < (2 * DAY_IN_SECONDS)){
$update_message = 'Yesterday';
}else{
$update_message = human_time_diff($last_update->format('U')) . ' ago';
}
else:
$update_message = '';
endif;
include __DIR__ . $this->tpl; include __DIR__ . $this->tpl;
} }
/**
* Only print meta-box .inside
* No header.
*/
function inside(){
$args = $this->setup_template_args();
extract($args);
include __DIR__ . $this->tpl_inside;
}
/**
* WPHelper classes debug info
*
* Prints inside Plugin Info Meta Box
*
* @since 0.26
*/
function wph_debug() {
include __DIR__ . $this->tpl_debug;
}
} }
endif; endif;

View File

@ -9,7 +9,7 @@ use function add_settings_field;
use function checked; use function checked;
use function get_option; use function get_option;
if ( ! class_exists( 'WPHelper\SettingsPage' ) ): if ( ! class_exists( SettingsPage::class ) ):
/** /**
* SettingsPage * SettingsPage
* *
@ -32,38 +32,45 @@ class SettingsPage{
/** /**
* Page slug to display sections * Page slug to display sections
* *
* @var String $page * @var string $page
*/ */
protected $page; public $page;
/** /**
* option_name key used in wp_options table * option_name key used in wp_options table
* *
* @var String $option_name * @var string $option_name
*/ */
protected $option_name; protected $option_name;
/** /**
* option_group used by register_setting() and settings_fields() * option_group used by register_setting() and settings_fields()
* *
* @var String $option_group * @var string $option_group
*/ */
public $option_group; public $option_group;
/** /**
* Sections * Sections
* *
* @var Array[] $sections * @var array[] $sections
*/ */
public $sections = []; public $sections = [];
/** /**
* Fields * Fields
* *
* @var Array[] $fields * @var array[] $fields
*/ */
public $fields = []; public $fields = [];
/**
* Sanitize Callback
*
* @var Callable $sanitize_callback
*/
public $sanitize_callback;
/** /**
* Constructor. * Constructor.
* *
@ -89,18 +96,20 @@ class SettingsPage{
$this->option_group = $settings['option_group'] ?? $this->page . '_option_group'; $this->option_group = $settings['option_group'] ?? $this->page . '_option_group';
foreach ( $settings['sections'] as $section ) { $this->sanitize_callback = $settings['sanitize_callback'] ?? null;
// PHP Warning: foreach() argument must be of type array|object
foreach ( $settings['sections'] ?? [] as $section ) {
// extract fields // extract fields
foreach ( $section['fields'] as $field ){ foreach ( $section['fields'] as $field ){
$field['section_id'] = $section['id']; // create back-reference in field to section. ( @see add_settings_field() ) $field['section_id'] = $section['id']; // create back-reference in field to section. ( @see add_settings_field() )
$field['name'] = $this->option_name . '[' . $field['id'] . ']';
$this->fields[] = $field; $this->fields[] = $field;
} }
unset( $section['fields'] ); unset( $section['fields'] );
$this->sections[] = $section; // save without fields $this->sections[] = $section; // save without fields
} }
}
function setup() {
add_action( 'admin_init', [ $this, 'register_settings' ] ); add_action( 'admin_init', [ $this, 'register_settings' ] );
} }
@ -108,7 +117,7 @@ class SettingsPage{
register_setting( register_setting(
$this->option_group, // $option_group - A settings group name. Must exist prior to the register_setting call. This must match the group name in settings_fields() $this->option_group, // $option_group - A settings group name. Must exist prior to the register_setting call. This must match the group name in settings_fields()
$this->option_name, // $option_name - The name of an option to sanitize and save. $this->option_name, // $option_name - The name of an option to sanitize and save.
[ $this,'sanitize_settings' ] // $sanitize_callback - A callback function that sanitizes the option's value. (see also: built-in php callbacks) $this->sanitize_callback ?? [ $this,'sanitize_settings' ] // callback ?? fallback // $sanitize_callback - A callback function that sanitizes the option's value. (see also: built-in php callbacks)
); );
foreach ( $this->sections as $section ){ foreach ( $this->sections as $section ){
@ -125,7 +134,7 @@ class SettingsPage{
add_settings_field( add_settings_field(
$field['id'], $field['id'],
$field['title'], $field['title'],
[ $this, "print_{$field['type']}" ], $field['render'] ?? [ $this, "print_{$field['type']}" ],
$this->page, // can built-in pages: (general, reading, writing, ...) $this->page, // can built-in pages: (general, reading, writing, ...)
$field['section_id'], $field['section_id'],
$field //send setting array as $args for print function $field //send setting array as $args for print function
@ -135,8 +144,8 @@ class SettingsPage{
} }
/** /**
* Print text input field * Print checkbox input field
* Support field type 'text' * Support field type 'checkbox'
* *
* @since 0.11 * @since 0.11
*/ */
@ -147,10 +156,11 @@ class SettingsPage{
$input_tag = sprintf( $input_tag = sprintf(
'<label for="%1$s"> '<label for="%1$s">
<input name="%2$s[%1$s]" type="checkbox" id="%1$s" value="1" %4$s /> <input name="%2$s" type="checkbox" id="%1$s" aria-describedby="%1$s-description" value="1" %4$s />
%3$s</label>', %3$s
</label>',
$id, $id,
$this->option_name, $name,
$description, $description,
checked( ( $options[$id] ?? false ), '1', false) checked( ( $options[$id] ?? false ), '1', false)
); );
@ -176,10 +186,11 @@ class SettingsPage{
$options = get_option( $this->option_name ); $options = get_option( $this->option_name );
$input_tag = sprintf( $input_tag = sprintf(
'<input name="%2$s[%1$s]" type="text" id="%1$s" value="%3$s" class="regular-text">', '<input name="%2$s" type="text" id="%1$s" aria-describedby="%1$s-description" value="%3$s" placeholder="%4$s" class="regular-text">',
$id, $id,
$this->option_name, $name,
$default $options[$id] ?: $default ?? '',
$placeholder ?? ''
); );
if ( ! empty( $description ) ) { if ( ! empty( $description ) ) {
@ -211,10 +222,11 @@ class SettingsPage{
$options = get_option( $this->option_name ); $options = get_option( $this->option_name );
$input_tag = sprintf( $input_tag = sprintf(
'<input name="%2$s[%1$s]" type="url" id="%1$s" value="%3$s" class="regular-text code ">', '<input name="%2$s" type="url" id="%1$s" aria-describedby="%1$s-description" placeholder="%4$s" value="%3$s" class="regular-text code ">',
$id, $id,
$this->option_name, $name,
$default $options[$id] ?: $default ?? '',
$placeholder ?? ''
); );
if ( ! empty( $description ) ) { if ( ! empty( $description ) ) {
@ -246,10 +258,11 @@ class SettingsPage{
$options = get_option( $this->option_name ); $options = get_option( $this->option_name );
$input_tag = sprintf( $input_tag = sprintf(
'<input name="%2$s[%1$s]" type="email" id="%1$s" aria-describedby="%1$s-description" value="%3$s" class="regular-text ltr">', '<input name="%2$s" type="email" id="%1$s" aria-describedby="%1$s-description" placeholder="%4$s" value="%3$s" class="regular-text ltr">',
$id, $id,
$this->option_name, $name,
$default $options[$id] ?: $default ?? '',
$placeholder ?? ''
); );
if ( ! empty( $description ) ) { if ( ! empty( $description ) ) {
@ -269,6 +282,42 @@ class SettingsPage{
} }
/**
* Print email input field
* Support field type 'email'
*
* @since 0.23
*/
function print_textarea( $field ){
extract($field);
$options = get_option( $this->option_name );
$textarea = sprintf(
'<textarea class="regular-text" rows="5" id="%1$s-description" name="%2$s" placeholder="%4$s">%3$s</textarea>',
$id,
$name,
$options[$id] ?: $default ?? '',
$placeholder ?? ''
);
if ( ! empty( $description ) ) {
$textarea .= sprintf(
'<p class="description" id="%1$s-description">%2$s</p>',
$id,
$description
);
}
/**
* Allow plugins to directly manipulate field HTML
*/
$textarea = apply_filters( 'wphelper/settings_page/textarea', $textarea, $field, $this->option_name, $options );
echo $textarea;
}
/** /**
* Sanitizes entire $options array. * Sanitizes entire $options array.
*/ */
@ -276,24 +325,25 @@ class SettingsPage{
$new_options = []; $new_options = [];
foreach( $options as $id => $option ) { foreach( $options as $id => $option ) {
$field = reset( $field = current(
array_filter( array_filter(
$this->fields, $this->fields,
fn($item) => $item['id'] == $id fn($item) => $item['id'] == $id
) )
); );
switch ( $field['type'] ){ switch ( $field['type'] ) {
case 'checkbox': case 'checkbox':
$new_options[$id] = $option == 1 ? 1 : 0; $new_options[$id] = $option == 1 ? 1 : 0;
break; break;
case 'text': case 'text':
case 'textarea':
$new_options[$id] = sanitize_text_field( $option ); $new_options[$id] = sanitize_text_field( $option );
break; break;
case 'email': case 'email':
$new_options[$id] = sanitize_email( $option ); $new_options[$id] = sanitize_email( $option );
break; break;
case 'url': case 'url':
$new_options[$id] = sanitize_url( $option ); $new_options[$id] = esc_url_raw( $option );
break; break;
default: default:
break; break;

View File

@ -1,13 +0,0 @@
<?php
/**
* Template for CMB2 Options Page
*
* @var WPHelper\CMB2_Options_Page $this
* @var CMB2_Options_Hook $hookup
*/
?>
<div class="wrap cmb2-options-page option-<?php echo esc_attr( sanitize_html_class( $hookup->option_key ) ); ?>">
<?php include 'cmb-title.php' ?>
<?php include 'tab-nav.php' ?>
<?php include 'cmb-form.php' ?>
</div>

View File

@ -7,8 +7,9 @@
?> ?>
<form method="post" action="options.php"> <form method="post" action="options.php">
<?php <?php
/** @var WPHelper\AdminPage $this */
settings_fields( $this->settings_page->option_group );// Print hidden setting fields settings_fields( $this->settings_page->option_group );// Print hidden setting fields
do_settings_sections( $this->get_slug() );// Print title, info callback and form-table do_settings_sections( $this->settings_page->page );// Print title, info callback and form-table
submit_button(); submit_button();
?> ?>
</form> </form>

View File

@ -0,0 +1,37 @@
<?php
/**
* Plugin Info Metabox - .inside
*/
?>
<h3 style="font-weight: 100; font-size: 1.5em;"><?php echo $plugin_data['Name']; ?></h3>
<p>
<?php if ( ! empty( $plugin_data['Version'] ) ): ?>
Version: <?php echo $plugin_data['Version']; ?><br/>
<?php endif; ?>
<?php if ( ! empty( $plugin_data['Author'] ) ): ?>
Author:
<?php if ( ! empty( $plugin_data['AuthorURI'] ) ): ?>
<a href="<?php echo $plugin_data['AuthorURI'] ?>"><?php echo $plugin_data['Author']; ?></a><br/>
<?php else: ?>
<?php echo $plugin_data['Author']; ?><br/>
<?php endif; ?>
<?php endif; ?>
<?php if ( ! empty( $plugin_data['UpdateURI'] ) || ! empty( $plugin_data['PluginURI'] ) ): ?>
Repo: <a href="<?php echo $plugin_data['UpdateURI'] ?: $plugin_data['PluginURI']; ?>">
<?php echo $plugin_data['TextDomain'] ?? $this->$plugin_core->slug(); ?>
</a><br/>
<?php endif; ?>
<?php if ( ! empty( $update_message ) ): ?>
Last Updated: <?php echo $update_message; ?>
<?php endif; ?>
</p>
<?php
/**
* Print WPHelper debug info in plugin info meta box
*
* @since 0.26
*/
if ( defined('WPH_DEBUG') && WPH_DEBUG ) {
/** @var WPHelper\PluginInfoMetaBox $this */
$this->wph_debug();
}

View File

@ -0,0 +1,84 @@
<?php
/**
* Plugin Info Metabox - .wph-debug
*
* @since 0.26
*/
use WPHelper\AdminPage;
use WPHelper\MetaBox;
use WPHelper\PluginCore;
use WPHelper\Utility\Singleton;
use WPHelper\DatabaseTable;
if (class_exists(AdminPage::class)){
$wph_admin_ref = new ReflectionClass(AdminPage::class);
$wph_admin_file = $wph_admin_ref->getFileName();
$wph_admin_composer = json_decode(file_get_contents( dirname( dirname( $wph_admin_file ) ) . '/composer.json' )) ;
}
if (class_exists(PluginCore::class)){
$wph_pc_ref = new ReflectionClass(PluginCore::class);
$wph_pc_file = $wph_pc_ref->getFileName();
$wph_pc_composer = json_decode(file_get_contents( dirname( $wph_pc_file ) . '/composer.json' )) ;
}
if (class_exists(MetaBox::class)){
$wph_mb_ref = new ReflectionClass(MetaBox::class);
$wph_mb_file = $wph_mb_ref->getFileName();
$wph_mb_composer = json_decode(file_get_contents( dirname( $wph_mb_file ) . '/composer.json' )) ;
}
if (trait_exists(Singleton::class)){
$wph_util_ref = new ReflectionClass(Singleton::class);
$wph_util_file = $wph_util_ref->getFileName();
$wph_util_composer = json_decode(file_get_contents( dirname( dirname( $wph_util_file ) ) . '/composer.json' )) ;
}
if (class_exists(DatabaseTable::class)){
$wph_db_ref = new ReflectionClass(DatabaseTable::class);
$wph_db_file = $wph_db_ref->getFileName();
$wph_db_composer = json_decode(file_get_contents( dirname( $wph_db_file ) . '/composer.json' )) ;
}
?>
<style>
.inside {
word-wrap: break-word;
}
</style>
<?php if ( ! empty( $wph_admin_composer ) ): ?>
<hr>
<p>
AdminPage: <?php echo $wph_admin_composer->version; ?><br/>
Location: <?php echo $wph_admin_file; ?><br/>
<?php endif; ?>
<?php if ( ! empty( $wph_pc_composer ) ): ?>
<hr>
<p>
PluginCore: <?php echo $wph_pc_composer->version; ?><br/>
Location: <?php echo $wph_pc_file; ?><br/>
<?php endif; ?>
<?php if ( ! empty( $wph_mb_composer ) ): ?>
<hr>
<p>
MetaBox: <?php echo $wph_mb_composer->version; ?><br/>
Location: <?php echo $wph_mb_file; ?><br/>
<?php endif; ?>
<?php if ( ! empty( $wph_util_composer ) ): ?>
<hr>
<p>
Utility: <?php echo $wph_util_composer->version; ?><br/>
Location: <?php echo $wph_util_file; ?><br/>
<?php endif; ?>
<?php if ( ! empty( $wph_db_composer ) ): ?>
<hr>
<p>
DatabaseTable: <?php echo $wph_db_composer->version; ?><br/>
Location: <?php echo $wph_db_file; ?><br/>
<?php endif; ?>
</p>

View File

@ -3,25 +3,10 @@
* Plugin Info Metabox * Plugin Info Metabox
*/ */
?> ?>
<style>
#plugin_info h2 {
border-bottom: 1px solid #eee;
}
#plugin_info h3{
font-weight: 100;
font-size: 1.5em;
}
</style>
<div id="plugin_info" class="postbox"> <div id="plugin_info" class="postbox">
<h2><span>Plugin Info</span></h2> <h2 style="border-bottom: 1px solid #eee;"><span>Plugin Info</span></h2>
<div class="inside"> <div class="inside">
<h3><?=$plugin_data['Name'] ?></h3> <?php include __DIR__ . '/plugin_info_meta_box-inside.php'; ?>
<p>
Version: <?= $plugin_data['Version'] ?><br/>
Author: <a href="<?= $plugin_data['AuthorURI'] ?>"><?= $plugin_data['Author'] ?></a><br/>
GitHub: <a href="<?= $plugin_data['PluginURI'] ?>"><?= $plugin_data['TextDomain'] ?></a><br/>
<?php if ( ! empty( $update_message ) ): ?>Last Updated: <?= $update_message ?><?php endif; ?>
</p>
</div><!-- .inside --> </div><!-- .inside -->
</div><!-- .postbox --> </div><!-- .postbox -->

View File

@ -0,0 +1,41 @@
<?php
/**
* Bootstrap WordPress core meta-boxes to generate metaboxes
*
* @var WPHelper\AdminPage $this
*/
?>
<style>
/*
we don't actually have draggable/movable metaboxes
.hide-if-no-js / hidden classes would help
*/
.handle-actions {
display: none;
}
.postbox .postbox-header .hndle {
cursor: unset;
}
</style>
<?php
/**
* Allow meta-boxes to hook to this page ('side' context).
*
*
*/
do_action('add_meta_boxes', $this->get_hook_suffix(), 'side' );
/**
* Remove 'Featured Image' meta-box added by core.
*
* @see register_and_do_post_meta_boxes() (wp-admin/includes/meta-boxes.php)
* @todo Investigate why $thumbnail_support returns true for our pages.
*/
remove_meta_box( 'postimagediv', $this->get_hook_suffix(), 'side' );
/**
* Render meta-boxes
*
* Renders div.meta-box-sortables
*/
do_meta_boxes( $this->get_hook_suffix(), 'side', null );

View File

@ -4,7 +4,7 @@
* *
* Print tabs navigation row. * Print tabs navigation row.
* *
* @var CMB2_Options_Hook $hookup * @var CMB2_Options_Hookup $hookup
*/ */
if ( ! isset( $hookup ) ){ if ( ! isset( $hookup ) ){
return; return;

View File

@ -0,0 +1,9 @@
<?php
/**
* Template - Tabs navigation row
*
* Print tabs navigation row.
*
* @var WPHelper\AdminPage $this
*/
do_action( "wphelper/adminpage/tab_nav/{$this->tab_group}" );

View File

@ -2,7 +2,7 @@
/** /**
* Template for CMB2 page title * Template for CMB2 page title
* *
* @var WPHelper\CMB2_Options_Page $this * @var WPHelper\CMB2_OptionsPage $this
*/ */
if ( $this->cmb->prop( 'title' ) ) { if ( $this->cmb->prop( 'title' ) ) {
echo '<h2>' . wp_kses_post( $this->cmb->prop( 'title' ) ) . '</h2>'; echo '<h2>' . wp_kses_post( $this->cmb->prop( 'title' ) ) . '</h2>';

View File

@ -2,8 +2,8 @@
/** /**
* Template for CMB2 Options Page * Template for CMB2 Options Page
* *
* @var WPHelper\CMB2_Options_Page $this * @var WPHelper\CMB2_OptionsPage $this
* @var CMB2_Options_Hook $hookup * @var CMB2_Options_Hookup $hookup
*/ */
?> ?>
<style> <style>
@ -17,8 +17,8 @@
</style> </style>
<div class="wrap cmb2-options-page option-<?php echo esc_attr( sanitize_html_class( $hookup->option_key ) ); ?>"> <div class="wrap cmb2-options-page option-<?php echo esc_attr( sanitize_html_class( $hookup->option_key ) ); ?>">
<?php include 'cmb-title.php' ?> <?php include 'title-cmb2.php' ?>
<?php include 'tab-nav.php' ?> <?php include 'tab-nav-cmb2.php' ?>
<div id="poststuff"> <div id="poststuff">
<div id="post-body" class="metabox-holder columns-2"> <div id="post-body" class="metabox-holder columns-2">
@ -26,7 +26,7 @@
<!-- main content --> <!-- main content -->
<div id="post-body-content"> <div id="post-body-content">
<div class="meta-box-sortables ui-sortable tabs-content"> <div class="meta-box-sortables ui-sortable tabs-content">
<?php include 'cmb-form.php' ?> <?php include 'form-cmb2.php' ?>
</div><!-- .meta-box-sortables --> </div><!-- .meta-box-sortables -->
</div><!-- #post-body-content --> </div><!-- #post-body-content -->

View File

@ -0,0 +1,13 @@
<?php
/**
* Template for CMB2 Options Page
*
* @var WPHelper\CMB2_OptionsPage $this
* @var CMB2_Options_Hookup $hookup
*/
?>
<div class="wrap cmb2-options-page option-<?php echo esc_attr( sanitize_html_class( $hookup->option_key ) ); ?>">
<?php include 'title-cmb2.php' ?>
<?php include 'tab-nav-cmb2.php' ?>
<?php include 'form-cmb2.php' ?>
</div>

View File

@ -4,6 +4,6 @@
<div class="card"> <div class="card">
<h3>CMB2 Plugin Missing</h3> <h3>CMB2 Plugin Missing</h3>
<p>CMB2 plugin is required to display this page. <p>CMB2 plugin is required to display this page.
<br>Download and activate CMB2 plugin. <br>Please install and activate <a href="<?php echo admin_url('plugin-install.php?s=cmb2&tab=search') ?>">CMB2 plugin</a>.
</div> </div>
</div> </div>

View File

@ -1,3 +1,10 @@
<?php
/**
* WordPress admin 'wrap' div
*
* @var WPHelper\AdminPage $this
*/
?>
<div class="wrap"> <div class="wrap">
<h1><?= get_admin_page_title() ?></h1> <h1><?= get_admin_page_title() ?></h1>

View File

@ -3,12 +3,12 @@
* Template for CMB2 Options Page * Template for CMB2 Options Page
* *
* @var string $ob_content - Render template or callback * @var string $ob_content - Render template or callback
* @var AdminPage $this * @var WPHelper\AdminPage $this
*/ */
?> ?>
<div class="wrap"> <div class="wrap">
<h1><?= get_admin_page_title() ?></h1> <h1><?= get_admin_page_title() ?></h1>
<?php include 'tab-nav.php' ?> <?php include 'tab-nav-simple.php' ?>
<div id="poststuff"> <div id="poststuff">
<div id="post-body" class="metabox-holder columns-2"> <div id="post-body" class="metabox-holder columns-2">
@ -21,9 +21,7 @@
<!-- sidebar --> <!-- sidebar -->
<div id="postbox-container-1" class="postbox-container"> <div id="postbox-container-1" class="postbox-container">
<div class="meta-box-sortables"> <?php include 'sidebar-add-meta-boxes.php'; ?>
<?php do_action("wphelper/adminpage/plugin_info_box/{$this->get_slug()}"); ?>
</div><!-- .meta-box-sortables -->
</div><!-- #postbox-container-1 .postbox-container --> </div><!-- #postbox-container-1 .postbox-container -->
</div><!-- #post-body --> </div><!-- #post-body -->
<div class="clear"></div> <div class="clear"></div>

View File

@ -1,10 +1,12 @@
<?php <?php
/** /**
* Simple wrap * Simple wrap
*
* @var string $ob_content - Render template or callback
*/ */
?> ?>
<div class="wrap"> <div class="wrap">
<h1><?= get_admin_page_title() ?></h1> <h1><?= get_admin_page_title() ?></h1>
<?php include 'tab-nav.php' ?> <?php include 'tab-nav-simple.php' ?>
<?php echo $ob_content; ?> <?php echo $ob_content; ?>
</div> </div>

View File

@ -0,0 +1,38 @@
# Create Github Release
# v1.0
# Create Github release on tag push
# - Use tag name as release title
# - Use CHANGELOG.md log entry as body
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- '*' # Match any tag
name: Create Release
jobs:
build:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Get Changelog Entry
id: changelog_reader
uses: mindsers/changelog-reader-action@v1.1.0
with:
version: ${{ github.ref }}
path: ./CHANGELOG.md
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
body: ${{ steps.changelog_reader.outputs.log_entry }} # This pulls from the GET CHANGELOG ENTRY step above, referencing it's ID to get its outputs object, which include a `log_entry`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
draft: false
prerelease: false

26
vendor/abuyoyo/metabox/CHANGELOG.md vendored Normal file
View File

@ -0,0 +1,26 @@
# Changelog
WPHelper\MetaBox
## 0.8
### Fixed
- Fix `Metabox::render()` callback arguments. Callback is passed `$data_object` and `$box`.
## 0.7
### Fixed
- Validate `is_callable(render_cb)` before `call_user_func` call.
## 0.6
### Added
- Accept callable `render_cb` as well as readable `render_tpl` as render template.
## 0.5
### Added
- Basic Metabox API.

220
vendor/abuyoyo/metabox/MetaBox.php vendored Normal file
View File

@ -0,0 +1,220 @@
<?php
namespace WPHelper;
use function wp_parse_args;
use function add_action;
use function add_meta_box;
/**
* MetaBox
*
* Object-Oriented WordPress meta box creator.
*
* @author abuyoyo
* @version 0.8
*/
class MetaBox
{
/**
* Screen context where the meta box should display.
*
* @var string
*/
private $context;
/**
* The ID of the meta box.
*
* @var string
*/
private $id;
/**
* The display priority of the meta box.
*
* @var string
*/
private $priority;
/**
* Screens where this meta box will appear.
*
* @var string[]
*/
private $screens;
/**
* Path to the template used to display the content of the meta box.
*
* @var string filename
*/
private $render_tpl;
/**
* Path to the template used to display the content of the meta box.
*
* @var callable
*/
private $render_cb;
/**
* The title of the meta box.
*
* @var string
*/
private $title;
/**
* Hook where this meta box will be added.
*
* @var string
*/
private $hook;
/**
* Array of $args to be sent to callback function's second parameter
*
* @var array
*/
private $args;
/**
* Constructor.
*
* @param string $id
* @param string $template
* @param string $title
* @param string $context
* @param string $priority
* @param string[] $screens
*/
public function __construct($options)
{
// should throw error if required fields (id, title) not given
// template is actually optional
$defaults = [
'context' => 'advanced',
'priority' => 'default',
'screens' => [],
'args' => null,
'hook' => 'add_meta_boxes',
];
$options = wp_parse_args( $options, $defaults );
extract($options);
$this->context = $context;
$this->id = $id;
$this->priority = $priority;
$this->screens = $screens;
$this->render_tpl = isset( $template ) ? rtrim( $template, '/' ) : '';
$this->render_cb = $render ?? '';
$this->title = $title;
$this->hook = $hook;
$this->args = $args;
}
/**
* Add metabox at given hook.
*
* @return void
*/
public function add()
{
add_action( $this->hook, [ $this, 'wp_add_metabox' ] );
}
public function wp_add_metabox(){
add_meta_box(
$this->id,
$this->title,
[ $this, 'render' ], // $this->render_tpl | $this->render_cb
$this->screens,
$this->context,
$this->priority,
$this->args
);
}
/**
* Get the callable that will render the content of the meta box.
*
* @return callable
*/
public function get_callback()
{
return [ $this, 'render' ];
}
/**
* Get the screen context where the meta box should display.
*
* @return string
*/
public function get_context()
{
return $this->context;
}
/**
* Get the ID of the meta box.
*
* @return string
*/
public function get_id()
{
return $this->id;
}
/**
* Get the display priority of the meta box.
*
* @return string
*/
public function get_priority()
{
return $this->priority;
}
/**
* Get the screen(s) where the meta box will appear.
*
* @return array|string|WP_Screen
*/
public function get_screens()
{
return $this->screens;
}
/**
* Get the title of the meta box.
*
* @return string
*/
public function get_title()
{
return $this->title;
}
/**
* Render the content of the meta box using a PHP template.
* Callback passed to to add_meta_box()
*
* @see do_meta_boxes()
*
* @param mixed $data_object Object that's the focus of the current screen. eg. WP_Post|WP_Comment
* @param array $box Meta-box data [id, title, callback, args] (@see global $wp_meta_boxes)
*/
public function render( $data_object, $box )
{
if ( ! is_readable( $this->render_tpl ) && ! is_callable( $this->render_cb ) ){
return;
}
if ( is_callable( $this->render_cb ) ){
call_user_func( $this->render_cb, $data_object, $box );
} else if ( isset( $this->render_tpl ) ){
include $this->render_tpl;
}
}
}

1
vendor/abuyoyo/metabox/README.md vendored Normal file
View File

@ -0,0 +1 @@
# WPHelper\MetaBox

12
vendor/abuyoyo/metabox/composer.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"name": "abuyoyo/metabox",
"description": "WordPress metabox helper class",
"type": "library",
"version": "0.8",
"license": "BSD-3-Clause",
"autoload": {
"psr-4": {
"WPHelper\\" : ""
}
}
}

View File

@ -1,5 +1,35 @@
# WPHelper\PluginCore Changelog # WPHelper\PluginCore Changelog
## 0.27
Release Date: Oct 3, 2023
### Added
- Support Plugin Update Checker v5 as well as v4. Create class alias `WPHelper\PucFactory` for `YahnisElsts\PluginUpdateChecker\v5\PucFactory` if available. Fallback to `Puc_v4_Factory`.
## 0.26
Release Date: Jun 9, 2023
### Fixed
- Fix passing PluginCore instance to AdminPage constructor in `admin_page()` method.
## 0.25
Release Date: Feb 3, 2023
### Added
- Property `token` and method `token`. Lowercase underscore token to be used as variable name.
## 0.24
Release Date: Jan 13, 2023
### Added
- Static `get_by_file` method. Get PluginCore instance by plugin filename.
## 0.23
Release Date: Aug 8, 2022
### Fixed
- Minor fixes.
## 0.22 ## 0.22
Release Date: Aug 8, 2022 Release Date: Aug 8, 2022

View File

@ -1,24 +1,23 @@
<?php <?php
namespace WPHelper; namespace WPHelper;
use Puc_v4_Factory;
defined( 'ABSPATH' ) || die( 'No soup for you!' ); defined( 'ABSPATH' ) || die( 'No soup for you!' );
if( ! function_exists('get_plugin_data') ) { if ( ! class_exists( 'WPHelper/PluginCore' ) ):
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
// require dependency get_plugin_data()
if( ! function_exists( 'get_plugin_data' ) ) {
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
} }
if ( ! class_exists( 'WPHelper/PluginCore' ) ):
/** /**
* PluginCore * PluginCore
* *
* Helper Class for creating WordPress Plugins * Helper Class for creating WordPress Plugins
* *
* Defines PLUGIN_PATH, PLUGIN_URL (etc.) constants
* (@see README.md) * (@see README.md)
* *
* @version 0.22 * @version 0.27
*/ */
class PluginCore { class PluginCore {
@ -42,6 +41,11 @@ class PluginCore {
*/ */
private $const; private $const;
/**
* @var string
*/
private $token;
/** /**
* @var string * @var string
*/ */
@ -57,6 +61,11 @@ class PluginCore {
*/ */
private $plugin_basename; private $plugin_basename;
/**
* @var array plugin header metadata
*/
private $plugin_data;
/** /**
* @var callable * @var callable
*/ */
@ -107,19 +116,20 @@ class PluginCore {
*/ */
private $update_branch; private $update_branch;
/** /**
* Static array of all PluginCore instances * Static array of all PluginCore instances
* Used in PluginCore::get($slug) * Used in PluginCore::get($slug)
* *
* @var array[PluginCore] Instances of PluginCore * @var array[PluginCore] Instances of PluginCore
*/ */
static $cores = []; private static $cores = [];
/** /**
* Retrieve instance of PluginCore by plugin slug. * Retrieve instance of PluginCore by plugin slug.
* *
* @since 0.5
*
* @param string $slug - Plugin slug * @param string $slug - Plugin slug
* @return PluginCore - Instance of specific plugin. * @return PluginCore - Instance of specific plugin.
*/ */
@ -127,6 +137,29 @@ class PluginCore {
return self::$cores[ $slug ] ?? null; return self::$cores[ $slug ] ?? null;
} }
/**
* Retrieve instance of PluginCore by plugin __FILE__.
*
* @since 0.24
*
* @param string $filename - Plugin filename
* @return PluginCore - Instance of specific plugin.
*/
static public function get_by_file( $filename ) {
return current(
array_filter(
self::$cores,
fn($core) => $core->file() == $filename
)
) ?: null;
}
/**
* Constructor
*
* @since 0.1
* @since 0.2 Accept filename as first param and options array as optional param
*/
function __construct( $plugin_file, $options = null ) { function __construct( $plugin_file, $options = null ) {
$this->plugin_file( $plugin_file ); $this->plugin_file( $plugin_file );
@ -141,6 +174,8 @@ class PluginCore {
$this->const( $options->const ?? null ); // fallback: generate const from slug $this->const( $options->const ?? null ); // fallback: generate const from slug
$this->token( $options->token ?? null ); // fallback: generate token from slug
if ( isset( $options->activate_cb ) ) if ( isset( $options->activate_cb ) )
$this->activate_cb( $options->activate_cb ); $this->activate_cb( $options->activate_cb );
@ -177,6 +212,9 @@ class PluginCore {
* Register activation, deactivation, uninstall, upgrade hooks. * Register activation, deactivation, uninstall, upgrade hooks.
* Init PUC update checker. * Init PUC update checker.
* *
* @since 0.1 setup()
* @since 0.21 bootstrap()
*
* @todo set plugin_dir_path, plugin_basename as accessible public variables (available thru methods atm) * @todo set plugin_dir_path, plugin_basename as accessible public variables (available thru methods atm)
*/ */
private function bootstrap() { private function bootstrap() {
@ -216,6 +254,11 @@ class PluginCore {
} }
} }
/**
* Register activation/deactivation/uninstall/upgrade hooks
*
* @since 0.5
*/
private function register_hooks() { private function register_hooks() {
if ( ! empty( $this->activate_cb ) ) // && is_callable() ? if ( ! empty( $this->activate_cb ) ) // && is_callable() ?
@ -236,6 +279,8 @@ class PluginCore {
* Plugin title. * Plugin title.
* If none provided - plugin header Title will be used. * If none provided - plugin header Title will be used.
* *
* @since 0.1
*
* @param string|null $title * @param string|null $title
* @return string $this->title * @return string $this->title
*/ */
@ -246,6 +291,8 @@ class PluginCore {
/** /**
* Wrapper function for $this->title() * Wrapper function for $this->title()
* *
* @since 0.6
*
* @deprecated * @deprecated
*/ */
public function name( $title = null ) { public function name( $title = null ) {
@ -258,6 +305,8 @@ class PluginCore {
* Plugin slug. * Plugin slug.
* If none provided - plugin file basename will be used * If none provided - plugin file basename will be used
* *
* @since 0.1
*
* @param string|null $slug * @param string|null $slug
* @return string $this->slug * @return string $this->slug
*/ */
@ -269,6 +318,8 @@ class PluginCore {
* Setter - plugin_file (also Getter - kinda) * Setter - plugin_file (also Getter - kinda)
* Plugin file fully qualified path. * Plugin file fully qualified path.
* *
* @since 0.1
*
* @param string $plugin_file - Path to plugin file * @param string $plugin_file - Path to plugin file
* @return string $this->plugin_file * @return string $this->plugin_file
*/ */
@ -281,6 +332,8 @@ class PluginCore {
* Might have to rethink this * Might have to rethink this
* used by test-plugin update_checker * used by test-plugin update_checker
* *
* @since 0.7
*
* @todo revisit this * @todo revisit this
*/ */
public function file() { public function file() {
@ -290,9 +343,11 @@ class PluginCore {
/** /**
* Getter/Setter - plugin data array * Getter/Setter - plugin data array
*
* @since 0.14
*/ */
public function plugin_data() { public function plugin_data() {
return $this->plugin_data ??= get_plugin_data( $this->plugin_file, false); return $this->plugin_data ??= get_plugin_data( $this->plugin_file, false ); // false = no markup (i think)
} }
/** /**
@ -300,6 +355,8 @@ class PluginCore {
* Prefix of plugin specific defines (PLUGIN_NAME_PATH etc.) * Prefix of plugin specific defines (PLUGIN_NAME_PATH etc.)
* If not provided - plugin slug will be uppercase. * If not provided - plugin slug will be uppercase.
* *
* @since 0.4
*
* @param string|null $const (string should be uppercase) * @param string|null $const (string should be uppercase)
* @return string $this->const * @return string $this->const
*/ */
@ -307,8 +364,23 @@ class PluginCore {
return $this->const ??= $const ?: str_replace( '-', '_' , strtoupper( $this->slug() ) ); return $this->const ??= $const ?: str_replace( '-', '_' , strtoupper( $this->slug() ) );
} }
/**
* Getter/Setter - token
* Create a single-token slug (convert to underscore + lowercase).
*
* @since 0.25
*
* @param string|null $token (string will be normalized)
* @return string $this->token
*/
public function token( $token = null ) {
return $this->token ??= str_replace( '-', '_' , strtolower( $token ?: $this->slug() ) );
}
/** /**
* Getter/setter * Getter/setter
*
* @since 0.6
*/ */
public function path() { public function path() {
return $this->path ??= plugin_dir_path( $this->plugin_file ); return $this->path ??= plugin_dir_path( $this->plugin_file );
@ -316,6 +388,8 @@ class PluginCore {
/** /**
* Getter/Setter * Getter/Setter
*
* @since 0.6
*/ */
public function url() { public function url() {
return $this->url ??= plugin_dir_url( $this->plugin_file ); return $this->url ??= plugin_dir_url( $this->plugin_file );
@ -323,6 +397,8 @@ class PluginCore {
/** /**
* Getter/Setter * Getter/Setter
*
* @since 0.12
*/ */
public function plugin_basename() { public function plugin_basename() {
return $this->plugin_basename ??= plugin_basename( $this->plugin_file ); return $this->plugin_basename ??= plugin_basename( $this->plugin_file );
@ -333,6 +409,8 @@ class PluginCore {
* Callback runs on 'register_activation_hook' * Callback runs on 'register_activation_hook'
* PluginCore does not validate. Authors must ensure valid callback. * PluginCore does not validate. Authors must ensure valid callback.
* *
* @since 0.4
*
* @param callable $activate_cb - Activation callback * @param callable $activate_cb - Activation callback
* *
* @access private * @access private
@ -346,6 +424,8 @@ class PluginCore {
* Callback runs on 'register_deactivation_hook' * Callback runs on 'register_deactivation_hook'
* PluginCore does not validate. Authors must ensure valid callback. * PluginCore does not validate. Authors must ensure valid callback.
* *
* @since 0.4
*
* @param callable $deactivate_cb - Deactivation callback. * @param callable $deactivate_cb - Deactivation callback.
* *
* @access private * @access private
@ -359,6 +439,8 @@ class PluginCore {
* Callback runs on 'register_uninstall_hook' * Callback runs on 'register_uninstall_hook'
* PluginCore does not validate. Authors must ensure valid callback. * PluginCore does not validate. Authors must ensure valid callback.
* *
* @since 0.4
*
* @param callable $uninstall_cb - Uninstall callback. * @param callable $uninstall_cb - Uninstall callback.
* *
* @access private * @access private
@ -375,6 +457,8 @@ class PluginCore {
* *
* PluginCore does not validate. Authors must ensure valid callback. * PluginCore does not validate. Authors must ensure valid callback.
* *
* @since 0.11
*
* @param callable $upgrade_cb - Upgrade callback. * @param callable $upgrade_cb - Upgrade callback.
* *
* @access private * @access private
@ -407,26 +491,27 @@ class PluginCore {
/** /**
* Getter/Setter - AdminPage * Getter/Setter - AdminPage
* *
* Construct AdminPage instance for plugin. * Construct AdminPage instance for plugin.
*
* @since 0.14
* @since 0.17 - Pass instance of PluginCore to AdminPage (~0.14)
* *
* @param array $admin_page - AdminPage settings array * @param array $admin_page - AdminPage settings array
*
* @return AdminPage * @return AdminPage
*/ */
public function admin_page( $admin_page ) { public function admin_page( $admin_page ) {
if ( ! class_exists( 'WPHelper\AdminPage' ) ) if ( ! class_exists( AdminPage::class ) )
return; return;
// validate if ( ! isset( $this->admin_page ) ){
$admin_page['slug'] ??= $this->slug();
$admin_page['title'] ??= $this->title(); // validate
$admin_page['slug'] ??= $this->slug();
$this->admin_page = new AdminPage( $admin_page ); $admin_page['title'] ??= $this->title();
$admin_page['plugin_core'] ??= $this;
// validate for older versions of AdminPage
if ( method_exists( $this->admin_page, 'plugin_core' ) ) { $this->admin_page = new AdminPage( $admin_page );
$this->admin_page->plugin_core( $this ); // back-reference
} }
return $this->admin_page; return $this->admin_page;
@ -435,13 +520,15 @@ class PluginCore {
/** /**
* Setter * Setter
* *
* Setup info used by Puc_v4_Factory * Setup info used by PucFactory
* *
* set $update_checker (bool) * set $update_checker (bool)
* set $update_repo_uri (string) * set $update_repo_uri (string)
* set $update_auth (optional) * set $update_auth (optional)
* set $update_branch (optional) * set $update_branch (optional)
* *
* @since 0.9
*
* @param bool|string|array $update_checker * @param bool|string|array $update_checker
*/ */
private function update_checker( $update_checker ) { private function update_checker( $update_checker ) {
@ -490,14 +577,35 @@ class PluginCore {
/** /**
* Init Puc update checker instance * Init Puc update checker instance
* *
* @uses Puc_v4_Factory::buildUpdateChecker * @since 0.9 init_update_checker()
* @since 0.21 build_update_checker()
* @since 0.27 Create class alias WPHelper\PucFactory - support plugin-update-checker v4 & v5
*
* @uses PucFactory::buildUpdateChecker
*/ */
private function build_update_checker() { private function build_update_checker() {
if ( ! class_exists('Puc_v4_Factory') ) /**
* Create class alias WPHelper\PucFactory
* Support YahnisElsts\PluginUpdateChecker v4 | v5
*
* @since 0.27
*/
if ( ! class_exists( 'WPHelper\PucFactory' ) ) {
if ( class_exists( 'YahnisElsts\PluginUpdateChecker\v5\PucFactory' ) ) {
$actual_puc = 'YahnisElsts\PluginUpdateChecker\v5\PucFactory';
} else if ( class_exists( 'Puc_v4_Factory' ) ) {
$actual_puc = 'Puc_v4_Factory';
}
if ( ! empty( $actual_puc ) ) {
class_alias( $actual_puc, 'WPHelper\PucFactory' );
}
}
if ( ! class_exists( 'WPHelper\PucFactory' ) )
return; return;
$update_checker = Puc_v4_Factory::buildUpdateChecker( $update_checker = PucFactory::buildUpdateChecker(
$this->update_repo_uri, $this->update_repo_uri,
$this->plugin_file, $this->plugin_file,
$this->slug() // using slug() $this->slug() // using slug()
@ -520,6 +628,8 @@ class PluginCore {
* This function called on upgrader_process_complete * This function called on upgrader_process_complete
* sanity-checks if our plugin was upgraded * sanity-checks if our plugin was upgraded
* if so - calls upgrade_cb provided by our plugin * if so - calls upgrade_cb provided by our plugin
*
* @since 0.12
*/ */
public function upgrade_cb_wrapper( $upgrader_object, $options ) { public function upgrade_cb_wrapper( $upgrader_object, $options ) {
if( if(

View File

@ -2,12 +2,12 @@
"name": "abuyoyo/plugincore", "name": "abuyoyo/plugincore",
"description": "WordPress plugin core helper class", "description": "WordPress plugin core helper class",
"type": "library", "type": "library",
"version": "0.22", "version": "0.27",
"time": "2022-08-05", "time": "2022-10-03",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"recommend": { "suggest": {
"yahnis-elsts/plugin-update-checker": "~4.12", "yahnis-elsts/plugin-update-checker": "~5.2",
"abuyoyo/adminmenupage": "~0.20" "abuyoyo/adminmenupage": "~0.27"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

View File

@ -2,6 +2,16 @@
API for adding custom `screen-meta-links` links and panels alongside the 'Screen Options' and 'Help' links on the WordPress admin page. API for adding custom `screen-meta-links` links and panels alongside the 'Screen Options' and 'Help' links on the WordPress admin page.
## [0.13](https://github.com/abuyoyo/screen-meta-links/releases/tag/0.13)
### Fixed
- Fix PHP 8.2 depreacted: Optional parameter declared before required parameter.
## [0.12](https://github.com/abuyoyo/screen-meta-links/releases/tag/0.12)
### Fixed
- Fix PHP notice: Constant already defined.
## [0.11](https://github.com/abuyoyo/screen-meta-links/releases/tag/0.11) ## [0.11](https://github.com/abuyoyo/screen-meta-links/releases/tag/0.11)
### Removed ### Removed

View File

@ -2,7 +2,7 @@
/** /**
* Plugin Name: abuyoyo / Screen Meta Links * Plugin Name: abuyoyo / Screen Meta Links
* Description: API for adding custom screen-meta-links alongside the "Screen Options" and "Help" links. * Description: API for adding custom screen-meta-links alongside the "Screen Options" and "Help" links.
* Version: 0.11 * Version: 0.13
* Author: abuyoyo * Author: abuyoyo
* Author URI: https://github.com/abuyoyo * Author URI: https://github.com/abuyoyo
* Plugin URI: https://github.com/abuyoyo/screen-meta-links * Plugin URI: https://github.com/abuyoyo/screen-meta-links
@ -16,9 +16,9 @@
* *
*/ */
if ( ! defined( 'SML_FILE' ) ) define ( 'SML_FILE', __FILE__ ); ! defined( 'SML_FILE' ) && define ( 'SML_FILE', __FILE__ );
if ( ! defined( 'SML_URL' ) ) define ( 'SML_URL', plugin_dir_url( __FILE__ ) ); ! defined( 'SML_URL' ) && define ( 'SML_URL' , plugin_dir_url( __FILE__ ) );
if ( ! defined( 'SML_PATH' ) ) define ( 'SML_PATH', plugin_dir_path( __FILE__ ) ); ! defined( 'SML_PATH' ) && define ( 'SML_PATH', plugin_dir_path( __FILE__ ) );
if ( ! class_exists('Screen_Meta_Links') ): if ( ! class_exists('Screen_Meta_Links') ):
@ -352,14 +352,15 @@ if ( ! function_exists( 'wph_add_screen_meta_panel' ) ):
* @param string $id - Link ID. Should be unique and a valid value for a HTML ID attribute. * @param string $id - Link ID. Should be unique and a valid value for a HTML ID attribute.
* @param string $text - Link text. * @param string $text - Link text.
* @param string $href - Optional. Link URL to be used if no panel is provided * @param string $href - Optional. Link URL to be used if no panel is provided
* @param string|array $page - The page(s) where you want to add the link. * @param string|array $page - Optional. The page(s) where you want to add the link. Accepts wildcard '*'. If left empty will not add to any page.
* @param array $attributes - Optional. Additional attributes for the link tag. Add 'aria-controls' => "{$id}-wrap" to toggle panel * @param array $attributes - Optional. Additional attributes for the link tag. Add 'aria-controls' => "{$id}-wrap" to toggle panel
* @param callback $panel - Optional. Callback should print out screen-meta panel contents * @param callback $panel - Optional. Callback should print out screen-meta panel contents
* @return void * @return void
* *
* @todo Remove $href parameter and functionailty * @todo Remove $href parameter and functionailty
* @todo $page should not be optional. We need to remove $href first.
*/ */
function wph_add_screen_meta_panel($id, $text, $href = '', $page, $attributes = null, $panel=''){ function wph_add_screen_meta_panel( $id, $text, $href = '', $page = '', $attributes = null, $panel = '' ){
static $sml_instance = null; static $sml_instance = null;
if ( null === $sml_instance){ if ( null === $sml_instance){

20
vendor/autoload.php vendored
View File

@ -2,6 +2,24 @@
// autoload.php @generated by Composer // autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit99e41faf4c8cd1b54927a50ca0e7ee5c::getLoader(); return ComposerAutoloaderInita13a895834453aad32a897cc456c73ff::getLoader();

View File

@ -42,30 +42,76 @@ namespace Composer\Autoload;
*/ */
class ClassLoader class ClassLoader
{ {
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir; private $vendorDir;
// PSR-4 // PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array(); private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array(); private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array(); private $fallbackDirsPsr4 = array();
// PSR-0 // PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array(); private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array(); private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false; private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array(); private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false; private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array(); private $missingClasses = array();
/** @var string|null */
private $apcuPrefix; private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array(); private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null) public function __construct($vendorDir = null)
{ {
$this->vendorDir = $vendorDir; $this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
} }
/**
* @return array<string, list<string>>
*/
public function getPrefixes() public function getPrefixes()
{ {
if (!empty($this->prefixesPsr0)) { if (!empty($this->prefixesPsr0)) {
@ -75,28 +121,42 @@ class ClassLoader
return array(); return array();
} }
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4() public function getPrefixesPsr4()
{ {
return $this->prefixDirsPsr4; return $this->prefixDirsPsr4;
} }
/**
* @return list<string>
*/
public function getFallbackDirs() public function getFallbackDirs()
{ {
return $this->fallbackDirsPsr0; return $this->fallbackDirsPsr0;
} }
/**
* @return list<string>
*/
public function getFallbackDirsPsr4() public function getFallbackDirsPsr4()
{ {
return $this->fallbackDirsPsr4; return $this->fallbackDirsPsr4;
} }
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap() public function getClassMap()
{ {
return $this->classMap; return $this->classMap;
} }
/** /**
* @param array $classMap Class to filename map * @param array<string, string> $classMap Class to filename map
*
* @return void
*/ */
public function addClassMap(array $classMap) public function addClassMap(array $classMap)
{ {
@ -111,22 +171,25 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either * Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix. * appending or prepending to the ones previously set for this prefix.
* *
* @param string $prefix The prefix * @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories * @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories * @param bool $prepend Whether to prepend the directories
*
* @return void
*/ */
public function add($prefix, $paths, $prepend = false) public function add($prefix, $paths, $prepend = false)
{ {
$paths = (array) $paths;
if (!$prefix) { if (!$prefix) {
if ($prepend) { if ($prepend) {
$this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0 = array_merge(
(array) $paths, $paths,
$this->fallbackDirsPsr0 $this->fallbackDirsPsr0
); );
} else { } else {
$this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0, $this->fallbackDirsPsr0,
(array) $paths $paths
); );
} }
@ -135,19 +198,19 @@ class ClassLoader
$first = $prefix[0]; $first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) { if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths; $this->prefixesPsr0[$first][$prefix] = $paths;
return; return;
} }
if ($prepend) { if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths, $paths,
$this->prefixesPsr0[$first][$prefix] $this->prefixesPsr0[$first][$prefix]
); );
} else { } else {
$this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix], $this->prefixesPsr0[$first][$prefix],
(array) $paths $paths
); );
} }
} }
@ -156,25 +219,28 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either * Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace. * appending or prepending to the ones previously set for this namespace.
* *
* @param string $prefix The prefix/namespace, with trailing '\\' * @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories * @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories * @param bool $prepend Whether to prepend the directories
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*
* @return void
*/ */
public function addPsr4($prefix, $paths, $prepend = false) public function addPsr4($prefix, $paths, $prepend = false)
{ {
$paths = (array) $paths;
if (!$prefix) { if (!$prefix) {
// Register directories for the root namespace. // Register directories for the root namespace.
if ($prepend) { if ($prepend) {
$this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4 = array_merge(
(array) $paths, $paths,
$this->fallbackDirsPsr4 $this->fallbackDirsPsr4
); );
} else { } else {
$this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4, $this->fallbackDirsPsr4,
(array) $paths $paths
); );
} }
} elseif (!isset($this->prefixDirsPsr4[$prefix])) { } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@ -184,18 +250,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
} }
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths; $this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) { } elseif ($prepend) {
// Prepend directories for an already registered namespace. // Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths, $paths,
$this->prefixDirsPsr4[$prefix] $this->prefixDirsPsr4[$prefix]
); );
} else { } else {
// Append directories for an already registered namespace. // Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix], $this->prefixDirsPsr4[$prefix],
(array) $paths $paths
); );
} }
} }
@ -204,8 +270,10 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, * Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix. * replacing any others previously set for this prefix.
* *
* @param string $prefix The prefix * @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories * @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/ */
public function set($prefix, $paths) public function set($prefix, $paths)
{ {
@ -220,10 +288,12 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, * Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace. * replacing any others previously set for this namespace.
* *
* @param string $prefix The prefix/namespace, with trailing '\\' * @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories * @param list<string>|string $paths The PSR-4 base directories
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*
* @return void
*/ */
public function setPsr4($prefix, $paths) public function setPsr4($prefix, $paths)
{ {
@ -243,6 +313,8 @@ class ClassLoader
* Turns on searching the include path for class files. * Turns on searching the include path for class files.
* *
* @param bool $useIncludePath * @param bool $useIncludePath
*
* @return void
*/ */
public function setUseIncludePath($useIncludePath) public function setUseIncludePath($useIncludePath)
{ {
@ -265,6 +337,8 @@ class ClassLoader
* that have not been registered with the class map. * that have not been registered with the class map.
* *
* @param bool $classMapAuthoritative * @param bool $classMapAuthoritative
*
* @return void
*/ */
public function setClassMapAuthoritative($classMapAuthoritative) public function setClassMapAuthoritative($classMapAuthoritative)
{ {
@ -285,6 +359,8 @@ class ClassLoader
* APCu prefix to use to cache found/not-found classes, if the extension is enabled. * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
* *
* @param string|null $apcuPrefix * @param string|null $apcuPrefix
*
* @return void
*/ */
public function setApcuPrefix($apcuPrefix) public function setApcuPrefix($apcuPrefix)
{ {
@ -305,6 +381,8 @@ class ClassLoader
* Registers this instance as an autoloader. * Registers this instance as an autoloader.
* *
* @param bool $prepend Whether to prepend the autoloader or not * @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/ */
public function register($prepend = false) public function register($prepend = false)
{ {
@ -324,6 +402,8 @@ class ClassLoader
/** /**
* Unregisters this instance as an autoloader. * Unregisters this instance as an autoloader.
*
* @return void
*/ */
public function unregister() public function unregister()
{ {
@ -343,7 +423,8 @@ class ClassLoader
public function loadClass($class) public function loadClass($class)
{ {
if ($file = $this->findFile($class)) { if ($file = $this->findFile($class)) {
includeFile($file); $includeFile = self::$includeFile;
$includeFile($file);
return true; return true;
} }
@ -394,15 +475,20 @@ class ClassLoader
} }
/** /**
* Returns the currently registered loaders indexed by their corresponding vendor directories. * Returns the currently registered loaders keyed by their corresponding vendor directories.
* *
* @return self[] * @return array<string, self>
*/ */
public static function getRegisteredLoaders() public static function getRegisteredLoaders()
{ {
return self::$registeredLoaders; return self::$registeredLoaders;
} }
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext) private function findFileWithExtension($class, $ext)
{ {
// PSR-4 lookup // PSR-4 lookup
@ -468,14 +554,26 @@ class ClassLoader
return false; return false;
} }
}
/** /**
* Scope isolated include. * @return void
* */
* Prevents access to $this/self from included files. private static function initializeIncludeClosure()
*/ {
function includeFile($file) if (self::$includeFile !== null) {
{ return;
include $file; }
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
} }

View File

@ -20,12 +20,27 @@ use Composer\Semver\VersionParser;
* *
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
* *
* To require it's presence, you can require `composer-runtime-api ^2.0` * To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/ */
class InstalledVersions class InstalledVersions
{ {
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed; private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors; private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array(); private static $installedByVendor = array();
/** /**
@ -83,7 +98,7 @@ class InstalledVersions
{ {
foreach (self::getInstalled() as $installed) { foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) { if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
} }
} }
@ -104,7 +119,7 @@ class InstalledVersions
*/ */
public static function satisfies(VersionParser $parser, $packageName, $constraint) public static function satisfies(VersionParser $parser, $packageName, $constraint)
{ {
$constraint = $parser->parseConstraints($constraint); $constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint); return $provided->matches($constraint);
@ -228,7 +243,7 @@ class InstalledVersions
/** /**
* @return array * @return array
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string} * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/ */
public static function getRootPackage() public static function getRootPackage()
{ {
@ -242,7 +257,7 @@ class InstalledVersions
* *
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[] * @return array[]
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>} * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/ */
public static function getRawData() public static function getRawData()
{ {
@ -265,7 +280,7 @@ class InstalledVersions
* Returns the raw data of all installed.php which are currently loaded for custom implementations * Returns the raw data of all installed.php which are currently loaded for custom implementations
* *
* @return array[] * @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}> * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/ */
public static function getAllRawData() public static function getAllRawData()
{ {
@ -288,7 +303,7 @@ class InstalledVersions
* @param array[] $data A vendor/composer/installed.php data set * @param array[] $data A vendor/composer/installed.php data set
* @return void * @return void
* *
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>} $data * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/ */
public static function reload($data) public static function reload($data)
{ {
@ -298,7 +313,7 @@ class InstalledVersions
/** /**
* @return array[] * @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}> * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/ */
private static function getInstalled() private static function getInstalled()
{ {
@ -313,7 +328,9 @@ class InstalledVersions
if (isset(self::$installedByVendor[$vendorDir])) { if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir]; $installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) { } elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1]; self::$installed = $installed[count($installed) - 1];
} }
@ -325,12 +342,17 @@ class InstalledVersions
// only require the installed.php file if this file is loaded from its dumped location, // only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') { if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php'; /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else { } else {
self::$installed = array(); self::$installed = array();
} }
} }
$installed[] = self::$installed;
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
return $installed; return $installed;
} }

View File

@ -2,7 +2,7 @@
// autoload_classmap.php @generated by Composer // autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__)); $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(

View File

@ -2,7 +2,7 @@
// autoload_files.php @generated by Composer // autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__)); $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(

View File

@ -2,7 +2,7 @@
// autoload_namespaces.php @generated by Composer // autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__)); $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(

View File

@ -2,9 +2,9 @@
// autoload_psr4.php @generated by Composer // autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__)); $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir); $baseDir = dirname($vendorDir);
return array( return array(
'WPHelper\\' => array($vendorDir . '/abuyoyo/adminmenupage/src', $vendorDir . '/abuyoyo/plugincore'), 'WPHelper\\' => array($vendorDir . '/abuyoyo/adminmenupage/src', $vendorDir . '/abuyoyo/metabox', $vendorDir . '/abuyoyo/plugincore'),
); );

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer // autoload_real.php @generated by Composer
class ComposerAutoloaderInit99e41faf4c8cd1b54927a50ca0e7ee5c class ComposerAutoloaderInita13a895834453aad32a897cc456c73ff
{ {
private static $loader; private static $loader;
@ -22,52 +22,27 @@ class ComposerAutoloaderInit99e41faf4c8cd1b54927a50ca0e7ee5c
return self::$loader; return self::$loader;
} }
spl_autoload_register(array('ComposerAutoloaderInit99e41faf4c8cd1b54927a50ca0e7ee5c', 'loadClassLoader'), true, true); spl_autoload_register(array('ComposerAutoloaderInita13a895834453aad32a897cc456c73ff', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit99e41faf4c8cd1b54927a50ca0e7ee5c', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInita13a895834453aad32a897cc456c73ff', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); require __DIR__ . '/autoload_static.php';
if ($useStaticLoader) { call_user_func(\Composer\Autoload\ComposerStaticInita13a895834453aad32a897cc456c73ff::getInitializer($loader));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true); $loader->register(true);
if ($useStaticLoader) { $filesToLoad = \Composer\Autoload\ComposerStaticInita13a895834453aad32a897cc456c73ff::$files;
$includeFiles = Composer\Autoload\ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c::$files; $requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
} else { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$includeFiles = require __DIR__ . '/autoload_files.php'; $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
foreach ($includeFiles as $fileIdentifier => $file) { require $file;
composerRequire99e41faf4c8cd1b54927a50ca0e7ee5c($fileIdentifier, $file); }
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
} }
return $loader; return $loader;
} }
} }
function composerRequire99e41faf4c8cd1b54927a50ca0e7ee5c($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload; namespace Composer\Autoload;
class ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c class ComposerStaticInita13a895834453aad32a897cc456c73ff
{ {
public static $files = array ( public static $files = array (
'8653524d908cf23a56335c6d210d6627' => __DIR__ . '/..' . '/abuyoyo/adminmenupage/wph_admin_page.php', '8653524d908cf23a56335c6d210d6627' => __DIR__ . '/..' . '/abuyoyo/adminmenupage/wph_admin_page.php',
@ -22,7 +22,8 @@ class ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c
'WPHelper\\' => 'WPHelper\\' =>
array ( array (
0 => __DIR__ . '/..' . '/abuyoyo/adminmenupage/src', 0 => __DIR__ . '/..' . '/abuyoyo/adminmenupage/src',
1 => __DIR__ . '/..' . '/abuyoyo/plugincore', 1 => __DIR__ . '/..' . '/abuyoyo/metabox',
2 => __DIR__ . '/..' . '/abuyoyo/plugincore',
), ),
); );
@ -33,9 +34,9 @@ class ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c
public static function getInitializer(ClassLoader $loader) public static function getInitializer(ClassLoader $loader)
{ {
return \Closure::bind(function () use ($loader) { return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c::$prefixLengthsPsr4; $loader->prefixLengthsPsr4 = ComposerStaticInita13a895834453aad32a897cc456c73ff::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c::$prefixDirsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInita13a895834453aad32a897cc456c73ff::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit99e41faf4c8cd1b54927a50ca0e7ee5c::$classMap; $loader->classMap = ComposerStaticInita13a895834453aad32a897cc456c73ff::$classMap;
}, null, ClassLoader::class); }, null, ClassLoader::class);
} }

View File

@ -2,24 +2,27 @@
"packages": [ "packages": [
{ {
"name": "abuyoyo/adminmenupage", "name": "abuyoyo/adminmenupage",
"version": "0.21", "version": "0.29",
"version_normalized": "0.21.0.0", "version_normalized": "0.29.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/abuyoyo/AdminMenuPage.git", "url": "https://github.com/abuyoyo/AdminMenuPage.git",
"reference": "d05a9e9977d7e7c4ba3c913993493fefba4359d6" "reference": "4cd47d5217ca25ed17af76f5fdbab3cab3b37ef8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/abuyoyo/AdminMenuPage/zipball/d05a9e9977d7e7c4ba3c913993493fefba4359d6", "url": "https://api.github.com/repos/abuyoyo/AdminMenuPage/zipball/4cd47d5217ca25ed17af76f5fdbab3cab3b37ef8",
"reference": "d05a9e9977d7e7c4ba3c913993493fefba4359d6", "reference": "4cd47d5217ca25ed17af76f5fdbab3cab3b37ef8",
"shasum": "" "shasum": ""
}, },
"require": {
"abuyoyo/metabox": "~0.8"
},
"suggest": { "suggest": {
"abuyoyo/plugincore": "~0.18", "abuyoyo/plugincore": "~0.26",
"cmb2/cmb2": "~2.9" "cmb2/cmb2": "~2.9"
}, },
"time": "2022-08-06T13:42:37+00:00", "time": "2023-10-05T00:00:00+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -37,26 +40,64 @@
"description": "WordPress admin menu page helper class", "description": "WordPress admin menu page helper class",
"support": { "support": {
"issues": "https://github.com/abuyoyo/AdminMenuPage/issues", "issues": "https://github.com/abuyoyo/AdminMenuPage/issues",
"source": "https://github.com/abuyoyo/AdminMenuPage/tree/0.21" "source": "https://github.com/abuyoyo/AdminMenuPage/tree/0.29"
}, },
"install-path": "../abuyoyo/adminmenupage" "install-path": "../abuyoyo/adminmenupage"
}, },
{ {
"name": "abuyoyo/plugincore", "name": "abuyoyo/metabox",
"version": "0.22", "version": "0.8",
"version_normalized": "0.22.0.0", "version_normalized": "0.8.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/abuyoyo/PluginCore.git", "url": "https://github.com/abuyoyo/MetaBox.git",
"reference": "736b38d82fc41c7102ec28f386f4df807a10ab05" "reference": "98cb4c30db4c366c0d273985eb9c31ffa1cd78f9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/abuyoyo/PluginCore/zipball/736b38d82fc41c7102ec28f386f4df807a10ab05", "url": "https://api.github.com/repos/abuyoyo/MetaBox/zipball/98cb4c30db4c366c0d273985eb9c31ffa1cd78f9",
"reference": "736b38d82fc41c7102ec28f386f4df807a10ab05", "reference": "98cb4c30db4c366c0d273985eb9c31ffa1cd78f9",
"shasum": "" "shasum": ""
}, },
"time": "2022-08-05T00:00:00+00:00", "time": "2023-07-18T19:14:03+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"WPHelper\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "WordPress metabox helper class",
"support": {
"issues": "https://github.com/abuyoyo/MetaBox/issues",
"source": "https://github.com/abuyoyo/MetaBox/tree/0.8"
},
"install-path": "../abuyoyo/metabox"
},
{
"name": "abuyoyo/plugincore",
"version": "0.27",
"version_normalized": "0.27.0.0",
"source": {
"type": "git",
"url": "https://github.com/abuyoyo/PluginCore.git",
"reference": "d730a674cbe2dc92e60ace8e25a2e0e3fdeee3e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/abuyoyo/PluginCore/zipball/d730a674cbe2dc92e60ace8e25a2e0e3fdeee3e6",
"reference": "d730a674cbe2dc92e60ace8e25a2e0e3fdeee3e6",
"shasum": ""
},
"suggest": {
"abuyoyo/adminmenupage": "~0.27",
"yahnis-elsts/plugin-update-checker": "~5.2"
},
"time": "2022-10-03T00:00:00+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -71,26 +112,26 @@
"description": "WordPress plugin core helper class", "description": "WordPress plugin core helper class",
"support": { "support": {
"issues": "https://github.com/abuyoyo/PluginCore/issues", "issues": "https://github.com/abuyoyo/PluginCore/issues",
"source": "https://github.com/abuyoyo/PluginCore/tree/0.22" "source": "https://github.com/abuyoyo/PluginCore/tree/0.27"
}, },
"install-path": "../abuyoyo/plugincore" "install-path": "../abuyoyo/plugincore"
}, },
{ {
"name": "abuyoyo/screen-meta-links", "name": "abuyoyo/screen-meta-links",
"version": "0.11", "version": "0.13",
"version_normalized": "0.11.0.0", "version_normalized": "0.13.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/abuyoyo/screen-meta-links.git", "url": "https://github.com/abuyoyo/screen-meta-links.git",
"reference": "04e3c892f0c6095b4c31a489e06336f0917128d3" "reference": "b324cef9eb5825d04ffa17f771237b7deca5cd01"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/abuyoyo/screen-meta-links/zipball/04e3c892f0c6095b4c31a489e06336f0917128d3", "url": "https://api.github.com/repos/abuyoyo/screen-meta-links/zipball/b324cef9eb5825d04ffa17f771237b7deca5cd01",
"reference": "04e3c892f0c6095b4c31a489e06336f0917128d3", "reference": "b324cef9eb5825d04ffa17f771237b7deca5cd01",
"shasum": "" "shasum": ""
}, },
"time": "2022-05-18T01:18:24+00:00", "time": "2023-08-08T22:37:03+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -100,7 +141,7 @@
}, },
"description": "API for adding custom screen-meta-links alongside the 'Screen Options' and 'Help' links.", "description": "API for adding custom screen-meta-links alongside the 'Screen Options' and 'Help' links.",
"support": { "support": {
"source": "https://github.com/abuyoyo/screen-meta-links/tree/0.11", "source": "https://github.com/abuyoyo/screen-meta-links/tree/0.13",
"issues": "https://github.com/abuyoyo/screen-meta-links/issues" "issues": "https://github.com/abuyoyo/screen-meta-links/issues"
}, },
"install-path": "../abuyoyo/screen-meta-links" "install-path": "../abuyoyo/screen-meta-links"

View File

@ -1,49 +1,58 @@
<?php return array( <?php return array(
'root' => array( 'root' => array(
'pretty_version' => '0.17', 'name' => 'abuyoyo/notice-manager',
'version' => '0.17.0.0', 'pretty_version' => '0.25',
'version' => '0.25.0.0',
'reference' => NULL,
'type' => 'wordpress-plugin', 'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
'reference' => NULL,
'name' => 'abuyoyo/notice-manager',
'dev' => true, 'dev' => true,
), ),
'versions' => array( 'versions' => array(
'abuyoyo/adminmenupage' => array( 'abuyoyo/adminmenupage' => array(
'pretty_version' => '0.21', 'pretty_version' => '0.29',
'version' => '0.21.0.0', 'version' => '0.29.0.0',
'reference' => '4cd47d5217ca25ed17af76f5fdbab3cab3b37ef8',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../abuyoyo/adminmenupage', 'install_path' => __DIR__ . '/../abuyoyo/adminmenupage',
'aliases' => array(), 'aliases' => array(),
'reference' => 'd05a9e9977d7e7c4ba3c913993493fefba4359d6', 'dev_requirement' => false,
),
'abuyoyo/metabox' => array(
'pretty_version' => '0.8',
'version' => '0.8.0.0',
'reference' => '98cb4c30db4c366c0d273985eb9c31ffa1cd78f9',
'type' => 'library',
'install_path' => __DIR__ . '/../abuyoyo/metabox',
'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'abuyoyo/notice-manager' => array( 'abuyoyo/notice-manager' => array(
'pretty_version' => '0.17', 'pretty_version' => '0.25',
'version' => '0.17.0.0', 'version' => '0.25.0.0',
'reference' => NULL,
'type' => 'wordpress-plugin', 'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
'reference' => NULL,
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'abuyoyo/plugincore' => array( 'abuyoyo/plugincore' => array(
'pretty_version' => '0.22', 'pretty_version' => '0.27',
'version' => '0.22.0.0', 'version' => '0.27.0.0',
'reference' => 'd730a674cbe2dc92e60ace8e25a2e0e3fdeee3e6',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../abuyoyo/plugincore', 'install_path' => __DIR__ . '/../abuyoyo/plugincore',
'aliases' => array(), 'aliases' => array(),
'reference' => '736b38d82fc41c7102ec28f386f4df807a10ab05',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'abuyoyo/screen-meta-links' => array( 'abuyoyo/screen-meta-links' => array(
'pretty_version' => '0.11', 'pretty_version' => '0.13',
'version' => '0.11.0.0', 'version' => '0.13.0.0',
'reference' => 'b324cef9eb5825d04ffa17f771237b7deca5cd01',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../abuyoyo/screen-meta-links', 'install_path' => __DIR__ . '/../abuyoyo/screen-meta-links',
'aliases' => array(), 'aliases' => array(),
'reference' => '04e3c892f0c6095b4c31a489e06336f0917128d3',
'dev_requirement' => false, 'dev_requirement' => false,
), ),
), ),