Skip to content

Instantly share code, notes, and snippets.

@igorbenic
Last active February 11, 2023 21:53
Show Gist options
  • Select an option

  • Save igorbenic/83059a7bfb1351f06a45f8883e3f462a to your computer and use it in GitHub Desktop.

Select an option

Save igorbenic/83059a7bfb1351f06a45f8883e3f462a to your computer and use it in GitHub Desktop.
Simple WordPress Advertising Plugin: Introduction | http://www.ibenic.com/simple-wordpress-advertising-plugin-introduction
<?php
// ...
public function load_dependencies(){
/**
* Base functions
*/
require_once SWA_ROOT .'inc/swa-cpt.php';
}
// ...
<?php
function swa_cpt() {
$labels = array(
'name' => _x( 'SWA', 'Post Type General Name', 'swa' ),
'singular_name' => _x( 'SWA', 'Post Type Singular Name', 'swa' ),
'menu_name' => __( 'SWA', 'swa' ),
'parent_item_colon' => __( 'Parent Ad:', 'swa' ),
'all_items' => __( 'All Ads', 'swa' ),
'view_item' => __( 'View Ad', 'swa' ),
'add_new_item' => __( 'Add New Ad', 'swa' ),
'add_new' => __( 'Add New', 'swa' ),
'edit_item' => __( 'Edit Ad', 'swa' ),
'update_item' => __( 'Update Ad', 'swa' ),
'search_items' => __( 'Search Ad', 'swa' ),
'not_found' => __( 'Not found', 'swa' ),
'not_found_in_trash' => __( 'Not found in Trash', 'swa' ),
'featured_image' => __( 'Ad Image', 'swa' ),
'set_featured_image' => __( 'Set Ad image', 'swa' ),
'remove_featured_image' => __( 'Remove Ad image', 'swa' ),
'use_featured_image' => __( 'Use as Ad image', 'swa' ),
);
$args = array(
'labels' => $labels,
'supports' => array( 'title', 'thumbnail', ),
'hierarchical' => false,
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 2,
'menu_icon' => 'dashicons-slides',
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => true,
'publicly_queryable' => false,
'capability_type' => 'page',
);
register_post_type( 'swa', $args );
}
// Hook into the 'init' action
add_action( 'init', 'swa_cpt', 0 );
<?php
// ...
public function load_dependencies(){
/**
* Abstracts
*/
require_once SWA_ROOT .'inc/abstracts/class-swa-settings.php'; //Settings class
/**
* Classes
*/
require_once SWA_ROOT .'inc/class-swa-status.php';
/**
* Base functions
*/
require_once SWA_ROOT .'inc/swa-cpt.php';
require_once SWA_ROOT .'inc/swa-statuses.php';
/**
* Load only on admin side
*/
if( is_admin() ) {
require_once SWA_ROOT .'inc/class-swa-metabox.php'; // Extending Settings class for Metaboxes
add_action( 'load-post.php', array( $this, 'construct_metabox_on_ad' ) ); // Adding metabox only on post screen
add_action( 'load-post-new.php', array( $this, 'construct_metabox_on_ad' ) ); // Adding metabox only on new post screen
}
}
/**
* Construct metabox(es) when on Ad edit/new post page
* @return void
*/
public function construct_metabox_on_ad(){
require_once SWA_ROOT .'inc/swa-metaboxes.php';
}
// ...
<?php
class SWA_Metabox extends SWA_Settings {
/**
* Metabox Title
*/
protected $title = '';
/**
* Metabox ID
*/
protected $slug = '';
/**
* Array of post types for which we allow the metabox
*/
protected $post_types = array();
/**
* Post ID used to save or retrieve the settings
*/
protected $post_id = 0;
/**
* Metabox context
*/
protected $context = '';
/**
* Metabox priority
*/
protected $priority = '';
public function __construct( $title, $slug, $post_types = array( 'post' ), $context = 'advanced', $priority = 'default' ) {
if( $slug == '' || $context == '' || $priority == '' ) {
return;
}
if( $title == '' ) {
$this->title = ucfirst( $slug );
}
if( empty( $post_types ) ) {
return;
}
$this->title = $title;
$this->slug = $slug;
$this->post_types = $post_types;
$this->settings_id = $this->slug;
$this->context = $context;
$this->priority = $priority;
add_action( 'add_meta_boxes', array( $this, 'register' ) );
add_action( 'save_post', array( $this, 'save_meta_settings' ) );
}
public function register( $post_type ) {
if ( in_array( $post_type, $this->post_types ) ) {
add_meta_box( $this->slug, $this->title, array( $this, 'render' ), $post_type, $this->context, $this->priority );
}
}
public function render( $post ) {
$this->post_id = $post->ID;
wp_nonce_field( 'metabox_' . $this->slug, 'metabox_' . $this->slug . '_nonce' );
$this->init_settings();
echo '<table class="form-table">';
$this->render_fields( 'general' );
echo '</table>';
}
/**
* Get the settings from the database
* @return void
*/
public function init_settings() {
$post_id = $this->post_id;
$this->settings = get_post_meta( $post_id, $this->settings_id, true );
foreach ( $this->fields as $tab_key => $tab ) {
foreach ( $tab as $name => $field ) {
if( isset( $this->settings[ $name ] ) ) {
$this->fields[ $tab_key ][ $name ]['default'] = $this->settings[ $name ];
}
}
}
}
public function save_meta_settings( $post_id ) {
if( ! in_array( get_post_type( $post_id ), $this->post_types ) ) {
return $post_id;
}
// Check if our nonce is set.
if ( ! isset( $_POST['metabox_' . $this->slug . '_nonce'] ) ) {
return $post_id;
}
$nonce = $_POST['metabox_' . $this->slug . '_nonce'];
// Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce, 'metabox_' . $this->slug ) ) {
return $post_id;
}
/*
* If this is an autosave, our form has not been submitted,
* so we don't want to do anything.
*/
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
$this->post_id = $post_id;
$this->save_settings();
}
/**
* Save settings from POST
* @return [type] [description]
*/
public function save_settings(){
$this->posted_data = $_POST;
if( empty( $this->settings ) ) {
$this->init_settings();
}
foreach ($this->fields as $tab => $tab_data ) {
foreach ($tab_data as $name => $field) {
$this->settings[ $name ] = $this->{ 'validate_' . $field['type'] }( $name );
}
}
update_post_meta( $this->post_id, $this->settings_id, $this->settings );
}
}
<?php
$swa_metabox = new SWA_Metabox( __( 'Ad Info'), 'swa_info', array( 'swa' ) );
$swa_metabox->add_field(
array(
'name' => 'duration',
'title' => __( 'Duration of the Ad', 'swa'),
'default' => 7,
'desc' => __( 'Add duration in days', 'swa' )
)
);
<?php
/**
* Plugin Name: Simple WP Ads
* Plugin URI: https://www.ibenic.com/simple-wordpress-advertising-plugin-the-introduction/
* Description: Plugin made from the tutorial on ibenic.com
* Version: 1.0
* Author: Igor Benic
* Author URI: https://ibenic.com
*
* Text Domain: swa
* Domain Path: /languages/
*
* @package Simple WP Ads
* @author Igor Benic
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'SWA_ROOT', plugin_dir_path( __FILE__ ) );
define( 'SWA_URI', plugin_dir_url( __FILE__ ) );
<?php
// ...
/**
* Main Class
*/
class Simple_WP_Ads {
/**
* The single instance of the class.
*/
protected static $_instance = null;
/**
* Getting the static instance
* @return object
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Load dependencies
* @return void
*/
public function load_dependencies(){
// We will load our dependencies here
}
}
<?php
// ...
function swa(){
return Simple_WP_Ads::instance();
}
function swa_start(){
$swa = swa();
$swa->load_dependencies();
}
//Load our plugin once everything has been loaded
add_action( 'plugins_loaded', 'swa_start');
<?php
abstract class SWA_Settings {
/**
* ID of the settings
* @var string
*/
public $settings_id = '';
/**
* Tabs for the settings page
* @var array
*/
public $tabs = array(
'general' => 'General' );
/**
* Settings from database
* @var array
*/
protected $settings = array();
/**
* Array of fields for the general tab
* array(
* 'tab_slug' => array(
* 'field_name' => array(),
* ),
* )
* @var array
*/
protected $fields = array();
/**
* Data gotten from POST
* @var array
*/
protected $posted_data = array();
/**
* Get the settings from the database
* @return void
*/
public function init_settings() {
$this->settings = (array) get_option( $this->settings_id );
foreach ( $this->fields as $tab_key => $tab ) {
foreach ( $tab as $name => $field ) {
if( isset( $this->settings[ $name ] ) ) {
$this->fields[ $tab_key ][ $name ]['default'] = $this->settings[ $name ];
}
}
}
}
/**
* Save settings from POST
* @return [type] [description]
*/
public function save_settings(){
$this->posted_data = $_POST;
if( empty( $this->settings ) ) {
$this->init_settings();
}
foreach ($this->fields as $tab => $tab_data ) {
foreach ($tab_data as $name => $field) {
$this->settings[ $name ] = $this->{ 'validate_' . $field['type'] }( $name );
}
}
update_option( $this->settings_id, $this->settings );
}
/**
* Gets and option from the settings API, using defaults if necessary to prevent undefined notices.
*
* @param string $key
* @param mixed $empty_value
* @return mixed The value specified for the option or a default value for the option.
*/
public function get_option( $key, $empty_value = null ) {
if ( empty( $this->settings ) ) {
$this->init_settings();
}
// Get option default if unset.
if ( ! isset( $this->settings[ $key ] ) ) {
$form_fields = $this->fields;
foreach ( $this->tabs as $tab_key => $tab_title ) {
if( isset( $form_fields[ $tab_key ][ $key ] ) ) {
$this->settings[ $key ] = isset( $form_fields[ $tab_key ][ $key ]['default'] ) ? $form_fields[ $tab_key ][ $key ]['default'] : '';
}
}
}
if ( ! is_null( $empty_value ) && empty( $this->settings[ $key ] ) && '' === $this->settings[ $key ] ) {
$this->settings[ $key ] = $empty_value;
}
return $this->settings[ $key ];
}
/**
* Adding tab
* @param array $array options
*/
public function add_tab( $array ) {
$defaults = array(
'slug' => '',
'title' => '' );
$array = array_merge( $defaults, $array );
if( $array['slug'] == '' || $array['title'] == '' ){
return;
}
$this->tabs[ $array['slug'] ] = $array['title'];
}
/**
* Rendering fields
* @param string $tab slug of tab
* @return void
*/
public function render_fields( $tab ) {
if( ! isset( $this->fields[ $tab ] ) ) {
echo '<p>' . __( 'There are no settings on these page.', 'textdomain' ) . '</p>';
return;
}
foreach ( $this->fields[ $tab ] as $name => $field ) {
$this->{ 'render_' . $field['type'] }( $field );
}
}
/**
* Adding fields
* @param array $array options for the field to add
* @param string $tab tab for which the field is
*/
public function add_field( $array, $tab = 'general' ) {
$allowed_field_types = array(
'text',
'textarea',
'wpeditor',
'select',
'radio',
'checkbox' );
// If a type is set that is now allowed, don't add the field
if( isset( $array['type'] ) &&$array['type'] != '' && ! in_array( $array['type'], $allowed_field_types ) ){
return;
}
$defaults = array(
'name' => '',
'title' => '',
'default' => '',
'placeholder' => '',
'type' => 'text',
'options' => array(),
'default' => '',
'desc' => '',
);
$array = array_merge( $defaults, $array );
if( $array['name'] == '' ) {
return;
}
foreach ( $this->fields as $tabs ) {
if( isset( $tabs[ $array['name'] ] ) ) {
trigger_error( 'There is alreay a field with name ' . $array['name'] );
return;
}
}
// If there are options set, then use the first option as a default value
if( ! empty( $array['options'] ) && $array['default'] == '' ) {
$array_keys = array_keys( $array['options'] );
$array['default'] = $array_keys[0];
}
if( ! isset( $this->fields[ $tab ] ) ) {
$this->fields[ $tab ] = array();
}
$this->fields[ $tab ][ $array['name'] ] = $array;
}
/**
* Render text field
* @param string $field options
* @return void
*/
public function render_text( $field ){
extract( $field );
?>
<tr>
<th>
<label for="<?php echo $name; ?>"><?php echo $title; ?></label>
</th>
<td>
<input type="<?php echo $type; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" value="<?php echo $default; ?>" placeholder="<?php echo $placeholder; ?>" />
<?php if( $desc != '' ) {
echo '<p class="description">' . $desc . '</p>';
}?>
</td>
</tr>
<?php
}
/**
* Render textarea field
* @param string $field options
* @return void
*/
public function render_textarea( $field ){
extract( $field );
?>
<tr>
<th>
<label for="<?php echo $name; ?>"><?php echo $title; ?></label>
</th>
<td>
<textarea name="<?php echo $name; ?>" id="<?php echo $name; ?>" placeholder="<?php echo $placeholder; ?>" ><?php echo $default; ?></textarea>
<?php if( $desc != '' ) {
echo '<p class="description">' . $desc . '</p>';
}?>
</td>
</tr>
<?php
}
/**
* Render WPEditor field
* @param string $field options
* @return void
*/
public function render_wpeditor( $field ){
extract( $field );
?>
<tr>
<th>
<label for="<?php echo $name; ?>"><?php echo $title; ?></label>
</th>
<td>
<?php wp_editor( $default, $name, array('wpautop' => false) ); ?>
<?php if( $desc != '' ) {
echo '<p class="description">' . $desc . '</p>';
}?>
</td>
</tr>
<?php
}
/**
* Render select field
* @param string $field options
* @return void
*/
public function render_select( $field ) {
extract( $field );
?>
<tr>
<th>
<label for="<?php echo $name; ?>"><?php echo $title; ?></label>
</th>
<td>
<select name="<?php echo $name; ?>" id="<?php echo $name; ?>" >
<?php
foreach ($options as $value => $text) {
echo '<option ' . selected( $default, $value, false ) . ' value="' . $value . '">' . $text . '</option>';
}
?>
</select>
<?php if( $desc != '' ) {
echo '<p class="description">' . $desc . '</p>';
}?>
</td>
</tr>
<?php
}
/**
* Render radio
* @param string $field options
* @return void
*/
public function render_radio( $field ) {
extract( $field );
?>
<tr>
<th>
<label for="<?php echo $name; ?>"><?php echo $title; ?></label>
</th>
<td>
<?php
foreach ($options as $value => $text) {
echo '<input name="' . $name . '" id="' . $name . '" type="'. $type . '" ' . checked( $default, $value, false ) . ' value="' . $value . '">' . $text . '</option><br/>';
}
?>
<?php if( $desc != '' ) {
echo '<p class="description">' . $desc . '</p>';
}?>
</td>
</tr>
<?php
}
/**
* Render checkbox field
* @param string $field options
* @return void
*/
public function render_checkbox( $field ) {
extract( $field );
?>
<tr>
<th>
<label for="<?php echo $name; ?>"><?php echo $title; ?></label>
</th>
<td>
<input <?php checked( $default, '1', true ); ?> type="<?php echo $type; ?>" name="<?php echo $name; ?>" id="<?php echo $name; ?>" value="1" placeholder="<?php echo $placeholder; ?>" />
<?php echo $desc; ?>
</td>
</tr>
<?php
}
/**
* Validate text field
* @param string $key name of the field
* @return string
*/
public function validate_text( $key ){
$text = $this->get_option( $key );
if ( isset( $this->posted_data[ $key ] ) ) {
$text = wp_kses_post( trim( stripslashes( $this->posted_data[ $key ] ) ) );
}
return $text;
}
/**
* Validate textarea field
* @param string $key name of the field
* @return string
*/
public function validate_textarea( $key ){
$text = $this->get_option( $key );
if ( isset( $this->posted_data[ $key ] ) ) {
$text = wp_kses( trim( stripslashes( $this->posted_data[ $key ] ) ),
array_merge(
array(
'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true )
),
wp_kses_allowed_html( 'post' )
)
);
}
return $text;
}
/**
* Validate WPEditor field
* @param string $key name of the field
* @return string
*/
public function validate_wpeditor( $key ){
$text = $this->get_option( $key );
if ( isset( $this->posted_data[ $key ] ) ) {
$text = wp_kses( trim( stripslashes( $this->posted_data[ $key ] ) ),
array_merge(
array(
'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true )
),
wp_kses_allowed_html( 'post' )
)
);
}
return $text;
}
/**
* Validate select field
* @param string $key name of the field
* @return string
*/
public function validate_select( $key ) {
$value = $this->get_option( $key );
if ( isset( $this->posted_data[ $key ] ) ) {
$value = wc_clean( stripslashes( $this->posted_data[ $key ] ) );
}
return $value;
}
/**
* Validate radio
* @param string $key name of the field
* @return string
*/
public function validate_radio( $key ) {
$value = $this->get_option( $key );
if ( isset( $this->posted_data[ $key ] ) ) {
$value = wc_clean( stripslashes( $this->posted_data[ $key ] ) );
}
return $value;
}
/**
* Validate checkbox field
* @param string $key name of the field
* @return string
*/
public function validate_checkbox( $key ) {
$status = '';
if ( isset( $this->posted_data[ $key ] ) && ( 1 == $this->posted_data[ $key ] ) ) {
$status = '1';
}
return $status;
}
}
<?php
// ...
public function load_dependencies(){
/**
* Classes
*/
require_once SWA_ROOT .'inc/class-swa-status.php'; // Status class
/**
* Base functions
*/
require_once SWA_ROOT .'inc/swa-cpt.php';
require_once SWA_ROOT .'inc/swa-statuses.php'; // Instantiating Status class
}
// ...
<?php
class SWA_Status {
/**
* Post Types for this status
* @var array
*/
protected $post_type = array();
/**
* Status slug
* @var string
*/
protected $slug = '';
/**
* Enable the button
* 'true', 'publish' mixed enables publishing from this status
* 'update' string enables updating from this status
* 'false' boolean disabled/removes the button
* @var boolean
*/
protected $enable_action= false;
/**
* Default definitons
* @var array
*/
protected $defaults = array(
'label' => '',
'public' => null,
'protected' => null,
'private' => null,
'publicly_queryable' => null,
'exclude_from_search' => false,
'internal' => null,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => false,
'label_count' => ''
);
/**
* Status settings
* @var array
*/
protected $settings = array();
public function __construct( $args = array() ) {
if( empty( $args ) ) {
return;
}
if( ! isset( $args['post_type'] ) || empty( $args['post_type'] ) ) {
return;
}
if( ! isset( $args['slug'] ) || $args['slug'] == '' ) {
return;
}
$this->post_type = $args['post_type'];
$this->slug = $args['slug'];
if( isset( $args['action'] ) && in_array( $args['action'], array( false, true, 'publish', 'update' ) ) ) {
$this->enable_action = $args['action'];
}
if( ! isset( $args['label'] ) || $args['label'] == '' ) {
$args['label'] = ucfirst( $args['slug'] );
}
if( ! isset( $args['label_count'] ) || $args['label_count'] == '' ) {
$args['label_count'] = _n_noop( $args['label'] . ' <span class="count">(%s)</span>', $args['label'] . ' <span class="count">(%s)</span>');
}
unset( $args['slug'] );
unset( $args['post_type'] );
unset( $args['action'] );
$this->settings = wp_parse_args( $args, $this->defaults );
add_action( 'init', array( $this, 'register_status' ) );
add_action( 'admin_footer', array( $this, 'set_status' ) );
}
public function register_status() {
register_post_status( $this->slug, $this->settings );
}
public function set_status() {
$set_status = apply_filters( 'ibenic_custom_post_status_' . $this->slug, true );
if( ! $set_status ) {
return;
}
global $post;
if( ! $post ) {
return;
}
if( ! in_array( $post->post_type, $this->post_type ) ) {
return;
}
$complete = '';
$label = '';
if( $post->post_status == $this->slug ) {
$complete = ' selected=\"selected\"';
$label = '<span id=\"post-status-display\">' . $this->settings['label'] . '</span>';
}
?>
<script>
( function($){
$(document).ready(function(){
$('select#post_status').append( "<option value='<?php echo $this->slug; ?>' <?php echo $complete; ?>><?php echo $this->settings['label']; ?></option>");
$('.misc-pub-section label').append( "<?php echo $label; ?>");
<?php if( $complete != '' ) {
// If the post has this status check the preferred action
// If true or 'publish', we leave it as default
if( ! $this->enable_action ) {
echo '$("#publish").remove();';
} elseif( $this->enable_action === 'update' ) {
echo '$("#publish").val("Update");$("#publish").attr("name","save");$("#original_publish").val("Update");';
}
} ?>
});
})( jQuery );
</script>
<?php
}
}
<?php
/**
* SWA Statuses used for CPT
*/
new SWA_Status( array(
'post_type' => array( 'swa' ),
'slug' => 'ended',
'label' => _x( 'Ended', 'swa' ),
'action' => 'update',
'label_count' => _n_noop( 'Ended <span class="count">(%s)</span>', 'Ended <span class="count">(%s)</span>' ),
));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment