WordPress.org

Plugin Directory

Changeset 1638674


Ignore:
Timestamp:
04/16/17 20:02:14 (4 months ago)
Author:
travislopes
Message:

Email Post Approval (2.0)

  • Added security enhancements when saving settings.
  • Rewrote plugin.
Location:
email-post-approval
Files:
3 added
2 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • email-post-approval/trunk/email-post-approval.php

    r782670 r1638674  
    11<?php 
    2  
    3     /* 
    4     Plugin Name: Email Post Approval 
    5     Description: Ability to review and approve posts for publishing via email. 
    6     Version: 1.2.2 
    7     Author: BinaryM Inc - Travis Lopes & Matt McInvale 
    8     Author URI: http://binarym.com/ 
    9     License: GPL2 
    10     */ 
    11      
    12     require_once('email-post-approval_options.php'); 
    13          
    14     class Email_Post_Approval { 
    15          
    16         var $post_status_types; 
    17         var $email_fields; 
    18      
    19         // Initialize plugin     
    20         public function __construct() { 
    21             add_action('save_post', array($this, 'send_email')); 
    22         } 
    23          
    24         // Fire off function when plugin is activated 
    25         public function activation() { 
    26             add_option('epa_send_to', get_bloginfo('admin_email')); 
    27             add_option('epa_post_statuses', array('pending')); 
    28             add_option('epa_email_fields', array('title', 'post_author', 'post_date', 'categories', 'tags', 'post_meta', 'body', 'thumbnail')); 
    29         }        
    30          
    31         // Fire off function when plugin is deactivated 
    32         public function deactivation() { 
    33             delete_option('epa_send_to'); 
    34             delete_option('epa_post_statuses'); 
    35             delete_option('epa_email_fields'); 
    36         } 
    37          
    38         // Generate hash for the post        
    39         private function generate_hash($post_ID){ 
    40             // Check to see if there is already a hash 
    41             $existing_hash = get_post_meta($post_ID, '_epa-approve_key', true); 
    42             if($existing_hash) { 
    43                 return $existing_hash; 
     2/** 
     3Plugin Name: Email Post Approval 
     4Description: Review and approve posts for publishing right from your inbox 
     5Version: 2.0 
     6Author: <a href="http://travislop.es">Travis Lopes</a> and <a href="http://binarym.com">Matt McInvale</a> 
     7Author URI: http://binarym.com/ 
     8License: GPL2 
     9 */ 
     10 
     11class Email_Post_Approval { 
     12 
     13    /** 
     14     * Instance of Share Drafts Publicly class 
     15     * 
     16     * @var    object 
     17     * @access private 
     18     * @static 
     19     */ 
     20    private static $_instance = null; 
     21 
     22    /** 
     23     * Get instance of this class. 
     24     * 
     25     * @access public 
     26     * @static 
     27     * @return $_instance 
     28     */ 
     29    public static function get_instance() { 
     30 
     31        if ( null === self::$_instance ) { 
     32            self::$_instance = new self; 
     33        } 
     34 
     35        return self::$_instance; 
     36 
     37    } 
     38 
     39    /** 
     40     * Register needed hooks. 
     41     * 
     42     * @since  1.0 
     43     * @access public 
     44     */ 
     45    public function __construct() { 
     46 
     47        register_activation_hook( __FILE__, array( 'Email_Post_Approval', 'activation' ) ); 
     48        register_deactivation_hook( __FILE__, array( 'Email_Post_Approval', 'deactivation' ) ); 
     49 
     50        add_action( 'save_post', array( $this, 'send_email' ) ); 
     51        add_action( 'init', array( $this, 'approve_post' ), 1 ); 
     52 
     53        add_action( 'admin_menu', array( $this, 'register_settings_page' ) ); 
     54 
     55    } 
     56 
     57 
     58 
     59 
     60 
     61    // # APPROVAL EMAIL ------------------------------------------------------------------------------------------------ 
     62 
     63    /** 
     64     * Send post approval email. 
     65     * 
     66     * @since  1.0 
     67     * @access public 
     68     * 
     69     * @param int $post_id Post ID to send approval email for. 
     70     * 
     71     * @uses Email_Post_Approval::generate_hash() 
     72     */ 
     73    public function send_email( $post_id = 0 ) { 
     74 
     75        // If this is an auto-save post, exit. 
     76        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { 
     77            return; 
     78        } 
     79 
     80        // Get post. 
     81        $post = get_post( $post_id ); 
     82 
     83        // If post could not be found, exit. 
     84        if ( ! $post ) { 
     85            return; 
     86        } 
     87 
     88        // If this is a revision post, exit. 
     89        if ( 'revision' === $post->post_type ) { 
     90            return; 
     91        } 
     92 
     93        // Get post statuses that require approval. 
     94        $approval_statuses = get_option( 'epa_post_statuses' ); 
     95 
     96        // If post is not a status that requires approval, exit. 
     97        if ( ! in_array( $post->post_status, $approval_statuses ) ) { 
     98            return; 
     99        } 
     100 
     101        // Get default author, post author, meta and taxonomies. 
     102        $default_author  = get_userdata( get_option( 'epa_default_author' ) ); 
     103        $post_author     = get_userdata( $post->post_author ); 
     104        $post_meta       = get_post_meta( $post->ID ); 
     105        $post_taxonomies = get_the_taxonomies( $post->ID, array( 'template' => '%l' ) ); 
     106 
     107        // Get post fields to display. 
     108        $fields_to_display = get_option( 'epa_email_fields' ); 
     109 
     110        // Initialize message. 
     111        $message = ''; 
     112 
     113        // Loop through email fields and generate message. 
     114        foreach ( $fields_to_display as $field ) { 
     115 
     116            switch ( $field ) { 
     117 
     118                case 'body': 
     119                    $message .= '<br/><strong>Post Body:</strong><br />'; 
     120                    $message .= str_replace( '<!--more-->', '&lt;!--more--&gt;', $post->post_content ); 
     121                    $message .= '<br /><br />'; 
     122                    break; 
     123 
     124                case 'categories': 
     125                    $message .= '<strong>Categories:</strong> '; 
     126                    $message .= isset( $post_taxonomies['category'] ) ? $post_taxonomies['category'] : 'None'; 
     127                    $message .= '<br />'; 
     128                    break; 
     129 
     130                case 'post_author': 
     131                    $message    .= '<strong>Author:</strong> ' . esc_html( $post_author->display_name ) . '<br />'; 
     132                    break; 
     133 
     134                case 'post_date': 
     135                    $message .= '<strong>Post Date:</strong> ' . esc_html( $post->post_date ) . '<br />'; 
     136                    break; 
     137 
     138                case 'post_meta': 
     139 
     140                    $message .= '<br /><strong>Post Meta:</strong><br />'; 
     141 
     142                    foreach ( $post_meta as $key => $value ) { 
     143 
     144                        // If this is a hidden meta key, skip it. 
     145                        if ( 0 === strpos( $key, '_' ) ) { 
     146                            continue; 
     147                        } 
     148 
     149                        // Prepare meta value. 
     150                        if ( is_array( $value ) ) { 
     151                            $value = implode( ', ', $value ); 
     152                        } 
     153 
     154                        // Display meta value. 
     155                        $message .= esc_html( $key ) . ': ' . esc_html( $value ) . '<br />'; 
     156 
     157                    } 
     158 
     159                    break; 
     160 
     161                case 'tags': 
     162                    $message .= '<strong>Tags:</strong> '; 
     163                    $message .= isset( $post_taxonomies['post_tag'] ) ? $post_taxonomies['post_tag'] : 'None'; 
     164                    $message .= '<br />'; 
     165                    break; 
     166 
     167                case 'thumbnail': 
     168                    $message .= '<strong>Featured Image:</strong><br />' . get_the_post_thumbnail( $post->ID, 'medium' ) . '<br /><br />'; 
     169                    break; 
     170 
     171                case 'title': 
     172                    $message .= '<strong>Title:</strong> ' . esc_html( $post->post_title ) . '<br />'; 
     173                    break; 
     174 
    44175            } 
    45              
    46             // Otherwise, generate and return a hash 
    47             $hash = sha1($post_ID*time()); 
    48             add_post_meta($post_ID, '_epa-approve_key', $hash); 
    49             return $hash; 
    50         } 
    51          
    52         // Fire off function if a post is saved 
    53         public function send_email($post_ID){ 
    54             $post_data = get_page($post_ID); 
    55              
    56             // If post is saved via autosave, post is a revision or if it is not in the designated list of post status types, stop running. 
    57             if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || $post_data->post_type=="revision" || ((array_search($post_data->post_status, get_option('epa_post_statuses')) == FALSE) && (array_search($post_data->post_status, get_option('epa_post_statuses')) !== 0))) { return false; } 
    58              
    59              
    60             // Get the needed information 
    61             $post_taxonomies = get_the_taxonomies($post_ID); 
    62             $post_author_email = get_the_author_meta('user_email', $post_data->post_author); 
    63             $post_hash = self::generate_hash($post_ID); 
    64             $post_meta = get_post_meta($post_ID); 
    65  
    66             // Clean up the taxonomies print out for the email message 
    67             if (isset($post_taxonomies['post_tag'])) $post_taxonomies['post_tag'] = str_replace('Tags: ', '', $post_taxonomies['post_tag']); 
    68             else $post_taxonomies['post_tag'] = ''; 
    69              
    70             if (isset($post_taxonomies['category'])) $post_taxonomies['category'] = str_replace('Categories: ', '', $post_taxonomies['category']); 
    71             else $post_taxonomies['category'] = ''; 
    72              
    73             // Remove hidden keys from post meta and then print out 
    74             foreach($post_meta as $key => $value) { 
    75                 if(strpos($key, '_')=="0") 
    76                     unset($post_meta[$key]); 
     176 
     177        } 
     178 
     179        // Add footer divider. 
     180        $message .= '<br />----------------------------------------------------<br />'; 
     181 
     182        // Prepare base approval URL. 
     183        $approval_url = add_query_arg( 
     184            array( 
     185                'approve_post' => true, 
     186                'approve_key'  => $this->generate_hash( $post->ID ), 
     187            ), 
     188            get_bloginfo( 'url' ) 
     189        ); 
     190 
     191        // Prepare default author link. 
     192        $default_author_link = ''; 
     193        if ( $default_author ) { 
     194            $default_author_link = sprintf( 
     195                esc_html__( ' or %sapprove as %s%s', 'email-post-approval' ), 
     196                '<a href="' . esc_url( add_query_arg( array( 'default_author' => 'true' ), $approval_url ) ) . '">', 
     197                esc_html( $default_author->display_name ), 
     198                '</a>' 
     199            ); 
     200        } 
     201 
     202        // Add approval links. 
     203        $message .= sprintf( 
     204            esc_html__( '%sApprove as %s%s%s.', 'email-post-approval' ), 
     205            '<a href="' . esc_url( $approval_url ) . '">', 
     206            esc_html( $post_author->display_name ), 
     207            '</a>', 
     208            $default_author_link 
     209        ); 
     210 
     211        // Add disclaimer. 
     212        $message .= '<br />' . esc_html__( 'This email was generated by the Email Post Approval plugin.', 'email-post-approval' ); 
     213 
     214        // Prepare email headers. 
     215        $email_headers = array( 
     216            'From: "' . get_bloginfo( 'name' ) . '" <' . get_bloginfo( 'admin_email' ) . '>', 
     217            'Reply-To: ' . $post_author->user_email, 
     218        ); 
     219 
     220        // Prepare email subject. 
     221        $email_subject = 'Post Needing Approval: ' . esc_html( $post->post_title ); 
     222 
     223        // Prepare email to. 
     224        $email_to = get_option( 'epa_send_to' ); 
     225        $email_to = explode( ',', $email_to ); 
     226        $email_to = array_map( 'sanitize_email', $email_to ); 
     227 
     228        // Set email content type. 
     229        add_filter( 'wp_mail_content_type', function() { return 'text/html'; } ); 
     230 
     231        // Send email. 
     232        wp_mail( $email_to, $email_subject, $message, $email_headers ); 
     233 
     234    } 
     235 
     236 
     237 
     238 
     239 
     240    // # POST APPROVAL ------------------------------------------------------------------------------------------------- 
     241 
     242    /** 
     243     * Approve post for publishing. 
     244     * 
     245     * @since  2.0 
     246     * @access public 
     247     */ 
     248    public function approve_post() { 
     249 
     250        // If "approve_post" argument is not defined, return. 
     251        if ( ! isset( $_GET['approve_post'] ) ) { 
     252            return; 
     253        } 
     254 
     255        // Get approval key. 
     256        $approval_key = isset( $_GET['approve_key'] ) ? sanitize_text_field( $_GET['approve_key'] ) : false; 
     257 
     258        // If no approval key was provided, exit. 
     259        if ( ! $approval_key ) { 
     260            wp_die( esc_html__( 'You must provide a post approval key.', 'email-post-approval' ) ); 
     261        } 
     262 
     263        // Get default author state. 
     264        $default_author = isset( $_GET['default_author'] ) && 'true' == $_GET['default_author']; 
     265 
     266        // Get post to approve. 
     267        $post = get_posts( 
     268            array( 
     269                'meta_key'       => '_epa-approve_key', 
     270                'meta_value'     => $approval_key, 
     271                'posts_per_page' => 1, 
     272                'post_status'    => 'any', 
     273            ) 
     274        ); 
     275 
     276        // If post was not found, exit. 
     277        if ( ! $post || empty( $post ) ) { 
     278            wp_die( esc_html__( 'The post you are attempting to approve could not be found.', 'email-post-approval' ) ); 
     279        } 
     280 
     281        // Reset post. 
     282        $post = $post[0]; 
     283 
     284        // Set post status to future. 
     285        $post->post_status = 'future'; 
     286 
     287        // Change post author to default author. 
     288        if ( $default_author ) { 
     289 
     290            // Get default author. 
     291            $author = get_option( 'epa_default_author' ); 
     292 
     293            // Set post author. 
     294            if ( $author ) { 
     295                $post->post_author = sanitize_text_field( $author ); 
    77296            } 
    78              
    79             $message = ''; 
    80              
    81             // Generate email message            
    82             if(in_array('title', get_option('epa_email_fields'))!==FALSE): 
    83                 $message .= '<b>Title:</b> '. $post_data->post_title .'<br />'; 
    84             endif; 
    85             if(in_array('post_author', get_option('epa_email_fields'))!==FALSE): 
    86                 $message .= '<b>Author:</b> '. get_the_author_meta('display_name', $post_data->post_author) .'<br />'; 
    87             endif; 
    88             if(in_array('post_date', get_option('epa_email_fields'))!==FALSE): 
    89                 $message .= '<b>Post Date:</b> '. $post_data->post_date .'<br />'; 
    90             endif; 
    91             if(in_array('categories', get_option('epa_email_fields'))!==FALSE): 
    92                 $message .= '<b>Categories:</b> '.$post_taxonomies['category'] .'<br />'; 
    93             endif; 
    94             if(in_array('tags', get_option('epa_email_fields'))!==FALSE): 
    95                 $message .= '<b>Tags:</b> '. $post_taxonomies['post_tag'] .'<br />'; 
    96             endif; 
    97             if(in_array('post_meta', get_option('epa_email_fields'))!==FALSE): 
    98                 $message .= '<br /><b>Post Meta: </b><br />'; 
    99                 foreach($post_meta as $key => $value) { 
    100                     $message .= $key .': '. $value[0] .'<br />';     
    101                 } 
    102             endif; 
    103          
    104             if(in_array('thumbnail', get_option('epa_email_fields'))!==FALSE): 
    105                 $message .= '<b>Featured Image: </b>' . get_the_post_thumbnail($post_data->ID, 'medium') . '<br />'; 
    106                  
    107             endif;           
    108              
    109             if(in_array('body', get_option('epa_email_fields'))!==FALSE): 
    110                 $message .= '<br /><b>Post Body:</b><br />'. str_replace('<!--more-->', '&lt;!--more--&gt;', $post_data->post_content) .'<br />'; 
    111             endif; 
    112              
    113             $message .= '<br />----------------------------------------------------<br />'; 
    114             $message .= '<a href="'. get_bloginfo('url') .'/?approve_post=true&approve_key='. $post_hash .'&default_author=false">Approve as '. get_the_author_meta('display_name', $post_data->post_author) .'</a> or <a href="'. get_bloginfo('url') .'/?approve_post=true&approve_key='. $post_hash .'&default_author=true">Approve as '. get_the_author_meta('display_name', get_option('epa_default_author')) .'</a><br />This email generated by the Email Post Approval plugin.'; 
    115              
    116              
    117             // Change From to site's name & admin email, author's email as the Reply-To email, set HTML header and send email. 
    118             $headers[] = 'From: "'.get_bloginfo('name').'" <'. get_bloginfo('admin_email') .'>'; 
    119             $headers[] = 'Reply-To: '. $post_author_email; 
    120              
    121             add_filter('wp_mail_content_type', create_function('', 'return "text/html";')); 
    122             wp_mail(get_option('epa_send_to'), 'Post Needing Approval: '. $post_data->post_title, $message, $headers); 
    123         } 
    124     } 
    125      
    126     $email_post_approval = new Email_Post_Approval; 
    127     register_activation_hook(__FILE__, array('Email_Post_Approval', 'activation')); 
    128     register_deactivation_hook(__FILE__, array('Email_Post_Approval', 'deactivation')); 
    129      
    130     add_action('init', 'epa_approve_post', 0); 
    131     function epa_approve_post() { 
    132         // If URL includes "approve_post" argument, check the key and approve post if key exists. 
    133         if(isset($_GET['approve_post'])){ 
    134             $get_post_to_approve = get_posts('posts_per_page=1&post_status=any&meta_key=_epa-approve_key&meta_value='. $_GET['approve_key']); 
    135             $change_author = $_GET['default_author']; 
    136                      
    137             // If key exists, publish post, delete key, and redirect to published post. 
    138             if($get_post_to_approve){ 
    139                 $the_post = get_post($get_post_to_approve[0]->ID, 'ARRAY_A'); 
    140                 $the_post['post_status'] = 'future'; 
    141                 if($change_author==="true"){ $the_post['post_author'] = get_option('epa_default_author'); } 
    142                 wp_update_post($the_post); 
    143                 delete_post_meta($get_post_to_approve[0]->ID, '_epa-approve_key'); 
    144                 wp_redirect(get_permalink($get_post_to_approve[0]->ID), 301); 
    145                 exit; 
    146             // If key doesn't exist, display an alert saying post is not found. 
    147             } else { 
    148                 if (!defined('MULTISITE')) echo '<script>alert(\'The post you are attempting to approve is not found.\');</script>'; 
     297 
     298        } 
     299 
     300        // Save post. 
     301        wp_update_post( $post ); 
     302 
     303        // Remove approval key. 
     304        delete_post_meta( $post->ID, '_epa-approve_key' ); 
     305 
     306        // Redirect to post. 
     307        wp_redirect( get_permalink( $post->ID ) ); 
     308        exit(); 
     309 
     310    } 
     311 
     312 
     313 
     314 
     315 
     316    // # SETTINGS ------------------------------------------------------------------------------------------------------ 
     317 
     318    /** 
     319     * Register Email Post Approval settings page. 
     320     * 
     321     * @since  2.0 
     322     * @access public 
     323     */ 
     324    public function register_settings_page() { 
     325 
     326        add_options_page( esc_html__( 'Email Post Approval Settings', 'email-post-approval' ), esc_html__( 'Email Post Approval', 'email-post-approval' ), 'manage_options', 'email-post-approval', array( $this, 'settings_page' ) ); 
     327 
     328    } 
     329 
     330    /** 
     331     * Display Email Post Approval settings page. 
     332     * 
     333     * @since  2.0 
     334     * @access public 
     335     * 
     336     * @uses Email_Post_Approval::get_email_fields() 
     337     * @uses Email_Post_Approval::get_post_stati() 
     338     * @uses Email_Post_Approval::maybe_save_settings() 
     339     */ 
     340    public function settings_page() { 
     341 
     342        // Open page. 
     343        printf( 
     344            '<div class="wrap"><h2>%s</h2>', 
     345            esc_html__( 'Email Post Approval Settings', 'email-post-approval' ) 
     346        ); 
     347 
     348        // Save and get settings. 
     349        $settings = $this->maybe_save_settings(); 
     350 
     351        // Get users. 
     352        $users = get_users( 
     353            array( 
     354                'fields'  => array( 'ID', 'display_name' ), 
     355                'orderby' => 'display_name', 
     356            ) 
     357        ); 
     358 
     359        // Display settings. 
     360 
     361    ?> 
     362 
     363        <form method="POST"> 
     364 
     365            <?php wp_nonce_field( 'email-post-approval-settings' ); ?> 
     366 
     367            <table class="form-table"> 
     368 
     369                <tbody> 
     370 
     371                    <tr> 
     372                        <th scope="row"><label for="epa_send_to"><?php esc_html_e( 'Send Post Approval Email To:', 'email-post-approval' ); ?></label></th> 
     373                        <td><input class="regular-text" name="send_to" id="send_to" value="<?php echo esc_attr( $settings['send_to'] ); ?>" /> 
     374                    </tr> 
     375 
     376                    <tr> 
     377                        <th scope="row"><label for="epa_default_author"><?php esc_html_e( 'Default Author For Approved Posts:', 'email-post-approval' ); ?></label></th> 
     378                        <td> 
     379                            <select name="default_author" id="epa_default_author"> 
     380                                <option value="0"><?php esc_html_e( 'Use Post Author', 'email-post-approval' ); ?></option> 
     381                                <?php 
     382                                    foreach ( $users as $user ) { 
     383                                        echo '<option value="' . esc_attr( $user->ID ) . '" ' . selected( $settings['default_author'], $user->ID, false ) . '>' . esc_html( $user->display_name ) . '</option>'; 
     384                                    } 
     385                                ?> 
     386                            </select> 
     387                        </td> 
     388                    </tr> 
     389 
     390                    <tr> 
     391                        <th scope="row"><label><?php esc_html_e( 'Send Email When Post Status Is:', 'email-post-approval' ); ?></label></th> 
     392                        <td> 
     393                            <fieldset> 
     394                                <?php 
     395 
     396                                    // Loop through post stati. 
     397                                    foreach ( $this->get_post_stati() as $post_status ) { 
     398 
     399                                        // Get checked state. 
     400                                        $checked = in_array( $post_status->name, $settings['post_statuses'] ) ? ' checked="checked"' : ''; 
     401 
     402                                        // Display field. 
     403                                        echo '<label><input name="post_statuses[]" type="checkbox" value="' . esc_attr( $post_status->name ) . '"' . $checked . '>' . esc_html( $post_status->label ) . '</label><br />'; 
     404 
     405                                    } 
     406 
     407                                ?> 
     408                            </fieldset> 
     409                        </td> 
     410                    </tr> 
     411 
     412                    <tr> 
     413                        <th scope="row"><label><?php esc_html_e( 'Fields To Include In Email:', 'email-post-approval' ); ?></label></th> 
     414                        <td> 
     415                            <fieldset> 
     416                                <?php 
     417 
     418                                    // Loop through email fields. 
     419                                    foreach ( $this->get_email_fields() as $email_field => $label ) { 
     420 
     421                                        // Get checked state. 
     422                                        $checked = in_array( $email_field, $settings['email_fields'] ) ? ' checked="checked"' : ''; 
     423 
     424                                        // Display field. 
     425                                        echo '<label><input name="email_fields[]" type="checkbox" value="' . esc_attr( $email_field ) . '"' . $checked . '>' . $label . '</label><br />'; 
     426 
     427                                    } 
     428 
     429                                ?> 
     430                            </fieldset> 
     431                        </td> 
     432                    </tr> 
     433 
     434                </tbody> 
     435 
     436            </table> 
     437 
     438            <p class="submit"> 
     439                <input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Save Settings', 'email-post-approval' ); ?>" /> 
     440            </p> 
     441 
     442        </form> 
     443 
     444    <?php 
     445 
     446        // Close page. 
     447        echo '</div>'; 
     448 
     449    } 
     450 
     451    /** 
     452     * Save Email Post Approval settings. 
     453     * 
     454     * @since  2.0 
     455     * @access public 
     456     * 
     457     * @uses Email_Post_Approval::get_email_fields() 
     458     * @uses Email_Post_Approval::get_post_stati() 
     459     * @uses Email_Post_Approval::is_postback() 
     460     * 
     461     * @return array 
     462     */ 
     463    public function maybe_save_settings() { 
     464 
     465        // Get current settings. 
     466        $settings = array( 
     467            'send_to'        => get_option( 'epa_send_to' ), 
     468            'post_statuses'  => get_option( 'epa_post_statuses' ), 
     469            'email_fields'   => get_option( 'epa_email_fields' ), 
     470            'default_author' => get_option( 'epa_default_author' ), 
     471        ); 
     472 
     473        // If there was no postback, return current settings. 
     474        if ( ! $this->is_postback() ) { 
     475            return $settings; 
     476        } 
     477 
     478        // Validate nonce. 
     479        check_admin_referer( 'email-post-approval-settings' ); 
     480 
     481        // Get new settings. 
     482        $new_settings = $_POST; 
     483 
     484        // Sanitize settings. 
     485        foreach ( $new_settings as $key => $value ) { 
     486 
     487            switch ( $key ) { 
     488 
     489                case 'email_fields': 
     490 
     491                    // Get email fields. 
     492                    $email_fields = $this->get_email_fields(); 
     493                    $email_fields = array_keys( $email_fields ); 
     494 
     495                    // Loop through values. 
     496                    foreach ( $value as $i => $field ) { 
     497 
     498                        // If this is a non-existent field, remove it. 
     499                        if ( ! in_array( $field, $email_fields ) ) { 
     500                            unset( $value[ $i ] ); 
     501                        } 
     502 
     503                    } 
     504 
     505                    $new_settings[ $key ] = $value; 
     506 
     507                    break; 
     508 
     509                case 'post_statuses': 
     510 
     511                    // Get post stati. 
     512                    $post_stati = $this->get_post_stati(); 
     513                    $post_stati = array_keys( $post_stati ); 
     514 
     515                    // Loop through values. 
     516                    foreach ( $value as $i => $field ) { 
     517 
     518                        // If this is a non-existent post status, remove it. 
     519                        if ( ! in_array( $field, $post_stati ) ) { 
     520                            unset( $value[ $i ] ); 
     521                        } 
     522 
     523                    } 
     524 
     525                    $new_settings[ $key ] = $value; 
     526 
     527                    break; 
     528 
     529                case 'send_to': 
     530                    $new_settings[ $key ] = sanitize_email( $value ); 
     531                    break; 
     532 
     533                default: 
     534                    $new_settings[ $key ] = sanitize_text_field( $value ); 
     535                    break; 
     536 
    149537            } 
    150         } 
    151     } 
     538 
     539        } 
     540 
     541        // Save settings. 
     542        foreach ( $new_settings as $key => $value ) { 
     543 
     544            update_option( 'epa_' . $key, $value ); 
     545 
     546        } 
     547 
     548        // Display save message. 
     549        printf( 
     550            '<div id="message" class="updated notice notice-success is-dismissible"><p>%s</p></div>', 
     551            esc_html__( 'Settings saved.', 'email-post-approval' ) 
     552        ); 
     553 
     554        return $new_settings; 
     555 
     556    } 
     557 
     558 
     559 
     560 
     561 
     562    // # HELPER METHODS ------------------------------------------------------------------------------------------------ 
     563 
     564    /** 
     565     * Generate secret post approval key. 
     566     * 
     567     * @since  1.0 
     568     * @access private 
     569     * 
     570     * @param int $post_id Post ID to generate approval key for. 
     571     * 
     572     * @return string 
     573     */ 
     574    private function generate_hash( $post_id = 0 ) { 
     575 
     576        // Check for existing hash. 
     577        $existing_hash = get_post_meta( $post_id, '_epa-approve_key', true ); 
     578 
     579        // If hash exists, return it. 
     580        if ( $existing_hash ) { 
     581            return $existing_hash; 
     582        } 
     583 
     584        // Generate hash. 
     585        $hash = sha1( $post_id * time() ); 
     586 
     587        // Save hash to post meta. 
     588        update_post_meta( $post_id, '_epa-approve_key', $hash ); 
     589 
     590        return $hash; 
     591 
     592    } 
     593 
     594    /** 
     595     * Get fields available for Email Post Approval email. 
     596     * 
     597     * @since  2.0 
     598     * @access public 
     599     * 
     600     * @return array 
     601     */ 
     602    public function get_email_fields() { 
     603 
     604        return array( 
     605            'title'       => esc_html__( 'Post Title', 'email-post-approval' ), 
     606            'post_author' => esc_html__( 'Post Author', 'email-post-approval' ), 
     607            'post_date'   => esc_html__( 'Publish Date', 'email-post-approval' ), 
     608            'categories'  => esc_html__( 'Categories', 'email-post-approval' ), 
     609            'tags'        => esc_html__( 'Tags', 'email-post-approval' ), 
     610            'post_meta'   => esc_html__( 'Post Meta', 'email-post-approval' ), 
     611            'body'        => esc_html__( 'Post Body', 'email-post-approval' ), 
     612            'thumbnail'   => esc_html__( 'Featured Image', 'email-post-approval' ), 
     613        ); 
     614 
     615    } 
     616 
     617    /** 
     618     * Get post stati available for Email Post Approval. 
     619     * 
     620     * @since  2.0 
     621     * @access public 
     622     * 
     623     * @return array 
     624     */ 
     625    public function get_post_stati() { 
     626 
     627        // Get post stati. 
     628        $post_stati = get_post_stati( null, 'objects' ); 
     629 
     630        // Loop through post stati. 
     631        foreach ( $post_stati as $name => $post_status ) { 
     632 
     633            // If this is an excluded post status, remove it. 
     634            if ( in_array( $name, array( 'trash', 'auto-draft', 'inherit' ) ) ) { 
     635                unset( $post_stati[ $name ] ); 
     636            } 
     637 
     638        } 
     639 
     640        return $post_stati; 
     641 
     642    } 
     643 
     644    /** 
     645     * Determine if the current request is a postback. 
     646     * 
     647     * @since  2.0 
     648     * @access public 
     649     * 
     650     * @return bool 
     651     */ 
     652    public function is_postback() { 
     653 
     654        return is_array( $_POST ) && count( $_POST ) > 0; 
     655 
     656    } 
     657 
     658 
     659 
     660 
     661 
     662    // # INSTALLATION -------------------------------------------------------------------------------------------------- 
     663 
     664    /** 
     665     * Define initial settings upon activation. 
     666     * 
     667     * @since  1.0 
     668     * @access public 
     669     */ 
     670    public static function activation() { 
     671 
     672        // Add default send to address. 
     673        if ( ! get_option( 'epa_send_to' ) ) { 
     674            add_option( 'epa_send_to', sanitize_email( get_bloginfo( 'admin_email' ) ) ); 
     675        } 
     676 
     677        // Add default post statuses to cause Email Post Approval. 
     678        if ( ! get_option( 'epa_post_statuses' ) ) { 
     679            add_option( 'epa_post_statuses', array( 'pending' ) ); 
     680        } 
     681 
     682        // Add default fields to display in post approval email. 
     683        if ( ! get_option( 'epa_email_fields' ) ) { 
     684            add_option( 'epa_email_fields', array( 'title', 'post_author', 'post_date', 'categories', 'tags', 'post_meta', 'body', 'thumbnail' ) ); 
     685        } 
     686 
     687    } 
     688 
     689 
     690 
     691 
     692 
     693    // # UNINSTALL ----------------------------------------------------------------------------------------------------- 
     694 
     695    /** 
     696     * Remove settings upon deactivation. 
     697     * 
     698     * @since  1.0 
     699     * @access public 
     700     */ 
     701    public static function deactivation() { 
     702 
     703        delete_option( 'epa_send_to' ); 
     704        delete_option( 'epa_post_statuses' ); 
     705        delete_option( 'epa_email_fields' ); 
     706 
     707    } 
     708 
     709} 
     710 
     711Email_Post_Approval::get_instance(); 
  • email-post-approval/trunk/readme.txt

    r782670 r1638674  
    11=== Email Post Approval === 
    22Contributors: travislopes, mcinvale 
    3 Tags: database, mysql, search, replace, admin, security 
     3Tags: email, post approval, publishing, review 
    44Requires at least: 3.0 
    5 Tested up to: 3.6.1 
    6 Stable tag: 3.4.2 
     5Tested up to: 4.7.3 
     6Stable tag: 4.7.3 
    77 
    8 Ability to review and approve posts for publishing via email. 
     8Review and approve posts for publishing right from your inbox 
    99 
    1010== Description == 
    11 Ability to review and approve posts for publishing via email. Upon the saving (or creation) of a post where the post status is set to "draft" or "pending publishing," the blog's admin will receive an email containing the post's title, publish date, tags, categories, and the content of the post. At the end of the email, there will be a link to approve the post. Clicking the link will set the post to be published on the set publish date. 
     11Email Post Approval allows you to review and approve posts for publishing right from your inbox. Upon the saving (or creation) of a post where the post status is set to "draft" or "pending publishing," the blog's admin will receive an email containing the post's title, publish date, tags, categories, and the content of the post. At the end of the email, there will be a link to approve the post. Clicking the link will set the post to be published on the set publish date. 
    1212 
    1313== Installation == 
     
    2121 
    2222== Changelog == 
     23 
     24= v2.0 = 
     25* Added security enhancements when saving settings. 
     26* Rewrote plugin. 
     27 
    2328= v1.2.2 = 
    2429* Added post thumbnail option 
     30 
    2531= v1.2.1 = 
    2632* Patched warnings 
    2733* Fixed multisite redirect on approval 
     34 
    2835= v1.2 = 
    2936* Added the ability to set a default author for approved posts 
    3037* Added post author field to emails 
     38 
    3139= v1.1.5 = 
    3240* Changed email sender to be from admin email 
     41 
    3342= v1.1.0 = 
    3443* Added options page with the ability to set: 
     
    3847* Made `<!--more-->` tag visible in email  
    3948* Changed post approval to set post to future instead of publish. 
     49 
    4050= v1.0.0 = 
    4151* Initial release 
Note: See TracChangeset for help on using the changeset viewer.