عکس mehrshaddarzi
Fast and standard development of WordPress pluginsPHP
موضوع‌ها
۶
فورک‌ها
۲
ستاره‌ها
۵
تاریخ ایجاد
۳ شهریور ۱۴۰۰
آخرین بروزرسانی
۲ ماه قبل
لایسنس
MIT License

Fast and standard development of WordPress plugins

Packagist Packagist Version GitHub repo size

WP-Trait is an easy framework for Standard and Fast development of WordPress plugins according php MVC model.

Table of Contents

Table of contents generated with markdown-toc

Installation

install with WP-CLI

You Can Generate new plugin with Wp-Trait Structure:

wp trait start

And fill Your Plugin information e.g. slug and namespace:

1/12 [--slug=<slug>]: wp-plugin
2/12 [--namespace=<namespace>]: WP_Plugin
3/12 [--plugin_name=<title>]: plugin-name
4/12 [--plugin_description=<description>]: plugin description
5/12 [--plugin_author=<author>]: Mehrshad Darzi
6/12 [--plugin_author_uri=<url>]: https://profiles.wordpress.org/mehrshaddarzi/
7/12 [--plugin_uri=<url>]: https://github.com/mehrshaddarzi/wp-trait
8/12 [--skip-tests] (Y/n): n
9/12 [--ci=<provider>]: travis
10/12 [--activate] (Y/n): y
11/12 [--activate-network] (Y/n): n
12/12 [--force] (Y/n): y

Read More About wp-cli-trait-command Package.

install with Composer

  1. First Create a new directory in your WordPress plugins dir e.g. wp-content/plugins/wp-user-mobile.

  2. Run This Command in your directory:

composer require mehrshaddarzi/wp-trait
  1. Create plugin main file e.g. wp-user-mobile.php and write:
/**
 * Plugin Name:       My Basics Plugin
 * Plugin URI:        https://example.com/plugins/the-basics/
 * Description:       Handle the basics with this plugin.
 * Version:           1.10.3
 * Requires at least: 5.2
 * Requires PHP:      7.2
 * Author:            John Smith
 * Author URI:        https://author.example.com/
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Update URI:        https://example.com/my-plugin/
 * Text Domain:       my-basics-plugin
 * Domain Path:       /languages
 */

# Load Package
require_once dirname(__FILE__) . '/vendor/autoload.php';

# Define Main Class
class WP_User_Mobile extends \WPTrait\Plugin
{

    public function __construct($slug, $args = [])
    {
        parent::__construct($slug, $args);
    }

    public function instantiate(){}

    public function register_activation_hook(){}

    public function register_deactivation_hook(){}

    public static function register_uninstall_hook(){}
}

new WP_User_Mobile('wp-user-mobile');
  1. You can add PSR-4 namespace in your Composer.json file:
{
    "require": {
        "mehrshaddarzi/wp-trait": "^1.0"
    },
    "autoload": {
        "psr-4": {
            "WP_User_Mobile\\": "src/"
        }
    }
}

Create New Model

Generate Model in Command Line

You Can Create new Model With Custom namespace in WP-CLI:

wp trait make model <class>

For Example:

wp trait make model Option

or

wp trait make model User\Register

Generate New Post-Type Model

wp trait make post-type Order

Generate New Taxonomy Model

wp trait make taxonomy City

Read More Options wp-cli-trait-command Package.

Generate Model manually

  1. Add new Admin.php file in src/ dir:
namespace WP_User_Mobile;

use WPTrait\Hook\Notice;
use WPTrait\Model;

class Admin extends Model
{
    use Notice;

    public function __construct($plugin)
    {
        parent::__construct($plugin);
    }

    public function admin_notices()
    {
        $text = __('This Notice is a example from your plugin', $this->plugin->textdomain);
        echo $this->add_alert($text, 'info');
    }
    
    public function method_name()
    {
        return 'Code is Poetry';
    }
}
  1. For Create new instance from this Class add to plugin main file in instantiate method:
public function instantiate()
{
    $this->Admin = new \WP_User_Mobile\Admin($this->plugin);
}

Global Function

You can access to all classes method with global template function by your plugin slug. for example if your plugin slug is wp-user-mobile, you can call method from Admin class:

echo wp_user_mobile()->Admin->method_name();

or use global variables:

gloabl $wp_user_mobile;
echo $wp_user_mobile->Admin->method_name();

This function show Code is Poetry.

How to Change Global variable and function name

You can add global parameters in PHP Main WordPress File:

new WP_User_Mobile('wp-user-mobile', ['global' => 'my_global']);

and Usage:

echo my_global()->Admin->method_name();

Also for disable global function set null.

new WP_User_Mobile('wp-user-mobile', ['global' => null]);

List of arguments when Create new Plugin object:

$default = [
   'main_file' => '',
   'global' => null,
   'prefix' => null,
   'when_load' => ['action' => 'plugins_loaded', 'priority' => 10]
];

WordPress Hooks

You can use $actions and $filters property in All Class, for example:

use WPTrait\Model;

class Post extends Model
{
    public $actions = [
        'init' => 'init_check_user',
        'save_post' => ['save_post_view', 10, 3],
        'pre_get_posts' => 'custom_query_action'
    ];

    public $filters = [
        'the_content' => 'add_custom_text',
        'show_admin_bar' => '__return_false',
        'rest_enabled' => false
    ];

    public function add_custom_text($content)
    {
        return $content . 'My Text';
    }

    public function save_post_view($post_ID, $post, $update)
    {
        if (!$update) {
            $this->post($post_ID)->meta->save('views', 1);
        }
    }
}

Model Property

Use WPDB

use $this->db for run Query in WordPress Database:

public function get_student_list()
{
    $lists = $this->db->get_results("SELECT ID, first_name FROM {$this->db->prefix}students ORDER BY ID");
    foreach ($lists as $student) {
        // Do Stuff
    }
}

Current Plugin information

for get Current plugin information use $this->plugin variable:

// Get Plugin Base Url
echo $this->plugin->url;

// Get Plugin Base Path
echo $this->plugin->path;

// Get Plugin TextDomain
echo $this->plugin->textdomain;

// Show All Variable
var_dump($this->plugin);

Get Current User data

for get Current User data use $this->user variable:

// Get Current User ID
// You Can Access All Object From WP_User Class
$this->user->id;

// Get Current User Email
$this->user->email;

// Get Current User Role
$this->user->roles;

// Get All User Meta
// Check Meta Collection Class
$this->user->meta->all();

Collection Class

This package has list of wordpress helper class, that you can uses.

Post

// Get Post
$this->post(1)->get();

// Get Post Meta
$this->post(1)->meta->all();

// Get Custom Meta
$this->post(1)->meta->get('key');

// Get Multiple Custom Meta Keys
$this->post(1)->meta->only(['key_1', 'key_2']);

// Save Post Meta
$this->post(1)->meta->save('key', 'value');

// Delete Post
$this->post(1)->delete();

// Get List Of post
$this->post->list(['type' => 'post', 'status' => 'publish', 'cache' => false]);

// Get Only SQL Query
$this->post->toSql([
    'type' => 'post',
    'status' => 'publish',
    'meta' => [
        'key' => 'is_active',
        'value' => 'yes',
        'compare' => '='
    ]
]);

// Get Post Thumbnail
$this->post(1)->thumbnail()->url

// Add Post
$insert_post = $this->post->add(['title' => '', 'content' => '']);
if($this->error->has($insert_post)){
    echo $this->error->message($insert_post);
}

// Edit Post
$this->post(38)->update(['title' => '']);

// Permalink
$this->post(1)->permalink();

// Check Exist
$this->post(53)->exists();

// Post Terms
$this->post(1)->terms('category');

// Post Comments
$this->post(1)->comments();

// Collection { Post + Meta + Terms }
$this->post(1)->collection(['meta_1', 'meta_2'], ['category', 'post_tag']);

Attachment


// Get Attachment
$attachment = $this->attachment(1)->get();

// Get Meta
$this->attachment(1)->meta->all();

// Delete Attachment
$this->attachment(1)->delete();

// Get Url
$this->attachment(1)->url();

// Get Image Src in Custom image size
$this->attachment(1)->src('thumbnail');

// Get Attachment File Path
$this->attachment(1)->path();

// Get Attachment Meta Data
$this->attachment(1)->metadata();

// Auto Upload File in WordPress Library
$attachment_id = $this->attachment->upload('image'); // <input type="file" name="image" />

// Regenerate Attachment image Size
$this->attachment(1)->generate_thumbnail();

// Get List Of WordPres Image Sizes
$this->attachment->get_wordpress_image_sizes();

// Get Uploads Dir
$this->attachment->upload_dir();

// Check Attachment type File (image or video or audio or other)
$this->attachment(1)->is('image');

// Get Size Of Attachment
$this->attachment(1)->size();

User

// Get User
$user = $this->user(1)->get();
/**
* List of object return:
* 
* $user->ID
* $user->user_login
* $user->user_pass
* $user->user_nicename
* $user->user_email
* $user->user_url
* $user->user_registered
* $user->user_activation_key
* $user->user_status
* $user->display_name
* $user->first_name
* $user->last_name
* $user->caps
* $user->roles
* $user->allcaps
*/

// Get All Meta
$this->user(1)->meta->all();

// Get Custom Meta
$this->user(1)->meta->get('meta_name');

// Save Meta
$this->user(1)->meta->update('phone', '09xxxxxxxx');

// Delete User
$this->user(1)->delete();

// Update User
$this->user(1)->update(['name' => 'Mehrshad Darzi', 'password' => '12345']);

// Add User
$this->user->add(['email' => 'info@site.com', 'username' => 'mehrshad']);

// Get Current User
$this->user->current();

// Check User is Login
$this->user->auth();

// Get current User id
$this->user->id();

// Check User Has Role
$this->user->has_role('administrator');

// Check User Has Capability
$this->user(1)->can('manage_options');

// Check Exist User Id
$this->user->exists(12);

// Login User
$this->user->login($username, $password, $remember = true);

// Authenticate User [Useful for REST-API or Ajax Without set any Cookie]
$this->user->authenticate($username, $password);

// Set New Password For User
$this->user(1)->password->set('new_password');

// Check User Password
$this->user(1)->password->check($this->request->input('password', 'trim'), $hash);

// Convert PlainText Password To Hash
$this->user->password->hash('123456');

// Generate Password With custom length
$this->user->password->generate(8, $special_chars = false);

// Set Role and Capability for User
$user = $this->user(1)->get();
$user->set_role('author');
$user->add_cap('cap_name');
$user->remove_cap('cap_name');
$user->add_role('role_name');
$user->remove_role('role_name');
$user->remove_all_caps();

Term

// Get Term
$this->term(1)->get();

// Get Meta
$this->term(1)->meta->all();

// Save Meta
$this->term(1)->meta->update('key', 'value');

// Delete Term
$this->term(1)->delete();

// Update Term
$this->term(1)->update(['name' => 'New name']);

// Add Term
$this->term->add('term name', ['parent' => 4, 'description' => ''], 'post_tag');

// Get List Terms
$this->term->list(['taxonomy' => 'product_cat', 'return' => 'id']);

// Get All Taxonomies in WordPress
$this->terms->get_taxonomies();

Option

// Get Option
$this->option('name')->get();

// Get default Value if Not Found
$this->option('name')->get($default);

// Get Nested Array Option Value With dot
$this->option('settings.user.id')->get();

// Save Option
$this->option('name')->save('value');

// Delete Options
$this->option('name')->delete();

// Add Option
$this->option->add('name', 'value', 'no');

Comment

// Get Comment
$this->comment(1)->get();

// Get Meta
$this->comment(1)->meta->all();

// Save Meta
$this->comment(1)->meta->update('key', 'value');

// Delete Meta
$this->comment(1)->meta->delete('key');

// Delete Comment
$this->comment(1)->delete();

// Update Comment
$this->comment(1)->update(['name' => 'Ali', 'approved' => true]);

// Add Comment
$this->comment->add(['post_id' => 1, 'name' => 'Mehrshad Darzi', 'content' => '']);

// Get List Comments
$this->comment->list(['post_id' => 1, 'nested' => true]);

Meta

Meta data list: post, user, term, comment.

// Get All Meta From Object
$this->post(1)->meta->all();

// Get Custom Meta
$this->user(1)->meta->get('first_name');

// Get Multiple Custom Meta Keys
$this->post(1)->meta->only(['key_1', 'key_2']);

// Get All Meta Key Except Custom keys
$this->post(1)->meta->except(['_edit_lock', '_edit_last']);

// Delete Meta
$this->user(1)->meta->delete('mobile');

// Save Meta
$this->term(1)->meta->save('key', 'value');

// Remove all Meta from Object
$this->comment(1)->meta->clean();

Request

// Get Request (GET or POST) field
# ?first_name=mehrshad&last_name=darzi&email=info@site.com&age=29
$this->request->input('first_name');

// Get Only `GET` fields
$this->request->query('email');

// Get Field with Custom filter e.g. trim value
$this->request->input('name', 'trim');

// Get field with multiple filter
$this->request->input('post_excerpt', ['trim', 'strip_tags']);

// Check Has input
$this->request->has('first_name');

// Check Equal fields
$this->request->equal('first_name', 'mehrshad');

// Check Exist and Not Empty fields
$this->request->filled('first_name');

// Check Exist and is Numeric value
$this->request->numeric('age');

// Get Custom Fields From Request
$this->request->only(['email', 'last_name']);

// Redirect in WordPress
$this->request->redirect('https://google.com', 302);

// Get $_FILES by id
$this->request->file('image'); //<input type="file" name="image" />

// Check Exists File
$this->request->hasFile('image');

// Get Cookie
$this->request->cookie('name');

// Get $_SERVER params
$this->request->server('REQUEST_URI');

// Check is REST API request
$this->request->is_rest();

// Check is Ajax Request
$this->request->is_ajax();

// New Request
$request = $this->request->new(
    'https://jsonplaceholder.typicode.com/todos/1',
    'GET',
    [
        'timeout' => 30,
        'ssl' => false,
        'headers' => [
            'Content-Type' => 'application/json',
        ]
    ]
);

if(!$this->error->has($request)) {
    return $request;
    # $request is an array:
    [
        'headers' => '', 
        'body' => '', 
        'response' => ['code' => '', 'message' => ''], 
        'cookies' => '', 
        'http_response' => ''
    ]
}

// Return Json Response
$this->response->json(['data' => 'value'], 200);

Handle Error

$input_email = $this->request->input('email');

// Define new error Handle system
$error = $this->error->new();

if(empty($input_email)) {
    $error->add('empty_email', __('Please Fill Your Email', 'my-plugin'));
}

if(!is_email($input_email)){
    $error->add('valid_email', __('Please Fill valid Email', 'my-plugin'));
}

if($this->error->has($error)){
    return $error; # Or use $error->get_error_messages();
} else {
    return true;
}

Cache and Transient

// Remember Cache last Post in One Hour
$this->cache->remember('latest_post', function(){
    return $this->post->list(['type' => 'product', 'return' => 'id'])
}, 'cache_group_name', $this->constant('hour'));

// Delete Cache
$this->cache->delete('cache_name', 'group');

// Add Cache
$this->cache->add('cache_name', $value, 'group_name', 5 * $this->constant('minute'));

// Get Cache
$this->cache->get('name', 'group');

// Remember Transient
$this->transient->remember('latest_users', function(){
    return $this->user->list(['role' => 'subscriber', 'return' => 'id'])
}, $this->constant('hour'));

// Delete transient
$this->transient->delete('name');

// Add Transient
$this->transient->add('name', $value, $this->constant('day'));

// Get Transient
$this->transient->get('name');

REST API

// Get REST API prefix url
$this->rest->prefix();

// get REST API url
$this->rest->url('namespace/endpoint');

// Making WordPress REST API Calls Internally
$this->rest->request('GET', 'wp/v2/posts', [ 'per_page' => 12 ]);

// Define new route in WordPress REST API with trait
class MY_REST_API extends Model
{
    use RestAPI;
    
    public function rest_api_init()
    {
        $this->route->add('student', 'register', [
            'method' => 'post',
            'function' => [$this, 'register'],
            'arg' => [
                'age' => [
                    'require' => true,
                    'validate' => function ($param, $request, $key) {
                        return is_numeric($param);
                    }
                ],
                'name' => [
                    'require' => true,
                    'sanitize' => function ($param, $request, $key) {
                        return strtolower($param);
                    }
                ]
            ]
        ]);
    }

    public function register($request)
    {
        # Get Params
        $name = $request->get_param('name');
        $age = $request->get_param('age');

        # insert To Database
        $this->db->insert(
            $this->db->prefix . 'student',
            ['name' => $name, 'age' => $age]
        );

        # Result Json
        return $this->response->json(
            ['message' => 'Completed Register', 'id' => $this->db->insert_id],
            200,
            ['X-Custom-Header' => 'value']
        );
    }
}

// Remove Route
$this->route->remove('/wp/v2/posts');

// Get List WordPress REST API routes
$list = $this->route->all();
$list->namespaces;
$list->routes;

Event

// Define single Event
$this->event->single($this->constant('hour'), 'action_name');

// Define recurring Event
$this->event->add(time(), 'hourly', 'action_name', []);

// Delete Event
$this->event->delete('action_name');

// Retrieve supported event recurrence schedules
$this->event->schedules();

// Get List Current CrobJobs
$this->event->list();

Log

// Add text log
# wp-content/debug.log
$this->log('text log', 'debug');

// Add Array log
$this->log(['user_id' => 1, 'status' => true], 'debug');

// Custom Log File
# wp-content/db.log
$this->log('text log', 'db');

// Custom Condition
# By Default when WP_DEBUG_LOG === true
# wp-content/plugin-slug.log
$is_active_plugin_log = get_option('my_plugin_active_log');
$this->log('text log', 'plugin-slug', $is_active_plugin_log);

// Change Datetime in Log File
# By default the dates are saved in the log file based on `UTC`, you can change it with the WordPress filter:
add_filter('wp_trait_log_date', function ($date, $type) {
    if ($type == "my-plugin-slug") {
        return date_i18n(get_option( 'date_format' ), current_time('timestamp')) . ' UTC+3.5';
    }
    return $date;
});

Collections Lists are available under /Collection.

Trait For WordPress Hooks

This package has list of php trait for WordPress Hooks, that you can uses. trait Lists are available under /Hook.

How To Work Trait Hooks

  1. First add trait in your class.
use Init;
  1. every method in your class that have init prefix in method name call in this action:
public function init(){
  // Code Here
}

public function init_check_user_login(){
  // Code Here
}

public function init_save_form_data() {
  // Code Here
}

List Of Trait With Prefix Method Name

Usage Method Prefix Variable option on your model
use Init; init_ public $init;
use AdminAssets; admin_enqueue_scripts_ public $adminAssets;
use AdminFooter; admin_footer_ public $adminFooter;
use AdminInit; admin_init_ public $adminInit;
use AdminMenu; admin_menu_ public $adminMenu;
use AdminSearchBox; get_search_fields_ public $adminSearchBox;
use Ajax; admin_ajax_{$method_name} public $ajax;
use BulkActions; bulk_actions_ & handle_bulk_actions_ public $bulkActions;
use FrontAssets; wp_enqueue_scripts_ public $frontAssets;
use ImageSize; setup_image_size_ public $imageSize;
use Notice; admin_notices_ public $notice;
use PostTypeColumns; columns_ & content_columns_ public $postTypeColumns;
use PreGetQuery; pre_get_posts_ & pre_get_users_ & pre_get_terms_ public $preGetQuery;
use RestAPI; rest_api_init_ public $restAPI;
use RowActions; row_actions_ public $rowActions;
use Shortcode; add_shortcode_ public $shortcode;
use SortableColumns; sortable_columns_ public $sortableColumns;
use TaxonomyColumns; columns_ & content_columns_ public $taxonomyColumns;
use UserColumns; columns_ & content_columns_ public $userColumns;
use UserProfileFields; admin_user_profile_fields_ & save_admin_user_profile_fields_ public $userProfileFields;
use ViewsSub; views_edit_sub_ public $viewsSub;

Example Create Ajax Request with Trait

use WPTrait\Hook\Ajax;

class Admin extends Model
{
    use Ajax;

    public $ajax = [
        'methods' => ['signup_user']
    ];

    public function admin_ajax_signup_user()
    {
        # Check User is Auth
        if ($this->user->auth()) {
            $this->response->json(['message' => __('You are a user of the site', 'wp-plugin')], 400);
        }

        # Get Input Email
        $email = $this->request->input('email');

        # Create User
        $user_id = $this->user->add([
            'email' => $email,
            'username' => $email
        ]);
        if ($this->error->has($user_id)) {
            $this->response->json(['message' => $this->error->message($user_id)], 400);
        }

        # Return Success
        $this->response->json(['user_id' => $user_id], 200);

        # Need for End of WordPress Ajax request
        exit;
    }
}

You can access top ajax request:

http://site.com/wp-admin/admin-ajax.php?action=signup_user&email=info@site.com

Starter Plugin

You Can read example folder ReadMe.md files /example. and start your project very fast.

Contributing

We appreciate you taking the initiative to contribute to this project. Contributing isn’t limited to just code. We encourage you to contribute in the way that best fits your abilities, by writing tutorials, giving a demo at your local meetup, helping other users with their support questions, or revising our documentation.

License

The WP-Trait is open-sourced software licensed under the MIT license.