getResourceSingleton() Not working multiple time on single call magento 1 - php

We are using Magento 1.
We have used this code:
Mage::getResourceSingleton('catalog/category_tree')->load();
$tree = Mage::getResourceSingleton('catalog/category_tree')->load();
$root = $tree->getNodeById($rootCategoryId);
if($root && $root->getId() == 1) {
$root->setName(Mage::helper('catalog')->__('Root'));
}
$collection = Mage::getModel('catalog/category')->getCollection()
->addAttributeToSelect('name')
->addAttributeToFilter('is_active','1');
//->addAttributeToFilter('display_mode',array('nlike'=>'PAGE'))
//->setLoadProductCount(true)
//->setProductStoreId($store)
//->addAttributeToFilter('include_in_menu','1');
$tree->addCollectionData($collection, true);
We have created a api, and calling this in widget categories as well as category listing, but its only loading for last one only, not resulting for all calls.
kindly suggest a proper way

that is the way a singleton works, use model instead.
Mage::getResourceModel('catalog/category_tree')

Related

PHP/Propel delete record 1:n

I've got two tables: step and links joined 1:n. I'm aiming to maintain the links through the step objects. I retrieve all steps from the database and populate the relation with the links table. I persist the step object containing a collection of links to JSON and return it to the front end using REST.
That means that if a step is linked or unlinked to another step in the front end I send the entire step back to the backend including a collection of links. In the back end I use the following code:
public function put($processStep) {
if (isset($processStep['Processesid']) && isset($processStep['Coordx']) && isset($processStep['Coordy'])) {
$p = $this->query->findPK($processStep['Id']);
$p->setId($processStep['Id']);
$p->setProcessesid($processStep['Processesid']);
if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']);
if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']);
$p->setCoordx($processStep['Coordx']);
$p->setCoordy($processStep['Coordy']);
$links = $p->getLinksRelatedByFromstep();
$links->clear();
foreach ($processStep['Links'] as $link) {
if (!isset($link['Linkid'])) {
$newLink = new \Link();
$newLink->setFromstep($link['Fromstep']);
$newLink->setTostep($link['Tostep']);
$links->prepend($newLink);
}
}
$p->save();
return $p;
} else {
throw new Exceptions\ProcessStepException("Missing mandatory fields.", 1);
}
}
I'm basically deleting every link from a step and based upon the request object I recreate the links. This saves me the effort to compare what links are deleted and added. The insert work like a charm Propel automatically creates the new links. Thing is it doesn't delete like it inserts. I've checked the object that is being persisted ($p) and I see the link being deleted but in the MySQL log there is absolutely no action being performed by Propel. It looks like a missing member from the link collection doesn't trigger a dirty flag or something like that.
Maybe I'm going about this the wrong way, I hope someone can offer some advice.
Thanks
To delete records, you absolutely always have to use delete. The diff method on the collection is extremely helpful when determining which entities need added, updated, and deleted.
Thanks to Ben I got on the right track, an explicit call for a delete is not needed. I came across a function called: setRelatedBy(ObjectCollection o) I use this function to provide a list of related objects, new objects are interpreted as inserts and omissions are interpreted as deletes.
I didn't find any relevant documentation regarding the problem so here's my code:
$p = $this->query->findPK($processStep['Id']);
$p->setId($processStep['Id']);
$p->setProcessesid($processStep['Processesid']);
$p->setCoordx($processStep['Coordx']);
$p->setCoordy($processStep['Coordy']);
if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']);
if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']);
//Get related records, same as populaterelation
$currentLinks = $p->getLinksRelatedByFromstep();
$links = new \Propel\Runtime\Collection\ObjectCollection();
//Check for still existing links add to new collection if so.
//This is because creating a new Link instance and setting columns marks the object as dirty creating an exception due to duplicate keys
foreach ($currentLinks as $currentLink) {
foreach ($processStep['Links'] as $link) {
if (isset($link['Linkid']) && $currentLink->getLinkid() == $link['Linkid']) {
$links->prepend($currentLink);
break;
}
}
}
//Add new link objects
foreach ($processStep['Links'] as $link) {
if (!isset($link['Linkid'])) {
$newLink = new \Link();
$newLink->setFromstep($link['Fromstep']);
$newLink->setTostep($link['Tostep']);
$links->prepend($newLink);
}
}
//Replace the collection and save the processstep.
$p->setLinksRelatedByFromstep($links);
$p->save();

How to call getItem() & getOptionList()in an Observer.php - Magento

I have an observer (checkout_cart_product_add_after) and would like to get the selected custom options array.
I have found the two elements I require in: app/design/frontend/MY-THEME/default/template/checkout/cart/item/default.phtml
Which are:
1. $_item = $this->getItem();
2. $_options = $this->getOptionList();
I just don't know how to get them in an observer i.e. what else I have to call.
Thanks in advance!!
please go to the following url
http://inchoo.net/magento/updating-options-of-configurable-product-that-is-already-in-the-cart/
thanks
Observers always start returning data from their respective "events".
So in your case you have to first get checkout-quote object in your observer's function code using below line:
$quote = $observer->getEvent()->getQuote();
Then you can get custom options for each item in items collection from the quote like below:
$quoteItems = $quote->getAllItems();
$helper = Mage::helper('catalog/product_configuration');
foreach ($quoteItems as $item) {
$product = $item->getProduct();
$options = $helper->getCustomOptions($item);
//do anything with $options.
}
Try this. hope it helps.
Also have you already referred below links ?
https://magento.stackexchange.com/questions/16804/get-the-object-of-the-whole-quotation-in-observer
https://magento.stackexchange.com/questions/63752/get-products-final-price-with-its-selected-custom-option-on-add-to-cart
https://magento.stackexchange.com/questions/6368/how-to-get-selected-custom-options-on-onepage

Attach simple products to a configurable product programmatically

I am trying to join some existing simple products programmatically to an existing configurable product.
I hardly found any hints / documentation on this. I examined the MAGMI Magento Mass Importer Plugin (in particular the magmi_productimportengine.php-file) with no success.
After that I found this snippet:
function attachProductToConfigurable($childProduct, $configurableProduct)
{
$loader = Mage::getResourceModel('catalog/product_type_configurable')
->load($configurableProduct, $configurableProduct->getId());
$ids = $configurableProduct
->getTypeInstance()
->getUsedProductIds();
$newids = array();
foreach ($ids as $id) {
$newids[$id] = 1;
}
$newids[$childProduct->getId()] = 1;
//$loader->saveProducts( $_configurableProduct->getid(), array_keys( $newids ) );
$loader->saveProducts($configurableProduct, array_keys($newids));
}
But when I am trying to call the function like this:
$sProduct = Mage::getModel('catalog/product')
->loadByAttribute('sku', $v);
$cProduct = Mage::getModel('catalog/product')
->loadByAttribute('sku', $sku);
attachProductToConfigurable($sProduct, $cProduct);
(each simple product SKU gets passed step by step to the configurable product)
Fatal error: Call to a member function getId() on a non-object in ... on line 1018
which is this line from the function itself
$loader = Mage::getResourceModel('catalog/product_type_configurable')
->load($configurableProduct, $configurableProduct
->getId());
Since I do not find anything similar to joining simple SKUs to an existing configurable product, I am stuck looking up what might be wrong upon initializing the function calls, resource models etc..
Any ideas on what to keep an eye on to get this going are highly appreciated.
Give this a try:
Mage::getResourceSingleton('catalog/product_type_configurable')
->saveProducts($mainConfigrableProduct, $simpleProductIds);
Where $mainConfigrableProduct must be an instance of the configurable product, and $simpleProductIds is an array with the ids of the simple products associated to the configurable products.
On a side note, be very careful when doing this. The simple products must be in the same attribute set as the configurable products. Here is what can happen if they are not.

Creating a new Laravel 4 model class with a string variable

TL;DR is at the end to cut to the chase.
I have a lot of belongsTo() models that can have any number of records, and I'm trying to bind them to an edit form. I have the following foreach that creates the form elements:
#foreach ($department->department_10 as $key => $value)
{{ Form::select(
'department_10['.(isset($value->pk_department_10)?$value->pk_department_10:0).']',
$department_10_opts,
(isset($value->department_10)?$value->department_10:''),
array('class'=>'form-control input-md department_10', 'placeholder'=>'Other Types of Service')) }}
#endforeach
Since there can be 0 records (rows?) that belong to the model, to simplify my #foreach, I wanted to create a "blank" instance of the model. Additionally, because I'm going to have to deal with about 70 more cases like this, I created a function that would create the new blank model. Here's the function (in my controller for lack of a better place):
function mkBlankModel($parentModel, $newModel){
if(count($parentModel->$newModel) === 0){
$parentModel->$newModel[0] = new $newModel();
$parentModel->$newModel[0]->fk_department = $parentModel->pk_department;
$parentModel->$newModel[0]->$newModel = '';
}
return $parentModel;
}
When I run it, I don't get any errors, but I do get unexpected results and I can't really make sense of them:
Test Step 1) View the edit page while loading a record with 2 department_10's. It works as expected; loads two fields properly.
Test Step 2) View the edit page while loading a record with 0 department_10's. The page loads but without any fields. Because apparently my function didn't work, so I verify by dumping dump($department->$department_10) and it confirms this.
Test Step 3) I replace the $parentModel->$newModel[0] with $parentModel->department_10[0] like so:
function mkBlankModel($parentModel, $newModel){
if(count($parentModel->$newModel) === 0){
$parentModel->department_10[0] = new $newModel();
$parentModel->department_10[0]->fk_department = $parentModel->pk_department;
$parentModel->department_10[0]->$newModel = '';
}
return $parentModel;
}
And both scenarios (with records and without) work just fine. So my problem likely isn't Laravel specific, but I'm just curious how I can accomplish this.
TL;DR:
I'm trying to create a model instance for a parent model, if one doesn't exist, so a blank field will be created by my #foreach loop in my edit.blade.php's form. I can do this just fine if I manually spell out the model's name when creating it, but since I'll be doing this frequently, I'd prefer to define the class, and populate it with a string.
So I figured it out; I needed to wrap the $newModel in curly-brackets:
function mkBlankModel($parentModel, $newModel){
if(count($parentModel->$newModel) === 0){
$parentModel->{$newModel}[0] = new $newModel();
$parentModel->{$newModel}[0]->fk_department = $parentModel->pk_department;
$parentModel->{$newModel}[0]->$newModel = '';
}
return $parentModel;
}
More info here: http://php.net/manual/en/language.types.string.php#language.types.string.parsing.complex

Get Child categories magento

Trying to get child of a specific category which is active. Please help. I am having trouble doing it. I'm currently able to show them all but not specifically. Would appreciate any help.
$category = Mage::getModel('catalog/category')->load(2);
$category->getChildCategories();
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
here is code to load active category
/* Load category by id*/
$cat = Mage::getModel('catalog/category')->load($id);
/*Returns comma separated ids*/
$subcats = $cat->getChildren();
//Print out categories string
#print_r($subcats);
foreach(explode(',',$subcats) as $subCatid)
{
$_category = Mage::getModel('catalog/category')->load($subCatid);
if($_category->getIsActive())
{
$caturl = $_category->getURL();
$catname = $_category->getName();
if($_category->getImageUrl())
{
$catimg = $_category->getImageUrl();
}
echo '<h2><img src="'.$catimg.'" alt="" />'.$catname.'</h2>';
}
}
?>
hope this is sure help you.
As mentioned by mhaupt, it is faster to load a collection rather than each category in a loop. But, as far as I am concerned, there is no need to manually load the child categories. Basically this is what $category->getChildrenCategories() already does.
There is also a filter to get active categories only. Just call addIsActiveFilter() on the collection.
a.) Load active child categories via getChildren()
// 1. Get a list of all child category ids (e.g "12,23,11,42")
$subcategoryIds = $category->getChildren();
// 2. Create collection
$categoryCollection = Mage::getModel('catalog/category')->getCollection();
// 3. Add all attributes to select, otherwise you can not
// access things like $cat->getName() etc.
$categoryCollection->addAttributeToSelect('*');
// 4. Filter by ids
$categoryCollection->addIdFilter($subcategoryIds);
// 5. Add filter to collection to get active categories only
$categoryCollection->addIsActiveFilter();
b.) Load active child categories with getChildrenCategories()
// 1. Load collection
$categoryCollection= $category->getChildrenCategories();
// 2. Add filter to collection to get active categories only
$categoryCollection->addIsActiveFilter();
The collection will be loaded form the database as soon as it is accessed. If the collection is not loaded and $subcategories->count() is called only a "SELECT count(*)" will be fired against the database (in contrast to count($subcategories) which will force the collection to load itself).
Iterating the collection
foreach($categoryCollection as $category) {
echo $category->getName();
}
If you add more filters to the collection after accessing it, the collection will not load itself again automatically. To apply changes to the collection, just call $categoryCollection->load() to reload the collection from the database.
Those who are saying to use getAllChildren() instead of getChildren() are simply wrong.
Both methods return the exact same thing, with one difference, getAllChildren(true) will return an array instead of a comma delimited string. getAllChildren($bool asArray) defaults to false. My point being that either way you're going to have to use
Mage::getModel('catalog/category')->load($catId);
inside of a loop unless you use the function below.
private function fetchCatsById($onlyThese)
{
$cats = Mage::getModel('catalog/category')
->getCollection(true)
->addAttributeToSelect('*')
->addIdFilter($onlyThese)
->addAttributeToFilter('level','2')
->addIsActiveFilter();
return $cats;
}
$cats = $this->fetchCatsById($onlyThese);
The one answer liyakat wrote, should not be used in professional shops, because it raises a performance issue, because of the multiple n time loads of the category object, rather use the collection of categories for that, get all children
$cat->getAllChildren()
, then limit the category collection by the needed category ids like
$coll->addIdFilter($idFilter);
then you won't have to load n times against the database.
Please do keep in mind that loads within loops are one of the most often used bad code examples in any Magento projects and to avoid them!
Hello you will see below code
$category_model = Mage::getModel('catalog/category');
$_category = $category_model->load(13);
$all_child_categories = $category_model->getResource()->getAllChildren($_category);
print_r($all_child_categories);
If you want any number of subcategories of parent category than Click here http://magentoo.blogspot.com/2014/01/get-all-subcategories-of-parent-category-magento.html

Categories