Development

Changeset 3372

You must first sign up to be able to contribute.

Changeset 3372

Show
Ignore:
Timestamp:
01/30/07 09:50:09 (2 years ago)
Author:
fabien
Message:

fixed symfony book markup

Files:

Legend:

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

    r3348 r3372  
    163163Using objects instead of records, and classes instead of tables, has another benefit: you can add new accessors to your tables. For instance, if you have a table called `Client` with two fields, `FirstName` and `LastName`, you might like to be able to require just a `Name`. In an object-oriented world, this is as easy as adding a new accessor method to the `Client` class, like this: 
    164164 
     165    [php] 
    165166    public function getName() 
    166167    { 
     
    170171All the repeated data-access functions and the business logic of the data can be maintained within such objects. For instance, consider a class ShoppingCart in which you keep items (which are objects). To retrieve the full amount of the shopping cart for the checkout, you can add a `getTotal()` method, like this: 
    171172 
     173    [php] 
    172174    public function getTotal() 
    173175    { 
  • doc/branches/1.0/book/02-Exploring-Symfony-s-Code.txt

    r3348 r3372  
    483483      uploads/ 
    484484 
    485 Table 2-1 - describes the contents of these directories. 
    486  
    487 Table 2-1.  Root Directories 
    488 Directory  Description 
    489  
    490 `apps/` 
    491  
    492 Contains one directory for each application of the project (typically, `frontend` and `backend` for the front and back office). 
    493  
    494 `batch/` 
    495  
    496 Contains PHP scripts called from a command line or a scheduler, to run batch processes. 
    497  
    498 `cache/` 
    499  
    500 Contains the cached version of the configuration, and (if you activate it) the cache version of the actions and templates of the project. The cache mechanism (detailed in Chapter 12) uses these files to speed up the answer to web requests. Each application will have a subdirectory here, containing preprocessed PHP and HTML files. 
    501  
    502 `config/` 
    503  
    504 Holds the general configuration of the project. 
    505  
    506 `data/` 
    507  
    508 Here, you can store the data files of the project, like a database schema, a SQL file that creates tables, or even a SQLite database file. 
    509  
    510 `doc/` 
    511  
    512 Stores the project documentation, including your own documents and the documentation generated by PHPdoc. 
    513  
    514 `lib/` 
    515  
    516 Dedicated to foreign classes or libraries. Here, you can add the code that needs to be shared among your applications. The `model/` subdirectory stores the object model of the project (described in Chapter 8). 
    517  
    518 `log/` 
    519  
    520 Stores the applicable log files generated directly by symfony. It can also contain web server log files, database log files, or log files from any part of the project. Symfony creates one log file per application and per environment (log files are discussed in Chapter 16). 
    521  
    522 `plugins/` 
    523  
    524 Stores the plug-ins installed in the application (plug-ins are discussed in Chapter 17). 
    525  
    526 `test/` 
    527  
    528 Contains unit and functional tests written in PHP and compatible with the symfony testing framework (discussed in Chapter 15). During the project setup, symfony automatically adds some stubs with a few basic tests. 
    529  
    530 `web/` 
    531  
    532 The root for the web server. The only files accessible from the Internet are the ones located in this directory. 
     485Table 2-1 describes the contents of these directories. 
     486 
     487Table 2-1 - Root Directories 
     488 
     489Directory  |  Description 
     490---------- | ------------ 
     491`apps/`    | Contains one directory for each application of the project (typically, `frontend` and `backend` for the front and back office). 
     492`batch/`   | Contains PHP scripts called from a command line or a scheduler, to run batch processes. 
     493`cache/`   | Contains the cached version of the configuration, and (if you activate it) the cache version of the actions and templates of the project. The cache mechanism (detailed in Chapter 12) uses these files to speed up the answer to web requests. Each application will have a subdirectory here, containing preprocessed PHP and HTML files. 
     494`config/`  | Holds the general configuration of the project. 
     495`data/`    | Here, you can store the data files of the project, like a database schema, a SQL file that creates tables, or even a SQLite database file. 
     496`doc/`     | Stores the project documentation, including your own documents and the documentation generated by PHPdoc. 
     497`lib/`     | Dedicated to foreign classes or libraries. Here, you can add the code that needs to be shared among your applications. The `model/` subdirectory stores the object model of the project (described in Chapter 8). 
     498`log/`     | Stores the applicable log files generated directly by symfony. It can also contain web server log files, database log files, or log files from any part of the project. Symfony creates one log file per application and per environment (log files are discussed in Chapter 16). 
     499`plugins/` | Stores the plug-ins installed in the application (plug-ins are discussed in Chapter 17). 
     500`test/`    | Contains unit and functional tests written in PHP and compatible with the symfony testing framework (discussed in Chapter 15). During the project setup, symfony automatically adds some stubs with a few basic tests. 
     501`web/`     | The root for the web server. The only files accessible from the Internet are the ones located in this directory. 
    533502 
    534503#### Application Tree Structure 
     
    547516          error.txtdelete 
    548517 
    549 Table 2-2 - describes the application subdirectories. 
    550  
    551 Table 2-2.  Application Subdirectories 
    552 Directory  Description 
    553  
    554 `config/` 
    555  
    556 Holds a hefty set of YAML configuration files. This is where most of the application configuration is, apart from the default parameters that can be found in the framework itself. Note that the default parameters can still be overridden here if needed. You'll learn more about application configuration in the Chapter 5. 
    557  
    558 `i18n/` 
    559  
    560 Contains files used for the internationalization of the application--mostly interface translation files (Chapter 13 deals with internationalization). You can bypass this directory if you choose to use a database for internationalization. 
    561  
    562 `lib/` 
    563  
    564 Contains classes and libraries that are specific to the application. 
    565  
    566 `modules/` 
    567  
    568 Stores all the modules that contain the features of the application. 
    569  
    570 `templates/` 
    571  
    572 Lists the global templates of the application--the ones that are shared by all modules. By default, it contains a `layout.php` file, which is the main layout in which the module templates are inserted. 
     518Table 2-2 describes the application subdirectories. 
     519 
     520Table 2-2 - Application Subdirectories 
     521 
     522Directory    | Description 
     523------------ | ----------- 
     524`config/`    | Holds a hefty set of YAML configuration files. This is where most of the application configuration is, apart from the default parameters that can be found in the framework itself. Note that the default parameters can still be overridden here if needed. You'll learn more about application configuration in the Chapter 5. 
     525`i18n/`      | Contains files used for the internationalization of the application--mostly interface translation files (Chapter 13 deals with internationalization). You can bypass this directory if you choose to use a database for internationalization. 
     526`lib/`       | Contains classes and libraries that are specific to the application. 
     527`modules/`   | Stores all the modules that contain the features of the application. 
     528`templates/` | Lists the global templates of the application--the ones that are shared by all modules. By default, it contains a `layout.php` file, which is the main layout in which the module templates are inserted. 
    573529 
    574530>**NOTE** 
     
    595551              validate/ 
    596552 
    597 Table 2-3 - describes the module subdirectories. 
    598  
    599 Table 2-3.  Module Subdirectories 
    600 Directory  Description 
    601  
    602 `actions/` 
    603  
    604 Generally contains a single class file named `actions.class.php`, in which you can store all the actions of the module. You can also write different actions of a module in separate files. 
    605  
    606 `config/` 
    607  
    608 Can contain custom configuration files with local parameters for the module. 
    609  
    610 `lib/` 
    611  
    612 Stores classes and libraries specific to the module. 
    613  
    614 `templates/` 
    615  
    616 Contains the templates corresponding to the actions of the module. A default template, called `indexSuccess.php`, is created during module setup. 
    617  
    618 `validate/` 
    619  
    620 Dedicated to configuration files used for form validation (discussed in Chapter 10). 
     553Table 2-3 describes the module subdirectories. 
     554 
     555Table 2-3 -  Module Subdirectories 
     556 
     557Directory    | Description 
     558------------ | ------------ 
     559`actions/`   | Generally contains a single class file named `actions.class.php`, in which you can store all the actions of the module. You can also write different actions of a module in separate files. 
     560`config/`    | Can contain custom configuration files with local parameters for the module. 
     561`lib/`       | Stores classes and libraries specific to the module. 
     562`templates/` | Contains the templates corresponding to the actions of the module. A default template, called `indexSuccess.php`, is created during module setup. 
     563`validate/`  | Dedicated to configuration files used for form validation (discussed in Chapter 10). 
    621564 
    622565>**NOTE** 
     
    635578Conventionally, the static files are distributed in the directories listed in Table 2-4. 
    636579 
    637 Table 2-4.  Typical Web Subdirectories 
    638 Directory  Description 
    639  
    640 `css/` 
    641  
    642 Contains style sheets with a `.css` extension. 
    643  
    644 `images/` 
    645  
    646 Contains images with a `.jpg`, `.png`, or `.gif` format. 
    647  
    648 `js/` 
    649  
    650 Holds JavaScript files with a `.js` extension. 
    651  
    652 `uploads/` 
    653  
    654 Must contain the files uploaded by the users. Even though the directory usually contains images, it is distinct from the images directory so that the synchronization of the development and production servers does not affect the uploaded images. 
     580Table 2-4 - Typical Web Subdirectories 
     581 
     582Directory  | Description 
     583---------- | ----------- 
     584`css/`     | Contains style sheets with a `.css` extension. 
     585`images/`  | Contains images with a `.jpg`, `.png`, or `.gif` format. 
     586`js/`      | Holds JavaScript files with a `.js` extension. 
     587`uploads/` | Must contain the files uploaded by the users. Even though the directory usually contains images, it is distinct from the images directory so that the synchronization of the development and production servers does not affect the uploaded images. 
    655588 
    656589>**NOTE** 
  • doc/branches/1.0/book/04-The-Basics-of-Page-Creation.txt

    r3348 r3372  
    5353The 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. 
    5454 
    55 >**NOTE* 
     55>**NOTE** 
    5656>Symfony offers other ways to initiate a module than the command line. One of them is to create the directories and files yourself. In many cases, actions and templates of a module are meant to manipulate data of a given table. As the necessary code to create, retrieve, update, and delete records from a table is often the same, symfony provides a mechanism called scaffolding to generate this code for you. Refer to Chapter 14 for more information about this technique. 
    5757 
     
    9494>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. 
    9595 
     96- 
     97 
    9698>**SIDEBAR** 
    9799>URLs are part of the response 
     
    99101>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: 
    100102> 
    101 >    http://localhost/myapp_dev.php/article/index?id=123 
     103>    http://localhost/myapp_dev.php/article/index?id=123 
    102104> 
    103105>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: 
    104106> 
    105 >    http://localhost/articles/europe/france/finance.html 
     107>    http://localhost/articles/europe/france/finance.html 
    106108> 
    107109>Not only is the resulting URL search engine-friendly, it is also significant for the user, who can then use the address bar as a pseudo command line to do custom queries, as in the following: 
    108110> 
    109 >    http://localhost/articles/tagged/finance+france+euro 
     111>    http://localhost/articles/tagged/finance+france+euro 
    110112> 
    111113>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. 
     
    217219>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: 
    218220> 
    219 
    220 >    [php] 
    221 >    <?php 
    222 >    $card_list = array( 
    223 >      'VISA' => 'Visa', 
    224 >      'MAST' => 'MasterCard', 
    225 >      'AMEX' => 'American Express', 
    226 >      'DISC' => 'Discover'); 
    227 >    echo select_tag('cc_type', options_for_select($card_list, 'AMEX')); 
    228 >    ?> 
    229 
     221>     [php] 
     222>     <?php 
     223>     $card_list = array( 
     224>       'VISA' => 'Visa', 
     225>       'MAST' => 'MasterCard', 
     226>       'AMEX' => 'American Express', 
     227>       'DISC' => 'Discover'); 
     228>     echo select_tag('cc_type', options_for_select($card_list, 'AMEX')); 
     229>     ?> 
    230230> 
    231231>This outputs the following HTML: 
    232232> 
    233 
    234 >    [php] 
    235 >    <select name="cc_type" id="cc_type"> 
    236 >      <option value="VISA">Visa</option> 
    237 >      <option value="MAST">MasterCard</option> 
    238 >      <option value="AMEX" selected="selected">American Express</option> 
    239 >      <option value="DISC">Discover</option> 
    240 >    </select> 
    241 
     233>     [php] 
     234>     <select name="cc_type" id="cc_type"> 
     235>       <option value="VISA">Visa</option> 
     236>       <option value="MAST">MasterCard</option> 
     237>       <option value="AMEX" selected="selected">American Express</option> 
     238>       <option value="DISC">Discover</option> 
     239>     </select> 
    242240> 
    243241>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. 
     
    301299Whenever you use a symfony helper that outputs an HTML tag, you can insert additional tag attributes (like the `class` attribute in the example in Listing 4-12) in the option argument. You can even write these attributes in the "quick-and-dirty" HTML 4.0 way (without double quotes), and symfony will output them in nicely formatted XHTML. That's another reason why helpers are faster to write than HTML. 
    302300 
    303 >**NOTE* 
     301>**NOTE** 
    304302>Because it requires an additional parsing and transformation, the string syntax is a little slower than the array syntax. 
    305303 
  • doc/branches/1.0/book/05-Configuring-Symfony.txt

    r3348 r3372  
    160160  * You miss a space between a key and its value: 
    161161 
    162     key1:value1      # A space is missing after the : 
     162        key1:value1      # A space is missing after the : 
    163163 
    164164  * Keys in a sequence are not indented the same way: 
    165165 
    166     all: 
    167       key1:  value1 
    168        key2: value2  # Indentation is not the same as the other sequence members 
    169       key3:  value3 
     166        all: 
     167          key1:  value1 
     168           key2: value2  # Indentation is not the same as the other sequence members 
     169          key3:  value3 
    170170 
    171171  * There is a reserved YAML character in a key or a value, without string delimiters: 
    172172 
    173     message: tell him: go way    # :, [, ], { and } are reserved in YAML 
    174     message: 'tell him: go way'  # Correct syntax 
     173        message: tell him: go way    # :, [, ], { and } are reserved in YAML 
     174        message: 'tell him: go way'  # Correct syntax 
    175175 
    176176  * You are modifying a commented line: 
    177177 
    178     # key: value     # Will never be taken into account due to the leading # 
     178        # key: value     # Will never be taken into account due to the leading # 
    179179 
    180180  * You set values with the same key name twice at the same level: 
    181181 
    182     key1: value1 
    183     key2: value2 
    184     key1: value3     # key1 is defined twice, the value is the last one defined 
     182        key1: value1 
     183        key2: value2 
     184        key1: value3     # key1 is defined twice, the value is the last one defined 
    185185 
    186186  * You think that the setting takes a special type, while it is always a string, until you convert it: 
    187187 
    188     income: 12,345   # Until you convert it, this is still a string 
     188        income: 12,345   # Until you convert it, this is still a string 
    189189 
    190190Overview of the Configuration Files 
     
    244244> 
    245245> 
    246 >    symfony/    # Private area 
    247 >      apps/ 
    248 >      batch/ 
    249 >      cache/ 
    250 >      ... 
    251 >    www/        # Public area 
    252 >      images/ 
    253 >      css/ 
    254 >      js/ 
    255 >      index.php 
     246>    symfony/    # Private area 
     247>      apps/ 
     248>      batch/ 
     249>      cache/ 
     250>      ... 
     251>    www/        # Public area 
     252>      images/ 
     253>      css/ 
     254>      js/ 
     255>      index.php 
    256256> 
    257257> 
    258258>In this case, the root directory is the `symfony/` directory. So the `index.php` front controller simply needs to define the `SF_ROOT_DIR` as follows for the application to work: 
    259259> 
    260 >    define('SF_ROOT_DIR', dirname(__FILE__).'/../symfony'); 
     260>    define('SF_ROOT_DIR', dirname(__FILE__).'/../symfony'); 
    261261 
    262262Chapter 19 will give you more information about how to tweak symfony to make it work on a specific directory structure. 
     
    309309 
    310310>**SIDEBAR** 
    311 >**Too many files? 
     311>Too many files? 
    312312> 
    313313>You might be overwhelmed by the number of configuration files present in the application. But please keep the following in mind: 
     
    350350> 
    351351> 
    352 >    http://localhost/myapp_dev.php/mymodule/index 
    353 >           _________ _____________ 
    354 >            server    environment 
     352>    http://localhost/myapp_dev.php/mymodule/index 
     353>            _________ _____________ 
     354>            server    environment 
    355355> 
    356356> 
  • doc/branches/1.0/book/06-Inside-the-Controller-Layer.txt

    r3348 r3372  
    430430You're familiar with the `getRequestParameter('myparam')` method, used to retrieve the value of a request parameter by its name. As a matter of fact, this method is a proxy for a chain of calls to the request's parameter holder `getRequest()->getParameter('myparam')`. The action class has access to the request object, called `sfWebRequest` in symfony, and to all its methods, via the `getRequest()` method. Table 6-1 lists the most useful `sfWebRequest` methods. 
    431431 
    432 Table 6-1.  Methods of the `sfWebRequest` Object 
    433 Name  Function  Sample Output 
    434 Request Information 
    435  
    436 `getMethod()` 
    437  
    438 Request method 
    439  
    440 Returns `sfRequest::GET` or `sfRequest::POST` constants 
    441  
    442 `getMethodName()` 
    443  
    444 Request method name 
    445  
    446 `'POST'` 
    447  
    448 `getHttpHeader('Server')` 
    449  
    450 Value of a given HTTP header 
    451  
    452 `'Apache/2.0.59 (Unix) DAV/2 PHP/5.1.6'` 
    453  
    454 `getCookie('foo')` 
    455  
    456 Value of a named cookie 
    457  
    458 `'bar'` 
    459  
    460 `isXmlHttpRequest()`* 
    461  
    462 Is it an Ajax request? 
    463  
    464 `true` 
    465  
    466 `isSecure()` 
    467  
    468 Is it an SSL request? 
    469  
    470 `true` 
    471  
    472 Request Parameters 
    473  
    474 `hasParameter('foo')` 
    475  
    476 Is a parameter present in the request? 
    477  
    478 `true` 
    479  
    480 `getParameter('foo')` 
    481  
    482 Value of a named parameter 
    483  
    484 `'bar'` 
    485  
    486 `getParameterHolder()->getAll()` 
    487  
    488 Array of all request parameters 
    489  
    490 URI-Related Information 
    491  
    492 `getUri()` 
    493  
    494 Full URI 
    495  
    496 `'http://localhost/myapp_dev.php/mymodule/myaction'` 
    497  
    498 `getPathInfo()` 
    499  
    500 Path info 
    501  
    502 `'/mymodule/myaction'` 
    503  
    504 `getReferer()`** 
    505  
    506 Referrer 
    507  
    508 `'http://localhost/myapp_dev.php/'` 
    509  
    510 `getHost()` 
    511  
    512 Host name 
    513  
    514 `'localhost'` 
    515  
    516 `getScriptName()` 
    517  
    518 Front controller path and name 
    519  
    520 `'myapp_dev.php'` 
    521  
    522 Client Browser Information 
    523  
    524 `getLanguages()` 
    525  
    526 Array of accepted languages 
    527  
    528 `Array( ` ` [0] => fr ` ` [1] => fr_FR ` ` [2] => en_US ` ` [3] => en )` 
    529  
    530 `getCharsets()` 
    531  
    532 Array of accepted charsets 
    533  
    534 `Array( ` ` [0] => ISO-8859-1 ` ` [1] => UTF-8 ` ` [2] => * )` 
    535  
    536 getAcceptableContentType() 
    537  
    538 Array of accepted content types 
    539  
    540 `Array( [0] => text/xml [1] => text/html` 
    541  
    542 *Works only with prototype **Sometimes blocked by proxies 
     432Table 6-1 - Methods of the `sfWebRequest` Object 
     433 
     434Name                             | Function                               |  Sample Output 
     435-------------------------------- | -------------------------------------- | ----------------------------------------------------------------------- 
     436**Request Information**          |                                        | 
     437`getMethod()`                    | Request method                         | Returns `sfRequest::GET` or `sfRequest::POST` constants 
     438`getMethodName()`                | Request method name                    | `'POST'` 
     439`getHttpHeader('Server')`        | Value of a given HTTP header           | `'Apache/2.0.59 (Unix) DAV/2 PHP/5.1.6'` 
     440`getCookie('foo')`               | Value of a named cookie                | `'bar'` 
     441`isXmlHttpRequest()`*            | Is it an Ajax request?                 | `true` 
     442`isSecure()`                     | Is it an SSL request?                  | `true` 
     443**Request Parameters**           |                                        | 
     444`hasParameter('foo')`            | Is a parameter present in the request? | `true` 
     445`getParameter('foo')`            | Value of a named parameter             | `'bar'` 
     446`getParameterHolder()->getAll()` | Array of all request parameters        | 
     447**URI-Related Information**      |                                        | 
     448`getUri()`                       | Full URI                               | `'http://localhost/myapp_dev.php/mymodule/myaction'` 
     449`getPathInfo()`                  | Path info                              | `'/mymodule/myaction'` 
     450`getReferer()`**                 | Referrer                               | `'http://localhost/myapp_dev.php/'` 
     451`getHost()`                      | Host name                              | `'localhost'` 
     452`getScriptName()`                | Front controller path and name         | `'myapp_dev.php'` 
     453**Client Browser Information**   |                                        | 
     454`getLanguages()`                 | Array of accepted languages            | `Array( ` ` [0] => fr ` ` [1] => fr_FR ` ` [2] => en_US ` ` [3] => en )` 
     455`getCharsets()`                  | Array of accepted charsets             | `Array( ` ` [0] => ISO-8859-1 ` ` [1] => UTF-8 ` ` [2] => * )` 
     456getAcceptableContentType()       | Array of accepted content types        | `Array( [0] => text/xml [1] => text/html` 
     457 
     458* *Works only with prototype* 
     459 
     460** *Sometimes blocked by proxies* 
    543461 
    544462The `sfActions` class offers a few proxies to access the request methods more quickly, as shown in Listing 6-15. 
  • doc/branches/1.0/book/07-Inside-the-View-Layer.txt

    r3348 r3372  
    44The view is responsible for rendering the output correlated to a particular action. In symfony, the view consists of several parts, with each part designed to be easily modified by the person who usually works with it. 
    55 
    6       * Web designers generally work on the templates (the presentation of the current action data) and on the layout (containing the code common to all pages). These are written in HTML with small embedded chunks of PHP, which are mostly calls to helpers. 
    7  
    8       * For reusability, developers usually package template code fragments into partials or components. They use slots and component slots to affect more than one zone of the layout. Web designers can work on these template fragments as well. 
    9  
    10       * Developers focus on the YAML view configuration file (setting the properties of the response and other interface elements) and on the response object. When dealing with variables in the templates, the risks of cross-site scripting must not be ignored, and a good comprehension of output escaping techniques is required to safely record user data. 
     6* Web designers generally work on the templates (the presentation of the current action data) and on the layout (containing the code common to all pages). These are written in HTML with small embedded chunks of PHP, which are mostly calls to helpers. 
     7* For reusability, developers usually package template code fragments into partials or components. They use slots and component slots to affect more than one zone of the layout. Web designers can work on these template fragments as well. 
     8* Developers focus on the YAML view configuration file (setting the properties of the response and other interface elements) and on the response object. When dealing with variables in the templates, the risks of cross-site scripting must not be ignored, and a good comprehension of output escaping techniques is required to safely record user data. 
    119 
    1210But whatever your role is, you will find useful tools to speed up the tedious job of presenting the results of the action. This chapter covers all of these tools. 
     
    4745    } 
    4846 
    49 As a matter of fact, the input_tag() function built into symfony is a little more complicated than that, as it accepts a third parameter to add other attributes to the <input> tag. You can check its complete syntax and options in the online API documentation (http://www.symfony-project.com/api/symfony.html). 
     47As a matter of fact, the input_tag() function built into symfony is a little more complicated than that, as it accepts a third parameter to add other attributes to the `<input>` tag. You can check its complete syntax and options in the online API documentation (http://www.symfony-project.com/api/symfony.html). 
    5048 
    5149Most of the time, helpers carry intelligence and save you long and complex coding: 
     
    311309A component is like an action, except it's much faster. The logic of a component is kept in a class inheriting from `sfComponents`, located in an `action/components.class.php` file. Its presentation is kept in a partial. Methods of the `sfComponents` class start with the word `execute`, just like actions, and they can pass variables to their presentation counterpart in the same way that actions can pass variables. Partials that serve as presentation for components are named by the component (without the leading `execute`, but with an underscore instead). Table 7-1 compares the naming conventions for actions and components. 
    312310 
    313 Table 7-1.  Action and Component Naming Conventions 
    314 Convention  Actions  Components 
    315  
    316 Logic file 
    317  
    318 `actions.class.php` 
    319  
    320 `components.class.php` 
    321  
    322 Logic class extends 
    323  
    324 `sfActions` 
    325  
    326 `sfComponents` 
    327  
    328 Method naming 
    329  
    330 `executeMyAction()` 
    331  
    332 `executeMyComponent()` 
    333  
    334 Presentation file naming 
    335  
    336 `myActionSuccess.php` 
    337  
    338 `_myComponent.php` 
     311Table 7-1 - Action and Component Naming Conventions 
     312 
     313Convention               |  Actions              |  Components 
     314------------------------ | --------------------- | ---------------------- 
     315Logic file               | `actions.class.php`   | `components.class.php` 
     316Logic class extends      | `sfActions`           | `sfComponents` 
     317Method naming            | `executeMyAction()`   | `executeMyComponent()` 
     318Presentation file naming | `myActionSuccess.php` | `_myComponent.php` 
    339319 
    340320>**TIP** 
     
    460440> 
    461441> 
    462 >    myproject/ 
    463 >      apps/ 
    464 >        application1/ 
    465 >          templates/       # Layouts for application 1 
    466 >          modules/ 
    467 >            module1/ 
    468 >              templates/   # Templates and partials for module 1 
    469 >            module2/ 
    470 >              templates/   # Templates and partials for module 2 
    471 >            module3/ 
    472 >              templates/   # Templates and partials for module 3 
     442>    myproject/ 
     443>      apps/ 
     444>        application1/ 
     445>          templates/       # Layouts for application 1 
     446>          modules/ 
     447>            module1/ 
     448>              templates/   # Templates and partials for module 1 
     449>            module2/ 
     450>              templates/   # Templates and partials for module 2 
     451>            module3/ 
     452>              templates/   # Templates and partials for module 3 
    473453> 
    474454> 
     
    713693 
    714694>**NOTE** 
    715 >Style sheet and JavaScript inclusions in the response are performed by a filter called sfCommonFilter. It looks for a <head> tag in the response, and adds the <link> and <script> just before the closing `</head>`. This means that the inclusion can't take place if there is no `<head>` tag in your layout or templates. 
     695>Style sheet and JavaScript inclusions in the response are performed by a filter called sfCommonFilter. It looks for a `<head>` tag in the response, and adds the `<link>` and `<script>` just before the closing `</head>`. This means that the inclusion can't take place if there is no `<head>` tag in your layout or templates. 
    716696 
    717697Remember that the configuration cascade principle applies, so any file inclusion defined in the application `view.yml` makes it appear in every page of the application. Listings 7-27, 7-28, and 7-29 demonstrate this principle. 
  • doc/branches/1.0/book/08-Inside-the-Model-Layer.txt

    r3348 r3372  
    187187But first, let's make sure we share the same vocabulary. Relational and object data model use similar concepts, but they each have their own nomenclature: 
    188188 
    189 Relational  Object-Oriented 
    190  
    191 Table 
    192  
    193 Class 
    194  
    195 Row, record 
    196  
    197 Object 
    198  
    199 Field, column 
    200  
    201 Property 
     189Relational    | Object-Oriented 
     190------------- | --------------- 
     191Table         | Class 
     192Row, record   | Object 
     193Field, column | Property 
    202194 
    203195### Retrieving the Column Value 
     
    271263The `getArticle()` method returns an object of class `Article`, which benefits from the `getTitle()` accessor. This is much better than doing the join yourself, which may take a few lines of code (starting from the `$comment->getArticleId()` call). 
    272264 
    273 The `$comments` variable in Listing 8-10 contains an array of objects of class `Comment`. You can display the first one with `$comments[0]` or iterate through the collection with `foreach ` ($comments as $comment)`. 
     265The `$comments` variable in Listing 8-10 contains an array of objects of class `Comment`. You can display the first one with `$comments[0]` or iterate through the collection with `foreach ($comments as $comment)`. 
    274266 
    275267>**NOTE** 
     
    360352>Why use `CommentPeer::AUTHOR` instead of `blog_comment.AUTHOR`, which is the way it will be output in the SQL query anyway? Suppose that you need to change the name of the author field to `contributor` in the database. If you used `blog_comment.AUTHOR`, you would have to change it in every call to the model. On the other hand, by using `CommentPeer::AUTHOR`, you simply need to change the column name in the `schema.yml` file, keep `phpName` as `AUTHOR`, and rebuild the model. 
    361353 
    362 Table 8-1 - compares the SQL syntax with the `Criteria` object syntax. 
    363  
    364 Table 8-1.  SQL and Criteria Object Syntax 
    365 SQL  Criteria 
    366  
    367 `WHERE column = value` 
    368  
    369 `->add(column, value);` 
    370  
    371 `WHERE column <> value` 
    372  
    373 `->add(column, value, Criteria::NOT_EQUAL);` 
    374  
    375 Other Comparison Operators 
    376  
    377 `> , <` 
    378  
    379 `Criteria::GREATER_THAN, Criteria::LESS_THAN` 
    380  
    381 `>=, <=` 
    382  
    383 `Criteria::GREATER_EQUAL, Criteria::LESS_EQUAL` 
    384  
    385 `IS NULL, IS NOT NULL` 
    386  
    387 `Criteria::ISNULL, Criteria::ISNOTNULL` 
    388  
    389 `LIKE, ILIKE` 
    390  
    391 `Criteria::LIKE, Criteria::ILIKE` 
    392  
    393 `IN, NOT IN` 
    394  
    395 `Criteria::IN, Criteria::NOT_IN` 
    396  
    397 Other SQL Keywords 
    398  
    399 `ORDER BY column ASC` 
    400  
    401 `->addAscendingOrderByColumn(column);` 
    402  
    403 `ORDER BY column DESC` 
    404  
    405 `->addDescendingOrderByColumn(column);` 
    406  
    407 `LIMIT limit` 
    408  
    409 `->setLimit(limit)` 
    410  
    411 `OFFSET offset` 
    412  
    413 `->setOffset(offset) ` 
    414  
    415 `FROM table1, table2 WHERE table1.col1 = table2.col2` 
    416  
    417 `->addJoin(col1, col2)` 
    418  
    419 `FROM table1 LEFT JOIN table2 ON table1.col1 = table2.col2` 
    420  
    421 `->addJoin(col1, col2, Criteria::LEFT_JOIN)` 
    422  
    423 `FROM table1 RIGHT JOIN table2 ON table1.col1 = table2.col2` 
    424  
    425 `->addJoin(col1, col2, Criteria::RIGHT_JOIN)` 
     354Table 8-1 compares the SQL syntax with the `Criteria` object syntax. 
     355 
     356Table 8-1 - SQL and Criteria Object Syntax 
     357 
     358SQL                                                          | Criteria 
     359------------------------------------------------------------ | ----------------------------------------------- 
     360`WHERE column = value`                                       | `->add(column, value);` 
     361`WHERE column <> value`                                      | `->add(column, value, Criteria::NOT_EQUAL);` 
     362**Other Comparison Operators**                               |  
     363`> , <`                                                      | `Criteria::GREATER_THAN, Criteria::LESS_THAN` 
     364`>=, <=`                                                     | `Criteria::GREATER_EQUAL, Criteria::LESS_EQUAL` 
     365`IS NULL, IS NOT NULL`                                       | `Criteria::ISNULL, Criteria::ISNOTNULL` 
     366`LIKE, ILIKE`                                                | `Criteria::LIKE, Criteria::ILIKE` 
     367`IN, NOT IN`                                                 | `Criteria::IN, Criteria::NOT_IN` 
     368**Other SQL Keywords**                                       | 
     369`ORDER BY column ASC`                                        | `->addAscendingOrderByColumn(column);` 
     370`ORDER BY column DESC`                                       | `->addDescendingOrderByColumn(column);` 
     371`LIMIT limit`                                                | `->setLimit(limit)` 
     372`OFFSET offset`                                              | `->setOffset(offset) ` 
     373`FROM table1, table2 WHERE table1.col1 = table2.col2`        | `->addJoin(col1, col2)` 
     374`FROM table1 LEFT JOIN table2 ON table1.col1 = table2.col2`  | `->addJoin(col1, col2, Criteria::LEFT_JOIN)` 
     375`FROM table1 RIGHT JOIN table2 ON table1.col1 = table2.col2` | `->addJoin(col1, col2, Criteria::RIGHT_JOIN)` 
    426376 
    427377>**TIP** 
     
    520470>For example, imagine the code needed in a blog to retrieve the ten most popular articles for a given tag (passed as request parameter). This code should not be in an action, but in the model. In fact, if you need to display this list in a template, the action should simply look like this: 
    521471> 
    522 >    [php] 
    523 >    public function executeShowPopularArticlesForTag() 
    524 >   
    525 >      $tag = TagPeer::retrieveByName($this->getRequestParameter('tag')); 
    526 >      $this->foward404Unless($tag); 
    527 >      $this->articles = $tag->getPopularArticles(10); 
    528 >   
     472>    [php] 
     473>    public function executeShowPopularArticlesForTag() 
     474>   
     475>      $tag = TagPeer::retrieveByName($this->getRequestParameter('tag')); 
     476>      $this->foward404Unless($tag); 
     477>      $this->articles = $tag->getPopularArticles(10); 
     478>   
    529479> 
    530480>The action creates an object of class `Tag` from the request parameter. Then all the code needed to query the database is located in a ->getPopularArticles() method of this class. It makes the action more readable, and the model code can easily be reused in another action. 
     
    724674> 
    725675> 
    726 >    // In config/business-schema.yml 
    727 >    propel: 
    728 >      blog_article: 
    729 >        _attributes: { phpName: Article } 
    730 >      id: 
    731 >      title: varchar(50) 
    732 > 
    733 >    // In config/stats-schema.yml 
    734 >    propel: 
    735 >      stats_hit: 
    736 >        _attributes: { phpName: Hit } 
    737 >      id: 
    738 >      resource: varchar(100) 
    739 >      created_at: 
     676>      // In config/business-schema.yml 
     677>      propel: 
     678>        blog_article: 
     679>          _attributes: { phpName: Article } 
     680>        id: 
     681>        title: varchar(50) 
     682> 
     683>      // In config/stats-schema.yml 
     684>      propel: 
     685>        stats_hit: 
     686>          _attributes: { phpName: Hit } 
     687>        id: 
     688>        resource: varchar(100) 
     689>        created_at: 
    740690> 
    741691> 
     
    745695> 
    746696> 
    747 >    // In config/business-schema.yml 
    748 >    propel: 
    749 >      blog_article: 
    750 >        _attributes: { phpName: Article, package: lib.model.business } 
    751 >      id: 
    752 >      title: varchar(50) 
    753 > 
    754 >    // In config/stats-schema.yml 
    755 >    propel_bis: 
    756 >      stats_hit: 
    757 >        _attributes: { phpName: Hit, package.lib.model.stat } 
    758 >      id: 
    759 >      resource: varchar(100) 
    760 >      created_at: 
     697>      // In config/business-schema.yml 
     698>      propel: 
     699>        blog_article: 
     700>          _attributes: { phpName: Article, package: lib.model.business } 
     701>        id: 
     702>        title: varchar(50) 
     703> 
     704>      // In config/stats-schema.yml 
     705>      propel_bis: 
     706>        stats_hit: 
     707>          _attributes: { phpName: Hit, package.lib.model.stat } 
     708>        id: 
     709>        resource: varchar(100) 
     710>        created_at: 
    761711> 
    762712> 
     
    983933> 
    984934> 
    985 >    propel.database.createUrl = mysql://login:passwd@localhost 
    986 >    propel.database.url       = mysql://login:passwd@localhost/blog 
     935>      propel.database.createUrl = mysql://login:passwd@localhost 
     936>      propel.database.url       = mysql://login:passwd@localhost/blog 
    987937> 
    988938> 
     
    990940> 
    991941> 
    992 >    // Base classes are autoloaded in symfony 
    993 >    // Set this to true to use include_once statements instead 
    994 >    // (Small negative impact on performance) 
    995 >    propel.builder.addIncludes = false 
    996 > 
    997 >    // Generated classes are not commented by default 
    998 >    // Set this to true to add comments to Base classes 
    999 >    // (Small negative impact on performance) 
    1000 >    propel.builder.addComments = false 
    1001 > 
    1002 >    // Behaviors are not handled by default 
    1003 >    // Set this to true to be able to handle them 
    1004 >    propel.builder.AddBehaviors = false 
     942>      // Base classes are autoloaded in symfony 
     943>      // Set this to true to use include_once statements instead 
     944>      // (Small negative impact on performance) 
     945>      propel.builder.addIncludes = false 
     946> 
     947>      // Generated classes are not commented by default 
     948>      // Set this to true to add comments to Base classes 
     949>      // (Small negative impact on performance) 
     950>      propel.builder.addComments = false 
     951> 
     952>      // Behaviors are not handled by default 
     953>      // Set this to true to be able to handle them 
     954>      propel.builder.AddBehaviors = false 
    1005955> 
    1006956> 
  • doc/branches/1.0/book/09-Links-and-the-Routing-System.txt

    r3348 r3372  
    349349>You don't need to mention a file extension for an asset. Symfony automatically adds `.png`, `.js`, or `.css` to an image, JavaScript, or style sheet helper call. Also, symfony will automatically look for those assets in the `web/images/`, `web/js/`, and `web/css/` directories. Of course, if you want to include a specific file format or a file from a specific location, just use the full file name or the full file path as an argument. And don't bother to specify an `alt` attribute if your media file has an explicit name, since symfony will determine it for you. 
    350350> 
    351 >    [php] 
    352 >    <?php echo image_tag('test') ?> 
    353 >    <?php echo image_tag('test.gif') ?> 
    354 >    <?php echo image_tag('/my_images/test.gif') ?> 
    355 >     => <img href="/images/test.png" alt="Test" /> 
    356 >        <img href="/images/test.gif" alt="Test" /> 
    357 >        <img href="/my_images/test.gif" alt="Test" /> 
     351>    [php] 
     352>    <?php echo image_tag('test') ?> 
     353>    <?php echo image_tag('test.gif') ?> 
     354>    <?php echo image_tag('/my_images/test.gif') ?> 
     355>      => <img href="/images/test.png" alt="Test" /> 
     356>        <img href="/images/test.gif" alt="Test" /> 
     357>        <img href="/my_images/test.gif" alt="Test" /> 
    358358> 
    359359>To fix the size of an image, use the `size` attribute. It expects a width and a height in pixels, separated by an `x`. 
    360360> 
    361 >    [php] 
    362 >    <?php echo image_tag('test', 'size=100x20')) ?> 
    363 >     => <img href="/images/test.png" alt="Test" width="100" height="20"/> 
     361>    [php] 
     362>    <?php echo image_tag('test', 'size=100x20')) ?> 
     363>      => <img href="/images/test.png" alt="Test" width="100" height="20"/> 
    364364> 
    365365>If you want the asset inclusion to be done in the `<head>` section (for JavaScript files and style sheets), you should use the `use_stylesheet()` and `use_javascript()` helpers in your templates, instead of the `_tag()` versions in the layout. They add the asset to the response, and these assets are included before the `</head>` tag is sent to the browser. 
     
    393393>The `mail_to()` helper takes two parameters: the actual e-mail address and the string that should be displayed. Additional options accept an `encode` parameter to output something pretty unreadable in HTML, which is understood by browsers but not by robots. 
    394394> 
    395 >    [php] 
    396 >    <?php echo mail_to('myaddress@mydomain.com', 'contact') ?> 
    397 >     => <a href="mailto:myaddress@mydomain.com'>contact</a> 
    398 >    <?php echo mail_to('myaddress@mydomain.com', 'contact', 'encode=true') ?> 
    399 >     => <a href="&#109;&#x61;... &#111;&#x6d;">&#x63;&#x74;... e&#115;&#x73;</a> 
     395>    [php] 
     396>    <?php echo mail_to('myaddress@mydomain.com', 'contact') ?> 
     397>      => <a href="mailto:myaddress@mydomain.com'>contact</a> 
     398>    <?php echo mail_to('myaddress@mydomain.com', 'contact', 'encode=true') ?> 
     399>      => <a href="&#109;&#x61;... &#111;&#x6d;">&#x63;&#x74;... e&#115;&#x73;</a> 
    400400> 
    401401>Encoded e-mail messages are composed of characters transformed by a random decimal and hexadecimal entity encoder. This trick stops most of the address-harvesting spambots for now, but be aware that the harvesting techniques evolve rapidly. 
     
    490490>A good security guideline for routing is to hide primary keys and replace them with significant strings as much as possible. What if you wanted to give access to articles from their title rather than from their ID? It would make external URLs look like this: 
    491491> 
    492 >    http://www.example.com/article/Finance_in_France 
     492>    http://www.example.com/article/Finance_in_France 
    493493> 
    494494>To that extent, you need to create a new `permalink` action, which will use a `slug` parameter instead of an `id` one, and add a new rule for it: 
    495495> 
    496 >    <