Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@
"choctawnationofoklahoma",
"classmap",
"cpts",
"kses",
"Linktree",
"macrosbysara",
"pmpro",
"remoteip",
"trackbacks",
"wght",
"wpcf"
"wpcf",
"wpdb"
],
"css.format.spaceAroundSelectorSeparator": true,
"editor.codeActionsOnSave": {
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 3.1.0 - [April 12, 2026]

- Added: PMPro_Handler to lock down CPTs and Queries for Consistency Club posts
- Fixed: Added Gutenberg handling back into the theme

## 3.0.1 - [April 11, 2026]

- Fixed: Add plugin handling back into the theme init
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
}
},
"require-dev": {
"wp-coding-standards/wpcs": "*"
"wp-coding-standards/wpcs": "*",
"php-stubs/wordpress-stubs": "*",
"php-stubs/acf-pro-stubs": "*"
}
}
106 changes: 105 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
wp_die( 'Autoloader not found. Please run composer install.' );
}
$theme = new Theme_Init();
add_action( 'after_setup_theme', array( $theme, 'bootstrap_theme' ) );
add_action( 'after_setup_theme', array( $theme, 'bootstrap_theme' ) );
109 changes: 109 additions & 0 deletions inc/plugins/class-pmpro-handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
/**
* PMPro Handler Class
*
* @package MacrosBySara
*/

namespace MacrosBySara\Plugins;

use WP_Query;

/**
* Class: PMPro Handler
*/
class PMPro_Handler {
/**
* An array of PMPro membership levels that grant access to the content.
*
* @var string[] $consistency_club_levels
*/
private array $consistency_club_levels;

/**
* The slug of the custom post type to lock.
*
* @var string $cc_post_type_slug
*/
private string $cc_post_type_slug;

/**
* Constructor
*
* @param string $cc_post_type_slug The slug of the custom post type to lock
* @param int[] $consistency_club_levels An array of PMPro membership levels that grant access to the content.
*/
public function __construct( string $cc_post_type_slug, array $consistency_club_levels = array() ) {
$this->cc_post_type_slug = $cc_post_type_slug;
$this->consistency_club_levels = array_map( 'strval', $consistency_club_levels );
}

/**
* Check if the current user has a valid membership level.
*
* @param ?int $user_id [Optional] The ID of the user to check. Defaults to the current user.
* @return bool True if the user has a valid membership level, false otherwise.
*/
private function user_has_valid_level( ?int $user_id = null ): bool {
if ( current_user_can( 'manage_options' ) ) {
return true;
}
return pmpro_hasMembershipLevel( $this->consistency_club_levels, $user_id );
}

/**
* Check if a post is marked as a freebie.
*
* @param ?int $post_id [Optional] The ID of the post to check. Defaults to the current post in the loop.
* @return bool True if the post is a freebie, false otherwise.
*/
private function post_is_freebie( ?int $post_id = null ): bool {
if ( is_null( $post_id ) ) {
$post_id = get_the_ID();
}
return has_term( 'freebie', 'cc-tag', $post_id );
}

/**
* Lock down CPT.
*/
public function lock_down_cpt() {
add_filter( 'the_content', array( $this, 'lock_down_single_content' ) );
add_action( 'pre_get_posts', array( $this, 'lock_down_queries' ) );
}

/**
* Lock down the content of single CPT pages.
*
* @param string $content The original content.
* @return string The modified content if access is denied, otherwise the original content.
*/
public function lock_down_single_content( $content ): string {
if ( is_singular( $this->cc_post_type_slug ) ) {
if ( ! $this->user_has_valid_level() && ! $this->post_is_freebie() ) {
return '<p>You must be a member to view this content.</p>';
}
}
return $content;
}

/**
* Lock down queries for the CPT archive and single pages.
*
* @param WP_Query $query The current query object.
*/
public function lock_down_queries( WP_Query $query ): void {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}

$restricted_post_types = array( $this->cc_post_type_slug );

if ( is_post_type_archive( $restricted_post_types ) || is_singular( $restricted_post_types ) ) {
if ( ! $this->user_has_valid_level() && ! $this->post_is_freebie() ) {
wp_safe_redirect( '/consistency-club' );
exit;
}
}
}
}
10 changes: 0 additions & 10 deletions inc/theme/class-gutenberg-handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@
* Gutenberg Handler
*/
class Gutenberg_Handler {

/**
* Constructor
*/
public function __construct() {
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_assets' ) );
add_action( 'after_setup_theme', array( $this, 'theme_supports' ) );
add_action( 'init', array( $this, 'register_theme_blocks' ) );
}

/**
* Enqueue the block editor assets that control the layout of the Block Editor.
*/
Expand Down
14 changes: 14 additions & 0 deletions inc/theme/class-plugin-handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace MacrosBySara\Theme;

use MacrosBySara\Plugins\ACF_Handler;
use MacrosBySara\Plugins\PMPro_Handler;

/**
* Class: Plugin Handler
Expand All @@ -18,6 +19,7 @@ class Plugin_Handler {
*/
public function handle_plugins() {
$this->handle_acf();
$this->handle_pmpro();
}

/**
Expand All @@ -31,4 +33,16 @@ private function handle_acf() {
$acf_handler->init_save_filters();
add_filter( 'acf/settings/load_json', array( $acf_handler, 'load_json_paths' ) );
}

/**
* Handle PMPro
*/
private function handle_pmpro() {
if ( ! is_plugin_active( 'paid-memberships-pro/paid-memberships-pro.php' ) ) {
return;
}
$consistency_club_levels = array( 2, 3, 4, 5 ); // Define your PMPro membership levels here
$pmpro_handler = new PMPro_Handler( 'cc-post', $consistency_club_levels );
$pmpro_handler->lock_down_cpt();
}
}
11 changes: 11 additions & 0 deletions inc/theme/class-theme-init.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Theme_Init {
public function bootstrap_theme() {
$this->disable_discussion();
$this->configure_theme_support();
$this->configure_gutenberg_support();
$plugin_handler = new Plugin_Handler();
$plugin_handler->handle_plugins();
add_action( 'init', array( $this, 'alter_post_types' ) );
Expand Down Expand Up @@ -67,6 +68,16 @@ public function configure_theme_support() {
);
}

/**
* Configure Gutenberg support by enqueuing block editor assets and adding theme supports for Gutenberg features.
*/
public function configure_gutenberg_support() {
$gutenberg_handler = new Gutenberg_Handler();
$gutenberg_handler->theme_supports();
add_action( 'enqueue_block_editor_assets', array( $gutenberg_handler, 'enqueue_block_assets' ) );
add_action( 'init', array( $gutenberg_handler, 'register_theme_blocks' ) );
}

/** Alter Post Types. */
public function alter_post_types() {
add_post_type_support( 'page', 'excerpt' );
Expand Down
2 changes: 1 addition & 1 deletion inc/theme/navwalkers/class-navwalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,4 +242,4 @@ protected function get_the_attributes(): string {
$attributes['class'] .= ' nav-link';
return $this->build_atts( $attributes );
}
}
}
Loading