miércoles, 24 de agosto de 2011

Call to a member function remove() on a non-object


Si estas usando el cache system de Symfony, debes tener un problema similar a  Call to a member function remove() on a non-object, eso siginifica que getViewCacheManager retorna null.

Seguro has estado mas de 2 dias googleando y llegaste aqui !

El problema es que cuando estas trabajando en el entorno .dev el cache no esta activo, por eso no funciona sfContext::getViewCacheManager()

Solo debes activarlo en settings.yml

   dev:
     .settings:
       error_reporting:                                                         
       web_debug:              true
       cache:                  true
Eso es todo!

Fuente: http://www.pbtg.com/blogs/jim/2009/07/15/symfony-cache-gotcha

Variables en Symfony

[sf_symfony_lib_dir] 
    [sf_root_dir] 
    [sf_apps_dir] 
    [sf_lib_dir] 
    [sf_log_dir] 
    [sf_data_dir] 
    [sf_config_dir]
    [sf_test_dir]
    [sf_plugins_dir]
    [sf_web_dir]
    [sf_upload_dir]
    [sf_cache_dir]
    [sf_app_base_cache_dir]
    [sf_app_cache_dir]
    [sf_template_cache_dir]
    [sf_i18n_cache_dir]
    [sf_config_cache_dir]
    [sf_test_cache_dir]
    [sf_module_cache_dir]
    [sf_app]
    [sf_environment]
    [sf_debug]
    [sf_app_dir]
    [sf_app_config_dir]
    [sf_app_lib_dir]
    [sf_app_module_dir]
    [sf_app_template_dir]
    [sf_app_i18n_dir]
    [sf_error_404_module]
    [sf_error_404_action]
    [sf_login_module]
    [sf_login_action]
    [sf_secure_module]
    [sf_secure_action]
    [sf_module_disabled_module]
    [sf_module_disabled_action]
    [sf_use_database]
    [sf_i18n]
    [sf_compressed]
    [sf_check_lock]
    [sf_csrf_secret]
    [sf_escaping_strategy]
    [sf_escaping_method]
    [sf_no_script_name]
    [sf_cache] 
    [sf_etag]
    [sf_web_debug]
    [sf_error_reporting]
    [sf_file_link_format]
    [sf_admin_web_dir]
    [sf_web_debug_web_dir]
    [sf_standard_helpers]
    [sf_enabled_modules]
    [sf_charset]
    [sf_logging_enabled]
    [sf_default_culture]
 
print_r(sfConfig::getAll());

Valores por defecto en formularios symfony

Para poner un valor por defecto al cargar un formulario, nada tan sencillo como poner en el actions:
$this->form->setDefault(’nombrecampo’, ‘valorcampo’);

Fuente: http://www.informaticosinmemoria.com/2009/10/valores-por-defecto-en-formularios-symfony/

Para ver el error en un al grabar un formulario


if ($form->isValid()){
     $form->save();
}else {
     echo $form->getErrorSchema()->getMessage();
}

¿ Que módulo o acción se está ejecutando?


Para saber el modulo que se está ejecutando:
$this->getModuleName()

Y para saber la acción:
$this->getActionName()


Fuente: http://www.informaticosinmemoria.com/2009/11/%c2%bf-que-modulo-o-accion-se-esta-ejecutando/

Mejorando el selector de culturas de Symfony

Extraído de Practical Symfony – Día 19: Internacionalización y Localización:
Pero la mayor parte del tiempo, tu sitio web no estará disponible en los 136 principales idiomas. El método getPreferredCulture() devuelve el mejor lenguaje mediante la comparación de los idiomas preferidos del usuario y los idiomas de tu sitio web:
// in an action
$language = $request->getPreferredCulture(array('en', 'fr'));
Sí, pero si quieres hilar fino en tus aplicaciones pronto descubrirás que se queda corto con el método getPreferredCulture():
/**
   * Returns the preferred culture for the current request.
   *
   * @  array  $cultures  An array of ordered cultures available
   *
   * @ string The preferred culture
   */
  public function getPreferredCulture(array $cultures = null)
  {
    $preferredCultures = $this->getLanguages();
 
    if (null === $cultures)
    {
      return isset($preferredCultures[0]) ? $preferredCultures[0] : null;
    }
 
    if (!$preferredCultures)
    {
      return $cultures[0];
    }
 
    $preferredCultures = array_values(array_intersect($preferredCultures, $cultures));
 
    return isset($preferredCultures[0]) ? $preferredCultures[0] : $cultures[0];
  }
O lo que viene a ser lo mismo: Devuélveme el primero que exista, el primero de los definidos en el navegador o nada en absoluto.
Aunque resulte raro, en la mayoría de los casos este nivel de complejidad es el suficiente ya que Symfony arreglará cualquier imprecisión que pueda darse si este mecanismo falla. No hay que olvidar que en el fichero settings.yml debemos definir una cultura por defecto para nuestra aplicación.
Pero, ¿qué pasa si un usuario configura su navegador para español de México e inglés (en ese orden de prioridad) y mi aplicación admite español (genérico) e inglés? El algoritmo anterior nos devolverá como preferido el inglés erróneamente. Según la configuración del navegador, se debería presentar un texto en español (aunque no sea en su variedad mexicana) y si esto no fuera posible, una traducción en inglés.
Es decir, los códigos de 5 carácteres de culturas como es_MX especifican una variedad del español pero no excluyen la cultura es a secas.
Por lo tanto, propongo el siguiente método para realizar una selección más precisa y configurable:
/**
   * Makes the best choice of culture. It can check the domain of preferred
   * languages in order to choose a more generic language if it's available.
   *
   * Example:
   * 
   * preferred cultures: es_ES, en
   * available cultures: es, en, fr
   * 
   * In this example this method will return 'es' over 'en' as the best choice
   * if $checkCultureDomains flag is enabled.
   *
   * If no preferred culture is available this method will return the
   * $defaultCulture.
   * 
   * @ array $availableCultures Array of valid available cultures
   * @ array $preferredCultures Array of preferred cultures. Order DOES matter (lower index => higher priority)
   * @ string $defaultCulture A default culture if none of the preferred cultures is available
   * @ bool $checkCultureDomains Flag to enable/disable language domain check
   * @ string best choice culture
   */
  public static function bestChoiceCulture($availableCultures, $preferredCultures, $defaultCulture, $checkCultureDomains = true) {
    foreach ($preferredCultures as $culture) {
      if (in_array($culture, $availableCultures)) {
        return $culture;
      }
      if ($checkCultureDomains) {
        $domain = substr($culture, 0, 2);
        if ($domain != $culture && in_array($domain, $availableCultures)) {
          return $domain;
        }
      }
    }
    return $defaultCulture;
  }
El único aspecto sobre el que dudo en este método es sobre la corrección de pasarle un valor por defecto a la función para ser devuelto si el algoritmo no encuentra una cultura apropiada. Qué se yo, prefiero dejarlo así por darle coherencia y atomicidad al método cuando lo use por ahí. Si molesta, se puede quitar y reemplazarlo por un return null o incluso una excepción. Al gusto del consumidor.
Happy coding!