Skip to content

Commit

Permalink
TASK: add backend module
Browse files Browse the repository at this point in the history
  • Loading branch information
Jens Schuett committed Jan 20, 2017
1 parent a9881f1 commit 36a89c3
Show file tree
Hide file tree
Showing 13 changed files with 601 additions and 2 deletions.
171 changes: 171 additions & 0 deletions Classes/Psmb/Newsletter/Controller/BackendController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php
namespace Psmb\Newsletter\Controller;

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

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

class BackendController extends AbstractModuleController
{
/**
* @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('The subscriber "%s" has been updated.', 'Remove Tag', Message::SEVERITY_OK, [$subscriber->getName()]);
} 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('The subscriber "%s" has been removed.', 'Remove Tag', Message::SEVERITY_OK, [$subscriber->getName()]);
} 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('Only csv is allowed.', 'Wrong file ending', Message::SEVERITY_WARNING);
$this->redirect('index');
}

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

if (!is_readable($filename)) {
$this->addFlashMessage('Sorry, but the file "%s" is not readable or does not exist...', 'File does not exist', Message::SEVERITY_WARNING, [$filename]);
$this->redirect('index');
}
$handle = fopen($filename, "r");
while (($line = fgetcsv($handle)) !== false) {
if (count($line) === 3) {
$email = $line[0];
$name = $line[1] ?: "";
$subscriptions = explode("|", $line[2]);

if ($this->subscriberRepository->countByEmail($email) > 0) {
$message = $this->translator->translateById('flash.alreadyRegistered', [], null, null, 'Main', 'Psmb.Newsletter');
$this->addFlashMessage('%s: ' . $message, null, Message::SEVERITY_WARNING, [$email]);
} else {
$subscriber = new Subscriber();
$subscriber->setEmail($email);
$subscriber->setName($name);
$subscriber->setSubscriptions($subscriptions);
$this->subscriberRepository->add($subscriber);
}
}
}
fclose($handle);

$this->addFlashMessage('Subscribers have been added.', null, Message::SEVERITY_OK);
$this->redirect('index');
}

/**
* @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('The subscriber "%s" has been added.', 'Remove Tag', Message::SEVERITY_OK, [$subscriber->getName()]);
} 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 TYPO3\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
@@ -1,6 +1,7 @@
<?php
namespace Psmb\Newsletter\Domain\Repository;

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

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

/**
* @param Filter $filter
* @return \TYPO3\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();
}
}
7 changes: 7 additions & 0 deletions Configuration/Policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ privilegeTargets:
TYPO3\Flow\Security\Authorization\Privilege\Method\MethodPrivilege:
'Psmb.Newsletter':
matcher: 'method(Psmb\Newsletter\Controller\(.*)Controller->(.*)Action())'
'Psmb.Newsletter:BackendModule':
matcher: 'method(Psmb\Newsletter\Controller\BackendController->.*Action())'

roles:
'TYPO3.Flow:Everybody':
privileges:
-
privilegeTarget: 'Psmb.Newsletter'
permission: GRANT
'TYPO3.Neos:Editor':
privileges:
-
privilegeTarget: 'Psmb.Newsletter:BackendModule'
permission: GRANT
15 changes: 13 additions & 2 deletions Configuration/Settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,19 @@ TYPO3:
typoScript:
autoInclude:
'Psmb.Newsletter': TRUE
#Psmb:
# Newsletter:
modules:
management:
submodules:
newsletter:
label: 'Newsletter'
controller: 'Psmb\Newsletter\Controller\BackendController'
description: 'Manage all subscriber lists for your Newsletter. You can edit/delete/update each subscription individually. Keep in mind that all subscribers are detached from Neos users.'
icon: 'icon-envelope'
privilegeTarget: 'Psmb.Newsletter:BackendModule'
Psmb:
Newsletter:
module:
itemsPerPage: 10
# globalSettings:
# senderAddress: '[email protected]'
# senderName: 'Your robot'
Expand Down
6 changes: 6 additions & 0 deletions Configuration/Views.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-
requestFilter: 'isPackage("Psmb.Newsletter") && isFormat("html") && isController("Backend")'
options:
partialRootPaths:
'Psmb.Newsletter': 'resource://Psmb.Newsletter/Private/Partials'
'TYPO3.Neos': 'resource://TYPO3.Neos/Private/Partials/'
9 changes: 9 additions & 0 deletions Resources/Private/Layouts/Default.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div id="neos-notification-container" class="neos-notification-top">
<f:render partial="Module/FlashMessages"/>
</div>
<div class="neos-row-fluid">
<f:render section="Content"/>
</div>
<div class="neos-footer">
<f:render section="Footer" optional="TRUE"/>
</div>
11 changes: 11 additions & 0 deletions Resources/Private/Layouts/EditSubscriber.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div id="neos-notification-container" class="neos-notification-top">
<f:render partial="Module/FlashMessages"/>
</div>
<f:form objectName="subscriber" object="{subscriber}" action="updateSubscriber" controller="Backend">
<div class="neos-row-fluid">
<f:render section="Content"/>
</div>
<div class="neos-footer">
<f:render section="Footer" optional="TRUE"/>
</div>
</f:form>
11 changes: 11 additions & 0 deletions Resources/Private/Layouts/NewSubscriber.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div id="neos-notification-container" class="neos-notification-top">
<f:render partial="Module/FlashMessages"/>
</div>
<f:form objectName="subscriber" object="{subscriber}" action="createSubscriber" controller="Backend">
<div class="neos-row-fluid">
<f:render section="Content"/>
</div>
<div class="neos-footer">
<f:render section="Footer" optional="TRUE"/>
</div>
</f:form>
Loading

0 comments on commit 36a89c3

Please sign in to comment.