Development

/branches/1.2/UPGRADE_TO_1_2

You must first sign up to be able to contribute.

root/branches/1.2/UPGRADE_TO_1_2

Revision 27178, 27.1 kB (checked in by FabianLange, 5 years ago)

[doc] fixed typo

Line 
1 Upgrading Projects from 1.1 to 1.2
2 ==================================
3
4 This document describes the changes made in symfony 1.2 and what need
5 to be done to upgrade your symfony 1.1 projects.
6
7 If you want more detailed information on what has been changed/added in symfony 1.2,
8 you can read the [What's new?](http://www.symfony-project.org/tutorial/1_2/whats-new) tutorial.
9
10 >**CAUTION**
11 >symfony 1.2 is compatible with PHP 5.2.4 or later.
12 >It might also work with PHP 5.2.0 to 5.2.3 but there is no guarantee.
13
14 How to upgrade?
15 ---------------
16
17 To upgrade a project:
18
19   * Check that all plugins used by your project are compatible with symfony
20     1.2
21
22   * If you don't use a SCM tool, please make a backup of your project.
23
24   * Upgrade symfony to 1.2
25
26   * Launch the `project:upgrade1.2` task from your project directory
27     to perform an automatic upgrade:
28
29         $ php symfony project:upgrade1.2
30
31     This task can be launched several times without any side effect. Each time
32     you upgrade to a new symfony 1.2 beta / RC or the final symfony 1.2, you
33     have to launch this task.
34
35   * Upgrade the plugins to their 1.2 version
36
37   * You need to rebuild your models and forms due to some changes described
38     below (read below how to upgrade to Propel 1.3 first):
39
40         $ php symfony propel:build-model
41         $ php symfony propel:build-forms
42         $ php symfony propel:build-filters
43
44   * Clear the cache:
45
46         $ php symfony cc
47
48 The remaining sections explain the main changes made in symfony 1.2 that need
49 some kind of upgrade (automatic or not).
50
51 Upgrade to 1.2 final
52 --------------------
53
54 If you have upgraded your 1.1 project before 1.2 final, you need to check the
55 following things:
56
57   * If you have generated CRUD modules with the `--non-verbose-templates` options,
58     you need to remove the extra `$form->renderHiddenFields()` statement in the `_form.php`
59     template. If not, you can have erroneous "CSRF attack detected" error messages.
60
61   * For all generated CRUD modules, and if you have enabled CSRF protection, you need
62     to insert `$request->checkCSRFProtection()` at the beginning of the generated
63     `executeDelete()` method to be protected from CSRF attacks.
64
65 Propel
66 ------
67
68 Propel has been upgraded to version 1.3, which replaces support for Creole
69 with PDO.
70
71 Due to the removal of Creole, the following classes are removed:
72
73  *class name*             | *equivalent*
74  ------------------------ | -------------------------------
75  `sfCreoleDatabase`       | `sfPropelDatabase`
76  `sfDebugConnection`      | `DebugPDO`
77  `sfMessageSource_Creole` | `sfMessageSource_PDO`
78  `sfCreoleSessionStorage` | `sfPDOSessionStorage`
79  
80 The `propel:build-db` task has been removed as this functionality is not yet
81 provided by Propel 1.3.
82
83 The first step to upgrading is changing from Creole to PDO syntax in the
84 database configuration from the project `databases.yml` file.
85
86 Locate the following:
87
88     [yml]
89     all:
90       propel:
91         class:      sfPropelDatabase
92         param:
93           dsn:      mysql://username:password@localhost/example
94
95 Replace with the following:
96
97     [yml]
98     dev:
99       propel:
100         param:
101           classname: DebugPDO
102
103     test:
104       propel:
105         param:
106           classname:  DebugPDO
107
108     all:
109       propel:
110         class: sfPropelDatabase
111         param:
112           dsn:        mysql:dbname=example;host=localhost
113           username:   username
114           password:   password
115           encoding:   utf8
116           persistent: true
117           pooling:    true
118           classname:  PropelPDO
119
120 Next, you must also upgrade the `propel.ini` with the PDO format DSN and updated
121 configuration options.
122
123 Locate the following:
124
125     [ini]
126     propel.database            = mysql
127     propel.database.createUrl  = mysql://username:password@localhost/
128     propel.database.url        = mysql://username:password@localhost/example
129
130 Replace with the following:
131
132     [ini]
133     propel.database            = mysql
134     propel.database.driver     = mysql
135     propel.database.url        = mysql:dbname=example;host=localhost
136     propel.database.user       = username
137     propel.database.password   = password
138     propel.database.encoding   = utf8
139
140 Since the underlying api has changed quite a bit, you need to rebuild the
141 object model:
142
143     $ php symfony propel:build-model
144
145 In most cases, this will be all that is required. If you have customized
146 object model classes, you may need to manually upgrade for the changes in
147 API from Creole to PDO. The upgrade task will attempt to change method
148 signatures to match the `Persistent` interface, by adding type hinting for
149 PropelPDO in `->save($con = null)` and `->delete($con = null)`.
150
151 Change instances of:
152
153     [php]
154     public function save($con = null)
155     public function delete($con = null)
156
157 To add PropelPDO type hint:
158
159     [php]
160     public function save(PropelPDO $con = null)
161     public function delete(PropelPDO $con = null)
162
163 The transaction api has change slightly: `->begin` has been renamed `->beginTransaction()`
164 and `->rollback()` has been renamed `->rollBack()`. Here are the differences:
165  
166 `Creole`:
167
168     [php]
169     $con->begin();
170     try {
171       /* db logic */
172       $con->commit();
173     } catch (SQLException $sqle) {
174       $con->rollback();
175       throw $sqle;
176     }
177    
178 `PDO`:
179
180     [php]
181     $con->beginTransaction();
182     try {
183       /* db logic */
184       $con->commit();
185     } catch (PDOException $sqle) {
186       $con->rollBack();
187       throw $sqle;
188     }
189
190 The `::doSelectRS` method has been renamed to `::doSelectStmt`. Here are the differences:
191
192 `Creole`:
193
194     [php]
195     // example of how to manually hydrate objects
196     $rs = AuthorPeer::doSelectRS(new Criteria());
197     while($rs->next()) {
198       $a = new Author();
199       $a->hydrate($rs);
200     }
201
202     // example of how to create array of single column
203     $rs = AuthorPeer::doSelectRS(new Criteria());
204     $names = array();
205     while($rs->next()) {
206       $names[] = $rs->getString(2);
207     }
208    
209     $con = Propel::getConnection(SomeTablePeer::DATABASE_NAME);
210     $stmt = $con->prepareStatement("SELECT * FROM some_table WHERE name = ?");
211     $stmt->setString(1, $name);
212     $rs = $stmt->executeQuery();
213     while($rs->next()) {
214        print "Name: " . $rs->getString("name") . "\n";
215     }
216
217
218 `PDO`:
219
220     [php]
221     // example of how to manually hydrate objects
222     $stmt = AuthorPeer::doSelectStmt(new Criteria());
223     while($row = $stmt->fetch(PDO::FETCH_NUM)) {
224       $a = new Author();
225       $a->hydrate($row);
226     }
227    
228     // example of how to create array of single column
229     $stmt = AuthorPeer::doSelectStmt(new Criteria());
230     $names = array();
231     while($res = $stmt->fetchColumn(1)) {
232       $names[] = $res;
233     }
234    
235     $con = Propel::getConnection(SomeTablePeer::DATABASE_NAME);
236     $stmt = $con->prepare("SELECT * FROM some_table WHERE name = ?");
237     $stmt->bindValue(1, $name);
238     $stmt->execute();
239     while($row = $stmt->fetch()) {
240        print "Name: " . $row['name'] . "\n";
241     }
242
243 The `Clob` and `Lob` classes from Creole are not used anymore. It means you
244 need to change your code when using these objects:
245
246     [php]
247     // Propel 1.1
248     $object->getClobColumn()->getContents();
249
250     // Propel 1.2
251     $object->getClobColumn();
252
253 See http://propel.phpdb.org/trac/wiki/Users/Documentation/1.3/Upgrading for more details
254 on upgrading.
255
256 All the Propel library have been moved from `lib/propel` to `lib`. The upgrade task
257 upgrades the `propel.ini` file to reflect these changes.
258
259 Request
260 -------
261
262 The `path_info_array`, `path_info_key`, and `relative_url_root` settings have
263 been moved from `settings.yml` to `factories.yml` (in the `param` section of the
264 `request` factory configuration).
265
266 This change removes the dependency between `sfRequest` and `sfConfig`.
267
268 These three request options are now passed to the request constructor as a
269 fourth argument. The formats are also passed as an option,
270 instead of being passed as an attribute.
271
272 The request method constants from `sfRequest` values have changed from integers
273 to strings and the `sfRequest::NONE` method has been removed:
274
275  **Constant** | **Old value** | **New value**
276  ------------ | ------------- | -------------
277  GET          | 2             | GET
278  POST         | 4             | POST
279  PUT          | 5             | PUT
280  DELETE       | 6             | DELETE
281  HEAD         | 7             | HEAD
282  NONE         | 1             | -
283
284 The `getMethod()` and `getMethodName()` methods now returns the same value,
285 so `getMethodName()` is deprecated.
286
287 The `sfAction::getMethodNames()` and the corresponding code in
288 `sfValidationExecutionFilter` from `sfCompat10Plugin` have been removed.
289 This method was deprecated in 1.1 and was not really useable in 1.0.
290
291 Validators
292 ----------
293
294 The `sfValidatorSchemaCompare` constant values have been changed. No change to
295 your code need to be done, but now, you can use nice shortcuts.
296 The following two examples are equivalent:
297
298     [php]
299     // symfony 1.1 and 1.2
300     $v = new sfValidatorSchemaCompare('left', sfValidatorSchemaCompare::EQUAL, 'right');
301
302     // symfony 1.2 only
303     $v = new sfValidatorSchemaCompare('left', '==', 'right');
304
305 The `sfValidatorI18nChoiceCountry` and `sfValidatorI18nChoiceLanguage` validators
306 had a required `culture` option in symfony 1.1. As the culture is not used in those
307 validators, the `culture` option is now deprecated. It is still there to maintain
308 backward compatibility but you don't need to provide it anymore.
309
310 Forms
311 -----
312    
313 In symfony 1.1, the `BaseFormPropel` was generated in the wrong place (under the
314 `lib/form/base/` directory). You need to move it to the `lib/form/` directory.
315
316 Widgets
317 -------
318
319 The new `sfWidgetFormChoice` widgets are now used by default by the Propel generated forms
320 instead of `sfWidgetFormSelect`. To take advantage of this more powerful widgets, you will
321 need to rebuilt your forms:
322
323     $ php symfony propel:build-forms
324
325 Response
326 --------
327
328 There is a new setting for the `response` factory: `send_http_headers`.
329 This setting is `true` by default, except for the `test` environment where
330 the headers must not be sent by PHP (the same goal was achieved by using
331 the `sf_test` setting in symfony 1.1).
332
333 This change removes the dependency between `sfResponse` and `sfConfig`.
334
335 The `getStylesheets()` and `getJavascripts()` methods can now return all the
336 stylesheets and javascripts ordered by position if you pass `sfWebResponse::ALL`
337 as their first argument:
338
339     [php]
340     $response = new sfWebResponse(new sfEventDispatcher());
341     $response->addStylesheet('foo.css');
342     $response->addStylesheet('bar.css', 'first');
343
344     var_export($response->getStylesheets());
345
346     // outputs
347     array(
348       'bar.css' => array(),
349       'foo.css' => array(),
350     )
351
352 The `sfWebResponse::ALL` is also now the default value for the position argument.
353 In symfony 1.1, as the default value is the empty string, the methods only return
354 the files registered for the default position by default, which is not very intuitive.
355
356 In symfony 1.1, you was able to get all the files by passing the `'ALL'` string
357 as the position, and this behavior is still available by passing
358 `sfWebResponse::RAW`:
359
360     [php]
361     var_export($response->getStylesheets(sfWebResponse::RAW));
362
363     // outputs
364     array(
365       'first' =>
366         array(
367           'bar.css' => array (),
368         ),
369       '' =>
370         array(
371         'foo.css' => array(),
372         ),
373       'last' => array(),
374     )
375
376 All the positions (first, '', and last) are now also available as constants:
377
378     [php]
379     sfWebResponse::FIRST  === 'first'
380     sfWebResponse::MIDDLE === ''
381     sfWebResponse::LAST   === 'last'
382
383 The `removeStylesheet()` and `removeJavascript()` methods now only take one argument,
384 the file to remove from the response. It will remove the file in all the available
385 positions. In symfony 1.1, they take the position as a second argument.
386
387 Prototype and Scriptaculous
388 ---------------------------
389
390 symfony continues to decouple its bundled software. In 1.2 the bundled Prototype
391 and Scriptaculous libraries and helpers (`JavascriptHelper`) have been moved to a
392 core-plugin. Core plugins behave like any plugin but are shipped with symfony.
393 This will make the JavaScript and CSS files of the new `sfProtoculousPlugin`
394 (the more or less unofficial name of the often featured duo) behave like real plugin
395 assets. They will be now in `web/sfProtoculousPlugin` rather than in `web/sf`
396 (as it has been in 1.0 and 1.1). The `prototype_web_dir` setting will also now point
397 to the new directory.
398
399 In addition some very basic javascript helpers that are reusable by any JS framework, have
400 been extracted to a `JavascriptBaseHelper` which stays in core.
401
402 As a new addition, `javascript_tag()` now can behave as `slot()`. This allows such usage
403
404     [php]
405     <?php javascript_tag() ?>
406     alert('All is good')
407     <?php end_javascript_tag() ?>
408
409 Assets from built-in plugins
410 ----------------------------
411
412 Some built-in plugins come with some stylesheet and JavaScript files. To make them
413 accessible to your project, you need to run the `plugin:publish-assets` task:
414
415     $ php symfony plugin:publish-assets
416
417 The `project:upgrade1.2` task do this for you.
418
419 Browser
420 -------
421
422 The `sfBrowser` and `sfTestBrowser` classes have been refactored in four classes:
423
424   * `sfBrowserBase`:        The base browser class. It knows nothing about symfony,
425                             except classes from the symfony platform.
426
427   * `sfBrowser`:            It inherits from `sfBrowserBase` and implements the
428                             methods specific to symfony.
429
430   * `sfTestFunctionalBase`: The base functional test class. It implements test
431                             methods that are independant from symfony.
432
433   * `sfTestFunctional`:     It inherits from `sfTestFunctionalBase` and implements
434                             the test methods specific to symfony.
435
436   * `sfTestBrowser`:        A BC class which is the same as the `sfTestFunctional`
437                             class with a constructor signature compatible with symfony 1.1
438
439 The idea behind the refactor is that the `sfTestFunctional` class is a test class,
440 not a browser. So, it takes a browser and a test object as its arguments:
441
442     [php]
443     $testBrowser = new sfTestBrowser('localhost');
444
445     $tester = new sfTestFunctional(new sfBrowser('localhost'), new lime_test());
446
447 The `sfTestFunctional` class acts as a proxy for the browser class which means
448 that all methods from the browser are accessible directly from the functional
449 tester object.
450
451 This refactor must not introduce backward incompatibility with symfony 1.1.
452
453 The browser classes now add the `HTTP_REFERER` header for each request.
454
455 Tests
456 -----
457
458 ### Testers
459
460 The `sfTestFunctionalBase` class now delegates the actual tests to `sfTester`
461 classes. symfony 1.2 has several built-in tester classes:
462
463   * `request`:    `sfTesterRequest`
464   * `response`:   `sfTesterResponse`
465   * `user`:       `sfTesterUser`
466   * `view_cache`: `sfTesterViewCache`
467
468 All the old methods from the test browser have been moved to one of the tester
469 class:
470
471  *method name*          | *tester class*      | *new method name*
472  ---------------------- | ------------------- | -----------------
473  `isRequestParameter`   | `sfTesterRequest`   | `isParameter`
474  `isRequestFormat`      | `sfTesterRequest`   | `isFormat`
475                         |                     |
476  `isStatusCode`         | `sfTesterResponse`  | `isStatusCode`
477  `responseContains`     | `sfTesterResponse`  | `contains`
478  `isResponseHeader`     | `sfTesterResponse`  | `isHeader`
479  `checkResponseElement` | `sfTesterResponse`  | `checkElement`
480                         |                     |
481  `isUserCulture`        | `sfTesterUser`      | `isCulture`
482                         |                     |
483  `isCached`             | `sfTesterViewCache` | `isCached`
484  `isUriCached`          | `sfTesterViewCache` | `isUriCached`
485
486 The tester classes also comes with new test methods:
487
488  *tester class*      | *new method name*
489  ------------------- | -----------------
490  `sfTesterRequest`   | `hasCookie`
491  `sfTesterRequest`   | `isCookie`
492  `sfTesterRequest`   | `isMethod`
493                      |
494  `sfTesterUser`      | `isAuthenticated`
495  `sfTesterUser`      | `hasCredential`
496  `sfTesterUser`      | `isAttribute`
497  `sfTesterUser`      | `isFlash`
498
499 Even if the old methods are deprecated, they do not send any warning and will
500 not be removed to maintain backward compatibility with symfony 1.0 and 1.1.
501
502 ### Links
503
504 When you simulate a click on a button or on a link, you give the name to the `click()`
505 method. But you don't have the possibility to differentiate two different links or buttons
506 with the same name.
507
508 As of symfony 1.2, the `click()` method takes a third argument to pass some options.
509
510 You can pass a `position` option to change the link you want to click on:
511
512     [php]
513     $b->
514       click('/', array(), array('position' => 1))->
515       // ...
516     ;
517
518 By default, symfony clicks on the first link it finds in the page.
519
520 You can also pass a `method` option to change the method of the link or the form
521 you are clicking on:
522
523     [php]
524     $b->
525       click('/delete', array(), array('method' => 'delete'))->
526       // ...
527     ;
528
529 This is very useful when a link is converted to a dynamic form generated
530 with JavaScript.
531
532 Actions
533 -------
534
535 By default, when you use the `redirectIf()` or `redirectUnless()` methods
536 in your actions, symfony automatically changes the response HTTP status
537 code to 302.
538
539 These two methods now have an additional optional argument to change this
540 default status code:
541
542     [php]
543     $this->redirectIf($condition, '@homepage', 301);
544     $this->redirectUnless($condition, '@homepage', 301);
545
546 The `redirect()` method already have this feature.
547
548 Components
549 ----------
550
551 If you have the output escaper enabled, there was a bug in symfony 1.0 and 1.1.
552 When you passed some variables from an action to a component, these were escaped
553 in the component. So, in some circumstances, you had to unescaped them:
554
555     [php]
556     public function executeInAComponent($request)
557     {
558       $this->foo = $this->foo->getRawValue();
559     }
560
561 As of symfony 1.2, this has been fixed and all variables are now unescaped
562 by default in a component method.
563
564 For the above example, you will need to remove the `getRawValue()` step as
565 the framework does this automatically for you.
566
567 sfParameterHolder
568 -----------------
569
570 The `has()` method of `sfParameterHolder` has been changed to be more
571 semantically correct.
572
573 It now returns `true` even if the value is `null`:
574
575     [php]
576     $ph = new sfParameterHolder();
577     $ph->set('foo', 'bar');
578     $ph->set('bar', null);
579
580     $ph->has('foo') === true;
581     $ph->has('bar') === true; // returns false under symfony 1.0 or 1.1
582
583 The `sfParameterHolder::has()` method is used by the `hasParameter()` and
584 `hasAttribute()` methods available for a large number of core classes.
585
586 Tasks
587 -----
588
589 The Propel tasks relying on Phing now output a clear error message if the embed
590 Phing task fails.
591
592 Some CLI tasks takes an application name as an argument because they need to connect
593 to the database. We need an application because the configuration can be customized
594 on an application basis and all the symfony configuration system is based on the
595 application level.
596
597 For these tasks, this argument has been removed in favor of an optional "application"
598 option. If you don't provide the "application" option, symfony will take the database
599 configuration from the project `databases.yml` file.
600
601 The following task signatures have been changed accordingly:
602
603  * `propel:build-all-load`
604  * `propel:data-dump`
605  * `propel:data-load`
606
607 >**Note**
608 >This is possible because `sfDatabaseManager` now takes a project configuration or an
609 application configuration. For the curious one, this works because
610 `sfDatabaseConfigHandler` now returns a static or a dynamic configuration based
611 on an array of configuration files (see the `execute()` and `evaluate()` methods).
612
613 The `propel:insert-sql` task removes all the data from the database.
614 As it destroys information, it now asks the user to confirm the execution of
615 the task. The same goes for the `propel:build-all` and `propel:build-all-load` tasks,
616 as they call the `propel:insert-sql` task.
617
618 If you want to use these tasks in a batch and want to avoid the confirmation question,
619 pass the `no-confirmation` option:
620
621     $ php symfony propel:insert-sql --no-confirmation
622
623 Before symfony 1.2, the `propel:insert-sql` task was the only task to read its
624 database configuration information from `propel.ini`. As of symfony 1.2, it
625 reads its information from `databases.yml`. So, if you use several different
626 connections in your model, the task will take those into account.
627 Thanks to this new feature, you can now use the `--connection` option
628 if you want to only load SQL statements for a given connection:
629
630     $ php symfony propel:insert-sql --connection=propel
631
632 You can also use the `--env` and the `--application` options to select a
633 specific configuration to use:
634
635     $ php symfony propel:insert-sql --env=prod --application=frontend
636
637 The `propel:generate-crud` has been renamed to `propel:generate-module`. The old
638 task name is still available as an alias.
639
640 The `non-atomic-actions` option of `propel:generate-module` has been removed
641 and some new options have been added:
642
643   * singular:          The singular name for the actions and templates
644   * plural:            The plural name for the actions and templates
645   * route-prefix:      The route prefix to use
646   * with-propel-route: Whether the related routes are Propel aware
647
648 To ease the debugging, the `propel:build-model`, `propel:build-all`, and
649 `propel:build-all-load` tasks do not remove the generated XML schemas anymore
650 if you pass the `--trace` option.
651
652 URL helpers
653 -----------
654
655 The old `post` option of `link_to` is still valid but deprecated:
656
657     [php]
658     // is deprecated
659     <?php echo link_to('@some_route', array('post' => true)) ?>
660
661     // and equivalent to
662     <?php echo link_to('@some_route', array('method' => 'post')) ?>
663
664 Using `link_to()` for non-symfony links is no longer possible in favour of the
665 new functionality. In fact, `link_to()` was never intended for cases like this:
666
667     [php]
668     // does no longer work
669     <?php echo link_to('Link', '#', array('onclick' => "alert('js')"); ?>
670
671     // use this instead
672     <a href="#" onclick="alert('js')">Link</a>
673
674 The `url_for()` and `link_to()` helpers support new signatures.
675 Instead of an internal URI, they can now also take the route name and
676 an array of parameters:
677
678     [php]
679     echo url_for('@article', array('id' => 1));
680     echo link_to('Link to article', '@article', array('id' => 1));
681
682 The old behavior still works without changing anything to your code.
683
684 Image helper
685 ------------
686
687 In symfony 1.0 and 1.1 the `image_tag` helper would generate the `alt`
688 attribute of the img-tag from the filename. This now only happens if
689 `sf_compat_10` is on. The new behaviour eases finding of unset alt attributes
690 using a (x)html validator. As a bonus, there is now a `alt_title` option that
691 will set alt and title attribute to the same value, which is useful for cross
692 browser tooltips.
693
694 View
695 ----
696
697 You can override `sfViewCacheManager::generateCacheKey()` by defining a
698 `sf_cache_namespace_callable` setting. As of symfony 1.2, the callable
699 is now called with an additional argument, the view cache manager instance.
700
701 Configuration
702 -------------
703
704 Before symfony 1.2, all the plugins installed under the `plugins` directory,
705 and all built-in plugins were automatically loaded.
706
707 As of symfony 1.2, you need to enable the plugins you want to use in your projects.
708 You can do this in your `ProjectConfiguration` class. Here is how to enable the
709 Doctrine plugin and disable the Propel one:
710
711     [php]
712     public function setup()
713     {
714       $this->enablePlugins('sfDoctrinePlugin');
715       $this->disablePlugins('sfPropelPlugin');
716     }
717
718 You can add several plugins in one call by passing an array of plugin names:
719
720     [php]
721     public function setup()
722     {
723       $this->enablePlugins(array('sfDoctrinePlugin', 'sfGuardPlugin'));
724     }
725
726 You can also change the order in which plugins are loaded by using the `setPlugins`
727 method:
728
729     [php]
730     public function setup()
731     {
732       $this->setPlugins(array('sfDoctrinePlugin', 'sfCompat10Plugin'));
733     }
734
735 The `orm` setting is deprecated in `settings.yml` as it is now automatically
736 set when the ORM plugin is loaded.
737
738 The `compat_10` setting is also deprecated in `settings.yml` as it is now
739 automatically set when the `sfCompat10Plugin` is loaded.
740
741 So, to enable the 1.0 compatibility plugin, you need to enable it in your
742 configuration:
743
744     [php]
745     public function setup()
746     {
747       $this->enablePlugins('sfCompat10Plugin');
748     }
749
750 By default, symfony only enables the Propel plugin.
751
752 You can also enable all installed plugins:
753
754     [php]
755     public function setup()
756     {
757       $this->enableAllPluginsExcept('sfDoctrinePlugin');
758     }
759
760 The previous example allows you to enable all plugins except the Doctrine one.
761 If you upgrade from 1.0 or 1.1, this line will make symfony behave like in
762 symfony 1.0 and 1.1.
763
764 The `sfLoader` class is deprecated as the `getHelperDirs()` and `loadHelpers()`
765 methods are now part of the `sfApplicationConfiguration` class. The `sfLoader`
766 methods now generate a deprecated log message and then call the new methods from
767 the current active configuration.
768
769 ### Plugin configuration
770
771 Plugins now have the option of providing a plugin configuration class. These
772 plugin configuration classes setup autoloading for the plugin, and are
773 instantiated in `sfProjectConfiguration`. This means symfony 1.2 tasks no
774 longer require an application argument for plugin classes to be used. This
775 allows plugins to connect to `command.*` events, something that was not
776 previously possible.
777
778 I18N
779 ----
780
781 Internally, the `sfCultureInfo` class is now only used as a singleton.
782 Even if it is still possible to bypass the `getInstance()` method and instantiate
783 a new object directly, it is deprecated. By using the singleton, the performance
784 are better as we only instantiate one culture info object per request and it
785 also means that you can now override some culture information globally in your
786 configuration classes.
787
788 The `sfCultureInfo::getCountries()`, `sfCultureInfo::getCurrencies()`, and
789 `sfCultureInfo::getLanguages()` methods now take an optional argument which allows
790 to restrict the return value:
791
792     [php]
793     // will only return the FR and ES countries in english
794     $countries = sfCultureInfo::getInstance('en')->getCountries(array('FR', 'ES'));
795
796 The `sfCultureInfo::getCurrencies()` method now returns an array of currency names.
797 In previous symfony versions, it returned an array with the symbol and the name.
798 To get the old behavior, just pass `true` as the second argument:
799
800     [php]
801     $currencies = sfCultureInfo::getInstance('en')->getCurrencies(null, true);
802
803 To get the translation of a single country, language, or currency, you can now
804 use the `getCountry()`, `getCurrency()`, and `getLanguage()` methods from the
805 `sfCultureInfo` class.
806
807 Exception Templates
808 -------------------
809
810 symfony now respects the current request format when rendering any uncaught
811 exceptions. You can customize each format's output by adding a template to
812 your project or application `config/error` directory.
813
814 For example, an uncaught exception during an XML request could render
815 `config/error/exception.xml.php` when your application is in debug mode, or
816 `config/error/error.xml.php` when your application is not in debug mode.
817
818 If you had customized the 500 error template in your project, you will
819 need to manually move it to the new directory:
820
821   * For symfony 1.1: from `config/error500.php` to `config/error/error.html.php`
822   * For symfony 1.0: from `web/errors/error500.php` to `config/error/error.html.php`
Note: See TracBrowser for help on using the browser.