Model

Model is used to create a easie CRUD interface to the database

  • Model ame: The name of the model, the table name wil be <module_name>_<model_name>.
  • Field name: The name of the database table field.
  • Field type: The type of database field.
  • Adminhtml grid: Add this field to the adminhtml grid layout

Model ID field: The snippet will auto add the model id field to the database table, the field name is <model_name>_id.

Use the snippet in the Magento 2 module creator.

Files

Model/TestRepository.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Model;

use Mage2Gen\Module\Api\Data\TestInterfaceFactory;
use Mage2Gen\Module\Api\Data\TestSearchResultsInterfaceFactory;
use Mage2Gen\Module\Api\TestRepositoryInterface;
use Mage2Gen\Module\Model\ResourceModel\Test as ResourceTest;
use Mage2Gen\Module\Model\ResourceModel\Test\CollectionFactory as TestCollectionFactory;
use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\Api\ExtensibleDataObjectConverter;
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
use Magento\Framework\Exception\CouldNotDeleteException;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Reflection\DataObjectProcessor;
use Magento\Store\Model\StoreManagerInterface;

class TestRepository implements TestRepositoryInterface
{

    protected $resource;

    protected $testFactory;

    protected $testCollectionFactory;

    protected $searchResultsFactory;

    protected $dataObjectHelper;

    protected $dataObjectProcessor;

    protected $dataTestFactory;

    protected $extensionAttributesJoinProcessor;

    private $storeManager;

    private $collectionProcessor;

    protected $extensibleDataObjectConverter;

    /**
     * @param ResourceTest $resource
     * @param TestFactory $testFactory
     * @param TestInterfaceFactory $dataTestFactory
     * @param TestCollectionFactory $testCollectionFactory
     * @param TestSearchResultsInterfaceFactory $searchResultsFactory
     * @param DataObjectHelper $dataObjectHelper
     * @param DataObjectProcessor $dataObjectProcessor
     * @param StoreManagerInterface $storeManager
     * @param CollectionProcessorInterface $collectionProcessor
     * @param JoinProcessorInterface $extensionAttributesJoinProcessor
     * @param ExtensibleDataObjectConverter $extensibleDataObjectConverter
     */
    public function __construct(
        ResourceTest $resource,
        TestFactory $testFactory,
        TestInterfaceFactory $dataTestFactory,
        TestCollectionFactory $testCollectionFactory,
        TestSearchResultsInterfaceFactory $searchResultsFactory,
        DataObjectHelper $dataObjectHelper,
        DataObjectProcessor $dataObjectProcessor,
        StoreManagerInterface $storeManager,
        CollectionProcessorInterface $collectionProcessor,
        JoinProcessorInterface $extensionAttributesJoinProcessor,
        ExtensibleDataObjectConverter $extensibleDataObjectConverter
    ) {
        $this->resource = $resource;
        $this->testFactory = $testFactory;
        $this->testCollectionFactory = $testCollectionFactory;
        $this->searchResultsFactory = $searchResultsFactory;
        $this->dataObjectHelper = $dataObjectHelper;
        $this->dataTestFactory = $dataTestFactory;
        $this->dataObjectProcessor = $dataObjectProcessor;
        $this->storeManager = $storeManager;
        $this->collectionProcessor = $collectionProcessor;
        $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor;
        $this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
    }

    /**
     * {@inheritdoc}
     */
    public function save(
        \Mage2Gen\Module\Api\Data\TestInterface $test
    ) {
        /* if (empty($test->getStoreId())) {
            $storeId = $this->storeManager->getStore()->getId();
            $test->setStoreId($storeId);
        } */
        
        $testData = $this->extensibleDataObjectConverter->toNestedArray(
            $test,
            [],
            \Mage2Gen\Module\Api\Data\TestInterface::class
        );
        
        $testModel = $this->testFactory->create()->setData($testData);
        
        try {
            $this->resource->save($testModel);
        } catch (\Exception $exception) {
            throw new CouldNotSaveException(__(
                'Could not save the test: %1',
                $exception->getMessage()
            ));
        }
        return $testModel->getDataModel();
    }

    /**
     * {@inheritdoc}
     */
    public function get($testId)
    {
        $test = $this->testFactory->create();
        $this->resource->load($test, $testId);
        if (!$test->getId()) {
            throw new NoSuchEntityException(__('Test with id "%1" does not exist.', $testId));
        }
        return $test->getDataModel();
    }

    /**
     * {@inheritdoc}
     */
    public function getList(
        \Magento\Framework\Api\SearchCriteriaInterface $criteria
    ) {
        $collection = $this->testCollectionFactory->create();
        
        $this->extensionAttributesJoinProcessor->process(
            $collection,
            \Mage2Gen\Module\Api\Data\TestInterface::class
        );
        
        $this->collectionProcessor->process($criteria, $collection);
        
        $searchResults = $this->searchResultsFactory->create();
        $searchResults->setSearchCriteria($criteria);
        
        $items = [];
        foreach ($collection as $model) {
            $items[] = $model->getDataModel();
        }
        
        $searchResults->setItems($items);
        $searchResults->setTotalCount($collection->getSize());
        return $searchResults;
    }

    /**
     * {@inheritdoc}
     */
    public function delete(
        \Mage2Gen\Module\Api\Data\TestInterface $test
    ) {
        try {
            $testModel = $this->testFactory->create();
            $this->resource->load($testModel, $test->getTestId());
            $this->resource->delete($testModel);
        } catch (\Exception $exception) {
            throw new CouldNotDeleteException(__(
                'Could not delete the Test: %1',
                $exception->getMessage()
            ));
        }
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function deleteById($testId)
    {
        return $this->delete($this->get($testId));
    }
}

Model/Test.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Model;

use Mage2Gen\Module\Api\Data\TestInterface;
use Mage2Gen\Module\Api\Data\TestInterfaceFactory;
use Magento\Framework\Api\DataObjectHelper;

class Test extends \Magento\Framework\Model\AbstractModel
{

    protected $testDataFactory;

    protected $dataObjectHelper;

    protected $_eventPrefix = 'mage2gen_module_test';

    /**
     * @param \Magento\Framework\Model\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param TestInterfaceFactory $testDataFactory
     * @param DataObjectHelper $dataObjectHelper
     * @param \Mage2Gen\Module\Model\ResourceModel\Test $resource
     * @param \Mage2Gen\Module\Model\ResourceModel\Test\Collection $resourceCollection
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        TestInterfaceFactory $testDataFactory,
        DataObjectHelper $dataObjectHelper,
        \Mage2Gen\Module\Model\ResourceModel\Test $resource,
        \Mage2Gen\Module\Model\ResourceModel\Test\Collection $resourceCollection,
        array $data = []
    ) {
        $this->testDataFactory = $testDataFactory;
        $this->dataObjectHelper = $dataObjectHelper;
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
    }

    /**
     * Retrieve test model with test data
     * @return TestInterface
     */
    public function getDataModel()
    {
        $testData = $this->getData();
        
        $testDataObject = $this->testDataFactory->create();
        $this->dataObjectHelper->populateWithArray(
            $testDataObject,
            $testData,
            TestInterface::class
        );
        
        return $testDataObject;
    }
}

Model/ResourceModel/Test.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Model\ResourceModel;

class Test extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{

    /**
     * Define resource model
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('mage2gen_module_test', 'test_id');
    }
}

Model/ResourceModel/Test/Collection.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Model\ResourceModel\Test;

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{

    /**
     * @var string
     */
    protected $_idFieldName = 'test_id';

    /**
     * Define resource model
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init(
            \Mage2Gen\Module\Model\Test::class,
            \Mage2Gen\Module\Model\ResourceModel\Test::class
        );
    }
}

Model/Data/Test.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Model\Data;

use Mage2Gen\Module\Api\Data\TestInterface;

class Test extends \Magento\Framework\Api\AbstractExtensibleObject implements TestInterface
{

    /**
     * Get test_id
     * @return string|null
     */
    public function getTestId()
    {
        return $this->_get(self::TEST_ID);
    }

    /**
     * Set test_id
     * @param string $testId
     * @return \Mage2Gen\Module\Api\Data\TestInterface
     */
    public function setTestId($testId)
    {
        return $this->setData(self::TEST_ID, $testId);
    }

    /**
     * Get Test
     * @return string|null
     */
    public function getTest()
    {
        return $this->_get(self::TEST);
    }

    /**
     * Set Test
     * @param string $test
     * @return \Mage2Gen\Module\Api\Data\TestInterface
     */
    public function setTest($test)
    {
        return $this->setData(self::TEST, $test);
    }

    /**
     * Retrieve existing extension attributes object or create a new one.
     * @return \Mage2Gen\Module\Api\Data\TestExtensionInterface|null
     */
    public function getExtensionAttributes()
    {
        return $this->_getExtensionAttributes();
    }

    /**
     * Set an extension attributes object.
     * @param \Mage2Gen\Module\Api\Data\TestExtensionInterface $extensionAttributes
     * @return $this
     */
    public function setExtensionAttributes(
        \Mage2Gen\Module\Api\Data\TestExtensionInterface $extensionAttributes
    ) {
        return $this->_setExtensionAttributes($extensionAttributes);
    }
}

etc/db_schema.xml

<?xml version="1.0" ?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
	<table name="mage2gen_module_test" resource="default" engine="innodb" comment="mage2gen_module_test Table">
		<column xsi:type="int" name="test_id" padding="10" unsigned="true" nullable="false" identity="true" comment="Entity Id"/>
		<constraint xsi:type="primary" referenceId="PRIMARY">
			<column name="test_id"/>
		</constraint>
		<column name="Test" nullable="false" xsi:type="text" comment="Test"/>
	</table>
</schema>

etc/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">
	<preference for="Mage2Gen\Module\Api\TestRepositoryInterface" type="Mage2Gen\Module\Model\TestRepository"/>
	<preference for="Mage2Gen\Module\Api\Data\TestInterface" type="Mage2Gen\Module\Model\Data\Test"/>
	<preference for="Mage2Gen\Module\Api\Data\TestSearchResultsInterface" type="Magento\Framework\Api\SearchResults"/>
</config>

Api/TestRepositoryInterface.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Api;

use Magento\Framework\Api\SearchCriteriaInterface;

interface TestRepositoryInterface
{

    /**
     * Save Test
     * @param \Mage2Gen\Module\Api\Data\TestInterface $test
     * @return \Mage2Gen\Module\Api\Data\TestInterface
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function save(
        \Mage2Gen\Module\Api\Data\TestInterface $test
    );

    /**
     * Retrieve Test
     * @param string $testId
     * @return \Mage2Gen\Module\Api\Data\TestInterface
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function get($testId);

    /**
     * Retrieve Test matching the specified criteria.
     * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
     * @return \Mage2Gen\Module\Api\Data\TestSearchResultsInterface
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getList(
        \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
    );

    /**
     * Delete Test
     * @param \Mage2Gen\Module\Api\Data\TestInterface $test
     * @return bool true on success
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function delete(
        \Mage2Gen\Module\Api\Data\TestInterface $test
    );

    /**
     * Delete Test by ID
     * @param string $testId
     * @return bool true on success
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function deleteById($testId);
}

Api/Data/TestInterface.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Api\Data;

interface TestInterface extends \Magento\Framework\Api\ExtensibleDataInterface
{

    const TEST_ID = 'test_id';
    const TEST = 'Test';

    /**
     * Get test_id
     * @return string|null
     */
    public function getTestId();

    /**
     * Set test_id
     * @param string $testId
     * @return \Mage2Gen\Module\Api\Data\TestInterface
     */
    public function setTestId($testId);

    /**
     * Get Test
     * @return string|null
     */
    public function getTest();

    /**
     * Set Test
     * @param string $test
     * @return \Mage2Gen\Module\Api\Data\TestInterface
     */
    public function setTest($test);

    /**
     * Retrieve existing extension attributes object or create a new one.
     * @return \Mage2Gen\Module\Api\Data\TestExtensionInterface|null
     */
    public function getExtensionAttributes();

    /**
     * Set an extension attributes object.
     * @param \Mage2Gen\Module\Api\Data\TestExtensionInterface $extensionAttributes
     * @return $this
     */
    public function setExtensionAttributes(
        \Mage2Gen\Module\Api\Data\TestExtensionInterface $extensionAttributes
    );
}

Api/Data/TestSearchResultsInterface.php

<?php
declare(strict_types=1);

namespace Mage2Gen\Module\Api\Data;

interface TestSearchResultsInterface extends \Magento\Framework\Api\SearchResultsInterface
{

    /**
     * Get Test list.
     * @return \Mage2Gen\Module\Api\Data\TestInterface[]
     */
    public function getItems();

    /**
     * Set Test list.
     * @param \Mage2Gen\Module\Api\Data\TestInterface[] $items
     * @return $this
     */
    public function setItems(array $items);
}