Moreover if you don't have some form of a SQL DB for your website to store and pull records from, most programmers will tell you it's impossible to use server side scripting to build XML files without an external data source.
My personal website just isn't big enough to justify setting up a DB for it. This is not to say, that I don't have access to any DB sources. In fact, quite the opposite. But again... I just cannot justify setting up a DB for my own, personal, little website. Even if I am using some of the biggest, boldest, most versatile, and cutting-edge techniques there are out in force on the Internet today; right here on my little slice of the InterWeb.
Because I pride myself on creating and using versatile code, I decided it was finally time to tackle the issue of cleaning and updating my RSS feeds through server side automation.
As per usual (with the exception of when I find myself using AJAX or the rarer occasion when I only need CSS) I accomplished my goal by using PHP.
What makes the whole process so unique is that fact that every time a person visits my website, they are getting the absolute most current version of my RSS feeds. Moreover the feeds are never compounded with new data on top of old data, because my RSS feed building program, aptly named: FeedBuilder has a key date comparison feature, so articles older than the programs (user selectable) predetermined date do not get added to the XML feed file. Furthermore the XML feed file is continuously wiped clean each time it's written to ensure that old data is stripped from the XML feed file.
Here's the PHP source code that makes is all happen:
<?php
/****************************************************************************
PHP Program:----: FeedBuilder [PHP] (TM)
Version:--------: v4
Author:---------: Rob Rayburn
Affiliation:----: Appcitement, LTD. (C)2012, All Rights Reserved
Website:--------: www.Appcitement.com
Licence:--------: Appcitement (C) Closed Source Product
****************************************************************************/
// define and/or input RSS+XML feed document and location on server, mapped through a relative path
//
$var_rss_feed_file_document = ''.$var_blog_rss_path.''.$var_blog_category.'.xml';
$var_rss_feed_file_location = ''.$var_path_to_rss_file.'';
// number of days old RSS feed should be
//
$var_age_of_rss_feed_in_days = "900";
// define and/or input feed article variables
//
/* title node */
$var_item_title = ''.$var_article_title.'';
/* pubDate node */
$var_item_pubDate = ''.$var_article_date.'';
/* link node */
$var_item_link = ''.$var_blog_website.'/blog-articles/'.$var_article_file.'';
/* description node */
$var_item_description = ''.$var_article_rss_description.'';
/* guid node */
$var_item_guid = $var_item_link;
// determine if program should clean the feed
//
switch($var_feedbuilder_job) {
default: die("404 ERROR");
case "clean":
// define and/or input feed header variables
//
/* title node */
$var_rss_feed_channel_title = "Rob Rayburn's ".$var_type_title;
/* link node */
$var_rss_feed_channel_link = "http://www.RobRayburn.com/blog".$var_type_link."/";
/* description node */
$var_rss_feed_channel_description = $var_type_description." Rob Rayburn";
/* language node */
$var_rss_feed_channel_language = "en-us";
/* copyright node */
$var_rss_feed_channel_copyright = "Copyright 2012, Rayburn Media, LLC.";
/* atomlink node */
$var_rss_feed_channel_atomlink = "http://robrayburn.com/rss/".$var_rss_feed_file_document."";
// open RSS feed
//
$var_file_handler = fopen("".$var_rss_feed_file_location."","w") or die("404 ERROR");
// update RSS feed LAST BUILD DATE
//
$var_rss_feed_channel_lastBuildDate = date("D, d M Y H:i:s");
// set time zone
//
$var_rss_feed_channel_lastBuildDate = $var_rss_feed_channel_lastBuildDate." GMT";
// clean the feed
//
$var_rss_xml_output = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\">
<channel>
<title>".htmlentities($var_rss_feed_channel_title, ENT_QUOTES)."</title>
<link>".htmlentities($var_rss_feed_channel_link, ENT_QUOTES)."</link>
<description>".htmlentities($var_rss_feed_channel_description, ENT_QUOTES)."</description>
<language>".htmlentities($var_rss_feed_channel_language, ENT_QUOTES)."</language>
<copyright>".htmlentities($var_rss_feed_channel_copyright, ENT_QUOTES)."</copyright>
<lastBuildDate>".htmlentities($var_rss_feed_channel_lastBuildDate, ENT_QUOTES)."</lastBuildDate>
<atom:link href=\"".htmlentities($var_rss_feed_channel_atomlink, ENT_QUOTES)."\" rel=\"self\" type=\"application/rss+xml\" />
</channel>
</rss>";
// write data to RSS feed
//
fwrite($var_file_handler, $var_rss_xml_output);
// close RSS feed
//
fclose($var_file_handler);
// finish cleaning the feed
//
break;
// determine if program should update the feed
//
case "update":
// reformat HTML elements to standard DOM format to be processed by PHP for XML
//
/* & */
$var_item_title = str_replace("&", "&", $var_item_title);
$var_item_pubDate = str_replace("&", "&", $var_item_pubDate);
$var_item_link = str_replace("&", "&", $var_item_link);
$var_item_description = str_replace("&", "&", $var_item_description);
$var_item_guid = str_replace("&", "&", $var_item_guid);
/* ' */
$var_item_title = str_replace("'", "'", $var_item_title);
$var_item_pubDate = str_replace("'", "'", $var_item_pubDate);
$var_item_link = str_replace("'", "'", $var_item_link);
$var_item_description = str_replace("'", "'", $var_item_description);
$var_item_guid = str_replace("'", "'", $var_item_guid);
/* ' */
$var_item_title = str_replace("'", "'", $var_item_title);
$var_item_pubDate = str_replace("'", "'", $var_item_pubDate);
$var_item_link = str_replace("'", "'", $var_item_link);
$var_item_description = str_replace("'", "'", $var_item_description);
$var_item_guid = str_replace("'", "'", $var_item_guid);
/* ' */
$var_item_title = str_replace("'", "'", $var_item_title);
$var_item_pubDate = str_replace("'", "'", $var_item_pubDate);
$var_item_link = str_replace("'", "'", $var_item_link);
$var_item_description = str_replace("'", "'", $var_item_description);
$var_item_guid = str_replace("'", "'", $var_item_guid);
// explode RSS feed PUBLISH DATE and list its individual parts
//
$var_list_date = explode(" ", $var_item_pubDate);
list($var_weekday, $var_day_number, $var_month_name, $var_year, $var_time_str, $var_time_zone) = $var_list_date;
// switch abbreviated month name to its corresponding numerical month number
//
switch($var_month_name) {
default: die("404 ERROR");
case "Jan":
$var_month_number = "1";
break;
case "Feb":
$var_month_number = "2";
break;
case "Mar":
$var_month_number = "3";
break;
case "Apr":
$var_month_number = "4";
break;
case "May":
$var_month_number = "5";
break;
case "Jun":
$var_month_number = "6";
break;
case "Jul":
$var_month_number = "7";
break;
case "Aug":
$var_month_number = "8";
break;
case "Sep":
$var_month_number = "9";
break;
case "Oct":
$var_month_number = "10";
break;
case "Nov":
$var_month_number = "11";
break;
case "Dec":
$var_month_number = "12";
break;
}
// reformat RSS feed PUBLISH DATE in YYYY-MM-DD format, seconds not accounted for, ultimately for lack of significance
//
$var_item_pubDate_ymd = $var_year."-".$var_month_number."-".$var_day_number;
// convert RSS feed PUBLISH DATE to Unix time stamp format
//
$var_CompareDate_strtotime = strtotime($var_item_pubDate_ymd);
// RSS feed is being built every time this program runs, so output the current date in YYYY-MM-DD format
//
$var_CurrentDate = date("Y-m-d");
// convert RSS feed BUILD DATE to Unix time stamp format
//
$var_CurrentDate_strtotime = strtotime($var_CurrentDate);
// calculates the number of days elapsed multiplied by the number of seconds in one day
//
$var_age_of_rss_feed_in_seconds = $var_age_of_rss_feed_in_days * 86400;
// RSS feed BUILD DATE minus the desired age of the RSS feed calculated in seconds
//
$var_CurrentDate_strtotime_subtracted = $var_CurrentDate_strtotime - $var_age_of_rss_feed_in_seconds;
// if the article is older than the desired age of the RSS feed it will not be added
//
if ($var_CompareDate_strtotime < $var_CurrentDate_strtotime_subtracted) {
// Warning: This article WILL NOT be added to the RSS feed!
// Reason: This article is to old to be added to the RSS feed.
}
// else the article is not older than the desired age of the RSS feed and will be added the RSS feed
//
else {
// create an XML Document space in memory through the DOM
//
$var_xmlDOMDoc = new DOMDocument;
// load an XML Document into the DOM memory slot
//
$var_xmlDOMDoc -> load($var_rss_feed_file_location);
// open the RSS CHANNEL node
//
$var_openCHANNELnode = $var_xmlDOMDoc -> getElementsByTagName('channel')->item(0);
// create a new RSS ITEM node
//
$var_newITEMnode = $var_xmlDOMDoc -> createElement('item');
// create a new RSS TITLE node, fill with text
//
$var_newTITLEnode = $var_xmlDOMDoc -> createElement('title');
$var_newTITLEnodeTEXT = $var_xmlDOMDoc -> createTextNode ($var_item_title);
$var_newTITLEnode -> appendChild($var_newTITLEnodeTEXT);
// create a new RSS DATE node, fill with text
//
$var_newDATEnode = $var_xmlDOMDoc -> createElement('pubDate');
$var_newDATEnodeTEXT = $var_xmlDOMDoc -> createTextNode ($var_item_pubDate);
$var_newDATEnode -> appendChild($var_newDATEnodeTEXT);
// create a new RSS LINK node, fill with text
//
$var_newLINKnode = $var_xmlDOMDoc -> createElement('link');
$var_newLINKnodeTEXT = $var_xmlDOMDoc -> createTextNode ($var_item_link);
$var_newLINKnode -> appendChild($var_newLINKnodeTEXT);
// create a new RSS DESCRIPTION node, fill with text
//
$var_newDESCRIPTIONnode = $var_xmlDOMDoc -> createElement('description');
$var_newDESCRIPTIONnodeTEXT = $var_xmlDOMDoc -> createTextNode ($var_item_description);
$var_newDESCRIPTIONnode -> appendChild($var_newDESCRIPTIONnodeTEXT);
// create a new RSS GUID node, fill with text
//
$var_newGUIDnode = $var_xmlDOMDoc -> createElement('guid');
$var_newGUIDnodeTEXT = $var_xmlDOMDoc -> createTextNode ($var_item_guid);
$var_newGUIDnode -> appendChild($var_newGUIDnodeTEXT);
// append ITEM node with new data
//
$var_newITEMnode -> appendChild($var_newTITLEnode);
$var_newITEMnode -> appendChild($var_newDATEnode);
$var_newITEMnode -> appendChild($var_newLINKnode);
$var_newITEMnode -> appendChild($var_newDESCRIPTIONnode);
$var_newITEMnode -> appendChild($var_newGUIDnode);
// append CHANNEL node with new data
//
$var_openCHANNELnode -> appendChild($var_newITEMnode);
// save XML Document, currently loaded within the DOM memory slot, to a Non Applicable variable
//
$var_run_NA = $var_xmlDOMDoc -> save($var_rss_feed_file_location);
}
// finish updating the feed
//
break;
}
?>
These 5 key ingredients give Firefox a distinct advantage over other web browsers (such as Chrome, Safari, Internet Explorer, and Opera). Other web browsers, may from time to time, have greater web page loading speed than Firefox. But none of the other major web browsers have all the options Firefox has available. All the major web browsers now offer Tab Browsing (an idea they adopted from Mozilla's Gecko web browser engine; the browsing engine for... oh ya: Firefox). Other web browsers (i.e.: Internet Explorer) have, like Firefox, adopted the use of Plug-ins (such as: QuickTime, Silverlight, Flash, Shockwave, and Java). Ultimately all the other web browsers have a few features, but none of them, with the exception of Firefox, are the full package.
Because Firefox is such a complete web browsing package... when it comes to laying out websites, building scripts, and debugging web pages... Firefox's key ingredients make life for Web Developers so sweet!
Firefox's Web Tools for Success First and Foremost... Add-ons: In my last article Firefox Add-ons: A Revitalization of Web Browsing I explained how and why Add-ons are so great. I also listed a variety of Add-ons every Web Surfer should have. Along with those core Add-ons, there are also a number of development Add-ons every Wed Dev should install. Here's a list of Add-ons every Web Dev will like [click + for more details]:
Bring Websites to Life through Plug-ins: Plug-ins are often confused with Add-ons. The key difference between the two is the functionally that Plug-ins give to websites; where as Add-ons give greater functionality to web browsers themselves. For example many websites use Adobe Flash or Microsoft Silverlight to present animation and video. Without Plug-ins web browsers could not display this type of media.
What sets Firefox apart from all the other web browsers out there is its extremely diverse library of Plug-ins. And Firefox Developers work hard to help Web Developers build and troubleshoot new Plug-ins. Dev working on OS X? You'll enjoy these Plug-ins [click + for more details]:
Integrate Firefox into your Life's Work... with Themes: If you've ever wanted your web browser to be more inline with the rest of your desktop experience then Firefox has the tool for you... Themes. With a website library of thousands of Themes, Firefox offers something for every developer's needs. Including Themes that make Firefox entirely text based (in the event you don't need or want icons in your web browser), and Themes that make Firefox look more like many of your favorite applications (like: iTunes, QuickTime, LimeWire, etc...), or even Themes that help integrate Firefox into your company's computing environment. Themes also offer Wed Developers the ability to take screen shots depicting what a website might look like on a different operating system platform than the one they are currently working on.
Make Web Browsing Faster & Simpler with Tab Browsing: It goes without saying that Tab Browsing, when used properly, makes web browsing & web development faster and more efficient. The Developers of Firefox are constantly working to add all the features that users & web developers want in a high quality Tab Browsing experience. One of the nicest features Firefox Tab Browsing has, that few web browsers have adopted, is the ability to not only rearrange tabs but also pull tabs out of the main window, making them their own window.
Tweak Firefox by using Configuration Preferences: One of the true hidden gems of Firefox, that comes with the web browser right out of box, is the Configuration Preferences. Generally you access the Configuration Preferences through the Preferences menu option. However, typing about:config into Firefox's web address bar will open a huge library of interchangeable Configuration Preferences settings. Settings that give Web Devs the ability to streamline their web browser to do a huge variety of actions (including but not limited to: improving memory usage, adjusting how colors are rendered, changing input field behavior, and much, much more).
Firefox Add-ons have reinvented the way I view and perceive the Internet. If you tried half the Add-ons I use, I bet you'd feel the same way.
Quick little Q & A...
Q: How many Add-ons does Firefox have?
Q: What kind of Add-ons are available for Firefox?
AT&T claims (per their own coverage map) that I live in their "Good Coverage" area, only yards from their "Best Coverage" area. Yet every time I flip open my phone, my signal and/or calls keep dropping every 30 seconds. Which means either their good'est, best'est cellular network is a total POS or my cell phone is a POJ. And I don't think it's a problem with my cell phone -- since the phone and all its parts have been replaced by AT&T's Warranty Department. And their Customer Service Department has yet to give me a straight answer as to why my phone calls never last more than 2 minutes.
Could AT&T really be worse than my previous cellular provider, Sprint ®?
When I was a Sprint PCS customer I had nearly the same number & level of problems I now have with AT&T. And I had a lot of problems when I was a Sprint customer, a lot.
For 4 years, while I was with Sprint, I had to deal with poor customer service, awful technical support, bottom of the barrel hardware, dropped calls constantly, and long periods without service... 4 very long years. After more dropped calls and awful Sprint Customer Service run-ins then I could keep track of -- I finally made the switch from Sprint PCS to AT&T's contract free Pay-As-You-Go service. Which may have been my first grave mistake, after leaving Sprint.
First and foremost AT&T's Pay-As-You-Go, GoPhone phone service is a complete rip-off. Never has a more insidious plan been hatched to trick a consumer into spending more money than they could've ever dreamed, than is Pay-As-You-Go service. First the cheapest GoPhone hardware costs $20 and text-messages cost 20¢ per message. Then you have to refill the phone with new "pre-paid" minutes before the old ones expire (after just 90 days) or you lose your GoPhone Phone Number. However, when you refill the GoPhone with new "pre-paid" minutes you lose whatever old minutes you had before refilling the phone [Messed up right?]. The rates for "pre-paid" refills vary, suffice to say, they're astronomical. What's worse, is the fact that AT&T GoPhone Customer Service works hard to convince Pay-As-You-Go customers to buy "pre-paid" minute refill cards from Best Buy ® instead of just paying AT&T directly. What's the downside they want consumers to overlook? Taxes! For example when a GoPhone user buys a $40 card of "pre-paid" minutes at Best Buy they also have to pay a sales tax fee on the card. However, when GoPhone users buy refill minutes with a debit card, directly from AT&T, they forego any sales tax charges (i.e.: $40 is $40! Not $42.80).
Now I had my GoPhone when I lived out west, and for the most part, ridiculous refill costs aside, my service worked pretty well. I didn't have nearly as many dropped calls as I did with Sprint. So about a year before I mooved to the Moodus area I decided to stop hemorrhaging money on refill minutes and got myself a contract plan with AT&T. If a GoPhone wasn't my first grave mistake after leaving Sprint... a full fledged contract plan with AT&T certainly was.
I was stuck with Sprint for 4 years because most contract plans last for 2 years, and the only way to get a new phone, new features, etc... (without switching cellular providers) is to renew your contract (usually for another 2 years minimum). And renew I did, just 3 months ago, while making the moove, after having an AT&T contract for 1 year, with decent service in my old area -- I renewed my contract; mostly so I could get a new "free" phone (as my old phone was falling apart). What a bad decision.
Right out the gate my new phone was a POS. It had this crummy little flip-flap, that did absolutely nothing. The flip-flap didn't even have a mic built into it, it just sat there covering the keys when it was flipped close. Beyond its useless parts, the "free" phone also has an awful Phone OS/UI. Navigating the phone was like trying to find your car-keys at the bottom of a gym-bag littered with hundreds of random items. Those initial "fail" points aside, as I said earlier in this article, my AT&T service has been piss poor since I mooved. But even before the moove things between me and AT&T weren't so peachy.
Most notably was the SIM card debacle that happend just after I switched from my GoPhone to my AT&T contract service. What happened was my original SIM card had come from my GoPhone, and when it was put into my contract phone it was never properly reprogrammed by the AT&T tech that made the exchange for me at the AT&T store. This mistake resulted in untold headaches for me when it came time to receive my billing statements after the install. The biggest headache was minutes I wasn't using during a given month where being reported by the GoPhone SIM to AT&T's contract billing department as "used" or "overage" minutes instead of "roll-over" minutes.
So I've been calling AT&T Customer Service, making sure to take down each employee's full name and identification number; and for the last 3 months I've argued my case with their customer service representatives, technical support staff members, & warranty department personnel -- to the point where I feel, I have finally achieved some form of resolution. After... approximately 17 calls, 4 phone exchanges, 3 debacles where they claimed I didn't return parts they told me not to return (the reason it's so important to keep fastidious documentation), 2 SIM card exchanges, and a partridge in a pear tree... AT&T has given me 5 months of free service and a new LG ® phone; and my service still sucks.
So... AT&T, worse than Sprint? Yes, No, Maybe, Who Cares. Everyone should get Verizon ®.
What's the shift all about? It's about... 16 pixels. Seriously though, it's about causing a nicely laid out web page to jump from side to side when you're navigating from page to page. It's a result of certain web browsers adding and removing the scroll bar on the right side of the page when pages don't require a user to scroll. This is fine & good on sites & pages aligned to the left. However, it's annoying, glitchy, and generally distracting to websites using a cleaner, centrally align style for web pages.
/* Vertical Scroll Shift Fix Revisited */
html {
min-height: 100%; /* set page height */
margin-bottom: 1px; /* force content beyond page */
overflow-y: scroll !important; /* Firefox 3.5 */
}
Oh if only the above line were true. That would imply an actual human being was on the phone when you called 1-800-COMCAST, which would be a small victory in the battle against Comcast ®. Who are perhaps the most vile... and when we rearrange the letters: evil Cable / Internet / Phone / Excrement provider that has ever been granted permission to do business inside the United States of America.
I currently rent a High Speed Internet Cable Modem and a High Definition DVR Cable Television Receiver from Comcast, and that alone is enough to mark the beginning of the end when you have to deal with this company.
Here's a quick run down of what they've managed to screw up since I moved into my new place 3 weeks ago.
So far in the last 24 days Comcast has...
I don't blame you if you didn't read every item I listed; there were a lot. And those are just the things I've dealt with over that last 24 days. That list doesn't cover half the battles I've fought with Comcast Customer Service over the last 2 years.
One major mistake they made about 18 months ago was signing me up for a package that didn't exist in my area. Let me elaborate... I decided I wanted a "bundle service" to save money on all the household IT services I normally use (i.e.: Landline Phone, Internet, and Television). So I gave good old Comcast a call.
Let's face it -- if you don't want a crappy DSL Modem, you're going to have to get a Cable Modem. However the modem I got from Comcast, after I purchased a $99.99 per month bundle service plan, was called a Phone Modem. And that is where all the trouble began...
Right away I called Comcast and told them my phone service was not working. 6 months, and 3 technicians later the Phone Modem still didn't give a dial tone. Why? After hours on the phone with Comcast I learned why. The reason was: There was no Comcast phone service in my area. My area had not yet been integrated into the phone portion of their network, or some such nonsense.
6 months I'm paying for this bundle service and only getting 2 out of 3 services. Seems pretty simple to me what should have been done to correct this. It doesn't take a degree in Rocket Science (heck it doesn't take a degree in Computer Engineering either and I've got one of those) to figure out what needed to be done to fix my problem... all anyone at Comcast needed was a little common sense. However I've learned that common sense is not a prerequisite to become an employee of Comcast.
Here's what I think should have been done: #1 - They should have refunded me the difference of 1/3 of my bundle service (since only 2 out of 3 services ever worked) times the 6 months I'd already paid [ $99.99 / 3 services × 6 months = $199.98 refund/credit ]. #2 - They should have removed phone service from my bundle.
Guess what? They didn't. Took me 4 months of phone calls and arm twisting to get anyone at Comcast to do what should have only taken someone in customer service 10 minutes to correct.
UPDATE [ Mon, 29 Jun 2009 23:48:00 GMT ]: In case anyone is wondering, thus far... since finishing this article: I've gotten Comcast to supply the DVR free of charge for one year. Been given, at least for the time being, some free channels on top of my basic channels (e.g.: Showtime, HBO, TLC, Science Channel, etc...). They've confirmed that all my old equipment has been returned. Given 2 standard credits of $20 each, which I had to request, for the missed appointments. I'm finally being billed the right package price for my bundle service and modem rental. One of their regional vice presidents of customer relations has given me a free month of service. And the largest miracle of all -- Comcast finally sent a construction crew to install new grounding rods, signal amplification boxes, and high speed coaxial cable drop lines to my home. Moreover the Western New England Region Manager of Executive Customer Care, Roger Falis actually sent me a printed letter guaranteeing me that my rates would not increase after my initial 6 month "promotional period" has ended.
[ see pictures below of the Comcast construction crew adding the new lines & equipment and a copy of Roger's letter. ]
Special Thanks to:
Thank you all for being shining examples of what customer service and technical support at Comcast should be!