Configuração de acesso a dados
Utilizando o ZendAccessManager é possível, dentro de uma estrutura pré-definida, construir estratégias de acesso a dados para serem utilizadas de uma maneira simples. Supondo que exista uma tabela cad_contrato, e diferentes usuários com diferentes níveis de acesso num sistema precisam acessar os dados dessa tabela, de formas diferentes, de modo que cada nível de acesso poderá ver apenas dados específicos, como proceder?
try
{
// Obtém o usuário armazenado na sessão
$usuario = (new UserContainer())->getCurrentUser();
// Obtém a estratégia de acesso definida para o usuário
$sm = new ContratoStrategyManager();
$estrategia = $sm->getStrategyFor($usuario);
// Acessa os dados de acordo com a estratégia
$contratos = $estrategia->fetchContratos();
// [...]
// Exibe contratos...
}
catch(StrategyNotFoundException $e)
{
// Acesso negado...
}
Para criar uma estrutura de acesso a dados personalizada devemos ter em mente que precisaremos de três coisas: um TableGateway, responsável por executar as operações nos banco de dados, ao menos uma Strategy de acesso aos dados, e um StrategyManager, responsável por fazer a escolha da estratégia de acordo com as regras definidas no mesmo.
Por definição, toda estratégia de acesso a dados, precisa estar ligada a um tablegateway. Portanto, se vai fazer uma estratégia de acesso a dados, o primeiro a se fazer, é criar a classe que acessa os dados, para em seguida, executá-la na estratégia. Para mais informações, veja a documentação do ZendFramework 2.
class ContractTable extends AbstractTableGateway
{
public function __construct()
{
$this->table = "cad_contrato";
$this->adapter = GlobalAdapterFeature::getStaticAdapter();
}
}
A interface, é um padrão que deverá ser seguido pelas estratégias de acesso aos dados. Isto é, presume-se existem diferentes estratégias, para se fazer as mesmas coisas, então, deverão as estratégias de acesso a dados implementar igualmente, os métodos definidos na interface, cada qual com sua regra específica.
interface ContractStrategyInterface extends DataAccessStrategyInterface
{
public function fetchRecentContracts();
public function fetchAllContracts();
}
Nesse exemplo implementaremos as funções da estratégia que foram definidas na interface.
class AdminContractAccessStrategy implements ContractStrategyInterface
{
/**
* Configura a estratégia
*/
public function __construct()
{
$this->setTableGateway(new ContractTable());
}
/**
* Localiza os contratos recentes
* @return ResultSet
*/
public function fetchRecentContracts()
{
return $this->getTableGateway()->select(function(Select $select){
$select->order('idcontrato DESC');
$select->limit(10);
});
}
/**
* Localiza todos os contratos
* @return ResultSet
*/
public function fetchAllContracts()
{
return $this->getTableGateway()->select();
}
}
class SalesContractAccessStrategy implements ContractStrategyInterface
{
/**
* Configura a estratégia
*/
public function __construct()
{
$this->setTableGateway(new ContractTable());
}
/**
* Localiza os contratos recentes
* @return ResultSet
*/
public function fetchRecentContracts()
{
$user = (new UserContainer())->getUser();
return $this->getTableGateway()->select(function(Select $select) use($user) {
$select->where->equalTo('idsalesman', $user->getId());
$select->order('idcontract DESC');
$select->limit(10);
});
}
/**
* Localiza todos os contratos
* @return ResultSet
*/
public function fetchAllContracts()
{
$user = (new UserContainer())->getUser();
return $this->getTableGateway()->select(function(Select $select){
$select->where->equalTo('idsalesman', $user->getId());
});
}
}
O StrategyManager é o elemento responsável por ler o contexto da aplicação, e retornar qual a melhor estratégia para o contexto, de acordo com o que fora definido pelo programador.
class ContractStrategyManager extends AbstractStrategyManager
{
public function getStrategyForContext($context)
{
$user = $context;
switch($user->getType())
{
case UserType::Admin: return new AdminContractAccessStrategy();
case UserType::Sales: return new SalesContractAccessStrategy();
}
}
}
class ContractController extends AbstractActionController
{
public function indexAction()
{
$user = (new UserContainer())->getUser();
$manager = new ContractStrategyManager();
$strategy = $manager->getStrategyFor($manager);
}
}