maccaj51
asked on
I need to update this xml / php script with new features...
This script works brilliantly:
<?php
// A little class for collect data together
//
class SnowData {
public $title;
public $description;
public $giud;
public $pubDate;
// Constructor
//
function __construct( $t, $d, $g, $p ) {
$this->title = $t;
$this->description = $d;
$this->guid = $g;
$this->pubDate = $p;
}
// Pull the base depth using a regex
//
function getDepth() {
preg_match('~^.*Base Depth:\s+([0-9]+)\s+cm\s*$ ~', $this->description, $matches );
return $matches[1];
}
}
// A custom sort based on snow depth
//
function snowDepthSort( $a, $b ) {
$aDepth = $a->getDepth();
$bDepth = $b->getDepth();
if ( $aDepth < $bDepth )
return 1;
else
if ( $aDepth > $bDepth )
return -1;
return 0;
}
// Load the XML
//
$xml = simplexml_load_file("http://www.onthesnow.co.uk/france/snow.rss");
// Array to collect the data
//
$arr = array();
// Process the XML
//
foreach( $xml->channel->item as $anEntry ) {
$arr [] = new SnowData(
(string) $anEntry->title,
(string) $anEntry->description,
(string) $anEntry->guid,
(string) $anEntry->pubDate
);
}
// Sort the array into descending snowdepth
//
uasort( $arr, 'snowDepthSort' );
// Keep only the first 10
//
$arr = array_slice( $arr, 0, 10 );
// Produce a table
//
$tab = "<table>\n";
foreach( $arr as $aSnowObj ) {
$tab .= "<tr>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->title;
$tab .= "</td>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->getDepth();
$tab .= "</td>\n";
$tab .= "</tr>\n";
}
$tab .= "</table>\n";
echo $tab;
?>
Produced the following output
La Clusaz 310
Oz-en-Oisans 270
Les Carroz 240
Les 2 Alpes 190
Morzine 180
Valmorel 180
Arêches - Beaufort 170
Peisey Vallandry 160
Courchevel 145
Les Arcs 133
BUT NOW
i need to be able to load multiple feeds....
feed://www.onthesnow.co.uk/austria/soll/snow.rss
feed://www.onthesnow.co.uk/austria/st-anton-am-arlberg/snow.rss
feed://www.onthesnow.co.uk/france/valloire/snow.rss
Then take the country from them and produce this output
Austria La Clusaz 310 - top result in a different .class in html output
Austria Oz-en-Oisans 270
Austria Les Carroz 240
France Les 2 Alpes 190
France Morzine 180
France Valmorel 180
France Arêches - Beaufort 170
France Peisey Vallandry 160
France Courchevel 145
France Les Arcs 133
Many Thanks
<?php
// A little class for collect data together
//
class SnowData {
public $title;
public $description;
public $giud;
public $pubDate;
// Constructor
//
function __construct( $t, $d, $g, $p ) {
$this->title = $t;
$this->description = $d;
$this->guid = $g;
$this->pubDate = $p;
}
// Pull the base depth using a regex
//
function getDepth() {
preg_match('~^.*Base Depth:\s+([0-9]+)\s+cm\s*$
return $matches[1];
}
}
// A custom sort based on snow depth
//
function snowDepthSort( $a, $b ) {
$aDepth = $a->getDepth();
$bDepth = $b->getDepth();
if ( $aDepth < $bDepth )
return 1;
else
if ( $aDepth > $bDepth )
return -1;
return 0;
}
// Load the XML
//
$xml = simplexml_load_file("http://www.onthesnow.co.uk/france/snow.rss");
// Array to collect the data
//
$arr = array();
// Process the XML
//
foreach( $xml->channel->item as $anEntry ) {
$arr [] = new SnowData(
(string) $anEntry->title,
(string) $anEntry->description,
(string) $anEntry->guid,
(string) $anEntry->pubDate
);
}
// Sort the array into descending snowdepth
//
uasort( $arr, 'snowDepthSort' );
// Keep only the first 10
//
$arr = array_slice( $arr, 0, 10 );
// Produce a table
//
$tab = "<table>\n";
foreach( $arr as $aSnowObj ) {
$tab .= "<tr>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->title;
$tab .= "</td>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->getDepth();
$tab .= "</td>\n";
$tab .= "</tr>\n";
}
$tab .= "</table>\n";
echo $tab;
?>
Produced the following output
La Clusaz 310
Oz-en-Oisans 270
Les Carroz 240
Les 2 Alpes 190
Morzine 180
Valmorel 180
Arêches - Beaufort 170
Peisey Vallandry 160
Courchevel 145
Les Arcs 133
BUT NOW
i need to be able to load multiple feeds....
feed://www.onthesnow.co.uk/austria/soll/snow.rss
feed://www.onthesnow.co.uk/austria/st-anton-am-arlberg/snow.rss
feed://www.onthesnow.co.uk/france/valloire/snow.rss
Then take the country from them and produce this output
Austria La Clusaz 310 - top result in a different .class in html output
Austria Oz-en-Oisans 270
Austria Les Carroz 240
France Les 2 Alpes 190
France Morzine 180
France Valmorel 180
France Arêches - Beaufort 170
France Peisey Vallandry 160
France Courchevel 145
France Les Arcs 133
Many Thanks
You can lose the ini_set(.... line just after the <?php tag - left over from my tests
ASKER
Thats seems to work brilliantly... do u have a solution to the other part... with regards to add a different css class to the top row?
NOt sure if it will work in all browsers, but try changing the table code to
// Produce a table
//
$tab = "<table border='1'>\n";
$topRowClass = " class='topRow'";
foreach( $arr as $index => $aSnowObj ) {
$tab .= "<tr$topRowClass>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->location;
$tab .= "</td>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->title;
$tab .= "</td>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->getDepth();
$tab .= "</td>\n";
$tab .= "</tr>\n";
$topRowClass = "";
}
and then add this to your style sheet
.topRow { font-weight: bold; }
// Produce a table
//
$tab = "<table border='1'>\n";
$topRowClass = " class='topRow'";
foreach( $arr as $index => $aSnowObj ) {
$tab .= "<tr$topRowClass>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->location;
$tab .= "</td>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->title;
$tab .= "</td>\n";
$tab .= "<td>\n";
$tab .= $aSnowObj->getDepth();
$tab .= "</td>\n";
$tab .= "</tr>\n";
$topRowClass = "";
}
and then add this to your style sheet
.topRow { font-weight: bold; }
ASKER
just comes up blank...
is there a way to run the script twice...
i.e run it once and output a table with first result - and class it .topresult
and then run the script again excluding the top result??
Thanks for all your help your scripts are so clear!
is there a way to run the script twice...
i.e run it once and output a table with first result - and class it .topresult
and then run the script again excluding the top result??
Thanks for all your help your scripts are so clear!
Put this at the top after the <?php tag like so
<?php
ini_set('display_errors',1 ); error_reporting(E_ALL & ~E_NOTICE);
and run it again. Do you get any error messages
If you want to use .topresult rather than .topRow then change this
$topRowClass = " class='topRow'";
to this
$topRowClass = " class='topresult'";
<?php
ini_set('display_errors',1
and run it again. Do you get any error messages
If you want to use .topresult rather than .topRow then change this
$topRowClass = " class='topRow'";
to this
$topRowClass = " class='topresult'";
ASKER
I got it to work... it was me being an idiot haha!
but it doesnt seem to put in descending numerical order anymore....?
but it doesnt seem to put in descending numerical order anymore....?
It is in descending order within *location*. If you want it in just descending order regardless of location then use the earlier sort routine. I think I misunderstood your requirements.
A little "bug" is that I am only keeping the first 10 results for each location rather than the BEST 10 results, so if it is to be the best 10 results REGARDLESS of location then use this code for collectRSS
function collectRSS( $location, $feedUrl, & $arr ) {
// Load the XML
//
$xml = simplexml_load_file( $feedUrl );
// Process the XML
//
foreach( $xml->channel->item as $anEntry ) {
$arr [] = new SnowData(
$location,
(string) $anEntry->title,
(string) $anEntry->description,
(string) $anEntry->guid,
(string) $anEntry->pubDate
);
}
}
Use the previous sort comparison
// A custom sort based on snow depth
//
function snowDepthSort( $a, $b ) {
$aDepth = $a->getDepth();
$bDepth = $b->getDepth();
if ( $aDepth < $bDepth )
return 1;
else
if ( $aDepth > $bDepth )
return -1;
return 0;
}
and put the array slice back after the sort
// Sort the array into descending snowdepth
//
uasort( $arr, 'snowDepthSort' );
$arr = array_slice( $arr, 0, 10);
Sorry for the confusion....
A little "bug" is that I am only keeping the first 10 results for each location rather than the BEST 10 results, so if it is to be the best 10 results REGARDLESS of location then use this code for collectRSS
function collectRSS( $location, $feedUrl, & $arr ) {
// Load the XML
//
$xml = simplexml_load_file( $feedUrl );
// Process the XML
//
foreach( $xml->channel->item as $anEntry ) {
$arr [] = new SnowData(
$location,
(string) $anEntry->title,
(string) $anEntry->description,
(string) $anEntry->guid,
(string) $anEntry->pubDate
);
}
}
Use the previous sort comparison
// A custom sort based on snow depth
//
function snowDepthSort( $a, $b ) {
$aDepth = $a->getDepth();
$bDepth = $b->getDepth();
if ( $aDepth < $bDepth )
return 1;
else
if ( $aDepth > $bDepth )
return -1;
return 0;
}
and put the array slice back after the sort
// Sort the array into descending snowdepth
//
uasort( $arr, 'snowDepthSort' );
$arr = array_slice( $arr, 0, 10);
Sorry for the confusion....
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ABSOLUTE HERO! This is guy is the best.... complete solution... easy to understand!!!!!!
Thanks for the praise! Better than points!!
;-)
Actually, I've been mulling this question over in my mind as I've been chatting with other experts here in the PHP forum. I would like to use it as a basis for an article using PHP classes as a data grouping andhandling mechanism. Would you mind if I used the code as a basis? I'd include an aknowledgment to yourself "maccaj51" and a link to the original question.
;-)
Actually, I've been mulling this question over in my mind as I've been chatting with other experts here in the PHP forum. I would like to use it as a basis for an article using PHP classes as a data grouping andhandling mechanism. Would you mind if I used the code as a basis? I'd include an aknowledgment to yourself "maccaj51" and a link to the original question.
ASKER
By all means! the website it will be used on is <a href="http://www.snow2moro.com>Skiing & Snowboarding News</a> !! we're relaunching soon!! we may need your help in the future... and ive got no issues with any accreditation that you require!!
ASKER
By all means! the website it will be used on is <a href="http://www.snow2moro.com">Skiing & Snowboarding News</a> !! we're relaunching soon!! we may need your help in the future... and ive got no issues with any accreditation that you require!!
I'm not sure the EE guidelines will let me link to a live site, but I would like to link to this article and the previous one as examples of how an OO class can simply the extension of a programming task involving data collection and selection.
Never fancied skiing myself.... I prefer my fun to have wings on it. http://www.youtube.com/watch?v=0uobI0cF3UI (not me in there I should point out)
Never fancied skiing myself.... I prefer my fun to have wings on it. http://www.youtube.com/watch?v=0uobI0cF3UI (not me in there I should point out)
BTW - I forgot to say "thanks" for letting me use the code. I'll post an update on here when I push the article up.
maccaj51 - I have converted this question into an article which you can read at
https://www.experts-exchange.com/articles/Web_Development/Web_Languages-Standards/PHP/Using-PHP-classes-to-group-data-in-memory.html
Thanks again for an interesting problem and for allowing me to use it.
https://www.experts-exchange.com/articles/Web_Development/Web_Languages-Standards/PHP/Using-PHP-classes-to-group-data-in-memory.html
Thanks again for an interesting problem and for allowing me to use it.
- Extended the class to hold the location and added an extra parameter to the constructor
- Modified the sort function to have a composite field beased on location and snow depth
- Added a new function by moving some code into a function body. This now collects individual RSS feed and adds them to the array which is passed by REFERENCE (so you can get the changes back). The array slicing (limiting to 10 entries) is now in here also.
- Added a "location" cell to the table and stuck a border on it so that I could be sure I had 3 columns (not obvious with the test data)
Unfortunately the feeds you supplied are all for closed resorts so I've used the ones from yesterday for testing
Open in new window