1. Create required folders and files for a module
Vasan
--KpsAddress
  --Api
    --Data
      --AddressInterface.php
      --AddressSearchResultsInterface.php
    --AddressRepositoryInterface.php
  --Block
    --Adminhtml
      --Edit
        --DeleteButton.php
        --GenericButton.php
        --ResetButton.php
        --SaveAndContinueButton.php
        --SaveButton.php
  --Console
    --InstallAddress.php
  --Controller
    --Adminhtml
      --Index
        --Delete.php
        --Edit.php
        --Index.php
        --NewAction.php
        --Save.php
  --etc
    --adminhtml
      --menu.xml
      --routes.xml
    --module.xml
    --di.xml
    --acl.xml
    --db_schema.xml
  --Model
    --Address
      --DataProvider.php
    --Repository
      --AddressRepository.php
    --ResourceModel
      --Address
        --Collection.php
      --Address.php
        
    --Address.php
    --AddressSearchResults.php
  --Source
  --Ui
    --Component
      --Listing
        --Column
          --AddressAction.php
  --view
    --adminhtml
      --layout
        --kpsaddress_index_edit.xml
        --kpsaddress_index_index.xml
       --ui_component
         --kspaddress_edit_form.xml
         --kpsaddress_index_listing.xml
         
  --composer.json
  --README.md
  --registration.php
2. Create menu.xml and acl.xml file
The acl.xml file is used for admin access
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * acl
 *
 * @copyright Copyright © 2021 Vasan. All rights reserved.
 * @author    survasp@gmail.com
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Vasan_Core::menu" title="Vasan Menu" translate="title" sortOrder="69">
                    <resource id="Vasan_KpsAddress::address" title="Address">
                        <resource id="Vasan_KpsAddress::save" title="Save"/>
                        <resource id="Vasan_KpsAddress::delete" title="Delete"/>
                    </resource>
                </resource>
            </resource>
        </resources>
    </acl>
</config>
The adminhtml/menu.xml is used to provide the link to access the admin controllers
Following menu xml file has the link of the Index controller to show the addresses as a grid display
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * menu
 *
 * @copyright Copyright © 2021 Vasan. All rights reserved.
 * @author    survasp@gmail.com
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
        <add id="Vasan_KpsAddress::address" title="KPS Address" module="Vasan_KpsAddress" sortOrder="1" parent="Vasan_Core::menu" action="kpsaddress/index" resource="Vasan_KpsAddress::address"/>
    </menu>
</config>
3. Create database table using declarative schema
The db_schema.xml is used to create the table columns and define the keys
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * db_schema.xml
 *
 * @copyright Copyright © 2021 Vasan. All rights reserved.
 * @author    survasp@gmail.com
 */
-->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="kps_address" resource="default" engine="innodb" comment="KPS Address">
        <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="ID" />
        <column xsi:type="varchar" name="province" comment="Province" nullable="false" />
        <column xsi:type="varchar" name="province_code" comment="Province Code" nullable="false" />
        <column xsi:type="varchar" name="city" comment="City" nullable="false" />
        <column xsi:type="varchar" name="city_code" comment="City Code" nullable="false" />
        <column xsi:type="varchar" name="urban" comment="Urban" nullable="false" />
        <column xsi:type="varchar" name="urban_code" comment="Urban Code" nullable="false" />
        <column xsi:type="varchar" name="sub_district" comment="Sub District" nullable="false" />
        <column xsi:type="varchar" name="sub_district_code" comment="Sub District Code" nullable="false" />
        <column xsi:type="varchar" name="zipcode" comment="Zipcode" nullable="false" />
        <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP"
                comment="Creation Time"/>
        <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP"
                comment="Update Time"/>
        <constraint xsi:type="primary" referenceId="PRIMARY">
            <column name="id"/>
        </constraint>
    </table>
</schema>
4. Create Api Interfaces
As per magento 2 standard, three api interfaces should be create for a module
The AddressInterface is used to define object represent the kps_address table and important method to access from repository.
<?php
namespace Vasan\KpsAddress\Api\Data;
interface AddressInterface
{
    const KEY_ID = 'id';
    const KEY_PROVINCE = 'province';
    const KEY_PROVINCE_CODE = 'province_code';
    const KEY_CITY_CODE = 'city_code';
    const KEY_CITY = 'city';
    const KEY_URBAN = 'urban';
    const KEY_URBAN_CODE = 'urban_code';
    const KEY_SUB_DISTRICT = 'sub_district';
    const KEY_SUB_DISTRICT_CODE = 'sub_district_code';
    const KEY_ZIPCODE = 'zipcode';
    const KEY_CREATED_AT = 'created_at';
    const KEY_UPDATED_AT = 'updated_at';
    /**
     * @return string
     */
    public function getProvince();
    /**
     * @return string
     */
    public function getProvinceCode();
    /**
     * @return string
     */
    public function getCity();
    /**
     * @return string
     */
    public function getCityCode();
    /**
     * @return string
     */
    public function getUrban();
    /**
     * @return string
     */
    public function getUrbanCode();
    /**
     * @return string
     */
    public function getSubDistrict();
    /**
     * @return string
     */
    public function getSubDistrictCode();
    /**
     * @return string
     */
    public function getZipcode();
    /**
     * @return string
     */
    public function getUpdatedAt();
    /**
     * @return string
     */
    public function getCreatedAt();
    /**
     * @param string $province
     * @return void
     */
    public function setProvince($province);
    /**
     * @param string $provinceCode
     * @return void
     */
    public function setProvinceCode($provinceCode);
    /**
     * @param string $city
     * @return void
     */
    public function setCity($city);
    /**
     * @param string $cityCode
     * @return void
     */
    public function setCityCode($cityCode);
    /**
     * @param string $urban
     * @return void
     */
    public function setUrban($urban);
    /**
     * @param string $urbanCode
     * @return void
     */
    public function setUrbanCode($urbanCode);
    /**
     * @param string $subDistrict
     * @return void
     */
    public function setSubDistrict($subDistrict);
    /**
     * @param string $subDistrictCode
     * @return void
     */
    public function setSubDistrictCode($subDistrictCode);
    /**
     * @param string $zipcode
     * @return void
     */
    public function setZipcode($zipcode);
}
The AddressRepositoryInterface is used to define the database operations methods.
<?php
namespace Vasan\KpsAddress\Api;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Vasan\KpsAddress\Api\Data\AddressInterface;
use Vasan\KpsAddress\Api\Data\AddressSearchResultsInterface;
interface AddressRepositoryInterface
{
    /**
     * @param SearchCriteriaInterface $searchCriteria
     * @return AddressSearchResultsInterface
     */
    public function getList(SearchCriteriaInterface $searchCriteria);
    /**
     * @param AddressInterface $address
     * @return AddressInterface
     * @throws LocalizedException
     */
    public function save(AddressInterface $address);
    /**
     * @param $id
     * @return AddressInterface
     * @throws LocalizedException
     */
    public function getById($id);
    /**
     * @param AddressInterface $address
     * @return bool
     * @throws LocalizedException
     */
    public function delete(AddressInterface $address);
    /**
     * @param $id
     * @return bool
     * @throws NoSuchEntityException
     * @throws LocalizedException
     */
    public function deleteById($id);
}
The AddressSearchResultsInterface is used to search the object from address collection
<?php
namespace Vasan\KpsAddress\Api\Data;
use Magento\Framework\Api\SearchResultsInterface;
interface AddressSearchResultsInterface extends SearchResultsInterface
{
    /**
     * Get list.
     *
     * @return AddressInterface[]
     */
    public function getItems();
    /**
     * Set list.
     *
     * @param AddressInterface[] $items
     * @return $this
     */
    public function setItems(array $items);
}
Posted by vasan to vasan's deck (2021-01-07 09:57)