Magento 2 is a Model View ViewModel (MVVM) system. While being closely related to its sibling Model View Controller (MVC), an MVVM architecture provides a more robust separation between the Model and the View layers. Below is an explanation of each of the layers of a MVVM system:
A Magento 2 module can in turn define external dependencies by using Composer, PHP’s dependency manager. Magento 2 core modules depend on the Zend Framework, Symfony as well as other third-party libraries.It is also interesting to notice that, in practice, all of Magento 2’s inner workings live inside a module. for example, Magento_Checkout responsible for the checkout process, and Magento_Catalog responsible for the handling of products and categories.
Below is the structure of Magento_Cms, a Magento 2 core module responsible for handling the creation of pages and static blocks.
Each folder of a Module holds one part of the architecture, as follows:
Now we will register our module with Magento. Go ahead and create a file registration.php in the location : app/code/UKM/Post/ with the following code where UKM is the namespace and Post is the Module name
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'UKM_Post',
__DIR__
);
Create a file composer.json in the location : app/code/UKM/Post/
Create a file module.xml in the location : app/code/UKM/Post/etc/ with the following code
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> <module name="UKM_Post" setup_version="0.1.1"> <sequence> <module name="Magento_Directory" /> <module name="Magento_Config" /> </sequence> </module> </config>
Now we run the following command to upgrade database info
projectname>php bin/magento setup:upgrade projectname>php bin/magento cache:flush
Now we check module status by the command
projectname>php bin/magento module:status
If the module is shown in the module list and is disable, then run the following command
projectname>php bin/magento module:enable UKM_Post
Create a file InstallSchema.php in the location: app/code/UKM/Post/Setup/ with the following code
<?php
namespace UKM\Post\Setup;
use \Magento\Framework\Setup\InstallSchemaInterface;
use \Magento\Framework\Setup\ModuleContextInterface;
use \Magento\Framework\Setup\SchemaSetupInterface;
use \Magento\Framework\DB\Ddl\Table;
/**
* Class InstallSchema
*
* @package UKM\Post\Setup
*/
class InstallSchema implements InstallSchemaInterface
{
/**
* Install Blog Posts table
*
* @param SchemaSetupInterface $setup
* @param ModuleContextInterface $context
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
$tableName = $setup->getTable('ukm_post');
if ($setup->getConnection()->isTableExists($tableName) != true) {
$table = $setup->getConnection()
->newTable($tableName)
->addColumn(
'post_id',
Table::TYPE_INTEGER,
null,
[
'identity' => true,
'unsigned' => true,
'nullable' => false,
'primary' => true
],
'ID'
)
->addColumn(
'title',
Table::TYPE_TEXT,
null,
['nullable' => false],
'Title'
)
->addColumn(
'content',
Table::TYPE_TEXT,
null,
['nullable' => false],
'Content'
)
->addColumn(
'created_at',
Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => Table::TIMESTAMP_INIT],
'Created At'
)
->setComment('Toptal Blog - Posts');
$setup->getConnection()->createTable($table);
}
$setup->endSetup();
}
}
Create a file UpgradeData.php in the location: app/code/UKM/Post/Setup/ with the following code to add some demo data in the table
<?php
namespace UKM\Post\Setup;
use \Magento\Framework\Setup\UpgradeDataInterface;
use \Magento\Framework\Setup\ModuleContextInterface;
use \Magento\Framework\Setup\ModuleDataSetupInterface;
/**
* Class UpgradeData
*
* @package UKM\Post\Setup
*/
class UpgradeData implements UpgradeDataInterface
{
/**
* Creates sample blog posts
*
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if ($context->getVersion()
&& version_compare($context->getVersion(), '0.1.1') < 0
) {
$tableName = $setup->getTable('ukm_post');
$data = [
[
'title' => 'Post 1 Title',
'content' => 'Content of the first post.',
],
[
'title' => 'Post 2 Title',
'content' => 'Content of the second post.',
],
];
$setup
->getConnection()
->insertMultiple($tableName, $data);
}
$setup->endSetup();
}
}
Run the following command to check table created sussessfully
projectname>php bin/magento setup:upgrade projectname>php bin/magento cache:flush
To get single record we will create a file Post.php in the location: app/code/UKM/Post/Model/ResourceModel/ with the following code:
<?php
namespace UKM\Post\Model\ResourceModel;
use \Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class Post extends AbstractDb
{
/**
* Post Abstract Resource Constructor
* @return void
*/
protected function _construct()
{
$this->_init('ukm_post', 'post_id');
}
}
To get all records we will create a file Collection.php in the location: app/code/UKM/Post/Model/ResourceModel/Post/ with the following code:
<?php
namespace UKM\Post\Model\ResourceModel\Post;
use \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
class Collection extends AbstractCollection
{
/**
* Remittance File Collection Constructor
* @return void
*/
protected function _construct()
{
$this->_init('UKM\Post\Model\Post', 'UKM\Post\Model\ResourceModel\Post');
}
}
Now we create a file PostInterface.php of an interface to get table field in the location: app/code/UKM/Post/Api/Data/, and it should hold the table’s fields names, along with the methods for accessing them:
<?php
namespace UKM\Post\Api\Data;
interface PostInterface
{
/**#@+
* Constants for keys of data array. Identical to the name of the getter in snake case
*/
const POST_ID = 'post_id';
const TITLE = 'title';
const CONTENT = 'content';
const CREATED_AT = 'created_at';
/**#@-*/
/**
* Get Title
*
* @return string|null
*/
public function getTitle();
/**
* Get Content
*
* @return string|null
*/
public function getContent();
/**
* Get Created At
*
* @return string|null
*/
public function getCreatedAt();
/**
* Get ID
*
* @return int|null
*/
public function getId();
/**
* Set Title
*
* @param string $title
* @return $this
*/
public function setTitle($title);
/**
* Set Content
*
* @param string $content
* @return $this
*/
public function setContent($content);
/**
* Set Crated At
*
* @param int $createdAt
* @return $this
*/
public function setCreatedAt($createdAt);
/**
* Set ID
*
* @param int $id
* @return $this
*/
public function setId($id);
}
Now create a file Post.php to implementation the data interface in the location: app/code/UKM/Post/Model/Post.php with the following codes
<?php
namespace UKM\Post\Model;
use \Magento\Framework\Model\AbstractModel;
use \Magento\Framework\DataObject\IdentityInterface;
use \Toptal\Blog\Api\Data\PostInterface;
/**
* Class File
* @package UKM\Post\Model
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Post extends AbstractModel implements PostInterface, IdentityInterface
{
/**
* Cache tag
*/
const CACHE_TAG = 'ukm_post';
/**
* Post Initialization
* @return void
*/
protected function _construct()
{
$this->_init('UKM\Post\Model\ResourceModel\Post');
}
/**
* Get Title
*
* @return string|null
*/
public function getTitle()
{
return $this->getData(self::TITLE);
}
/**
* Get Content
*
* @return string|null
*/
public function getContent()
{
return $this->getData(self::CONTENT);
}
/**
* Get Created At
*
* @return string|null
*/
public function getCreatedAt()
{
return $this->getData(self::CREATED_AT);
}
/**
* Get ID
*
* @return int|null
*/
public function getId()
{
return $this->getData(self::POST_ID);
}
/**
* Return identities
* @return string[]
*/
public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}
/**
* Set Title
*
* @param string $title
* @return $this
*/
public function setTitle($title)
{
return $this->setData(self::TITLE, $title);
}
/**
* Set Content
*
* @param string $content
* @return $this
*/
public function setContent($content)
{
return $this->setData(self::CONTENT, $content);
}
/**
* Set Created At
*
* @param string $createdAt
* @return $this
*/
public function setCreatedAt($createdAt)
{
return $this->setData(self::CREATED_AT, $createdAt);
}
/**
* Set ID
*
* @param int $id
* @return $this
*/
public function setId($id)
{
return $this->setData(self::POST_ID, $id);
}
}
Create a file routes.xml in the location: app/code/UKM/Post/etc/frontend/ with the following code
<?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="post" frontName="post"> <module name="UKM_Post"/> </route> </router> </config>
Create a file Index.php in the location: app/code/UKM/Post/Controller/Index/ with the following code
<?php
namespace UKM\Post\Controller\Index;
use \Magento\Framework\App\Action\Action;
use \Magento\Framework\View\Result\PageFactory;
use \Magento\Framework\View\Result\Page;
use \Magento\Framework\App\Action\Context;
use \Magento\Framework\Exception\LocalizedException;
class Index extends Action
{
/**
* @var PageFactory
*/
protected $resultPageFactory;
/**
* @param Context $context
* @param PageFactory $resultPageFactory
*
* @codeCoverageIgnore
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Context $context,
PageFactory $resultPageFactory
) {
parent::__construct(
$context
);
$this->resultPageFactory = $resultPageFactory;
}
/**
* Prints the blog from informed order id
* @return Page
* @throws LocalizedException
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
return $resultPage;
}
}
Create a file post_index_index.xml in the location: app/code/UKM/Post/view/frontend/layout with the following code to define layout in which container the post will appear
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="UKM\Post\Block\Posts" name="posts.list" template="UKM_Post::post/list.phtml" /> </referenceContainer> </body> </page>
Create a file Posts.php in the location: app/code/UKM/Post/Block/ with the following code
<?php
namespace UKM\Post\Block;
use \Magento\Framework\View\Element\Template;
use \Magento\Framework\View\Element\Template\Context;
use \UKM\Post\Model\ResourceModel\Post\Collection as PostCollection;
use \UKM\Post\Model\ResourceModel\Post\CollectionFactory as PostCollectionFactory;
use \UKM\Post\Model\Post;
class Posts extends Template
{
/**
* CollectionFactory
* @var null|CollectionFactory
*/
protected $_postCollectionFactory = null;
/**
* Constructor
*
* @param Context $context
* @param PostCollectionFactory $postCollectionFactory
* @param array $data
*/
public function __construct(
Context $context,
PostCollectionFactory $postCollectionFactory,
array $data = []
) {
$this->_postCollectionFactory = $postCollectionFactory;
parent::__construct($context, $data);
}
/**
* @return Post[]
*/
public function getPosts()
{
/** @var PostCollection $postCollection */
$postCollection = $this->_postCollectionFactory->create();
$postCollection->addFieldToSelect('*')->load();
return $postCollection->getItems();
}
/**
* For a given post, returns its url
* @param Post $post
* @return string
*/
public function getPostUrl(
Post $post
) {
return $this->getBaseUrl().'/post/post/view/id/' . $post->getId();
}
}
Create a file list.phtml in the location: app/code/UKM/Post/view/frontend/templates/post/ with the following code
<?php /** @var UKM\Post\Block\Posts $block */ ? > <h1 >Toptal Posts </h1 > <?php foreach($block->getPosts() as $post): ? > <?php /** @var UKM\Post\Model\Post */ ? > <h2 > <a href=" <?php echo $block->getPostUrl($post);? >" > <?php echo $post->getTitle(); ? > </a > </h2 > <p > <?php echo $post->getContent(); ? > </p > <?php endforeach; ? >
Run the following command or manually flush cache from admiin panel
projectname>php bin/magento setup:upgrade projectname>php bin/magento cache:flush
browse the following url:http://localhost/projectname/post/index/index
Create a file View.php in the location: app/code/UKM/Post/Controller/Post/ with the following code
<?php
namespace UKM\Post\Controller\Post;
use \Magento\Framework\App\Action\Action;
use \Magento\Framework\View\Result\PageFactory;
use \Magento\Framework\View\Result\Page;
use \Magento\Framework\App\Action\Context;
use \Magento\Framework\Exception\LocalizedException;
use \Magento\Framework\Registry;
class View extends Action
{
const REGISTRY_KEY_POST_ID = 'ukm_post_post_id';
/**
* Core registry
* @var Registry
*/
protected $_coreRegistry;
/**
* @var PageFactory
*/
protected $_resultPageFactory;
/**
* @param Context $context
* @param Registry $coreRegistry
* @param PageFactory $resultPageFactory
*
* @codeCoverageIgnore
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Context $context,
Registry $coreRegistry,
PageFactory $resultPageFactory
) {
parent::__construct(
$context
);
$this->_coreRegistry = $coreRegistry;
$this->_resultPageFactory = $resultPageFactory;
}
/**
* Saves the blog id to the register and renders the page
* @return Page
* @throws LocalizedException
*/
public function execute()
{
$this->_coreRegistry->register(self::REGISTRY_KEY_POST_ID, (int) $this->_request->getParam('id'));
$resultPage = $this->_resultPageFactory->create();
return $resultPage;
}
}
Create a file View.php in the location: app/code/UKM/Post/Block/ with the following code
<?php
namespace UKM\Post\Block;
use \Magento\Framework\Exception\LocalizedException;
use \Magento\Framework\View\Element\Template;
use \Magento\Framework\View\Element\Template\Context;
use \Magento\Framework\Registry;
use \UKM\Post\Model\Post;
use \UKM\Post\Model\PostFactory;
use \UKM\Post\Controller\Post\View as ViewAction;
class View extends Template
{
/**
* Core registry
* @var Registry
*/
protected $_coreRegistry;
/**
* Post
* @var null|Post
*/
protected $_post = null;
/**
* PostFactory
* @var null|PostFactory
*/
protected $_postFactory = null;
/**
* Constructor
* @param Context $context
* @param Registry $coreRegistry
* @param PostFactory $postCollectionFactory
* @param array $data
*/
public function __construct(
Context $context,
Registry $coreRegistry,
PostFactory $postFactory,
array $data = []
) {
$this->_postFactory = $postFactory;
$this->_coreRegistry = $coreRegistry;
parent::__construct($context, $data);
}
/**
* Lazy loads the requested post
* @return Post
* @throws LocalizedException
*/
public function getPost()
{
if ($this->_post === null) {
/** @var Post $post */
$post = $this->_postFactory->create();
$post->load($this->_getPostId());
if (!$post->getId()) {
throw new LocalizedException(__('Post not found'));
}
$this->_post = $post;
}
return $this->_post;
}
/**
* Retrieves the post id from the registry
* @return int
*/
protected function _getPostId()
{
return (int) $this->_coreRegistry->registry(
ViewAction::REGISTRY_KEY_POST_ID
);
}
}
Create a file view.phtml in the location: app/code/UKM/Post/view/frontend/templates/post/ with the following code
<?php /** @var Toptal\Blog\Block\View $block */ ?> <h1><?php echo $block->getPost()->getTitle(); ?></h1> <p><?php echo $block->getPost()->getContent(); ?></p>
Create a file post_post_view.xml in the location: app/code/UKM/Post/view/frontend/layout/ with the following code
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <block class="UKM\Post\Block\View" name="post.view" template="UKM_Post::post/view.phtml" /> </referenceContainer> </body> </page>
Run the following command or manually flush cache from admiin panel
projectname>php bin/magento setup:upgrade projectname>php bin/magento cache:flush
browse the following url:http://localhost/projectname/post/post/view/id/1
Total : 27273
Today :9
Today Visit Country :