Archivos de Tags: date.timezone @es

SonataAdminBundle: Arreglar “The “ batch action is not defined” at app/vendor/sonata-project/admin-bundle/Controller/CRUDController.php in a shared hosting: magic_quotes_gpc

Estaba teniendo errores http 500 al borrar entidades en SonataAdminBundle usando el batch mode (es decir seleccionar varios elementos mediante los check box y luego aplicando la acción de borrado para todos ellos a la vez):

batch-delete

[2014-03-06 13:05:37] request.CRITICAL: Uncaught PHP Exception RuntimeException:
"The `` batch action is not defined" at /xxx/vendor/sonata-project/admin-bundle/Controller/CRUDController.php line 424
{"exception":
"[object] (RuntimeException: The `` batch action is not defined at /xxx/vendor/sonata-project/admin-bundle/Controller/CRUDController.php:424)"
} []

El problema era que mi hosting compartido tiene la opción de PHP magic_quotes_gpc con valor 1 (o true). Esta opción está obsoleta para PHP 5.3 e incluso la han borrado desde la versión 5.4 en adelante. Esta opción es PHP_INI_PERDIR así que no se puede cambiar su valor en ejecución, por lo tanto ini_set('magic_quotes_gpc', '0') en mi código PHP no funcionaría. Solo las opciones PHP_INI_ALL pueden ser modificadas en ejecución mediante ini_set('...', '...').

También intenté cambiar el valor mediante .htaccess añadiendo esta línea:

<IfModule mod_php5.c>
  php_flag magic_quotes_gpc off
</IfModule>

Pero esto provocaba un error http 500 y toda la aplicación fallaba.

Mi siguiente estrategia fue usar un php.ini adaptado a mi aplicación. Añadí un nuevo fichero php.ini en la carpeta web de mi aplicación Symfony2 con lo siguiente:

magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off

Pero esto hacía que mi app se quejara de que no estaba la timezone definida, ya que esto es obligatorio para Symfony2:

Warning: date_default_timezone_get() [function.date-default-timezone-get]:
It is not safe to rely on the system's timezone settings.
You are *required* to use the date.timezone setting or the date_default_timezone_set() function.
In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier.
We selected 'Europe/Berlin' for 'CET/1.0/no DST' instead in /xxx/app/cache/prod/classes.php on line 5148

La añadí pero entonces me decía que no encontraba la clase PDO:

Fatal error: Class 'PDO' not found in /xxx/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php on line 148

Al final este fue el php.ini que me funcionó:

date.timezone = "Europe/Berlin"
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
extension=pdo.so
extension=pdo_mysql.so

¡CUIDADO! Como este php.ini está alojado dentro de la carpeta web y por tanto es accesible desde el exterior tienes que añadir lo siguiente al fichero .htaccess de esa misma carpeta para que nadie pueda ver el fichero:

<files php.ini>
  order deny,allow
  deny from all
</files>

Añadir un fichero php.ini a tu aplicación hace que se sobreescriban/añadan las opciones definidas en él pero si lo que tu quieres que es solo se usen los valores de tu php.ini y sobreescribir por completo el que hay por defecto en el servidor debes añadir lo siguiente a tu .htaccess y de esta forma el php.ini de tu hosting compartido será ignorado:

SetEnv PHPRC /ruta/a/tu/php.ini

Recuerda que en este caso deberás configurar todas las opciones necesarias para que funcione PHP.

Ref: http://stackoverflow.com/questions/517008/how-to-turn-off-magic-quotes-on-shared-hosting
http://jesin.tk/using-custom-php-ini-files-on-shared-hosting/
http://www.php.net/manual/en/security.magicquotes.disabling.php
http://www.php.net/manual/en/configuration.changes.php