Your IP : 216.73.217.79


Current Path : /var/www/v3.cesa.co.za/src/ContentBundle/Services/
Upload File :
Current File : /var/www/v3.cesa.co.za/src/ContentBundle/Services/FormCompletedManager.php

<?php

namespace App\ContentBundle\Services;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
use Ddeboer\DataImport\Writer\CsvWriter;
use Ddeboer\DataImport\Writer\ExcelWriter;
use Monolog\Logger;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use App\ContentBundle\Entity\Form;
use App\ContentBundle\Entity\FormCompleted;
use App\UserBundle\Util\CCEStudentDisplayOrder;
use App\ContentBundle\Entity\FormItemCompleted;
use App\SessionsBundle\Entity\Sessions;
use App\UserBundle\Entity\UserList;

/**
 * Form Items manager
 *
 * @author Otto Saayman <otto@igotafrica.com>
 * @package ContentBundle
 * @subpackage Form Items
 * @version 0.0.1
 */
final class FormCompletedManager
{
    private const PLAIN_TEXT_ANSWER_BOUNDARY = '------------';

    /**
     * Service Container
     * @var object
     */
    private $container = null;

    /**
     * Entity manager
     * @var object
     */
    private $em;

    /**
     * Security Context
     * @var object
     */
    private $securityContext = null;

    /**
     * Class construct
     *
     * @param  ContainerInterface $container
     * @param  Logger             $logger
     * @return void
     */
    public function __construct(
        ContainerInterface $container,
        UsageTrackingTokenStorage $securityContext
    ) {
        $this->setContainer($container);
        $this->setSecurityContext($securityContext);
        $this->setEm($container->get('doctrine')->getManager('default'));

        return;
    }

    /**
     * Get Container
     *
     * @return ContainerInterface $container
     */
    public function getContainer()
    {
        return $this->container;
    }

    /**
     * Set Container
     *
     * @param  ContainerInterface $container
     * @return void
     */
    public function setContainer($container)
    {
        $this->container = $container;
    }

    /**
     * Get Entity Manager
     *
     * @return string
     */
    public function getEm()
    {
        return $this->em;
    }

    /**
     * Set Container
     *
     * @param  string $em
     * @return void
     */
    public function setEm($em)
    {
        $this->em = $em;
    }

    public function getSecurityContext()
    {
        return $this->securityContext;
    }

    public function setSecurityContext(UsageTrackingTokenStorage $securityContext)
    {
        $this->securityContext = $securityContext;
    }

    /**
     * Get a completed form
     *
     * @param string $id
     * @return FormCompleted
     */
    public function find($id)
    {
        return $this->getEm()->getRepository(FormCompleted::class)->find($id);
    }

    /**
     * Get a completed form
     *
     * @param array $params
     * @return array
     */
    public function findBy($params)
    {
        return $this->getEm()->getRepository(FormCompleted::class)->findBy($params);
    }

    /**
     * Get completed form by form, user and/ or session
     *
     * @param Form $form
     * @param UserList $userList
     * @param Session $session
     * @return array
     */
    public function getObject(Form $form, ?UserList $userList = null, ?Sessions $session = null)
    {

        if (!is_object($session)) {
            $session = $this->getContainer()->get('sessions.manager')->getSession();
        }

        if (is_object($userList)) {
            $formCompleted = $this->getEm()->getRepository(FormCompleted::class)->findOneBy(array('form' => $form, 'created_by' => $userList->getId()));
        } elseif (is_object($session)) {
            $formCompleted = $this->getEm()->getRepository(FormCompleted::class)->findOneBy(array('form' => $form, 'session' => $session));
        } else {
            $formCompleted = null;
        }

        if (!is_object($formCompleted)) {
            $formCompleted = new FormCompleted();
        }

        $formCompleted->setForm($form);

        if (is_object($session)) {
            $formCompleted->setSession($session);
        }

        if (is_object($userList)) {
            $formCompleted->setCreatedBy($userList->getId());
        }

        $this->save($formCompleted);

        return $formCompleted;
    }

    /**
     * Check completed form object default values
     *
     * @param FormCompleted $formCompleted
     * @return void
     */
    public function checkDefaults(FormCompleted &$formCompleted)
    {

        if (is_null($formCompleted->getCreatedBy()) && is_object($this->getContainer()->get('user_list.manager')->getLoggedInUser())) {
            $formCompleted->setCreatedBy($this->getContainer()->get('user_list.manager')->getLoggedInUser()->getId());
        }

        if (is_null($formCompleted->isIsActive())) {
            $formCompleted->setIsActive(true);
        }

        if (is_null($formCompleted->isIsDeleted())) {
            $formCompleted->setIsDeleted(false);
        }

        if (is_null($formCompleted->getBceModule())) {
            $formCompleted->setBceModule(0);
        }
    }

    /**
     * Save completed form object
     *
     * @param FormCompleted $formCompleted
     * @return void
     */
    public function save(FormCompleted &$formCompleted)
    {

        $this->checkDefaults($formCompleted);

        $this->getEm()->persist($formCompleted);
        $this->getEm()->flush();
    }

    /**
     * Remove completed form object
     *
     * @param Event $event
     * @return void
     */
    public function remove(FormCompleted $formCompleted)
    {
        $this->getEm()->remove($formCompleted);
        $this->getEm()->flush();
    }

    /**
     * Remove completed form object by ID
     *
     * @param string $id
     * @return void
     */
    public function removeById($id)
    {
        if (strlen($id) > 0) {

            $formCompleted = $this->find($id);

            if (is_object($formCompleted)) {
                $this->remove($formCompleted);
            }
        }
    }

    /**
     * Save completed form details from request array
     *
     * @param array $formCompletedValues
     * @param FormCompleted $formCompleted
     * @return string
     */
    public function saveFromRequest($formCompletedValues, ?FormCompleted &$formCompleted = null, $contentId = '', $conf = array())
    {

        $return = '';

        if (!isset($formCompletedValues['id'])) {
            $formCompletedValues['id'] = '0';
        }

        if (!is_object($formCompleted)) {
            $formCompleted = $this->find($formCompletedValues['id']);
        }

        if (!is_object($formCompleted)) {
            $formCompleted = new FormCompleted();
        }

        if (!isset($formCompletedValues['is_active'])) {
            $formCompletedValues['is_active'] = $formCompleted->isIsActive();
        }

        if (!isset($formCompletedValues['is_deleted'])) {
            $formCompletedValues['is_deleted'] = $formCompleted->isIsDeleted();
        }

        if (!isset($conf['valid'])) {
            $conf['valid'] = true;
        }

        $formCompleted->setIsActive($formCompletedValues['is_active']);
        $formCompleted->setIsDeleted($formCompletedValues['is_deleted']);

        $session = $this->getContainer()->get('sessions.manager')->getSession();

        if (is_object($session)) {
            $formCompleted->setSession($session);
        }

        if (!isset($formCompletedValues['form'])) {
            $formCompletedValues['form'] = '0';
        }

        if (!is_object($formCompletedValues['form'])) {
            $formCompletedValues['form'] = $this->getContainer()->get('form_manager.manager')->find($formCompletedValues['form']);
        }

        if (is_object($formCompletedValues['form'])) {
            $formCompleted->setForm($formCompletedValues['form']);
        } else {
            return $this->getContainer()->get('language_phrases.manager')->translate('Invalid form');
        }

        $this->checkDefaults($formCompleted);

        $this->save($formCompleted);

        $formItemCompletedManager = $this->getContainer()->get('form_item_completed.manager');

        $formItemLinks = $formCompleted->getForm()->getFormItems();
        //        var_dump(array_keys($formCompletedValues));
        //        var_dump($formCompletedValues);
        //        echo '<br />';
        //        exit;

        foreach ($formItemLinks as $formItemLink) {

            $formItemCompleted = $formItemCompletedManager->findOneBy(array('form_item' => $formItemLink->getFormItem(), 'form_completed' => $formCompleted));

            if (!is_object($formItemCompleted)) {
                $formItemCompleted = new FormItemCompleted();
            }

            $formItemCompleted->setFormItem($formItemLink->getFormItem());
            $formItemCompleted->setFormCompleted($formCompleted);

            if (isset($formCompletedValues[$formCompleted->getForm()->getId() . '-' . $formItemLink->getFormItem()->getId()])) {
                //                echo 'saving: ' . $formCompletedValues[$formCompleted->getForm()->getId() . '-' . $formItemLink->getFormItem()->getId()] . '<br />';
                $formItemCompleted->setValue(serialize($formCompletedValues[$formCompleted->getForm()->getId() . '-' . $formItemLink->getFormItem()->getId()]));
            }

            if (
                isset($formCompletedValues['comment_' . $formCompleted->getForm()->getId() . '-' . $formItemLink->getFormItem()->getId()]) &&
                strlen($formCompletedValues['comment_' . $formCompleted->getForm()->getId() . '-' . $formItemLink->getFormItem()->getId()]) > 0
            ) {
                $formItemCompleted->setAdditionalComments($formCompletedValues['comment_' . $formCompleted->getForm()->getId() . '-' . $formItemLink->getFormItem()->getId()]);
            }

            $formItemCompletedManager->save($formItemCompleted);
        }

        //        if ($conf['valid']) {
        //            $this->sendMails($formCompleted, $contentId);
        //        }

        return $return;
    }

    /**
     * Get list of all completed fields
     *
     * @param FormCompleted $formCompleted
     * @return string
     */
    public function getCompletedFormHtml(FormCompleted $formCompleted)
    {

        $return = '<p>';

        $formCompletedItemsManager = $this->getContainer()->get('form_item_completed.manager');
        $systemSettingManager = $this->getContainer()->get('system_setting.manager');

        $formCompletedItems = $formCompletedItemsManager->findByFormCompleted($formCompleted, true);

        foreach ($formCompletedItems as $formCompletedItem) {

            if (
                $formCompletedItem->getFormItem()->getFormItemType()->getId() != $systemSettingManager->getSetting('heading_form_item_type') &&
                $formCompletedItem->getFormItem()->getFormItemType()->getId() != $systemSettingManager->getSetting('paragraph_form_item_type')
            ) {

                $valueString = $formCompletedItemsManager->getValueString($formCompletedItem);

                $return .= '<b>' . $formCompletedItem->getFormItem()->getPrompt() . ': </b> ' . $valueString . '<br />' . "\r\n";
            }
        }

        return $return . '</p>';
    }

    /**
     * Save completed form details from request array
     *
     * @param FormCompleted $formCompleted
     * @return string
     */
    public function sendRsvpMails(FormCompleted $formCompleted)
    {

        $languagePhrases = $this->getContainer()->get('language_phrases.manager');
        $userManager = $this->getContainer()->get('user_list.manager');
        $settingManager = $this->getContainer()->get('system_setting.manager');
        $messageManager = $this->getContainer()->get('contact_message.manager');
        $userLanguage = $this->getContainer()->get('languages.manager')->getUserLanguage();

        $notificationMail = $this->getContainer()->get('sites.manager')->getSiteEMail();
        $notificationName = $this->getContainer()->get('sites.manager')->getSiteName();

        if (strlen($notificationMail) <= 0) {
            $notificationMail = $messageManager->getSystemEMail();
        }
        if (strlen($notificationName) <= 0) {
            $notificationName = $messageManager->getSystemName();
        } else {
            $notificationName .= ' Team';
        }

        if (is_object($formCompleted->getForm())) {
            $notificationMail = $formCompleted->getForm()->getToEMail();
            $notificationName = $formCompleted->getForm()->getToName();
        }

        $recipient = $this->em->getRepository(UserList::class)->findOneByEMailAddress(
            array(
                'e_mail_address' => $notificationMail,
                'user_type_id' => array(
                    $settingManager->getSetting('crm_user_type'),
                    $settingManager->getSetting('fe_user_type'),
                    $settingManager->getSetting('client_user_type'),
                    $settingManager->getSetting('media_user_type'),
                    $settingManager->getSetting('employee_user_type')
                )
            )
        );

        if (!is_object($recipient)) {

            $userValues['user_type_id'] = $settingManager->getSetting('crm_user_type');
            $userValues['username'] = $notificationMail;
            $userValues['password'] = microtime();
            $userValues['first_name_string'] = $notificationName;

            $userEMailAddress = new UserEMailAddress();
            $userEMailAddress->setEMailAddress($notificationMail);
            $userEMailAddress->setSubscribed(true);

            $userValues['e_mail_address'] = $userEMailAddress;

            $error = $userManager->saveFromRequest($userValues);

            if (strlen($error) > 0)
                throw new \Exception($error);

            $recipient = $this->em->getRepository(UserList::class)->findOneByEMailAddress(array('e_mail_address' => $notificationMail));

            if (!is_object($recipient))
                throw new \Exception($languagePhrases->translate('Could not capture recipient data. Please try again.'));
        }

        $sender = $userManager->find($formCompleted->getCreatedBy());

        if (!is_object($sender)) {
            throw new \Exception($languagePhrases->translate('Invalid user completed RSVP form. Please try again.'));
        }

        $content = null;

        if (is_object($formCompleted->getForm()->getContent())) {

            $contents = $formCompleted->getForm()->getContent();

            foreach ($contents as $content) {
                if (!is_object($content)) {
                    $content = $formCompleted->getForm()->getContent();
                }
            } //foreach
        }

        if (!is_object($content)) {
            $content = $formCompleted->getForm()->getEvent()->getContent();
        }

        if (!is_object($content)) {
            throw new \Exception($languagePhrases->translate('Invalid RSVP form. Please try again.'));
        }

        $messageType = $this->em->getRepository(MessageType::class)->find($settingManager->getSetting('contact_message_type_contact_us'));
        $contactMethod = $this->em->getRepository(ContactMethod::class)->find($settingManager->getSetting('contact_method_e_mail'));
        $contactReason = $this->em->getRepository(ContactReason::class)->find($settingManager->getSetting('contact_reason_contact_us'));

        $twig = $this->getContainer()->get('twig');
        $router = $this->getContainer()->get('router');
        $eventName = '';
        $eventStartDateTimeString = '';
        $eventRsvpUrl = '';

        $formItemsHtml = $this->getCompletedFormHtml($formCompleted);

        if (is_object($content->getEvent())) {

            $eventName = $content->getEvent()->getEventName($userLanguage);
            $eventStartDateTimeString = $content->getEvent()->getStartDateTimeString();
            $eventRsvpUrl = 'http://' . $_SERVER['HTTP_HOST'] . $router->generate(
                'iga_company_event_rsvp',
                array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $content->getEvent()->getId(), 'user_token' => $sender->getId())
            );

            $subject = $content->getEvent()->getEventName($userLanguage) . ' ' . $languagePhrases->translate('RSVP received');
            $messageHtml = '<p>This is to notify you that the RSVP form for ' . $content->getEvent()->getEventName($userLanguage) . ' has been completed by ' . $sender->getFullNameString() . '.</p>'
                . '<p><a href="' . $router->generate('iga_company_event_edit', array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $content->getEvent()->getId()))
                . '">Click here to view the edit event screen</a></p>'
                . $formItemsHtml
                . '<p>Warmest regards,</p>'
                . '<p>ITSA Site</p>';
            $messageText = 'This is to notify you that the RSVP form for ' . $content->getEvent()->getEventName($userLanguage) . ' has been completed by ' . $sender->getFullNameString() . '.' . "\r\n\r\n"
                . 'Follow this link to see the event edit screen: '
                . $router->generate('iga_company_event_edit', array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $content->getEvent()->getId())) . "\r\n\r\n"
                . strip_tags($formItemsHtml)
                . 'Warmest regards,</p>' . "\r\n\r\n"
                . 'ITSA Site' . "\r\n\r\n";
        } else {

            $subject = $languagePhrases->translate('Form completed for') . ' ' . $content->getContentTitle($userLanguage);
            $messageHtml = '<p>This is to notify you that the form for ' . $content->getContentTitle($userLanguage) . ' has been completed</p>'
                . $formItemsHtml
                . '<p>Warmest regards,</p>'
                . '<p>ITSA Site</p>';
            $messageText = 'This is to notify you that the form for ' . $content->getContentTitle($userLanguage) . ' has been completed' . "\r\n\r\n"
                . strip_tags($formItemsHtml)
                . 'Warmest regards,</p>' . "\r\n\r\n"
                . 'ITSA Site' . "\r\n\r\n";
        }

        //Send Contact us form data
        $messageHTML = $twig->render(
            '@ContactBundle/Email/notification.html.twig',
            array(
                'sender' => $sender,
                'messageText' => $messageHtml,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST']
            )
        );
        $messageText = $twig->render(
            '@ContactBundle/Email/notification.txt.twig',
            array(
                'sender' => $sender,
                'messageText' => $messageText,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST']
            )
        );

        $messageValues = array(
            'subject' => $subject,
            'messageHTML' => $messageHTML,
            'messageText' => $messageText,
            'contactMethod' => $contactMethod,
            'contactReason' => $contactReason,
            'messageType' => $messageType,
        );

        $messageManager->saveMessage($sender, array($recipient), $messageValues);

        if (is_object($content->getEvent())) {
            if (!is_null($content->getEvent()->getAttending($sender))) {
                //Send RSVP thank you message
                if (is_object($content->getEvent()) && $content->getEvent()->getAttending($sender)) {
                    $messageHTML = $twig->render(
                        'IGACompanyBundle:Email:rsvp.thanks.html.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                    $messageText = $twig->render(
                        'IGACompanyBundle:Email:rsvp.thanks.txt.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                } else {
                    $messageHTML = $twig->render(
                        'IGACompanyBundle:Email:rsvp.thanks.declined.html.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                    $messageText = $twig->render(
                        'IGACompanyBundle:Email:rsvp.thanks.declined.txt.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                }

                $messageValues = array(
                    'subject' => $languagePhrases->translate('Thank you for your RSVP'),
                    ', ' . $content->getEvent()->getEventName($userLanguage),
                    'messageHTML' => $messageHTML,
                    'messageText' => $messageText,
                    'contactMethod' => $contactMethod,
                    'contactReason' => $contactReason,
                    'messageType' => $messageType,
                );

                $messageManager->saveMessage($recipient, array($sender), $messageValues);
            } else {
                //Thank you for your info message
                //                $messageValues = array(
                //                    'subject' => $languagePhrases->translate('Thank you for your information'),
                //                    'messageHTML' => $messageHTML,
                //                    'messageText' => $messageText,
                //                    'contactMethod' => $contactMethod,
                //                    'contactReason' => $contactReason,
                //                    'messageType' => $messageType,
                //                        );
                //                $messageManager->saveMessage($recipient, array($sender), $messageValues);
            }

            //            $messageManager->saveMessage($recipient, array($sender), $messageValues);
        }
    }

    /**
     * Save completed form details from request array
     *
     * @param FormCompleted $formCompleted
     * @return string
     */
    public function sendMails(FormCompleted $formCompleted, $contentId = '')
    {

        $languagePhrases = $this->getContainer()->get('language_phrases.manager');
        $userManager = $this->getContainer()->get('user_list.manager');
        $settingManager = $this->getContainer()->get('system_setting.manager');
        $messageManager = $this->getContainer()->get('contact_message.manager');
        $userLanguage = $this->getContainer()->get('languages.manager')->getUserLanguage();

        $notificationMail = $messageManager->getSystemEMail();
        $notificationName = $messageManager->getSystemName();

        if (is_object($formCompleted->getForm())) {
            $notificationMail = $formCompleted->getForm()->getToEMail();
            $notificationName = $formCompleted->getForm()->getToName();
        }

        $recipient = $this->em->getRepository(UserList::class)->findOneByEMailAddress(
            array(
                'e_mail_address' => $notificationMail,
                'user_type_id' => array(
                    $settingManager->getSetting('crm_user_type'),
                    $settingManager->getSetting('fe_user_type'),
                    $settingManager->getSetting('client_user_type'),
                )
            )
        );

        if (!is_object($recipient)) {

            $userValues['user_type_id'] = $settingManager->getSetting('crm_user_type');
            $userValues['username'] = $notificationMail;
            $userValues['password'] = microtime();
            $userValues['first_name_string'] = $notificationName;

            $userEMailAddress = new UserEMailAddress();
            $userEMailAddress->setEMailAddress($notificationMail);
            $userEMailAddress->setSubscribed(true);

            $userValues['e_mail_address'] = $userEMailAddress;

            $error = $userManager->saveFromRequest($userValues);

            if (strlen($error) > 0)
                throw new \Exception($error);

            $recipient = $this->em->getRepository(UserList::class)->findOneByEMailAddress(array('e_mail_address' => $notificationMail));

            if (!is_object($recipient))
                throw new \Exception($languagePhrases->translate('Could not capture recipient data. Please try again.'));
        }

        if (strlen($formCompleted->getCreatedBy()) > 0) {
            $sender = $userManager->find($formCompleted->getCreatedBy());
        } else {
            $sender = $recipient;
        }

        if (!is_object($sender)) {
            throw new \Exception($languagePhrases->translate('Invalid user completed form. Please try again.'));
        }

        $content = null;

        if (strlen($contentId) > 0) {
            $content = $this->getContainer()->get('content.manager')->find($contentId);
        } else {
            $contents = $formCompleted->getForm()->getContent();
            if (count($contents) > 0) {
                $content = $contents[0];
            }

            if (!is_object($content)) {
                $content = $formCompleted->getForm()->getEvent()->getContent();
            }

            if (!is_object($content)) {
                throw new \Exception($languagePhrases->translate('Invalid form. Please try again.'));
            }
        }

        $messageType = $this->em->getRepository(MessageType::class)->find($settingManager->getSetting('contact_message_type_contact_us'));
        $contactMethod = $this->em->getRepository(ContactMethod::class)->find($settingManager->getSetting('contact_method_e_mail'));
        $contactReason = $this->em->getRepository(ContactReason::class)->find($settingManager->getSetting('contact_reason_contact_us'));

        $twig = $this->getContainer()->get('twig');
        $router = $this->getContainer()->get('router');
        $eventName = '';
        $eventStartDateTimeString = '';
        $eventRsvpUrl = '';

        $formItemsHtml = $this->getCompletedFormHtml($formCompleted);

        if (is_object($content->getEvent())) {

            $eventName = $content->getEvent()->getEventName($userLanguage);
            $eventStartDateTimeString = $content->getEvent()->getStartDateTimeString();
            $eventRsvpUrl = 'http://' . $_SERVER['HTTP_HOST'] . $router->generate(
                'iga_company_event_rsvp',
                array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $content->getEvent()->getId(), 'user_token' => $sender->getId())
            );

            $subject = $content->getEvent()->getEventName($userLanguage) . ' ' . $languagePhrases->translate('RSVP received');
            $messageHtml = '<p>This is to notify you that the RSVP form for ' . $content->getEvent()->getEventName($userLanguage) . ' has been completed by ' . $sender->getFullNameString() . '.</p>'
                . '<p><a href="' . $router->generate('iga_company_event_edit', array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $content->getEvent()->getId()))
                . '">Click here to view the edit event screen</a></p>'
                . $formItemsHtml;
            $messageText = 'This is to notify you that the RSVP form for ' . $content->getEvent()->getEventName($userLanguage) . ' has been completed by ' . $sender->getFullNameString() . '.' . "\r\n\r\n"
                . 'Follow this link to see the event edit screen: '
                . $router->generate('iga_company_event_edit', array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $content->getEvent()->getId())) . "\r\n\r\n"
                . strip_tags($formItemsHtml);
        } else {

            $subject = $languagePhrases->translate('Form completed for') . ' ' . $content->getContentTitle($userLanguage);
            $messageHtml = '<p>This is to notify you that the form for ' . $content->getContentTitle($userLanguage) . ' has been completed</p>'
                . $formItemsHtml;
            $messageText = 'This is to notify you that the form for ' . $content->getContentTitle($userLanguage) . ' has been completed' . "\r\n\r\n"
                . strip_tags($formItemsHtml);
        }

        //Send Contact us form data
        $messageHTML = $twig->render(
            '@ContactBundle/Email/notification.html.twig',
            array(
                'sender' => $sender,
                'messageText' => $messageHtml,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                'contactFromName' => $notificationName,
                'contactFromEMail' => $notificationMail,
            )
        );
        $messageText = $twig->render(
            '@ContactBundle/Email/notification.txt.twig',
            array(
                'sender' => $sender,
                'messageText' => $messageText,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                'contactFromName' => $notificationName,
                'contactFromEMail' => $notificationMail,
            )
        );

        $messageValues = array(
            'subject' => $subject,
            'messageHTML' => $messageHTML,
            'messageText' => $messageText,
            'contactMethod' => $contactMethod,
            'contactReason' => $contactReason,
            'messageType' => $messageType,
        );

        $messageManager->saveMessage($sender, array($recipient), $messageValues);

        if (is_object($content->getEvent())) {
            if (!is_null($content->getEvent()->getAttending($sender))) {
                //Send RSVP thank you message
                if (is_object($content->getEvent()) && $content->getEvent()->getAttending($sender)) {
                    $messageHTML = $twig->render(
                        'IGAEventBundle:Email:rsvp.thanks.html.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                    $messageText = $twig->render(
                        'IGAEventBundle:Email:rsvp.thanks.txt.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                } else {
                    $messageHTML = $twig->render(
                        'IGAEventBundle:Email:rsvp.thanks.declined.html.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                    $messageText = $twig->render(
                        'IGAEventBundle:Email:rsvp.thanks.declined.txt.twig',
                        array(
                            'sender' => $sender,
                            'hostName' => $_SERVER["HTTP_HOST"],
                            'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                            'eventName' => $eventName,
                            'eventStartDateTimeString' => $eventStartDateTimeString,
                            'eventRsvpUrl' => $eventRsvpUrl,
                        )
                    );
                }

                $messageValues = array(
                    'subject' => $languagePhrases->translate('Thank you for your RSVP'),
                    ', ' . $content->getEvent()->getEventName($userLanguage),
                    'messageHTML' => $messageHTML,
                    'messageText' => $messageText,
                    'contactMethod' => $contactMethod,
                    'contactReason' => $contactReason,
                    'messageType' => $messageType,
                );

                $messageManager->saveMessage($recipient, array($sender), $messageValues);
            } else {
                //Thank you for your info message
                $messageValues = array(
                    'subject' => $languagePhrases->translate('Thank you for your information'),
                    'messageHTML' => $messageHTML,
                    'messageText' => $messageText,
                    'contactMethod' => $contactMethod,
                    'contactReason' => $contactReason,
                    'messageType' => $messageType,
                );
                $messageManager->saveMessage($recipient, array($sender), $messageValues);
            }

            //            $messageManager->saveMessage($recipient, array($sender), $messageValues);
        }
    }

    /**
     * Send declined e-mails
     *
     * @param UserList $userList
     * @return string
     */
    public function sendRsvpMailsDeclined(UserList $userList, Event $event, FormCompleted $formCompleted)
    {

        $languagePhrases = $this->getContainer()->get('language_phrases.manager');
        $userManager = $this->getContainer()->get('user_list.manager');
        $settingManager = $this->getContainer()->get('system_setting.manager');
        $messageManager = $this->getContainer()->get('contact_message.manager');
        $userLanguage = $this->getContainer()->get('languages.manager')->getUserLanguage();

        $recipient = $this->em->getRepository(UserList::class)->findOneByEMailAddress(
            array(
                'e_mail_address' => $messageManager->getSystemEMail(),
                'user_type_id' => array(
                    $settingManager->getSetting('crm_user_type'),
                    $settingManager->getSetting('fe_user_type'),
                    $settingManager->getSetting('client_user_type'),
                    $settingManager->getSetting('media_user_type'),
                    $settingManager->getSetting('employee_user_type')
                )
            )
        );

        if (!is_object($recipient)) {

            $userValues['user_type_id'] = $settingManager->getSetting('crm_user_type');
            $userValues['username'] = $messageManager->getSystemEMail();
            $userValues['password'] = microtime();
            $userValues['first_name_string'] = $messageManager->getSystemName();
            $userValues['e_mail_address'] = $messageManager->getSystemEMail();

            $error = $userManager->saveFromRequest($userValues);

            if (strlen($error) > 0)
                throw new \Exception($error);

            $recipient = $this->em->getRepository(UserList::class)->findOneByEMailAddress(array('e_mail_address' => $messageManager->getSystemEMail()));

            if (!is_object($recipient))
                throw new \Exception($languagePhrases->translate('Could not capture recipient data. Please try again.'));
        }

        $messageType = $this->em->getRepository(MessageType::class)->find($settingManager->getSetting('contact_message_type_contact_us'));
        $contactMethod = $this->em->getRepository(ContactMethod::class)->find($settingManager->getSetting('contact_method_e_mail'));
        $contactReason = $this->em->getRepository(ContactReason::class)->find($settingManager->getSetting('contact_reason_contact_us'));

        $twig = $this->getContainer()->get('twig');
        $router = $this->getContainer()->get('router');

        $eventName = $event->getEventName($userLanguage);

        $formItemsHtml = $this->getCompletedFormHtml($formCompleted);

        $subject = $event->getEventName($userLanguage) . ' ' . $languagePhrases->translate('decline received');
        $messageHtml = '<p>This is to notify you that ' . $userList->getFullnameString() . ' has declined the invite for ' . $event->getEventName($userLanguage) . '.</p>'
            . '<p><a href="' . $router->generate('iga_company_event_rsvp', array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $event->getId()))
            . '">Click here to view the edit event screen</a></p>'
            . $formItemsHtml
            . '<p>Warmest regards,</p>'
            . '<p>ITSA Site</p>';
        $messageText = 'This is to notify you that ' . $userList->getFullnameString() . ' has declined the invite for ' . $event->getEventName($userLanguage) . '.' . "\r\n\r\n"
            . 'Follow this link to see the event edit screen: '
            . $router->generate('iga_company_event_edit', array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $event->getId())) . "\r\n\r\n"
            . strip_tags($formItemsHtml)
            . 'Warmest regards,</p>' . "\r\n\r\n"
            . 'ITSA Site' . "\r\n\r\n";

        //Send Contact us form data
        $messageHTML = $twig->render(
            '@ContactBundle/Email/notification.html.twig',
            array(
                'sender' => $userList,
                'messageText' => $messageHtml,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST']
            )
        );
        $messageText = $twig->render(
            '@ContactBundle/Email/notification.txt.twig',
            array(
                'sender' => $userList,
                'messageText' => $messageText,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST']
            )
        );

        $messageValues = array(
            'subject' => $subject,
            'messageHTML' => $messageHTML,
            'messageText' => $messageText,
            'contactMethod' => $contactMethod,
            'contactReason' => $contactReason,
            'messageType' => $messageType,
        );

        $messageManager->saveMessage($userList, array($recipient), $messageValues);

        //Send RSVP thank you message

        $messageHTML = $twig->render(
            'IGACompanyBundle:Email:rsvp.thanks.declined.html.twig',
            array(
                'sender' => $userList,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                'eventName' => $eventName,
                'event' => $event,
                'eventRsvpUrl' => 'http://' . $_SERVER['HTTP_HOST']
                    . $router->generate(
                        'iga_company_event_rsvp',
                        array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $event->getId(), 'user_token' => $userList->getId(), 'decline' => 1)
                    ),
            )
        );
        $messageText = $twig->render(
            'IGACompanyBundle:Email:rsvp.thanks.declined.txt.twig',
            array(
                'sender' => $userList,
                'hostName' => $_SERVER["HTTP_HOST"],
                'sitePath' => 'http://' . $_SERVER['HTTP_HOST'],
                'eventName' => $eventName,
                'event' => $event,
                'eventRsvpUrl' => 'http://' . $_SERVER['HTTP_HOST']
                    . $router->generate(
                        'iga_company_event_rsvp',
                        array('cultureString' => $userLanguage->getCultureString(), 'eventId' => $event->getId(), 'user_token' => $userList->getId(), 'decline' => 1)
                    ),
            )
        );

        $messageValues = array(
            'subject' => $languagePhrases->translate('Thank you for your RSVP received'),
            'messageHTML' => $messageHTML,
            'messageText' => $messageText,
            'contactMethod' => $contactMethod,
            'contactReason' => $contactReason,
            'messageType' => $messageType,
        );

        $messageManager->saveMessage($recipient, array($userList), $messageValues);
    }

    /**
     * Check form completed items for an event
     *
     * @param Form $form
     * @return void
     */
    public function checkEventFormsCompleted(Form $form)
    {

        $event = $form->getEvent();

        if (!is_object($event)) {
            return;
        }

        $attendees = $event->getEventAttendee();

        foreach ($attendees as $attendee) {
            $formCompleted = $this->getObject($form, $attendee->getAttendee());
            $this->save($formCompleted);
        }
    }

    /**
     * Extract all requested user data, return CSV string
     *
     * @param  string Form $form
     * @return string
     */
    public function generateCsv(Form $form)
    {

        $formCompletedManager = $this->getContainer()->get('form_completed.manager');
        $formItemCompletedManager = $this->getContainer()->get('form_item_completed.manager');
        $formItemManager = $this->getContainer()->get('form_item.manager');
        $userListManager = $this->getContainer()->get('user_list.manager');
        $systemSettingManager = $this->getContainer()->get('system_setting.manager');

        $this->checkEventFormsCompleted($form);

        $formCompleteds = $formCompletedManager->findby(array('form' => $form));

        $event = $form->getEvent();

        if (!is_object($event)) {
            $event = null;
        }

        if (is_array($formCompleteds) && count($formCompleteds) > 0) {

            $fileName = 'form-data-export ' . $form->getTitle() . ' ' . date('Y-m-d-H-i-s') . '.csv';

            $formItems = $formItemManager->findByForm($form);

            $CSVWriter = new CsvWriter();
            $CSVWriter->setStream(fopen(sys_get_temp_dir() . '/' . $fileName, 'w'));

            $csvHeaders = array(
                'Form Title',
                'Username',
                'Event Attending Status',
                'Last Updated',
                'Date Created',
            );

            foreach ($formItems as $formItem) {
                if ($systemSettingManager->getSetting('heading_form_item_type') != $formItem->getFormItemType()->getId() && $systemSettingManager->getSetting('paragraph_form_item_type') != $formItem->getFormItemType()->getId()) {
                    $csvHeaders[] = $formItem->getPrompt();
                }
            }

            $CSVWriter->writeItem($csvHeaders);

            //Loop through the array and write the data to CSV
            foreach ($formCompleteds as $formCompleted) {

                $completedBy = $userListManager->find($formCompleted->getCreatedBy());

                if (is_object($completedBy)) {
                    $username = $completedBy->getUsername();
                } else {
                    $username = 'Anonymous';
                }

                $csvDataLine = array(
                    $form->getTitle(),
                    $username,
                );

                if (is_object($event) && is_object($completedBy)) {
                    $csvDataLine[] = $completedBy->getAttendingEventStringExport($event->getId());
                } else {
                    $csvDataLine[] = '-';
                }

                $csvDataLine[] = $formCompleted->getUpdatedAt()->format('Y-m-d H:i:s');
                $csvDataLine[] = $formCompleted->getCreatedAt()->format('Y-m-d H:i:s');

                foreach ($formItems as $formItem) {

                    if ($systemSettingManager->getSetting('heading_form_item_type') != $formItem->getFormItemType()->getId() && $systemSettingManager->getSetting('paragraph_form_item_type') != $formItem->getFormItemType()->getId()) {
                        $formCompletedItem = $formItemCompletedManager->findOneBy(array('form_item' => $formItem, 'form_completed' => $formCompleted));

                        if (is_object($formCompletedItem)) {
                            $valueString = $formItemCompletedManager->getValueString($formCompletedItem);
                        } else {
                            $valueString = '';
                        }

                        $csvDataLine[] = $valueString;
                    }
                }

                $CSVWriter->writeItem($csvDataLine);
            }

            $CSVWriter->finish();

            return file_get_contents(sys_get_temp_dir() . '/' . $fileName);
        } else {
            throw new \Exception('No RSVP forms have been completed');
        }

        return '';
    }

    /**
     * Extract all requested event user data, return CSV string
     *
     * @param  string Form $form
     * @return string
     */
    public function generateEventExcel(Form $form)
    {

        $formCompletedManager = $this->getContainer()->get('form_completed.manager');
        $formItemCompletedManager = $this->getContainer()->get('form_item_completed.manager');
        $formItemManager = $this->getContainer()->get('form_item.manager');
        $userListManager = $this->getContainer()->get('user_list.manager');
        $systemSettingManager = $this->getContainer()->get('system_setting.manager');

        $this->checkEventFormsCompleted($form);

        $formCompleteds = $formCompletedManager->findby(array('form' => $form));

        $event = $form->getEvent();

        if (is_array($formCompleteds) && count($formCompleteds) > 0) {

            $fileName = 'form-data-export ' . $form->getTitle() . ' ' . date('Y-m-d-H-i-s') . '.xls';

            $formItems = $formItemManager->findByForm($form);

            $file = new \SplFileObject(sys_get_temp_dir() . '/' . $fileName, 'w');
            $CSVWriter = new ExcelWriter($file);
            $CSVWriter->prepare();
            $numerics = array();

            if (is_object($event)) {
                $csvHeaders = array(
                    'Form Title',
                    'Username',
                    'Name',
                    'Surname',
                    'Email Address',
                    'Cell Number',
                    'Dealership/ Company',
                    'Event Attending Status',
                    'Event Attending Day',
                    'Form Completed',
                    'Last Updated',
                    'Date Created',
                );
            } else {
                $csvHeaders = array(
                    'Form Title',
                    'Username',
                    'Name',
                    'Surname',
                    'Email Address',
                    'Cell Number',
                    'Dealership/ Company',
                    'Form Completed',
                    'Last Updated',
                    'Date Created',
                );
            }

            foreach ($formItems as $formItem) {
                if ($systemSettingManager->getSetting('heading_form_item_type') != $formItem->getFormItemType()->getId() && $systemSettingManager->getSetting('paragraph_form_item_type') != $formItem->getFormItemType()->getId()) {
                    $csvHeaders[] = $formItem->getPrompt();
                }
            }

            $CSVWriter->writeItem($csvHeaders);
            $rowCnt = 1;

            if (is_object($event)) {

                $attendees = $event->getEventAttendee();

                //Order attendees by attending date
                for ($cnt1 = 0; $cnt1 < count($attendees); $cnt1++) {
                    for ($cnt2 = 1; $cnt2 < count($attendees); $cnt2++) {

                        if (is_object($attendees[$cnt1]->getEventDay()) && is_object($attendees[$cnt2]->getEventDay()) && $attendees[$cnt1]->getEventDay()->getDayDate()->getTimestamp() > $attendees[$cnt2]->getEventDay()->getDayDate()->getTimestamp()) {
                            $dummy = $attendees[$cnt1];
                            $attendees[$cnt1] = $attendees[$cnt2];
                            $attendees[$cnt2] = $dummy;
                        }
                    }
                }

                //Loop through the array and write the data to CSV
                foreach ($attendees as $attendee) {

                    $formCompleted = $this->getObject($form, $attendee->getAttendee());

                    if (is_object($formCompleted)) {
                        $completedBy = $userListManager->find($formCompleted->getCreatedBy());
                    } else {
                        $completedBy = null;
                    }

                    if (is_object($completedBy)) {
                        $username = $completedBy->getUsername();
                        $name = $completedBy->getFirstNameString();
                        $surname = $completedBy->getLastNameString();
                        $eMail = $completedBy->getEMailAddressString();
                        $cellNo = $completedBy->getUserCellNumber();
                        $company = $completedBy->getCompanyName();
                    } else {
                        $username = 'Anonymous';
                        $name = '';
                        $surname = '';
                        $eMail = '';
                        $cellNo = '';
                        $company = '';
                    }

                    $csvDataLine = array(
                        $form->getTitle(),
                        $username,
                        $name,
                        $surname,
                        $eMail,
                        $cellNo,
                        $company,
                    );

                    if (is_object($event) && is_object($completedBy)) {
                        //                    $csvDataLine[] = $completedBy->getInviteSentString($event->getId());
                        //                    $csvDataLine[] = $completedBy->getInviteSentDateString($event->getId());
                        $csvDataLine[] = $completedBy->getAttendingEventStringExport($event->getId());
                        $csvDataLine[] = $completedBy->getAttendingEventDayString($event->getId());
                    } else {
                        $csvDataLine[] = '-';
                        $csvDataLine[] = '-';
                        $csvDataLine[] = '-';
                    }

                    if (is_object($formCompleted)) {

                        if (is_null($formCompleted->getCreatedAt()) || is_null($formCompleted->getSession())) {
                            $csvDataLine[] = 'No';
                        } else {
                            $csvDataLine[] = 'Yes';
                        }

                        $csvDataLine[] = $formCompleted->getUpdatedAtString();
                        $csvDataLine[] = $formCompleted->getCreatedAtString();

                        $colCnt = 5;

                        foreach ($formItems as $formItem) {

                            if ($systemSettingManager->getSetting('heading_form_item_type') != $formItem->getFormItemType()->getId() && $systemSettingManager->getSetting('paragraph_form_item_type') != $formItem->getFormItemType()->getId()) {
                                $formCompletedItem = $formItemCompletedManager->findOneBy(array('form_item' => $formItem, 'form_completed' => $formCompleted->getId()));

                                if (is_object($formCompletedItem)) {

                                    $valueString = trim($formItemCompletedManager->getValueString($formCompletedItem));

                                    if (is_numeric($valueString)) {
                                        $valueString = ' ' . $valueString . ' ';
                                        $numerics[] = array($colCnt, $rowCnt);
                                    }
                                } else {
                                    $valueString = '';
                                }

                                $csvDataLine[] = $valueString;
                                $colCnt++;
                            } //if data field
                        } //foreach field
                    } else {
                        $csvDataLine[] = 'No';
                    }

                    $CSVWriter->writeItem($csvDataLine);
                    $rowCnt++;
                } //foreach attendee
            } else {
                //Normal form
                if (is_object($form->getContentMessage())) {
                    $respondants = $form->getContentMessage()->getMessageRespondant();
                } else {
                    $respondants = array();
                }

                //Loop through the array and write the data to CSV
                foreach ($respondants as $respondant) {

                    $formCompleted = $this->getObject($form, $respondant->getRespondant());

                    if (is_object($formCompleted)) {
                        $completedBy = $userListManager->find($formCompleted->getCreatedBy());
                    } else {
                        $completedBy = null;
                    }

                    if (is_object($completedBy)) {
                        $username = $completedBy->getUsername();
                        $name = $completedBy->getFirstNameString();
                        $surname = $completedBy->getLastNameString();
                        $eMail = $completedBy->getEMailAddressString();
                        $cellNo = $completedBy->getUserCellNumber();
                    } else {
                        $username = 'Anonymous';
                        $name = '';
                        $surname = '';
                        $eMail = '';
                        $cellNo = '';
                    }

                    $csvDataLine = array(
                        $form->getTitle(),
                        $username,
                        $name,
                        $surname,
                        $eMail,
                        $cellNo
                    );

                    if (is_object($formCompleted)) {

                        if (is_null($formCompleted->getCreatedAt())) {
                            $csvDataLine[] = 'No';
                        } else {
                            $csvDataLine[] = 'Yes';
                        }

                        $csvDataLine[] = $formCompleted->getUpdatedAtString();
                        $csvDataLine[] = $formCompleted->getCreatedAtString();

                        $colCnt = 5;

                        foreach ($formItems as $formItem) {

                            if ($systemSettingManager->getSetting('heading_form_item_type') != $formItem->getFormItemType()->getId() && $systemSettingManager->getSetting('paragraph_form_item_type') != $formItem->getFormItemType()->getId()) {
                                $formCompletedItem = $formItemCompletedManager->findOneBy(array('form_item' => $formItem, 'form_completed' => $formCompleted->getId()));

                                if (is_object($formCompletedItem)) {

                                    $valueString = trim($formItemCompletedManager->getValueString($formCompletedItem));

                                    if (is_numeric($valueString)) {
                                        $valueString = ' ' . $valueString . ' ';
                                        $numerics[] = array($colCnt, $rowCnt);
                                    }
                                } else {
                                    $valueString = '';
                                }

                                $csvDataLine[] = $valueString;
                                $colCnt++;
                            } //if data field
                        } //foreach field
                    } else {
                        $csvDataLine[] = 'No';
                    }

                    $CSVWriter->writeItem($csvDataLine);
                    $rowCnt++;
                } //foreach attendee
            }

            $CSVWriter->finish();

            if (count($numerics) > 0) {

                $filePath = sys_get_temp_dir() . '/' . $fileName;
                $reader = \PHPExcel_IOFactory::createReader('Excel2007');

                if ($reader->canRead($filePath)) {
                    $excel = $reader->load($filePath);
                } else {
                    $excel = new \PHPExcel();
                }

                $excel->setActiveSheetIndex(0);

                foreach ($numerics as $numeric) {

                    $cell = $excel->getActiveSheet()->getCellByColumnAndRow($numeric[0], $numeric[1]);

                    $cell->setDataType(\PHPExcel_Cell_DataType::TYPE_STRING);
                    $cell->setValueExplicit($cell->getValue(), \PHPExcel_Cell_DataType::TYPE_STRING);
                }

                $writer = \PHPExcel_IOFactory::createWriter($excel, 'Excel2007');
                $writer->save($filePath);
            }

            return file_get_contents(sys_get_temp_dir() . '/' . $fileName);
        } else {
            throw new \Exception('No RSVP forms have been completed');
        }

        return '';
    }

    /**
     * Get value
     *
     * @param string $formId
     * @return array
     */
    public function getFormReportData($formId)
    {

        $form = $this->getContainer()->get('form_manager.manager')->find($formId);
        $formItemListManager = $this->getContainer()->get('form_item_list.manager');
        $formItemCompletedManager = $this->getContainer()->get('form_item_completed.manager');
        $formItemTypeManager = $this->getContainer()->get('form_item_type.manager');

        if (!is_object($form)) {
            return array();
        }

        $return = $form->getArray();
        $return['id'] = $form->getId();

        $return['items'] = array();
        $formItemForms = $this->getContainer()->get('form_item_form.manager')->findBy(array('form' => $form), array('order_by' => 'ASC'));

        foreach ($formItemForms as $formItemForm) {

            $formItem = $formItemForm->getFormItem();

            if (!isset($return['items'][$formItem->getId()])) {
                $return['items'][$formItem->getId()] = $formItem->getAsArray($form);
                $return['items'][$formItem->getId()]['value'] = array();
                $return['items'][$formItem->getId()]['additional_comments_text'] = array();
                $return['items'][$formItem->getId()]['form_item_list'] = array();
            }

            $itemsCompleted = $formItemCompletedManager->findBy(array('form_item' => $formItem));

            $formItemLists = $formItem->getSelectListOptions();

            if (!is_array($formItemLists)) {
                $formItemLists = $formItemTypeManager->getArrayFromList($formItemLists);
            }
            //            var_dump($formItemLists);
            //            echo '<br />';

            if (is_countable($formItemLists) && count($formItemLists) > 1) {

                foreach ($formItemLists as $formItemList) {

                    if (!isset($return['items'][$formItem->getId()]['form_item_list'][$formItemList])) {
                        $return['items'][$formItem->getId()]['form_item_list'][$formItemList] = array(
                            'name' => $formItemList,
                            'valueCount' => 0,
                        );
                    }

                    foreach ($itemsCompleted as $completedItem) {
                        //                        echo $formItemList . ' == ' . unserialize($completedItem->getValue()) . '<br />';
                        $value = unserialize($completedItem->getValue());

                        if ((is_array($value) && in_array(trim($formItemList), $value)) || (!is_array($value) && trim($formItemList) == trim($value))) {
                            $return['items'][$formItem->getId()]['form_item_list'][$formItemList]['valueCount']++;
                        }
                    }
                } //foreach
            } else {
                foreach ($itemsCompleted as $completedItem) {
                    if (strlen(unserialize($completedItem->getValue())) > 0) {
                        if (!isset($return['items'][$formItem->getId()]['value'][unserialize($completedItem->getValue())])) {
                            $return['items'][$formItem->getId()]['value'][unserialize($completedItem->getValue())] = 0;
                        }
                        $return['items'][$formItem->getId()]['value'][unserialize($completedItem->getValue())] += 1;
                    }
                }
            }

            foreach ($itemsCompleted as $completedItem) {
                if (strlen($completedItem->getAdditionalComments()) > 0) {

                    if (!isset($return['items'][$formItem->getId()]['additional_comments_text'][$completedItem->getAdditionalComments()])) {
                        $return['items'][$formItem->getId()]['additional_comments_text'][$completedItem->getAdditionalComments()] = 0;
                    }

                    $return['items'][$formItem->getId()]['additional_comments_text'][$completedItem->getAdditionalComments()] += 1;
                }
            }
        } //foreach

        $keyValueManager = $this->getContainer()->get('key_value.manager');
        $studentManager = $this->getContainer()->get('cce_student.manager');
        $additionalValues = $keyValueManager->getKeysByStartValue('form_extended_' . $formId);
        $return['additional_items'] = [];

        foreach ($additionalValues as $additionalValueObj) {

            $additionalValue = $keyValueManager->getKeyValue(
                $additionalValueObj->getKeyValueName(),
                json_decode($additionalValueObj->getKeyValue(), true),
                true
            );

            // var_dump($additionalValue);
            // echo '<br />';

            $student = $studentManager->findForReportLabel($additionalValue['studentId']);
            if (!is_object($student)) {
                continue;
            }
            $additionalValue['student'] = $student;

            $return['additional_items'][] = $additionalValue;
        }

        $surveyValues = $keyValueManager->getKeysByStartValue('survey_data_' . $formId);
        $return['survey_items'] = [];

        foreach ($surveyValues as $surveyValueObj) {

            $surveyValue = $keyValueManager->getKeyValue(
                $surveyValueObj->getKeyValueName(),
                json_decode($surveyValueObj->getKeyValue(), true),
                true
            );

            $student = $studentManager->findForReportLabel($surveyValue['studentId']);

            if (!is_object($student) || in_array($student->getId(), [269, 270, 271, 272, 273], true)) {
                // Empty student (Exam))
                continue;
            }

            $surveyValue['student'] = $student;
            $return['survey_items'][] = $surveyValue;
        }

        CCEStudentDisplayOrder::sortRowsWithStudentObject($return['survey_items'], 'student');

        $return['survey_non_respondent_items'] = $this->buildSurveyNonRespondentItems(
            $formId,
            $return['survey_items'],
            $studentManager
        );

        // echo 'survey_data_' . $formId . '<br />';
        // var_dump($return['survey_items']);
        // echo '<br />';

        return $return;
    }

    /**
     * Build an Excel workbook (xlsx) for the aggregated form completed report (same data as the HTML report).
     *
     * Plain-text style answers (free-text values and comments) are concatenated into one cell, one answer per line,
     * separated by a line break and a boundary line (PLAIN_TEXT_ANSWER_BOUNDARY).
     *
     * @param string $formId
     * @return string Binary .xlsx contents
     */
    public function generateFormReportExcel($formId): string
    {
        $form = $this->getContainer()->get('form_manager.manager')->find($formId);
        if (!is_object($form)) {
            throw new \InvalidArgumentException('Form not found');
        }

        $report = $this->getFormReportData($formId);
        if (!is_array($report) || count($report) <= 0) {
            throw new \InvalidArgumentException('Form not found');
        }

        $items = isset($report['items']) && is_array($report['items']) ? $report['items'] : array();
        uasort(
            $items,
            static function (array $a, array $b): int {
                $oa = isset($a['order_by']) ? (int) $a['order_by'] : 0;
                $ob = isset($b['order_by']) ? (int) $b['order_by'] : 0;

                return $oa <=> $ob;
            }
        );

        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setTitle('Form report');

        $row = 1;
        $sheet->setCellValue('A' . $row, 'Form title');
        $sheet->setCellValue('B' . $row, isset($report['title']) ? (string) $report['title'] : '');
        $row += 2;

        $sheet->setCellValue('A' . $row, 'Prompt');
        $sheet->setCellValue('B' . $row, 'Values');
        $sheet->getStyle('A' . $row . ':B' . $row)->getFont()->setBold(true);
        $row++;

        foreach ($items as $formItem) {
            $widgetName = '';
            if (isset($formItem['form_item_type']) && is_array($formItem['form_item_type'])) {
                $widgetName = (string) ($formItem['form_item_type']['widgetName'] ?? '');
            }

            if ($widgetName === 'heading') {
                $sheet->setCellValue('A' . $row, (string) ($formItem['prompt'] ?? ''));
                $sheet->mergeCells('A' . $row . ':B' . $row);
                $sheet->getStyle('A' . $row)->getFont()->setBold(true)->setSize(14);
                $row++;
                continue;
            }

            if ($widgetName === 'sub-heading') {
                $sheet->setCellValue('A' . $row, (string) ($formItem['prompt'] ?? ''));
                $sheet->mergeCells('A' . $row . ':B' . $row);
                $sheet->getStyle('A' . $row)->getFont()->setBold(true)->setSize(12);
                $row++;
                continue;
            }

            if ($widgetName === 'paragraph') {
                $sheet->setCellValue('A' . $row, (string) ($formItem['description'] ?? ''));
                $sheet->mergeCells('A' . $row . ':B' . $row);
                $row++;
                continue;
            }

            $sheet->setCellValue('A' . $row, $this->buildFormReportExportPromptLabel($formItem));
            $sheet->setCellValue('B' . $row, $this->buildFormReportExportValuesCell($formItem));
            $sheet->getStyle('A' . $row . ':B' . $row)->getAlignment()
                ->setWrapText(true)
                ->setVertical(Alignment::VERTICAL_TOP);
            $row++;
        }

        if (!empty($report['additional_items']) && is_array($report['additional_items'])) {
            $row++;
            $sheet->setCellValue('A' . $row, 'Referrals completed');
            $sheet->mergeCells('A' . $row . ':B' . $row);
            $sheet->getStyle('A' . $row)->getFont()->setBold(true)->setSize(12);
            $row++;

            foreach ($report['additional_items'] as $oneItem) {
                if (!is_array($oneItem)) {
                    continue;
                }
                $student = $oneItem['student'] ?? null;
                $name = '';
                if (is_object($student) && method_exists($student, 'getKnownAs') && method_exists($student, 'getSurname')) {
                    $name = trim((string) $student->getKnownAs() . ' ' . (string) $student->getSurname());
                }
                $formData = isset($oneItem['formData']) && is_array($oneItem['formData']) ? $oneItem['formData'] : array();
                $likely = isset($formData['refer_likely']) ? (string) $formData['refer_likely'] : '';
                $reasons = isset($formData['refer_friends']) ? (string) $formData['refer_friends'] : '';

                $block = $name . "\nLikely to recommend: " . $likely . "\nThree reasons:\n" . $reasons;
                $sheet->setCellValue('A' . $row, $block);
                $sheet->mergeCells('A' . $row . ':B' . $row);
                $sheet->getStyle('A' . $row)->getAlignment()->setWrapText(true)->setVertical(Alignment::VERTICAL_TOP);
                $row++;
            }
        }

        if (!empty($report['survey_items']) && is_array($report['survey_items'])) {
            $row++;
            $sheet->setCellValue('A' . $row, 'Survey respondents (' . count($report['survey_items']) . ')');
            $sheet->mergeCells('A' . $row . ':B' . $row);
            $sheet->getStyle('A' . $row)->getFont()->setBold(true)->setSize(12);
            $row++;

            $names = array();
            foreach ($report['survey_items'] as $oneItem) {
                if (!is_array($oneItem)) {
                    continue;
                }
                $student = $oneItem['student'] ?? null;
                if (is_object($student) && method_exists($student, 'getKnownAs') && method_exists($student, 'getSurname')) {
                    $names[] = trim((string) $student->getKnownAs() . ' ' . (string) $student->getSurname());
                }
            }
            $sheet->setCellValue('A' . $row, implode("\n", $names));
            $sheet->mergeCells('A' . $row . ':B' . $row);
            $sheet->getStyle('A' . $row)->getAlignment()->setWrapText(true)->setVertical(Alignment::VERTICAL_TOP);
            $row++;
        }

        if (!empty($report['survey_non_respondent_items']) && is_array($report['survey_non_respondent_items'])) {
            $row++;
            $sheet->setCellValue(
                'A' . $row,
                'Did not respond (' . count($report['survey_non_respondent_items']) . ')'
            );
            $sheet->mergeCells('A' . $row . ':B' . $row);
            $sheet->getStyle('A' . $row)->getFont()->setBold(true)->setSize(12);
            $row++;

            $names = array();
            foreach ($report['survey_non_respondent_items'] as $oneItem) {
                if (!is_array($oneItem)) {
                    continue;
                }
                $student = $oneItem['student'] ?? null;
                if (is_object($student) && method_exists($student, 'getKnownAs') && method_exists($student, 'getSurname')) {
                    $names[] = trim((string) $student->getKnownAs() . ' ' . (string) $student->getSurname());
                }
            }
            $sheet->setCellValue('A' . $row, implode("\n", $names));
            $sheet->mergeCells('A' . $row . ':B' . $row);
            $sheet->getStyle('A' . $row)->getAlignment()->setWrapText(true)->setVertical(Alignment::VERTICAL_TOP);
        }

        $sheet->getColumnDimension('A')->setWidth(42);
        $sheet->getColumnDimension('B')->setWidth(72);

        $tmp = tempnam(sys_get_temp_dir(), 'frx');
        if ($tmp === false) {
            throw new \RuntimeException('Could not create temporary file for Excel export.');
        }
        $writer = new Xlsx($spreadsheet);
        $writer->save($tmp);
        $binary = file_get_contents($tmp);
        unlink($tmp);
        if ($binary === false) {
            throw new \RuntimeException('Could not read Excel export file.');
        }

        return $binary;
    }

    /**
     * @param array<int|string, string> $segments Non-empty lines; empty strings are skipped
     */
    public function joinPlainTextSegmentsWithBoundary(array $segments): string
    {
        $clean = array();
        foreach ($segments as $segment) {
            $s = trim((string) $segment);
            if ($s !== '') {
                $clean[] = $s;
            }
        }

        if (count($clean) === 0) {
            return '';
        }

        return implode("\n" . self::PLAIN_TEXT_ANSWER_BOUNDARY . "\n", $clean);
    }

    private function buildFormReportExportPromptLabel(array $formItem): string
    {
        $lines = array();
        $dateCol = isset($formItem['date_col']) ? trim((string) $formItem['date_col']) : '';
        if ($dateCol !== '') {
            $lines[] = $dateCol;
            if (isset($formItem['time_col']) && strlen(trim((string) $formItem['time_col'])) > 0) {
                $lines[] = trim((string) $formItem['time_col']);
            }
            if (isset($formItem['prompt']) && strlen(trim((string) $formItem['prompt'])) > 0) {
                $lines[] = trim((string) $formItem['prompt']);
            }
            if (isset($formItem['presenter_name']) && strlen(trim((string) $formItem['presenter_name'])) > 0) {
                $lines[] = trim((string) $formItem['presenter_name']);
            }
        } else {
            $lines[] = trim((string) ($formItem['prompt'] ?? ''));
        }

        return implode("\n", array_filter($lines, static function ($line) {
            return strlen(trim((string) $line)) > 0;
        }));
    }

    private function buildFormReportExportValuesCell(array $formItem): string
    {
        $parts = array();

        $formItemList = isset($formItem['form_item_list']) && is_array($formItem['form_item_list'])
            ? $formItem['form_item_list']
            : array();

        if (count($formItemList) > 0) {
            foreach ($formItemList as $listItem) {
                if (!is_array($listItem)) {
                    continue;
                }
                $name = isset($listItem['name']) ? (string) $listItem['name'] : '';
                $cnt = isset($listItem['valueCount']) ? (int) $listItem['valueCount'] : 0;
                if ($name !== '') {
                    $parts[] = $name . ': ' . $cnt;
                }
            }
            $mainBlock = implode("\n", $parts);
        } else {
            $values = isset($formItem['value']) && is_array($formItem['value']) ? $formItem['value'] : array();
            foreach ($values as $oneValue => $number) {
                $text = trim((string) $oneValue);
                if ($text !== '') {
                    $parts[] = $text . ' (' . (int) $number . ')';
                }
            }
            $mainBlock = $this->joinPlainTextSegmentsWithBoundary($parts);
        }

        $commentsBlock = '';
        if (!empty($formItem['additional_comments'])) {
            $comments = isset($formItem['additional_comments_text']) && is_array($formItem['additional_comments_text'])
                ? $formItem['additional_comments_text']
                : array();
            $commentLines = array();
            foreach ($comments as $comment => $number) {
                $c = trim((string) $comment);
                if ($c !== '') {
                    $commentLines[] = $c . ' (' . (int) $number . ')';
                }
            }
            if (count($commentLines) > 0) {
                $commentsBlock = "Comments / Suggestions / Improvements:\n"
                    . $this->joinPlainTextSegmentsWithBoundary($commentLines);
            }
        }

        if ($mainBlock !== '' && $commentsBlock !== '') {
            return $mainBlock . "\n\n" . $commentsBlock;
        }

        return $mainBlock !== '' ? $mainBlock : $commentsBlock;
    }

    /**
     * @return array<int, int>
     */
    private function getExamPlaceholderStudentIds(): array
    {
        return array(269, 270, 271, 272, 273);
    }

    /**
     * @param array<int, array<string, mixed>> $surveyItems
     * @return array<int, int>
     */
    private function collectRespondentStudentIdsFromSurveyItems(array $surveyItems): array
    {
        $respondentIds = array();
        foreach ($surveyItems as $surveyItem) {
            if (!is_array($surveyItem)) {
                continue;
            }
            $student = $surveyItem['student'] ?? null;
            if (is_object($student) && method_exists($student, 'getId')) {
                $studentId = (int) $student->getId();
                if ($studentId > 0) {
                    $respondentIds[$studentId] = $studentId;
                }
            }
        }

        return array_values($respondentIds);
    }

    /**
     * @return array<int, int>
     */
    private function getSubmittedStudentIdsForFeedbackForm(string $formId): array
    {
        $formId = trim($formId);
        if ($formId === '') {
            return array();
        }

        $connection = $this->getEm()->getConnection();
        $rows = $connection->fetchFirstColumn(
            'SELECT DISTINCT sa.CCEStudentID
             FROM CCEStudentAssignments sa
             INNER JOIN CCEAssignments a ON a.CCEAssignmentID = sa.CCEAssignmentID
             WHERE a.FeedbackFormID = :formId
               AND sa.DateSubmitted IS NOT NULL
               AND sa.DateSubmitted > :minDate',
            array(
                'formId' => $formId,
                'minDate' => '1970-01-01 00:00:00',
            )
        );

        $studentIds = array();
        $examPlaceholderIds = $this->getExamPlaceholderStudentIds();
        foreach ($rows as $studentId) {
            $studentId = (int) $studentId;
            if ($studentId <= 0 || in_array($studentId, $examPlaceholderIds, true)) {
                continue;
            }
            $studentIds[$studentId] = $studentId;
        }

        return array_values($studentIds);
    }

    /**
     * Students who submitted the linked assignment but have no survey_data completion for this form.
     *
     * @param array<int, array<string, mixed>> $surveyItems
     * @param object $studentManager cce_student.manager
     * @return array<int, array<string, mixed>>
     */
    private function buildSurveyNonRespondentItems(string $formId, array $surveyItems, $studentManager): array
    {
        $submittedStudentIds = $this->getSubmittedStudentIdsForFeedbackForm($formId);
        if (count($submittedStudentIds) === 0) {
            return array();
        }

        $respondentIds = $this->collectRespondentStudentIdsFromSurveyItems($surveyItems);
        $nonRespondentIds = array_values(array_diff($submittedStudentIds, $respondentIds));
        if (count($nonRespondentIds) === 0) {
            return array();
        }

        if (!method_exists($studentManager, 'findForReportLabelsByIds')) {
            return array();
        }

        $labelsById = $studentManager->findForReportLabelsByIds($nonRespondentIds);
        $items = array();
        foreach ($nonRespondentIds as $studentId) {
            if (!isset($labelsById[$studentId])) {
                continue;
            }
            $items[] = array('student' => $labelsById[$studentId]);
        }

        CCEStudentDisplayOrder::sortRowsWithStudentObject($items, 'student');

        return $items;
    }
}