Skip to content

Commit

Permalink
Merge pull request ezsystems#116 from ezsystems/EZP-22324-premium_con…
Browse files Browse the repository at this point in the history
…tent

Implemented premium subscriber content
  • Loading branch information
bdunogier committed Nov 19, 2014
2 parents 0a59a6e + 46293b4 commit a7ba7b3
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 9 deletions.
16 changes: 16 additions & 0 deletions Features/Content/premium_content.feature
@@ -0,0 +1,16 @@
Feature: Premium content

Scenario: As a subscribed User, I get the full content
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 "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 "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 "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
16 changes: 8 additions & 8 deletions Features/Content/tag_cloud.feature
Expand Up @@ -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 |
Expand All @@ -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 |
Expand All @@ -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

Expand All @@ -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
3 changes: 2 additions & 1 deletion Features/Context/Demo.php
Expand Up @@ -26,7 +26,8 @@ public function __construct()
parent::__construct();

$this->pageIdentifierMap += array(
"search" => "/content/search"
"search" => "/content/search",
"premium_article" => "/Getting-Started/Selected-Features/Getting-Started-with-eZ-Publish-Platform"
);

$this->mainAttributes += array(
Expand Down
61 changes: 61 additions & 0 deletions PremiumContent/PremiumLocationViewProvider.php
@@ -0,0 +1,61 @@
<?php
/**
* This file is part of the eZ Publish Kernel package
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributd with this source code.
*/
namespace EzSystems\DemoBundle\PremiumContent;

use eZ\Publish\API\Repository\Repository;
use eZ\Publish\API\Repository\Values\Content\Location;
use eZ\Publish\API\Repository\Values\User\Role;
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
use eZ\Publish\Core\MVC\Symfony\View\Provider\Location as LocationViewProvider;

/**
* Returns the premium_content view if it applies to a location and if the user isn't a Premium subscriber.
*/
class PremiumLocationViewProvider implements LocationViewProvider
{
/**
* ID of the section used to mark content as Premium
* @var int
*/
private $premiumSectionId;

/** @var PremiumSubscriptionChecker */
private $subscriptionChecker;

/**
* @var Repository
*/
private $repository;

public function __construct( Repository $repository, PremiumSubscriptionChecker $subscriptionChecker, $premiumSectionId )
{
$this->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" );
}
}
57 changes: 57 additions & 0 deletions PremiumContent/PremiumSubscriptionChecker.php
@@ -0,0 +1,57 @@
<?php
/**
* This file is part of the eZ Publish Kernel package
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributd with this source code.
*/
namespace EzSystems\DemoBundle\PremiumContent;

use eZ\Publish\API\Repository\Values\User\User;
use eZ\Publish\API\Repository\Repository;
use eZ\Publish\API\Repository\Values\User\Role;

class PremiumSubscriptionChecker
{
/**
* ID of the premium subscriber role
*/
private $roleId = 6;

/**
* @var Repository|\eZ\Publish\Core\Repository\Repository
*/
private $repository;

public function __construct( Repository $repository, $subscriberRoleId )
{
$this->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;
}
}
4 changes: 4 additions & 0 deletions Resources/config/default_settings.yml
Expand Up @@ -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
15 changes: 15 additions & 0 deletions Resources/config/services.yml
Expand Up @@ -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%
21 changes: 21 additions & 0 deletions Resources/views/full/premium_content.html.twig
@@ -0,0 +1,21 @@
{% extends "eZDemoBundle::pagelayout.html.twig" %}

{% block content %}
<section class="content-view-full">
<article class="class-article row">
<div class="span8">
<div class="attribute-header">
<h1>{{ ez_render_field( content, 'title' ) }}</h1>
</div>

{% if not ez_is_field_empty( content, 'subscriber_teaser' ) %}
<div class="attribute-short">
{{ ez_render_field( content, 'subscriber_teaser' ) }}
</div>
{% endif %}

This article is only available to Premium subscribers.
</div>
</article>
</section>
{% endblock %}
11 changes: 11 additions & 0 deletions 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.

0 comments on commit a7ba7b3

Please sign in to comment.