I am new in magento i have tried to remove items in cart when call this event checkout_cart_product_add_after when i try this code nothing can doing. any body help me. thanks.
$myProductId=20;
$product = Mage::getModel('catalog/product')->setStoreId(Mage::app()->getStore()->getId())->load($myProductId);
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getItemByProduct($product);
if ($cartItems) { $quote->removeItem($cartItems->getId())->save();}
The ItemId (ID of an item in the cart) is not the same as the ProductId of the product it represents. Try iterating through the items in the cart until you find the one with the ProductId you want to remove:
$cartHelper = Mage::helper('checkout/cart');
$items = $cartHelper->getCart()->getItems();
foreach ($items as $item) {
if ($item->getProduct()->getId() == $productId) {
$itemId = $item->getItemId();
$cartHelper->getCart()->removeItem($itemId)->save();
break;
}
}
Please try as described above.
Below code work for me you can try this you can call this function using ajax or post method put this function inside your controller and call it. pass the customer id and product it to it
public function removeCartAction()
{
$productId = trim($_POST['productId']);
$customer = trim($_POST['requesterId']);
if ($customer) {
$storeId = Mage::app()->getWebsite(true)->getDefaultGroup()->getDefaultStoreId();
// get quote table cart detail of all customer added
$quote = Mage::getModel('sales/quote')->setStoreId($storeId)->loadByCustomer($customer);
if ($quote) {
$collection = $quote->getItemsCollection(false);
if ($collection->count() > 0) {
foreach( $collection as $item ) {
if ($item && $item->getId()) {
$quote->removeItem($item->getId());
$quote->collectTotals()->save();
}
}
}
}
}
}
To remove item by specific item_id from cart(quote) you can use this:
$cart = Mage::getModel('checkout/session')->getQuote();
$cartHelper = Mage::helper('checkout/cart');
$items = $cart->getAllVisibleItems();
foreach($items as $item):
if($item->getItemId() == $id):
$itemId = $item->getItemId();
$cartHelper->getCart()->removeItem($itemId)->save();
break;
endif;
endforeach;
Execute this you will get the output
$product = $observer->getEvent()->getProduct();
$cart = Mage::getSingleton('checkout/cart');
foreach ($cart->getQuote()->getItemsCollection() as $_item) {
if ($_item->getProductId() == $productId) {
$_item->isDeleted(true);
//Mage::getSingleton('core/session')->addNotice('This product cannot be added to shopping cart.');
}
}
Related
Is it possible fetching data from a cached xml file and then showing them on front end?
I was thinking doing it in a TYPO3 extension and with its domain model (and getter/setter) but without a database table. And then filling in data with SimpleXML just to "store" them in memory. At least display the data from domain model with fluid on front end. But I don't know is this approach right or is there a better way to do that? In particular setting up the persistence layer I don't understand.
For any help I thank you very much for your effort in advance.
I found an "acceptable" solution. My approach for that was:
Get all items from xml file
Add a slug field
Sort the items
Display sorted items on the front end
Create unique pretty url
1. Get all items from xml file
Controller: listAction, detailAction
public function listAction() {
$jobs = $this->xmlDataRepository->findAll();
$jobsArray = $this->simpleXmlObjToArr($jobs);
$jobsArraySorted = $this->sortJobsByTitle($jobsArray);
$this->view->assign('jobs', $jobsArraySorted);
}
public function detailAction($slugid) {
$job = $this->xmlDataRepository->findBySlugWithId($slugid);
$this->view->assign('job', $job[0]);
}
Repository: findAll, findBySlugWithId
public function findAll() {
$objectStorage = new ObjectStorage();
$dataFolder = ConfigurationService::setDataFolder();
$xmlFile = glob($dataFolder . '*.xml')[0];
$xmlData = simplexml_load_file($xmlFile,'SimpleXMLElement',LIBXML_NOWARNING);
// error handling
if ($xmlData === false) {
...
}
foreach($xmlData->children() as $job) {
$objectStorage->attach($job);
}
return $objectStorage;
}
public function findBySlugWithId($slugid) {
// get id from slugid
$id = substr($slugid,strrpos($slugid,'-',-1)+1);
$objectStorage = new ObjectStorage();
$dataFolder = ConfigurationService::setDataFolder();
$xmlFile = glob($dataFolder . '*.xml')[0];
$xmlData = simplexml_load_file($xmlFile,'SimpleXMLElement',LIBXML_NOWARNING);
// error handling
if ($xmlData === false) {
...
}
$jobfound = false;
foreach($xmlData->children() as $job) {
if ($job->JobId == $id) {
$objectStorage->attach($job);
$jobfound = true;
}
}
// throw 404-error
if (!$jobfound) {
$response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
$GLOBALS['TYPO3_REQUEST'],
'Ihre angeforderte Seite wurde nicht gefunden',
['code' => PageAccessFailureReasons::PAGE_NOT_FOUND]
);
throw new ImmediateResponseException($response, 9000006460);
}
return $objectStorage;
}
2. Add a slug field (controller)
protected function simpleXmlObjToArr($obj) {
// 2-dimensional array
$array = [];
foreach($obj as $item){
$row = [];
foreach($item as $key => $val){
$row[(string)$key] = (string)$val;
}
//add slug field, build it with Title
$row['Slug'] = $this->convertToPathSegment($row['Titel']);
// add $row to $array
array_push($array,$row);
}
return $array;
}
3. Sort the items (controller)
protected function sortJobsByTitle(array $jobs) {
$title = array();
$id = array();
foreach ($jobs as $key => $job) {
$title[$key] = $job['Titel'];
$id[$key] = $job['JobId'];
}
// sort jobs array according to title, uid (uid because if there are courses with the same title!)
array_multisort($title,SORT_ASC, $id,SORT_ASC, $jobs,SORT_STRING);
return $jobs;
}
4. Display sorted items on the front end (templates)
List.html:
...
<ul>
<f:for each="{jobs}" as="job">
<li>
<f:comment>
<f:link.action class="" pageUid="2" action="show" arguments="{id: job.JobId, slug: job.Slug}">{job.Titel}</f:link.action> ({job.JobId})<br>
<f:link.action class="" pageUid="2" action="detail" arguments="{xml: job}">NEW {job.Titel}</f:link.action> ({job.JobId})
</f:comment>
<f:variable name="slugid" value="{job.Slug}-{job.JobId}"/>
<f:link.action class="" pageUid="2" action="detail" arguments="{slugid: slugid}"><f:format.raw>{job.Titel}</f:format.raw></f:link.action> ({job.JobId})
</li>
</f:for>
</ul>
...
Detail.html:
...
<f:image src="{job.Grafik}" width="500" alt="Detailstellenbild" />
<p><strong><f:format.raw>{job.Titel}</f:format.raw></strong> ({job.JobId})</p>
<p>Region: {job.Region}</p>
<f:format.html>{job.Beschreibung}</f:format.html>
...
5. Create unique pretty url
...
routeEnhancers:
XmlJobDetail:
type: Extbase
limitToPages:
- 2
extension: Wtdisplayxmldata
plugin: Displayxmldata
routes:
-
routePath: '/{job-slugid}'
_controller: 'XmlData::detail'
_arguments:
job-slugid: slugid
defaultController: 'XmlData::list'
aspects:
job-slugid:
type: XmlDetailMapper
Routing/Aspect/XmlDetailMapper.php:
use TYPO3\CMS\Core\Routing\Aspect\StaticMappableAspectInterface;
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
class XmlDetailMapper implements StaticMappableAspectInterface {
/**
* {#inheritdoc}
*/
public function generate(string $value): ?string
{
return $value !== false ? (string)$value : null;
}
/**
* {#inheritdoc}
*/
public function resolve(string $value): ?string
{
return isset($value) ? (string)$value : null;
}
}
I have a ContactsTable.php module and an function like this:
public function getContactsByLastName($last_name){
$rowset = $this->tableGateway->select(array('last_name' => $last_name));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row record");
}
return $row;
}
which is ok, but it only returns one row.
The problem is in my database I have multiple records with the same Last Name, so my question is:
How can I return a set of data?
I tried this:
$where = new Where();
$where->like('last_name', $last_name);
$resultSet = $this->tableGateway->select($where);
return $resultSet;
but it doesn't work.
Your first function should work as you expect, just remove line
$row = $rowset->current();
So, complete function should look like this:
public function getContactsByLastName($last_name){
$rowset = $this->tableGateway->select(array('last_name' => $last_name));
foreach ($rowset as $row) {
echo $row['id'] . PHP_EOL;
}
}
More info you can find in documentation http://framework.zend.com/manual/2.2/en/modules/zend.db.table-gateway.html
You can use the resultset to get array of rows:
public function getContactsByLastName($last_name) {
$select = new Select();
$select->from(array('u' => 'tbl_users'))
->where(array('u.last_name' => $last_name));
$statement = $this->adapter->createStatement();
$select->prepareStatement($this->adapter, $statement);
$result = $statement->execute();
$rows = array();
if ($result->count()) {
$rows = new ResultSet();
return $rows->initialize($result)->toArray();
}
return $rows;
}
Its working for me.
I'm using the zend framework with centurion and I'm having a problem with my form. I have fields num_ordre and code, both of which are primary keys and I have columns in my table named conca, it's the concatenation of two fields, num_ordre and code.
My question is, in my method post, I want to test if the concatanation of num_ordre and code already exists in my database; but the problem is how to take a value of to fields before posting it.
This is my code
public function postAction(){
$this->_helper->viewRenderer->setNoRender(TRUE);
$user = new Param_Model_DbTable_Verification();
$form= $this->_getForm();
$form->getElement('Num_ordre')->addValidator(new Zend_Validate_Db_NoRecordExists('verifications','Num_ordre'));
$form->getElement('Num_ordre')->setRequired(true);
$posts = $this->_request->getPost();
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$row=$user->createRow();
$row->code=$this->_getParam('code');
$row->Num_ordre=$this->_getParam('Num_ordre');
$row->Libelle_champ=$this->_getParam('Libelle_champ');
$row->comparaison=$this->_getParam('comparaison');
$row->formule=$this->_getParam('formule');
$row->obligatoire=$this->_getParam('obligatoire');
$row->Req_traduction=$this->_getParam('Req_traduction');
$row->tolerance_erreur=$this->_getParam('tolerance_erreur');
$row->Mess_erreur=$this->_getParam('Mess_erreur');
$row->conca=$this->_getParam('Num_ordre').$this->_getParam('code');
$row->save();
if( isset ($posts['_addanother'])){
$_form = $this->_getForm();
$_form->removeElement('id');
$this->_helper->redirector('new','admin-verification');
}
else
$this->_helper->redirector(array('controller'=>'Admin-verification'));
}else{
parent::postAction();
}
}}
How about you just check it like this ?
public function postAction(){
$this->_helper->viewRenderer->setNoRender(TRUE);
$user = new Param_Model_DbTable_Verification();
$form= $this->_getForm();
$form->getElement('Num_ordre')->addValidator(new Zend_Validate_Db_NoRecordExists('verifications','Num_ordre'));
$form->getElement('Num_ordre')->setRequired(true);
$posts = $this->_request->getPost();
if ($this->getRequest()->isPost()) {
$formData = $this->getRequest()->getPost();
$mdl = new Model_Something(); //Call your model so you can test it
//Add a condition here
if ($form->isValid($formData) && $mdl->uniqueConcatenated($this->_getParam('num_ordre'), $this->_getParam('code')) {
$row=$user->createRow();
/**truncated, keep your existing code here**/
}
}
}
Then in your model Model_Something
public function uniqueConcatenated($numOrder, $code) {
$concatenated = $numOrder.$code;
//Check for the existence of a row with the concatenated field values
$select = $this->select();
$select->where('concatenatedField = '.$concatenated);
$row = $this->fetchRow($select);
return $row;
}
Hope this helps
You could manually call isValid on the validator:
$formData = $this->getRequest()->getPost();
if ($form->isValid($formData)) {
$formValues = $form->getValues();
$uniqueValidator = new Zend_Validate_Db_NoRecordExists('verifications','conca');
if ($uniqueValidator->isValid($formValues['Num_ordre'] . $formValues['Num_ordre'])) {
// valid
} else {
// not unique
}
}
untested code
This is my code:
public function is_existing($url) {
$query = $this->select()
->where("url=?",$url);
if(!$query) {
return false;
} else {
$row = $this->fetchRow($query);
$row = $row->toArray();
return $row;
}
}
But sometimes, I receive
Fatal error: Call to a member function toArray() on a non-object in...
Is it right to use if(!$query) to check the existing rows in DB?
Change your code to this
public function is_existing($url) {
$query = $this->select()
->where("url=?",$url);
$row = $this->fetchRow($query);
if(!$row) {
return false;
} else {
return $row->toArray();
}
}
Because $query object will always be created irrespective $url matches record or not hence will always pass if condition .
Is it right to use if(!$query) to check the existing rows in DB ?
No, you should evaluate the result of fetchRow to determine if there are results, fetchRow either returns a Zend_Db_Table_Row or null if no rows are found.
public function is_existing($url) {
$query = $this->select()
->where("url=?",$url);
$row = $this->fetchRow($query);
if(is_null($row)) {
return false;
} else {
return $row->toArray();
}
}
I have basically the following table,
Categories
id name categories_id_categories
1 Clothes null
2 Shirts 1
3 Pants 1
4 Electronics null
5 Tv 4
The table stores categories and sub-categories, if the categories_id_categories is null theyre main categories else theyre sub-categories of the category with that id. I want to show this on a page so I created this functions on my Categories model:
public function getAllCategories()
{
$select = $this->select()
->where('categories_id_categories IS NULL');
return $this->fetchAll($select);
}
public function getAllSubCategories()
{
$select = $this->select()
->where('categories_id_categories IS NOT NULL');
return $this->fetchAll($select);
}
And on my controller:
$categories = new Model_DbTable_Categories();
$categoryList = $categories->getAllCategories();
$categoriesAll = array();
foreach ($categoryList->toArray() as $category) {
$subCategories = $categories->getSubCategoriesByCategory($category['id']);
$category['sub_categories'] = $subCategories->toArray();
$categoriesAll[] = $category;
}
$this->view->categoryList = $categoriesAll;
So categoryList is an array with all the categories and the key sub_categories is another array with all sub-categories. This works but I was wondering if there was a way to do it using objects instead of an array, and maybe using just one query instead of 2?
If I select all from the table I'd get categories and sub-categories but then I'd have to move some logic into the view to select the sub-categories I believe.
Thanks in advance!
Just put $id to getAllSubcategories and create getSubCategories in your model like this:
public function geSubCategories($id = null)
{
$select = $this->select();
if ( $id == null ) {
$select->where('categories_id_categories IS NOT NULL');
}
else {
$select->where('id = ?', $id);
}
return $this->fetchAll($select);
}
$sql = "SELECT * FROM TABLE_NAME WHERE ID = 1";
$rows = $db->fetchAll($sql);
//One row return array
echo $rows[0]['field_name'];
http://framework.zend.com/manual/1.12/en/zend.db.table.row.html
http://framework.zend.com/manual/1.12/en/zend.db.table.rowset.html