00001 <?PHP 00002 00003 # 00004 # FILE: Scout--RSSClient.php 00005 # 00006 # METHODS PROVIDED: 00007 # RSSClient() 00008 # - constructor 00009 # SomeMethod($SomeParameter, $AnotherParameter) 00010 # - short description of method 00011 # 00012 # AUTHOR: Edward Almasy 00013 # 00014 # Copyright 2005 Internet Scout Project 00015 # http://scout.wisc.edu 00016 # 00017 00018 class RSSClient { 00019 00020 # ---- PUBLIC INTERFACE -------------------------------------------------- 00021 00022 # object constructor 00023 function RSSClient($ServerUrl, $CacheDB = NULL, $CacheTablePrefix = "", $RefreshTime = 600, $DebugLevel = 0) 00024 { 00025 # set default debug level 00026 $this->DebugLevel = $DebugLevel; 00027 00028 # query server (or cache) for XML text 00029 $this->XmlText = $this->QueryServerWithCaching($ServerUrl, $CacheDB, $CacheTablePrefix, $RefreshTime); 00030 00031 # create XML parser and parse text 00032 $this->Parser = new XMLParser(); 00033 if ($this->DebugLevel > 3) { $Parser->SetDebugLevel($this->DebugLevel - 3); } 00034 $this->Parser->ParseText($this->XmlText); 00035 00036 if ($this->DebugLevel) { print("RSSClient->RSSClient() returned ".strlen($this->XmlText)." characters from server query<br>\n"); } 00037 } 00038 00039 # get/set server URL 00040 function ServerUrl($NewValue = NULL) 00041 { 00042 # if new RSS server URL supplied 00043 if (($NewValue != NULL) && ($NewValue != $this->ServerUrl)) 00044 { 00045 # save new value 00046 $this->ServerUrl = $NewValue; 00047 00048 # re-read XML from server at new URL 00049 $this->XmlText = $this->QueryServerWithCaching($NewValue); 00050 00051 # create new XML parser and parse text 00052 $this->Parser = new XMLParser(); 00053 if ($this->DebugLevel > 3) { $Parser->SetDebugLevel($this->DebugLevel - 3); } 00054 $this->Parser->ParseText($this->XmlText); 00055 } 00056 00057 # return RSS server URL to caller 00058 return $this->ServerUrl; 00059 } 00060 00061 # retrieve RSS items (from first channel if not otherwise specified) 00062 function GetItems($NumberOfItems = NULL, $ChannelName = NULL) 00063 { 00064 # start by assuming no items will be found 00065 $Items = array(); 00066 00067 # move parser to area in XML with items 00068 $Parser = $this->Parser; 00069 $Parser->SeekToRoot(); 00070 $Result = $Parser->SeekTo("rss"); 00071 if ($Result === NULL) 00072 { 00073 $Result = $Parser->SeekTo("rdf:RDF"); 00074 } 00075 else 00076 { 00077 $Parser->SeekTo("channel"); 00078 } 00079 00080 # if items are found 00081 $ItemCount = $Parser->SeekTo("item"); 00082 if ($ItemCount) 00083 { 00084 # for each record 00085 $Index = 0; 00086 do 00087 { 00088 # retrieve item info 00089 $Items[$Index]["title"] = $Parser->GetData("title"); 00090 $Items[$Index]["description"] = $Parser->GetData("description"); 00091 $Items[$Index]["link"] = $Parser->GetData("link"); 00092 $Items[$Index]["enclosure"] = $Parser->GetAttributes("enclosure"); 00093 00094 $Index++; 00095 } 00096 while ($Parser->NextItem() && (($NumberOfItems == NULL) || ($Index < $NumberOfItems))); 00097 } 00098 00099 # return records to caller 00100 return $Items; 00101 } 00102 00103 # retrieve site name as given in feed 00104 function GetChannelTitle() 00105 { 00106 if (!isset($this->ChannelTitle)) { $this->LoadChannelInfo(); } 00107 return $this->ChannelTitle; 00108 } 00109 00110 # retrieve site link as given in feed 00111 function GetChannelLink() 00112 { 00113 if (!isset($this->ChannelLink)) { $this->LoadChannelInfo(); } 00114 return $this->ChannelLink; 00115 } 00116 00117 # retrieve site description as given in feed 00118 function GetChannelDescription() 00119 { 00120 if (!isset($this->ChannelDescription)) { $this->LoadChannelInfo(); } 00121 return $this->ChannelDescription; 00122 } 00123 00124 # tell caller whether client is using cached data 00125 function UsedCachedData() 00126 { 00127 return $this->CachedDataWasUsed; 00128 } 00129 00130 00131 # ---- PRIVATE INTERFACE ------------------------------------------------- 00132 00133 var $ServerUrl; 00134 var $MetadataPrefix; 00135 var $SetSpec; 00136 var $DebugLevel; 00137 var $XmlText; 00138 var $Parser; 00139 var $ChannelTitle; 00140 var $ChannelLink; 00141 var $ChannelDescription; 00142 var $CachedDataWasUsed; 00143 00144 # set current debug output level (0-9) 00145 function SetDebugLevel($NewLevel) 00146 { 00147 $this->DebugLevel = $NewLevel; 00148 } 00149 00150 # load RSS XML from server or cache 00151 function QueryServerWithCaching($ServerUrl, $CacheDB, $CacheTablePrefix, $RefreshTime) 00152 { 00153 # save RSS server URL 00154 $this->ServerUrl = $ServerUrl; 00155 00156 # save caching info (if any) 00157 if ($CacheDB) 00158 { 00159 $this->CacheDB = $CacheDB; 00160 } 00161 $this->CacheTablePrefix = $CacheTablePrefix; 00162 00163 # if caching info was supplied 00164 if ($this->CacheDB) 00165 { 00166 # create cache table if it doesn't exist 00167 $DB = $this->CacheDB; 00168 $TableName = $CacheTablePrefix."RSSClientCache"; 00169 $DB->Query("CREATE TABLE IF NOT EXISTS ".$TableName." (" 00170 ."ServerUrl TEXT," 00171 ."CachedXml TEXT," 00172 ."LastQueryTime DATETIME" 00173 .");"); 00174 00175 # look up cached information for this server 00176 $QueryTimeCutoff = date("Y-m-d H:i:s", (time() - $RefreshTime)); 00177 $DB->Query("SELECT * FROM ".$TableName." WHERE ServerUrl = '".addslashes($ServerUrl)."'" 00178 ." AND LastQueryTime > '".$QueryTimeCutoff."'"); 00179 00180 # if we have cached info that has not expired 00181 if ($CachedXml = $DB->FetchField("CachedXml")) 00182 { 00183 # use cached info 00184 $QueryResult = $CachedXml; 00185 $this->CachedDataWasUsed = TRUE; 00186 } 00187 else 00188 { 00189 # query server for XML text 00190 $QueryResult = $this->QueryServer($ServerUrl); 00191 $this->CachedDataWasUsed = FALSE; 00192 00193 # if query was successful 00194 if (strlen($QueryResult)) 00195 { 00196 # clear out any old cache entries 00197 $DB->Query("DELETE FROM ".$TableName." WHERE ServerUrl = '".addslashes($ServerUrl)."'"); 00198 00199 # save info in cache 00200 $DB->Query("INSERT INTO ".$TableName." (ServerUrl, CachedXml, LastQueryTime)" 00201 ." VALUES ('".addslashes($ServerUrl)."', '".addslashes($QueryResult)."', NOW())"); 00202 } 00203 } 00204 } 00205 00206 # return query result to caller 00207 return $QueryResult; 00208 } 00209 00210 # perform RSS query and return resulting data to caller 00211 function QueryServer() 00212 { 00213 # open stream to RSS server 00214 $QueryUrl = $this->ServerUrl; 00215 $FHndl = fopen($QueryUrl, "r"); 00216 00217 # while lines left in response 00218 $Text = ""; 00219 while (!feof($FHndl)) 00220 { 00221 # read line from server and add it to text to be parsed 00222 $Text .= fgets($FHndl, 2000000); 00223 } 00224 00225 # close RSS server stream 00226 fclose($FHndl); 00227 00228 # return query result data to caller 00229 return $Text; 00230 } 00231 00232 function LoadChannelInfo() 00233 { 00234 $Parser = $this->Parser; 00235 $Parser->SeekToRoot(); 00236 $Result = $Parser->SeekTo("rss"); 00237 if ($Result === NULL) 00238 { 00239 $Result = $Parser->SeekTo("rdf:RDF"); 00240 } 00241 $Parser->SeekTo("channel"); 00242 $this->ChannelTitle = $Parser->GetData("title"); 00243 $this->ChannelLink = $Parser->GetData("link"); 00244 $this->ChannelDescription = $Parser->GetData("description"); 00245 } 00246 } 00247 00248 00249 ?>