<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>Veikko Mäkinen</title><generator>Tumblr (3.0; @v-dogg)</generator><link>http://blog.veikko.fi/</link><item><title>Preemptive HTTP Authentication with Android 2.2</title><description>&lt;h1&gt;Preemptive HTTP Authentication with Android 2.2&lt;/h1&gt;
&lt;p&gt;I just spend a good few hours trying to figure out why my Android application fails to communicate with a web service which requires preemptive Basic HTTP Authentication. Here&amp;#8217;s an example code for anyone else on the same quest:&lt;/p&gt;
&lt;pre class="sh_java"&gt;String auth = android.util.Base64.encodeToString(
	(username + ":" + password).getBytes("UTF-8"), 
	android.util.Base64.NO_WRAP
);
HttpGet request = new HttpGet(url);
request.addHeader("Authorization", "Basic "+ auth);
&lt;/pre&gt;
&lt;p&gt;Thanks &lt;a href="http://commonsware.com/AndTutorials/"&gt;Mark Murphy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;David Linsin shows &lt;a href="http://dlinsin.blogspot.com/2009/08/http-basic-authentication-with-android.html"&gt; in his blog&lt;/a&gt; how to use &lt;code&gt;HttpRequestInterceptor&lt;/code&gt; to fiddle with the request before it is sent. For some reason I wasn&amp;#8217;t  able to make it work and I don&amp;#8217;t see any reason why adding the Authorization header manually wouldn&amp;#8217;t be enough. Feel free to correct me if I&amp;#8217;m missing something here.&lt;/p&gt;
&lt;p&gt;Android 2.2 ships with Base64 utility class. With older versions you can use &lt;a href="http://iharder.net/base64"&gt;&lt;a href="http://iharder.net/base64"&gt;http://iharder.net/base64&lt;/a&gt;&lt;/a&gt;.  This is what Mark Murphy uses in his examples. The interface is almost identical.&lt;/p&gt;
&lt;h2&gt;android.util.Log Trims, Base64 Doesn&amp;#8217;t!&lt;/h2&gt;
&lt;p&gt;This is actually the reason why all this took so long to figure out. The web server returned &amp;#8220;400 Bad Request&amp;#8221; and I couldn&amp;#8217;t figure out what was wrong.  I knew the problem was in the Authorization header but when I logged the authorization token everything looked OK&amp;#8230; until I did this:&lt;/p&gt;
&lt;pre&gt;Log.i("AUTH", "\""+auth+"\"");
&lt;/pre&gt;
&lt;p&gt;I turned out that the base64 encoded authorization token had an extra newline at the end. Hence, &lt;code&gt;android.util.Base64.NO_WRAP&lt;/code&gt;.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/2510952605</link><guid>http://blog.veikko.fi/post/2510952605</guid><pubDate>Wed, 29 Dec 2010 12:46:00 +0200</pubDate><category>java</category><category>android</category></item><item><title>My name is MÃ¤kinen, Veikko MÃ¤kinen</title><description>&lt;p&gt;Sometimes it&amp;#8217;s not easy to be a Finn with weird characters in my surname&amp;#8230;&lt;/p&gt;
&lt;pre&gt;On 18.12.2010 20:22, devenroll@apple.com wrote:
&amp;gt; Please include the line below in follow-up emails for this request.
&amp;gt;
&amp;gt; Follow-up:  XXXXXXXXXXX
&amp;gt;
&amp;gt; Re: iOS Developer Program
&amp;gt;
&amp;gt; Dear Mr Makinen,
&amp;gt;
&amp;gt; We are currently in the process of reviewing your iOS Developer
&amp;gt; Program enrolment information.
&amp;gt;
&amp;gt; In reviewing your company enrolment application, we have found the
&amp;gt; following information:
&amp;gt;
&amp;gt; Enrollment ID: XXXXXXXXXX 
&amp;gt; Company Name: XXXXXXXXXX  
&amp;gt; Applicant Name: Veikko MÃ¤kinen 
&amp;gt; Email: veikko.makinen@xxxxx
&amp;gt;
&amp;gt;
&amp;gt; Please note that the applicant name is in double-byte characters. We
&amp;gt; are unable to properly view this on our system since we require
&amp;gt; registered information to be in standard English characters. We have
&amp;gt; therefore withdrawn your enrolment XXXXXXXXXXX and you can submit a
&amp;gt; new enrolment request with the correct applicant name.
&amp;gt;
&amp;gt; We ask that you please submit a new enrolment using a different Apple
&amp;gt; ID and email address from the ones used for your original enrolment.


Dear Apple Developer Support,


I have read this message over and over again and several times checked 
my calendar to make sure I'm still in year 2010 and not leaped back to 
the 90'ies. Don't get me wrong, though. Many quality software systems 
were built in the 90'ies and if your enrollment system still runs just 
fine there's no need to update it to support other character sets besides 
the legendary American Standard Code for Information Interchange, or 
ASCII. After all, if we get by with ten digits, 128 characters should 
be plenty.

This can, however, become problematic now that developing countries like 
Finland or Germany are joining the party. Some of these newcomers, me 
being one of them, might expect to be able to use their actual names 
or at least GET A NOTICE AND A CHANCE TO CORRECT IF THE NAME PROVIDED 
IS NOT ACCEPTABLE!

And then about creating a totally new Apple ID just to be able to enroll 
with a fake name: You have got to be kidding...? No? Absolutely sure? 
I have changed the name in my Apple ID account but the enrollment system 
still insists that my name is Veikko MÃ¤kinen. Can't I reset the information 
from the Apple ID account? I was under the impression that Apple systems 
Just Work.


Sincerely,
Veikko Mäkinen
&lt;/pre&gt;</description><link>http://blog.veikko.fi/post/2376941796</link><guid>http://blog.veikko.fi/post/2376941796</guid><pubDate>Sun, 19 Dec 2010 21:47:00 +0200</pubDate><category>nonsense</category></item><item><title>Why do so many companies actively using email for marketing know...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_lbsgaiV0Mt1qzsqewo1_250.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Why do so many companies actively using email for marketing know so little about basic do’s and dont’s… Well here’s a Dont for you all: don’t write “www.something.com” and then link it to “www.somethingelse.net”.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/1554477111</link><guid>http://blog.veikko.fi/post/1554477111</guid><pubDate>Fri, 12 Nov 2010 22:15:54 +0200</pubDate></item><item><title>Facelift</title><description>&lt;p&gt;Long overdue facelift of my ever-so active blog happened finally. Briefly tested with Firefox 3, IE8, and Safari [something]. Can&amp;#8217;t be bothered with anything more.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/1233793204</link><guid>http://blog.veikko.fi/post/1233793204</guid><pubDate>Sun, 03 Oct 2010 10:06:00 +0300</pubDate><category>nonsense</category></item><item><title>A Great Article Series on Agavi</title><description>&lt;p&gt;Vikram Vaswani has written a great article series on Agavi. The five-part series starts off with the basic but in the end goes quite deep into building a multi presentational layer web application. Go read it on the IBM developerWorks! Now!&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/library/x-agavipt1/"&gt;Part 1: Open a whole new world with Agavi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/library/x-agavipt2/"&gt;Part 2: Add forms and database support with Agavi and Doctrine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/library/x-agavipt3/"&gt;Part 3: Add authentication and administrative functions with Agavi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/library/x-agavipt4/"&gt;Part 4: Create an Agavi search engine with multiple output types including XML, RSS, or SOAP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/library/x-agavipt5/"&gt;Part 5: Add paging, file uploads, and custom input validators to your Agavi application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.veikko.fi/post/189176770</link><guid>http://blog.veikko.fi/post/189176770</guid><pubDate>Wed, 16 Sep 2009 09:58:52 +0300</pubDate><category>agavi</category><category>tips</category></item><item><title>Propel Developers' Held a Meeting</title><description>&lt;p&gt;Propel developers held an IRC meeting last night discussing the projects future. Amazingly many showed up and the discussion was active and fruitful.&lt;/p&gt;

&lt;p&gt;Read &lt;a href="http://propel.phpdb.org/trac/wiki/Users/News/MinutesSept10Meeting"&gt;the log at Propel Wiki&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/185115463</link><guid>http://blog.veikko.fi/post/185115463</guid><pubDate>Fri, 11 Sep 2009 09:10:06 +0300</pubDate></item><item><title>Say It!</title><description>&lt;h1&gt;Disqus Comments&lt;/h1&gt;

&lt;p&gt;Integrating &lt;a href="http://disqus.com"&gt;Disqus&lt;/a&gt; commenting system to my Tumblr blog was ridiculously easy. Just have to figure out why the comment form completely breaks my design :)&lt;/p&gt;</description><link>http://blog.veikko.fi/post/83505298</link><guid>http://blog.veikko.fi/post/83505298</guid><pubDate>Wed, 04 Mar 2009 19:07:30 +0200</pubDate><category>nonsense</category></item><item><title>Be Careful with PHP's version_compare</title><description>&lt;h1&gt;Be Careful with PHP&amp;#8217;s version_compare&lt;/h1&gt;

&lt;pre class="sh_php"&gt;
var_dump(version_compare("5.2.8-0.dotdeb.1", "5.2.8", "&amp;lt;="));
&lt;/pre&gt;

&lt;p&gt;Expected result: &lt;span style="color: blue"&gt;&lt;code&gt;bool(true)&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Actual result: &lt;span style="color: blue"&gt;&lt;code&gt;bool(false)&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The moral of the story: use &lt;span style="color: blue"&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;/span&gt; or &lt;span style="color: blue"&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;&lt;/span&gt;.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/83110343</link><guid>http://blog.veikko.fi/post/83110343</guid><pubDate>Tue, 03 Mar 2009 13:33:48 +0200</pubDate><category>tips</category><category>php</category></item><item><title>Installing a Project-local Propel</title><description>&lt;h1&gt;Installing a Project-local Propel&lt;/h1&gt;

&lt;p&gt;Installing &lt;a href="http://propel.phpdb.org/trac/"&gt;Propel&lt;/a&gt; is often seen as a difficult task. Official installion instructions recommend installing via Pear and say more initial work is requireq to install it manually. I usually advice not to use global Pear installations but install everything per project because it gives you better control and you are able to use different versions of libraries for different project. This article shows you how easy it actually is to have a project-local installation of Propel 1.3.&lt;/p&gt;

&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://phing.info/trac/"&gt;Phing&lt;/a&gt; 2.2.x (and, thus, Pear)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Phing is the only exception to my &amp;#8220;no pear installations&amp;#8221; rule. It can be installed per project but I see Phing as a development tool you can have globally on your development machine.&lt;/p&gt;

&lt;h2&gt;Suggested Directory Layout&lt;/h2&gt;

&lt;pre&gt;
/            project root
  dev/       development-time files (docs, database schemas, code templates etc.)
    db/      database development files (schema.xml, diagrams, docs etc.)
    libs/    development-time libraries
  libs/      runtime libraries (3rd party)
&lt;/pre&gt;

&lt;h2&gt;Getting Propel from the SVN&lt;/h2&gt;

&lt;p&gt;I recommend fetching Propel directly from the SVN repository simply because I see that as the easiest choice and you have full control of which version to pick. Also, should you ever want to upgrade to a newer revision (maybe there is a bugfix that isn&amp;#8217;t officially released yet), you can just retrieve it from the repository. Personally I have 3rd party libraries set up as svn:external where possible but we don&amp;#8217;t go into that in this article.&lt;/p&gt;

&lt;p&gt;Propel is split into two components - generator and runtime libraries and we&amp;#8217;ll keep those two appart. So, in your project root execute following SVN commands:&lt;/p&gt;

&lt;pre&gt;
svn export &lt;a href="http://svn.phpdb.org/propel/branches/1.3/generator"&gt;http://svn.phpdb.org/propel/branches/1.3/generator&lt;/a&gt; dev/libs/propel

svn export &lt;a href="http://svn.phpdb.org/propel/branches/1.3/runtime/classes/propel"&gt;http://svn.phpdb.org/propel/branches/1.3/runtime/classes/propel&lt;/a&gt; libs/propel
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;And that is it.&lt;/strong&gt; YES, I mean it!&lt;/p&gt;

&lt;p&gt;Propel is now ready to be used. You don&amp;#8217;t need to set &lt;code&gt;PATH&lt;/code&gt; or &lt;code&gt;include_path&lt;/code&gt;, you don&amp;#8217;t need to copy executables anywhere and you don&amp;#8217;t have to modify a single file.&lt;/p&gt;

&lt;h2&gt;Building a Propel Project&lt;/h2&gt;

&lt;p&gt;Create your &lt;code&gt;schema.xml&lt;/code&gt;, &lt;code&gt;runtime-conf.xml&lt;/code&gt; and &lt;code&gt;build.properties&lt;/code&gt; files in &lt;code&gt;dev/db&lt;/code&gt;. To build your project go to your project root and run&lt;/p&gt;

&lt;pre&gt;
dev/libs/propel/bin/propel-gen dev/db
&lt;/pre&gt;

&lt;p&gt;&amp;#8230; and whatch Propel do its magic. Propel creates output files into ´dev/db/build/´&lt;/p&gt;

&lt;h2&gt;Fine-tuning The Building Process&lt;/h2&gt;

&lt;p&gt;You can control where Propel puts the output with a few &lt;code&gt;build.properties&lt;/code&gt; directives. Here&amp;#8217;s an example that probably needs no explanation.&lt;/p&gt;

&lt;pre&gt;
#relative to propel-gen script
propel.output.dir = ../../..
propel.php.dir = ${propel.output.dir}/app/lib/propel
propel.phpconf.dir = ${propel.output.dir}/dev/db/config
propel.sql.dir = ${propel.output.dir}/dev/db/sql
&lt;/pre&gt;

&lt;h2&gt;What About Runtime?&lt;/h2&gt;

&lt;p&gt;Yeah, you got me there - there&amp;#8217;s still one thing you need to take care of before everything &amp;#8220;just works&amp;#8221;.&lt;/p&gt;

&lt;pre class="sh_php"&gt;
//propel runtime + path to your om classes
$path = '/my/project/libs' . PATH_SEPARATOR . '/my/project/app/lib/propel';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
&lt;/pre&gt;</description><link>http://blog.veikko.fi/post/82466126</link><guid>http://blog.veikko.fi/post/82466126</guid><pubDate>Sun, 01 Mar 2009 10:11:00 +0200</pubDate><category>tips</category><category>propel</category></item><item><title>Agavi 1.0.0 Beta 8 Includes a Critical Security Fix</title><description>&lt;h1&gt;Agavi 1.0.0 Beta 8 Includes a Critical Security Fix&lt;/h1&gt;

&lt;p&gt;A new &lt;a href="http://agavi.org"&gt;Agavi&lt;/a&gt; 1.0.0 Beta 8 was released late yesterday (European time). As usual, the new version contains several improvements and bug fixes but &lt;strong&gt;also a fix to a critical cross-site scripting vulnerability&lt;/strong&gt; described in &lt;a href="http://trac.agavi.org/ticket/1019"&gt;&lt;a href="http://trac.agavi.org/ticket/1019"&gt;http://trac.agavi.org/ticket/1019&lt;/a&gt;&lt;/a&gt;. The vulnerability actually affects, as far as we know, only Internet Explorer 6 and 7 which fail to encode URL according to standards.&lt;/p&gt;

&lt;h2&gt;Affected versions:&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Agavi 0.11 up to and including 0.11.6-RC2&lt;/li&gt;
&lt;li&gt;Agavi 1.0 up to and including 1.0.0-beta7&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Solutions&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;Upgrade to 0.11.6 or 1.0.0 Beta 8&lt;/li&gt;
&lt;li&gt;Patch your Agavi with a hot fix attached to the &lt;a href="http://trac.agavi.org/ticket/1019"&gt;ticket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use one of the workarounds described in the ticket.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.veikko.fi/post/75810346</link><guid>http://blog.veikko.fi/post/75810346</guid><pubDate>Thu, 05 Feb 2009 09:28:00 +0200</pubDate><category>agavi</category><category>security</category></item><item><title>Agavi Tip: Automatic Output of Validation Errors</title><description>&lt;h1&gt;Agavi Tip: Automatic Output of Validation Errors&lt;/h1&gt;

&lt;p&gt;I decided today to stop printing my validation error messages manually in the template. I knew that Form Population Filter (one of Agavi&amp;#8217;s many excellent features also referred to as &lt;em&gt;FPF&lt;/em&gt;) could be used to inject error messages into the HTML form next to erroneous fields but I want my error messages above the form. Once again &lt;a href="http://blog.wombert.de"&gt;David&lt;/a&gt; was there to help me and with a few iterations of trial and error he offered a working solution for me. And the solution was so simple and nice that I just had to blog it.&lt;/p&gt;

&lt;h2&gt;Filter Configuration&lt;/h2&gt;

&lt;p&gt;global_filters.xml&lt;/p&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;filter name="FormPopulationFilter" class="AgaviFormPopulationFilter"&amp;gt;

  &amp;lt;ae:parameter name="methods"&amp;gt;
    &amp;lt;ae:parameter&amp;gt;write&amp;lt;/ae:parameter&amp;gt;
  &amp;lt;/ae:parameter&amp;gt;
  
  &amp;lt;ae:parameter name="output_types"&amp;gt;
    &amp;lt;ae:parameter&amp;gt;html&amp;lt;/ae:parameter&amp;gt;
  &amp;lt;/ae:parameter&amp;gt;

  &amp;lt;ae:parameter name="error_messages"&amp;gt;
    &amp;lt;ae:parameter name="self::${htmlnsPrefix}form"&amp;gt;
    &amp;lt;ae:parameter name="location"&amp;gt;before&amp;lt;/ae:parameter&amp;gt;
    &amp;lt;ae:parameter name="container"&amp;gt;&amp;lt;![CDATA[&amp;lt;div class="errors"&amp;gt;${errorMessages}&amp;lt;/div&amp;gt;]]&amp;gt;&amp;lt;/ae:parameter&amp;gt;
    &amp;lt;ae:parameter name="markup"&amp;gt;&amp;lt;![CDATA[&amp;lt;p class="error"&amp;gt;${errorMessage}&amp;lt;/p&amp;gt;]]&amp;gt;&amp;lt;/ae:parameter&amp;gt;
    &amp;lt;/ae:parameter&amp;gt;
  &amp;lt;/ae:parameter&amp;gt;
  
&amp;lt;/filter&amp;gt;

&lt;/pre&gt;

&lt;p&gt;And that&amp;#8217;s it. FPF injects all error messages above your form. Each error message in its own paragraph and all paragraphs wrapped inside a &amp;lt;div&amp;gt;&lt;/p&gt;

&lt;h2&gt;Want More?&lt;/h2&gt;

&lt;p&gt;FPF can have different rules for different kinds of errors and with XPath you can inject them pretty much anywhere you want. See the Agavi&amp;#8217;s sample application for &lt;a href="http://trac.agavi.org/browser/branches/1.0/samples/app/config/global_filters.xml"&gt;more examples&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/75101068</link><guid>http://blog.veikko.fi/post/75101068</guid><pubDate>Mon, 02 Feb 2009 21:13:48 +0200</pubDate><category>agavi</category><category>tips</category></item><item><title>Running IE6, IE7 and IE8 Virtually</title><description>&lt;h1&gt;Running IE6, IE7 and IE8 Virtually&lt;/h1&gt;

&lt;p&gt;Now, this is not easy for me to admit but I just learned about an awesome Windows application by Microsoft.. from a &lt;a href="http://blog.wombert.de/post/72614373/running-ie6-ie7-and-ie8-on-your-mac"&gt;mac user&lt;/a&gt;  :)&lt;/p&gt;

&lt;h2&gt;Microsoft Virtual PC 2007 SP1 &amp;amp; Internet Explorer VPC Images&lt;/h2&gt;

&lt;p&gt;I cannot believe this has been under my radar all this time. Finally I can &lt;strong&gt;easily&lt;/strong&gt; have different windows/IE setups. The software is free (yes, I found it hard to believe too but it&amp;#8217;s true!) and Microsoft gives you ready-to-use virtual hard-drive images with operating system and IE ready.&lt;/p&gt;

&lt;p&gt;It has been a long time since I last praised Microsoft for doing something right. And now I&amp;#8217;m getting suspicious&amp;#8230; what&amp;#8217;s the catch here?!&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/Downloads/details.aspx?FamilyID=21eabb90-958f-4b64-b5f1-73d0a413c8ef&amp;amp;displaylang=en"&gt;Download&lt;/a&gt; Virtual PC 2007 setup.exe, execute it and enjoy the no-reboot-required installation (yet another amazing thing).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=28C97D22-6EB8-4A09-A7F7-F6C7A1F000B5&amp;amp;displaylang=en"&gt;Download&lt;/a&gt; one or more hard-drive images, execute and select a directory where you want the image to be extracted.&lt;/li&gt;
&lt;li&gt;Start Virtual PC 2007 and create a new virtual machine. Use the extracted hard-drive image.&lt;/li&gt;
&lt;li&gt;Boot up the virtual machine and enjoy the IE experience&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;P.S. Like the &lt;a href="http://blog.mozmonkey.com/2008/vpc-ie6-ie7-ie8-on-mac-os-x/"&gt;original post&lt;/a&gt; describes you can use virtual images provided by MS with other operating systems / virtual machine hosts too.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/73204624</link><guid>http://blog.veikko.fi/post/73204624</guid><pubDate>Mon, 26 Jan 2009 13:34:00 +0200</pubDate><category>tips</category><category>web development</category></item><item><title>Agavi 1.0.0 beta 7 released!</title><description>&lt;h1&gt;Agavi 1.0.0 Beta 7&lt;/h1&gt;

&lt;p&gt;Out of many changes there are two (or actually three) I want to emphasise because they may be backwards compatibility breaks for someone.&lt;/p&gt;

&lt;h2&gt;Default View Security Fixes&lt;/h2&gt;

&lt;p&gt;Two separate changes have been made to action&amp;#8217;s default view handling to ensure strict security.&lt;/p&gt;

&lt;p&gt;To make sure a developer doesn&amp;#8217;t use unvalidated input data by mistake global unvalidated request data is locked during action and view execution. However, before 1.0.0 beta 7 it was possible to access the global request data in &lt;code&gt;Action::getDefaultViewName()&lt;/code&gt;. This has now been fixed and anyone using the global request will be punished severely with an exception. Mind you, it has always been recommended that no application logic is put into &lt;code&gt;getDefaultView()&lt;/code&gt;. It should just return the default view name for the action.&lt;/p&gt;

&lt;p&gt;It was also recently discovered that the strict validation mode (default mode in Agavi 1.0) wasn&amp;#8217;t working as it is supposed to when an action didn&amp;#8217;t provide an execute method for the current request and the default view was used. In this case the request data was given to the view unfiltered which is against the strict validation mode principles.&lt;/p&gt;

&lt;h2&gt;PHP 5.2.8 Requirement (conditional)&lt;/h2&gt;

&lt;p&gt;Due to issues with magic quotes in PHP&amp;#8217;s earlier versions and the fact that making Agavi bullet proof in all situations is beginning to be a maintenance nightmare it was decided to require PHP 5.2.8 if magic_quotes_gpc is ON. I&amp;#8217;ll repeat: &lt;strong&gt;Agavi requires PHP 5.2.8 ONLY if magic_quotes_gpc is enabled on your server.&lt;/strong&gt; If it&amp;#8217;s not you can still use Agavi with PHP 5.2.0 or later (5.1.3 with Agavi 0.11).&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://blog.agavi.org/post/69709059/agavi-1-0-0-beta-7-released"&gt;Agavi Blog&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://trac.agavi.org/browser/tags/1.0.0beta7/RELEASE_NOTES"&gt;1.0.0 Beta 7 Release Notes&lt;/a&gt;
&lt;/p&gt;</description><link>http://blog.veikko.fi/post/69754879</link><guid>http://blog.veikko.fi/post/69754879</guid><pubDate>Sun, 11 Jan 2009 15:41:15 +0200</pubDate><category>agavi</category></item><item><title>Agavi Tip: Validation Gotchas</title><description>&lt;h1&gt;Agavi Validation Gotchas&lt;/h1&gt;

&lt;p&gt;Agavi&amp;#8217;s input validation system is extremely versatile and even people with long history with Agavi - me for example - sometimes struggle to get their head around it.
So I decided to put down a few gotchas. Here goes&amp;#8230;&lt;/p&gt;

&lt;h2&gt;Validators Can Be Grouped&lt;/h2&gt;

&lt;p&gt;You can use AgaviAndValidator, AgaviOrValidator and AgaviXorValidator to group several validators.&lt;/p&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;validator class="or"&amp;gt;
  &amp;lt;validators&amp;gt;
    &amp;lt;validator class="email" required="false" &amp;gt;
      &amp;lt;arguments&amp;gt;
        &amp;lt;argument&amp;gt;email&amp;lt;/argument&amp;gt;
      &amp;lt;/arguments&amp;gt;
    &amp;lt;/validator&amp;gt;
    &amp;lt;validator class="MyPhoneNumberValidator" required="false" &amp;gt;
      &amp;lt;arguments&amp;gt;
        &amp;lt;argument&amp;gt;phone&amp;lt;/argument&amp;gt;
      &amp;lt;/arguments&amp;gt;
    &amp;lt;/validator&amp;gt;
  &amp;lt;/validators&amp;gt;
  &amp;lt;errors&amp;gt;
    &amp;lt;error&amp;gt;Please provide email or phone&amp;lt;/error&amp;gt;
  &amp;lt;/errors&amp;gt;
&amp;lt;/validator&amp;gt;

&lt;/pre&gt;

&lt;h2&gt;Validator Can Depend on Another Validator&lt;/h2&gt;

&lt;p&gt;Quite often you only want validate input B only if the user provided input A. Agavi makes this simple:&lt;/p&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;validator ... required="false" provides="street_set"&amp;gt;
  &amp;lt;arguments base="contact"&amp;gt;
    &amp;lt;argument&amp;gt;Street&amp;lt;/argument&amp;gt;
  &amp;lt;/arguments&amp;gt;
&amp;lt;/validator&amp;gt;

&amp;lt;validator ... required="true" depends="contact[street_set]"&amp;gt;
  &amp;lt;arguments base="contact"&amp;gt;
    &amp;lt;argument&amp;gt;Zip&amp;lt;/argument&amp;gt;
  &amp;lt;/arguments&amp;gt;
&amp;lt;/validator&amp;gt;

&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; argument&amp;#8217;s &lt;code&gt;base&lt;/code&gt; attribute affects also provides/depends attributes (see example above) &lt;strong&gt;!!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Pimp My Error Messages&lt;/h2&gt;

&lt;p&gt;A validator can throw different error message based on what went wrong and &lt;strong&gt;error messages can be translated on the fly&lt;/strong&gt;. Error message options vary between validators. See API docs for more.&lt;/p&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;validator class="string" translation_domain="default.errors"&amp;gt;
  &amp;lt;arguments&amp;gt;
    &amp;lt;argument&amp;gt;my_input&amp;lt;/argument&amp;gt;
  &amp;lt;/arguments&amp;gt;
  &amp;lt;errors&amp;gt;
    &amp;lt;error for="required"&amp;gt;Please fill this input&amp;lt;/error&amp;gt;
    &amp;lt;error for="max"&amp;gt;Please keep it shorter than 40 characters&amp;lt;/error&amp;gt;
  &amp;lt;/errors&amp;gt;
  &amp;lt;ae:parameters&amp;gt;
    &amp;lt;ae:parameter name="max"&amp;gt;40&amp;lt;/ae:parameter&amp;gt;
  &amp;lt;/ae:parameters&amp;gt;
&amp;lt;/validator&amp;gt;

&lt;/pre&gt;

&lt;h2&gt;Validating Array Inputs&lt;/h2&gt;

&lt;h3&gt;&amp;lt;input name=&amp;#8221;rows[Id]&amp;#8221;&lt;/h3&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;arguments base="rows"&amp;gt;
    &amp;lt;argument&amp;gt;Id&amp;lt;/argument&amp;gt;
&amp;lt;/arguments&amp;gt;

&amp;lt;!-- or --&amp;gt;

&amp;lt;arguments&amp;gt;
    &amp;lt;argument&amp;gt;rows[Id]&amp;lt;/argument&amp;gt;
&amp;lt;/arguments&amp;gt;

&lt;/pre&gt;

&lt;h3&gt;&amp;lt;input name=&amp;#8221;rows[1][Id]&amp;#8221;&lt;/h3&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;arguments base="rows[]"&amp;gt;
    &amp;lt;argument&amp;gt;Id&amp;lt;/argument&amp;gt;
&amp;lt;/arguments&amp;gt;

&lt;/pre&gt;

&lt;h3&gt;&amp;lt;input name=&amp;#8221;rows[]&amp;#8221;&lt;/h3&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;arguments base="rows[]"&amp;gt;
    &amp;lt;argument/&amp;gt;
&amp;lt;/argument&amp;gt;

&lt;/pre&gt;

&lt;h2&gt;Validator Can Normalize And Export Combined Values&lt;/h2&gt;

&lt;p&gt;This example shows how to get AgaviDateValidator to validate a compound value. But that&amp;#8217;s not all! It&amp;#8217;ll even export a proper timestamp for you to use in your application code.&lt;/p&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;validator class="AgaviDateTimeValidator"&amp;gt;
    &amp;lt;arguments&amp;gt;
        &amp;lt;argument name="AgaviDateDefinitions::DATE"&amp;gt;day&amp;lt;/argument&amp;gt;
        &amp;lt;argument name="AgaviDateDefinitions::MONTH"&amp;gt;month&amp;lt;/argument&amp;gt;
        &amp;lt;argument name="AgaviDateDefinitions::YEAR"&amp;gt;year&amp;lt;/argument&amp;gt;
    &amp;lt;/arguments&amp;gt;
    &amp;lt;errors&amp;gt;
        &amp;lt;error&amp;gt;Validation error&amp;lt;/error&amp;gt;
    &amp;lt;/errors&amp;gt;
    &amp;lt;ae:parameters&amp;gt;
        &amp;lt;ae:parameter name="export"&amp;gt;MyDatestamp&amp;lt;/ae:parameter&amp;gt;
    &amp;lt;/ae:parameters&amp;gt;
&amp;lt;/validator&amp;gt;

&lt;/pre&gt;

&lt;h2&gt;Remember to Validate ALL Input&lt;/h2&gt;

&lt;p&gt;Validation is not limited to GET/POST input parameters but HTTP headers and cookies can (&lt;strong&gt;and should&lt;/strong&gt;) be validated too. Use the source attribute to tell the validator where to get the data from.&lt;/p&gt;

&lt;pre class="sh_xml"&gt;

&amp;lt;validator ... source="headers"&amp;gt; &amp;lt;argument&amp;gt;REFERER&amp;lt;/argument&amp;gt;

&lt;/pre&gt;

&lt;h2&gt;Validator is ran only if the parameter is non-empty.&lt;/h2&gt;

&lt;p&gt;By default the validator base class AgaviValidator checks that all the arguments are set before executing the actual validation. If the input value is empty or non-existent but required error is thrown. But if required attribute is set to False the validation just quietly continues to another validator. Normally this is not a problem but you might want to code a custom validator that exports a default value for empty parameters. In this case you need to override AgaviValidator&amp;#8217;s &lt;code&gt;checkAllArgumentsSet()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Did I forget something?&lt;/h2&gt;

&lt;p&gt;Join #agavi IRC channel and hassle me there or send email to &lt;a href="mailto:veikko@veikko.fi"&gt;veikko@veikko.fi&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/68983308</link><guid>http://blog.veikko.fi/post/68983308</guid><pubDate>Wed, 07 Jan 2009 21:18:00 +0200</pubDate><category>agavi</category><category>tips</category></item><item><title>Agavi Tip: Checking Validation Results</title><description>&lt;h1&gt;Agavi Tip: Checking Validation Results&lt;/h1&gt;

&lt;p&gt;Normally when an input validator fails you&amp;#8217;ll just want to show the form again and let FormPopulationFilter do its magic (you do know you can it have re-populate the form &lt;strong&gt;and&lt;/strong&gt; inject error messages into the form, don&amp;#8217;t you?-). But occasionally you want to decide the next move based on what validator failed. With Agavi 1.0 getting validation incidents of a named validator is this simple:&lt;/p&gt;

&lt;pre class="sh_php"&gt;
public function handleError(AgaviRequestDataHolder $rd)
{
  $vm = $this-&amp;gt;container-&amp;gt;getValidationManager();
  if (count($vm-&amp;gt;getReport()-&amp;gt;getValidatorResult('my_special_validator')-&amp;gt;getIncidents())) {
    return 'CriticalError';
  }
  else {
    return 'Error';
  }
  
}
&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; that AgaviValidationValidatorResult was missing from the core autoload.xml in 1.0 Beta 6. This has been fixed in the SVN If you aren&amp;#8217;t using the bleeding edge version add the following line to your &lt;code&gt;config/autoload.xml&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="sh_xml"&gt;
&amp;lt;autoload name="AgaviValidationValidatorResult"&amp;gt;%core.agavi_dir%/validator/AgaviValidationValidatorResult.class.php&amp;lt;/autoload&amp;gt; 
&lt;/pre&gt;</description><link>http://blog.veikko.fi/post/68773061</link><guid>http://blog.veikko.fi/post/68773061</guid><pubDate>Tue, 06 Jan 2009 23:25:00 +0200</pubDate><category>agavi</category><category>tips</category></item><item><title>Agavi Debug Tools now supports Propel query logging (both...</title><description>&lt;img src="http://24.media.tumblr.com/8wIjDX8qOid572mwDzIv0tZro1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Agavi Debug Tools now supports &lt;a href="http://propel.phpdb.org"&gt;Propel&lt;/a&gt; query logging (both FirePHP and HTML output). Just configure Propel to use DebugPDO and AdtFilter to use AdtPropelDataSource. Nothing else required.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/68560026</link><guid>http://blog.veikko.fi/post/68560026</guid><pubDate>Mon, 05 Jan 2009 22:41:09 +0200</pubDate><category>agavi</category><category>tips</category><category>php</category></item><item><title>Agavi 1.0.0 Beta 6</title><description>&lt;h1&gt;Agavi 1.0.0 Beta 6 - Even More Secure&lt;/h1&gt;

&lt;h2&gt;Default: Strict Validation ALWAYS&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.agavi.org"&gt;Agavi&lt;/a&gt; has a very special input validation system which, by default, will not let your application use any unvalidated input data. And this doesn&amp;#8217;t mean only POST or GET parameters in HTTP world but also &lt;strong&gt;cookies&lt;/strong&gt; and &lt;strong&gt;headers&lt;/strong&gt;. Remember, those too are user input and must be considered insecure.&lt;/p&gt;

&lt;p&gt;This strict validation mode has been the default setting for production environment for quite some time already but after Agavi was &lt;a href="http://blog.agavi.org/post/58189391/false-agavi-vulnerability-reports"&gt;blamed&lt;/a&gt; for somebody&amp;#8217;s poor input validation it was made default for development environments too. It had already been discussed earlier because different defaults for different environments was sometimes confusing and caused applications to break when moved to production.&lt;/p&gt;

&lt;h2&gt;Production-ready Exception Templates&lt;/h2&gt;

&lt;p&gt;Because people seem to be too &lt;a href="http://www.google.fi/search?q=agavi+exception"&gt;lazy&lt;/a&gt; to configure exception templates for production use a new set of default templates was added to Agavi 1.0.0 Beta 6.&lt;/p&gt;

&lt;p&gt;Download Agavi: &lt;a href="http://www.agavi.org/download"&gt;http://www.agavi.org/download&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.veikko.fi/post/59493548</link><guid>http://blog.veikko.fi/post/59493548</guid><pubDate>Tue, 25 Nov 2008 21:55:00 +0200</pubDate><category>agavi</category><category>php</category><category>security</category></item><item><title>Thanks to Harald “digitarald” Kirschner ADT’s...</title><description>&lt;img src="http://25.media.tumblr.com/8wIjDX8qOgfsk949WGf9HuVNo1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Thanks to &lt;a href="http://digitarald.de"&gt;Harald “digitarald” Kirschner&lt;/a&gt; ADT’s FirePHP output is now 174% nicer. And a few bugs was fixed too. Check out ADT at &lt;a href="http://adt.projectbin.org/."&gt;http://adt.projectbin.org/.&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.veikko.fi/post/60254039</link><guid>http://blog.veikko.fi/post/60254039</guid><pubDate>Tue, 18 Nov 2008 09:51:00 +0200</pubDate><category>agavi</category><category>php</category></item><item><title>Kübler-Ross Model</title><description>&lt;h1&gt;Five Steps to Agile Development&lt;/h1&gt;

&lt;ol&gt;&lt;li&gt;Denial&lt;/li&gt;
&lt;li&gt;Anger&lt;/li&gt;
&lt;li&gt;Bargaining&lt;/li&gt;
&lt;li&gt;Depression&lt;/li&gt;
&lt;li&gt;Acceptance&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Elisabeth Kübler-Ross&amp;#8217; &lt;a href="http://en.wikipedia.org/wiki/Kubler-Ross_model"&gt;Five Stages of Grief&lt;/a&gt; describes how people handle grief and tragedy, especially when diagnosed with a terminal illness. &lt;a href="http://agileproductdesign.com/blog/emerging_best_agile_ux_practice.html"&gt;Apparently&lt;/a&gt; these also apply to agile development and user experience practice &lt;code&gt;:D&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Originally blogged/linked by &lt;a href="http://agileweb.org/"&gt;&lt;a href="http://agileweb.org/"&gt;http://agileweb.org/&lt;/a&gt;&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/60147695</link><guid>http://blog.veikko.fi/post/60147695</guid><pubDate>Mon, 17 Nov 2008 20:01:00 +0200</pubDate></item><item><title>Happy Birthday to Me</title><description>&lt;p&gt;28 (0x1c) years today.&lt;/p&gt;</description><link>http://blog.veikko.fi/post/60051940</link><guid>http://blog.veikko.fi/post/60051940</guid><pubDate>Mon, 17 Nov 2008 06:23:08 +0200</pubDate><category>personal</category><category>nonsense</category></item></channel></rss>

