TigerZF
🌐Español

35.6. Zend_Filter_Inflector

Zend_Filter_Inflector es una herramienta de propósito general para la inflexión de cadenas basada en reglas hacia un destino dado.

Por ejemplo, puede que necesite transformar palabras en MixedCase o camelCase en una ruta; por legibilidad, políticas del sistema operativo, u otras razones, también necesita ponerlo en minúsculas, y quiere separar las palabras usando un guion ('-'). Un inflector puede hacer esto por usted.

Zend_Filter_Inflector implementa Zend_Filter_Interface; usted realiza la inflexión llamando a filter() en la instancia del objeto.

Ejemplo 35.1. Transformar texto MixedCase y camelCase a otro formato

$inflector = new Zend_Filter_Inflector('pages/:page.:suffix');
$inflector->setRules(array(
    ':page'  => array('Word_CamelCaseToDash', 'StringToLower'),
    'suffix' => 'html'
));

$string   = 'camelCasedWords';
$filtered = $inflector->filter(array('page' => $string));
// pages/camel-cased-words.html

$string   = 'this_is_not_camel_cased';
$filtered = $inflector->filter(array('page' => $string));
// pages/this_is_not_camel_cased.html

35.6.1. Funcionamiento

Un inflector requiere un destino y una o más reglas. Un destino es básicamente una cadena que define marcadores de posición para las variables que desea sustituir. Estos se especifican con el prefijo ':': :script.

Al llamar a filter(), usted pasa un array de pares clave y valor correspondientes a las variables del destino.

Cada variable del destino puede tener cero o más reglas asociadas a ella. Las reglas pueden ser estáticas o hacer referencia a una clase Zend_Filter. Las reglas estáticas sustituirán por el texto proporcionado. En caso contrario, se usará una clase que coincida con la regla proporcionada para inflexionar el texto. Las clases se especifican típicamente usando un nombre corto que indica el nombre del filtro sin ningún prefijo común.

Por ejemplo, puede usar cualquier implementación concreta de Zend_Filter; sin embargo, en lugar de referirse a ellas como 'Zend_Filter_Alpha' o 'Zend_Filter_StringToLower', debe especificar únicamente 'Alpha' o 'StringToLower'.

35.6.2. Establecer rutas a filtros alternativos

Zend_Filter_Inflector usa Zend_Loader_PluginLoader para gestionar la carga de filtros a usar con la inflexión. Por defecto, cualquier filtro con el prefijo Zend_Filter estará disponible. Para acceder a filtros con ese prefijo pero que se encuentran más profundamente en la jerarquía, como los distintos filtros Word, simplemente elimine el prefijo Zend_Filter:

// use Zend_Filter_Word_CamelCaseToDash as a rule
$inflector->addRules(array('script' => 'Word_CamelCaseToDash'));

Para establecer rutas alternativas, Zend_Filter_Inflector tiene un método de utilidad que actúa como proxy hacia el cargador de plugins, addFilterPrefixPath():

$inflector->addFilterPrefixPath('My_Filter', 'My/Filter/');

Alternativamente, puede recuperar el cargador de plugins del inflector, e interactuar con él directamente:

$loader = $inflector->getPluginLoader();
$loader->addPrefixPath('My_Filter', 'My/Filter/');

Para más opciones sobre cómo modificar las rutas a los filtros, consulte la documentación de PluginLoader.

35.6.3. Establecer el destino del inflector

El destino del inflector es una cadena con algunos marcadores de posición para variables. Los marcadores de posición toman la forma de un identificador, un signo de dos puntos (':') por defecto, seguido de un nombre de variable: ':script', ':path', etc. El método filter() busca el identificador seguido del nombre de variable que se va a sustituir.

Puede cambiar el identificador usando el método setTargetReplacementIdentifier(), o pasándolo como tercer argumento al constructor:

// Via constructor:
$inflector = new Zend_Filter_Inflector('#foo/#bar.#sfx', null, '#');

// Via accessor:
$inflector->setTargetReplacementIdentifier('#');

Normalmente, establecerá el destino a través del constructor. Sin embargo, puede que desee volver a establecer el destino más adelante (por ejemplo, para modificar el inflector predeterminado en componentes principales, como ViewRenderer o Zend_Layout). setTarget() se puede usar para este propósito:

$inflector = $layout->getInflector();
$inflector->setTarget('layouts/:script.phtml');

Además, puede que desee tener un miembro de clase para su clase que pueda usar para mantener actualizado el destino del inflector -- sin necesidad de actualizar directamente el destino cada vez (ahorrando así llamadas a métodos). setTargetReference() le permite hacer esto:

class Foo
{
    /**
     * @var string Inflector target
     */
    protected $_target = 'foo/:bar/:baz.:suffix';

    /**
     * Constructor
     * @return void
     */
    public function __construct()
    {
        $this->_inflector = new Zend_Filter_Inflector();
        $this->_inflector->setTargetReference($this->_target);
    }

    /**
     * Set target; updates target in inflector
     *
     * @param  string $target
     * @return Foo
     */
    public function setTarget($target)
    {
        $this->_target = $target;
        return $this;
    }
}

35.6.4. Reglas de inflexión

Como se mencionó en la introducción, hay dos tipos de reglas: estáticas y basadas en filtros.

[Note] Nota

Es importante tener en cuenta que, independientemente del método con el que agregue reglas al inflector, ya sea una por una o todas a la vez, el orden es muy importante. Los nombres más específicos, o los nombres que puedan contener otros nombres de regla, deben agregarse antes que los nombres menos específicos. Por ejemplo, suponiendo los dos nombres de regla 'moduleDir' y 'module', la regla 'moduleDir' debe aparecer antes que 'module', ya que 'module' está contenido dentro de 'moduleDir'. Si 'module' se agregara antes que 'moduleDir', 'module' coincidiría con parte de 'moduleDir' y lo procesaría, dejando 'Dir' dentro del destino sin inflexionar.

35.6.4.1. Reglas estáticas

Las reglas estáticas realizan una simple sustitución de cadenas; úselas cuando tenga un segmento en el destino que normalmente será estático, pero que desea permitir que el desarrollador modifique. Use el método setStaticRule() para establecer o modificar la regla:

$inflector = new Zend_Filter_Inflector(':script.:suffix');
$inflector->setStaticRule('suffix', 'phtml');

// change it later:
$inflector->setStaticRule('suffix', 'php');

Al igual que con el propio destino, también puede vincular una regla estática a una referencia, lo que le permite actualizar una sola variable en lugar de requerir una llamada a método; esto suele ser útil cuando su clase usa un inflector internamente, y no quiere que sus usuarios necesiten obtener el inflector para actualizarlo. El método setStaticRuleReference() se usa para lograr esto:

class Foo
{
    /**
     * @var string Suffix
     */
    protected $_suffix = 'phtml';

    /**
     * Constructor
     * @return void
     */
    public function __construct()
    {
        $this->_inflector = new Zend_Filter_Inflector(':script.:suffix');
        $this->_inflector->setStaticRuleReference('suffix', $this->_suffix);
    }

    /**
     * Set suffix; updates suffix static rule in inflector
     *
     * @param  string $suffix
     * @return Foo
     */
    public function setSuffix($suffix)
    {
        $this->_suffix = $suffix;
        return $this;
    }
}

35.6.4.2. Reglas de inflector con filtro

Los filtros de Zend_Filter también pueden usarse como reglas de inflector. Al igual que las reglas estáticas, están vinculados a una variable de destino; a diferencia de las reglas estáticas, puede definir varios filtros para usar al inflexionar. Estos filtros se procesan en orden, así que tenga cuidado de registrarlos en un orden que tenga sentido para los datos que reciba.

Las reglas pueden agregarse usando setFilterRule() (que sobrescribe cualquier regla anterior para esa variable) o addFilterRule() (que añade la nueva regla a cualquier regla existente para esa variable). Los filtros se especifican de una de las siguientes formas:

  • Cadena. La cadena puede ser un nombre de clase de filtro, o un segmento de nombre de clase menos cualquier prefijo establecido en el cargador de plugins del inflector (por defecto, sin el prefijo 'Zend_Filter').

  • Objeto filtro. Cualquier instancia de objeto que implemente Zend_Filter_Interface puede pasarse como filtro.

  • Array. Un array de una o más cadenas u objetos filtro como se definió anteriormente.

$inflector = new Zend_Filter_Inflector(':script.:suffix');

// Set rule to use Zend_Filter_Word_CamelCaseToDash filter
$inflector->setFilterRule('script', 'Word_CamelCaseToDash');

// Add rule to lowercase string
$inflector->addFilterRule('script', new Zend_Filter_StringToLower());

// Set rules en-masse
$inflector->setFilterRule('script', array(
    'Word_CamelCaseToDash',
    new Zend_Filter_StringToLower()
));

35.6.4.3. Establecer muchas reglas a la vez

Generalmente, es más fácil establecer muchas reglas a la vez que configurar una única variable y sus reglas de inflexión de una en una. Los métodos addRules() y setRules() de Zend_Filter_Inflector permiten esto.

Cada método recibe un array de pares variable y regla, donde la regla puede ser de cualquier tipo aceptado (cadena, objeto filtro, o array). Los nombres de variable aceptan una notación especial para permitir establecer reglas estáticas y reglas de filtro, según la siguiente notación:

  • prefijo ':': reglas de filtro.

  • Sin prefijo: regla estática.

Ejemplo 35.2. Establecer múltiples reglas a la vez

// Could also use setRules() with this notation:
$inflector->addRules(array(
    // filter rules:
    ':controller' => array('CamelCaseToUnderscore','StringToLower'),
    ':action'     => array('CamelCaseToUnderscore','StringToLower'),

    // Static rule:
    'suffix'      => 'phtml'
));

35.6.5. Métodos de utilidad

Zend_Filter_Inflector tiene una serie de métodos de utilidad para obtener y establecer el cargador de plugins, manipular y recuperar reglas, y controlar si se lanzan excepciones y cuándo.

  • setPluginLoader() puede usarse cuando ha configurado su propio cargador de plugins y desea usarlo con Zend_Filter_Inflector; getPluginLoader() recupera el actualmente establecido.

  • setThrowTargetExceptionsOn() puede usarse para controlar si filter() lanza o no una excepción cuando un identificador de sustitución dado que se le pasa no se encuentra en el destino. Por defecto, no se lanzan excepciones. isThrowTargetExceptionsOn() le indicará cuál es el valor actual.

  • getRules($spec = null) puede usarse para recuperar todas las reglas registradas para todas las variables, o solo las reglas de una única variable.

  • getRule($spec, $index) obtiene una única regla para una variable dada; esto puede ser útil para obtener una regla de filtro específica para una variable que tiene una cadena de filtros. Debe pasarse $index.

  • clearRules() borrará todas las reglas registradas actualmente.

35.6.6. Uso de Zend_Config con Zend_Filter_Inflector

Puede usar Zend_Config para establecer reglas, rutas de prefijo de filtro, y otros estados del objeto en sus inflectores, ya sea pasando un objeto Zend_Config al constructor o a setOptions(). Se pueden especificar los siguientes ajustes:

  • target especifica el destino de la inflexión.

  • filterPrefixPath especifica uno o más pares de prefijo y ruta de filtro para usar con el inflector.

  • throwTargetExceptionsOn debe ser un booleano que indique si se deben lanzar o no excepciones cuando un identificador de sustitución sigue presente después de la inflexión.

  • targetReplacementIdentifier especifica el carácter a usar al identificar las variables de sustitución en la cadena de destino.

  • rules especifica un array de reglas de inflexión; debe consistir en claves que especifiquen valores o arrays de valores, consistentes con addRules().

Ejemplo 35.3. Uso de Zend_Config con Zend_Filter_Inflector

// With the constructor:
$config    = new Zend_Config($options);
$inflector = new Zend_Filter_Inflector($config);

// Or with setOptions():
$inflector = new Zend_Filter_Inflector();
$inflector->setOptions($config);