Newer
Older
use QUI\ERP\Products\Handler\Products;
use QUI\Lock\Locker;
use QUI\Memberships\Users\Handler as MembershipUsersHandler;
use QUI\Utils\Security\Orthos;
use QUI\ERP\Products\Search\BackendSearch;
use QUI\Memberships\Products\MembershipField;
use QUI\ERP\Products\Handler\Products as ProductsHandler;
use QUI\ERP\Products\Handler\Fields as ProductFields;
/**
* Get IDs of all QUIQQER Groups
*
* @return int[]
*/
public function getGroupIds()
{
$groupIds = $this->getAttribute('groupIds');
return explode(",", trim($groupIds, ","));
}
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* Get membership title
*
* @param Locale $Locale (optional)
* @return string - localized title
*/
public function getTitle($Locale = null)
{
if (is_null($Locale)) {
$Locale = QUI::getLocale();
}
$trans = json_decode($this->getAttribute('title'), true);
if (isset($trans[$Locale->getCurrent()])) {
return $trans[$Locale->getCurrent()];
}
return '';
}
/**
* Get membership description
*
* @param Locale $Locale (optional)
* @return string - localized description
*/
public function getDescription($Locale = null)
{
if (is_null($Locale)) {
$Locale = QUI::getLocale();
}
$trans = json_decode($this->getAttribute('description'), true);
if (isset($trans[$Locale->getCurrent()])) {
return $trans[$Locale->getCurrent()];
}
return '';
}
/**
* Get membership content
*
* @param Locale $Locale (optional)
* @return string - localized content
*/
public function getContent($Locale = null)
{
if (is_null($Locale)) {
$Locale = QUI::getLocale();
}
$trans = json_decode($this->getAttribute('content'), true);
if (isset($trans[$Locale->getCurrent()])) {
return $trans[$Locale->getCurrent()];
}
return '';
}
* Check if this membership is auto-extended
public function isAutoExtend()
return $this->getAttribute('autoExtend') ? true : false;
Permission::checkPermission(Handler::PERMISSION_EDIT);
$attributes = $this->getAttributes();
// check groups
if (empty($attributes['groupIds'])
) {

Patrick Müller
committed
throw new QUI\Memberships\Exception([
'quiqqer/memberships',
'exception.handler.no.groups'

Patrick Müller
committed
]);

Patrick Müller
committed
$attributes['groupIds'] = ','.$attributes['groupIds'].',';
if (empty($attributes['duration'])
|| $attributes['duration'] === 'infinite'
) {
$attributes['duration'] = 'infinite';
} else {
$duration = explode('-', $attributes['duration']);

Patrick Müller
committed
throw new QUI\Memberships\Exception([
'quiqqer/memberships',
'exception.membership.update.duration.invalid'

Patrick Müller
committed
]);
}
// edit user and timestamp
$attributes['editUser'] = QUI::getUserBySession()->getId();
$attributes['editDate'] = Utils::getFormattedTimestamp();
$this->setAttributes($attributes);

Patrick Müller
committed
* Only possible if membership has no users in it!

Patrick Müller
committed
* @throws \QUI\Memberships\Exception
* @throws \QUI\Permissions\Exception
* @throws \QUI\Exception
*/
public function delete()
{
Permission::checkPermission(Handler::PERMISSION_DELETE);
$MembershipUsers = MembershipUsersHandler::getInstance();
if (count($MembershipUsers->getIdsByMembershipId($this->id))) {

Patrick Müller
committed
throw new Exception([
'quiqqer/memberships',
'exception.membership.cannot.delete.with.users.left'

Patrick Müller
committed
]);
if ($this->isDefault()) {
$Conf = QUI::getPackage('quiqqer/memberships')->getConfig();
$Conf->set('memberships', 'defaultMembershipId', '0');
$Conf->save();
}
// remove from products
if (Utils::isQuiqqerProductsInstalled()) {
/** @var QUI\ERP\Products\Product\Product $Product */
foreach ($this->getProducts() as $Product) {

Patrick Müller
committed
$MembershipField = $Product->getField(
Handler::getProductMembershipField()->getId()
);

Patrick Müller
committed
$MembershipFlagField = $Product->getField(
Handler::getProductMembershipFlagField()->getId()
);
$MembershipFlagField->setValue(null);
$Product->deactivate();
$Product->save();
}
}
if (Utils::isQuiqqerContractsInstalled()) {
// @todo quiqqer/contracts abhandeln
}
* Get a user of this membership (non-archived)
* @return QUI\Memberships\Users\MembershipUser
* @throws QUI\Memberships\Exception
*/
public function getMembershipUser($userId)
{

Patrick Müller
committed
$result = QUI::getDataBase()->fetch([
'select' => [

Patrick Müller
committed
],
'from' => MembershipUsersHandler::getInstance()->getDataBaseTableName(),

Patrick Müller
committed
'where' => [
'userId' => $userId,
'archived' => 0

Patrick Müller
committed
]
]);

Patrick Müller
committed
throw new Exception([
'quiqqer/memberships',
'exception.membership.user.not.found',

Patrick Müller
committed
[

Patrick Müller
committed
]
], 404);
}
return MembershipUsersHandler::getInstance()->getChild($result[0]['id']);
}
/**
* Get IDs of all QUIQQER Groups that are UNIQUE to this membership
public function getUniqueGroupIds()
$Memberships = Handler::getInstance();
$groupIds = $this->getGroupIds();
$uniqueGroupIds = $groupIds;
foreach ($Memberships->getMembershipIdsByGroupIds($groupIds) as $membershipId) {
if ($membershipId == $this->getId()) {
continue;
}
$Membership = $Memberships->getChild($membershipId);
foreach ($Membership->getGroupIds() as $groupId) {
if (in_array($groupId, $groupIds)) {
$k = array_search($groupId, $uniqueGroupIds);
if ($k !== false) {
unset($uniqueGroupIds[$k]);
}
}
}
}
* Checks if this membership has an (active, non-archived) user assigned
*
* @param int $userId
* @return bool
*/
public function hasMembershipUserId($userId)
{

Patrick Müller
committed
$result = QUI::getDataBase()->fetch([

Patrick Müller
committed
'select' => [

Patrick Müller
committed
],
'from' => MembershipUsersHandler::getInstance()->getDataBaseTableName(),

Patrick Müller
committed
'where' => [

Patrick Müller
committed
]
]);
return current(current($result)) > 0;
}
/**
* @param bool $archivedOnly (optional) - search archived users only [default: false]
* @param bool $countOnly (optional) - get count for search result only [default: false]
* @return int[]|int - membership user IDs or count
public function searchUsers($searchParams, $archivedOnly = false, $countOnly = false)

Patrick Müller
committed
$membershipUserIds = [];
$Grid = new QUI\Utils\Grid($searchParams);
$gridParams = $Grid->parseDBParams($searchParams);
$tbl = MembershipUsersHandler::getInstance()->getDataBaseTableName();
$usersTbl = QUI::getDBTableName('users');

Patrick Müller
committed
$binds = [];
$where = [];
$sql = "SELECT COUNT(*)";
} else {
$sql = "SELECT `musers`.id";
}

Patrick Müller
committed
$sql .= " FROM `".$tbl."` musers, `".$usersTbl."` users";
$where[] = '`musers`.userId = `users`.id';

Patrick Müller
committed
$where[] = '`musers`.membershipId = '.$this->id;
if ($archivedOnly === false) {
$where[] = '`musers`.archived = 0';
} else {
$where[] = '`musers`.archived = 1';
}
if (!empty($searchParams['search'])) {

Patrick Müller
committed
$whereOR = [];

Patrick Müller
committed
$searchColumns = [
'`users`.username',
'`users`.firstname',
'`users`.lastname'

Patrick Müller
committed
];
foreach ($searchColumns as $tbl => $column) {

Patrick Müller
committed
$whereOR[] = $column.' LIKE :search';
$binds['search'] = [
'value' => '%'.$searchParams['search'].'%',
'type' => \PDO::PARAM_STR

Patrick Müller
committed
];

Patrick Müller
committed
$where[] = '('.implode(' OR ', $whereOR).')';
if (!empty($searchParams['productId'])) {
$where[] = '`musers`.productId = :productId';

Patrick Müller
committed
$binds['productId'] = [
'value' => (int)$searchParams['productId'],
'type' => \PDO::PARAM_INT

Patrick Müller
committed
];
// build WHERE query string
if (!empty($where)) {

Patrick Müller
committed
$sql .= " WHERE ".implode(" AND ", $where);
}
// ORDER
if (!empty($searchParams['sortOn'])
) {
$sortOn = Orthos::clear($searchParams['sortOn']);
switch ($sortOn) {
case 'username':
case 'firstname':
case 'lastname':

Patrick Müller
committed
$sortOn = '`users`.'.$sortOn;

Patrick Müller
committed
$sortOn = '`musers`.'.$sortOn;

Patrick Müller
committed
$order = "ORDER BY ".$sortOn;
if (isset($searchParams['sortBy']) &&
!empty($searchParams['sortBy'])
) {

Patrick Müller
committed
$order .= " ".Orthos::clear($searchParams['sortBy']);
} else {
$order .= " ASC";
}

Patrick Müller
committed
$sql .= " ".$order;
}
// LIMIT
if (!empty($gridParams['limit'])
&& !$countOnly
) {

Patrick Müller
committed
$sql .= " LIMIT ".$gridParams['limit'];
} else {
if (!$countOnly) {

Patrick Müller
committed
$sql .= " LIMIT ".(int)20;
$Stmt = QUI::getPDO()->prepare($sql);
// bind search values
foreach ($binds as $var => $bind) {

Patrick Müller
committed
$Stmt->bindValue(':'.$var, $bind['value'], $bind['type']);
}
try {
$Stmt->execute();
$result = $Stmt->fetchAll(\PDO::FETCH_ASSOC);
} catch (\Exception $Exception) {
QUI\System\Log::addError(

Patrick Müller
committed
self::class.' :: searchUsers() -> '.$Exception->getMessage()

Patrick Müller
committed
return [];
}
if ($countOnly) {
return (int)current(current($result));
}
foreach ($result as $row) {
$membershipUserIds[] = (int)$row['id'];
}
return $membershipUserIds;
}
/**
* Calculate the end date for this membership based on a given time
*
* @param int $start (optional) - UNIX timestamp; if omitted use time()
*/
public function calcEndDate($start = null)
{
if ($this->isInfinite()) {
return null;
}
if (is_null($start)) {
$start = time();
}
$start = Utils::getFormattedTimestamp($start);
$duration = explode('-', $this->getAttribute('duration'));
$durationCount = $duration[0];
$durationScope = $duration[1];

Patrick Müller
committed
$durationMode = Handler::getSetting('durationMode');
switch ($durationMode) {
case 'day':

Patrick Müller
committed
$endTime = strtotime($start.' +'.$durationCount.' '.$durationScope);

Patrick Müller
committed
$beginOfDay = strtotime("midnight", $endTime);
$end = strtotime("tomorrow", $beginOfDay) - 1;
break;
default:

Patrick Müller
committed
$end = strtotime($start.' +'.$durationCount.' '.$durationScope);

Patrick Müller
committed
}
return Utils::getFormattedTimestamp($end);
}
* Requires: quiqqer/products
*
* Get all products that have this membership assigned
*
* @return QUI\ERP\Products\Product\Product[]
*/
public function getProducts()
{
if (!Utils::isQuiqqerProductsInstalled()) {

Patrick Müller
committed
return [];

Patrick Müller
committed
$Search = new BackendSearch();
$MembershipField = Handler::getProductMembershipField();
if ($MembershipField === false) {
return [];
}
$result = $Search->search([
'fields' => [
$MembershipField->getId() => "$this->id" // has to be string
]
]);
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
return [];

Patrick Müller
committed
$products = [];

Patrick Müller
committed
try {
$products[] = ProductsHandler::getProduct($id);
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
}
return $products;
}
/**
* Requires: quiqqer/products
*
* Create a Product from this Membership
*
* Hint: Every time this method is called, a new Product is created, regardless
* of previous calls!
*
* @return QUI\ERP\Products\Product\Product|false
*/
public function createProduct()
{
if (!Utils::isQuiqqerProductsInstalled()) {
return false;
}

Patrick Müller
committed
$categories = [];
$fields = [];
$Category = Handler::getProductCategory();
if ($Category) {
$categories[] = $Category;
}
$MembershipField = Handler::getProductMembershipField();
if ($MembershipField !== false) {
$MembershipField->setValue($this->id);
$fields[] = $MembershipField;
}
$MembershipFlagField = Handler::getProductMembershipFlagField();
if ($MembershipFlagField !== false) {
$MembershipFlagField->setValue(true);
$fields[] = $MembershipFlagField;
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
}
// set title and description
$TitleField = ProductFields::getField(ProductFields::FIELD_TITLE);
$DescField = ProductFields::getField(ProductFields::FIELD_SHORT_DESC);
$title = json_decode($this->getAttribute('title'), true);
$description = json_decode($this->getAttribute('description'), true);
if (!empty($title)) {
$TitleField->setValue($title);
$fields[] = $TitleField;
}
if (!empty($description)) {
$DescField->setValue($description);
$fields[] = $DescField;
}
$Product = ProductsHandler::createProduct($categories, $fields);
if (!empty($categories)) {
$Product->setMainCategory($categories[0]);
$Product->save();
}
return $Product;
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
/**
* Locks editing of this membership for the current session user
*
* @return void
*/
public function lock()
{
Locker::lock(QUI::getPackage('quiqqer/memberships'), $this->getLockKey());
}
/**
* Unlock membership (requires permission!)
*
* @return void
* @throws QUI\Permissions\Exception
*/
public function unlock()
{
Locker::unlockWithPermissions(
QUI::getPackage('quiqqer/memberships'),
$this->getLockKey(),
Handler::PERMISSION_FORCE_EDIT
);
}
/**
* Check if this membership is currently locked
*
* @return bool
*/
public function isLocked()
{
return Locker::isLocked(QUI::getPackage('quiqqer/memberships'), $this->getLockKey());
}
/**
* Get membership lock key
*
* @return string
*/
protected function getLockKey()
{

Patrick Müller
committed
return 'membership_'.$this->id;
/**
* Get membership data for backend view/edit purposes
*
* @return array
*/
public function getBackendViewData()
{

Patrick Müller
committed
return [
'id' => $this->getId(),
'title' => $this->getTitle(),
'description' => $this->getDescription(),
'content' => $this->getContent()

Patrick Müller
committed
];
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
/**
* Check if this membership has an infinite duration (never expires)
*
* @return bool
*/
public function isInfinite()
{
return $this->getAttribute('duration') === 'infinite';
}
/**
* Check if this Membership is the default Memberships
*
* @return bool
*/
public function isDefault()
{
$DefaultMembership = Handler::getDefaultMembership();
if ($DefaultMembership === false) {
return false;
}
return $DefaultMembership->getId() === $this->getId();
}
/**
* Add user to the membership
*
* @param QUI\Users\User $User
* @return QUI\Memberships\Users\MembershipUser
*/
public function addUser(QUI\Users\User $User)
{

Patrick Müller
committed
return MembershipUsersHandler::getInstance()->createChild([
'userId' => $User->getId(),
'membershipId' => $this->id

Patrick Müller
committed
]);