├── Block
└── Attributes
│ └── Avatar.php
├── Controller
└── Avatar
│ └── View.php
├── Model
├── Attribute
│ └── Backend
│ │ └── Avatar.php
└── Source
│ └── Validation
│ └── Image.php
├── Plugin
├── CustomerData
│ └── Customer.php
└── Metadata
│ └── Form
│ └── Image.php
├── README.md
├── Setup
├── InstallData.php
└── Uninstall.php
├── Snapshot
├── avatar-in-customer-grid.png
├── customer-review.png
├── header-avatar.png
├── image-is-invalid.png
├── upload-delete-an-avatar.png
├── upload-new-avatar.png
└── validate-by-js.png
├── Ui
└── Component
│ └── Listing
│ └── Columns
│ └── Avatar.php
├── composer.json
├── etc
├── di.xml
├── frontend
│ ├── routes.xml
│ └── sections.xml
└── module.xml
├── registration.php
└── view
├── adminhtml
├── ui_component
│ └── customer_listing.xml
└── web
│ └── images
│ └── no-profile-photo.jpg
└── frontend
├── layout
├── customer_account_edit.xml
├── default.xml
└── review_product_listajax.xml
├── templates
├── account
│ └── customer.phtml
├── form
│ └── edit.phtml
└── review
│ └── product
│ └── view
│ └── list.phtml
└── web
├── css
├── avatar.css
├── global-avatar.css
└── review-item.css
├── images
└── no-profile-photo.jpg
└── js
└── avatar-validation.js
/Block/Attributes/Avatar.php:
--------------------------------------------------------------------------------
1 | objectManager = $objectManager;
49 | $this->viewFileUrl = $viewFileUrl;
50 | $this->customer = $customer;
51 | parent::__construct($context);
52 | }
53 |
54 | /**
55 | * Check the file is already exist in the path.
56 | * @return boolean
57 | */
58 | public function checkImageFile($file)
59 | {
60 | $file = base64_decode($file);
61 | $filesystem = $this->objectManager->get('Magento\Framework\Filesystem');
62 | $directory = $filesystem->getDirectoryRead(DirectoryList::MEDIA);
63 | $fileName = CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER . '/' . ltrim($file, '/');
64 | $path = $directory->getAbsolutePath($fileName);
65 | if (!$directory->isFile($fileName)
66 | && !$this->objectManager->get('Magento\MediaStorage\Helper\File\Storage')->processStorageFile($path)
67 | ) {
68 | return false;
69 | }
70 | return true;
71 | }
72 |
73 | /**
74 | * Get the avatar of the customer is already logged in
75 | * @return string
76 | */
77 | public function getAvatarCurrentCustomer($file)
78 | {
79 | if ($this->checkImageFile(base64_encode($file)) === true) {
80 | return $this->getUrl('viewfile/avatar/view/', ['image' => base64_encode($file)]);
81 | }
82 | return $this->viewFileUrl->getUrl('PHPCuong_CustomerProfilePicture::images/no-profile-photo.jpg');
83 | }
84 |
85 | /**
86 | * Get the avatar of the customer by the customer id
87 | * @return string
88 | */
89 | public function getCustomerAvatarById($customer_id = false)
90 | {
91 | if ($customer_id) {
92 | $customerDetail = $this->customer->load($customer_id);
93 | if ($customerDetail && !empty($customerDetail->getProfilePicture())) {
94 | if ($this->checkImageFile(base64_encode($customerDetail->getProfilePicture())) === true) {
95 | return $this->getUrl('viewfile/avatar/view/', ['image' => base64_encode($customerDetail->getProfilePicture())]);
96 | }
97 | }
98 | }
99 | return $this->viewFileUrl->getUrl('PHPCuong_CustomerProfilePicture::images/no-profile-photo.jpg');
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/Controller/Avatar/View.php:
--------------------------------------------------------------------------------
1 | resultRawFactory = $resultRawFactory;
47 | $this->urlDecoder = $urlDecoder;
48 | $this->fileFactory = $fileFactory;
49 | return parent::__construct($context);
50 | }
51 |
52 | /**
53 | * View action
54 | *
55 | * @return \Magento\Framework\View\Result\PageFactory
56 | * @SuppressWarnings(PHPMD.NPathComplexity)
57 | */
58 | public function execute()
59 | {
60 | $file = null;
61 | $plain = false;
62 | if ($this->getRequest()->getParam('file')) {
63 | // download file
64 | $file = $this->urlDecoder->decode(
65 | $this->getRequest()->getParam('file')
66 | );
67 | } elseif ($this->getRequest()->getParam('image')) {
68 | // show plain image
69 | $file = $this->urlDecoder->decode(
70 | $this->getRequest()->getParam('image')
71 | );
72 | $plain = true;
73 | } else {
74 | throw new NotFoundException(__('Page not found.'));
75 | }
76 |
77 | /** @var \Magento\Framework\Filesystem $filesystem */
78 | $filesystem = $this->_objectManager->get('Magento\Framework\Filesystem');
79 | $directory = $filesystem->getDirectoryRead(DirectoryList::MEDIA);
80 | $fileName = CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER . '/' . ltrim($file, '/');
81 | $path = $directory->getAbsolutePath($fileName);
82 |
83 | if (!$directory->isFile($fileName)
84 | && !$this->_objectManager->get('Magento\MediaStorage\Helper\File\Storage')->processStorageFile($path)
85 | ) {
86 | throw new NotFoundException(__('Page not found.'));
87 | }
88 |
89 | if ($plain) {
90 | $extension = pathinfo($path, PATHINFO_EXTENSION);
91 | switch (strtolower($extension)) {
92 | case 'gif':
93 | $contentType = 'image/gif';
94 | break;
95 | case 'jpg':
96 | $contentType = 'image/jpeg';
97 | break;
98 | case 'png':
99 | $contentType = 'image/png';
100 | break;
101 | default:
102 | $contentType = 'application/octet-stream';
103 | break;
104 | }
105 | $stat = $directory->stat($fileName);
106 | $contentLength = $stat['size'];
107 | $contentModify = $stat['mtime'];
108 |
109 | /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
110 | $resultRaw = $this->resultRawFactory->create();
111 | $resultRaw->setHttpResponseCode(200)
112 | ->setHeader('Pragma', 'public', true)
113 | ->setHeader('Content-type', $contentType, true)
114 | ->setHeader('Content-Length', $contentLength)
115 | ->setHeader('Last-Modified', date('r', $contentModify));
116 | $resultRaw->setContents($directory->readFile($fileName));
117 | return $resultRaw;
118 | } else {
119 | $name = pathinfo($path, PATHINFO_BASENAME);
120 | $this->fileFactory->create(
121 | $name,
122 | ['type' => 'filename', 'value' => $fileName],
123 | DirectoryList::MEDIA
124 | );
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/Model/Attribute/Backend/Avatar.php:
--------------------------------------------------------------------------------
1 | getAttribute()->getAttributeCode();
26 | if ($attrCode == 'profile_picture') {
27 | if ($validation->isImageValid('tmpp_name', $attrCode) === false) {
28 | throw new \Magento\Framework\Exception\LocalizedException(
29 | __('The profile picture is not a valid image.')
30 | );
31 | }
32 | }
33 |
34 | return parent::beforeSave($object);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Model/Source/Validation/Image.php:
--------------------------------------------------------------------------------
1 | currentCustomer = $currentCustomer;
46 | $this->customerViewHelper = $customerViewHelper;
47 | $this->customerAvatar = $customerAvatar;
48 | }
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function afterGetSectionData()
54 | {
55 | if (!$this->currentCustomer->getCustomerId()) {
56 | return [];
57 | }
58 | $customer = $this->currentCustomer->getCustomer();
59 | if (!empty($customer->getCustomAttribute('profile_picture'))) {
60 | $file = $customer->getCustomAttribute('profile_picture')->getValue();
61 | } else {
62 | $file = '';
63 | }
64 | return [
65 | 'fullname' => $this->customerViewHelper->getCustomerName($customer),
66 | 'firstname' => $customer->getFirstname(),
67 | 'avatar' => $this->customerAvatar->getAvatarCurrentCustomer($file)
68 | ];
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Plugin/Metadata/Form/Image.php:
--------------------------------------------------------------------------------
1 | validImage = $validImage;
21 | }
22 |
23 | /**
24 | * {@inheritdoc}
25 | *
26 | * @return ImageContentInterface|array|string|null
27 | */
28 | public function beforeExtractValue(\Magento\Customer\Model\Metadata\Form\Image $subject, $value)
29 | {
30 | $attrCode = $subject->getAttribute()->getAttributeCode();
31 |
32 | if ($this->validImage->isImageValid('tmp_name', $attrCode) === false) {
33 | $_FILES[$attrCode]['tmpp_name'] = $_FILES[$attrCode]['tmp_name'];
34 | unset($_FILES[$attrCode]['tmp_name']);
35 | }
36 |
37 | return [];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # You can get the professional version of this extension here (No issues and is supported free)
2 | https://www.giaphugroup.com/magento-2-customer-avatar-extension.html
3 |
4 | # How to add the profile picture for a customer in Magento 2
5 | This is an awesome module, it allows the customers the opportunity to personalize their account by uploading an avatar.
6 |
7 | Please donate if you enjoy my extension.
8 |
9 | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CR756BABGNDC4)
10 |
11 | ## See the video How this extension can work here
12 | https://www.youtube.com/watch?v=3Tt82EvXLLA&list=PL98CDCbI3TNvPczWSOnpaMoyxVISLVzYQ&index=96
13 |
14 | ## The features of this extension:
15 | ### Frontend:
16 | - The customer can upload a new avatar.
17 | - The avatar can be displayed in the header of the website.
18 | - The avatar can be displayed in the reviews list.
19 |
20 | ### Backend:
21 | - Display the avatar of the customer in the customer's grid of Magento Admin.
22 | - Upload a new avatar or delete an avatar of the customer.
23 |
24 | ## Introduction installation:
25 |
26 | ### 1 - Using Composer
27 |
28 | ```
29 | composer require php-cuong/magento2-customer-avatar:dev-master
30 |
31 | ```
32 |
33 | ### 2- Enable the Customer Avatar extension
34 | * php bin/magento setup:upgrade
35 | * php bin/magento setup:static-content:deploy
36 | * php bin/magento indexer:reindex
37 | * php bin/magento cache:flush
38 |
39 | ### 3 - See results
40 | #### Frontend
41 | Log into your customer account, go to Edit Account Information
42 |
43 | ##### The avatar in the header
44 |
45 | 
46 |
47 | ##### The avatar in the edit account information
48 |
49 | 
50 |
51 | ##### The avatar in the reviews list
52 |
53 | 
54 |
55 | #### Backend
56 | Log into your Magento admin, go to Customers -> All Customers
57 |
58 | ##### The avatar in the customer's grid of Magento Admin
59 |
60 | 
61 |
62 | ##### Upload a new avatar or delete an avatar of the customer
63 |
64 | 
65 |
66 | ## Donations
67 | Please donate if you enjoy my extension.
68 |
69 | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CR756BABGNDC4)
70 |
71 |
72 |
--------------------------------------------------------------------------------
/Setup/InstallData.php:
--------------------------------------------------------------------------------
1 | customerSetupFactory = $customerSetupFactory;
46 | $this->attributeSetFactory = $attributeSetFactory;
47 | }
48 |
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
54 | {
55 |
56 | /** @var CustomerSetup $customerSetup */
57 | $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
58 |
59 | $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
60 | $attributeSetId = $customerEntity->getDefaultAttributeSetId();
61 |
62 | /** @var $attributeSet AttributeSet */
63 | $attributeSet = $this->attributeSetFactory->create();
64 | $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
65 |
66 | $customerSetup->addAttribute(Customer::ENTITY, 'profile_picture', [
67 | 'type' => 'varchar',
68 | 'label' => 'Profile Picture',
69 | 'input' => 'image',
70 | 'backend' => 'PHPCuong\CustomerProfilePicture\Model\Attribute\Backend\Avatar',
71 | 'required' => false,
72 | 'visible' => true,
73 | 'user_defined' => true,
74 | 'sort_order' => 10,
75 | 'position' => 10,
76 | 'system' => 0,
77 | 'is_used_in_grid' => true,
78 | 'is_visible_in_grid' => true,
79 | 'is_html_allowed_on_front' => true,
80 | 'visible_on_front' => true
81 | ]);
82 |
83 | $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'profile_picture')
84 | ->addData([
85 | 'attribute_set_id' => $attributeSetId,
86 | 'attribute_group_id' => $attributeGroupId,
87 | 'used_in_forms' => ['adminhtml_customer', 'customer_account_edit'],
88 | ]);
89 |
90 | $attribute->save();
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Setup/Uninstall.php:
--------------------------------------------------------------------------------
1 | eavSetupFactory = $eavSetupFactory;
32 | }
33 |
34 | /**
35 | * {@inheritdoc}
36 | * @SuppressWarnings(PHPMD.CyclomaticComplexity)
37 | * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
38 | * @SuppressWarnings(PHPMD.NPathComplexity)
39 | */
40 | public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
41 | {
42 | $setup->startSetup();
43 | $eavSetup = $this->eavSetupFactory->create();
44 | $eavSetup->removeAttribute(
45 | \Magento\Customer\Model\Customer::ENTITY,
46 | 'profile_picture'
47 | );
48 | $setup->endSetup();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Snapshot/avatar-in-customer-grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-cuong/magento2-customer-avatar/3f467418f9206efc00690e95c19ab4a3d37f3320/Snapshot/avatar-in-customer-grid.png
--------------------------------------------------------------------------------
/Snapshot/customer-review.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-cuong/magento2-customer-avatar/3f467418f9206efc00690e95c19ab4a3d37f3320/Snapshot/customer-review.png
--------------------------------------------------------------------------------
/Snapshot/header-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-cuong/magento2-customer-avatar/3f467418f9206efc00690e95c19ab4a3d37f3320/Snapshot/header-avatar.png
--------------------------------------------------------------------------------
/Snapshot/image-is-invalid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-cuong/magento2-customer-avatar/3f467418f9206efc00690e95c19ab4a3d37f3320/Snapshot/image-is-invalid.png
--------------------------------------------------------------------------------
/Snapshot/upload-delete-an-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-cuong/magento2-customer-avatar/3f467418f9206efc00690e95c19ab4a3d37f3320/Snapshot/upload-delete-an-avatar.png
--------------------------------------------------------------------------------
/Snapshot/upload-new-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-cuong/magento2-customer-avatar/3f467418f9206efc00690e95c19ab4a3d37f3320/Snapshot/upload-new-avatar.png
--------------------------------------------------------------------------------
/Snapshot/validate-by-js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php-cuong/magento2-customer-avatar/3f467418f9206efc00690e95c19ab4a3d37f3320/Snapshot/validate-by-js.png
--------------------------------------------------------------------------------
/Ui/Component/Listing/Columns/Avatar.php:
--------------------------------------------------------------------------------
1 | urlBuilder = $urlBuilder;
41 | $this->viewFileUrl = $viewFileUrl;
42 | }
43 |
44 | /**
45 | * Prepare Data Source
46 | *
47 | * @param array $dataSource
48 | * @return array
49 | */
50 | public function prepareDataSource(array $dataSource)
51 | {
52 | if (isset($dataSource['data']['items'])) {
53 | $fieldName = $this->getData('name');
54 | foreach ($dataSource['data']['items'] as & $item) {
55 | $customer = new \Magento\Framework\DataObject($item);
56 | $picture_url = !empty($customer["profile_picture"]) ? $this->urlBuilder->getUrl(
57 | 'customer/index/viewfile/image/'.base64_encode($customer["profile_picture"])) : $this->viewFileUrl->getUrl('PHPCuong_CustomerProfilePicture::images/no-profile-photo.jpg');
58 | $item[$fieldName . '_src'] = $picture_url;
59 | $item[$fieldName . '_orig_src'] = $picture_url;
60 | $item[$fieldName . '_alt'] = 'The profile picture';
61 | }
62 | }
63 |
64 | return $dataSource;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "php-cuong/magento2-customer-avatar",
3 | "description":"Magento 2 Customer Avatar",
4 | "keywords": [
5 | "magento 2",
6 | "Avatar",
7 | "Profile picture",
8 | "Customer Avatar",
9 | "Customer Profile Picture",
10 | "Magento 2 Customer Avatar",
11 | "Magento 2 Customer Profile Picture"
12 | ],
13 | "require": {
14 | "php": "~5.6.0|7.0.2|~7.0.6",
15 | "magento/module-backend": "100.0.*|100.1.*",
16 | "magento/framework": "100.0.*|100.1.*"
17 | },
18 | "type": "magento2-module",
19 | "version": "2.1.0",
20 | "license": [
21 | "OSL-3.0",
22 | "AFL-3.0"
23 | ],
24 | "authors": [
25 | {
26 | "name": "Cuong NQ",
27 | "email": "bestearnmoney87@gmail.com",
28 | "role": "Developer"
29 | }
30 | ],
31 | "autoload": {
32 | "files": [
33 | "registration.php"
34 | ],
35 | "psr-4": {
36 | "PHPCuong\\CustomerProfilePicture\\": ""
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
59 | 60 | 61 |
62 |