<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CE8BRXs_eSp7ImA9WhRVGEo.&quot;"><id>tag:blogger.com,1999:blog-23214170</id><updated>2012-01-18T17:47:34.541+10:00</updated><category term="ruby" /><category term="linux" /><category term="business" /><category term="pcm" /><category term="proc_open" /><category term="ext" /><category term="web" /><category term="make money online" /><category term="development" /><category term="codeigniter" /><category term="doctrine" /><category term="ebusiness" /><category term="ideas" /><category term="dtmf" /><category term="c#" /><category term="mvc" /><category term="PHP" /><category term="filters" /><category term="execution" /><category term="transactions" /><category term="pinvoke" /><category term="shell" /><category term="rails" /><category term="orm" /><category term="script" /><category term="unit testing" /><category term="windows" /><category term="asp.net" /><category term="layouts" /><category term="popen" /><category term="redux" /><category term="wave" /><category term="extjs" /><category term="sampling" /><category term="profile" /><category term="money" /><title>The Code Abode</title><subtitle type="html">Primarily PHP, C#, .NET and web related technologies. Tips and tricks, code samples and discussions on web related technologies and business</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://thecodeabode.blogspot.com/" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/TheCodeAbode" /><feedburner:info uri="thecodeabode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DE8ARnY8fip7ImA9Wx9WE04.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-3212095664368907577</id><published>2011-01-18T08:45:00.003+10:00</published><updated>2011-01-18T17:47:27.876+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-18T17:47:27.876+10:00</app:edited><title>Detect the Adobe Reader Plugin</title><content type="html">Recently I had to be able to detect the Adobe Reader Plugin in Javascript. I have included the code I used to flag if the Adobe Reader Plugin is installed, as well as get the version of the current adobe reader plugin. This code will detect:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Adobe Reader Plugin for Firefox&lt;/li&gt;
&lt;li&gt;Adobe Reader Plugin for IE ( &amp;lt;5 and 5+)&lt;/li&gt;
&lt;li&gt;Adobe Reader Plugin for Chrome and&lt;/li&gt;
&lt;li&gt;The PDF Reader for Chrome (Chrome's default alternative to the&amp;nbsp;Adobe Reader Plugin)&lt;/li&gt;
&lt;li&gt;Adobe Reader Plugin for most other browsers&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/acrobat_detection.js.txt&amp;amp;track=TCA"&gt;View or Download the code here....&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To call it in javascript:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: lightgray; border: 1px dotted; color: black; font-size: 10px;"&gt;&lt;code&gt;
var browser_info = perform_acrobat_detection();
alert(browser_info.name + " "+browser_info.acrobat + " " + browser_info.acrobat_ver);
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-3212095664368907577?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4W9NWWpJnrJoCQiSf88FbnghJtg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4W9NWWpJnrJoCQiSf88FbnghJtg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4W9NWWpJnrJoCQiSf88FbnghJtg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4W9NWWpJnrJoCQiSf88FbnghJtg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/a4aQUT1z9cQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/3212095664368907577/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=3212095664368907577&amp;isPopup=true" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/3212095664368907577?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/3212095664368907577?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/a4aQUT1z9cQ/detect-adobe-reader-plugin.html" title="Detect the Adobe Reader Plugin" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2011/01/detect-adobe-reader-plugin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYCRns8eCp7ImA9Wx9RFUk.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-6307836527963592513</id><published>2010-12-01T11:36:00.003+10:00</published><updated>2010-12-17T09:29:27.570+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-17T09:29:27.570+10:00</app:edited><title>SQLite and Doctrine: in memory databases</title><content type="html">Recently for a client's project, I incorporated a SQLite in memory database into my persistence tests as its a good (and fast) alternative to managing separate unit test and system databases. Typically in my test setup / tear down methods, I drop and recreate the unit test database to ensure clean testing conditions.... however I found that Doctrine doesn't support SQLite in memory database drops. &lt;br /&gt;
&lt;br /&gt;
To drop an in memory db - I don't believe the standard sql drop statement works. As this is the case, when calling Doctrine::dropDatabases(), Doctrine's SQLite Driver produces in a 'Database could not be found' Exception in its dropDatabases method.&lt;br /&gt;
&lt;br /&gt;
As the SQLite in memory databases exist for the life of the connection only, a good solution is to simply reset the connection.&lt;br /&gt;
&lt;br /&gt;
Burrowing through the Doctrine framework, within the SQLite Driver (Doctrine/Connection/SQLite.php) I made the following modification:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: lightgray; border: 1px dotted; color: black; font-size: 10px;"&gt;&lt;code&gt;
 public function dropDatabase()
    {
        if ( ! $dsn = $this-&amp;gt;getOption('dsn')) {
            throw new Doctrine_Connection_Exception('You must create your Doctrine_Connection by using a valid Doctrine style dsn in order to use the create/drop database functionality');
        }
        
        $info = $this-&amp;gt;getManager()-&amp;gt;parseDsn($dsn);
        
        //
        // BENS EDIT: If the db is in memory only - simply recreate a new connection
        //
        if(strcasecmp($info["dsn"], "sqlite::memory:") == 0)
        {         
         $c = $this-&amp;gt;getManager()-&amp;gt;getCurrentConnection();

  $this-&amp;gt;getManager()-&amp;gt;closeConnection($c);
  $this-&amp;gt;getManager()-&amp;gt;connection("sqlite::memory:","unit_test");
     
         return;
        }
        //
        // END BENS EDIT
        //

        $this-&amp;gt;export-&amp;gt;dropDatabase($info['database']);
    }
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
There are probably better ways to do this - so feel free to leave comments - however the above worked for me...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-6307836527963592513?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nX2foYgk9kxOKuQ40d_92LgsWb8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nX2foYgk9kxOKuQ40d_92LgsWb8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nX2foYgk9kxOKuQ40d_92LgsWb8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nX2foYgk9kxOKuQ40d_92LgsWb8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/g225Jutq7Sw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/6307836527963592513/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=6307836527963592513&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/6307836527963592513?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/6307836527963592513?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/g225Jutq7Sw/dropping-sqlite-in-memory-databases-in.html" title="SQLite and Doctrine: in memory databases" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/12/dropping-sqlite-in-memory-databases-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEANQ3syeSp7ImA9Wx9TF08.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-7492060794765548514</id><published>2010-11-25T21:06:00.004+10:00</published><updated>2010-11-26T09:13:12.591+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T09:13:12.591+10:00</app:edited><title>CodeIgniter and PHP Howto - Embedding images in Email</title><content type="html">&lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/MyPages_Email.php.txt&amp;amp;track=TCA"&gt;DOWNLOAD THE CODEIGNITER EMAIL EXTENSION HERE&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I recently had an issue in a client's development which required images to be embedded in html email code (&amp;lt;img src='cid:embeddedImage' /&amp;gt;), rather than referenced via a public url (i.e. &amp;lt;img src='http://www.mysite.com/myImage.png' /&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;QUICK OVERVIEW - THE PUNCH LINE&lt;/h3&gt;I have written a CodeIgniter Library Extension to the basic Email class that facilitates the embedding of images in emails. You can download the code &lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/MyPages_Email.php.txt&amp;amp;track=TCA"&gt;HERE&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
To implement it, follow the instructions for Extending Native Libraries on the CodeIgniter website &lt;a href="http://codeigniter.com/user_guide/general/creating_libraries.html"&gt;http://codeigniter.com/user_guide/general/creating_libraries.html &lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Finally, in the body of your email, use the following macro - making sure the class_id attribute matches the one used in the img src attribute (i.e. &amp;lt;img src='cid:my_image' /&amp;gt;). An exmaple message body would be as follows&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: lightgray; border: 1px dotted; color: black; font-size: 10px;"&gt;&lt;code&gt;
&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;img src="cid:my_image" /&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

// Macro in Windows
{embedded_image file=C:\\my_image.png class_id=my_image}{/embedded_image}

//Alternative Linux Macro
{embedded_image file=/var/my_image.png class_id=my_image}{/embedded_image}

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
And thats it - the library encodes the image file as a base64 string and embeds it in your email.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;PROS AND CONS OF EMBEDDING IMAGES IN EMAIL:&lt;/h3&gt;&lt;h4&gt;PROS&lt;/h4&gt;- Images are immediately displayed when opening a message, rather than the client prompting the user to allow remote content... great for newsletters&lt;br /&gt;
- Emails are independent, once downloaded, they don't require a live connection to view in all their glory&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;CONS&lt;/h4&gt;- A little bit more coding and knowledge of email message format is required to get them to work if your framework does not support embedding images in email&lt;br /&gt;
- Some conjecture about spam filtering for bulk messages with embedded images. Some believe spam filtering is more pessimistic for emails with embedded images than not when sending to more than 100 addresses&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;HOW TO EMBED AN IMAGE&lt;/h3&gt;I'm not going to go too far into the coding of native php code to email with embedded images (unless I get requests) - so Ill give a brief overview and some references.&lt;br /&gt;
&lt;br /&gt;
Like most things on the web, email message content can be defined in a series of envelopes. These envelopes are defined by content type. You can read about all of them here &lt;a href="http://www.freesoft.org/CIE/RFC/1521/15.htm"&gt;http://www.freesoft.org/CIE/RFC/1521/15.htm&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
One of the most useful images to exemplify the content structure of a html email can be found at &lt;a href="http://www.phpeveryday.com/articles/PHP-Email-Using-Embedded-Images-in-HTML-Email-P113.html"&gt;http://www.phpeveryday.com/articles/PHP-Email-Using-Embedded-Images-in-HTML-Email-P113.html&lt;/a&gt;&lt;br /&gt;
Bit of a warning though - the article itself has buggy code and examples.&lt;br /&gt;
&lt;br /&gt;
Grossly speaking - your email message if it supports html with embedded images, and a plain text alternative (for non html email clients) should render the following content in the email body&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: lightgray; border: 1px dotted; color: black; font-size: 10px;"&gt;&lt;code&gt;
Content-Type: multipart/alternative; boundary="UNIQUE_ID_1"

--UNIQUE_ID_1
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

.... plain text alternative content for your html email....

--UNIQUE_ID_1
Content-Type: multipart/related;
 boundary="UNIQUE_ID_2"

--UNIQUE_ID_2
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

--UNIQUE_ID_2
Content-Type: image/jpeg
 name='embedded_image.jpg'
Content-Transfer-Encoding: base64
Content-ID: &amp;lt;class_id_referenced_in_img_src&amp;gt;
Content-Disposition: inline;
 filename='embedded_image.jpg'

(Base64 encoded binary for the image)

--UNIQUE_ID_2-- 

--UNIQUE_ID_1--

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;NOTE on the above.&lt;/h3&gt;-- means open content type. Trailing -- means closing content type. When content type is 'multipart', you can define more than one content type under the same section identifier as you are either specifying alternative content, or related content. multipart/alternative content means one of the specified content sections is used. multipart/related content means that one content section references the other. We use the multipart/alternative content type to specify html, and plain text message alternatives. We use the multipart/related for relating html content with embedded image content.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-7492060794765548514?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aa62hftRPYMXe45-vikx85GvXKE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aa62hftRPYMXe45-vikx85GvXKE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aa62hftRPYMXe45-vikx85GvXKE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aa62hftRPYMXe45-vikx85GvXKE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/KbzeGMYPd94" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/7492060794765548514/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=7492060794765548514&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7492060794765548514?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7492060794765548514?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/KbzeGMYPd94/codeigniter-and-php-howto-embedding.html" title="CodeIgniter and PHP Howto - Embedding images in Email" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/11/codeigniter-and-php-howto-embedding.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MMQHY4eyp7ImA9Wx9TFUg.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-4354167329149660528</id><published>2010-11-22T10:34:00.002+10:00</published><updated>2010-11-24T09:38:01.833+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-24T09:38:01.833+10:00</app:edited><title>noscript tag and google index</title><content type="html">The noscript tag is indexed by google! I recently released work for a client which used the noscript tag to display the typical 'this site needs javascript' warning if javascript was disabled on the client's browser.... unfortunately I did this in the head of my page AND used a h3 element to title the warning segment....&lt;br /&gt;
&lt;br /&gt;
As a result, most pages on the site were indexed as 'Javascript not enabled' as the title, and the site's metatagged description as the content. Not happy.&lt;br /&gt;
&lt;br /&gt;
Best practice - if you are going to use the noscript tag for simple javascript warnings, use it at the bottom of the rendered page.... many sites do this (including StackOverflow). Might also help not to use any heading elements (i.e. h1,h2,h3) but rely on styling another element as a heading.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-4354167329149660528?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6peyjSdunaA3oL5XJB2dp5_MwYE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6peyjSdunaA3oL5XJB2dp5_MwYE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6peyjSdunaA3oL5XJB2dp5_MwYE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6peyjSdunaA3oL5XJB2dp5_MwYE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/07QMfaJFCdQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/4354167329149660528/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=4354167329149660528&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/4354167329149660528?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/4354167329149660528?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/07QMfaJFCdQ/noscript-and-google-index.html" title="noscript tag and google index" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/11/noscript-and-google-index.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUGSX8-cCp7ImA9Wx5aGUU.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-7123436432804949578</id><published>2010-11-07T21:58:00.005+10:00</published><updated>2010-11-17T18:57:08.158+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-17T18:57:08.158+10:00</app:edited><title>Free DNS Servers: Free DNS Online</title><content type="html">For the last few years of web development, I have had to find a couple of reliable free DNS online services to manage my, and client Domains. I thought I'd post up a few and rate my experience with them. &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Free DNS Online - My Experiences&lt;/h2&gt;&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=www.zoneedit.com&amp;amp;track=TCA"&gt;Zone Edit&lt;/a&gt; : A great free DNS online service, 100% private and 100% free. Accounts used to be able to serve up to 5 domains, however recently this has been restricted to 2. The User Interface / Administration feels a bit clunky and old school web - but pretty straight forward and easy to use. &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=freedns.afraid.org&amp;amp;track=TCA"&gt;FreeDNS&lt;/a&gt; : Another good free DNS online service, however you entries can be reviewed by other users. Other users can configure subdomains off your domain, however you can pipe this through an authorisation process (where you the administrator are emailed and confirm any config changes). Payment is required if you want to make your listing private.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=www.dnsexit.com&amp;amp;track=TCA"&gt;DNSExit&lt;/a&gt; : An uncapped free DNS online service. You can have as many accounts as you require... you can even set up dynamic DNS which is nice. Very slow though - and I have some questions regarding reliability. Recently the service was brought down by a DDOS attack for a couple of days.... have a backup - secondary dns on an alternate name server if possible.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=www.dyndns.com&amp;amp;track=TCA"&gt;DynDns &lt;/a&gt;: Free Dynamic DNS online service. Been around for years - can't recommend it enough for publicly serving from your dev box. Great for limited serving (i.e. demoing sites during development). Have a range of other paid services - however, a bit of googling for these will uncover alternative free services.&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-7123436432804949578?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PrZPobv3RBsdZ2Swv1liYY9sWC4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PrZPobv3RBsdZ2Swv1liYY9sWC4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PrZPobv3RBsdZ2Swv1liYY9sWC4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PrZPobv3RBsdZ2Swv1liYY9sWC4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/eXdjHUUtZ7A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/7123436432804949578/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=7123436432804949578&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7123436432804949578?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7123436432804949578?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/eXdjHUUtZ7A/free-dns-servers-free-dns-online.html" title="Free DNS Servers: Free DNS Online" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/11/free-dns-servers-free-dns-online.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkABRHs8cSp7ImA9Wx5aEEk.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-8602669158428547150</id><published>2010-11-02T11:03:00.008+10:00</published><updated>2010-11-06T23:05:55.579+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-06T23:05:55.579+10:00</app:edited><title>Detect Popup Blocker: Popup Blocker  Detection for Chrome + all browsers</title><content type="html">The mother of all popup blocker detection in Javascript.... based on a few other blog posts around the below combines popup blocker detection for all major browsers including Chrome....&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The below javascript can be downloaded here &lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/popup_detection.js&amp;amp;track=TCA"&gt;popup_detection.js&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The chrome popup testing page used in the below fragment can be downloaded here&amp;nbsp;&lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/popup_with_chrome_js.html.txt&amp;amp;track=TCA"&gt;popup_with_chrome_js.html&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 10px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;var PopupWarning = {
  
  init : function()
  {      
      
    if(this.popups_are_disabled() == true)
    {       
      this.redirect_to_instruction_page();
    }
  },

  redirect_to_instruction_page : function()
  {
    document.location.href = "http://thecodeabode.blogspot.com/";
  },

  popups_are_disabled : function()
  {
    var popup = window.open("http://localhost/my_chrome_popup_test.html", "popup_tester", "width=1,height=1,left=0,top=0");
    
    if(!popup || popup.closed || typeof popup == 'undefined' || typeof popup.closed=='undefined')
    {
        return true;
    }

    window.focus();
    popup.blur();    

    //
    // Chrome popup detection requires that the popup validates itself 
    // - so we need to give
    // the popup time to load, then call js on the popup itself
    //
    if(navigator &amp;amp;&amp;amp; (navigator.userAgent.toLowerCase()).indexOf("chrome") &amp;gt; -1)
    {      
      var on_load_test = function(){PopupWarning.test_chrome_popups(popup);};    
      var timer = setTimeout(on_load_test, 60);
      return;
    }
    
    
    popup.close();
    return false;
  },

  test_chrome_popups : function(popup)
  {
    if(popup &amp;amp;&amp;amp; popup.chrome_popups_permitted &amp;amp;&amp;amp; popup.chrome_popups_permitted() == true)
    {      
      popup.close();
      return true;
    }
    
    //
    // If the popup js fails - popups are blocked
    //
    this.redirect_to_instruction_page();
  }
  };
  
  PopupWarning.init();
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Chrome popup blocker detection is a little different to others in that Chrome returns a valid window object after calling window.open, even with popups being disabled. There are a heap of posts around all basically stating that to determine whether this window object has been blocked by Chrome, we need to embed some simple detection code in the popup html itself.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As this is the case, you will need to create an additional html page which will be called as a popup in the PopupWarning.popups_are_disabled function. We also have to give it time to load in the new window, so that we can call the js method after it has been added to the popup dom. We achieve this by setting a timeout to call the popup js. The delay between creating the popup and calling the js test in the code above is about 60 ms. &lt;b&gt;This may have to be extended in an implementing page as 60ms may be too fast&lt;/b&gt;. This page is as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 10px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;script type="text/javascript"&amp;gt;
    //&amp;lt;![CDATA[
      function chrome_popups_permitted()
      {
        if(window.innerHeight != 0) 
        { 
          return true;
        } 
        else return false;
      }
    //]]&amp;gt;
    &amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;The javascript can be downloaded here &lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/popup_detection.js&amp;amp;track=TCA"&gt;popup_detection.js&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The chrome popup testing page used in the below fragment can be downloaded here&amp;nbsp;&lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/popup_with_chrome_js.html.txt&amp;amp;track=TCA"&gt;popup_with_chrome_js.html&lt;/a&gt;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-8602669158428547150?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gGOeQwoqC4uGXMlJ-sNv3eGa8fQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gGOeQwoqC4uGXMlJ-sNv3eGa8fQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gGOeQwoqC4uGXMlJ-sNv3eGa8fQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gGOeQwoqC4uGXMlJ-sNv3eGa8fQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/uig4Dg4nEVI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/8602669158428547150/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=8602669158428547150&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/8602669158428547150?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/8602669158428547150?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/uig4Dg4nEVI/window-open-popup-blocker-detect-for.html" title="Detect Popup Blocker: Popup Blocker  Detection for Chrome + all browsers" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/11/window-open-popup-blocker-detect-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8CRnc_fyp7ImA9Wx5UFU8.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-8955563210890621149</id><published>2010-10-15T19:26:00.002+10:00</published><updated>2010-10-20T08:37:47.947+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-20T08:37:47.947+10:00</app:edited><title>Google Analytics - multi domain named site tracking</title><content type="html">&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
Another quick blog... Recently I added analytics to a couple of sites with more than one domain name. Its easy to see how much of your traffic is from each hostname (Vistors-&amp;gt;Network Properties-&amp;gt;Hostnames), but&lt;br /&gt;
I wanted to be able to overlay how much traffic was arriving to the site from each domain (to see which one was most effectively being advertised).....&lt;br /&gt;
&lt;br /&gt;
I was able to achieve this by creating a &lt;b&gt;Custom Segment.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When first logging into the &lt;b&gt;Google Analytics Dashboard&lt;/b&gt; for the desired site / account, just above the Date Range, there is the &lt;b&gt;Advanced Segments&lt;/b&gt; drop down list. Clicking on that drop down I was able to create a new &lt;b&gt;Advanced Segment.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In the Advanced Segment editor, I could expand the &lt;b&gt;Content submenu&lt;/b&gt; from the Dimensions menu on the left, and drag the&lt;b&gt; 'HOSTNAME'&lt;/b&gt; field into my segment.&lt;br /&gt;
&lt;br /&gt;
I then set the &lt;b&gt;Condition&lt;/b&gt; field to &lt;b&gt;'CONTAINS'&lt;/b&gt;, then enter the base hostname of the additional domain I want to analyse separately (i.e. myseconddomain.com).&lt;br /&gt;
&lt;br /&gt;
After naming and saving the segment, I can apply it via the &lt;b&gt;Advanced Segments &lt;/b&gt;drop down in the &lt;b&gt;dashboard &lt;/b&gt;and viola....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-8955563210890621149?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/u9FcxlfFmnKpoe71G0q5hqMczAc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u9FcxlfFmnKpoe71G0q5hqMczAc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/u9FcxlfFmnKpoe71G0q5hqMczAc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/u9FcxlfFmnKpoe71G0q5hqMczAc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/NwX9lULb27E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/8955563210890621149/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=8955563210890621149&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/8955563210890621149?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/8955563210890621149?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/NwX9lULb27E/google-analytics-multi-domain-named.html" title="Google Analytics - multi domain named site tracking" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/10/google-analytics-multi-domain-named.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MNRHs8fSp7ImA9Wx5VFUw.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-5025641096962877729</id><published>2010-10-08T15:23:00.001+10:00</published><updated>2010-10-08T15:24:55.575+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-08T15:24:55.575+10:00</app:edited><title>CodeIgniter - Supporting Multiple Domains in config["base_url"]</title><content type="html">A very quick blog.....&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Within the site config file (application_folder/config/config.php file), a base_url property is set. This is read by the base_url() method to generate server side redirections......&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;If you are creating a site which has more than domain name (ie. www.domain_one.com and www.domain_two.com), its probably a good idea to dynamically create this value in the config file. This way, the domain name is preserved when redirecting between pages.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;br /&gt;
//...config ...//&lt;br /&gt;
$config['base_url'] = 'http';&lt;br /&gt;
if (isset($_SERVER["HTTPS"]) &amp;amp;&amp;amp; $_SERVER["HTTPS"] == "on") $config['base_url'] .= "s";&lt;br /&gt;
&lt;br /&gt;
$config['base_url'] .= "://";&lt;br /&gt;
&lt;br /&gt;
if ($_SERVER["SERVER_PORT"] != "80") $config['base_url'] .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"];&lt;br /&gt;
else $config['base_url'] .= $_SERVER["SERVER_NAME"];&lt;br /&gt;
&lt;br /&gt;
$config["base_url"]."/";&lt;br /&gt;
//... config ...//&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-5025641096962877729?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gg3mOdL0AqQdFCFON-Wze000jr4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gg3mOdL0AqQdFCFON-Wze000jr4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gg3mOdL0AqQdFCFON-Wze000jr4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gg3mOdL0AqQdFCFON-Wze000jr4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/j-OearYyA-Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/5025641096962877729/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=5025641096962877729&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/5025641096962877729?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/5025641096962877729?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/j-OearYyA-Y/codeigniter-supporting-multiple-domains.html" title="CodeIgniter - Supporting Multiple Domains in config[&quot;base_url&quot;]" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/10/codeigniter-supporting-multiple-domains.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcGRH4-fyp7ImA9Wx5aEEg.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-1560218569421241441</id><published>2010-10-06T16:04:00.011+10:00</published><updated>2010-11-06T23:27:05.057+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-06T23:27:05.057+10:00</app:edited><title>IE Cache and AJAX: Cache Busting Ajax requests</title><content type="html">Yet another 'special case' caveat for Internet Explorer, the red headed step child of the browser family..... (sorry to any red headed step children who might be reading this - chalk it up to the savage injustices of life). I discovered that IE cache and Ajax requests are not the best of friends compared to how other browsers handle Ajax requests.   &lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Recently I found that IE cached ajax requests in a CodeIgniter + ExtJS site. I was using url rewriting, so all GET params were encoded as URI segments...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;eg. (http://host/controller/action/param1/param2)&lt;/div&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;The Problem:&lt;/span&gt;&lt;br /&gt;
Usually, I would use ExtJS inherent cache busting tools (Ext.Ajax.disableCaching - which normally defaults to true).... but due to the url rewriting, the ExtJS method caused issues. Query string values (?blah=value) are disallowed in my app due to the url rewriting, therefore EXTs native cache disabling does not work as it simply appends a uid to the querystring (?_dc=123453443343). This caused 'disallowed character' exceptions.&lt;br /&gt;
&lt;br /&gt;
Furthermore - I couldn't simply add a random variable to the end of a request, as this could be misinterpreted as an actual parameter for actions with parameters with default values&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;eg. http://host/controller/action/param1/param2/no_cache01223213312&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
no_cache01223213312 could be misinterpreted as param3 in the following action:&lt;br /&gt;
&lt;div class="highlight"&gt;public function action($param1, $param2, $param3 = "default value")&lt;br /&gt;
{&lt;br /&gt;
//..//&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;The Solution:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;The Big Stick:&lt;/span&gt;&lt;br /&gt;
Whether you use an MVC framework, URL rewriting, the first thing you should consider is that on all Ajax actions, make sure the header 'pragma' is set to no-cache..... so in php - write the header somewhere before content is returned to the browser&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;header("Pragma: no-cache");&lt;/div&gt;&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;The ExtJS (Javascript) way:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
The Ext solution was at the page level to intercept all AJAX requests, and add a random POSTED variable to the parameter listing.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
Ext.Ajax.disableCaching = false;&lt;br /&gt;
Ext.Ajax.addListener("beforerequest", function (conn, options ){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;if(!options.params) options.params = {};&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;options.params.cacheBuster = Ext.id();  &lt;br /&gt;
}, this);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
This forces a server side request as the request is unique (thanks to the random post variable). It also allows me to free specify GET params in the rewritten url, as I am adding a POST variable to uniquify the request.&lt;br /&gt;
&lt;br /&gt;
For generic javascript.... when calling the target url, simply append a generated dummy query string parameter (like a timestamp)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;"http://myhost.com/myAjaxPage.php?_nocache=321313213445462"&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-1560218569421241441?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ypMSQp3vpDWTfD0fQmuKAA3US_M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ypMSQp3vpDWTfD0fQmuKAA3US_M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ypMSQp3vpDWTfD0fQmuKAA3US_M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ypMSQp3vpDWTfD0fQmuKAA3US_M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/tOW0Vm4h0Fs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/1560218569421241441/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=1560218569421241441&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/1560218569421241441?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/1560218569421241441?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/tOW0Vm4h0Fs/cache-busting-ajax-requests-in-ie.html" title="IE Cache and AJAX: Cache Busting Ajax requests" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQARXY7eSp7ImA9Wx5VEE0.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-7055085493556659460</id><published>2010-10-02T11:38:00.002+10:00</published><updated>2010-10-02T17:09:04.801+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-02T17:09:04.801+10:00</app:edited><title>Extra Bucks Online</title><content type="html">So in the past I have blogged a bit about finding an &lt;a href="http://thecodeabode.blogspot.com/2010/09/e-business-ideas.html"&gt;eBusiness which is quick to setup and get running&lt;/a&gt;. I'm pleased to announce that my latest attempt at this is entering its final proofing.....&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=www.extrabucks.com.au&amp;track=TCA"&gt;ExtraBucks&lt;/a&gt; is now online and is in its final proofing stages. The official launch date will come soon.... Essentially it is an odd jobs and piece work bulletin board. Its designed for those who want to make a bit of extra work outside of business hours to link up with people who need the odd job done. All 100% free to use. Check it out - have a play and feel free to leave some comments!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-7055085493556659460?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FMtv_sW1XM-JE1emdVbGdwT8YpM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FMtv_sW1XM-JE1emdVbGdwT8YpM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FMtv_sW1XM-JE1emdVbGdwT8YpM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FMtv_sW1XM-JE1emdVbGdwT8YpM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/udAypX-JAeQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/7055085493556659460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=7055085493556659460&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7055085493556659460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7055085493556659460?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/udAypX-JAeQ/extra-bucks-online.html" title="Extra Bucks Online" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/10/extra-bucks-online.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUANQX4_cSp7ImA9Wx5aGUU.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-7974576962989132421</id><published>2010-09-06T19:15:00.005+10:00</published><updated>2010-11-17T18:49:50.049+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-17T18:49:50.049+10:00</app:edited><title>Javascript Objects and Structures</title><content type="html">The difference between javascript objects and structures for the beginner (and often more experienced coders) is not always obvious, especially as Javascripts syntax differs a bit from other OO languages.&lt;br /&gt;
&lt;br /&gt;
In addition (generally speaking), I find that code conventions and format for Javascript are pretty loosely defined on most sites, encapsulation is generally pretty poor, which could be a pain when developing a heavily javascript dependent site, using structures with common names.&lt;br /&gt;
&lt;br /&gt;
I figured I'd post up examples of the differences between javascript objects and structures, as well as a few patterns and practices I use...&lt;br /&gt;
&lt;br /&gt;
Broadly speaking, the decision to code a javascript object, as opposed to a structure is determined by scope.... that is how its is to be used. Am I going to include this javascript fragment on a rendered page once? Or is it part of a resusable component that can be rendered any number of times on a page.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=downloads.beninzambia.com/blog/js_objects_and_variables.html.txt&amp;amp;track=TCA" target="_code"&gt;You can download the code for this here&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Javascript Objects&lt;/h4&gt;Javascript objects, can be thought of as components, or controls that can be &lt;b&gt;reused many times in a single page&lt;/b&gt;. Javascript Objects / Components are classes, whose definitions are included once in a page, but can be instantiated many times in a page (e.g. using the keyword 'new'). Below is a simple example - the component essentially renders a div with a text message, that is hidden when clicked.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;//&lt;br /&gt;
// All functions are objects in Javascript&lt;br /&gt;
//&lt;br /&gt;
var MessageElement = function(message, parentId)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; this.message = message;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; this.parentId = parentId;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; this.parent = document.getElementById(this.parentId);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; this.element = null;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; MessageElement.prototype.init = function()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{          &lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.element = document.createElement("div");&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.bindToElement(this.element);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.element.innerHTML = this.message;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.element.onclick = this.hide;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.parent.appendChild(this.element);                     &lt;br /&gt;
&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;// &lt;br /&gt;
&amp;nbsp;&amp;nbsp;// A helper function to ensure all MessageElement functions &lt;br /&gt;
&amp;nbsp;&amp;nbsp;// and variables are accessible from the element itself - &lt;br /&gt;
&amp;nbsp;&amp;nbsp;// this is important as when the div is clicked, the JS &lt;br /&gt;
&amp;nbsp;&amp;nbsp;// interpreter assigns key variable 'this' to be the DOM element&lt;br /&gt;
&amp;nbsp;&amp;nbsp;// that was clicked - not the actual MessageElement. For this &lt;br /&gt;
&amp;nbsp;&amp;nbsp;// reason, we ensure that the created DOM element references &lt;br /&gt;
&amp;nbsp;&amp;nbsp;// all variables and properties of MessageElement&lt;br /&gt;
&amp;nbsp;&amp;nbsp;//&lt;br /&gt;
&amp;nbsp;&amp;nbsp; MessageElement.prototype.bindToElement = function(element)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;for(prop in this) this.element[prop] = this[prop];          &lt;br /&gt;
&amp;nbsp;&amp;nbsp;};&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;MessageElement.prototype.addHandler = function(target, event, fn)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{            &lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;for(prop in this) target[prop] = this[prop];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;};&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; MessageElement.prototype.hide = function()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.element.setAttribute("style", "visibility:hidden;width:100px;height:20px");&lt;br /&gt;
&amp;nbsp;&amp;nbsp;};&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;this.init();&lt;br /&gt;
};&lt;/div&gt;&lt;br /&gt;
The code to add MessageElements to a page is demonstrated in Page Level Structures below.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Javascript Structures&lt;/h4&gt;Page level structures are essentially Singletons; page level, global variables - they can only be used once on a page. Typically, when used, they are used in base page markup, or on views / includes that are included no more than once on any given page. The following example is included in page markup, and creates 2 new MessageElement Components and adds them to the page. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;var MessagePanel = {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;messages : [],&lt;br /&gt;
&amp;nbsp;&amp;nbsp;init : function()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.messages.push(new MessageElement("The first element"));&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.messages.push(new MessageElement("The second element"));&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}        &lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
MessagePanel.init();&lt;/div&gt;&lt;br /&gt;
&lt;h4&gt;In Practice&lt;/h4&gt;Generally speaking, you could probably keep most javascript object definitions separately in js files, where as structures are defined inline in your scripted views / includes (i.e. php, rb, aspx views etc) as part of your page markup.&lt;br /&gt;
&lt;br /&gt;
Typically, javascript on webpages tends to be a hodge podge of directly included functions, which can at times get messy and sometimes confusing.&lt;br /&gt;
&lt;br /&gt;
As a rule of thumb, when starting a new system, I try to always include an Application variable, within the site's layout (masterpage / template / any other name for it), in which all common JS functions and variables exist, and can be accessed by all includes / views.&lt;br /&gt;
&lt;br /&gt;
Any Javascript specific to a view or include, I include in a scoped variable within script tags in the view markup (see above).&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Reasons why this approach is better:&lt;/h4&gt;&lt;b&gt;Its cleaner:&lt;/b&gt; all functions and variables are scoped within the MessagePanel, providing a form of namespacing. Should this be rendered as part of a view, you can easily identify all methods and variables owned by that view. This is not so important on simple screens, however, in more complicated web apps, you can avoid a lot of confusion by using this practice, and code remains well encapsulated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-7974576962989132421?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Y16QA7RIH75zrjp-uoKC20YW8qI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y16QA7RIH75zrjp-uoKC20YW8qI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Y16QA7RIH75zrjp-uoKC20YW8qI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y16QA7RIH75zrjp-uoKC20YW8qI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/JXy7ecbJKjg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/7974576962989132421/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=7974576962989132421&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7974576962989132421?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/7974576962989132421?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/JXy7ecbJKjg/javascript-objects-components-and-page.html" title="Javascript Objects and Structures" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/09/javascript-objects-components-and-page.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4BRXo_eip7ImA9Wx5UFU8.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-8591506709531646499</id><published>2010-09-03T12:53:00.024+10:00</published><updated>2010-10-20T08:39:14.442+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-20T08:39:14.442+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ideas" /><category scheme="http://www.blogger.com/atom/ns#" term="ebusiness" /><category scheme="http://www.blogger.com/atom/ns#" term="money" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><category scheme="http://www.blogger.com/atom/ns#" term="make money online" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>E-Business Ideas</title><content type="html">If any web developer is like me, you seem to spend a lot of time developing other people's business ideas and never seem to get enough time developing your own. I think I have tried about half a dozen different ideas for web businesses ranging from selling products to trying to create the next facebook. My problem has always been that of divided interests. Coding vs. Marketing. I am a developer first and foremost, and so my interest in my own projects has really been largely motivated by my need to try out new designs, patterns and methodologies, rather than making money.&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Another issue is that of long term plan. Do I want one 'big earner' business which I pour all my effort into, or a string of smaller websites, all of them bringing in a little bit. I have been involved (equity) in a number of larger web&amp;nbsp;endeavors, indeed, I find that as a developer, most startups are willing to carve up part of their new company in an effort to get some cut price development time. This is usually a bad sign - if the business had promise, they would risk a bit and get a loan to pay developer rates, rather than&amp;nbsp;marginalize&amp;nbsp;their profit.&lt;br /&gt;
&lt;br /&gt;
Personal choice - for me investment principles apply... don't put all your eggs in one basket. I would rather have a heap of small earners, than one big one. It gives a bit more stability as the marketplace can change rapidly. To do this - I need a string of LOW MAINTENANCE businesses, so that I am not forced to spend my time bouncing from business to business.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;How to find a business that runs itself:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
So, with that in mind, and with the intention to actually earn some extra cash, I've tried to move away from hands on development, and look for third party systems, or rebrandable eBusinesses, that I can install and configure in a short amount of time, and market, and hopefully gain an additional income!&lt;br /&gt;
&lt;br /&gt;
I want low fuss, low maintenance eBusinesses, so anything to do with me having to ship a product was out, as I didn't want to much around with postage issues. I wanted something that could run itself (i.e. an online service, or selling software), and that didn't require my intervention on a daily basis.&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: medium; font-weight: normal;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;eBusiness Ideas and Rebrandable Services:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Below are just a few sites, services and ideas I have found so far. Feel free to leave comments on anything you have found (no spammers).&lt;br /&gt;
&lt;br /&gt;
&lt;div style="float: left; margin-right: 15px;"&gt;&lt;a href="http://utils.beninzambia.com/linker.php?pt=0998cwrkygvr2q2652j7yaubav&amp;amp;track=TCA" target="_top"&gt;&lt;br /&gt;
&lt;img src="http://downloads.beninzambia.com/images/ebook.jpg" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?pt=0998cwrkygvr2q2652j7yaubav&amp;amp;track=TCA" target="_top"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Selling eBooks&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
eBooks are a great product - simple, useful, eBooks don't breakdown, and are rarely refunded. Customers can download the product, so there is no postage and handling, all you need to do is&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Find the eBooks to sell&lt;/li&gt;
&lt;li&gt;Promote the site and&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Collect the cash.&lt;/li&gt;
&lt;/ol&gt;There are a couple of web apps which pretty much gives you cheap way to get a ready-made eBook Business.&amp;nbsp;&lt;a href="http://utils.beninzambia.com/linker.php?pt=0998cwrkygvr2q2652j7yaubav&amp;amp;track=TCA" target="_top"&gt;eBook Sales Page&lt;/a&gt;&amp;nbsp;is one of these. It provides you with an onsellable eBook library site. You get the site, as well as an initial eBook library to sell. I haven't tried it personally, but (from the sales blurb) I believe its as easy as creating an account with them to get started.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="float: left; margin-right: 15px;"&gt;&lt;a href="http://utils.beninzambia.com/linker.php?pt=be6e30oeld5wcwdme83k4bz71x&amp;amp;track=TCAA" target="_top"&gt;&lt;br /&gt;
&lt;img src="http://downloads.beninzambia.com/images/tcslogoA.gif" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?pt=be6e30oeld5wcwdme83k4bz71x&amp;amp;track=TCA" target="_top"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Web Host reselling&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;
Onsell webspace to other developers (and recoup some of your own development costs). This isn't as 'set and forget' as eBooks, however, the idea is not to become a huge web hosting datacenter, but simply onsell to existing clients (if you are a developer). Chances are, if you are a developer, you'd spend a bit of time playing around with other client web host config and maintenance anyway.... why not work it for you?&lt;br /&gt;
&lt;br /&gt;
To get you started, have a look at &lt;a href="http://utils.beninzambia.com/linker.php?pt=be6e30oeld5wcwdme83k4bz71x&amp;amp;track=TCA" target="_top"&gt;Time Critical Solutions&lt;/a&gt;. They have a solid reselling program. Another is&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?pt=239cc2iky4wvcn8shxn0e9gu1w&amp;amp;track=TCA" target="_top"&gt;Atom Bull&lt;/a&gt;. Alternatively, if you don't want a turnkey solution, you could set up a VPS for some small scale, self managed webhosting. &lt;a href="http://utils.beninzambia.com/linker.php?pt=c3f13-j8ra4qaq1b0iug7cexe5&amp;amp;track=TCA" target="_top"&gt;Smart FX&lt;/a&gt; offer a decent VPS service. However, I recently set up one with &lt;a href="http://utils.beninzambia.com/linker.php?direct=www.jumba.com.au&amp;amp;track=TCA"&gt;Jumba&lt;/a&gt; for about $10 AUD per month.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="float: left; margin-right: 15px;"&gt;&lt;a href="http://utils.beninzambia.com/linker.php?direct=extensions.joomla.org&amp;amp;track=TCA" target="_top"&gt;&lt;br /&gt;
&lt;img src="http://downloads.beninzambia.com/images/joomla.png" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=www.joomla.org&amp;amp;track=TCA"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;CMS + Extensions&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
Half the time great ideas already exist, and people are making money off them so I don't see the point in killing &amp;nbsp;yourself trying to invent the next big thing online. Content Management Systems like Joomla! and Drupal have thousands of useful extensions which could be configured into ready made businesses - especially if your a little tech savy. For example, creating an ad / classified site is dead easy using Joomla! with the Sobi2 extension. All payment infrastructure and ad posting / searching facilities are baked in. Other things like SMS content based services, document management services etc. are all freely accessible in the extensions directories of the CMS of your choice.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;u&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Online SMS&lt;/span&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
Even though we have well and truly entered the age of the smart phone, and mobile internet, there are still a heap of business applications for content delivery via SMS. Services requiring information alerting and timed content delivery (i.e. reminder services, appointment confirmation services, stock market monitoring) still exist, and SMS is still a viable option.&lt;br /&gt;
&lt;br /&gt;
These sort of online services do require development work, although there probably are a heap of CMS extensions which allow you to manage an SMS service (if not - you could write one and make money).&lt;br /&gt;
An SMS Information delivery service simply wraps services like&amp;nbsp;&lt;a href="http://utils.beninzambia.com/linker.php?direct=www.clickatel.com&amp;amp;track=TCA"&gt;ClickATel&lt;/a&gt;, and &lt;a href="http://utils.beninzambia.com/linker.php?direct=www.redcoal.com.au&amp;amp;track=TCA"&gt;RedCoal&lt;/a&gt;, who give you a way to integrate SMS into your site (ClickATel is cheapest). I have &amp;nbsp;written many SMS based services for online sites / applications.... don't let fear of the unknown scare you - it is a real no brainer to integrate third party services. Some site ideas include:&lt;br /&gt;
&lt;br /&gt;
ONE WAY SMS:&lt;br /&gt;
&amp;nbsp;- Daily SMS Service - Inspirational Quotes, Motivational Messages, Natural Disasters... there are already a heap of people making money out of this sort of daily sms service.&lt;br /&gt;
&lt;br /&gt;
TWO WAY SMS:&lt;br /&gt;
&amp;nbsp;- Request and Send services: Train timetables, Stock Market quotes, people send a request, your site sends the info&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-8591506709531646499?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HQS0TZQ4S7hJIau9RR2Vj04jwoI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HQS0TZQ4S7hJIau9RR2Vj04jwoI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HQS0TZQ4S7hJIau9RR2Vj04jwoI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HQS0TZQ4S7hJIau9RR2Vj04jwoI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/4bQrnN9p7J0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/8591506709531646499/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=8591506709531646499&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/8591506709531646499?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/8591506709531646499?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/4bQrnN9p7J0/e-business-ideas.html" title="E-Business Ideas" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/09/e-business-ideas.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUEQXk8fyp7ImA9Wx5XF0o.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-6150499578541559126</id><published>2010-08-09T22:42:00.003+10:00</published><updated>2010-09-18T10:36:40.777+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-18T10:36:40.777+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="development" /><category scheme="http://www.blogger.com/atom/ns#" term="proc_open" /><category scheme="http://www.blogger.com/atom/ns#" term="execution" /><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><category scheme="http://www.blogger.com/atom/ns#" term="script" /><category scheme="http://www.blogger.com/atom/ns#" term="popen" /><title>Calling the php interpreter within web script</title><content type="html">Recently, part of a development required me to execute shell script as part of a web request. The design was to kick start a long running php process (via shell script), which would run beyond the length of a standard web request.&amp;nbsp;To do this, I used forking shell script and popen... (if using shared hosting, shell execution methods are generally disabled - check php.ini's disable_functions config value to verify).&lt;br /&gt;
&lt;br /&gt;
Within my dev environment (Windows) I was able to execute the following with no issues:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;popen("start /b php my_script.php my_args", "w");&lt;/div&gt;&lt;b&gt;Note: 'start /b' forks a windows process - making it run in the background&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When executing its equivalent in a Linux environment&lt;br /&gt;
&lt;div class="highlight"&gt;popen("php my_script.php my_args &amp;amp;", "w");&lt;/div&gt;&lt;br /&gt;
In Linux, the server was thrown into a state of confusion, perpetually executing, then aborting the requested shell script command (infinitely starting and exiting the requested php script in the popen command). Obviously explicitly calling the php interpreter from within an executing php process is a particularly nasty thing to do. &lt;br /&gt;
&lt;br /&gt;
I'm assuming this sort of thing doesn't happen in windows as shell script executes in its own command window (which when using proc_open with get_proc_status makes getting a correct PID value problematic). Anyone with futher insight - feel free to leave comments.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To get around this issue&lt;/b&gt;, I ensured that in the linux environment, the shebang path to the interpreter appeared on the first line of the executing script, and it was chmod'ed to allow direct cli execution... ie&lt;br /&gt;
&lt;br /&gt;
my_script.php:&lt;br /&gt;
&lt;div class="highlight"&gt;#!/usr/local/bin/php&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// my code&lt;br /&gt;
//&lt;br /&gt;
?&amp;gt;&lt;/div&gt;&lt;br /&gt;
CHMOD command used:&lt;br /&gt;
&lt;div class="highlight"&gt;chmod 755 my_script.php&lt;/div&gt;&lt;br /&gt;
Then finally the linux popen command:&lt;br /&gt;
&lt;div class="highlight"&gt;popen("./my_script.php my_args &amp;amp;", "w");&lt;/div&gt;&lt;br /&gt;
The default working directory of popen, and all other shell script execution methods is always web root (so my_script.php sat in the web root dir).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The same issue occurs with all other shell script execution methods:&lt;/b&gt;&lt;br /&gt;
system, exec, proc_open, passthru, back ticks (`) etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-6150499578541559126?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8EC7esUe9FypOE5GVQ7YZspXKm4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8EC7esUe9FypOE5GVQ7YZspXKm4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8EC7esUe9FypOE5GVQ7YZspXKm4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8EC7esUe9FypOE5GVQ7YZspXKm4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/KEN1hR81qJc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/6150499578541559126/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=6150499578541559126&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/6150499578541559126?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/6150499578541559126?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/KEN1hR81qJc/calling-php-interpreter-within-web.html" title="Calling the php interpreter within web script" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/08/calling-php-interpreter-within-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMMRnk7fCp7ImA9Wx5XF0o.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-1643870170773988151</id><published>2010-06-27T21:45:00.003+10:00</published><updated>2010-09-18T11:14:47.704+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-18T11:14:47.704+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="transactions" /><category scheme="http://www.blogger.com/atom/ns#" term="filters" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="doctrine" /><category scheme="http://www.blogger.com/atom/ns#" term="layouts" /><category scheme="http://www.blogger.com/atom/ns#" term="codeigniter" /><title>CodeIgniter - Ruby on Rails (RoR) Layouts and filters</title><content type="html">&lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/CodeIgniter-Doctrine-ExtJS_Base_Project.zip&amp;amp;track=TCA"&gt;DOWNLOAD THE CODEIGNITER DOCTRINE STARTER (~8Mb)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Continuing to list starter features, I have also integrated Ruby on Rails (RoR) style layouts and before / after filters.&lt;br /&gt;
&lt;br /&gt;
Both were implemented as CI hooks - both the layout and filter code was obtained from the CodeIgniter forums and wiki posts&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Layouts:&amp;nbsp;&lt;a href="http://utils.beninzambia.com/linker.php?direct=codeigniter.com/forums/viewthread/57902/&amp;amp;track=TCA"&gt;CodeIgniter Forums Post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Filters:&amp;nbsp;&lt;a href="http://utils.beninzambia.com/linker.php?direct=codeigniter.com/wiki/Filters_system/&amp;amp;track=TCA"&gt;CodeIgniter Forums Post - Filters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Using the Filters hook, each action is wrapped in a Doctrine Transaction, which ensures all db updates etc. are ATOMIC.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;One hassle I found with the above Filters system was that I couldn't implement a before / after filter directly in the controller class. Within the Doctrine_Transaction filter I ensure that if a controller has a before_action, or after_action function within its class definition, it is called before, or after the action is executed. This obviously could / should be abstracted out eventually into its own Filter class.... but it works just the same as is.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/CodeIgniter-Doctrine-ExtJS_Base_Project.zip&amp;amp;track=TCA"&gt;DOWNLOAD THE CODEIGNITER DOCTRINE STARTER (~8Mb)&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-1643870170773988151?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RY9Cx4nu5C6j704CtyNKGLPeaCw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RY9Cx4nu5C6j704CtyNKGLPeaCw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RY9Cx4nu5C6j704CtyNKGLPeaCw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RY9Cx4nu5C6j704CtyNKGLPeaCw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/2cEHqhq8GWw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/1643870170773988151/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=1643870170773988151&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/1643870170773988151?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/1643870170773988151?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/2cEHqhq8GWw/codeigniter-ruby-on-rails-ror-layouts.html" title="CodeIgniter - Ruby on Rails (RoR) Layouts and filters" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/06/codeigniter-ruby-on-rails-ror-layouts.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQHR3w5eip7ImA9Wx5VEk4.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-3941891294278005183</id><published>2010-06-08T18:06:00.011+10:00</published><updated>2010-10-05T10:25:36.222+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-05T10:25:36.222+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="doctrine" /><category scheme="http://www.blogger.com/atom/ns#" term="codeigniter" /><title>CodeIgniter - Doctrine unit testing - starter features</title><content type="html">&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
So to expand on the previous post... specifically to describe a few of the extra bells and whistles in the project starter....&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/CodeIgniter-Doctrine-ExtJS_Base_Project.zip&amp;amp;track=TCA"&gt;DOWNLOAD THE CODEIGNITER-DOCTRINE STARTER (~8Mb)&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Unit Testing&lt;/b&gt;&lt;/div&gt;&lt;div&gt;I have created a (very) simple extension to the codeigniter unit testing as I wanted to have a simple, web based interface to unit tests. I found the whole CodeIgniter terminology used in unit testing a little confusing (coming from a NUnit / JUnit testing background). Unless I missed something in the doc (which is very possible), CodeIgniter supports test assertions ($controller-&amp;gt;unit-&amp;gt;run when the test helper is loaded), there was no way to group a number of assertions together into a logical unit of testing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I'm going to use a little NUnit / JUnit terminology to describe unit testing via the web page interface in the starter. In the ApplicationCode/libraries folder I have a &lt;b&gt;base_test_controller&lt;/b&gt; which when extended replicates basic &lt;b&gt;TestFixture &lt;/b&gt;functionality. To create a &lt;b&gt;Unit Test&lt;/b&gt; within the fixture, simply create a function prefixed with the name test_. The following demonstrates using a controller as a &lt;b&gt;test fixture&lt;/b&gt;:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;// My Test Fixture&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;class MyTest extends base_test_controller {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;   &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;// This method is executed before any test methods are run&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;function fixture_setup(){}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;// This method is executed after all test methods are run&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;function fixture_tear_down(){}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;// This method is executed before each test method is run&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;function unit_setup(){}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;// This method is executed after each test method is run&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;//&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;function unit_tear_down(){}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// Your Unit Test&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;function test_My_unit_test()&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;    $this-&amp;gt;test_description = "This is a description of my unit test";&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;    $this-&amp;gt;unit-&amp;gt;run(true, true, "Assertion one has passed");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;    $this-&amp;gt;unit-&amp;gt;run(true, true, "Assertion two has passed");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif;"&gt;&lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/CodeIgniter-Doctrine-ExtJS_Base_Project.zip&amp;amp;track=TCA"&gt;DOWNLOAD THE CODEIGNITER-DOCTRINE STARTER (~8Mb)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-3941891294278005183?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FE3UzRXV1HzH0DYTh6nWn6H7Df4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FE3UzRXV1HzH0DYTh6nWn6H7Df4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FE3UzRXV1HzH0DYTh6nWn6H7Df4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FE3UzRXV1HzH0DYTh6nWn6H7Df4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/LdbtgxK-4H0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/3941891294278005183/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=3941891294278005183&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/3941891294278005183?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/3941891294278005183?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/LdbtgxK-4H0/codeigniter-doctrine-starter-features.html" title="CodeIgniter - Doctrine unit testing - starter features" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/06/codeigniter-doctrine-starter-features.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYGRns6eyp7ImA9Wx5UFU8.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-6551842118105245495</id><published>2010-06-05T14:08:00.021+10:00</published><updated>2010-10-20T08:42:07.513+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-20T08:42:07.513+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="ext" /><category scheme="http://www.blogger.com/atom/ns#" term="orm" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><category scheme="http://www.blogger.com/atom/ns#" term="redux" /><category scheme="http://www.blogger.com/atom/ns#" term="doctrine" /><category scheme="http://www.blogger.com/atom/ns#" term="codeigniter" /><title>PHP, CodeIgniter, Doctrine and ExtJS</title><content type="html">&lt;div&gt;&lt;span class="Apple-style-span" style="color: #ff6600;"&gt;&lt;b&gt;&lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/CodeIgniter-Doctrine-ExtJS_Base_Project.zip&amp;amp;track=TCA"&gt;DOWNLOAD THE  PROJECT STARTER (~8Mb)&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;So, its been ages since I have posted anything on this particular blog, so time for an update. &lt;br /&gt;
&lt;/div&gt;&lt;script type="text/javascript"&gt;
&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;Although I still dabble with MS technologies, I find the bulk of my development has moved to MVC geared frameworks (ideally rails based) - which (I find) works best within the contexts of dynamic languages..... so I have been using platforms like Ruby, JRuby, PHP, even ColdFusion for the last few projects. My tech stack of choice is:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;ExtJS : client side JS library&lt;/div&gt;&lt;div&gt;JRuby : presentation tier&lt;/div&gt;&lt;div&gt;Java + Hibernate : domain + data layer&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;In the latest project however I have been developing a survey site in PHP. I thought that to save anyone else time, I have created a 'project starter' development stub which incorporates:&lt;/div&gt;&lt;div style="background: #338888; border: 1px solid black; color: white; margin-top: 20px;"&gt;&lt;ul&gt;&lt;li&gt;ExtJS 3.2.0: client side JS library, &lt;/li&gt;
&lt;li&gt;CodeIgniter 1.7.2: presentation + domain tier,&lt;/li&gt;
&lt;li&gt;Doctrine 1.2: ORM data layer framework&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The idea being that you can simply extract and develop, without wasting time integrating all the techologies so that they work together....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Some features of this project starter are:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;CodeIgniter Models have been replaced with Doctrine Records&lt;/li&gt;
&lt;li&gt;Doctrine is loaded into CI as a plugin&lt;/li&gt;
&lt;li&gt;RoR type before and after filters....&lt;/li&gt;
&lt;li&gt;Doctrine transactions automatically wrapped around every action at execution time (ATOMIC db updates)&lt;/li&gt;
&lt;li&gt;Basic Role based security (I think Redux may be in there as well?)&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Simply extract, hook up the database.php config file and viola.... You can start coding your layouts, views and models.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;Licensing: refer to all integrated frameworks licensing agreements for details (i.e. Doctrine, ExtJS, CodeIgniter). &lt;/b&gt;Original licensing agreements are bundled in the Project starter for your reference. The Project starter is a freely distributed, open source integration of technologies. Just make sure that you are using each framework in adherence to their respective licensing terms.&amp;nbsp;As far as I am aware all technologies can be freely used under GPL....&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #ff6600;"&gt;&lt;b&gt;&lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/CodeIgniter-Doctrine-ExtJS_Base_Project.zip&amp;amp;track=TCA"&gt;DOWNLOAD THE  PROJECT STARTER (~8Mb)&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-6551842118105245495?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HChFdcvzsdUQehyb6iUBrtZrNp4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HChFdcvzsdUQehyb6iUBrtZrNp4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HChFdcvzsdUQehyb6iUBrtZrNp4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HChFdcvzsdUQehyb6iUBrtZrNp4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/hdbdljiO9DA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/6551842118105245495/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=6551842118105245495&amp;isPopup=true" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/6551842118105245495?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/6551842118105245495?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/hdbdljiO9DA/php-codeigniter-doctrine-and-extjs.html" title="PHP, CodeIgniter, Doctrine and ExtJS" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2010/06/php-codeigniter-doctrine-and-extjs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcMSX8zfyp7ImA9Wx9SFkw.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-847097292281451558</id><published>2006-12-06T16:47:00.000+10:00</published><updated>2010-12-06T16:48:08.187+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-06T16:48:08.187+10:00</app:edited><title>Reimaging a RAID array from ATA using Windows XP</title><content type="html">&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: verdana;"&gt;Recently I found myself in the awkward position of needing to&amp;nbsp;&lt;span style="font-weight: bold;"&gt;replace&amp;nbsp;&lt;/span&gt;my laptop's&amp;nbsp;&lt;span style="font-weight: bold;"&gt;ATA&amp;nbsp;&lt;/span&gt;Hard Drive with a&amp;nbsp;&lt;span style="font-weight: bold;"&gt;RAID&amp;nbsp;&lt;/span&gt;array (RAID 0 - Striping). Generally this should be a happy time due to the HDD performance boost you could expect from a striped array. Unfortunately - I could not afford to loose too much time installing the drive and setting up the necessary software environment.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: verdana;"&gt;The obvious solution to this is to&amp;nbsp;&lt;span style="font-weight: bold;"&gt;image the new RAID array using the old drive's contents&lt;/span&gt;&amp;nbsp;and generally, this would be a relatively painless proceedure. RAID tends to complicate matters however, as windows requires RAID drivers at installation. Using an installation of XP from an image taken from a non RAID'ed drive results unpredicatable results (freezes, BSOD etc.) when imaged to a RAID'ed one. In addition,&amp;nbsp;&lt;span style="font-weight: bold;"&gt;not all imaging software supports RAID&lt;/span&gt;&amp;nbsp;imaging. Norton Ghost 2003 and earlier do not support RAID..... I used a trial version of&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.acronis.com/" style="font-family: verdana;"&gt;Acronis True Image&lt;/a&gt;&lt;span style="font-family: verdana;"&gt;&amp;nbsp;which worked like a charm.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: verdana;"&gt;To get Windows working, after applying the image to the newly installed RAID array, you can boot from the Windows CD and&amp;nbsp;&lt;span style="font-weight: bold;"&gt;repair the imaged windows&lt;/span&gt;&amp;nbsp;installation. Other drivers such as&amp;nbsp;&lt;span style="font-weight: bold;"&gt;video drivers&lt;/span&gt;&amp;nbsp;should probably be installed - I found my nVidia GeForce 6800 prevented me from booting into Windows. I could load Windows Safe mode with network support however.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: verdana;"&gt;Below is a list of&amp;nbsp;&lt;span style="font-weight: bold;"&gt;the steps I took&lt;/span&gt;&amp;nbsp;to install RAID and restore my previous software environment:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;fieldset title="Steps"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: verdana; font-weight: bold;"&gt;PREPARATION&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol style="font-family: verdana;"&gt;&lt;li&gt;Installed&amp;nbsp;&lt;a href="http://www.acronis.com/"&gt;Acronis True Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ran a backup to an external USB HDD&lt;/li&gt;
&lt;li&gt;Created a bootable CD in Acronis&lt;/li&gt;
&lt;/ol&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: verdana; font-weight: bold;"&gt;RAID INSTALLATION&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol style="font-family: verdana;"&gt;&lt;li&gt;Copied RAID Drivers to floppy disk&lt;/li&gt;
&lt;li&gt;Booted into BIOS to check boot order (floppy, CD, hdd etc.)&lt;/li&gt;
&lt;li&gt;Cracked open the laptop and removed the old hdd.&lt;/li&gt;
&lt;li&gt;Set the jumpers on the new Slave hdd to cable select (as per specs for Alienware laptops)&lt;/li&gt;
&lt;li&gt;Installed 2 new hdds (of equal size, speed etc)&lt;/li&gt;
&lt;li&gt;Booted into BIOS and set the HDD Mode to RAID&lt;/li&gt;
&lt;li&gt;Save and Exit&lt;/li&gt;
&lt;li&gt;Boot into RAID BIOS (I used FastTrack.... CTRL-F at bootup)&lt;/li&gt;
&lt;li&gt;Include both the installed hdds to a Striped (RAID 0) array&lt;/li&gt;
&lt;li&gt;Save and Exit&lt;/li&gt;
&lt;li&gt;Verify on bootup display that the RAID array can be detected&lt;/li&gt;
&lt;/ol&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: verdana;"&gt;&lt;span style="font-weight: bold;"&gt;REIMAGING&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol style="font-family: verdana;"&gt;&lt;li&gt;Boot off the Acronis Bootable CD (PREPARATION - step 3)&lt;/li&gt;
&lt;li&gt;Follow the prompts to reinstate the image stored on the USB HDD - resizing the target partition size if necessary.&lt;/li&gt;
&lt;li&gt;Boot off the Windows CD leaving the RAID Drivers in the floppy drive (RAID INSTALLATION Step 1)&lt;/li&gt;
&lt;li&gt;Press F6 when prompted to install third party SCSI or RAID Driver&lt;/li&gt;
&lt;li&gt;Select the driver from the options given&lt;/li&gt;
&lt;li&gt;Proceed through Windows installation until asked if you wish to repair an existing installation of Windows&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;-NOTE - Do not choose the Recover a Windows installation option at the start of the Windows installation process.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Select Yes and select the installation of Windows you wish to repair&lt;/li&gt;
&lt;li&gt;Continue reinstalling Windows.&lt;/li&gt;
&lt;li&gt;Boot into Windows safe mode.&lt;/li&gt;
&lt;li&gt;Reinstall motherboard chipset, video and sound drivers.&lt;/li&gt;
&lt;li&gt;Boot into Windows and everyone's happy.&lt;/li&gt;
&lt;/ol&gt;&lt;/fieldset&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-847097292281451558?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8b1Y0qIKsdKtaU9oK7Dn27CG12I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8b1Y0qIKsdKtaU9oK7Dn27CG12I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8b1Y0qIKsdKtaU9oK7Dn27CG12I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8b1Y0qIKsdKtaU9oK7Dn27CG12I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/9xvQdWXf9Jg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/847097292281451558/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=847097292281451558&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/847097292281451558?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/847097292281451558?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/9xvQdWXf9Jg/reimaging-raid-array-from-ata-using.html" title="Reimaging a RAID array from ATA using Windows XP" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2006/12/reimaging-raid-array-from-ata-using.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYCRX48eip7ImA9Wx5VEk4.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-114791209426743438</id><published>2006-05-18T09:50:00.005+10:00</published><updated>2010-10-05T10:22:44.072+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-05T10:22:44.072+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="profile" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>Asp.net 2.0 Profiling - Auto Saving Form Data</title><content type="html">&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;div class="MsoNormal"&gt;Microsoft has extended the standard web state persistence models with the addition of profiling in the ASP.NET 2.0 framework. Essentially using profiling is identical to using the HttpSession, the difference is that user data is persisted between site visits. By using the Profile, a website is able to save and retrieve persisted user data regardless of the user's browser / session / machine state. &lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;We are now able to persist user specific data (i.e. session information) between site visits without needing to write a data abstraction layer (db interface). &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="MsoNormal"&gt;In other words, we can save session related information between sessions. Ignoring all the extra ASP.NET 2.0 Framework bells and whistles, an obvious use for Profiling would be found in UI design; saving and repopulating the entered data of Form input controls (i.e. Textbox) between a user's visits. One use for this sort of functionality would be remembering a User’s previous search in search pages. Another use would be to temporarily save a User’s progress through larger form based work processes (i.e. completing an online survey). This way, should the User’s Session be interrupted (i.e. browser crash), the User can continue data entry from where they last left off the next time they log onto your Site.&lt;span style="font-weight: bold;"&gt; User form data is automatically saved on postback without the need for special persistence code.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;
The &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/ProfilePersistence.zip&amp;amp;track=TCA"&gt;example code&lt;/a&gt; demonstrates how to construct a custom Profile responsible for &lt;span style="font-weight: bold;"&gt;transparently saving and restoring&lt;/span&gt; registered control values on Page loading.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;
By looking at &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/Profile.cs.txt&amp;amp;track=TCA"&gt;PROFILE.CS&lt;/a&gt; we can see that it inherits System.Web.Profile.ProfileBase. It contains a public method ‘Register’ which takes a System.Web.UI.Control as one of its parameters. Register is responsible for persisting a passed control’s property to the profile, and registering it for repopulation on the next postback. The second parameter is a string defining a property name with which to bind to (i.e. when registering a TextBox, we could bind the “Text” property). Using the given control’s Page property, event handlers are assigned to the parent page’s Pre Render and Pre Loading events. Note that within the PreLoading event handler, profiled data is only loaded into the target control on the first load (Page.IsPostBack == false) preventing any overwriting of entered data between postbacks (ViewState).&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;
The Profile manages a collection of &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/UrlProfile.cs.txt&amp;amp;track=TCA"&gt;UrlProfiles.&lt;/a&gt; Essentially a UrlProfile is a Serializable object (data container) responsible for managing profile data for a particular url. It is also responsible for managing the profiled data for registered controls within its Target Page. &lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;
The UrlProfile was implemented in preference of a Page Profile as quite often a page functionality can be quite varied depending on its Url (address + query string parameters). Each registered control has a ControlProfile constructed.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;
Ideally the reading / populating of target controls should be abstracted, requiring as little handling code as possible. Looking at &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/ProfilePersistence.zip&amp;amp;track=TCA"&gt;PROFILETEST.ASPX&lt;/a&gt;, we can see that only one line of code at initialization is required to register a control for Profile persistence.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;blockquote&gt;&lt;br /&gt;
protected override void OnInit(EventArgs e)&lt;br /&gt;
&lt;div class="MsoNormal"&gt;{              &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;base.OnInit(e);&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Profile.Register(testBox, "Text");&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: 85%;"&gt;}&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;o:p&gt;  &lt;/o:p&gt;&lt;/div&gt;&lt;/blockquote&gt;The only thing remaining is to hook up the custom profile in the website's &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/web.config.txt&amp;amp;track=TCA"&gt;web.config&lt;/a&gt; specifying a default profile provider (see &lt;span style="font-weight: bold;"&gt;Custom Persistence Layer&lt;/span&gt; below):&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Custom Persistence Layer&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div class="MsoNormal"&gt;By using a provider model, how this data is persisted is highly configurable. The standard (implicit) provider is the SQLProfileProvider (all data is serialized and stored to db). One can however, inherit the System.Web.Profile.ProfileProvider base class and assume control of the data persistance In the example code, the &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/TextFileProfileProvider.cs.txt&amp;amp;track=TCA"&gt;TEXTFILEPROFILEPROVIDER.CS&lt;/a&gt; serializes User data to a text file. This implementation is based heavily on the &lt;a href="http://utils.beninzambia.com/linker.php?direct=msdn2.microsoft.com/en-us/library/0580x1f5%28d=ide%29.aspx&amp;amp;track=TCA"&gt;MSDN Example&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-114791209426743438?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hf2_ImzfsspseZOmVrZF2jPOCDY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hf2_ImzfsspseZOmVrZF2jPOCDY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hf2_ImzfsspseZOmVrZF2jPOCDY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hf2_ImzfsspseZOmVrZF2jPOCDY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/GwVL2TGfi0A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/114791209426743438/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=114791209426743438&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/114791209426743438?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/114791209426743438?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/GwVL2TGfi0A/aspnet-20-profiling-auto-saving-form.html" title="Asp.net 2.0 Profiling - Auto Saving Form Data" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2006/05/aspnet-20-profiling-auto-saving-form.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYMSX88eSp7ImA9Wx5VEk4.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-114139747769687621</id><published>2006-03-04T00:35:00.006+10:00</published><updated>2010-10-05T10:23:08.171+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-05T10:23:08.171+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pcm" /><category scheme="http://www.blogger.com/atom/ns#" term="dtmf" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="wave" /><category scheme="http://www.blogger.com/atom/ns#" term="pinvoke" /><category scheme="http://www.blogger.com/atom/ns#" term="sampling" /><title>DTMF Sampling - Constructing a Wave</title><content type="html">&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-8226778256743425";
/* In article ads */
google_ad_slot = "7464771992";
google_ad_width = 250;
google_ad_height = 250;
//--&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
How the heck do you generate dynamic sample data suitable for the wave format (PCM)? It's actually not that bad. The key is to follow the wave format specification&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://photos1.blogger.com/blogger/2623/537/1600/wav-sound-format.0.gif" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" src="http://photos1.blogger.com/blogger/2623/537/320/wav-sound-format.0.jpg" style="cursor: pointer; display: block; margin: 0px auto 10px; text-align: center;" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=replaygain.hydrogenaudio.org/file_format_wav.html&amp;amp;track=TCA"&gt;  http://replaygain.hydrogenaudio.org/file_format_wav.html  &lt;/a&gt;&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=http://ccrma.stanford.edu/courses/422/projects/WaveFormat/&amp;amp;track=TCA" waveformat=""&gt;http://ccrma.stanford.edu/courses/422/projects/WaveFormat/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=www.sonicspot.com/guide/wavefiles.html&amp;amp;track=TCA"&gt;http://www.sonicspot.com/guide/wavefiles.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic; font-weight: bold;"&gt;CONSTRUCTING THE WAVE&lt;/span&gt;&lt;br /&gt;
So we see that the first 44 bytes of a wave file is dedicated to wave format / header information, from byte 45 onwards contains all the sample data - the bits which make the noise.&lt;br /&gt;
&lt;br /&gt;
In my &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/Wave.cs.txt&amp;amp;track=TCA"&gt;Wave&lt;/a&gt; class - the constructor allows setting of basic Wave settings (sample rate, Resolution [8 or 16 bit], Channel [left, right, mono, left-right stereo]) and creates a byte array 44 cells in size populating it with intial header values. All this code is pretty much standard, not really worth explaining as much of it can be a copy paste job. The main thing is to follow the wave format spec given in the above links.&lt;br /&gt;
&lt;br /&gt;
The sampling code is a bit more interesting as a bit of maths is involved. Essentially DTMF requires the summation of Sine waves of two frequencies to generate a tone recognised by a phone exchange (DUAL TONE multi Frequency). Standard Frequencies for each digit on the phone dial pad (0-9 * # a b c d) can be found at :&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://utils.beninzambia.com/linker.php?direct=users.tkk.fi/~then/mytexts/dtmf_generation.html&amp;amp;track=TCA"&gt;http://users.tkk.fi/~then/mytexts/dtmf_generation.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
As far as I am aware, DTMF frequencies are international standards and so the posted frequencies should work with phone exchanges world wide.&lt;br /&gt;
&lt;br /&gt;
In my solution I created a basic data containing class called &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/SineWave.cs.txt&amp;amp;track=TCA"&gt;SineWave&lt;/a&gt;. In it's constructor, the frequency (Hz) is given as an int, along with its left and right amplitude (volume) at which the frequency should be should be sampled.&lt;br /&gt;
&lt;br /&gt;
Ok, so looking at the &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/Wave.cs.txt&amp;amp;track=TCA"&gt;Wave&lt;/a&gt; class we have a static method ConstructWave (internal method), which in addition to encoding properties takes an array of SineWaves (the frequencies to be summed) and a TimeSpan (how long the resulting sample should be played).&lt;br /&gt;
&lt;br /&gt;
Say for instance we wanted to generate a tone for the digit '1', using the frequencies specified at &lt;a href="http://utils.beninzambia.com/linker.php?direct=users.tkk.fi/~then/mytexts/dtmf_generation.html&amp;amp;track=TCA"&gt;http://users.tkk.fi/~then/mytexts/dtmf_generation.html&lt;/a&gt; we can construct 2 SineWaves, and pass them to ConstructWave :&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// playing frequencies at full volume&lt;br /&gt;
//&lt;br /&gt;
SineWave[] sineWaves = new SineWave[2];&lt;br /&gt;
sineWaves[0] = new SineWave(1209, 1, 1);&lt;br /&gt;
sineWaves[1] = new SineWave(697, 1, 1);&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// generate an 8 bit 16kHz sample in mono&lt;br /&gt;
//&lt;br /&gt;
Wave digitOne = Wave.ConstructWave(sineWaves, 16000, Resolution.EightBit, AudioMode.Mono, TimeSpan.FromMilliseconds(250));&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic; font-weight: bold;"&gt;THE IMPLEMENTATION OF SAMPLING&lt;br /&gt;
&lt;/span&gt;&lt;a href="http://209.171.52.99/audio/concatwavefiles.asp"&gt;&lt;/a&gt;&lt;br /&gt;
On closer inspection of the ConstructWave method in the &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/Wave.cs.txt&amp;amp;track=TCA"&gt;Wave&lt;/a&gt; class we can see that all sampling is contained in the AppendSample method. Using the target sample rate and sample duration (provided in the Wave constructor) its relatively easy to determine how many bytes the wave sample data should be (Data Size):&lt;br /&gt;
&lt;br /&gt;
i.e.&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
sample data Byte count =  (Sample Rate (Hz) / duration (in seconds)) * no. bytes per sample&lt;br /&gt;
&lt;br /&gt;
WHERE&lt;br /&gt;
no. of bytes per sample = (resolution / 8) * no.of channels&lt;br /&gt;
IF             Mono : no. of channels = 1&lt;br /&gt;
ELSE                           no. of channels = 2&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
According to the wave header format (above) the total sample data byte count (or data size) should be assigned to bytes 40 - 43. Helper methods ExtractByte and ExtractInt have been written in the &lt;a href="http://utils.beninzambia.com/linker.php?direct=175.107.156.152/blog/Wave.cs.txt&amp;amp;track=TCA"&gt;Wave&lt;/a&gt; class to extract each byte in a 4 byte int (int 32) via bit masking. The Frame Size should also be set  in bytes 4 - 7 :&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
Frame Size = DataSize + 36&lt;br /&gt;
[NOTE: 36 is the number of remaining bytes in wave header passed the Frame Size record]&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Ok, now to calculate the sample byte data itself..... Both frequencies should be assigned a constant, which in code I have called dataSlice:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
dataSlice = (2 * PI) / (waveTime / sampleTime);&lt;br /&gt;
[NOTE: waveTime = 1 / frequency (Hz)&lt;br /&gt;
sampleTime = 1 / sample rate (Hz)]&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Using the number of samples as the loop invariant ( Sample Rate (Hz) / duration (in seconds))  we can calculate each fragment of sample data (bytes 44 - end of array) for the left and right channel (or just the left if mono) as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
&lt;br /&gt;
dataLeft    = (Math.Sin (i * FrequencyOneDataSlice) * LeftAmplitude) + (Math.Sin (i * FrequencyTwoDataSlice) * LeftAmplitude) ;&lt;br /&gt;
&lt;br /&gt;
dataRight = (Math.Sin (i * FrequencyOneDataSlice) * RightAmplitude) + (Math.Sin (i * FrequencyTwoDataSlice) * RightAmplitude) ;&lt;br /&gt;
&lt;br /&gt;
WHERE&lt;br /&gt;
LeftAmplitude  = relative volume of left channel (must be &amp;lt;= 0.5)   RightAmplitude = relative volume of right channel (must be &amp;lt;= 0.5)   i              = current loop iteration          &lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally, we mask the resulting number using the resolution of the wave we are sampling (8 / 16 / 24 bit) and store it in the underlying byte array. If you are storing multi channel data (Left, Right, LeftRight Stereo), each data byte should be interleaved....   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
i.e. &lt;span style="font-weight: bold;"&gt;8-bit LeftRight Stereo: &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
waveBytes[n]    = ExtractFirstByte(dataLeft)&lt;br /&gt;
&lt;br /&gt;
waveBytes[n+1]  = ExtractFirstByte(dataRight) &lt;br /&gt;
&lt;br /&gt;
...    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;16-bit Stereo: &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
waveBytes[n]    = ExtractFirstByte(dataLeft)&lt;br /&gt;
&lt;br /&gt;
waveBytes[n+1]  = ExtractSecondByte(dataLeft)&lt;br /&gt;
&lt;br /&gt;
waveBytes[n+2]  = ExtractFirstByte(dataRight)&lt;br /&gt;
&lt;br /&gt;
waveBytes[n+3]  = ExtractSecondByte(dataRight)&lt;br /&gt;
&lt;br /&gt;
...     &lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
And that's it! As the iteration continues, the byte array is filled with Dual Tone byte samples until the target sample size has been reached ( Sample Rate (Hz) / duration (in seconds)).    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic; font-weight: bold;"&gt;PLAYING DIRECTLY TO THE SOUNDCARD  &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using Pinvoke, we can access winmm.dll - a windows resource to play or save the generated wave as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="highlight"&gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
//External method declaration&lt;br /&gt;
[DllImport("winmm.dll", SetLastError = true)]&lt;br /&gt;
static extern bool PlaySound( IntPtr pszSound, System.UIntPtr hmod, uint fdwSound );&lt;br /&gt;
&lt;br /&gt;
// calling the declared external method&lt;br /&gt;
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(this.m_waveBytes, 0);&lt;br /&gt;
PlaySound(ptr, UIntPtr.Zero, (uint) SoundFlags.SND_MEMORY);&lt;br /&gt;
...&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
References : &lt;a href="http://utils.beninzambia.com/linker.php?direct=209.171.52.99/audio/concatwavefiles.asp&amp;amp;track=TCA"&gt;http://209.171.52.99/audio/concatwavefiles.asp&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic; font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-114139747769687621?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eDDDpSJNyI8AljkJQ07zLn8w-kM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eDDDpSJNyI8AljkJQ07zLn8w-kM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/eDDDpSJNyI8AljkJQ07zLn8w-kM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eDDDpSJNyI8AljkJQ07zLn8w-kM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/yKWQ8B4bYBo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/114139747769687621/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=114139747769687621&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/114139747769687621?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/114139747769687621?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/yKWQ8B4bYBo/dtmf-sampling-constructing-wave.html" title="DTMF Sampling - Constructing a Wave" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2006/03/dtmf-sampling-constructing-wave.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUBSXk7fip7ImA9Wx5XF0o.&quot;"><id>tag:blogger.com,1999:blog-23214170.post-114121492368527006</id><published>2006-03-01T20:53:00.002+10:00</published><updated>2010-09-18T11:27:38.706+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-18T11:27:38.706+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pcm" /><category scheme="http://www.blogger.com/atom/ns#" term="dtmf" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="wave" /><title>Mp3's &amp; Wave - Constructing DTMF audio files in C#</title><content type="html">&lt;span style="font-weight: bold;"&gt;TERMS:&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;DTMF: Dual Tone Multi-Frequency - the beeps sent by a phone to the exchange when the User enters a phone number.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;THE PROBLEM:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
1 - Constructing a wave using a common format (PCM)&lt;br /&gt;
2 - Constructing / sampling each digit's tone using standard frequencies&lt;br /&gt;
3 - Convert a phone number to a wave&lt;br /&gt;
4 - Setting  channel (left, right, mono, left - Right stereo) and sampling settings&lt;br /&gt;
5 - Integrating unmanaged code into a managed app (using winmm.dll and the Lame encoder)&lt;br /&gt;
6 - Encoding the generated wave as an Mp3&lt;br /&gt;
&lt;br /&gt;
** NOTE: This process has been patented as MP3 Telephony by &lt;a href="http://utils.beninzambia.com/linker.php?direct=www.hcvwireless.com&amp;amp;track=TCA"&gt;HCV Wireless&lt;/a&gt;&lt;small&gt;&lt;sup&gt;TM&lt;/sup&gt;&lt;/small&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;THE PLATFORM:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
C# (easily transferrable to other syntax though) using the Lame Mp3 encoder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;BACKGROUND:&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;I recently had to create a  basic DTMF  converter for a client using managed code. It's initial inception would be an application with the view that it would eventually be ported over to a website to be used as a service.&lt;br /&gt;
&lt;br /&gt;
Esentially, all the app needed to do was take a phone number string and encode it into its DTMF representation as an Mp3 file. This meant that first I would have to create the sample as a Wave before ripping it as an Mp3 using the Lame encoder. An added feature was to be able to set which channel the DTMF tones would be generated for - Left, Right, Mono, or Left - Right stereo.&lt;br /&gt;
&lt;br /&gt;
Over the next few blog entries I will tackle each segment of the problem.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic; font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23214170-114121492368527006?l=thecodeabode.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/e175_ezfJd-vrd6xGsN-kue2rS4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e175_ezfJd-vrd6xGsN-kue2rS4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/e175_ezfJd-vrd6xGsN-kue2rS4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/e175_ezfJd-vrd6xGsN-kue2rS4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeAbode/~4/8mHN6H-s4I0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://thecodeabode.blogspot.com/feeds/114121492368527006/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=23214170&amp;postID=114121492368527006&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/114121492368527006?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/23214170/posts/default/114121492368527006?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/TheCodeAbode/~3/8mHN6H-s4I0/mp3s-wave-constructing-dtmf-audio.html" title="Mp3's &amp; Wave - Constructing DTMF audio files in C#" /><author><name>Ben Kitzelman</name><uri>http://www.blogger.com/profile/11465248091245614781</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="24" height="32" src="http://1.bp.blogspot.com/-VVEy0BBBccM/TofN4dK-5AI/AAAAAAAAGD4/b3LXk_TQLtI/s1600/267520_10150303417928688_601408687_9383123_4232169_n.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://thecodeabode.blogspot.com/2006/03/mp3s-wave-constructing-dtmf-audio.html</feedburner:origLink></entry></feed>

