<?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:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description>Symfony Guru at opensky.com.
Discussing web development, Symfony and fatherhood.</description><title>Kris Wallsmith</title><generator>Tumblr (3.0; @kriswallsmith)</generator><link>http://kriswallsmith.net/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/KrisWallsmith" /><feedburner:info uri="kriswallsmith" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><item><title>Symfony2 Security Voters</title><description>&lt;p&gt;I answered &lt;a href="http://stackoverflow.com/questions/8879221/dynamically-adding-roles-to-a-user/8883269" target="_blank"&gt;this question&lt;/a&gt; on StackOverflow today that is probably worth repeating
here. The poster was asking how to implement subscription-based authorization
logic in Symfony2. I imagine he models his problem something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Subscription
{
    const SECURED_AREA_FOO = 'FOO';
    const SECURED_AREA_BAR = 'BAR';

    // ...

    /** @ManyToOne(targetEntity="User", inversedBy="subscriptions") */
    public $user;

    /** @Column */
    public $securedArea;

    /** @Column(type="date") */
    public $start;

    /** @Column(type="date") */
    public $end;

    public function isActive()
    {
        $now = new DateTime();

        return $now &gt;= $this-&gt;start &amp;&amp; $now &lt; $this-&gt;end;
    }

    // ...
}

class User implements UserInterface
{
    // ...

    public function getRoles()
    {
        $roles = $this-&gt;roles;

        foreach ($this-&gt;subscriptions as $subscription) {
            if ($subscription-&gt;isActive()) {
                $roles[] = 'ROLE_SUBSCRIPTION_'.$subscription-&gt;securedArea;
            }
        }

        return $roles;
    }

    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;He may then configure access control in his &lt;code&gt;security.yml&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;access_control:
    - { path: "^/sections/foo", roles: [ ROLE_SUBSCRIPTION_FOO ] }
    - { path: "^/sections/bar", roles: [ ROLE_SUBSCRIPTION_BAR ] }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This solution is nice enough, but we can do better. As the poster pointed out
when someone suggested this solution, it doesn’t make sense to hydrate all of
a user’s subscription objects (some of which may have expired &lt;em&gt;years&lt;/em&gt; ago)
just to fetch a string value. On top of that, fetching all of these objects
every request is a waste of resources because the system will only be checking
for the existence of one of them in any given request.&lt;/p&gt;

&lt;p&gt;This authorization logic can be implemented much more lightly by encapsulating
it in a custom security voter.&lt;/p&gt;

&lt;h2&gt;Voters&lt;/h2&gt;

&lt;p&gt;When questions about authorization are asked in Symfony2, the answer is
arrived at by a process of voting. For example, when someone requests an URL
that matches a configured &lt;code&gt;access_control&lt;/code&gt; rule, a vote is held to decide
whether to allow or deny access to that resource.&lt;/p&gt;

&lt;p&gt;This voting process is similar in some ways to a US appeals court. There are a
certain numbers of judges presiding over any given proceeding and in the end
a decision is rendered. Occasionally judges recuse themselves from a case for
this or that reason.&lt;/p&gt;

&lt;p&gt;The authorization portion of the Symfony2 security component also includes a
panel of judges called voters. These voters each have a say whenever questions
of authorization come up in your application. Not every voter will have an
opinion on every decision; some will abstain.&lt;/p&gt;

&lt;p&gt;There are two basic types of votes: whether a user is granted a certain
security attribute (i.e. the &lt;code&gt;ROLE_USER&lt;/code&gt; attribute) and whether a user is
granted a certain security attribute for a certain object (i.e. the &lt;code&gt;EDIT&lt;/code&gt;
attribute on blog post X). Each voter can be tuned to only chime in when
certain votes are held. For example, you could write a voter that only
participates when considering users with Gmail addresses.&lt;/p&gt;

&lt;p&gt;In this particular case, we want to create a voter that only chimes in when
questions regarding access to areas secured by subscriptions are raised. We
can signify this by creating a new set of attributes that start with the
string &lt;code&gt;SUBSCRIPTION_&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;access_control:
    - { path: "^/sections/foo", roles: [ SUBSCRIPTION_FOO ] }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This configuration proposes that only users with access to the security
attribute &lt;code&gt;SUBSCRIPTION_FOO&lt;/code&gt; should be granted access to any URL that starts
with &lt;code&gt;/sections/foo&lt;/code&gt;. Since there are no voters configured to evaluate this
particular set of attributes, access with always be denied. But that is solved
easy enough by creating a custom security voter.&lt;/p&gt;

&lt;p&gt;This voter will look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class SubscriptionVoter implements VoterInterface
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this-&gt;em = $em;
    }

    public function supportsAttribute($attribute)
    {
        return 0 === strpos($attribute, 'SUBSCRIPTION_');
    }

    public function supportsClass($class)
    {
        return true;
    }

    public function vote(TokenInterface $token, $object, array $attributes)
    {
        $user = $token-&gt;getUser();

        foreach ($attributes as $attribute) {
            if ($this-&gt;supportsAttribute($attribute)) {
                $securedArea = substr($attribute, strlen('SUBSCRIPTION_'));

                // use the entity manager to query for active
                // subscriptions that connect the current user to the
                // requested secured area

                return $success ? VoterInterface::ACCESS_GRANTED : VoterInterface::ACCESS_DENIED;
            }
        }

        return VoterInterface::ACCESS_ABSTAIN;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And be configured in the service container something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;services:
    subscription_voter:
        class: SubscriptionVoter
        public: false
        arguments:
            - @doctrine.orm.entity_manager
        tags:
            - { name: security.voter }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that’s all there is to it. You have encapsulated your custom authorization
logic in one clean class and added it to the Symfony2 security layer.&lt;/p&gt;

&lt;h2&gt;Other Applications&lt;/h2&gt;

&lt;p&gt;This is an example of one specific application of security voters, but there
are many more. If you are struggling with how to implement some special access
control logic that doesn’t fit nicely into either security roles or the
security component’s ACL, consider creating a custom voter.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/hu3UFx5MZgQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/hu3UFx5MZgQ/15994931191</link><guid isPermaLink="false">http://kriswallsmith.net/post/15994931191</guid><pubDate>Mon, 16 Jan 2012 21:14:58 -0800</pubDate><category>Symfony2</category><category>security</category><feedburner:origLink>http://kriswallsmith.net/post/15994931191</feedburner:origLink></item><item><title>Twig Node Visitors (Part 2)</title><description>&lt;blockquote&gt;
  &lt;p&gt;This is the second in a series of articles on Twig node visitors. Please read
  &lt;a href="http://kriswallsmith.net/post/13551737951/getting-twiggy-with-it-node-visitors" target="_blank"&gt;part one&lt;/a&gt; first.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Node visitors can be used for any number of things. The
&lt;code&gt;Twig_NodeVisitorInterface&lt;/code&gt; interface itself is just three methods:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;interface Twig_NodeVisitorInterface
{
    /**
     * @return Twig_NodeInterface The modified node
     */
    function enterNode(Twig_NodeInterface $node, Twig_Environment $env);

    /**
     * @return Twig_NodeInterface The modified node
     */
    function leaveNode(Twig_NodeInterface $node, Twig_Environment $env);

    /**
     * @return integer The priority level
     */
    function getPriority();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The interface is simple and powerful. It provides a mechanism for manipulating
nodes before a template is compiled down to a PHP class. It puts no
constraints on what it can be used for. In the Twig core there are node
visitors for escaping and optimization, both of which bear no semblance to
what we are going to do here.&lt;/p&gt;

&lt;p&gt;Our use case at OpenSky has to do with querying blocks of CMS content from the database
eagerly, based on what blocks have been included in the template using the
following function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{{ cms_block('header') }}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can accomplish this eager loading by using a node visitor to statically
analyze each template and stashing the CMS blocks it calls for. The first
method of the interface, &lt;code&gt;enterNode()&lt;/code&gt;, can be used to look at every node in
each template to see if it represents a call to this function.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
{
    if ($cmsBlock = $this-&gt;getCmsBlockKey($node)) {
        $this-&gt;cmsBlocks[] = $cmsBlock;
    }

    return $node;
}

// ...

private function getCmsBlockKey(Twig_NodeInterface $node)
{
    if ($node instanceof Twig_Node_Expression_Function
        &amp;&amp; 'cms_block' == $node-&gt;getAttribute('name')) {
        return $node-&gt;getNode('arguments')-&gt;getNode(0)-&gt;getAttribute('value');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This code looks at each node to see if it represents a call to the &lt;code&gt;cms_block&lt;/code&gt;
function and pushes the first argument (the name of the CMS block) to an
internal array for use later.&lt;/p&gt;

&lt;p&gt;After running this and debugging what was being stacked onto that array we
found a few issues. First, the visitor was not smart enough to crawl included
or imported templates and look for CMS blocks there. Second, the node visitor
was not being reset for each template so by the end of cache warmup all CMS
blocks called across the entire application were stacked on that internal
array.&lt;/p&gt;

&lt;p&gt;Solving the first issue meant adding a way to recursively crawl the graph of
each template’s children — a child being a call to either &lt;code&gt;{% include %}&lt;/code&gt; or
&lt;code&gt;{% import %}&lt;/code&gt; in our case. We did this by adding another internal stack:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
{
    if ($cmsBlock = $this-&gt;getCmsBlockKey($node)) {
        $this-&gt;cmsBlocks[] = $cmsBlock;
    } elseif ($templateName = $this-&gt;getIncludedTemplateName($node)) {
        $this-&gt;includes[] = $templateName;
    }

    return $node;
}

// ...

private function getIncludedTemplateName(Twig_NodeInterface $node)
{
    if ($node instanceof Twig_Node_Include || $node instanceof Twig_Node_Import) {
        return $node-&gt;getNode('expr')-&gt;getAttribute('value');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We solved the second issue by listening for the root node, an instance of
&lt;code&gt;Twig_Node_Module&lt;/code&gt;, and clearing the internal stacks when we leave that node:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
{
    if ($node instanceof Twig_Node_Module) {
        // todo: make these stacks available at runtime

        // reset
        $this-&gt;cmsBlocks = array();
        $this-&gt;includes  = array();
    }

    return $node;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We’re in pretty good shape at this point. We have built a node visitor that
collects the information necessary for eagerly querying our CMS for the blocks
that each template calls for. Now we just need to make this information
available at runtime, when the eager query needs to be executed.&lt;/p&gt;

&lt;p&gt;We’ll do this
in the next post by wrapping the &lt;code&gt;Twig_Node_Module&lt;/code&gt; in our own module node
that compiles down the a PHP class with the necessary public methods. Stay tuned!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/MtOa5ZuE5Jw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/MtOa5ZuE5Jw/15421960092</link><guid isPermaLink="false">http://kriswallsmith.net/post/15421960092</guid><pubDate>Fri, 06 Jan 2012 16:06:00 -0800</pubDate><category>twig</category><feedburner:origLink>http://kriswallsmith.net/post/15421960092</feedburner:origLink></item><item><title>Getting Twiggy With It: Node Visitors</title><description>&lt;p&gt;I am going to write about node visitors: one of the more obscure but powerful
concepts in Twig. To help make sense of it I will be using a simple, real
world example.&lt;/p&gt;

&lt;p&gt;At OpenSky we recently added a basic CMS to our site that allows us to make
edits to text without going through the hassle of editing a template and
redeploying the entire codebase. We added a module to our admin that manages
these CMS “blocks” as documents in MongoDB. Each document represents a block
and includes a unique, descriptive key and the text content. In our templates
we render these blocks using a simple Twig function. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{{ cms_block('welcome') }}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When rendering a template, Twig would come across this function and issue a
query to MongoDB for the &lt;code&gt;welcome&lt;/code&gt; document in the collection of CMS blocks.
Easy enough, right?&lt;/p&gt;

&lt;p&gt;Not quite. We would like to speckle these blocks all over pages across the
site: a paragraph here, a header there, an image over there, meta tags,
Facebook tags… We could be looking at adding a dozen or more queries to a
page for our little CMS, which is unacceptable.&lt;/p&gt;

&lt;h2&gt;Twig’s own Flux Capacitor&lt;/h2&gt;

&lt;p&gt;Imagine being able to look into the future to see what CMS blocks a template
was going to use and issue a single query to prefetch them all from the
database. That is exactly the sort of thing you can do by taking advantage of
the static compilation phase, when Twig converts your templates into optimized
PHP classes.&lt;/p&gt;

&lt;h2&gt;A Quick Primer on Twig Internals&lt;/h2&gt;

&lt;p&gt;Let’s take a step back and review some of the guts of Twig. I promise I’ll
return to &lt;em&gt;Back to the Future&lt;/em&gt; references later.&lt;/p&gt;

&lt;p&gt;Compilation of a template into a PHP class is a four step process:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Load&lt;/li&gt;
&lt;li&gt;Tokenize&lt;/li&gt;
&lt;li&gt;Parse&lt;/li&gt;
&lt;li&gt;Compile&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The first step involves an implementation of &lt;a href="https://github.com/fabpot/Twig/blob/master/lib/Twig/LoaderInterface.php" target="_blank"&gt;&lt;code&gt;Twig_LoaderInterface&lt;/code&gt;&lt;/a&gt;, of
which only one method is pertinent to us: &lt;code&gt;getSource()&lt;/code&gt;. This method accepts a
template name and returns the raw content of that template. In the case of the
default &lt;a href="https://github.com/fabpot/Twig/blob/master/lib/Twig/Loader/Filesystem.php" target="_blank"&gt;&lt;code&gt;Twig_Loader_Filesystem&lt;/code&gt;&lt;/a&gt; implementation, this boils down to a
simple call to &lt;code&gt;file_get_contents()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The second step, tokenizing the loaded source, is handled by an implementation
of &lt;a href="https://github.com/fabpot/Twig/blob/master/lib/Twig/LexerInterface.php" target="_blank"&gt;&lt;code&gt;Twig_LexerInterface&lt;/code&gt;&lt;/a&gt; which consists of one method, &lt;code&gt;tokenize()&lt;/code&gt;. If
you are having a hard time sleeping at night you can read up on &lt;a href="http://en.wikipedia.org/wiki/Lexical_analysis" target="_blank"&gt;lexical
analysis&lt;/a&gt; on Wikipedia. For the purpose of this article, you only need to
understand that the lexer converts what you’ve written in your template using
Twig’s grammar into a stream of simple PHP objects called tokens.&lt;/p&gt;

&lt;p&gt;In the third step the stream of tokens created by the lexer is parsed into a
multi-dimensional tree of nodes. This work is done by the &lt;a href="https://github.com/fabpot/Twig/blob/master/lib/Twig/Parser.php" target="_blank"&gt;parser&lt;/a&gt; in
cooperation with a collection of &lt;a href="https://github.com/fabpot/Twig/blob/master/lib/Twig/TokenParserInterface.php" target="_blank"&gt;token parsers&lt;/a&gt;. This is the extension
point you would hook into if you wanted to create a new &lt;code&gt;{% foo %}&lt;/code&gt; tag, a
topic outside the scope of this article.&lt;/p&gt;

&lt;p&gt;In the final step the node tree created by the parser is compiled into runtime
PHP code. Each node in the tree implements &lt;a href="https://github.com/fabpot/Twig/blob/master/lib/Twig/NodeInterface.php" target="_blank"&gt;&lt;code&gt;Twig_NodeInterface&lt;/code&gt;&lt;/a&gt;, which
includes a &lt;code&gt;compile()&lt;/code&gt; method that allows it to write arbitrary code to the
resulting template class.&lt;/p&gt;

&lt;h2&gt;Great Scott!&lt;/h2&gt;

&lt;p&gt;That description of the Twig engine was criminally brief, but it should give
you enough knowledge to understand where node visitors come in. After the
parser creates the node tree but before the tree is compiled into PHP code,
the parser recursively iterates over the tree and filters each node through
its registered node visitors. Each visitor has a chance to inspect every
single node in the tree, make changes, replace it with another, or even remove
it altogether. It’s using this tool that we are able to inspect each template
and magically anticipate what CMS blocks each template will need, before that
template is rendered.&lt;/p&gt;

&lt;h2&gt;Coming Soon…&lt;/h2&gt;

&lt;p&gt;Dive into code with a working example of a Twig node visitor.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/7yY4PKsEbMw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/7yY4PKsEbMw/13551737951</link><guid isPermaLink="false">http://kriswallsmith.net/post/13551737951</guid><pubDate>Wed, 30 Nov 2011 10:11:00 -0800</pubDate><category>twig</category><feedburner:origLink>http://kriswallsmith.net/post/13551737951</feedburner:origLink></item><item><title>Cancer</title><description>&lt;p&gt;I’ve been sitting on this for awhile and think I should share now.&lt;/p&gt;

&lt;p&gt;My wife of 7 years, partner of 10 and mother of my three young children was diagnosed with stage 4 breast cancer a few months ago. It’s been an extremely difficult fact to come to terms with. The diagnosis is serious, but we are very hopeful. She has just finished her third round of chemotherapy and the scans say all the marshmallows are shrinking. That news and the outpouring of support from our family, friends and colleagues adds up to a lot to be grateful for.&lt;/p&gt;

&lt;p&gt;If you pray, please pray for the complete eradication of cancer from Franya’s body. If you don’t pray, please send some happy thoughts our way.&lt;/p&gt;

&lt;p&gt;Anyway… this is why I’ve been relatively quiet lately, will only be at ZendCon for less than 24 hours and won’t be coming to Cologne for Symfony Day at all. I’m not leaving anything, I just have less time and energy to spread around.&lt;/p&gt;

&lt;p&gt;Blessings and protection,&lt;br/&gt;
Kris&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/Z0x-fB99wZI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/Z0x-fB99wZI/11589956631</link><guid isPermaLink="false">http://kriswallsmith.net/post/11589956631</guid><pubDate>Mon, 17 Oct 2011 16:32:00 -0700</pubDate><category>cancer</category><feedburner:origLink>http://kriswallsmith.net/post/11589956631</feedburner:origLink></item><item><title>My first passport...</title><description>&lt;p&gt;…has expired! I have stamps for these countries:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;The Bahamas&lt;/li&gt;
&lt;li&gt;France&lt;/li&gt;
&lt;li&gt;The Netherlands&lt;/li&gt;
&lt;li&gt;The British Virgin Islands&lt;/li&gt;
&lt;li&gt;Japan&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;What will the next 10 years will bring?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/FUZcJQztPB0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/FUZcJQztPB0/2977713267</link><guid isPermaLink="false">http://kriswallsmith.net/post/2977713267</guid><pubDate>Fri, 28 Jan 2011 09:32:25 -0800</pubDate><category>travel</category><feedburner:origLink>http://kriswallsmith.net/post/2977713267</feedburner:origLink></item><item><title>Old Glory</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_lcv1maaVAD1qzyw1go1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Old Glory&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/ORvmVuTViAM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/ORvmVuTViAM/2083045296</link><guid isPermaLink="false">http://kriswallsmith.net/post/2083045296</guid><pubDate>Fri, 03 Dec 2010 08:25:00 -0800</pubDate><feedburner:origLink>http://kriswallsmith.net/post/2083045296</feedburner:origLink></item><item><title>Unit Tests, Mocking, and PHPUnit 3.5's new Mock Builder</title><description>&lt;a href="http://engineering.shopopensky.com/post/unit-tests-mocking-and-phpunit-3-5s-new-mock-builder"&gt;Unit Tests, Mocking, and PHPUnit 3.5's new Mock Builder&lt;/a&gt;: &lt;p&gt;My latest tidbit of testing goodness, this time on the OpenSky engineering blog.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/vcFEu-e4b08" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/vcFEu-e4b08/1432753430</link><guid isPermaLink="false">http://kriswallsmith.net/post/1432753430</guid><pubDate>Fri, 29 Oct 2010 10:25:33 -0700</pubDate><category>PHPUnit</category><feedburner:origLink>http://kriswallsmith.net/post/1432753430</feedburner:origLink></item><item><title>Look Behind the "Feature Veil"</title><description>&lt;p&gt;I’ve been thinking about a decision Apple made awhile ago to allow free iOS
apps to offer in-app purchases. My recollection of their argument against
doing this is that users would be frustrated by downloading a free app only to
have to purchase something in-app to get it to work.&lt;/p&gt;

&lt;p&gt;Around the same time Apple decided to allow free apps to offer in-app
purchases, the App Store also began promoting each application’s “Top In-App
Purchases.” This feature is pretty silly (who cares?), but it’s positioned
prominently at the top of each app’s page.&lt;/p&gt;

&lt;p&gt;It seems clear that Apple’s intention here is to denote which apps ask you to
buy more stuff. This is a valid objective, but they’ve accomplished it in a
strange way. The feature, when taken at face value, appears to do something
unrelated.&lt;/p&gt;

&lt;p&gt;This particular “feature veil” is pretty easy to see through, but I’m guessing
the technique has been used before, by Apple and others, in less obvious
instances. Can you think of any?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/3DXz1Betfrw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/3DXz1Betfrw/1416097470</link><guid isPermaLink="false">http://kriswallsmith.net/post/1416097470</guid><pubDate>Wed, 27 Oct 2010 09:59:47 -0700</pubDate><category>Apple</category><feedburner:origLink>http://kriswallsmith.net/post/1416097470</feedburner:origLink></item><item><title>Who can find the jet lagged American?</title><description>&lt;img src="http://28.media.tumblr.com/tumblr_lawcmwOjlU1qzyw1go1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Who can find the jet lagged American?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/32ZyFeidOZM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/32ZyFeidOZM/1406270197</link><guid isPermaLink="false">http://kriswallsmith.net/post/1406270197</guid><pubDate>Tue, 26 Oct 2010 05:13:44 -0700</pubDate><category>sfdaycgn</category><feedburner:origLink>http://kriswallsmith.net/post/1406270197</feedburner:origLink></item><item><title>Keep a trim autoloader</title><description>&lt;p&gt;The symfony 1.4 autoloader works by scanning your PHP class files and
remembering where each class and interface is defined, so it can magically
load it when needed. This class-to-filename mapping is stored as an array in
your application’s cache directory.&lt;/p&gt;

&lt;p&gt;You can (and should) look at this array by opening this cache file in your
text editor from time to time:
&lt;code&gt;cache/%SF_APP%/%SF_ENVIRONMENT%/config/config_autoload.yml.php&lt;/code&gt;. Inside
you’ll see a big array with &lt;code&gt;// comment&lt;/code&gt; headers.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;?php
// auto-generated by sfAutoloadConfigHandler
// date: 2010/10/24 05:29:41
return array(

  // sfDoctrineGuardPlugin_lib
  'pluginsfguardgroupformfilter' =&gt; '/path/to/plugins/sfDoctrineGuardPlugin/lib/filter/doctrine/PluginsfGuardGroupFormFilter.class.php',
  'pluginsfguardpermissionformfilter' =&gt; '/path/to/plugins/sfDoctrineGuardPlugin/lib/filter/doctrine/PluginsfGuardPermissionFormFilter.class.php',
  'pluginsfguarduserformfilter' =&gt; '/path/to/plugins/sfDoctrineGuardPlugin/lib/filter/doctrine/PluginsfGuardUserFormFilter.class.php',

  // ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A few things to look for in this file:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;You should &lt;strong&gt;not&lt;/strong&gt; see any reference to libraries that have their own
autoloader. This includes the symfony core classes, Swiftmailer, Zend
Framework, etc. If you see references to classes from one of these
libraries, your autoloader is not configured correctly.&lt;/li&gt;
&lt;li&gt;You should &lt;strong&gt;not&lt;/strong&gt; see any non-runtime classes.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;You’ll probably need to add some configuration to accomplish that second
point. For example, your tasks and Doctrine migration classes will never be
involved in a runtime request, so they should not be included in the
autoloader’s cache.&lt;/p&gt;

&lt;h2&gt;Configure the autoloader&lt;/h2&gt;

&lt;p&gt;Fortunately, excluding these files is easy enough using &lt;code&gt;autoload.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add this file to your project…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# config/autoload.yml
autoload:
  # extend the "project" configuration block defined in the symfony core
  project:
    exclude: [vendor, symfony, model, migration, task]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Clear your cache…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ php symfony cache:clear
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Visit your site in the browser to prime the cache, and re-inspect the cached
&lt;code&gt;config_autoload.yml.php&lt;/code&gt; file. Your task and Doctrine migration classes
should no longer be represented there.&lt;/p&gt;

&lt;h2&gt;Add this to your installer&lt;/h2&gt;

&lt;p&gt;The new installer mechanism in symfony 1.4 is the perfect place to add this
sort of thing since you’re going to want to do it on every project. For an
example of how this is done, check out commit &lt;a href="http://github.com/kriswallsmith/symfony-installer/commit/dede92eefc5e54d6c913e354486c045e3b6b03cc" target="_blank"&gt;dede92e&lt;/a&gt; on my GitHub
&lt;a href="http://github.com/kriswallsmith/symfony-installer" target="_blank"&gt;symfony-installer&lt;/a&gt; project.&lt;/p&gt;

&lt;h2&gt;Read more&lt;/h2&gt;

&lt;p&gt;If you want to learn more about configuring the symfony 1.4 autoloader, please
read through &lt;a href="http://www.symfony-project.org/reference/1_4/en/" target="_blank"&gt;The symfony Reference Guide&lt;/a&gt;, specifically the section on
&lt;a href="http://www.symfony-project.org/reference/1_4/en/14-Other-Configuration-Files#chapter_14_autoload_yml" target="_blank"&gt;autoload.yml&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/IHFu-Z9-Rjs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/IHFu-Z9-Rjs/1389089654</link><guid isPermaLink="false">http://kriswallsmith.net/post/1389089654</guid><pubDate>Sun, 24 Oct 2010 05:46:00 -0700</pubDate><category>symfony</category><feedburner:origLink>http://kriswallsmith.net/post/1389089654</feedburner:origLink></item><item><title>My MongoDB slides</title><description>&lt;a href="http://www.slideshare.net/kriswallsmith/mongod-pdxphp"&gt;My MongoDB slides&lt;/a&gt;: &lt;p&gt;I had a great time talking about MongoDB and the Doctrine ODM at PDXPHP last night. Thanks to ShopIgniter for hosting (and deciding OpenSky is not a competitor — phew!). I’m looking forward to talking about these things more someday.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/_1jb0tzI2W0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/_1jb0tzI2W0/1359087331</link><guid isPermaLink="false">http://kriswallsmith.net/post/1359087331</guid><pubDate>Wed, 20 Oct 2010 07:58:44 -0700</pubDate><category>MongoDB</category><category>PDXPHP</category><category>Doctrine</category><feedburner:origLink>http://kriswallsmith.net/post/1359087331</feedburner:origLink></item><item><title>The truth shall set you free…</title><description>&lt;img src="http://29.media.tumblr.com/tumblr_lajfxyZ50U1qzyw1go1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The truth shall set you free…&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/ByCp52T8_UA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/ByCp52T8_UA/1351132436</link><guid isPermaLink="false">http://kriswallsmith.net/post/1351132436</guid><pubDate>Tue, 19 Oct 2010 05:56:22 -0700</pubDate><category>Symfony2</category><feedburner:origLink>http://kriswallsmith.net/post/1351132436</feedburner:origLink></item><item><title>The Geek Talk interviews… Me!</title><description>&lt;a href="http://thegeektalk.com/interviews/kris-wallsmith/"&gt;The Geek Talk interviews… Me!&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/aMN0GNDaUgA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/aMN0GNDaUgA/1346591383</link><guid isPermaLink="false">http://kriswallsmith.net/post/1346591383</guid><pubDate>Mon, 18 Oct 2010 15:23:53 -0700</pubDate><feedburner:origLink>http://kriswallsmith.net/post/1346591383</feedburner:origLink></item><item><title>Joining OpenSky</title><description>&lt;a href="https://blog.shopopensky.com/2010/10/joining-opensky/"&gt;Joining OpenSky&lt;/a&gt;: &lt;p&gt;I blogged about joining OpenSky last week, and about the compatibility of the OpenSky and open source philosophies, as I see them.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/FYdE8aSCkHo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/FYdE8aSCkHo/1343735406</link><guid isPermaLink="false">http://kriswallsmith.net/post/1343735406</guid><pubDate>Mon, 18 Oct 2010 06:12:09 -0700</pubDate><category>OpenSky</category><feedburner:origLink>http://kriswallsmith.net/post/1343735406</feedburner:origLink></item><item><title>RFC: Mocking Fluent Interfaces in PHPUnit</title><description>&lt;p&gt;I sent a pair of &lt;a href="https://github.com/sebastianbergmann/phpunit/pull/51" target="_blank"&gt;pull&lt;/a&gt; &lt;a href="https://github.com/sebastianbergmann/phpunit-mock-objects/pull/24" target="_blank"&gt;requests&lt;/a&gt; to Sebastian this morning for a very simple change that will make mocking fluent interfaces much easier.&lt;/p&gt;

&lt;p&gt;This is how you might mock a fluent interface using PHPUnit 3.5.1:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$mock = $this-&gt;getMock('Person');
$mock
  -&gt;expects($this-&gt;any())
  -&gt;method('setName')
  -&gt;will($this-&gt;returnValue($mock));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I’ve proposed a new &lt;code&gt;returnSelf()&lt;/code&gt; method, which would cleanup this code, just a bit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$mock = $this-&gt;getMock('Person');
$mock
  -&gt;expects($this-&gt;any())
  -&gt;method('setName')
  -&gt;will($this-&gt;returnSelf());
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What do you think?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/_MdWjsHnaRQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/_MdWjsHnaRQ/1343657668</link><guid isPermaLink="false">http://kriswallsmith.net/post/1343657668</guid><pubDate>Mon, 18 Oct 2010 05:52:36 -0700</pubDate><category>PHPUnit</category><category>RFC</category><feedburner:origLink>http://kriswallsmith.net/post/1343657668</feedburner:origLink></item><item><title>My last presentation during my month of travel was a tech talk...</title><description>&lt;img src="http://27.media.tumblr.com/tumblr_lahkshnyZI1qzyw1go1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;My last presentation during my month of travel was a tech talk on Symfony2 at the &lt;a href="http://www.liip.ch/" target="_blank"&gt;L//P&lt;/a&gt; offices in Zürich. I did some live coding and demonstrated how to reference a controller from the DIC and unit test that controller using PHPUnit.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/C46kAyGGfSg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/C46kAyGGfSg/1343631067</link><guid isPermaLink="false">http://kriswallsmith.net/post/1343631067</guid><pubDate>Mon, 18 Oct 2010 05:45:00 -0700</pubDate><category>Symfony2</category><category>PHPUnit</category><feedburner:origLink>http://kriswallsmith.net/post/1343631067</feedburner:origLink></item><item><title>How to Test a Symfony2 Bundle</title><description>&lt;p&gt;The Symfony2 Framework is fully unit tested using PHPUnit. When you create a
Symfony2 bundle to share with the community, it’s important that your bundle
also be fully unit tested. It’s also important that users be able to run your
bundle’s test suite without having to wrap it in a dummy project. This blog
post is about how to set that up.&lt;/p&gt;

&lt;h2&gt;PHPUnit Configuration&lt;/h2&gt;

&lt;p&gt;Configuration for PHPUnit should be in a file named &lt;code&gt;phpunit.xml.dist&lt;/code&gt; in your
bundle’s root directory. This file is suffixed &lt;code&gt;.dist&lt;/code&gt; since it is the
distributed configuration. Users can copy this default configuration to
&lt;code&gt;phpunit.xml&lt;/code&gt; and make modifications there for their environment. This is
necessary when testing bundles, as we’ll see below.&lt;/p&gt;

&lt;p&gt;The distributed configuration file should look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;phpunit bootstrap="./Tests/bootstrap.php"&gt;
  &lt;php&gt;
    &lt;!-- &lt;server name="SYMFONY" value="/path/to/symfony" /&gt; --&gt;
  &lt;/php&gt;
  &lt;testsuites&gt;
    &lt;testsuite name="FacebookBundle Test Suite"&gt;
      &lt;directory suffix="Test.php"&gt;./Tests&lt;/directory&gt;
    &lt;/testsuite&gt;
  &lt;/testsuites&gt;
  &lt;filter&gt;
    &lt;whitelist&gt;
      &lt;directory&gt;./&lt;/directory&gt;
      &lt;exclude&gt;
        &lt;directory&gt;./Tests&lt;/directory&gt;
      &lt;/exclude&gt;
    &lt;/whitelist&gt;
  &lt;/filter&gt;
&lt;/phpunit&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This configuration instructs PHPUnit to include a bootstrap file located at
the base of your bundles &lt;code&gt;Tests/&lt;/code&gt; directory before running any tests. We’ll
take a look at this file below.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&lt;php&gt;&lt;/code&gt; portion of the configuration will define the &lt;code&gt;$_SERVER['SYMFONY']&lt;/code&gt;
variable. After copying this file to &lt;code&gt;phpunit.xml&lt;/code&gt;, users will need to
uncomment this line and enter the actual path to the Symfony2 &lt;code&gt;src/&lt;/code&gt; directory
here.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&lt;testsuites&gt;&lt;/code&gt; section of the file tells PHPUnit where to find your test
cases. The &lt;code&gt;&lt;filter&gt;&lt;/code&gt; section defines a whitelist of files that the test suite
is covering, which excludes the test cases themselves.&lt;/p&gt;

&lt;h2&gt;Autoloading&lt;/h2&gt;

&lt;p&gt;The purpose of the bootstrap file referenced in the PHPUnit configuration is
to initialize autoloading of classes from the Symfony core and from your
bundle. The former can be done using the &lt;code&gt;UniversalClassLoader&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require_once $_SERVER['SYMFONY'].'/Symfony/Component/HttpFoundation/UniversalClassLoader.php';

use Symfony\Component\HttpFoundation\UniversalClassLoader;

$loader = new UniversalClassLoader();
$loader-&gt;registerNamespace('Symfony', $_SERVER['SYMFONY']);
$loader-&gt;register();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the use of &lt;code&gt;$_SERVER['SYMFONY']&lt;/code&gt;, which we defined earlier in the
PHPUnit configuration?&lt;/p&gt;

&lt;p&gt;Loading of your bundle’s classes is a bit more complicated since we can’t rely
on them be installed in any particular directory, but a hack like this will do
the trick:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;spl_autoload_register(function($class)
{
    if (0 === strpos($class, 'Bundle\\Kris\\FacebookBundle\\')) {
        $path = implode('/', array_slice(explode('\\', $class), 3)).'.php';
        require_once __DIR__.'/../'.$path;
        return true;
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this configuration and bootstrap script in place, running your bundle’s
test suite is easy as pie:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd ~/Sites/FacebookBundle
$ phpunit
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/0kMc3uZjs1s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/0kMc3uZjs1s/1338263070</link><guid isPermaLink="false">http://kriswallsmith.net/post/1338263070</guid><pubDate>Sun, 17 Oct 2010 13:06:51 -0700</pubDate><category>Symfony2</category><category>PHPUnit</category><feedburner:origLink>http://kriswallsmith.net/post/1338263070</feedburner:origLink></item><item><title>How to create a Symfony2 templating helper</title><description>&lt;p&gt;As you get started with Symfony2 you will probably find yourself getting stuck
on some tasks that are second-nature to you when developing in symfony 1. One
of these will probably be adding a custom helper to your view layer. Hopefully
this quick article will clarify that particular process.&lt;/p&gt;

&lt;h4&gt;Create a helper class&lt;/h4&gt;

&lt;p&gt;In order to work with the Symfony2 view layer your helper class must implement
the HelperInterface interface. This interface is quite simple:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace Symfony\Components\Templating\Helper;

interface HelperInterface
{
    function getName();
    function setCharset($charset);
    function getCharset();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Most of the time you’ll be extending the abstract base helper class provided
in the core, which provides concrete implementations of the latter two
methods. This remaining method, &lt;code&gt;getName()&lt;/code&gt;, should return the name your
helper can be called by from the view layer.&lt;/p&gt;

&lt;p&gt;For example, a helper that outputs the Google Analytics tracking code could
look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace Application\HelloBundle\Helper;

use Symfony\Components\Templating\Helper\Helper;

class TrackerHelper extends Helper
{
    public function getName()
    {
        return 'tracker';
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Register your helper&lt;/h4&gt;

&lt;p&gt;Once you have a concrete helper class you could add it directly to the
templating engine using the &lt;code&gt;$engine-&gt;set($helper)&lt;/code&gt; method. However, Symfony2
provides another, more scalable way to register helpers using the dependency
injection container’s tagging mechanism.&lt;/p&gt;

&lt;p&gt;To register a service as a templating helper, add a &lt;code&gt;templating.helper&lt;/code&gt; tag
that includes an &lt;code&gt;alias&lt;/code&gt; attribute of the name you would like to use to
reference this helper. For example, in &lt;code&gt;hello/config/config.xml&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;services&gt;
    &lt;service id="tracker_helper" class="Application\HelloBundle\Helper\TrackerHelper"&gt;
        &lt;tag name="templating.helper" alias="tracker" /&gt;
    &lt;/service&gt;
&lt;/services&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Make it do something!&lt;/h4&gt;

&lt;p&gt;Now that your helper is registered you can access it in your template files
via the templating engine (i.e. &lt;code&gt;$view['tracker']&lt;/code&gt;). Let’s make it do something
now so this isn’t just academic.&lt;/p&gt;

&lt;p&gt;In order to output the correct tracking code, our helper will need to know
what site id to use. We can pass this value to our helper’s constructor:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class TrackerHelper extends Helper
{
    protected $profileId;

    public function __construct($profileId)
    {
        $this-&gt;profileId = $profileId;
    }

    public function __toString()
    {
        // return tracking code that includes $this-&gt;profileId
    }

    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Last we just need to configure the constructor parameter in the service
container configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;parameters&gt;
    &lt;parameter key="tracker.profile_id"&gt;UA-XXXXX-XX&lt;/parameter&gt;
&lt;/parameters&gt;

&lt;services&gt;
    &lt;service id="tracker_helper" class="Application\HelloBundle\Helper\TrackerHelper"&gt;
        &lt;tag name="templating.helper" alias="tracker" /&gt;
        &lt;argument&gt;%tracker.profile_id%&lt;/argument&gt;
    &lt;/service&gt;
&lt;/services&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With that, you can now output the tracking code in your template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;?php echo $view['tracker'] ?&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Voilà! You can now get started developing your own Symfony2 templating
helpers.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/xKqj464ak1w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/xKqj464ak1w/878278731</link><guid isPermaLink="false">http://kriswallsmith.net/post/878278731</guid><pubDate>Thu, 29 Jul 2010 21:50:00 -0700</pubDate><category>Symfony2</category><category>php</category><feedburner:origLink>http://kriswallsmith.net/post/878278731</feedburner:origLink></item><item><title>Blog Post Cut Short</title><description>&lt;blockquote&gt;
  &lt;p&gt;Me &lt; Metro &lt; Paris&lt;br/&gt;
  I would like to eat a crepe.&lt;br/&gt;
  What more can I say?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That about sums it up! I’m headed to the symfony live training day, bracing myself for the first of three OSS geek-out days.&lt;/p&gt;

&lt;p&gt;I arrived in Paris yesterday morning after flying nine hours up and over the top of the world, getting nary a wink of sleep. This is my second trip to Paris and my first flying solo; so I don’t have my wife’s talented tongue to lean on ( how’s that for imagery?) but am much more comfortable getting around than I would have been otherwise. I know how to read a subway map, buy food and thank people what I hope is graciously.&lt;/p&gt;

&lt;p&gt;After I found the hotel yesterday morning, which only took about 1M of exorbitantly priced international AT&amp;T data (read $20), I unpacked and almost immediately went for an aimless walk. I was really just trying to stay away from my bed to help beat this jet lag as quick as possible. I ended up walking about 10k.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/PHH1jf8TiV8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/PHH1jf8TiV8/391289524</link><guid isPermaLink="false">http://kriswallsmith.net/post/391289524</guid><pubDate>Mon, 15 Feb 2010 12:13:00 -0800</pubDate><category>sflive2010</category><category>paris</category><feedburner:origLink>http://kriswallsmith.net/post/391289524</feedburner:origLink></item><item><title>Shifting the Sun </title><description>&lt;blockquote&gt;
  &lt;p&gt;When your father dies, say the Irish,
  you lose your umbrella against bad weather. 
  May his sun be your light, say the Armenians.&lt;/p&gt;
  
  &lt;p&gt;When your father dies, say the Welsh,
  you sink a foot deeper into the earth. 
  May you inherit his light, say the Armenians.&lt;/p&gt;
  
  &lt;p&gt;When your father dies, say the Canadians, 
  you run out of excuses. 
  May you inherit his sun, say the Armenians.&lt;/p&gt;
  
  &lt;p&gt;When your father dies, say the French, 
  you become your own father. 
  May you stand up in his light, say the Armenians.&lt;/p&gt;
  
  &lt;p&gt;When you father dies, say the Indians, 
  he comes back as the thunder. 
  May you inherit his light, say the Armenians.&lt;/p&gt;
  
  &lt;p&gt;When your father dies, say the Russians, 
  he takes your childhood with him. 
  May you inherit his light, say the Armenians.&lt;/p&gt;
  
  &lt;p&gt;When your father dies, say the English, 
  you join his club you vowed you wouldn’t. 
  May you inherit his sun, say the Armenians.&lt;/p&gt;
  
  &lt;p&gt;When your father dies, say the Armenians, 
  your sun shifts forever. 
  And you walk in his light.&lt;/p&gt;
  
  &lt;p&gt;Diana Der-Hovanessian&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;RIP Richard Louis Berkman, 1935-2009&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/KrisWallsmith/~4/4Z2uGj1gIDs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/KrisWallsmith/~3/4Z2uGj1gIDs/163051844</link><guid isPermaLink="false">http://kriswallsmith.net/post/163051844</guid><pubDate>Fri, 14 Aug 2009 14:10:00 -0700</pubDate><feedburner:origLink>http://kriswallsmith.net/post/163051844</feedburner:origLink></item></channel></rss>

