Zend Framework

Zend_Filter_Boolean

Details

  • Type: New Feature New Feature
  • Status: Resolved Resolved
  • Priority: Minor Minor
  • Resolution: Needs Proposal
  • Affects Version/s: 1.0.3
  • Fix Version/s: 1.10.0
  • Component/s: Zend_Filter
  • Labels:
    None
  • Fix Version Priority:
    Nice to Have

Description

A new filter that converts values to booleans.

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;
    }
}

Activity

Hide
Simone Carletti added a comment -

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?

Show
Simone Carletti added a comment - 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?
Hide
Jordan Ryan Moore added a comment -

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.

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;
    }
}
Show
Jordan Ryan Moore added a comment - 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.
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;
    }
}
Hide
Jordan Ryan Moore added a comment -

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.

Show
Jordan Ryan Moore added a comment - 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.
Hide
Darby Felton added a comment -

(reposting comment with formatting )

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

public function filter($value)
{
    return (boolean) $value;
}

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

Show
Darby Felton added a comment - (reposting comment with formatting ) Maybe someone can educate me on why the following wouldn't be the best and most understandable solution?
public function filter($value)
{
    return (boolean) $value;
}
Of course, for custom needs this filter could be extended.
Hide
Jordan Ryan Moore added a comment -

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.

Show
Jordan Ryan Moore added a comment - 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.
Hide
Darby Felton added a comment -

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

Show
Darby Felton added a comment - Aha, I see now. Thanks, Jordan, for clarifying this for me.
Hide
Wil Sinclair added a comment -

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

Show
Wil Sinclair added a comment - This doesn't appear to have been fixed in 1.5.0. Please update if this is not correct.
Hide
Wil Sinclair added a comment -

Please evaluate and categorize/assign as necessary.

Show
Wil Sinclair added a comment - Please evaluate and categorize/assign as necessary.
Hide
Thomas Weidner added a comment -

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

Show
Thomas Weidner added a comment - Proposal has been added to Wiki. Waiting for Recommendation and Response from Zend since 15.April.2009
Hide
Thomas Weidner added a comment -

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

Show
Thomas Weidner added a comment - Closing as "needs proposal". The related proposal has been accepted for incubator.

People

Vote (2)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: