How not to use ObjectManager in phtml from template
-
28-03-2021 - |
Pergunta
First a bit of context, and at the end, my question
I added an EAV attribute to my customer. It's an attribute with multiple values, and I want to add it to the account information (for reasons).
I've made a module, added a source for my select element, observer, etc...
It's working ok.
Let's say it's in
app/code/MyCompany/MyEAVAttributeModule
I've got a custom theme, made by another team, in
app/design/frontend/ThemeTeam/ThemeInUse
To add my attribute to the register and edit form, I've added on the custom theme
app/design/frontend/ThemeTeam/ThemeInUse/Magento_Customer/templates/form/register.phtml
and
app/design/frontend/ThemeTeam/ThemeInUse/Magento_Customer/templates/form/edit.phtml
which are copies from
/vendor/magento/module-customer/view/frontend/templates/form/register.phtml
and edit.phtml
And to get all my values to add a select element, I've added in the phtml
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$my_attributes = $objectManager->create('Magento\Eav\Model\Config')->getAttribute('customer', 'my_attribute');
if ($my_attributes->getSource()) {
$my_attribute_list = $my_attributes->getSource()->getAllOptions();
}
and then a <select>
and a foreach
It works, my attribute is shown, the value is saved.
Now, for my question :-)
To get all the values, I get an instance of ObjectManager
at the begining of my phtml
I know it's wrong to do that, but I couldn't find another way.
So how to do it ?
I know I should make a function and use a Helper (which I read is not recommended) or perhaps use it in the Block ?
But where ? In the theme ? In my module ? Somewhere else ?
Thanks if you can guide me on this one !
Solução
You should create a view model and inject it via DI. You can access the view model instance from within the template.
customer_account_edit.xml:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="customer_edit">
<arguments>
<argument name="view_model" xsi:type="object">Vendor\Package\ViewModel\YourEavAttribute</argument>
</arguments>
</referenceBlock>
</body>
</page>
EavAttribute.php:
<?php
/**
* YourEavAttribute.php
*/
declare(strict_types=1);
namespace Vendor\Package\ViewModel;
use Magento\Eav\Model\Config;
use Magento\Framework\View\Element\Block\ArgumentInterface;
class YourEavAttribute implements ArgumentInterface
{
/** @property Config $config */
protected $config;
/**
* @param Config $config
* @return void
*/
public function __construct(
Config $config
) {
$this->config = $config;
}
/**
* @return Config
*/
public function getConfig(): Config
{
return $this->config;
}
}
From inside your template:
$viewModel = $block->getViewModel();
$config = $viewModel->getConfig();