LLMS_Integration_BBPress
bbPress Integration
Source Source
File: includes/integrations/class.llms.integration.bbpress.php
class LLMS_Integration_BBPress extends LLMS_Abstract_Integration { /** * Integration ID * * @var string */ public $id = 'bbpress'; /** * Display order on Integrations tab * * @var integer */ protected $priority = 5; /** * Configure the integration * * @since 3.8.0 * @since 3.30.3 Fixed spelling errors. * * @return void */ protected function configure() { $this->title = __( 'bbPress', 'lifterlms' ); $this->description = sprintf( __( 'Restrict forums and topics to memberships, add forums to courses, and %1$smore%2$s.', 'lifterlms' ), '<a href="https://lifterlms.com/docs/lifterlms-and-bbpress/" target="_blank">', '</a>' ); if ( $this->is_available() ) { // Custom engagements. add_filter( 'lifterlms_engagement_triggers', array( $this, 'register_engagement_triggers' ) ); add_action( 'bbp_new_topic', array( llms()->engagements(), 'maybe_trigger_engagement' ), 10, 4 ); add_action( 'bbp_new_reply', array( llms()->engagements(), 'maybe_trigger_engagement' ), 10, 5 ); add_filter( 'lifterlms_external_engagement_query_arguments', array( $this, 'engagement_query_args' ), 10, 3 ); // Register shortcode. add_filter( 'llms_load_shortcodes', array( $this, 'register_shortcodes' ) ); // Add memberships restriction metabox. add_filter( 'llms_membership_restricted_post_types', array( $this, 'add_membership_restrictions' ) ); // Check forum/bbp template restrictions. add_filter( 'llms_page_restricted_before_check_access', array( $this, 'restriction_checks_memberships' ), 40, 1 ); add_filter( 'llms_page_restricted_before_check_access', array( $this, 'restriction_checks_courses' ), 50, 1 ); // Add and save custom fields. add_filter( 'llms_metabox_fields_lifterlms_course_options', array( $this, 'course_settings_fields' ) ); add_action( 'llms_metabox_after_save_lifterlms-course-options', array( $this, 'save_course_settings' ) ); add_filter( 'llms_get_course_properties', array( $this, 'add_course_props' ), 10, 2 ); add_action( 'llms_content_restricted_by_bbp_course_forum', array( $this, 'handle_course_forum_restriction' ), 10, 1 ); } } /** * Register the custom course property with the LLMS_Course Model * * @since 3.12.0 * * @param array $props Default properties. * @param LLMS_Course $course Course object. * @return array */ public function add_course_props( $props, $course ) { $props['bbp_forum_ids'] = 'array'; return $props; } /** * Add the membership restrictions metabox to bbPress forums on admin panel * * @since 3.0.0 * * @param string[] $post_types Array of existing post types. * @return string[] */ public function add_membership_restrictions( $post_types ) { $post_types[] = bbp_get_forum_post_type(); return $post_types; } /** * Register custom bbPress tab with the LLMS Course metabox * * @since 3.12.0 * * @param array $fields Existing fields. * @return array */ public function course_settings_fields( $fields ) { global $post; $selected = $this->get_course_forum_ids( $post ); $fields[] = array( 'title' => __( 'bbPress', 'lifterlms' ), 'fields' => array( array( 'allow_null' => false, 'data_attributes' => array( 'post-type' => 'forum', 'allow-clear' => true, 'placeholder' => __( 'Select forums', 'lifterlms' ), ), 'desc' => __( 'Add forums which will only be available to students currently enrolled in this course.', 'lifterlms' ), 'class' => 'llms-select2-post', 'id' => '_llms_bbp_forum_ids', 'type' => 'select', 'label' => __( 'Private Course Forums', 'lifterlms' ), 'multi' => true, 'value' => llms_make_select2_post_array( $selected ), ), ), ); return $fields; } /** * Parse action arguments for bbPress engagements and pass them back to the LLMS Engagements handler * * @since 3.12.0 * @since 3.37.11 Use strict comparison for `in_array()`. * * @param array $query_args Query args for handler. * @param string $action Triggering action name. * @param array $orig_args Original arguments from the action (indexed array). * @return array */ public function engagement_query_args( $query_args, $action, $orig_args ) { if ( in_array( $action, array( 'bbp_new_reply', 'bbp_new_topic' ), true ) ) { $query_args['trigger_type'] = $action; $query_args['related_post_id'] = ''; if ( 'bbp_new_reply' === $action ) { $query_args['user_id'] = $orig_args[4]; // Reply Author. } elseif ( 'bbp_new_topic' === $action ) { $query_args['user_id'] = $orig_args[3]; // Topic Author. } } return $query_args; } /** * Handle course forum restrictions * * Add a notice and redirect to the course * * @since 3.12.0 * @since 3.13.0 Unknown. * @since 3.37.11 Use `llms_redirect_and_exit()` in favor of `wp_redirect()`. * * @param array $restriction Restriction Results from `llms_page_restricted()`. * @return void */ public function handle_course_forum_restriction( $restriction ) { /** * Customize the restriction notice message displayed when a forum is restricted to a course. * * @since 3.37.11 * * @param string $msg Default message. * @param array $restriction Results from `llms_page_restricted()`. */ $msg = apply_filters( 'llms_bbp_course_forum_restriction_msg', __( 'You must be enrolled in this course to access the course forum.', 'lifterlms' ), $restriction ); llms_add_notice( $msg, 'error' ); llms_redirect_and_exit( get_permalink( $restriction['restriction_id'] ) ); } /** * Retrieve course ids restricted to a LifterLMS course * * @since 3.12.0 * * @param mixed $course WP_Post, LLMS_Course, or WP_Post ID. * @return array */ public function get_course_forum_ids( $course ) { $course = llms_get_post( $course ); if ( ! $course ) { $ids = array(); } else { $ids = $course->get( 'bbp_forum_ids' ); if ( '' === $ids ) { $ids = array(); } } /** * Customize the bbPress forum IDs associated with a course. * * @since 3.37.11 * * @param int[] $ids Array of WP_Post IDs of the bbPress forums restricted to the course. * @param LLMS_Course $course LifterLMS course object. */ return apply_filters( 'llms_bbp_get_course_forum_ids', $ids, $course ); } /** * Check if a forum is restricted to a course(s) * * @since 3.12.0 * @since 3.38.1 Make the query more generic so that it matches forum ids whether they've been saved as integers or strings. * @since 4.0.0 Escape `{` character in SQL query to add MySQL 8.0 support. * * @param int $forum_id WP_Post ID of the forum. * @return int[] */ public function get_forum_course_restrictions( $forum_id ) { global $wpdb; $query = $wpdb->get_col( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->prepare( "SELECT metas.post_id FROM {$wpdb->postmeta} AS metas JOIN {$wpdb->posts} AS posts on posts.ID = metas.post_id WHERE metas.meta_key = '_llms_bbp_forum_ids' AND metas.meta_value REGEXP %s AND posts.post_status = 'publish';", 'a:[0-9][0-9]*:\{(i:[0-9][0-9]*;(i|s:[0-9][0-9]*):"?[0-9][0-9]*"?;)*(i:[0-9][0-9]*;(i|s:[0-9][0-9]*):"?' . sprintf( '%d', absint( $forum_id ) ) . '"?;)' ) ); $query = array_map( 'absint', $query ); return $query; } /** * Determine if bbPress is installed and activated * * @since 3.0.0 * * @return boolean */ public function is_installed() { return class_exists( 'bbPress' ); } /** * Register shortcodes via LifterLMS core registration methods * * @since 3.12.0 * * @param string[] $classes Existing shortcode classes. * @return array */ public function register_shortcodes( $classes ) { $classes[] = 'LLMS_BBP_Shortcode_Course_Forums_List'; return $classes; } /** * Check forum restrictions for course restrictions * * @since 3.12.0 * @since 3.12.2 Unknown. * * @param array $results Array of restriction results. * @return array */ public function restriction_checks_courses( $results ) { $post_id = null; if ( bbp_is_forum( $results['content_id'] ) ) { $user_id = get_current_user_id(); $courses = $this->get_forum_course_restrictions( $results['content_id'] ); // No user and at least one course restriction, return the first. if ( $courses && ! $user_id ) { $post_id = $courses[0]; // Courses and a user, find at least one enrollment. } elseif ( $courses && $user_id ) { foreach ( $courses as $course_id ) { // Not enrolled, use this for the restriction but dont break because we may find an enrollment later. if ( ! llms_is_user_enrolled( $user_id, $course_id ) ) { $post_id = $course_id; // Enrolled in one, reset the post id and break. } else { $post_id = null; break; } } } } elseif ( bbp_is_topic( $results['content_id'] ) ) { $results['content_id'] = bbp_get_topic_forum_id( $results['content_id'] ); return $this->restriction_checks_courses( $results ); } if ( $post_id ) { $results['restriction_id'] = $post_id; $results['reason'] = 'bbp_course_forum'; } return $results; } /** * Check membership restrictions for Topics and Forum Archive pages * * @since 3.12.0 * * @param array $results Array of restriction results. * @return array */ public function restriction_checks_memberships( $results ) { $post_id = null; // Forum archive, grab the page (if set). if ( bbp_is_forum_archive() ) { $page = bbp_get_page_by_path( bbp_get_root_slug() ); $post_id = ( $page && $page->ID ) ? $page->ID : null; $reason = 'membership'; } elseif ( bbp_is_topic( $results['content_id'] ) ) { $post_id = bbp_get_topic_forum_id( $results['content_id'] ); $reason = 'membership'; } if ( $post_id ) { $restriction_id = llms_is_post_restricted_by_membership( $post_id, get_current_user_id() ); if ( $restriction_id ) { $results['restriction_id'] = $restriction_id; $results['reason'] = 'membership'; } } return $results; } /** * Register engagement triggers * * @since 3.12.0 * * @param string[] $triggers Existing triggers. * @return array */ public function register_engagement_triggers( $triggers ) { $triggers['bbp_new_topic'] = __( 'Student creates a new forum topic', 'lifterlms' ); $triggers['bbp_new_reply'] = __( 'Student creates a new forum reply', 'lifterlms' ); return $triggers; } /** * Save course metabox custom fields * * @since 3.12.0 * @since 3.35.0 Sanitize input data. * @since 3.37.11 Don't update saved forum values during course quick edits & remove redundant sanitization. * @since 5.9.0 Stop using deprecated `FILTER_SANITIZE_STRING`. * * @param int $post_id WP_Post ID of the course. * @return null|int[] */ public function save_course_settings( $post_id ) { // Return early on quick edits. $action = llms_filter_input( INPUT_POST, 'action' ); if ( 'inline-save' === $action ) { return null; } $ids = array(); if ( isset( $_POST['_llms_bbp_forum_ids'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing $ids = llms_filter_input( INPUT_POST, '_llms_bbp_forum_ids', FILTER_SANITIZE_NUMBER_INT, FILTER_REQUIRE_ARRAY ); } update_post_meta( $post_id, '_llms_bbp_forum_ids', $ids ); return $ids; } }
Expand full source code Collapse full source code View on GitHub
Methods Methods
- add_course_props — Register the custom course property with the LLMS_Course Model
- add_membership_restrictions — Add the membership restrictions metabox to bbPress forums on admin panel
- configure — Configure the integration
- course_settings_fields — Register custom bbPress tab with the LLMS Course metabox
- engagement_query_args — Parse action arguments for bbPress engagements and pass them back to the LLMS Engagements handler
- get_course_forum_ids — Retrieve course ids restricted to a LifterLMS course
- get_forum_course_restrictions — Check if a forum is restricted to a course(s)
- handle_course_forum_restriction — Handle course forum restrictions
- is_installed — Determine if bbPress is installed and activated
- register_engagement_triggers — Register engagement triggers
- register_shortcodes — Register shortcodes via LifterLMS core registration methods
- restriction_checks_courses — Check forum restrictions for course restrictions
- restriction_checks_memberships — Check membership restrictions for Topics and Forum Archive pages
- save_course_settings — Save course metabox custom fields
Changelog Changelog
Version | Description |
---|---|
4.0.0 | Added MySQL 8.0 compatibility. |
3.38.1 | When looking for forum course restrictions make sure to run a more generic query so that it matches forum ids whether they've been save as integers or strings. |
3.37.11 | Don't update saved forum values during course quick edits. |
3.35.0 | Sanitize input data. |
3.30.3 | Fixed spelling errors. |
3.0.0 | Introduced. |