Fwd: Routing and controller arguments in K3

Shad Laws <shad-xpYdmXCiSuZWk0Htik3J/[email protected]> Tue, 16 Apr 2013 11:52:00 +0200
Newsgroups gmane.comp.web.gallery.devel
Message-ID <CA+z51A7z9YBVd=DMFDARLeFxN4Wgx2_YLAcTtaDNT_YrNW7joA@mail.gmail.com>
--===============0180390569735985280==
Content-Type: multipart/alternative; boundary=089e013c66a65c364904da775351

--089e013c66a65c364904da775351
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hey Bharat,
(sorry, forgot to hit reply all the first time...)

Yes, Kohana gives us a few precedents to having the number of arguments
change the semantics of the function.  Perhaps most relevant here are
Request's param(), query(), and post() functions.

For query() and post():
- 0 arguments: get whole array
- 1 array argument: set whole array
- 1 non-array argument: get one value (default to null)
- 2 arguments: set one value

For param():
- 0 arguments: get whole array
- 1 argument: get one value (default to null)
- 2 arguments: get one value, default to second argument (really just a
variation of the 1-argument case)

So while I can see your point regarding overloading required vs. optional,
I think that overloading array vs. value follows precedent rather closely.

Speaking of following Kohana precedent, I'm starting to realize that the
core of this functionality shouldn't be in Controller.  Rather, it should
be in Request along with its sister functions param(), query(), and post().
 Then, in Controller we should have arg() as an alias and arg_required()
that fires HTTP 400 if required.

So, take three:
- core of arg getting and filtering in Request
- arg() alias in Controller
- arg_required($key) in Controller that fires HTTP 400 if not found
- arg_required($key, $rule) in Controller that also fires HTTP 400 if the
found value doesn't match the rule

Okay, so that last bullet is new to the discussion, but I think it'd be
pretty useful.  Examples are in the code comments below...


class Gallery_Request extends Kohana_Request {
  protected $_args;

  /**
   * Retrieves a value from the route args.  This uses a syntax similar to
param().
   *
   *   $args =3D $request->arg();          // Returns all args
   *   $id   =3D $request->arg(0);         // Returns 0th arg
   *   $type =3D $request->arg(1, "item"); // Returns 1st arg, defaults to
"item" if not set
   *
   * @param   mixed  $key      Key of the value (string or int)
   * @param   mixed  $default  Default value if the key is not set
(optional)
   * @return  mixed
   */
  public function arg($key=3Dnull, $default=3Dnull) {
    if (!isset($this->_args)) {
      $this->_args =3D preg_replace("|/+|", "/", trim($this->param("args"),
"/"));
      $this->_args =3D (array) explode("/", $this->_args);
      $this->_args =3D Purifier::clean_html($this->_args);
    }

    return isset($key) ? Arr::get($this->_args, $key, $default) :
$this->_args;
  }
}

class Gallery_Controller extends Kohana_Controller {
  // Other code ...

  /**
   * Retrieves a value from the route args.  This is an alias of
$this->request->arg().
   *
   *   $args =3D $this->arg();          // Returns all args
   *   $id   =3D $this->arg(0);         // Returns 0th arg
   *   $type =3D $this->arg(1, "item"); // Returns 1st arg, defaults to "it=
em"
if not set
   *
   * @param   mixed  $key      Key of the value (string or int)
   * @param   mixed  $default  Default value if the key is not set
(optional)
   * @return  mixed
   */
  public function arg($key=3Dnull, $default=3Dnull) {
    return $this->request->arg($key, $default);
  }

  /**
   * Retrieves a value from the route args, and throws an HTTP 400 Bad
Request error if not found.
   * Optionally, a rule argument can be specified that sets further
restrictions on the value and
   * throws an HTTP 400 Bad Request if invalid.
   *
   *   $arg0 =3D $this->arg(0);               // must be defined (no furthe=
r
restrictions)
   *   $id   =3D $this->arg(1, "digit");      // must be [0-9]; useful for =
ids
   *   $type =3D $this->arg(2, "alpha");      // must be [A-Za-z]; useful f=
or
types
   *                                        // (e.g. movie, photo, item,
group, tag,...)
   *   $name =3D $this->arg(3, "alpha_dash"); // must be [A-Za-z0-9-_];
useful for module-like names
   *                                        // (e.g. server_add, items_tag,
admin_wind,...)
   *
   * Note that the names "digit", "alpha", and "alpha_dash" are similar to
their like-named
   * functions in the Valid class, except that the filters here are more
restrictive in that they
   * do not support UTF-8 and are locale-invariant (e.g. Valid::alpha()
could pass "=C3=A2=C3=A7c=C3=A9=C3=B1ts").
   *
   * @param   mixed  $key   Key of the value (string or int)
   * @param   string $rule  Name Default value if the key is not set
   * @return  mixed
   */
  public function arg_required($key, $rule=3Dnull) {
    $value =3D $this->request->arg($key);
    if (is_null($value) ||
        (($rule =3D=3D "digit")      && preg_match("/[^0-9]/", $value)) ||
        (($rule =3D=3D "alpha")      && preg_match("/[^A-Za-z]/", $value)) =
||
        (($rule =3D=3D "alpha_dash") && preg_match("/[^A-Za-z0-9-_]/",
$value))) {
      throw HTTP_Exception::factory(400);
    }

    return $value;
  }
}

I'm starting to really like this approach... your thoughts?

Take care,
Shad


On 16 April 2013 00:41, Bharat Mediratta <[email protected]> wrote:

>
> Here's take two.  No arguments means give full array; one argument means
>> required; two arguments means not required with default value specified.
>>
>
> In a hurry so I'll keep this short...
>
> As APIs go, I'm not thrilled about varying the semantics based on the
> number of arguments to the function.  It feels a little overloaded to me.
>  Is there any precedent for this in Kohana?  I can't find it.
>
> I think I'd prefer
>
>   function args();               // return all args
>   function arg($key, $default);  // return value with default if it's
> missing
>   function arg_required($key);   // return value or throw exception
>
> Then it's very obvious in the controller code what's required and what
> isn't.  A 404 isn't really right either - I think we should be throwing a
> 400 Bad Request instead in these cases.
>

--089e013c66a65c364904da775351
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hey Bharat,<div>(sorry, forgot to hit reply all the first time...)<br><div =
class=3D"gmail_quote"><div><br></div><div>Yes, Kohana gives us a few preced=
ents to having the number of arguments change the semantics of the function=
. =C2=A0Perhaps most relevant here are Request&#39;s param(), query(), and =
post() functions.</div>


<div><br></div><div>For query() and post():</div><div>- 0 arguments: get wh=
ole array</div><div>- 1 array argument: set whole array</div><div>- 1 non-a=
rray argument: get one value (default to null)</div><div>- 2 arguments: set=
 one value</div>


<div><br></div><div>For param():</div><div>- 0 arguments: get whole array</=
div><div>- 1 argument: get one value (default to null)</div><div>- 2 argume=
nts: get one value, default to second argument (really just a variation of =
the 1-argument case)</div>


<div><br></div><div>So while I can see your point regarding overloading req=
uired vs. optional, I think that overloading array vs. value follows preced=
ent rather closely.</div><div><br></div><div>Speaking of following Kohana p=
recedent, I&#39;m starting to realize that the core of this functionality s=
houldn&#39;t be in Controller. =C2=A0Rather, it should be in Request along =
with its sister functions param(), query(), and post(). =C2=A0Then, in Cont=
roller we should have arg() as an alias and arg_required() that fires HTTP =
400 if required.</div>


<div><br></div><div>So, take three:</div><div>- core of arg getting and fil=
tering in Request</div><div>- arg() alias in Controller</div><div>- arg_req=
uired($key) in Controller that fires HTTP 400 if not found</div><div>- arg_=
required($key, $rule) in Controller that also fires HTTP 400 if the found v=
alue doesn&#39;t match the rule</div>


<div><br></div><div>Okay, so that last bullet is new to the discussion, but=
 I think it&#39;d be pretty useful. =C2=A0Examples are in the code comments=
 below...</div><div><br></div><div><br></div><div><div style>
<div><font color=3D"#222222" face=3D"courier new, monospace">class Gallery_=
Request extends Kohana_Request {</font></div><div><font color=3D"#222222" f=
ace=3D"courier new, monospace">=C2=A0 protected $_args;</font></div><div><f=
ont color=3D"#222222" face=3D"courier new, monospace"><br>


</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 /**</font></div><div><font color=3D"#222222" face=3D"courier new, mo=
nospace">=C2=A0 =C2=A0* Retrieves a value from the route args. =C2=A0This u=
ses a syntax similar to param().</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 =C2=A0* =C2=A0 $args =3D $request-&gt;arg(); =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0// Returns all args</font></div><div><font color=3D"#222222" f=
ace=3D"courier new, monospace">=C2=A0 =C2=A0* =C2=A0 $id =C2=A0 =3D $reques=
t-&gt;arg(0); =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Returns 0th arg</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 =C2=A0 $type =3D $request-&gt;arg(1, &quot;item&quot;); // Returns 1st arg=
, defaults to &quot;item&quot; if not set</font></div><div><font color=3D"#=
222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 @param =C2=A0 mixed =C2=A0$key =C2=A0 =C2=A0 =C2=A0Key of the value (strin=
g or int)</font></div><div><font color=3D"#222222" face=3D"courier new, mon=
ospace">=C2=A0 =C2=A0* @param =C2=A0 mixed =C2=A0$default =C2=A0Default val=
ue if the key is not set (optional)</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 @return =C2=A0mixed</font></div><div><font color=3D"#222222" face=3D"couri=
er new, monospace">=C2=A0 =C2=A0*/</font></div><div><font color=3D"#222222"=
 face=3D"courier new, monospace">=C2=A0 public function arg($key=3Dnull, $d=
efault=3Dnull) {</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =
if (!isset($this-&gt;_args)) {</font></div><div><font color=3D"#222222" fac=
e=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 $this-&gt;_args =3D preg_=
replace(&quot;|/+|&quot;, &quot;/&quot;, trim($this-&gt;param(&quot;args&qu=
ot;), &quot;/&quot;));</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 $this-&gt;_args =3D (array) explode(&quot;/&quot;, $this-&gt;_args);=
</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 =C2=A0 =C2=A0 $this-&gt;_args =3D Purifier::clean_html($this-&gt;_ar=
gs);</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =
}</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
<br></font></div><div><font color=3D"#222222" face=3D"courier new, monospac=
e">=C2=A0 =C2=A0 return isset($key) ? Arr::get($this-&gt;_args, $key, $defa=
ult) : $this-&gt;_args;</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 }</font=
></div><div><font color=3D"#222222" face=3D"courier new, monospace">}</font=
></div><div><font color=3D"#222222" face=3D"courier new, monospace"><br></f=
ont></div><div>


<font color=3D"#222222" face=3D"courier new, monospace">class Gallery_Contr=
oller extends Kohana_Controller {</font></div><div><font color=3D"#222222" =
face=3D"courier new, monospace">=C2=A0 // Other code ...</font></div><div><=
font color=3D"#222222" face=3D"courier new, monospace"><br>


</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 /**</font></div><div><font color=3D"#222222" face=3D"courier new, mo=
nospace">=C2=A0 =C2=A0* Retrieves a value from the route args. =C2=A0This i=
s an alias of $this-&gt;request-&gt;arg().</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 =C2=A0* =C2=A0 $args =3D $this-&gt;arg(); =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0// Returns all args</font></div><div><font color=3D"#222222" face=
=3D"courier new, monospace">=C2=A0 =C2=A0* =C2=A0 $id =C2=A0 =3D $this-&gt;=
arg(0); =C2=A0 =C2=A0 =C2=A0 =C2=A0 // Returns 0th arg</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 =C2=A0 $type =3D $this-&gt;arg(1, &quot;item&quot;); // Returns 1st arg,=
=C2=A0</font><span style=3D"color:rgb(34,34,34);font-family:&#39;courier ne=
w&#39;,monospace">defaults to</span><font color=3D"#222222" face=3D"courier=
 new, monospace">=C2=A0&quot;item&quot; if not set</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 =C2=A0* @param =C2=A0 mixed =C2=A0$key =C2=A0 =C2=A0 =C2=A0Key of th=
e value (string or int)</font></div><div><font color=3D"#222222" face=3D"co=
urier new, monospace">=C2=A0 =C2=A0* @param =C2=A0 mixed =C2=A0$default =C2=
=A0Default value if the key is not set (optional)</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 @return =C2=A0mixed</font></div><div><font color=3D"#222222" face=3D"couri=
er new, monospace">=C2=A0 =C2=A0*/</font></div><div><font color=3D"#222222"=
 face=3D"courier new, monospace">=C2=A0 public function arg($key=3Dnull, $d=
efault=3Dnull) {</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =
return $this-&gt;request-&gt;arg($key, $default);</font></div><div><font co=
lor=3D"#222222" face=3D"courier new, monospace">=C2=A0 }</font></div><div><=
font color=3D"#222222" face=3D"courier new, monospace"><br>


</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 /**</font></div><div><font color=3D"#222222" face=3D"courier new, mo=
nospace">=C2=A0 =C2=A0* Retrieves a value from the route args, and throws a=
n HTTP 400 Bad Request error if not found.</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 Optionally, a rule argument can be specified that sets further restriction=
s on the value and</font></div><div><font color=3D"#222222" face=3D"courier=
 new, monospace">=C2=A0 =C2=A0* throws an HTTP 400 Bad Request if invalid.<=
/font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 =C2=A0* =C2=A0 $arg0 =3D $this-&gt;arg(0); =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 // must be defined (no further restrictions)</font=
></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 =C2=A0 $id =C2=A0 =3D $this-&gt;arg(1, &quot;digit&quot;); =C2=A0 =C2=A0 =
=C2=A0// must be [0-9]; useful for ids</font></div><div><font color=3D"#222=
222" face=3D"courier new, monospace">=C2=A0 =C2=A0* =C2=A0 $type =3D $this-=
&gt;arg(2, &quot;alpha&quot;); =C2=A0 =C2=A0 =C2=A0// must be [A-Za-z]; use=
ful for types</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0// (e.g. =
movie, photo, item, group, tag,...)</font></div><div><font color=3D"#222222=
" face=3D"courier new, monospace">=C2=A0 =C2=A0* =C2=A0 $name =3D $this-&gt=
;arg(3, &quot;alpha_dash&quot;); // must be [A-Za-z0-9-_]; useful for modul=
e-like names</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0// (e.g. =
server_add, items_tag, admin_wind,...)</font></div><div><font color=3D"#222=
222" face=3D"courier new, monospace">=C2=A0 =C2=A0*</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 Note that the names &quot;digit&quot;, &quot;alpha&quot;, and &quot;alpha_=
dash&quot; are similar to their like-named</font></div><div><font color=3D"=
#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0* functions in the Va=
lid class, except that the filters here are more restrictive in that they</=
font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 do not support UTF-8 and are locale-invariant (e.g. Valid::alpha() could p=
ass &quot;=C3=A2=C3=A7c=C3=A9=C3=B1ts&quot;).</font></div><div><font color=
=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 @param =C2=A0 mixed =C2=A0$key =C2=A0 Key of the value (string or int)</fo=
nt></div><div><font color=3D"#222222" face=3D"courier new, monospace">=C2=
=A0 =C2=A0* @param =C2=A0 string $rule =C2=A0Name Default value if the key =
is not set</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0*=
 @return =C2=A0mixed</font></div><div><font color=3D"#222222" face=3D"couri=
er new, monospace">=C2=A0 =C2=A0*/</font></div><div><font color=3D"#222222"=
 face=3D"courier new, monospace">=C2=A0 public function arg_required($key, =
$rule=3Dnull) {</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =
$value =3D $this-&gt;request-&gt;arg($key);</font></div><div><font color=3D=
"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 if (is_null($value)=
 ||</font></div><div><font color=3D"#222222" face=3D"courier new, monospace=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 (($rule =3D=3D &quot;digit&quot;) =C2=A0 =C2=
=A0 =C2=A0&amp;&amp; preg_match(&quot;/[^0-9]/&quot;, $value)) ||</font></d=
iv>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 (($rule =3D=3D &quot;alpha&quot;) =C2=A0 =C2=A0 =C2=A0&amp;&a=
mp; preg_match(&quot;/[^A-Za-z]/&quot;, $value)) ||</font></div><div><font =
color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (($rule =3D=3D &quot;alpha_dash&quot;) &amp;&amp; preg_match(&quot;/[^A=
-Za-z0-9-_]/&quot;, $value))) {</font></div>


<div><font color=3D"#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 =
=C2=A0 throw HTTP_Exception::factory(400);</font></div><div><font color=3D"=
#222222" face=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></div><div><=
font color=3D"#222222" face=3D"courier new, monospace"><br>


</font></div><div><font color=3D"#222222" face=3D"courier new, monospace">=
=C2=A0 =C2=A0 return $value;</font></div><div><font color=3D"#222222" face=
=3D"courier new, monospace">=C2=A0 }</font></div><div><font color=3D"#22222=
2" face=3D"courier new, monospace">}</font></div>


<div style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13=
px"><br></div><div style=3D"color:rgb(34,34,34);font-family:arial,sans-seri=
f;font-size:13px">I&#39;m starting to really like this approach... your tho=
ughts?</div>


<div style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13=
px"><br></div><div style=3D"color:rgb(34,34,34);font-family:arial,sans-seri=
f;font-size:13px">Take care,</div><div style=3D"color:rgb(34,34,34);font-fa=
mily:arial,sans-serif;font-size:13px">


Shad</div><div style=3D"color:rgb(34,34,34);font-family:arial,sans-serif;fo=
nt-size:13px"><br></div><div style=3D"color:rgb(34,34,34);font-family:arial=
,sans-serif;font-size:13px"><br></div></div><div class=3D"gmail_quote">On 1=
6 April 2013 00:41, Bharat Mediratta <span dir=3D"ltr">&lt;<a href=3D"mailt=
o:[email protected]" target=3D"_blank">[email protected]</a>&gt;</span> w=
rote:<br>


<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div class=3D"gmail_ext=
ra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div><div class=3D"gmail_quote"><div>Here&#39;s take two. =C2=A0No argument=
s means give full array; one argument means required; two arguments means n=
ot required with default value specified.</div>

<div></div></div></div></blockquote></div><br></div><div class=3D"gmail_ext=
ra">In a hurry so I&#39;ll keep this short...=C2=A0</div><div class=3D"gmai=
l_extra"><br></div><div class=3D"gmail_extra">As APIs go, I&#39;m not thril=
led about varying the semantics based on the number of arguments to the fun=
ction. =C2=A0It feels a little overloaded to me. =C2=A0Is there any precede=
nt for this in Kohana? =C2=A0I can&#39;t find it.</div>




<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">I think I&#=
39;d prefer</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_e=
xtra"><font face=3D"courier new, monospace">=C2=A0 function args(); =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 // return all args</font></div>




<div class=3D"gmail_extra"><font face=3D"courier new, monospace">=C2=A0 fun=
ction arg($key, $default); =C2=A0// return value with default if it&#39;s m=
issing</font></div><div class=3D"gmail_extra"><font face=3D"courier new, mo=
nospace">=C2=A0 function arg_required($key); =C2=A0 // return value or thro=
w exception</font></div>




<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Then it&#39=
;s very obvious in the controller code what&#39;s required and what isn&#39=
;t. =C2=A0A 404 isn&#39;t really right either - I think we should be throwi=
ng a 400 Bad Request instead in these cases.</div>




</div>
</blockquote></div><br></div>
</div><br></div>

--089e013c66a65c364904da775351--


--===============0180390569735985280==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
--===============0180390569735985280==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

__[ g a l l e r y - d e v e l ]_________________________

[ list info/archive --> http://gallery.sf.net/lists.php ]
[ gallery info/FAQ/download --> http://gallery.sf.net ]
--===============0180390569735985280==--