diff --git a/README.md b/README.md index 85050b4..b74a4be 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,22 @@ This is an example plugin to demonstrate how we at WPify create plugins. The aim is to create simple plugin that stores information about books and their authors. On this, we demonstrate the advanced techniques of creating a plugin. +## Steps: -[Next step >>>](https://github.com/wpify/plugin-tutorial/tree/01-basics-php-di) +### 01 - Basic concepts - OOP, Namespaces, Composer, Dependency Injection + +Let's start with building the basic plugin structure using OOP, Namespaces, Composer and Dependency Injection. + +Links: + +* [Object oriented programming - OOP](https://www.phptutorial.net/php-oop/) +* [Namespaces](https://www.phptutorial.net/php-oop/php-namespace/) +* [Composer](https://getcomposer.org/doc/01-basic-usage.md) +* [Understanding Dependency Injection](https://php-di.org/doc/understanding-di.html) +* DI Containers - [PHP/DI](https://php-di.org/), [Symfony DI](https://symfony.com/doc/current/components/dependency_injection.html), [League](https://container.thephpleague.com/), [Nette](https://doc.nette.org/en/dependency-injection/container), [Dice](https://github.com/Level-2/Dice) + +```bash +composer require php-di/php-di +``` + +[Next step >>>](https://github.com/wpify/plugin-tutorial/tree/02-scoper) diff --git a/bootstrap.php b/bootstrap.php new file mode 100644 index 0000000..ab388f9 --- /dev/null +++ b/bootstrap.php @@ -0,0 +1,95 @@ +addDefinitions( array() ); + $container = $containerBuilder->build(); + } + + return $container; +} + +/** + * Returns the main plugin class from DI container. + * + * @return Plugin + * @throws DependencyException + * @throws NotFoundException + */ +function wpifypt(): Plugin { + return wpifypt_container()->get( Plugin::class ); +} + +/** + * Method called on plugin activation. + * + * @param $network_wide Plugin Activated network wide. + * + * @return void + * @throws DependencyException + * @throws NotFoundException + */ +function wpifypt_activate( $network_wide ): void { + wpifypt()->activate( $network_wide ); +} + +/** + * Method called on plugin deactivation. + * + * @param $network_wide Plugin Deactivated network wide. + * + * @return void + * @throws DependencyException + * @throws NotFoundException + */ +function wpifypt_deactivate( $network_wide ): void { + wpifypt()->deactivate( $network_wide ); +} + +/** + * Method called on plugin uninstall. + * + * @return void + * @throws DependencyException + * @throws NotFoundException + */ +function wpifypt_uninstall(): void { + wpifypt()->uninstall(); +} + +add_action( 'plugins_loaded', 'wpifypt' ); + +register_activation_hook( __FILE__, 'wpifypt_activate' ); +register_deactivation_hook( __FILE__, 'wpifypt_deactivate' ); +register_uninstall_hook( __FILE__, 'wpifypt_uninstall' ); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..3c63f0e --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "wpify/plugin-tutorial", + "type": "project", + "license": "MIT", + "autoload": { + "psr-4": { + "WpifyPluginTutorial\\": "src/" + } + }, + "authors": [ + { + "name": "WPify", + "email": "info@wpify.io" + } + ], + "require": { + "php": "^8.0", + "php-di/php-di": "^7.0" + } +} diff --git a/src/Managers/PostTypesManager.php b/src/Managers/PostTypesManager.php new file mode 100644 index 0000000..7e006bf --- /dev/null +++ b/src/Managers/PostTypesManager.php @@ -0,0 +1,13 @@ + _x( 'Books', 'Post Type General Name', 'wpifypt' ), + 'singular_name' => _x( 'Book', 'Post Type Singular Name', 'wpifypt' ), + 'menu_name' => __( 'Books', 'wpifypt' ), + 'name_admin_bar' => __( 'Book', 'wpifypt' ), + 'archives' => __( 'Book Archives', 'wpifypt' ), + 'attributes' => __( 'Book Attributes', 'wpifypt' ), + 'parent_item_colon' => __( 'Parent Book:', 'wpifypt' ), + 'all_items' => __( 'All Books', 'wpifypt' ), + 'add_new_item' => __( 'Add New Book', 'wpifypt' ), + 'add_new' => __( 'Add New', 'wpifypt' ), + 'new_item' => __( 'New Book', 'wpifypt' ), + 'edit_item' => __( 'Edit Book', 'wpifypt' ), + 'update_item' => __( 'Update Book', 'wpifypt' ), + 'view_item' => __( 'View Book', 'wpifypt' ), + 'view_items' => __( 'View Books', 'wpifypt' ), + 'search_items' => __( 'Search Book', 'wpifypt' ), + 'not_found' => __( 'Not found', 'wpifypt' ), + 'not_found_in_trash' => __( 'Not found in Trash', 'wpifypt' ), + 'featured_image' => __( 'Featured Image', 'wpifypt' ), + 'set_featured_image' => __( 'Set featured image', 'wpifypt' ), + 'remove_featured_image' => __( 'Remove featured image', 'wpifypt' ), + 'use_featured_image' => __( 'Use as featured image', 'wpifypt' ), + 'insert_into_item' => __( 'Insert into book', 'wpifypt' ), + 'uploaded_to_this_item' => __( 'Uploaded to this book', 'wpifypt' ), + 'items_list' => __( 'Books list', 'wpifypt' ), + 'items_list_navigation' => __( 'Books list navigation', 'wpifypt' ), + 'filter_items_list' => __( 'Filter books list', 'wpifypt' ), + ); + + $args = array( + 'label' => __( 'Book', 'wpifypt' ), + 'description' => __( 'Example post type Book', 'wpifypt' ), + 'labels' => $labels, + 'supports' => array( 'title', 'editor', 'thumbnail', 'custom-fields' ), + 'taxonomies' => array( BookAuthorTaxonomy::KEY ), + 'hierarchical' => false, + 'public' => true, + 'show_ui' => true, + 'show_in_menu' => true, + 'menu_position' => 25, + 'menu_icon' => 'dashicons-book', + 'show_in_admin_bar' => true, + 'show_in_nav_menus' => true, + 'can_export' => true, + 'has_archive' => true, + 'exclude_from_search' => false, + 'publicly_queryable' => true, + 'capability_type' => 'page', + 'show_in_rest' => false, + ); + + register_post_type( self::KEY, $args ); + } +} diff --git a/src/Taxonomies/BookAuthorTaxonomy.php b/src/Taxonomies/BookAuthorTaxonomy.php new file mode 100644 index 0000000..321646a --- /dev/null +++ b/src/Taxonomies/BookAuthorTaxonomy.php @@ -0,0 +1,57 @@ + _x( 'Book Authors', 'Taxonomy General Name', 'wpifypt' ), + 'singular_name' => _x( 'Book Author', 'Taxonomy Singular Name', 'wpifypt' ), + 'menu_name' => __( 'Book Author', 'wpifypt' ), + 'all_items' => __( 'All Book Authors', 'wpifypt' ), + 'parent_item' => __( 'Parent Book Author', 'wpifypt' ), + 'parent_item_colon' => __( 'Parent Book Author:', 'wpifypt' ), + 'new_item_name' => __( 'New Book Author', 'wpifypt' ), + 'add_new_item' => __( 'Add Book Author', 'wpifypt' ), + 'edit_item' => __( 'Edit Book Author', 'wpifypt' ), + 'update_item' => __( 'Update Book Author', 'wpifypt' ), + 'view_item' => __( 'View Book Author', 'wpifypt' ), + 'separate_items_with_commas' => __( 'Separate items with commas', 'wpifypt' ), + 'add_or_remove_items' => __( 'Add or remove book authors', 'wpifypt' ), + 'choose_from_most_used' => __( 'Choose from the most used', 'wpifypt' ), + 'popular_items' => __( 'Popular Book Authors', 'wpifypt' ), + 'search_items' => __( 'Search Book Authors', 'wpifypt' ), + 'not_found' => __( 'Not Found', 'wpifypt' ), + 'no_terms' => __( 'No Book Authors', 'wpifypt' ), + 'items_list' => __( 'Book Authors list', 'wpifypt' ), + 'items_list_navigation' => __( 'Book Authors list navigation', 'wpifypt' ), + ); + + $rewrite = array( + 'slug' => 'book-author', + 'with_front' => true, + 'hierarchical' => false, + ); + + $args = array( + 'labels' => $labels, + 'hierarchical' => false, + 'public' => true, + 'show_ui' => true, + 'show_admin_column' => true, + 'show_in_nav_menus' => true, + 'show_tagcloud' => true, + 'rewrite' => $rewrite, + ); + + register_taxonomy( self::KEY, array( BookPostType::KEY ), $args ); + } +}