How to sort XML prices using php - php

I'm very new to learning how to use XML, I know a few programming languages. I've tried searching for this answer but I get very confused and cannot relate back to how I would implement this in my code. At the moment I would like to be able to sort prices
Here's an example of how it currently looks
<?php
$xmlFile = "hotel.xml";
$HTML = "";
$count = 0;
$dom = DOMDocument::load($xmlFile);
$hotel = $dom->getElementsByTagName("hotel");
foreach($hotel as $node)
{
$city = $node->getElementsByTagName("City");
$city = $city->item(0)->nodeValue;
$type = $node->getElementsByTagName("Type");
$type = $type->item(0)->nodeValue;
$name = $node->getElementsByTagName("Name");
$name = $name->item(0)->nodeValue;
$price = $node->getElementsByTagName("Price");
$price = $price->item(0)->nodeValue;
if (($type == $_GET["type"]) && ($city == $_GET["city"]) )
{
$HTML = $HTML."<br><span>Hotel: ".$name."</span><br><span>Price: ".$price."</span><br>";
$count++;
}
}
if ($count ==0)
{
$HTML ="<br><span>No hotels available</span>";
}
echo $HTML;
?>

Related

PHP, using two counters to decide top results of an array

I have a block of PHP code where I'm using two counters (one specifically for a particular key of featured if the value is 1.
So far, the counter works by putting any records where featured == 1 in $cnt1 and everything else in $cnt2. However, this doesn't do anything for my sorting.
How can I make this so that the final array puts all featured ($cnt1) records at the top of the array/the first results?
if(count($myresults)>0){
foreach ($myresults as $key => $value) {
$id = $value->ID;
if(get_post_meta($id,'_awpcp_extra_field[36]',true) !='' && get_post_meta($id,'_awpcp_extra_field[37]',true) != ''){
$lat = get_post_meta($id,'_awpcp_extra_field[36]',true);
$lon = get_post_meta($id,'_awpcp_extra_field[37]',true);
$area = get_post_meta($id,'_awpcp_extra_field[38]',true);
$amnt = get_post_meta($id,'_awpcp_price',true)/100;
$ttle = get_the_title($id);
$link = get_permalink($id);
$desc = get_the_excerpt($id);
$date = get_the_time('m/d/Y',$id);
$is_featured = get_post_meta($id,'_awpcp_is_featured',true);
$imgpath = get_the_post_thumbnail_url($id,'dailymag-featured');
$counter_name = ($is_featured == 1) ? 'cnt1' : 'cnt2';
$ress[$$counter_name]['featured'] = $is_featured;
$ress[$$counter_name]['lat'] = $lat;
$ress[$$counter_name]['lon'] = $lon;
$ress[$$counter_name]['area'] = $area;
$ress[$$counter_name]['amnt'] = $amnt;
$ress[$$counter_name]['ttle'] = $ttle;
$ress[$$counter_name]['link'] = $link;
$ress[$$counter_name]['desc'] = $desc;
$ress[$$counter_name]['date'] = $date;
$ress[$$counter_name]['count'] = $counter_name;
if($imgpath){
$ress[$$counter_name]['imgs'] = $imgpath;
}else{
$ress[$$counter_name]['imgs'] = '/wp-content/uploads/2022/03/fairfax-4670d9c9.jpeg';
}
$$counter_name++;
}
}

Wordpress sql, re-ordering array based on meta value

In my wordpress functions file, I'm getting sql query results of only post IDs, then taking those IDs to create an array that I send to my page.
This works perfectly but I want to re-order it based on one of the values I generate in the array process. I have a value of 'featured' and I want to make it so that any results where featured = 1 are first in the array.
$myresults = $wpdb->get_results( $sqlStatement );
$ress = array();
$cnt = 0;
$imgpath = '';
if(count($myresults)>0){
foreach ($myresults as $key => $value) {
$id = $value->ID;
if(get_post_meta($id,'_awpcp_extra_field[36]',true) !='' && get_post_meta($id,'_awpcp_extra_field[37]',true) != ''){
$ress[$cnt]['featured'] = get_post_meta($id,'_awpcp_is_featured',true);
$imgpath = get_the_post_thumbnail_url($id,'dailymag-featured');
if($imgpath){
$ress[$cnt]['imgs'] = $imgpath;
}else{
$ress[$cnt]['imgs'] = '/wp-content/uploads/2022/03/fairfax-4670d9c9.jpeg';
}
$cnt++;
}
}
echo json_encode($ress);
}
Is there a way to simply use conditions in order to put those values first in the array?
Using a function get_post_meta in an array is bad practice. I would advise first querying the database to extract data from custom fields.
However, I think there are two ways to answer your question:
Use 2 arrays and merge them together after iteration:
$myresults = $wpdb->get_results( $sqlStatement );
$ress1 = $ress2 = array();
$cnt = 0;
$imgpath = '';
if(count($myresults)>0){
foreach ($myresults as $key => $value) {
$id = $value->ID;
if(get_post_meta($id,'_awpcp_extra_field[36]',true) !='' && get_post_meta($id,'_awpcp_extra_field[37]',true) != ''){
$is_featured = get_post_meta($id,'_awpcp_is_featured',true);
$imgpath = get_the_post_thumbnail_url($id,'dailymag-featured');
$array_name = !empty($is_featured) ? 'ress1' : 'ress2';
$$array_name[$cnt]['featured'] = $is_featured;
if($imgpath){
$$array_name[$cnt]['imgs'] = $imgpath;
}else{
$$array_name[$cnt]['imgs'] = '/wp-content/uploads/2022/03/fairfax-4670d9c9.jpeg';
}
$cnt++;
}
}
$ress = array_merge($ress1, $ress2);
echo json_encode($ress);
}
Use 2 counters:
$myresults = $wpdb->get_results( $sqlStatement );
$ress = array();
$cnt1 = 0;
$cnt2 = 1000000;
$imgpath = '';
if(count($myresults)>0){
foreach ($myresults as $key => $value) {
$id = $value->ID;
if(get_post_meta($id,'_awpcp_extra_field[36]',true) !='' && get_post_meta($id,'_awpcp_extra_field[37]',true) != ''){
$is_featured = get_post_meta($id,'_awpcp_is_featured',true);
$imgpath = get_the_post_thumbnail_url($id,'dailymag-featured');
$counter_name = !empty($is_featured) ? 'cnt1' : 'cnt2';
$ress[$$counter_name]['featured'] = get_post_meta($id,'_awpcp_is_featured',true);
$imgpath = get_the_post_thumbnail_url($id,'dailymag-featured');
if($imgpath){
$ress[$$counter_name]['imgs'] = $imgpath;
}else{
$ress[$$counter_name]['imgs'] = '/wp-content/uploads/2022/03/fairfax-4670d9c9.jpeg';
}
$$counter_name++;
}
}
$ress = array_values( $ress );
echo json_encode($ress);
}

Show RSS feed items based on other PHP script

I want to create an RSS feed in PHP based on other RSS feeds. That works.
But, Now I want to change how many items are shown in the new created feed. This based on calculation of the items of another feed.
I use this script for the calculation, which works fine:
<?php
$url = 'http://www.nu.nl/rss/Algemeen';
$xml = simplexml_load_file($url);
$tags = array();
foreach($xml->channel->item as $item) {
$children = $item->children(); // get all children of each item tag
foreach ($children as $node) {
$tags[] = $node->getName(); // get the node name of each children
}
}
$test = count($tags);
$count = array_count_values($tags); // count the values
?>
<?php
$mystring = count($tags);
$findme = '3';
$pos = strpos($mystyring, $findme);
?>
<?php
$artikel = ($mystring / 5);
echo $artikel;
?>
I use this script, magpierss, fow creating a new feed:
<?php
/**
* Setup
*
*/
$DOMAIN_NAME = 'http://sitename.nl/';
$FEED_URL = $DOMAIN_NAME . 'rss/full.php';
$SITE_TITLE = 'test';
$SITE_DESRIPTION = '-';
$SITE_AUTHOR = 'test2';
$RSS_CACHE = "/tmp/rsscache";
$RSS_CACHE_EXP = 3600;
$FEED_LIST = array(
'http://www.nu.nl/rss/Economie',
'http://www.nu.nl/rss/Internet'
);
/**
* Do not modify below this point
*
*/
define('MAGPIE_CACHE_DIR', $RSS_CACHE);
define('MAGPIE_CACHE_AGE', $RSS_CACHE_EXP);
define('MAGPIE_OUTPUT_ENCODING', 'utf-8');
// include required files
require_once ('magpierss-0.72/rss_fetch.inc');
include ('feedcreator.class.php');
/* Set RSS properties */
$rss = new UniversalFeedCreator();
$rss->useCached();
$rss->title = $SITE_TITLE;
$rss->description = $SITE_DESRIPTION;
$rss->link = $DOMAIN_NAME;
$rss->syndicationURL = $FEED_URL;
$rss->encoding = 'utf8';
/* Set Image properties
$image = new FeedImage();
$image->title = $SITE_TITLE . " Logo";
$image->url = $SITE_LOG_URL;
$image->link = $DOMAIN_NAME;
$image->description = "Feed provided by " . $SITE_TITLE . ". Click to visit.";
$rss->image = $image;
*/
function showSummary($url, $num = 10, $showfullfeed = false) {
global $rss, $DOMAIN_NAME, $SITE_AUTHOR, $SITE_TITLE;
$num_items = $num;
# $rss1 = fetch_rss($url);
if ($rss1) {
$items = array_slice($rss1->items, 0, $num_items);
foreach ($items as $item) {
$href = $item['link'];
$title = $item['title'];
if (!$showfullfeed) {
$desc = $item['description'];
} else {
$desc = $item['content']['encoded'];
}
// $desc .= '
//Copyright © '.$SITE_TITLE.'. All Rights Reserved.
//';
$pdate = $item['pubdate'];
$rss_item = new FeedItem();
$rss_item->title = $item['title'];
$rss_item->link = $item['link'];
$rss_item->description = $item['content']['encoded'];
$rss_item->date = $item['pubdate'];
$rss_item->source = $DOMAIN_NAME;
$rss_item->author = $SITE_AUTHOR;
$rss->addItem($rss_item);
}
} else {
echo "Error: Cannot fetch feed url - " . $url;
}
}
// Fetch all feeds
foreach($FEED_LIST as $v) showSummary($v);
// Sort items by date
function __usort($ad, $bd) {return strtotime($bd->date) - strtotime($ad->date);}
usort($rss->items, '__usort');
// Display items
$rss->saveFeed("RSS1.0", $RSS_CACHE . "/feed.xml");
How could I let the variable $artikel decide how many items are showed in the feed?

XML parsing in php

I am parsing a xml and but there is a tag which contain image and text both and i want to seprate both image and text in diffrent columns of table in my design layout but i dont know how to do it. please help me. my php file is :
<?php
$RSS_Content = array();
function RSS_Tags($item, $type)
{
$y = array();
$tnl = $item->getElementsByTagName("title");
$tnl = $tnl->item(0);
$title = $tnl->firstChild->textContent;
$tnl = $item->getElementsByTagName("link");
$tnl = $tnl->item(0);
$link = $tnl->firstChild->textContent;
$tnl = $item->getElementsByTagName("description");
$tnl = $tnl->item(0);
$img = $tnl->firstChild->textContent;
$y["title"] = $title;
$y["link"] = $link;
$y["description"] = $img;
$y["type"] = $type;
return $y;
}
function RSS_Channel($channel)
{
global $RSS_Content;
$items = $channel->getElementsByTagName("item");
// Processing channel
$y = RSS_Tags($channel, 0); // get description of channel, type 0
array_push($RSS_Content, $y);
// Processing articles
foreach($items as $item)
{
$y = RSS_Tags($item, 1); // get description of article, type 1
array_push($RSS_Content, $y);
}
}
function RSS_Retrieve($url)
{
global $RSS_Content;
$doc = new DOMDocument();
$doc->load($url);
$channels = $doc->getElementsByTagName("channel");
$RSS_Content = array();
foreach($channels as $channel)
{
RSS_Channel($channel);
}
}
function RSS_RetrieveLinks($url)
{
global $RSS_Content;
$doc = new DOMDocument();
$doc->load($url);
$channels = $doc->getElementsByTagName("channel");
$RSS_Content = array();
foreach($channels as $channel)
{
$items = $channel->getElementsByTagName("item");
foreach($items as $item)
{
$y = RSS_Tags($item, 1);
array_push($RSS_Content, $y);
}
}
}
function RSS_Links($url, $size = 15)
{
global $RSS_Content;
$page = "<ul>";
RSS_RetrieveLinks($url);
if($size > 0)
$recents = array_slice($RSS_Content, 0, $size + 1);
foreach($recents as $article)
{
$type = $article["type"];
if($type == 0) continue;
$title = $article["title"];
$link = $article["link"];
$img = $article["description"];
$page .= "$title\n";
}
$page .="</ul>\n";
return $page;
}
function RSS_Display($url, $click, $size = 8, $site = 0, $withdate = 0)
{
global $RSS_Content;
$opened = false;
$page = "";
$site = (intval($site) == 0) ? 1 : 0;
RSS_Retrieve($url);
if($size > 0)
$recents = array_slice($RSS_Content, $site, $size + 1 - $site);
foreach($recents as $article)
{
$type = $article["type"];
if($type == 0)
{
if($opened == true)
{
$page .="</ul>\n";
$opened = false;
}
$page .="<b>";
}
else
{
if($opened == false)
{
$page .= "<table width='369' border='0'>
<tr>";
$opened = true;
}
}
$title = $article["title"];
$link = $article["link"];
$img = $article["description"];
$page .= "<td width='125' align='center' valign='middle'>
<div align='center'>$img</div></td>
<td width='228' align='left' valign='middle'><div align='left'><a
href=\"$click\" target='_top'>$title</a></div></td>";
if($withdate)
{
$date = $article["date"];
$page .=' <span class="rssdate">'.$date.'</span>';
}
if($type==0)
{
$page .="<br />";
}
}
if($opened == true)
{
$page .="</tr>
</table>";
}
return $page."\n";
}
?>
To separate the image and description you need to parse the HTML that is stored inside the description element again as XML. Luckily it is valid XML inside that element, therefore you can do this straight forward with SimpleXML, the following code-example take the URL and converts each item *description* into the text only and extracts the src attribute of the image to store it as the image element:
<item>
<title>Fake encounter: BJP backs Kataria, says CBI targeting Modi</title>
<link>http://ibnlive.in.com/news/fake-encounter-bjp-backs-kataria-says-cbi-targeting-modi/391802-37-64.html</link>
<description>The BJP lashed out at the CBI and questioned its 'shoddy investigation' into the Sohrabuddin fake encounter case.</description>
<pubDate>Wed, 15 May 2013 13:48:56 +0530</pubDate>
<guid>http://ibnlive.in.com/news/fake-encounter-bjp-backs-kataria-says-cbi-targeting-modi/391802-37-64.html</guid>
<image>http://static.ibnlive.in.com/ibnlive/pix/sitepix/05_2013/bjplive_kataria3.jpg</image>
</item>
The code-example is:
$url = 'http://ibnlive.in.com/ibnrss/top.xml';
$feed = simplexml_load_file($url);
$items = $feed->xpath('(//channel/item)');
foreach ($items as $item) {
list($description, $image) =
simplexml_load_string("<r>$item->description</r>")
->xpath('(/r|/r//#src)');
$item->description = (string)$description;
$item->image = (string)$image;
}
You can then import the SimpleXML into a DOMElement with dom_import_simplexml() however honestly, I just would wrap that little HTML creation as well into a foreach of SimpleXML because you can make use of LimitIterator for the paging as well as you could with DOMDocument and the data you access is actually easily at hand with SimpleXML, it's just easy to pass along the XML elements as SimpleXMLElements instead of parsing into an array first and then processing the array. That's moot.

Magento : Category Name instead of category ids in category path.

I am trying to get category names in category path based on product id in magento.
Suppose My Product Id = 1 and In that I define category5 (id = 5) and I get category path like 2/3/5. Instead of this type of category path I need category path like category2/category3/category5. That means I need category names in path Instead of category Ids. I got this by using following code but its takes so much time. I need to reduce processing time.
Please give me suggestions for how can I reduce process time.
$category_model = Mage::getModel('catalog/category');
$product_model = Mage::getModel('catalog/product');
$all_cats = array();
$product_model->reset();
$_product = $product_model->load($entityId);
$all_cats = $product_model->getCategoryIds($_product);
$main_cnt = count($all_cats);
$cat_str_main = '';
$j = 0;
foreach($all_cats as $ac)
{
$root_category = $category_model->load($ac);
$cat_path = $root_category->getPath();
$cat_arr = explode("/",$cat_path);
$cnt = count($cat_arr);
$cat_str = '';
$main_str = '';
$i=0;
foreach($cat_arr as $ids)
{
$root_category = $category_model->load($ids); //load root catalog
if($i == 2)
{
$cat_str = $category_model->getName();
}
else if($i > 2)
{
$cat_str = $cat_str."/".$category_model->getName();
}
$i = $i+1;
}
if($j < 1)
{
$cat_str_main = $cat_str;
}
else
{
$cat_str_main = $cat_str_main .",".$cat_str;
}
$j = $j+1;
}
Thanks.....
You should use the category collection instead of load for each category to reduce the database queries.
Edit:
I have written you a code sample. I assume you have the category ID of the category of which you want to get the names of the path as $categoryId:
$category = Mage::getModel('catalog/category')->load($categoryId);
$collection = $category->getResourceCollection();
$pathIds = $category->getPathIds();
$collection->addAttributeToSelect('name');
$collection->addAttributeToFilter('entity_id', array('in' => $pathIds));
$result = '';
foreach ($collection as $cat) {
$result .= $cat->getName().'/';
}
I think you should look into magento catalog url rewrites which handles this issue for you... in your magento admin it should be in catalog >> URL rewrite management
Edit:
Because you want to do it in some other page you can simply do:
$store = Mage::app()->getStore();
$product_url = $store->getBaseUrl().$product->getUrlPath();
$category_url = $store->getBaseUrl().$category->getUrlPath();
Here is solution which works quicker than #mpaepper suggestion. My loads the collection only once and doesn's ask database then.
echo "################################", PHP_EOL;
$collection = Mage::getResourceModel('catalog/category_collection');
/* #var $collection Mage_Catalog_Model_Resource_Category_Collection */
$pattern = '1/2/';
$collection->addNameToResult()
->addPathFilter($pattern . '.+');
$categories = array();
foreach ($collection as $id => $_cat) {
/* #var $_cat Mage_Catalog_Model_Category */
$path = explode('/', $_cat->getPath());
$namedPath = [];
foreach ($path as $_id) {
$subcat = $collection->getItemById($_id);
if ($subcat) {
$namedPath[] = $subcat->getName();
}
}
$categories[implode('/', $namedPath)] = $id;
}
print_r($categories);
echo $collection->count(), $collection->getSelect()->assemble(), PHP_EOL;
Here is code Magento : get Category Name with category path. please try it . I hope it will help you.
<?php
set_time_limit(0);
require_once '../app/Mage.php';
Mage::app();
?>
<table class="category-data" border="1" align="center">
<tr>
<td><h2>Category Path</h2></td>
<td><h2>Category Id</h2></td>
</tr>
<?php
$category = Mage::getModel('catalog/category');
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
$categories = array();
if ($ids)
{
foreach ($ids as $id)
{
$category->load($id);
$root = 'Root Catalog';
$isRoot = strtolower($root);
$categoryName = strtolower($category->getName());
if($categoryName == $isRoot){
continue;
}
$categories[$id]['name'] = $category->getName();
$categories[$id]['path'] = $category->getPath();
}
foreach ($ids as $id)
{
$path = explode('/', $categories[$id]['path']);
$len = count($path);
$string = '';
if($id > 2){
foreach ($path as $k=>$pathId)
{
$separator = '';
if($pathId > 2){
if($k != $len-1){ $separator = ' || ';}
$string.= $categories[$pathId]['name'] . $separator;
}
$cnt++;
}
?>
<tr>
<td><?php echo $string; ?></td>
<td><?php echo $id; ?></td>
</tr>
<?php
}
?>
<?php
}
}
?>
</table>

Categories