From 9c5b83bff701e5c9d56cc3f4efb540f3477eb7a4 Mon Sep 17 00:00:00 2001 From: Bertrand Dunogier Date: Fri, 7 Nov 2014 16:57:17 +0100 Subject: [PATCH 1/4] EZP-22324: Implemented premium subscriber content A custom location view provider displays a teasing template if the content is Premium (section id 7 (Premium)), and if the user doesn't have the subscriber role (id: 6) section_id and role_id are configured in default_settings.yml. --- .../PremiumLocationViewProvider.php | 61 +++++++++++++++++++ PremiumContent/PremiumSubscriptionChecker.php | 57 +++++++++++++++++ Resources/config/default_settings.yml | 4 ++ Resources/config/services.yml | 15 +++++ .../views/full/premium_content.html.twig | 21 +++++++ doc/specifications/premium_content.md | 11 ++++ 6 files changed, 169 insertions(+) create mode 100644 PremiumContent/PremiumLocationViewProvider.php create mode 100644 PremiumContent/PremiumSubscriptionChecker.php create mode 100644 Resources/views/full/premium_content.html.twig create mode 100644 doc/specifications/premium_content.md diff --git a/PremiumContent/PremiumLocationViewProvider.php b/PremiumContent/PremiumLocationViewProvider.php new file mode 100644 index 0000000..7b1cfe0 --- /dev/null +++ b/PremiumContent/PremiumLocationViewProvider.php @@ -0,0 +1,61 @@ +repository = $repository; + $this->premiumSectionId = $premiumSectionId; + $this->subscriptionChecker = $subscriptionChecker; + } + + public function getView( Location $location, $viewType ) + { + if ( $viewType !== 'full' ) + { + return null; + } + + if ( $location->getContentInfo()->sectionId !== $this->premiumSectionId ) + { + return null; + } + + if ( $this->subscriptionChecker->userIsSubscriber( $this->repository->getCurrentUser() ) ) + { + return null; + } + + return new ContentView( "eZDemoBundle:$viewType:premium_content.html.twig" ); + } +} diff --git a/PremiumContent/PremiumSubscriptionChecker.php b/PremiumContent/PremiumSubscriptionChecker.php new file mode 100644 index 0000000..15a9dc3 --- /dev/null +++ b/PremiumContent/PremiumSubscriptionChecker.php @@ -0,0 +1,57 @@ +repository = $repository; + $this->roleId = $subscriberRoleId; + } + + public function userIsSubscriber( User $user ) + { + $roleService = $this->repository->getRoleService(); + return $this->repository->sudo( + function ( Repository $repository ) use ( $user, $roleService ) + { + foreach ( $repository->getUserService()->loadUserGroupsOfUser( $user ) as $group ) + { + foreach ( $roleService->getRoleAssignmentsForUserGroup( $group ) as $role ) + { + if ( $this->isSubscriberRole( $role->role ) ) + { + return true; + } + } + } + return false; + } + ); + } + + public function isSubscriberRole( Role $role ) + { + return $role->id === $this->roleId; + } +} diff --git a/Resources/config/default_settings.yml b/Resources/config/default_settings.yml index ea8fc5e..10e7e74 100644 --- a/Resources/config/default_settings.yml +++ b/Resources/config/default_settings.yml @@ -34,3 +34,7 @@ parameters: ## Search Page # Number of results displayed per page in the simple search ezdemo.search.list.limit: 10 + + ## Premium content + ezdemo.premium_content.section_id: 7 + ezdemo.premium_content.role_id: 6 diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 77d3196..10c2e1e 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -69,3 +69,18 @@ services: scope: request # needed as we have the request as a dependency here tags: - { name: knp_menu.menu, alias: top } # The alias is what is used to retrieve the menu + + ezdemo.premium_content.location_view_provider: + class: EzSystems\DemoBundle\PremiumContent\PremiumLocationViewProvider + arguments: + - @ezpublish.api.repository + - @ezdemo.premium_content.subscription_checker + - %ezdemo.premium_content.section_id% + tags: + - {name: ezpublish.location_view_provider, priority: 30} + + ezdemo.premium_content.subscription_checker: + class: EzSystems\DemoBundle\PremiumContent\PremiumSubscriptionChecker + arguments: + - @ezpublish.api.repository + - %ezdemo.premium_content.role_id% diff --git a/Resources/views/full/premium_content.html.twig b/Resources/views/full/premium_content.html.twig new file mode 100644 index 0000000..d243b4d --- /dev/null +++ b/Resources/views/full/premium_content.html.twig @@ -0,0 +1,21 @@ +{% extends "eZDemoBundle::pagelayout.html.twig" %} + +{% block content %} +
+
+
+
+

{{ ez_render_field( content, 'title' ) }}

+
+ + {% if not ez_is_field_empty( content, 'subscriber_teaser' ) %} +
+ {{ ez_render_field( content, 'subscriber_teaser' ) }} +
+ {% endif %} + + This article is only available to Premium subscribers. +
+
+
+{% endblock %} diff --git a/doc/specifications/premium_content.md b/doc/specifications/premium_content.md new file mode 100644 index 0000000..ddccd26 --- /dev/null +++ b/doc/specifications/premium_content.md @@ -0,0 +1,11 @@ +# Premium content + +This feature displays content marked as Premium using a special teaser and informations about the status. It is +an example of what could be used to offer a paywall. + +## Implementation +Premium content is identified belonging to section Premium (ID: 7). Subscribers have the Subscriber role (ID: 6). + +A standard policy check can't be used here, as it would prevent the content from being returned in searches and lists. +Instead, Anonymous user can read this content, but a custom ViewProvider is used to return a special premium_teaser +template when a premium content is viewed by a non-subscriber. From fbb2fd887484f5fdaa8153471eabe27e1ae0905e Mon Sep 17 00:00:00 2001 From: Bertrand Dunogier Date: Fri, 7 Nov 2014 16:53:37 +0100 Subject: [PATCH 2/4] EZP-22324: BDD tests for premium content --- Features/Content/premium_content.feature | 24 ++++++++++++++++++++++++ Features/Context/Demo.php | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 Features/Content/premium_content.feature diff --git a/Features/Content/premium_content.feature b/Features/Content/premium_content.feature new file mode 100644 index 0000000..8a4f4ad --- /dev/null +++ b/Features/Content/premium_content.feature @@ -0,0 +1,24 @@ +Feature: Premium content + + Scenario: As a subscribed User, I get the full content + Given I am logged in as "john.doe" with password "publish" + When I go to "/Premium-article" + Then I am on the "premium_article" page + And I see "This summary will only be shown to subscribers" text + And I see "This body will also be limited to premium subscribers" text + + Scenario: As a regular member, I get a teaser for Premium Content + Given I am logged in as "zachary.zoe" with password "publish" + When I go to "/Premium-article" + Then I am on the "premium_article" page + And I see "This is the subscriber teaser" text + And I see "This article is only available to Premium subscribers" text + And I don't see "This summary will only be shown to subscribers" text + + Scenario: As an anonymous user, I get a login box on Premium Content + When I go to "/Premium-article" + Then I am on the "premium_article" page + And I see "This is the subscriber teaser" text + And I see "This article is only available to Premium subscribers" text + And I don't see "This summary will only be shown to subscribers" text + # And I see a login form diff --git a/Features/Context/Demo.php b/Features/Context/Demo.php index 37c213d..0ce1a1d 100644 --- a/Features/Context/Demo.php +++ b/Features/Context/Demo.php @@ -26,7 +26,8 @@ public function __construct() parent::__construct(); $this->pageIdentifierMap += array( - "search" => "/content/search" + "search" => "/content/search", + "premium_article" => "/Premium-article" ); $this->mainAttributes += array( From 8a812d4edf44ffdf8d27f2eb5dd3f0d6c3944453 Mon Sep 17 00:00:00 2001 From: Bertrand Dunogier Date: Tue, 18 Nov 2014 23:44:30 +0100 Subject: [PATCH 3/4] EZP-22324: updated premium content scenarii --- Features/Content/premium_content.feature | 26 ++++++++---------------- Features/Context/Demo.php | 2 +- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Features/Content/premium_content.feature b/Features/Content/premium_content.feature index 8a4f4ad..0863148 100644 --- a/Features/Content/premium_content.feature +++ b/Features/Content/premium_content.feature @@ -1,24 +1,16 @@ Feature: Premium content Scenario: As a subscribed User, I get the full content - Given I am logged in as "john.doe" with password "publish" - When I go to "/Premium-article" + Given I am logged in as "subscriber" with password "publish" + When I go to "/Getting-Started/Selected-Features/Getting-Started-with-eZ-Publish-Platform" Then I am on the "premium_article" page - And I see "This summary will only be shown to subscribers" text - And I see "This body will also be limited to premium subscribers" text + And I see "Our objective is to provide you the most compelling" text + And I see "Welcome to eZ Publish Platform 5.4, the Castor release." text Scenario: As a regular member, I get a teaser for Premium Content - Given I am logged in as "zachary.zoe" with password "publish" - When I go to "/Premium-article" + Given I am logged in as "member" with password "publish" + When I go to "/Getting-Started/Selected-Features/Getting-Started-with-eZ-Publish-Platform" Then I am on the "premium_article" page - And I see "This is the subscriber teaser" text - And I see "This article is only available to Premium subscribers" text - And I don't see "This summary will only be shown to subscribers" text - - Scenario: As an anonymous user, I get a login box on Premium Content - When I go to "/Premium-article" - Then I am on the "premium_article" page - And I see "This is the subscriber teaser" text - And I see "This article is only available to Premium subscribers" text - And I don't see "This summary will only be shown to subscribers" text - # And I see a login form + And I see "Key new features you don't want to miss" text + And I see "This article is only available to Premium subscribers." text + And I don't see "Our objective is to provide you the most compelling" text diff --git a/Features/Context/Demo.php b/Features/Context/Demo.php index 0ce1a1d..d623701 100644 --- a/Features/Context/Demo.php +++ b/Features/Context/Demo.php @@ -27,7 +27,7 @@ public function __construct() $this->pageIdentifierMap += array( "search" => "/content/search", - "premium_article" => "/Premium-article" + "premium_article" => "/Getting-Started/Selected-Features/Getting-Started-with-eZ-Publish-Platform" ); $this->mainAttributes += array( From 46293b42dd0b2f9d95f87be238f60bada5de204d Mon Sep 17 00:00:00 2001 From: Bertrand Dunogier Date: Wed, 19 Nov 2014 00:14:52 +0100 Subject: [PATCH 4/4] Updated tag cloud tests to demo content --- Features/Content/tag_cloud.feature | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Features/Content/tag_cloud.feature b/Features/Content/tag_cloud.feature index 6c6e9b6..acb3656 100644 --- a/Features/Content/tag_cloud.feature +++ b/Features/Content/tag_cloud.feature @@ -13,7 +13,7 @@ Feature: Tag cloud When I go to "Tag cloud" page Then I should see links: | tags | - | Ventoux | + | Castor | | Blog Post | | cxm | | deliver | @@ -29,12 +29,12 @@ Feature: Tag cloud Examples: | tag | | Social | - | Ventoux | + | Castor | | deliver | Scenario: See where tags are used Given I am on "Tag cloud" page - When I click at "Ventoux" link + When I click at "Castor" link Then I should see table with: | column 1 | column 2 | | Link | Type | @@ -43,7 +43,7 @@ Feature: Tag cloud Scenario: Follow to Content object where Tag is used - Given I am on tag page for "Ventoux" + Given I am on tag page for "Castor" When I click at "Optimize" link Then I should see "Optimize" title @@ -52,7 +52,7 @@ Feature: Tag cloud When I go to tag cloud for "Getting started" Then I should see links: | links | - | deliver | - | Ventoux | - | kilimanjaro | - And I should see "Ventoux" text emphasized + | automate | + | Castor | + | create | + And I should see "Castor" text emphasized