C h a p t e r 1 0 : A P I s , R S S , a n d X M L 261 C h a p t e r 1 0 : A P I s , R S S , a n d X M L 261 Variables, Arrays, and Functions $url String containing the Yahoo! Stocks URL $check String containing the result of checking whether a ticker symbol exists $reports Array containing returned news reports $xml String containing news reports in RSS format $sxml SimpleXML object created from $xml $flag Boolean value set if a story title is too similar to another $title String containing the current title $temp Array used to extract the publishing site from the title $site String containing the current publisher of the story $desc String containing the current description/summary $date String containing the current story date $percent Integer representing how similar one title is to another $url1 String containing the URL of a small stock chart $url2 String containing the URL of a large stock chart How It Works This plug-in starts by ensuring the value entered for the stock ticker symbol in $stock is in uppercase using the strtoupper() function. Then file_get_contents() is called, passing the values in $url (the main Yahoo! Finance URL), and $stock, to see whether any information is returned. If the string Invalid Ticker Symbol appears anywhere in the returned text, saved in $check, then there is no such stock and so a single-element array with the value FALSE is returned. Otherwise, the array $reports, which will hold the news reports returned later, is initialized, and $xml is loaded with the XML string returned from calling the RSS feed for the ticker in $stock. Next, because the SimpleXML routines that will be used to process the XML don’t seem to like CDATA (character data; see plug-in 76, Search Yahoo! for more details), the next few lines of code massage the data into a format it will accept by removing or translating certain tags, replacing them with entities it understands. After this, $xml is passed to simplexml_load_string() and the resulting object created from it is placed in $sxml. From here, a foreach loop iterates through all the elements in $sxml->channel->item, each time storing them in the object $item to make them easier to access. Inside the loop, the Boolean variable $flag is set to FALSE at the start of each iteration. Later on, if a story title appears too similar to a previously returned title, this flag will be changed to the value TRUE. Next, the URL of the original story is extracted into $url and the title is also retrieved in $title. However, because the title also contains the name of the publishing web site in brackets, the explode() function is used to split the title into two elements of an array in $temp. The first now contains just the title so that is saved back to the variable $title. 262 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 262 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s The second then has the brackets and the word at removed, and the resulting publishing site name is placed in $site. The description, or summary, is then placed in $desc and the date, which is returned as a timestamp, is converted to a friendly string using the strtotime() and date() functions, and saved in $date. Next a for loop checks through all the news reports so far saved in the $reports array. Using the similar_text() function, each title is compared to the current one (first converting both to lowercase using the strtolower() function), with a score of between 0 and 100 percent being allocated to the variable $percent, depending on how similar the strings are to each other. A score of 0 means totally different, and 100 means identical. After some testing, I chose a value of 70 percent or greater to mean that the same or a similar story has already been saved in the array and, if so, the variable $flag is set to TRUE and a break command is issued to exit the loop. Finally, in the foreach loop, the value of $flag is checked. If it’s not TRUE, the story summary doesn’t relate to an item on a paid-for subscription site (indicated by the string [$$] in the title), and the value in $desc isn’t the empty string, then the story details are grouped together into an array that is inserted into the next available element in the $reports array. Lastly, the two variables $url1 and $url2 are assigned the URLs of a small (192 × 96 pixels) and a large (512 × 288 pixels) chart of the most recent (or current) day’s trading of $stock. A three-element array is then returned by the plug-in, the first of which is the number of news items returned, the second is a sub-array of two elements containing the small and large chart URLs, and the third element is the $reports array containing all the news stories. How to Use It To retrieve stock data using this plug-in, all you have to do is pass the name of a valid stock ticker symbol to it, like this: $stock = "AAPL"; $results = PIPHP_GetYahooStockNews($stock); if (!$results[0]) echo "No stories found for $stock."; If $results[0] is FALSE, then an error message is displayed. Otherwise, it contains the number of news stories returned and the value of $results[1] will be an array containing a pair of URLs for a small and a large chart of the stock, which you can display using one or the other of the following lines of code: echo "<img echo "<img src='" . $results[1][1] . "' />"; // Large chart Each of the news stories will be supplied in separate details, which can be accessed like this for the first story: $title = $results[2][0][0]; $site = $results[2][0][1]; $date = $results[2][0][2]; C h a p t e r 1 0 : A P I s , R S S , a n d X M L 263 C h a p t e r 1 0 : A P I s , R S S , a n d X M L 263 $story = $results[2][0][3]; $url = $results[2][0][4]; And the second story’s details can be accessed like this (and so on): $title = $results[2][1][0]; $site = $results[2][1][1]; $date = $results[2][1][2]; $story = $results[2][1][3]; $url = $results[2][1][4]; But the best way to iterate through the array of stories is to use a foreach loop, assigning the value of each element of $results[2] to another array such as $result (singular as opposed to plural), like this: foreach($results[2] as $result) echo "<a href='$result[4]'>$result[0]</a> " . "($result[1], $result[2])<br />$result[3]<br /><br />'; Because all the individual parts of the story are returned separately, you can rearrange and display each story exactly the way you want. In the preceding code, each title in $result[0] is displayed as part of a link to the original story in $result[4], then the originating site in $result[1] and the date in $result[2] are placed inside brackets, and a <br /> tag is displayed. Finally, the story in $result[3] is displayed followed by a couple more <br /> tags. As with some of the other plug-ins similar to this, please be aware that you ar e using servers and data belonging to other organizations, so make sure you have the relevant permissions required to republish any data. Please also respect the bandwidth and CPU cycles of these companies by caching the results returned, and only requesting updates when necessary. The Plug-in function PIPHP_GetYahooStockNews($stock) { $stock = strtoupper($stock); $url = 'http://finance.yahoo.com'; $check = @file_get_contents("$url/q?s=$stock"); if (stristr($check, 'Invalid Ticker Symbol') || $check == '') return FALSE; $reports = array(); $xml = file_get_contents("$url/rss/headline?s=$stock"); $xml = preg_replace('/<\/?summary>/', '', $xml); $xml = preg_replace('/<\/?image>/', '', $xml); $xml = preg_replace('/<\/?guid>/', '', $xml); $xml = preg_replace('/<\/?p?link>/', '', $xml); $xml = str_replace('<![CDATA[', '', $xml); $xml = str_replace(']]>', '', $xml); $xml = str_replace('&', '[ampersand]', $xml); 264 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s 264 P l u g - i n P H P : 1 0 0 P o w e r S o l u t i o n s $xml = str_replace('&', '&', $xml); $xml = str_replace('[ampersand]', '&', $xml); $xml = str_replace('<b>', '<b>', $xml); $xml = str_replace('</b>', '</b>', $xml); $xml = str_replace('<wbr>', '<wbr>', $xml); $sxml = simplexml_load_string($xml); foreach($sxml->channel->item as $item) { $flag = FALSE; $url = $item->link; $title = $item->title; $temp = explode(' (', $title); $title = $temp[0]; $site = str_replace(')', '', $temp[1]); $site = str_replace('at ', '', $site); $desc = $item->description; $date = date("M jS, g:ia", strtotime(substr($item->pubDate, 0, 25))); for ($j = 0 ; $j < count($reports) ; ++$j) { similar_text(strtolower($reports[$j][0]), strtolower($title), $percent); if ($percent > 70) { $flag = TRUE; break; } } if (!$flag && !strstr($title, '[$$]') && strlen($desc)) $reports[] = array($title, $site, $date, $desc, $url); } $url1 = "http://ichart.finance.yahoo.com/t?s=$stock"; $url2 = "http://ichart.finance.yahoo.com/b?s=$stock"; return array(count($reports), array($url1, $url2), $reports); } Get Yahoo! News In the last of this chapter’s Yahoo! related plug-ins, you can request the latest news results for a given search query. What this plug-in does is load in the Yahoo! News RSS feed for a query and extract the various elements into arrays which are then returned to your program. Figure 10-11 shows it being used to retrieve all the latest news for the query climate change. 78 C h a p t e r 1 0 : A P I s , R S S , a n d X M L 265 C h a p t e r 1 0 : A P I s , R S S , a n d X M L 265 About the Plug-in This plug-in takes a search query and returns news items from http://news.yahoo.com based on it. Upon success, it returns a two-element array, the first of which is the number of news items returned, and the second is a sub-array containing the following details: • Title • Publishing site • Date • Story summary/description • URL to the original story On failure it returns a single element array with the value FALSE. It requires this argument: • $search A standard search query FIGURE 10-11 With this plug-in you can fetch the news headlines for any search query. Variables, Arrays, and Functions $reports Array containing returned news reports $url String containing the Yahoo! News URL $xml String containing news reports in RSS format $sxml SimpleXML object created from $xml $flag Boolean value set if a story title is too similar to another $date String containing the current date . Functions $url String containing the Yahoo! Stocks URL $check String containing the result of checking whether a ticker symbol exists $reports Array containing returned news reports $xml String containing. extract the publishing site from the title $site String containing the current publisher of the story $desc String containing the current description/summary $date String containing the current. date $percent Integer representing how similar one title is to another $url1 String containing the URL of a small stock chart $url2 String containing the URL of a large stock chart How It Works This plug- in