Traverse XML file to find products recursively - php

I am trying to read remote XML file to find products in a specific category. I am facing issue because XML file has nested categories and each category has products. I need help in preparing a recursive function which will output products from a specific category given the category name.
Here is the code i have started with
<?php
$xml = simplexml_load_file('https://www.deere.com/en/us-en.taxonomy');
getProducts($xml);
function getProducts($xml) {
foreach ($xml as $obj) {
if ($obj->getName() == 'en_us_tractors') { //if category name is en_us_tractors
if ($obj->children()) {
foreach ($obj->children() as $child) {
echo '<h1>' . $child->name . '</h1>';
if ($child->products) {
foreach ($child->products as $product) {
foreach ($product as $p) {
echo 'sku is ' . $p->sku . '<br>';
echo 'path is ' . $p->path . '<br>';
}
}
}
}
}
}
}
}

It's simple to use XPath to find the data, this finds all of the products inside the category you want...
$xml = simplexml_load_file('https://www.deere.com/en/us-en.taxonomy');
$products = $xml->xpath("//en_us_tractors//products/*");
foreach ( $products as $product ){
echo $product->sku."/".$product->path.PHP_EOL;
}

Related

Getting XML node names without duplicating in simplexml_load_file

I'm getting the node names of an XML using this code:
$url = 'https://www.toptanperpa.com/xml.php?c=shopphp&xmlc=e7ef2a0122';
$xml = simplexml_load_file($url) or die("URL Read Error");
echo $xml->getName() . "<br>";
foreach ($xml->children() as $child) {
echo $child->getName() . "<br>";
foreach ($child->children() as $child2) {
echo $child2->getName() . "<br>";
foreach ($child2->children() as $child3) {
echo $child3->getName() . "<br>";
foreach ($child3->children() as $child4) {
echo $child4->getName() . "<br>";
}
}
}
}
I'm getting the nodes and children correctly, however, it's duplicating.
Result is as below:
urunler
urun
urun_aktif
urun_metaKeywords
urun_metaDescription
urun_url
urun
urun_aktif
urun_metaKeywords
urun_metaDescription
urun_url
Should I just use array_unique or is there a better method?
Thanks
i used recursive function this is simple
function getChildrens($x) {
$children = array();
array_push($children, $x->getName());
foreach ($x->children() as $chld) {
$children = array_merge($children, getChildrens($chld));
}
return array_unique($children);
}
echo implode("<br>", getChildrens($xml));

how to pass input value via jquery to php in magento adminhtml

In Catalog > Attribute > manage atrribute > Manage label/ options. I have created a module that will pull/display
options of selected category. i have done all the code that will do the work.
Now the problem is here:
i want to pass a value of selected option (category id) from html list.
This is how I pull and display the list of my categories.
app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Options.php
public function getCategoryCollection(){
$parentCategoryName = 'Default Category';
$collection = Mage::getResourceModel('catalog/category_collection')
->addFieldToFilter('name', $parentCategoryName)
->getFirstItem()// The parent category
->getChildrenCategories();
$html = "<select>";
$html = $html. "<option>Select</option>";
foreach ($collection as $items => $item) {
$html = $html . "<option value=" . $item->getEntityId() . ">" . $item->getName() . "</option>";
}
$html = $html . "</select>";
return $html;
}
this is the function I want to pass when user do "onchange()" on the html select list
app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Options.php
public function getCategoryOptions(){
// Id of category we want to get attributes for
$categoryId = 123;
$sizeOption = array();
// Products in that category
$products = Mage::getModel('catalog/category')->load($categoryId); //put your category id here
$productslist = $products->getProductCollection()->addAttributeToSelect('*');
foreach($productslist as $product)
{
$sizeOption[] = $product['attribute_variant'];
}
return $sizeOption;
}
app/design/adminhtml/default/default/template/eav/attribute/options.phtml
I use "<td><?php echo $this->getCategoryCollection(); ?></td>" to display the select options list.
Your help would be appreciated.

Shop with two items

I have two models. Shop and Item. I am trying to retrieve all of the shops, with 2 items each - however, I cannot get it working. The value of $shop['items'] is not changing.
foreach($shops as &$shop) {
foreach($shop->items as $item) {
$item->formatPreview();
}
$shop = $shop->toArray();
$shop['items'] = array_slice($shop['items'], 2);
}
How can I achieve this, and are there a smarter way using Eloquent?
EDITED
$shops = Shop::with('items')->get();
foreach ($shops as $shop) {
echo 'shop name: '. $shop->name . '<br>';
if($shop->items()->count()) {
foreach ($shop->items()->take(2)->get() as $item) {
echo 'item: ' . $item->name . '<br>';
}
}
echo '<hr>';
}
I was testing this inside a route closure so please format it as you want orfourse. Hope it is working now.

Errors simplexml - Complicated URL

I am trying to display items from an XML feed on a page
This is my code...
$feed = 'http://awebsite.co.uk/directory/rssfeed.php?thecondition=(title%20LIKE%20'%british%'%20OR%20description%20LIKE%20'%british%')';
$xml = simplexml_load_file("$feed");
if ( $xml->channel->item !='' ) {
foreach ($xml->channel->item as $item) {
echo '<li>' . $item->title . '</li>';
}
}
else { echo 'None'; }
However, due to the complicated feed URL it is giving lots of errors.
Note: I have changed the domain in the URL for this example.
How can I make this work?
Can't judge anything without seeing the XML source first but if it's a standard RSS channel file you should be iterating through your items something like this:
$items = $xml->xpath('/channel/item');
foreach ($items as $item) {
echo '<li>' . $item->title . '</li>';
}
Also the initial condition: if ( $xml->channel->item !='' ) {/*...*/} isn't really going to work.

PHP + RSS duplicate elements

Im using this PHP to get a list of Title's from an RSS feed:
<?php require_once('magpie/rss_fetch.inc');
$rss = fetch_rss('http://live.visitmix.com/Sessions/RSS');
foreach ($rss->items as $item) {
$cat = $item['category'];
$title = $item['title'];
echo '<li class="'.$cat.'">'.$title.'</li>';
}
?>
I want to use <category> and add it as the class, however the <category> element appears for each <item> 1,2,3,4 or more times depending on the Title. How can I take the category element and seperate each category with a space if there is more than 1?
what about accumulating the categories in an array and then implode the array?
$categoriesArray = array();
foreach ($rss->items as $item) {
array_push($categoriesArray, $item['category']);
}
$categories = implode(" ", $categoriesArray);
EDIT TO ADD
If the categories are cumulated, you can try something like this:
$categoriesByTitle = array();
foreach ($rss->items as $item) {
$currentTitle = $item['title'];
$categories = $categoriesByTitle[$currentTitle];
if ($categories == NULL) {
$categories = array();
$categoriesByTitle[$currentTitle] = $categories;
}
if (!in_array($item['category'], $categories)) {
array_push($categories, $item['category']);
}
}
foreach ($categoriesByTitle as $title=>$category) {
// use implode for each title
$categoryString = implode(" ", $category);
echo '<li class="'.$categoryString.'">'.$title.'</li>';
}
Check this reference for arrays, it could be very useful for dealing with this kind of problems

Categories