Plugin Directory

Changeset 3140556


Ignore:
Timestamp:
08/23/2024 08:20:37 PM (19 months ago)
Author:
mdawaffe
Message:

Ability to opt in to or opt out of one post's diff emails.

Incomplete.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • email-post-changes/trunk/class.email-post-changes.php

    r3139466 r3140556  
    1212    const OPTION_GROUP = 'email_post_changes';
    1313    const OPTION = 'email_post_changes';
     14    const META_KEY = '_epc_user_override';
    1415
    1516    static function init() {
     
    3940            add_action( 'admin_menu', array( $this, 'admin_menu' ), 115 );
    4041        }
     42
     43        register_post_meta( '', self::META_KEY, [
     44            'type' => 'string',
     45            'description' => 'A per-user, per-post setting determining if the user should receive emails for changes to the post. Values look like `{(int) $user_id}:{(int) $should_receive_changes}.',
     46            'single' => false,
     47            'show_in_rest' => false,
     48            'revisions_enabled' => false,
     49        ] );
    4150    }
    4251
     
    6069
    6170        return wp_parse_args( $options, $this->defaults );
     71    }
     72
     73    /**
     74     * @param int $post_id
     75     * @return array<int, bool> Keys are User IDs, values are whether that user wants to receive changes for the given post.
     76     */
     77    function get_post_overrides( $post_id ) {
     78        $overrides = get_post_meta( $post_id, self::META_KEY, false );
     79
     80        $return = [];
     81        foreach ( $overrides as $override ) {
     82            [ $user_id, $value ] = explode( ':', $override );
     83            $return[$user_id] = (bool) $value;
     84        }
     85
     86        return $return;
     87    }
     88
     89    /**
     90     * @param int $user_id
     91     * @return array<int, bool> Keys are Post IDs, values are whether the given user wants to receive changes for that post.
     92     */
     93    function get_user_overrides( $user_id ) {
     94        $query = new WP_Query;
     95
     96        $posts = $query->query( [
     97            'meta_key' => self::META_KEY,
     98            'meta_value' => "{$user_id}:.*",
     99            'meta_compare' => 'REGEXP',
     100            'post_type' => 'any',
     101            'post_status' => 'any',
     102            'posts_per_page' => -1,
     103        ] );
     104
     105        $return = [];
     106        foreach ( $posts as $post ) {
     107            $return[$post->ID] = $this->get_post_user_override( $post->ID, $user_id );
     108        }
     109
     110        return $return;
     111    }
     112
     113    function get_post_user_override( $post_id, $user_id ) {
     114        $overrides = $this->get_post_overrides( $post_id );
     115        foreach ( $overrides as $override_user_id => $override ) {
     116            if ( $override_user_id === $user_id ) {
     117                return $override;
     118            }
     119        }
     120
     121        return null;
     122    }
     123
     124    /**
     125     * @param int $post_id
     126     * @param int $user_id
     127     * @param bool|null $override Null to delete, bool to set.
     128     */
     129    function set_post_user_override( $post_id, $user_id, $override ) {
     130        $current_override = $this->get_post_user_override( $post_id, $user_id );
     131
     132        if ( $current_override === $override ) {
     133            return;
     134        }
     135
     136        if ( null === $override ) {
     137            delete_post_meta( $post_id, self::META_KEY, "{$user_id}:{ (int) $current_override }" );
     138            return;
     139        }
     140
     141        if ( null === $current_override ) {
     142            add_post_meta( $post_id, self::META_KEY, "{$user_id}:{ $override ? 1 : 0 }", false );
     143        } else {
     144            update_post_meta( $post_id, self::META_KEY, "{$user_id}:{ $override ? 1 : 0 }", "{$user_id}:{ (int) $current_override }" );
     145        }
    62146    }
    63147
     
    150234        add_action( 'phpmailer_init', array( $this, 'phpmailer_init' ) );
    151235
     236        $overrides = $this->get_post_overrides( $this->right_post->ID );
     237
     238        $opt_ins = array_keys( array_filter( $overrides ) );
     239        $opt_outs = array_diff( array_keys( $overrides ), $opt_ins );
     240
     241        $user_ids = array_diff( $options['users'], $opt_outs );
     242        $user_ids = array_merge( $user_ids, $opt_ins );
     243
    152244        $user_emails = array();
    153         foreach( $options['users'] as $user_id ) {
     245        foreach( $user_ids as $user_id ) {
    154246            if ( function_exists( 'is_multisite' ) && is_multisite() ) {
    155                 if ( is_user_member_of_blog( $user_id, get_current_blog_id() ) )
     247                if ( is_user_member_of_blog( $user_id, get_current_blog_id() ) ) {
    156248                    $user_emails[] = get_user_option( 'user_email', $user_id );
     249                }
    157250            } else {
    158                 if ( $user_email = get_user_option( 'user_email', $user_id ) )
     251                if ( $user_email = get_user_option( 'user_email', $user_id ) ) {
    159252                    $user_emails[] = $user_email;
     253                }
    160254            }
    161255        }
     
    286380        register_setting( self::OPTION_GROUP, self::OPTION, array( $this, 'validate_options' ) );
    287381
     382        $current_user = wp_get_current_user();
     383
    288384        add_settings_section( self::ADMIN_PAGE, __( 'Email Post Changes' ), array( $this, 'settings_section' ), self::ADMIN_PAGE );
    289385        add_settings_field( self::ADMIN_PAGE . '_enable', __( 'Enable' ), array( $this, 'enable_setting' ), self::ADMIN_PAGE, self::ADMIN_PAGE );
     
    292388        add_settings_field( self::ADMIN_PAGE . '_post_types', __( 'Post Types' ), array( $this, 'post_types_setting' ), self::ADMIN_PAGE, self::ADMIN_PAGE );
    293389        add_settings_field( self::ADMIN_PAGE . '_drafts', __( 'Drafts' ), array( $this, 'drafts_setting' ), self::ADMIN_PAGE, self::ADMIN_PAGE );
     390        add_settings_field( self::ADMIN_PAGE . '_exceptions', sprintf( __( 'Post Exceptions for %s' ), $current_user->display_name ), array( $this, 'overrides_setting' ), self::ADMIN_PAGE, self::ADMIN_PAGE );
    294391
    295392        $hook = add_options_page( __( 'Email Post Changes' ), __( 'Email Post Changes' ), 'manage_options', self::ADMIN_PAGE, array( $this, 'admin_page' ) );
     
    493590    }
    494591
     592    function overrides_setting() {
     593        $options = $this->get_options();
     594
     595        $is_active = in_array( get_current_user_id(), $options['users'], false );
     596
     597        $description = $is_active
     598            ? __( 'Your user account currently receives post changes via email. You can turn off those emails for specific posts below.' )
     599            : __( 'Your user account currently does not receive post changes via email. You can turn on those emails for specific posts below.' );
     600
     601        ?>
     602        <p class="description"><?php echo esc_html( $description ); ?></p>
     603        <ul>
     604
     605        <?php // TODO - real UI
     606        foreach ( $this->get_user_overrides( get_current_user_id() ) as $post_id => $override ) {
     607            ?>
     608            <li><?php echo get_the_title( $post_id ); ?></li>
     609            <?php
     610        }
     611    }
     612
    495613    function wp_text_diff( $left_string, $right_string, $args = null ) {
    496614        $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' );
Note: See TracChangeset for help on using the changeset viewer.