-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/admin pages menu #1810
base: master
Are you sure you want to change the base?
Feature/admin pages menu #1810
Conversation
Deprecated: DateTime::setTime(): Passing null to parameter #1 ($hour) of type int is deprecated
Deprecated: Constant FILTER_SANITIZE_STRING is deprecated
Deprecated: strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated
…s-menu Makes working in PHP 8.1 so much easier!
ALter the way Traits interact with the build process. Add CPT as a Trait. Make it work with Submenu. Start Settings as a Trait.
Are we re-doing what we recently introduced here? https://github.com/the-events-calendar/tribe-common/blob/master/src/Tribe/Admin/Pages.php We introduced that as part of the Tickets menu, and all plugins are using now that "framework" to already register and manage admin pages. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would decomplicate the stack by removing interfaces and traits to have a menu and sub-menu abstract class.
* | ||
* @var string | ||
*/ | ||
protected $page_title = ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment applies here and to other properties: if a property is meant to be overridden and provided a non-empty value to make sense, do not make it a property. Make it a method, abstract
in this class, that extending classes will have to implement (e.g. here it would be get_page_title
) the method should be protected
(it's not part of the public API); if a public
method by the same name already exists, just use that.
This would allow someone to come in, extend the abstract class and get a complete checklist of the methods to fill.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I agree with this logic...
You are saying this:
/**
* {@inheritDoc}
*/
public function get_icon_url() : string {
return $this->get_menu_icon();
}
/**
* {@inheritDoc}
*/
public function get_page_title() : string {
return _x( 'The Events Calendar', 'The title for the admin page', 'the-events-calendar');
}
/**
* {@inheritDoc}
*/
public function get_menu_title() : string {
return _x( 'The Events Calendar', 'The title for the admin menu link', 'the-events-
}
is simpler than this:
public function init() : void {
$this->page_title = _x( 'The Events Calendar', 'The title for the admin page', 'the-events-calendar');
$this->menu_title = _x( 'The Events Calendar', 'The title for the admin menu link', 'the-events-calendar');
$this->icon_url = $this->get_menu_icon();
parent::init();
}
* | ||
* @package TEC\Common\Menus | ||
*/ | ||
abstract class Submenu_Example extends Abstract_Menu implements Menu_Contract { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where I see the noise coming up: we have Menu pages and sub-menu pages. They are different things requiring different logic. I think the extension/inheritance/implementation stack here could be cut down having a base abstract
class for menu pages and a base abstract
class for sub-menu pages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we re-doing what we recently introduced here? https://github.com/the-events-calendar/tribe-common/blob/master/src/Tribe/Admin/Pages.php
We introduced that as part of the Tickets menu, and all plugins are using now that "framework" to already register and manage admin pages.
@juanfra - yes. the idea behind this is something that is less opinionated, less tied to TEC/ET, does not include admin pages in it automatically, and can be separated out and shared both with Stellar and with the rest of the world.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why GitHub decided to attach that to this comment 🤦🏼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Camwyn I don't understand the opinionated part. Could you please expand?
I feel that menus and submenus are just pages, thinking abstractly. Creating whole new classes for something that was already done a couple months ago (and that's ~300 lines) would be maybe taking valuable time from us. To add up, we are still using tec_
prefixes, so I don't understand how this would be less tied to TEC/ET.
With the current admin pages implementation there's no page generated, that was moved to the plugins, and it was kind of one of the goals, because for ET as standalone the TEC page was created automatically from common.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The final home for this would be a public Stellar library - so not tec_
prefixed (just convenient for now) and not built with TEC/ET's needs specifically in mind.
Note it uses no tribe()
functionality (although that would be convenient - it won't, come time to separate it)
|
||
namespace TEC\Common\Menus\Traits; | ||
|
||
trait Submenu { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used only by one class, I would make this part of an abstract
sub-menu class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The traits are designed to be used when extending the abstract menu class - a la carte menu pages.
See the way they were implemented in the TEC PR.
I can see where it might make more sense to make Submenu the default though 🤔
public $adminbar_parent = ''; | ||
|
||
public function hooks() { | ||
add_action( 'wp_before_admin_bar_render', [ $this, 'add_toolbar_item' ], 20 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hook should live in a service provider, could this code be refactored to have this live there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not. I want the (Abstract_Menu
) class to be all the user has to deal with (remember - this is intended to become a standalone) so all they have to do is extend Abstract_Menu
and use any needed Traits...and not instantiate a Service Provider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually have some ideas about this so...maybe 😉
|
||
namespace TEC\Common\Menus\Traits; | ||
|
||
trait With_Admin_Bar { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this trait will be used only in menu, or sub-menu, pages, then I would just include it in the competent abstract
class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will - but not all of them.
*/ | ||
public $adminbar_parent = ''; | ||
|
||
public function hooks() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too generic a method name for a trait, conflicts will arise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree (and have had said collisions 😜) - I am working on that
|
||
namespace TEC\Common\Menus\Traits; | ||
|
||
trait With_Settings { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the same note as the Admin Bar one, if this one will be used only by menu or sub-menu pages, then I would just include it there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? Why add all the code for settings (which isn't working yet BTW) when all I want is a simple top-level menu?
* | ||
* @param array<string,mixed> $data The data for creating the settings page. | ||
*/ | ||
public function init( array $data ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too generic a method name for a trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Furthermore, this looks like something that should live in a __construct
method, not in a method that implementers have to remember to call.
Remove all tribe() refs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes with build configuration files.
@@ -11,7 +11,9 @@ phpunit.xml | |||
.env.local | |||
.env.*.local | |||
codeception.tric.yml | |||
codeception.slic.yml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we used to ignore the tric
configuration files in Common, but I think we should not: TEC and other plugins are including tric
configuration files in VCS.
@@ -42,8 +42,8 @@ env: | |||
- WP_ADMIN_PASSWORD="password" | |||
|
|||
before_install: | |||
# Rollback Composer to version 1. | |||
- composer self-update --rollback | |||
# Set Composer to version 2. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good chance to move Common build away from Travis CI, as is the case for the other plugins, and just remove any configuration file related to it.
"codeception/codeception": "^2.5.5", | ||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", | ||
"lucatume/codeception-snapshot-assertions": "^0.2.4", | ||
"lucatume/function-mocker-le": "^1.0", | ||
"lucatume/wp-browser": "^3.0.14", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update this to 3.1.6
(latest version).
}, | ||
"minimum-stability": "dev", | ||
"prefer-stable": true, | ||
"config": { | ||
"preferred-install": "dist", | ||
"platform": { | ||
"php": "7.3.33" | ||
"php": "7.4.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minimum required version of PHP in the plugins is 7.3; the platform.php
value should stay on 7.3.33
.
namespace TEC\Common\Menus; | ||
|
||
|
||
class Menus { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove excess empty line before, add class doc-block.
Adding a catch-all comment here to address my previous comments regarding the abstract class and trait architecture. To frame my comment, I'm thinking about my experience implementing Views v2 and the ORM/Repository; my guiding light there was to keep the code clean and strive for good architecture that would make sense. In actual, day-to-day use, it turned out both implementations had missed the mark putting a knowledge requirement on the developers willing to use and extend them. In more than one dev meeting we discussed how to make one or the other simpler and @borkweb created an adapter API on top of Views v2 code to address the issue when he found himself struggling to come to terms with some non-obvious implementation choices. This PR deals with code to be used by developers to base more code upon, and I think there is merit in it. If I start from the end of the path, the one where a developer pulls the library, copies and pastes a JSON schema from the documentation and runs with it, then I ask myself how the PHP class consuming it would look. Beside ACF, there are other notable examples of schema-based, general purpose, libraries like johnbillion/extended-cpts. I propose the use of two, possibly one, abstract class as, I think, it would solve the pain points of both scenarios above.
In the second scenario:
The <?php
abstract class Abstract_Settings {
abstract protected function is_menu(): bool;
abstract protected function is_cpt(): bool;
protected function set_up_menu(): void {
if ( ! $this->is_menu() ) {
return;
}
// do stuff
}
protected function set_up_cpt(): void {
if ( ! $this->is_cpt() ) {
return;
}
// do stuff
}
} The use of How would it play out in scenario 1? Example code follows (with reference to the code above): class Schema_Settings extends Abstract_Settings {
protected $schema = [];
public function __construct( array $schema ) {
$this->schema = $schema;
}
protected function is_menu(): bool {
return isset($this->schema['menu']);
}
protected function is_cpt(): bool {
return isset($this->schema['cpt']);
}
}
class JSON_Schema_Settings extends Schema_Settings {
public function __construct( string $json_file ) {
$schema = json_decode( file_get_contents( $json_file ), true, 512, JSON_THROW_ON_ERROR );
parent::__construct( $schema );
}
} A schema-based implementation would, then, make testing very easy. That would include bug reports. I know this was a long comment, thanks for taking the time to read it. |
Draft so folks can see and comment on where I am with the new admin page/menu architecture.
Note: one premise I have been working on is that all pages are handled by their respective plugins - None of them are contained in common.
This is for reasons:
NOTE: tests will fail - this uses Composer 2 and our workflows aren't set up for that!