Development

Changeset 8376

You must first sign up to be able to contribute.

Changeset 8376

Show
Ignore:
Timestamp:
04/09/08 22:44:11 (3 months ago)
Author:
dwhittle
Message:

trunk: merged doc changes to trunk

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • doc/trunk/book/01-Introducing-Symfony.txt

    r6117 r8376  
    100100### PHP 5 
    101101 
    102 Symfony is developed in PHP 5 ([http://www.php.net/](http://www.php.net/)) and dedicated to building web applications with the same language. Therefore, a solid understanding of PHP 5 is required to get the most out of the framework. 
     102Symfony is developed in PHP 5 ([http://www.php.net/](http://www.php.net/)) and dedicated to building web applications with the same language. Therefore, a solid understanding of PHP 5 is required to get the most out of the framework. The minimal version of PHP required to run symfony is PHP 5.1. 
    103103 
    104104Developers who already know PHP 4 but not PHP 5 should mainly focus on the language's new object-oriented model. 
     
    184184And that's it. Imagine how long it would have required to write a SQL query doing the same thing! 
    185185 
    186 Propel, another open source project, is currently one of the best object/relational abstraction layers for PHP 5. Symfony integrates Propel seamlessly into the framework, so most of the data manipulation described in this book follows the Propel syntax. This book will describe how to use the Propel objects, but for a more complete reference, a visit to the Propel website ([http://propel.phpdb.org/trac/](http://propel.phpdb.org/trac/)) is recommended. 
     186Propel, another open source project, is currently one of the best object/relational abstraction layers for PHP 5. Symfony integrates Propel seamlessly as its default ORM, so most of the data manipulation described in this book follows the Propel syntax. This book will describe how to use the Propel objects, but for a more complete reference, a visit to the Propel website ([http://propel.phpdb.org/trac/](http://propel.phpdb.org/trac/)) is recommended. 
    187187 
    188188### Rapid Application Development (RAD) 
  • doc/trunk/book/02-Exploring-Symfony-s-Code.txt

    r4537 r8376  
    543543              templates/ 
    544544                indexSuccess.php 
    545               validate/ 
    546545 
    547546Table 2-3 describes the module subdirectories. 
     
    555554`lib/`       | Stores classes and libraries specific to the module. 
    556555`templates/` | Contains the templates corresponding to the actions of the module. A default template, called `indexSuccess.php`, is created during module setup. 
    557 `validate/`  | Dedicated to configuration files used for form validation (discussed in Chapter 10). 
    558556 
    559557>**NOTE** 
    560 >The `config/`, `lib/`, and `validate/` directories are empty for a new module. 
     558>The `config/`, and `lib/` directories are empty for a new module. 
    561559 
    562560#### Web Tree Structure 
     
    591589### Parameter Holders 
    592590 
    593 Many of the symfony classes contain a parameter holder. It is a convenient way to encapsulate attributes with clean getter and setter methods. For instance, the sfResponse class holds a parameter holder that you can retrieve by calling the `getParameterHolder()` method. Each parameter holder stores data the same way, as illustrated in Listing 2-15. 
    594  
    595 Listing 2-15 - Using the `sfResponse` Parameter Holder 
    596  
    597     [php] 
    598     $response->getParameterHolder()->set('foo', 'bar'); 
    599     echo $response->getParameterHolder()->get('foo'); 
     591Many of the symfony classes contain a parameter holder. It is a convenient way to encapsulate attributes with clean getter and setter methods. For instance, the sfRequest class holds a parameter holder that you can retrieve by calling the `getParameterHolder()` method. Each parameter holder stores data the same way, as illustrated in Listing 2-15. 
     592 
     593Listing 2-15 - Using the `sfRequest` Parameter Holder 
     594 
     595    [php] 
     596    $request->getParameterHolder()->set('foo', 'bar'); 
     597    echo $request->getParameterHolder()->get('foo'); 
    600598     => 'bar' 
    601599 
    602 Most of the classes using a parameter holder provide proxy methods to shorten the code needed for get/set operations. This is the case for the `sfResponse` object, so you can do the same as in Listing 2-15 with the code of Listing 2-16. 
    603  
    604 Listing 2-16 - Using the `sfResponse` Parameter Holder Proxy Methods 
    605  
    606     [php] 
    607     $response->setParameter('foo', 'bar'); 
    608     echo $response->getParameter('foo'); 
     600Most of the classes using a parameter holder provide proxy methods to shorten the code needed for get/set operations. This is the case for the `sfRequest` object, so you can do the same as in Listing 2-15 with the code of Listing 2-16. 
     601 
     602Listing 2-16 - Using the `sfRequest` Parameter Holder Proxy Methods 
     603 
     604    [php] 
     605    $request->setParameter('foo', 'bar'); 
     606    echo $request->getParameter('foo'); 
    609607     => 'bar' 
    610608 
     
    615613    [php] 
    616614    // The 'foobar' parameter is not defined, so the getter returns an empty value 
    617     echo $response->getParameter('foobar'); 
     615    echo $request->getParameter('foobar'); 
    618616     => null 
    619617 
    620618    // A default value can be used by putting the getter in a condition 
    621     if ($response->hasParameter('foobar')) 
    622     { 
    623       echo $response->getParameter('foobar'); 
     619    if ($request->hasParameter('foobar')) 
     620    { 
     621      echo $request->getParameter('foobar'); 
    624622    } 
    625623    else 
     
    630628 
    631629    // But it is much faster to use the second getter argument for that 
    632     echo $response->getParameter('foobar', 'default'); 
     630    echo $request->getParameter('foobar', 'default'); 
    633631     => default 
    634632 
    635 The parameter holders even support namespaces. If you specify a third argument to a setter or a getter, it is used as a namespace, and the parameter will be defined only within that namespace. Listing 2-18 shows an example. 
    636  
    637 Listing 2-18 - Using the `sfResponse` Parameter Holder Namespace 
    638  
    639     [php] 
    640     $response->setParameter('foo', 'bar1'); 
    641     $response->setParameter('foo', 'bar2', 'my/name/space'); 
    642     echo $response->getParameter('foo'); 
     633Some symfony core classes also use a parameter holder that support namespaces (thanks to the `sfNamespacedParameterHolder` class). If you specify a third argument to a setter or a getter, it is used as a namespace, and the parameter will be defined only within that namespace. Listing 2-18 shows an example. 
     634 
     635Listing 2-18 - Using the `sfUser` Parameter Holder Namespace 
     636 
     637    [php] 
     638    $user->setAttribute('foo', 'bar1'); 
     639    $user->setAttribute('foo', 'bar2', 'my/name/space'); 
     640    echo $user->getAttribute('foo'); 
    643641     => 'bar1' 
    644     echo $response->getParameter('foo', null, 'my/name/space'); 
     642    echo $user->getAttribute('foo', null, 'my/name/space'); 
    645643     => 'bar2' 
    646644 
     
    652650    class MyClass 
    653651    { 
    654       protected $parameter_holder = null; 
    655  
    656       public function initialize ($parameters = array()) 
     652      protected $parameterHolder = null; 
     653 
     654      public function initialize($parameters = array()) 
    657655      { 
    658         $this->parameter_holder = new sfParameterHolder(); 
    659         $this->parameter_holder->add($parameters); 
     656        $this->parameterHolder = new sfParameterHolder(); 
     657        $this->parameterHolder->add($parameters); 
    660658      } 
    661659 
    662660      public function getParameterHolder() 
    663661      { 
    664         return $this->parameter_holder; 
     662        return $this->parameterHolder; 
    665663      } 
    666664    } 
     
    676674    define('SF_FOO', 'bar'); 
    677675    echo SF_FOO; 
    678     // Symfony uses the sfConfig object 
     676 
     677    // symfony uses the sfConfig object 
    679678    sfConfig::set('sf_foo', 'bar'); 
    680679    echo sfConfig::get('sf_foo'); 
     
    700699 
    701700>**NOTE** 
    702 >For better performance, the symfony autoloading scans a list of directories (defined in an internal configuration file) during the first request. It then registers all the classes these directories contain and stores the class/file correspondence in a PHP file as an associative array. That way, future requests don't need to do the directory scan anymore. This is why you need to clear the cache every time you add or move a class file in your project by calling the `symfony clear-cache` command (except in the development environment). You will learn more about the cache in Chapter 12, and about the autoloading configuration in Chapter 19. 
     701>For better performance, the symfony autoloading scans a list of directories (defined in an internal configuration file) during the first request. It then registers all the classes these directories contain and stores the class/file correspondence in a PHP file as an associative array. That way, future requests don't need to do the directory scan anymore. This is why you need to clear the cache every time you add or move a class file in your project by calling the `symfony cache:clear` command (except in the development environment). You will learn more about the cache in Chapter 12, and about the autoloading configuration in Chapter 19. 
    703702 
    704703Summary 
  • doc/trunk/book/03-Running-Symfony.txt

    r6117 r8376  
    44As you've learned in previous chapters, the symfony framework is a set of files written in PHP. A symfony project uses these files, so installing symfony means getting these files and making them available for the project. 
    55 
    6 Being a PHP 5 framework, symfony requires PHP 5. Make sure you have it installed by opening a command line and typing this command: 
     6Symfony requires at least PHP 5.1. Make sure you have it installed by opening a command line and typing this command: 
    77 
    88    > php -v 
    99 
    10     PHP 5.2.0 (cli) (built: Nov 2 2006 11:57:36) 
    11     Copyright (c) 1997-2006 The PHP Group 
    12     Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies 
    13  
    14 If the version number is 5.0 or higher, then you're ready for the installation, as described in this chapter. 
     10    PHP 5.2.5 (cli) (built: Nov 20 2007 16:55:40)  
     11    Copyright (c) 1997-2007 The PHP Group 
     12    Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies 
     13 
     14If the version number is 5.1 or higher, then you're ready for the installation, as described in this chapter. 
    1515 
    1616Installing the Sandbox 
     
    1919If you just want to see what symfony is capable of, you'll probably go for the fast installation. In that case, you need the sandbox. 
    2020 
    21 The sandbox is a simple archive of files. It contains an empty symfony project including all the required libraries (symfony, pake, lime, Creole, Propel, and Phing), a default application, and basic configuration. It will work out of the box, without specific server configuration or any additional packages. 
    22  
    23 To install it, download the sandbox archive from [http://www.symfony-project.org/get/sf_sandbox.tgz](http://www.symfony-project.org/get/sf_sandbox.tgz). Unpack it under the root web directory configured for your server (usually `web/` or `www/`). For the purposes of uniformity, this chapter will assume you unpacked it to the directory `sf_sandbox/`. 
     21The sandbox is a simple archive of files. It contains an empty symfony project including all the required libraries (symfony, lime, Creole, Propel, and Phing), a default application, and basic configuration. It will work out of the box, without specific server configuration or any additional packages. 
     22 
     23To install it, download the sandbox archive from [http://www.symfony-project.org/get/sf_sandbox_1_1.tgz](http://www.symfony-project.org/get/sf_sandbox_1_1.tgz). Unpack it under the root web directory configured for your server (usually `web/` or `www/`). For the purposes of uniformity, this chapter will assume you unpacked it to the directory `sf_sandbox/`. 
    2424 
    2525>**CAUTION** 
    2626>Having all the files under the root web directory is fine for your own tests in a local host, but is a bad practice in a production server. It makes all the internals of your application visible to end users. 
    2727 
    28 Test your installation by executing the symfony CLI. Go to the new `sf_sandbox/` directory and type the following on a *nix system: 
    29  
    30     > ./symfony -V 
    31  
    32 On Windows, issue this command: 
    33  
    34     > symfony -V 
     28Test your installation by executing the symfony CLI. Go to the new `sf_sandbox/` directory and type the following: 
     29 
     30    > php symfony -V 
    3531 
    3632You should see the sandbox version number: 
    3733 
    38     symfony version 1.0.0 
     34    symfony version 1.1.0 (/path/to/the/symfony/lib/dir/used/by/the/sandbox) 
    3935 
    4036Now make sure that your web server can browse the sandbox by requesting this URL: 
     
    5248To uninstall a sandbox, just remove the `sf_sandbox/` directory from your `web/` folder. 
    5349 
    54 Installing the Symfony Libraries 
     50Installing the symfony Libraries 
    5551-------------------------------- 
    5652 
     
    6662Symfony integrates a few other packages: 
    6763 
    68   * pake is a CLI utility. 
    6964  * lime is a unit testing utility. 
    7065  * Creole is a database abstraction engine. Just like PHP Data Objects (PDO), it provides an interface between your code and the database SQL code, and makes it possible to switch to another engine. 
    7166  * Propel is for ORM. It provides object persistence and query service. 
    72   * Phing is a CLI for Propel. 
    73  
    74 Pake and lime are developed by the symfony team. Creole, Propel, and Phing come from another team and are released under the GNU Lesser Public General License (LGPL). All these packages are bundled with symfony. 
    75  
    76 ### Installing the Symfony PEAR Package 
     67  * Phing is a build system used by Propel to generate the model classes. 
     68 
     69Lime are developed by the symfony team. Creole, Propel, and Phing come from another team and are released under the GNU Lesser Public General License (LGPL). All these packages are bundled with symfony. 
     70 
     71>**TIP** 
     72>The symfony framework is licensed under a MIT license. 
     73>All the copyrights for the bundled third party libraries can be found in the `COPYRIGHT` file and the associated licenses are stored in the `licenses/` directory. 
     74 
     75### Installing the symfony PEAR Package 
    7776 
    7877The symfony PEAR package contains the symfony libraries and all its dependencies. It also contains a script that will extend your CLI to include the `symfony` command. 
     
    9089    > pear install symfony/symfony 
    9190 
    92     downloading symfony-1.0.0.tgz ... 
    93     Starting to download symfony-1.0.0.tgz (1,283,270 bytes) 
     91    downloading symfony-1.1.0.tgz ... 
     92    Starting to download symfony-1.1.0.tgz (1,283,270 bytes) 
    9493    ................................................................. 
    9594    ................................................................. 
    9695    .............done: 1,283,270 bytes 
    97     install ok: channel://pear.symfony-project.com/symfony-1.0.0 
     96    install ok: channel://pear.symfony-project.com/symfony-1.1.0 
    9897 
    9998That's it. The symfony files and CLI are installed. Check that the installation succeeded by calling the new `symfony` command line, asking for the version number: 
     
    101100    > symfony -V 
    102101 
    103     symfony version 1.0.0 
    104  
    105 >**TIP** 
    106 >If you prefer to install the most recent beta, which has the latest bug fixes and enhancements, type `pear install symfony/symfony-beta` instead. Beta releases are not completely stable and are generally not recommended for production environments. 
     102    symfony version 1.1.0 (/path/to/the/pear/symfony/lib/dir) 
    107103 
    108104The symfony libraries are now installed in directories as follows: 
    109105 
    110106  * `$php_dir/symfony/` contains the main libraries. 
    111   * `$data_dir/symfony/` contains the skeleton of symfony applications; default modules; and configuration, i18n data, and so on
     107  * `$data_dir/symfony/` contains the web assets used by symfony default modules; and command line scripts
    112108  * `$doc_dir/symfony/` contains the documentation. 
    113109  * `$test_dir/symfony/` contains unit tests. 
     
    117113    > pear config-show 
    118114 
    119 ### Checking Out Symfony from the SVN Repository 
     115### Checking Out symfony from the SVN Repository 
    120116 
    121117For production servers, or when PEAR is not an option, you can download the latest version of the symfony libraries directly from the symfony Subversion repository by requesting a checkout: 
     
    123119    > mkdir /path/to/symfony 
    124120    > cd /path/to/symfony 
    125     > svn checkout http://svn.symfony-project.com/tags/RELEASE_1_0_0/ . 
     121    > svn checkout http://svn.symfony-project.com/tags/RELEASE_1_1_0/ . 
    126122 
    127123The `symfony` command, available only for PEAR installations, is a call to the `/path/to/symfony/data/bin/symfony` script. So the following would be the equivalent to the `symfony -V` command for an SVN installation: 
     
    129125    > php /path/to/symfony/data/bin/symfony -V 
    130126 
    131     symfony version 1.0.0 
    132  
    133 If you chose an SVN installation, you probably already have an existing symfony project. For this project to make use of the symfony files, you need to change the two variables defined in your project's `config/config.php` file, as follows: 
     127    symfony version 1.1.0 (/path/to/the/svn/symfony/lib/dir) 
     128 
     129If you chose an SVN installation, you probably already have an existing symfony project. For this project to make use of the symfony files, you need to change the a path defined in your project's `lib/ProjectConfiguration.class.php` file, as follows: 
    134130 
    135131    [php] 
    136132    <?php 
    137133 
    138     $sf_symfony_lib_dir  = '/path/to/symfony/lib/'; 
    139     $sf_symfony_data_dir = '/path/to/symfony/data/'; 
     134    require_once '/path/to/symfony/lib/autoload/sfCoreAutoload.class.php'; 
     135    sfCoreAutoload::register(); 
     136 
     137    class ProjectConfiguration extends sfProjectConfiguration 
     138    { 
    140139 
    141140Chapter 19 proposes other ways to link a project with a symfony installation (including symbolic links and relative paths). 
    142141 
    143142>**TIP** 
    144 >Alternatively, you can also download the PEAR package ([http://pear.symfony-project.com/get/symfony-1.0.0.tgz](http://pear.symfony-project.com/get/symfony-1.0.0.tgz)) and unpack it somewhere. You will have the same result as with a checkout. 
     143>Alternatively, you can also download the PEAR package ([http://pear.symfony-project.com/get/symfony-1.1.0.tgz](http://pear.symfony-project.com/get/symfony-1.1.0.tgz)) and unpack it somewhere. You will have the same result as with a checkout. 
    145144 
    146145Setting Up an Application 
     
    157156    > mkdir ~/myproject 
    158157    > cd ~/myproject 
    159     > symfony init-project myproject 
     158    > symfony generate:project myproject 
    160159 
    161160For an SVN installation, create a project with these commands: 
     
    163162    > mkdir ~/myproject 
    164163    > cd ~/myproject 
    165     > php /path/to/symfony/data/bin/symfony init-project myproject 
    166  
    167 The `symfony` command must always be called from the project's root directory (`myproject/` in the preceding examples), because all the tasks performed by this command are project-specific. 
     164    > php /path/to/symfony/data/bin/symfony generate:project myproject 
    168165 
    169166Symfony will create a directory structure that looks like this: 
     
    182179 
    183180>**TIP** 
    184 >The `init-project` task adds a `symfony` script in the project root directory. This PHP script does the same as the `symfony` command installed by PEAR, so you can call `php symfony` instead of `symfony` if you don't have native command-line support (for SVN installations). 
     181>The `generate:project` task adds a `symfony` script in the project root directory. This PHP script does the same as the `symfony` command installed by PEAR, so you can call `php symfony` instead of `symfony` if you don't have native command-line support (for SVN installations). 
    185182 
    186183### Creating the Application 
    187184 
    188 The project is not yet ready to be viewed, because it requires at least one application. To initialize it, use the `symfony init-app` command and pass the name of the application as an argument: 
    189  
    190     > symfony init-app myapp 
    191  
    192 This will create a `myapp/` directory in the `apps/` folder of the project root, with a default application configuration and a set of directories ready to host the file of your website: 
     185The project is not yet ready to be viewed, because it requires at least one application. To initialize it, use the `symfony generate:app` command and pass the name of the application as an argument: 
     186 
     187    > php symfony generate:app frontend 
     188 
     189This will create a `frontend/` directory in the `apps/` folder of the project root, with a default application configuration and a set of directories ready to host the file of your website: 
    193190 
    194191    apps/ 
    195       myapp
     192      frontend
    196193        config/ 
    197194        i18n/ 
     
    204201    web/ 
    205202      index.php 
    206       myapp_dev.php 
    207  
    208 `index.php` is the production front controller of the new application. Because you created the first application of the project, symfony created a file called `index.php` instead of `myapp.php` (if you now add a new application called `mynewapp`, the new production front controller will be named `mynewapp.php`). To run your application in the development environment, call the front controller `myapp_dev.php`. You'll learn more about these environments in Chapter 5. 
     203      frontend_dev.php 
     204 
     205`index.php` is the production front controller of the new application. Because you created the first application of the project, symfony created a file called `index.php` instead of `frontend.php` (if you now add a new application called `backend`, the new production front controller will be named `backend.php`). To run your application in the development environment, call the front controller `frontend_dev.php`. You'll learn more about these environments in Chapter 5. 
     206 
     207The `symfony` command must always be called from the project's root directory (`myproject/` in the preceding examples), because all the tasks performed by this command are project-specific. 
    209208 
    210209Configuring the Web Server 
     
    236235In the configuration in Listing 3-1, the `$sf_symfony_data_dir` placeholder must be replaced by the actual path. For example, for a PEAR installation in *nix, you should type something like this: 
    237236 
    238         Alias /sf /usr/local/lib/php/data/symfony/web/sf 
     237    Alias /sf /usr/local/lib/php/data/symfony/web/sf 
    239238 
    240239>**NOTE** 
     
    243242Restart Apache, and that's it. Your newly created application can now be called and viewed through a standard web browser at the following URL: 
    244243 
    245     http://localhost/myapp_dev.php/ 
     244    http://localhost/frontend_dev.php/ 
    246245 
    247246You should see a congratulations page similar to the one shown earlier in Figure 3-1. 
     
    259258> 
    260259> 
    261 >For Internet Information Services (IIS), you will need `isapi/rewrite` installed and running. Check the symfony online documentation for a detailed IIS installation guide. 
     260>For Internet Information Services (IIS), you will need `isapi/rewrite` installed and running. Check the symfony online cookbook for a detailed IIS installation guide. 
    262261 
    263262### Configuring a Shared-Host Server 
     
    270269Let's imagine that your shared host requires that the web folder is named `www/` instead of `web/`, and that it doesn't give you access to the `httpd.conf` file, but only to an `.htaccess` file in the web folder. 
    271270 
    272 In a symfony project, every path to a directory is configurable. Chapter 19 will tell you more about it, but in the meantime, you can still rename the `web` directory to `www` and have the application take it into account by changing the configuration, as shown in Listing 3-2. These lines are to be added to the end of the application `config.php` file. 
    273  
    274 Listing 3-2 - Changing the Default Directory Structure Settings, in `apps/myapp/config/config.php` 
     271In a symfony project, every path to a directory is configurable. Chapter 19 will tell you more about it, but in the meantime, you can still rename the `web` directory to `www` and have the application take it into account by changing the configuration, as shown in Listing 3-2. These lines are to be added to the end of the `lib/ProjectConfiguration.class.php` file. 
     272 
     273Listing 3-2 - Changing the Default Directory Structure Settings, in `lib/ProjectConfiguration.class.php` 
    275274 
    276275    [php] 
    277     $sf_root_dir = sfConfig::get('sf_root_dir'); 
    278     sfConfig::add(array( 
    279       'sf_web_dir_name' => $sf_web_dir_name = 'www', 
    280       'sf_web_dir'      => $sf_root_dir.DIRECTORY_SEPARATOR.$sf_web_dir_name, 
    281       'sf_upload_dir'   => $sf_root_dir.DIRECTORY_SEPARATOR.$sf_web_dir_name.DIRECTORY_SEPARATOR.sfConfig::get('sf_upload_dir_name'), 
    282     )); 
     276    class ProjectConfiguration extends sfProjectConfiguration 
     277    { 
     278       public function setup() 
     279       { 
     280         $this->setWebDir($this->getRootDir().'/www'); 
     281       } 
     282    } 
    283283 
    284284The project web root contains an .htaccess file by default. It is shown in Listing 3-3. Modify it as necessary to match your shared host requirements. 
     
    291291      RewriteEngine On 
    292292 
     293      # uncomment the following line, if you are having trouble 
     294      # getting no_script_name to work 
     295      #RewriteBase / 
     296 
    293297      # we skip all files with .something 
    294       RewriteCond %{REQUEST_URI} \..+$ 
    295       RewriteCond %{REQUEST_URI} !\.html$ 
    296       RewriteRule .* - [L] 
     298      #RewriteCond %{REQUEST_URI} \..+$ 
     299      #RewriteCond %{REQUEST_URI} !\.html$ 
     300      #RewriteRule .* - [L] 
    297301 
    298302      # we check if the .html version is here (caching) 
     
    305309    </IfModule> 
    306310 
    307     # big crash from our front web controller 
    308     ErrorDocument 500 "<h2>Application error</h2>symfony applicationfailed to start properly" 
    309  
    310311You should now be ready to browse your application. Check the congratulation page by requesting this URL: 
    311312 
    312     http://www.example.com/myapp_dev.php/ 
     313    http://www.example.com/frontend_dev.php/ 
    313314 
    314315>**SIDEBAR** 
  • doc/trunk/book/04-The-Basics-of-Page-Creation.txt

    r4908 r8376  
    1111As Chapter 2 explained, symfony groups pages into modules. Before creating a page, you need to create a module, which is initially an empty shell with a file structure that symfony can recognize. 
    1212 
    13 The symfony command line automates the creation of modules. You just need to call the `init-module` task with the application name and the module name as arguments. In the previous chapter, you created a `myapp` application. To add a `mymodule` module to this application, type the following commands: 
     13The symfony command line automates the creation of modules. You just need to call the `generate:module` task with the application name and the module name as arguments. In the previous chapter, you created a `frontend` application. To add a `content` module to this application, type the following commands: 
    1414 
    1515    > cd ~/myproject 
    16     > symfony init-module myapp mymodule 
    17  
    18     >> dir+      ~/myproject/apps/myapp/modules/mymodule 
    19     >> dir+      ~/myproject/apps/myapp/modules/mymodule/actions 
    20     >> file+     ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php 
    21     >> dir+      ~/myproject/apps/myapp/modules/mymodule/config 
    22     >> dir+      ~/myproject/apps/myapp/modules/mymodule/lib 
    23     >> dir+      ~/myproject/apps/myapp/modules/mymodule/templates 
    24     >> file+     ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php 
    25     >> dir+      ~/myproject/apps/myapp/modules/mymodule/validate 
    26     >> file+     ~/myproject/test/functional/myapp/mymoduleActionsTest.php 
    27     >> tokens    ~/myproject/test/functional/myapp/mymoduleActionsTest.php 
    28     >> tokens    ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php 
    29     >> tokens    ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php 
    30  
    31 Apart from the `actions/`, `config/`, `lib/`, `templates/`, and `validate/` directories, this command created only three files. The one in the test/ folder concerns unit tests, and you don't need to bother with it until Chapter 15. The `actions.class.php` (shown in Listing 4-1) forwards to the default module congratulation page. The `templates/indexSuccess.php` file is empty. 
     16    > php symfony generate:module frontend content 
     17 
     18    >> dir+      ~/myproject/apps/frontend/modules/content/actions 
     19    >> file+     ~/myproject/apps/frontend/modules/content/actions/actions.class.php 
     20    >> dir+      ~/myproject/apps/frontend/modules/content/templates 
     21    >> file+     ~/myproject/apps/frontend/modules/content/templates/indexSuccess.php 
     22    >> file+     ~/myproject/test/functional/frontend/contentActionsTest.php 
     23    >> tokens    ~/myproject/test/functional/frontend/contentActionsTest.php 
     24    >> tokens    ~/myproject/apps/frontend/modules/content/actions/actions.class.php 
     25    >> tokens    ~/myproject/apps/frontend/modules/content/templates/indexSuccess.php 
     26 
     27Apart from the `actions/`, and `templates/` directories, this command created only three files. The one in the test/ folder concerns functional tests, and you don't need to bother with it until Chapter 15. The `actions.class.php` (shown in Listing 4-1) forwards to the default module congratulation page. The `templates/indexSuccess.php` file is empty. 
    3228 
    3329Listing 4-1 - The Default Generated Action, in `actions/actions.class.php` 
     
    3632    <?php 
    3733 
    38     class mymoduleActions extends sfActions 
     34    class contentActions extends sfActions 
    3935    { 
    4036      public function executeIndex() 
     
    4945For each new module, symfony creates a default `index` action. It is composed of an action method called `executeIndex` and a template file called `indexSuccess.php`. The meanings of the `execute` prefix and `Success` suffix will be explained in Chapters 6 and 7, respectively. In the meantime, you can consider that this naming is a convention. You can see the corresponding page (reproduced in Figure 4-1) by browsing to the following URL: 
    5046 
    51     http://localhost/myapp_dev.php/mymodule/index 
     47    http://localhost/frontend_dev.php/content/index 
    5248 
    5349The default `index` action will not be used in this chapter, so you can remove the `executeIndex()` method from the `actions.class.php` file, and delete the `indexSuccess.php` file from the `templates/` directory. 
     
    6763### Adding an Action 
    6864 
    69 The "Hello, world!" page will be accessible through a `myAction` action. To create it, just add an `executeMyAction` method to the `mymoduleActions` class, as shown in Listing 4-2. 
     65The "Hello, world!" page will be accessible through a `show` action. To create it, just add an `executeShow` method to the `contentActions` class, as shown in Listing 4-2. 
    7066 
    7167Listing 4-2 - Adding an Action Is Like Adding an Execute Method to the Action Class 
     
    7470    <?php 
    7571 
    76     class mymoduleActions extends sfActions 
    77     { 
    78       public function executeMyAction() 
    79       { 
    80       } 
    81     } 
    82  
    83 The name of the action method is always `execute``Xxx``()`, where the second part of the name is the action name with the first letter capitalized. 
     72    class contentActions extends sfActions 
     73    { 
     74      public function executeShow() 
     75      { 
     76      } 
     77    } 
     78 
     79The name of the action method is always `executeXxx()`, where the second part of the name is the action name with the first letter capitalized. 
    8480 
    8581Now, if you request the following URL: 
    8682 
    87     http://localhost/myapp_dev.php/mymodule/myAction 
    88  
    89 symfony will complain that the `myActionSuccess.php` template is missing. That's normal; in symfony, a page is always made of an action and a template. 
     83    http://localhost/frontend_dev.php/content/show 
     84 
     85symfony will complain that the `showSuccess.php` template is missing. That's normal; in symfony, a page is always made of an action and a template. 
    9086 
    9187>**CAUTION** 
    92 >URLs (not domain names) are case-sensitive, and so is symfony (even though the method names are case-insensitive in PHP). This means that if you add an `executemyaction()` method, or an `executeMyaction()`, and then you call `myAction` with the browser, symfony will return a 404 error. 
     88>URLs (not domain names) are case-sensitive, and so is symfony (even though the method names are case-insensitive in PHP). This means that if you add an `executeshow()` method, or an `executeShow()`, and then you call `show` with the browser, symfony will return a 404 error. 
    9389 
    9490- 
     
    9995>Symfony contains a routing system that allows you to have a complete separation between the actual action name and the form of the URL needed to call it. This allows for custom formatting of the URL as if it were part of the response. You are no longer limited by the file structure nor by the request parameters; the URL for an action can look like the phrase you want. For instance, the call to the index action of a module called article usually looks like this: 
    10096> 
    101 >     http://localhost/myapp_dev.php/article/index?id=123 
     97>     http://localhost/frontend_dev.php/article/index?id=123 
    10298> 
    10399>This URL retrieves a given article from a database. In this example, it retrieves an article (with `id=123`) in the Europe section that specifically discusses finance in France. But the URL can be written in a completely different way with a simple change in the `routing.yml` configuration file: 
     
    111107>Symfony knows how to parse and generate smart URLs for the user. The routing system automatically peels the request parameters from a smart URL and makes them available to the action. It also formats the hyperlinks included in the response so that they look "smart." You will learn more about this feature in Chapter 9. 
    112108> 
    113 >Overall, this means that the way you name the actions of your applications should not be influenced by the way the URL used to call them should look, but by the actions' functions in the application. An action name explains what the action actually does, and it's often a verb in the infinitive form (like `show`, `list`, `edit`, and so on). Action names can be made totally invisible to the end user, so don't hesitate to use explicit action names (like `listByName` or `showWithComments`). You will economize on code comments to explain your action function, plus the code will be much easier to read. 
     109>Overall, this means that the way you name the actions of your applications should not be influenced by the way the URL used to call them should look, but by the actions' functions in the application. An action name explains what the action actually does, and it is often a verb in the infinitive form (like `show`, `list`, `edit`, and so on). Action names can be made totally invisible to the end user, so don't hesitate to use explicit action names (like `listByName` or `showWithComments`). You will economize on code comments to explain your action function, plus the code will be much easier to read. 
    114110 
    115111### Adding a Template 
    116112 
    117 The action expects a template to render itself. A template is a file located in the `templates/` directory of a module, named by the action and the action termination. The default action termination is a "success," so the template file to be created for the `myAction` action is to be called `myActionSuccess.php`. 
     113The action expects a template to render itself. A template is a file located in the `templates/` directory of a module, named by the action and the action termination. The default action termination is a "success," so the template file to be created for the `show` action is to be called `showSuccess.php`. 
    118114 
    119115Templates are supposed to contain only presentational code, so keep as little PHP code in them as possible. As a matter of fact, a page displaying "Hello, world!" can have a template as simple as the one in Listing 4-3. 
    120116 
    121 Listing 4-3 - The `mymodule/templates/myActionSuccess.php` Template 
     117Listing 4-3 - The `content/templates/showSuccess.php` Template 
    122118 
    123119    [php] 
     
    159155    <?php 
    160156 
    161     class mymoduleActions extends sfActions 
    162     { 
    163       public function executeMyAction() 
     157    class contentActions extends sfActions 
     158    { 
     159      public function executeShow() 
    164160      { 
    165161        $today = getdate(); 
     
    173169    <p>Hello, world!</p> 
    174170    <?php if ($hour >= 18): ?> 
    175     <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> 
    176     <?php endif; ?> 
    177  
    178 >**NOTE** 
    179 >The template already has access to a few pieces of data without the need of any variable setup in the action. Every template can call methods of the `$sf_context`, `$sf_request`, `$sf_params`, and `$sf_user` objects. They contain data related to the current context, request, request parameters, and session. You will soon learn how to use them efficiently. 
    180  
    181 Gathering Information from the User with Forms 
    182 ---------------------------------------------- 
    183  
    184 Forms are a good way to get information from the user. Writing form and form elements in HTML can sometimes be cumbersome, especially when you want to be XHTML-compliant. You could include form elements in symfony templates the usual way, as shown in Listing 4-8, but symfony provides helpers that make this task easier. 
    185  
    186 Listing 4-8 - Templates Can Include Usual HTML Code 
     171    <p>Or should I say good evening? It is already <?php echo $hour ?>.</p> 
     172    <?php endif; ?> 
     173 
     174Note that the use of the short opening tags (`<?=`, equivalent to `<?php echo`) is not recommended for professional web applications, since your production web server may be able to understand more than one scripting language and consequently get confused. Besides, the short opening tags do not work with the default PHP configuration and need server tweaking to be activated. Ultimately, when you have to deal with XML and validation, it falls short because `<?` has a special meaning in XML. 
     175 
     176>**NOTE** 
     177>The template already has access to a few pieces of data without the need of any variable setup in the action. Every template can call methods of the `$sf_request`, `$sf_params`, `$sf_response`, and `$sf_user` objects. They contain data related to the current request, request parameters, response, and session. You will soon learn how to use them efficiently. 
     178 
     179Linking to Another Action 
     180------------------------- 
     181 
     182You already know that there is a total decoupling between an action name and the URL used to call it. So if you create a link to `update` in a template as in Listing 4-10, it will only work with the default routing. If you later decide to change the way the URLs look, then you will need to review all templates to change the hyperlinks. 
     183 
     184Listing 4-10 - Hyperlinks, the Classic Way 
     185 
     186    [php] 
     187    <a href="/frontend_dev.php/content/update?name=anonymous"> 
     188      I never say my name 
     189    </a> 
     190 
     191To avoid this hassle, you should always use the `link_to()` helper to create hyperlinks to your application's actions. And if you only want the generate the URL part, the `url_for()` is the helper you're looking for. 
     192 
     193A helper is a PHP function defined by symfony that is meant to be used within templates. It outputs some HTML code and is faster to use than writing the actual HTML code by yourself. Listing 4-11 demonstrates the use of the hyperlink helpers. 
     194 
     195Listing 4-11 - The `link_to()`, and `url_for()` Helpers 
    187196 
    188197    [php] 
    189198    <p>Hello, world!</p> 
    190199    <?php if ($hour >= 18): ?> 
    191     <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> 
    192     <?php endif; ?>   
    193     <form method="post" target="/myapp_dev.php/mymodule/anotherAction"> 
     200    <p>Or should I say good evening? It is already <?php echo $hour ?>.</p> 
     201    <?php endif; ?> 
     202    <form method="post" action="<?php echo url_for('content/update') ?>"> 
    194203      <label for="name">What is your name?</label> 
    195204      <input type="text" name="name" id="name" value="" /> 
    196205      <input type="submit" value="Ok" /> 
     206      <?php echo link_to('I never say my name','content/update?name=anonymous') ?> 
    197207    </form> 
    198208 
    199 A helper is a PHP function defined by symfony that is meant to be used within templates. It outputs some HTML code and is faster to use than writing the actual HTML code by yourself. Using symfony helpers, you can have the same result as in Listing 4-8 with the code shown in Listing 4-9. 
    200  
    201 Listing 4-9 - It Is Faster and Easier to Use Helpers Than to Use HTML Tags 
    202  
    203     [php] 
    204     <p>Hello, world!</p> 
    205     <?php if ($hour >= 18): ?> 
    206     <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> 
    207     <?php endif; ?> 
    208     <?php echo form_tag('mymodule/anotherAction') ?> 
    209       <?php echo label_for('name', 'What is your name?') ?> 
    210       <?php echo input_tag('name') ?> 
    211       <?php echo submit_tag('Ok') ?> 
    212     </form> 
    213  
    214 >**SIDEBAR** 
    215 >Helpers are here to help you 
    216 > 
    217 >If, in the example in Listing 4-9, you think the helper version is not really faster to write than the HTML one, consider this one: 
    218 > 
    219 >     [php] 
    220 >     <?php 
    221 >     $card_list = array( 
    222 >       'VISA' => 'Visa', 
    223 >       'MAST' => 'MasterCard', 
    224 >       'AMEX' => 'American Express', 
    225 >       'DISC' => 'Discover'); 
    226 >     echo select_tag('cc_type', options_for_select($card_list, 'AMEX')); 
    227 >     ?> 
    228 > 
    229 >This outputs the following HTML: 
    230 > 
    231 >     [php] 
    232 >     <select name="cc_type" id="cc_type"> 
    233 >       <option value="VISA">Visa</option> 
    234 >       <option value="MAST">MasterCard</option> 
    235 >       <option value="AMEX" selected="selected">American Express</option> 
    236 >       <option value="DISC">Discover</option> 
    237 >     </select> 
    238 > 
    239 >The benefit of helpers in templates is raw speed of coding, clarity of code, and concision. The only price to pay is the time to learn them, which will end when you finish this book, and the time to write <?php echo ?>, for which you should already have a shortcut in your favorite text editor. So you could not use the symfony helpers in templates and write HTML the way you always did, but this would be a great loss and much less fun. 
    240  
    241 Note that the use of the short opening tags (`<?=`, equivalent to `<?php echo`) is not recommended for professional web applications, since your production web server may be able to understand more than one scripting language and consequently get confused. Besides, the short opening tags do not work with the default PHP configuration and need server tweaking to be activated. Ultimately, when you have to deal with XML and validation, it falls short because `<?` has a special meaning in XML. 
    242  
    243 Form manipulation deserves a whole chapter of its own, since symfony provides many tools, mostly helpers, to make it easier. You will learn more about these helpers in Chapter 10. 
    244  
    245 Linking to Another Action 
    246 ------------------------- 
    247  
    248 You already know that there is a total decoupling between an action name and the URL used to call it. So if you create a link to `anotherAction` in a template as in Listing 4-10, it will only work with the default routing. If you later decide to change the way the URLs look, then you will need to review all templates to change the hyperlinks. 
    249  
    250 Listing 4-10 - Hyperlinks, the Classic Way 
    251  
    252     [php] 
    253     <a href="/myapp_dev.php/mymodule/anotherAction?name=anonymous"> 
    254       I never say my name 
    255     </a> 
    256  
    257 To avoid this hassle, you should always use the `link_to()` helper to create hyperlinks to your application's actions. Listing 4-11 demonstrates the use of the hyperlink helper. 
    258  
    259 Listing 4-11 - The `link_to()` Helper 
    260  
    261     [php] 
    262     <p>Hello, world!</p> 
    263     <?php if ($hour >= 18): ?> 
    264     <p>Or should I say good evening? It's already <?php echo $hour ?>.</p> 
    265     <?php endif; ?> 
    266     <?php echo form_tag('mymodule/anotherAction') ?> 
    267       <?php echo label_for('name', 'What is your name?') ?> 
    268       <?php echo input_tag('name') ?> 
    269       <?php echo submit_tag('Ok') ?> 
    270       <?php echo link_to('I never say my name','mymodule/anotherAction?name=anonymous') ?> 
    271     </form> 
    272  
    273209The resulting HTML will be the same as previously, except that when you change your routing rules, all the templates will behave correctly and reformat the URLs accordingly. 
    274210 
     211Form manipulation deserves a whole chapter of its own, since symfony provides many tools to make it even easier. You will learn more about these helpers in Chapter 10. 
     212 
    275213The `link_to()` helper, like many other helpers, accepts another argument for special options and additional tag attributes. Listing 4-12 shows an example of an option argument and the resulting HTML. The option argument is either an associative array or a simple string showing `key=value` couples separated by blanks. 
    276214 
     
    279217    [php] 
    280218    // Option argument as an associative array 
    281     <?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous', 
     219    <?php echo link_to('I never say my name', 'content/update?name=anonymous', 
    282220      array( 
    283221        'class'    => 'special_link', 
     
    287225 
    288226    // Option argument as a string 
    289     <?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous', 
     227    <?php echo link_to('I never say my name', 'content/update?name=anonymous', 
    290228      'class=special_link confirm=Are you sure? absolute=true') ?> 
    291229 
    292230    // Both calls output the same 
    293231     => <a class="special_link" onclick="return confirm('Are you sure?');" 
    294         href="http://localhost/myapp_dev.php/mymodule/anotherAction/name/anonymous"> 
     232        href="http://localhost/frontend_dev.php/content/update/name/anonymous"> 
    295233        I never say my name</a> 
    296234 
     
    300238>Because it requires an additional parsing and transformation, the string syntax is a little slower than the array syntax. 
    301239 
    302 Like the form helpers, the link helpers are numerous and have many options. Chapter 9 will describe them in detail. 
     240Like all symfony helpers, the link helpers are numerous and have many options. Chapter 9 will describe them in detail. 
    303241 
    304242Getting Information from the Request 
    305243------------------------------------ 
    306244 
    307 Whether the user sends information via a form (usually in a POST request) or via the URL (GET request), you can retrieve the related data from the action with the `getRequestParameter()` method of the `sfActions` object. Listing 4-13 shows how, in `anotherAction`, you retrieve the value of the `name` parameter. 
     245Whether the user sends information via a form (usually in a POST request) or via the URL (GET request), you can retrieve the related data from the action with the `getParameter()` method of the `sfRequest` object. Listing 4-13 shows how, in `update`, you retrieve the value of the `name` parameter. 
    308246 
    309247Listing 4-13 - Getting Data from the Request Parameter in the Action 
     
    312250    <?php 
    313251 
    314     class mymoduleActions extends sfActions 
    315     { 
    316       ... 
    317  
    318       public function executeAnotherAction() 
    319       { 
    320         $this->name = $this->getRequestParameter('name'); 
    321       } 
    322     } 
    323  
    324 If the data manipulation is simple, you don't even need to use the action to retrieve the request parameters. The template has access to an object called `$sf_params`, which offers a `get`() method to retrieve the request parameters, just like the getRequestParameter() in the action. 
    325  
    326 If `executeAnotherAction()` were empty, Listing 4-14 shows how the `anotherActionSuccess.php` template would retrieve the same `name` parameter. 
     252    class contentActions extends sfActions 
     253    { 
     254      // ... 
     255 
     256      public function executeUpdate($request) 
     257      { 
     258        $this->name = $request->getParameter('name'); 
     259      } 
     260    } 
     261 
     262As a convenience, all `executeXxx()` methods take the current `sfRequest` object as its first argument. 
     263 
     264If the data manipulation is simple, you don't even need to use the action to retrieve the request parameters. The template has access to an object called `$sf_params`, which offers a `get`() method to retrieve the request parameters, just like the `getParameter()` in the action. 
     265 
     266If `executeUpdate()` were empty, Listing 4-14 shows how the `updateSuccess.php` template would retrieve the same `name` parameter. 
    327267 
    328268Listing 4-14 - Getting Data from the Request Parameter Directly in the Template 
     
    355295In symfony, pages are composed of an action (a method in the `actions/actions.class.php` file prefixed with `execute`) and a template (a file in the `templates/` directory, usually ending with `Success.php`). They are grouped in modules, according to their function in the application. Writing templates is facilitated by helpers, which are functions provided by symfony that return HTML code. And you need to think of the URL as a part of the response, which can be formatted as needed, so you should refrain from using any direct reference to the URL in action naming or request parameter retrieval. 
    356296 
    357 Once you know these basic principles, you can already write a whole web application with symfony. But it would take you way too long, since almost every task you will have to achieve during the course of the application development is facilitated one way or another by some symfony feature . . . which is why the book doesn't stop now. 
     297Once you know these basic principles, you can already write a whole web application with symfony. But it would take you way too long, since almost every task you will have to achieve during the course of the application development is facilitated one way or another by some symfony feature... which is why the book doesn't stop now. 
  • doc/trunk/book/05-Configuring-Symfony.txt

    </
    r4908 r8376  
    155155>And if you don't like YAML 
    156156> 
    157 >YAML is just an interface to define settings to be used by PHP code, so the configuration defined in YAML files ends up being transformed into PHP. After browsing an application, check its cached configuration (in `cache/myapp/dev/config/`, for instance). You will see the PHP files corresponding to your YAML configuration. You will learn more about the configuration cache later in this chapter. 
     157>YAML is just an interface to define settings to be used by PHP code, so the configuration defined in YAML files ends up being transformed into PHP. After browsing an application, check its cached configuration (in `cache/frontend/dev/config/`, for instance). You will see the PHP files corresponding to your YAML configuration. You will learn more about the configuration cache later in this chapter. 
    158158> 
    159159>The good news is that if you don't want to use YAML files, you can still do what the configuration files do by hand, in PHP or via another format (XML, INI, and so on). Throughout this book, you will meet alternative ways to define configuration without YAML, and you will even learn to replace the symfony configuration handlers (in Chapter 19). If you use them wisely, these tricks will enable you to bypass configuration files or define your own configuration format. 
     
    225225    <?php 
    226226 
    227     define('SF_ROOT_DIR',    realpath(dirname(__FILE__).'/..')); 
    228     define('SF_APP',         'myapp'); 
    229     define('SF_ENVIRONMENT', 'prod'); 
    230     define('SF_DEBUG',       false); 
    231