Move dynamic segments from Premium plugin

[MAILPOET-2382]
This commit is contained in:
Jan Jakeš
2019-10-03 09:37:46 +02:00
committed by Jack Kitterhing
parent 0af9f09f50
commit 70a89b7939
41 changed files with 2674 additions and 0 deletions

View File

@ -0,0 +1,109 @@
<?php
namespace MailPoet\Premium\DynamicSegments\Filters;
use MailPoet\Models\StatisticsClicks;
use MailPoet\Models\StatisticsNewsletters;
use MailPoet\Models\StatisticsOpens;
use MailPoet\Models\Subscriber;
class EmailAction implements Filter {
const SEGMENT_TYPE = 'email';
const ACTION_OPENED = 'opened';
const ACTION_NOT_OPENED = 'notOpened';
const ACTION_CLICKED = 'clicked';
const ACTION_NOT_CLICKED = 'notClicked';
private static $allowed_actions = [
EmailAction::ACTION_OPENED,
EmailAction::ACTION_NOT_OPENED,
EmailAction::ACTION_CLICKED,
EmailAction::ACTION_NOT_CLICKED,
];
/** @var int */
private $newsletter_id;
/** @var int */
private $link_id;
/** @var string */
private $action;
/** @var string */
private $connect;
/**
* @param int $newsletter_id
* @param int $link_id
* @param string $action
* @param string $connect
*/
public function __construct($action, $newsletter_id, $link_id = null, $connect = null) {
$this->newsletter_id = (int)$newsletter_id;
if ($link_id) {
$this->link_id = (int)$link_id;
}
$this->setAction($action);
$this->connect = $connect;
}
private function setAction($action) {
if (!in_array($action, EmailAction::$allowed_actions)) {
throw new \InvalidArgumentException("Unknown action " . $action);
}
$this->action = $action;
}
function toSql(\ORM $orm) {
if (($this->action === EmailAction::ACTION_CLICKED) || ($this->action === EmailAction::ACTION_NOT_CLICKED)) {
$table = StatisticsClicks::$_table;
} else {
$table = StatisticsOpens::$_table;
}
if (($this->action === EmailAction::ACTION_NOT_CLICKED) || ($this->action === EmailAction::ACTION_NOT_OPENED)) {
$orm->rawJoin(
'INNER JOIN ' . StatisticsNewsletters::$_table,
'statssent.subscriber_id = ' . Subscriber::$_table . '.id AND statssent.newsletter_id = ' . $this->newsletter_id,
'statssent'
);
$orm->rawJoin(
'LEFT JOIN ' . $table,
$this->createNotStatsJoin(),
'stats'
);
$orm->whereNull('stats.id');
} else {
$orm->rawJoin(
'INNER JOIN ' . $table,
'stats.subscriber_id = ' . Subscriber::$_table . '.id AND stats.newsletter_id = ' . $this->newsletter_id,
'stats'
);
}
if (($this->action === EmailAction::ACTION_CLICKED) && ($this->link_id)) {
$orm->where('stats.link_id', $this->link_id);
}
return $orm;
}
private function createNotStatsJoin() {
$clause = 'statssent.subscriber_id = stats.subscriber_id AND stats.newsletter_id = ' . $this->newsletter_id;
if (($this->action === EmailAction::ACTION_NOT_CLICKED) && ($this->link_id)) {
$clause .= ' AND stats.link_id = ' . $this->link_id;
}
return $clause;
}
function toArray() {
return [
'action' => $this->action,
'newsletter_id' => $this->newsletter_id,
'link_id' => $this->link_id,
'connect' => $this->connect,
'segmentType' => EmailAction::SEGMENT_TYPE,
];
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace MailPoet\Premium\DynamicSegments\Filters;
interface Filter {
function toSql(\ORM $orm);
function toArray();
}

View File

@ -0,0 +1,44 @@
<?php
namespace MailPoet\Premium\DynamicSegments\Filters;
class UserRole implements Filter {
const SEGMENT_TYPE = 'userRole';
/** @var string */
private $role;
/** @var string */
private $connect;
/**
* @param string $role
* @param string $connect
*/
public function __construct($role, $connect = null) {
$this->role = $role;
$this->connect = $connect;
}
function toSql(\ORM $orm) {
global $wpdb;
$orm->join($wpdb->users, ['wpusers.id', '=', MP_SUBSCRIBERS_TABLE . '.wp_user_id'], 'wpusers')
->join($wpdb->usermeta, ['wpusers.ID', '=', 'wpusermeta.user_id'], 'wpusermeta')
->whereEqual('wpusermeta.meta_key', $wpdb->prefix . 'capabilities')
->whereLike('wpusermeta.meta_value', '%"' . $this->role . '"%');
return $orm;
}
public function toArray() {
return [
'wordpressRole' => $this->role,
'connect' => $this->connect,
'segmentType' => UserRole::SEGMENT_TYPE,
];
}
function getRole() {
return $this->role;
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace MailPoet\Premium\DynamicSegments\Filters;
use MailPoet\Models\Subscriber;
use MailPoet\WP\Functions as WPFunctions;
class WooCommerceCategory implements Filter {
const SEGMENT_TYPE = 'woocommerce';
const ACTION_CATEGORY = 'purchasedCategory';
/** @var int */
private $category_id;
/** @var string */
private $connect;
/**
* @param int $category_id
* @param string $connect
*/
public function __construct($category_id, $connect = null) {
$this->category_id = (int)$category_id;
$this->connect = $connect;
}
function toSql(\ORM $orm) {
global $wpdb;
$orm->distinct();
$orm->rawJoin(
'INNER JOIN ' . $wpdb->postmeta,
"postmeta.meta_key = '_customer_user' AND " . Subscriber::$_table . '.wp_user_id=postmeta.meta_value',
'postmeta'
);
$orm->join($wpdb->prefix . 'woocommerce_order_items', ['postmeta.post_id', '=', 'items.order_id'], 'items');
$orm->rawJoin(
'INNER JOIN ' . $wpdb->prefix . 'woocommerce_order_itemmeta',
"itemmeta.order_item_id = items.order_item_id AND itemmeta.meta_key = '_product_id'",
'itemmeta'
);
$orm->join($wpdb->term_relationships, ['itemmeta.meta_value', '=', 'term_relationships.object_id'], 'term_relationships');
$orm->rawJoin(
'INNER JOIN ' . $wpdb->term_taxonomy,
'
term_taxonomy.term_taxonomy_id=term_relationships.term_taxonomy_id
AND
term_taxonomy.term_id IN (' . join(',', $this->getAllCategoryIds()) . ')',
'term_taxonomy'
);
$orm->where('status', Subscriber::STATUS_SUBSCRIBED);
return $orm;
}
private function getAllCategoryIds() {
$subcategories = WPFunctions::get()->getTerms('product_cat', ['child_of' => $this->category_id]);
if (!is_array($subcategories)) return [];
$ids = array_map(function($category) {
return $category->term_id;
}, $subcategories);
$ids[] = $this->category_id;
return $ids;
}
function toArray() {
return [
'action' => WooCommerceCategory::ACTION_CATEGORY,
'category_id' => $this->category_id,
'connect' => $this->connect,
'segmentType' => WooCommerceCategory::SEGMENT_TYPE,
];
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace MailPoet\Premium\DynamicSegments\Filters;
use MailPoet\Models\Subscriber;
class WooCommerceProduct implements Filter {
const SEGMENT_TYPE = 'woocommerce';
const ACTION_PRODUCT = 'purchasedProduct';
/** @var int */
private $product_id;
/** @var string */
private $connect;
/**
* @param int $product_id
* @param string $connect
*/
public function __construct($product_id, $connect = null) {
$this->product_id = (int)$product_id;
$this->connect = $connect;
}
function toSql(\ORM $orm) {
global $wpdb;
$orm->distinct();
$orm->rawJoin(
'INNER JOIN ' . $wpdb->postmeta,
"postmeta.meta_key = '_customer_user' AND " . Subscriber::$_table . '.wp_user_id=postmeta.meta_value',
'postmeta'
);
$orm->join($wpdb->prefix . 'woocommerce_order_items', ['postmeta.post_id', '=', 'items.order_id'], 'items');
$orm->rawJoin(
'INNER JOIN ' . $wpdb->prefix . 'woocommerce_order_itemmeta',
"itemmeta.order_item_id=items.order_item_id
AND itemmeta.meta_key='_product_id'
AND itemmeta.meta_value=" . $this->product_id,
'itemmeta'
);
$orm->where('status', Subscriber::STATUS_SUBSCRIBED);
return $orm;
}
function toArray() {
return [
'action' => WooCommerceProduct::ACTION_PRODUCT,
'product_id' => $this->product_id,
'connect' => $this->connect,
'segmentType' => WooCommerceProduct::SEGMENT_TYPE,
];
}
}