diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8ecb50e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019 Henner Setyono + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index dfd7b31..9e7a309 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,126 @@ -# Edje WordPress +# Edje WordPress Library -![Edje Wordpress](http://cdn.setyono.net/edge/wp-edge.jpg) +![Edje Wordpress](https://cdn.setyono.net/edge/wp-edge.jpg) -Simplify WordPress complicated functions. +WordPress is a fantastic web platform, but it's complicated for developer. This plugin helps simplifying many functions. -## Requirement +**REQUIREMENT** -- PHP 5.6+ -- WordPress 4.9+ +- PHP 7.0+ +- WordPress 5.0+ -## Sample Features +**TABLE OF CONTENTS** -Create new Custom Post Type +1. [Custom Post Type](#custom-post-type) +1. [Custom Taxonomy](#custom-taxonomy) +1. [Theme Customizer](#theme-customizer) +1. [Post Table Columns](#post-table-columns) +1. [Other Features](#other-features) + +## 1. Custom Post Type + +[Read full documentation »](https://github.com/hrsetyono/edje-wp-library/wiki/Custom-Post-Type) + +![Edje WordPress - Product Custom Post Type](https://cdn.setyono.net/edjewp/cpt-product.jpg) ```php -H::register_post_type( 'product' ); +H::register_post_type( 'product', [ + 'icon' => 'dashicons-cart', + 'supports' => [ 'comments' ] +] ); ``` -Add new Admin Sidebar menu: +## 2. Custom Taxonomy + +[Read full documentation »](https://github.com/hrsetyono/edje-wp-library/wiki/Custom-Taxonomy) + +![Edje WordPress - Product Custom Post Type](https://cdn.setyono.net/edjewp/cpt-product.jpg) ```php -H::add_menu( 'Home' array( - 'slug' => 'post.php?post=10&action=edit', - 'icon' => 'dashicons-admin-home', - 'position' => 'above Pages' -)); +H::register_taxonomy( 'brand' , [ + 'post_type' => 'product', +] ); ``` -Sending push notification after publishing new post: + +## 3. Theme Customizer + +[Read full documentation »](https://github.com/hrsetyono/edje-wp-library/wiki/Customizer) + +You can access this from **Appearance > Customizer**. By default, only Administrator role can see this page. + +![Edje Customize Example](https://cdn.setyono.net/edjewp/cust-sample-header.jpg) ```php -add_action( 'publish_post', 'after_publish_notify_users', 10, 2 ); - -function after_publish_notify_users( $id, $post ) { - $payload = array( - 'title' => $post->post_title, - 'body' => $post->post_excerpt, - ); - H::send_push( $payload ); +add_action( 'customize_register', 'my_customize_register' ); + +function my_customize_register( $wp_customize ) { + $c = H::customizer( $wp_customize ); // init the class + + $c->add_section( 'header' ); + + $c->add_theme_mod( 'head_code', 'code_editor htmlmixed' ); + $c->add_theme_mod( 'background_color', 'color' ); + $c->add_theme_mod( 'phone_no', 'text' ); } ``` -## Visit our [WIKI](https://github.com/hrsetyono/edje-wp/wiki) for full documentation. +## 4. Post Table Columns + +[Read full documentation »](https://github.com/hrsetyono/edje-wp-library/wiki/Table-Columns) + +![Edje WordPress - Complex Column](https://cdn.setyono.net/edjewp/cpt-column.jpg) + +```php +H::override_columns( 'product', [ + 'title', + 'price', + 'Discount' => 'show_discounted_price', +] ); + +function show_discounted_price( $post, $fields ) { + $discount = isset( $fields['discount'] ) ? $fields['discount'][0] : null; + $price = isset( $fields['price'] ) ? $fields['price'][0] : null; + + $total = $price - ($price * $discount / 100); + $saving = $price - $total; + + return $discount . '% Discount - You save ' . $saving; +} +``` + +## 5. Other Features + +All these features are enabled by default: + +**JavaScript** + +- Removed emoji converter. +- Removed ability to embed WordPress post. +- Removed Jetpack's Device-px script because it's useless. +- Removed Jetpack's Sharing script. It's only for sharing via email which is rarely used. +- [COMING SOON] Removed jQuery and jQuery migrate. If you need jQuery, enqueue it in your Theme. + +**SEO** + +- Disabled automatic URL guessing if a visitor enters 404 page. +- Disabled Jetpack's Open Graph module when Yoast or The SEO Framework is installed + +**CUSTOMIZER** + +- Added Head and Footer code field. +- Added Theme Color field in Site Identity for changing the actionbar color in Chrome mobile. + +**EDIT POST** + +- Removed Medium-Large size when uploading new image. +- Changed the Category checklist to always be in same the position. +- Added a better styling to WYSIWYG classic editor. +- Added styling to Gutenberg editor for ACF block. + +**OTHER** + +- Removed "Created by Wordpress" message in the bottom-left of WP Admin +- Changed the login error message to "Sorry, your username or password is wrong" instead of giving hint of which one is wrong. +- Changed the Wordpress logo in login page to the one you have set in Customizer > Site Identity. +- Added the ability to edit TWIG file in Appearance > Editor. But it's still recommended to disable Editor by adding this line in WP Config: `define('DISALLOW_FILE_EDIT', true);` \ No newline at end of file diff --git a/admin/h-on-activate.php b/activation-hook.php similarity index 84% rename from admin/h-on-activate.php rename to activation-hook.php index 73a6cfc..46cf01d 100644 --- a/admin/h-on-activate.php +++ b/activation-hook.php @@ -1,85 +1,107 @@ _create_default_page(); - $this->_create_default_post(); - $this->_set_default_setting(); + // If first time activation + if( !isset($options['init'] ) ) { + $this->_create_frontpage(); + $this->_create_blogpage(); + $this->_set_default_setting(); $this->_create_default_nav(); $options['init'] = true; } - // if post not initialized - if(!isset($options['post_init']) ) { + // If sample post never created before + if( !isset($options['post_init']) ) { $this->_create_default_post(); $options['post_init'] = true; } - update_option('h_options', $options); + update_option( 'h_options', $options ); } + /* - Create default page for HOME and BLOG + Run when the plugin is deactivated */ - function _create_default_page() { - $frontpage_id = get_option('page_on_front'); - $blogpage_id = get_option('page_for_posts'); + function deactivation_hook() { + + } + + ///// + + /* + Create default Frontpage + */ + private function _create_frontpage() { + $frontpage_id = get_option( 'page_on_front' ); // if already exists, just change the title - if($frontpage_id) { - $args = array( + if( $frontpage_id ) { + $args = [ 'ID' => $frontpage_id, 'post_title' => get_bloginfo() - ); + ]; - wp_update_post($args); + wp_update_post( $args ); } - // if not exists, create it + // if does not exists, create it else { - $home = array( + $home = [ 'post_title' => get_bloginfo(), 'post_type' => 'page', 'post_status' => 'publish', - ); + ]; - $home_id = wp_insert_post($home); - update_option('show_on_front', 'page'); - update_option('page_on_front', $home_id); + $home_id = wp_insert_post( $home ); + update_option( 'show_on_front', 'page' ); + update_option( 'page_on_front', $home_id ); } + } - // create posts page if not set - if(!$blogpage_id) { - $blog = array( + /* + Create default Blog page + */ + private function _create_blogpage() { + $blogpage_id = get_option( 'page_for_posts' ); + + // If does not exists, create one + if( !$blogpage_id ) { + $blog = [ 'post_title' => 'Blog', 'post_type' => 'page', 'post_status' => 'publish', - ); + ]; - $blog_id = wp_insert_post($blog); - update_option('page_for_posts', $blog_id); + $blog_id = wp_insert_post( $blog ); + update_option( 'page_for_posts', $blog_id ); } } + /* Create default navigation menu */ - function _create_default_nav() { + private function _create_default_nav() { $navs = array( // MAIN array( @@ -121,8 +143,6 @@ function _create_default_nav() { $locations = get_theme_mod('nav_menu_locations'); foreach($navs as $nav): - // var_dump($nav); - // exit(); // if doesn't exist AND the location isn't occupied if(! wp_get_nav_menu_object($nav['name'] && !has_nav_menu($nav['location'])) ) { // create empty menu @@ -142,32 +162,33 @@ function _create_default_nav() { } /* - Create sample post that also acts as guide to WordPress + Create sample post content */ - function _create_default_post() { - $args = array( + private function _create_default_post() { + $args = [ 'post_title' => 'Welcome to WordPress', 'post_name' => 'welcome-to-wordpress', 'post_type' => 'post', 'post_content' => $this->sample_content, 'post_status' => 'publish' - ); + ]; - // if post ID 1 exist - if(is_string(get_post_status(1)) ) { + // if post ID 1 exist, edit it + if( is_string(get_post_status(1)) ) { $args['ID'] = 1; - wp_update_post($args); + wp_update_post( $args ); } + // if does not exist, create new post with ID 1 else { $args['import_id'] = 1; - wp_insert_post($args); + wp_insert_post( $args ); } } /* Default setting for Standard website */ - function _set_default_setting() { + private function _set_default_setting() { // general update_option('use_smiles', 0); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9de2c3e --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "pixelstudio/edje-wp-library", + "version": "2.0.0", + "description": "Plugin to simplify WordPress complicated functions.", + "keywords": ["wordpress", "plugin", "library"], + "type": "wordpress-plugin", + "homepage": "https://github.com/hrsetyono/edje-wp-library/", + "authors": [ + { + "name": "Pixel Studio", + "email": "info@pixelstudio.id", + "homepage": "https://pixelstudio.id" + } + ], + "license": "MIT", + "require": { + "php": ">=7.0.0", + "composer/installers": ">=1.6.0" + } +} \ No newline at end of file diff --git a/edje-wp-library.php b/edje-wp-library.php new file mode 100644 index 0000000..52b2522 --- /dev/null +++ b/edje-wp-library.php @@ -0,0 +1,281 @@ +load_modules(); + $this->register_activation_hook(); + } + + /* + Load all modules + */ + private function load_modules() { + add_action( 'plugins_loaded' , function() { + $this->module_helper(); + $this->module_post_type(); + $this->module_customizer(); + $this->module_admin_sidenav(); + $this->module_change_default(); + $this->module_vendor(); + } ); + } + + /* + Register activation and deactivation hook + */ + private function register_activation_hook() { + if( defined( 'EDJE' ) ) { + require_once 'activation-hook.php'; + + register_activation_hook( H_BASE, ['H_Hook', 'activation_hook'] ); + register_deactivation_hook( H_BASE, ['H_Hook', 'deactivation_hook'] ); + } + } + + // + + private function module_helper() { + require_once 'module-helper/h-helper.php'; + + // only if not in admin + if( !is_admin() ) { + require_once 'module-helper/h-shortcode.php'; + new H_Shortcode(); + } + + // If Timber is activated + if( class_exists('Timber') ) { + require_once 'module-helper/h-twig.php'; + require_once 'module-helper/timber-block.php'; + + new H_Twig(); + } + } + + + private function module_post_type() { + require_once 'module-post-type/post-type.php'; + require_once 'module-post-type/taxonomy.php'; + + if( is_admin() ) { + require_once 'module-post-type/post-column.php'; + require_once 'module-post-type/post-filter.php'; + require_once 'module-post-type/post-action.php'; + } + } + + + private function module_customizer() { + require_once 'module-customizer/customizer.php'; + require_once 'module-customizer/customizer-default.php'; + + new \h\Customizer_Default(); + } + + + private function module_admin_sidenav() { + if( is_admin() ) { + require_once 'module-admin-sidenav/sidenav.php'; + require_once 'module-admin-sidenav/sidenav-sub.php'; + } + } + + + private function module_change_default() { + require_once 'module-change-default/default-public.php'; + new \h\Default_Public(); + + // if in admin + if( is_admin() ) { + require_once 'module-change-default/default-codemirror.php'; + require_once 'module-change-default/default-admin.php'; + new \h\Default_Admin(); + new \h\Default_Codemirror(); + } + // if not in admin + else { + require_once 'module-change-default/default-jetpack.php'; + require_once 'module-change-default/default-seo.php'; + new \h\Default_Jetpack(); + new \h\Default_SEO(); + } + } + + + private function module_vendor() { + require_once 'module-vendor/inflector.php'; + require_once 'module-vendor/parsedown.php'; + } +} + +new Edje_WP_Library(); +endif; + + +///// + + +/* + Main portal for calling all static methods +*/ +if( !class_exists('H') ): +class H { + /* + Register custom post type + */ + static function register_post_type( string $name, array $args = [] ) { + $pt = new \h\Post_Type( $name, $args ); + $pt->register(); + } + + /* + Register custom taxonomy + */ + static function register_taxonomy( string $name, array $args ) { + $tx = new \h\Taxonomy( $name, $args ); + $tx->register(); + } + + + /* + Override all columns in the Post Type table with this one + + @param $post_type (string) + @param $args (array) - List of columns + */ + static function override_columns( $post_type, $args ) { + if( !is_admin() ) { return false; } + + $pc = new \h\Post_Column(); + $pc->override( $post_type, $args ); + } + + // Alias for override_columns + static function register_columns( $post_type, $args ) { + self::override_columns( $post_type, $args ); + } + + + /* + Append a column to the Post Type table + @since 0.9.0 + + @param $post_type (string). + @param $title (string) - Column title, or slug of Custom Fields. + @param $value (function) - Optional. If $title is already slug of custom fields, this can be null. + */ + static function add_column( $post_type, $title, $value = null ) { + if( !is_admin() ) { return false; } + + $pc = new \h\Post_Column(); + $pc->add( $post_type, $title, $value ); + } + + + ///// ACTIONS + // TODO: still not working + + static function add_actions( $post_type, $actions ) { + if( !is_admin() ) { return false; } + + $pa = new \h\Post_Action( $post_type, $actions ); + $pa->add(); + } + + static function replace_actions( $post_type, $actions ) { + if( !is_admin() ) { return false; } + + $pa = new \h\Post_Action( $post_type, $actions ); + $pa->replace(); + } + + + ///// ADMIN SIDENAV + + static function remove_menu( $args ) { + if( !is_admin() ) { return false; } + + $menu = new \h\Sidenav( $args ); + $menu->remove(); + } + + static function add_menus( $args ) { + if( !is_admin() ) { return false; } + + $menu = new \h\Sidenav( $args ); + $menu->add(); + } + + static function add_menu( $title, $args ) { + $new_args = [ + $title => $args + ]; + + H::add_menus( $new_args ); + } + + static function add_submenu( $parent_title, $args ) { + H::add_menus( [ + $parent_title => [ + 'position' => "on $parent_title", + 'submenu' => $args + ] + ] ); + } + + static function add_menu_counter( $parent_title, $count_cb ) { + H::add_menus( [ + $parent_title => [ + 'position' => "on $parent_title", + 'counter' => $count_cb, + ] + ] ); + } + + + + ///// CUSTOMIZER + + /* + Inititate Edje customizer object + @param $wp_customize (Obj) - WP_Customize object from customize_register action. + */ + static function customizer( $wp_customize ) { + return new \h\Customizer( $wp_customize ); + } + + + ///// WEB PUSH + + static function send_push( $payload, $target = null ) { + if( !class_exists('H_WebPush') ) { + var_dump( 'ERROR: Edje Web-Push plugin is not installed.' ); + return false; + } + + $push = new \h\WebPush_Send(); + $push->send( $payload, $target ); + } + +} + +endif; // class_exists \ No newline at end of file diff --git a/module-admin-sidenav/_run.php b/module-admin-sidenav/_run.php deleted file mode 100644 index ec65601..0000000 --- a/module-admin-sidenav/_run.php +++ /dev/null @@ -1,9 +0,0 @@ -post_title; - } - // reposition the tax name - elseif( is_tax() ) { - $term_title = single_term_title( '', false ); - $tax = get_taxonomy( get_query_var('taxonomy') ); - - $title = $term_title . ' - ' . $tax->labels->singular_name; - - return $title . ' | ' . get_bloginfo(); - } - // use post title + site name if on other page - else { - return $title . ' | ' . get_bloginfo(); - } - } - - /* - Add custom SEO tag - @filter wp_head - */ - function add_seo_tag() { - global $post; - $description = ''; - - // if not front page, use excerpt from content - if( !is_front_page() && $post ) { - $excerpt = $post->post_excerpt ? $post->post_excerpt : \_H::trim_content( $post->post_content ); - $description = $excerpt ? $excerpt : $description; - } else { - $description = get_bloginfo( 'description' ); - } - - echo ""; - } - - /* - Add custom meta tag - @filter wp_head - */ - function add_color_tag() { - $color = get_background_color(); - if( $color ) { - echo ""; - } - } - - /* - Add a new tag to Jetpack's list. If og:description doesn't exist, do not add any new tag - - @filter jetpack_open_graph_tags - @param array $tags - Existing list - @return array - Added list - */ - function jetpack_meta_tags($tags) { - if ( isset( $tags['og:description'] ) ) { - $tags['description'] = $tags['og:description']; - } - return $tags; - } - - /* - Replace property="description" by name="description" in the new tag. - - @filter jetpack_open_graph_output - @param string $og_tag - The description tag - @return string - The modified description tag - */ - function jetpack_meta_output($og_tag) { - $og_tag = str_replace( 'property="description"', 'name="description"', $og_tag ); - return $og_tag; } /* diff --git a/module-customizer/_run.php b/module-customizer/_run.php deleted file mode 100644 index f62576f..0000000 --- a/module-customizer/_run.php +++ /dev/null @@ -1,9 +0,0 @@ -add_code(); + // add the custom code to Head or Footer + add_action( 'wp_head', array($this, 'add_head_code'), 100 ); + add_action( 'wp_footer', array($this, 'add_footer_code'), 100 ); } /* @@ -24,16 +26,16 @@ function head_footer_code( $wp_customize ) { $c = \H::customizer( $wp_customize ); $c->add_section( 'h_head_footer', array( - 'title' => __( 'Head & Footer Code', 'h' ), - 'description' => __( 'Add custom code for Head and Footer area', 'h' ), + 'title' => __( 'Head & Footer Code' ), + 'description' => __( 'Add custom code for Head and Footer area' ), ) ); $c->add_option( 'h[head_code]', 'code_editor htmlmixed', array( - 'label' => __( 'HEAD code', 'h' ), + 'label' => __( 'HEAD code' ), ) ); $c->add_option( 'h[footer_code]', 'code_editor htmlmixed', array( - 'label' => __( 'FOOTER code', 'h' ), + 'label' => __( 'FOOTER code' ), ) ); } @@ -53,26 +55,38 @@ function site_identity( $wp_customize ) { } $c->add_theme_mod( 'background_color', 'color', array( - 'label' => 'Theme Color', - 'description' => 'Used for taskbar color in Mobile browser' + 'label' => __('Theme Color'), + 'description' => __('Used for taskbar color in Mobile browser') ) ); } - ///// + //// /* - Add extra code to HEAD and FOOTER + Add custom code to wp_head() section. + @action wp_head 100 */ - private function add_code() { + function add_head_code() { + // Add Theme color tag + $color = get_background_color(); + if( $color ) { + echo ""; + } + + // Add custom HEAD code if( isset( $this->option['head_code'] ) ) { - add_action( 'wp_head', array($this, 'add_head_code'), 100 ); + echo $this->option['head_code']; } + } + /* + Add custom code to wp_footer() section. + @action wp_footer 100 + */ + function add_footer_code() { if( isset( $this->option['footer_code'] ) ) { - add_action( 'wp_footer', array($this, 'add_footer_code'), 100 ); + echo $this->option['footer_code']; } } - function add_head_code() { echo $this->option['head_code']; } - function add_footer_code() { echo $this->option['footer_code']; } } diff --git a/module-helper/_run.php b/module-helper/_run.php deleted file mode 100644 index 99f3370..0000000 --- a/module-helper/_run.php +++ /dev/null @@ -1,23 +0,0 @@ - $char_number ) { - $text = substr( $text, 0, $char_number ); - $text = substr( $text, 0, strrpos( $text, ' ' ) ); - - $punctuation = '.!?:;,-'; // punctuation you want removed - - $text = (strspn(strrev($text), $punctuation) != 0) - ? - substr($text, 0, -strspn(strrev($text), $punctuation)) - : - $text; - } - $text = htmlentities( $text, ENT_QUOTES ); - return $text; + static function to_icon( $name ) { + $full_name = 'dashicons-' . str_replace( 'dashicons-', '', $name ); + return $full_name; } /* @@ -117,32 +100,4 @@ static function is_plugin_active( $slug ) { return false; } -} - -// PHP 5.5 Array Column -if (! function_exists('array_column') ) { - function array_column( array $input, $columnKey, $indexKey = null ) { - $array = array(); - foreach ( $input as $value ) { - if( ! isset( $value[$columnKey] ) ) { - trigger_error('Key "$columnKey" does not exist in array'); - return false; - } - if( is_null( $indexKey ) ) { - $array[] = $value[$columnKey]; - } - else { - if ( ! isset( $value[$indexKey] ) ) { - trigger_error('Key "$indexKey" does not exist in array'); - return false; - } - if ( ! is_scalar($value[$indexKey])) { - trigger_error('Key "$indexKey" does not contain scalar value'); - return false; - } - $array[$value[$indexKey]] = $value[$columnKey]; - } - } - return $array; - } -} +} \ No newline at end of file diff --git a/module-helper/h-shortcode.php b/module-helper/h-shortcode.php index f0e0ab4..2d6d16b 100644 --- a/module-helper/h-shortcode.php +++ b/module-helper/h-shortcode.php @@ -4,9 +4,10 @@ */ class H_Shortcode { function __construct() { - add_shortcode( 'row', array($this, 'row') ); + add_shortcode( 'row', array($this, 'row') ); // deprecated, use [grid] + add_shortcode( 'column', array($this, 'column') ); // deprecated, use [grid] + add_shortcode( 'grid', array($this, 'grid') ); - add_shortcode( 'column', array($this, 'column') ); // remove empty
on shortcode
add_filter( 'the_content', array($this, 'shortcode_unautop'), 10 );
@@ -22,13 +23,13 @@ function row( $atts, $content = null ) {
/*
Wrap the content with CSS3 Grid (only works in Edje >=2.0).
- You need to specify which is opening / closing grid by adding "start" and "end" at the parameter.
+ You need to specify which is opening / closing grid by adding "start" and "end" at the parameter.
- [grid size="8 start"]
- ...
- [/grid] [grid size="4 end"]
- ...
- [/grid]
+ [grid size="8 start"]
+ ...
+ [/grid] [grid size="4 end"]
+ ...
+ [/grid]
*/
function grid( $atts, $content = null ) {
$atts = shortcode_atts( array(
@@ -36,23 +37,23 @@ function grid( $atts, $content = null ) {
), $atts);
$opening = '';
- $closing = '';
+ $closing = '';
// if contains "start", add opening of grid
if( preg_match( '/start/', $atts['size'] ) ) {
- $opening .= '