Como era difícil para mim encontrar o caminho certo, abaixo você encontrava a melhor prática que fiz. Aproveite, corrija meu inglês, se necessário, e diga que estou errado, se estiver. :)
Edit: ... e eu descobri que estava errado em algum aspecto. Atualizei o post original depois que as respostas de Raphael me ajudaram a entender mais. Graças a ele !
Conceito usado abaixo :
Será mais fácil para você entender códigos e explicações abaixo se estiver familiarizado com estes conceitos:
- Dependência de injeção (como todas as
$this->variablevariáveis nos códigos são injetadas) - Contrato de Serviço e Repositório
- Fábrica
Contexto :
Apenas para ter mais contexto, imagine que temos um módulo construído corretamente com:
- uma classe de bloco CustomBlock contendo um método
getCustomModel($id), - esse método retorna um objeto CustomModel com base no ID passado em param,
- O tipo CustomModel corresponde ao modelo em
\Vendor\Module\Model\CustomModel - Este modelo vem com seu modelo de recursos (in
\Vendor\Module\Model\ResourceModel\CustomModel) - e com seu repositório (in
\Vendor\Module\Model\CustomModelRepository).
Pergunta :
- Qual é a melhor prática para permitir que tudo carregue um objeto CustomModel?
Você não pode usar o load()objeto de CustomModel, pois esse método está obsoleto.
A boa prática diz que você precisa usar o contrato de serviço CustomModel. Os contratos de serviço são interfaces de dados (por exemplo, CustomModelInterface) e interfaces de serviço (por exemplo, CustomModelRepositoryInterface). Então, meu bloco fica assim:
/ ** @var SlideRepositoryInterface * /
protegido $ slideRepository;
/ **
* Construtor CustomBlock
* ...
* @param CustomModelRepositoryInterface $ customModelRepository
* ...
* /
função pública __construct (
...
CustomModelRepositoryInterface $ customModelRepository
...
) {
$ this-> customModelRepository = $ customModelRepository;
}
função pública getCustomModel ($ id) {
retornar $ this-> customModelRepository-> get ($ id);
}
Primeiro, injetamos o CustomModelRepositoryInterfaceobjeto no construtor e o usamos em nosso getCustomModel()método.
Na classe Api\CustomModelRepositoryInterfacenão há muito. Geralmente (mas nada impedi-lo de fazer diferente), você irá declarar métodos básicos: get, getList, save, delete, deleteById. Para os fins deste tópico, abaixo está apenas a getdeclaração do método:
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
Ok, mas se minha interface CustomModel é chamada por injeção de dependência no meu construtor de blocos, onde está o código? Para responder a esta pergunta, você precisa explicar ao Magento onde encontra a classe que implementa essa interface. No arquivo etc / di.xml do módulo, você deve adicionar:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
Então CustomModelRepositoryInterfaceclasse é uma interface de serviço. Ao implementá-lo, você precisará implementar também interfaces de dados (pelo menos Vendor\Module\Api\Data\CustomModelInterfacee Vendor\Module\Api\Data\CustomModelSearchResultsInterface). Seu modelo precisará implementar Vendor\Module\Api\Data\CustomModelInterfacee adicionar <preference ... />linhas para cada uma de suas interfaces. Finalmente, sempre que você usar um contrato de serviço, mySomethingInterfacenão pense mais em mySomething: deixe o magento usar o di.xmlmecanismo de preferências.
Ok, o que vem a seguir? Quando injetamos CustomModelRepositoryInterfaceno construtor do bloco, obtemos um CustomModelRepositoryobjeto. CustomModelRepositorydeve implementar o método declare in CustomModelRepositoryInterface. Então, temos isso em Vendor\Module\Model\CustomModelRepository:
função pública get ($ id) {
$ customModel = $ this-> customModelFactory-> create ();
$ customModel-> load ($ id);
if (! $ customModel-> getId ()) {
lança nova NoSuchEntityException (__ ('CustomModel com o ID "% 1" não existe.', $ id));
}
return $ customModel;
}
O que estamos fazendo ? Criamos um CustomModelobjeto vazio graças à fábrica. Em seguida, carregamos dados no CustomModelmétodo usando o modelo de carregamento. Em seguida, retornamos a NoSuchEntityExceptionse não conseguimos carregar o CustomModelcom o id nos parâmetros. Mas se estiver tudo bem, retornamos o objeto modelo e a vida continua.
Mas uau ...! Neste exemplo, o que é isso?
$customModel->load($id);
Não é o mesmo loadmétodo obsoleto do que no começo? Sim, ele é. Acho uma pena, mas você deve usá-lo, pois neste método load () existem alguns eventos despachados e o desenvolvedor pode ouvi-los (consulte a resposta de Raphael abaixo).
No futuro, seremos salvos pelo Entity Manager. É outra história como um novo conceito Magento 2, mas se você quiser dar uma olhada, o Entity Manager já está implementado no Modelo de Recursos da Página CMS (v2.1):
public function load(AbstractModel $object, $value, $field = null)
{
$pageId = $this->getPageId($object, $value, $field);
if ($pageId) {
$this->entityManager->load($object, $pageId);
}
return $this;
}