Best practice: via the service contract
The best practice is always to use the service contract whenever it's possible. You can find the list of reasons here: Magento 2: what are the benefits of using service contracts?
For details on how to implement a service contract I suggest you check this topic: How to implement service contract for a custom module in Magento 2?
If no service contract available
If there is no service contract available, you should use the model repository get
method. Using this method, you benefit from the magento caching system for example for the CategoryRepository
class:
public function get($categoryId, $storeId = null)
{
$cacheKey = null !== $storeId ? $storeId : 'all';
if (!isset($this->instances[$categoryId][$cacheKey])) {
/** @var Category $category */
$category = $this->categoryFactory->create();
if (null !== $storeId) {
$category->setStoreId($storeId);
}
$category->load($categoryId);
if (!$category->getId()) {
throw NoSuchEntityException::singleField('id', $categoryId);
}
$this->instances[$categoryId][$cacheKey] = $category;
}
return $this->instances[$categoryId][$cacheKey];
}
Deprecated load()
method
Magento 2 is slowly moving away from the standard CRUD system by dropping the inheritance system and implementing it via composition using the new 2.1 EntityManager you can find details here: Magento 2.1: using the entity manager
Also I suggest you read this interesting topic about the deprecated CRUD methods: Deprecated save and load methods in Abstract Model
Why not using the resource model load
The main reason is that if you use the resource model load
method, you will skip some important part of the loading system that are implemented in the model load
method, see Magento\Framework\Model\AbstractModel
:
public function load($modelId, $field = null)
{
$this->_beforeLoad($modelId, $field);
$this->_getResource()->load($this, $modelId, $field);
$this->_afterLoad();
$this->setOrigData();
$this->_hasDataChanges = false;
$this->updateStoredData();
return $this;
}
Calling the resource model load
method directly will have the following impact:
_beforeLoad
is not called: thus the model load before events are not dispatched
_afterLoad
is not called: thus the model load after events are not dispatched
- the stored data are not updated which can cause various problems (for instance if you call
prepareDataForUpdate
from Magento\Framework\Model\ResourceModel\Db\AbstractDb
)
Finally i have resolve my issue .
Only Need to override Subscriber.
I am posting my entire code. may be it will helpful to someone.
di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Newsletter\Model\Subscriber" type="Navin\Subscribe\Model\Subscriber" />
</config>
Subscriber.php Model Files
namespace Navin\Subscribe\Model;
class Subscriber extends \Magento\Newsletter\Model\Subscriber {
/**
* Initialize resource model
*
* @return void
*/
public function subscribe($email, $subscriber_name = '', $subscriber_date_of_birth = '', $subscriber_country_code = '') {
$this->loadByEmail($email);
if (!$this->getId()) {
$this->setSubscriberConfirmCode($this->randomSequence());
}
$isConfirmNeed = $this->_scopeConfig->getValue(
self::XML_PATH_CONFIRMATION_FLAG, \Magento\Store\Model\ScopeInterface::SCOPE_STORE
) == 1 ? true : false;
$isOwnSubscribes = false;
$isSubscribeOwnEmail = $this->_customerSession->isLoggedIn() && $this->_customerSession->getCustomerDataObject()->getEmail() == $email;
if (!$this->getId() || $this->getStatus() == self::STATUS_UNSUBSCRIBED || $this->getStatus() == self::STATUS_NOT_ACTIVE
) {
if ($isConfirmNeed === true) {
// if user subscribes own login email - confirmation is not needed
$isOwnSubscribes = $isSubscribeOwnEmail;
if ($isOwnSubscribes == true) {
$this->setStatus(self::STATUS_SUBSCRIBED);
} else {
$this->setStatus(self::STATUS_NOT_ACTIVE);
}
} else {
$this->setStatus(self::STATUS_SUBSCRIBED);
}
$this->setSubscriberEmail($_POST['email']);
}
if(!empty($_POST['subscriber_name']) ){
$this->setSubscriberName($_POST['subscriber_name']); //subscriber_name
$this->setSubscriberDateofbirth($_POST['subscriber_dateofbirth']); //date of birth
$this->setSubscriberCountrycode($_POST['subscriber_countrycode']); //country code
}
if ($isSubscribeOwnEmail) {
try {
$customer = $this->customerRepository->getById($this->_customerSession->getCustomerId());
$this->setStoreId($customer->getStoreId());
$this->setCustomerId($customer->getId());
} catch (NoSuchEntityException $e) {
$this->setStoreId($this->_storeManager->getStore()->getId());
$this->setCustomerId(0);
}
} else {
$this->setStoreId($this->_storeManager->getStore()->getId());
$this->setCustomerId(0);
}
$this->setStatusChanged(true);
try {
$this->save();
if ($isConfirmNeed === true && $isOwnSubscribes === false
) {
$this->sendConfirmationRequestEmail();
} else {
$this->sendConfirmationSuccessEmail();
}
return $this->getStatus();
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
}
Best Answer
Use Plugins to achieve this
create write following code inside di.xml
Create Plugin file Layer.php as we mentioned in type in di.xml file Vendor/Module/Plugin/Model/Layer.php
paste the following code inside Layer.php
Chech now it will work It worked for me.Hope It will help you too