Skip to content

Commit

Permalink
Merge pull request psmb#3 from Snejmann/backend_module
Browse files Browse the repository at this point in the history
FEATURE: backend module to manage subscribers
  • Loading branch information
dimaip authored Dec 25, 2018
2 parents a5a48f5 + 3418db2 commit 92dd421
Show file tree
Hide file tree
Showing 18 changed files with 750 additions and 6 deletions.
15 changes: 15 additions & 0 deletions Classes/Psmb/Newsletter/Command/NewsletterCommandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,19 @@ protected function sendLettersForSubscription($subscription, $dryRun)
});
}

/**
* @return ActionRequest
*/
protected function createRequest() {
$_SERVER['FLOW_REWRITEURLS'] = 1;
$httpRequest = Request::createFromEnvironment();
if ($this->baseUri) {
$baseUri = new Uri($this->baseUri);
$httpRequest->setBaseUri($baseUri);
}
$actionRequest = new ActionRequest($httpRequest);
$actionRequest->setFormat('html');
return $actionRequest;
}

}
224 changes: 224 additions & 0 deletions Classes/Psmb/Newsletter/Controller/BackendController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
<?php
namespace Psmb\Newsletter\Controller;

/*
* This file is part of the Globit.Newsletter package.
*/

use League\Csv\Reader;
use League\Csv\Writer;
use Psmb\Newsletter\Domain\Model\Filter;
use Psmb\Newsletter\Domain\Model\Subscriber;
use Psmb\Newsletter\Domain\Repository\SubscriberRepository;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Error\Message;
use Neos\Flow\I18n\Translator;
use Neos\Flow\Persistence\Exception\IllegalObjectTypeException;
use Neos\Flow\Persistence\QueryInterface;
use Neos\Media\Domain\Model\Document;
use Neos\Neos\Controller\Module\AbstractModuleController;

class BackendController extends AbstractModuleController
{
const STATUS_CREATED = 0, STATUS_UPDATED = 1, STATUS_CORRUPTED = 2;

/**
* @Flow\Inject
* @var SubscriberRepository
*/
protected $subscriberRepository;

/**
* @Flow\InjectConfiguration(path="subscriptions", package="Psmb.Newsletter")
* @var array
*/
protected $subscriptions;

/**
* @Flow\Inject
* @var Translator
*/
protected $translator;

/**
* @param Filter $filter
* @return void
*/
public function indexAction($filter = NULL)
{
$this->subscriberRepository->setDefaultOrderings(['name' => QueryInterface::ORDER_ASCENDING]);
$subscriptions = $filter ? $this->subscriberRepository->findAllByFilter($filter) : $this->subscriberRepository->findAll();

$this->view->assign('subscribers', $subscriptions);
$this->view->assign('filter', $filter);
$this->view->assign('subscriptions', array_map(function ($subscription) {
return $subscription['identifier'];
}, $this->subscriptions));
}

/**
* @param Subscriber $subscriber
* @return void
*/
public function editSubscriberAction($subscriber)
{
$this->view->assign('subscriber', $subscriber);
$this->view->assign('subscriptions', array_map(function ($subscription) {
return $subscription['identifier'];
}, $this->subscriptions));
}

/**
* @param Subscriber $subscriber
* @return void
*/
public function updateSubscriberAction($subscriber)
{
try {
$this->subscriberRepository->update($subscriber);
$this->addFlashMessage(
$this->translator->translateById('flash.subscriber.updated', ["s" => $subscriber->getName()], null, null, 'Main', 'Psmb.Newsletter'),
'Update Subscriber'
);
} catch (IllegalObjectTypeException $e) {
$this->addFlashMessage('An Error occurred: %s', 'Error', Message::SEVERITY_ERROR, [$e->getMessage()]);
}

$this->redirect('editSubscriber', NULL, NULL, ['subscriber' => $subscriber]);
}

/**
* @param Subscriber $subscriber
* @return void
*/
public function deleteSubscriberAction($subscriber)
{
try {
$this->subscriberRepository->remove($subscriber);
$this->addFlashMessage(
$this->translator->translateById('flash.subscriber.removed', ["s" => $subscriber->getName()], null, null, 'Main', 'Psmb.Newsletter'),
'Remove Subscriber'
);
} catch (IllegalObjectTypeException $e) {
$this->addFlashMessage('An Error occurred: %s', 'Error', Message::SEVERITY_ERROR, [$e->getMessage()]);
}

$this->redirect('index');
}

/**
* @return void
*/
public function newSubscriberAction()
{
$this->view->assign('subscriptions', array_map(function ($subscription) {
return $subscription['identifier'];
}, $this->subscriptions));
}

/**
* @param Document $file
* @return void
*/
public function importSubscribersAction($file)
{
if ($file->getMediaType() != 'text/csv') {
$this->addFlashMessage(
$this->translator->translateById('flash.csv', [], null, null, 'Main', 'Psmb.Newsletter'),
'Wrong file ending',
MESSAGE::SEVERITY_WARNING
);
$this->redirect('index');
}

$filename = $_FILES['moduleArguments']['tmp_name']['file']['resource'];

if (!is_readable($filename)) {
$this->addFlashMessage(
$this->translator->translateById('flash.file.error', [], null, null, 'Main', 'Psmb.Newsletter'),
'File error',
MESSAGE::SEVERITY_ERROR
);
$this->redirect('index');
}
$csv = Reader::createFromPath($filename);
$status[self::STATUS_CREATED] = 0;
$status[self::STATUS_UPDATED] = 0;
$status[self::STATUS_CORRUPTED] = 0;
foreach ($line = $csv->getRecords() as $line) {
if (count($line) === 3) {
$email = $line[0];
$name = $line[1] ?: "";
$subscriptions = explode("|", $line[2]);

if ($this->subscriberRepository->countByEmail($email) > 0) {
/** @var Subscriber $subscriber */
$subscriber = $this->subscriberRepository->findByEmail($email)->getFirst();
$subscriber->setSubscriptions($subscriptions);
$subscriber->setName($name);
$this->subscriberRepository->update($subscriber);
$status[self::STATUS_UPDATED]++;
} else {
$subscriber = new Subscriber();
$subscriber->setEmail($email);
$subscriber->setName($name);
$subscriber->setSubscriptions($subscriptions);
$this->subscriberRepository->add($subscriber);
$status[self::STATUS_CREATED]++;
}
} else {
$status[self::STATUS_CORRUPTED]++;
}
}

$this->addFlashMessage(
$this->translator->translateById('flash.file.error', $status, null, null, 'Main', 'Psmb.Newsletter'),
'Remove Subscriber'
);
$this->redirect('index');
}

/**
* @return void
*/
public function exportSubscribersAction()
{
$csv = Writer::createFromFileObject(new \SplTempFileObject());

/** @var Subscriber $subscriber */
foreach ($this->subscriberRepository->findAll() as $subscriber) {
$csv->insertOne([
$subscriber->getEmail(),
$subscriber->getName(),
implode('|', $subscriber->getSubscriptions())
]);
}

$csv->output('subscriberlist.csv');
die();
}

/**
* @param Subscriber $subscriber
* @return void
*/
public function createSubscriberAction($subscriber)
{
if ($this->subscriberRepository->countByEmail($subscriber->getEmail()) > 0) {
$message = $this->translator->translateById('flash.alreadyRegistered', [], null, null, 'Main', 'Psmb.Newsletter');
$this->addFlashMessage($message, null, Message::SEVERITY_WARNING);
} else {
try {
$this->subscriberRepository->add($subscriber);
$this->addFlashMessage(
$this->translator->translateById('flash.subscriber.added', ['s' => $subscriber->getName()], null, null, 'Main', 'Psmb.Newsletter'),
'Add successful'
);
} catch (IllegalObjectTypeException $e) {
$this->addFlashMessage('An Error occurred: %s', 'Error', Message::SEVERITY_ERROR, [$e->getMessage()]);
}
}

$this->redirect('index');
}
}
74 changes: 74 additions & 0 deletions Classes/Psmb/Newsletter/Domain/Model/Filter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
namespace Psmb\Newsletter\Domain\Model;

use Doctrine\Common\Collections\ArrayCollection;
use Neos\Flow\Annotations as Flow;

/**
* @Flow\Scope("singleton")
*/
class Filter
{
/**
* @var string
*/
protected $name;

/**
* @var string
*/
protected $email;

/**
* @var array
*/
protected $subscriptions;

/**
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}

/**
* @return string
*/
public function getEmail()
{
return $this->email;
}

/**
* @param string $email
*/
public function setEmail($email)
{
$this->email = $email;
}

/**
* @return array
*/
public function getSubscriptions()
{
return $this->subscriptions;
}

/**
* @param array $subscriptions
*/
public function setSubscriptions($subscriptions)
{
$this->subscriptions = $subscriptions;
}
}
2 changes: 2 additions & 0 deletions Classes/Psmb/Newsletter/Domain/Model/Subscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Subscriber {
* @ORM\Column(length=80)
* @Flow\Identity
* @Flow\Validate(type="EmailAddress")
* @Flow\Validate(type="NotEmpty")
* @Flow\Validate(type="StringLength", options={"minimum"=1, "maximum"=80})
*/
protected $email;
Expand All @@ -30,6 +31,7 @@ class Subscriber {

/**
* @var array
* @Flow\Validate(type="NotEmpty")
*/
protected $subscriptions;

Expand Down
33 changes: 33 additions & 0 deletions Classes/Psmb/Newsletter/Domain/Repository/SubscriberRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Persistence\Repository;
use Psmb\Newsletter\Domain\Model\Filter;

/**
* @Flow\Scope("singleton")
Expand All @@ -20,4 +21,36 @@ public function findBySubscriptionId($subscriptionId)
$query->like('subscriptions', '%"' . $subscriptionId . '"%')
)->execute();
}

/**
* @param Filter $filter
* @return \Neos\Flow\Persistence\QueryResultInterface
*/
public function findAllByFilter($filter)
{
$query = $this->createQuery();
$constraint = [];

if (!empty($filter->getName())) {
$constraint[] = $query->like('name', '%' . $filter->getName() . '%');
}
if (!empty($filter->getEmail())) {
$constraint[] = $query->like('email', '%' . $filter->getEmail() . '%');
}
if (!empty($filter->getSubscriptions())) {
$subs = [];

foreach ($filter->getSubscriptions() as $subscription) {
$subs[] = $query->like('subscriptions', '%"' . $subscription . '"%');
}
$constraint[] = $query->logicalAnd($subs);
}
if (empty($constraint)) {
return $this->findAll();
}

return $query->matching($query->logicalAnd(
$constraint
))->execute();
}
}
1 change: 0 additions & 1 deletion Classes/Psmb/Newsletter/Service/FusionMailService.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,5 +258,4 @@ protected function getSiteNode($dimensions = [])
$context = $this->contextFactory->create($contextProperties);
return $context->getCurrentSiteNode();
}

}
Loading

0 comments on commit 92dd421

Please sign in to comment.