Magento 2 Catalog rule can not applied after reindex automatic - magento2

I wrote the code for creating a Catalog rule in Magento 2.3.5 and after saving I have the code to re-index it automatically.
/** #var \Magento\CatalogRule\Model\Rule $model */
$ruleRepository = $this->_objectManager->get(
\Magento\CatalogRule\Api\CatalogRuleRepositoryInterface::class
);
$catalogRule = $this->_objectManager->create(\Magento\CatalogRule\Model\Rule::class);
$ruleByBoRefId = $this->getRuleByBoRefId($boRefId);
if (isset($ruleByBoRefId["rule_id"]) && $ruleId = $ruleByBoRefId["rule_id"]) {
$catalogRule = $ruleRepository->get($ruleId);
}
$catalogRule->loadPost($catalogRuleData);
//$catalogRule->save();
$ruleRepository->save($catalogRule);
$this->reindexCatalogRule($catalogRule);
Code Reindex:
public function reindexCatalogRule($catalogRule){
if($catalogRule->isRuleBehaviorChanged()){
$this->_objectManager
->create(\Magento\CatalogRule\Model\Flag::class)
->loadSelf()
->setState(0)
->save();
}
$collection = $this->_indexerCollectionFactory->create()->getAllIds();
foreach ($collection as $id) {
$indexer = $this->_indexerFactory->create()->load($id);
$indexer->getState()
->setStatus(\Magento\Framework\Indexer\StateInterface::STATUS_INVALID)
->save();
$indexer->reindexAll();
}
}
But after reindex the Rule still doesn't apply to the product. However, after I go to the admin and edited the previously saved catalog rule => Click Save => Then I ran the Indexer: reindex command of magento, the rule applies normally.
I don't understand why like that. Please help me How to apply rules to products automatically ? Thanks

Related

How to write an extbase Repository-Method for Update in TYPO3?

I have written an update query in TYPO3, Now I need to change it to query-object repository method. How to change the code below?
public function updatePaymentDetails($uid, $txnID, $amt, $stats)
{
$itemUID = $uid;
$transID = $txnID;
$amountPaid = $amt;
$txStatus = $stats;
$tableName = 'tx_paypalpayment_domain_model_transactions AS tpp';
$whereCondition = 'tpp.uid=' . '"' . $itemUID . '"';
$setValues = ['transactionid' => $transID, 'amount' => $amountPaid, 'txnstatus' => $txStatus];
$result = $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tableName, $whereCondition, $setValues);
return $result;
}
I created this much in my own idea (don't know it is correct or not), What should be the remaining portion?
public function paymentUpdate($uid, $txnID, $amt, $stats) {
$query = $this->createQuery();
$query->matching(
$query->logicalAnd(
$query->equals("transactionid", $txnID),
$query->equals("amount", $amt),
$query->equals("txnstatus", $stats)
)
);
/*--- Update Code ---*/
return $query->execute();
}
Is there any way to do that?
The TYPO3/Extbase way is to first fetch your transaction from the persistence layer then apply your changes to the domain object and then update it in your repository.
Something like below in your controller action:
$transaction = $this->transactionRepository->findByIdentifier($itemUid);
$transaction->setTransactionId($transID);
$transaction->setAmount($amountPaid);
$transaction->setStatus($txStatus);
$this->transactionRepository->update($transaction);
If you wants to do a direct update instead of first fetching the record then take a look at the \TYPO3\CMS\Core\Database\Query\QueryBuilder (Only exists in newer versions of TYPO3 - 8.7 and above). In older versions of TYPO3 you could take a look at $GLOBALS['TYPO3_DB']->exec_*.

how to use insert record function in moodle

I am trying to insert record into my database using moodle.
I am using version 1.9.19. i am trying the following code :
<?php
require_once('config.php');
require_once('uplo.php');
$mform = new uplo();
$mform->display();
if(isset($_POST['submitbutton'])){
$name = $mform->get_data('name');
$email = $mform->get_data('email');
$table='mdl_tet';
$res=insert_record($table, '$name','$email') ;
}
?>
But this is not working correctly. How to do that correctly.
Note : Why am using 1.9.19 means my client using this version so i cant change the version.
The insert_record() function takes two parameters - the name of the table (without the prefix) and an object containing the data to insert into the table.
So, in this case, you should write something like:
$ins = (object)array('name' => $name, 'email' => $email);
$ins->id = insert_record('tet', $ins);
OR:
$ins = new stdClass();
$ins->name = $name;
$ins->email = $email;
$ins->id = insert_record('tet', $ins);
(As an aside - make sure you turn on debugging - https://docs.moodle.org/19/en/Debugging - it will make your life a lot easier).

how to: use Tx_Extbase_Domain_Repository_FrontendUserRepository in typo3 v4.5

I am trying to read the username of a front end user whose uid is known. I tried this in my controller's showAction method:
$objectManger = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
// get repository
$repository = $objectManger->get('Tx_Extbase_Domain_Repository_FrontendUserRepository ');
$newObject = $repository->findByUid($coupon->getCreator()); //this is the uid of whoever was loggin in
print_r($newObject);
echo $newObject->getUsername(); die;
but when that code runs I get:
Oops, an error occured!
"Tx_Extbase_Domain_Repository_FrontendUserRepository " is not a valid cache entry identifier.
It turns out that $repository is empty, so how do I get fe_user data?
I am using typo3 v4.5 with extbase.
Thanks
Update to show complete answer.
This is the code (it goes in my CouponController) that worked (plus the typoscript mentioned):
/**
* #var Tx_Extbase_Domain_Repository_FrontendUserRepository
*/
protected $userRepository;
/**
* Inject the user repository
* #param Tx_Extbase_Domain_Repository_FrontendUserRepository $userRepository
* #return void */
public function injectFrontendUserRepository(Tx_Extbase_Domain_Repository_FrontendUserRepository $userRepository) {
$this->userRepository = $userRepository;
}
public function showAction(Tx_Coupons_Domain_Model_Coupon $coupon) {
$userRepository = $this->objectManager->get("Tx_Extbase_Domain_Repository_FrontendUserRepository");
$newObject = $userRepository->findByUid($coupon->getCreator());
$this->view->assign('coupon', $coupon);
$this->view->assign('creatorname', $newObject->getUsername() );
}
If you are using extbase yourself you dont have to call makeInstance for your objectManager, it's already there ($this->objectManager).
anyway, you should inject this repository (see my answer here: TYPO3 - Call another repository)
Clear the Cache after the Injection.
You maybe have to disable the recordtype extbase sets for its FrontendUser:
config.tx_extbase.persistence.classes.Tx_Extbase_Domain_Model_FrontendUser.mapping.recordType >
Set the source storage pid where the repository fetches the data from:
/** #var Tx_Extbase_Domain_Repository_FrontendUserRepository $repos */
$repos = $this->objectManager->get("Tx_Extbase_Domain_Repository_FrontendUserRepository");
$querySettings = $repos->createQuery()->getQuerySettings();
$querySettings->setStoragePageIds(array(123, 567));
$repos->setDefaultQuerySettings($querySettings);
$user = $repos->findByUid(56); // Queries for user 56 in storages 123 and 567

zfcuser add user role after registration

I'm using Zend Framework 2 with ZfcUser, BjyAuthorize and Doctrine for the database. Registration etc. works very well so far. My problem is, that registered users have no role assigned, so i want to add the role "user" to the user during registration.
I think i could attach this to the "register" event, but i don't know how to do that.
I hope someone can help me ...
(i used this tutorial for setting up zfcuser etc. http://samminds.com/2013/03/zfcuser-bjyauthorize-and-doctrine-working-together/)
public function onBootstrap(MvcEvent $e)
{
$zfcServiceEvents = $e->getApplication()->getServiceManager()->get('zfcuser_user_service')->getEventManager();
$zfcServiceEvents->attach('register', function($e) {
$user = $e->getParam('user');
// probably the role must be added here, with $user->addRole();
// but how do i get the user Role Entity to add from DB?
});
Building on DangelZM's answer, and using another reference (see link at end of my post) about the Event Manager, I came up with this solution which organizes the potential ZfcUser event listeners out into a user listener object.
Note: I created my own user module called NvUser, so depending on the name of your module you'll have to replace all references of NvUser to your user module name.
Summary
I created an NvUserListener object that can itself attach event listeners to the shared event manager, and house the event listener callbacks.
Inside NvUser/Module.php:
<?php
namespace NvUser;
use Zend\Mvc\MvcEvent;
use NvUser\Listener\NvUserListener;
class Module
{
public function onBootstrap(MvcEvent $mvcEvent)
{
$em = $mvcEvent->getApplication()->getEventManager();
$em->attach(new NvUserListener());
}
}
Inside NvUser/src/NvUser/Listener/NvUserListener.php:
<?php
namespace NvUser\Listener;
use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\Event;
class NvUserListener extends AbstractListenerAggregate
{
public function attach(EventManagerInterface $events)
{
$sharedManager = $events->getSharedManager();
$this->listeners[] = $sharedManager->attach('ZfcUser\Service\User', 'register', array($this, 'onRegister'));
$this->listeners[] = $sharedManager->attach('ZfcUser\Service\User', 'register.post', array($this, 'onRegisterPost'));
}
public function onRegister(Event $e)
{
$sm = $e->getTarget()->getServiceManager();
$em = $sm->get('doctrine.entitymanager.orm_default');
$user = $e->getParam('user');
$config = $sm->get('config');
$criteria = array('roleId' => $config['zfcuser']['new_user_default_role']);
$defaultUserRole = $em->getRepository('NvUser\Entity\Role')->findOneBy($criteria);
if ($defaultUserRole !== null)
{
$user->addRole($defaultUserRole);
}
}
public function onRegisterPost(Event $e)
{
$user = $e->getParam('user');
$form = $e->getParam('form');
// Do something after user has registered
}
}
Inside NvUser/config/module.config.php:
<?php
namespace NvUser;
return array(
'zfcuser' => array(
'new_user_default_role' => 'user',
),
);
References:
Understanding the Zend Framework 2 Event Manager
Maybe it's not the best solution, but it works for me.
Add user_role_id option in config scope.
public function onBootstrap(MvcEvent $mvcEvent)
{
$zfcServiceEvents = $mvcEvent->getApplication()->getServiceManager()->get('zfcuser_user_service')->getEventManager();
$zfcServiceEvents->attach('register', function($e) use($mvcEvent) {
$user = $e->getParam('user');
$em = $mvcEvent->getApplication()->getServiceManager()->get('doctrine.entitymanager.orm_default');
$config = $mvcEvent->getApplication()->getServiceManager()->get('config');
$defaultUserRole = $em->getRepository('SamUser\Entity\Role')->find($config['user_role_id']);
$user->addRole($defaultUserRole);
});
}
Maybe someone will offer better solution.
This work too.
public function onBootstrap(MvcEvent $mvcEvent)
{
$zfcServiceEvents = $mvcEvent->getApplication()-getServiceManager()->get('zfcuser_user_service')->getEventManager();
$zfcServiceEvents->attach('register', function($e) use($mvcEvent) {
$user = $e->getParam('user');
$em = $mvcEvent->getApplication()->getServiceManager()-get('doctrine.entitymanager.orm_default');
$defaultUserRole = $em->getRepository('SamUser\Entity\Role')-find('id_of_your_role_on_table_role_for_example: '2'');
$user->addRole($defaultUserRole);
});
}
I just used a MySQL trigger
DROP TRIGGER IF EXISTS `user_role_after_insert_trig`;
DELIMITER //
CREATE TRIGGER `user_role_after_insert_trig` AFTER INSERT ON `user`
FOR EACH ROW begin
insert into user_role_linker (user_id,role_id) values (new.user_id, 5);
end
//
DELIMITER ;

Integrating Zend Framework 1.11 with MongoDB using Doctrine ODM

Does any know of a way to integrate zend framework with Mongo using Doctrine 2 beta ODM?
I've viewed the zendcast video on integrating with Doctrine 2 ORM for MySQL but Bisna was never updated to support Mongo.
I guess I can try and hack Bisna to get it working but I'd like to know if someone else has already found a way to get it working.
It's pretty easy to write a Zend Bootstrap Resource.
Here is one I use:
<?php
namespace Cob\Application\Resource;
use Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ODM\MongoDB\DocumentManager,
Doctrine\MongoDB\Connection,
Doctrine\ODM\MongoDB\Configuration,
Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver,
Doctrine\Common\EventManager;
/**
* Creates a MongoDB connection and DocumentManager instance
*
* #author Andrew Cobby <cobby#cobbweb.me>
*/
class Mongo extends \Zend_Application_Resource_ResourceAbstract
{
/**
* #return \Doctrine\ODM\MongoDB\DocumentManager
*/
public function init()
{
$options = $this->getOptions() + array(
'defaultDB' => 'my_database',
'proxyDir' => APPLICATION_PATH . '/domain/Proxies',
'proxyNamespace' => 'Application\Proxies',
'hydratorDir' => APPLICATION_PATH . '/domain/Hydrators',
'hydratorNamespace' => 'Application\Hydrators'
);
$config = new Configuration();
$config->setProxyDir($options['proxyDir']);
$config->setProxyNamespace($options['proxyNamespace']);
$config->setHydratorDir($options['hydratorDir']);
$config->setHydratorNamespace($options['hydratorNamespace']);
$config->setDefaultDB($options['defaultDB']);
$reader = new AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ODM\MongoDB\Mapping\\');
$config->setMetadataDriverImpl(new AnnotationDriver($reader, $this->getDocumentPaths()));
$evm = new EventManager();
$evm->addEventSubscriber(new SlugSubscriber());
return DocumentManager::create(new Connection(), $config, $evm);
}
public function getDocumentPaths()
{
$paths = array();
foreach(new \DirectoryIterator(APPLICATION_PATH . '/modules') as $module){
$path = $module->getPathname() . '/src/Domain/Document';
if((!$module->isDir() || $module->isDot()) || !is_dir($path)){
continue;
}
$paths[] = $path;
}
if(!count($paths)){
throw new \Exception("No document paths found");
}
return $paths;
}
}
Though you'll have to update the getDocumentPaths() method to suit your application directory structure.
I wrote my own very simple application resource plugin and container, using Guilherme's integration suite for inspiration.
I'm sure this could be much more featured in terms of capturing options but I figured I'll add those in as I need them.
See https://gist.github.com/891415