From 3d4a3de3d71c701d063b2471aa3a49c6e5dbfd64 Mon Sep 17 00:00:00 2001
From: Thomas Patrick Levy
Date: Fri, 19 Feb 2021 17:08:11 -0700
Subject: [PATCH 01/12] content filtering conditions WIP
---
includes/functions/llms-functions-content.php | 41 ++++++++-
.../class-llms-test-functions-content.php | 85 ++++++++++++++++++-
2 files changed, 119 insertions(+), 7 deletions(-)
diff --git a/includes/functions/llms-functions-content.php b/includes/functions/llms-functions-content.php
index bc2993c0d6..cc09cac2b9 100644
--- a/includes/functions/llms-functions-content.php
+++ b/includes/functions/llms-functions-content.php
@@ -63,7 +63,6 @@ function llms_get_post_content( $content ) {
$template_after = llms_get_template_part_contents( 'content', 'single-lesson-after' );
}
} elseif ( 'llms_quiz' === $post->post_type ) {
-
$template_before = llms_get_template_part_contents( 'content', 'single-quiz-before' );
$template_after = llms_get_template_part_contents( 'content', 'single-quiz-after' );
@@ -84,7 +83,7 @@ function llms_get_post_content( $content ) {
/**
* Filter the post_content of a LifterLMS post type.
*
- * @since Unknown.
+ * @since [version]
*
* @param string $content Post content.
* @param WP_Post $post Post object.
@@ -94,4 +93,40 @@ function llms_get_post_content( $content ) {
}
}
-add_filter( 'the_content', 'llms_get_post_content' );
+
+/**
+ * Initialize LifterLMS post type content filters
+ *
+ * This method is used to determine whether or `llms_get_post_content()` should automatically
+ * be added as a filter callback for the WP core `the_content` filter.
+ *
+ * When working with posts on the admin panel (during course building, importing) we don't want
+ * other plugins that may desire running `apply_filters( 'the_content', $content )` to apply our
+ * plugin's filters.
+ *
+ * Additionally, we don't want to return template information when processing REST requests.
+ *
+ * @since [version]
+ *
+ * @return boolean Returns `true` if content filters are added and `false` if not.
+ */
+function llms_post_content_init() {
+
+ // Don't filter any requests on the admin panel or when processing REST requests.
+ $should_filter = ( ! is_admin() && ! llms_is_rest() );
+
+ /**
+ * Filters whether or not LifterLMS content filters should be applied.
+ *
+ * @since [version]
+ *
+ * @param boolean $should_filter Whether or not to filter the content.
+ */
+ if ( apply_filters( 'llms_should_filter_post_content', $should_filter ) ) {
+ return add_filter( 'the_content', 'llms_get_post_content' );
+ }
+
+ return false;
+
+}
+add_action( 'init', 'llms_post_content_init' );
diff --git a/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php b/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php
index 9306baac51..333fa7df3f 100644
--- a/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php
+++ b/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php
@@ -1,10 +1,13 @@
Lorem ipsum dolor sit amet.
';
$post_types = array( 'llms_membership', 'course', 'lesson', 'post', 'page' );
foreach ( $post_types as $post_type ) {
@@ -34,4 +39,76 @@ public function test_llms_get_post_content() {
}
+ /**
+ * Test that llms_get_post_content() will return early if the `$post` global is not set.
+ *
+ * @since [version]
+ *
+ * @return void
+ */
+ public function test_llms_get_post_content_no_global() {
+
+ llms_post_content_init();
+
+ $input = 'whatever';
+ $this->assertEquals( $input, llms_get_post_content( $input ) );
+
+ }
+
+ /**
+ * Test llms_post_content_init() when filters should be applied
+ *
+ * @since [version]
+ *
+ * @return void
+ */
+ public function test_llms_post_content_init() {
+
+ remove_filter( 'the_content', 'llms_get_post_content' );
+
+ $this->assertTrue( llms_post_content_init() );
+ $this->assertEquals( 10, has_filter( 'the_content', 'llms_get_post_content' ) );
+
+ }
+
+ /**
+ * Test llms_post_content_init() when on the admin panel
+ *
+ * @since [version]
+ *
+ * @return void
+ */
+ public function test_llms_post_content_init_is_admin() {
+
+ remove_filter( 'the_content', 'llms_get_post_content' );
+
+ set_current_screen( 'admin.php' );
+
+ $this->assertFalse( llms_post_content_init() );
+ $this->assertFalse( has_filter( 'the_content', 'llms_get_post_content' ) );
+
+ set_current_screen( 'front' ); // Reset.
+
+ }
+
+ /**
+ * Test llms_post_content_init() during REST requests
+ *
+ * @since [version]
+ *
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * @return void
+ */
+ public function test_llms_post_content_init_is_rest() {
+
+ remove_filter( 'the_content', 'llms_get_post_content' );
+
+ define( 'REST_REQUEST', true );
+ $this->assertFalse( llms_post_content_init() );
+ $this->assertFalse( has_filter( 'the_content', 'llms_get_post_content' ) );
+
+ }
+
}
From 9408aed448172984ac9c6c342751cfc969105bcd Mon Sep 17 00:00:00 2001
From: Thomas Patrick Levy
Date: Fri, 19 Feb 2021 20:54:11 -0700
Subject: [PATCH 02/12] Add 'llms-sales-page' as a post type feature
---
includes/class.llms.post-types.php | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/includes/class.llms.post-types.php b/includes/class.llms.post-types.php
index c13d635c71..905e618413 100644
--- a/includes/class.llms.post-types.php
+++ b/includes/class.llms.post-types.php
@@ -5,7 +5,7 @@
* @package LifterLMS\Classes
*
* @since 1.0.0
- * @version 4.5.1
+ * @version [version]
*/
defined( 'ABSPATH' ) || exit;
@@ -344,6 +344,7 @@ public static function register_post_type( $name, $data ) {
* @since 3.33.0 `llms_question` post type is not publicly queryable anymore.
* @since 3.37.12 Added 'revisions' support to course, lesson, and llms_mebership post types.
* @since 4.5.1 Removed "excerpt" support for the course post type.
+ * @since [version] Add "llms-sales-page" feature to course and membership post types.
*
* @return void
*/
@@ -385,7 +386,7 @@ public static function register_post_types() {
'feeds' => true,
),
'query_var' => true,
- 'supports' => array( 'title', 'author', 'editor', 'thumbnail', 'comments', 'custom-fields', 'page-attributes', 'revisions', 'llms-clone-post', 'llms-export-post' ),
+ 'supports' => array( 'title', 'author', 'editor', 'thumbnail', 'comments', 'custom-fields', 'page-attributes', 'revisions', 'llms-clone-post', 'llms-export-post', 'llms-sales-page' ),
'has_archive' => ( $catalog_id && get_page( $catalog_id ) ) ? get_page_uri( $catalog_id ) : _x( 'courses', 'course archive url slug', 'lifterlms' ),
'show_in_nav_menus' => true,
'menu_position' => 52,
@@ -580,7 +581,7 @@ public static function register_post_types() {
'feeds' => true,
),
'query_var' => true,
- 'supports' => array( 'title', 'editor', 'thumbnail', 'comments', 'custom-fields', 'page-attributes', 'revisions' ),
+ 'supports' => array( 'title', 'editor', 'thumbnail', 'comments', 'custom-fields', 'page-attributes', 'revisions', 'llms-sales-page' ),
'has_archive' => ( $membership_page_id && get_page( $membership_page_id ) ) ? get_page_uri( $membership_page_id ) : _x( 'memberships', 'membership archive url slug', 'lifterlms' ),
'show_in_nav_menus' => true,
'menu_position' => 52,
From 5e57fe45faf1cd3853ae8fff62d49f9ae983e47a Mon Sep 17 00:00:00 2001
From: Thomas Patrick Levy
Date: Fri, 19 Feb 2021 20:54:29 -0700
Subject: [PATCH 03/12] Refactor
---
includes/functions/llms-functions-content.php | 113 ++++++++++--------
1 file changed, 62 insertions(+), 51 deletions(-)
diff --git a/includes/functions/llms-functions-content.php b/includes/functions/llms-functions-content.php
index cc09cac2b9..32a6c8eff3 100644
--- a/includes/functions/llms-functions-content.php
+++ b/includes/functions/llms-functions-content.php
@@ -5,7 +5,7 @@
* @package LifterLMS/Functions
*
* @since 3.25.1
- * @version 3.25.2
+ * @version [version]
*/
defined( 'ABSPATH' ) || exit;
@@ -15,10 +15,11 @@
/**
* Post Template Include
*
- * Appends LLMS content above and below post content.
+ * Adds LifterLMS template content before and after the post's default content.
*
* @since 1.0.0
* @since 3.25.2 Unknown.
+ * @since [version] TODO.
*
* @param string $content WP_Post post_content.
* @return string
@@ -26,74 +27,84 @@
function llms_get_post_content( $content ) {
global $post;
- if ( ! $post instanceof WP_Post ) {
+ if ( ! $post instanceof WP_Post || ! in_array( $post->post_type, array( 'course', 'llms_membership', 'lesson', 'llms_quiz' ), true ) ) {
return $content;
}
- $page_restricted = llms_page_restricted( $post->ID );
- $before = '';
- $template_before = '';
- $after = '';
- $template_after = '';
+ $restrictions = llms_page_restricted( $post->ID );
+ $post_type = str_replace( 'llms_', '', $post->post_type );
+ $template_before = 'single-' . $post_type . '-before';
+ $template_after = 'single-' . $post_type . '-after';
- if ( 'course' === $post->post_type || 'llms_membership' === $post->post_type ) {
-
- $sales_page = get_post_meta( $post->ID, '_llms_sales_page_content_type', true );
-
- if ( $page_restricted['is_restricted'] && ( '' === $sales_page || 'content' === $sales_page ) ) {
-
- add_filter( 'the_excerpt', array( $GLOBALS['wp_embed'], 'autoembed' ), 9 );
- if ( $post->post_excerpt ) {
- $content = llms_get_excerpt( $post->ID );
- }
- }
-
- $template_name = str_replace( 'llms_', '', $post->post_type );
- $template_before = llms_get_template_part_contents( 'content', 'single-' . $template_name . '-before' );
- $template_after = llms_get_template_part_contents( 'content', 'single-' . $template_name . '-after' );
-
- } elseif ( 'lesson' === $post->post_type ) {
-
- if ( $page_restricted['is_restricted'] ) {
+ if ( $restrictions['is_restricted'] ) {
+ $content = llms_get_post_sales_page_content( $post, $content );
+ if ( in_array( $post->post_type, array( 'lesson', 'llms_quiz' ), true ) ) {
$content = '';
- $template_before = llms_get_template_part_contents( 'content', 'no-access-before' );
- $template_after = llms_get_template_part_contents( 'content', 'no-access-after' );
- } else {
- $template_before = llms_get_template_part_contents( 'content', 'single-lesson-before' );
- $template_after = llms_get_template_part_contents( 'content', 'single-lesson-after' );
+ $template_before = 'no-access-before';
+ $template_after = 'no-access-after';
}
- } elseif ( 'llms_quiz' === $post->post_type ) {
- $template_before = llms_get_template_part_contents( 'content', 'single-quiz-before' );
- $template_after = llms_get_template_part_contents( 'content', 'single-quiz-after' );
-
}
- if ( $template_before ) {
- ob_start();
- load_template( $template_before, false );
- $before = ob_get_clean();
- }
+ ob_start();
+ load_template( llms_get_template_part_contents( 'content', $template_before ), false );
+ $before = ob_get_clean();
- if ( $template_after ) {
- ob_start();
- load_template( $template_after, false );
- $after = ob_get_clean();
- }
+ ob_start();
+ load_template( llms_get_template_part_contents( 'content', $template_after ), false );
+ $after = ob_get_clean();
/**
* Filter the post_content of a LifterLMS post type.
*
- * @since [version]
+ * @since Unknown
*
- * @param string $content Post content.
- * @param WP_Post $post Post object.
- * @param array $page_restricted Result from `llms_page_restricted()` for the current post.
+ * @param string $content Post content.
+ * @param WP_Post $post Post object.
+ * @param array $restrictions Result from `llms_page_restricted()` for the current post.
*/
- return apply_filters( 'llms_get_post_content', do_shortcode( $before . $content . $after ), $post, $page_restricted );
+ return apply_filters( 'llms_get_post_content', do_shortcode( $before . $content . $after ), $post, $restrictions );
}
}
+/**
+ * Retrieve the sales page content for a course or membership
+ *
+ * By default only courses and memberships support sales pages, the meta property
+ * must be set to `content` or an empty string, and the post must have a `post_excerpt`
+ * property value.
+ *
+ * @since [version]
+ *
+ * @param WP_Post $post The post object.
+ * @param string $default Optional. Default content to use when no override content can be found.
+ * @return string
+ */
+function llms_get_post_sales_page_content( $post, $default = '' ) {
+
+ $content = $default;
+
+ if ( post_type_supports( $post->post_type, 'llms-sales-page' ) ) {
+ $sales_page = get_post_meta( $post->ID, '_llms_sales_page_content_type', true );
+ if ( $post->post_excerpt && ( '' === $sales_page || 'content' === $sales_page ) ) {
+ add_filter( 'the_excerpt', array( $GLOBALS['wp_embed'], 'autoembed' ), 9 );
+ $content = llms_get_excerpt( $post->ID );
+ }
+ }
+
+ /**
+ * Filters the HTML content of a LifterLMS post type's sales page content
+ *
+ * @since [version]
+ *
+ * @param string $content HTML content of the sales page.
+ * @param WP_Post $content Post object.
+ * @param string $default Default content used when no override content can be found.
+ */
+ return apply_filters( 'llms_post_sales_page_content', $content, $post, $default );
+
+}
+
/**
* Initialize LifterLMS post type content filters
*
From 978f06a6f0a7acbad4d59fc1ea563af30dc4de11 Mon Sep 17 00:00:00 2001
From: Thomas Patrick Levy
Date: Fri, 19 Feb 2021 20:57:30 -0700
Subject: [PATCH 04/12] Add better test coverage for all possible conditions
---
.../class-llms-test-functions-content.php | 340 +++++++++++++++++-
1 file changed, 337 insertions(+), 3 deletions(-)
diff --git a/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php b/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php
index 333fa7df3f..10c7e84248 100644
--- a/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php
+++ b/tests/phpunit/unit-tests/functions/class-llms-test-functions-content.php
@@ -11,21 +11,73 @@
*/
class LLMS_Test_Functions_Content extends LLMS_UnitTestCase {
- public function get_post_content( $post ) {
+ /**
+ * Helper to retrieve filtered post content for a given post
+ *
+ * @since [version]
+ *
+ * @param WP_Post $post Post object
+ * @return string
+ */
+ private function get_post_content( $post ) {
return trim( apply_filters( 'the_content', $post->post_content ) );
}
+ /**
+ * Retrieve a mock post of a give type with expected content and excerpts.
+ *
+ * @since [version]
+ *
+ * @param WP_Post $post Post object
+ * @return WP_Post
+ */
+ private function get_mock_post( $post_type ) {
+
+ global $post;
+ $post = $this->factory->post->create_and_get( array(
+ 'post_type' => $post_type,
+ 'post_content' => '
Post Content
',
+ 'post_excerpt' => '
Post Excerpt
',
+ ) );
+
+ return $post;
+
+ }
+
+ /**
+ * Callback for `llms_page_restricted` filter to force a page to look restricted
+ *
+ * @since [version]
+ *
+ * @param array $restrictions Restriction data array from llms_page_restricted().
+ * @return array
+ */
+ public function make_restricted( $restrictions ) {
+ $restrictions['is_restricted'] = true;
+ return $restrictions;
+ }
+
+ /**
+ * Test llms_get_post_content() for various post types
+ *
+ * This test was never a very good one but it's retained as it does ensure WP core post types
+ * are not affected by our functions.
+ *
+ * @since [version]
+ *
+ * @return void
+ */
public function test_llms_get_post_content() {
llms_post_content_init();
$content = '