This article shows how you can upload file or image in the customer registration and in the customer account page in Magento 2.
For this, first, we need to add a new customer attribute. In this example, we will be adding a new image attribute for the customer so that we can upload the customer image.
I have written an article before about creating customer attribute. Here’s the link: Magento 2: Create Customer Attribute Programmatically [Also Update & Delete Customer Attribute]
Here, we will create a new customer attribute from our module’s install script. We assume our module’s name to be Chapagain_CustomerAttribute.
Add/Create Customer Attribute Using the Install Script
Here, we create a customer attribute with the attribute code my_customer_image
.
File: app/code/Chapagain/CustomerAttribute/Setup/InstallData.php
<?php
namespace Chapagain\CustomerAttribute\Setup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
class InstallData implements InstallDataInterface
{
/**
* EAV setup factory
*
* @var \Magento\Eav\Setup\EavSetupFactory
*/
private $eavSetupFactory;
/**
* Customer setup factory
*
* @var CustomerSetupFactory
*/
private $customerSetupFactory;
/**
* Constructor
*
* @param EavSetupFactory $eavSetupFactory
* @param CustomerSetupFactory $customerSetupFactory
*/
public function __construct(
EavSetupFactory $eavSetupFactory,
CustomerSetupFactory $customerSetupFactory
)
{
$this->eavSetupFactory = $eavSetupFactory;
$this->customerSetupFactory = $customerSetupFactory;
}
/**
* {@inheritdoc}
*/
public function install(
ModuleDataSetupInterface $setup,
ModuleContextInterface $context
) {
$setup->startSetup();
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
$customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
/**
* Create a file type attribute
* For File or Image Upload
*/
$attributeCode = 'my_customer_image';
$customerSetup->addAttribute(
\Magento\Customer\Model\Customer::ENTITY,
$attributeCode,
[
'type' => 'text',
'label' => 'My Customer File/Image',
'input' => 'file',
'source' => '',
'required' => false,
'visible' => true,
'position' => 200,
'system' => false,
'backend' => ''
]
);
// show the attribute in the following forms
$attribute = $customerSetup
->getEavConfig()
->getAttribute(
\Magento\Customer\Model\Customer::ENTITY,
$attributeCode
)
->addData(
['used_in_forms' => [
'adminhtml_customer',
'adminhtml_checkout',
'customer_account_create',
'customer_account_edit'
]
]);
$attribute->save();
$setup->endSetup();
}
}
Add Image Upload Field in Customer Registration Page
For this, you need to create a new XML layout file and a new template file.
We define the block class and template file in the newly created XML file.
Here’s the XML file code:
File: app/code/Chapagain/CustomerAttribute/view/frontend/layout/customer_account_create.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="form.additional.info">
<block class="Magento\Framework\View\Element\Template" name="additional_field_register" template="Chapagain_CustomerAttribute::customer/form/additionalfieldregister.phtml"/>
</referenceContainer>
</body>
</page>
Here’s the template file code where we add the image input field code:
File: app/code/Chapagain/CustomerAttribute/view/frontend/template/customer/form/additionalfieldregister.phtml
<fieldset class="fieldset create account" data-hasrequired="<?php /* @escapeNotVerified */
echo __('* Required Fields') ?>">
<legend class="legend">
<span>
<?php
/* @escapeNotVerified */
echo __('Additional Information')
?>
</span>
</legend>
<div class="field my_customer_image ">
<label for="my_customer_image" class="label"><span><?php /* @escapeNotVerified */
echo __('Logo Image') ?></span></label>
<div class="control">
<input type="file" name="my_customer_image" id="my_customer_image" title="<?php /* @escapeNotVerified */
echo __('Logo Image') ?>" class="input-text" data-validate="{required:false}">
</div>
</div>
</fieldset>
Note: The image/file uploaded using the above file field will be stored inside the pub/media/customer folder.
Add Image Upload Field in Customer Account Page
Here’s the XML file code:
File: app/code/Chapagain/CustomerAttribute/view/frontend/layout/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">
<update handle="customer_account"/>
<body>
<referenceContainer name="form.additional.info">
<block class="Chapagain\CustomerAttribute\Block\Customer\Account" name="additional_field_account" template="Chapagain_CustomerAttribute::customer/form/additionalfieldaccount.phtml"/>
</referenceContainer>
</body>
</page>
As you can see in the above XML code, we also have defined a Block class. So, we need to create one:
File: app/code/Chapagain/CustomerAttribute/Block/Customer/Account.php
<?php
namespace Chapagain\CustomerAttribute\Block\Customer;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\UrlInterface;
use Magento\Customer\Model\SessionFactory;
class Account extends \Magento\Framework\View\Element\Template
{
/**
* @var \Magento\Framework\UrlInterface
*/
protected $urlBuilder;
/**
* @var \Magento\Customer\Model\Session
*/
protected $customerSession;
/**
* @var \Magento\Store\Model\StoreManagerInterface $storeManager
*/
protected $storeManager;
/**
* @var \Magento\Customer\Model\Customer
*/
protected $customerModel;
public function __construct(
Context $context,
UrlInterface $urlBuilder,
SessionFactory $customerSession,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Customer\Model\Customer $customerModel,
array $data = []
)
{
$this->urlBuilder = $urlBuilder;
$this->customerSession = $customerSession->create();
$this->storeManager = $storeManager;
$this->customerModel = $customerModel;
parent::__construct($context, $data);
$collection = $this->getContracts();
$this->setCollection($collection);
}
public function getBaseUrl()
{
return $this->storeManager->getStore()->getBaseUrl();
}
public function getMediaUrl()
{
return $this->getBaseUrl() . 'pub/media/';
}
public function getCustomerLogoUrl($logoPath)
{
return $this->getMediaUrl() . 'customer' . $logoPath;
}
public function getLogoUrl()
{
$customerData = $this->customerModel->load($this->customerSession->getId());
$logo = $customerData->getData('my_customer_image');
if (!empty($logo)) {
return $this->helper->getCustomerLogoUrl($logo);
}
return false;
}
}
?>
Here’s the template file code where we add the image input field code:
File: app/code/Chapagain/CustomerAttribute/view/frontend/template/customer/form/additionalfieldaccount.phtml
<fieldset class="fieldset create account" data-hasrequired="<?php /* @escapeNotVerified */
echo __('* Required Fields') ?>">
<legend class="legend">
<span>
<?php
/* @escapeNotVerified */
echo __('Logo')
?>
</span>
</legend>
<?php if ($logo = $block->getLogoUrl()): ?>
<img src="<?php echo $logo ?>" alt="logo" />
<?php endif; ?>
<div class="field my_customer_image ">
<label for="my_customer_image" class="label"><span><?php /* @escapeNotVerified */
echo __('Logo Image') ?></span></label>
<div class="control">
<input type="file" name="my_customer_image" id="my_customer_image" title="<?php /* @escapeNotVerified */
echo __('Logo Image') ?>" class="input-text" data-validate="{required:false}">
</div>
</div>
</fieldset>
Hope this helps. Thanks.