I have a simple newsfeed which is pulling from an xml file which works great. The news feed is broken down into separate XML files for each year. I want the page to show only one year at a time with links to other years above. Ideally when a new year is clicked I would like the content below to update without going to a new page.
I am trying to avoid repeating the PHP code which is parsing the XML for each year and instead would like to simply update the $dom_object->load source when the user clicks a different year.
I am a PHP newbie so some help would be appreciated!
<?php
$dom_object = new DOMDocument();
$dom_object->load("http://EXAMPLE.com/XML-Feed-10100524539?year=2013");
$item = $dom_object->getElementsByTagName("item");
foreach( $item as $value )
{
$titles = $value->getElementsByTagName("title");
$title = $titles->item(0)->nodeValue;
$pubDates = $value->getElementsByTagName("pubDate");
$pubDate = $pubDates->item(0)->nodeValue;
$pdf_urls = $value->getElementsByTagName("pdf_url");
$pdf_url = $pdf_urls->item(0)->nodeValue;
//Trims after last space - REMOVES EST
$pubDate=substr($pubDate, 0, strrpos($pubDate, ' '));
//Trims after remaining space - REMOVES TIME
$pubDate=substr($pubDate, 0, strrpos($pubDate, ' '));
$pubDater = str_replace('/', '-', $pubDate);
$newDate = DateTime::createFromFormat("m/d/Y", $pubDate);
$newDate = $newDate->format('F d, Y');
echo "<div style=\"width:33%; float:left; display:inline-block; height:150px;\"><div style=\"padding:10px;\"><h4>$newDate</h4><p>$title</p></div></div>";
}
?>
You would need to use ajax by using $.get or $.post so you could do something like:
$('#yourElement').click(function(){
var path = $('#path'); // for example
$.post("your/path/getXML.php", { path: path },
function (dat) {
console.log(dat);
}
);
});
Where getXML would be a file similar to this one:
$dom_object = new DOMDocument();
$dom_object->load($_POST["path"]);
$item = $dom_object->getElementsByTagName("item");
foreach( $item as $value )
{
$titles = $value->getElementsByTagName("title");
$title = $titles->item(0)->nodeValue;
$pubDates = $value->getElementsByTagName("pubDate");
$pubDate = $pubDates->item(0)->nodeValue;
$pdf_urls = $value->getElementsByTagName("pdf_url");
$pdf_url = $pdf_urls->item(0)->nodeValue;
//Trims after last space - REMOVES EST
$pubDate=substr($pubDate, 0, strrpos($pubDate, ' '));
//Trims after remaining space - REMOVES TIME
$pubDate=substr($pubDate, 0, strrpos($pubDate, ' '));
$pubDater = str_replace('/', '-', $pubDate);
$newDate = DateTime::createFromFormat("m/d/Y", $pubDate);
$newDate = $newDate->format('F d, Y');
echo "<div style=\"width:33%; float:left; display:inline-block; height:150px;\"><div style=\"padding:10px;\"><h4>$newDate</h4><p>$title</p></div></div>";
Related
I am working on a small script where I wanna take only my website's latest post which is posted yesterday mean I wanna get all yesterday's links and titles.
I tried with my script but I am getting all URLs I am not sure how can I fix it.
Can anyone help me solve this problem?
I was wondering if I can use 'where' attribute like we usually use in SQL. I want only 1 days posts to be scraped.
<?php
header('Content-Type: application/json');
$url = "https://www.lifegoals.co.in/feed/";
$i=0;
$invalidurl = false;
if(#simplexml_load_file($url)){
$feeds = simplexml_load_file($url);
}else{
$invalidurl = true;
echo "<h2>Invalid RSS feed URL.</h2>";
}
if(!empty($feeds)){
//$site = $feeds->channel->title;
//$sitelink = $feeds->channel->link;
//echo "<h1>".$site."</h1>";
foreach ($feeds->channel->item as $item) {
$title = $item->title;
$link = $item->link;
//$description = $item->description;
$postDate = $item->pubDate;
$pubDate = date('D, d M Y',strtotime($postDate));
$currDate = date('D, d M Y');
if($i>=10) break;
if($pubDate=$currDate){
$rss = "<item>
<title>$title</title>
<link>$link</link>
</item>";
echo $rss;
$i++;
}
}
}
?>
i want only 1 days posts there are 4 days posts
I'd add some debugging to this to ensure that you're getting what you think you want. Try the following in your foreach loop:
print_r([
$postDate,
$pubDate,
$currDate,
($pubDate == $currDate),
]);
if($pubDate==$currDate){
$rss = "<item>
<title>$title</title>
<link>$link</link>
</item>";
echo $rss;
$i++;
}
The == was missing thanks.
I am trying to learn Simple HTML Dom Parser, and as an introduction, I am trying to parse ESPN's college football score webpage and translate it into a plain HTML table. I've been able to do everything so far except for importing the date. The problem I'm having is that the data is structured like this:
<div class=gameDay-Container>
<h4 class="games-date">Thursday, August 28 2014</h4>
<div class=mod-ncf-scorebox> Containing games that I have scraped, which I want to add the date (Aug 28) to </div>
<h4 class="games-date">Friday, August 29 2014</h4>
<div class=mod-ncf-scorebox> containing the next games that I will scrape, which I want the date (Aug 29) appended to </div>
</div>
The top section scrapes for the number of games within each date and places it into an array, and then the bottom section compiles the data for the table. (This is messy as I write it via trial and error; is there an easier way to do this?)
foreach($html_base->find('.gameDay-Container') as $dates) {
$rows = $dates->find('.mod-ncf-scorebox');
$count = count($rows);
$supercount=$count.',';
$megacount=explode(', ',$supercount);
print_r($megacount);
}
foreach($html_base->find('.mod-ncf-scorebox') as $event) {
$item['Date'] = '';
$item['Away Team'] = $event->find('.team-name', 0)->plaintext;
$item['Away Team'] = substr($item['Away Team'], 0, -1);
$item['Away Score'] = $event->find('li.finalScore', 1);
$item['Home Team'] = $event->find('.team-name', 1)->plaintext;
$item['Home Team'] = substr($item['Home Team'], 0, -1);
$item['Home Score'] = $event->find('li.finalScore', 2)->plaintext;
$item['Game Status'] = $event->find('div.game-status', 0)->plaintext;
$item['Game ID'] = $event->find('p', 0)->id;
$item['Game ID'] = substr($item['Game ID'], 0, strpos( $item['Game ID'], '-'));
$item['Week'] = $week;
$item['League'] = 'NCAA Football';
$NCAAFscores[] = $item;
}
The question: can I get the date of the game to be added to each line within the table? If I have to use the array setup, can I take the values from it and do some sort of count? Is there an easier way that I'm just completely overlooking?
The answer:
Per Enissay's suggestion below, I nested the foreach statements, which worked out perfectly. Here is the final snippet of code in case anyone out there has similar things.
foreach($html_base->find('.gameDay-Container') as $event2) {
$date1 = $event2->prev_sibling()->plaintext;
$date2 = new DateTime($date1);
$ymd = ($date2->format('Y-m-d'));
foreach($event2->find('.mod-ncf-scorebox') as $event) {
$item['Date'] = $ymd;
$item['Away Team'] = $event->find('.team-name', 0)->plaintext;
$item['Away Team'] = substr($item['Away Team'], 0, -1);
$item['Away Score'] = $event->find('li.finalScore', 1);
$item['Home Team'] = $event->find('.team-name', 1)->plaintext;
$item['Home Team'] = substr($item['Home Team'], 0, -1);
$item['Home Score'] = $event->find('li.finalScore', 2)->plaintext;
$item['Game Status'] = $event->find('div.game-status', 0)->plaintext;
$item['Game ID'] = $event->find('p', 0)->id;
$item['Game ID'] = substr($item['Game ID'], 0, strpos( $item['Game ID'], '-'));
$item['Week'] = $week;
$item['League'] = 'NCAA Football';
$NCAAFscores[] = $item;
}
}
Simply change the way you proceed...
Follow this:
Games are grouped in div blocks/containers, each preceeded by the corresponding date, fetch these blocks ▶ $html_base->find('.gameDay-Container')
For each block, you can get the date ▶ $block->prev_sibling()->plaintext;
Then you find every game inside that block
▶ foreach( $block->find('.mod-ncf-scorebox') as $game ) { ... }
Not tested but it should work :)
I am trying to return twitter titles based on today's date only. I have made the following code below, but it returns every title no matter if its today's date or not.
$dom = new DOMDocument();
#$dom->loadHTMLFile('http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=google');
$xml = simplexml_import_dom($dom);
$twitter = $xml->xpath("//item");
foreach ($twitter as $item) {
$timezone = new DateTimeZone('America/Los_Angeles');
$date = new DateTime($item->pubdate);
$date->setTimeZone($timezone);
$twitter_date = $date->format("F j Y");
$todays_date = date("F j Y");
if ($twitter_date == $todays_date) {
foreach ($twitter as $item) {
$text = $item->title;
echo $text.'<br />';
}
}
}
You are looping again through EVERY $twitter inside the if statement. Try removing the foreach tag inside and just using the current $item:
if ($twitter_date == $todays_date) {
$text = $item->title;
echo $text.'<br />';
}
Here is my code:
<?php
$RSSFEEDS = array(
0 => "http://samnabi.posterous.com/rss.xml",
);
function FormatRow($date, $title, $link, $description) {
return <<<HTML
<p class="blogdate">$date</p><h2 class="blogtitle">$title</h2>
<div class="clearer"> </div>
$description
HTML;
}
ob_start();
if (!isset($feedid)) $feedid = 0;
$rss_url = $RSSFEEDS[$feedid];
$rss_feed = file_get_contents($rss_url);
$rss_feed = str_replace("<![CDATA[", "", $rss_feed);
$rss_feed = str_replace("]]>", "", $rss_feed);
$rss_feed = str_replace("\n", "", $rss_feed);
$rss_feed = preg_replace('#<image>(.*?)</image>#', '', $rss_feed, 1 );
preg_match_all('#<pubDate>(.*?)</pubDate>#', $rss_feed, $date, PREG_SET_ORDER);
preg_match_all('#<title>(.*?)</title>#', $rss_feed, $title, PREG_SET_ORDER);
preg_match_all('#<link>(.*?)</link>#', $rss_feed, $link, PREG_SET_ORDER);
preg_match_all('#<description>(.*?)</description>#', $rss_feed, $description, PREG_SET_ORDER);
if(count($title) <= 1) {
echo "No new blog posts. Check back soon!";
}
else {
for ($counter = 1; $counter <= 3; $counter++ ) {
if(!empty($title[$counter][1])) {
$title[$counter][1] = str_replace("&", "&", $title[$counter][1]);
$title[$counter][1] = str_replace("'", "'", $title[$counter][1]);
$row = FormatRow($date[$counter][1],$title[$counter][1],$link[$counter][1],$description[$counter][1]);
echo $row;
}
}
}
ob_end_flush();
?>
When this script is run, the first item displays the second item's pubDate. The second item displays the third item's pubDate, and so on. So the dates that are shown are not the dates that you see in the original XML file. How do I fix this?
Bonus question: how do I strip characters off the beginning and end of the pubDate tag, so that I end up with "15 May 2010" instead of "Sat, 15 May 2010 03:28:00 -0700" ?
I've said it before, so I'll say it again: Use Magpie RSS to parse your RSS feeds. It takes care of all this stuff for you, and will be much more reliable.
Magpie RSS works great. Here's the code I used to replace what was in my original question:
<?php
define('MAGPIE_INPUT_ENCODING', 'UTF-8');
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
//Tell it to use the fetch script to grab the RSS feed
require_once('magpie/rss_fetch.inc');
//Now it knows how to fetch RSS, tell it which one to fetch
$rss = fetch_rss('http://samnabi.posterous.com/rss.xml');
//In this case, we only want to display the first 3 items
$items = array_slice($rss->items,0,3);
//Now we tell Magpie how to format our output
foreach ($items as $item) {
$title = $item['title'];
$date = date('d M Y', strtotime($item['pubdate']));
$link = $item['link'];
$description = $item['description'];
//And now we want to put it all together.
echo "<p>$date</p><h2>$title</h2><p>$description</p>";
}
?>
I have asked in two earlier questions to place multiple markers from a XML file created from Lightroom, which had to be tranformed in degrees instead of Degrees,Minutes,Seconds.
This part i managed but then...
The answers in the previous question were very informative but it's my poor skill of programming (first project) that i just cannot manage to solve it.
The problem is i want to show multiple markers.
the complete code:
<?php
require('GoogleMapAPI.class.php');
$objDOM = new DOMDocument("1.0", 'utf-8');
$objDOM->preserveWhiteSpace = false;
$objDOM->load("googlepoints.xml"); //make sure path is correct
$photo = $objDOM->getElementsByTagName("photo");
foreach ($photo as $value) {
$album = $value->getElementsByTagName("album");
$albu = $album->item(0)->nodeValue;
$description = $value->getElementsByTagName("description");
$descriptio = $description->item(0)->nodeValue;
$title = $value->getElementsByTagName("title");
$titl = $title->item(0)->nodeValue;
$link = $value->getElementsByTagName("link");
$lin = $link->item(0)->nodeValue;
$guid = $value->getElementsByTagName("guid");
$gui = $guid->item(0)->nodeValue;
$gps = $value->getElementsByTagName("gps");
$gp = $gps->item(0)->nodeValue;
$Deglon = str_replace("'", "/", $gp);
$Deglon = str_replace("°", "/", $Deglon);
$Deglon = str_replace("", "/", $Deglon);
$str = $Deglon;
$arr1 = str_split($str, 11);
$date = $arr1[0]; // Delimiters may be slash, dot, or hyphen
list ($latdeg, $latmin, $latsec, $latrichting) = split ('[°/".-]', $date);
$Lat = $latdeg + (($latmin + ($latsec/60))/60);
$latdir = $latrichting.$Lat;
If (preg_match("/N /", $latdir)) {$Latcoorl = str_replace(" N ", "+",$latdir);}
else {$Latcoorl = str_replace ("S ", "-",$latdir);}
//$Latcoord=$Latcoorl.",";
$date1 = $arr1[1]; // Delimiters may be slash, dot, or hyphen
list ($londeg, $lonmin, $lonsec, $lonrichting) = split ('[°/".-]', $date1);
$Lon = $londeg + (($lonmin + ($lonsec/60))/60);
$londir = $lonrichting.$Lon;
If (preg_match("/W /", $londir)) {$Loncoorl = str_replace("W ", "+",$londir);}
else {$Loncoorl = str_replace ("E", "-",$londir);}
$Lonarr = array($Loncoorl);
foreach ($Lonarr as &$LonArray);
$Latarr = array($Latcoorl);
foreach ($Latarr as &$LatArray);
$titarr = array($titl);
foreach ($titarr as &$titArray);
$guarr = array($gui);
foreach ($guarr as &$guaArray);
$albuarr = array($albu);
foreach ($albuarr as &$albuArray);
print_r ($LonArray);
print_r ($LatArray);
print_r ($guaArray);
print_r ($albuArray);
$map = new GoogleMapAPI('map');
// setup database for geocode caching
// $map->setDSN('mysql://USER:PASS#localhost/GEOCODES');
// enter YOUR Google Map Key
$map->setAPIKey('ABQIAAAAiA4e9c1IW0MDrtoPQRaLgRQmsvD_kVovrOh_CkQEnehxpBb-yhQq1LkA4BJtjWw7lWmjfYU8twZvPA');
$map->addMarkerByCoords($LonArray,$LatArray,$albuArray,$guaArray);
}
?>
The problem is that the "$map->addMarkerByCoords($LonArray,$LatArray,$albuArray,$guaArray);" only shows the last value's from the 4 arrays.
And there fore there is only one marker created.
The output (print_r) of for example the $guaArray is IMG_3308IMG_3309IMG_3310IMG_3311IMG_3312 (5 name's of filename's from photographs).
The function addMarkersByCoords from the 'GoogleMapAPI.class.php' is like this:
function addMarkerByCoords($lon,$lat,$title = '',$html = '',$tooltip = '') {
$_marker['lon'] = $lon;
$_marker['lat'] = $lat;
$_marker['html'] = (is_array($html) || strlen($html) > 0) ? $html : $title;
$_marker['title'] = $title;
$_marker['tooltip'] = $tooltip;
$this->_markers[] = $_marker;
$this->adjustCenterCoords($_marker['lon'],$_marker['lat']);
// return index of marker
return count($this->_markers) - 1;
}
I hope that someone can help me ?
You must create the new instance of the google map above the foreach
like this
$map = new GoogleMapAPI('map');
// setup database for geocode caching
// $map->setDSN('mysql://USER:PASS#localhost/GEOCODES');
// enter YOUR Google Map Key
$map->setAPIKey('ABQIAAAAiA4e9c1IW0MDrtoPQRaLgRQmsvD_kVovrOh_CkQEnehxpBb-yhQq1LkA4BJtjWw7lWmjfYU8twZvPA');
foreach ()
{
}
now you are creating every loop a new map with the last coord
Your foreach loops aren't accomplishing annything useful:
$Lonarr = array($Loncoorl);
foreach ($Lonarr as &$LonArray);
$LonArray is just one element from the $Lonarr array. I think the foreach loop is adding each element of the array onto one big string ($LonArray).