Created
July 16, 2015 06:53
-
-
Save akadlec/fc5efd9b85535f48b5e5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Control.php | |
* | |
* @copyright More in license.md | |
* @license http://www.ipublikuj.eu | |
* @author Adam Kadlec http://www.ipublikuj.eu | |
* @package iPublikuj:AccountModule! | |
* @subpackage DataGrids | |
* @since 5.0 | |
* | |
* @date 26.07.14 | |
*/ | |
namespace IPub\AccountModule\DataGrids\Emails; | |
use Nette; | |
use Nette\Security as NS; | |
use Nette\ComponentModel; | |
use Nette\Utils; | |
use Tracy\Debugger; | |
use Kdyby; | |
use Kdyby\Autowired; | |
use Kdyby\Doctrine; | |
use Kdyby\Translation; | |
use IPub; | |
use IPub\AccountModule\Entities; | |
use IPub\AccountModule\Exceptions; | |
use IPub\AccountModule\Forms; | |
use IPub\AccountModule\Helpers; | |
use IPub\AccountModule\Models; | |
use IPub\AccountModule\Queries; | |
use IPub\Framework\Application\UI; | |
use IPub\DataTables; | |
use IPub\DataTables\Components; | |
use IPub\DataTables\Components\Columns; | |
use IPub\ConfirmationDialog\Components as ConfirmationDialog; | |
class Control extends Components\Control | |
{ | |
/** | |
* Implements components rendering | |
*/ | |
use UI\TControlRender { beforeRender as traitBeforeRender; } | |
/** | |
* Implements components entity transformation to handles | |
*/ | |
use IPub\Application\UI\TEntityCall; | |
/** | |
* Implement flash messages | |
*/ | |
use IPub\FlashMessages\TFlashMessages; | |
/** | |
* Implements autowiring extension | |
*/ | |
use Autowired\AutowireComponentFactories; | |
/** | |
* @var Entities\Users\IUser | |
*/ | |
protected $account; | |
/** | |
* @var Models\Emails\IEmailsManager | |
*/ | |
protected $emailsManager; | |
/** | |
* @var Models\Emails\IEmailFacade | |
*/ | |
protected $emailFacade; | |
/** | |
* @var Helpers\VerifyHash | |
*/ | |
protected $verifyHash; | |
/** | |
* @var IPub\Gravatar\Gravatar | |
*/ | |
protected $gravatar; | |
/** | |
* @var string | |
*/ | |
public $translationDomain = 'account.datagrids.emails'; | |
/** | |
* @param IPub\Gravatar\Gravatar $gravatar | |
*/ | |
public function injectGravatar(IPub\Gravatar\Gravatar $gravatar) | |
{ | |
$this->gravatar = $gravatar; | |
} | |
/** | |
* @param Models\Emails\IEmailsManager $emailsManager | |
* @param Models\Emails\IEmailFacade $emailFacade | |
* @param Helpers\VerifyHash $verifyHash | |
*/ | |
public function __construct( | |
Models\Emails\IEmailsManager $emailsManager, | |
Models\Emails\IEmailFacade $emailFacade, | |
Helpers\VerifyHash $verifyHash | |
) { | |
parent::__construct(); | |
// Modules managers | |
$this->emailsManager = $emailsManager; | |
// Modules facades | |
$this->emailFacade = $emailFacade; | |
// Modules helpers | |
$this->verifyHash = $verifyHash; | |
} | |
/** | |
* @param \Nette\ComponentModel\IComponent | |
*/ | |
public function attached($presenter) | |
{ | |
parent::attached($presenter); | |
// Set translator domain | |
$this->setTranslator($this->getTranslator()->domain($this->translationDomain)); | |
} | |
/** | |
* Set user account or identity | |
* | |
* @param Entities\Users\IUser|NS\IIdentity $account | |
* | |
* @return $this | |
* | |
* @throws Exceptions\LogicException | |
*/ | |
public function setAccount($account) | |
{ | |
if ($account instanceof Entities\Identities\Identity) { | |
$this->account = $account->getOwner(); | |
} else if ($account instanceof Entities\Users\IUser ) { | |
$this->account = $account; | |
} else { | |
throw new Exceptions\LogicException('This call support only instance of "Nette\Security\IIdentity" or "Entities\Users\IUser", instance of "'. get_class($account) .'" was given'); | |
} | |
return $this; | |
} | |
/** | |
* @param ComponentModel\IComponent $presenter | |
*/ | |
protected function configure($presenter) | |
{ | |
// Store object into variable | |
$self = $this; | |
// Remap columns names | |
$filterMapping = [ | |
]; | |
// Define table primary key | |
$this->setPrimaryKey('id'); | |
// Data are loaded on demand | |
$this->enableServerSide(); | |
// Enable processing animation | |
$this->enableProcessing(); | |
// Enable data grid state saving | |
$this->enableStateSave(); | |
// And store it into session | |
$this->saveStateIntoSession(); | |
// Define default sorting | |
$this->setDefaultSort(['address' => Columns\IColumn::ORDER_DESC]); | |
// Get data query builder | |
$qb = $this->emailFacade->getQBForDataGrid(); | |
$qb | |
->where('e.owner = :owner') | |
->setParameter(':owner', $this->account); | |
// Assign data source to the grid | |
$this->setModel(new IPub\DataTables\DataSources\Doctrine($qb, $filterMapping)); | |
$columnAvatar = $this->addColumnImage('avatar', $this->translationDomain .'.column.avatar.title') | |
->setClassName('pk-table-width-minimum') | |
->setImage(function(Entities\Emails\IEmail $row){ | |
return [ | |
'src' => $this->gravatar->buildUrl($row->getAddress(), 40), | |
'alt' => $row->getAddress(), | |
'class' => 'uk-img-preserve uk-border-circle' | |
]; | |
}); | |
$columnAddress = $this->addColumnText('address', $this->translationDomain .'.column.address.title') | |
->setClassName('uk-text-nowrap'); | |
$columnAddress | |
->addFilterText($this->translationDomain .'.column.address.filter') | |
->setColumn('address'); | |
$columnVerified = $this->addColumnAction('verified', $this->translationDomain .'.column.verified.title') | |
->setClassName('uk-text-center') | |
->enableSearchable() | |
->enableSortable(); | |
$columnVerified | |
->addButton('verified') | |
->showAsLink() | |
->setClass(function(Entities\Emails\IEmail $row){ | |
// Get user status | |
return $row->isVerified() ? 'uk-icon-circle uk-text-primary' : 'uk-icon-circle uk-text-muted'; | |
}) | |
->setTitle(function(Entities\Emails\IEmail $row){ | |
// Get user status | |
return $row->isVerified() ? $this->translationDomain .'.column.verified.tooltip.verified' : $this->translationDomain .'.column.verified.tooltip.notVerified'; | |
}) | |
->addAttributes(function(Entities\Emails\IEmail $row){ | |
return $row->isVerified() ? ['disabled' => 'disabled', 'data-uk-tooltip' => ''] : ['data-uk-tooltip' => '']; | |
}) | |
->setCallback(function(Entities\Emails\IEmail $row){ | |
// Get user status | |
$row->isVerified() ? NULL : $this->handleRequestVerification([$row]); | |
}); | |
$columnVerified | |
->addFilterSelect($this->translationDomain .'.column.verified.filter', [ | |
'' => $this->translationDomain .'.column.verified.values.none', | |
TRUE => $this->translationDomain .'.column.verified.values.verified', | |
FALSE => $this->translationDomain .'.column.verified.values.notVerified', | |
]); | |
$columnDefault = $this->addColumnAction('default', $this->translationDomain .'.column.default.title') | |
->setClassName('uk-text-center') | |
->enableSearchable() | |
->enableSortable(); | |
$columnDefault | |
->addButton('default') | |
->showAsLink() | |
->setClass(function(Entities\Emails\IEmail $row){ | |
// Get user status | |
return $row->isDefault() ? 'uk-icon-circle uk-text-primary' : 'uk-icon-circle uk-text-muted'; | |
}) | |
->setTitle(function(Entities\Emails\IEmail $row){ | |
// Get user status | |
return $row->isDefault() ? $this->translationDomain .'.column.default.tooltip.default' : ($row->isVerified() ? $this->translationDomain .'.column.default.tooltip.notDefault' : $this->translationDomain .'.column.default.tooltip.notVerified'); | |
}) | |
->addAttributes(function(Entities\Emails\IEmail $row){ | |
return $row->isDefault() || !$row->isVerified() ? ['disabled' => 'disabled', 'data-uk-tooltip' => ''] : ['data-uk-tooltip' => '']; | |
}) | |
->setCallback(function(Entities\Emails\IEmail $row){ | |
// Get user status | |
$row->isDefault() || !$row->isVerified() ? NULL : $this->handleSetPrimary([$row]); | |
}); | |
// Global actions | |
$this->addGlobalButton('delete', 'deleteEmail.title') | |
->showAsLink() | |
->setCallback(function(array $rows){ | |
$params = []; | |
foreach($rows as $row) { | |
$params['emails'][] = $row->getId(); | |
} | |
$this['confirmAction']->showConfirm('delete', $params); | |
}); | |
$this->addGlobalButton('verify', 'verifyEmail.title') | |
->showAsLink() | |
->setCallback(function(array $rows){ | |
$this->handleRequestVerification($rows); | |
}); | |
} | |
/** | |
* Before render component | |
* | |
* @throws Exceptions\LogicException | |
*/ | |
protected function beforeRender() | |
{ | |
self::traitBeforeRender(); | |
// Check if account entity is set | |
if (!$this->account) { | |
throw new Exceptions\LogicException('Missing call ' . get_called_class() . '::setAccount($entity)'); | |
} | |
} | |
/** | |
* Component for action confirmation | |
* | |
* @param ConfirmationDialog\IControl $factory | |
* | |
* @return ConfirmationDialog\Control | |
*/ | |
protected function createComponentConfirmAction(ConfirmationDialog\IControl $factory) | |
{ | |
// Init action confirm | |
$form = $factory->create(); | |
// Define confirm windows | |
$form | |
// Set template defined in presenter | |
->setTemplateFile($this->getPresenter()->getConfirmerTemplate()) | |
// Email delete confirm | |
->addConfirmer( | |
'delete', | |
[$this, 'handleDelete'], | |
[$this, 'questionDelete'], | |
$this->getTranslator()->translate("delete.heading.deleteAddress") | |
); | |
return $form; | |
} | |
/** | |
* Create question for delete email dialog | |
* | |
* @param ConfirmationDialog\Confirmer $dialog | |
* @param $params | |
* | |
* @return bool|string | |
*/ | |
public function questionDelete(ConfirmationDialog\Confirmer $dialog, $params) | |
{ | |
// Set dialog icon | |
$dialog->setIcon('trash'); | |
// Create question | |
return $this->getTranslator()->translate("delete.text.deleteAddress", ['count' => count($params['emails'])]); | |
} | |
/** | |
* Handler for delete user emails | |
* | |
* @param array $emails | |
* | |
* @throws Exceptions\BadRequestException | |
* @throws Exceptions\ForbiddenRequestException | |
*/ | |
public function handleDelete(array $emails) | |
{ | |
// Do the full table redraw | |
$this->enableFullRedraw(); | |
// Deleted emails count | |
$deleted = 0; | |
foreach($emails as $id) { | |
// Try to load email by id | |
if ($email = $this->emailFacade->findOneByIdentifier($id)) { | |
// Check if user is item owner | |
if ($email->getOwner()->getId() != $this->account->getId()) { | |
// Store info message | |
$this->flashNotifier->error("framework.messages.accessOnlyToOwnerRecords"); | |
throw new Exceptions\ForbiddenRequestException; | |
} | |
// Only not default email could be deleted | |
if (!$email->isDefault()) { | |
try { | |
// Delete email from database | |
$this->emailsManager->delete($email); | |
$deleted++; | |
} catch (\Exception $ex) { | |
// Log error message | |
Debugger::log($ex->getMessage(), Debugger::ERROR); | |
// Store info message | |
$this->flashNotifier->warning(new Translation\Phrase($this->translationDomain . ".delete.validation.email.notDeleted", ['address' => $email->getAddress()])); | |
} | |
// For default email raise error message | |
} else { | |
// Store info message | |
$this->flashNotifier->warning(new Translation\Phrase($this->translationDomain . ".delete.validation.email.isDefault", ['address' => $email->getAddress()])); | |
} | |
} | |
} | |
// Only if some emails were deleted | |
if ($deleted) { | |
// Store info message | |
$this->flashNotifier->success(new Translation\Phrase($this->translationDomain . ".delete.success", $deleted)); | |
} else { | |
// Store info message | |
$this->flashNotifier->success(new Translation\Phrase($this->translationDomain . ".delete.validation.email.noEmails")); | |
} | |
} | |
/** | |
* Handler for marking selected email as default | |
* | |
* @param array $emails | |
* | |
* @throws Exceptions\ForbiddenRequestException | |
*/ | |
public function handleSetPrimary(array $emails) | |
{ | |
// Do the full table redraw | |
$this->enableFullRedraw(); | |
// Process all emails | |
foreach($emails as $email) { | |
// Check if user is item owner | |
if ($email->getOwner()->getId() != $this->account->getId()) { | |
// Store info message | |
$this->flashNotifier->error("framework.messages.accessOnlyToOwnerRecords"); | |
throw new Exceptions\ForbiddenRequestException; | |
} | |
// Check if email is verified | |
if ($email->getVerified()) { | |
try { | |
// Deactivate all user emails | |
foreach ($this->account->getEmails() as $userEmail) { | |
// Create values for updating | |
$values = new Utils\ArrayHash(); | |
// Add entity identifier | |
$values->id = $userEmail->getId(); | |
// Change default status | |
$values->default = FALSE; | |
// Updated data in database | |
$this->emailsManager->update($userEmail, $values); | |
} | |
// Create values for updating | |
$values = new Utils\ArrayHash(); | |
// Add entity identifier | |
$values->id = $email->getId(); | |
// Change default status | |
$values->default = TRUE; | |
// Updated data in database | |
$this->emailsManager->update($email, $values); | |
// Store info message | |
$this->flashNotifier->success($this->translationDomain .".setPrimary.success"); | |
// Only one email could be set as primary | |
return; | |
} catch (\Exception $ex) { | |
// Log error message | |
Debugger::log($ex->getMessage(), Debugger::ERROR); | |
// Store info message | |
$this->flashNotifier->warning(new Translation\Phrase($this->translationDomain .".setPrimary.validation.email.notSet", ['address' => $email->getAddress()])); | |
} | |
// Email is not verified | |
} else { | |
// Store info message | |
$this->flashNotifier->warning(new Translation\Phrase($this->translationDomain .".setPrimary.validation.email.notVerified", ['address' => $email->getAddress()])); | |
} | |
} | |
} | |
/** | |
* Handler for sending verification email to selected email | |
* | |
* @param array $emails | |
* | |
* @throws Exceptions\ForbiddenRequestException | |
* @throws Exceptions\BadRequestException | |
*/ | |
public function handleRequestVerification(array $emails) | |
{ | |
// Do the full table redraw | |
$this->enableFullRedraw(); | |
// Process all emails | |
foreach($emails as $email) { | |
// Check if user is item owner | |
if ($email->getOwner()->getId() != $this->account->getId()) { | |
// Store info message | |
$this->flashNotifier->error("framework.messages.accessOnlyToOwnerRecords"); | |
throw new Exceptions\ForbiddenRequestException; | |
} | |
// Email is not verified yer | |
if (!$email->isVerified()) { | |
try { | |
// Create values for updating | |
$values = new Utils\ArrayHash(); | |
// Add entity identifier | |
$values->id = $email->getId(); | |
// Add verification info | |
$values->verificationCreated = new Utils\DateTime(); | |
$values->verificationHash = $this->verifyHash->createKey(); | |
// Save item into database | |
$this->emailsManager->update($email, $values); | |
// Store info message | |
$this->flashNotifier->success(new Translation\Phrase($this->translationDomain . ".verify.success", ["address" => $email->getAddress()])); | |
} catch (\Exception $ex) { | |
// Log error message | |
Debugger::log($ex->getMessage(), Debugger::ERROR); | |
// Store info message | |
$this->flashNotifier->warning(new Translation\Phrase($this->translationDomain . ".verify.validation.email.notSent", ["address" => $email->getAddress()])); | |
} | |
// Email is already verified | |
} else { | |
// Store info message | |
$this->flashNotifier->warning(new Translation\Phrase($this->translationDomain . ".verify.validation.email.isVerified", ["address" => $email->getAddress()])); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment