initial
This commit is contained in:
@@ -0,0 +1,718 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.27.31] - 2026-06-29
|
||||
### Changed
|
||||
- Update dependencies. [#50001]
|
||||
|
||||
## [0.27.30] - 2026-06-25
|
||||
### Changed
|
||||
- Update package dependencies. [#49831]
|
||||
|
||||
## [0.27.29] - 2026-06-22
|
||||
### Changed
|
||||
- Update package dependencies. [#49631] [#49691] [#49757]
|
||||
|
||||
## [0.27.28] - 2026-06-15
|
||||
### Changed
|
||||
- Update package dependencies. [#49273]
|
||||
|
||||
## [0.27.27] - 2026-06-08
|
||||
### Changed
|
||||
- Update dependencies. [#49354]
|
||||
|
||||
## [0.27.26] - 2026-05-25
|
||||
### Changed
|
||||
- Update package dependencies. [#48405]
|
||||
|
||||
## [0.27.25] - 2026-05-19
|
||||
### Changed
|
||||
- Update package dependencies. [#48695]
|
||||
|
||||
## [0.27.24] - 2026-05-11
|
||||
### Changed
|
||||
- Update dependencies. [#46383]
|
||||
|
||||
## [0.27.23] - 2026-05-04
|
||||
### Changed
|
||||
- Internal: No longer require automattic/jetpack-changelogger as a per-project dev dependency. [#48225]
|
||||
|
||||
## [0.27.22] - 2026-04-27
|
||||
### Changed
|
||||
- Update package dependencies. [#48302]
|
||||
|
||||
## [0.27.21] - 2026-04-20
|
||||
### Changed
|
||||
- Update package dependencies. [#48106]
|
||||
|
||||
## [0.27.20] - 2026-04-09
|
||||
### Changed
|
||||
- Update package dependencies. [#47890]
|
||||
|
||||
## [0.27.19] - 2026-04-06
|
||||
### Changed
|
||||
- Update dependencies. [#46383]
|
||||
|
||||
## [0.27.18] - 2026-03-30
|
||||
### Changed
|
||||
- Update package dependencies. [#47818]
|
||||
|
||||
## [0.27.17] - 2026-03-23
|
||||
### Changed
|
||||
- Update package dependencies. [#47684]
|
||||
|
||||
## [0.27.16] - 2026-03-16
|
||||
### Changed
|
||||
- Update dependencies. [#47472]
|
||||
|
||||
## [0.27.15] - 2026-03-09
|
||||
### Changed
|
||||
- Update package dependencies. [#47496]
|
||||
|
||||
## [0.27.14] - 2026-02-26
|
||||
### Changed
|
||||
- Admin Menu: Move Upgrades menu registration to jetpack-mu-wpcom for all admin interfaces. [#47146]
|
||||
- Update package dependencies. [#47288] [#47300]
|
||||
|
||||
### Fixed
|
||||
- Fix admin menu upsell banner layout shift by rendering server-side instead of via AJAX. [#47268]
|
||||
|
||||
## [0.27.13] - 2026-02-23
|
||||
### Changed
|
||||
- Update package dependencies. [#47173]
|
||||
|
||||
## [0.27.12] - 2026-02-16
|
||||
### Changed
|
||||
- Update package dependencies. [#47099]
|
||||
|
||||
## [0.27.11] - 2026-02-10
|
||||
### Changed
|
||||
- Update package dependencies. [#46936] [#47002]
|
||||
|
||||
### Fixed
|
||||
- Admin Menu: Fix passing JSON string instead of array to JITM `get_messages()`. [#46906]
|
||||
|
||||
## [0.27.10] - 2026-02-02
|
||||
### Changed
|
||||
- Update package dependencies. [#46854]
|
||||
|
||||
## [0.27.9] - 2026-01-26
|
||||
### Changed
|
||||
- Update dependencies. [#46383]
|
||||
|
||||
## [0.27.8] - 2026-01-19
|
||||
### Changed
|
||||
- Update package dependencies. [#46552] [#46647]
|
||||
|
||||
## [0.27.7] - 2026-01-09
|
||||
### Changed
|
||||
- Update package dependencies. [#46456]
|
||||
|
||||
## [0.27.6] - 2025-12-22
|
||||
### Changed
|
||||
- Update dependencies. [#46381]
|
||||
|
||||
## [0.27.5] - 2025-12-15
|
||||
### Changed
|
||||
- Update dependencies. [#46271]
|
||||
|
||||
## [0.27.4] - 2025-12-08
|
||||
### Fixed
|
||||
- Ensure proper flags are used with `json_encode()`. [#46092]
|
||||
|
||||
## [0.27.3] - 2025-12-01
|
||||
### Changed
|
||||
- Update package dependencies. [#46143]
|
||||
|
||||
## [0.27.2] - 2025-11-18
|
||||
### Changed
|
||||
- Update package dependencies. [#45961]
|
||||
|
||||
## [0.27.1] - 2025-11-17
|
||||
### Changed
|
||||
- Update package dependencies. [#45915]
|
||||
|
||||
## [0.27.0] - 2025-11-03
|
||||
### Changed
|
||||
- Don't translate product names. [#43961]
|
||||
- Update dependencies. [#45664]
|
||||
|
||||
## [0.26.0] - 2025-10-20
|
||||
### Fixed
|
||||
- Show Additional CSS nudges on both Simple and Atomic, independently of the admin interface. [#45458]
|
||||
|
||||
## [0.25.0] - 2025-10-10
|
||||
### Removed
|
||||
- Admin Menu: Remove `P2_Admin_Menu` class. [#45355]
|
||||
|
||||
## [0.24.0] - 2025-10-06
|
||||
### Changed
|
||||
- Admin Menu: Use original menu order for self-hosted Jetpack sites in Calypso. [#45336]
|
||||
- Clean up the code for quick switcher after RDV. [#45353]
|
||||
- Update package dependencies. [#45334]
|
||||
|
||||
### Removed
|
||||
- Admin Menu: Remove unused menu registrations. [#45351]
|
||||
|
||||
## [0.23.3] - 2025-09-29
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.23.2] - 2025-09-22
|
||||
### Changed
|
||||
- Update dependencies. [#44736]
|
||||
|
||||
## [0.23.1] - 2025-09-19
|
||||
### Changed
|
||||
- Update package dependencies. [#45173] [#45229]
|
||||
|
||||
## [0.23.0] - 2025-09-15
|
||||
### Changed
|
||||
- Update package dependencies. [#45127] [#45128]
|
||||
|
||||
### Removed
|
||||
- Admin Menu: Remove Settings > Newsletter. [#45041]
|
||||
|
||||
## [0.22.3] - 2025-09-08
|
||||
### Changed
|
||||
- Update package dependencies. [#45027]
|
||||
|
||||
## [0.22.2] - 2025-09-01
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.22.1] - 2025-08-25
|
||||
### Fixed
|
||||
- Fix the target upsell plan for the Additional CSS feature (needed for WP Cloud Personal sites). [#44838]
|
||||
|
||||
## [0.22.0] - 2025-08-18
|
||||
### Removed
|
||||
- Admin Menu: Remove "Settings > Podcasting". [#44750]
|
||||
- Admin Menu: Remove "Tools > Monetize". [#44748]
|
||||
- Admin Menu: Remove "Users > Subscribers". [#44749]
|
||||
|
||||
## [0.21.0] - 2025-08-14
|
||||
### Changed
|
||||
- Admin Menu: Move Jetpack menu before Posts. [#44733]
|
||||
- Update package dependencies. [#44701]
|
||||
|
||||
## [0.20.0] - 2025-08-11
|
||||
### Changed
|
||||
- Admin Menu: Move "Hosting > Marketing" to "Tools > Marketing". [#44663]
|
||||
- Update dependencies. [#44673]
|
||||
- Update package dependencies. [#44677]
|
||||
|
||||
### Deprecated
|
||||
- Admin Menu: Deprecate "Settings > Newsletter". [#44630]
|
||||
|
||||
## [0.19.2] - 2025-08-04
|
||||
### Removed
|
||||
- Remove Dashboard link from Jetpack admin menu. [#44565]
|
||||
|
||||
## [0.19.1] - 2025-07-28
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.19.0] - 2025-07-21
|
||||
### Changed
|
||||
- Update package dependencies. [#44356]
|
||||
|
||||
### Deprecated
|
||||
- Admin Menu: Deprecate "Settings > Podcasting" menu. [#44367]
|
||||
- Admin Menu: Deprecate "Tools > Monetize" menu. [#44216]
|
||||
- Admin Menu: Deprecate "Users > Subscribers" menu. [#44302]
|
||||
|
||||
## [0.18.2] - 2025-07-14
|
||||
### Changed
|
||||
- Update dependencies. [#44229]
|
||||
|
||||
## [0.18.1] - 2025-07-07
|
||||
### Changed
|
||||
- Update package dependencies. [#44148] [#44151]
|
||||
|
||||
## [0.18.0] - 2025-06-30
|
||||
### Changed
|
||||
- Admin Menu: Show Jetpack > Stats to Calypso users. [#44090]
|
||||
|
||||
### Fixed
|
||||
- Admin Menu: Add JITM upsells back to default admin interface. [#44125]
|
||||
- Phan: Clean up error due to errant file reference. [#44031]
|
||||
|
||||
## [0.17.11] - 2025-06-23
|
||||
### Changed
|
||||
- Admin Menu: Consolidate "Dashboard" and "My Home" menus. [#43983]
|
||||
- Update dependencies. [#44002]
|
||||
- Update package dependencies. [#44020]
|
||||
|
||||
## [0.17.10] - 2025-06-16
|
||||
### Changed
|
||||
- Update package dependencies. [#43914]
|
||||
|
||||
## [0.17.9] - 2025-06-09
|
||||
### Changed
|
||||
- Forms: Update Feedback menu slug to point to forms inbox. [#43780]
|
||||
|
||||
## [0.17.8] - 2025-06-06
|
||||
### Fixed
|
||||
- Fix the Jetpack submenu order for WordPress.com sites that use Nav Unification. [#43781]
|
||||
|
||||
## [0.17.7] - 2025-06-05
|
||||
### Changed
|
||||
- Update dependencies. [#43785]
|
||||
|
||||
## [0.17.6] - 2025-06-03
|
||||
### Changed
|
||||
- Update package dependencies. [#43734]
|
||||
|
||||
## [0.17.5] - 2025-06-02
|
||||
### Changed
|
||||
- Update package dependencies. [#43710]
|
||||
|
||||
## [0.17.4] - 2025-05-26
|
||||
### Changed
|
||||
- Update package dependencies. [#43516] [#43578]
|
||||
|
||||
## [0.17.3] - 2025-05-19
|
||||
### Changed
|
||||
- Update package dependencies. [#43398]
|
||||
|
||||
## [0.17.2] - 2025-05-12
|
||||
### Changed
|
||||
- Update package dependencies. [#43400]
|
||||
|
||||
### Fixed
|
||||
- Add "Additional CSS" in the Appearance menu for Atomic sites. [#43272]
|
||||
|
||||
## [0.17.1] - 2025-05-05
|
||||
### Changed
|
||||
- Update package dependencies. [#43326]
|
||||
|
||||
### Fixed
|
||||
- Linting: Address final rules in WordPress Stylelint config. [#43296]
|
||||
- Linting: Do additional stylesheet cleanup. [#43247]
|
||||
|
||||
## [0.17.0] - 2025-04-28
|
||||
### Removed
|
||||
- Remove unused Phan exception. [#43063]
|
||||
|
||||
### Fixed
|
||||
- Code: Remove unneeded `data:` URI components. [#43227]
|
||||
- Linting: Fix more Stylelint violations. [#43213]
|
||||
|
||||
## [0.16.1] - 2025-04-21
|
||||
### Fixed
|
||||
- Add translation context to Search menu item. [#43094]
|
||||
|
||||
## [0.16.0] - 2025-04-14
|
||||
### Changed
|
||||
- Admin Menu: Update the icon of WooCommerce for the Woo installation. [#43029]
|
||||
|
||||
### Removed
|
||||
- Color Scheme: Clean up `*-rgb` CSS variables. [#42960]
|
||||
- Remove the site card from the admin sidebar. [#42499]
|
||||
|
||||
### Fixed
|
||||
- Linting: Clean up various Stylelint violations. [#43010]
|
||||
- Linting: Format SCSS imports consistently. [#43018]
|
||||
- Linting: Update stylesheets to use WordPress rules for fonts and colors. [#42920] [#42928]
|
||||
- Linting: Use double colon notation for pseudo-element selectors. [#43019]
|
||||
|
||||
## [0.15.1] - 2025-04-07
|
||||
### Changed
|
||||
- Code: First pass of style coding standards. [#42734]
|
||||
|
||||
## [0.15.0] - 2025-04-04
|
||||
### Changed
|
||||
- Stop using RDV experiment assignment. [#42765]
|
||||
|
||||
## [0.14.4] - 2025-04-02
|
||||
### Changed
|
||||
- Update dependencies. [#42820]
|
||||
- Update package dependencies. [#42809]
|
||||
|
||||
## [0.14.3] - 2025-03-31
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.14.2] - 2025-03-24
|
||||
### Changed
|
||||
- Update dependencies. [#42564]
|
||||
|
||||
### Fixed
|
||||
- Admin Color Scheme: Fix colors in the Aquatic color scheme. [#42632]
|
||||
- Site Badge: Update styles of the Coming Soon badge. [#42496]
|
||||
|
||||
## [0.14.1] - 2025-03-18
|
||||
### Changed
|
||||
- Update package dependencies. [#42511]
|
||||
|
||||
## [0.14.0] - 2025-03-17
|
||||
### Added
|
||||
- Add subscribers in WP Admin boilerplate. [#42066]
|
||||
|
||||
### Fixed
|
||||
- Upsell to correct plan in Additional CSS customizer menu when running the Global Styles experiment. [#42471]
|
||||
|
||||
## [0.13.2] - 2025-03-12
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.13.1] - 2025-03-10
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.13.0] - 2025-03-03
|
||||
### Changed
|
||||
- Admin Color Schemes: Update color schemes to match Calypso. [#40908]
|
||||
- Update package dependencies. [#42163]
|
||||
|
||||
### Removed
|
||||
- Masterbar: Remove My Mailboxes admin link. [#40885]
|
||||
|
||||
### Fixed
|
||||
- Admin menu: do not display the dashboard switcher button twice. [#42068]
|
||||
|
||||
## [0.12.4] - 2025-02-24
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.12.3] - 2025-02-17
|
||||
### Fixed
|
||||
- JITMs: Ensure we offer the same shortcircuit as in other elements where JITMs can be injected. [#41380]
|
||||
|
||||
## [0.12.2] - 2025-02-10
|
||||
### Changed
|
||||
- Update package dependencies. [#41491]
|
||||
|
||||
## [0.12.1] - 2025-02-03
|
||||
### Changed
|
||||
- Phan: Update baselines. [#41263]
|
||||
- Update package dependencies. [#41286]
|
||||
|
||||
## [0.12.0] - 2025-01-27
|
||||
### Added
|
||||
- Hide the calypso based Performance menu item on wordpress.com, show page-optimize based Performance menu item on Atomic sites. [#41145]
|
||||
|
||||
### Removed
|
||||
- Remove classic view admin notice from general settings (for Atomic sites). [#41155]
|
||||
|
||||
## [0.11.0] - 2025-01-20
|
||||
### Changed
|
||||
- Add watch command in the masterbar package. [#41066]
|
||||
- Code: Use function-style exit() and die() with a default status code of 0. [#41167]
|
||||
- Updated package dependencies. [#41099]
|
||||
|
||||
### Removed
|
||||
- Removed Settings > Security menu item from wpcom atomic sites in the hold out experiment. [#41112]
|
||||
|
||||
## [0.10.6] - 2025-01-10
|
||||
### Changed
|
||||
- Fixes the self-hosted link when WooCommerce is installed alongside SSO. [#40840]
|
||||
|
||||
## [0.10.5] - 2025-01-06
|
||||
### Changed
|
||||
- Updated package dependencies. [#40784] [#40792] [#40831]
|
||||
|
||||
## [0.10.4] - 2024-12-23
|
||||
### Fixed
|
||||
- Exclude the wpcom_admin_interface from the admin_menu action. [#40669]
|
||||
|
||||
## [0.10.3] - 2024-12-16
|
||||
### Changed
|
||||
- Updated package dependencies. [#40564]
|
||||
|
||||
## [0.10.2] - 2024-12-04
|
||||
### Changed
|
||||
- Updated package dependencies. [#40363]
|
||||
|
||||
## [0.10.1] - 2024-11-25
|
||||
### Changed
|
||||
- Updated dependencies. [#40286]
|
||||
- Updated package dependencies. [#40258] [#40288]
|
||||
|
||||
## [0.10.0] - 2024-11-18
|
||||
### Removed
|
||||
- General: Update minimum PHP version to 7.2. [#40147]
|
||||
|
||||
### Fixed
|
||||
- Update the upgrade nudge for Additional CSS with the correct plan names. [#40107]
|
||||
|
||||
## [0.9.9] - 2024-11-11
|
||||
### Changed
|
||||
- Updated package dependencies. [#39999] [#40060]
|
||||
|
||||
## [0.9.8] - 2024-11-04
|
||||
### Added
|
||||
- Enable test coverage. [#39961]
|
||||
|
||||
### Fixed
|
||||
- Fix PHPUnit coverage warnings. [#39989]
|
||||
|
||||
## [0.9.7] - 2024-10-28
|
||||
### Changed
|
||||
- Updated package dependencies. [#39910]
|
||||
|
||||
## [0.9.6] - 2024-10-14
|
||||
### Changed
|
||||
- Updated package dependencies. [#39707]
|
||||
|
||||
### Fixed
|
||||
- Admin bar: Clean up WPCOM_ADMIN_BAR_UNIFICATION feature flag. [#39692]
|
||||
|
||||
## [0.9.5] - 2024-10-07
|
||||
### Changed
|
||||
- Updated package dependencies. [#39594]
|
||||
- Update Jetpack Scan link. [#39619]
|
||||
|
||||
## [0.9.4] - 2024-09-30
|
||||
### Changed
|
||||
- Remove user connection nudges where they aren't needed. Add user connection nudges where needed [#39533]
|
||||
|
||||
### Removed
|
||||
- Masterbar: Remove User Info side-panel [#39546]
|
||||
|
||||
### Fixed
|
||||
- Admin bar: don't enqueue obsolete Core CSS overrides for Default scheme [#39453]
|
||||
|
||||
## [0.9.3] - 2024-09-23
|
||||
### Changed
|
||||
- Update dependencies.
|
||||
|
||||
## [0.9.2] - 2024-09-16
|
||||
### Fixed
|
||||
- Admin bar: align colors with Calypso's [#39314]
|
||||
- Help Center: Fix the icon color when previewing color scheme [#39371]
|
||||
|
||||
## [0.9.1] - 2024-09-10
|
||||
### Changed
|
||||
- Updated package dependencies. [#39302]
|
||||
|
||||
## [0.9.0] - 2024-09-09
|
||||
### Added
|
||||
- Admin menu: Add text-overflow ellipsis for the site title and domain. [#39224]
|
||||
|
||||
### Changed
|
||||
- Enable Users -> Profile (profile.php) on all sites [#39181]
|
||||
- Updated package dependencies. [#39176]
|
||||
|
||||
### Fixed
|
||||
- Hosting Configuration: Make the menu title under the settings the same as the destination [#39183]
|
||||
|
||||
## [0.8.1] - 2024-08-30
|
||||
### Changed
|
||||
- Updated package dependencies. [#39111]
|
||||
|
||||
## [0.8.0] - 2024-08-23
|
||||
### Changed
|
||||
- Remove locale sync [#39009]
|
||||
- Updated package dependencies. [#39004]
|
||||
|
||||
### Fixed
|
||||
- Inconsistent Color Scheme when previewing on Simple Default [#39048]
|
||||
|
||||
## [0.7.0] - 2024-08-21
|
||||
### Changed
|
||||
- Site Level User Profile: expose all relevant fields on profile.php [#38949]
|
||||
|
||||
### Fixed
|
||||
- Revert recent SVG image optimizations. [#38981]
|
||||
|
||||
## [0.6.1] - 2024-08-19
|
||||
### Changed
|
||||
- Updated package dependencies. [#38662]
|
||||
|
||||
### Fixed
|
||||
- Lossless image optimization for images (should improve performance with no visible changes). [#38750]
|
||||
|
||||
## [0.6.0] - 2024-07-29
|
||||
### Changed
|
||||
- Remove Browse sites from sidebar as it's on WordPress logo in masterbar [#38547]
|
||||
|
||||
## [0.5.0] - 2024-07-22
|
||||
### Added
|
||||
- Add background color to address overlapping. [#38438]
|
||||
|
||||
### Changed
|
||||
- Nav Redesign: Use Core admin bar for Simple and Atomic Default-view sites. [#38419]
|
||||
|
||||
## [0.4.0] - 2024-07-18
|
||||
### Changed
|
||||
- Admin Bar: Make it consistent between Calypso and WP Admin regardless of the value of Admin Interface Style [#38399]
|
||||
|
||||
### Fixed
|
||||
- Masterbar: Fix undefined array key warning in Base_Admin_Menu::hide_parent_of_hidden_submenus [#38363]
|
||||
|
||||
## [0.3.1] - 2024-07-15
|
||||
### Fixed
|
||||
- Hide "My Mailboxes" link on P2 sites [#38232]
|
||||
|
||||
## [0.3.0] - 2024-07-08
|
||||
### Changed
|
||||
- As we've launched untangling & nav redesign, the wpcom_is_nav_redesign_enabled() function name is not relevant anymore and can be confusing for future developers, so we replace it with the equivalent get_option call. [#38197]
|
||||
- Updated package dependencies. [#38132]
|
||||
|
||||
### Fixed
|
||||
- Fixes scrollbar issue if upsell nudge is loaded in specific viewport. [#38170]
|
||||
|
||||
## [0.2.5] - 2024-06-28
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.2.4] - 2024-06-26
|
||||
### Changed
|
||||
- Internal updates.
|
||||
|
||||
## [0.2.3] - 2024-06-26
|
||||
### Fixed
|
||||
- For sites with Classic view, don't load the masterbar package except the admin color schemes functionality. [#38020]
|
||||
|
||||
## [0.2.2] - 2024-06-25
|
||||
### Fixed
|
||||
- Masterbar: Fix missing private badge on admin menu for private WoA sites [#38026]
|
||||
|
||||
## [0.2.1] - 2024-06-25
|
||||
### Fixed
|
||||
- Profile: Restore profile fields on Classic interface [#38016]
|
||||
|
||||
## [0.2.0] - 2024-06-21
|
||||
### Changed
|
||||
- Masterbar: Require and use 'jetpack-masterbar' package in jetpack-mu-wpcom [#37812]
|
||||
|
||||
### Fixed
|
||||
- Masterbar: Remove old fly panel [#37764]
|
||||
|
||||
## [0.1.1] - 2024-06-17
|
||||
### Changed
|
||||
- Updated package dependencies. [#37796]
|
||||
|
||||
### Fixed
|
||||
- Color Schemes: Fix Sakura color issues on masterbar [#37806]
|
||||
|
||||
## 0.1.0 - 2024-06-10
|
||||
### Added
|
||||
- Initial version. [#37277]
|
||||
|
||||
### Changed
|
||||
- Auto-labeling: label changes to the Masterbar feature in the Masterbar package. [#37309]
|
||||
- Masterbar: Copy module code to package [#37342]
|
||||
- Notifications: Change Icon [#37676]
|
||||
- Updated package dependencies. [#37669] [#37706]
|
||||
|
||||
[0.27.31]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.30...v0.27.31
|
||||
[0.27.30]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.29...v0.27.30
|
||||
[0.27.29]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.28...v0.27.29
|
||||
[0.27.28]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.27...v0.27.28
|
||||
[0.27.27]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.26...v0.27.27
|
||||
[0.27.26]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.25...v0.27.26
|
||||
[0.27.25]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.24...v0.27.25
|
||||
[0.27.24]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.23...v0.27.24
|
||||
[0.27.23]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.22...v0.27.23
|
||||
[0.27.22]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.21...v0.27.22
|
||||
[0.27.21]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.20...v0.27.21
|
||||
[0.27.20]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.19...v0.27.20
|
||||
[0.27.19]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.18...v0.27.19
|
||||
[0.27.18]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.17...v0.27.18
|
||||
[0.27.17]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.16...v0.27.17
|
||||
[0.27.16]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.15...v0.27.16
|
||||
[0.27.15]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.14...v0.27.15
|
||||
[0.27.14]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.13...v0.27.14
|
||||
[0.27.13]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.12...v0.27.13
|
||||
[0.27.12]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.11...v0.27.12
|
||||
[0.27.11]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.10...v0.27.11
|
||||
[0.27.10]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.9...v0.27.10
|
||||
[0.27.9]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.8...v0.27.9
|
||||
[0.27.8]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.7...v0.27.8
|
||||
[0.27.7]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.6...v0.27.7
|
||||
[0.27.6]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.5...v0.27.6
|
||||
[0.27.5]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.4...v0.27.5
|
||||
[0.27.4]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.3...v0.27.4
|
||||
[0.27.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.2...v0.27.3
|
||||
[0.27.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.1...v0.27.2
|
||||
[0.27.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.27.0...v0.27.1
|
||||
[0.27.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.26.0...v0.27.0
|
||||
[0.26.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.25.0...v0.26.0
|
||||
[0.25.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.24.0...v0.25.0
|
||||
[0.24.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.23.3...v0.24.0
|
||||
[0.23.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.23.2...v0.23.3
|
||||
[0.23.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.23.1...v0.23.2
|
||||
[0.23.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.23.0...v0.23.1
|
||||
[0.23.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.22.3...v0.23.0
|
||||
[0.22.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.22.2...v0.22.3
|
||||
[0.22.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.22.1...v0.22.2
|
||||
[0.22.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.22.0...v0.22.1
|
||||
[0.22.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.21.0...v0.22.0
|
||||
[0.21.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.20.0...v0.21.0
|
||||
[0.20.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.19.2...v0.20.0
|
||||
[0.19.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.19.1...v0.19.2
|
||||
[0.19.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.19.0...v0.19.1
|
||||
[0.19.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.18.2...v0.19.0
|
||||
[0.18.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.18.1...v0.18.2
|
||||
[0.18.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.18.0...v0.18.1
|
||||
[0.18.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.11...v0.18.0
|
||||
[0.17.11]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.10...v0.17.11
|
||||
[0.17.10]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.9...v0.17.10
|
||||
[0.17.9]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.8...v0.17.9
|
||||
[0.17.8]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.7...v0.17.8
|
||||
[0.17.7]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.6...v0.17.7
|
||||
[0.17.6]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.5...v0.17.6
|
||||
[0.17.5]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.4...v0.17.5
|
||||
[0.17.4]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.3...v0.17.4
|
||||
[0.17.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.2...v0.17.3
|
||||
[0.17.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.1...v0.17.2
|
||||
[0.17.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.17.0...v0.17.1
|
||||
[0.17.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.16.1...v0.17.0
|
||||
[0.16.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.16.0...v0.16.1
|
||||
[0.16.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.15.1...v0.16.0
|
||||
[0.15.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.15.0...v0.15.1
|
||||
[0.15.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.14.4...v0.15.0
|
||||
[0.14.4]: https://github.com/Automattic/jetpack-masterbar/compare/v0.14.3...v0.14.4
|
||||
[0.14.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.14.2...v0.14.3
|
||||
[0.14.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.14.1...v0.14.2
|
||||
[0.14.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.14.0...v0.14.1
|
||||
[0.14.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.13.2...v0.14.0
|
||||
[0.13.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.13.1...v0.13.2
|
||||
[0.13.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.13.0...v0.13.1
|
||||
[0.13.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.12.4...v0.13.0
|
||||
[0.12.4]: https://github.com/Automattic/jetpack-masterbar/compare/v0.12.3...v0.12.4
|
||||
[0.12.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.12.2...v0.12.3
|
||||
[0.12.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.12.1...v0.12.2
|
||||
[0.12.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.12.0...v0.12.1
|
||||
[0.12.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.11.0...v0.12.0
|
||||
[0.11.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.10.6...v0.11.0
|
||||
[0.10.6]: https://github.com/Automattic/jetpack-masterbar/compare/v0.10.5...v0.10.6
|
||||
[0.10.5]: https://github.com/Automattic/jetpack-masterbar/compare/v0.10.4...v0.10.5
|
||||
[0.10.4]: https://github.com/Automattic/jetpack-masterbar/compare/v0.10.3...v0.10.4
|
||||
[0.10.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.10.2...v0.10.3
|
||||
[0.10.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.10.1...v0.10.2
|
||||
[0.10.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.10.0...v0.10.1
|
||||
[0.10.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.9...v0.10.0
|
||||
[0.9.9]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.8...v0.9.9
|
||||
[0.9.8]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.7...v0.9.8
|
||||
[0.9.7]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.6...v0.9.7
|
||||
[0.9.6]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.5...v0.9.6
|
||||
[0.9.5]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.4...v0.9.5
|
||||
[0.9.4]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.3...v0.9.4
|
||||
[0.9.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.2...v0.9.3
|
||||
[0.9.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.1...v0.9.2
|
||||
[0.9.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.9.0...v0.9.1
|
||||
[0.9.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.8.1...v0.9.0
|
||||
[0.8.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.8.0...v0.8.1
|
||||
[0.8.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.7.0...v0.8.0
|
||||
[0.7.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.6.1...v0.7.0
|
||||
[0.6.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.6.0...v0.6.1
|
||||
[0.6.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.5.0...v0.6.0
|
||||
[0.5.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.4.0...v0.5.0
|
||||
[0.4.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.3.1...v0.4.0
|
||||
[0.3.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.3.0...v0.3.1
|
||||
[0.3.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.2.5...v0.3.0
|
||||
[0.2.5]: https://github.com/Automattic/jetpack-masterbar/compare/v0.2.4...v0.2.5
|
||||
[0.2.4]: https://github.com/Automattic/jetpack-masterbar/compare/v0.2.3...v0.2.4
|
||||
[0.2.3]: https://github.com/Automattic/jetpack-masterbar/compare/v0.2.2...v0.2.3
|
||||
[0.2.2]: https://github.com/Automattic/jetpack-masterbar/compare/v0.2.1...v0.2.2
|
||||
[0.2.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.2.0...v0.2.1
|
||||
[0.2.0]: https://github.com/Automattic/jetpack-masterbar/compare/v0.1.1...v0.2.0
|
||||
[0.1.1]: https://github.com/Automattic/jetpack-masterbar/compare/v0.1.0...v0.1.1
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#008763;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#007053}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#096484;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#2a46ce}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#b26200;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#8a4d00}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#2c3338;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#c9356e;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#ab235a}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#c9356e;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#ab235a}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#c7a589;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#8a4d00}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#2c3338;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#044b7a;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#055d9c}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#a3b745;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#647d00}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#wpadminbar .ab-icon{color:#a7aaad}#wpadminbar .ab-top-menu>#wp-admin-bar-blog.my-sites>.ab-item{background:#23282d}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#2271b1;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#135e96}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#04a4cc;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#2a46ce}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#e14d43;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#00417d}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#3858e9;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#2145e6}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#0675c4;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#055d9c}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#9ebaa0;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#007053}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#0675c4;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#055d9c}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#0675c4;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#055d9c}
|
||||
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#dd823b;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#8a4d00}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
#adminmenu .toplevel_page_site-notices .upsell_banner{background-color:#fff;color:#000}#adminmenu .toplevel_page_site-notices .upsell_banner .button{background-color:#b26200;color:#fff}#adminmenu .toplevel_page_site-notices .upsell_banner .button:hover{background-color:#8a4d00}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => 'f1ca383f6230f66d3754');
|
||||
+1
File diff suppressed because one or more lines are too long
wp-content/plugins/jetpack/jetpack_vendor/automattic/jetpack-masterbar/dist/admin-menu/admin-menu.js
Vendored
+1
@@ -0,0 +1 @@
|
||||
(()=>{"use strict";var e={921(){}},t={};(function n(o){var s=t[o];if(void 0!==s)return s.exports;var a=t[o]={exports:{}};return e[o](a,a.exports,n),a.exports})(921);!function(e){function t(){const t=document.querySelector("#wpadminbar");if(!t)return;const o=document.querySelector("#wpwrap"),s=document.querySelector("#adminmenu"),a="dismissible-card__close-icon";function r(e){const n=t.querySelectorAll("#wp-admin-bar-blog a");for(let t=0;t<n.length;t++)n[t].setAttribute("aria-expanded",e)}!function(){const e=document.querySelector(".wp-submenu .current > a");if(!e)return;e.focus({preventScroll:!0})}(),r("false");const i=t.querySelector("#wp-admin-bar-blog.my-sites > a");function c(n){if(e(window).width()>782)return n.stopImmediatePropagation(),!0;n.preventDefault(),e("#wp-admin-bar-menu-toggle").off("click.wp-responsive");const s=t.querySelectorAll(".hover"),a=s.length;for(let e=0;e<a;e++)s[e].classList.remove("hover");if(o.classList.toggle("wp-responsive-open"),o.classList.contains("wp-responsive-open")){r("true");const e=document.querySelector("#adminmenu a");e&&e.focus()}else r("false")}if(i&&!document.body.classList.contains("wpcom-admin-interface")&&(e("#wp-admin-bar-blog.my-sites > a").off("click.wp-responsive"),i.removeAttribute("aria-haspopup"),i.addEventListener("click",c),document.addEventListener("click",function(e){const t=!!e.target.closest("#wp-admin-bar-blog > a"),n=document.getElementById("adminmenu").contains(e.target),s=o.classList.contains("wp-responsive-open");!s||t||n||c(e)})),s){const e=s.querySelector("#collapse-button");e&&e.addEventListener("click",function(e){setTimeout(function(){var t;t=e.target.parentNode.getAttribute("aria-expanded"),n("POST",ajaxurl,"application/x-www-form-urlencoded; charset=UTF-8","action=sidebar_state&expanded="+t)},50)}),s.addEventListener("click",function(e){if(e.target.classList.contains(a)||e.target.closest("."+a)){e.preventDefault();const t=document.getElementById("toplevel_page_site-notices");t&&(t.style.display="none");const o=e.target;n("POST",ajaxurl,"application/x-www-form-urlencoded; charset=UTF-8","id="+encodeURIComponent(o.dataset.feature_id)+"&feature_class="+encodeURIComponent(o.dataset.feature_class)+"&action=jitm_dismiss&_ajax_nonce="+jetpackAdminMenu.jitmDismissNonce)}})}}function n(e,t,n,o=null,s=null){const a=new XMLHttpRequest;a.open(e,t,!0),a.setRequestHeader("X-Requested-With","XMLHttpRequest"),n&&a.setRequestHeader("Content-Type",n),a.withCredentials=!0,s&&(a.onreadystatechange=function(){s(a)}),a.send(o)}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",t):t()}(jQuery)})();
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => '7a523bec6c0fce2fca12');
|
||||
+1
@@ -0,0 +1 @@
|
||||
.a8c-faux-inline-help{bottom:24px;position:fixed;right:24px;z-index:9999}.a8c-faux-inline-help .a8c-faux-inline-help__button{background-color:#1d2327;background-color:var(--color-primary);border:1px solid #3c434a;border:1px solid var(--color-primary-dark);border-radius:100%;bottom:10px;box-shadow:0 4px 5px 0 rgba(16,21,23,.14),0 1px 10px 0 rgba(16,21,23,.12),0 2px 4px -1px rgba(16,21,23,.2);box-shadow:0 4px 5px 0 color-mix(in sRGB,var(--color-neutral-100) 14%,transparent),0 1px 10px 0 color-mix(in sRGB,var(--color-neutral-100) 12%,transparent),0 2px 4px -1px color-mix(in sRGB,var(--color-neutral-100) 20%,transparent);box-sizing:border-box;height:40px;line-height:0;overflow:visible;padding:1px;position:absolute;right:0;transition:all .2s ease-in-out;width:40px}.a8c-faux-inline-help .a8c-faux-inline-help__button:before{background:#fff;background:var(--color-surface);border-radius:100%;content:"";display:block;height:28px;left:5px;position:absolute;top:5px;width:28px}.a8c-faux-inline-help .a8c-faux-inline-help__button:focus{background-color:#1d2327;background-color:var(--color-primary);box-shadow:0 0 0 2px #8c8f94;box-shadow:0 0 0 2px var(--color-primary-light)}.a8c-faux-inline-help .a8c-faux-inline-help__button .gridicon{fill:#1d2327;fill:var(--color-primary);height:42px;margin:-3px 0 0 -3px;pointer-events:none;position:relative;top:0;width:42px}.a8c-faux-inline-help .a8c-faux-inline-help__button .gridicon>g:first-child,.a8c-faux-inline-help .a8c-faux-inline-help__button .gridicon>use:first-child{transform:none}.a8c-faux-inline-help .a8c-faux-inline-help__button:hover:not(.is-active){background:#1d2327;background:var(--color-primary);transform:scale(1.15)}
|
||||
+1
@@ -0,0 +1 @@
|
||||
(()=>{"use strict";var r={337(){}},t={};(function e(o){var s=t[o];if(void 0!==s)return s.exports;var i=t[o]={exports:{}};return r[o](i,i.exports,e),i.exports})(337)})();
|
||||
+1
@@ -0,0 +1 @@
|
||||
.a8c-faux-inline-help{bottom:24px;left:24px;position:fixed;z-index:9999}.a8c-faux-inline-help .a8c-faux-inline-help__button{background-color:#1d2327;background-color:var(--color-primary);border:1px solid #3c434a;border:1px solid var(--color-primary-dark);border-radius:100%;bottom:10px;box-shadow:0 4px 5px 0 rgba(16,21,23,.14),0 1px 10px 0 rgba(16,21,23,.12),0 2px 4px -1px rgba(16,21,23,.2);box-shadow:0 4px 5px 0 color-mix(in sRGB,var(--color-neutral-100) 14%,transparent),0 1px 10px 0 color-mix(in sRGB,var(--color-neutral-100) 12%,transparent),0 2px 4px -1px color-mix(in sRGB,var(--color-neutral-100) 20%,transparent);box-sizing:border-box;height:40px;left:0;line-height:0;overflow:visible;padding:1px;position:absolute;transition:all .2s ease-in-out;width:40px}.a8c-faux-inline-help .a8c-faux-inline-help__button:before{background:#fff;background:var(--color-surface);border-radius:100%;content:"";display:block;height:28px;position:absolute;right:5px;top:5px;width:28px}.a8c-faux-inline-help .a8c-faux-inline-help__button:focus{background-color:#1d2327;background-color:var(--color-primary);box-shadow:0 0 0 2px #8c8f94;box-shadow:0 0 0 2px var(--color-primary-light)}.a8c-faux-inline-help .a8c-faux-inline-help__button .gridicon{fill:#1d2327;fill:var(--color-primary);height:42px;margin:-3px -3px 0 0;pointer-events:none;position:relative;top:0;width:42px}.a8c-faux-inline-help .a8c-faux-inline-help__button .gridicon>g:first-child,.a8c-faux-inline-help .a8c-faux-inline-help__button .gridicon>use:first-child{transform:none}.a8c-faux-inline-help .a8c-faux-inline-help__button:hover:not(.is-active){background:#1d2327;background:var(--color-primary);transform:scale(1.15)}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => 'c123e499128886efeab6');
|
||||
+1
@@ -0,0 +1 @@
|
||||
.customize-control-cssNudge .nudge-container{padding:50px 0;width:100%}.customize-control-cssNudge .nudge-container p{text-align:center}.customize-control-cssNudge .nudge-container .button-container{margin-top:20px;text-align:center}
|
||||
+1
@@ -0,0 +1 @@
|
||||
(()=>{"use strict";var t={330(){}},o={};(function n(i){var e=o[i];if(void 0!==e)return e.exports;var c=o[i]={exports:{}};return t[i](c,c.exports,n),c.exports})(330);!function(t){const o={init:function(){this.clickifyNavigateToButtons()},clickifyNavigateToButtons:function(){const t=document.querySelector(".navigate-to");t&&t.addEventListener("click",function(){const t=this.getAttribute("data-navigate-to-page");t&&(window._tkq=window._tkq||[],window._tkq.push(["recordEvent","calypso_upgrade_nudge_cta_click",{cta_name:"customizer_css"}]),window.location.search.match(/calypso=true/)&&window.parent.location!==window.location?window.top.postMessage(JSON.stringify({calypso:!0,command:"navigateTo",destination:t}),"*"):window.location="https://wordpress.com"+t)})}};t(document).ready(function(){o.init()})}(jQuery)})();
|
||||
+1
@@ -0,0 +1 @@
|
||||
.customize-control-cssNudge .nudge-container{padding:50px 0;width:100%}.customize-control-cssNudge .nudge-container p{text-align:center}.customize-control-cssNudge .nudge-container .button-container{margin-top:20px;text-align:center}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array(), 'version' => '7d644e449d5df4b79dc9');
|
||||
+1
@@ -0,0 +1 @@
|
||||
.posts-page .info{display:inline-block;margin-left:8px;position:relative}.posts-page .info .message{background-color:#fff;border:1px solid #c3c4c7;border-radius:2px;box-shadow:0 2px 5px rgba(0,0,0,.1),0 0 56px rgba(0,0,0,.075);color:#646970;font-size:.875rem;margin-left:5px;padding:16px;position:absolute;text-align:left;visibility:hidden;width:220px;z-index:1}.posts-page .info:hover .message{visibility:visible}@media screen and (max-width:782px){.posts-page .info .icon{font-size:28px;height:28px;width:28px}}
|
||||
+1
@@ -0,0 +1 @@
|
||||
(()=>{"use strict";var r={945(){}},t={};(function e(o){var s=t[o];if(void 0!==s)return s.exports;var i=t[o]={exports:{}};return r[o](i,i.exports,e),i.exports})(945)})();
|
||||
+1
@@ -0,0 +1 @@
|
||||
.posts-page .info{display:inline-block;margin-right:8px;position:relative}.posts-page .info .message{background-color:#fff;border:1px solid #c3c4c7;border-radius:2px;box-shadow:0 2px 5px rgba(0,0,0,.1),0 0 56px rgba(0,0,0,.075);color:#646970;font-size:.875rem;margin-right:5px;padding:16px;position:absolute;text-align:right;visibility:hidden;width:220px;z-index:1}.posts-page .info:hover .message{visibility:visible}@media screen and (max-width:782px){.posts-page .info .icon{font-size:28px;height:28px;width:28px}}
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
/**
|
||||
* Unifies admin color scheme selection across WP.com sites.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
|
||||
/**
|
||||
* Unifies admin color scheme selection across WP.com sites.
|
||||
*
|
||||
* @phan-constructor-used-for-side-effects
|
||||
*/
|
||||
class Admin_Color_Schemes {
|
||||
|
||||
/**
|
||||
* A list of core color schemes to override.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const CORE_COLOR_SCHEMES = array( 'blue', 'coffee', 'ectoplasm', 'fresh', 'light', 'midnight', 'modern', 'ocean', 'sunrise' );
|
||||
|
||||
/**
|
||||
* Admin_Color_Schemes constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
// We want to register the admin color schemes across all environments.
|
||||
add_action( 'admin_init', array( $this, 'register_admin_color_schemes' ) );
|
||||
// We don't want to make the admin_color available in users REST API endpoint for Simple sites.
|
||||
if ( false === ( new Host() )->is_wpcom_simple() ) {
|
||||
add_action( 'rest_api_init', array( $this, 'register_admin_color_meta' ) );
|
||||
}
|
||||
|
||||
if ( ( new Host() )->is_wpcom_platform() ) { // Simple and Atomic sites.
|
||||
add_filter( 'css_do_concat', array( $this, 'disable_css_concat_for_color_schemes' ), 10, 2 );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_color_scheme_for_sidebar_notice' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes admin_color available in users REST API endpoint.
|
||||
*/
|
||||
public function register_admin_color_meta() {
|
||||
register_meta(
|
||||
'user',
|
||||
'admin_color',
|
||||
array(
|
||||
'auth_callback' => array( $this, 'update_admin_color_permissions_check' ),
|
||||
'description' => __( 'Slug of the admin color scheme.', 'jetpack-masterbar' ),
|
||||
'single' => true,
|
||||
'show_in_rest' => array(
|
||||
'schema' => array( 'default' => 'fresh' ),
|
||||
),
|
||||
'type' => 'string',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission callback to edit the `admin_color` user meta.
|
||||
*
|
||||
* @param bool $allowed Whether the given user is allowed to edit this meta value.
|
||||
* @param string $meta_key Meta key. In this case `admin_color`.
|
||||
* @param int $object_id Queried user ID.
|
||||
* @return bool
|
||||
*/
|
||||
public function update_admin_color_permissions_check( $allowed, $meta_key, $object_id ) {
|
||||
return current_user_can( 'edit_user', $object_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the admin color scheme URL based on the environment
|
||||
*
|
||||
* @param string $color_scheme The color scheme to get the URL for.
|
||||
* @param string $file The file name (optional, default: colors.css).
|
||||
* @return string
|
||||
*/
|
||||
public function get_admin_color_scheme_url( $color_scheme, $file = 'colors.css' ) {
|
||||
return plugins_url( '../../dist/admin-color-schemes/colors/' . $color_scheme . '/' . $file, __FILE__ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new admin color schemes
|
||||
*/
|
||||
public function register_admin_color_schemes() {
|
||||
|
||||
wp_admin_css_color(
|
||||
'aquatic',
|
||||
__( 'Aquatic', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'aquatic' ),
|
||||
array( '#135e96', '#007e65', '#043959', '#c5d9ed' ),
|
||||
array(
|
||||
'base' => '#c5d9ed',
|
||||
'focus' => '#fff',
|
||||
'current' => '#01263a',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'classic-blue',
|
||||
__( 'Classic Blue', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'classic-blue' ),
|
||||
array( '#135e96', '#b26200', '#dcdcde', '#646970' ),
|
||||
array(
|
||||
'base' => '#646970',
|
||||
'focus' => '#2271b1',
|
||||
'current' => '#fff',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'classic-bright',
|
||||
__( 'Classic Bright', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'classic-bright' ),
|
||||
array( '#135e96', '#c9256e', '#ffffff', '#e9eff5' ),
|
||||
array(
|
||||
'base' => '#646970',
|
||||
'focus' => '#1d2327',
|
||||
'current' => '#0a4b78',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'classic-dark',
|
||||
__( 'Classic Dark', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'classic-dark' ),
|
||||
array( '#101517', '#c9356e', '#32373c', '#0073aa' ),
|
||||
array(
|
||||
'base' => '#a2aab2',
|
||||
'focus' => '#00b9eb',
|
||||
'current' => '#fff',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'contrast',
|
||||
__( 'Contrast', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'contrast' ),
|
||||
array( '#101517', '#ffffff', '#32373c', '#b4b9be' ),
|
||||
array(
|
||||
'base' => '#1d2327',
|
||||
'focus' => '#fff',
|
||||
'current' => '#fff',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'fresh',
|
||||
__( 'Default', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'fresh' ),
|
||||
array( '#1d2327', '#2c3338', '#2271b1', '#72aee6' ),
|
||||
array(
|
||||
'base' => '#a7aaad',
|
||||
'focus' => '#72aee6',
|
||||
'current' => '#fff',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'nightfall',
|
||||
__( 'Nightfall', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'nightfall' ),
|
||||
array( '#00131c', '#043959', '#2271b1', '#9ec2e6' ),
|
||||
array(
|
||||
'base' => '#9ec2e6',
|
||||
'focus' => '#fff',
|
||||
'current' => '#fff',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'powder-snow',
|
||||
__( 'Powder Snow', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'powder-snow' ),
|
||||
array( '#101517', '#2271b1', '#dcdcde', '#646970' ),
|
||||
array(
|
||||
'base' => '#646970',
|
||||
'focus' => '#135e96',
|
||||
'current' => '#fff',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'sakura',
|
||||
__( 'Sakura', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'sakura' ),
|
||||
array( '#005042', '#f2ceda', '#2271b1', '#8c1749' ),
|
||||
array(
|
||||
'base' => '#8c1749',
|
||||
'focus' => '#4f092a',
|
||||
'current' => '#fff',
|
||||
)
|
||||
);
|
||||
|
||||
wp_admin_css_color(
|
||||
'sunset',
|
||||
__( 'Sunset', 'jetpack-masterbar' ),
|
||||
$this->get_admin_color_scheme_url( 'sunset' ),
|
||||
array( '#691c1c', '#b26200', '#f0c930', '#facfd2' ),
|
||||
array(
|
||||
'base' => '#facfd2',
|
||||
'focus' => '#fff',
|
||||
'current' => '#4f3500',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues current color-scheme sidebar notice overrides for core color schemes
|
||||
*/
|
||||
public function enqueue_color_scheme_for_sidebar_notice() {
|
||||
$color_scheme = get_user_option( 'admin_color' );
|
||||
if ( in_array( $color_scheme, static::CORE_COLOR_SCHEMES, true ) ) {
|
||||
wp_enqueue_style(
|
||||
'jetpack-core-color-schemes-overrides-sidebar-notice',
|
||||
$this->get_admin_color_scheme_url( $color_scheme, 'sidebar-notice.css' ),
|
||||
array(),
|
||||
Main::PACKAGE_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently, the selected color scheme CSS (with id = "colors") is concatenated (by Jetpack Boost / Page Optimize),
|
||||
* and is output before the default color scheme CSS, making it lose in specificity.
|
||||
*
|
||||
* To prevent this, we disable CSS concatenation for color schemes.
|
||||
|
||||
* @param boolean $do_concat Whether to concat the CSS file.
|
||||
* @param string $handle The file handle.
|
||||
* @return boolean
|
||||
*/
|
||||
public function disable_css_concat_for_color_schemes( $do_concat, $handle ) {
|
||||
if ( $handle === 'colors' ) {
|
||||
return false;
|
||||
}
|
||||
return $do_concat;
|
||||
}
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Menu file.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
require_once __DIR__ . '/class-base-admin-menu.php';
|
||||
|
||||
/**
|
||||
* Class Admin_Menu.
|
||||
*/
|
||||
class Admin_Menu extends Base_Admin_Menu {
|
||||
|
||||
/**
|
||||
* Create the desired menu output.
|
||||
*/
|
||||
public function reregister_menu_items() {
|
||||
$this->add_appearance_menu();
|
||||
$this->add_plugins_menu();
|
||||
$this->add_users_menu();
|
||||
|
||||
// Remove Links Manager menu since its usage is discouraged. https://github.com/Automattic/wp-calypso/issues/51188.
|
||||
// @see https://core.trac.wordpress.org/ticket/21307#comment:73.
|
||||
if ( $this->should_disable_links_manager() ) {
|
||||
remove_menu_page( 'link-manager.php' );
|
||||
}
|
||||
|
||||
ksort( $GLOBALS['menu'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred view for the given screen.
|
||||
*
|
||||
* @param string $screen Screen identifier.
|
||||
* @param bool $fallback_global_preference (Optional) Whether the global preference for all screens should be used
|
||||
* as fallback if there is no specific preference for the given screen.
|
||||
* Default: true.
|
||||
* @return string
|
||||
*/
|
||||
public function get_preferred_view( $screen, $fallback_global_preference = true ) {
|
||||
$force_default_view = in_array( $screen, array( 'users.php', 'options-general.php' ), true );
|
||||
$use_wp_admin = $this->use_wp_admin_interface();
|
||||
|
||||
// When no preferred view has been set for "Users > All Users" or "Settings > General", keep the previous
|
||||
// behavior that forced the default view regardless of the global preference.
|
||||
// This behavior is overriden by the wpcom_admin_interface option when it is set to wp-admin.
|
||||
if ( ! $use_wp_admin && $fallback_global_preference && $force_default_view ) {
|
||||
$preferred_view = parent::get_preferred_view( $screen, false );
|
||||
if ( self::UNKNOWN_VIEW === $preferred_view ) {
|
||||
return self::DEFAULT_VIEW;
|
||||
}
|
||||
return $preferred_view;
|
||||
}
|
||||
|
||||
return parent::get_preferred_view( $screen, $fallback_global_preference );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Links Manager is being used.
|
||||
*/
|
||||
public function should_disable_links_manager() {
|
||||
// The max ID number of the auto-generated links.
|
||||
// See /wp-content/mu-plugins/wpcom-wp-install-defaults.php in WP.com.
|
||||
$max_default_id = 10;
|
||||
|
||||
// We are only checking the latest entry link_id so are limiting the query to 1.
|
||||
$link_manager_links = get_bookmarks(
|
||||
array(
|
||||
'orderby' => 'link_id',
|
||||
'order' => 'DESC',
|
||||
'limit' => 1,
|
||||
'hide_invisible' => 0,
|
||||
)
|
||||
);
|
||||
|
||||
// Ordered links by ID descending, check if the first ID is more than $max_default_id.
|
||||
if ( is_countable( $link_manager_links ) && count( $link_manager_links ) > 0 && $link_manager_links[0]->link_id > $max_default_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Appearance menu.
|
||||
*
|
||||
* @return string The Customizer URL.
|
||||
*/
|
||||
public function add_appearance_menu() {
|
||||
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
|
||||
$default_customize_slug = add_query_arg( 'return', rawurlencode( remove_query_arg( wp_removable_query_args(), $request_uri ) ), 'customize.php' );
|
||||
$default_customize_header_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $default_customize_slug );
|
||||
// TODO: Remove WPCom_Theme_Customizer::modify_header_menu_links() and WPcom_Custom_Header::modify_admin_menu_links().
|
||||
$default_customize_header_slug_2 = admin_url( 'themes.php?page=custom-header' );
|
||||
$default_customize_background_slug_1 = add_query_arg( array( 'autofocus' => array( 'control' => 'background_image' ) ), $default_customize_slug );
|
||||
// TODO: Remove Colors_Manager::modify_header_menu_links() and Colors_Manager_Common::modify_header_menu_links().
|
||||
$default_customize_background_slug_2 = add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), admin_url( 'customize.php' ) );
|
||||
|
||||
if ( $this->is_api_request ) {
|
||||
// In case this is an api request we will have to add the 'return' querystring via JS.
|
||||
$customize_url = 'customize.php';
|
||||
} else {
|
||||
$customize_url = $default_customize_slug;
|
||||
}
|
||||
|
||||
$submenus_to_update = array(
|
||||
$default_customize_slug => $customize_url,
|
||||
$default_customize_header_slug_1 => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ),
|
||||
$default_customize_header_slug_2 => add_query_arg( array( 'autofocus' => array( 'control' => 'header_image' ) ), $customize_url ),
|
||||
$default_customize_background_slug_1 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ),
|
||||
$default_customize_background_slug_2 => add_query_arg( array( 'autofocus' => array( 'section' => 'colors_manager_tool' ) ), $customize_url ),
|
||||
);
|
||||
|
||||
if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'themes.php' ) ) {
|
||||
$submenus_to_update['themes.php'] = 'https://wordpress.com/themes/' . $this->domain;
|
||||
}
|
||||
|
||||
$this->update_submenus( 'themes.php', $submenus_to_update );
|
||||
|
||||
$this->hide_submenu_page( 'themes.php', 'custom-header' );
|
||||
$this->hide_submenu_page( 'themes.php', 'custom-background' );
|
||||
|
||||
return $customize_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Plugins menu.
|
||||
*/
|
||||
public function add_plugins_menu() {
|
||||
if ( self::CLASSIC_VIEW === $this->get_preferred_view( 'plugins.php' ) ) {
|
||||
return;
|
||||
}
|
||||
$this->hide_submenu_page( 'plugins.php', 'plugin-install.php' );
|
||||
$this->hide_submenu_page( 'plugins.php', 'plugin-editor.php' );
|
||||
|
||||
$this->update_menu( 'plugins.php', 'https://wordpress.com/plugins/' . $this->domain );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Users menu.
|
||||
*/
|
||||
public function add_users_menu() {
|
||||
$submenus_to_update = array(
|
||||
'profile.php' => 'https://wordpress.com/me',
|
||||
);
|
||||
|
||||
if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'users.php' ) ) {
|
||||
$submenus_to_update['users.php'] = 'https://wordpress.com/people/team/' . $this->domain;
|
||||
$submenus_to_update['user-new.php'] = 'https://wordpress.com/people/new/' . $this->domain;
|
||||
}
|
||||
|
||||
$slug = current_user_can( 'list_users' ) ? 'users.php' : 'profile.php';
|
||||
$this->update_submenus( $slug, $submenus_to_update );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the upsell nudge directly in the admin menu.
|
||||
*
|
||||
* This renders server-side via the `adminmenu` hook to avoid the layout
|
||||
* shift caused by the previous AJAX-based approach.
|
||||
*/
|
||||
public function render_upsell_nudge() {
|
||||
// Skip if jetpack-mu-wpcom is already rendering the upsell banner.
|
||||
if ( has_action( 'adminmenu', 'wpcom_add_sidebar_notice_menu_page' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** This action is already documented in \Automattic\Jetpack\JITMS\JITM */
|
||||
if ( ! apply_filters( 'jetpack_just_in_time_msgs', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nudge = $this->get_upsell_nudge();
|
||||
if ( ! $nudge ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$link = $nudge['link'];
|
||||
if ( str_starts_with( $link, '/' ) ) {
|
||||
$link = 'https://wordpress.com' . $link;
|
||||
}
|
||||
?>
|
||||
<li class="wp-not-current-submenu menu-top menu-icon-generic toplevel_page_site-notices" id="toplevel_page_site-notices">
|
||||
<a href="<?php echo esc_url( $link ); ?>" class="wp-not-current-submenu menu-top menu-icon-generic toplevel_page_site-notices">
|
||||
<div class="wp-menu-arrow">
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="wp-menu-image dashicons-before dashicons-admin-generic" aria-hidden="true"><br></div>
|
||||
<div class="wp-menu-name">
|
||||
<div class="upsell_banner">
|
||||
<div class="banner__info">
|
||||
<div class="banner__title">
|
||||
<?php echo wp_kses( $nudge['content'], array() ); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="banner__action">
|
||||
<button type="button" class="button">
|
||||
<?php echo wp_kses( $nudge['cta'], array() ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php if ( $nudge['dismissible'] ) : ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" data-feature_class="<?php echo esc_attr( $nudge['feature_class'] ); ?>" data-feature_id="<?php echo esc_attr( $nudge['id'] ); ?>" viewBox="0 0 24 24" class="gridicon gridicons-cross dismissible-card__close-icon" height="24" width="24"><g><path d="M18.36 19.78L12 13.41l-6.36 6.37-1.42-1.42L10.59 12 4.22 5.64l1.42-1.42L12 10.59l6.36-6.36 1.41 1.41L13.41 12l6.36 6.36z"></path></g></svg>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<script>
|
||||
( function ( el ) {
|
||||
if ( el && el.parentNode ) {
|
||||
el.parentNode.prepend( el );
|
||||
}
|
||||
} )( document.getElementById( 'toplevel_page_site-notices' ) );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first available upsell nudge.
|
||||
* Needs to be implemented separately for each child menu class.
|
||||
* Empty by default.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_upsell_nudge() {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/**
|
||||
* Atomic Admin Menu file.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Connection\Client;
|
||||
use Automattic\Jetpack\JITMS\JITM;
|
||||
use Automattic\Jetpack\Modules;
|
||||
|
||||
require_once __DIR__ . '/class-admin-menu.php';
|
||||
|
||||
/**
|
||||
* Class Atomic_Admin_Menu.
|
||||
*/
|
||||
class Atomic_Admin_Menu extends Admin_Menu {
|
||||
|
||||
/**
|
||||
* Atomic_Admin_Menu constructor.
|
||||
*/
|
||||
protected function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'dequeue_scripts' ), 20 );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'dequeue_scripts' ), 20 );
|
||||
add_action( 'wp_ajax_sidebar_state', array( $this, 'ajax_sidebar_state' ) );
|
||||
add_action( 'wp_ajax_jitm_dismiss', array( $this, 'wp_ajax_jitm_dismiss' ) );
|
||||
add_action( 'adminmenu', array( $this, 'render_upsell_nudge' ), 100 );
|
||||
|
||||
if ( ! $this->is_api_request ) {
|
||||
add_filter( 'submenu_file', array( $this, 'override_the_theme_installer' ), 10, 2 );
|
||||
}
|
||||
|
||||
add_action(
|
||||
'admin_menu',
|
||||
function () {
|
||||
remove_action( 'admin_menu', 'gutenberg_menu', 9 );
|
||||
},
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dequeues unnecessary scripts.
|
||||
*/
|
||||
public function dequeue_scripts() {
|
||||
wp_dequeue_script( 'a8c_wpcom_masterbar_overrides' ); // Initially loaded in modules/masterbar/masterbar/class-masterbar.php.
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the current locale is right-to-left (RTL).
|
||||
*
|
||||
* Performs the check against the current locale set on the WordPress.com's account settings.
|
||||
* See `Masterbar::__construct` in `modules/masterbar/masterbar/class-masterbar.php`.
|
||||
*/
|
||||
public function is_rtl() {
|
||||
return get_user_option( 'jetpack_wpcom_is_rtl' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the desired menu output.
|
||||
*/
|
||||
public function reregister_menu_items() {
|
||||
parent::reregister_menu_items();
|
||||
|
||||
$this->remove_gutenberg_menu();
|
||||
|
||||
// Not needed outside of wp-admin.
|
||||
if ( ! $this->is_api_request ) {
|
||||
$this->add_new_site_link();
|
||||
}
|
||||
|
||||
ksort( $GLOBALS['menu'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred view for the given screen.
|
||||
*
|
||||
* @param string $screen Screen identifier.
|
||||
* @param bool $fallback_global_preference (Optional) Whether the global preference for all screens should be used
|
||||
* as fallback if there is no specific preference for the given screen.
|
||||
* Default: true.
|
||||
* @return string
|
||||
*/
|
||||
public function get_preferred_view( $screen, $fallback_global_preference = true ) {
|
||||
|
||||
// Export on Atomic sites are always managed on WP Admin.
|
||||
if ( in_array( $screen, array( 'export.php' ), true ) ) {
|
||||
return self::CLASSIC_VIEW;
|
||||
}
|
||||
|
||||
/**
|
||||
* When Jetpack SSO is disabled, we need to force Calypso because it might create confusion to be redirected to WP-Admin.
|
||||
* Furthermore, because we don't display the quick switcher, users having an WP-Admin interface by default won't be able to go back to the Calyso version.
|
||||
*/
|
||||
if ( ! ( new Modules() )->is_active( 'sso' ) ) {
|
||||
return self::DEFAULT_VIEW;
|
||||
}
|
||||
|
||||
return parent::get_preferred_view( $screen, $fallback_global_preference );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the appearance menu.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function add_appearance_menu() {
|
||||
$customize_url = parent::add_appearance_menu();
|
||||
$should_display_additional_css = current_user_can( 'customize' ) && ! wp_is_block_theme();
|
||||
|
||||
if ( ! $should_display_additional_css ) {
|
||||
return $customize_url;
|
||||
}
|
||||
|
||||
$customize_custom_css_url = add_query_arg( array( 'autofocus' => array( 'section' => 'custom_css' ) ), $customize_url );
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_submenu_page( 'themes.php', esc_attr__( 'Additional CSS', 'jetpack-masterbar' ), __( 'Additional CSS', 'jetpack-masterbar' ), 'customize', esc_url( $customize_custom_css_url ), null, 20 );
|
||||
|
||||
return $customize_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Users menu.
|
||||
*/
|
||||
public function add_users_menu() {
|
||||
$slug = current_user_can( 'list_users' ) ? 'users.php' : 'profile.php';
|
||||
if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'users.php' ) ) {
|
||||
$submenus_to_update = array(
|
||||
'users.php' => 'https://wordpress.com/people/team/' . $this->domain,
|
||||
);
|
||||
$this->update_submenus( $slug, $submenus_to_update );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Plugins menu.
|
||||
*/
|
||||
public function add_plugins_menu() {
|
||||
|
||||
global $submenu;
|
||||
|
||||
// Calypso plugins screens link.
|
||||
$plugins_slug = 'https://wordpress.com/plugins/' . $this->domain;
|
||||
|
||||
// Link to the Marketplace from Plugins > Add New on Atomic sites where the wpcom_admin_interface option is set to wp-admin.
|
||||
if ( self::CLASSIC_VIEW === $this->get_preferred_view( 'plugins.php' ) ) {
|
||||
$submenus_to_update = array( 'plugin-install.php' => $plugins_slug );
|
||||
$this->update_submenus( 'plugins.php', $submenus_to_update );
|
||||
return;
|
||||
}
|
||||
|
||||
// Link to the Marketplace on sites that can't manage plugins.
|
||||
if (
|
||||
function_exists( 'wpcom_site_has_feature' ) &&
|
||||
! wpcom_site_has_feature( \WPCOM_Features::MANAGE_PLUGINS )
|
||||
) {
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_menu_page( __( 'Plugins', 'jetpack-masterbar' ), __( 'Plugins', 'jetpack-masterbar' ), 'manage_options', $plugins_slug, null, 'dashicons-admin-plugins', 65 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $submenu['plugins.php'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugins_submenu = $submenu['plugins.php'];
|
||||
|
||||
// Move "Add New" plugin submenu to the top position.
|
||||
foreach ( $plugins_submenu as $submenu_key => $submenu_keys ) {
|
||||
if ( 'plugin-install.php' === $submenu_keys[2] ) {
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$submenu['plugins.php'] = array( $submenu_key => $plugins_submenu[ $submenu_key ] ) + $plugins_submenu;
|
||||
}
|
||||
}
|
||||
|
||||
$submenus_to_update = array( 'plugin-install.php' => $plugins_slug );
|
||||
|
||||
$this->update_submenus( 'plugins.php', $submenus_to_update );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom element class for Site Switcher menu item.
|
||||
*
|
||||
* @param array $menu Associative array of administration menu items.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function set_browse_sites_link_class( array $menu ) {
|
||||
foreach ( $menu as $key => $menu_item ) {
|
||||
if ( 'site-switcher' !== $menu_item[3] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$menu[ $key ][4] = add_cssclass( 'site-switcher', $menu_item[4] );
|
||||
break;
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a link to the menu to create a new site.
|
||||
*/
|
||||
public function add_new_site_link() {
|
||||
$site_count = get_user_option( 'wpcom_site_count' );
|
||||
if ( $site_count && $site_count > 1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_menu_page( __( 'Add New Site', 'jetpack-masterbar' ), __( 'Add New Site', 'jetpack-masterbar' ), 'read', 'https://wordpress.com/start?ref=calypso-sidebar', null, 'dashicons-plus-alt' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first available upsell nudge.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_upsell_nudge() {
|
||||
$jitm = JITM::get_instance();
|
||||
$message_path = 'calypso:sites:sidebar_notice';
|
||||
$message = $jitm->get_messages( $message_path, array( 'message_path' => $message_path ), false );
|
||||
|
||||
if ( isset( $message[0] ) ) {
|
||||
$message = $message[0];
|
||||
return array(
|
||||
'content' => $message->content->message,
|
||||
'cta' => $message->CTA->message, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
'link' => $message->CTA->link, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
'tracks_impression_event_name' => $message->tracks->display->name,
|
||||
'tracks_impression_cta_name' => $message->tracks->display->props->cta_name,
|
||||
'tracks_click_event_name' => $message->tracks->click->name,
|
||||
'tracks_click_cta_name' => $message->tracks->click->props->cta_name,
|
||||
'dismissible' => $message->is_dismissible,
|
||||
'feature_class' => $message->feature_class,
|
||||
'id' => $message->id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the global submenu_file for theme-install.php page so the WP Admin menu item gets highlighted correctly.
|
||||
*
|
||||
* @param string $submenu_file The current pages $submenu_file global variable value.
|
||||
* @return string | null
|
||||
*/
|
||||
public function override_the_theme_installer( $submenu_file ) {
|
||||
global $pagenow;
|
||||
|
||||
if ( 'themes.php' === $submenu_file && 'theme-install.php' === $pagenow ) {
|
||||
return null;
|
||||
}
|
||||
return $submenu_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Also remove the Gutenberg plugin menu.
|
||||
*/
|
||||
public function remove_gutenberg_menu() {
|
||||
// Always remove the Gutenberg menu.
|
||||
remove_menu_page( 'gutenberg' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the sidebar state ( expanded / collapsed ) via an ajax request.
|
||||
*/
|
||||
public function ajax_sidebar_state() {
|
||||
$expanded = isset( $_REQUEST['expanded'] ) ? filter_var( wp_unslash( $_REQUEST['expanded'] ), FILTER_VALIDATE_BOOLEAN ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
Client::wpcom_json_api_request_as_user(
|
||||
'/me/preferences',
|
||||
'2',
|
||||
array(
|
||||
'method' => 'POST',
|
||||
),
|
||||
array( 'calypso_preferences' => (object) array( 'sidebarCollapsed' => ! $expanded ) ),
|
||||
'wpcom'
|
||||
);
|
||||
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ajax requests to dismiss a just-in-time-message
|
||||
*/
|
||||
public function wp_ajax_jitm_dismiss() {
|
||||
check_ajax_referer( 'jitm_dismiss' );
|
||||
$jitm = \Automattic\Jetpack\JITMS\JITM::get_instance();
|
||||
if ( isset( $_REQUEST['id'] ) && isset( $_REQUEST['feature_class'] ) ) {
|
||||
$jitm->dismiss( sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ), sanitize_text_field( wp_unslash( $_REQUEST['feature_class'] ) ) );
|
||||
}
|
||||
wp_die();
|
||||
}
|
||||
}
|
||||
+748
@@ -0,0 +1,748 @@
|
||||
<?php
|
||||
/**
|
||||
* Base Admin Menu file.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Assets;
|
||||
use Automattic\Jetpack\Status;
|
||||
|
||||
/**
|
||||
* Class Base_Admin_Menu
|
||||
*/
|
||||
abstract class Base_Admin_Menu {
|
||||
/**
|
||||
* Holds class instances.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $instances;
|
||||
|
||||
/**
|
||||
* Whether the current request is a REST API request.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $is_api_request = false;
|
||||
|
||||
/**
|
||||
* Domain of the current site.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $domain;
|
||||
|
||||
/**
|
||||
* The CSS classes used to hide the submenu items in navigation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HIDE_CSS_CLASS = 'hide-if-js';
|
||||
|
||||
/**
|
||||
* Identifier denoting that the default WordPress.com view should be used for a certain screen.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DEFAULT_VIEW = 'default';
|
||||
|
||||
/**
|
||||
* Identifier denoting that the classic WP Admin view should be used for a certain screen.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const CLASSIC_VIEW = 'classic';
|
||||
|
||||
/**
|
||||
* Identifier denoting no preferred view has been set for a certain screen.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const UNKNOWN_VIEW = 'unknown';
|
||||
|
||||
/**
|
||||
* Base_Admin_Menu constructor.
|
||||
*/
|
||||
protected function __construct() {
|
||||
$this->is_api_request = defined( 'REST_REQUEST' ) && REST_REQUEST || isset( $_SERVER['REQUEST_URI'] ) && str_starts_with( filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/?rest_route=%2Fwpcom%2Fv2%2Fadmin-menu' );
|
||||
$this->domain = ( new Status() )->get_site_suffix();
|
||||
|
||||
add_action( 'admin_menu', array( $this, 'reregister_menu_items' ), 99998 );
|
||||
add_action( 'admin_menu', array( $this, 'hide_parent_of_hidden_submenus' ), 99999 );
|
||||
|
||||
if ( ! $this->is_api_request ) {
|
||||
add_filter( 'admin_menu', array( $this, 'override_svg_icons' ), 99999 );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 11 );
|
||||
add_action( 'in_admin_header', array( $this, 'add_dashboard_switcher' ) );
|
||||
add_action( 'admin_footer', array( $this, 'dashboard_switcher_scripts' ) );
|
||||
add_action( 'admin_menu', array( $this, 'handle_preferred_view' ), 99997 );
|
||||
add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns class instance.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function get_instance() {
|
||||
$class = static::class;
|
||||
|
||||
if ( empty( static::$instances[ $class ] ) ) {
|
||||
// @phan-suppress-next-line PhanTypeInstantiateAbstract -- If someone calls `Admin_Menu_Base::get_instance()` they deserve what they get.
|
||||
static::$instances[ $class ] = new $class();
|
||||
}
|
||||
|
||||
return static::$instances[ $class ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the menu data of the given menu slug.
|
||||
*
|
||||
* @param string $slug Slug of the menu to update.
|
||||
* @param ?string $url New menu URL. Defaults to null.
|
||||
* @param ?string $title New menu title. Defaults to null.
|
||||
* @param ?string $cap New menu capability. Defaults to null.
|
||||
* @param ?string $icon New menu icon. Defaults to null.
|
||||
* @param ?int $position New menu position. Defaults to null.
|
||||
* @return bool Whether the menu has been updated.
|
||||
*/
|
||||
public function update_menu( $slug, $url = null, $title = null, $cap = null, $icon = null, $position = null ) {
|
||||
global $menu, $submenu;
|
||||
|
||||
$menu_item = null;
|
||||
$menu_position = 0;
|
||||
|
||||
foreach ( $menu as $i => $item ) {
|
||||
if ( $slug === $item[2] ) {
|
||||
$menu_item = $item;
|
||||
$menu_position = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $menu_item ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $title ) {
|
||||
$menu_item[0] = $title;
|
||||
$menu_item[3] = esc_attr( $title );
|
||||
}
|
||||
|
||||
if ( $cap ) {
|
||||
$menu_item[1] = $cap;
|
||||
}
|
||||
|
||||
// Change parent slug only if there are no submenus (the slug of the 1st submenu will be used if there are submenus).
|
||||
if ( $url ) {
|
||||
$this->hide_submenu_page( $slug, $slug );
|
||||
|
||||
if ( ! isset( $submenu[ $slug ] ) || ! $this->has_visible_items( $submenu[ $slug ] ) ) {
|
||||
$menu_item[2] = $url;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $icon ) {
|
||||
$menu_item[4] = 'menu-top';
|
||||
$menu_item[6] = $icon;
|
||||
}
|
||||
|
||||
unset( $menu[ $menu_position ] );
|
||||
if ( $position ) {
|
||||
$menu_position = $position;
|
||||
}
|
||||
$this->set_menu_item( $menu_item, $menu_position );
|
||||
|
||||
// Only add submenu when there are other submenu items.
|
||||
if ( $url && isset( $submenu[ $slug ] ) && $this->has_visible_items( $submenu[ $slug ] ) ) {
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_submenu_page( $slug, $menu_item[3], $menu_item[0], $menu_item[1], $url, null, 0 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the submenus of the given menu slug.
|
||||
*
|
||||
* It hides the menu by adding the `hide-if-js` css class and duplicates the submenu with the new slug.
|
||||
*
|
||||
* @param string $slug Menu slug.
|
||||
* @param array $submenus_to_update Array of new submenu slugs.
|
||||
*/
|
||||
public function update_submenus( $slug, $submenus_to_update ) {
|
||||
global $submenu;
|
||||
|
||||
if ( ! isset( $submenu[ $slug ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is needed for cases when the submenus to update have the same new slug.
|
||||
$submenus_to_update = array_filter(
|
||||
$submenus_to_update,
|
||||
static function ( $item, $old_slug ) {
|
||||
return $item !== $old_slug;
|
||||
},
|
||||
ARRAY_FILTER_USE_BOTH
|
||||
);
|
||||
|
||||
/**
|
||||
* Iterate over all submenu items and add the hide the submenus with CSS classes.
|
||||
* This is done separately of the second foreach because the position of the submenu might change.
|
||||
*/
|
||||
foreach ( $submenu[ $slug ] as $index => $item ) {
|
||||
if ( ! array_key_exists( $item[2], $submenus_to_update ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->hide_submenu_element( $index, $slug, $item );
|
||||
}
|
||||
|
||||
$submenu_items = array_values( $submenu[ $slug ] );
|
||||
|
||||
/**
|
||||
* Iterate again over the submenu array. We need a copy of the array because add_submenu_page will add new elements
|
||||
* to submenu array that might cause an infinite loop.
|
||||
*/
|
||||
foreach ( $submenu_items as $i => $submenu_item ) {
|
||||
if ( ! array_key_exists( $submenu_item[2], $submenus_to_update ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
add_submenu_page(
|
||||
$slug,
|
||||
$submenu_item[3] ?? '',
|
||||
$submenu_item[0] ?? '',
|
||||
$submenu_item[1] ?? 'read',
|
||||
$submenus_to_update[ $submenu_item[2] ],
|
||||
null, // @phan-suppress-current-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
0 === $i ? 0 : $i + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a menu separator.
|
||||
*
|
||||
* @param int $position The position in the menu order this item should appear.
|
||||
* @param string $cap Optional. The capability required for this menu to be displayed to the user.
|
||||
* Default: 'read'.
|
||||
*/
|
||||
public function add_admin_menu_separator( $position = null, $cap = 'read' ) {
|
||||
$menu_item = array(
|
||||
'', // Menu title (ignored).
|
||||
$cap, // Required capability.
|
||||
wp_unique_id( 'separator-custom-' ), // URL or file (ignored, but must be unique).
|
||||
'', // Page title (ignored).
|
||||
'wp-menu-separator', // CSS class. Identifies this item as a separator.
|
||||
);
|
||||
|
||||
$this->set_menu_item( $menu_item, $position );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues scripts and styles.
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
$assets_base_path = '../../dist/admin-menu/';
|
||||
|
||||
Assets::register_script(
|
||||
'jetpack-admin-menu',
|
||||
$assets_base_path . 'admin-menu.js',
|
||||
__FILE__,
|
||||
array(
|
||||
'enqueue' => true,
|
||||
'css_path' => $assets_base_path . 'admin-menu.css',
|
||||
)
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'jetpack-admin-menu',
|
||||
'jetpackAdminMenu',
|
||||
array(
|
||||
'jitmDismissNonce' => wp_create_nonce( 'jitm_dismiss' ),
|
||||
)
|
||||
);
|
||||
|
||||
$this->configure_colors_for_rtl_stylesheets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the core colors stylesheets as RTL depending on the value from the environment.
|
||||
* This fixes a core issue where the extra RTL data is not added to the colors stylesheet.
|
||||
* https://core.trac.wordpress.org/ticket/53090
|
||||
*/
|
||||
public function configure_colors_for_rtl_stylesheets() {
|
||||
wp_style_add_data( 'colors', 'rtl', $this->is_rtl() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the submenu page based on slug and return the item that was hidden.
|
||||
*
|
||||
* Instead of actually removing the submenu item, a safer approach is to hide it and filter it in the API response.
|
||||
* In this manner we'll avoid breaking third-party plugins depending on items that no longer exist.
|
||||
*
|
||||
* A false|array value is returned to be consistent with remove_submenu_page() function
|
||||
*
|
||||
* @param string $menu_slug The parent menu slug.
|
||||
* @param string $submenu_slug The submenu slug that should be hidden.
|
||||
* @return false|array
|
||||
*/
|
||||
public function hide_submenu_page( $menu_slug, $submenu_slug ) {
|
||||
global $submenu;
|
||||
|
||||
if ( ! isset( $submenu[ $menu_slug ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $submenu[ $menu_slug ] as $i => $item ) {
|
||||
if ( $submenu_slug !== $item[2] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->hide_submenu_element( $i, $menu_slug, $item );
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the hide-if-js CSS class to a submenu item.
|
||||
*
|
||||
* @param int $index The position of a submenu item in the submenu array.
|
||||
* @param string $parent_slug The parent slug.
|
||||
* @param array $item The submenu item.
|
||||
*/
|
||||
public function hide_submenu_element( $index, $parent_slug, $item ) {
|
||||
global $submenu;
|
||||
|
||||
$css_classes = empty( $item[4] ) ? self::HIDE_CSS_CLASS : $item[4] . ' ' . self::HIDE_CSS_CLASS;
|
||||
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$submenu [ $parent_slug ][ $index ][4] = $css_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the menu has submenu items visible
|
||||
*
|
||||
* @param array $submenu_items The submenu items.
|
||||
* @return bool
|
||||
*/
|
||||
public function has_visible_items( $submenu_items ) {
|
||||
$visible_items = array_filter(
|
||||
$submenu_items,
|
||||
array( $this, 'is_item_visible' )
|
||||
);
|
||||
|
||||
return array() !== $visible_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of existing submenu items under the supplied parent slug.
|
||||
*
|
||||
* @param string $parent_slug The slug of the parent menu.
|
||||
* @return int The number of submenu items under $parent_slug.
|
||||
*/
|
||||
public function get_submenu_item_count( $parent_slug ) {
|
||||
global $submenu;
|
||||
|
||||
if ( empty( $parent_slug ) || empty( $submenu[ $parent_slug ] ) || ! is_array( $submenu[ $parent_slug ] ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count( $submenu[ $parent_slug ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given menu item in the specified position.
|
||||
*
|
||||
* @param array $item The menu item to add.
|
||||
* @param int $position The position in the menu order this item should appear.
|
||||
*/
|
||||
public function set_menu_item( $item, $position = null ) {
|
||||
global $menu;
|
||||
|
||||
// Handle position (avoids overwriting menu items already populated in the given position).
|
||||
// Inspired by https://core.trac.wordpress.org/browser/trunk/src/wp-admin/menu.php?rev=49837#L160.
|
||||
if ( null === $position ) {
|
||||
$menu[] = $item; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
} elseif ( isset( $menu[ "$position" ] ) ) {
|
||||
$position += (int) substr( base_convert( md5( $item[2] . $item[0] ), 16, 10 ), -5 ) * 0.00001;
|
||||
$menu[ "$position" ] = $item; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
} else {
|
||||
$menu[ $position ] = $item; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the current locale is right-to-left (RTL).
|
||||
*/
|
||||
public function is_rtl() {
|
||||
return is_rtl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for any SVG icons in the menu, and overrides things so that
|
||||
* we can display the icon in the correct colour for the theme.
|
||||
*/
|
||||
public function override_svg_icons() {
|
||||
global $menu;
|
||||
|
||||
$svg_items = array();
|
||||
foreach ( $menu as $idx => $menu_item ) {
|
||||
// Menu items that don't have icons, for example separators, have less than 7
|
||||
// elements, partly because the 7th is the icon. So, if we have less than 7,
|
||||
// let's skip it.
|
||||
if ( ! is_countable( $menu_item ) || ( count( $menu_item ) < 7 ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the hookname contain a URL than sanitize it by replacing invalid characters.
|
||||
if ( str_contains( $menu_item[5], '://' ) ) {
|
||||
$menu_item[5] = preg_replace( '![:/.]+!', '_', $menu_item[5] );
|
||||
}
|
||||
|
||||
$menu_item[5] = preg_replace( '|[^a-zA-Z0-9_:.]|', '-', $menu_item[5] );
|
||||
|
||||
if ( str_starts_with( $menu_item[6], 'data:image/svg+xml' ) && 'site-card' !== $menu_item[3] ) {
|
||||
$svg_items[] = array(
|
||||
'icon' => $menu_item[6],
|
||||
'id' => $menu_item[5],
|
||||
);
|
||||
$menu_item[4] .= ' menu-svg-icon';
|
||||
$menu_item[6] = 'none';
|
||||
}
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$menu[ $idx ] = $menu_item;
|
||||
}
|
||||
if ( $svg_items !== array() ) {
|
||||
$styles = '.menu-svg-icon .wp-menu-image { background-repeat: no-repeat; background-position: center center } ';
|
||||
foreach ( $svg_items as $svg_item ) {
|
||||
$styles .= sprintf( '#%s .wp-menu-image { background-image: url( "%s" ) }', $svg_item['id'], $svg_item['icon'] );
|
||||
}
|
||||
$styles .= '@supports ( mask-image: none ) or ( -webkit-mask-image: none ) { ';
|
||||
$styles .= '.menu-svg-icon .wp-menu-image { background-image: none; } ';
|
||||
$styles .= '.menu-svg-icon .wp-menu-image::before { background-color: currentColor; ';
|
||||
$styles .= 'mask-size: contain; mask-position: center center; mask-repeat: no-repeat; ';
|
||||
$styles .= '-webkit-mask-size: contain; -webkit-mask-position: center center; -webkit-mask-repeat: no-repeat; content:"" } ';
|
||||
foreach ( $svg_items as $svg_item ) {
|
||||
$styles .= sprintf(
|
||||
'#%s .wp-menu-image { background-image: none; } #%s .wp-menu-image::before{ mask-image: url( "%s" ); -webkit-mask-image: url( "%s" ) }',
|
||||
$svg_item['id'],
|
||||
$svg_item['id'],
|
||||
$svg_item['icon'],
|
||||
$svg_item['icon']
|
||||
);
|
||||
}
|
||||
$styles .= '}';
|
||||
|
||||
wp_register_style( 'svg-menu-overrides', false, array(), '20210331' );
|
||||
wp_enqueue_style( 'svg-menu-overrides' );
|
||||
wp_add_inline_style( 'svg-menu-overrides', $styles );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide menus that are unauthorized and don't have visible submenus and cases when the menu has the same slug
|
||||
* as the first submenu item.
|
||||
*
|
||||
* This must be done at the end of menu and submenu manipulation in order to avoid performing this check each time
|
||||
* the submenus are altered.
|
||||
*/
|
||||
public function hide_parent_of_hidden_submenus() {
|
||||
global $menu, $submenu;
|
||||
|
||||
$this->sort_hidden_submenus();
|
||||
|
||||
foreach ( $menu as $menu_index => $menu_item ) {
|
||||
// Skip if the menu doesn't have submenus.
|
||||
if ( empty( $submenu[ $menu_item[2] ] ) || ! is_array( $submenu[ $menu_item[2] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the first submenu item is hidden then we should also hide the parent.
|
||||
// Since the submenus are ordered by self::HIDE_CSS_CLASS (hidden submenus should be at the end of the array),
|
||||
// we can say that if the first submenu is hidden then we should also hide the menu.
|
||||
$first_submenu_item = array_values( $submenu[ $menu_item[2] ] )[0];
|
||||
$is_first_submenu_visible = $this->is_item_visible( $first_submenu_item );
|
||||
|
||||
// if the user does not have access to the menu and the first submenu is hidden, then hide the menu.
|
||||
if ( ! current_user_can( $menu_item[1] ) && ! $is_first_submenu_visible ) {
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$menu[ $menu_index ][4] = self::HIDE_CSS_CLASS;
|
||||
}
|
||||
|
||||
// if the menu has the same slug as the first submenu then hide the submenu.
|
||||
if ( $menu_item[2] === $first_submenu_item[2] && ! $is_first_submenu_visible ) {
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$menu[ $menu_index ][4] = self::HIDE_CSS_CLASS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the hidden submenus by moving them at the end of the array in order to avoid WP using them as default URLs.
|
||||
*
|
||||
* This operation has to be done at the end of submenu manipulation in order to guarantee that the hidden submenus
|
||||
* are at the end of the array.
|
||||
*/
|
||||
public function sort_hidden_submenus() {
|
||||
global $submenu;
|
||||
|
||||
foreach ( $submenu as $menu_slug => $submenu_items ) {
|
||||
if ( ! $submenu_items ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $submenu_items as $submenu_index => $submenu_item ) {
|
||||
if ( $this->is_item_visible( $submenu_item ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset( $submenu[ $menu_slug ][ $submenu_index ] );
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$submenu[ $menu_slug ][] = $submenu_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given item is visible or not in the admin menu.
|
||||
*
|
||||
* @param array $item A menu or submenu array.
|
||||
*/
|
||||
public function is_item_visible( $item ) {
|
||||
return ! isset( $item[4] ) || ! str_contains( $item[4], self::HIDE_CSS_CLASS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dashboard switcher to the list of screen meta links of the current page.
|
||||
*/
|
||||
public function add_dashboard_switcher() {
|
||||
$menu_mappings = require __DIR__ . '/menu-mappings.php';
|
||||
$screen = $this->get_current_screen();
|
||||
|
||||
// Let's show the switcher only in screens that we have a Calypso mapping to switch to.
|
||||
if ( empty( $menu_mappings[ $screen ] ) ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div id="view-link-wrap" class="hide-if-no-js screen-meta-toggle">
|
||||
<button type="button" id="view-link" class="button show-settings" aria-expanded="false"><?php echo esc_html_x( 'View', 'View options to switch between', 'jetpack-masterbar' ); ?></button>
|
||||
</div>
|
||||
<div id="view-wrap" class="screen-options-tab__wrapper hide-if-no-js hidden" tabindex="-1">
|
||||
<div class="screen-options-tab__dropdown" data-testid="screen-options-dropdown">
|
||||
<div class="screen-switcher">
|
||||
<a class="screen-switcher__button" href="<?php echo esc_url( add_query_arg( 'preferred-view', 'default' ) ); ?>" data-view="default">
|
||||
<strong><?php esc_html_e( 'Default view', 'jetpack-masterbar' ); ?></strong>
|
||||
<?php esc_html_e( 'Our WordPress.com redesign for a better experience.', 'jetpack-masterbar' ); ?>
|
||||
</a>
|
||||
<button class="screen-switcher__button" data-view="classic">
|
||||
<strong><?php esc_html_e( 'Classic view', 'jetpack-masterbar' ); ?></strong>
|
||||
<?php esc_html_e( 'The classic WP-Admin WordPress interface.', 'jetpack-masterbar' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a script to append the dashboard switcher to screen meta
|
||||
*/
|
||||
public function dashboard_switcher_scripts() {
|
||||
wp_add_inline_script(
|
||||
'common',
|
||||
"(function( $ ) {
|
||||
$( '#view-link-wrap' ).appendTo( '#screen-meta-links' );
|
||||
|
||||
var viewLink = $( '#view-link' );
|
||||
var viewWrap = $( '#view-wrap' );
|
||||
|
||||
viewLink.on( 'click', function() {
|
||||
viewWrap.toggle();
|
||||
viewLink.toggleClass( 'screen-meta-active' );
|
||||
} );
|
||||
|
||||
$( document ).on( 'mouseup', function( event ) {
|
||||
if ( ! viewLink.is( event.target ) && ! viewWrap.is( event.target ) && viewWrap.has( event.target ).length === 0 ) {
|
||||
viewWrap.hide();
|
||||
viewLink.removeClass( 'screen-meta-active' );
|
||||
}
|
||||
});
|
||||
})( jQuery );"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given view as preferred for the givens screen.
|
||||
*
|
||||
* @param string $screen Screen identifier.
|
||||
* @param string $view Preferred view.
|
||||
*/
|
||||
public function set_preferred_view( $screen, $view ) {
|
||||
remove_filter( 'get_user_option_jetpack_admin_menu_preferred_views', 'wpcom_admin_get_user_option_jetpack' );
|
||||
$preferred_views = $this->get_preferred_views();
|
||||
if ( function_exists( 'wpcom_admin_get_user_option_jetpack' ) ) {
|
||||
add_filter( 'get_user_option_jetpack_admin_menu_preferred_views', 'wpcom_admin_get_user_option_jetpack' );
|
||||
}
|
||||
|
||||
$screen = str_replace( '?post_type=post', '', $screen );
|
||||
$preferred_views[ $screen ] = $view;
|
||||
update_user_option( get_current_user_id(), 'jetpack_admin_menu_preferred_views', $preferred_views );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred views for all screens.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_preferred_views() {
|
||||
$preferred_views = get_user_option( 'jetpack_admin_menu_preferred_views' );
|
||||
|
||||
if ( ! $preferred_views ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $preferred_views;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred view for the given screen.
|
||||
*
|
||||
* @param string $screen Screen identifier.
|
||||
* @param bool $fallback_global_preference (Optional) Whether the global preference for all screens should be used
|
||||
* as fallback if there is no specific preference for the given screen.
|
||||
* Default: true.
|
||||
* @return string
|
||||
*/
|
||||
public function get_preferred_view( $screen, $fallback_global_preference = true ) {
|
||||
$preferred_views = $this->get_preferred_views();
|
||||
|
||||
if ( ! isset( $preferred_views[ $screen ] ) ) {
|
||||
if ( ! $fallback_global_preference ) {
|
||||
return self::UNKNOWN_VIEW;
|
||||
}
|
||||
|
||||
$should_link_to_wp_admin = $this->should_link_to_wp_admin() || $this->use_wp_admin_interface();
|
||||
return $should_link_to_wp_admin ? self::CLASSIC_VIEW : self::DEFAULT_VIEW;
|
||||
}
|
||||
|
||||
return $preferred_views[ $screen ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the identifier of the current screen.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_current_screen() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification
|
||||
global $pagenow;
|
||||
$screen = isset( $_REQUEST['screen'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['screen'] ) ) : $pagenow;
|
||||
if ( isset( $_GET['post_type'] ) ) {
|
||||
$screen = add_query_arg( 'post_type', sanitize_text_field( wp_unslash( $_GET['post_type'] ) ), $screen );
|
||||
}
|
||||
if ( isset( $_GET['taxonomy'] ) ) {
|
||||
$screen = add_query_arg( 'taxonomy', sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ), $screen );
|
||||
}
|
||||
if ( isset( $_GET['page'] ) ) {
|
||||
$screen = add_query_arg( 'page', sanitize_text_field( wp_unslash( $_GET['page'] ) ), $screen );
|
||||
}
|
||||
return $screen;
|
||||
// phpcs:enable WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the preferred view for the current screen.
|
||||
*/
|
||||
public function handle_preferred_view() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification
|
||||
if ( ! isset( $_GET['preferred-view'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification
|
||||
$preferred_view = sanitize_key( $_GET['preferred-view'] );
|
||||
|
||||
if ( ! in_array( $preferred_view, array( self::DEFAULT_VIEW, self::CLASSIC_VIEW ), true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_screen = $this->get_current_screen();
|
||||
|
||||
$this->set_preferred_view( $current_screen, $preferred_view );
|
||||
|
||||
/**
|
||||
* Dashboard Quick switcher action triggered when a user switches to a different view.
|
||||
*
|
||||
* @module masterbar
|
||||
*
|
||||
* @since jetpack-9.9.1
|
||||
*
|
||||
* @param string The current screen of the user.
|
||||
* @param string The preferred view the user selected.
|
||||
*/
|
||||
\do_action( 'jetpack_dashboard_switcher_changed_view', $current_screen, $preferred_view );
|
||||
|
||||
if ( self::DEFAULT_VIEW === $preferred_view ) {
|
||||
// Redirect to default view if that's the newly preferred view.
|
||||
$menu_mappings = require __DIR__ . '/menu-mappings.php';
|
||||
if ( isset( $menu_mappings[ $current_screen ] ) ) {
|
||||
// Using `wp_redirect` intentionally because we're redirecting to Calypso.
|
||||
wp_redirect( $menu_mappings[ $current_screen ] . $this->domain ); // phpcs:ignore WordPress.Security.SafeRedirect
|
||||
exit( 0 );
|
||||
}
|
||||
} elseif ( self::CLASSIC_VIEW === $preferred_view ) {
|
||||
// Removes the `preferred-view` param from the URL to avoid issues with
|
||||
// screens that don't expect this param to be present in the URL.
|
||||
wp_safe_redirect( remove_query_arg( 'preferred-view' ) );
|
||||
exit( 0 );
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the necessary CSS class to the admin body class.
|
||||
*
|
||||
* @param string $admin_body_classes Contains all the admin body classes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function admin_body_class( $admin_body_classes ) {
|
||||
return " is-nav-unification $admin_body_classes ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use wp-admin pages rather than Calypso.
|
||||
*
|
||||
* Options:
|
||||
* false - Calypso (Default).
|
||||
* true - wp-admin.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_link_to_wp_admin() {
|
||||
return get_user_option( 'jetpack_admin_menu_link_destination' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current user has indicated they want to use the wp-admin interface for the given screen.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function use_wp_admin_interface() {
|
||||
return 'wp-admin' === get_option( 'wpcom_admin_interface' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the desired menu output.
|
||||
*/
|
||||
abstract public function reregister_menu_items();
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/**
|
||||
* Quick switcher tracking file.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Current_Plan as Jetpack_Plan;
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
use Automattic\Jetpack\Terms_Of_Service;
|
||||
use Automattic\Jetpack\Tracking;
|
||||
|
||||
/**
|
||||
* Class Dashboard_Switcher_Tracking
|
||||
*/
|
||||
class Dashboard_Switcher_Tracking {
|
||||
|
||||
/**
|
||||
* Jetpack Tracking library will prefix the event name with "jetpack_*" automatically.
|
||||
*/
|
||||
const JETPACK_EVENT_NAME = 'dashboard_quick_switch_link_clicked';
|
||||
|
||||
const WPCOM_EVENT_NAME = 'wpcom_dashboard_quick_switch_link_clicked';
|
||||
/**
|
||||
* Jetpack tracking object.
|
||||
*
|
||||
* @var Tracking
|
||||
*/
|
||||
private $tracking;
|
||||
|
||||
/**
|
||||
* Current site plan.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $plan;
|
||||
|
||||
/**
|
||||
* The wpcom_tracks wrapper function.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
private $wpcom_tracking;
|
||||
|
||||
/**
|
||||
* Dashboard_Switcher_Tracking constructor.
|
||||
*
|
||||
* @param Tracking $tracking Jetpack tracking object.
|
||||
* @param callable $wpcom_tracking A wrapper over wpcom event record.
|
||||
* @param string $plan The current site plan.
|
||||
*/
|
||||
public function __construct( Tracking $tracking, callable $wpcom_tracking, $plan ) {
|
||||
$this->tracking = $tracking;
|
||||
$this->plan = $plan;
|
||||
$this->wpcom_tracking = $wpcom_tracking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an event for the Quick switcher when the user changes it's preferred view.
|
||||
*
|
||||
* @param string $screen The screen page.
|
||||
* @param string $view The new preferred view.
|
||||
*/
|
||||
public function record_switch_event( $screen, $view ) {
|
||||
$event_props = array(
|
||||
'current_page' => $screen,
|
||||
'destination' => $view,
|
||||
'plan' => $this->plan,
|
||||
);
|
||||
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
$event_props['blog_id'] = get_current_blog_id();
|
||||
|
||||
/**
|
||||
* Callable injected in the constructor with the static::wpcom_tracks_record_event() static method.
|
||||
*
|
||||
* @see wpcom_tracks_record_event A static method from this class that executes the actual WPCOM event record.
|
||||
*/
|
||||
$wpcom_tracking = $this->wpcom_tracking;
|
||||
$wpcom_tracking( $event_props );
|
||||
} else {
|
||||
$this->record_jetpack_event( $event_props );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current site plan or 'N/A' when we cannot determine site's plan.
|
||||
*
|
||||
* @todo: This method can be reused as a wrapper over WPCOM and Atomic as way to get site's current plan (display name).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_plan() {
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
if ( class_exists( '\WPCOM_Store_API' ) ) {
|
||||
// @todo: Maybe introduce a wrapper for this since we are duplicating it from WPCOM_Admin_Menu:253
|
||||
$products = \WPCOM_Store_API::get_current_plan( \get_current_blog_id() );
|
||||
if ( ! empty( $products['product_slug'] ) ) {
|
||||
return $products['product_slug'];
|
||||
}
|
||||
}
|
||||
|
||||
return 'N/A'; // maybe we should return free or null? At the moment it's safe to return 'N/A' since we use it only for passing it to the event.
|
||||
}
|
||||
|
||||
// @todo: Maybe introduce a helper for this since we are duplicating it from Atomic_Admin_Menu:240
|
||||
$products = Jetpack_Plan::get();
|
||||
if ( ! empty( $products['product_slug'] ) ) {
|
||||
return $products['product_slug'];
|
||||
}
|
||||
|
||||
return 'N/A'; // maybe we should return free or null? At the moment we use it for passing it to the event.
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the event with Jetpack implementation.
|
||||
*
|
||||
* For Atomic sites we mark the Jetpack ToS option temporary as read.
|
||||
*
|
||||
* @todo Remove the jetpack_options_tos_agreed filter for Atomic sites after the Tracking is properly working for AT sites.
|
||||
*
|
||||
* @param array $event_properties The event properties.
|
||||
*/
|
||||
private function record_jetpack_event( $event_properties ) {
|
||||
$woa = ( new Host() )->is_woa_site();
|
||||
if ( $woa ) {
|
||||
add_filter( 'jetpack_options', array( __CLASS__, 'mark_jetpack_tos_as_read' ), 10, 2 );
|
||||
}
|
||||
|
||||
$this->tracking->record_user_event( self::JETPACK_EVENT_NAME, $event_properties );
|
||||
|
||||
if ( $woa ) {
|
||||
\remove_filter( 'jetpack_options', array( __CLASS__, 'mark_jetpack_tos_as_read' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the WPCOM tracks_record_event.
|
||||
*
|
||||
* @param array $event_props Event props.
|
||||
*/
|
||||
public static function wpcom_tracks_record_event( $event_props ) {
|
||||
require_lib( 'tracks/client' );
|
||||
\tracks_record_event( \wp_get_current_user(), self::WPCOM_EVENT_NAME, $event_props );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tracking product name for the Tracking library.
|
||||
*
|
||||
* The tracking product name is used by the Tracking as a prefix for the event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_jetpack_tracking_product() {
|
||||
return ( new Host() )->is_woa_site() ? 'atomic' : 'jetpack';
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the Jetpack ToS as read for Atomic Sites.
|
||||
*
|
||||
* @param mixed $option_value The value of the Jetpack option.
|
||||
* @param string $option_name The name of the Jetpack option.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mark_jetpack_tos_as_read( $option_value, $option_name ) {
|
||||
if ( Terms_Of_Service::OPTION_NAME === $option_name ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $option_value;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Domain-only sites Admin Menu file.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Domain_Only_Admin_Menu.
|
||||
*/
|
||||
class Domain_Only_Admin_Menu extends Base_Admin_Menu {
|
||||
/**
|
||||
* The `WPCOM_Email_Subscription_Checker` instance used to verify if a site has an email subscription.
|
||||
*
|
||||
* @var WPCOM_Email_Subscription_Checker
|
||||
*/
|
||||
private $email_subscriptions_checker;
|
||||
|
||||
/**
|
||||
* Constructor that lets us pass in a WPCOM_Email_Subscription_Checker dependency.
|
||||
*
|
||||
* @param WPCOM_Email_Subscription_Checker $email_subscriptions_checker The WPCOM_Email_Subscription_Checker instance.
|
||||
*/
|
||||
protected function __construct( $email_subscriptions_checker = null ) {
|
||||
parent::__construct();
|
||||
|
||||
$this->email_subscriptions_checker = $email_subscriptions_checker;
|
||||
|
||||
if ( empty( $this->email_subscriptions_checker ) ) {
|
||||
$this->set_email_subscription_checker( new WPCOM_Email_Subscription_Checker() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This setter lets us inject an WPCOM_Email_Subscription_Checker instance.
|
||||
*
|
||||
* @param WPCOM_Email_Subscription_Checker $email_subscriptions_checker An WPCOM_Email_Subscription_Checker instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_email_subscription_checker( $email_subscriptions_checker ) {
|
||||
$this->email_subscriptions_checker = $email_subscriptions_checker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the desired menu output.
|
||||
*/
|
||||
public function reregister_menu_items() {
|
||||
global $menu, $submenu;
|
||||
|
||||
$menu = array(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$submenu = array(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_menu_page( esc_attr__( 'Manage Domain', 'jetpack-masterbar' ), __( 'Manage Domain', 'jetpack-masterbar' ), 'manage_options', 'https://wordpress.com/domains/manage/' . $this->domain . '/edit/' . $this->domain, null, 'dashicons-admin-settings' );
|
||||
|
||||
if ( $this->email_subscriptions_checker->has_email() ) {
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_menu_page( esc_attr__( 'Manage Email', 'jetpack-masterbar' ), __( 'Manage Email', 'jetpack-masterbar' ), 'manage_options', 'https://wordpress.com/email/' . $this->domain . '/manage/' . $this->domain, null, 'dashicons-admin-settings' );
|
||||
}
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_menu_page( esc_attr__( 'Manage Purchases', 'jetpack-masterbar' ), __( 'Manage Purchases', 'jetpack-masterbar' ), 'manage_options', 'https://wordpress.com/purchases/subscriptions/' . $this->domain, null, 'dashicons-cart' );
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_menu_page( esc_attr__( 'My Mailboxes', 'jetpack-masterbar' ), __( 'My Mailboxes', 'jetpack-masterbar' ), 'manage_options', 'https://wordpress.com/mailboxes/' . $this->domain, null, 'dashicons-email' );
|
||||
}
|
||||
}
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/**
|
||||
* WP.com Admin Menu file.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Jetpack_Custom_CSS;
|
||||
use JITM;
|
||||
|
||||
require_once __DIR__ . '/class-admin-menu.php';
|
||||
|
||||
/**
|
||||
* Class WPcom_Admin_Menu.
|
||||
*/
|
||||
class WPcom_Admin_Menu extends Admin_Menu {
|
||||
/**
|
||||
* WPcom_Admin_Menu constructor.
|
||||
*/
|
||||
protected function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_action( 'wp_ajax_sidebar_state', array( $this, 'ajax_sidebar_state' ) );
|
||||
add_action( 'wp_ajax_jitm_dismiss', array( $this, 'wp_ajax_jitm_dismiss' ) );
|
||||
add_action( 'adminmenu', array( $this, 'render_upsell_nudge' ), 100 );
|
||||
add_action( 'admin_init', array( $this, 'sync_sidebar_collapsed_state' ) );
|
||||
add_action( 'admin_menu', array( $this, 'remove_submenus' ), 140 ); // After hookpress hook at 130.
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the desired menu output.
|
||||
*/
|
||||
public function reregister_menu_items() {
|
||||
parent::reregister_menu_items();
|
||||
|
||||
$this->remove_gutenberg_menu();
|
||||
|
||||
// Not needed outside of wp-admin.
|
||||
if ( ! $this->is_api_request ) {
|
||||
$this->add_new_site_link();
|
||||
}
|
||||
|
||||
ksort( $GLOBALS['menu'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred view for the given screen.
|
||||
*
|
||||
* @param string $screen Screen identifier.
|
||||
* @param bool $fallback_global_preference (Optional) Whether the global preference for all screens should be used
|
||||
* as fallback if there is no specific preference for the given screen.
|
||||
* Default: true.
|
||||
* @return string
|
||||
*/
|
||||
public function get_preferred_view( $screen, $fallback_global_preference = true ) {
|
||||
// When no preferred view has been set for Themes, keep the previous behavior that forced the default view
|
||||
// regardless of the global preference.
|
||||
if ( $fallback_global_preference && 'themes.php' === $screen ) {
|
||||
$preferred_view = parent::get_preferred_view( $screen, false );
|
||||
if ( self::UNKNOWN_VIEW === $preferred_view ) {
|
||||
return self::DEFAULT_VIEW;
|
||||
}
|
||||
return $preferred_view;
|
||||
}
|
||||
|
||||
// Plugins on Simple sites are always managed on Calypso.
|
||||
if ( 'plugins.php' === $screen ) {
|
||||
return self::DEFAULT_VIEW;
|
||||
}
|
||||
|
||||
return parent::get_preferred_view( $screen, $fallback_global_preference );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the number of blogs that the current user has.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_current_user_blog_count() {
|
||||
if ( function_exists( '\get_blog_count_for_user' ) ) {
|
||||
return \get_blog_count_for_user( get_current_user_id() );
|
||||
}
|
||||
|
||||
$blogs = get_blogs_of_user( get_current_user_id() );
|
||||
return is_countable( $blogs ) ? count( $blogs ) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom element class for Site Switcher menu item.
|
||||
*
|
||||
* @param array $menu Associative array of administration menu items.
|
||||
* @return array
|
||||
*/
|
||||
public function set_browse_sites_link_class( array $menu ) {
|
||||
foreach ( $menu as $key => $menu_item ) {
|
||||
if ( 'site-switcher' !== $menu_item[3] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$menu[ $key ][4] = add_cssclass( 'site-switcher', $menu_item[4] );
|
||||
break;
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a link to the menu to create a new site.
|
||||
*/
|
||||
public function add_new_site_link() {
|
||||
if ( $this->get_current_user_blog_count() > 1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->add_admin_menu_separator();
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_menu_page( __( 'Add New Site', 'jetpack-masterbar' ), __( 'Add New Site', 'jetpack-masterbar' ), 'read', 'https://wordpress.com/start?ref=calypso-sidebar', null, 'dashicons-plus-alt' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first available upsell nudge.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_upsell_nudge() {
|
||||
require_lib( 'jetpack-jitm/jitm-engine' );
|
||||
$jitm_engine = new JITM\Engine();
|
||||
|
||||
$message_path = 'calypso:sites:sidebar_notice';
|
||||
$current_user = wp_get_current_user();
|
||||
$user_id = $current_user->ID;
|
||||
$user_roles = implode( ',', $current_user->roles );
|
||||
$query_string = array(
|
||||
'message_path' => $message_path,
|
||||
);
|
||||
|
||||
// Get the top message only.
|
||||
$message = $jitm_engine->get_top_messages( $message_path, $user_id, $user_roles, $query_string );
|
||||
|
||||
if ( isset( $message[0] ) ) {
|
||||
$message = $message[0];
|
||||
return array(
|
||||
'content' => $message->content['message'],
|
||||
'cta' => $message->CTA['message'], // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
'link' => $message->CTA['link'], // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
'tracks_impression_event_name' => $message->tracks['display']['name'] ?? null,
|
||||
'tracks_impression_cta_name' => $message->tracks['display']['props']['cta_name'] ?? null,
|
||||
'tracks_click_event_name' => $message->tracks['click']['name'] ?? null,
|
||||
'tracks_click_cta_name' => $message->tracks['click']['props']['cta_name'] ?? null,
|
||||
'dismissible' => $message->is_dismissible,
|
||||
'feature_class' => $message->feature_class,
|
||||
'id' => $message->id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Appearance menu.
|
||||
*
|
||||
* @return string The Customizer URL.
|
||||
*/
|
||||
public function add_appearance_menu() {
|
||||
$customize_url = parent::add_appearance_menu();
|
||||
|
||||
$this->hide_submenu_page( 'themes.php', 'theme-editor.php' );
|
||||
|
||||
$user_can_customize = current_user_can( 'customize' );
|
||||
|
||||
if ( wp_is_block_theme() ) {
|
||||
add_filter( 'safecss_is_freetrial', '__return_false', PHP_INT_MAX );
|
||||
if ( class_exists( 'Jetpack_Custom_CSS' ) && empty( Jetpack_Custom_CSS::get_css() ) ) {
|
||||
$user_can_customize = false;
|
||||
}
|
||||
remove_filter( 'safecss_is_freetrial', '__return_false', PHP_INT_MAX );
|
||||
}
|
||||
|
||||
if ( $user_can_customize ) {
|
||||
$customize_custom_css_url = add_query_arg( array( 'autofocus' => array( 'section' => 'jetpack_custom_css' ) ), $customize_url );
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_submenu_page( 'themes.php', esc_attr__( 'Additional CSS', 'jetpack-masterbar' ), __( 'Additional CSS', 'jetpack-masterbar' ), 'customize', esc_url( $customize_custom_css_url ), null, 20 );
|
||||
}
|
||||
|
||||
return $customize_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Users menu.
|
||||
*/
|
||||
public function add_users_menu() {
|
||||
$submenus_to_update = array(
|
||||
'grofiles-editor' => 'https://wordpress.com/me',
|
||||
'grofiles-user-settings' => 'https://wordpress.com/me/account',
|
||||
);
|
||||
|
||||
if ( self::DEFAULT_VIEW === $this->get_preferred_view( 'users.php' ) ) {
|
||||
$submenus_to_update['users.php'] = 'https://wordpress.com/people/team/' . $this->domain;
|
||||
}
|
||||
|
||||
$slug = current_user_can( 'list_users' ) ? 'users.php' : 'profile.php';
|
||||
$this->update_submenus( $slug, $submenus_to_update );
|
||||
// @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539.
|
||||
add_submenu_page( 'users.php', esc_attr__( 'Add New User', 'jetpack-masterbar' ), __( 'Add New User', 'jetpack-masterbar' ), 'promote_users', 'https://wordpress.com/people/new/' . $this->domain, null, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Also remove the Gutenberg plugin menu.
|
||||
*/
|
||||
public function remove_gutenberg_menu() {
|
||||
// Always remove the Gutenberg menu.
|
||||
remove_menu_page( 'gutenberg' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use wp-admin pages rather than Calypso.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_link_to_wp_admin() {
|
||||
$result = false; // Calypso.
|
||||
|
||||
$user_attribute = get_user_attribute( get_current_user_id(), 'calypso_preferences' );
|
||||
if ( ! empty( $user_attribute['linkDestination'] ) ) {
|
||||
$result = $user_attribute['linkDestination'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the sidebar state ( expanded / collapsed ) via an ajax request.
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
public function ajax_sidebar_state() {
|
||||
$expanded = isset( $_REQUEST['expanded'] ) ? filter_var( wp_unslash( $_REQUEST['expanded'] ), FILTER_VALIDATE_BOOLEAN ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$user_id = get_current_user_id();
|
||||
$preferences = get_user_attribute( $user_id, 'calypso_preferences' );
|
||||
if ( empty( $preferences ) ) {
|
||||
$preferences = array();
|
||||
}
|
||||
|
||||
$value = array_merge( (array) $preferences, array( 'sidebarCollapsed' => ! $expanded ) );
|
||||
$value = array_filter(
|
||||
$value,
|
||||
function ( $preference ) {
|
||||
return null !== $preference;
|
||||
}
|
||||
);
|
||||
|
||||
update_user_attribute( $user_id, 'calypso_preferences', $value );
|
||||
|
||||
die( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ajax requests to dismiss a just-in-time-message
|
||||
*/
|
||||
public function wp_ajax_jitm_dismiss() {
|
||||
check_ajax_referer( 'jitm_dismiss' );
|
||||
require_lib( 'jetpack-jitm/jitm-engine' );
|
||||
if ( isset( $_REQUEST['id'] ) && isset( $_REQUEST['feature_class'] ) ) {
|
||||
JITM\Engine::dismiss( sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ), sanitize_text_field( wp_unslash( $_REQUEST['feature_class'] ) ) );
|
||||
}
|
||||
wp_die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs the sidebar collapsed state from Calypso Preferences.
|
||||
*/
|
||||
public function sync_sidebar_collapsed_state() {
|
||||
$calypso_preferences = get_user_attribute( get_current_user_id(), 'calypso_preferences' );
|
||||
|
||||
$sidebar_collapsed = $calypso_preferences['sidebarCollapsed'] ?? false;
|
||||
|
||||
// Read the current stored setting and convert it to boolean in order to be able to compare the values later.
|
||||
$current_sidebar_collapsed_setting = 'f' === get_user_setting( 'mfold' );
|
||||
|
||||
// Only set the setting if the value differs, as `set_user_setting` always updates at least the timestamp
|
||||
// which leads to unnecessary user meta cache purging on all wp-admin screen requests.
|
||||
if ( $current_sidebar_collapsed_setting !== $sidebar_collapsed ) {
|
||||
set_user_setting( 'mfold', $sidebar_collapsed ? 'f' : 'o' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes unwanted submenu items.
|
||||
*
|
||||
* These submenus are added across wp-content and should be removed together with these function calls.
|
||||
*/
|
||||
public function remove_submenus() {
|
||||
global $_registered_pages;
|
||||
|
||||
remove_submenu_page( 'index.php', 'akismet-stats' );
|
||||
remove_submenu_page( 'index.php', 'my-comments' );
|
||||
remove_submenu_page( 'index.php', 'stats' );
|
||||
remove_submenu_page( 'index.php', 'subscriptions' );
|
||||
|
||||
/* @see https://github.com/Automattic/wp-calypso/issues/49210 */
|
||||
remove_submenu_page( 'index.php', 'my-blogs' );
|
||||
$_registered_pages['admin_page_my-blogs'] = true; // phpcs:ignore
|
||||
|
||||
remove_submenu_page( 'themes.php', 'customize.php?autofocus[panel]=amp_panel&return=' . rawurlencode( admin_url() ) );
|
||||
|
||||
remove_submenu_page( 'users.php', 'wpcom-invite-users' ); // Wpcom_Invite_Users::action_admin_menu.
|
||||
|
||||
remove_submenu_page( 'options-general.php', 'adcontrol' );
|
||||
|
||||
// Remove menu item but continue allowing access.
|
||||
foreach ( array( 'openidserver', 'webhooks' ) as $page_slug ) {
|
||||
remove_submenu_page( 'options-general.php', $page_slug );
|
||||
$_registered_pages[ 'admin_page_' . $page_slug ] = true; // phpcs:ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* A class that checks for the existence of email subscriptions for a user.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
/**
|
||||
* WPCOM_Email_Subscription_Checker
|
||||
*/
|
||||
class WPCOM_Email_Subscription_Checker {
|
||||
|
||||
/**
|
||||
* Checks if a user's site has an email subscription
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_email() {
|
||||
if ( ! function_exists( 'wpcom_site_has_feature' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return wpcom_site_has_feature( \WPCOM_Features::EMAIL_SUBSCRIPTION );
|
||||
}
|
||||
}
|
||||
+358
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
/**
|
||||
* Array that contains all the core dashicons.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
return array(
|
||||
'dashicons-admin-appearance' => true,
|
||||
'dashicons-admin-collapse' => true,
|
||||
'dashicons-admin-comments' => true,
|
||||
'dashicons-admin-customizer' => true,
|
||||
'dashicons-admin-generic' => true,
|
||||
'dashicons-admin-home' => true,
|
||||
'dashicons-admin-links' => true,
|
||||
'dashicons-admin-media' => true,
|
||||
'dashicons-admin-multisite' => true,
|
||||
'dashicons-admin-network' => true,
|
||||
'dashicons-admin-page' => true,
|
||||
'dashicons-admin-plugins' => true,
|
||||
'dashicons-admin-post' => true,
|
||||
'dashicons-admin-settings' => true,
|
||||
'dashicons-admin-site-alt' => true,
|
||||
'dashicons-admin-site-alt2' => true,
|
||||
'dashicons-admin-site-alt3' => true,
|
||||
'dashicons-admin-site' => true,
|
||||
'dashicons-admin-tools' => true,
|
||||
'dashicons-admin-users' => true,
|
||||
'dashicons-airplane' => true,
|
||||
'dashicons-album' => true,
|
||||
'dashicons-align-center' => true,
|
||||
'dashicons-align-full-width' => true,
|
||||
'dashicons-align-left' => true,
|
||||
'dashicons-align-none' => true,
|
||||
'dashicons-align-pull-left' => true,
|
||||
'dashicons-align-pull-right' => true,
|
||||
'dashicons-align-right' => true,
|
||||
'dashicons-align-wide' => true,
|
||||
'dashicons-amazon' => true,
|
||||
'dashicons-analytics' => true,
|
||||
'dashicons-archive' => true,
|
||||
'dashicons-arrow-down-alt' => true,
|
||||
'dashicons-arrow-down-alt2' => true,
|
||||
'dashicons-arrow-down' => true,
|
||||
'dashicons-arrow-left-alt' => true,
|
||||
'dashicons-arrow-left-alt2' => true,
|
||||
'dashicons-arrow-left' => true,
|
||||
'dashicons-arrow-right-alt' => true,
|
||||
'dashicons-arrow-right-alt2' => true,
|
||||
'dashicons-arrow-right' => true,
|
||||
'dashicons-arrow-up-alt' => true,
|
||||
'dashicons-arrow-up-alt2' => true,
|
||||
'dashicons-arrow-up-duplicate' => true,
|
||||
'dashicons-arrow-up' => true,
|
||||
'dashicons-art' => true,
|
||||
'dashicons-awards' => true,
|
||||
'dashicons-backup' => true,
|
||||
'dashicons-bank' => true,
|
||||
'dashicons-beer' => true,
|
||||
'dashicons-bell' => true,
|
||||
'dashicons-block-default' => true,
|
||||
'dashicons-book-alt' => true,
|
||||
'dashicons-book' => true,
|
||||
'dashicons-buddicons-activity' => true,
|
||||
'dashicons-buddicons-bbpress-logo' => true,
|
||||
'dashicons-buddicons-buddypress-logo' => true,
|
||||
'dashicons-buddicons-community' => true,
|
||||
'dashicons-buddicons-forums' => true,
|
||||
'dashicons-buddicons-friends' => true,
|
||||
'dashicons-buddicons-groups' => true,
|
||||
'dashicons-buddicons-pm' => true,
|
||||
'dashicons-buddicons-replies' => true,
|
||||
'dashicons-buddicons-topics' => true,
|
||||
'dashicons-buddicons-tracking' => true,
|
||||
'dashicons-building' => true,
|
||||
'dashicons-businessman' => true,
|
||||
'dashicons-businessperson' => true,
|
||||
'dashicons-businesswoman' => true,
|
||||
'dashicons-button' => true,
|
||||
'dashicons-calculator' => true,
|
||||
'dashicons-calendar-alt' => true,
|
||||
'dashicons-calendar' => true,
|
||||
'dashicons-camera-alt' => true,
|
||||
'dashicons-camera' => true,
|
||||
'dashicons-car' => true,
|
||||
'dashicons-carrot' => true,
|
||||
'dashicons-cart' => true,
|
||||
'dashicons-category' => true,
|
||||
'dashicons-chart-area' => true,
|
||||
'dashicons-chart-bar' => true,
|
||||
'dashicons-chart-line' => true,
|
||||
'dashicons-chart-pie' => true,
|
||||
'dashicons-clipboard' => true,
|
||||
'dashicons-clock' => true,
|
||||
'dashicons-cloud-saved' => true,
|
||||
'dashicons-cloud-upload' => true,
|
||||
'dashicons-cloud' => true,
|
||||
'dashicons-code-standards' => true,
|
||||
'dashicons-coffee' => true,
|
||||
'dashicons-color-picker' => true,
|
||||
'dashicons-columns' => true,
|
||||
'dashicons-controls-back' => true,
|
||||
'dashicons-controls-forward' => true,
|
||||
'dashicons-controls-pause' => true,
|
||||
'dashicons-controls-play' => true,
|
||||
'dashicons-controls-repeat' => true,
|
||||
'dashicons-controls-skipback' => true,
|
||||
'dashicons-controls-skipforward' => true,
|
||||
'dashicons-controls-volumeoff' => true,
|
||||
'dashicons-controls-volumeon' => true,
|
||||
'dashicons-cover-image' => true,
|
||||
'dashicons-dashboard' => true,
|
||||
'dashicons-database-add' => true,
|
||||
'dashicons-database-export' => true,
|
||||
'dashicons-database-import' => true,
|
||||
'dashicons-database-remove' => true,
|
||||
'dashicons-database-view' => true,
|
||||
'dashicons-database' => true,
|
||||
'dashicons-desktop' => true,
|
||||
'dashicons-dismiss' => true,
|
||||
'dashicons-download' => true,
|
||||
'dashicons-drumstick' => true,
|
||||
'dashicons-edit-large' => true,
|
||||
'dashicons-edit-page' => true,
|
||||
'dashicons-edit' => true,
|
||||
'dashicons-editor-aligncenter' => true,
|
||||
'dashicons-editor-alignleft' => true,
|
||||
'dashicons-editor-alignright' => true,
|
||||
'dashicons-editor-bold' => true,
|
||||
'dashicons-editor-break' => true,
|
||||
'dashicons-editor-code-duplicate' => true,
|
||||
'dashicons-editor-code' => true,
|
||||
'dashicons-editor-contract' => true,
|
||||
'dashicons-editor-customchar' => true,
|
||||
'dashicons-editor-expand' => true,
|
||||
'dashicons-editor-help' => true,
|
||||
'dashicons-editor-indent' => true,
|
||||
'dashicons-editor-insertmore' => true,
|
||||
'dashicons-editor-italic' => true,
|
||||
'dashicons-editor-justify' => true,
|
||||
'dashicons-editor-kitchensink' => true,
|
||||
'dashicons-editor-ltr' => true,
|
||||
'dashicons-editor-ol-rtl' => true,
|
||||
'dashicons-editor-ol' => true,
|
||||
'dashicons-editor-outdent' => true,
|
||||
'dashicons-editor-paragraph' => true,
|
||||
'dashicons-editor-paste-text' => true,
|
||||
'dashicons-editor-paste-word' => true,
|
||||
'dashicons-editor-quote' => true,
|
||||
'dashicons-editor-removeformatting' => true,
|
||||
'dashicons-editor-rtl' => true,
|
||||
'dashicons-editor-spellcheck' => true,
|
||||
'dashicons-editor-strikethrough' => true,
|
||||
'dashicons-editor-table' => true,
|
||||
'dashicons-editor-textcolor' => true,
|
||||
'dashicons-editor-ul' => true,
|
||||
'dashicons-editor-underline' => true,
|
||||
'dashicons-editor-unlink' => true,
|
||||
'dashicons-editor-video' => true,
|
||||
'dashicons-ellipsis' => true,
|
||||
'dashicons-email-alt' => true,
|
||||
'dashicons-email-alt2' => true,
|
||||
'dashicons-email' => true,
|
||||
'dashicons-embed-audio' => true,
|
||||
'dashicons-embed-generic' => true,
|
||||
'dashicons-embed-photo' => true,
|
||||
'dashicons-embed-post' => true,
|
||||
'dashicons-embed-video' => true,
|
||||
'dashicons-excerpt-view' => true,
|
||||
'dashicons-exit' => true,
|
||||
'dashicons-external' => true,
|
||||
'dashicons-facebook-alt' => true,
|
||||
'dashicons-facebook' => true,
|
||||
'dashicons-feedback' => true,
|
||||
'dashicons-filter' => true,
|
||||
'dashicons-flag' => true,
|
||||
'dashicons-food' => true,
|
||||
'dashicons-format-aside' => true,
|
||||
'dashicons-format-audio' => true,
|
||||
'dashicons-format-chat' => true,
|
||||
'dashicons-format-gallery' => true,
|
||||
'dashicons-format-image' => true,
|
||||
'dashicons-format-quote' => true,
|
||||
'dashicons-format-status' => true,
|
||||
'dashicons-format-video' => true,
|
||||
'dashicons-forms' => true,
|
||||
'dashicons-fullscreen-alt' => true,
|
||||
'dashicons-fullscreen-exit-alt' => true,
|
||||
'dashicons-games' => true,
|
||||
'dashicons-google' => true,
|
||||
'dashicons-googleplus' => true,
|
||||
'dashicons-grid-view' => true,
|
||||
'dashicons-groups' => true,
|
||||
'dashicons-hammer' => true,
|
||||
'dashicons-heading' => true,
|
||||
'dashicons-heart' => true,
|
||||
'dashicons-hidden' => true,
|
||||
'dashicons-hourglass' => true,
|
||||
'dashicons-html' => true,
|
||||
'dashicons-id-alt' => true,
|
||||
'dashicons-id' => true,
|
||||
'dashicons-image-crop' => true,
|
||||
'dashicons-image-filter' => true,
|
||||
'dashicons-image-flip-horizontal' => true,
|
||||
'dashicons-image-flip-vertical' => true,
|
||||
'dashicons-image-rotate-left' => true,
|
||||
'dashicons-image-rotate-right' => true,
|
||||
'dashicons-image-rotate' => true,
|
||||
'dashicons-images-alt' => true,
|
||||
'dashicons-images-alt2' => true,
|
||||
'dashicons-index-card' => true,
|
||||
'dashicons-info-outline' => true,
|
||||
'dashicons-info' => true,
|
||||
'dashicons-insert-after' => true,
|
||||
'dashicons-insert-before' => true,
|
||||
'dashicons-insert' => true,
|
||||
'dashicons-instagram' => true,
|
||||
'dashicons-laptop' => true,
|
||||
'dashicons-layout' => true,
|
||||
'dashicons-leftright' => true,
|
||||
'dashicons-lightbulb' => true,
|
||||
'dashicons-linkedin' => true,
|
||||
'dashicons-list-view' => true,
|
||||
'dashicons-location-alt' => true,
|
||||
'dashicons-location' => true,
|
||||
'dashicons-lock-duplicate' => true,
|
||||
'dashicons-lock' => true,
|
||||
'dashicons-marker' => true,
|
||||
'dashicons-media-archive' => true,
|
||||
'dashicons-media-audio' => true,
|
||||
'dashicons-media-code' => true,
|
||||
'dashicons-media-default' => true,
|
||||
'dashicons-media-document' => true,
|
||||
'dashicons-media-interactive' => true,
|
||||
'dashicons-media-spreadsheet' => true,
|
||||
'dashicons-media-text' => true,
|
||||
'dashicons-media-video' => true,
|
||||
'dashicons-megaphone' => true,
|
||||
'dashicons-menu-alt' => true,
|
||||
'dashicons-menu-alt2' => true,
|
||||
'dashicons-menu-alt3' => true,
|
||||
'dashicons-menu' => true,
|
||||
'dashicons-microphone' => true,
|
||||
'dashicons-migrate' => true,
|
||||
'dashicons-minus' => true,
|
||||
'dashicons-money-alt' => true,
|
||||
'dashicons-money' => true,
|
||||
'dashicons-move' => true,
|
||||
'dashicons-nametag' => true,
|
||||
'dashicons-networking' => true,
|
||||
'dashicons-no-alt' => true,
|
||||
'dashicons-no' => true,
|
||||
'dashicons-open-folder' => true,
|
||||
'dashicons-palmtree' => true,
|
||||
'dashicons-paperclip' => true,
|
||||
'dashicons-pdf' => true,
|
||||
'dashicons-performance' => true,
|
||||
'dashicons-pets' => true,
|
||||
'dashicons-phone' => true,
|
||||
'dashicons-pinterest' => true,
|
||||
'dashicons-playlist-audio' => true,
|
||||
'dashicons-playlist-video' => true,
|
||||
'dashicons-plugins-checked' => true,
|
||||
'dashicons-plus-alt' => true,
|
||||
'dashicons-plus-alt2' => true,
|
||||
'dashicons-plus' => true,
|
||||
'dashicons-podio' => true,
|
||||
'dashicons-portfolio' => true,
|
||||
'dashicons-post-status' => true,
|
||||
'dashicons-pressthis' => true,
|
||||
'dashicons-printer' => true,
|
||||
'dashicons-privacy' => true,
|
||||
'dashicons-products' => true,
|
||||
'dashicons-randomize' => true,
|
||||
'dashicons-reddit' => true,
|
||||
'dashicons-redo' => true,
|
||||
'dashicons-remove' => true,
|
||||
'dashicons-rest-api' => true,
|
||||
'dashicons-rss' => true,
|
||||
'dashicons-saved' => true,
|
||||
'dashicons-schedule' => true,
|
||||
'dashicons-screenoptions' => true,
|
||||
'dashicons-search' => true,
|
||||
'dashicons-share-alt' => true,
|
||||
'dashicons-share-alt2' => true,
|
||||
'dashicons-share' => true,
|
||||
'dashicons-shield-alt' => true,
|
||||
'dashicons-shield' => true,
|
||||
'dashicons-shortcode' => true,
|
||||
'dashicons-slides' => true,
|
||||
'dashicons-smartphone' => true,
|
||||
'dashicons-smiley' => true,
|
||||
'dashicons-sort' => true,
|
||||
'dashicons-sos' => true,
|
||||
'dashicons-spotify' => true,
|
||||
'dashicons-star-empty' => true,
|
||||
'dashicons-star-filled' => true,
|
||||
'dashicons-star-half' => true,
|
||||
'dashicons-sticky' => true,
|
||||
'dashicons-store' => true,
|
||||
'dashicons-superhero-alt' => true,
|
||||
'dashicons-superhero' => true,
|
||||
'dashicons-table-col-after' => true,
|
||||
'dashicons-table-col-before' => true,
|
||||
'dashicons-table-col-delete' => true,
|
||||
'dashicons-table-row-after' => true,
|
||||
'dashicons-table-row-before' => true,
|
||||
'dashicons-table-row-delete' => true,
|
||||
'dashicons-tablet' => true,
|
||||
'dashicons-tag' => true,
|
||||
'dashicons-tagcloud' => true,
|
||||
'dashicons-testimonial' => true,
|
||||
'dashicons-text-page' => true,
|
||||
'dashicons-text' => true,
|
||||
'dashicons-thumbs-down' => true,
|
||||
'dashicons-thumbs-up' => true,
|
||||
'dashicons-tickets-alt' => true,
|
||||
'dashicons-tickets' => true,
|
||||
'dashicons-tide' => true,
|
||||
'dashicons-translation' => true,
|
||||
'dashicons-trash' => true,
|
||||
'dashicons-twitch' => true,
|
||||
'dashicons-twitter-alt' => true,
|
||||
'dashicons-twitter' => true,
|
||||
'dashicons-undo' => true,
|
||||
'dashicons-universal-access-alt' => true,
|
||||
'dashicons-universal-access' => true,
|
||||
'dashicons-unlock' => true,
|
||||
'dashicons-update-alt' => true,
|
||||
'dashicons-update' => true,
|
||||
'dashicons-upload' => true,
|
||||
'dashicons-vault' => true,
|
||||
'dashicons-video-alt' => true,
|
||||
'dashicons-video-alt2' => true,
|
||||
'dashicons-video-alt3' => true,
|
||||
'dashicons-visibility' => true,
|
||||
'dashicons-warning' => true,
|
||||
'dashicons-welcome-add-page' => true,
|
||||
'dashicons-welcome-comments' => true,
|
||||
'dashicons-welcome-learn-more' => true,
|
||||
'dashicons-welcome-view-site' => true,
|
||||
'dashicons-welcome-widgets-menus' => true,
|
||||
'dashicons-welcome-write-blog' => true,
|
||||
'dashicons-whatsapp' => true,
|
||||
'dashicons-wordpress-alt' => true,
|
||||
'dashicons-wordpress' => true,
|
||||
'dashicons-xing' => true,
|
||||
'dashicons-yes-alt' => true,
|
||||
'dashicons-yes' => true,
|
||||
'dashicons-youtube' => true,
|
||||
'dashicons-editor-distractionfree' => true,
|
||||
'dashicons-exerpt-view' => true,
|
||||
'dashicons-format-links' => true,
|
||||
'dashicons-format-standard' => true,
|
||||
'dashicons-post-trash' => true,
|
||||
'dashicons-share1' => true,
|
||||
'dashicons-welcome-edit-page' => true,
|
||||
);
|
||||
+1
@@ -0,0 +1 @@
|
||||
<svg class="gridicon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>Globe</title><rect fill-opacity="0" x="0" width="24" height="24"/><g><path fill="#fff" d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm0 18l2-2 1-1v-2h-2v-1l-1-1H9v3l2 2v1.93c-3.94-.494-7-3.858-7-7.93l1 1h2v-2h2l3-3V6h-2L9 5v-.41C9.927 4.21 10.94 4 12 4s2.073.212 3 .59V6l-1 1v2l1 1 3.13-3.13c.752.897 1.304 1.964 1.606 3.13H18l-2 2v2l1 1h2l.286.286C18.03 18.06 15.24 20 12 20z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 501 B |
+129
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Menu loader.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Modules;
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
use Automattic\Jetpack\Tracking;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the navigation customizations should be performed for the given class.
|
||||
*
|
||||
* @param string $admin_menu_class Class name.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function should_customize_nav( $admin_menu_class ) {
|
||||
// Make sure the class extends the base admin menu class.
|
||||
if ( ! is_subclass_of( $admin_menu_class, Base_Admin_Menu::class ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$is_api_request = defined( 'REST_REQUEST' ) && REST_REQUEST || isset( $_SERVER['REQUEST_URI'] ) && str_starts_with( filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/?rest_route=%2Fwpcom%2Fv2%2Fadmin-menu' );
|
||||
|
||||
// No nav customizations on WP Admin of Atomic sites when SSO is disabled.
|
||||
if ( is_a( $admin_menu_class, Atomic_Admin_Menu::class, true ) && ! $is_api_request && ! ( new Modules() )->is_active( 'sso' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the class that customizes the admin menu.
|
||||
*
|
||||
* @return string Class name.
|
||||
*/
|
||||
function get_admin_menu_class() {
|
||||
// WordPress.com Atomic sites.
|
||||
if ( ( new Host() )->is_woa_site() ) {
|
||||
|
||||
// DIFM Lite In Progress Atomic Sites. Uses the same menu used for domain-only sites.
|
||||
// Ignore this check if we are in a support session.
|
||||
$is_difm_lite_in_progress = wpcomsh_is_site_sticker_active( 'difm-lite-in-progress' );
|
||||
$is_support_session = defined( 'WPCOM_SUPPORT_SESSION' ) && WPCOM_SUPPORT_SESSION;
|
||||
if ( $is_difm_lite_in_progress && ! $is_support_session ) {
|
||||
require_once __DIR__ . '/class-domain-only-admin-menu.php';
|
||||
return Domain_Only_Admin_Menu::class;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/class-atomic-admin-menu.php';
|
||||
return Atomic_Admin_Menu::class;
|
||||
}
|
||||
|
||||
// WordPress.com Simple sites.
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
$blog_id = get_current_blog_id();
|
||||
|
||||
// Domain-only sites.
|
||||
$blog_options = get_blog_option( $blog_id, 'options' );
|
||||
$is_domain_only = ! empty( $blog_options['is_domain_only'] );
|
||||
if ( $is_domain_only ) {
|
||||
require_once __DIR__ . '/class-domain-only-admin-menu.php';
|
||||
return Domain_Only_Admin_Menu::class;
|
||||
}
|
||||
|
||||
// DIFM Lite In Progress Sites. Uses the same menu used for domain-only sites.
|
||||
// Ignore this check if we are in a support session.
|
||||
$is_difm_lite_in_progress = has_blog_sticker( 'difm-lite-in-progress' );
|
||||
$is_support_session = defined( 'WPCOM_SUPPORT_SESSION' ) && WPCOM_SUPPORT_SESSION;
|
||||
if ( $is_difm_lite_in_progress && ! $is_support_session ) {
|
||||
require_once __DIR__ . '/class-domain-only-admin-menu.php';
|
||||
return Domain_Only_Admin_Menu::class;
|
||||
}
|
||||
|
||||
// Rest of simple sites.
|
||||
require_once __DIR__ . '/class-wpcom-admin-menu.php';
|
||||
return WPcom_Admin_Menu::class;
|
||||
}
|
||||
|
||||
// Default menu class.
|
||||
require_once __DIR__ . '/class-admin-menu.php';
|
||||
return Admin_Menu::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the name of the class that customizes the admin menu. It should extends the `Base_Admin_Menu` class.
|
||||
*
|
||||
* @module masterbar
|
||||
*
|
||||
* @since jetpack-9.6.0
|
||||
*
|
||||
* @param string $admin_menu_class Class name.
|
||||
*/
|
||||
$admin_menu_class = apply_filters( 'jetpack_admin_menu_class', get_admin_menu_class() );
|
||||
if ( should_customize_nav( $admin_menu_class ) ) {
|
||||
/** The admin menu singleton instance. @var Base_Admin_Menu $instance */
|
||||
$admin_menu_class::get_instance();
|
||||
|
||||
/**
|
||||
* Trigger an event when the user uses the dashboard quick switcher.
|
||||
*
|
||||
* @param string $screen The current screen.
|
||||
* @param string $view The view the user choosed to go to.
|
||||
*/
|
||||
function dashboard_quick_switcher_record_usage( $screen, $view ) {
|
||||
require_once __DIR__ . '/class-dashboard-switcher-tracking.php';
|
||||
|
||||
$tracking = new Dashboard_Switcher_Tracking(
|
||||
new Tracking( Dashboard_Switcher_Tracking::get_jetpack_tracking_product() ),
|
||||
array( Dashboard_Switcher_Tracking::class, 'wpcom_tracks_record_event' ),
|
||||
Dashboard_Switcher_Tracking::get_plan()
|
||||
);
|
||||
|
||||
$tracking->record_switch_event( $screen, $view );
|
||||
}
|
||||
|
||||
\add_action( 'jetpack_dashboard_switcher_changed_view', __NAMESPACE__ . '\dashboard_quick_switcher_record_usage', 10, 2 );
|
||||
} else {
|
||||
\add_filter( 'jetpack_load_admin_menu_class', '__return_false' );
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper mapping between WP Admin pages and WordPress.com
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
$common_mappings = array(
|
||||
'users.php' => 'https://wordpress.com/people/team/',
|
||||
);
|
||||
|
||||
return $common_mappings;
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* Main class for the Masterbar package.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
|
||||
/**
|
||||
* Main class for the Masterbar package.
|
||||
*/
|
||||
class Main {
|
||||
|
||||
const PACKAGE_VERSION = '0.27.31';
|
||||
|
||||
/**
|
||||
* Initializer.
|
||||
* Used to configure the Masterbar package.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
if ( did_action( 'jetpack_masterbar_init' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
new Admin_Color_Schemes();
|
||||
|
||||
remove_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option' );
|
||||
$is_wp_admin_interface = get_option( 'wpcom_admin_interface' ) === 'wp-admin';
|
||||
if ( function_exists( 'wpcom_admin_interface_pre_get_option' ) ) {
|
||||
add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 );
|
||||
}
|
||||
|
||||
// Show Additional CSS nudges on both Simple and Atomic, independently of the admin interface.
|
||||
require_once __DIR__ . '/nudges/bootstrap.php';
|
||||
|
||||
if ( $is_wp_admin_interface ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$host = new Host();
|
||||
|
||||
new Inline_Help();
|
||||
require_once __DIR__ . '/wp-posts-list/bootstrap.php';
|
||||
|
||||
if ( $host->is_woa_site() ) {
|
||||
require_once __DIR__ . '/profile-edit/bootstrap.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to load the admin menu functionality.
|
||||
*
|
||||
* @use add_filter( 'jetpack_load_admin_menu_class', '__return_true' );
|
||||
*
|
||||
* @param bool $load_admin_menu_class Load Jetpack's custom admin menu functionality. Default to false.
|
||||
*/
|
||||
if ( apply_filters( 'jetpack_load_admin_menu_class', false ) ) {
|
||||
require_once __DIR__ . '/admin-menu/load.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after the Masterbar package is initialized.
|
||||
* Used mainly to ensure the package is initialized once.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
do_action( 'jetpack_masterbar_init' );
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Inline Help.
|
||||
*
|
||||
* Handles providing a LiveChat icon within WPAdmin until such time
|
||||
* as the full live chat experience can be run in a non-Calypso environment.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Assets;
|
||||
|
||||
/**
|
||||
* Class Inline_Help.
|
||||
*
|
||||
* @phan-constructor-used-for-side-effects
|
||||
*/
|
||||
class Inline_Help {
|
||||
|
||||
/**
|
||||
* Inline_Help constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'current_screen', array( $this, 'register_actions' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers actions.
|
||||
*
|
||||
* @param object $current_screen Current screen object.
|
||||
* @return void
|
||||
*/
|
||||
public function register_actions( $current_screen ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
// Do not inject the FAB icon on embedded screens since the parent window may already contain a FAB icon.
|
||||
$is_framed = ! empty( $_GET['frame-nonce'] );
|
||||
|
||||
// Do not inject the FAB icon on Yoast screens to avoid overlap with the Yoast help icon.
|
||||
$is_yoast = ! empty( $current_screen->base ) && str_contains( $current_screen->base, '_page_wpseo_' );
|
||||
|
||||
if ( $is_framed || $is_yoast ) {
|
||||
return;
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
add_action( 'admin_footer', array( $this, 'add_fab_icon' ) );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'add_fab_styles' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs "FAB" icon markup and SVG.
|
||||
*
|
||||
* @return void|string the HTML markup for the FAB or early exit.
|
||||
*/
|
||||
public function add_fab_icon() {
|
||||
|
||||
if ( wp_doing_ajax() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$svg_allowed = array(
|
||||
'svg' => array(
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
'aria-hidden' => true,
|
||||
'aria-labelledby' => true,
|
||||
'role' => true,
|
||||
'xmlns' => true,
|
||||
'width' => true,
|
||||
'height' => true,
|
||||
'viewbox' => true, // <= Must be lower case!
|
||||
),
|
||||
'g' => array( 'fill' => true ),
|
||||
'title' => array( 'title' => true ),
|
||||
'path' => array(
|
||||
'd' => true,
|
||||
'fill' => true,
|
||||
),
|
||||
);
|
||||
|
||||
$gridicon_help = file_get_contents( __DIR__ . '/gridicon-help.svg', true );
|
||||
|
||||
// Add tracking data to link to be picked up by Calypso for GA and Tracks usage.
|
||||
$tracking_href = add_query_arg(
|
||||
array(
|
||||
'utm_source' => 'wp_admin',
|
||||
'utm_medium' => 'other',
|
||||
'utm_content' => 'jetpack_masterbar_inline_help_click',
|
||||
'flags' => 'a8c-analytics.on',
|
||||
),
|
||||
'https://wordpress.com/help'
|
||||
);
|
||||
|
||||
load_template(
|
||||
__DIR__ . '/inline-help-template.php',
|
||||
true,
|
||||
array(
|
||||
'href' => $tracking_href,
|
||||
'icon' => $gridicon_help,
|
||||
'svg_allowed' => $svg_allowed,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues FAB CSS styles.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_fab_styles() {
|
||||
$assets_base_path = '../../dist/inline-help/';
|
||||
|
||||
Assets::register_script(
|
||||
'a8c-faux-inline-help',
|
||||
$assets_base_path . 'inline-help.js',
|
||||
__FILE__,
|
||||
array(
|
||||
'enqueue' => true,
|
||||
'css_path' => $assets_base_path . 'inline-help.css',
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="gridicon gridicons-help" height="48" width="48"><svg viewBox="0 0 24 24" id="gridicons-help"><g><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm1 16h-2v-2h2v2zm0-4.14V15h-2v-2c0-.552.448-1 1-1 1.103 0 2-.897 2-2s-.897-2-2-2-2 .897-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 1.862-1.278 3.413-3 3.86z"></path></g></svg></svg>
|
||||
|
After Width: | Height: | Size: 418 B |
+21
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Inline Help FAB icon template.
|
||||
*
|
||||
* @html-template load_template
|
||||
* @html-template-var array{href:string,icon:string,svg_allowed:array} $args
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- HTML template, let Phan handle it.
|
||||
?>
|
||||
|
||||
<div class="a8c-faux-inline-help">
|
||||
<a class="a8c-faux-inline-help__button" href="<?php echo esc_url( $args['href'] ); ?>" target="_blank" rel="noopener noreferrer" title="<?php echo esc_attr__( 'Help', 'jetpack-masterbar' ); ?>">
|
||||
<?php echo wp_kses( $args['icon'], $args['svg_allowed'] ); ?>
|
||||
</a>
|
||||
</div>
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* WPORG_Additional_CSS_Manager file
|
||||
*
|
||||
* Responsible with replacing the Core Additional CSS section with an upgrade nudge on Atomic.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
/**
|
||||
* Class Atomic_Additional_CSS_Manager
|
||||
*/
|
||||
class Atomic_Additional_CSS_Manager {
|
||||
|
||||
/**
|
||||
* The site domain.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain;
|
||||
|
||||
/**
|
||||
* Atomic_Additional_CSS_Manager constructor.
|
||||
*
|
||||
* @param string $domain the Site domain.
|
||||
*/
|
||||
public function __construct( $domain ) {
|
||||
$this->domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the Additional CSS section from Customiz¡er with an upgrade nudge.
|
||||
*
|
||||
* @param \WP_Customize_Manager $wp_customize_manager Core customize manager.
|
||||
*/
|
||||
public function register_nudge( \WP_Customize_Manager $wp_customize_manager ) {
|
||||
$plan_name = $this->get_plan()->product_name_short;
|
||||
|
||||
$nudge_url = $this->get_nudge_url();
|
||||
/* translators: %s is the plan name. */
|
||||
$nudge_text = sprintf( __( 'Purchase the %s plan to<br> activate CSS customization', 'jetpack-masterbar' ), $plan_name );
|
||||
|
||||
$nudge = new CSS_Customizer_Nudge(
|
||||
$nudge_url,
|
||||
$nudge_text
|
||||
);
|
||||
|
||||
$wp_customize_manager->remove_control( 'custom_css' );
|
||||
$wp_customize_manager->remove_section( 'custom_css' );
|
||||
|
||||
$nudge->customize_register_nudge( $wp_customize_manager );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nudge URL in WPCOM.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_nudge_url() {
|
||||
return '/checkout/' . $this->domain . '/' . $this->get_plan()->path_slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plan.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function get_plan() {
|
||||
$plan_slug = apply_filters( 'wpcom_customize_css_plan_slug', 'value_bundle' );
|
||||
|
||||
return \Automattic\Jetpack\Plans::get_plan( $plan_slug );
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* CSS_Customizer_Nudge file.
|
||||
* CSS Nudge implementation for Atomic and WPCOM.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Assets;
|
||||
|
||||
/**
|
||||
* Class WPCOM_CSS_Customizer
|
||||
*/
|
||||
class CSS_Customizer_Nudge {
|
||||
/**
|
||||
* Call to Action URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $cta_url;
|
||||
|
||||
/**
|
||||
* The nudge message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $nudge_copy;
|
||||
|
||||
/**
|
||||
* The name of the control in Customizer.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $control_name;
|
||||
|
||||
/**
|
||||
* CSS_Customizer_Nudge constructor.
|
||||
*
|
||||
* @param string $cta_url The URL to the plans.
|
||||
* @param string $nudge_copy The nudge text.
|
||||
* @param string $control_name The slug prefix of the nudge.
|
||||
*/
|
||||
public function __construct( $cta_url, $nudge_copy, $control_name = 'custom_css' ) {
|
||||
$this->cta_url = $cta_url;
|
||||
$this->nudge_copy = $nudge_copy;
|
||||
$this->control_name = $control_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the assets required for the CSS nudge page from the Customizer.
|
||||
*/
|
||||
public function customize_controls_enqueue_scripts_nudge() {
|
||||
$assets_base_path = '../../../dist/nudges/additional-css/';
|
||||
|
||||
Assets::register_script(
|
||||
'additional-css-js',
|
||||
$assets_base_path . 'additional-css.js',
|
||||
__FILE__,
|
||||
array(
|
||||
'enqueue' => true,
|
||||
'css_path' => $assets_base_path . 'additional-css.css',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the CSS nudge in the Customizer.
|
||||
*
|
||||
* @param \WP_Customize_Manager $wp_customize The customize manager.
|
||||
*/
|
||||
public function customize_register_nudge( \WP_Customize_Manager $wp_customize ) {
|
||||
// Show a nudge in place of the normal CSS section.
|
||||
\add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_scripts_nudge' ) );
|
||||
|
||||
$wp_customize->add_setting(
|
||||
$this->control_name . '[dummy_setting]',
|
||||
array(
|
||||
'type' => $this->control_name . '_dummy_setting',
|
||||
'default' => '',
|
||||
'transport' => 'refresh',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_section( $this->create_css_nudge_section( $wp_customize ) );
|
||||
|
||||
$wp_customize->add_control( $this->create_css_nudge_control( $wp_customize ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a nudge control object.
|
||||
*
|
||||
* @param \WP_Customize_Manager $wp_customize The Core Customize Manager.
|
||||
*
|
||||
* @return CSS_Nudge_Customize_Control
|
||||
*/
|
||||
public function create_css_nudge_control( \WP_Customize_Manager $wp_customize ) {
|
||||
return new CSS_Nudge_Customize_Control(
|
||||
$wp_customize,
|
||||
$this->control_name . '_control',
|
||||
array(
|
||||
'cta_url' => $this->cta_url,
|
||||
'nudge_copy' => $this->nudge_copy,
|
||||
'label' => __( 'Custom CSS', 'jetpack-masterbar' ),
|
||||
'section' => $this->control_name,
|
||||
'settings' => $this->control_name . '[dummy_setting]',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the nudge section.
|
||||
*
|
||||
* @param \WP_Customize_Manager $wp_customize The core Customize Manager.
|
||||
*
|
||||
* @return \WP_Customize_Section
|
||||
*/
|
||||
public function create_css_nudge_section( \WP_Customize_Manager $wp_customize ) {
|
||||
return new \WP_Customize_Section(
|
||||
$wp_customize,
|
||||
$this->control_name,
|
||||
array(
|
||||
'title' => __( 'Additional CSS', 'jetpack-masterbar' ),
|
||||
'priority' => 200,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* CSS_Nudge_Customize_Control file.
|
||||
* CSS Nudge implementation for Atomic and WPCOM.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class CSS_Nudge_Customize_Control
|
||||
*/
|
||||
class CSS_Nudge_Customize_Control extends \WP_Customize_Control {
|
||||
|
||||
/**
|
||||
* The type of the nudge.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'cssNudge';
|
||||
|
||||
/**
|
||||
* The Call to Action URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $cta_url;
|
||||
|
||||
/**
|
||||
* The nudge text displayed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $nudge_copy;
|
||||
|
||||
/**
|
||||
* Render the nudge on the page.
|
||||
*/
|
||||
public function render_content() {
|
||||
$cta_url = $this->cta_url;
|
||||
$nudge_copy = $this->nudge_copy;
|
||||
$nudge_button_copy = __( 'Upgrade now', 'jetpack-masterbar' );
|
||||
|
||||
echo '<div class="nudge-container">
|
||||
<p>
|
||||
' . wp_kses( $nudge_copy, array( 'br' => array() ) ) . '
|
||||
</p>
|
||||
<div class="button-container">
|
||||
<button type="button" class="button-primary navigate-to" data-navigate-to-page="' . esc_url( $cta_url ) . '">' . esc_html( $nudge_button_copy ) . '</button>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* WPCOM_Additional_CSS_Manager file
|
||||
*
|
||||
* Is responsible with registering the Additional CSS section in WPCOM.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
/**
|
||||
* Class WPCOM_Disable_Additional_CSS
|
||||
*/
|
||||
class WPCOM_Additional_CSS_Manager {
|
||||
|
||||
/**
|
||||
* The site domain.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $domain;
|
||||
|
||||
/**
|
||||
* WPCOM_Additional_CSS_Manager constructor.
|
||||
*
|
||||
* @param string $domain the Site domain.
|
||||
*/
|
||||
public function __construct( $domain ) {
|
||||
$this->domain = $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Additional CSS nudge.
|
||||
*
|
||||
* @param \WP_Customize_Manager $wp_customize_manager The core customize manager.
|
||||
*/
|
||||
public function register_nudge( \WP_Customize_Manager $wp_customize_manager ) {
|
||||
$plan_name = $this->get_plan()->product_name_short;
|
||||
|
||||
$nudge_url = $this->get_nudge_url();
|
||||
/* translators: %s is the plan name. */
|
||||
$nudge_text = sprintf( __( 'Purchase the %s plan to<br> activate CSS customization', 'jetpack-masterbar' ), $plan_name );
|
||||
|
||||
$nudge = new CSS_Customizer_Nudge(
|
||||
$nudge_url,
|
||||
$nudge_text,
|
||||
'jetpack_custom_css'
|
||||
);
|
||||
|
||||
$nudge->customize_register_nudge( $wp_customize_manager );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nudge URL in WPCOM.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_nudge_url() {
|
||||
return '/checkout/' . $this->domain . '/' . $this->get_plan()->path_slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plan.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function get_plan() {
|
||||
$plan_slug = apply_filters( 'wpcom_customize_css_plan_slug', 'value_bundle' );
|
||||
|
||||
return \Automattic\Jetpack\Plans::get_plan( $plan_slug );
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Bootstrap file for the nudges.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Status;
|
||||
use Automattic\Jetpack\Status\Host;
|
||||
|
||||
/**
|
||||
* The WP_Customize_Control core class is loaded only on customize_register.
|
||||
*
|
||||
* @param \WP_Customize_Manager $customize_manager Core customize manager.
|
||||
*/
|
||||
function register_css_nudge_control( \WP_Customize_Manager $customize_manager ) {
|
||||
$domain = ( new Status() )->get_site_suffix();
|
||||
|
||||
if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
|
||||
$manager = new WPCOM_Additional_CSS_Manager( $domain );
|
||||
} elseif ( ( new Host() )->is_woa_site() ) {
|
||||
$manager = new Atomic_Additional_CSS_Manager( $domain );
|
||||
}
|
||||
|
||||
if ( ! isset( $manager ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$manager->register_nudge( $customize_manager );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the bootstrap on init action.
|
||||
*
|
||||
* We need to load on init because otherwise the filter will not be set to true in WPCOM (since the add_filter is set on init).
|
||||
*/
|
||||
function load_bootstrap_on_init() {
|
||||
|
||||
/**
|
||||
* Disable Additional CSS section from Customizer in WPCOM and Atomic and replace it with a nudge.
|
||||
*
|
||||
* @module masterbar
|
||||
*
|
||||
* @since jetpack-9.9.0
|
||||
*
|
||||
* @param bool
|
||||
*/
|
||||
if ( \apply_filters( 'jetpack_customize_enable_additional_css_nudge', false ) ) {
|
||||
\add_action( 'customize_register', __NAMESPACE__ . '\register_css_nudge_control' );
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'init', __NAMESPACE__ . '\load_bootstrap_on_init' );
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* Bootstrap the WP.com User profile edit restriction.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/class-wpcom-user-profile-fields-revert.php';
|
||||
|
||||
/**
|
||||
* Prevent WP.com user profile fields (first_name, last_name, display_name, description) to be updated.
|
||||
*/
|
||||
function load_the_user_profile_info_revert() {
|
||||
new WPCOM_User_Profile_Fields_Revert( new Connection_Manager( 'jetpack' ) );
|
||||
}
|
||||
|
||||
\add_action( 'load-profile.php', __NAMESPACE__ . '\load_the_user_profile_info_revert' );
|
||||
\add_action( 'load-user-edit.php', __NAMESPACE__ . '\load_the_user_profile_info_revert' );
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Manage User profile fields.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
|
||||
/**
|
||||
* Responsible with preventing the back-end default implementation to save the fields that are managed on WP.com profiles.
|
||||
*
|
||||
* Class Profile_Edit_Filter_Fields
|
||||
*
|
||||
* @phan-constructor-used-for-side-effects
|
||||
*/
|
||||
class WPCOM_User_Profile_Fields_Revert {
|
||||
|
||||
/**
|
||||
* Jetpack connection manager object.
|
||||
*
|
||||
* @var Connection_Manager
|
||||
*/
|
||||
private $connection_manager;
|
||||
|
||||
/**
|
||||
* Profile_Edit_Filter_Fields constructor.
|
||||
*
|
||||
* @param Connection_Manager $connection_manager The connection manager.
|
||||
*/
|
||||
public function __construct( Connection_Manager $connection_manager ) {
|
||||
$this->connection_manager = $connection_manager;
|
||||
|
||||
\add_filter( 'wp_pre_insert_user_data', array( $this, 'revert_user_data_on_wp_admin_profile_update' ), 10, 3 );
|
||||
\add_filter( 'insert_user_meta', array( $this, 'revert_user_meta_on_wp_admin_profile_change' ), 10, 3 );
|
||||
|
||||
/**
|
||||
* Core sends two E-mail notifications that have to be disabled:
|
||||
* - To the existing e-mail address
|
||||
* - To the new email address
|
||||
*/
|
||||
\add_filter( 'send_email_change_email', array( $this, 'disable_send_email_change_email' ), 10, 3 );
|
||||
\add_action( 'personal_options_update', array( $this, 'disable_email_notification' ), 1, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the built-in user profile fields.
|
||||
*
|
||||
* @param array $data {
|
||||
* Values and keys for the user.
|
||||
*
|
||||
* @type string $user_login The user's login. Only included if $update == false
|
||||
* @type string $user_pass The user's password.
|
||||
* @type string $user_email The user's email.
|
||||
* @type string $user_url The user's url.
|
||||
* @type string $user_nicename The user's nice name. Defaults to a URL-safe version of user's login
|
||||
* @type string $display_name The user's display name.
|
||||
* @type string $user_registered MySQL timestamp describing the moment when the user registered. Defaults to
|
||||
* the current UTC timestamp.
|
||||
* }
|
||||
*
|
||||
* @param bool $update Whether the user is being updated rather than created.
|
||||
* @param int|null $id ID of the user to be updated, or NULL if the user is being created.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function revert_user_data_on_wp_admin_profile_update( $data, $update, $id ) {
|
||||
|
||||
// bail if the id is null, meaning that this was triggered in the context of user create.
|
||||
// bail if the user is not connected (e.g. non-WP.com users or disconnected users).
|
||||
if ( ! $update || null === $id || ! $this->connection_manager->is_user_connected( $id ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert the data in the form submission with the data from the database.
|
||||
*/
|
||||
$user = \get_userdata( $id );
|
||||
|
||||
/**
|
||||
* E-mail has a different flow for changing it's value. It stores it in an option until the user confirms it via e-mail.
|
||||
* Based on this, it displays in the UI a section mentioning the e-mail pending change.
|
||||
* We hide the entire section, but we should also clean it up just in case.
|
||||
*/
|
||||
\delete_user_meta( $id, '_new_email' );
|
||||
|
||||
$data['user_email'] = $user->user_email;
|
||||
$data['user_url'] = $user->user_url;
|
||||
$data['user_nicename'] = $user->user_nicename;
|
||||
$data['display_name'] = $user->display_name;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert the first_name, last_name and description since this is managed by WP.com.
|
||||
*
|
||||
* @param array $meta {
|
||||
* Default meta values and keys for the user.
|
||||
*
|
||||
* @type string $nickname The user's nickname. Default is the user's username.
|
||||
* @type string $first_name The user's first name.
|
||||
* @type string $last_name The user's last name.
|
||||
* @type string $description The user's description.
|
||||
* @type string $rich_editing Whether to enable the rich-editor for the user. Default 'true'.
|
||||
* @type string $syntax_highlighting Whether to enable the rich code editor for the user. Default 'true'.
|
||||
* @type string $comment_shortcuts Whether to enable keyboard shortcuts for the user. Default 'false'.
|
||||
* @type string $admin_color The color scheme for a user's admin screen. Default 'fresh'.
|
||||
* @type int|bool $use_ssl Whether to force SSL on the user's admin area. 0|false if SSL
|
||||
* is not forced.
|
||||
* @type string $show_admin_bar_front Whether to show the admin bar on the front end for the user.
|
||||
* Default 'true'.
|
||||
* @type string $locale User's locale. Default empty.
|
||||
* }
|
||||
* @param \WP_User $user User object.
|
||||
* @param bool $update Whether the user is being updated rather than created.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function revert_user_meta_on_wp_admin_profile_change( $meta, $user, $update ) {
|
||||
|
||||
// bail if not in update context.
|
||||
if ( ! $update || ! $this->connection_manager->is_user_connected( $user->ID ) ) {
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert the data in the form submission with the data from the database.
|
||||
*/
|
||||
$database_user = \get_userdata( $user->ID );
|
||||
|
||||
$meta['first_name'] = $database_user->first_name;
|
||||
$meta['last_name'] = $database_user->last_name;
|
||||
$meta['description'] = $database_user->description;
|
||||
$meta['nickname'] = $database_user->nickname;
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the e-mail notification.
|
||||
*
|
||||
* @param bool $send Whether to send or not the email.
|
||||
* @param array $user User data.
|
||||
*/
|
||||
public function disable_send_email_change_email( $send, $user ) {
|
||||
if ( ! isset( $user['ID'] ) || ! $this->connection_manager->is_user_connected( $user['ID'] ) ) {
|
||||
return $send;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable notification on E-mail changes for Atomic WP-Admin Edit Profile. (for WP.com we use a different section for changing the E-mail).
|
||||
*
|
||||
* We need this because WP.org uses a custom flow for E-mail changes.
|
||||
*
|
||||
* @param int $user_id The id of the user that's updated.
|
||||
*/
|
||||
public function disable_email_notification( $user_id ) {
|
||||
// Don't remove the notification for non-WP.com connected users.
|
||||
if ( ! $this->connection_manager->is_user_connected( $user_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
\remove_action( 'personal_options_update', 'send_confirmation_on_profile_email' );
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* WP-Admin Profile edit.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
|
||||
use WP_User;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides profile fields for WordPress.com connected users.
|
||||
*
|
||||
* @param WP_User $user The current WP_User object.
|
||||
*/
|
||||
function jetpack_masterbar_hide_profile_fields( $user ) {
|
||||
$connection_manager = new Connection_Manager( 'jetpack' );
|
||||
if ( ! $connection_manager->is_user_connected( $user->ID ) ) {
|
||||
// If this is a local user, show the default UX.
|
||||
return;
|
||||
}
|
||||
$wp_kses_rule = array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'rel' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
);
|
||||
// Since there is no hook for altering profile fields, we will use CSS and JS.
|
||||
$name_info_wpcom_link_message = sprintf(
|
||||
/* translators: 1 link */
|
||||
__( 'WordPress.com users can change their profile’s basic details ( i.e., First Name, Last Name, Display Name, About ) in <a href="%1$s" target="_blank" rel="noopener noreferrer">WordPress.com Profile settings.</a>', 'jetpack-masterbar' ),
|
||||
'https://wordpress.com/me'
|
||||
);
|
||||
$contact_info_wpcom_link_message = sprintf(
|
||||
/* translators: 1 link */
|
||||
__( 'WordPress.com users can change their profile’s email & website address in <a href="%1$s" target="_blank" rel="noopener noreferrer">WordPress.com Account settings.</a>', 'jetpack-masterbar' ),
|
||||
'https://wordpress.com/me/account'
|
||||
);
|
||||
?>
|
||||
<script>
|
||||
document.addEventListener( 'DOMContentLoaded', function() {
|
||||
// Field to be hidden.
|
||||
var fieldsToHide = '.user-first-name-wrap, .user-last-name-wrap, .user-nickname-wrap, .user-display-name-wrap, .user-email-wrap, .user-url-wrap, .user-description-wrap';
|
||||
document.querySelectorAll( fieldsToHide ).forEach( element => element.classList.add( 'hidden' ) );
|
||||
|
||||
// Name Info.
|
||||
var nameInfo = document.querySelector( '.user-first-name-wrap' ).closest( 'table' );
|
||||
var nameInfoWpcomLink = document.createElement( 'div' );
|
||||
nameInfoWpcomLink.className = 'notice inline notice-large notice-warning';
|
||||
nameInfoWpcomLink.innerHTML = '<?php echo wp_kses( $name_info_wpcom_link_message, $wp_kses_rule ); ?>';
|
||||
nameInfo.parentNode.insertBefore( nameInfoWpcomLink, nameInfo.nextSibling );
|
||||
|
||||
// Contact Info.
|
||||
var contactInfo = document.querySelector( '.user-email-wrap' ).closest( 'table' );
|
||||
var contactInfoWpcomLink = document.createElement( 'div' );
|
||||
contactInfoWpcomLink.className = 'notice inline notice-large notice-warning';
|
||||
contactInfoWpcomLink.innerHTML = '<?php echo wp_kses( $contact_info_wpcom_link_message, $wp_kses_rule ); ?>';
|
||||
contactInfo.parentNode.insertBefore( contactInfoWpcomLink, contactInfo.nextSibling );
|
||||
});
|
||||
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
add_action( 'personal_options', __NAMESPACE__ . '\jetpack_masterbar_hide_profile_fields' );
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* WP-Admin Posts list bootstrap file.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the Posts_List_Notification.
|
||||
*/
|
||||
function masterbar_init_wp_posts_list() {
|
||||
global $pagenow;
|
||||
|
||||
if (
|
||||
( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && 'page' === $_GET['post_type'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
) {
|
||||
Posts_List_Page_Notification::init();
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'init', __NAMESPACE__ . '\masterbar_init_wp_posts_list', 1 );
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/**
|
||||
* Posts_List_Page_Notification file.
|
||||
* Disable edit_post and delete_post capabilities for Posts Pages in WP-Admin and display a notification icon.
|
||||
*
|
||||
* @package automattic/jetpack-masterbar
|
||||
*/
|
||||
|
||||
namespace Automattic\Jetpack\Masterbar;
|
||||
|
||||
use Automattic\Jetpack\Assets;
|
||||
|
||||
/**
|
||||
* Class Posts_List_Page_Notification
|
||||
*/
|
||||
class Posts_List_Page_Notification {
|
||||
|
||||
/**
|
||||
* Site's Posts page id
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
private $posts_page_id;
|
||||
|
||||
/**
|
||||
* If the Post_list contains the site's Posts Page
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_page_in_list = false;
|
||||
|
||||
/**
|
||||
* Class instance.
|
||||
*
|
||||
* @var Posts_List_Page_Notification|null
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Posts_List_Page_Notification constructor.
|
||||
*
|
||||
* @param string $posts_page_id The Posts page configured in WordPress.
|
||||
* @param string $show_on_front The show_on_front site option.
|
||||
* @param string $page_on_front The page_on_front site_option.
|
||||
*/
|
||||
public function __construct( $posts_page_id, $show_on_front, $page_on_front ) {
|
||||
if ( 'page' === $show_on_front && $posts_page_id !== $page_on_front ) {
|
||||
add_action( 'init', array( $this, 'init_actions' ) );
|
||||
}
|
||||
|
||||
$this->posts_page_id = '' === $posts_page_id ? null : (int) $posts_page_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add in all hooks.
|
||||
*/
|
||||
public function init_actions() {
|
||||
\add_filter( 'map_meta_cap', array( $this, 'disable_posts_page' ), 10, 4 );
|
||||
\add_filter( 'post_class', array( $this, 'add_posts_page_css_class' ), 10, 3 );
|
||||
\add_action( 'admin_print_footer_scripts-edit.php', array( $this, 'add_notification_icon' ) );
|
||||
\add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_css' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates instance.
|
||||
*
|
||||
* @return Posts_List_Page_Notification
|
||||
*/
|
||||
public static function init() {
|
||||
if ( self::$instance === null ) {
|
||||
self::$instance = new self( \get_option( 'page_for_posts' ), \get_option( 'show_on_front' ), \get_option( 'page_on_front' ) );
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable editing and deleting for the page that is configured as a Posts Page.
|
||||
*
|
||||
* @param array $caps Array of capabilities.
|
||||
* @param string $cap The current capability.
|
||||
* @param string $user_id The user id.
|
||||
* @param array $args Argument array.
|
||||
* @return array
|
||||
*/
|
||||
public function disable_posts_page( $caps, $cap, $user_id, $args ) {
|
||||
if ( 'edit_post' !== $cap && 'delete_post' !== $cap ) {
|
||||
return $caps;
|
||||
}
|
||||
|
||||
if ( isset( $args[0] ) && $this->posts_page_id === (int) $args[0] ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
}
|
||||
|
||||
return $caps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the CSS for the WP Posts List
|
||||
*
|
||||
* We would probably need to move this elsewhere when new features are introduced to wp-posts-list.
|
||||
*/
|
||||
public function enqueue_css() {
|
||||
$assets_base_path = '../../dist/wp-posts-list/';
|
||||
|
||||
Assets::register_script(
|
||||
'wp-posts-list',
|
||||
$assets_base_path . 'wp-posts-list.js',
|
||||
__FILE__,
|
||||
array(
|
||||
'enqueue' => true,
|
||||
'css_path' => $assets_base_path . 'wp-posts-list.css',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a CSS class on the page configured as a Posts Page.
|
||||
*
|
||||
* @param array $classes A list of CSS classes.
|
||||
* @param string $class A CSS class.
|
||||
* @param string $post_id The current post id.
|
||||
* @return array
|
||||
*/
|
||||
public function add_posts_page_css_class( $classes, $class, $post_id ) {
|
||||
if ( $this->posts_page_id !== (int) $post_id ) {
|
||||
return $classes;
|
||||
}
|
||||
|
||||
$this->is_page_in_list = true;
|
||||
|
||||
$classes[] = 'posts-page';
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a info icon on the Posts Page letting the user know why they cannot delete and remove the page.
|
||||
*/
|
||||
public function add_notification_icon() {
|
||||
// No need to add the JS since the site is not configured with a Posts Page or the current listview doesn't contain the page.
|
||||
if ( null === $this->posts_page_id || ! $this->is_page_in_list ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$text_notice = __( 'The content of your latest posts page is automatically generated and cannot be edited.', 'jetpack-masterbar' );
|
||||
?>
|
||||
<script>
|
||||
document.querySelector(".posts-page .check-column").innerHTML = '' +
|
||||
'<div class="info"><span class="icon dashicons dashicons-info-outline"></span><span class="message"><?php echo esc_html( $text_notice ); ?></span></div>';
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user