Implement userRole filter using Doctrine

[MAILPOET-3077]
This commit is contained in:
Rostislav Wolny
2020-09-16 14:50:39 +02:00
committed by Veljko V
parent d2e46c17ed
commit cf76480ab3
5 changed files with 117 additions and 7 deletions

View File

@ -256,6 +256,7 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\Segments\WooCommerce::class)->setPublic(true);
$container->autowire(\MailPoet\Segments\SubscribersFinder::class);
$container->autowire(\MailPoet\Segments\SegmentsRepository::class);
$container->autowire(\MailPoet\Segments\DynamicSegments\Filters\UserRole::class)->setPublic(true);
// Services
$container->autowire(\MailPoet\Services\Bridge::class)->setPublic(true);
$container->autowire(\MailPoet\Services\AuthorizedEmailsController::class);

View File

@ -18,6 +18,8 @@ class DynamicSegmentFilterEntity {
use UpdatedAtTrait;
use SafeToOneAssociationLoadTrait;
const TYPE_USER_ROLE = 'userRole';
/**
* @ORM\ManyToOne(targetEntity="MailPoet\Entities\SegmentEntity", inversedBy="filters")
* @var SegmentEntity|null

View File

@ -2,8 +2,9 @@
namespace MailPoet\Segments\DynamicSegments\Filters;
use MailPoet\Entities\DynamicSegmentFilterEntity;
use MailPoetVendor\Doctrine\DBAL\Query\QueryBuilder;
interface Filter {
public function apply(QueryBuilder $queryBuilder): QueryBuilder;
public function apply(QueryBuilder $queryBuilder, DynamicSegmentFilterEntity $filterEntity): QueryBuilder;
}

View File

@ -2,17 +2,31 @@
namespace MailPoet\Segments\DynamicSegments\Filters;
use MailPoet\Entities\DynamicSegmentFilterEntity;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Segments\DynamicSegments\Exceptions\InvalidFilterException;
use MailPoetVendor\Doctrine\DBAL\Query\QueryBuilder;
use MailPoetVendor\Doctrine\ORM\EntityManager;
class UserRole implements Filter {
/** @var string */
private $role;
/** @var EntityManager */
private $entityManager;
public function __construct(string $role) {
$this->role = $role;
public function __construct(EntityManager $entityManager) {
$this->entityManager = $entityManager;
}
public function apply(QueryBuilder $queryBuilder): QueryBuilder {
return $queryBuilder;
public function apply(QueryBuilder $queryBuilder, DynamicSegmentFilterEntity $filterEntity): QueryBuilder {
global $wpdb;
$role = $filterEntity->getFilterDataParam('wordpressRole');
if (!$role) {
throw new InvalidFilterException('Missing role', InvalidFilterException::MISSING_ROLE);
}
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
return $queryBuilder->join($subscribersTable, $wpdb->users, 'wpusers', "$subscribersTable.wp_user_id = wpusers.id")
->join('wpusers', $wpdb->usermeta, 'wpusermeta', 'wpusers.id = wpusermeta.user_id')
->andWhere("wpusermeta.meta_key = '{$wpdb->prefix}capabilities' AND wpusermeta.meta_value LIKE :role")
->setParameter(':role', '%"' . $role . '"%');
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace MailPoet\Segments\DynamicSegments\Filters;
use MailPoet\Entities\DynamicSegmentFilterEntity;
use MailPoet\Entities\SegmentEntity;
use MailPoet\Entities\SubscriberEntity;
require_once(ABSPATH . 'wp-admin/includes/user.php');
class UserRoleTest extends \MailPoetTest {
private $userRole;
public function _before() {
$this->userRole = $this->diContainer->get(UserRole::class);
$this->cleanWpUsers();
// Insert WP users and subscribers are created automatically
wp_insert_user([
'user_login' => 'user-role-test1',
'user_email' => 'user-role-test1@example.com',
'role' => 'editor',
'user_pass' => '12123154',
]);
wp_insert_user([
'user_login' => 'user-role-test2',
'user_email' => 'user-role-test2@example.com',
'role' => 'administrator',
'user_pass' => '12123154',
]);
wp_insert_user([
'user_login' => 'user-role-test3',
'user_email' => 'user-role-test3@example.com',
'role' => 'editor',
'user_pass' => '12123154',
]);
}
public function testItAppliesFilter() {
$segmentFilter = $this->getSegmentFilter('editor');
$queryBuilder = $this->userRole->apply($this->getQueryBuilder(), $segmentFilter);
$result = $queryBuilder->execute()->fetchAll();
expect(count($result))->equals(2);
$subscriber1 = $this->entityManager->find(SubscriberEntity::class, $result[0]['id']);
assert($subscriber1 instanceof SubscriberEntity);
$subscriber2 = $this->entityManager->find(SubscriberEntity::class, $result[1]['id']);
assert($subscriber2 instanceof SubscriberEntity);
expect($subscriber1->getEmail())->equals('user-role-test1@example.com');
expect($subscriber2->getEmail())->equals('user-role-test3@example.com');
}
public function testItDoesntGetSubString() {
$segmentFilter = $this->getSegmentFilter('edit');
$queryBuilder = $this->userRole->apply($this->getQueryBuilder(), $segmentFilter);
$result = $queryBuilder->execute()->fetchAll();
expect(count($result))->equals(0);
}
private function getQueryBuilder() {
$subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName();
return $this->entityManager
->getConnection()
->createQueryBuilder()
->select("$subscribersTable.id")
->from($subscribersTable);
}
private function getSegmentFilter(string $role): DynamicSegmentFilterEntity {
return new DynamicSegmentFilterEntity(
new SegmentEntity('segment', SegmentEntity::TYPE_DYNAMIC),
[
'segmentType' => DynamicSegmentFilterEntity::TYPE_USER_ROLE,
'wordpressRole' => $role,
]
);
}
public function _after() {
$this->cleanWpUsers();
$this->truncateEntity(SubscriberEntity::class);
}
private function cleanWpUsers() {
$emails = ['user-role-test1@example.com', 'user-role-test2@example.com', 'user-role-test3@example.com'];
foreach ($emails as $email) {
$user = get_user_by('email', $email);
if ($user) {
wp_delete_user($user->ID);
}
}
}
}