Issue

ZF-2270: Zend_Filter_Boolean

Issue Type: New Feature Created: 2007-12-05T14:07:57.000+0000 Last Updated: 2009-09-30T11:59:07.000+0000 Status: Resolved Fix version(s): - 1.10.0 (27/Jan/10)

Reporter: Jordan Ryan Moore (jordanryanmoore) Assignee: Thomas Weidner (thomas) Tags: - Zend_Filter

Related issues: Attachments: - Boolean.php

Description

A new filter that converts values to booleans.

<pre class="highlight">
class Zend_Filter_Boolean implements Zend_Filter_Interface {
    /**
     * Values that are equivilent to true.
     *
     * @var array
     */
    protected $_true = array('t', 'true', 'y', 'yes', '1');

    /**
     * Values that are equivilent to false.
     *
     * @var array
     */
    protected $_false = array('f', 'false', 'n', 'no', '0');

    /**
     * The default value if the provided value does not match any of the
     * expected values.
     *
     * @var bool
     */
    protected $_default = false;

    /**
     * Constructs a boolean filter.
     *
     * @param   bool    $default    The default value if the provided value
     *                              does not match any of the expected values.
     */
    public function __construct($default = false) {
        $this->_default = (bool) $default;
    }

    /**
     * Casts value to a boolean.
     *
     * @param   mixed   $value
     *
     * @return  bool
     */
    public function filter($value) {
        if (is_bool($value) || is_null($value)) {
            return (bool) $value;
        }

        $value = strtolower(trim($value));

        if (in_array($value, $this->_true)) {
            return true;
        }

        if (in_array($value, $this->_false)) {
            return false;
        }

        return $this->_default;
    }
}

Comments

Posted by Simone Carletti (weppos) on 2007-12-26T17:48:17.000+0000

Hi Jordan, I agree with this filter, but I think the class deserves a little more discussion.

I gave a look at your suggestion but, for example, it seems unable to handle an array. I would expect an empty array to be evaluated as false and a not empty array as true, as (bool) already does. It doesn't handle objects as well.

I suggest to check whether the variable is a scalar type (http://php.net/manual/en/function.is-scalar.php). If no, the default (bool) cast statement might be used, otherwise we could rely to in_array() comparison.

Additionally, it would be great to provide an #addValue method (or perhaps #addTrue() and #addFalse() methods) to let developers add more values to default array.

What do you think?

Posted by Jordan Ryan Moore (jordanryanmoore) on 2007-12-27T11:18:36.000+0000

Added an addValue() method and support for Zend_Locale. I'm not sure if a non-scalar should return its default PHP boolean cast, or if it should return the default value set in the filter. This version returns its default PHP boolean cast.

<pre class="highlight">
class Zend_Filter_Boolean implements Zend_Filter_Interface
{
    /**
     * Default values and their boolean counterparts.
     *
     * @var array
     */
    protected $_defaultValues = array(
        't'     => true,
        'true'  => true,
        'y'     => true,
        'yes'   => true,
        '1'     => true,
        'f'     => false,
        'false' => false,
        'n'     => false,
        'no'    => false,
        '0'     => false,
    );

    /**
     * Values and their boolean counterparts.
     *
     * @var array
     */
    protected $_values = array();

    /**
     * The default value if the provided value does not match any of the expected values.
     *
     * @var bool
     */
    protected $_default = false;

    /**
     * Constructs a boolean filter.
     *
     * @param   bool                $default    The default value if the provided value does not match any of the
     *                                          expected values.
     * @param   Zend_Locale|string  $locale     An optional locale to retreive true/false values from.
     */
    public function __construct($default = null, $locale = null)
    {
        if (!is_null($default)) {
            $this->_default = (bool) $default;
        }

        $this->setLocale($locale);
    }

    /**
     * Sets the locale.
     *
     * @param   Zend_Locale|null    $locale
     *
     * @return  Zend_Filter_Boolean
     */
    public function setLocale($locale)
    {
        $this->_values = $this->_defaultValues;

        if (!is_null($locale)) {
            if (!class_exists('Zend_Locale')) {
                require_once 'Zend/Locale.php';
            }

            if (!$local instanceof Zend_Locale) {
                $locale = new Zend_Locale($locale);
            }

            $q = $locale->getQuestion();

            $this->_values[$q['yes']]       = true;
            $this->_values[$q['yesabbr']]   = true;
            $this->_values[$q['no']]        = false;
            $this->_values[$q['noabbr']]    = false;
        }

        return $this;
    }

    /**
     * Adds a value to the list.
     *
     * @param   mixed   $value
     * @param   bool    $bool
     *
     * @return  Zend_Filter_Boolean
     */
    public function addValue($value, $bool)
    {
        if (!is_scalar($value)) {
            require_once 'Zend/Filter/Exception.php';
            throw new Zend_Filter_Exception('$value must be a scalar');
        }

        $this->_defaultValues[trim($value)] = (bool) $bool;

        return $this;
    }

    /**
     * Casts value to a boolean.
     *
     * @param   mixed   $value
     *
     * @return  bool
     */
    public function filter($value) {
        if (!is_scalar($value) || is_bool($value) || is_null($value)) {
            return (bool) $value;
        }

        $value = trim($value);

        if (function_exists('mb_strtolower')) {
            $value = mb_strtolower($value);
        } else {
            $value = strtolower($value);
        }

        if (array_key_exists($value, $this->_values)) {
            return $this->_values[$value];
        }

        return $this->_default;
    }
}

Posted by Jordan Ryan Moore (jordanryanmoore) on 2007-12-28T13:15:09.000+0000

Attached new Zend_Filter_Boolean that fixes a couple bugs, returns the default value for non-scalars, uses the mb extension (if available), and ever-so-slightly improves memory usage.

Posted by Darby Felton (darby) on 2008-01-29T09:59:20.000+0000

(reposting comment with formatting :))

Maybe someone can educate me on why the following wouldn't be the best and most understandable solution?

<pre class="highlight">
public function filter($value)
{
    return (boolean) $value;
}

Of course, for custom needs this filter could be extended.

Posted by Jordan Ryan Moore (jordanryanmoore) on 2008-01-29T10:22:04.000+0000

Sure, the simple version would work fine for most scenarios, but this filter takes "yes/no" and "true/false" string values and returns the corresponding boolean. I've found it handy quite a few times. I've used the filter for user-input, GET/POST variable parsing, and returning data from a database.

Posted by Darby Felton (darby) on 2008-01-29T10:29:55.000+0000

Aha, I see now. Thanks, Jordan, for clarifying this for me. :)

Posted by Wil Sinclair (wil) on 2008-04-18T13:12:00.000+0000

This doesn't appear to have been fixed in 1.5.0. Please update if this is not correct.

Posted by Wil Sinclair (wil) on 2008-04-18T17:11:46.000+0000

Please evaluate and categorize/assign as necessary.

Posted by Thomas Weidner (thomas) on 2009-04-16T23:59:14.000+0000

Proposal has been added to Wiki. Waiting for Recommendation and Response from Zend since 15.April.2009

Posted by Thomas Weidner (thomas) on 2009-09-30T11:59:07.000+0000

Closing as "needs proposal". The related proposal has been accepted for incubator.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2017 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts