<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shiki &#187; Web Development</title>
	<atom:link href="http://shikii.net/blog/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://shikii.net/blog</link>
	<description>no awesome tagline here</description>
	<lastBuildDate>Thu, 26 Aug 2010 08:41:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Creating a custom image service for Twitter for iPhone</title>
		<link>http://shikii.net/blog/creating-a-custom-image-service-for-twitter-for-iphone/</link>
		<comments>http://shikii.net/blog/creating-a-custom-image-service-for-twitter-for-iphone/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 00:52:30 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=191</guid>
		<description><![CDATA[We&#8217;ve just recently deployed a custom endpoint to allow Twitter for iPhone users to post their pics through PicLyf. When you attach an image to a tweet, Twitter for iPhone will upload that image to the image service of your choice. It allows you to choose from various image services (e.g. yFrog, Twitpic, TweetPhoto) or [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignright">
  <img src="http://shikii.net/blog/wp-content/uploads/2010/08/img_0031.png" alt="" title="Custom Image Service" width="320" height="240" class="alignright size-full wp-image-217" />
</div>

<p>We&#8217;ve just recently deployed a custom endpoint to allow <a href="http://itunes.apple.com/app/twitter/id333903271?mt=8">Twitter for iPhone</a> users to post their pics through <a href="http://piclyf.com">PicLyf</a>.</p>

<p>When you attach an image to a tweet, Twitter for iPhone will upload that image to the image service of your choice. It allows you to choose from various image services (e.g. yFrog, Twitpic, TweetPhoto) or a custom image service. In our (PicLyf) case, it was custom. We made a custom endpoint: <code>http://api.piclyf.com/twitter</code>. Using this url as the custom image service, attached images will be uploaded to the user&#8217;s PicLyf account.</p>

<h2>Implementation</h2>

<p>This functionality works through the use of <a href="http://dev.twitter.com/pages/oauth_echo">OAuth Echo</a>. From Twitter:</p>

<blockquote>
  <p>OAuth Echo is a means to securely delegate OAuth authorization with a third party while interacting with an API. Within the Twitter ecosystem, we use OAuth Echo as a means to allow your application to use services such as Twitpic and yfrog.</p>
</blockquote>

<p>You may want to read about OAuth Echo first. Basically, Twitter for iPhone sends you the image along with the OAuth credentials of the user who wants to upload the image. Note that the OAuth credentials also includes the app&#8217;s consumer key. What you&#8217;ll have to do is use these credentials and verify them with the Twitter API. If the verification succeeds, you will receive the user&#8217;s Twitter information. You may then save the image in your server and link it with the user&#8217;s Twitter account. Lastly, you will have to return the correct response to Twitter for iPhone specifying the url where the image can be viewed:</p>

<pre><code>&lt;mediaurl&gt;http://foo.com/bar/pic-url.html&lt;/mediaurl&gt;
</code></pre>

<h3>Sample code in PHP</h3>

<p>Here is a sample class which encapsulates the OAuth Echo process:</p>

<pre><code>class TwitterOAuthEcho
{
  public $verificationUrl = 'https://api.twitter.com/1/account/verify_credentials.json';
  public $userAgent = __CLASS__;

  public $verificationCredentials;

  /**
   *
   * @var int
   */
  public $resultHttpCode;
  /**
   *
   * @var array
   */
  public $resultHttpInfo;
  public $responseText;

  /**
   * Save the OAuth credentials sent by the Consumer (e.g. Twitter for iPhone, Twitterrific)
   */
  public function setCredentialsFromRequestHeaders()
  {    
    $this-&gt;verificationCredentials = isset($_SERVER['HTTP_X_VERIFY_CREDENTIALS_AUTHORIZATION']) 
      ? $_SERVER['HTTP_X_VERIFY_CREDENTIALS_AUTHORIZATION'] : '';
  }

  /**
   * Verify the given OAuth credentials with Twitter
   * @return boolean
   */
  public function verify()
  {
    $curl = curl_init($this-&gt;verificationUrl);
    curl_setopt($curl, CURLOPT_USERAGENT, $this-&gt;userAgent);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
        'Authorization: ' . $this-&gt;verificationCredentials,
      ));

    $this-&gt;responseText = curl_exec($curl);
    $this-&gt;resultHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    $this-&gt;resultHttpInfo = curl_getinfo($curl);
    curl_close($curl);

    return $this-&gt;resultHttpCode == 200;
  }
}
</code></pre>

<p>The <code>setCredentialsFromRequestHeaders</code> method saves the OAuth credentials sent by the consumer (e.g. Twitter for iPhone, Twitterrific). These credentials will be used in the <code>verify</code> method which sends the verification request to Twitter.</p>

<p>Using the class above, your custom image service page <em>(e.g. <code>http://api.piclyf.com/twitter</code>)</em> should handle the request like this:</p>

<pre><code>$oauthecho = new TwitterOAuthEcho();
$oauthecho-&gt;userAgent = 'My Custom Image Service App 1.0';
$oauthecho-&gt;setCredentialsFromRequestHeaders();
if ($oauthecho-&gt;verify()) {      
  // Verification was a success, we should be able to access the user's Twitter info from the responseText.
  $userInfo = json_decode($oauthecho-&gt;responseText, true);
  $twitterId = isset($userInfo['id']) ? $userInfo['id'] : null;      
  // You can use $userInfo or $twitterId above to maybe check if you have a record of this user
  // in your db.

  // You can access the uploaded image using $_FILES. Save it and create a url where it can be accessed.

  // Return the image url back to the consumer
  $imagePageUrl = 'http://somwhere.com/image1';
  echo '&lt;mediaurl&gt;' . $imagePageUrl . '&lt;/mediaurl&gt;';

} else {
  // verification failed, we should return the error back to the consumer
  $response = json_decode($oauthecho-&gt;responseText, true);      
  $message = isset($response['error']) ? $response['error'] : null;      
  if (!headers_sent())
    header('HTTP/1.0 ' . $oauthecho-&gt;resultHttpCode);
  echo $message;
}
</code></pre>

<p>The code above is just a sample and your final code will look very different especially if you&#8217;re using a framework. I&#8217;ve also left
out the part where you&#8217;ll get the image from $_FILES and save/process it. That is beyond the scope of this article.</p>

<h2>Notes</h2>

<p>The note in Twitter for iPhone&#8217;s custom image service screen says you can get more (developer) info in this url: http://developer.atebits.com. As of this writing, the information on that page is no longer accurate. Twitter for iPhone no longer sends you the user&#8217;s username and password. The info at <a href="http://twitterrific.com/ipad/poweruser">Twitterrific</a> is more accurate. And yes, if your service works for Twitter for iPhone, it should work on Twitterrific too.</p>

<h3>Further reading:</h3>

<ul>
<li><a href="http://www.bennadel.com/blog/1965-Creating-A-Custom-Image-Upload-Service-For-Tweetie-Twitter-For-iPhone-Using-ColdFusion.htm">Creating A Custom Image Upload Service For Tweetie (Twitter For iPhone) Using ColdFusion</a></li>
<li><a href="http://dev.twitter.com/pages/oauth_echo">Using OAuth Echo</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/creating-a-custom-image-service-for-twitter-for-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I don&#8217;t code in Ruby</title>
		<link>http://shikii.net/blog/why-i-dont-code-in-ruby/</link>
		<comments>http://shikii.net/blog/why-i-dont-code-in-ruby/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 15:35:57 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/why-i-dont-code-in-ruby/</guid>
		<description><![CDATA[Well, not yet anyway. Perhaps when those hosting prices go down I&#8217;d go and take a shot at building something useful. I did start reading a few books on Ruby and Rails. It&#8217;s an incredibly awesome and fun language. I&#8217;ve never been very excited when learning a new language. I drool when I see Ruby [...]]]></description>
			<content:encoded><![CDATA[<p>Well, not yet anyway. Perhaps when those hosting prices go down I&#8217;d go and take a shot at building something useful. I did start reading a few books on Ruby and Rails. It&#8217;s an incredibly awesome and fun language. I&#8217;ve never been very excited when learning a new language. I drool when I see Ruby code. It&#8217;s easy to learn but I&#8217;ve already forgotten most about it since I don&#8217;t use it fulltime.</p>

<p>If it were just me, I&#8217;d have built <a href="http://piclyf.com">PicLyf</a> using Ruby to make it more exciting. But there&#8217;s the city talent pool we had to think of. Currently, it&#8217;s hard to find good PHP developers. I reckon it&#8217;ll be more hard to find those who know Ruby.</p>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/why-i-dont-code-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FirePHP Logger for Yii Framework</title>
		<link>http://shikii.net/blog/firephp-logger-for-yii-framework/</link>
		<comments>http://shikii.net/blog/firephp-logger-for-yii-framework/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 11:59:41 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[firephp]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=96</guid>
		<description><![CDATA[I made this a few weeks ago. It is a Yii Framework extension which routes log messages to FirePHP. Requirements Download the extension from the Yii Framework extension page or GitHub. Install Firebug and FirePHP plugins for Firefox. Enable output_buffering in php.ini. Installation Download and extract the &#8220;shiki&#8221; folder to your extensions directory. This is [...]]]></description>
			<content:encoded><![CDATA[<p>I made this a few weeks ago. It is a <a href="http://yiiframework.com">Yii Framework</a> extension which routes log messages to 
<a href="http://firephp.org">FirePHP</a>.</p>

<h3>Requirements</h3>

<ul>
<li>Download the extension from the Yii Framework <a href="http://www.yiiframework.com/extension/firephp-logroute/">extension page</a>
or <a href="http://github.com/shiki/yii-firephplogroute">GitHub</a>.</li>
<li>Install <a href="http://getfirebug.com/">Firebug</a> and FirePHP plugins for Firefox.</li>
<li>Enable <a href="http://www.php.net/manual/en/outcontrol.configuration.php#ini.output-buffering">output_buffering</a> in php.ini.</li>
</ul>

<h3>Installation</h3>

<ol>
<li>Download and extract the &#8220;shiki&#8221; folder to your extensions directory. This is usually <code>/protected/extensions</code>.</li>
<li>Download the FirePHP core class and put it somewhere in your <code>/protected</code> directory. I usually put these files in <code>/protected/vendors</code>.</li>
<li>Modify your config file to include this LogRoute class and set the <code>fbPath</code> property to the path of fb.php. Use a Yii alias 
(e.g. <code>application.vendors.FirePHPCore031.lib.FirePHPCore.fb</code>):</li>
</ol>

<h4>config file code (e.g. /protected/config/main.php)</h4>

<pre><code>'log'=&gt;array(
    'class'=&gt;'CLogRouter',
    'routes'=&gt;array(
        // the default (file logger)
        array(
            'class'=&gt;'CFileLogRoute',
            'levels'=&gt;'error, warning',
        ),
        // the FirePHP LogRoute
        array(
            'class' =&gt; 'ext.shiki.firePHPLogRoute.ShikiFirePHPLogRoute', // "ext" alias points to /protected/extensions
            'fbPath' =&gt; 'application.vendors.FirePHPCore031.lib.FirePHPCore.fb', // set path to fb.php
        ),
    ),
),
</code></pre>

<h3>Usage</h3>

<p>Once you&#8217;ve got the extension setup in the config, you can use Yii&#8217;s logging methods to log messages to FirePHP.</p>

<pre><code>// logging an INFO message (arrays will work and looks awesome in FirePHP)
Yii::log(array('username' =&gt; 'Shiki', 'profiles' =&gt; array('twidl', 'twitter', 'facebook')), CLogger::LEVEL_INFO);

// logging a WARNING message
Yii::log("You didn't setup a profile, are you really a person?", CLogger::LEVEL_WARNING);

// logging with a CATEGORY (categories are displayed as "labels" in FirePHP -- just an additional info text)
Yii::log('Profile successfully created', CLogger::LEVEL_INFO, 'application.user.profiles');

// tracing simple text
Yii::trace('Loading application.user.profiles.ninja', 'application.user.profiles');

// logging an ERROR
Yii::log('We have successfully determined that you are not a person', CLogger::LEVEL_ERROR, 'Any category/label will work');
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/firephp-logger-for-yii-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Installing Memcached for PHP 5.3 on Windows 7</title>
		<link>http://shikii.net/blog/installing-memcached-for-php-5-3-on-windows-7/</link>
		<comments>http://shikii.net/blog/installing-memcached-for-php-5-3-on-windows-7/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 06:23:30 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wampserver]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=80</guid>
		<description><![CDATA[First off, all credits go to this guy. I&#8217;m just listing the steps on how I did it in Windows 7 with PHP 5.3. Also, I tested this using WampServer but I believe it should work on any PHP install. Install memcached Download the Memcached Win32 library here: http://code.jellycan.com/memcached/. Extract the downloaded archive file in [...]]]></description>
			<content:encoded><![CDATA[<div class="wide"><img title="Memcached" src="http://shikii.net/blog/wp-content/uploads/2010/03/memcached-win7.jpg" alt="" width="640" /></div>

<p>First off, all credits go to <a href="http://pureform.wordpress.com/2008/01/10/installing-memcache-on-windows-for-php/">this guy</a>. 
I&#8217;m just listing the steps on how I did it in Windows 7 with PHP 5.3. Also, I tested this using 
<a href="http://www.wampserver.com/en/">WampServer</a> but I believe it should work on any PHP install.</p>

<h2>Install memcached</h2>

<ul>
<li>Download the Memcached Win32 library here: http://code.jellycan.com/memcached/. Extract the downloaded archive file in a 
directory (e.g. <code>c:\memcached</code>). There should be a <code>memcached.exe</code> in there.</li>
<li>Run a command prompt <strong>as an administrator</strong>. Some info on how to do that 
<a href="http://blogs.msdn.com/tims/archive/2006/11/02/windows-vista-secret-10-open-an-elevated-command-prompt-in-six-keystrokes.aspx">here</a>.</li>
<li><p>Install memcached as a service. Go to the memcached directory, type and run:</p>

<pre><code>memcached -d install
</code></pre></li>
<li><p>Start the memcached service by running:</p>

<pre><code>memcached -d start
</code></pre></li>
</ul>

<h2>Install PHP Memcache extension (php_memcache.dll)</h2>

<ul>
<li>Chances are you don&#8217;t have <code>php_memcache.dll</code> in your PHP extensions yet. 
You can download a build of it <a href="http://downloads.php.net/pierre/">here</a>. Make sure to download the correct one for your system. 
Mine was 32bit and PHP 5.3 so I used this: <a href="http://downloads.php.net/pierre/php_memcache-cvs-20090703-5.3-VC6-x86.zip">php_memcache-cvs-20090703-5.3-VC6-x86.zip</a>. 
The archive should contain <code>php_memcache.dll</code>. Extract the archive to your php extensions directory. On my system (WampServer), 
this was <code>C:\wamp\bin\php\php5.3.0\ext</code>.</li>
<li><p>Edit <code>php.ini</code>, add this line to enable the extension:</p>

<pre><code>extension=php_memcache.dll
</code></pre>

<p>This is a little easier for WampServer users because there&#8217;s a menu for enabling extensions ^_^x</p></li>
</ul>

<h2>Test</h2>

<p>Test the installation using the sample PHP code here: <a href="http://www.php.net/manual/en/memcache.examples-overview.php">http://www.php.net/manual/en/memcache.examples-overview.php</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/installing-memcached-for-php-5-3-on-windows-7/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Zend Studio (Eclipse) Remote Editing through a secure proxy</title>
		<link>http://shikii.net/blog/zend-studio-eclipse-remote-editing-through-a-secure-proxy/</link>
		<comments>http://shikii.net/blog/zend-studio-eclipse-remote-editing-through-a-secure-proxy/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 15:47:05 +0000</pubDate>
		<dc:creator>Shiki</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[putty]]></category>
		<category><![CDATA[remote-editing]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tunnel]]></category>
		<category><![CDATA[zend-studio]]></category>

		<guid isPermaLink="false">http://shikii.net/blog/?p=11</guid>
		<description><![CDATA[Remote Editing in Zend Studio for Eclipse has to be one of the biggest reasons why I use it in my current job. I work from home and our team&#8217;s development environment is securely setup on a Linux server with a firewall open only to specific IP addresses. This is a no biggie if my [...]]]></description>
			<content:encoded><![CDATA[<p>Remote Editing in Zend Studio for Eclipse has to be one of the biggest reasons why I use it in my current job. I work from home and our team&#8217;s development environment is securely setup on a Linux server with a firewall open only to specific IP addresses. This is a no biggie if my IP address never changes or if I work only in one place. Unfortunately, that&#8217;s not the case for my DSL setup &#8212; I get a different IP address everyday. And since I can&#8217;t bug the server admin every time I need to have my IP address added to the firewall, I connect through our proxy server first and then connect to the main development server. The setup&#8217;s kinda like this:</p>

<p style="text-align: center;"><img class="size-full wp-image-16 aligncenter" title="Local Machine to Proxy Server to Development Server setup" src="http://shikii.net/blog/wp-content/uploads/2009/08/zendstudioproxy.jpg" alt="Local Machine to Proxy Server to Development Server setup" width="640" /></p>

<p>The problem now is Zend Studio doesn&#8217;t seem to support this kind of setup. At least, that&#8217;s what I concluded after so many hours of googling. Then I found this super awesome <a href="http://paulstamatiou.com/how-to-surf-securely-with-ssh-tunnel">article</a>. We can use Putty! Or just plain ol&#8217; Terminal on a Mac (Linux should be the same I think).<span id="more-11"></span></p>

<h2>Tools needed</h2>

<p>Of course you need Zend Studio for Eclipse. You just need <a href="http://www.putty.org/">Putty</a> if you&#8217;re on Windows. You&#8217;ll just need the already available/installed Terminal on a Mac (it&#8217;s in <em>Applications &gt; Utilities</em>).</p>

<h2>Proxy setup</h2>

<p>Open up Putty/Terminal. Enter this into the console:</p>

<p><code>ssh -D 8080 username@proxydomain.com</code></p>

<p>The &#8220;8080&#8243; should be an unused port on your machine. In most cases, port 8080 is fine. The &#8220;username&#8221; should be the user name you need to login to the proxy server (ie proxydomain.com). You should be prompted with the password after entering this command. This will create a tunnel on the port 8080 where all HTTP traffic will go through the proxy server. That is, if an application uses the port 8080 as a proxy. This won&#8217;t have any effect on your current applications (i.e. browsers) unless you modify your settings to use this proxy. Please note that you&#8217;ll have to keep the terminal window open so your proxy session won&#8217;t be destroyed. There are probably other ways to make it work without the window left open but I&#8217;m content with this.</p>

<h2>Modifying Zend Studio settings</h2>

<p>Since we now have a proxy available, we need to instruct Zend Studio to use it.</p>

<ol>
    <li>Open Zend Studio.</li>
    <li>Go to Preferences (located under the <em>Application</em> menu on Mac and under <em>Window</em> on Windows)</li>
    <li>Navigate to <em>General &gt; Network Connections</em></li>
    <li>Set the proxy setting to <em>Manual proxy configuration</em>. And enter <strong>127.0.0.1</strong> in the SOCKS proxy field and <strong>8080</strong> on the Port field beside that.</li>
</ol>

<p>Your setup should look something like this:</p>

<div id="attachment_19" class="wp-caption aligncenter" style="width: 650px"><img class="size-full wp-image-19" title="Zend Studio Network Settings" src="http://shikii.net/blog/wp-content/uploads/2009/08/Preferences-1.jpg" alt="Zend Studio Network Settings" width="610" /><p class="wp-caption-text">Zend Studio Network Settings</p></div>

<p>Save the settings and you should be ready to open up a connection to the target server (in this case, the main development server). Create a remote connection to your target server like you normally would. I couldn&#8217;t discuss that here but <a href="http://files.zend.com/help/Zend-Studio-Eclipse/remote_systems_view.htm">this</a> might help.</p>

<h3>Other References</h3>

<ul>
    <li><a href="http://paulstamatiou.com/how-to-surf-securely-with-ssh-tunnel">How To: Surf Securely with an SSH Tunnel</a></li>
    <li><a href="http://www.linuxjournal.com/content/use-ssh-create-http-proxy">Use SSH to Create an HTTP Proxy</a></li>
    <li><a href="http://blogs.techrepublic.com.com/security/?p=421">Use PuTTY as a secure proxy on Windows</a></li>
    <li><a href="http://files.zend.com/help/Zend-Studio-Eclipse/remote_systems_view.htm">Zend Studio Remote Systems View</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://shikii.net/blog/zend-studio-eclipse-remote-editing-through-a-secure-proxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
