Magento 2 เพิ่มฟิลด์ใหม่ให้กับฟอร์มผู้ดูแลระบบ Magento_User


11

ฉันกำลังมองหาวิธีการที่ดีด้วยการเพิ่ม / อัปเดตที่เตรียมไว้แล้ว (โดยค่าเริ่มต้น) แบบฟอร์มของผู้ใช้ Magento (โมดูลผู้ใช้) แบบฟอร์มสามารถเข้าถึงได้ในแผงควบคุมโดยเส้นทางนี้:

ระบบ> ผู้ใช้ทั้งหมด> [selected_user]> แท็บแก้ไขหลักของผู้ใช้ (ข้อมูลบัญชี)

ตอนนี้ฉันกำลังลองใช้ di.xml ในโมดูลที่กำหนดเองที่ฉันระบุการพึ่งพา: `

<preference for="Magento\User\Block\User\Edit\Tab\Main" type="Vendor_Name\Module_Name\Block\User\Edit\Tab\Main" />
<preference for="Magento\User\Block\Role\Grid\User" type="Vendor_Name\Module_Name\Block\Role\Grid\User" />

`

นี่คือเนื้อหาที่ฉันสร้างขึ้นสำหรับคลาส Main.php

// @codingStandardsIgnoreFile

เนมสเปซ Vendor_Name \ Module_Name \ Block \ User \ Edit \ Tab;

ใช้ \ Magento \ User \ Block \ User \ Edit \ Tab \ Main เป็น UserEditMainTab;
ใช้ \ Magento \ Backend \ Block \ Template \ Context;
ใช้ \ Magento \ Framework \ Registry;
ใช้ \ Magento \ Framework \ Data \ FormFactory;
ใช้ \ Magento \ Backend \ Model \ Auth \ Session;
ใช้ \ Magento \ Framework \ Locale \ ListsInterface;

คลาส Main ขยาย UserEditMainTab
{
    ฟังก์ชั่นสาธารณะ __ โครงสร้าง (
        บริบท $ บริบท
        การลงทะเบียน $ Registry
        FormFactory $ formFactory
        เซสชัน $ authSession
        ListsInterface $ locale รายการ,
        อาร์เรย์ $ data = []
    ) {
        parent :: __ สร้าง ($ context, $ registry, $ formFactory, $ authSession, $ localeLists, $ data);
    }

    ฟังก์ชันที่มีการป้องกัน _prepareForm ()
    {
        / ** @var $ model \ Magento \ User \ Model \ User * /
        $ model = $ this -> _ coreRegistry-> การลงทะเบียน ('Permissions_user');

        / ** @var \ Magento \ Framework \ Data \ Form $ form * /
        $ form = $ this -> _ formFactory-> create ();
        $ form-> setHtmlIdPrefix ( 'USER_');

        $ baseFieldset = $ form-> addFieldset ('base_fieldset', ['legend' => __ ('ข้อมูลบัญชี __ ทดสอบ')]);

        if ($ model-> getUserId ()) {
            $ baseFieldset-> addField ('user_id', 'ซ่อน', ['name' => 'user_id']);
        } อื่น {
            if (! $ model-> hasData ('is_active')) {
                $ model-> setIsActive (1);
            }
        }

        $ baseFieldset-> addField (
            'user_image'
            'ภาพ',
            [
                'name' => 'user_image'
                'label' => __ ('ภาพผู้ใช้'),
                'id' => 'user_image'
                'title' => __ ('ภาพผู้ใช้'),
                'ต้องใช้' => false
                'note' => 'อนุญาตประเภทภาพ: jpg, jpeg, png'
            ]
        );

        $ baseFieldset-> addField (
            'ชื่อผู้ใช้'
            'ข้อความ'
            [
                'name' => 'ชื่อผู้ใช้',
                'label' => __ ('ชื่อผู้ใช้'),
                'id' => 'ชื่อผู้ใช้',
                'title' => __ ('ชื่อผู้ใช้'),
                'ต้องใช้' => จริง
            ]
        );

        $ baseFieldset-> addField (
            'ชื่อจริง',
            'ข้อความ'
            [
                'name' => 'ชื่อแรก'
                'label' => __ ('ชื่อจริง')
                'id' => 'ชื่อแรก'
                'title' => __ ('ชื่อจริง')
                'ต้องใช้' => จริง
            ]
        );

        $ baseFieldset-> addField (
            'นามสกุล',
            'ข้อความ'
            [
                'name' => 'นามสกุล'
                'label' => __ ('นามสกุล'),
                'id' => 'นามสกุล'
                'title' => __ ('นามสกุล'),
                'ต้องใช้' => จริง
            ]
        );

        $ baseFieldset-> addField (
            'อีเมล'
            'ข้อความ'
            [
                'name' => 'อีเมล'
                'label' => __ ('อีเมล')
                'id' => 'customer_email'
                'title' => __ ('อีเมลผู้ใช้'),
                'class' => 'required-entry validate-email',
                'ต้องใช้' => จริง
            ]
        );

        $ isNewObject = $ model-> isObjectNew ();
        ถ้า ($ isNewObject) {
            $ passwordLabel = __ ('รหัสผ่าน');
        } อื่น {
            $ passwordLabel = __ ('รหัสผ่านใหม่');
        }
        $ confirmLabel = __ ('ยืนยันรหัสผ่าน');
        $ this -> _ addPasswordFields ($ baseFieldset, $ passwordLabel, $ confirmLabel, $ isNewObject);

        $ baseFieldset-> addField (
            'interface_locale'
            'เลือก',
            [
                'name' => 'interface_locale',
                'label' => __ ('สถานที่ตั้งของส่วนต่อประสาน'),
                'title' => __ ('สถานที่ตั้งของส่วนต่อประสาน'),
                'values' => $ this -> _ LocaleLists-> getTranslatedOptionLocales ()
                'class' => 'เลือก'
            ]
        );

        if ($ this -> _ authSession-> getUser () -> getId ()! = $ model-> getUserId ()) {
            $ baseFieldset-> addField (
                'is_active'
                'เลือก',
                [
                    'name' => 'is_active',
                    'label' => __ ('บัญชีนี้คือ'),
                    'id' => 'is_active',
                    'title' => __ ('สถานะบัญชี'),
                    'class' => 'input-select',
                    'options' => ['1' => __ ('ใช้งานอยู่'), '0' => __ ('ไม่ใช้งาน')]
                ]
            );
        }

        $ baseFieldset-> addField ('user_roles', 'ซ่อน', ['name' => 'user_roles', 'id' => '_user_roles']);

        $ currentUserVerificationFieldset = $ form-> addFieldset (
            'current_user_verification_fieldset'
            ['legend' => __ ('การยืนยันตัวตนผู้ใช้ปัจจุบัน')]
        );
        $ currentUserVerificationFieldset-> addField (
            ตนเอง :: CURRENT_USER_PASSWORD_FIELD,
            'รหัสผ่าน'
            [
                'name' => ตนเอง :: CURRENT_USER_PASSWORD_FIELD
                'label' => __ ('รหัสผ่านของคุณ')
                'id' => ตนเอง :: CURRENT_USER_PASSWORD_FIELD
                'title' => __ ('รหัสผ่านของคุณ')
                'class' => 'ต้องป้อนข้อมูลตรวจสอบความถูกต้องของรหัสผ่านปัจจุบัน,'
                'ต้องใช้' => จริง
            ]
        );

        $ data = $ model-> getData ();
        ไม่มีการตั้งค่า ($ data [ 'รหัสผ่าน']);
        ไม่มีการตั้งค่า ($ ข้อมูล [ตนเอง :: CURRENT_USER_PASSWORD_FIELD]);
        $ form-> setValues ​​($ data);

        $ this-> setForm ($ รูปแบบ);

        ผู้ปกครองกลับ :: _ PreparForm ();
    }
}

และบางรหัสสำหรับ User.php

เนมสเปซ Vendor_Name \ Module_Name \ Block \ Role \ Grid;

ใช้ \ Magento \ User \ Block \ Role \ Grid \ User เป็น RoleGridUser;
ใช้ \ Magento \ Backend \ Block \ Widget \ Grid \ Extended เป็น ExtendedGrid;

ผู้ใช้คลาสขยาย RoleGridUser
{
    ฟังก์ชันที่มีการป้องกัน _prepareColumns ()
    {
        ผู้ปกครอง :: _ prepareCollection ();

        $ this-> addColumn (
            'user_image'
            [
                'header' => __ ('ภาพผู้ใช้'),
                'width' => 5,
                'align' => 'left',
                'sortable' => จริง
                'index' => 'user_image'
            ]
        );

        ส่งคืน ExtendedGrid :: _ PreparCollection ();
    }
}

หากคุณมองเข้าไปใกล้คุณแล้วตอนนี้ฉันกำลังพยายามเพิ่มเขตข้อมูลด้วยภาพของผู้ใช้

น่าเสียดายที่ฉันไม่เห็นการเปลี่ยนแปลงใด ๆ ในหน้าผู้ดูแลระบบ แน่นอนว่าคอลัมน์ที่ต้องการถูกเพิ่มโดยสคริปต์ InstallSchema ก่อนหน้านี้ในตาราง ' admin_user '

เนื้อหาของไดเรกทอรีในรูปแบบที่เหมือนต้นไม้:

module_name
├──บล็อก
แคตตาล็อก│├──
││└──ผลิตภัณฑ์
Post │└──บทความที่เกี่ยวข้อง
│├──บทบาท
└──│└──กริด
. │└── User.php
└──└──ผู้ใช้
│└──แก้ไข
แท็บ│└──
└──└── Main.php
├── composer.json
├──เป็นต้น
│├── di.xml
│└── module.xml
├──ตั้งค่า
    └── InstallSchema.php

ฉันทำอะไรผิด?


วิธีแก้ปัญหาข้างต้นนั้นยอดเยี่ยม แต่ค่าไม่ได้ตั้งค่าในฟิลด์ที่เพิ่มเข้ามา .. มีอย่างอื่นที่เราต้องทำในสิ่งเดียวกัน โดยทั่วไปเราจะลบล้างแบบฟอร์มคำวิจารณ์ ขอบคุณล่วงหน้า ..
สมองอินเดียที่ยิ่งใหญ่

คำตอบ:


24

สำหรับการเพิ่มฟิลด์รูปภาพคุณสามารถลองใช้ปลั๊กอินและพยายามหลีกเลี่ยงเขียนทับคลาสทั้งหมด

ผู้ขาย / โมดูล / etc / adminhtml / di.xml


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\User\Block\User\Edit\Tab\Main">
        <plugin name="sr_stackexchange_user_form" type="Vendor\Module\Plugin\Block\Adminhtml\User\Edit\Tab\Main" sortOrder="1"/>
    </type>
</config>

ผู้ขาย / โมดูล / ปลั๊กอิน / บล็อก / Adminhtml / ผู้ใช้ / แก้ไข / แท็บ / main.php


namespace Vendor\Module\Plugin\Block\Adminhtml\User\Edit\Tab;

class Main
{
    /**
     * Get form HTML
     *
     * @return string
     */
    public function aroundGetFormHtml(
        \Magento\User\Block\User\Edit\Tab\Main $subject,
        \Closure $proceed
    )
    {
        $form = $subject->getForm();
        if (is_object($form)) {
            $fieldset = $form->addFieldset('admin_user_image', ['legend' => __('User Image')]);
            $fieldset->addField(
                'user_image',
                'image',
                [
                    'name' => 'user_image',
                    'label' => __('Image'),
                    'id' => 'user_image',
                    'title' => __('Image'),
                    'required' => false,
                    'note' => 'Allow image type: jpg, jpeg, png'
                ]
            );

            $subject->setForm($form);
        }

        return $proceed();
    }
}

ล้างแคช


สวัสดี Sohel ขอบคุณมากสำหรับคำตอบของคุณ! ดูเหมือนจะเป็นสิ่งที่ฉันต้องการให้สำเร็จ :) ฉันจะให้ข้อเสนอแนะแก่คุณทันทีที่ฉันลองใช้รหัสนี้ในเครื่อง โดยวิธีการที่ฉันเห็นว่าคุณสร้าง fieldset ใหม่และฉันเริ่มสงสัยว่าเป็นไปได้ที่จะปรับปรุงหนึ่งที่มีอยู่แล้วเช่น 'base_fieldset' คุณคิดอย่างไร? นอกจากนี้ฉันอยากรู้อยากเห็นวิธีปลั๊กอินนี้ครอบคลุมการปรับปรุงตัวควบคุมด้วยหรือไม่ ฉันจำเป็นต้องอัปเดตความคิดบางอย่างในอนาคตที่นี่: /module-user/Controller/Adminhtml/User/Save.php- บันทึกสตริงพร้อมเส้นทางของรูปภาพในตาราง 'admin_user' ขออภัยเกี่ยวกับคำถามมากมาย ขอบคุณที่คุณช่วย! ไชโย!
Rob

ตกลงเป็นไปได้ที่จะใช้ปลั๊กอินสำหรับตัวควบคุม แต่ในกรณีของฉันไม่เพียงพอ อย่างไรก็ตามคำแนะนำของคุณช่วยฉันแก้ปัญหาได้ ขอบคุณอีกครั้ง!
Rob

วิธีแก้ปัญหาข้างต้นนั้นยอดเยี่ยม แต่ค่าไม่ได้ตั้งค่าในฟิลด์ที่เพิ่มเข้ามา .. มีอย่างอื่นที่เราต้องทำในสิ่งเดียวกัน โดยทั่วไปเราจะลบล้างแบบฟอร์มคำวิจารณ์ ขอบคุณล่วงหน้า ..
สมองอินเดียที่ยิ่งใหญ่

ฉันจะสนใจวิธีการบันทึกค่าของฟิลด์ใหม่ในฟอร์มผู้ใช้ของผู้ดูแลระบบไปยังตาราง admin_user คุณแก้ปัญหาได้ด้วยการขยาย / แทนที่ตัวควบคุม /module-user/Controller/Adminhtml/User/Save.php Controller หรือไม่?
hallleron

@Sohel Rana ฟิลด์ที่เลือกจะไม่แสดงที่ไหน หรือวิธีการที่เราจะได้รับรหัสผู้ใช้ปัจจุบันที่นี่?
SagarPPanchal

2

หลังจากการวิจัยมีวิธีแก้ปัญหาสำหรับเรื่องนี้

เพิ่มคุณสมบัติ "value" ใหม่ในวิธีการ addField

ด้วยคุณค่าที่คุณต้องการ ดูตัวอย่าง:

        $fieldset->addField(
            'user_image',
            'image',
            [
                'name' => 'user_image',
                'label' => __('Image'),
                'id' => 'user_image',
                'title' => __('Image'),
                'value' => $value_that_you_need,
                'required' => false,
                'note' => 'Allow image type: jpg, jpeg, png'
            ]
        );

ฉันหวังว่ามันจะช่วยให้คุณบางคน ..


2

การแทนที่คำสั่ง

return parent::_prepareForm();

ด้วยสิ่งนี้

return \Magento\Backend\Block\Widget\Form\Generic::_prepareForm();

ทำงานให้ฉัน นี่คือรหัสที่สมบูรณ์ การเพิ่มช่อง "ร้านค้าที่สามารถเข้าถึงได้" ดังต่อไปนี้

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

namespace [vendor]\[module]\Block\User\Edit\Tab;

use Magento\Framework\App\ObjectManager;
use Magento\Framework\Locale\OptionInterface;

/**
 * Cms page edit form main tab
 *
 * @SuppressWarnings(PHPMD.DepthOfInheritance)
 */
class Main extends \Magento\User\Block\User\Edit\Tab\Main
{

    /**
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Framework\Data\FormFactory $formFactory
     * @param \Magento\Backend\Model\Auth\Session $authSession
     * @param \Magento\Framework\Locale\ListsInterface $localeLists
     * @param array $data
     * @param OptionInterface $deployedLocales Operates with deployed locales.
     */

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Backend\Model\Auth\Session $authSession,
        \Magento\Framework\Locale\ListsInterface $localeLists,
        array $data = [],
        OptionInterface $deployedLocales = null
    ) {
        $this->deployedLocales = $deployedLocales
            ?: ObjectManager::getInstance()->get(OptionInterface::class);
        parent::__construct($context, $registry, $formFactory, $authSession, $localeLists, $data, $this->deployedLocales);
    }

    /**
     * Prepare form fields
     *
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     * @return \Magento\Backend\Block\Widget\Form
     */
    protected function _prepareForm()
    {
        //die('test');
        /** @var $model \Magento\User\Model\User */
        $model = $this->_coreRegistry->registry('permissions_user');

        /** @var \Magento\Framework\Data\Form $form */
        $form = $this->_formFactory->create();
        $form->setHtmlIdPrefix('user_');

        $baseFieldset = $form->addFieldset('base_fieldset', ['legend' => __('Account Information')]);

        if ($model->getUserId()) {
            $baseFieldset->addField('user_id', 'hidden', ['name' => 'user_id']);
        } else {
            if (!$model->hasData('is_active')) {
                $model->setIsActive(1);
            }
        }

        $baseFieldset->addField(
            'username',
            'text',
            [
                'name' => 'username',
                'label' => __('User Name'),
                'id' => 'username',
                'title' => __('User Name'),
                'required' => true
            ]
        );

        $baseFieldset->addField(
            'firstname',
            'text',
            [
                'name' => 'firstname',
                'label' => __('First Name'),
                'id' => 'firstname',
                'title' => __('First Name'),
                'required' => true
            ]
        );

        $baseFieldset->addField(
            'lastname',
            'text',
            [
                'name' => 'lastname',
                'label' => __('Last Name'),
                'id' => 'lastname',
                'title' => __('Last Name'),
                'required' => true
            ]
        );

        // Adding new field for Scope Access
        $baseFieldset->addField(
            'accessible_store',
            'select',
            [
                'name' => 'accessible_store',
                'label' => __('Accessible Store'),
                'id' => 'accessible_store',
                'title' => __('Accessible Store'),
                'class' => 'input-select',
                'options' => ['3' => __('Global Store'), 
                              '1' => __('Malaysia Pavillion'), 
                              '2' => __('Thailand Pavilion')],
                'required' => true
            ]
        );

        $baseFieldset->addField(
            'email',
            'text',
            [
                'name' => 'email',
                'label' => __('Email'),
                'id' => 'customer_email',
                'title' => __('User Email'),
                'class' => 'required-entry validate-email',
                'required' => true
            ]
        );

        $isNewObject = $model->isObjectNew();
        if ($isNewObject) {
            $passwordLabel = __('Password');
        } else {
            $passwordLabel = __('New Password');
        }
        $confirmationLabel = __('Password Confirmation');
        $this->_addPasswordFields($baseFieldset, $passwordLabel, $confirmationLabel, $isNewObject);

        $baseFieldset->addField(
            'interface_locale',
            'select',
            [
                'name' => 'interface_locale',
                'label' => __('Interface Locale'),
                'title' => __('Interface Locale'),
                'values' => $this->deployedLocales->getOptionLocales(),
                'class' => 'select'
            ]
        );

        if ($this->_authSession->getUser()->getId() != $model->getUserId()) {
            $baseFieldset->addField(
                'is_active',
                'select',
                [
                    'name' => 'is_active',
                    'label' => __('This account is'),
                    'id' => 'is_active',
                    'title' => __('Account Status'),
                    'class' => 'input-select',
                    'options' => ['1' => __('Active'), '0' => __('Inactive')]
                ]
            );
        }

        $baseFieldset->addField('user_roles', 'hidden', ['name' => 'user_roles', 'id' => '_user_roles']);

        $currentUserVerificationFieldset = $form->addFieldset(
            'current_user_verification_fieldset',
            ['legend' => __('Current User Identity Verification')]
        );
        $currentUserVerificationFieldset->addField(
            self::CURRENT_USER_PASSWORD_FIELD,
            'password',
            [
                'name' => self::CURRENT_USER_PASSWORD_FIELD,
                'label' => __('Your Password'),
                'id' => self::CURRENT_USER_PASSWORD_FIELD,
                'title' => __('Your Password'),
                'class' => 'input-text validate-current-password required-entry',
                'required' => true
            ]
        );

        $data = $model->getData();
        unset($data['password']);
        unset($data[self::CURRENT_USER_PASSWORD_FIELD]);
        $form->setValues($data);

        $this->setForm($form);

        //return parent::_prepareForm();
        return \Magento\Backend\Block\Widget\Form\Generic::_prepareForm();
    }

}

และขอบคุณ @Rob สำหรับการแบ่งปันเบาะแสที่จะเริ่มต้นด้วย


2

เพียงเพิ่มตัวอย่างการทำงานอื่นฉันได้ประสบความสำเร็จในการเขียนทับหน้าผู้ดูแลเว็บไซต์ ฉันพยายามเพิ่มฟิลด์ URL ลงในหน้าแก้ไขเว็บไซต์

ฉันทำสิ่งที่มันพูดในคำตอบที่ตรวจสอบแล้ว แต่ฉันไม่ได้เพิ่ม fieldset ใหม่ ฉันได้ทำสำเร็จแล้วโดยใช้รหัสที่กำหนดไว้ในคลาสเว็บไซต์

นอกจากนี้ฉันได้ใช้การสืบทอดเพื่อดึงข้อมูลโมเดลเว็บไซต์และดึงค่าปัจจุบันจากฐานข้อมูลเพื่อวางไว้ในแบบฟอร์ม (คัดลอกมาจากคลาสเว็บไซต์ Magento ด้วย)

ในเบื้องต้นจำเป็นต้องเพิ่มคอลัมน์ 'url' ในตาราง store_website ของฐานข้อมูล magento

นี่คือผลการทำงาน (ทดสอบใน Magento 2.1):

<?php

namespace Vendor\Store\Plugin\Block\System\Store\Edit\Form;

class Website extends \Magento\Backend\Block\System\Store\Edit\Form\Website
{
    /**
     * Get form HTML
     *
     * @return string
     */
    public function aroundGetFormHtml(
        \Magento\Backend\Block\System\Store\Edit\Form\Website $subject,
        \Closure $proceed
    )
    {
        $form = $subject->getForm();
        if (is_object($form)) {

            // From \Magento\Backend\Block\System\Store\Edit\Form\Website :
            $websiteModel = $this->_coreRegistry->registry('store_data');
            $postData = $this->_coreRegistry->registry('store_post_data');
            if ($postData) {
                $websiteModel->setData($postData['website']);
            }

            // Fieldset name from \Magento\Backend\Block\System\Store\Edit\Form\Website
            $fieldset = $form->getElement('website_fieldset');
            $fieldset->addField(
                'website_url',
                'text',
                [
                    'name' => 'website[url]', // From \Magento\Backend\Block\System\Store\Edit\Form\Website
                    'label' => __('Website URL'),
                    'value' => $websiteModel->getData('url'),
                    'title' => __('Website URL'),
                    'required' => false
                ]
            );

            $subject->setForm($form);
        }

        return $proceed();
    }
}

และไฟล์ di.xml ในไดเรกทอรีVendor / Store / etc / adminhtml (ไม่มีอะไรใหม่ที่นี่จากคำตอบที่ตรวจสอบแล้ว):

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Backend\Block\System\Store\Edit\Form\Website">
        <plugin name="admin_website_plugin" type="Vendor\Store\Plugin\Block\System\Store\Edit\Form\Website" sortOrder="1"/>
    </type>
</config>

0

ฉันเพิ่งทำการเปลี่ยนแปลงเล็กน้อยในโซลูชันของคุณและได้ผลกับฉัน:

class Main extends \Magento\Backend\Block\Widget\Form\Generic
{
//Copied All the code in --- Magento\User\Block\User\Edit\Tab\Main
//added my own field in _prepareForm function

}

หากคุณต้องการฉันสามารถโพสต์โซลูชั่นทั้งหมด - แต่ฉันต้องแก้ไขเพราะตามบรรทัดฐาน บริษัท ของฉันฉันไม่สามารถแสดงรหัสในฟอรัมสาธารณะ ดังนั้นเพียงแค่ให้ฉันรู้ว่าคุณสามารถทำมันเอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.