<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged code</title>
    <link href="https://passingcuriosity.com/tags/code/code.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/code/code.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2010-01-18T00:00:00Z</updated>
    <entry>
    <title>Attribute Oriented Programming in PHP</title>
    <link href="https://passingcuriosity.com/2010/oplm2010-4-aop-in-php/" />
    <id>https://passingcuriosity.com/2010/oplm2010-4-aop-in-php/</id>
    <published>2010-01-18T00:00:00Z</published>
    <updated>2010-01-18T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>The fourth talk at the <a href="http://blogs.tucs.org.au/oplm/">Open Programming Language Miniconf 2010</a> was
Peter Serwylo’s presentation about <em><a href="http://blogs.tucs.org.au/oplm/programme/#aopphp">Attribute Oriented Programming in
PHP</a></em>. His <a href="http://lca2010.serwylo.com/">notes</a> are available online.</p>
<h2 id="attributes">Attributes</h2>
<p>Attributes are “extra” bits embedded in source code that doesn’t <em>necessarily</em>
mean anything in the language. Common examples include the documentation
annotations in many comment systems (such as the tags used in Javadoc
comments), JVM annotations, and .Net attributes.</p>
<p>A testing framework, for example, might use a <code>TestFunction</code> attribute to
identify which methods should be called.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="at">@TestFunction</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> function <span class="fu">testValidation</span><span class="op">()</span> <span class="op">{</span><span class="kw">...</span><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb2"><pre class="sourceCode cs"><code class="sourceCode cs"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="op">[</span>TestFunction<span class="op">]</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> function <span class="fu">testValidation</span><span class="op">()</span> <span class="op">{...}</span></span></code></pre></div>
<h2 id="use-cases">Use cases</h2>
<p>In Java EE you have “beans” which encapsulate business logic. Each bean
requires a bunch of wrappers for remote access, “home” access (whatever that
means), XML files, etc. Keeping all this relatively “boiler-plate” code in
synch is painful. Annotating the bean classes and methods with attributes
makes it possible to generate most of this automatically. No more manual
synching XML files.</p>
<p>Java, though, (as of Java 5) has built in support for <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html">annotations</a> and
is a compiled language. This makes it relatively simple to do this analysis
and generation at build time. PHP, on the other hand, doesn’t have an
annotation mechanism and doesn’t <em>have</em> a built time.</p>
<p>Instead, Peter’s approach is to use PHP comments to add the attributes. At
load time, these comments are processed using the reflection API and this is
used to build a data structure to use for access control. See the
<a href="http://lca2010.serwylo.com/06_ivt_example.html">permissions example</a>.</p>
<h2 id="a-more-complex-case">A more complex case</h2>
<p>To take this a little further, Peter <a href="http://lca2010.serwylo.com/07_php_zend_example.html">wrote a Zend
extension</a> that makes it
possible to [sort of] do aspect oriented programming (on function points) in
PHP. The <code>add_function_hook()</code> function allows you to register an attribute
and a callback and the extension will call your callback before a function
with that attribute is executed:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;?php</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> RequiresLogging</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>	<span class="co">/**</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="co">	 * </span><span class="an">@log</span><span class="co"> notice &quot;Secret action performed by user [user]</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="co">	 */</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>	<span class="kw">public</span> <span class="kw">function</span> secretAction()</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>	{</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>		<span class="co">// perform secret action...</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>	}</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="co">// </span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a><span class="co">// The callback function</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a><span class="co">//</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> performLog( <span class="va">$message</span> )</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>{</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>	<span class="va">$parts</span> <span class="op">=</span> <span class="cn">split</span>( <span class="st">&quot; &quot;</span><span class="ot">,</span> <span class="va">$message</span><span class="ot">,</span> <span class="dv">2</span> )<span class="ot">;</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>	<span class="va">$level</span> <span class="op">=</span> <span class="va">$parts</span>[<span class="dv">0</span>]<span class="ot">;</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>	<span class="va">$message</span> <span class="op">=</span> <span class="va">$parts</span>[<span class="dv">1</span>]<span class="ot">;</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>	Logger::<span class="fu">log</span>( <span class="va">$level</span><span class="ot">,</span> <span class="va">$message</span> )<span class="ot">;</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a><span class="co">// </span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a><span class="co">// Register the callback</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a><span class="co">// </span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a>add_function_hook( <span class="st">&quot;log&quot;</span><span class="ot">,</span> <span class="st">&quot;performLog&quot;</span> )<span class="ot">;</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a><span class="co">// Now code like this will result in a log message being recorded</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a><span class="va">$object</span> <span class="op">=</span> <span class="kw">new</span> RequiresLogging()<span class="ot">;</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a><span class="va">$object</span>-&gt;secretAction()<span class="ot">;</span></span></code></pre></div>
<p>This type approach is flexible and extremely powerful. You can inject
permission checking code and raise an exception before the real function is
even called.</p>
<p>There are a bunch of memory leaks and possible bugs in the Zend extension, but
it is working and in production use!</p>]]></summary>
</entry>
<entry>
    <title>Notes on Preparing for PHP6</title>
    <link href="https://passingcuriosity.com/2010/oplm2010-3-php6/" />
    <id>https://passingcuriosity.com/2010/oplm2010-3-php6/</id>
    <published>2010-01-18T00:00:00Z</published>
    <updated>2010-01-18T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>The third talk at the <a href="http://blogs.tucs.org.au/oplm/">Open Programming Language Miniconf 2010</a> was
by <a href="http://benbalbo.com/">Ben Balbo</a> presentation about <em><a href="http://blogs.tucs.org.au/oplm/programme/#php6">Preparing for PHP6</a></em>. Though the
slides were a little hard to read – Ben used one of those horrible
hand-writing style fonts – it was chockablock full of useful information.</p>
<p>He started with a list of things that have been removed or altered in PHP6 and
then described some of the new features. Some of the things from both lists
are present in version 5.3.</p>
<h3 id="removals-and-changes">Removals and changes</h3>
<p>In PHP6 <code>E_ALL</code> will include <code>E_STRICT</code> which may cause errors to be reported
in code that is OK in PHP5. A new <code>E_DEPRECATED</code> has been introduced and is
also included in <code>E_ALL</code>. This new error is raised when you use any deprecated
functions.</p>
<p>These deprecated functions and features include register globals, magic
quotes, safe mode and ASP-style <code>&lt;% %&gt;</code> tags. Also going/gone are the
<code>$HTTP_POST_VARS</code> and <code>$HTTP_GET_VARS</code> variables.</p>
<p>Other changes include assign-by-reference (using <code>=&amp;</code>) and <code>zend_compat</code>
raising <code>E_STRICT</code>. Class members defined without a visibility modifier will
be <code>public</code> by default (and will also raise <code>E_STRICT</code>).</p>
<p>Dynamically loading extensions is now disabled by default on all SAPIs except
the command-line interpreter. This needs to be enabled (in <code>php.ini</code>, I
assume) if required.</p>
<p>In a rather acrobatic backflip, the formerly deprecated <code>$str[1]</code> is no-longer
deprecated and its replacement <code>$str{1}</code> now <em>is</em> deprecated. You can also now
use the subscript syntax to take a slice of a string – like <code>$str[1,3]</code> – as
you in some other languages.</p>
<p>The wacky variable <code>break</code> feature (where one breaks out of a variable number
of looping constructs: <code>break $anint;</code>) is deprecated. It’s disappearance make
me wonder (again) why it was added in the first place. I can’t help but wonder
if there was a use-case in mind, or if it was just “because”.</p>
<p>The <code>microtime()</code> function now returns the float value by default; you’ll no
longer need to use <code>microtime(TRUE)</code> in every invocation.</p>
<p>The move to using the PCRE-based <a href="http://php.net/manual/en/book.pcre.php"><code>preg_*</code></a> functions for regular
expressions is finally complete. The <a href="http://php.net/manual/en/book.regex.php"><code>ereg_*</code></a> functions have been
removed from core and stuck in a PECL extension. At the same time,
<a href="http://php.net/manual/en/book.mime-magic.php"><code>mime_magic</code></a> has also been moved to a PECL extension and its
more useful and popular cousin <a href="http://php.net/manual/en/book.fileinfo.php"><code>fileinfo</code></a> has replaced it in core.</p>
<h3 id="additions">Additions</h3>
<p>The big ticket new item must be namespaces. The controversial choice to use
backslash as the separator was due to the simple fact that it is the only
single character available. This doesn’t make it any less silly, especially
because of the way that function “references” in PHP are just strings:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="va">$func</span> <span class="op">=</span> <span class="st">&quot;\application</span><span class="sc">\n</span><span class="st">ames\afunc&quot;</span><span class="ot">;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="va">$func</span>()<span class="ot">;</span></span></code></pre></div>
<p>All names refer to the current namespace, but prefixing a name with a
backslash will make it relative to the “root” namespace.</p>
<p>You can import things from other name spaces with the <code>use</code> keyword and, if
required – perhaps there is a clash – alias them by taking an <code>as</code> clause on
the end:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">use</span> \MyCompany\Blog\User <span class="kw">as</span> BlogUser<span class="ot">;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">use</span> \MyCompany\<span class="cn">CMS</span>\User <span class="kw">as</span> CMSUser<span class="ot">;</span></span></code></pre></div>
<p>Functions and classes both belong to namespaces and definitions are processed
top-down. Thus the following code defines a <code>foo()</code> function and then a
<code>bundle\foo()</code> function:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> foo() { <span class="kw">echo</span> <span class="st">&quot;G&quot;</span><span class="ot">;</span> }</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> bundle<span class="ot">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> foo() { <span class="kw">echo</span> <span class="st">&quot;NS&quot;</span><span class="ot">;</span> }</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>bundle\foo()<span class="ot">;</span> <span class="co">// &quot;NS&quot;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>foo()<span class="ot">;</span> <span class="co">// &quot;G&quot;</span></span></code></pre></div>
<p>Another important change is the addition of late static binding. In previous
versions of PHP <code>self::foo</code> in the code of a superclass method refers the
<code>foo</code> member of that superclass, even if the subclass defines a <code>foo</code> member.
This problem is ameliorated with the addition of a new <code>static</code> keyword.
<code>static::foo</code> will do what you expect: look in subclass, then in the parent/s.</p>
<p>All in all, it looks like PHP6 is a great big leap forward in the evolution of
PHP. A few more major versions and it might catch up to modern languages.</p>]]></summary>
</entry>
<entry>
    <title>Logging the locking in SPIP</title>
    <link href="https://passingcuriosity.com/2009/logging-the-locking-in-spip/" />
    <id>https://passingcuriosity.com/2009/logging-the-locking-in-spip/</id>
    <published>2009-11-03T00:00:00Z</published>
    <updated>2009-11-03T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>At <a href="http://bouncingorange.com/">work</a>, we use
<a href="http://www.spip.net/">SPIP</a> for the vast majority of our sites.
Almost all of them are on Linux shared hosting at our favourite local
hosting company <a href="http://www.hostaway.net.au/">HostAway</a>.
Unfortunately, we’ve been running into a recurring problem with some
of our SPIP 2.0 sites that is having a detrimental impact on the sites
(some requests block forever) and the servers (PHP FastCGI processes
blocking forever leading to resource starvation).</p>
<p>The problem, it seems, lies in SPIP’s use of locking to serialise
access to a number of files containing cached data. In essence: SPIP
seems to deadlock when attempting to lock certain files in the <code>/tmp/</code>
directory. This hangs the PHP process (FastCGI, in our case) which
consumes resources and, eventually, prevents the web-servers from
being able to serve requests for PHP. To make a bad problem even
worse, we seem to be the only people to experience this problem.
Literally no-one else in the SPIP community has ever encountered it!</p>
<p>As a first step in trying to diagnose and resolve the problem, I’ve
instrumented the code that implement’s SPIP’s locking techniques to
log all locking operations. Thankfully, this is relatively easy as
SPIP wraps the actual <a href="http://php.net/flock"><code>flock</code></a> calls with its
own <code>spip_fopen_lock()</code> and <code>spip_fclose_unlock()</code> functions defined
in
<a href="http://trac.rezo.net/trac/spip/browser/spip/ecrire/inc/flock.php"><code>/ecrire/inc/flock.php</code></a>.</p>
<p>I can’t use the built in SPIP logging functions because they use the
locking functions I’m trying to instrument to prevent interleaving of
log messages. The obvious choice (and far superior to <code>spip_log()</code>, in
my opinion) is using the <a href="http://en.wikipedia.org/wiki/Syslog">syslog</a>
protocol supported by pretty much everything that matters (i.e.
everything UNIX and lots of networking gear). Alas, PHP’s built-in
<a href="http://php.net/syslog"><code>syslog()</code></a> function logs to the local syslog
daemon. Instead, I’ve used a small class that implements a <a href="http://www.phpclasses.org/browse/file/12157.html">Pure PHP
syslog client</a>.</p>
<p>Rather than copy-‘n’-paste a bunch of code into the SPIP locking
functions, I’ve created a function to figure out what the message
should be<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> and then log it. <code>logtrace()</code> creates a PHP backtrace
and inspects it to determine which function (lock or unlock) it is
logging and which function (of the dozen or so alternatives) called
it. Once it’s figured that out, it uses a static instance of the
Syslog class to send the message to the log server. The code is
simple:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;?php</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">require_once</span>(<span class="st">'syslog.php'</span>)<span class="ot">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="pp">@</span><span class="fu">define</span>(<span class="st">&quot;_SYSLOG_SERVER&quot;</span><span class="ot">,</span> <span class="st">&quot;192.168.1.1&quot;</span>)<span class="ot">;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> logtrace() {</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>	<span class="co">// The syslog client</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>	<span class="kw">static</span> <span class="va">$log</span><span class="ot">;</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>	<span class="cf">if</span> (<span class="op">!</span> <span class="va">$log</span>) {</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>		<span class="va">$pid</span> <span class="op">=</span> <span class="fu">getmypid</span>()<span class="ot">;</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>		<span class="va">$log</span> <span class="op">=</span> <span class="kw">new</span> <span class="fu">Syslog</span>()<span class="ot">;</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>		<span class="va">$log</span>-&gt;SetProcess(<span class="st">&quot;PHP-</span><span class="va">$pid</span><span class="st">&quot;</span>)<span class="ot">;</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>		<span class="va">$log</span>-&gt;SetIpFrom(<span class="va">$_SERVER</span>[<span class="st">'REMOTE_ADDR'</span>])<span class="ot">;</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>	}</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>	<span class="co">// Get the functions from the backtrace</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>	<span class="va">$bt</span> <span class="op">=</span> <span class="fu">debug_backtrace</span>()<span class="ot">;</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>	<span class="va">$callee</span> <span class="op">=</span> <span class="va">$bt</span>[<span class="dv">1</span>]<span class="ot">;</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>	<span class="va">$caller</span> <span class="op">=</span> <span class="va">$bt</span>[<span class="dv">2</span>]<span class="ot">;</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>	</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>	<span class="co">// Build and log the message</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>	<span class="va">$func</span> <span class="op">=</span> <span class="va">$callee</span>[<span class="st">'function'</span>]<span class="op">.</span><span class="st">'('</span><span class="op">.</span><span class="va">$callee</span>[<span class="st">'args'</span>][<span class="dv">0</span>] <span class="op">.</span><span class="st">')'</span><span class="ot">;</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>	<span class="va">$from</span> <span class="op">=</span> <span class="va">$caller</span>[<span class="st">'function'</span>]<span class="op">.</span><span class="st">'('</span><span class="op">.</span> <span class="va">$caller</span>[<span class="st">'args'</span>][<span class="dv">0</span>] <span class="op">.</span><span class="st">')'</span><span class="ot">;</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>	<span class="va">$log</span>-&gt;Send(<span class="cn">_SYSLOG_SERVER</span><span class="ot">,</span> <span class="st">&quot;</span><span class="va">$func</span><span class="st"> from </span><span class="va">$from</span><span class="st">&quot;</span>)<span class="ot">;</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>With that defined, it’s just a matter of adding a call to <code>logtrace()</code> to <code>spip_fopen_lock()</code> and <code>spip_fclose_unlock()</code> in <code>/ecrire/inc/flock.php</code> and we get log messages something like this<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>:</p>
<blockquote>
<pre><code>Nov  3 13:54:07 server2.example.com WEBSERVER PHP-1234: www.example.com 10.10.10.10 spip_fopen_lock(../tmp/verifier_plugins.txt, ...) from lire_fichier(../tmp/verifier_plugins.txt, ...)
Nov  3 13:54:07 server2.example.com WEBSERVER PHP-1234: www.example.com 10.10.10.10 spip_fclose_unlock(Resource id #69, ...) from lire_fichier(../tmp/verifier_plugins.txt, ...)</code></pre>
</blockquote>
<p>Of course, this is not enough information to debug the locking problems – I’ll also need the IP address of the client and the PID of the PHP interpreter to distinguish interleaved messages from concurrent requests – but it’s a start.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Note that the I’m including only the first argument in the log message. Why? Because the second argument to some of them is <em>the entire contents of the file</em>!<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Note that the theme I’m using is cutting off most of these log lines.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>]]></summary>
</entry>
<entry>
    <title>Writing view decorators for Django</title>
    <link href="https://passingcuriosity.com/2009/writing-view-decorators-for-django/" />
    <id>https://passingcuriosity.com/2009/writing-view-decorators-for-django/</id>
    <published>2009-07-20T00:00:00Z</published>
    <updated>2009-07-20T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Using decorators to wrap and modify Django views is quick, easy, composable,
and just about the most awesome thing I’ve seen in a while. It also takes a
little bit of figuring out. Here’s my explanation…</p>
<h2 id="more-than-just-decoration">More than just decoration</h2>
<p>Using a decorator looks (in Python) like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="at">@a_decorator</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> a_function(an_arg):</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="st">&quot;Functionate: </span><span class="sc">%s</span><span class="st">!&quot;</span> <span class="op">%</span> (an_arg)</span></code></pre></div>
<p>Where <code>a_decorator</code> is some function or other which takes an argument
(<code>a_function</code>, in this particular case) and returns a value. When Python loads
a module containing this code it creates a new function <code>a_function</code> as
normal, but then it calls <code>a_decorator</code> on it and binds the value it returns
to the name <code>a_function</code> rather than the original function created from the
definition. So how do we write these decorators? Just like a normal function!</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> a_decorator(the_func):</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="co">    Make another a function more beautiful.</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="co">    &quot;&quot;&quot;</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> _decorated(<span class="op">*</span>args, <span class="op">**</span>kwargs):</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> the_func(<span class="op">*</span>args, <span class="op">**</span>kwargs)</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> _decorated</span></code></pre></div>
<p>But what about parameterised decorators? It’s just a little more involved.
Recall that you use a decorator like this: <code>@the_decorator</code>. It turns out that
such decorator statements don’t just <em>name</em> a decorator to be called, but can
also call a function to return a decorator to be called:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> wrap_in_a(tag):</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="co">    Wrap the result of a function in a `tag` HTML tag.</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="co">    &quot;&quot;&quot;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> _dec(func):</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">def</span> _new_func(<span class="op">*</span>args, <span class="op">**</span>kwargs):</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="st">&quot;&lt;</span><span class="sc">%s</span><span class="st">&gt;</span><span class="sc">%s</span><span class="st">&lt;/</span><span class="sc">%s</span><span class="st">&gt;&quot;</span> <span class="op">%</span> (tag, func(<span class="op">*</span>args, <span class="op">**</span>kwargs), tag)</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> _new_func</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> _dec</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="at">@wrap_in_a</span>(<span class="st">'div'</span>)</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a><span class="at">@login_required</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> my_name(request):</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> request.user.first_name</span></code></pre></div>
<p>The first decorator statement <code>@wrap_in_a('div')</code> calls <code>wrap_in_a('div')</code>
which returns a function (<code>_dec</code>). This function is then applied to the
following definition (<code>@login_required</code> applied to <code>my_name</code>). Simple!</p>
<p>It’s probably a good idea to add a few more bits and pieces to the function
returned by a decorator (copying <code>__doc__</code> and <code>__dict__</code>, for instance), but
that’s the core of it.</p>
<h2 id="using-it-in-django">Using it in Django</h2>
<p>So this is all pretty cool, but how do we use it in Django? We’ll here’s a
<code>anonymous_required</code> decorator that you can use to redirect authenticated
users to their home page if they try to login again:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> anonymous_required(function<span class="op">=</span><span class="va">None</span>, home_url<span class="op">=</span><span class="va">None</span>, redirect_field_name<span class="op">=</span><span class="va">None</span>):</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;Check that the user is NOT logged in.</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="co">    This decorator ensures that the view functions it is called on can be </span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="co">    accessed only by anonymous users. When an authenticated user accesses</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="co">    such a protected view, they are redirected to the address specified in </span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="co">    the field named in `next_field` or, lacking such a value, the URL in </span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="co">    `home_url`, or the `USER_HOME_URL` setting.</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="co">    &quot;&quot;&quot;</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> home_url <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>        home_url <span class="op">=</span> settings.USER_HOME_URL</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> _dec(view_func):</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">def</span> _view(request, <span class="op">*</span>args, <span class="op">**</span>kwargs):</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> request.user.is_authenticated():</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>                url <span class="op">=</span> <span class="va">None</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> redirect_field_name <span class="kw">and</span> redirect_field_name <span class="kw">in</span> request.REQUEST:</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>                    url <span class="op">=</span> request.REQUEST[redirect_field_name]</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> <span class="kw">not</span> url:</span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>                    url <span class="op">=</span> home_url</span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> <span class="kw">not</span> url:</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a>                    url <span class="op">=</span> <span class="st">&quot;/&quot;</span></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> HttpResponseRedirect(url)</span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a>            <span class="cf">else</span>:</span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> view_func(request, <span class="op">*</span>args, <span class="op">**</span>kwargs)</span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a>        _view.<span class="va">__name__</span> <span class="op">=</span> view_func.<span class="va">__name__</span></span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a>        _view.__dict__ <span class="op">=</span> view_func.__dict__</span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a>        _view.__doc__ <span class="op">=</span> view_func.__doc__</span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-31"><a href="#cb4-31" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> _view</span>
<span id="cb4-32"><a href="#cb4-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-33"><a href="#cb4-33" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> function <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb4-34"><a href="#cb4-34" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> _dec</span>
<span id="cb4-35"><a href="#cb4-35" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb4-36"><a href="#cb4-36" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> _dec(function)</span></code></pre></div>
<p>It’s probably not very Django-ish, but you get the impression. Just use it
like Django’s built-in <code>login_required</code> decorator:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="at">@anonynous_required</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> a_view(request):</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> HttpResponse(<span class="st">&quot;We are anonymous! We are legion!&quot;</span>)</span></code></pre></div>
<p>Comments and suggestions welcome!</p>
<p><strong>Update:</strong> Amended the example decorator above to work correctly as
<code>@anonymous_required</code>, <code>@anonymous_required(...)</code> or <code>foo = anonymous_required(foo)</code>.</p>]]></summary>
</entry>
<entry>
    <title>Authorising user actions in SPIP</title>
    <link href="https://passingcuriosity.com/2009/authorising-user-actions-in-spip/" />
    <id>https://passingcuriosity.com/2009/authorising-user-actions-in-spip/</id>
    <published>2009-03-30T00:00:00Z</published>
    <updated>2009-03-30T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>One of the APIs that many SPIP plug-ins will need to use is <code>autoriser()</code> –
the function which determines whether a user should be permitted to perform a
given operation. As I couldn’t find any document on using this function, I’ll
provide a few notes below.</p>
<p>Checking that a user if authorised to perform an action is a little more
haphazard than I’d like in SPIP (“No authorisation check? No worries!” is not
a particularly comforting approach), but it seems to get the job done even if
it does depend on more developer discipline than seems warranted. Checking
that a user is “authorised” to perform an action is done by calling the
<a href="http://doc.spip.org/@autoriser"><code>autoriser()</code></a> function with arguments to
describe the operation. If it returns <code>true</code> then the operation is authorised,
it not, then it isn’t.</p>
<p>Like most of SPIP’s core functions, <code>autoriser</code> is implemented in a way that
makes it easy to override and extend its functions: rather than make any
decision itself, it simply delegates the decision to the first function it
finds that can decide for that type of operation and object (or object, or
operation).</p>
<p>First, though, lets look at <code>autoriser</code>’s arguments:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> autoriser_dist(<span class="va">$faire</span><span class="ot">,</span> <span class="va">$type</span><span class="op">=</span><span class="st">''</span><span class="ot">,</span> <span class="va">$id</span><span class="op">=</span><span class="dv">0</span><span class="ot">,</span> <span class="va">$qui</span> <span class="op">=</span> <span class="kw">NULL</span><span class="ot">,</span> <span class="va">$opt</span> <span class="op">=</span> <span class="kw">NULL</span>)</span></code></pre></div>
<p>This first (and only required) argument is <code>$faire</code> (French, I’m told, for “to
do”) which takes a string: the name of the operation. The second argument
<code>$type</code> is another string: the type of object being operated on; and the third
is an integer: the ID of the particular object, if there is one. The fourth,
<code>$qui</code> (“who”) is an array of details of the current user; and the fifth, I
assume, is an array of optional values if the previous four are not enough to
make some decisions).</p>
<p>Only the first of these – the operation being performed – is required and
only the first should need to be specified in the vast majority of situations
(it’ll work out the user by itself and there are many operations without a
<code>$type</code> or an <code>$id</code>). Once it’s been called, <code>autoriser</code> uses these values to
look for a function that can make a decision for the given type and
operations.</p>
<p>You can see the code of <a href="http://trac.rezo.net/trac/spip/browser/spip/ecrire/inc/autoriser.php#L87"><code>/ecrire/inc/autoriser.php</code> (around line
87)</a>
for the particular functions that it will call, but the full list of
alternatives that ‘’autoriser($faire, $type, $id, $qui, $opts)’’ is (in order
of preference):</p>
<ol type="1">
<li><code>autoriser_$type_$faire()</code></li>
<li><code>autoriser_$type()</code></li>
<li><code>autoriser_$faire()</code></li>
<li><code>autoriser_default()</code></li>
<li><code>autoriser_$type_$faire_dist()</code></li>
<li><code>autoriser_$type_dist()</code></li>
<li><code>autoriser_$faire_dist()</code></li>
<li><code>autoriser_default_dist()</code></li>
</ol>
<p>Adding authorisation checks to your plug-in is easy: just implement one of
these checking functions (in a file that’ll be included by a <code>&lt;fonctons&gt;</code>
entry in your <code>plugin.xml</code> file is probably best) and then get <code>autoriser</code> to
call it when appropriate.</p>
<p>From <code>aplugin_fonctions.php</code> or some other file:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="co">/**</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="co"> * Perform authorisation checks for &quot;elephant&quot; objects.</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="co"> */</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> autoriser_elephant(<span class="va">$faire</span><span class="ot">,</span> <span class="va">$type</span><span class="op">=</span><span class="st">'elephant'</span><span class="ot">,</span> <span class="va">$id</span><span class="op">=</span><span class="dv">0</span><span class="ot">,</span> <span class="va">$qui</span><span class="op">=</span><span class="kw">NULL</span><span class="ot">,</span> <span class="va">$opt</span><span class="op">=</span><span class="kw">NULL</span>) {</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>   <span class="cf">if</span> ( <span class="st">'0minirezo'</span> <span class="op">==</span> <span class="va">$qui</span>[<span class="st">'statut'</span>] ) {</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>       <span class="cf">return</span> <span class="kw">true</span><span class="ot">;</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>   }</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>   <span class="cf">return</span> <span class="kw">false</span><span class="ot">;</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>With this code in place, only administrators will be able to perform actions
(or, strictly speaking, perform actions checked with the <code>autoriser</code> function)
on <em>elephant</em> objects. Any call specifying <code>$type='elephant'</code> will use the
above function to determine if the operation should proceed.</p>
<p>In <code>exec/anaction.php</code> or similar, we might use code like this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> ( autoriser(<span class="st">'kill'</span><span class="ot">,</span> <span class="st">'elephant'</span><span class="ot">,</span> <span class="va">$id_elephant</span>) ) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>   launch_missiles_at(<span class="st">'elephant'</span><span class="ot">,</span> <span class="va">$id_elephant</span>)<span class="ot">;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>} <span class="cf">else</span> {</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>   <span class="kw">echo</span> <span class="cn">_T</span>(<span class="st">'aplugin:cannot_shoot_elephant'</span>)<span class="ot">,</span> <span class="cn">_T</span>(<span class="st">'aplugin:permission_denied'</span>)<span class="ot">;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Which will try the following functions, in order, to decide whether or not to
<code>launch_missiles_at()</code> our poor elephant:</p>
<ol type="1">
<li><code>autoriser_elephant_kill()</code></li>
<li><code>autoriser_elephant()</code></li>
<li><code>autoriser_kill()</code></li>
<li><code>autoriser_default()</code></li>
<li><code>autoriser_elephant_kill_dist()</code></li>
<li><code>autoriser_elephant_dist()</code></li>
<li><code>autoriser_kill_dist()</code></li>
<li><code>autoriser_default_dist()</code></li>
</ol>
<p>That’s about all there is to it. Of course, there’s a lot more you can do to
make your authorisation decisions: per-user and per-object configurations you
might like implement (similar to the way SPIP allows us to restrict
administrators and editors “to a section”), time-based or geographic
restrictions (editing during working hours only, or from an IP address in
Africa), or restricting access to those within your organisation’s network.</p>
<p>The world of authorisation is your oyster!</p>]]></summary>
</entry>
<entry>
    <title>SPIP tags with multiple aliases</title>
    <link href="https://passingcuriosity.com/2009/spip-tags-with-multiple-aliases/" />
    <id>https://passingcuriosity.com/2009/spip-tags-with-multiple-aliases/</id>
    <published>2009-03-27T00:00:00Z</published>
    <updated>2009-03-27T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>This is yet another post about creating tags for use in <a href="http://www.spip.net/">SPIP</a> templates.
First I’ll describe how to create tags with multiple “names” (e.g. <code>#INCLURE</code>
and <code>#INCLUDE</code>) and then I’ll build on this technique, my previous post
<a href="/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/">Dynamic tags, fake arguments, and AST mangling in
SPIP</a>, and a pattern
used in SPIP’s code to create suites of tags with multiple similar but
slightly different functions.</p>
<p>As usual, you’ll need to know <a href="http://www.php.net/">PHP</a>, and the <a href="/2008/spip-template-languag/">SPIP template
language</a> before this will make much sense, and
I’d recommend reading my posts about <a href="/2008/creating-custom-tags-spip-static/">creating static
tags</a>, <a href="/2009/creating-custom-tags-spip-dynamic/">dynamic
tags</a>, and <a href="/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/">faking tag
arguments</a> as well.</p>
<p>SPIP tags are just a specially named function that accepts an AST node as a
parameter and returns that AST node modified so that the code generator will
generate the PHP code to implement the function. With static tags this means
filling the node with some PHP code that evaluates to a string (often just a
string literal with, perhaps, some variable interpolation). The functions for
dynamic tags, on the other hand, fill their AST node with PHP code that, when
evaluated by the code generator, generates more PHP. This second piece of PHP
will form part of the page template and will [potentially] be evaluated at
each request.</p>
<h3 id="different-but-same">Different but same</h3>
<p>It’s sometimes desirable to make certain tags available under more than one
name. The canonical example of this from SPIP’s built-in tags is
<code>#INCLURE</code>/<code>#INCLUDE</code>. Rather than provide just the French <code>#INCLURE</code> tag or
just the English (and PHP-ish) <code>#INCLUDE</code>, SPIP provides both. This can help
make your API more user friendly and is easy enough to do: just define a
second tag function that calls the first (notice that I check for an
overriding version of my original tag implementation and call that instead):</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>    <span class="co">/* The original tag */</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">function</span> balise_FOO_dist(<span class="va">$p</span>) {</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>        <span class="va">$p</span>-&gt;code <span class="op">=</span> <span class="st">&quot;'This is foo'&quot;</span><span class="ot">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="va">$p</span><span class="ot">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">/* The additional name */</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">function</span> balise_BAR_dist(<span class="va">$p</span>) {</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> ( <span class="fu">function_exists</span>(<span class="st">'balise_FOO'</span>) ) {</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>             <span class="cf">return</span> balise_FOO(<span class="va">$p</span>)<span class="ot">;</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>        } <span class="cf">else</span> {</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>             <span class="cf">return</span> balise_FOO_dist(<span class="va">$p</span>)<span class="ot">;</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>        }</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div>
<h3 id="similar-but-different">Similar but different</h3>
<p>If you’re looking for identical functionality under a different name (see
<a href="http://trac.rezo.net/trac/spip/browser/spip/ecrire/public/balises.php#balise_INCLURE_dist">#INCLURE</a> and <a href="http://trac.rezo.net/trac/spip/browser/spip/ecrire/public/balises.php#balise_INCLUDE_dist">#INCLUDE</a>), this is all you need, but imagine that you,
like me, have a number of tags with related but slightly different
functionality. You <em>could</em> implement each of them – copy-and-pasting the code
and changing perhaps a single variable – or extract the common code into a
set of library functions – slowing things down slightly – <em>or</em> you could
implement a generic tag and a number of wrappers around it. SPIP does this in
a number of places, but the best example is the <code>#ENV</code>, <code>#CONFIG</code> and <code>#GET</code>
tags, each of which are <em>actually</em> implemented by the same piece of code (the
<code>balise_ENV_dist</code> function, as it turns out).</p>
<p>This is easily accomplished by adding a second, optional, parameter to your
main tag function and then passing different values from your stub tags. This
is the approach that <a href="http://trac.rezo.net/trac/spip/browser/spip/ecrire/public/balises.php#balise_ENV_dist"><code>#ENV</code></a>, <code>#CONFIG</code>, and <code>#GET</code> use:
<code>balise_ENV_dist</code> check the environment by default, but if it’s passed a
second parameter (the <code>'$GLOBALS["meta"]'</code> that <code>#CONFIG</code> passes it, for
example), then it operates on <em>that</em> instead.</p>
<h3 id="mangling-for-fun-and-profit">Mangling for fun and profit</h3>
<p>A second, but rather more involved, option for passing values into other tags
is described in my <a href="/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/">faking tag
arguments</a> post. This
can be useful when you don’t control the code that you are wrapping. Perhaps
you want to modify the <code>#MODELE</code> tag in such a way that it adds the name and
line number of the tag to the environment of the model it calls. Rather than
duplicating the code for <code>balise_MODELE_dist</code> and modifying it slightly, you
could write a wrapper around it <code>balise_MODELE</code> and just add another two
parameters (<code>skeleton</code> and <code>line</code>) to the AST before calling
<code>balise_MODELE_dist</code>. As far as <code>balise_MODEL_dist</code> is concerned, it’s as
though some conscientious web-master has gone through every template adding
<code>{skeleton=filename}{line=123}</code> to every call.</p>
<p>The difficult bit is to modify the AST correctly, but that’s not too hard and
you can <a href="/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/">read the
post</a> to find out
how.</p>
<h3 id="conclusion">Conclusion</h3>
<p>This is a powerful technique that can simplify the code for plug-ins with
large numbers of similar tags immensely. Rather than producing large amounts
of “boiler-plate” code, or defining large libraries of API functions, I can
just reuse my existing generic code in ways that hide it’s complexity and
power, thereby making the API much more simple and obvious to my users.</p>]]></summary>
</entry>
<entry>
    <title>Dynamic tags, fake arguments, and AST mangling in SPIP</title>
    <link href="https://passingcuriosity.com/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/" />
    <id>https://passingcuriosity.com/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/</id>
    <published>2009-03-11T00:00:00Z</published>
    <updated>2009-03-11T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>One occasion in which <a href="/2009/creating-custom-tags-spip-dynamic/">SPIP’s dynamic tag
facilities</a> is a little lacking is
when you need to access details of the AST – perhaps the name of the template
file, perhaps something else – to generate your content. In this post I’ll
describe the obvious (but wrong) approach to passing values into a dynamic tag
and another technique that actually works.</p>
<p>You should know about the <a href="http://www.spip.net/">SPIP</a>, its <a href="/2008/spip-template-languag/">template
language</a>, <a href="/2008/creating-custom-tags-spip-static/">static
tags</a>, <a href="/2009/creating-custom-tags-spip-dynamic/">dynamic
tags</a> and be comfortable with
<a href="http://www.php.net/">PHP</a> before reading this article.</p>
<p>Unlike static tags – which are implemented by a single function – dynamic
tags are comprised of a set of three functions (in a magically named file)
which are called by the SPIP engine as appropriate. This first of these three
functions (identical to the single function of static tags) is called
something like <code>balise_FOO()</code> and is responsible asking SPIP to call the other
two functions: <code>balise_FOO_stat()</code> – which performs whatever static
calculations are required – and <code>balise_FOO_dyn()</code> which performs the dynamic
calculations and display the final content to the user.</p>
<p>An example might make this more clearer. Suppose I’m creating a <code>#HITS</code> tag to
output the number of hits an article has received. My <code>balise_HITS</code> function
arranges for SPIP to call the <code>balise_HITS_*</code> functions like so:</p>
<ol type="1">
<li><p>It calls <code>balise_HITS_stat</code> to determine the static parameters for the tag
(e.g. “id_article=36”).</p></li>
<li><p>It arranges to call <code>balise_HITS_dyn</code>, passing it the static parameters as
determined by <code>balise_HITS_stat</code>.</p></li>
<li><p><code>balise_HITS_dyn</code> uses the static parameters to query the database, etc.
and produces the appropriate output.</p></li>
</ol>
<p>The code to implement the <code>#HITS</code> tag might look like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HITS(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="op">=</span><span class="st">'HITS'</span>) {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="va">$args</span> <span class="op">=</span> <span class="dt">array</span>(<span class="st">'id_article'</span>)<span class="ot">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> calculer_balise_dynamique(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="ot">,</span> <span class="va">$args</span>)<span class="ot">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HITS_stat(<span class="va">$args</span><span class="ot">,</span> <span class="va">$filters</span>) {</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dt">array</span>(<span class="va">$args</span>[<span class="dv">0</span>])<span class="ot">;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HITS_dyn(<span class="va">$id_article</span>) {</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="va">$now</span> <span class="op">=</span> <span class="fu">date</span>(<span class="st">'c'</span>)<span class="ot">;</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="st">&quot;Article </span><span class="va">$id_article</span><span class="st"> has had 1,000,000 hits as of </span><span class="va">$now</span><span class="st">!&quot;</span><span class="ot">;</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>One way this can fall down is if I want to access details of, for example, the
SPIP templates in determining my static parameters. By the time I’m
determining the parameters, I no longer have access to the abstract-syntax
tree node passed to <code>balise_FOO</code>. All I’ve got at this point, is an array of
arguments to the tag and an array of filters applied to the tag.</p>
<h3 id="the-obvious-solution">The obvious solution</h3>
<p>The obvious solution is to add the value to the “<code>$args</code>” array I pass to
<code>calculer_balise_dynamique()</code>. Alas, this will not work as <code>$args</code> is not (in
spite of its usual name) an array of arguments. It is, in fact, an array of
the names of arguments which SPIP is to automatically fetch and pass on the
the <code>balise_*_stat()</code> call. Appending the name of the template file
(<code>"squelettes/foo.html"</code>, for instance) to <code>$args</code> tells SPIP to look for a
variable called <code>squelettes/foo.html</code> in the context the tag is being used and
pass it through to the next function. Needless to say, this doesn’t work.</p>
<h3 id="the-correct-solution">The correct solution</h3>
<p>The correct solution to this problem is to arrange for SPIP to add the values
you want to the <code>$arguments</code> array (or perhaps the <code>$filters</code> array, but this
may not be a good idea). This array contains the values I requested in the
call to <code>calculer_balise_dynamique</code> along with the values of the parameters
passed into the tag in the template. If I can’t use the former route, then
it’ll have to be the second – I’ll need to add a another “fake” parameter to
the AST node before I call <code>calculer_balise_dynamique</code>. (Yes, I agree. This is
a rather odd way to accomplish my goal, but that’s how it goes in SPIP-land).</p>
<p>There are two parts of the SPIP AST that are relevant here: the <code>Champ</code> nodes
that represent tags, and the <code>Texte</code> nodes the represent “strings” (amongst
other things). The <code>$p</code> that is passed to my <code>balise_*</code> functions is an
instance of the <code>Champ</code> class and I’m going to add a new instance of the
<code>Texte</code> class representing my new “fake” parameter. Creating the new object is
pretty simple, just construct it and set it’s <code>type</code> and <code>texte</code> members. The
following example adds a new parameter containing the name of the template
file:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_TEMPLATE(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="op">=</span><span class="st">'TEMPLATE'</span>) {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="va">$file</span> <span class="op">=</span> <span class="va">$p</span>-&gt;descr[<span class="st">'sourcefile'</span>]<span class="ot">;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Create the new object</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="va">$t</span> <span class="op">=</span> <span class="kw">new</span> Texte<span class="ot">;</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="va">$t</span>-&gt;type <span class="op">=</span> <span class="st">'texte'</span><span class="ot">;</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="va">$t</span>-&gt;texte <span class="op">=</span> <span class="va">$file</span><span class="ot">;</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Make sure that $p-param is an array (of the right dimensions)</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="op">!</span> <span class="fu">is_array</span>(<span class="va">$p</span>-&gt;param) ) {</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>        <span class="va">$p</span>-&gt;param <span class="op">=</span> <span class="dt">array</span>(<span class="dt">array</span>(<span class="dv">0</span>=&gt;<span class="kw">NULL</span>))<span class="ot">;</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Append the object to the tag parameters</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="va">$p</span>-&gt;param[<span class="dv">0</span>][] <span class="op">=</span> <span class="dt">array</span>(<span class="va">$t</span>)<span class="ot">;</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Call SPIP's dynamic tags code</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    <span class="va">$args</span> <span class="op">=</span> <span class="dt">array</span>()<span class="ot">;</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> calculer_balise_dynamique(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="ot">,</span> <span class="va">$args</span>)<span class="ot">;</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>First the previous code gets the name of the template file from the AST node
for the tag being processed. Then it creates a new <code>Texte</code> object with the
filename as its value. It ensures that the <code>$p-&gt;param</code> member of the <code>Champ</code>
object is an array (and yes, it <em>does</em> seem to start with a <code>NULL</code> so that we
can pretend that the arrays are 1-indexed) and then appends the new object to
it. All that’s left is to call <code>calculer_balise_dynamique</code> as usual.</p>
<p>With this done, the value of the new “fake” parameter will be evaluated and
passed to the <code>balise_TEMPLATE_stat()</code> call in the <code>$args</code> array and then (if
I choose) passed on to the <code>balise_TEMPLATE_dyn()</code> call.</p>
<h3 id="conclusion">Conclusion</h3>
<p>This technique still strikes me as a bit odd, but it’s the only way I can see
to implement this effect without introducing global variables. In my opinion,
<code>calculer_balise_dynamique</code> should take an array of argument values as an
optional fourth argument, but needing to do this sort of thing is probably
fairly rare (though I have seen it in the code for one or two built-in tags).
Even if this technique is the “Right Way(TM)” to pass extra values around,
then it really does need a helper function like <code>interprete_argument_balise</code>
instead of mucking around with AST internals in every tag that need it.</p>]]></summary>
</entry>
<entry>
    <title>A better way to control attributes in SPIP templates</title>
    <link href="https://passingcuriosity.com/2008/better-control-attributes-spip-templates/" />
    <id>https://passingcuriosity.com/2008/better-control-attributes-spip-templates/</id>
    <published>2008-11-25T00:00:00Z</published>
    <updated>2008-11-25T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><em>Edit:</em> En español:
“<a href="http://nqnwebs.com/blog/article/una-mejor-manera-de-controlar-los">Una mejor manera de controlar los atributos en SPIP</a>”.</p>
<p>Lots of SPIP tags and filters generate HTML mark-up as output (the <code>#LOGO_*</code>
tags and <code>|image_*</code> filters are the most prominent) and we often need or want
to modify this mark-up in our templates. There are several built-in filters to
help with this
(<a href="http://www.spip.net/en_article2465.html#inserer_attribut"><code>inserer_attribut</code></a>
to insert an attribute and
<a href="http://www.spip.net/en_article2465.html#extraire_attribut"><code>extraire_attribut</code></a>
to extract the value of an attribute) but they are pretty long and tedious to
type. Given that I uses these filters quite often when implementing such
things as image galleries, and I still have to think quite hard to type the
French words correctly the can be a bit annoying. Thankfully, a small wrapper
(see below) can smooth these small annoyances away.</p>
<p>When it comes to accessing and modifying the values of attributes nothing, in
my opinion, comes any where near to <a href="http://docs.jquery.com/Attributes">jQuery’s attributes
API</a>. The single <a href="http://docs.jquery.com/Attributes/attr">jQuery <code>attr</code>
method</a> allows you to get and set the
value for any attribute on any node: it takes one or two parameters, the name
of the attribute and, optionally, the value. If only the name is specified,
then <code>attr</code> simply extracts and returns the value of the attribute. If both a
name and a value are specified, then <code>attr</code> modifies the object setting
specified attribute to the specified value. This “polymorphic” style of
interface – where a single method has two complementary behaviours which are
distinguished by the number and/or types of the arguments – is everywhere in
jQuery and is part of what makes it so concise and so productive. Seeing as
it’s the best structure for such interfaces that I know (and also, one I use
daily), I decided that my wrapper should mirror it. Thus the <code>attr</code> filter was
born.</p>
<p>Like the jQuery <code>attr</code> method, the SPIP <code>attr</code> filter takes one or two
parameters (and an implicit “object”, but we’ll ignore if for now). If only
one, it passes the input on to <code>extraire_attribut</code> to get and return the
value. If called with two parameters, it calls <code>inserer_attribut</code> instead to
modify the tag. Like the idea, the code is reasonably straightforward; the
only even slightly unusual but is the use of
<a href="http://php.net/func_get_args" title="PHP manual for func_get_args"><code>func_get_args</code></a>
to get an array of the arguments passed into the function call. With such an
array, we can use <a href="http://php.net/count" title="PHP manual for count"><code>count</code></a> to
check how many arguments the function was given and decide whether we should
get or set the attribute. This is safer than specifying and checking a default
value (<code>FALSE</code> or <code>NULL</code>, for example) because some user may genuinely want to
use that value (perhaps <code>NULL</code> will mean delete the attribute in a future
version?) and silently ignoring user input is never good.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;?php</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>include_spip(<span class="st">&quot;inc/filtres&quot;</span>)<span class="ot">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="co">/**</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co"> * The `attr` function allows the user to get and set the attributes of an</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="co"> * HTML tag. It is intended to be used as a SPIP filter and depends on </span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="co"> * existing SPIP functionality.</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="co"> *</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">$tag</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="co"> *     The HTML code.</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">$name</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="co"> *     The name of the attribute.</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@param</span><span class="co"> </span><span class="cv">$val..</span><span class="co">.</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="co"> *     The new value for the attribute $nom. Optional.</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="co"> * </span><span class="an">@return</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co"> *     If $val was given, the code for tag with $name=$val</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="co"> *     Otherwise, the value for the $name attribute in $tag.</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="co"> */</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> attr(<span class="va">$tag</span><span class="ot">,</span> <span class="va">$name</span>){</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>        <span class="va">$args</span> <span class="op">=</span> <span class="fu">func_get_args</span>()<span class="ot">;</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> (<span class="fu">count</span>(<span class="va">$args</span>) <span class="op">&gt;</span> <span class="dv">2</span>) {</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>                <span class="co">// SET</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span>  inserer_attribut(<span class="va">$tag</span><span class="ot">,</span> <span class="va">$name</span><span class="ot">,</span> <span class="va">$args</span>[<span class="dv">2</span>])<span class="ot">;</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>        } <span class="cf">else</span> {</span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>                <span class="co">// GET</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> extraire_attribut(<span class="va">$tag</span><span class="ot">,</span> <span class="va">$name</span>)<span class="ot">;</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>        }</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Simply copy the code into the <code>mes_fonctions.php</code> file for your site (see
“Adding your own filters” in <a href="http://www.spip.net/en_article2465.html">SPIP’s
Filters</a>) and use <code>attr</code> in your SPIP
templates:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;[(#FICHIER|attr{src})]&quot;</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;lightbox&quot;</span><span class="ot"> title</span><span class="op">=</span><span class="st">&quot;#TITRE&quot;</span><span class="dt">&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    [(#FICHIER|image_reduire{100,100}|attr{alt,#TITRE})]</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;/</span><span class="kw">a</span><span class="dt">&gt;</span></span></code></pre></div>
<p>There are a few changes that could be made to this function: passing <code>$args</code>
directly to <code>inserer_attribut</code> and <code>extraire_attribut</code> rather than the
individual variables, adding a <code>$value=FALSE</code> parameter for the sake of
documentation and then ignoring it (I’m not sure if this will work and don’t
care enough to try it), deleting attributes when passed e.g. <code>NULL</code> as a
value, etc. For the time being, however, it does the job.</p>
<p>A final note: you’ll probably need to be running PHP 5 for this to work – the
<code>func_get_args</code> documentation (linked above) mentions version 5.3.0 – and the
code above was modified after I last tested it, but should work anyway.</p>]]></summary>
</entry>
<entry>
    <title>Creating custom tags for SPIP - Static tags</title>
    <link href="https://passingcuriosity.com/2008/creating-custom-tags-spip-static/" />
    <id>https://passingcuriosity.com/2008/creating-custom-tags-spip-static/</id>
    <published>2008-11-19T00:00:00Z</published>
    <updated>2008-11-19T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>The SPIP template language has two constructions: loops (which determine the
objects to be “output”) and tags (which actually output particular values).
The reasonably simple syntax of tags – most look like ’‘#THE_TAG’’ – belies
their power and flexibility and the ease with which we can use them to extend
SPIP with additional features and integrate it with other PHP-based packages.</p>
<p>In this post, I’ll describe how to create your own static SPIP tags. In a
future post, I’ll cover dynamic tags, and how to package your tags (and other
code) as a plug-in. Before reading this post, you should be familiar with
<a href="http://www.spip.net/">SPIP</a> and it’s <a href="/2008/spip-template-languag/">template
language</a>, and with programming in PHP.</p>
<p>SPIP tags are used to “output” a “value”. For many tags, this value is taken
from the context in which it is called: the title of the “current” article,
for example, or the logo the “current” news item. Others output global values
like the name of the web-site, or the version of the software. Still more tags
allow users to interact with the site (e.g. <code>#LOGIN_PUBLIC</code> which outputs a
log-in form <em>and</em> processes the log-in request when the user submits it) and a
few (like ’‘#SET’’ and ’‘#GET’’) implement the features of a general purpose
programming language and producing output is only a side effect. All of these
effects are achieved using the same relatively simple syntax and mechanism.</p>
<p>Tags can be divided into two groups based on their behaviour. <em>Static</em> tags
are those that output some statically determined value – one that does not
necessarily change from one evaluation to another. The title of an article,
for example, will not <em>necessarily</em> change between one page view and another.
It <em>may</em>, but not necessarily. <em>Dynamic</em> tags are those that generate dynamic
output – values that necessarily change between invocations. The current date
and time, for example. Implementing a static tag is significantly easier than
a dynamic tag, so we’ll look at that first and leave dynamic tags to a later
post.</p>
<h2 id="static-tags">Static tags</h2>
<p>Static tags are those that output a “static” value. That is, a value that is
not expected to change over any particular time period. This means that SPIP
can evaluate a static tag once and then cache the result and reuse it in
future requests.</p>
<p>Like many aspects of SPIP, a tag (for the rest of this section, you can assume
that “tag” means “static tag”) is a function<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> with a special name – the
name of the tag appended to “balise_”. For example a tag called <code>#FOO</code> will be
implemented by a function called <code>balise_FOO</code>. Like much of SPIP, these
functions can be overridden by plug-ins, or site-specific files. When it sees
a <code>#FOO</code> tag, SPIP will first look for a function called <code>balise_FOO</code>, then
one called <code>balise_FOO_dist</code>, and then decide that the tag doesn’t exist.</p>
<p>Rather than blather on, I’ll give you a trivial example: the <code>#HELLO_WORLD</code>
tag. This tag simply outputs the string “Hello World!” (To use the code,
simply copy the function into the file <code>mes_fonctions.php</code> in the root of your
SPIP installation):</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;?php</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HELLO_WORLD(<span class="va">$p</span>) {</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="va">$p</span>-&gt;code <span class="op">=</span> <span class="st">&quot;'Hello World!'&quot;</span><span class="ot">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="va">$p</span><span class="ot">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>As you can see there are a few more details than just the name, namely, this
<code>$p</code> thing. The parameter to the function implementing the tag is a reference
to the abstract syntax tree node for that tag. This contains all of the
information about the tag that SPIP has about the tag, the filters called on
it, the brackets around it, the context, etc., etc., etc. All that is missing
is the value itself, which is where our function comes into play. After SPIP
has analysed the templates and handled everything <em>it</em> can, it calls the
function responsible for each tag to fill in the gaps.</p>
<p>There a numerous fields in the <code>Champ</code> object (the class is defined in
<a href="http://trac.rezo.net/trac/spip/browser/spip/ecrire/public/interfaces.php"><code>ecrire/public/interfaces.php</code></a>
but the definition isn’t particularly edifying), but most of them are best
left alone and accessed by way of helper functions:</p>
<ul>
<li><p><code>type</code> – a string describing the type of AST node. Should be <code>"champ"</code> for
tags.</p></li>
<li><p><code>nom_champ</code> – the name of the tag without the <code>#</code>.</p></li>
<li><p><code>nom_boucle</code> – the name of the loop. Tags aren’t loops, so this will be
empty.</p></li>
<li><p><code>avant</code> – a list of preceding nodes that are conditional on this one.</p></li>
<li><p><code>apres</code> – a list of succeeding nodes that are conditional on this one.</p></li>
<li><p><code>etoile</code> – “star”. The tag was called like <code>#HELLO_WORLD*</code> and, thus,
should output raw, as opposed to HTML safe, values.</p></li>
<li><p><code>param</code> – a list of parameters and filters to the tag call. This is pretty
complex.</p></li>
<li><p><code>fonctions</code> – similar to <code>param</code> but structured differently.</p></li>
<li><p><code>id_boucle</code> – the name of the loop within which this tag occurs.</p></li>
<li><p><code>boucles</code> – an array of AST nodes for the loops (“boulces”) in the
template.</p></li>
<li><p><code>type_requete</code> – no idea.</p></li>
<li><p><code>code</code> – the PHP code which, when <code>eval()</code>d, produces the value of the tag.</p></li>
<li><p><code>interdire_scripts</code> – whether “scripts” will be interpreted. No idea.</p></li>
<li><p><code>ramasser_miettes</code> – whether to “collect the crumbs”. No idea.</p></li>
<li><p><code>descr</code> – an array of values describing the AST node, the file it came
from, etc.</p></li>
<li><p><code>ligne</code> – the line number of the tag call in the template.</p></li>
</ul>
<p><strong>An example</strong> Replacing the contents of your <code>dist/sommaire.html</code> template
with this:</p>
<pre><code>[before (#HELLO_WORLD{arg1}|strtoupper) after]</code></pre>
<p>might result in the following AST being passed to <code>balise_HELLO_WORLD</code> above
(<a href="/files/2008/11/spip-ast-example.txt">download the full SPIP AST</a>):</p>
<pre><code>type =&gt; &quot;champ&quot;
nom_champ =&gt; &quot;HELLO_WORLD&quot;
avant =&gt; the node/s for &quot;before&quot;, ...
apres =&gt; the node/s for &quot;after&quot;, ...
etoile =&gt; 
param =&gt; [
        0 =&gt; &quot;arg1&quot; is in here, ...
        1 =&gt; &quot;strtoupper&quot; is in here, ...
        ]
fonctions =&gt; [
        0 =&gt; &quot;{arg1}&quot; is also in here, ...
        1 =&gt; &quot;strtoupper&quot; is also in here, ...
        ]</code></pre>
<p>Thankfully, you can ignore almost all of this and trust to the helpers. The
function <a href="http://doc.spip.org/@interprete_argument_balise" title="fonction interprete_argument_balise"><code>interprete_argument_balise</code>
(FR)</a> is particularly useful:
<code>interprete_argument_balise(1, $p)</code> returns the first argument in the AST node
<code>$p</code>.</p>
<p>Using what I’ve described so far, it’s pretty to write a <code>#HELLO</code> tag which
output’s a message “Hello <em>name</em>” when given a name, and “Hello World!”
otherwise (again, this code goes in <code>mes_fonctions.php</code>):</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">&lt;?php</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HELLO(<span class="va">$p</span>) {</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="va">$name</span> <span class="op">=</span> interprete_argument_balise(<span class="dv">1</span><span class="ot">,</span> <span class="va">$p</span>)<span class="ot">;</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="op">!</span> <span class="va">$name</span>) {</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>        <span class="va">$name</span> <span class="op">=</span> <span class="st">&quot;World!&quot;</span><span class="ot">;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    <span class="va">$p</span>-&gt;code <span class="op">=</span> <span class="st">&quot;'Hello </span><span class="va">$name</span><span class="st">'&quot;</span><span class="ot">;</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="va">$p</span><span class="ot">;</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>There are a number of other issues involved in writing static templates. It’s
good practice to make sure that your tags (and everything else, for that
matter) supports translation, especially if you’re going to be distributing it
to others. Doing so is reasonably easy using the <a href="http://doc.spip.org/@Les-chaines-de-langue" title="Les chaines de langue"><code>_T</code>
(FR)</a>
function and “lang” files. Getting data from a loop (article titles, section
IDs, etc.) is also reasonably straightforward with <a href="http://doc.spip.org/@champ_sql"><code>champ_sql</code>
(FR)</a>.</p>
<p>For more examples, you can have a look at the code for some of SPIP’s built-in
tags in the code of <a href="http://doc.spip.org/balises-php"><code>ecrire/public/balises.php</code>
(FR)</a> (I rather like
<a href="http://doc.spip.org/@balise_INTRODUCTION_dist"><code>balise_INTRODUTION_dist</code>
(FR)</a>). If you do look to the
SPIP source code for examples, you should be aware that a lot of the built-in
tags are not implemented using this mechanism, but are magically drawn from
database columns with the same name. If you extend the database this magic
will work for you too, but that is beyond the scope of this post and will have
to wait for my post/s about writing SPIP plug-ins.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>In one sense, this is not entirely true: the function just manipulates
the abstract syntax tree node for the tag which will then be processed by SPIP
to generate the tag. For more on this see <a href="http://doc.spip.org/@details-sur-l-AST" title="dÈtails sur líAST">details of the AST
(FR)</a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>]]></summary>
</entry>

</feed>
