<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Zitec Blog</title>
	
	<link>http://blog.zitec.com</link>
	<description>Zitec Blog</description>
	<lastBuildDate>Sun, 20 May 2012 17:16:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ZitecBlog" /><feedburner:info uri="zitecblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Mobile development frameworks</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/z3qsi0TeHOY/</link>
		<comments>http://blog.zitec.com/2012/05/mobile-development-frameworks/#comments</comments>
		<pubDate>Sun, 20 May 2012 17:16:57 +0000</pubDate>
		<dc:creator>Vlad STEFANESCU, Software Engineer</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[featured]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[titanium]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=1242</guid>
		<description><![CDATA[Why should you use a framework? I recently started investigating the ways I could develop a mobile application (especially Android), which is the right and/or fastest way and how could I improve my overall thinking when it comes to mobile development. The only method I used &#8217;till now is the native one. I relied on Android application framework and [...]]]></description>
			<content:encoded><![CDATA[<h2>Why should you use a framework?</h2>
<p>I recently started investigating the ways I could develop a mobile application (especially Android), which is the right and/or fastest way and how could I improve my overall thinking when it comes to mobile development. The only <em>method</em> I used &#8217;till now is the native one. I relied on Android application framework and I liked to take care of all the little details, even if those details slowed the development process a little bit. I&#8217;m talking about details like <em>custom</em> layouts on multiple screen densities. Not necessarily a hard thing to do, but still time consuming. Sometimes even working with system services seem hard to debug or test properly. I wanted a <em>tool </em>that could help me with those little details and let me concentrate on application logic, rather than the sub-components.</p>
<p>But after discussing with other developers, I discovered <a title="PhoneGap homepage" href="http://phonegap.com/" target="_blank">PhoneGap</a>, an application framework, which allows developers to write <em>native</em>, mobile applications using HTML5 and JavaScript. And it isn&#8217;t the only one. I found out that there are a lot of other frameworks like this one, which provide high level APIs  for the most common mobile components and even more, can open the mobile development world to a web developer. You can find a list of the most used frameworks <a title="Mobile Frameworks Comparison Chart" href="http://www.markus-falk.com/mobile-frameworks-comparison-chart/" target="_blank">here</a>. But wait, there&#8217;s more. Most of these frameworks are multi-platform, which basically means that you can cut the development costs in half, by coding once and deploying that code on Android, IOS, WP7 and other platforms. This seems to be great, but portability has it&#8217;s own costs.</p>
<h2>How does it work ?</h2>
<p>What <strong>PhoneGap</strong> actualy does is create a web container inside a native application in which you can run your own JavaScript code, using HTML5 for the user interface and taking advantage of the main system features through a JavaScript API. You can do almost anything that you can do in a browser, including AJAX calls in order to exchange data. Here are some samples of some quick cool stuff:</p>
<p><strong>Taking a picture:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">navigator.<span style="color: #660066;">camera</span>.<span style="color: #660066;">getPicture</span><span style="color: #009900;">&#40;</span>onSuccess<span style="color: #339933;">,</span> onFail<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> quality<span style="color: #339933;">:</span> <span style="color: #CC0000;">50</span><span style="color: #339933;">,</span>
    destinationType<span style="color: #339933;">:</span> Camera.<span style="color: #660066;">DestinationType</span>.<span style="color: #660066;">DATA_URL</span>
 <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> onSuccess<span style="color: #009900;">&#40;</span>imageData<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> image <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'myImage'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    image.<span style="color: #660066;">src</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;data:image/jpeg;base64,&quot;</span> <span style="color: #339933;">+</span> imageData<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">function</span> onFail<span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Failed because: '</span> <span style="color: #339933;">+</span> message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>&nbsp;</p>
<p><strong>Geolocation:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">navigator.<span style="color: #660066;">geolocation</span>.<span style="color: #660066;">getCurrentPosition</span><span style="color: #009900;">&#40;</span>onSuccess<span style="color: #339933;">,</span> <span style="color: #000066;">onError</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// onSuccess Callback</span>
<span style="color: #006600; font-style: italic;">//   This method accepts a `Position` object, which contains</span>
<span style="color: #006600; font-style: italic;">//   the current GPS coordinates</span>
<span style="color: #003366; font-weight: bold;">var</span> onSuccess <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>position<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Latitude: '</span>          <span style="color: #339933;">+</span> position.<span style="color: #660066;">coords</span>.<span style="color: #660066;">latitude</span>          <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'Longitude: '</span>         <span style="color: #339933;">+</span> position.<span style="color: #660066;">coords</span>.<span style="color: #660066;">longitude</span>         <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'Altitude: '</span>          <span style="color: #339933;">+</span> position.<span style="color: #660066;">coords</span>.<span style="color: #660066;">altitude</span>          <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'Accuracy: '</span>          <span style="color: #339933;">+</span> position.<span style="color: #660066;">coords</span>.<span style="color: #660066;">accuracy</span>          <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'Altitude Accuracy: '</span> <span style="color: #339933;">+</span> position.<span style="color: #660066;">coords</span>.<span style="color: #660066;">altitudeAccuracy</span>  <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'Heading: '</span>           <span style="color: #339933;">+</span> position.<span style="color: #660066;">coords</span>.<span style="color: #660066;">heading</span>           <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'Speed: '</span>             <span style="color: #339933;">+</span> position.<span style="color: #660066;">coords</span>.<span style="color: #660066;">speed</span>             <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'Timestamp: '</span>         <span style="color: #339933;">+</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>position.<span style="color: #660066;">timestamp</span><span style="color: #009900;">&#41;</span>      <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// onError Callback receives a PositionError object</span>
<span style="color: #003366; font-weight: bold;">function</span> <span style="color: #000066;">onError</span><span style="color: #009900;">&#40;</span>error<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'code: '</span>    <span style="color: #339933;">+</span> error.<span style="color: #660066;">code</span>    <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span>
          <span style="color: #3366CC;">'message: '</span> <span style="color: #339933;">+</span> error.<span style="color: #660066;">message</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>&nbsp;</p>
<p><strong>Notifications:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Vibrate for 2.5 seconds</span>
navigator.<span style="color: #660066;">notification</span>.<span style="color: #660066;">vibrate</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Beep twice!</span>
navigator.<span style="color: #660066;">notification</span>.<span style="color: #660066;">beep</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">//alert</span>
navigator.<span style="color: #660066;">notification</span>.<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>
    <span style="color: #3366CC;">'You are the winner!'</span><span style="color: #339933;">,</span>  <span style="color: #006600; font-style: italic;">// message</span>
    alertDismissed<span style="color: #339933;">,</span>         <span style="color: #006600; font-style: italic;">// callback</span>
    <span style="color: #3366CC;">'Game Over'</span><span style="color: #339933;">,</span>            <span style="color: #006600; font-style: italic;">// title</span>
    <span style="color: #3366CC;">'Done'</span>                  <span style="color: #006600; font-style: italic;">// buttonName</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">//Alert callback</span>
<span style="color: #003366; font-weight: bold;">function</span> alertDismissed<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// do something</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>&nbsp;</p>
<p>Of course you can make use of those other <em>common </em>features like file system, contacts and so on, but what bothers me is that the application will look and feel like a web application. I mean, it&#8217;s basically just a mobile browser and, from the user-interface point of view, you are limited to it. This might not be a problem for some users or clients, but others expect to see the native UI, the native theme, transitions and accessibility. Here are some screenshots of some cool apps made with PhoneGap.</p>
<table border="0">
<tbody>
<tr>
<td style="text-align: center;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px;">A dashboard</span></td>
<td style="text-align: center;">Buttons and forms</td>
<td style="text-align: center;">A journal (basically, a list)</td>
<td style="text-align: center;">A list of options</td>
</tr>
<tr>
<td><a href="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.cvhwjwdc.320x480-75.jpg" rel="lightbox[1242]"><img class="aligncenter size-thumbnail wp-image-1522" title="Dashboard" src="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.cvhwjwdc.320x480-75-150x150.jpg" alt="" width="135" height="135" /></a></td>
<td><a href="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.owspovap.320x480-75.jpg" rel="lightbox[1242]"><img class="aligncenter size-thumbnail wp-image-1524" title="Buttons and forms" src="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.owspovap.320x480-75-150x150.jpg" alt="" width="135" height="135" /></a></td>
<td><a href="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.gxjuwmei.320x480-75.jpg" rel="lightbox[1242]"><img class="aligncenter size-thumbnail wp-image-1523" title="List" src="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.gxjuwmei.320x480-75-150x150.jpg" alt="" width="135" height="135" /></a></td>
<td><a href="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.braqrphc.320x480-75.jpg" rel="lightbox[1242]"><img class="aligncenter size-thumbnail wp-image-1521" title="A list of options" src="http://blog.zitec.com/wp-content/uploads/2012/05/mzl.braqrphc.320x480-75-150x150.jpg" alt="" width="135" height="135" /></a></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>As you can see, there is a lot of flexibility in terms of design, and you can reach a very large scale of devices and platforms, after all it&#8217;s just HTML, CSS and Javascript, therefore you have to accept that you can never mimic the native look and feel using this type of approach, but still you can use a <em>touch-optimization framework</em> like <a title="jQuery Mobile homepage" href="http://jquerymobile.com/" target="_blank">jQueryMobile</a> (or <a title="Sencha Touch" href="http://www.sencha.com/products/touch/" target="_blank">Sencha&#8217;s Touch</a> visual features) in order to create a &#8220;mobile&#8221; feel. It looks good, but the <em>web-browser </em> is still felt.</p>
<h2>Titanium</h2>
<p><a title="Titanium homepage" href="http://www.appcelerator.com/" target="_blank">Titanium Mobile</a> still uses JavaScript as a main application language but it also fixes this UI issue by rendering native user interface components at runtime, using the native  javascript interpreters from each platform. And yes, you would still have the cross-platform advantage (although Titanium&#8217;s approach is &#8220;<em>write once</em>, <em>adapt everywhere</em>&#8220;). It looks wonderful and the UI is so consistent and responsive. One issue that bothers me is that you don&#8217;t have access to declarative layout, meaning that each component has to be manually initialized&#8230; Even so, the fact that it reaches a large scale of devices makes it very suitable for companies that need to reach many users. Let&#8217;s see how some visual components are initialized in Titanium:</p>
<p>A simple button:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> button <span style="color: #339933;">=</span> Titanium.<span style="color: #660066;">UI</span>.<span style="color: #660066;">createButton</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
   title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Hello'</span><span style="color: #339933;">,</span>
   top<span style="color: #339933;">:</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">,</span>
   width<span style="color: #339933;">:</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span>
   height<span style="color: #339933;">:</span> <span style="color: #CC0000;">50</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
button.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   Titanium.<span style="color: #660066;">API</span>.<span style="color: #660066;">info</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;You clicked the button&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>&nbsp;</p>
<p>A slider:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> slider <span style="color: #339933;">=</span> Titanium.<span style="color: #660066;">UI</span>.<span style="color: #660066;">createSlider</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    top<span style="color: #339933;">:</span> <span style="color: #CC0000;">50</span><span style="color: #339933;">,</span>
    min<span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
    max<span style="color: #339933;">:</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">,</span>
    width<span style="color: #339933;">:</span> <span style="color: #3366CC;">'100%'</span><span style="color: #339933;">,</span>
    value<span style="color: #339933;">:</span> <span style="color: #CC0000;">50</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> label <span style="color: #339933;">=</span> Ti.<span style="color: #660066;">UI</span>.<span style="color: #660066;">createLabel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    text<span style="color: #339933;">:</span> slider.<span style="color: #660066;">value</span><span style="color: #339933;">,</span>
    width<span style="color: #339933;">:</span> <span style="color: #3366CC;">'100%'</span><span style="color: #339933;">,</span>
    height<span style="color: #339933;">:</span> <span style="color: #3366CC;">'auto'</span><span style="color: #339933;">,</span>
    top<span style="color: #339933;">:</span> <span style="color: #CC0000;">30</span><span style="color: #339933;">,</span>
    left<span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
    textAlign<span style="color: #339933;">:</span> Ti.<span style="color: #660066;">UI</span>.<span style="color: #660066;">TEXT_ALIGNMENT_CENTER</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
slider.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'change'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    label.<span style="color: #660066;">text</span> <span style="color: #339933;">=</span> String.<span style="color: #660066;">format</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;%3.1f&quot;</span><span style="color: #339933;">,</span> e.<span style="color: #660066;">value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><a href="http://blog.zitec.com/wp-content/uploads/2012/05/Charger-Titanium-12.png" rel="lightbox[1242]"><img class="size-medium wp-image-1534 alignright" title="Titanium UI on iPhone and Android" src="http://blog.zitec.com/wp-content/uploads/2012/05/Charger-Titanium-12-300x277.png" alt="Titanium UI on iPhone and Android" width="180" height="166" /></a><br />
As you can see, Titanium&#8217;s APIs are straight-forward and easy to learn. You may notice that there is a naming convention that all the methods that return new UI elements start with the word &#8220;create&#8221;, thus being more verbose. Each UI component has it&#8217;s own implementation on each platform, so if you create<em>, let&#8217;s say,</em> a button, it will always be native on Android, IOS, WP and on the other platforms supported. Just take a look on the following screenshot, notice that it represents the same application on Android and IOS.</p>
<h2>So, which one ?</h2>
<p>It all depends on the project. I would use PhoneGap for an improved version of a website, if the company or the product already has a website. This would be much efficient, because you already have the data model which you can use through AJAX calls. Being able to access some device functionality like local storage or geolocation might enhance a website&#8217;s experience on the mobile world. An example of a good PhoneGap application would be, in my opinion, <a title="Facebook for Android page on Google Play" href="https://play.google.com/store/apps/details?id=com.facebook.katana" target="_blank">Facebook for Android</a>. If I were to learn something from it is keep that web feel on the mobile and do not try to mimic the mobile UI using HTML, you might realize that you have started on the wrong foot. But, again, it all depends on the goal. If your goal is, let&#8217;s say, to sell computer parts, maybe it&#8217;s better just to create a mobile version of your website, having in mind that a user is familiar with browsing a website on the mobile device.</p>
<p>I guess it all comes to pleasing the user. That&#8217;s why, in some cases, the native look and feel is a must. And it&#8217;s not just all about the looks. It may look good, but it&#8217;s more than that. A native UI has many things besides looks. It has accessibility, it is fast, it is power efficient and, above all, it&#8217;s the UI the user has grown familiar with. We should consider other aspects, too, like package size. Of course you can expect the smallest size from a native application (up to 100 Kb, without any assets). Using PhoneGap you can expect an application size of a few hundred kilos, but with Titanium, the basic HelloWorld application can be 10 times larger, reaching 3-4 Mb. It is true that package size grows proportionaly with the number of the devices supported (different screen densities), but the framework adds its payload nevertheless. If size is a concern, you might not want to use Titanium.</p>
<p>Finally, you can use any application framework, as long as you do not want (or need) to create games or interact directly with low level features like services, graphics etc. And Titanium and PhoneGap aren&#8217;t the only ones. <a title="Mobile Frameworks Comparison Chart" href="http://www.markus-falk.com/mobile-frameworks-comparison-chart/" target="_blank">Here</a> is an extensive list. One thing that still needs to be mentioned is that most of these frameworks are extensible through plug-ins, so if you need some custom, exotic functionality, you can implement a plugin yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2012/05/mobile-development-frameworks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2012/05/mobile-development-frameworks/</feedburner:origLink></item>
		<item>
		<title>What is Drupal?</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/EMc3t0vCM1E/</link>
		<comments>http://blog.zitec.com/2012/05/what-is-drupal/#comments</comments>
		<pubDate>Mon, 07 May 2012 12:42:20 +0000</pubDate>
		<dc:creator>Vlad ROSCA, Lead Software Engineer</dc:creator>
				<category><![CDATA[Drupal]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[featured]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=1477</guid>
		<description><![CDATA[Drupal is the result of the combined effort of nearly 800.000 developers, designers and site-builders who collaborate in a vibrant community to produce a state of the art content management platform. What is Drupal? CMS, Framework or Platform? Most people see Drupal as a content management system &#8211; and they are right to do so. [...]]]></description>
			<content:encoded><![CDATA[<p>Drupal is the result of the combined effort of nearly 800.000 developers, designers and site-builders who collaborate in a vibrant community to produce a state of the art content management platform.</p>
<h2>What is Drupal? CMS, Framework or Platform?</h2>
<p>Most people see Drupal as a content management system &#8211; and they are right to do so.</p>
<p><img title="Drupal CMS" src="http://blog.zitec.com/wp-content/uploads/2012/05/poza-blog-post-drupal-cms.jpg" alt="Drupal CMS" /></p>
<p>&#8220;A <strong>content management system (CMS)</strong> allows publishing, editing, and modifying content as well as site maintenance from a central page. It provides a collection of procedures used to manage work flow in a collaborative environment.&#8221;</p>
<p>Out of the box, Drupal provides many features you would expect from a modern CMS.<br />
It helps users:</p>
<ul>
<li>organize, structure and manage content with an easy-to-use web interface,</li>
<li>handle a variety of content types including video, articles, blogs, podcasts, polls</li>
<li>organize and manage users, user roles and access control.</li>
</ul>
<p>However, ask a developer, engineer or architect involved in the community “What is Drupal?” and you may get a slightly different response. They will probably tell you that Drupal is a Content Management <strong>Framework</strong>.</p>
<p><img title="Drupal Framework" src="http://blog.zitec.com/wp-content/uploads/2012/05/poza-blog-post-drupal-framework.jpg" alt="Drupal Framework" width="610" height="150" /></p>
<p>I certainly agree with this point of view and I see the CMS part of the project as an implementation &#8211; a proof of concept, if you will, of the framework.</p>
<p>&#8220;In computer programming, a <strong>software framework</strong> is an abstraction in which software providing generic functionality can be selectively changed by user code, thus providing application specific software. It is a collection of software libraries providing a defined application programming interface (API).&#8221;</p>
<p>Drupal &#8220;ships&#8221; with a rich list of APIs, libraries and subsystems that enables developers to extend the Core functionality in a modular / pluggable fashion.</p>
<p>The most important framework APIs and libraries include:</p>
<ul>
<li>Module system (300+ Core hooks)</li>
<li>Database abstraction layer</li>
<li>Menu system</li>
<li>Form API</li>
<li>File management system</li>
<li>Field API</li>
<li>Search system</li>
<li>Node access system</li>
<li>Theme layer</li>
</ul>
<p>In the beginning of this article, I described Drupal as a Content Management <strong>Platform</strong> so let&#8217;s see if the shoe fits.</p>
<p><img title="Drupal Platform" src="http://blog.zitec.com/wp-content/uploads/2012/05/poza-blog-post-drupal-platform.jpg" alt="Drupal Platform" /></p>
<p>The keys to any successful software platform are:</p>
<ul>
<li><strong>Efficiency</strong>: The platform should enable its users to do key tasks quickly.</li>
<li><strong>Standardization</strong>: The platform should conform to a documented set of standards and best practices.</li>
<li><strong>Scalability</strong>: Rather than referring to server load, this means that any product built on the platform has to be easily repeatable.</li>
<li><strong>Extensibility</strong>: It should be easy to add features and functionality.</li>
</ul>
<p>An excellent example of these concepts and practices is the <a title="the White House website" href="http://www.whitehouse.gov/" target="_blank">whitehouse.gov</a> website. Rather than being a single large website, whitehouse.gov includes a collection of 100 microsites &#8211; one for each representative. This was achieved through the use of Drupal&#8217;s installation profiles &#8211; a key feature of the platform.</p>
<p>&#8220;<strong>Installation profiles</strong> are scripts that run once when a new Drupal website is initially installed by running the install.php script. A standard installation profile is included with the <a href="http://drupal.org/project/drupal">Drupal core</a> software, and additional installation profiles are available that pre-configure Drupal for various specialized purposes.&#8221;</p>
<p>Other mature software platforms, like Linux, have a variety of distributions and Drupal makes no exception.</p>
<p>&#8220;<strong>Distributions</strong> are full copies of Drupal that include a full version of Drupal core and may also include additional software including extra themes, modules and installation profiles.&#8221;</p>
<p>There are currently around 200 distributions and installation profiles available for download on drupal.org.</p>
<h2>Drupal development and collaboration within the community</h2>
<p><img title="Drupal Community" src="http://blog.zitec.com/wp-content/uploads/2012/05/poza-blog-post-drupal-community.jpg" alt="Drupal Community" width="610" height="150" /></p>
<p>Perhaps the most important strength of Drupal is the community itself. Hundreds of thousands of people cooperate and constantly produce new modules, themes, documentation, translations, installation profiles and distributions. These are known as &#8220;contrib&#8221; projects.</p>
<p>You can find nearly 10.000 contrib modules on drupal.org &#8211; 3800 of which are compatible with the latest stable release of Drupal Core (Drupal 7). Each of these modules leverage both the Framework and the CMS in order to extend the core functionality and provide new features.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2012/05/what-is-drupal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2012/05/what-is-drupal/</feedburner:origLink></item>
		<item>
		<title>Google Engage Training</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/gIIrXsTKvlA/</link>
		<comments>http://blog.zitec.com/2012/04/google-engage-training/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 14:19:31 +0000</pubDate>
		<dc:creator>Mihalea PATROLEA, Online Marketing Assistant</dc:creator>
				<category><![CDATA[Online Marketing]]></category>
		<category><![CDATA[Google Engage]]></category>
		<category><![CDATA[Google Engage Event]]></category>
		<category><![CDATA[Google Engage Training]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=1410</guid>
		<description><![CDATA[&#160; After attending a training a few weeks ago, hosted by Google, I decided to write this article in order to share some of the most important things I learned during this event. The training was part of the relatively new Google Engage for Agencies program. &#160; If you&#8217;ve never heard of the Google Engage [...]]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>After attending a training a few weeks ago, hosted by Google, I decided to write this article in order to share some of the most important things I learned during this event. The training was part of the relatively new Google Engage for Agencies program.</p>
<p>&nbsp;</p>
<p><strong>If you&#8217;ve never heard of the Google Engage program here are a few details that might interest you:</strong></p>
<p><strong>Google Engage </strong>is a program designed to help agencies master the marketing art on Google. It offers its user free training, AdWords vouchers and marketing materials. Joining the program is simple: you sign up, pass the basic training and receive 10 AdWords vouchers, then find new clients and open up new AdWords accounts for them where you will use the voucher codes.</p>
<p>The program also gives you the option of becoming a <em>Platinum Member</em>. This of course comes with a few perks: vouchers of greater value, personalized materials and dedicated live training. There are only three conditions you must fulfill in order to become a Platinum Member:</p>
<ol>
<li>the total budget of your clients must be at least $1000</li>
<li>you must have am MCC account used to manage your clients&#8217; AdWords accounts</li>
<li>you must be a Google Certified Partner</li>
</ol>
<p>So far there are 400 agencies around the world that have signed up for this program. 150 of these agencies have managed to get new clients using the AdWords vouchers.</p>
<p><a href="https://google-engage.appspot.com/us/" target="_blank">Click here for more details about the <strong>Google Engage for Agencies</strong> program</a>.</p>
<p>&nbsp;</p>
<h2>The presentations</h2>
<p>Apart from the short presentation at the beginning about the Google Engage program and its evolution from when it was launched 4 months ago, there were 4 more presentations.</p>
<h2><strong>1. In the black with colored letters of Google</strong></h2>
<p>This first presentation was held by Martin Gaubitz from e-wolff. He talked about how you can start earning money using AdWords. Here are a few tips from his presentation that I found interesting and helpful:</p>
<ol>
<li>it&#8217;s very important to be visible: there are many different ways in which you can increase your visibility, for example: have a website, make cold calls to potential customers, host events, get recommendations and partnernishps</li>
<li>manage customer expectations: show your knowledge by creating case studies and obtaining Google certification badges you can place on your site, get more experience by working with clients from different domains, sign fair contracts that offer transparency and measurable results</li>
<li>offer your clients additional services – for example: SEM/SEO, Webanalytics, Coversion Optimization.</li>
<li>and the most important thing (or &#8216;The big secret&#8217; as Martin called it): Just Do It!</li>
</ol>
<p>&nbsp;</p>
<h2><strong>2.  Optimizing a Google AdWords Campaign</strong></h2>
<p>- presentation held by Tudor Marian. Here is a summary:</p>
<ol>
<li>in order to best optimize a Google AdWords Campaign you must start with the campaign structure and settings – make sure your ad groups have a certain topic and corresponding keywords, also make sure your campaign targets your specific demographic (user location and language)</li>
<li>the second step is to optimize your list of keywords (analyze what keywords your potential customers use to find your products or services), make sure your ads are convincing and have a strong call-to-action, and establish your bids and budget so that you make sure not to lose any potential clients.</li>
<li>and the final step is optimizing the landing page – make sure the content of your landing page matches what your ad promises and that it&#8217;s simple for the users to register conversions.</li>
</ol>
<p>&nbsp;</p>
<p>A few tips that I found helpful and applied on the campaigns I manage were:</p>
<ul>
<li>checking how the keywords perfom for the three different match types (broad, phrase and exact) – some keywords might have a better CTR with a lower CPC if the set match type is &#8216;exact match&#8217;. Even though for my campaigns there wasn&#8217;t a great number of keywords that performed better under &#8216;exact match&#8217;, it&#8217;s still a good way to bring in better quality traffic and save as much money per click as possible.</li>
<li>checking what keywords triggered which ads – this is a good way of finding if there are certain keywords that you should include in your campaign because they bring quality traffic. It&#8217;s also a good way of finding keywords that you might want to exclude because they&#8217;re not really accurate for your site.</li>
</ul>
<p>&nbsp;</p>
<h2><strong>3. Google Analytics &amp; Website Optimizer</strong></h2>
<p>There were also two more presentations, held by Norbert Simionescu, one about Google Analytics and the second about the Website Optimizer Tool.</p>
<p>A few important aspects from the Analytics presentation:</p>
<ol>
<li>your tool is only as good as your ability to use it</li>
<li>success is defined by your objectives (it&#8217;s important to define goals for your site; what you expect your clients to to on the site)</li>
<li>bounce rate can be a good way to see if your pages (landing pages) are useful to users, or if the keywords that brought the users to the site are accurate.</li>
<li>the new version of the tool alows you to set automatic alerts (for example you might set an alert that tells when the bounce rate exceeds a certain limit)</li>
<li>the new verions also introduces real-time reporting – that shows you exactly how many users are on your site and how they interact with the site</li>
</ol>
<p>&nbsp;</p>
<p>Although the presentation of the Website Optimizer tool was quite brief, here are some important aspects to consider:</p>
<ol>
<li>start testing different versions of pages that aren&#8217;t performing the way you were expecting (for example landing pages with a high bounce rate)</li>
<li>test different pictures or messages on the landing page (for example a different picture for the users that visit the site in the morning and a different picture for those visiting in the evening) – it&#8217;s important to mention here that a users will never see different versions of the site.</li>
<li>the tool is free, easy to use, does not impact SEO and has been known to increase conversions</li>
</ol>
<p>&nbsp;</p>
<p>I must admit I have not yet used the Website Optimizer tool, but I would very much like to try it out in the future. I think it would be very interesting to see how changing an image or a header on a landing page affect the way users interact with the certain page. It would also be interesting to see if a certain version of a page would trigger more conversions.</p>
<p>&nbsp;</p>
<p>If you&#8217;ve worked with the Website Optimizer Tool, I&#8217;d be very interested in reading what you think about it and how it helped you improve your site.</p>
<p>Also, any other tips about Google AdWords campaigns or the Google Analytics tool are more than welcome.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2012/04/google-engage-training/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2012/04/google-engage-training/</feedburner:origLink></item>
		<item>
		<title>Handling .NET assemblies in PHP</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/jOFh30On-_Q/</link>
		<comments>http://blog.zitec.com/2012/04/handling-net-assemblies-in-php/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 21:05:37 +0000</pubDate>
		<dc:creator>Ionut VODA, CTO,</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[dll]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=1264</guid>
		<description><![CDATA[This story is about manipulating or consuming managed assemblies (AKA DLLs) in PHP, mostly (but not only) on Windows systems. Managed and Un-Managed Code First I would like to go a little bit further to explain what managed and un-managed code means. A managed component (which can be an .exe file, an ActiveX control, a [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This story is about manipulating or consuming managed assemblies (AKA DLLs) in PHP, mostly (but not only) on Windows systems.</strong></p>
<h2>Managed and Un-Managed Code</h2>
<p>First I would like to go a little bit further to explain what managed and un-managed code means.<br />
A <strong>managed component</strong> (which can be an .exe file, an ActiveX control, a DLL and so on) means that it runs under the <a title="Common Language Runtime" href="http://en.wikipedia.org/wiki/Common_Language_Runtime" target="_blank">CLR</a> that <a title=".NET framework" href="http://en.wikipedia.org/wiki/.NET_Framework" target="_blank">.NET</a> provides. Nevertheless, it can execute in other CLR implementations such as <a title="Mono" href="http://www.mono-project.com/Main_Page" target="_blank">Mono</a>.</p>
<p>On the other hand, an <strong>un-managed component</strong> runs outside the CLR (so outside the control of the virtual machine), it can have access to Win32 APIs and is typically coded in C/C++. The latter are also recognized to have a lower footprint in terms of system resources.</p>
<p>Visual C++ Studio can produce both managed and un-managed code, while Visual C# Studio generates manged code only.</p>
<h2>Introducing the DOTNET class</h2>
<p>But how comes that you can actually load and consume such a DLL in PHP ? Well, this is because the managed DLLs have a &#8220;built in&#8221; component called <a title="OLE automation layer" href="http://en.wikipedia.org/wiki/OLE_Automation" target="_blank">OLE Automation Layer</a>. This is basically a <a title="Component Object Model" href="http://en.wikipedia.org/wiki/Component_Object_Model">COM</a> subset that expose a set of  interfaces so that a DLL can be consumed at run-time without prior compiling knowledge. COM is one of the main methods of gluing components on Windows platform.</p>
<p>PHP interacts with .NET DLLs via the <a title="DOTNET class" href="http://php.net/manual/en/class.dotnet.php" target="_blank">DOTNET</a> class. This one simply instantiates a class available with the DLL so you can call the public methods and properties. There are a couple of things you should consider here:</p>
<ol>
<li>you have to have the .NET framework installed on the system you are playing on</li>
<li>you have to be aware of the DLL structure in order know what class(es) to instantiate and what method(s) to call &#8211; more details in a minute</li>
</ol>
<h2>Consuming an existing DLL</h2>
<p>At a first look, you need to simply give it a try an load it in PHP with the DOTNET class. Sounds simple enough, right ? However you will quickly find out that DOTNET class loads DLLs from the Global Assembly Cache (<a title="Global Assembly Cache" href="http://en.wikipedia.org/wiki/Global_Assembly_Cache" target="_blank">GAC</a>) only.</p>
<p>Fortunately for us, we have a command line tool called <em>gacutil.exe</em> that can add DLLs to GAC with the press of a button. If you&#8217;re on Windows 7 it should be located under<br />
<em>c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\</em><br />
or<br />
<em>c:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin\</em>.<br />
Once you find it out, just run the following command on the console<br />
<em>gacutil.exe -i &#8220;\path\to\dll-file.dll&#8221;. </em><br />
The &#8220;i&#8221; flag tells the program to add it to GAC.</p>
<p>Once the DLL is added to GAC you will need another more detail to make it work from PHP. That is to find the corresponding Public Key Token that was assigned to your DLL.  A simple way to find it out is to open Windows Explorer and navigate to &#8220;C:\Windows\assembly&#8221;.</p>
<p><img src="http://blog.zitec.ro/wp-content/uploads/2012/04/public_key_token.png" alt="Public Key Token of an assembly" width="540" height="125" /></p>
<p>And this is how you invoke it from PHP:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$phpdotnet</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOTNET<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;PhpDotnet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=07a115ce41e79116&quot;</span><span style="color: #339933;">,</span>
<span style="color: #0000ff;">&quot;PhpDotnet.HelloWorld&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$phpdotnet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">GetTitle</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Attention must be paid at <em>Version</em> tag. You must use the same version number as indicated in GAC. The &#8220;<em>PhpDotnet</em>&#8221; string,  in the second parameter of DOTNET class constructor, indicates the namespace the class is being part of, while the &#8221;<em>HelloWorld</em>&#8221; string indicates the actual class you want to instantiate.</p>
<p>Each class within the DLL must be instantiated separately.</p>
<p><strong>Let&#8217;s do a quick recap</strong>: (1) register the DLL to GAC and (2) identify the Public Key Token and Version Number.</p>
<h2>When making your own DLL</h2>
<p>To prepare your own DLL to be used in PHP or any other applications in fact, you will need 2 additional steps.</p>
<p>1. The first one is to make your DLL &#8220;COM visible&#8221;.</p>
<p>To do that from Visual Studio, you need to go Project Properties -&gt; Application tab -&gt; click the Assembly Information button -&gt; check the &#8220;Make assembly COM-Visibile&#8221; checkbox.</p>
<p><img src="http://blog.zitec.com/wp-content/uploads/2012/04/make_assembly_com_visible.png" alt="How to make assembly COM visible" width="400" height="250" /></p>
<p>2. Then you will have to <a title="Strong-Named Assemblies" href="http://msdn.microsoft.com/en-us/library/wd40t7ad.aspx" target="_blank">strongly name</a> your DLL.</p>
<p>To do that in Visual Studio, go to Project Properties -&gt; Signing tab and click the &#8220;Sign the assembly&#8221; checkbox, select &#8220;New&#8221; and fill in the opened form, as indicated below.</p>
<p><img src="http://blog.zitec.com/wp-content/uploads/2012/04/strongly_name_assembly.png" alt="How to strongly name an assembly" width="400" height="219" /></p>
<p>Once you do these two things and compile your DLL, just stick to the above procedure regarding GAC and you&#8217;re done with it.</p>
<h2>Known limitations</h2>
<p>There are few issues when doing this integration that you might want to consider:</p>
<p><strong>1. Public methods</strong></p>
<p>Just like the PHP manual says, the returned object is an <a title="PHP object overloading" href="http://php.net/manual/en/language.oop5.overloading.php" target="_blank">overloaded object</a> which makes PHP unaware of the public methods the object might contain. So, if you var_dump it, you will see nothing but an empty array. That is why the inner DLL class structure mus be known prior to calling it.</p>
<p>Luckily for us there is another tool specialized for this job shipped with the .NET framework called <em>ildasm.exe</em>. It is located next to <em>gacutil.exe</em> under<br />
<em>c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\</em> or <em>c:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin\. </em><br />
To load and display the DLL structure simply call &#8220;<em>ildasm.exe \path\to\your.dll</em>&#8220;.</p>
<p><strong>2. Parameters</strong></p>
<p>Another issue is that you cannot pass parameters to a class constructor within a DLL.</p>
<p><strong>3. Data types</strong></p>
<p>Being two different programming language, we have different data types involved. This being said, you will have to make sure the DLL class methods return data types that PHP understands (mostly strings, ints, booleans, etc). In case your methods needs to return an array list or a more complicated structure, you might want to consider JSON for encoding.</p>
<h2>Wrapping it up</h2>
<p>We&#8217;ve found out that PHP offers quite an elegant way to handle .NET specific DLLs. You only need to pay a little attention to &#8220;instantiate&#8221; them in a proper way. However you might be wondering where this stuff will be needed in your projects, right ? Below are two examples, in fact use cases, that we&#8217;ve met with our projects.</p>
<p><strong>Reusing or encapsulating business logic</strong></p>
<p>You may find this approach useful in cases where the business logic is encapsulated in a .NET component but you need to use it from PHP too. Here you just load the DLL class and your good to go as opposed of doing them in PHP again.</p>
<p><strong>WCF webservices authentication</strong></p>
<p>It can also serve as an approach of consuming WCF webservices with <a title="WSHttpBinding, Bindings and Security" href="http://msdn.microsoft.com/en-us/library/ms731172.aspx" target="_blank">WSHttpBinding</a> stack enabled, backed by Windows authentication method. While this kind of service has one or two implementations in PHP, they are difficult to setup which could make the DOTNET class &amp; DLL combo a viable alternative.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2012/04/handling-net-assemblies-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2012/04/handling-net-assemblies-in-php/</feedburner:origLink></item>
		<item>
		<title>Zitec. Rebranded.</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/P2T0CvJJxrk/</link>
		<comments>http://blog.zitec.com/2012/04/zitec-rebranded/#comments</comments>
		<pubDate>Sat, 31 Mar 2012 22:10:26 +0000</pubDate>
		<dc:creator>Alex AXON, Chief Creative Officer</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[featured]]></category>
		<category><![CDATA[logo]]></category>
		<category><![CDATA[rebrading]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=1163</guid>
		<description><![CDATA[There&#8217;s a time in every company’s life when rebranding is inevitable. Most of the times you want to target a different market, or simply to highlight a new focus of your business or a change in your products. Sometimes, an “it just looks old” is simply enough. There are no certain indicators for this, but [...]]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_1217" class="wp-caption alignleft" style="width: 189px"><img class="size-full wp-image-1217" title="Zitec old logo" src="http://blog.zitec.com/wp-content/uploads/2012/04/logozitec.png" alt="Zitec old logo" width="179" height="127" /><p class="wp-caption-text">Zitec old logo</p></div> There&#8217;s a time in every company’s life when rebranding is inevitable. Most of the times you want to target a different market, or simply to highlight a new focus of your business or a change in your products. Sometimes, an “it just looks old” is simply enough. There are no certain indicators for this, but when the moment comes, you will know. However, changing a company&#8217;s objective, message and even culture is not an easy task &#8211; many have tried and most fail. We gladly accepted the challenge: we decided to make this happen with our own resources.</p>
<h2>Why now?</h2>
<p>The Zitec logo was created in 2003. It’s old. Period. It doesn’t meet the current needs anymore. It’s not web 2.0 enough. It’s not up to today’s graphical standards. It can’t deliver our corporate message anymore.</p>
<p><img class="alignnone size-full wp-image-1205" title="Zitec and coffee cup" src="http://blog.zitec.com/wp-content/uploads/2012/04/coffeecupimage.jpg" alt="" width="610" height="210" /></p>
<h2>The goal</h2>
<p>The new brand image should reinforce the excellence of our products and services. We are the best company out there that creates web apps. The new brand image should be new and fresh, distinctive and original, timeless and memorable. It should inspire trust, quality and admiration. Our goal was to create a new, powerful logo that accurately communicates our mission.</p>
<h2>Sketches and colors</h2>
<p>A good logo redesign takes time and coffee. Our entire creative team brainstormed hours, days even. They started from scratch with an empty sheet of paper and lots of ideas. We definitely needed to change the old company colors. The Pantone 2945 CVC blue and Pantone 021 CVC Orange simply didn’t reflect anymore our growing business and quality of our service. Colors have a language of their own so it’s worthwhile to define the colors that send the right message to our customers. After extensive research, with our target market in mind we came to the conclusions that the best color scheme should contain a new and very powerful shade of orange, called <span style="color: #ff6700;">Tangerine</span> (color of the year) and the same blue!</p>
<p>The new logo needed to be abstract and specific in the same time, classy and modern. We had to design our own unique font to accomplish our purposes. Any commercial font, no matter how original and expensive might be, would simply not do. We had to hand-craft the font very carefully to efficiently communicate our future-proof services and solutions.</p>
<p><strong> Some early explorations and sketches:</strong></p>
<p><img class="alignnone size-full wp-image-1238" title="Sketches" src="http://blog.zitec.com/wp-content/uploads/2012/04/z-sketches.jpg" alt="" width="610" height="400" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The creation of our new logo took several long days and sleepless nights but the results are more than satisfactory. Feel free to share your thoughts  in the comments below, all feedback is appreciated although we clearly expect only positive feedback. Let’s not be modest here, the new logo is simply awesome.</p>
<h2>And here it is the final logo:</h2>
<p><img class="alignnone size-full wp-image-1237" title="Old Logo New Logo" src="http://blog.zitec.com/wp-content/uploads/2012/04/old-logo-new-logo.png" alt="" width="610" height="210" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2012/04/zitec-rebranded/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2012/04/zitec-rebranded/</feedburner:origLink></item>
		<item>
		<title>Preventing SSL session exploits</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/4XUVz79AodU/</link>
		<comments>http://blog.zitec.com/2012/01/preventing-ssl-session-exploits/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 21:04:23 +0000</pubDate>
		<dc:creator>Ionut VODA, CTO,</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[featured]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=1018</guid>
		<description><![CDATA[Safe enough ? I would start by stating that the current article does not underline any vulnerability with the SSL protocol itself, but it shows how can a person be induced into error despite the high level of confidence and comfort that SSL provides. This type of exploit is known as Man In The Middle [...]]]></description>
			<content:encoded><![CDATA[<h2>Safe enough ?</h2>
<p>I would start by stating that the current article does not underline any vulnerability with the <a title="SSL/TSL" href="http://en.wikipedia.org/wiki/Transport_Layer_Security" rel="nofollow" target="_blank">SSL protocol</a> itself, but it shows how can a person be induced into error despite the high level of confidence and comfort that SSL provides.</p>
<p>This type of exploit is known as <a title="Man-in-the-middle attack" href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack" rel="nofollow" target="_blank">Man In The Middle</a> (shortly MITM) which is a form of <a title="Eavesdropper" href="http://en.wikipedia.org/wiki/Eavesdropper" rel="nofollow" target="_blank">eavesdropper</a> attack. Although this type of exploit is mostly (and sometimes only) associated to plain non-secured connections like HTTP, it can be employed to HTTPS connections as well.</p>
<p>Below I will present the two most common techniques of running such an attack. While there are other methods to conduct a MITM attack, the two below are the easily camouflaged to user and they require no &#8220;intervention&#8221; on his/her computer.</p>
<p><strong>These two procedures run with the following assumptions:</strong></p>
<ol>
<li>the attacker has access to your network router</li>
<li>the user ignores the lack of HTTP<strong>S</strong> in the browser navigation bar and/or accepts an invalid server certificate</li>
<li>the SSL setup works with server certificates only</li>
</ol>
<div>The procedures exposed below also assume you are familiar with the basic concepts of SSL protocol. In case you need a refresh you might take a look <a title="SSL certificates" href="http://blog.zitec.com/2012/01/ssl-certificates/">here</a>.</div>
<p>&nbsp;</p>
<h2>HTTP mapping</h2>
<p>This method was documented by <a title="Moxie Marlinspike" href="http://www.thoughtcrime.org/about.html" rel="nofollow" target="_blank">Moxie Marlinspike</a> (a security researcher and hacker) on his blog. It all started from the fact that most of the times a SSL session is not initiated directly by the user. Instead, a user is redirected to secure page from a main page or login button on a non-secure page. The trick here is to take control of the SSL session before it even starts.</p>
<p>That being said, Moxie created a tool called <a title="SSLstrip" href="http://www.thoughtcrime.org/software/sslstrip/" rel="nofollow" target="_blank">SSLstrip</a> which should be deployed on the router, server, machine, middleware you want to control. Once configured, the tool will stop all the incoming HTTPS traffic from client and it will initiate the SSL session from here. The client, at his turn, will see only HTTP pages. So SSL strip will securiley communicate with the server and talk back to client on plain HTTP. As far as the server is concerned, the HTTPS connection is fulfilled and the client still gets his content on the page. So both parties are satisfied. The only thing changed here that might be noticed by the client is the HTTP connection instead of HTTPS.</p>
<p><strong>The process follows these steps:</strong></p>
<ol>
<li>client asks a HTTPS URL</li>
<li>SSLstrip gets the URL and forward it to server; so, the client never talks HTTPS with the server</li>
<li>the server response is retrieved, parsed (HTTPS HREFs are replaced with HTTP and Location headers follow the same rule) and passed back to client by SSLstrip</li>
<li>also a mapping of stripped URLs is being kept; that is when such a link is called (http://site.com/page.html), SSLstrip automatically calls the secure version (https://site.com/page.html)</li>
</ol>
<h2>Certificate replacement</h2>
<p>This approach also assumes the attacker controls the middleware like in the above examples. The way it works is that a fake certificate is being generated on the fly (with a tool like <a title="OpenSSL" href="http://www.openssl.org/" rel="nofollow" target="_blank">OpenSSL</a>) and signed with the attacker&#8217;s private key. The fake certificate contains all the information available in the root certificate as  the essential information is taken from the original certificate.</p>
<p>Now, the browsers will issue a security warning but as the certificate seems to be valid &#8211; the identification data match the original one &#8211; the users are tempted to ignore it.</p>
<p>This scenario involves the following steps:</p>
<ol>
<li>the client calls a HTTPS resource on the server</li>
<li>the attacker stops and intercepts it and issue the same request on his behalf; so the SSL session is started between the attacker and the server</li>
<li>the attacker prepares a fake certificate</li>
<li>the response is taken from the server and sent back to client along with the fake certificate</li>
<li>depending on the browser, a SSL security warning will be issued (but only for the first time)</li>
<li>if the client ignores the error, then it&#8217;s all done: all the requests are proxied through the attacker, that simply passes them along to server and returns the response back to client</li>
</ol>
<div>Although I am not aware of any out of the box tool for such a thing, there a few papers out there describing quite detailed what and how you need to do to build up your own tool. <a title="MITM tool guide" href="http://www8.cs.umu.se/education/examina/Rapporter/MattiasEriksson.pdf" rel="nofollow" target="_blank">One of them</a> was published by Ume University in Sweden.</div>
<p>&nbsp;</p>
<h2>What can you do about it ?</h2>
<p>Despite the technical and fancy terms that characterize these attacks, there are a few simple things that you can do to avoid them. All you need is a little attention.</p>
<ul>
<li>do not ignore the browser security warnings</li>
<li>pay attention to HTTPS in browser&#8217;s navigation bar</li>
<li>save the banking operations for home as there are little chances for someone to get control of your home router</li>
<li>and password protected your internet access to your home router (WEP security is available on most of the routers)</li>
<li>for organizations, make sure to employ the SSL client certificates</li>
<li>in case your business expose sensitive webservices: make use of message encryption provided by <a title="WS Security" href="http://en.wikipedia.org/wiki/WS-Security" rel="nofollow" target="_blank">WS-* stack</a></li>
</ul>
<div><strong>Update:</strong> I&#8217;ve got a tip from a reader who pointed out <a title="Cain and Abel" href="http://www.oxid.it/cain.html" target="_blank">Cain and Abel</a>, a Windows based tool that can also be used to impersonate digital certificates. An extensive tutorial explaining how to do that can be found <a title="Cain and Abel at work" href="http://www.thehackerslibrary.com/?p=419" target="_blank">here</a>.</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2012/01/preventing-ssl-session-exploits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2012/01/preventing-ssl-session-exploits/</feedburner:origLink></item>
		<item>
		<title>SSL certificates</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/AklgfqNap2Y/</link>
		<comments>http://blog.zitec.com/2012/01/ssl-certificates/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 18:15:37 +0000</pubDate>
		<dc:creator>Ionut VODA, CTO,</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=1035</guid>
		<description><![CDATA[What is SSL? SSL is a protocol, not a HTTP extension, not a digital certificate nor an encryption method. As it finds itself at the TCP layer it can be employed for other application protocols than HTTP (i.e FTP, SMTP, etc). SSL is the predecessor of  Transport Layer Security (TSL) and although they do the [...]]]></description>
			<content:encoded><![CDATA[<h2>What is SSL?</h2>
<p><a title="SSL/TLS" href="http://en.wikipedia.org/wiki/Secure_Sockets_Layer" rel="nofollow" target="_blank">SSL</a> is a protocol, not a HTTP extension, not a digital certificate nor an encryption method. As it finds itself at the TCP layer it can be employed for other application protocols than HTTP (i.e FTP, SMTP, etc). SSL is the predecessor of  Transport Layer Security (TSL) and although they do the same thing &#8211; until a certain point &#8211; the former definition is much popular among the developers. TSL has a few enhancements compared to SSL when it comes to client&#8217;s and server&#8217;s ability to specify which hash algorithms to use, sha-256 for pseudo random function, etc.</p>
<p>SSL protocol enforces 3 aspects of  client-server communication:</p>
<ol>
<li>authentication &#8211; both one-way (server authenticates to client) and two-way (client authenticates to server as well)</li>
<li>privacy &#8211; which is <a title="symmetric encryption" href="http://en.wikipedia.org/wiki/Symmetric-key_algorithm" rel="nofollow" target="_blank">message encryption</a></li>
<li>message integrity &#8211; by using <a title="MAC" href="http://en.wikipedia.org/wiki/Message_authentication_code" rel="nofollow" target="_blank">MACs</a> to make sure the message content hasn&#8217;t changed during transmission</li>
</ol>
<h2>Certificates</h2>
<p>The <a title="Digital Certificates" href="http://en.wikipedia.org/wiki/Public_key_certificate" rel="nofollow" target="_blank">certificates</a> are at the base of SSL protocol as they encapsulate the vital information needed for this protocol to work. The most important information in a certificate are: the certificate issuer, the identified entity, validity dates, the public key and the algorithms used to create the signature and public key.</p>
<p>Simply put the main roles of a certificate are to guarantee that the entity presenting it, is the entity claiming to be (that is a valid CA signing the certificate) and to generate the &#8220;master secret&#8221; needed for the symmetric data encryption.</p>
<h3>CA</h3>
<p>CA comes from <a title="Certificate Authority" href="http://en.wikipedia.org/wiki/Certificate_authority" rel="nofollow" target="_blank">Certificate Authority</a> which is an entity that issues digital certificates. Every browser out there has a predefined list of CAs that come along. Everytime a SSL session is initiated with a server, the root CA of the certificate is verified against the local list of CAs. Whenever an issuer is not on that list, the browsers pops up a security warning, usually in a dedicated page.</p>
<h3>Server certificates</h3>
<p>This the most common deployment form of certificates today and it employs an one-way authentication mechanism.  This assures the client that the server is who pretends to be by providing it a digital certificate. The client checks the CA that signed the digital certificate against the local CAs list.  The detailed procedure used to establish the SSL session is detailed below in Handshake section.</p>
<p>The diagram below (taken from <a href="http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s02.html" rel="nofollow" target="_blank">HP site</a>) depicts the server certificate check.</p>
<p><img title="Server Certificates" src="http://blog.zitec.com/wp-content/uploads/2012/01/server_certs.gif" alt="Server Certificates" width="479" height="287" /></p>
<p>With this approach the client is not authenticated to server, so the server has no guarantee that the client is who pretends to be from the SSL protocol perspective. Application level authentication is out of the question here.</p>
<p>Server certificates are heavily used by social networks, public webmails, intranet portals and so on.</p>
<h3>Client certificates</h3>
<p>Client certificates leverage the full power of SSL protocol by employing the two-way authentication model. Here, not only the server is authenticated to client but the client, at his turn, is authenticated to server. This way both parties are trusted and the identification problem is solved.</p>
<p>This model requires  a certificate to be installed on the client machine (his/her browser most likely). The client certificate is signed with the private key of the issuing server. The client certificate contains both a private and a public key and, exactly like with the server certificates, the public key is sent along with the certificate to the server requesting it. An important thing to note here is that the client certificate is used during the handshake process only, when establishing the SSL session parameters.</p>
<p>Given the fact that each client must install a client certificate to access a server or a service, this model is not easy to scale and that is why it is less popular nowadays.  It is especially used by banking institutions where knowing the identity of both parties is a must.</p>
<p>The diagram below (also from <a href="http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s02.html" rel="nofollow" target="_blank">HP site</a>) shows the two-way auth process with client and server certificates.</p>
<p><img title="Client-Server Certificates" src="http://blog.zitec.com/wp-content/uploads/2012/01/client_server_certs.gif" alt="Client-Server Certificates" width="479" height="287" /></p>
<p>With client certificates you can easily achieve a two-factor authentication by combining something you have (a digital certificate) with something you know (a password). This could be a good option for the random code generator devices that most of the banking systems uses today.</p>
<p>One downside of client certificates could be in the fact that they are no easily portable. That is once you installed a certificate on a browser, you cannot use it from another work station unless you install it there too.</p>
<h2>Handshake</h2>
<p>The handshake is that process in which the client and server agree on various parameters to establish the secure SSL session. A detailed description of each step involved in handshaking process can be found in the corresponding <a title="Detailed handshake process" href="http://en.wikipedia.org/wiki/Secure_Sockets_Layer#TLS_handshake_in_detail" rel="nofollow" target="_blank">wiki article</a>.</p>
<p>The authentication part of the handshake process is encrypted with asymmetric algorithms, while the rest of the SSL session communication is encrypted with symmetric algorithms which are by far much faster.</p>
<p>By default the SSL handshake is performed with every new TCP connection being made to server. That is why the <em>Connection: Keep-Alive</em> header should be used so a TCP session (and therefore a SSL one) to be reused across multiple HTTP requests. By not doing so you will overwhelm  the server in the SSL handshaking process.</p>
<h2>Browser support</h2>
<p>Any major browser supports at least on TLS version with fail-over to SSL 3. For instance IE8 on Win has TLS 1.2, FF 3 and Chrome have 1.0 and Safari on Mac has on version of TLS (not specified which one though).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2012/01/ssl-certificates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2012/01/ssl-certificates/</feedburner:origLink></item>
		<item>
		<title>Ditch expensive SEO tools – Use free APIs</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/ETSBnHF4dJY/</link>
		<comments>http://blog.zitec.com/2011/12/ditch-seo-tools-use-free-apis/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 15:55:57 +0000</pubDate>
		<dc:creator>Cristian Raiber, Online Marketing Specialist</dc:creator>
				<category><![CDATA[Online Marketing]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=910</guid>
		<description><![CDATA[Why the need for SEO tools? Using tools, in general, for automating tedious tasks is an idealistic principle in a perfect world. And why not use them &#8211; tools make our lives easier by removing the necessity to perform daunting, repetitive tasks. What seasoned SEO wouldn&#8217;t give a small fortune for an all-in-one tool that [...]]]></description>
			<content:encoded><![CDATA[<h3>Why the need for SEO tools?</h3>
<p>Using tools, in general, for automating tedious tasks is an idealistic principle in a perfect world. And why not use them &#8211; tools make our lives easier by removing the necessity to perform daunting, repetitive tasks. What seasoned SEO wouldn&#8217;t give a small fortune for an all-in-one tool that can do on-page analysis, perform a competition analysis and potentially rank a website with a few clicks  - let alone send an email with a summary to a client, fully automated ? I know I would.</p>
<p>Sadly, such a tool doesn&#8217;t exist &#8211; at least none that I know of &#8211; and if it did, I&#8217;m pretty sure it would actually cost a small fortune. Various SEO tools have emerged on the market in the past couple of years,with functionalities ranging from <span style="text-decoration: underline;">backlink analysis</span> to generating <span style="text-decoration: underline;">automated white label reports</span> for clients. While I&#8217;m not a fan of this large-scale completely impersonal approach, I do reckon that paid SEO tools have an advantage in the industry &#8211; they are offering to automate the aforementioned daily tasks, at a reasonable cost.</p>
<p>But why should anyone pay for something that offers a handful to almost no customization options? Why should I be limited to using a couple of template reports, that are also being used by thousands of other people? If I&#8217;m paying for a tool, I want to gain full control over it and tweak it to my personal liking. I want to be able to customize the reports, move and remove blocks of irrelevant data from them, possibly graph the data in a more compelling way and also add my personal suggestions at the end of the document.</p>
<h3>Advantages of using free SEO tools</h3>
<p>The obvious, they&#8217;re free and of course the possibility of building upon these tools and enhancing them even further. Recently, SEOmoz published an article on the &#8220;<a href="http://www.seomoz.org/blog/what-does-your-ideal-rank-tracker-look-like-we-want-to-know" rel="external nofollow">ideal rank tracker</a>&#8221; and what people expect from such a tool &#8211; they&#8217;ve listed ten industry tools that all do the same thing, track your rankings across search engines and save your historic data for further analysis. The lowdown &#8211; they all fail to deliver what they&#8217;re supposed to, in the simplest manner.</p>
<p><span style="text-decoration: underline;">Backlink analysis</span> &#8211; On the 21st of November, Yahoo&#8217;s Site Explorer closed its gates to the public and moved its data to Bing&#8217;s Webmaster Tools, completing the move over to Bing. A lot of the SEO tools available on the market that were capable of performing a backlink analysis are merely scrapers &#8211; gathering information publicly available, filtering it for duplicates and outputting into a window. One of the best free tools available for backlink analysis was indeed Yahoo&#8217;s Site Explorer &#8211; but don&#8217;t worry, we&#8217;ve still got <a title="Majestic SEO" href="http://www.majesticseo.com" rel="external nofollow">Majestic Tools</a> and <a title="Open Site Explorer Backlink Analysis SEO Tool" href="http://www.opensiteexplorer.org/" rel="external nofollow">Open Site Explorer</a> to get the job done.</p>
<p><span style="text-decoration: underline;">Screen-shot of OpenSiteExplorer analysis for techcrunch.com</span></p>
<p><a href="http://blog.zitec.com/wp-content/uploads/2011/11/opensiteexplorer_backlink_seo_tool.jpg" rel="lightbox[910]"><img class="alignnone size-full wp-image-911" title="opensiteexplorer_backlink_seo_tool" src="http://blog.zitec.com/wp-content/uploads/2011/11/opensiteexplorer_backlink_seo_tool.jpg" alt="Open Site Explorer Backlink Analysis SEO Tool" width="608" height="67" /></a></p>
<p>Sure, there a few missing stats that would are accessible to the &#8220;PRO only&#8221;, luckily those are the stats you could get for free by writing up your own scrapers, using only free, publicly available APIs. Below is a screen-shot of a dashboard that I&#8217;m using for a quick competition analysis &#8211; all built using free APIs.</p>
<p><span style="text-decoration: underline;">Screen-shot of dashboard built using free tools and publicly available APIs </span></p>
<p><a href="http://blog.zitec.com/wp-content/uploads/2011/11/competition-dashboard.jpg" rel="lightbox[910]"><img class="alignnone size-full wp-image-917" title="competition dashboard" src="http://blog.zitec.com/wp-content/uploads/2011/11/competition-dashboard.jpg" alt="SEO Competition Dashboard - SEO Tool" width="603" height="93" /></a></p>
<p>Pretty close, right ? The numbers aren&#8217;t a perfect match with OpenSiteExplorer because they update their indexes on a time frame basis, so you don&#8217;t know exactly when the numbers were crunched last time and how accurate they are. Lastly, but not least, using a free API does have it&#8217;s own limitations &#8211; as you can see I&#8217;m able to retrieve a count of under 1M backlinks for techcrunch.com, whilst the OpenSiteExplorer reports around 1,2M backlinks for that particular URL. At that backlink volume, the difference is nothing to shy about &#8211; I got the overall picture, trying to rank for &#8220;techcrunch&#8221; would be <strong><span style="text-decoration: underline;">extremely difficult</span></strong>.</p>
<h3>Usages of such an SEO Dashboard</h3>
<ul>
<li>You get a quick overview over a certain keyword &#8211; assess the difficulty of the niche, interpret the data and put it into actionable stats.</li>
<li>You could create your own &#8220;difficulty&#8221; analysis formula based solely on these raw metrics and incorporate it into your dashboard &#8211; for those that know that PageRank is merely an indicator and not a factor.</li>
<li>You could run it on a cron-job (scheduler) and have it &#8220;screenshot&#8221; the competition, monitoring it weekly.</li>
<li>You could graph the data and output it in a presentation for a potential customer &#8211; remember, flexibility is power.</li>
</ul>
<h3>How to get started on creating your own SEO Dashboard</h3>
<p>For starters you should be able to understand what an API is and how it works, what a JSON encoded response is and how you can parse it easily. If all these things are new to you, performing a simple Google search will give you the required amount of knowledge in a maximum of 30 minutes. We have used Google Docs in this example to take advantage of its flexibile programming interface as well as to make sure we can present the data in a more friendly manner.</p>
<h4><strong>Writing a function in Google Docs</strong></h4>
<p>If you haven&#8217;t already, sign-up for an account on  <a href="http://www.docs.google.com/" rel="nofollow" target="_blank">Google Docs </a>and start harvesting its power. Not many know that Google Docs offers a script editor, a javascript development medium that allows you to use the Spreadsheets as a database and perform automated tasks on them. You can find the Google Docs Script Editor in the Tools -&gt; Script Editor menu.</p>
<h4><strong>Your first function in Google Docs</strong></h4>
<p>Assuming you have started your Google Docs Script Editor and were presented with a blank workspace &#8211; which we will be naming, for the sake of this article, &#8220;My SEO Dashboard&#8221;. Below is your first function that will fetch the number of shares Facebook reports for a certain specified URL. Write it down into your Google Docs Script Editor and hit the Save button &#8211; that&#8217;s it, now let&#8217;s put it to some good usage.</p>
<pre>function fbshares(url)
{
  var jsondata = UrlFetchApp.fetch("http://graph.facebook.com"+url);
  var object = Utilities.jsonParse(jsondata.getContentText());
  return object.shares;
}</pre>
<h4>How to incorporate your function into an SEO tool</h4>
<p>Assuming you will have a set of URLs &#8211; maybe the first 50 results from Google for a particular keyword &#8211; you would call the function as follows:</p>
<pre>iferror(fbshares(A1),"no available data")</pre>
<p>Where <em>A1</em> would be the cell in your Google Docs Spreadsheet that holds the actual URL.</p>
<p>Obviously, the functionality of such a dashboard could be extended to something more complex that returns direct actionable data, the parsing and filtering happening in the back. The purpose of this article was to highlight some of the advantages of building your own free SEO tools as well as to give you a few ideas on how you could easily automate some of the most daunting tasks when it comes to SEO.</p>
<div>Free resources, publicly available that were used to build the dashboard:</div>
<div>
<ul>
<li>The <a title="Facebook Graph API" href="https://developers.facebook.com/docs/reference/api/" rel="nofollow external">Facebook Graph API</a>.</li>
<li>The <a title="Twitter API" href="https://dev.twitter.com/" rel="external nofollow">Twitter API</a>.</li>
<li>The <a title="Google Page Speed Score API" href="http://code.google.com/apis/pagespeedonline/" rel="nofollow external">Google Page Speed API</a>.</li>
<li>The <a title="SEOmoz Free API" href="http://apiwiki.seomoz.org/w/page/13991148/SEOmoz%20Free%20API" rel="external nofollow">SEOmoz Free API</a>.</li>
<li>The <a title="Google Docs" href="https://docs.google.com/" rel="external nofollow" target="_blank">Google Docs</a>.</li>
</ul>
</div>
<div class="clear"></div>
<div>More Resources:</div>
<div>
<ul>
<li>The <a title="Google Docs Script Tutorial " href="http://code.google.com/googleapps/appsscript/guide.html" rel="nofollow" target="_blank">Google Docs Script Editor Tutorial</a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2011/12/ditch-seo-tools-use-free-apis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2011/12/ditch-seo-tools-use-free-apis/</feedburner:origLink></item>
		<item>
		<title>How to find a really special deal for this winter</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/9eXVyxK7-VQ/</link>
		<comments>http://blog.zitec.com/2011/12/how-to-find-a-really-special-deal-for-this-winter/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 08:52:57 +0000</pubDate>
		<dc:creator>Costinela NISTOR, Online Marketing Specialist,</dc:creator>
				<category><![CDATA[Online Marketing]]></category>
		<category><![CDATA[holiday]]></category>
		<category><![CDATA[hotel]]></category>
		<category><![CDATA[popular destinations]]></category>
		<category><![CDATA[special deals]]></category>
		<category><![CDATA[trends]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=970</guid>
		<description><![CDATA[Since it&#8217;s the winter holidays season and we&#8217;re all about travelling, I thought today we could have a close look at HotelPeeps.com, a travel concept meant to help you find the best accommodation options for worldwide destinations and save up to 75% for your next trip. What&#8217;s different about HotelPeeps? HotelPeeps has two special features [...]]]></description>
			<content:encoded><![CDATA[<p>Since it&#8217;s the winter holidays season and we&#8217;re all about travelling, I thought today we could have a close look at <a href="http://hotelpeeps.com" target="_blank">HotelPeeps.com</a>, a travel concept meant to help you find the best accommodation options for worldwide destinations and save up to 75% for your next trip.<br />
</p>
<h2>What&#8217;s different about HotelPeeps?</h2>
<p>HotelPeeps has two special features – Price Trends and Special Deals – meant to constantly monitor the evolution on the hotel market and display the attractive variations, as special deals.<br />
Finding better prices than the big guys in this market is happening quite often. Take for example some of the hotels below and their prices for this season.</p>
<style>
.table-header{
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -136px repeat-x;
	display:block;
	width:603px;
	height:68px;
	-webkit-border-top-left-radius: 3px;
	-webkit-border-top-right-radius: 3px;
	-moz-border-radius-topleft: 3px;
	-moz-border-radius-topright: 3px;
	border-top-left-radius: 3px;
	border-top-right-radius: 3px;
	margin-left:10px;
	}
.hotelpeeps-col{
	float:left;
	clear:none;
	display:block;
	width:412px;
	height:68px;
	text-align:center;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 12px 0px no-repeat;
	}
.hotelpeeps-col a{
	display:block;
	height:68px;
	width:241px;
	border:none;
	margin-left:12px;
	}
.booking-col, .hotels-col{
	float:left;
	clear:none;
	display:block;
	height:68px;
	width:95px;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -469px no-repeat;
	text-align:center;
	line-height:68px;
	font-family:Arial, Helvetica, sans-serif;
	font-size:13px;
	color:#000000;
	text-decoration:none;
	font-weight:normal;
	}
.table-content{
	border:1px solid #e0e0e0;
	background:#fff;
	display:block;
	width:595px;
	padding:3px;
	margin-left:10px;
	}
.row{
	width:595px;
	height:65px;
	display:block;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -697px repeat-x;
	}
.hotel-info{
	float:left;
	clear:none;
	display:block;
	height:65px;
	width:315px;
	position:relative;
	}
.hotel-info a{
	display:block;
	position:absolute;
	height:65px;
	width:410px;
	z-index:10;
	}
.hotel-name{
	float:left;
	clear:none;
	font-family:Arial, Helvetica, sans-serif;
	font-size:14px;
	color:#000;
	text-decoration:none;
	font-weight:none;
	margin:16px 0px 0px 10px;
	}
.hotel-name span{
	color:#4d6fa1;
	font-size:12px;
	}
.stars1{
	float:right;
	clear:none;
	}
.hotelpeeps-price{
	float:left;
	clear:none;
	margin-right:2px;
	display:block;
	height:51px;
	width:93px;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -404px repeat-x;
	}
.booking-price{
	float:left;
	clear:none;
	display:block;
	margin-right:2px;
	height:51px;
	width:93px;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -339px repeat-x;
	}
.hotels-price{
	float:left;
	clear:none;
	display:block;
	margin-right:0px;
	height:51px;
	width:90px;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -339px repeat-x;
	}
.hotelpeeps-price, .booking-price, .hotels-price{
	font-family:Arial, Helvetica, sans-serif;
	font-size:26px;
	font-style:italic;
	text-decoration:none;
	text-shadow:1px 1px 0px #fff;
	font-weight:normal;
	text-align:center;
	line-height:23px;
	padding-top:14px;
	}
.booking-price, .hotels-price{
	color:#8c8c8c;
	}
.hotelpeeps-price{
	color:#132d0e;
	}
.hotelpeeps-price span, .booking-price span, .hotels-price span{
	font-size:14px;
	text-transform:uppercase;
	line-height:14px !important;
	}
.first-row{
	height:67px !important;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -272px repeat-x !important;
	}
.first-row .hotelpeeps-price{
	height:52px !important;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -205px repeat-x !important;
	}
.first-row .booking-price, .first-row .hotels-price{
	height:53px !important;
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) 0px -69px repeat-x !important;
	}
.stars1{
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) -1px -562px no-repeat;
	width:16px;
	}
.stars2{
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) -1px -584px no-repeat;
	width:32px;
	}
.stars3{
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) -1px -605px no-repeat;
	width:48px;
	}
.stars4{
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) -1px -626px no-repeat;
	width:64px;
	}
.stars5{
	background:url(http://blog.zitec.com/wp-content/themes/canvas/images/sprite-hp-post.png) -1px -647px no-repeat;
	width:80px;
	}
.stars1, .stars2, .stars3, .stars4, .stars5{
	display:block;
	height:16px;
	position:absolute;
	top:23px;
	right:10px;
	z-index:1;
	}
.hotel-info br{line-height:0px !important; display:none;}
.hotel-info span br{line-height:normal !important; display:block;}
</style>
<div class="table-header">
<div class="hotelpeeps-col"><a href="http://www.hotelpeeps.com/" target="_blank" alt="hotelpeeps" title="Hotelpeeps.com"></a></div>
<div class="booking-col">Booking.com</div>
<div class="hotels-col">Hotels.com</div>
</div>
<div class="table-content">
<div class="row first-row">
<div class="hotel-info">
        	<a href="http://www.hotelpeeps.com/rome/mariano/14952" target="_blank" title="Mariano, Rome&#13;Checkin: 23.12.2011, 4 Nights"></a><br />
        	<span class="hotel-name">Mariano, Rome<br /><span>Checkin: 23.12.2011, 4 Nights</span></span><br />
            <span class="stars3">&nbsp;</span>
        </div>
<div class="hotelpeeps-price">207<br /><span>EUR</span></div>
<div class="booking-price">274<br /><span>EUR</span></div>
<div class="hotels-price">292<br /><span>eur</span></div>
</p></div>
<div class="row">
<div class="hotel-info">
        	<a href="http://www.hotelpeeps.com/prague/archibald-city/28235" target="_blank" title="Archibald City, Prague&#13;Checkin: 23.12.2011, 5 Nights"></a><br />
        	<span class="hotel-name">Archibald City, Prague<br /><span>Checkin: 23.12.2011, 5 Nights</span></span><br />
            <span class="stars4">&nbsp;</span>
        </div>
<div class="hotelpeeps-price">195<br /><span>EUR</span></div>
<div class="booking-price">267<br /><span>EUR</span></div>
<div class="hotels-price">267<br /><span>eur</span></div>
</p></div>
<div class="row">
<div class="hotel-info">
        	<a href="http://www.hotelpeeps.com/prague/clement/5423" target="_blank" title="Clement, Prague&#13;Checkin: 23.12.2011, 5 Nights"></a><br />
        	<span class="hotel-name">Clement, Prague<br /><span>Checkin: 23.12.2011, 5 Nights</span></span><br />
            <span class="stars4">&nbsp;</span>
        </div>
<div class="hotelpeeps-price">255<br /><span>EUR</span></div>
<div class="booking-price">598<br /><span>EUR</span></div>
<div class="hotels-price">596<br /><span>eur</span></div>
</p></div>
<div class="row">
<div class="hotel-info">
        	<a href="http://www.hotelpeeps.com/vienna/senator-hotel/30687" target="_blank" title="Senator, Vienna&#13;Checkin: 23.12.2011, 4 Nights"></a><br />
        	<span class="hotel-name">Senator, Vienna<br /><span>Checkin: 23.12.2011, 4 Nights</span></span><br />
            <span class="stars3">&nbsp;</span>
        </div>
<div class="hotelpeeps-price">238<br /><span>EUR</span></div>
<div class="booking-price">321<br /><span>EUR</span></div>
<div class="hotels-price">268<br /><span>eur</span></div>
</p></div>
<div class="row">
<div class="hotel-info">
        	<a href="http://www.hotelpeeps.com/budapest/hilton-westend/12317" target="_blank" title="Hilton WestEnd, Budapest&#13;Checkin: 29.12.2011, 5 Nights"></a><br />
        	<span class="hotel-name">Hilton WestEnd, Budapest<br /><span>Checkin: 29.12.2011, 5 Nights</span></span><br />
            <span class="stars5">&nbsp;</span>
        </div>
<div class="hotelpeeps-price">472<br /><span>EUR</span></div>
<div class="booking-price">576<br /><span>EUR</span></div>
<div class="hotels-price">551<br /><span>eur</span></div>
</p></div>
</div>
<p style="font-size:12px; padding:0px 10px; font-style:italic;">These offers are available for November, 29th. All prices are subject to availability or change without notice.</p>
<div class="clear" style="height:20px;"></div>
<h2>Price Trends &#038; Special Deals</h2>
<p>One of the main features of <a href="http://hotelpeeps.com" target="_blank">HotelPeeps.com</a> is Price Trends – a chart that allows you to keep an eye on some of the most popular destinations and the market trends. By checking the Price Trends for your favourite city, you can actually see when the prices are low or shift departure dates a bit, in order to save up for your next trip.<br />
<br />
Moreover, you can check the Special Deals for more then 50 destinations, and save up to 75%! What HotelPeeps.com does is to detect high price variation compared to the hotel market and mark these variations as Special Deal. So basically you get more quality for the same budget.<br />
</p>
<p style="text-align:left;">For example, here&#8217;s how the Prague Special Deals look like: <a href="http://www.hotelpeeps.com/prague/923" target="_blank">http://www.hotelpeeps.com/prague/923</a> (click on the Show Price Trends button to see the chart).</p>
<p></p>
<p style="text-align:left;">I know you&#8217;re probably dying to check upon your favourite destination, so I&#8217;ll just add one more thing: you can find the HotelPeeps site available in <a href="http://www.hotelpeeps.com" target="_blank">English</a>, <a href="http://www.hotelpeeps.ru" target="_blank">Russian</a> and <a href="http://www.hotelpeeps.ro" target="_blank">Romanian</a>, on <a href="http://www.facebook.com/HotelPeeps" target="_blank">Facebook</a> or on <a href="http://twitter.com/hotelpeeps" target="_blank">Twitter</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2011/12/how-to-find-a-really-special-deal-for-this-winter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2011/12/how-to-find-a-really-special-deal-for-this-winter/</feedburner:origLink></item>
		<item>
		<title>Parallel processing with PHP and Gearman</title>
		<link>http://feedproxy.google.com/~r/ZitecBlog/~3/3omXA4xYh2A/</link>
		<comments>http://blog.zitec.com/2011/11/parallel-processing-with-php-and-gearman/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 21:51:55 +0000</pubDate>
		<dc:creator>Ionut VODA, CTO,</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.zitec.com/?p=655</guid>
		<description><![CDATA[Some background first Often you come to a point where you need to process data in a non-blocking fashion and in multiple threads at once. A solution for doing this is Gearman that we also used in one of our recent projects. This specific project contains a collection of RSS feeds (a few thousand items) that [...]]]></description>
			<content:encoded><![CDATA[<h2>Some background first</h2>
<p>Often you come to a point where you need to process data in a non-blocking fashion and in multiple threads at once. A solution for doing this is <a title="Gearman" href="http://gearman.org/">Gearman</a> that we also used in one of our recent projects.</p>
<p>This specific project contains a collection of RSS feeds (a few thousand items) that need to be permanently pulled by specific rules. Each time new content is detected in a feed, one or more callback URLs need to be fired. A great part of the RSS items have to be checked every 5 minutes.</p>
<p>The first solution and the fastest, would be to set-up a <a href="http://ro.wikipedia.org/wiki/Cron" target="_blank">cron</a> to run every 1 minute to scan the items against the time rules and fetch them sequentially. While this approach seems to be the winner it has a couple of drawbacks, out of which I&#8217;ll mention these two:</p>
<ol>
<li>If one of the feeds gets into a network congestion the script will block, a new one will be started a minute later (by the cron tab) and you will end-up with a lot of zombie PHP processes</li>
<li>Scaling. With a single script that checks each feed at a time, you cannot scale.</li>
</ol>
<p>So, we went to Gearman.</p>
<h2>But what is Gearman ?</h2>
<p>Gearman is a framework that provides parallel data processing and load balancing between processes. It comes with implementations for various programming languages, <a title="PHP Gearman" href="http://php.net/manual/en/book.gearman.php" target="_blank">including PHP</a>. Gearman operates with 3 basic concepts:</p>
<ol>
<li><strong>The Client</strong> &#8211; the part where the processing requests are issued &#8211; this can be a PHP script for instance</li>
<li><strong>The Job Server</strong> &#8211; this is where the magic happens: it receives requests from clients and dispatch them to registered workers in a load balanced fashion</li>
<li><strong>The Worker</strong> &#8211; the part of the system that actually process a job &#8211; one or more PHP scripts</li>
</ol>
<div>The main advantage of this architecture is in fact that the components are totally decoupled which allows you to run each of it on separate machines. You can have multiple clients, multiple worker scripts and, why not, multiple job servers. The diagram below shows how the client, the job server and the worker scripts interact:</div>
<div><img class="alignnone size-full wp-image-898" title="gearman diagram" src="http://blog.zitec.com/wp-content/uploads/2011/11/gearman-diagram.png" alt="" width="460" height="178" /></div>
<h2></h2>
<h2>Putting it all together</h2>
<p>Back to our project. We have the RSS feeds stored in a MySQL table. Each feed has a time rule when it needs to be pulled. A cron runs every 5 minutes and decides what feeds need to be pulled.</p>
<p>The feeds that need to fetched are sent one by one to the job server in a non-blocking manner. This way you achieve a better throughput than having the cron to check the feed. Below is is the client part of the Gearman:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$feeds</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Feeds<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//retrieve the feeds from the table</span>
<span style="color: #000088;">$feeds_list</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$feeds</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAllForUpdate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// set-up the client by connecting to a server</span>
<span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GearmanClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addServer</span><span style="color: #009900;">&#40;</span>GEARMAN_SERVER<span style="color: #339933;">,</span> GEARMAN_PORT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$feeds_list</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$feed_info</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addTaskBackground</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'process_feed'</span><span style="color: #339933;">,</span> <span style="color: #990000;">serialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$feed_info</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">runTasks</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p lang="php">The worker script is daemonized with <a title="SupervisorD" href="http://supervisord.org/" target="_blank">SupervisorD</a>. SupevisorD is a process control system that takes care of maintaining the desired number of processes for a given script, in our case the worker. A good practice is to start as many worker scripts as the number of processor cores available on the system.</p>
<p lang="php">This is how we&#8217;ve configured SupervisorD to meet our needs:</p>
<pre>[program:feedworker]
process_name=%(process_num)s
command=php worker.php
numprocs=12
directory=/var/local/gearman
autostart=true
autorestart=true</pre>
<p lang="php">The worker script that actually handles the feed processing looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$worker</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GearmanWorker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$worker</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addServer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Register the same function we invoked on the client</span>
<span style="color: #000088;">$worker</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addFunction</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;process_feed&quot;</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$_job</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">unserialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">workload</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #666666; font-style: italic;">// delegate to a specialized class to process the feed</span>
	<span style="color: #000088;">$feed</span> <span style="color: #339933;">=</span> FeedProcessor<span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$feed</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">work</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// keep an infinite loop so the script won't die</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$worker</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">work</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2 lang="php">The set-up</h2>
<p>Our current set-up, which runs on <a title="Amazon Web Services" href="http://aws.amazon.com/" target="_blank">AWS</a>, consists in a machine that runs the  client script and the Gearman server and another machine that runs the worker scripts. The worker scripts machine is part of a scalable set-up so the system can automatically spin up more machines when the processing demand increase.</p>
<p>Before adding Gearman to our set-up we were able to process ~52 feeds/minute with a single php script. The things totally changed with Gearman when we achieved a ~154 feeds/minute processing ratio. Both the single php script and the Gearman workers scripts were tested on the same machine, with the only change that the later was in fact multiplexed in 10 worker processes instead of a single one.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zitec.com/2011/11/parallel-processing-with-php-and-gearman/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.zitec.com/2011/11/parallel-processing-with-php-and-gearman/</feedburner:origLink></item>
	</channel>
</rss>

