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

<channel>
	<title>itora web</title>
	<atom:link href="http://www.itora.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.itora.net/blog</link>
	<description></description>
	<lastBuildDate>Thu, 05 Jan 2012 19:50:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Contare child rows per un determinato record.</title>
		<link>http://www.itora.net/blog/2011/12/09/contare-child-rows-per-un-determinato-record/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=contare-child-rows-per-un-determinato-record</link>
		<comments>http://www.itora.net/blog/2011/12/09/contare-child-rows-per-un-determinato-record/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 12:03:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=480</guid>
		<description><![CDATA[Supponiamo il caso di avere un post con relativi articoli, un autore con molti libri, una ditta che ha ricevuto degli ordini, o ancora, un la risposta piu' votata all'interno di un questionario. In tutti questi casi, per ogni record principale avremo piu' record correlati. Supponiamo il caso di voler contare, nella pagina dove vengono [...]]]></description>
			<content:encoded><![CDATA[<p>Supponiamo il caso di avere un post con relativi articoli, un autore con molti libri, una ditta che ha ricevuto degli ordini, o ancora, un la risposta piu' votata all'interno di un questionario.<br />
In tutti questi casi, per ogni record principale avremo piu' record correlati. Supponiamo il caso di voler contare, nella pagina dove vengono elencate le risposte, quanti voti ogni risposta ha ricevuto, mostrando la piu' votata per prima. In Rails, possiamo scrivere un apposito metodo direttamente nel model.</p>
<pre>
class Answer < ActiveRecord::Base
	belongs_to :survey
	has_many :vote, :dependent => :destroy	

	def self.more_voted(survey_id)
		voted_answer = find(
			:all, :select => 'answers.*, count(votes.id) as vote_count',
			:conditions => ["answers.survey_id = ?", survey_id],
			:joins => 'left outer join votes on votes.answer_id = answers.id',
			:group => 'answers.id',
			:Order => 'vote_count DESC'
		)
	end
end
</pre>
<p>Ora nella nostra action 'show' per il controller survey, dove vengono elencate tutte le risposte per il tal survey, possiamo recuperare le answer con il metodo appena creato.</p>
<pre>
@answers = Answer.more_voted(params[:survey_id])
</pre>
<p>e mostrare nella view il valore 'vote_count'</p>
<pre>
&lt;% @answers.each do |a| %&gt;
	&lt;tr class=&quot;even&quot;&gt;
	&lt;td&gt;&lt;%= &quot;#{a.reply}&quot; %&gt;&lt;/td&gt;
	&lt;td&gt;&lt;%= &quot;#{a.vote_count}&quot; %&gt; &lt;/td&gt;
	&lt;/tr&gt;
&lt;% end %&gt;
</pre>
<p>Link consigliati:<br />
<a href="http://therailsway.com/2007/6/1/railsconf-recap-skinny-controllers">http://therailsway.com/2007/6/1/railsconf-recap-skinny-controllers</a><br />
<a href="http://blog.devinterface.com/2010/06/rails-best-practices-1-fat-model-skinny-controller/">http://blog.devinterface.com/2010/06/rails-best-practices-1-fat-model-skinny-controller/</a><br />
<a href="http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model">http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/12/09/contare-child-rows-per-un-determinato-record/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aggiungere una action ad un controller in rails3</title>
		<link>http://www.itora.net/blog/2011/12/02/aggiungere-una-action-ad-un-controller-in-rails3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=aggiungere-una-action-ad-un-controller-in-rails3</link>
		<comments>http://www.itora.net/blog/2011/12/02/aggiungere-una-action-ad-un-controller-in-rails3/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 16:11:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[routes]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=468</guid>
		<description><![CDATA[Rails3 cread i default sette azioni per ogni controller generato dinamicamente. Se vogliamo aggiungere un azione, che ne so, per aggiornare un solo valore nel database, per una nuova view, o per quasiasi altra cosa, dobbiamo: 1)Scrivere la nostra azione nel controller, in questo esempio scrivero' un azione per disapprovare un commento, settando a "0" [...]]]></description>
			<content:encoded><![CDATA[<p>Rails3 cread i default <a href="http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions">sette azioni</a> per ogni controller generato dinamicamente.<br />
Se vogliamo aggiungere un azione, che ne so, per aggiornare un solo valore nel database, per una nuova view, o per quasiasi altra cosa, dobbiamo:<br />
1)Scrivere la nostra azione nel controller, in questo esempio scrivero' un azione per disapprovare un commento, settando a "0" il valore del campo "approved".</p>
<pre>
def disapprove
	@comment = Comment.find(params[:id])
	if ( @comment.update_attribute(:approved, "0"))
		respond_to do |format|
			format.html { redirect_to(admin_comment_url(@comment),
					:notice => 'Comment was unapproved.') }
			format.xml  { head:ok }
		end
	else
		respond_to do |format|
			format.html { render :action => "edit" }
			format.xml  {render:xml=>@comment.errors, :status => :unprocessable_entity }
		end
	end
end
</pre>
<p>Nel mio file routes.rb, dovro' dire alla mia app che oltre alle 7 azioni canoniche ce ne' un altra, disapprove. E dovro' specifivare che tipo di http request e', tra post, get, put e delete. Nel mio caso ho messo post, piu' dettagli <a href="http://guides.rubyonrails.org/routing.html#adding-more-restful-actions">qui</a></p>
<pre>
resources :comment do
	post 'disapprove',:on=>:member
end
</pre>
<p>Lanciando "rake routes" nella cartella della mia app, posso vedere la nuova route creata, e vedere quale e' l'url da utlizzare nell'helper. Nel mio caso l'approvazione dei commenti si trova nell'admin area.</p>
<pre>
disapprove_admin_comment POST   /admin/comments/:id/disapprove(.:format)              {:controller=>"admin/comments", :action=>"disapprove"}
</pre>
<p>Ora creaimo un link all'azione</p>
<pre>
&lt;%= link_to &#039;Disapprove&#039;, disapprove_admin_comment_path(@comment)%&gt;
</pre>
<p>Dopo aver generato questo link, ottenevo un errore "No route matches..." la mia azione.<br />
Errore risolto<a href="http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to"> specificando</a> nel link il tipo di http verb</p>
<pre>
&lt;%= link_to &#039;Disapprove&#039;, disapprove_admin_comment_path(@comment), :method=&gt;&#039;post&#039; %&gt;
</pre>
<p>Consiglio questi screencast, per capire come vengono generate le routes, <a href="http://railscasts.com/episodes/231-routing-walkthrough">1</a> e <a href="http://railscasts.com/episodes/232-routing-walkthrough-part-2">2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/12/02/aggiungere-una-action-ad-un-controller-in-rails3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creare un admin area in rails3 usando l&#8217;autenticazione scritta in devise</title>
		<link>http://www.itora.net/blog/2011/11/17/creare-un-admin-area-in-rails3-usando-lautenticazione-scritta-in-devise/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creare-un-admin-area-in-rails3-usando-lautenticazione-scritta-in-devise</link>
		<comments>http://www.itora.net/blog/2011/11/17/creare-un-admin-area-in-rails3-usando-lautenticazione-scritta-in-devise/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 19:56:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[devise]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=451</guid>
		<description><![CDATA[1)aggiungere il namespace "admin" in routes.rb, ed abbinarlo ai controller per i quali vogliamo l'autenticazione, in questo esempio "questions". namespace :admin do match '/' => 'questions#index' resources :questions end 2In views/layout creare il layout admin.html.erb specificando le parti che vogliamo mostrare nella sezione admin. 3) creare il controller admin_controller.rb in controllers/admin e utilizzare "autenticate_user" (vedere [...]]]></description>
			<content:encoded><![CDATA[<p><strong>1)</strong>aggiungere il namespace "admin" in routes.rb, ed abbinarlo ai controller per i quali vogliamo l'autenticazione, in questo esempio "questions".</p>
<pre>
namespace :admin do
	match '/' => 'questions#index'
	resources :questions
end
</pre>
<p><strong>2</strong>In views/layout creare il layout admin.html.erb specificando le parti che vogliamo mostrare nella sezione admin.<br />
<strong>3)</strong> creare il controller admin_controller.rb in controllers/admin e utilizzare "autenticate_user" (vedere il tutorial su <a href="http://www.itora.net/blog/2011/07/24/ruby-on-rails-devise-authentication/">devise</a>) per verificare che un utente sia loggato</p>
<pre>
class Admin::AdminController &lt; ApplicationController
	layout "admin"
	before_filter :authenticate_user!
end
</pre>
<p><strong>4)</strong> Sempre in controllers/admin, creare il file questions_controller.rb</p>
<pre>
class Admin::QuestionsController < Admin::AdminController
  def index
    @questions = Question.all
    respond_to do |format|
      format.html # index.html.erb
    end
  end
end
</pre>
<p><strong>5)</strong>in views/admin creaimo la cartella "questions" e inderiamo tutte le views richieste dal controller controllers/admin/questions_controller.rb, in questo caso, solo il file index.html.rb<br />
<strong>6</strong><br />
Le action dei form all'interno delle views in views/admin/questions devono rimandare ai controllers in controllers/admin/question controller. Quindi, sempre tenendo "question" come esempio da:</p>
<pre>
&lt;%= form_for(@answer) do |f| %&gt;
</pre>
<p>dobbiamo passare a </p>
<pre>
&lt;%= form_for(:admin, @answer) do |f| %&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/11/17/creare-un-admin-area-in-rails3-usando-lautenticazione-scritta-in-devise/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>creare un fork da un plugin su Github e svilupparlo come submodule</title>
		<link>http://www.itora.net/blog/2011/10/15/creare-un-fork-da-un-plugin-su-github-e-svilupparlo-come-submodule/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creare-un-fork-da-un-plugin-su-github-e-svilupparlo-come-submodule</link>
		<comments>http://www.itora.net/blog/2011/10/15/creare-un-fork-da-un-plugin-su-github-e-svilupparlo-come-submodule/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 21:35:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[allday]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[submodule]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=435</guid>
		<description><![CDATA[Sto sviluppando un'applicazione in CakePhp 2.0 e voglio usare dei plugin che sono ancora fermi alla versione 1.3 di CakePhp. Per ora, rinominare qualche cartella sembra essere sufficiente. Per tenere traccia del lavoro fatto e per far si che qualcun altro possa usufruirne, ho trovato molto utile "git sumbodule". Vediamo come creare un fork da [...]]]></description>
			<content:encoded><![CDATA[<p>Sto sviluppando un'applicazione in CakePhp 2.0 e voglio usare dei plugin che sono ancora fermi alla versione 1.3 di CakePhp. Per ora, rinominare qualche cartella sembra essere sufficiente. Per tenere traccia del lavoro fatto e per far si che qualcun altro possa usufruirne, ho trovato molto utile "git sumbodule". Vediamo come creare un <a href="http://help.github.com/fork-a-repo/">fork</a> da un plugin e svilupparlo in locale come un submodule.<br />
Per prima cosa installiamo la versione 2.0 di cake e inizializzamo un repository git.<br />
Poi andiamo su github e scegliamo il plugin da adattare alla versione 2.0 di Cake, per esempio il plugin <a href="https://github.com/CakeDC/categories">categories di CakeDc</a>. Creiamo un fork con il bottone... fork. Poi Andiamo in "Admin", selezioniamo il repository appena forkato e diciamo a github quale deve essere il "default branch", in questo caso, scegliamo il 2.0.<br />
Importante! quando cloniamo o installiamo come submodule un repo da github, questo si porta con appresso tutti i branches. Sta a noi decidere con "git checkout nomebranch" su quale branch lavorare.</p>
<h5>Aggiungere il submodule</h5>
<p>Dobbiamo dire a git di aggiungere un submodule contenente il codice del nostro fork, per esempio git@github.com:user/categories.git</p>
<pre>
git submodule add git@github.com:user/categories.git app/Plugin/Categories
</pre>
<p>Poi spostiamoci nella cartella del plugin appena scaricato e diciamo a git dove e' il repository remote</p>
<pre>
cd app/Plugin/Categories
git remote add push git@github.com:user/categories.git
</pre>
<p>Proviamo a modificare un file del plugin, e sempre dalla cartella del plugin, eseguiamo il commit ed il push.</p>
<pre>
git add .
git commit -m "test commit"
git push master
</pre>
<h5>Aggiungere l'indirizzo remote originario del repo forkato</h5>
<p>Automaticamente, la nostra "origin" e' il nostro repo forkato su github, non il repo originario(quello di CakeDC in questo esempio).<br />
Per dire a git di scaricare gli aggiornamenti fatti dagli sviluppatori di cakedc, dobbiamo aggiungere un altro remote.<br />
sempre nella cartella del submodule</p>
<pre>
git remote add upstream git://github.com/CakeDC/categorie.git
</pre>
<h5>Sincronizzare il nostro submodule con il repo originario forkato</h5>
<p>Per scaricare gli aggiornamenti</p>
<pre>
git fetch upstream
</pre>
<p>Per fare un merge fra gli aggiornamenti appena scaricati da upstream ed il vostro repo in locale</p>
<pre>
git merge upstream/master
</pre>
<p>Per capire la differenza tra "git pull upstream" e "git fetch upstream", consiglio di leggere il punto "Pull in upstream changes" di questa <a href="http://help.github.com/fork-a-repo/">guida</a>.<br />
Qui un link su<a href="http://stackoverflow.com/questions/3903817/how-to-pull-new-updates-for-forked-repository-in-github"> stackoverflow </a>riguardante questa parte.</p>
<h5>Rimuovere submodules</h5>
<p>Per rimuovere un submodule erronemente creato:<br />
Delete the relevant line from the .gitmodules file.<br />
Delete the relevant section from .git/config.<br />
Run git rm --cached path_to_submodule (no trailing slash).<br />
via <a href="http://stackoverflow.com/questions/1260748/how-do-i-remove-a-git-submodule">Stackoverflow</a></p>
<h5>Clonare un progetto contenente submodules</h5>
<pre>
git clone git://github.com/user/progettoconsubmodules.git
</pre>
<p>Questo clonera' il progetto e la cartella del submodule, ma non il contenuto di quest'ultima. Per farlo lanciamo:</p>
<pre>
git submodule init
git submodule update
</pre>
<p>Altre info su questa parte nel <a href="http://progit.org/book/ch6-6.html">git pro book</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/10/15/creare-un-fork-da-un-plugin-su-github-e-svilupparlo-come-submodule/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jquery screensaver</title>
		<link>http://www.itora.net/blog/2011/10/11/jquery-screensaver/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jquery-screensaver</link>
		<comments>http://www.itora.net/blog/2011/10/11/jquery-screensaver/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 09:39:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=429</guid>
		<description><![CDATA[Uno screensaver stile windows, fatto con jquery. questo l'html &#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62; &#60;html&#62; &#60;head&#62; &#60;script src=&#34;http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js&#34;&#62;&#60;/script&#62; &#60;style&#62; body{ background-color:#b0c4de; margin:0px; width:100%; } #container{ position: relative; } #saver{ background-color:lime; width:100px; height:100px; position: fixed; z-index: 50; } &#60;/style&#62; &#60;/head&#62; &#60;body&#62; &#60;div id =&#34;container&#34;&#62; &#60;div id =&#34;saver&#34;&#62;I&#039;m a screensaver &#60;/div&#62; &#60;/div&#62; &#60;/body&#62; &#60;/html&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Uno screensaver stile windows, fatto con jquery.<br />
questo l'html</p>
<pre>
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;script src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;style&gt;
body{
	background-color:#b0c4de;
	margin:0px;
	width:100%;
}
#container{
	position: relative;
}
#saver{
	background-color:lime;
	width:100px;
	height:100px;
	position: fixed;
	z-index: 50;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id =&quot;container&quot;&gt;
		&lt;div id =&quot;saver&quot;&gt;I&#039;m a screensaver
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Dopo la fine del tag
<pre>head</pre>
<p> inserite questo codice js</p>
<pre>
&lt;script&gt;
$(function(){
var savescreen = function(speed, vertical, horizontal){
	$(&quot;#saver&quot;).animate({left: &#039;+=&#039;+horizontal, top: &#039;+=&#039;+vertical}, speed);
	$(&quot;#saver&quot;).animate({left: &#039;-=&#039;+horizontal, top: &#039;+=&#039;+vertical}, speed);
	$(&quot;#saver&quot;).animate({left: &#039;-=&#039;+horizontal, top: &#039;-=&#039;+vertical}, speed);
	$(&quot;#saver&quot;).animate({left: &#039;+=&#039;+horizontal, top: &#039;-=&#039;+vertical}, speed);
};

$(function(){
	larg_saver = $(&#039;#saver&#039;).width();
	alt_saver = $(&#039;#saver&#039;).height();
	width = $(window).width();
	height = $(window).height();
	margin_top_saver = (height - alt_saver)/2;
	margin_left_saver = (width - larg_saver)/2;
	$(&#039;#saver&#039;).css(&#039;top&#039;,0);
	$(&#039;#saver&#039;).css(&#039;left&#039;,margin_left_saver);
  });

window.setInterval(function(){
	speed = 1000
	savescreen(speed, margin_top_saver, margin_left_saver);
}, 1000);

});
&lt;/script&gt;
</pre>
<p>Qui una demo per lo <a href="http://www.itora.net/demo/screensaver.html">screensaver</a> in jquery</p>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/10/11/jquery-screensaver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git Branches</title>
		<link>http://www.itora.net/blog/2011/09/20/git_branch/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=git_branch</link>
		<comments>http://www.itora.net/blog/2011/09/20/git_branch/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 13:06:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git branch]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=410</guid>
		<description><![CDATA[Per lo sviluppo di un progetto sto utilizzando git in locale con due branches. Un branch master/origin, dove risiede il lavoro pronto per essere caricato in produzione, e uno develop, su cui effettuo i commits, sviluppo nuove featurse, e, quando tutto va bene, implemento nel branch master/origin. Qui sotto un breve tutorial su come cominciare. [...]]]></description>
			<content:encoded><![CDATA[<p>Per lo sviluppo di un progetto sto utilizzando git in locale con due branches. Un branch master/origin, dove risiede il lavoro pronto per essere caricato in produzione, e uno develop, su cui effettuo i commits, sviluppo nuove featurse, e, quando tutto va bene, implemento nel branch master/origin. Qui sotto un breve tutorial su come cominciare. Diamo per scontato di avere un repo inizializzato, con il branch master/origin. Per creare il nuovo branch 'develop'</p>
<pre>
git branch develop
</pre>
<p>per vedere i vari branches</p>
<pre>
git branch
</pre>
<p>l'asterisco indica il branch attualmente selezionato<br />
per passare da un branch all'altro</p>
<pre>
git checkout master
git checkout develop
</pre>
<p>Per portare avanti il codice su develop, selezioniamo il branch develop</p>
<pre>
git checkout develop
</pre>
<p>andiamo avanti con i nostri commit che verranno eseguiti SOLO sul branch develop.<br />
Difatti, se torniamo sul branch master e cerchiamo le modifiche appena fatte, non le troveremo perche' sono solo su develop.<br />
quando le modifiche sono pronte per essere messe nel branch 'master', selezioniamolo<br />
git checkout master<br />
e diciamo al branch master di prendere le modifiche fatte su develop</p>
<pre>
git merge develop
</pre>
<p>Una volta che le nuove modifiche sono state implementate, possiamo taggare il branch master con il corrente numero di versione</p>
<pre>
git tag 0.1
</pre>
<p>se un giorno decidessimo che il branch develop non ci serve più, cancelliamolo </p>
<pre>
git branch -d develop
</pre>
<p><strong>Differenze tra i due branches</strong><br />
Può capitare che alcune modifiche fatte su 'develop' differiscano dal codice presente su master. Puoà darsi che abbiate innavertitamente lavorato su master per delle modifiche che dovevano essere effettuate su develop, o altri scenari simili. Quando, dal branch master lanciamo</p>
<pre>
git merge develop
</pre>
<p>Le modifiche fatte su master vengono fuse alle modifiche fatte su develop. Se alcune di queste modifiche riguardano la stessa porzione di codice, al primo commit git ci segnalerà che dobbiamo risolvere un conflitto prima di proseguire.</p>
<pre>
file_config.txt: needs merge
</pre>
<p>Apriamo il file incriminato, sistemiamolo e poi git add e git commit.</p>
<pre>
git add file_config.txt
git commit
</pre>
<p><strong>Il control-Z dell'ultimo merge</strong><br />
Se avete appena fatto il merge sul branch master di una bizzarra feature che avevate sviluppato su develop, che credevate pronta e superefficiente ma in realtà ha scatenato un turbine di email di protesta da parte degli utenti che rivogliono indietro il loro vecchio sistema, dove "tutto funzionava", dove "tutto era più semplice" e sentite che sta per arrivare la email "si stava meglio quando si stava peggio", beh, allora, forse è meglio tornare indietro, e levare l'ultima feature aggiunta.</p>
<pre>
git reset --hard ORIG_HEAD
</pre>
<p>Qui il <a href="http://book.git-scm.com/3_basic_branching_and_merging.html">tutorial completo</a><br />
Per vedere tutti i commit fatti nei minimi dettagli, installate <a href="http://lwn.net/Articles/140350/">gitk</a> e lanciatelo da console nella directory dove avete un progetto versionato</p>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/09/20/git_branch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP 2.0 Authentication</title>
		<link>http://www.itora.net/blog/2011/09/20/cakephp-2-0-authentication/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cakephp-2-0-authentication</link>
		<comments>http://www.itora.net/blog/2011/09/20/cakephp-2-0-authentication/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 11:13:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[cakephp2.0]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=393</guid>
		<description><![CDATA[Con CakePHP 2.0 ci sono tante novità. In questo post spiegherò come realizzare una semplice sistema di autenticazione per l'admin area, in cui abbiamo differenti users che possono accedervi, ma solo uno e' l'admin, gli altri sono amministratori con funzioni limitate. Per un piccolo sistema, con pochi utenti, ho deciso di non usare ACL, troppo ingombrante [...]]]></description>
			<content:encoded><![CDATA[<p>Con CakePHP 2.0 ci sono tante novità. In questo post spiegherò come realizzare una semplice sistema di <a href="http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html">autenticazione</a> per l'admin area, in cui abbiamo differenti users che possono accedervi, ma solo uno e' l'admin, gli altri sono amministratori con funzioni limitate. Per un piccolo sistema, con pochi utenti, ho deciso di non usare ACL, troppo ingombrante e dispendiosa, ma di scrivere un metodo apposito, allowedGroups da richiamare nelle azioni in cui voglio verificare che solo un determinato gruppo di utenti possa accedere a determinate funzioni. Alcune note sulle novità che influiscono sull'autenticazione.</p>
<ul>
<li>Sono supporati diversi tipi di autenticazione, configurabili tramite degli handlers, quello usato in questo articolo è il FormAuthenticate handler di default.</li>
<li>Nelle versioni precedenti di CakePHP 2.0 bastava aggiungere l'Auth Component e chiamare la funzione login nello user controller,  nella nuova versione, nella nostra function login, dovremo chiamare manualmente "$this-&gt;Auth-&gt;login()"</li>
<li>La password non viene più crittata di default, il metodo va chiamato manualmente</li>
</ul>
<p>Creiamo un database per gli users e uno per i groups</p>
<pre>
CREATE TABLE IF NOT EXISTS `groups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(70) NOT NULL,
  `description` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL,
  `name` varchar(70) NOT NULL,
  `email` varchar(70) NOT NULL,
  `password` varchar(60) NOT NULL,
  `description` text NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
</pre>
<p>
Creiamo i relativi controllers, models e views usando "cake bake".<br />
Andiamo ad eliminare tutte le action e tutte le view che non saranno accessibili al di fuori dell'admin area. Rimuoviamo quindi,per esempio, dallo UserController le action delete, add, edit. Aggiungiamo i metodi per il login ed il logout dello user in app/Controllers/UsersController.php</p>
<pre>
/**
 * Users Controller
 *
 * @property User $User
 */
class UsersController extends AppController {
	public function beforeFilter() {
		parent::beforeFilter();
		$this->Auth->allow('admin_login');
	}
/**
 * login method
 *
 * @return void
 */
	public function admin_login() {
		if ($this->request->is('post')) {
			if ($this->Auth->login()) {
				$user_id = $this->Auth->user('id');
				$group_id = $this->Auth->user('group_id');
				$group = $this->User->getGroup($group_id);
				$this->Session->write('Auth.User.group', $group);
				$this->redirect(array('action' => 'profile', $user_id,
										'admin' => true));
			} else {
				$this->Session->setFlash(__('email o password errata'),
											'default', array(), 'auth');
			}
		}
	}
/**
 * logout method
 *
 * @return void
 */
	public function admin_logout() {
        $this->Session->setFlash('Sei ora sloggato dal sistema');
		$this->Session->destroy();
		$this->redirect($this->Auth->logout());
	}
</pre>
<p>Come vedete ho utilizzato il metodo getGroup, che dovro' scrivere nel mio App/Model/User.php</p>
<pre>
function getGroup($group_id){
	$conditions = array('id' => $group_id);
	$group = $this->Group->field('nome', $conditions);
	if ($group) {
		return $group;
	}
	else {
		return false;
	}
}
</pre>
<p>Passiamo ora all'AppController.php, richiediamo l'autenticazione per chiunque voglia accedere all'admin area, e creiamo in App/Views/Layouts il file admin.ctp che conterrà il layout specifico per l'admin. Inoltre, andiamo a scrivere nella sessione il nome del gruppo, in modo da poterlo sempre leggere nella variabile $current_user, e da poterlo utilizzare sia per decidere quali elementi nelle view mostrare, sia per verificare che il nome del gruppo sia nell'elenco delle funzioni che vogliamo restringere solo ad alcuni gruppi.</p>
<pre>
class AppController extends Controller {
	var $components = array('Auth','Session');
	var $helpers = array('Session','Form','Html');
    var $current_user = false;

    function beforeFilter() {
		if (isset($this->request->params['admin'])) {
            $this->layout = 'admin';
			$this->Auth->logoutRedirect = '/';
			$this->Auth->authenticate = array(
				AuthComponent::ALL => array(
					'fields' => array(
						'username' => 'email',
						'password' => 'password'),
					'userModel' => 'Users.User'
				), 'Form'
			);
        } else {
            $this->Auth->allow();
        }
        $this->current_user = $this->Auth->user();
    }

    function beforeRender() {
        $this->set('current_user',$this->current_user );
    }

	function allowGroups($groups = array(), $options = array()){
		if (empty($options['message'])) {
			$options['message'] = 'non sei autorizzato ad accedere';
		}

		$group = $this->Session->read('Auth.User.group');
		if (in_array($group, $groups) || ($groups[0] == "*")) {
			return true;
		}
		else {
			$this->Session->setFlash(__($options['message']));
			$this->Session->destroy();
			$this->redirect($this->Auth->logout());

		}
	}
}
</pre>
<p>Creaimo il file Views/Users/admin_login.ctp</p>
<pre>
&lt;?
echo $this-&gt;Session-&gt;flash(&#039;auth&#039;);
echo $this-&gt;Form-&gt;create(&#039;User&#039;, array(&#039;url&#039; =&gt; array(&#039;controller&#039; =&gt; &#039;users&#039;, &#039;action&#039; =&gt;&#039;login&#039;)));
echo $this-&gt;Form-&gt;input(&#039;User.email&#039;, array(&#039;label&#039;=&gt;&#039;Email&#039;));
echo $this-&gt;Form-&gt;input(&#039;User.password&#039;, array(&#039;label&#039;=&gt;&#039;password&#039;));
echo $this-&gt;Form-&gt;end(&#039;Loggati&#039;);
?&gt;
</pre>
<p>Qui sotto un esempio su come utilizzare allowGroups.</p>
<pre>
#se voglio autorizzare tutti i gruppi esistenti
$this->allowGroups(array('*'));
#se voglio autorizzare solo il gruppo admin
$this->allowGroups(array('admin'));
#se voglio autorizzare admin e supervisori
$this->allowGroups(array('admin','supervisori'));
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/09/20/cakephp-2-0-authentication/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>php strtoupper umlauts</title>
		<link>http://www.itora.net/blog/2011/08/15/php-strtoupper-umlauts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-strtoupper-umlauts</link>
		<comments>http://www.itora.net/blog/2011/08/15/php-strtoupper-umlauts/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 09:43:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[allday]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[preg]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=388</guid>
		<description><![CDATA[Strtoupper non funziona con i default local characters, come le umlauts. Per risolvere questo problema si può usare preg_replace. setlocale(LC_ALL, 'de_DE'); $title = 'viele umlauts, zum beispiel ä, ü, ö...und eine ß'; $umaluts = array('/ä/i','/ü/i','/ö/i','/ß/i'); $replacing_umlauts = array('Ä','Ü','Ö','SS'); $title = preg_replace($umaluts, $replacing_umlauts, $title); echo strtoupper($title);]]></description>
			<content:encoded><![CDATA[<p>Strtoupper non funziona con i default local characters, come le umlauts.<br />
Per risolvere questo problema si può usare preg_replace.</p>
<pre>
setlocale(LC_ALL, 'de_DE');
$title = 'viele umlauts, zum beispiel ä, ü, ö...und eine ß';
$umaluts = array('/ä/i','/ü/i','/ö/i','/ß/i');
$replacing_umlauts = array('Ä','Ü','Ö','SS');
$title = preg_replace($umaluts, $replacing_umlauts, $title);
echo strtoupper($title);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/08/15/php-strtoupper-umlauts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress how to get ONE random image from the gallery</title>
		<link>http://www.itora.net/blog/2011/08/05/wordpress-how-to-get-one-random-image-from-the-gallery/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wordpress-how-to-get-one-random-image-from-the-gallery</link>
		<comments>http://www.itora.net/blog/2011/08/05/wordpress-how-to-get-one-random-image-from-the-gallery/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 12:28:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress template]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=381</guid>
		<description><![CDATA[Tramite lo shortcode gallery e' possibile inserire una galleria nel nostro tema personalizzato senza alcun problema. Per poter pero' estrarre un'immagine random dalla galleria e mostrarla nella larghezza desiderata dobbiamo scrivere un metodo apposito, perche' non vi sono opzioni sufficienti nello shortcode di default (si, esistono tanti plugin che permettono di avere un'immagine random senza [...]]]></description>
			<content:encoded><![CDATA[<p>Tramite lo <a href="http://codex.wordpress.org/Gallery_Shortcode">shortcode gallery</a> e' possibile inserire una galleria nel nostro tema personalizzato senza alcun problema. Per poter pero' estrarre un'immagine random dalla galleria e mostrarla nella larghezza desiderata dobbiamo scrivere un metodo apposito, perche' non vi sono opzioni sufficienti nello shortcode di default (si, esistono tanti plugin che permettono di avere un'immagine random senza scrivere una linea di codice....ma che noia!)</p>
<pre>
/*
 * find a random image from the gallery, that is related to a post
 */
function get_random_image_from_gallery($custom_width) {
	$query = new WP_Query(array(
		&#039;showposts&#039; =&gt; 1,
		&#039;post_type&#039; =&gt; array(&#039;attachment&#039;),
		&#039;post_status&#039; =&gt; &#039;inherit&#039;,
		&#039;meta_query&#039; =&gt; array(array(
			&#039;key&#039; =&gt; &#039;_wp_attached_file&#039;,
			&#039;value&#039; =&gt; &#039;&#039;,
			&#039;compare&#039; =&gt; &#039;!=&#039;
		)),
		&#039;orderby&#039; =&gt; &#039;rand&#039;
	));
	if($query-&gt;have_posts()) : while ($query-&gt;have_posts()) : $query-&gt;the_post();
		$image_attributes = wp_get_attachment_image_src(get_the_ID(), &#039;large&#039;);
		$width = $image_attributes[1];
		$height = $image_attributes[2];
		$resize_factor = $custom_width/$image_attributes[1];
		$relative_height = $resize_factor * $image_attributes[2];
		?&gt;&lt;img src=&quot;&lt;?php echo $image_attributes[0] ?&gt;&quot;
			width=&quot;&lt;?= $custom_width?&gt;px&quot;
			height=&quot;&lt;?= ceil($relative_height)?&gt;px&quot;/&gt;
		&lt;?
	endwhile;
 	else: ?&gt;
		&lt;p class=&quot;empty&quot;&gt;&lt;?php _e(no images found.&#039;); ?&gt;&lt;/p&gt;
	&lt;?php endif;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/08/05/wordpress-how-to-get-one-random-image-from-the-gallery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails themes generator</title>
		<link>http://www.itora.net/blog/2011/07/24/ruby-on-rails-themes-generator/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ruby-on-rails-themes-generator</link>
		<comments>http://www.itora.net/blog/2011/07/24/ruby-on-rails-themes-generator/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 12:57:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[themes]]></category>

		<guid isPermaLink="false">http://www.itora.net/blog/?p=378</guid>
		<description><![CDATA[Questa gemma leva un sacco di castagne dal fuoco. Aggiungere stili e classi ad un'applicazione fatta prevalentemente da form e' decisamente noioso. web-app-theme e' la gemma che fa al caso nostro. Aggiungete al vostro Gemfile (su rails 3) group :development, :test do gem 'web-app-theme', '>= 0.6.2' end poi bundle install e scegliete quale tema installare. [...]]]></description>
			<content:encoded><![CDATA[<p>Questa gemma leva un sacco di castagne dal fuoco. Aggiungere stili e classi ad un'applicazione fatta prevalentemente da form e' decisamente noioso.<br />
<a href="https://github.com/pilu/web-app-theme">web-app-theme</a> e' la gemma che fa al caso nostro.<br />
Aggiungete al vostro Gemfile (su rails 3)</p>
<pre>
group :development, :test do
  gem 'web-app-theme', '>= 0.6.2'
end
</pre>
<p>poi</p>
<pre>
bundle install
</pre>
<p>e scegliete quale tema installare. <a href="http://pilu.github.com/web-app-theme/#themes/drastic-dark">Qua</a> una lista con i relativi esempi.</p>
<pre>
rails g web_app_theme:theme --theme="drastic-dark" --app-name="Nome della mia app"
</pre>
<p>via <a href="http://blog.bryanbibat.net/2011/01/03/starting-a-professional-rails-app-with-haml-rspec-devise-and-web-app-theme/">bryanbibat</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.itora.net/blog/2011/07/24/ruby-on-rails-themes-generator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

