最近、Doctrine 2.2 と Zend Framework 2 の一部を使用して、組織を改善し、重複を減らすなどの取り組みを開始しました。今日、私は、コントローラーと Doctrine エンティティーの間の仲介役として機能するサービス層を実装するためのアイデアを投げかけ始めました。
現在、ロジックの大部分はコントローラーにあります。さらに、アクション ヘルパーを使用して特定の権限をテストします。しかし、Zend\Di を実装した後、新しいアプローチを思い付きました。Zend\Di を使用して EntityManager インスタンスと現在のユーザーのアクセス許可を注入する、エンティティ固有のサービス モデルの作成を開始しました。
コントローラーのコードは次のとおりです。
class Project_DeleteController extends Webjawns_Controller_Action
{
public function init()
{
$this->_initJsonContext();
}
public function indexAction()
{
$response = $this->_getAjaxResponse();
$auditId = (int) $this->_getParam('audit_id');
if (!$auditId) {
throw new DomainException('Audit ID required');
}
/* @var $auditService Service\Audit */
$auditService = $this->getDependencyInjector()->get('Service\Audit');
try {
$auditService->delete($auditId);
$response->setStatusSuccess();
} catch (Webjawns\Exception\SecurityException $e) {
$this->_noAuth();
} catch (Webjawns\Exception\Exception $e) {
$response->setStatusFailure($e->getMessage());
}
$response->sendResponse();
}
}
そして、サービス層の 1 つの例です。コンストラクターは 2 つのパラメーターを受け取ります。1 つは EntityManager を受け取り、もう 1 つは Zend\Di によって注入された Entity\UserAccess オブジェクトを受け取ります。
namespace Service;
use Webjawns\Service\Doctrine,
Webjawns\Exception;
class Audit extends AbstractService
{
public function delete($auditId)
{
// Only account admins can delete audits
if (\Webjawns_Acl::ROLE_ACCT_ADMIN != $this->getUserAccess()->getAccessRole()) {
throw new Exception\SecurityException('Only account administrators can delete audits');
}
$audit = $this->get($auditId);
if ($audit->getAuditStatus() !== \Entity\Audit::STATUS_IN_PROGRESS) {
throw new Exception\DomainException('Audits cannot be deleted once submitted for review');
}
$em = $this->getEntityManager();
$em->remove($audit);
$em->flush();
}
/**
* @param integer $auditId
* @return \Entity\Audit
*/
public function get($auditId)
{
/* @var $audit \Entity\Audit */
$audit = $this->getEntityManager()->find('Entity\Audit', $auditId);
if (null === $audit) {
throw new Exception\DomainException('Audit not found');
}
if ($audit->getAccount()->getAccountId() != $this->getUserAccess()->getAccount()->getAccountId()) {
throw new Exception\SecurityException('User and audit accounts do not match');
}
return $audit;
}
}
- これは、達成しようとしていることに使用する適切なパターンですか?
- 掲載されているように、サービス レイヤー内でアクセス許可の検証を行うことをお勧めしますか?
- 私が理解しているように、ビュー ロジックは引き続きコントローラーに存在し、さまざまなコンテキスト (JSON、XML、HTML など) でモデルを柔軟に使用できるようにします。考え?
これまでのやり方には満足していますが、私たちのやり方にマイナス面を見つけた人は、あなたの考えを投稿してください.