********************************
* *
* symfony requirements check *
* *
********************************
php.ini used by PHP: /etc/php5/cli/php.ini
** WARNING **
* The PHP CLI can use a different php.ini file
* than the one used with your web server.
* If this is the case, please launch this
* utility from your web server.
** WARNING **
** Mandatory requirements **
OK PHP version is at least 5.2.4
** Optional checks **
OK PDO is installed
[[WARNING]] PDO has some drivers installed: : FAILED
*** Install PDO drivers (mandatory for Propel and Doctrine) ***
OK PHP-XML module is installed
[[WARNING]] XSL module is installed: FAILED
*** Install the XSL module (recommended for Propel) ***
OK The token_get_all() function is available
OK The mb_strlen() function is available
OK The iconv() function is available
OK The utf8_decode() is available
[[WARNING]] A PHP accelerator is installed: FAILED
*** Install a PHP accelerator like APC (highly recommended) ***
[[WARNING]] php.ini has short_open_tag set to off: FAILED
*** Set it to off in php.ini ***
[[WARNING]] php.ini has magic_quotes_gpc set to off: FAILED
*** Set it to off in php.ini ***
OK php.ini has register_globals set to off
OK php.ini has session.auto_start set to off
OK PHP version is not 5.2.9
Por partes:
**PDO**
Si hago un:
php -m
Obtengo:
...
pcre
PDO
posix
...
Por lo que entiendo que SI está habilitado
**XLS**
aptitude install php5-xsl
**Acelerador**
aptitude install php-apc
**short_open_tag**
Editar el fichero de configuración de php:
nano /etc/php5/apache2/php.ini
Y dejar la linea tal que así:
short_open_tag = Off
**magic_quotes_gpc**
Editar el fichero de configuración de php:
nano /etc/php5/apache2/php.ini
Y dejar la linea tal que así:
magic_quotes_gpc = Off
Tras los cambios en php.ini:
apache2ctl restart
Como yo me decanto por la instalación individual de symfony, lo copiamos a su ubicación:
cp -Rv /ruta/fuente/symfony /tmp/proyectos_symfony/proyecto_1/symfony_1_2_8
===== Crear proyecto =====
Como me he decantado por la instalación individual de symfony, tenemos la siguiente estructura:
| /tmp/proyectos_symfony/proyecto_1 | Directorio donde residirá el proyecto 1 |
| /tmp/proyectos_symfony/proyecto_1/symfony_1_2_8 | Directorio donde residirá symfony solo para el proyecto 1 |
De esa forma, tanto 'proyecto_1' como 'proyecto_2' comparten la version 1.2 de symfony:
mkdir /tmp/proyectos_symfony/proyecto_1 /tmp/proyectos_symfony/proyecto_2
cp -Rv /ruta/fuente/symfony/* /tmp/symfony/symfony_1_2_8/
Y por último creamos 'proyecto_1':
cd /tmp/proyectos_symfony/proyecto_1
php symfony_1_2_8/data/bin/symfony generate:project proyecto_1
Ha creado la siguiente estructura dentro de '/tmp/proyectos_symfony/proyecto_1':
drwxr-xr-x 2 root root 4096 sep 11 01:47 apps
drwxrwxrwx 2 root root 4096 sep 11 01:47 cache
drwxr-xr-x 2 root root 4096 sep 11 01:47 config
drwxr-xr-x 3 root root 4096 sep 11 01:47 data
drwxr-xr-x 2 root root 4096 sep 11 01:47 doc
drwxr-xr-x 2 root root 4096 sep 11 01:47 lib
drwxrwxrwx 2 root root 4096 sep 11 01:47 log
drwxr-xr-x 2 root root 4096 sep 11 01:47 plugins
-rwxrwxrwx 1 root root 446 sep 11 01:47 symfony
drwxr-xr-x 7 root root 4096 sep 11 01:45 symfony_1_2_8
drwxr-xr-x 5 root root 4096 sep 11 01:47 test
drwxr-xr-x 6 root root 4096 sep 11 01:47 web
Para conocer donde está el 'core' de symfony de ese proyecto, una vez en el directorio del proyecto:
php symfony -V
symfony version 1.2.8 (/tmp/proyectos_symfony/proyecto_1/symfony_1_2_8/lib)
===== Crear frontend =====
Nos aseguramos estar dentro de '/tmp/proyectos_symfony/proyecto_1':
cd /tmp/proyectos_symfony/proyecto_1
php symfony generate:app --escaping-strategy=on --csrf-secret=UniqueSecret frontend
Esto ha creado la siguiente estructura, dentro de '/tmp/proyectos_symfony/proyecto_1/apps/frontend/':
drwxr-xr-x 2 root root 4096 sep 14 10:37 config
drwxr-xr-x 2 root root 4096 sep 14 10:37 i18n
drwxr-xr-x 2 root root 4096 sep 14 10:37 lib
drwxr-xr-x 2 root root 4096 sep 14 10:37 modules
drwxr-xr-x 2 root root 4096 sep 14 10:37 templates
===== Crear módulo =====
Nos aseguramos estar dentro de '/tmp/proyectos_symfony/proyecto_1':
cd /tmp/proyectos_symfony/proyecto_1
php symfony generate:module frontend modulo_1
Esto ha creado la siguiente estructura, dentro de '/tmp/proyectos_symfony/proyecto_1/apps/frontend/modules/modulo_1':
drwxr-xr-x 2 javi javi 4096 oct 6 18:31 actions
drwxr-xr-x 2 javi javi 4096 oct 6 18:31 templates
^ Archivo ^ Url ^
| /tmp/proyectos_symfony/proyecto_1/apps/frontend/modules/modulo_1/actions | http://localhost/proyecto_1/web/frontend_dev.php/modulo_1/index
|
===== Permisos =====
cd /tmp/proyectos_symfony/proyecto_1
chmod 777 cache/ log/
Si se usa subversion conviene eludir estos directorios a la hora de exportar:
[[informatica:linux:subversion#ignorar_cambios_en_directorios|Igonrar determinados directorios]]
===== Ruta =====
Si en lugar de dejarse el núcleo de symfony en un directorio 'estático' se hubiese incluido dentro del proyecto, para mover el proyecto a cualquier otro directorio:
1. Editar el fichero:
nano /tmp/proyectos_symfony/proyecto_1/config/ProjectConfiguration.class.php
2. Dejar el fichero así (siguiendo el ejemplo):
require_once dirname(__FILE__).'/../symfony_1_2_8/lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
// for compatibility / remove and enable only the plugins you want
$this->enableAllPluginsExcept(array('sfDoctrinePlugin', 'sfCompat10Plugin'));
}
}
3. Crear un enlace simbólico:
cd /tmp/proyectos_symfony/proyecto_1/web
ln -s ../symfony_1_2_8/data/web/sf/ .
De esta forma hemos optado por la instalación individual de symfony: moviendo el directorio '/tmp/proyectos_symfony/proyecto_1' tenemos nuestro proyecto entero, al coste de que pesa, vacío, 25 Mb
===== Configurar la bd =====
En este ejemplo vamos a usar mysql. Desde dentro del proyecto:
^ ORM ^ SGBD ^ Comando ^
| Propel | MySQL | php symfony configure:database "mysql:host=localhost;dbname=blog" root mYsEcret
|
| Propel | Sqlite | php symfony configure:database "sqlite://%SF_DATA_DIR%/sqlite/bd_sqlite.bd"
|
| Doctrine | MySQL | php symfony configure:database --name=doctrine --class=sfDoctrineDatabase "mysql:host=localhost;dbname=jobeet" root mYsEcret
|
| Doctrine | Sqlite | php symfony configure:database --name=doctrine --class=sfDoctrineDatabase "sqlite:///%SF_DATA_DIR%/sqlite/bd_sqlite.bd"
|
===== Configurar el servidor de páginas web =====
Ejemplo de configuración para este ejemplo en el caso de que optemos por una instalación compartida de symfony, que no es el caso:
ServerName mi_pagina.mine.nu
DocumentRoot /tmp/proyectos_symfony/proyecto_1/web
AllowOverride All
Allow from All
Alias /sf /tmp/symfony/data/web/sf
AllowOverride All
Allow from All
Ahora la web (ojo, con estilos e imagen de fondo) debería verse desde:
http://mi_pagina.mine.nu
Teóricamente también deberíamos ver el frontend en desarrollo:
http://mi_pagina.mine.nu/frontend_dev.php
Pero a mí me sale el siguiente mensaje:
You are not allowed to access this file. Check frontend_dev.php for more information.
El motivo es que por defecto está configurado para que solo se pueda acceder a ese entorno desde la misma máquina (127.0.0.1) que aloja symfony. Para hacer accesible ese entorno a cualquiera:
1. Editar el fichero:
nano /tmp/proyectos_symfony/proyecto_1/web/frontend_dev.php
2. Y dejarlo tal que así:
dispatch();
===== Diagramas =====
**Flujo de trabajo de symfony**
{{informatica:linux:php:01.png|}}
**Organización de código**
{{informatica:linux:php:02.png|}}
**Directorios**
apps/
frontend/
backend/
cache/
config/
data/
sql/
doc/
lib/
model/
log/
plugins/
test/
bootstrap/
unit/
functional/
web/
css/
images/
js/
uploads/
**Directorio 'Applications'**
apps/
[application name]/
modules/
[module name]/
actions/
actions.class.php
config/
lib/
templates/
indexSuccess.php
**Capa vista**
{{informatica:linux:php:03.png|}}
===== Conceptos =====
| Parameter holder |
$request->getParameterHolder()->set('foo', 'bar');
echo $request->getParameterHolder()->get('foo');
// The 'foobar' parameter is not defined, so the getter returns an empty value
echo $request->getParameter('foobar');
=> null
// A default value can be used by putting the getter in a condition
if ($request->hasParameter('foobar'))
{
echo $request->getParameter('foobar');
}
else
{
echo 'default';
}
=> default
// But it is much faster to use the second getter argument for that
echo $request->getParameter('foobar', 'default');
=> default
// Uso de namespaces
$user->setAttribute('foo', 'bar1');
$user->setAttribute('foo', 'bar2', 'my/name/space');
echo $user->getAttribute('foo');
=> 'bar1'
echo $user->getAttribute('foo', null, 'my/name/space');
=> 'bar2'
// Añadir Parameter Holder a una clase
class MyClass
{
protected $parameterHolder = null;
public function initialize($parameters = array())
{
$this->parameterHolder = new sfParameterHolder();
$this->parameterHolder->add($parameters);
}
public function getParameterHolder()
{
return $this->parameterHolder;
}
}
|
| Constantes |
// Instead of PHP constants,
define('FOO', 'bar');
echo FOO;
// symfony uses the sfConfig object
sfConfig::set('foo', 'bar');
echo sfConfig::get('foo');
|
| Autocarga de clases |
$myObject = new MyClass();
|
| Helper |
Listing 4-11 - The link_to(), and url_for() Helpers
Hello, world!
= 18): ?>
Or should I say good evening? It is already .
|
| Partial | {{http://www.symfony-project.org/images/book/1_2/F0702.png}} |
| Componente | {{http://www.symfony-project.org/images/book/1_2/F0703.png}} |
| Slot | {{http://www.symfony-project.org/images/book/1_2/F0704.png}} |
| Component slot | http://www.symfony-project.org/book/1_2/07-Inside-the-View-Layer |
===== Comandos =====
**NOTA** supongo que antes de lanzar cada comando, es conveniente limpiar la caché (teóricamente en entornos 'dev'... la caché se genera cada vez)
* Limpiar la caché
php symfony cc
* Configurar la conexión a la base de datos con PROPEL**
# Ejemplo MySQL
php symfony configure:database "mysql:host=localhost;dbname=blog" root mYsEcret
# Ejemplo Sqlite
php symfony configure:database "sqlite://%SF_DATA_DIR%/sqlite/bd_sqlite.bd"
O editar el archivo:
/mi_proyecto/config/databases.yml
* Crear el modelo de objetos con PROPEL
php symfony propel:build-model
Luego hay que limpiar la caché:
php symfony cache:clear
* Crear el diagrama entidad-relación a partir del modelo .yml con PROPEL
php symfony propel:build-sql
Genera el siguiente archivo:
/mi_proyecto/data/sql/lib.model.sql
* Habilitar los activos (assets) asociados a un plugin que acaba de ser habilitado
php symfony plugin:publish-assets
* Crear la bd a partir del archivo '/mi_proyecto/data/sql/schema.sql' con PROPEL
php symfony propel:insert-sql --no-confirmation
**NOTA** Todo lo marcado con 'con PROPEL' se puede hacer con doctrine sustituyendo en el comando 'propel' por 'doctrine' y viceversa
* Cargar los datos a partir de '/mi_proyecto/data/fixtures/'fixtures con DOCTRINE
php symfony doctrine:data-load
**TODOS los comandos anteriores para PROPEL**
php symfony doctrine:build-all-reload --no-confirmation
php symfony cc
* Listar rutas de una aplicación
php symfony app:routes frontend
* Mostrar el detalle de una ruta
php symfony app:routes frontend job_edit
===== Errores =====
**Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 71 bytes) in /mnt/disco_1/datos/www/privado/inmobiliaria2/symfony_1_2_8/lib/plugins/sfPropelPlugin/lib/vendor/phing/util/StringHelper.php on line 136
**
Al intentar crear el modelo de datos:
php symfony propel:build-all
Aparece el siguiente error:
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 71 bytes) in /mnt/disco_1/datos/www/privado/inmobiliaria2/symfony_1_2_8/lib/plugins/sfPropelPlugin/lib/vendor/phing/util/StringHelper.php on line 136
**SOLUCION**
1) (Todo como root) Incrementar el máximo de memoria RAM que puede consumir un guión php (es decir, ejecutado desde su CLI):
nano /etc/php5/cli/php.ini
Y dejar el siguiente valor, por ejemplo, así:
memory_limit = 40M ; Maximum amount of memory a script may consume (32MB)
2) Grabar y salir
**SQLSTATE[HY000]: General error: 26 file is encrypted or is not a database**
El problema es que la bd sqlite se creó con sqlite 2.x. Para comprobar que es así:
cat /mi_proyecto/data/mi_bd_sqlite.db
La primera linea tiene que ser parecida a:
This file contains an SQLite 2.1 database...
**Solución**
1. (Como root) Instalar sqlite3:
aptitude update && aptitude install sqlite3
2. Volver a crear la bd con el comando:
sqlite3 /mi_proyecto/data/mi_bd_sqlite.db
3. (No sé si es necesario si la ubicación y nombre de la bd es exacta) Volver a crear el modelo... (desde la raíz del proyecto):
php symfony cache:clear
php symfony configure:database "sqlite://%SF_DATA_DIR%/mi_bd_sqlite.db"
php symfony propel:build-model
**Fatal error: Class 'sfProjectConfiguration' not found in /mnt/disco_1/datos/proyectos_symfony/jobeet/config/ProjectConfiguration.class.php on line 10**
En el archivo '/mi_proyecto/config/ProjectConfiguration.class.php':
* No se ha modificado la ruta para que incluya el archivo correctamente
* Se ha comentado por error la linea 'sfCoreAutoload::register();'
**Fatal error: Class 'sfPropelDatabase' not found in /mnt/disco_1/datos/proyectos_symfony/jobeet/cache/frontend/dev/config/config_databases.yml.php on line 6**
Se está intentando crear las sentencias sql con doctrine:
php symfony doctrine:build-sql
Pero en el archivo de configuración:
/mi_proyecto/apps/frontend/config/databases.yml
Todavía quedan residuos de propel que hay que eliminar:
dev:
propel:
param:
classname: DebugPDO
test:
propel:
param:
classname: DebugPDO
all:
propel:
class: sfPropelDatabase
param:
classname: PropelPDO
dsn: 'mysql:dbname=jobeet;host=localhost'
username: root
password: null
encoding: utf8
persistent: true
pooling: true
doctrine:
class: sfDoctrineDatabase
param:
dsn: 'sqlite:///%SF_DATA_DIR%/sqlite/bd_sqlite.bd'
username: root
password: null
Debería quedar tal que así:
all:
doctrine:
class: sfDoctrineDatabase
param:
dsn: 'sqlite:///%SF_DATA_DIR%/sqlite/bd_sqlite.bd'
username: root
password: null