4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ユーザが自分のアバター(画像アイコン)を登録できるモジュールの作成方法

Posted at

Magento Advent Calender 2017 の9日目の記事です。
ユーザが自分のアバター(画像アイコン)を登録できるモジュールを作成したいと思います。

スクリーンショット 2017-12-06 11.22.17.png
この記事から習得できる技術
  • テーブルへの属性追加
  • 画像の追加方法
全体的なイメージ
  1. カラムをcustomerテーブルに追加する
  2. 画像をバックエンドから追加、表示
  3. 画像をフロントエンドから追加、表示

カラムをcustomerテーブルに追加する

まず初めに、作成するモジュール名を決めてください。
今回は、Veriteworks_Avatarというモジュール名で作成したいと思います。

Veriteworks\Avatar\etc\module.xml

<sequence>タグでは、Magento_Catalogモジュールを読み込んでいます。
このAvatarモジュールが処理をする前に、読み込んでおきたいモジュールがあれば、<sequence>タグを使って読み込みましょう。

```xml:module.xml ```

Veriteworks\Avatar\registration.php

MODULEにはmodule.xmlで定義したモジュール名を入れてください。

```php:registration.php \Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Veriteworks_Avatar',
DIR
);

<h3>Veriteworks\Avatar\etc\frontend\routes.xml<br>
Veriteworks\Avatar\etc\adminhtml\routes.xml</h3>
<p>URLのルーティングに関する処理を行います。</p>
```xml:frontend/routes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="viewfile" frontName="viewfile">
            <module name="Veriteworks_Avatar" />
        </route>
    </router>
</config>
adminhtml/routes.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="adminhtml">
            <module name="Veriteworks_Avatar" before="Magento_Backend" />
        </route>
        <route id="avatar" frontName="avatar">
            <module name="Veriteworks_Avatar" />
        </route>
    </router>
</config>

Veriteworks\Avatar\etc\adminhtml\system.xml

ここで、設定ページで設定する項目を作成することができます。
今回は、アバターモジュールの画像を表示するかしないかのプルダウンを作成しています。

```xml:system.xml Veriteworks
veriteworks Avatar Veriteworks_Avatar::veriteworks_avatar General Enable Magento\Config\Model\Config\Source\Yesno enable avatar.
```

次に、customer_entityテーブルにアバター画像の情報を属性として追加したいと思います。

Veriteworks\Avatar\Setup\InstallData.php

attributesInfoで、その属性の型を設定することができます。
57-60行目で、管理画面の顧客グリッドでアバター画像を表示するための設定をしています。
75行目では、サイト上のどのページでこの属性を使用できるようにするかの設定をしています。

```php:InstallData.php use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Customer\Model\Customer;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
/**
  • @codeCoverageIgnore
    /
    class InstallData implements InstallDataInterface
    {
    /
    *

    • Customer setup factory
    • @var CustomerSetupFactory
      /
      private $customerSetupFactory;
      /
      *
    • @var AttributeSetFactory
      /
      private $attributeSetFactory;
      /
      *
    • Init
    • @param CustomerSetupFactory $customerSetupFactory
      */
      public function __construct(
      CustomerSetupFactory $customerSetupFactory,
      AttributeSetFactory $attributeSetFactory
      ) {
      $this->customerSetupFactory = $customerSetupFactory;
      $this->attributeSetFactory = $attributeSetFactory;
      }

    /**

    • @param ModuleDataSetupInterface $setup
    • @param ModuleContextInterface $context
      /
      public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
      {
      $setup->startSetup();
      /
      * @var CustomerSetup $customerSetup /
      $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
      $attributesInfo = [
      'vwp_avatar' => [
      'label' => 'Avatar',
      'type' => 'varchar',
      'input' => 'image',
      'position' => 1000,
      'visible' => true,
      'required' => false,
      'system' => 0,
      'user_defined' => true,
      'is_used_in_grid' => true,
      'is_visible_in_grid' => true,
      'is_html_allowed_on_front' => true,
      'visible_on_front' => true,
      ]
      ];
      $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
      $attributeSetId = $customerEntity->getDefaultAttributeSetId();
      /
      * @var $attributeSet AttributeSet */
      $attributeSet = $this->attributeSetFactory->create();
      $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
      foreach ($attributesInfo as $attributeCode => $attributeParams) {
      $customerSetup->addAttribute(Customer::ENTITY, $attributeCode, $attributeParams);
      }
      $magentoUsernameAttribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'vwp_avatar');
      $magentoUsernameAttribute->addData([
      'attribute_set_id' => $attributeSetId,
      'attribute_group_id' => $attributeGroupId,
      'used_in_forms' => ['customer_account_create', 'customer_account_edit', 'adminhtml_customer'],
      ]);
      $magentoUsernameAttribute->save();
      $setup->endSetup();
      }
      }

<h2>画像をバックエンドから追加、表示</h2>
<p>次に実際に画像をアップロードし、ちゃんとテーブルに保存されるか確認したいと思います。<br>
管理画面から顧客情報を確認してみてください。</p>
<img width="144" alt="スクリーンショット 2017-11-30 11.14.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/119742/671e9c48-35eb-2bfc-0b0a-915b4f86b2bb.png"><p>まずグリッドにアバターの列が表示されているのがわかります。
そして、アカウント情報編集では、アバター画像がアップロードできるようボタンが追加されていると思います。</p>
<img width="1130" alt="スクリーンショット 2017-11-30 11.11.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/119742/52fc2444-cc31-b420-8e47-a469dd55282d.png"><br>
<p>アバター画像を保存すると、画像パスだけがグリッドに表示されるため、画像を表示するよう変更します。</p>

<h3>Veriteworks\Avatar\view\adminhtml\ui_component\customer_listing.xml</h3>
```xml:customer_listing.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
        <column name="vwp_avatar" class="Veriteworks\Avatar\Ui\Component\Listing\Columns\Avatar">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/thumbnail</item>
                    <item name="sortable" xsi:type="boolean">false</item>
                    <item name="has_preview" xsi:type="string">1</item>
                    <item name="label" xsi:type="string" translate="true">Avatar</item>
                    <item name="sortOrder" xsi:type="number">1</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

Veriteworks\Avatar\Ui\Component\Listing\Columns\Avatar.php

```php:Avatar.php namespace Veriteworks\Avatar\Ui\Component\Listing\Columns;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;

/**

  • Class Avatar
  • @package Veriteworks\Avatar\Ui\Component\Listing\Columns
    /
    class Avatar extends \Magento\Ui\Component\Listing\Columns\Column
    {
    /
    *
    • @var \Magento\Framework\View\Element\AbstractBlock
      /
      protected $viewFileUrl;
      /
      *
    • @param ContextInterface $context
    • @param UiComponentFactory $uiComponentFactory
    • @param \Magento\Catalog\Helper\Image $imageHelper
    • @param \Magento\Framework\UrlInterface $urlBuilder
    • @param array $components
    • @param array $data
      /
      public function __construct(
      ContextInterface $context,
      UiComponentFactory $uiComponentFactory,
      \Magento\Framework\UrlInterface $urlBuilder,
      \Magento\Framework\View\Asset\Repository $viewFileUrl,
      array $components = [],
      array $data = []
      ) {
      parent::__construct($context, $uiComponentFactory, $components, $data);
      $this->urlBuilder = $urlBuilder;
      $this->viewFileUrl = $viewFileUrl;
      }
      /
      *
    • Prepare Data Source
    • @param array $dataSource
    • @return array
      */
      public function prepareDataSource(array $dataSource)
      {
      if (isset($dataSource['data']['items'])) {
      $fieldName = $this->getData('name');
      foreach ($dataSource['data']['items'] as & $item) {
      $customer = new \Magento\Framework\DataObject($item);
      $picture_url = !empty($customer["vwp_avatar"]) ? $this->urlBuilder->getUrl(
      'customer/index/viewfile/image/'.base64_encode($customer["vwp_avatar"])) : $this->viewFileUrl->getUrl('Veriteworks_Avatar::images/no-profile-img.png');
      $item[$fieldName . '_src'] = $picture_url;
      $item[$fieldName . '_orig_src'] = $picture_url;
      $item[$fieldName . '_alt'] = 'The profile picture';
      }
      }
      return $dataSource;
      }
      }
<p>画像がまだ保存されていない顧客のために、デフォルトのアバター画像を表示するよう設定をしています。<br>
画像は<br>
Veriteworks\Avatar\view\adminhtml\web\images<br>
Veriteworks\Avatar\view\frontend\web\images<br>
に追加しておきましょう。</p>
<img width="90" alt="スクリーンショット 2017-12-06 11.23.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/119742/00b9524a-2d80-0fc3-dc3f-1e92cc523790.png"><br>
<p>画像が表示、追加されているのがわかると思います。</p>

<h2>画像をフロントエンドから追加、表示</h2>
<p>次に画像をフロントエンドから追加し、表示したいと思います。</p>

<h3>Veriteworks\Avatar\view\frontend\layout\customer_account_edit.xml</h3>
<p>アカウント情報ページから画像を追加するので、このファイルを追加します。</p>
```xml: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>
    <referenceContainer name="form.additional.info">
        <block class="Veriteworks\Avatar\Block\Form\ChangeAvatar" name="vwp_avatar_form_edit" template="form/changeAvatar.phtml"/>
    </referenceContainer>
</body>
</page>

Veriteworks\Avatar\view\frontend\templates\changeAvatar.phtml

```php:changeAvatar.phtml
profile-picture
```

Veriteworks\Avatar\Controller\Avatar\View.php

```php:view.php namespace Veriteworks\Avatar\Controller\Avatar;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Customer\Api\CustomerMetadataInterface;
use Magento\Framework\Exception\NotFoundException;

/**

  • Class View

  • @package Veriteworks\Avatar\Controller\Avatar
    /
    class View extends \Magento\Framework\App\Action\Action
    {
    /
    *

    • @var \Magento\Framework\Controller\Result\RawFactory
      */
      protected $resultRawFactory;

    /**

    • @var \Magento\Framework\Url\DecoderInterface
      */
      protected $urlDecoder;

    /**

    • @var \Magento\Framework\App\Response\Http\FileFactory
      */
      protected $fileFactory;

    /**

    • @param \Magento\Framework\App\Action\Context $context
    • @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
    • @param \Magento\Framework\Url\DecoderInterface $urlDecoder
    • @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
      */
      public function __construct(
      \Magento\Framework\App\Action\Context $context,
      \Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
      \Magento\Framework\Url\DecoderInterface $urlDecoder,
      \Magento\Framework\App\Response\Http\FileFactory $fileFactory
      ) {
      $this->resultRawFactory = $resultRawFactory;
      $this->urlDecoder = $urlDecoder;
      $this->fileFactory = $fileFactory;
      return parent::__construct($context);
      }

    /**

    • View action

    • @return \Magento\Framework\View\Result\PageFactory

    • @SuppressWarnings(PHPMD.NPathComplexity)
      */
      public function execute()
      {
      $file = null;
      $plain = false;
      if ($this->getRequest()->getParam('file')) {
      // download file
      $file = $this->urlDecoder->decode(
      $this->getRequest()->getParam('file')
      );
      } elseif ($this->getRequest()->getParam('image')) {
      // show plain image
      $file = $this->urlDecoder->decode(
      $this->getRequest()->getParam('image')
      );
      $plain = true;
      } else {
      throw new NotFoundException(__('Page not found.'));
      }

      /** @var \Magento\Framework\Filesystem $filesystem */
      $filesystem = $this->_objectManager->get('Magento\Framework\Filesystem');
      $directory = $filesystem->getDirectoryRead(DirectoryList::MEDIA);
      $fileName = CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER . '/' . ltrim($file, '/');
      $path = $directory->getAbsolutePath($fileName);

      if (!$directory->isFile($fileName)
      && !$this->_objectManager->get('Magento\MediaStorage\Helper\File\Storage')->processStorageFile($path)
      ) {
      throw new NotFoundException(__('Page not found.'));
      }

      if ($plain) {
      $extension = pathinfo($path, PATHINFO_EXTENSION);
      switch (strtolower($extension)) {
      case 'gif':
      $contentType = 'image/gif';
      break;
      case 'jpg':
      $contentType = 'image/jpeg';
      break;
      case 'png':
      $contentType = 'image/png';
      break;
      default:
      $contentType = 'application/octet-stream';
      break;
      }
      $stat = $directory->stat($fileName);
      $contentLength = $stat['size'];
      $contentModify = $stat['mtime'];

       /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
       $resultRaw = $this->resultRawFactory->create();
       $resultRaw->setHttpResponseCode(200)
           ->setHeader('Pragma', 'public', true)
           ->setHeader('Content-type', $contentType, true)
           ->setHeader('Content-Length', $contentLength)
           ->setHeader('Last-Modified', date('r', $contentModify));
       $resultRaw->setContents($directory->readFile($fileName));
       return $resultRaw;
      

      } else {
      $name = pathinfo($path, PATHINFO_BASENAME);
      $this->fileFactory->create(
      $name,
      ['type' => 'filename', 'value' => $fileName],
      DirectoryList::MEDIA
      );
      }
      }
      }


<h3>Veriteworks\Avatar\Block\Form\ChangeAvatar.php</h3>
```php:changeAvatar.phtml
<?php
namespace Veriteworks\Avatar\Block\Form;

use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Customer\Api\CustomerMetadataInterface;

/**
 * Class ChangeAvatar
 * @package Veriteworks\Avatar\Block\Form
 */
class ChangeAvatar extends \Magento\Customer\Block\Form\Edit
{

    /**
     * @var \Magento\Newsletter\Model\Subscriber
     */
    protected $subscription;

    /**
     * @var \Magento\Customer\Model\Session
     */
    protected $customerSession;

    /**
     * @var \Magento\Newsletter\Model\SubscriberFactory
     */
    protected $subscriberFactory;

    /**
     * @var CustomerRepositoryInterface
     */
    protected $customerRepository;

    /**
     * @var AccountManagementInterface
     */
    protected $customerAccountManagement;


    /**
     * @return string
     */
    public function getImage()
    {
        $file = $this->customerSession->getCustomer()->getVwpAvatar();
        if(is_null($file)) return $this->_assetRepo->getUrl('Veriteworks_Avatar::images/no-profile-img.png');

        $directory = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA);
        $fileName = CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER . '/' . ltrim($file, '/');
        $imageUrl = $directory->getAbsolutePath($fileName);

        $currentStore = $this->_storeManager->getStore();
        $mediaUrl = $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
        $imagePath = $mediaUrl.$fileName;
        return $this->getUrl('viewfile/avatar/view/', ['image' => base64_encode($file)]);
    }
}

対応するテンプレートとブロックとコントローラを作成します。

スクリーンショット 2017-12-06 11.22.17.png

画像が表示、追加できるのがわかると思います。

まとめ

今回の記事では、ユーザが自分のアバター(画像アイコン)を登録できるモジュールの作成方法について説明しました。
この記事から、テーブルへの属性追加と画像の追加方法が習得できます。

これを応用することで、例えばレビューやログイン画面などでユーザ名の横にアバターアイコンを表示することができます。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?