Skip to content
Code-Schnipsel Gruppen Projekte
MembershipUser.php 13,8 KiB
Newer Older
Patrick Müller's avatar
Patrick Müller committed
<?php

namespace QUI\Memberships\Users;

use QUI;
use QUI\CRUD\Child;
use QUI\Memberships\Handler as MembershipsHandler;
Patrick Müller's avatar
Patrick Müller committed
use QUI\Memberships\Users\Handler as MembershipUsersHandler;
use QUI\Memberships\Utils;
use QUI\Mail\Mailer;
Patrick Müller's avatar
Patrick Müller committed

/**
 * Class MembershipUser
 *
 * Represents a user that is assigned to a specific membership
 *
 * @package QUI\Memberships\Users
 */
class MembershipUser extends Child
{
Patrick Müller's avatar
Patrick Müller committed
    /**
     * @inheritdoc
     */
    public function update()
    {
        // check certain attributes
        $beginDate = strtotime($this->getAttribute('beginDate'));
        $endDate   = strtotime($this->getAttribute('endDate'));

        if ($beginDate === false
            || $endDate === false
        ) {
            throw new QUI\Memberships\Exception(array(
                'quiqqer/memberships',
                'exception.users.membershipuser.wrong.dates'
            ));
        }

        if ($beginDate >= $endDate) {
            throw new QUI\Memberships\Exception(array(
                'quiqqer/memberships',
                'exception.users.membershipuser.begin.after.end'
            ));
        }

        parent::update();
    }

Patrick Müller's avatar
Patrick Müller committed
    /**
     * Extend the current membership cycle of this membership user
Patrick Müller's avatar
Patrick Müller committed
     *
     * @param bool $auto (optional) - Used if the membership is automatically extended.
     * If set to false, the setting membershipusers.extendMode is used [default: true]
Patrick Müller's avatar
Patrick Müller committed
     * @return void
     */
    public function extend($auto = true)
Patrick Müller's avatar
Patrick Müller committed
    {
        $Membership = $this->getMembership();
        $extendMode = MembershipUsersHandler::getConfigEntry('extendMode');
        if ($auto || $extendMode === 'reset') {
            $start         = time();
            $extendCounter = $this->getAttribute('extendCounter');
            $this->setAttributes(array(
                'beginDate'     => Utils::getFormattedTimestamp($start),
                'endDate'       => $Membership->calcEndDate($start),
                'extendCounter' => $extendCounter + 1
            ));
        } else {
            $endDate = $this->getAttribute('endDate');

            $this->setAttributes(array(
                'endDate' => $Membership->calcEndDate(strtotime($endDate))
            ));
        }

        $historyEntry = 'start: ' . $this->getAttribute('beginDate');
        $historyEntry .= ' | end: ' . $this->getAttribute('endDate');
        $historyEntry .= ' | auto: ';
        $auto ? $historyEntry .= '1' : $historyEntry .= '0';

        $this->addHistoryEntry(MembershipUsersHandler::HISTORY_TYPE_EXTENDED, $historyEntry);
        $this->update();

        // send autoextend mail
        $subject = $this->getUser()->getLocale()->get('quiqqer/memberships', 'templates.mail.autoextend.subject');
        $this->sendMail($subject, dirname(__FILE__, 5) . '/templates/mail_autoextend.html');
    }

    /**
     * Expires this memberships user
     *
     * @return void
     */
    public function expire()
    {
        $this->addHistoryEntry(MembershipUsersHandler::HISTORY_TYPE_EXPIRED);
        $this->archive(MembershipUsersHandler::ARCHIVE_REASON_EXPIRED);

        // send expire mail
        $subject = $this->getUser()->getLocale()->get('quiqqer/memberships', 'templates.mail.expired.subject');
        $this->sendMail($subject, dirname(__FILE__, 5) . '/templates/mail_expired.html');
     * Start the manual membership cancellation process
     *
     * Generates a random hash and sends an email to the user
Patrick Müller's avatar
Patrick Müller committed
     *
     * @return void
     */
    public function startManualCancel()
Patrick Müller's avatar
Patrick Müller committed
    {
        if ($this->isCancelled()) {
            // @todo throw Exception?
            return;
        }

        $cancelDate = Utils::getFormattedTimestamp();
        $cancelHash = md5(openssl_random_pseudo_bytes(256));
        $cancelUrl  = QUI::getRewrite()->getProject()->getVHost(true);
        $cancelUrl  .= URL_OPT_DIR . 'quiqqer/memberships/bin/membership.php';

        $params = array(
            'mid'    => $this->id,
            'hash'   => $cancelHash,
            'action' => 'confirmManualCancel'
Patrick Müller's avatar
Patrick Müller committed
        );

        $cancelUrl .= '?' . http_build_query($params);

        // generate random hash
        $this->setAttributes(array(
            'cancelHash' => $cancelHash,
            'cancelDate' => $cancelDate
        ));

Patrick Müller's avatar
Patrick Müller committed
        $this->addHistoryEntry(MembershipUsersHandler::HISTORY_TYPE_CANCEL_START);

Patrick Müller's avatar
Patrick Müller committed
        // save cancel hash and date to database
        $this->update();

        // send cancellation mail
        $this->sendMail(
            QUI::getLocale()->get('quiqqer/memberships', 'templates.mail.startcancel.subject'),
            dirname(__FILE__, 5) . '/templates/mail_startcancel.html',
            array(
                'cancelDate' => $cancelDate,
                'cancelUrl'  => $cancelUrl
Patrick Müller's avatar
Patrick Müller committed
            )
        );
    }

    /**
     * Confirm membership cancellation
     *
     * @param string $confirmHash - cancel hash
     * @return void
     *
     * @throws QUI\Memberships\Exception
     */
    public function confirmManualCancel($confirmHash)
Patrick Müller's avatar
Patrick Müller committed
        if ($this->isCancelled()) {
            throw new QUI\Memberships\Exception(array(
                'quiqqer/memberships',
                'exception.users.membershipuser.confirmManualCancel.already.cancelled'
            ));
        }

Patrick Müller's avatar
Patrick Müller committed
        $cancelHash = $this->getAttribute('cancelHash');

//        if (empty($cancelHash)) {
//            throw new QUI\Memberships\Exception(array(
//                'quiqqer/memberships',
//                'exception.users.membershipuser.confirmManualCancel.no.hash'
//            ));
//        }
Patrick Müller's avatar
Patrick Müller committed

        if ($confirmHash !== $cancelHash) {
            throw new QUI\Memberships\Exception(array(
                'quiqqer/memberships',
                'exception.users.membershipuser.confirmManualCancel.hash.mismatch'
        $this->setAttributes(array(
            'cancelled' => true
        ));

        $this->addHistoryEntry(MembershipUsersHandler::HISTORY_TYPE_CANCEL_CONFIRM);
Patrick Müller's avatar
Patrick Müller committed
        $this->update();

        // send confirm cancel mail
        $this->sendConfirmCancelMail();
    }

    /**
     * Send mail to user to confirm cancellation
     *
     * @return void
     */
    public function sendConfirmCancelMail()
    {
        $subject = $this->getUser()->getLocale()->get('quiqqer/memberships', 'templates.mail.confirmcancel.subject');
        $this->sendMail($subject, dirname(__FILE__, 5) . '/templates/mail_confirmcancel.html');
     * Cancel membership
Patrick Müller's avatar
Patrick Müller committed
     *
     * @return void
     */
    public function cancel()
        $this->archive(MembershipUsersHandler::ARCHIVE_REASON_CANCELLED);
        // send expired mail
        $subject = $this->getUser()->getLocale()->get('quiqqer/memberships', 'templates.mail.expired.subject');
        $this->sendMail($subject, dirname(__FILE__, 5) . '/templates/mail_expired.html');
Patrick Müller's avatar
Patrick Müller committed
    }

    /**
     * Check if this user has cancelled his membership
     *
     * @return mixed
     */
    public function isCancelled()
    {
        return boolval($this->getAttribute('cancelled'));
    /**
     * Delete membership user and remove QUIQQER user from all unique groups
     *
Patrick Müller's avatar
Patrick Müller committed
     * A deleted membership user is not removed from the database but set to "archived".
     *
     * @return void
     */
    public function delete()
Patrick Müller's avatar
Patrick Müller committed
    {
        $this->addHistoryEntry(MembershipUsersHandler::HISTORY_TYPE_DELETED);

        // do not delete, just set to archived
        $this->archive(MembershipUsersHandler::ARCHIVE_REASON_DELETED);
Patrick Müller's avatar
Patrick Müller committed
    }

    /**
     * Set User to all membership QUIQQER groups
     *
     * @return void
     */
    public function addToGroups()
Patrick Müller's avatar
Patrick Müller committed
    {
        $groupIds = $this->getMembership()->getGroupIds();
        $User     = $this->getUser();

        foreach ($groupIds as $groupId) {
            $User->addToGroup($groupId);
        }

        $User->save(QUI::getUsers()->getSystemUser());
    }

    /**
     * Removes the membership user from all quiqqer groups (that he is part of because of
     * his membership)
     *
     * @return void
     */
    protected function removeFromGroups()
        $Groups             = QUI::getGroups();
        $User               = QUI::getUsers()->get($this->getUserId());
        $Memberships        = MembershipsHandler::getInstance();
        $Membership         = $this->getMembership();
        $membershipGroupIds = $Membership->getGroupIds();

        // remove user from unique group ids
        foreach ($Membership->getUniqueGroupIds() as $groupId) {
            $Groups->get($groupId)->removeUser($User);

            $k = array_search($groupId, $membershipGroupIds);
            if ($k !== false) {
                unset($membershipGroupIds[$k]);
            }

        // remove user from all non-unique group ids where the user is not part of
        // the membership
        foreach ($membershipGroupIds as $groupId) {
            foreach ($Memberships->getMembershipIdsByGroupIds(array($groupId)) as $membershipId) {
                $OtherMembership = $Memberships->getChild($membershipId);

                if (!$OtherMembership->hasMembershipUserId($User->getId())) {
                    $User->removeGroup($groupId);
                }
            }
        }

        $User->save(QUI::getUsers()->getSystemUser());
Patrick Müller's avatar
Patrick Müller committed
    /**
     * Archive this membership user
     *
     * @param string $reason - The reason why this user is archived
Patrick Müller's avatar
Patrick Müller committed
     * @return void
     */
    public function archive($reason)
        $this->removeFromGroups();
Patrick Müller's avatar
Patrick Müller committed
        $this->addHistoryEntry(MembershipUsersHandler::HISTORY_TYPE_ARCHIVED);
        $this->setAttributes(array(
            'archived'      => 1,
            'archiveDate'   => Utils::getFormattedTimestamp(),
            'archiveReason' => $reason
        ));
Patrick Müller's avatar
Patrick Müller committed
        $this->update();
    }

    /**
     * Checks if this membership user is archived
     *
     * @retun bool
     */
    public function isArchived()
    {
        return boolval($this->getAttribute('archived'));
Patrick Müller's avatar
Patrick Müller committed
    /**
     * Get the Membership this membership user is assigned to
     *
     * @return QUI\Memberships\Membership
     */
    public function getMembership()
    {
        return MembershipsHandler::getInstance()->getChild(
            $this->getAttribute('membershipId')
        );
    }

    /**
     * Get QUIQQER User ID of membership user
     *
     * @return int
     */
    public function getUserId()
    {
        return (int)$this->getAttribute('userId');
    }
Patrick Müller's avatar
Patrick Müller committed

    /**
     * Get QUIQQER User
     *
     * @return QUI\Users\User
     */
    public function getUser()
    {
        return QUI::getUsers()->get($this->getUserId());
    }

    /**
     * Add an entry to the membership user history
     *
     * @param string $type - History entry type (see \QUI\Memberships\Users\Handler)
     * @param string $msg (optional) - additional custom message
     */
Patrick Müller's avatar
Patrick Müller committed
    public function addHistoryEntry($type, $msg = "")
Patrick Müller's avatar
Patrick Müller committed
    {
        $history = $this->getAttribute('history');

        if (empty($history)) {
            $history = array();
        } else {
            $history = json_decode($history, true);
        }

        $User = QUI::getUserBySession();

        $history[] = array(
            'type' => $type,
            'time' => Utils::getFormattedTimestamp(),
            'user' => $User->getUsername() . ' (' . $User->getId() . ')',
Patrick Müller's avatar
Patrick Müller committed
            'msg'  => $msg
Patrick Müller's avatar
Patrick Müller committed
        );

        $this->setAttribute('history', json_encode($history));
    }
Patrick Müller's avatar
Patrick Müller committed
    /**
     * Get history data of this MembershipUser
     *
     * @return array
     */
    public function getHistory()
    {
        $history = $this->getAttribute('history');

        if (empty($history)) {
            $history = array();
        } else {
            $history = json_decode($history, true);
        }

        return $history;
    }

    /**
     * Get membership data for backend view/edit purposes
     *
     * @return array
     */
    public function getBackendViewData()
    {
        $QuiqqerUser = $this->getUser();
        $Membership  = $this->getMembership();

        return array(
            'id'              => $this->getId(),
            'userId'          => $QuiqqerUser->getId(),
            'membershipId'    => $Membership->getId(),
            'membershipTitle' => $Membership->getTitle(),
            'username'        => $QuiqqerUser->getUsername(),
            'fullName'        => $QuiqqerUser->getName(),
            'addedDate'       => $this->getAttribute('addedDate'),
            'beginDate'       => $this->getAttribute('beginDate'),
            'endDate'         => $this->getAttribute('endDate'),
            'archived'        => $this->isArchived(),
            'archiveReason'   => $this->getAttribute('archiveReason'),
            'cancelled'       => $this->isCancelled()
        );
    }

    /**
     * Send an email to the membership user
     *
     * @param string $subject - mail subject
     * @param string $templateFile
     * @param array $templateVars (optional) - additional template variables (besides $this)
     * @return void
Patrick Müller's avatar
Patrick Müller committed
     *
     * @throws QUI\Memberships\Exception
     */
    protected function sendMail($subject, $templateFile, $templateVars = array())
    {
Patrick Müller's avatar
Patrick Müller committed
        $User  = $this->getUser();
        $email = $User->getAttribute('email');

        if (empty($email)) {
            throw new QUI\Memberships\Exception(array(
                'quiqqer/memberships',
                'exception.users.membershipuser.no.email'
            ));
        }

        $Engine = QUI::getTemplateManager()->getEngine();

        $Engine->assign(array_merge(
            array(
                'MembershipUser' => $this,
                'Locale'         => $this->getUser()->getLocale()
            ),
            $templateVars
        ));

        $template = $Engine->fetch($templateFile);

        $Mailer = new Mailer();

Patrick Müller's avatar
Patrick Müller committed
        $Mailer->addRecipient($email, $User->getName());
        $Mailer->setSubject($subject);
        $Mailer->setBody($template);
        $Mailer->send();
    }