To truly leverage OOP, you need to learn about design principles, design patterns, standards.
→ Set of guidelines that help avoiding a bad software design.
Bad:
interface Car {
public function set_price( float $price );
public function sell();
}
Better:
interface Car {
public function set_price( float $price );
}
interface Car_Dealership {
public function sell_car( Car $car );
}
SRP is part of SOLID, the first five object-oriented design principles made popular by Robert C. Martin.
→ Formalized best practices to solve common software problems.
class My_Plugin {
private static $instance = null;
public static function instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
My_Plugin_Settings_Controller::instance()->initialize();
}
}
This is an anti-pattern!
class My_Plugin {
private $settings;
public function __construct( My_Plugin_Settings_Controller $settings ) {
$this->settings = $settings;
$this->settings->initialize();
}
}
Oh, another pattern: Dependency Injection!
→ Improves interoperability of otherwise independent projects.
class My_Plugin {
/**
* The settings controller instance.
*
* @since 1.0.0
* @var My_Plugin_Settings_Controller
*/
private $settings;
/**
* Constructor.
*
* @since 1.0.0
*
* @param My_Plugin_Settings_Controller Settings controller instance to use.
*/
public function __construct( My_Plugin_Settings_Controller $settings ) {
$this->settings = $settings;
$this->settings->initialize();
}
}
class MyPlugin
{
/** @var MyPluginSettingsController The settings controller instance. */
private $settings;
/**
* Constructor.
*
* @since 1.0.0
*
* @param My_Plugin_Settings_Controller Settings controller instance to use.
*/
public function __construct(MyPluginSettingsController $settings)
{
$this->settings = $settings;
$this->settings->initialize();
}
}
PSR-2 is a standard established by the PHP-FIG,
a group whose goal is to define standards for PHP projects.
This project implements a reusable abstraction layer around the WordPress Admin Menu API. We will go through it one by one.
https://github.com/felixarntz/oop-admin-pagescd my-wordpress-site
cd wp-content/plugins
git clone git@github.com:felixarntz/oop-admin-pages.git oop-admin-pages
cd oop-admin-pages
composer install
cd ../../..
wp plugin activate oop-admin-pages
cd wp-content/plugins/oop-admin-pages
Admin_Page
Interfacegit checkout 8f4f979ee4318570557d0e855fe06977ce57f9ec
Abstract_Admin_Page
Classgit checkout f6ef1da22f4ab20a79192f5b3b88970aba561a6a
Admin_Page_Factory
Interfacegit checkout 255b4d4af50d9f0bc753cd2f8e8cd53f3bc0fec5
Admin_Page_Collection
Interfacegit checkout 84b6d689821b820fbd6cfc93123ef6db1f9a7cd4
Base_Admin_Page_Collection
Classgit checkout e7e6a21f32f1305bee47cf127707d1ef599065cc
WordPress_Admin_Page
Classgit checkout 3f73ca49e15d6c11338f3812afb55d014b092b9d
WordPress_Admin_Menu_Page
Classgit checkout 76281736965958e01446abcdf1031b277530a4e6
WordPress_Admin_Submenu_Page
Classgit checkout fc6019694dc7c73d03f9bfa67bf5badd21f82858
WordPress_Admin_Page_Factory
Classgit checkout 758c3f1aac6aa67a13f4935d28543f8545a32a80
git checkout 76d65113b43aa780049ddbf52ce6e7d3181f9bf4
Okay, we just turned two simple functionsadd_menu_page()
andadd_submenu_page()
plus theadmin_menu
hook into 3 interfaces and 8 classes. WTF?
Base_Admin_Page_Collection
instance and pass in an array instead of looking up the parameter order of the WordPress functions multiple times.Drupal_Admin_Page
and Drupal_Admin_Page_Factory
implementations for example.In WordPress Multisite there is not only a site admin panel,
but also network and user administration panels.
How can we enhance our project so that
admin pages for these panels can also be registered?
git checkout 2e08d5bb50734f594c011eb43727f8bbb5761d42
git checkout 6326675a7b408992eb8af8de514dcb0f905a2bd6
git checkout 857892236e62ce932715919f213aa47b81ffd29c
Plugin Developer / Core Committer / Freelancer