<?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>Deep Shift Labs Development Blog</title>
	
	<link>http://www.deepshiftlabs.com/dev_blog</link>
	<description />
	<lastBuildDate>Sat, 18 May 2013 09:59:14 +0000</lastBuildDate>
	<language>en-us</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DeepShiftLabsDevelopmentBlog" /><feedburner:info uri="deepshiftlabsdevelopmentblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>DeepShiftLabsDevelopmentBlog</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Tricky sorting technique in MySQL</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/-3c8Chx-Zbw/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2245&amp;lang=en-us#comments</comments>
		<pubDate>Fri, 17 May 2013 09:31:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2245</guid>
		<description><![CDATA[Recently, I faced an interesting challenge and I want to share my solution with the readers using a simple example. Suppose we have a list of TODO items. Each entry in the list may have a due date, the priority and creation date. Now, suppose that you need to get the records from the database, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/mauro_orlando/4886191611/"><img src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/05/logo.jpg" alt="" title="Order and disorder" width="300" height="200" class="alignleft size-full wp-image-2252" /></a>Recently, I faced an interesting challenge and I want to share my solution with the readers using a simple example. Suppose we have a list of TODO items. Each entry in the list may have a due date, the priority and creation date.</p>
<p>Now, suppose that you need to get the records from the database, sorted this way – first, show records with due date in ascending order, second, show records with no due date ordered by priority from higher to lower, and finally, show records that do not have due date and priority and sort them by date created. The first thing that comes to mind is to write this query:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code9'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p22459"><td class="code" id="p2245code9"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> todo <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">...</span> <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> due_date <span style="color: #993333; font-weight: bold;">asc</span><span style="color: #66cc66;">,</span> priority <span style="color: #993333; font-weight: bold;">desc</span><span style="color: #66cc66;">,</span> create_date <span style="color: #993333; font-weight: bold;">asc</span></pre></td></tr></table></div>

<p>It would seem that&#8217;s all, the problem is solved, but there&#8217;s a catch &#8211; the first field (due_date) is not compulsory and that&#8217;s what we get as a result of this query:<br />
<br /><a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/05/simple_order.png"><img src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/05/simple_order.png" alt="" title="Simple order results" width="530" height="166" class="aligncenter size-full wp-image-2247" /></a><span id="more-2245"></span><br />
As you can see we have first records with no due date, but we wanted to show records with most recent due dates first. Obviously reversing sorting order from ASC to DESC will not help. Usually in such cases, a UNION of two SELECT queries is used. In the first query we select only the records with the due date, in the second &#8211; on the contrary, only the records with no due date. Something like this:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code10'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p224510"><td class="code" id="p2245code10"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> todo <span style="color: #993333; font-weight: bold;">WHERE</span> due_date <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">...</span> <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> due_date <span style="color: #993333; font-weight: bold;">asc</span>
<span style="color: #993333; font-weight: bold;">UNION</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> todo <span style="color: #993333; font-weight: bold;">WHERE</span> due_date <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">...</span> <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> priority <span style="color: #993333; font-weight: bold;">desc</span><span style="color: #66cc66;">,</span> create_date <span style="color: #993333; font-weight: bold;">asc</span></pre></td></tr></table></div>

<p>Does everyone agree with this solution? Don’t you want to look at it one more time? Okay, I’ll put you out of your misery; the query does not work for the simple reason that when you use ORDER BY with UNION it is applied to all records in a result set. In this case, you might say, UNION does not solve our problem, because the result would be no different from the first query and you will be right. However, UNION does gives us the ability to change the result in a simple way. What didn’t we like in the first query? The fact that the records without a due date were at the beginning. Besides, why did they go to the top? Because we sorted in ascending order by column allowing NULLs, and according to <a href="http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html" target="_blank">documentation</a> NULL values are presented first if you do ORDER BY. What should you do to move these records to the bottom? That’s right, to make sure that we use some other very big value instead of NULL. According to the <a href="http://dev.mysql.com/doc/refman/5.5/en/datetime.html" target="_blank">manual</a> the maximum value of the datetime field is &#8217;9999-12-31 23:59:59&#8242;, which we will use. We now have the following query</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code11'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p224511"><td class="code" id="p2245code11"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> priority<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">,</span> due_date<span style="color: #66cc66;">,</span> due_date <span style="color: #993333; font-weight: bold;">AS</span> sort_due_date<span style="color: #66cc66;">,</span> create_date <span style="color: #993333; font-weight: bold;">FROM</span> todo
<span style="color: #993333; font-weight: bold;">WHERE</span> due_date <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">...</span>
<span style="color: #993333; font-weight: bold;">UNION</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> priority<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">,</span> due_date<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'9999-12-31 23:59:59'</span> <span style="color: #993333; font-weight: bold;">AS</span> sort_due_date<span style="color: #66cc66;">,</span> create_date <span style="color: #993333; font-weight: bold;">FROM</span> todo
<span style="color: #993333; font-weight: bold;">WHERE</span> due_date <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">...</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> sort_due_date <span style="color: #993333; font-weight: bold;">ASC</span><span style="color: #66cc66;">,</span> priority <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">,</span> create_date <span style="color: #993333; font-weight: bold;">ASC</span></pre></td></tr></table></div>

<p>and the result looks like this:<br />
<br /><a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/05/union_order_column.png"><img src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/05/union_order_column.png" alt="" title="Union results" width="694" height="166" class="aligncenter size-full wp-image-2250" /></a><br />
This query keeps the original due_date column intact, and sorting is performed by using the synthetic column &#8216;sort_due_date&#8217;. We need this in order not to distort the real data, we do not want to confuse ourselves and show the user the date of the end of the (MySQL) world? The problem is solved. I don’t know about you, but I love the elegant solutions, and this solution is definitely not elegant. Do you want to know what the elegant version of the solution is? Then read on.<br />
<br />In the last few months, we have been working with CodeIgniter and previously we worked mostly with ZendFramework. So, in CI and ZF, and in many other frameworks the ActiveRecord pattern is widely used. This means that the first SQL query we wrote is created this way:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code12'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p224512"><td class="code" id="p2245code12"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">select</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'priority, description, due_date, create_date'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">from</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'todo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">...</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">order_by</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'due_date asc, priority desc, create_date asc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And yet, I have not found the capabilities in CI to build UNION queries using this pattern. If you know how, I would appreciate your input. If a WHERE clause in the query is simple, in principle, we can form the first request and compile it. Then we can create the second request using the same method and compile it, and finally connect them with UNION manually and run it. Often, however, the conditions in the query are formed depending on the parameters passed, and the logic can be quite daunting. As a result, we get a strong code duplication. However, there are no hopeless situations, and here a very handy feature of MySQL helps us &#8211; the use of conditional logic in the ORDER BY construction. It works as follows:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code13'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p224513"><td class="code" id="p2245code13"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> priority<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">,</span> due_date<span style="color: #66cc66;">,</span> create_date
<span style="color: #993333; font-weight: bold;">FROM</span> todo <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">...</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> IFNULL<span style="color: #66cc66;">&#40;</span>due_date<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'9999-12-31 23:59:59'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ASC</span><span style="color: #66cc66;">,</span> priority <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">,</span> create_date <span style="color: #993333; font-weight: bold;">ASC</span></pre></td></tr></table></div>

<p>That&#8217;s what I call an elegant solution! Those who disagree with me please write in the comments, I will remove them anyway <img src='http://www.deepshiftlabs.com/dev_blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . We do not duplicate the code because we have one request. We just need the right way to create ORDER BY conditions. Unfortunately CI has some problems with it. If you try (and I have tried, no doubt) to set sorting using Active Record this way:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code14'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p224514"><td class="code" id="p2245code14"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">order_by</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;IFNULL(due_date, '9999-12-31 23:59:59') ASC, priority DESC, create_date ASC&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Then you, like me, will be disappointed. The super smart framework will split the passed string and will surround the first word with the quotation marks. As a result, a request will be completed with an error. By the way, if anyone knows how to ask CI not to do it, please let me know. Finally, we are left with the only workaround – to add an order condition to a query without using the Active Record, ie manually. Yes, it violates our beautiful code a little, but in my opinion, it is a lesser evil. I did it like this:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code15'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p224515"><td class="code" id="p2245code15"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">select</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'priority, description, due_date, create_date'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">from</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'todo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">...</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span>_compile_select<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$sql</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">&quot; ORDER BY IFNULL(due_date, '9999-12-31 23:59:59') ASC, priority DESC, create_date ASC&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db_app</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">result_array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>The attentive reader will notice one inconsistency here &#8211; the method is called _compile_select(), defined in the class CI_DB_active_record as protected. I confess, though I do not like to change the code of any good framework, but I saw no other way to generate a query without executing it but to make this method public. Again – let us know how to do it better. That’s it – we shared what we learned and are looking forward to your comments.<br />
<br />Finally, a little note. Column&#8217;s due_date default values is NULL, in our example. However this is not always the case and sometimes you can find, for example, &#8217;0000-00-00&#8242; as a default value. How to form ORDER BY statement in this case? You can use CASE expression this way:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2245code16'); return false;">View Code</a> SQL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p224516"><td class="code" id="p2245code16"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> priority<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">,</span> due_date<span style="color: #66cc66;">,</span> create_date
<span style="color: #993333; font-weight: bold;">FROM</span> todo <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">...</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span>
  CASE WHEN due_date <span style="color: #66cc66;">=</span><span style="color: #ff0000;">'0000-00-00'</span> THEN <span style="color: #ff0000;">'9999-12-31 23:59:59'</span>
    ELSE due_date
  END <span style="color: #993333; font-weight: bold;">ASC</span><span style="color: #66cc66;">,</span> priority <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">,</span> create_date <span style="color: #993333; font-weight: bold;">ASC</span></pre></td></tr></table></div>

<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/-3c8Chx-Zbw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2245&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2245&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>Grow file system on Fedora on VMWare</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/9ZiU4gedr3o/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2235&amp;lang=en-us#comments</comments>
		<pubDate>Thu, 25 Apr 2013 06:01:43 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2235</guid>
		<description><![CDATA[In this post I would like to show how to increase file system space on installed Fedora VMWare instance. You might need it if you use VMWare (and we know many people do) to spin VMs for Selenium testing. In this particular case I use I installed Fedora and allocated 10GB but later I started [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I would like to show how to increase file system space on installed Fedora VMWare instance. You might need it if you use VMWare (and we know many people do) to spin VMs for Selenium testing.</p>
<p>In this particular case I use I installed Fedora and allocated 10GB but later I started using this VM for quite large databases and free space quickly disappeared.</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2235code22'); return false;">View Code</a> SH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p223522"><td class="code" id="p2235code22"><pre class="sh" style="font-family:monospace;"># df -k
Filesystem                    1K-blocks    Used Available Use% Mounted on
devtmpfs                         498132       0    498132   0% /dev
tmpfs                            508060       0    508060   0% /dev/shm
tmpfs                            508060     772    507288   1% /run
/dev/mapper/vg_fedora-lv_root   7641992 6590912    656228  91% /
tmpfs                            508060       0    508060   0% /sys/fs/cgroup
tmpfs                            508060       0    508060   0% /media
/dev/sda1                        487652   84379    377673  19% /boot</pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2235code23'); return false;">View Code</a> SH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p223523"><td class="code" id="p2235code23"><pre class="sh" style="font-family:monospace;"># fdisk -l
&nbsp;
Disk /dev/sda: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000e3a8c
&nbsp;
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     1026047      512000   83  Linux
/dev/sda2         1026048    20971519     9972736   8e  Linux LVM
&nbsp;
&nbsp;
Disk /dev/mapper/vg_fedora-lv_swap: 2113 MB, 2113929216 bytes
255 heads, 63 sectors/track, 257 cylinders, total 4128768 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
&nbsp;
&nbsp;
Disk /dev/mapper/vg_fedora-lv_root: 8086 MB, 8086618112 bytes
255 heads, 63 sectors/track, 983 cylinders, total 15794176 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes</pre></td></tr></table></div>

<p>To grow disk space I went to VMWare console and added one more disk as shown below:<br />
&nbsp;<br />
&nbsp;<br />
<img class="aligncenter" style="-ms-interpolation-mode: bicubic;" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/04/adding_disk_vm_vmware.png" alt="Adding a disk to existing VMWare VM" title="Adding a disk to existing VMWare VM" /><br />
&nbsp;<br />
&nbsp;<br />
Now we can see a new disk in &#8220;fdisk -l&#8221; command output.</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2235code24'); return false;">View Code</a> SH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p223524"><td class="code" id="p2235code24"><pre class="sh" style="font-family:monospace;">Disk /dev/sdb: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes</pre></td></tr></table></div>

<p>Now we create partition sdb1 covering all new disk using &#8220;fdisk /dev/sdb&#8221;.</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2235code25'); return false;">View Code</a> SH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p223525"><td class="code" id="p2235code25"><pre class="sh" style="font-family:monospace;">Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p):
Using default response p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-41943039, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039):
Using default value 41943039
Partition 1 of type Linux and of size 20 GiB is set
&nbsp;
Command (m for help): v
Remaining 2047 unallocated 512-byte sectors
&nbsp;
Command (m for help): w
The partition table has been altered!</pre></td></tr></table></div>

<p>Finally we just expand our volume group and file system:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p2235code26'); return false;">View Code</a> SH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p223526"><td class="code" id="p2235code26"><pre class="sh" style="font-family:monospace;">pvcreate /dev/sdb1
vgextend vg_fedora /dev/sdb1
lvextend -l +100%FREE /dev/mapper/vg_fedora-lv_root
resize2fs /dev/mapper/vg_fedora-lv_root</pre></td></tr></table></div>


<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/9ZiU4gedr3o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2235&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2235&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>Blogging</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/FH57NutaO1U/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2218&amp;lang=en-us#comments</comments>
		<pubDate>Sat, 23 Mar 2013 08:34:33 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2218</guid>
		<description><![CDATA[Some time ago we translated to Russian &#8216;Marketing by sharing&#8217; talk by Jason Fried at ChicagoConvergence 2009 conference. Today we would like to share how it works for us so far. These are the stats for our two blogs only &#8211; Selenium and Development. Stats for Nerrvana and Startyco are not included. &#160; &#160;]]></description>
			<content:encoded><![CDATA[<p>Some time ago we translated to Russian <a href="http://www.deepshiftlabs.com/dev_blog/?p=1819&#038;lang=en-us" target="_blank">&#8216;Marketing by sharing&#8217;</a> talk by Jason Fried at ChicagoConvergence 2009 conference. Today we would like to share how it works for us so far. These are the stats for our two blogs only &#8211; <a href="http://www.deepshiftlabs.com/sel_blog" target="_blank">Selenium</a> and <a href="http://www.deepshiftlabs.com/dev_blog" target="_blank">Development</a>. Stats for <a href="http://www.nerrvana.com" target="_blank">Nerrvana</a> and <a href="http://www.starty.co" target="_blank">Startyco</a> are not included.<br />
&nbsp;<br />
&nbsp;<br />
<img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Marketing by sharing - how it worked for us" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Deep_Shift_Labs_blogging.jpg" alt="Marketing by sharing - how it worked for us" /></p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/FH57NutaO1U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2218&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2218&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>‘Answers’ – questions &amp; answers portal for your site</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/-fYekNke60Y/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2080&amp;lang=en-us#comments</comments>
		<pubDate>Tue, 19 Mar 2013 12:31:17 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2080</guid>
		<description><![CDATA[Most of all we would not want to turn the Answers announcement into advertising. Instead, we decided to share our thoughts about two kinds of software &#8211; subscription based and the one you can pay for once and own, and specifically about web applications. As a rule, web apps are not to be for personal [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left;"><img class="alignleft size-full wp-image-1752" style="padding: 5px 20px 10px 0;" title="'Answers' - questions &amp; answers portal for your site" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Answers.jpg" alt="'Answers' - questions &amp; answers portal for your site" /></div>
<p>Most of all we would not want to turn the <a href="http://answers.starty.co" target="_blank">Answers</a> announcement into advertising. Instead, we decided to  share our thoughts about two kinds of software &#8211; subscription based and the one you can pay for once and own, and specifically about web applications. As a rule, web apps are not to be for personal use, and to work in peer groups, like school teachers, employees, software developers. Then we actually explain how and why an idea was born to create some <a href="http://www.starty.co" target="_blank">downloadable web applications</a>. You don&#8217;t think we made Answers just because we didn&#8217;t want to use existing SaaS? Excellent! Then tune in to the philosophical mood (pipe, rocking chairs, a fireplace, and Sherlock Holmes nearby are highly recommended).</p>
<p>Because the whole internet world creates web services with monthly subscriptions (with some variations) and sells these services for a lot of money to the end user, we, at Deep Shift Labs, believe that there are still fans out there who like the concept of buying and owning a piece of software. System administrators are not yet extinct, they are the heroes, who are able to maintain the server software without spending hours on it, because they are professionals in their field and as a result are efficient and valuable.<br />
<span id="more-2080"></span><br />
For some strange reason, even the world of traditional desktop applications now also wants to sign you in. <a href="http://www.adobe.com/products/creativesuite.html" target="_bank">Adobe</a> (<a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Adobe.png" target="_bank">picture</a>) and <a href="http://office.microsoft.com/en-au/business/compare-office-for-business-plans-FX102918419.aspx" target="_bank">Microsoft</a> (<a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/microsoft.jpg" target="_bank">picture</a>) offer you to use their products with a monthly payment. Even <a href="http://usa.autodesk.com" target="_bank">AutoDesk</a> (for free, as we understood &#8211; <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Autocad.jpg" target="_bank">the picture</a>) offers to view and edit your drawings in a browser and on mobile devices. Vendors of web applications are moving in the same direction. Products such as <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Kayako_dual.png" target="_bank">Kayako</a>, <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Atlassian_dual.png" target="_bank">Atlassian</a>, and even the smaller, not so well known, open source CMS &#8211; <a href="http://www.squiz.com.au/web-solutions/cloud-hosting" target="_bank">Matrix</a> (<a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/squiz.jpg" target="_bank">picture</a>) are moving to subscription based services.</p>
<p>Time will show how successful these efforts will be. Perhaps, in the near future, we will all become accustomed to the fact that the software is available only by subscription &#8211; by month (subscription), by a user (per seat or named user license), by size (volume license) or their combination. We do not want to believe in it, and even somehow want to resist.</p>
<p>We are not talking about social networks, where they themselves are the product, and exist as a single copy to make sense. We are talking about systems that solve a particular problem; a real problem for your company or your personal one.</p>
<p>The list of web applications which can be purchased and installed is getting smaller and smaller. What types of licenses can we find here? Perpetual &#8211; our <a href="http://answers.starty.co/buy" target="_blank">Answers</a>, as an example &#8211; a one-time payment. For the named account &#8211; Atlassian and Kayako. Recurring revenue in this case is coming from the sale of support and providing access to new versions of the product for a fraction of the full license fee.</p>
<p><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Kayako additional revenue sources" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Kayako.jpg" alt="Kayako additional revenue sources" /></p>
<p style="text-align: center;">Fig. 1 Kayako</p>
<p>If you do not need support and do not care about upgrades, you pay once for a perpetual license. Enterprises do not do that but small businesses and startups can. With per seat licenses, you only pay when you have crossed the threshold of license restrictions (for example, Kayako and Atlassian license registered accounts).</p>
<p align="center"><em>Kayako Resolve<br />
10 staff $599<br />
20 staff $1099</em></p>
<p align="center">Atlassian JIRA<br />
<em>10 users $10<br />
25 users $1,200</em></p>
<p>Splunk gives us an example of volume licensing. &#8220;Splunk Enterprise pricing in North America starts at US $ 6,000 for a 500 megabyte-per-day perpetual license, including first year support, or US $ 2,000 per year for a term license including support.&#8221; Here we see a rather unusual approach of using term licenses &#8211; in essence a subscription for locally installed software. That is, we pay 6K we own Splunk, but only if the volume of logs per day is less than 500MB. When you pay for a subscription, you pay every year, and are also limited to 500MB per day. I think we can find a similar approach amongst the monsters of the server software &#8211; Oracle, Microsoft, SAP.</p>
<p>Furthermore Splunk also promotes <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/splunk.jpg" target="_blank">online service</a> similar to <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/loggly.jpg" target="_blank">Loggly</a>.</p>
<p>Subscription services want to buy clients by giving them an option not to find/buy hardware, install, make updates, do backups. All updates are available immediately to all their users. Let us try to formulate the arguments of those who creates SaaS and those who do not want to buy or purchases subscription based services in the absence of other alternatives?</p>
<p>On the <strong>one side</strong> we have SaaS vendors:</p>
<p>- Cash flow comes regularly every month</p>
<p>- Not too much testing is required &#8211; release, monitor errors and quickly fix them on the server. No patches and updates to ship and headaches to support their rollover.</p>
<p>- Site hacked, passwords stolen, outage &#8211; apologize to users.</p>
<p>- Easy to sell the business. If the new owner will break the product, or close it; what will the end users do? God be with them. Here are just a few services we accidentally found while writing this post &#8211; <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Snip.it_closed.png" target="_blank">Snip.it</a>, <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Connotea_closed.png" target="_blank">Connotea</a>, <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Qualaroo_closed.jpg" target="_blank">Qualaroo</a>.</p>
<p>- Decide to raise prices or change plans – no problem. </p>
<p>- Remove some features and added another ones &#8211; well &#8230; some clients will be upset, some will even leave. The main idea is that more should come.</p>
<p>- Want to use your data? Learn our API and get what we provide and in the way we provide it. There are a few services which allow you to walk away with your own data. When such option is available &#8211; it is often AWS S3 bucket. Is this the only place where you can store the data now? Here are some examples &#8211; <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Loggly_export_AWS.jpg" target="_blank">Loggly</a> and <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Kissmetrics_export_AWS.jpg" target="_blank">Kissmetrics</a>. In both cases we are talking about the log files. We found these SaaS companies which provide data export &#8211; <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/DeployHQ.jpg" target="_blank">DeployHQ</a> and <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Sifter_export.jpg" target="_blank">Sifter</a>. Did you meet SaaS companies who providing database dump? Tell us in the comments.</p>
<p>- Do you have more traffic, customers, and employees? Excellent &#8211; you need another subscription plan. Yes &#8211; it is more expensive as this is our pricing model. That is, the additional resources that are often worthless are now used as an argument for a greater payment. In fact, you are already using their service, your data is already out there in a strange format and the cost to go to another service/product is significant. Argument is – you use it more – you have to be able to pay more. The real situation does not bother anyone.</p>
<p>- You can sell the impersonal data (<a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Kissmetrics_case.png" target="_blank"> or not</a>) that only you possess &#8211; the owners of the service, or use them to add functionality in the premium subscriptions. That is, data is created collectively by all users and sold back to them.</p>
<p>On <strong>the other hand</strong> the position of those who want to buy and install web applications:</p>
<p>- I want to buy a web app and own it. I see a fixed price and its functionality suits me as is. The purchased product becomes an asset of the company, not an expense.</p>
<p>- If the price depends on the number of users &#8211; not a problem. When, for example, the help desk department will have not 2 people, but 22, I am happy to pay the additional license cost as it is a one-time fee again.</p>
<p>- If an update is released and I need it &#8211; I can upgrade to it, or even pay 30-50% of the initial price.</p>
<p>- Do not worry that something you desperately need will disappear from a service you use, and something that is not necessary will pop up. You are in control and you decide to upgrade or not.</p>
<p>- My company has a system administrator, and he can install all correctly, make sure all is secure and set a  backup. Or … my company is serviced by an on-call system administrator. The same system administrator knows how to provide continuity of critical applications you need &#8211; raid, failover cluster. Here&#8217;s an example &#8211; <a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/web_service_in_action.jpg" target="_blank">Kissmetrics</a>Kissmetrics</a> at the time I wrote this post (possibly analytics collection service worked). Guys from <a href="http://renderedtext.com/blog/2012/08/03/why-we-moved-away-from-heroku/" target="_blank">SemaphoreApp</a> (<a href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/03/Semaphore_Heroku.png" target="_blank">picture</a>) &#8211; are still happy to run client sites in Heroku, but migrated their service elsewhere. With their application it is not a problem. The problem is when you cannot pick up your stuff and go, because your data is in this particular application, and businesses cannot wait until you get the data from one provider and find a way to import them to another without loss. It is virtually impossible, and therefore makes you dependent on your provider.<br />
See <a href="https://www.scriptrock.com/blog/top-5-configuration-errors-in-the-cloud-for-2012/" target="_blank">ScriptRock&#8217;s</a> blog post &#8211; disruptions in 2012 at AWS, Azure, Skype, Google &#8211; companies with multi-million dollar budgets and thousands of employees. More recently in 2013 &#8211; <a href="http://techcrunch.com/2013/01/08/another-major-github-outage-this-is-not-good-for-its-100m-enterprise-push/" target="_blank">GitHub</a> and <a href="http://techcrunch.com/2013/03/12/microsoft-is-currently-experiencing-hotmail-outlook-and-skydrive-service-disruptions/" target="_blank">Office 365 with Outlook.com</a>. People already calling it Office 364 after this incident.  </p>
<p>- All the data is in my database &#8211; you can do any reports, integrate with other applications &#8211; no restrictions.</p>
<p>- Even if a vendor of the system does not promise to supply the source code in the event of business cessation, for some reason, we can always continue to use our web application. When you need to convert data into another application, if it is also not a web service, it is not a problem, because we have access to both databases. If the source code was not protected &#8211; even better, because we can make changes and possibly avoid migration to a new vendor.</p>
<p>Of course, there are SaaS that charge for usage. We pay Skype $16, use it and if we do not want to use Skype we will simply not pay any more. By the same principle, we created Nerrvana &#8211; no monthly subscription plans. We do not know how much testing time we will need this month and how much in the next, and so we assume that you do not know too. You can buy $50 worth of credit and use it in 3 days or 3 months. When it runs out &#8211; buy more credit or set up auto-recharge. Tests Nerrvana runs do not require major changes, which means you are free to leave at any time. There&#8217;s nothing holding you, and you do not pay for what you do not use. Both, Skype and our <a href="http://www.nerrvana.com/pricing" target="_blank">Nerrvana</a> &#8211; SaaS. It is almost impossible to assume that you can buy, install and maintain such services yourself. They are both quite easy to replace if you are a business relying on them too. Project management, analytics, technical support systems, bug trackers, feedback collection, questions and answers portals – completely different. All of these systems can be downloadable and installable products.</p>
<p>Of course, if the company does not employ a system administrator, but needs a web service to operate and it is so good that you are willing to pay for it every month for as long as you will use it there is no alternative to SaaS. Somehow, it turned out that most companies do use them, and it is sad.</p>
<p>As you understand &#8211; we are primarily talking about things which lock you in and are hard to pick up and move. Moving a server from AWS is easier than an accounting system. If your site is for geeks, a simple loss of data will not be as critical as if you are tight with strict SLA with your clients and the clients may ask you to compensate for their losses.</p>
<p>As Steve Wozniak said: &#8220;With the cloud, you don&#8217;t own anything. You already signed it away. I want to feel that I own things. A lot of people feel, &#8216;Oh, everything is really on my computer&#8217;, but I say the more we transfer everything onto the web, onto the cloud, the less we&#8217;re going to have control over it.&#8221;</p>
<p>To summarize we would like to wish:</p>
<p>- SaaS vendors to adopt a standard of providing data export. Not API but the bulk data dump. It seems to us that the export must be in some kind of universal format, for example, XML. It can quite easily be imported into any modern database. We found a few good examples and it would be great if this approach will evolve into a standard for SaaS solutions.</p>
<p>- Downloadable web application vendors to ensure the provision of source code in the event of business termination or closure of the company or a change in business. Unfortunately it is hard to get going since there is no organization promoting this approach, which vendors can just mention they support. No one wants to sound pessimistic.</p>
<p>This will benefit customers but such openness is not yet achieved.</p>
<p>You can douse the fire and tell Sherlock Holmes to go clean his pipe – we finished our philosophical part and now further explain the idea of Startyco, where Answers is a first product.</p>
<p>So, when we were working on Nerrvana, being about half way in 2010, and not obviously knowing that it is only the middle, we wanted to make it easy for our users to collaborate and talk to us. We needed to find out what else we will need for our future users. By that time, we were well aware of the systems we needed, and wrote a series of articles &#8211; <a href="(http://www.deepshiftlabs.com/dev_blog/?p=42&amp;lang=en-us" target="_blank">&#8220;Own Web analytics for startups&#8221;</a> (the timestamp proves my point – 2010. We started building Nerrvana in 2008 and finished in 2012).</p>
<p>It was already clear that in addition to your product or service you at least need a marketing site, and then depending on the focus of your business, you&#8217;ll use a combination of the following systems &#8211; a blog (example WordPress), forums (example phpBB), customer support (example ZenDesk), ideas (example GetSatisfaction), questions/answers (example StackOverflow). Each company will use some combination of these systems, if you want your users to feel comfortable and important. It is true that in our articles we talked about web analytics only. It seemed to us, that it is impossible to obtain all the necessary data without integrating these systems and having access to the web analytics log files. Now we can say that our opinion has not changed. Log files access can be provided only by installing such systems on a server you can control. With SaaS solutions you do not have access to log files and even more – you cannot change the format, even if the logs will be provided to you. As a rule, you can add Google Analytics, which you cannot use to track individual visitors. It is even more complex when you use many different SaaS. In order to have a single session you not only need all systems to be on the same server but they should be pluggable. They should become a part of your system.</p>
<p>Logged in Nerrvana users can post feedback or answer questions, even view their own tickets in support system &#8211; no more registrations and separate logins. If it is not a Nerrvana user but just a visitor, it is natural to authorize via Twitter or GitHub. Such a visitor may, for example, ask a question on the Q &#038; A site. That is, clients can do everything, visitors &#8211; not everything, and with the authorization through the social networks via oAuth, but still without registration.</p>
<p>We will illustrate our point with an example. Visitor (a person who does not have access to our application &#8211; <a href="http://www.nerrvana.com" target="_blank">www.nerrvana.com</a>) may write an email to our support. Then, if he wants, he will visit the Answers (<a href="http://answers.nerrvana.com" target="_blank">answers.nerrvana.com</a>) and login via Twitter. If he used the same browser, it will allow us to relate its mailing address with his Twitter’s name. That is, in fact, the information is collected about all visitors and is stored in a single table in the database. For example, access for visitors and users can be expressed this way:</p>
<table>
<tbody>
<tr>
<td><strong>Component</strong></td>
<td><strong>Client</strong></td>
<td><strong>Visitor</strong></td>
</tr>
<tr>
<td>Nerrvana</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Answers</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Feedback/Ideas</td>
<td>Yes</td>
<td>Read only</td>
</tr>
<tr>
<td>Support</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Forum</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Blog</td>
<td>Yes</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<p>When a visitor registers in Nerrvana, his access is expanding, but we already know from where a user came from, what questions he or she asked using their Twitter or GitHub account. There is much more opportunity for analysis and, as a result, there is a chance to provide a better and more customized service to a particular client.</p>
<p>At first we went the simple way. We used our free time and realized that Ideas and Questions/Answers can be implemented inside the forum (we took phpBB). Then there will be only one step to integrate phpBB with Nerrvana. But if you see the admin panel in phpBB, you will realize that its integration with anything else is possible, but it will be a half-measure. It is too complex for what we need. We managed to implement two special types of forums in phpBB (type is specified when you create a new forum in the admin UI). One type &#8211; Ideas, the other &#8211; Questions and Answers. In Ideas forum, users can vote up or down, and leave comments. Each forum’s topic is a new idea. The administrator can set the status of the ideas – completed, in progress, duplicate, rejected. In Q/A forum each topic is a question and the posts in the topic are the answers. A person who posted a question (the questioner) can mark one of the posts as the answer. Voting for answers as in StackExchange is not implemented as we wanted to keep it simple. Finally we decided not to launch the Ideas and Questions/Answers in phpBB. It happened because we understood that it will be hard to support and customise.</p>
<p>We also postponed the blog and forum integration, as we had to create a forum and a blog that would be visited first. This is a task much more difficult than integration. The idea of a blog and a forum integration was that Nerrvana’s authorized users can comment in the blog without re-entering email. New blog posts will create a topic in the forum. Forum comments in this thread created automatically when a blog post is published will be visible in the blog on one side and the comments under the blog post will be visible in the forum. A year later, we saw a <a href="http://wordpress.org/extend/plugins/vanilla-forums/" target="_blank">similar integration</a> with WordPress in VanillaForums.</p>
<p>Around the same time, we needed to install a help desk system to support our big client in Australia. It was clear that we needed a single system to support clients for projects we do and for our own products we were going to launch. We published our requirements in a <a href="http://www.deepshiftlabs.com/dev_blog/?p=1398&amp;lang=en-us" target="_blank">separate blog post</a>. We looked at ZenDesk with &#8220;Multi-brand management&#8221;. To make a few portals for different products would cost us $99 a month for a single agent (the agent &#8211; the one who responds to requests from clients). We have four team members. Count yourself. 400$ per month. But even with this price tag we will end up with &#8220;Remote authentication/SSO&#8221; &#8211; users will log in with Nerrvana credentials, but they still need to enter a user name and password. We will not have access to web logs for our analytics as ZenDesk does not provide them and all the data is in their database. I will not repeat myself again; same problems. Finally we settled with Kayako as nothing better was found. It took a long time to set and customise, a lot of bugs, not built for easy integration &#8211; the user has access to the profile page in Kayako and can change the mailbox and password. There is a SSO option but how would you serve potential Nerrvana users who do not have a Nerrvana account yet? For some reason, every company considers its system to be in the center and do not even think that it can be made pluggable into another higher-level system. We <a href="http://www.deepshiftlabs.com/dev_blog/?p=1564&amp;lang=en-us" target="_blank">managed</a> to work around some problems, but again, the situation is painfully reminiscent of our attempts to integrate with phpBB.</p>
<p>Thus, our dissatisfaction with the existing state of affairs (as often happens) prompted us to create Startyco &#8211; a family of products that are not intended to be dominant, and were originally designed so that they can be easily integrated into your main application. That is, you select only those Startyco components, which are needed and plug them in one hour. Put custom styles so that the applications stylistically become a part of your main application and forget about it. That is &#8211; purchase, install, integrate and enjoy. Customers are happy, you do not waste time searching for solutions and integrations. Clients do not authenticate ten times, actively ask questions or talk to each other; the data is in your database. Since Startyco is not open source &#8211; bugs should be <smile> fixed promptly. You decide if you want to upgrade your Startyco products – check the features and if you can have access to free upgrades. Instead of paying 400$ per month for four staff, you  pay 100$ once for as many staff as you need. Startyco Help Desk system, will certainly be the most difficult to implement, and the license will be more expensive than the Answers, but we think that the embedded products can compete with downloadable (Kayako) or services (ZenDesk) for ease of integration, and even functionality.</p>
<p>To fill the gaps between working for clients and creating Nerrvana, we created <a href="http://answers.starty.co" target="_blank">Answers</a>. They do not have all the functionality we wanted but we are actively working on it. We seem to have achieved the ease of embedding. For example – it only took one hour to embed Nerrvana Answers (<a href="http://answers.nerrvana.com" target="_blank">answers.nerrvana.com</a>), including CSS customisation. You can register to Nerrvana, go to Answers and see that you also already have authorised in Answers. You can logout from Nerrvana, go to Answers and click &#8216;login&#8217; &#8211; you will end up on the Nerrvana login page. After authorization in Nerrvana you will be redirected to Answers, because you came from there.</p>
<p>For now Answers can be integrated only when the main application is also written in PHP and if your main product is built with MySQL or PostgreSQL. To test, I integrated the Answers with WordPress (MySQL) and Mantis (using PostgreSQL). Given that I had to integrate with products I haven’t built &#8211; WordPress and Mantis, integration process took not more time when we integrated Answers with Nerrvana. We assume that it will take less than an hour if the development team which built your main site/service will plug Answers in!</p>
<p>In the next version we will add WYSYWIG, to make it possible to have basic formatting, inserting of code snippets into your posts, inline images and attachments. Also in the new version you will be able to set Answers as a standalone application with own registration and authorization. That is, you can simply create a niche questions and answers site, for example, for <a href="http://robowiki.net/" target="_blank">Robocode</a> players, and not worrying that your passion will not be drawn in <a href="http://area51.stackexchange.com/" target="_blank">Area51</a> of StackExchange.</p>
<p>While post was finally finished we actually added three new modes to run your Questions &#038; Answers site. You can now use Answers in four different modes:</p>
<p>- Plug-in (your web app + Answers) </p>
<p>- Plug-in + oAuth (your web app + Answers + participation from visitors logging from social networks)</p>
<p>- Standalone (your niche Q\A site with registrations within)</p>
<p>- Standalone + oAuth (your niche Q\A site with registrations within + participation from visitors logging from social networks)</p>
<p>We will show how it works in a separate post.</p>
<p>Soon after this update we will launch Ideas &#8211; customer feedback/ideas collection or roadmap shaper for your main product or application. Then, quite obviously, we will stop using UserVoice for Nerrvana and other products we will have by then.</p>
<p>Tell us what you think!</p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/-fYekNke60Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2080&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2080&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>Out of touch with the clouds</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/MsqdNvAgeMQ/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2105&amp;lang=en-us#comments</comments>
		<pubDate>Wed, 06 Feb 2013 10:37:13 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2105</guid>
		<description><![CDATA[We decided to translate to English Michail Emel&#8217;yanikov&#8217;s post as we think it brings some importrant questions many people forget to ask. Did you? &#8220;Over the past week, there seem to be more and more articles and notes about cloud computing &#8211; periodical influx of interest to any topic; nothing out of the ordinary. But [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left;"><a href="http://www.flickr.com/photos/hansh/57073969/" target="_blank"><img class="alignleft size-full wp-image-1752" style="padding: 5px 20px 10px 0;" title="Be aware of clouds!" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2013/02/cloud_300.jpg" alt="No pasaran!" /></a></div>
<p>We decided to translate to English Michail Emel&#8217;yanikov&#8217;s post as we think it brings some importrant questions many people forget to ask. Did you?</p>
<p>&#8220;Over the past week, there seem to be more and more articles and notes about cloud computing &#8211; periodical influx of interest to any topic; nothing out of the ordinary. But after reading the latest material, I experienced a little déjà vu. All of this was written a year ago, if not more; worded the same way, and applicable to the same situations. On one hand, purveyors of cloud services try to convince us that their corporate clients are enthusiastically clambering into the clouds. On the other hand – all these years there has not been a single vivid answer to all of the simple, obvious questions. Namely:</p>
<p>1. What happens to the data when its uploaded to the cloud after the completion of any actions specified by the customer (editing, data processing, pressing the Delete key on the user’s computer, working with the cloud’s infrastructure)?<br />
<span id="more-2105"></span></p>
<p>2. How are the access rights of each user maintained in the SaaS/IaaS/PaaS and other *aaS clouds. How was the reliability and safety of these mechanisms guaranteed, and who guaranteed it?</p>
<p>3. What’s with the virtual architecture inside the cloud, attacks on the hypervisor, super-users, and why don’t they just sell our information to our competitors who receive everything on demand right in the same cloud?</p>
<p>4. Who controls the encryption keys used to secure a connection to the cloud? Why isn’t it FSB/BND/Mossad/MI6/CIA (add more as you wish here)?</p>
<p>As you understand, there is practically an infinite amount of questions to be answered, and they are all related to confidentiality. But, as soon as you raise your head to look at those clouds, more questions start to arise. The list grows further:</p>
<p>5. Who exactly is responsible for your data being intact in the cloud? How is this demonstrated?</p>
<p>6. What will you do when you will lose the internet access?</p>
<p>7. What will you do when the provider won’t be able to serve you for one reason or another?</p>
<p>8. What will you do, when your data simply vanishes?</p>
<p>9. What will you do when you decide to find another provider, and migrate to them? How will you transfer your data, if at all?</p>
<p>All these years the cloud services industry has been talking about advantages &#8211; brainwashing the customers and denying us any answers. Instead it presents us with an eclectic brew – the universal description of the great experience and responsibility of the developers, about a large amount of specific security solutions which cannot be described now due to “a lack of time in this interview”. Besides, 95% of such interviews and presentations are marketing tales anyway. They are about the inevitable technological progress and the future of outsourcing everything noncore – nothing to do with the actual questions.</p>
<p>But the absence of answers to all the above listed questions made me return to my own post and presentation, created one year ago.</p>
<p>I found no differences when comparing this how things are happening today. For information technology and informational safety, a year is a large period of time, and if there is no reaction to all of these challenges, but there is noticeable growth in aggressive marketing, it is no accident. And I, as a security consultant, have a new question for cloud service providers. How and where customers can see security log events associated with their specific data? Do they have them? And what about targeted attacks, with all new Stuxnet, Flame, Gauss? Clouds are more appealing for hackers than individual sites.</p>
<p>Until these questions are not only answered, but also become a part of the contracts with providers &#8211; public clouds will mostly be used for consumer services like social networks, email, file and photo sharing. As for examples of international corporations who already migrated their IT infrastructure (names, for obvious reasons, are not disclosed by providers), we will have to believe the cloud companies statements. I used ‘public’ cloud term, because I still cannot get the difference between a private cloud and an ordinary commercial data center. I have never heard a distinct explanation describing the differences between them. Well, except for the system of payment for services provided, of course.&#8221;</p>
<p><em>Michail Emel&#8217;yanikov</em></p>
<p><a href="http://emeliyannikov.blogspot.ru/2012/08/blog-post_3317.html" target="_blank">Link</a> to an original post in Russian<br />
</p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/MsqdNvAgeMQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2105&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2105&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>How Ideas are different from Answers</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/5QEP1Ej5pLc/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2033&amp;lang=en-us#comments</comments>
		<pubDate>Tue, 02 Oct 2012 02:46:54 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2033</guid>
		<description><![CDATA[In our new product – Ideas, users will be able to vote for a published idea only. In Answers we called responses &#8211; answers; in Ideas we call responses &#8211; comments. Users can comment on an original idea to improve or discuss things with the idea’s contributor. Also users can like/dislike other users’ comments or [...]]]></description>
			<content:encoded><![CDATA[<p>In our new product – Ideas, users will be able to vote for a published idea only. In <a href="http://answers.starty.co/" target="_blank">Answers</a> we called responses &#8211; answers; in Ideas we call responses &#8211; comments. Users can comment on an original idea to improve or discuss things with the idea’s contributor. Also users can like/dislike other users’ comments or reply to other users comments (see below).</p>
<p><a title="Click to enlarge" href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/ideas.png" target="_blank"><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Startyco Ideas" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/ideas_tn.png" alt="Startyco Ideas" /></a></p>
<p>If Answers is a modern implementation of FAQ, where your users can ask questions and get answers, Ideas is your public roadmap channel, where you and your users can collaborate on your product’s or service’s future.</p>
<p>Administrators of your Ideas portal will be able to create idea statuses like – rejected, in development, implemented etc. and maintain your Ideas portal in an up to date state with them.</p>
<p>All planned new features – WYSIWYG, spam protection, mobile version, widget, oAuth authorization will be added simultaneously to Answers and Ideas.<br />
</p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/5QEP1Ej5pLc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2033&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2033&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>Dashboard UI in Answers</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/o64essGb3eA/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2040&amp;lang=en-us#comments</comments>
		<pubDate>Tue, 02 Oct 2012 02:30:34 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2040</guid>
		<description><![CDATA[Managing our products from the configuration file is possible but inconvenient, and we understand this. We decided not to include it in our first release and concentrated on the creation of the install script’s UI instead. But we, at Deep Shift Labs, already started discussing the appearance of the dashboard, and what functionalities it will [...]]]></description>
			<content:encoded><![CDATA[<p>Managing our products from the configuration file is possible but inconvenient, and we understand this. We decided not to include it in our first release and concentrated on the creation of the install script’s UI instead. But we, at Deep Shift Labs, already started discussing the appearance of the dashboard, and what functionalities it will include.</p>
<p>No doubts it will be a single interface for all Startyco products our clients will buy and plug to the same core product. This is our goal; to create pluggable web apps with a single dashboard to manage them all.</p>
<p>For now we do not have many features (and we do not rush to implement them all), and this is how dashboard can look like to administer users:</p>
<p><a title="Click to enlarge" href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/admin_dashboard_startyco.png" target="_blank"><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Startyco Admin's Dashboard - Users" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/admin_dashboard_startyco_tn.png" alt="Startyco Admin's Dashboard - Users" /></a>  </p>
<p>We think this would be a better way to share permissions rather than manipulate user IDs from the database and edit a configuration file.</p>
<p>Here is a wireframe of the spam protection part of our dashboard which shows messages which were suspected as spam by, for example, SpamAssassin. You will decide how Startyco products will react, post them, and notify you or delay posting and notify. You will be able to ban and train your own instance of SpamAssassin to make it smarter.</p>
<p><a title="Click to enlarge" href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/admin_ui_spam.png" target="_blank"><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Startyco Admin's Dashboard - Spam" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/admin_ui_spam_tn.png" alt="Startyco Admin's Dashboard - Spam" /></a><br />
</p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/o64essGb3eA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2040&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2040&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>Comments in Answers</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/SOs2NOzosJY/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2024&amp;lang=en-us#comments</comments>
		<pubDate>Mon, 01 Oct 2012 09:35:22 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2024</guid>
		<description><![CDATA[One of the features from our TODO list is ‘Comments’. This mode can be turned on to allow your users to clarify a question or an answer. We think, this mode will add some interactivity to your Answers portal and make it more convenient for your users.]]></description>
			<content:encoded><![CDATA[<p><br />
One of the features from our TODO list is ‘Comments’. This mode can be turned on to allow your users to clarify a question or an answer. We think, this mode will add some interactivity to your <a href="http://answers.starty.co/" target="_blank">Answers</a> portal and make it more convenient for your users. </p>
<p><a title="Click to enlarge" href="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/comments.png" target="_blank"><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Comments UI in Answers" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/comments_tn.png" alt="Comments UI in Answers" /></a><br />
</p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/SOs2NOzosJY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2024&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2024&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>Voting in Answers</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/mhCm06im654/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=2008&amp;lang=en-us#comments</comments>
		<pubDate>Mon, 01 Oct 2012 06:25:40 +0000</pubDate>
		<dc:creator>Igor Kryltsov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=2008</guid>
		<description><![CDATA[We are adding a voting feature in the next Answers release. Users will be able to vote for questions (for example, ‘I also have this question’ or ‘this question does not make any sense’) and answers. You will be able to turn on voting by setting it in the configuration file. You can allow voting [...]]]></description>
			<content:encoded><![CDATA[<p>We are adding a voting feature in the next <a href="http://answers.starty.co/" target="_blank">Answers</a> release. Users will be able to vote for questions (for example, ‘I also have this question’ or ‘this question does not make any sense’) and answers. You will be able to turn on voting by setting it in the configuration file. You can allow voting for questions only, for answers only, both, or none.</p>
<p>We thought it will be quite important to be able to show up and down votes split. To keep the UI simple you will be able to see it when you hover your mouse over voting arrows or score. It makes sense to show a votes split when there are a few votes in different directions which also means it has to be at least two votes. Maybe we will show votes spit without hover when an answer’s score is 0 with equal amount of votes up and down (‘controversial answer’, I would say). </p>
<p><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Voting UI in Answers and Ideas" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/voting.png" alt="Voting UI in Answers and Ideas" /><span id="more-2008"></span></p>
<p>To let users see what they have voted for, and how they voted; this info will also be displayed. Here are some options I offered guys to look at and comment.</p>
<p><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="My votes UI in Answers and Ideas" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/my_votes.png" alt="My votes UI in Answers and Ideas" /></p>
<p>In our next product – &#8216;Ideas&#8217;, voting is essential and can’t be switched off. In here users leave feedback and voting will be only possible for an idea itself but not comments users will be able to leave to improve, clarify and criticize the idea. In here voting will have additional simple analytics you will be able to pre-configure and enjoy using.  Once done, you and your team will be able to see the distribution of votes between, for example, guests, staff, demo users and paying clients.  Hope you agree with us that an idea to add a feature with 20 votes from paying clients of yours requires more thought and attention than idea with 30 votes up from demo users and 10 votes down from your existing paying customers.</p>
<p>This is how it may look like:</p>
<p><img class="aligncenter size-full wp-image-1734" style="-ms-interpolation-mode: bicubic;" title="Voting analytics in Ideas" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/10/votes_ideas.png" alt="Voting analytics in Ideas" /></p>
<p><em>Igor</em><br />
</p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/mhCm06im654" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=2008&amp;lang=en-us</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=2008&amp;lang=en-us</feedburner:origLink></item>
		<item>
		<title>XSS and HTML formatted text</title>
		<link>http://feedproxy.google.com/~r/DeepShiftLabsDevelopmentBlog/~3/2Yd3Brq2B78/</link>
		<comments>http://www.deepshiftlabs.com/dev_blog/?p=1885&amp;lang=en-us#comments</comments>
		<pubDate>Fri, 14 Sep 2012 13:26:31 +0000</pubDate>
		<dc:creator>bear</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.deepshiftlabs.com/dev_blog/?p=1885</guid>
		<description><![CDATA[We have been working on Starty.co Answers for quite a while, and we cannot stop adding new features and hone existing ones. Finally we decided to release the first version of Answers without such a convenient thing as text markup, like BBCode. However, we did some preparatory work in this area and decided that in [...]]]></description>
			<content:encoded><![CDATA[<div style="float: left;"><img class="alignleft size-full wp-image-1752" style="padding: 5px 20px 10px 0;" title="No pasaran!" src="http://www.deepshiftlabs.com/dev_blog/wp-content/uploads/2012/09/2463.jpg" alt="No pasaran!" /></div>
<p><br />
We have been working on <a href="http://answers.starty.co">Starty.co Answers</a> for quite a while, and we cannot stop adding new features and hone existing ones.<br />
Finally we decided to release the first version of Answers without such a convenient thing as text markup, like <a href="http://ru.wikipedia.org/wiki/Bbcode">BBCode</a>. However, we did some preparatory work in this area and decided that in the near future it will include the <a href="http://www.tinymce.com/">TinyMCE</a>  WYSYWIG and <a href="http://softwaremaniacs.org/soft/highlight/">Highlight.js</a> module to highlight code snippets.</p>
<p>Even though we decided not to include a full markup in version one, it was necessary to implement the basic things &#8211; to replace the line breaks with &lt;br&gt; and parse http(s):// links in the text and replace them with &lt;a href=&#8221;"&gt;&lt;/a&gt;.<br />
<span id="more-1885"></span><br />
After adding a new line to &lt;br&gt; translation, I started looking how smart people implement link parsing and replacement with &lt;a href=&#8221;"&gt;&lt;/a&gt; in the text. In the end I settled on <a href="http://saturnboy.com/2010/02/parsing-twitter-with-regexp/">this approach</a>:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1885code32'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p188532"><td class="code" id="p1885code32"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$string</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/preg_replace"><span style="color: #990000;">preg_replace</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@(https?://([-\w\.]+)+(/([\w/_\.]*(\?\S+)?(#\S+)?)?)?)@'</span><span style="color: #339933;">,</span>
<span style="color: #0000ff;">'&lt;a href=&quot;$1&quot;&gt;$1&lt;/a&gt;'</span><span style="color: #339933;">,</span>
<span style="color: #000088;">$string</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>But first, as usual, I looked if there was anything suitable on the <a href="http://php.net">php.net</a> site. I came across <a href="http://www.php.net/manual/en/function.preg-replace.php#83974">this</a> comment where simple rules are described for preg_replace() to process BBCode. And I thought of adding support of at least a few basic BBCode tags, but we were planning to add TinyMCE with HTML-markup! If I would implement a simple BBCode in the first version, then we will have to support it in a next version as someone will use BBCode and it will suddenly stop working. Or, during an upgrade from version one it will be necessary to look for and change the BBCode in the database. This is not good, I thought, and decided that with the same success I can quickly implement several popular html-tags.</p>
<p>At this point I started reading how to store and display text with html-markup. There are no problems storing it, actually; everything is clear. For databases, it does not matter what is inside the text.<br />
The problem, of course, is with the output. On the one hand, there is a requirement to keep entered HTML-tags, on the other hand, we can’t allow <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS</a> to be dragged in, or just not allow them to break the entire page layout.</p>
<p>You may ask: Why developers of TinyMCE, an advanced WYSIWYG-editor, do not take care of elimination of XSS from HTML code, generated as the output? After all, if we disable the ability to edit HTML code in TinyMCE &#8211; the user will not be able to push XSS through TinyMCE.<br />
Unfortunately, we must remember that we cannot trust any data coming from the client. Switched off HTML mode can be enabled on the client side easily as it is JavaScript. And anyway, no one will prevent a hacker from POST-ing data – the server cannot distinguish who prepared the data in the request, TinyMCE or not.<br />
Therefore, although TinyMCE developers did some stuff to prevent attacks, complete protection from XSS is not the task of the editor running on client side.</p>
<p>It would seem, PHP has the tools for XSS prevention &#8211; such as strip_tags() and htmlentities(). However, with custom text with HTML-markup they won’t help.<br />
Suppose we want to implement even the simplest tag &lt;b&gt;&lt;/b&gt;, and parse a custom text user_msg this way:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1885code33'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p188533"><td class="code" id="p1885code33"><pre class="php" style="font-family:monospace;">user_msg_safe <span style="color: #339933;">=</span> <a href="http://www.php.net/strip_tags"><span style="color: #990000;">strip_tags</span></a> <span style="color: #009900;">&#40;</span>user_msg<span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;b&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Nothing bad can happen right? Wrong. <a href="http://stackoverflow.com/questions/6976053/xss-which-html-tags-and-attributes-can-trigger-javascript-events">That&#8217;s</a> a great discussion on stackoverflow. The following can occur:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1885code34'); return false;">View Code</a> HTML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p188534"><td class="code" id="p1885code34"><pre class="html" style="font-family:monospace;">&lt;b style=&quot;width: expression(alert(document.location));&quot;&gt; XSS &lt;/b&gt;</pre></td></tr></table></div>

<p>Yes, in most browsers, in all modern and popular browsers, such an attack may not lead to anything. But this is not a reason to relax. And this is just a &lt;b&gt; tag! We would like to implement the usual &#8211; &lt;b&gt;, &lt;i&gt;, &lt;s&gt;, &lt;pre&gt;, &lt;img&gt;, &lt;a&gt;!<br />
&lt;img&gt;, for example, with its &#8220;src&#8221; attribute – simply terrible things can happen:</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1885code35'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p188535"><td class="code" id="p1885code35"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>img src<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;javascript:alert('XSS');&quot;</span> alt<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&quot;</span> <span style="color: #339933;">/&gt;</span></pre></td></tr></table></div>

<p>And even replacing or cutting substring &#8220;javascript:&#8221; from user_msg is not helping as</p>

<div class="wp_codebox_msgheader"><span class="right"></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1885code36'); return false;">View Code</a> PHP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p188536"><td class="code" id="p1885code36"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>IMG SRC<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;jav&amp;#x0A;ascript:alert('XSS');&quot;</span><span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>has the same bad effect.</p>
<p>There’s a tonne of <a href="http://ha.ckers.org/xss.html">these</a> examples. Yes, most of the vulnerabilities are closed in modern browsers, but even their diversity allows us to understand that processing of custom text with HTML-markup is not a trivial task.</p>
<p>What to do?<br />
One option &#8211; use other markup languages &#8211; such as BBCode, Markdown, Wiki markup. With them it is much easier to build HTML-safe design. However they are still vulnerable to XSS.<br />
The second option &#8211; still use HTML-markup, but pass user_msg through so-called &#8220;HTML sanitizer&#8221;. In particular, many folks at stackoverflow are recommending HTML Purifier.<br />
It seems that the first pilot Answers version will not support markup language, but very soon we will return to this question, because understand how important this feature is.</p>
<p><strong>References</strong></p>
<p>- <a href="http://www.technicalinfo.net/papers/CSS.html/">vulnerable tags and examples of XSS attacks</a><br />
- an interesting scientific <a href="http://habrahabr.ru/post/149152/">view</a> at XSS (Russian), at the end of the article suggestions concerning http headers, which help to avoid XSS<br />
- related questions (<a href="http://stackoverflow.com/questions/6219003/tinymce-protection-against-cross-site-scripting">first</a>, <a href="http://stackoverflow.com/questions/1414986/using-safe-filter-in-django-for-rich-text-fields">second</a>, <a href="http://stackoverflow.com/questions/9826970/prevent-xss-but-allow-all-html-tags">third</a>) on StackOverflow<br />
- <a href=" http://htmlpurifier.org/">HTML sanitizer</a>  HTML Purifier<br />
- <a href="http://freecode.com/projects/inputfilter">HTML sanitizer</a> PHP Input Filter<br />
- <a href="http://stackoverflow.com/questions/1947021/libs-for-html-sanitizing">more on sanitizers</a> on StackOverflow<br />
- <a href="http://ha.ckers.org/xss.html ">XSS Cheat Sheet </a>(used as a reference inside this post)<br />
- <a href="http://stackoverflow.com/questions/6976053/xss-which-html-tags-and-attributes-can-trigger-javascript-events">vulnerability tags</a> and XSS attacks examples (used as a reference inside this post)</p>
<p><em>Dmitry</em></p>
<p>P.S. While I was preparing my post, containing lots of HTML tags, for a publication in WordPress, I ran out of steam by trying to make it look correctly. Probably, we should seriously think about using an alternative markup designed specifically for text entered by the users themselves.<br />
</p>
<img src="http://feeds.feedburner.com/~r/DeepShiftLabsDevelopmentBlog/~4/2Yd3Brq2B78" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.deepshiftlabs.com/dev_blog/?feed=rss2&amp;p=1885&amp;lang=en-us</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.deepshiftlabs.com/dev_blog/?p=1885&amp;lang=en-us</feedburner:origLink></item>
	</channel>
</rss>
